from sdl2 import * import ctypes import atexit import numpy from polycal5 import KEY_NONE, KEY_LEFT, KEY_UP, KEY_DOWN, KEY_RIGHT, \ KEY_ENTER, KEY_ESC, KEY_LEFT_PARENTHESIS, KEY_RIGHT_PARENTHESIS, \ KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 window = None renderer = None surface = None pixels = None WIDTH, HEIGHT, SCALE = -1, -1, -1 pause_on_quit = False def polycalc_pc_init(width=0, height=0, scale=1): if SDL_Init(SDL_INIT_VIDEO) < 0: raise Exception("Failed to initialize SDL") dm = SDL_DisplayMode() SDL_GetCurrentDisplayMode(0, ctypes.byref(dm)) global window, renderer, surface, pixels, WIDTH, HEIGHT, SCALE if width <= 0: width = dm.w // SCALE if height <= 0: height = dm.h // SCALE WIDTH, HEIGHT, SCALE = width, height, scale window = SDL_CreateWindow("Polycalc SDL2".encode(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width*SCALE, height*SCALE, SDL_WINDOW_SHOWN) renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED) surface = SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0) if None in [window, renderer, surface]: raise Exception("Failed to create SDL2 objects: " + SDL_GetError()) SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, b'0') SDL_SetRenderTarget(renderer, None) SDL_RenderSetScale(renderer, SCALE, SCALE) w = surface.contents.pitch // 4 h = surface.contents.h pxtype = ctypes.POINTER(ctypes.c_uint32 * (w*h)) pxbuffer = ctypes.cast(surface.contents.pixels, pxtype) pixels = numpy.ctypeslib.as_array(pxbuffer.contents) atexit.register(polycalc_pc_quit) def mkRGBA(color): return (color[0] << 16) + (color[1] << 8) + color[2] def poly_clean_screen(): for i in range(WIDTH*HEIGHT): pixels[i] = 0xffffffff def poly_set_pixel(x, y, color): if x >= 0 and x < WIDTH and y >= 0 and y < HEIGHT: pixels[y*WIDTH + x] = mkRGBA(color) def poly_show(): texture = SDL_CreateTextureFromSurface(renderer, surface) SDL_RenderCopy(renderer, texture, None, None) SDL_RenderPresent(renderer) SDL_DestroyTexture(texture) def poly_sdl2_screenshot(scale=-1, fname=None): global renderer global texture if scale == -1: scale = SCALE w = WIDTH * scale h = HEIGHT * scale if fname == None: fname = b"poly_sdl2_screenshot.bmp" fname = bytes(fname) surface = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0) SDL_SetRenderTarget(renderer, None) SDL_RenderSetScale(renderer, scale, scale) SDL_RenderReadPixels(renderer, None, 0, surface.contents.pixels, surface.contents.pitch) SDL_SaveBMP(surface, fname) SDL_SetRenderTarget(renderer, texture) SDL_RenderSetScale(renderer, 1, 1) def poly_pause(): event = SDL_Event() while 1: SDL_WaitEvent(event) if event.type == SDL_KEYDOWN: break if event.type == SDL_QUIT: raise SystemExit def poly_fill_rect(x, y, w, h, color): SDL_SetRenderDrawColor(renderer, color[0], color[1], color[2], 255) SDL_RenderFillRect(renderer, SDL_Rect(x, y, w, h)) _keys = { KEY_LEFT: (SDLK_LEFT, SDL_SCANCODE_LEFT), KEY_UP: (SDLK_UP, SDL_SCANCODE_UP), KEY_DOWN: (SDLK_DOWN, SDL_SCANCODE_DOWN), KEY_RIGHT: (SDLK_RIGHT, SDL_SCANCODE_RIGHT), KEY_ENTER: (SDLK_RETURN, SDL_SCANCODE_RETURN), KEY_ESC: (SDLK_ESCAPE, SDL_SCANCODE_ESCAPE), KEY_LEFT_PARENTHESIS: (SDLK_LEFTPAREN, SDL_SCANCODE_5), KEY_RIGHT_PARENTHESIS: (SDLK_RIGHTPAREN, SDL_SCANCODE_MINUS), KEY_0: (SDLK_0, SDL_SCANCODE_0), KEY_1: (SDLK_1, SDL_SCANCODE_1), KEY_2: (SDLK_2, SDL_SCANCODE_2), KEY_3: (SDLK_3, SDL_SCANCODE_3), KEY_4: (SDLK_4, SDL_SCANCODE_4), KEY_5: (SDLK_5, SDL_SCANCODE_5), KEY_6: (SDLK_6, SDL_SCANCODE_6), KEY_7: (SDLK_7, SDL_SCANCODE_7), KEY_8: (SDLK_8, SDL_SCANCODE_8), KEY_9: (SDLK_9, SDL_SCANCODE_9), } def poly_wait_key(): event = SDL_Event() while 1: SDL_WaitEvent(event) if event.type == SDL_KEYDOWN: for key, value in _keys.items(): if event.key.keysym.sym == value[0]: return key def poly_test_key(key): st = SDL_GetKeyboardState(None) return st[_keys[key][1]] != 0 def poly_esc_key(): return poly_test_key(KEY_ESC) def poly_get_key(): for key in _keys: if poly_test_key(key): return key return KEY_NONE def poly_wait_release(): t = 1 while t: poly_ignore_events() t = 0 for key in _keys: if poly_test_key(key): t = 1 break def polycalc_pc_quit(): poly_show() if pause_on_quit: poly_pause() SDL_FreeSurface(surface) SDL_DestroyRenderer(renderer) SDL_DestroyWindow(window) SDL_Quit() def poly_ignore_events(): event = SDL_Event() while SDL_PollEvent(ctypes.byref(event)): pass