add SDL2 rendering with a simple test

This commit is contained in:
Lephe 2019-10-01 13:40:52 +02:00
parent f08f613a17
commit 8269ab3f19
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
2 changed files with 120 additions and 0 deletions

113
drawing.py Normal file
View File

@ -0,0 +1,113 @@
# 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)

View File

@ -4,6 +4,7 @@ import sys
from parser import UrlParser
from printer import print_ast
from drawing import Window
#---
# fx-92 SC+ interpreter
@ -39,5 +40,11 @@ def main(argv):
print_ast(ast, lang="ast")
with Window(width=96, height=32, scale=8) as w:
w.clear(w.WHITE)
w.line(1, 1, 20, 20, w.BLACK)
w.update()
w.wait()
if __name__ == "__main__":
main(sys.argv)