# fx-92 Scientifique Collège+ language interpreter: On-screen drawing from sdl2 import * class Window: """ An SDL window with pixel scaling. """ BLACK = (0, 0, 0, 255) WHITE = (255, 255, 255, 255) def __init__(self, width, height, scale): self.width = width self.height = height self.scale = scale def __enter__(self): """ Enter window context: allocate and create a window. """ if SDL_WasInit(SDL_INIT_VIDEO): raise Exception("Cannot create two windows") if SDL_Init(SDL_INIT_VIDEO) < 0: raise Exception("Failed to initialize SDL") # Create the window self.w = SDL_CreateWindow("fx-92 Scientifique Collège+".encode(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, self.width*self.scale, self.height*self.scale, SDL_WINDOW_SHOWN) if self.w is None: raise Exception("Failed to create window") # Create the renderer self.r = SDL_CreateRenderer(self.w, -1, SDL_RENDERER_ACCELERATED) if self.r is None: SDL_DestroyWindow(self.w) raise Exception("Failed to create renderer") # Create the base texture where things will be rendered at scale 1 self.t = SDL_CreateTexture(self.r, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, self.width, self.height) if self.t is None: SDL_DestroyRenderer(r) SDL_DestroyWindow(w) raise Exception("Failed to create texture") SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, b'0') SDL_SetRenderTarget(self.r, self.t) self.clear(self.WHITE) self.update() return self def __exit__(self, *args): """ Exit context: close and destroy window. """ if self.t is not None: SDL_SetRenderTarget(self.r, None) SDL_DestroyTexture(self.t) if self.r is not None: SDL_DestroyRenderer(self.r) if self.w is not None: SDL_DestroyWindow(self.w) SDL_Quit() def clear(self, color): """Clear screen in a uniform color.""" SDL_SetRenderDrawColor(self.r, *color) SDL_RenderClear(self.r) def line(self, x1, x2, y1, y2, color): """Draw a straight line.""" SDL_SetRenderDrawColor(self.r, *color) SDL_RenderDrawLine(self.r, x1, x2, y1, y2) def wait(self): """Wait for the window to be closed.""" event = SDL_Event() while 1: SDL_WaitEvent(event) if event.type == SDL_QUIT: break if event.type == SDL_KEYDOWN: key = event.key.keysym.sym if key == SDLK_s: print("Going to save the picture, probably") def update(self): """Push window contents on-screen.""" # Target the window with scaling SDL_SetRenderTarget(self.r, None) SDL_RenderSetScale(self.r, self.scale, self.scale) # Push that to the screen SDL_RenderCopy(self.r, self.t, None, None) SDL_RenderPresent(self.r) # Go back to the texture SDL_SetRenderTarget(self.r, self.t) SDL_RenderSetScale(self.r, 1, 1)