Skip to content
Snippets Groups Projects
Verified Commit 222ee11c authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

chore: improved support for graphics

parent 1753a825
No related branches found
No related tags found
1 merge request!36Support for Python
Pipeline #3647 passed
......@@ -223,9 +223,7 @@ This is a [Game Boy](https://en.wikipedia.org/wiki/Game_Boy) emulator built usin
self._video.save_frame(self.image(), self._frame_index)
self._video.compute_next(self._frame_index)
# @TODO: this should be sample, meaning that not every
# single frame is sent to the display (performance)
if self._display != None:
if self._display != None and self._display.should_render(self._frame_index):
from .graphics import Display
cast(Display, self._display).render_frame(self.frame_buffer())
......
from math import ceil
from typing import Union
from sdl2 import (
SDL_QUIT,
......@@ -8,15 +9,18 @@ from sdl2 import (
SDL_DestroyTexture,
SDL_FreeSurface,
)
from sdl2.ext import Window, Renderer, Color, init as init_sdl, get_events
from sdl2.ext import Window, Renderer, init as init_sdl, get_events
from .boytacean import DISPLAY_WIDTH, DISPLAY_HEIGHT
from .boytacean import DISPLAY_WIDTH, DISPLAY_HEIGHT, VISUAL_FREQ
class Display:
_width: int = DISPLAY_WIDTH
_height: int = DISPLAY_HEIGHT
_title: str = "Boytacean"
_scale: float = 3.0
_frame_gap: int = 60
_next_frame: int = 60
_window: Union[Window, None] = None
_renderer: Union[Renderer, None] = None
......@@ -25,20 +29,32 @@ class Display:
width: int = DISPLAY_WIDTH,
height: int = DISPLAY_HEIGHT,
title="Boytacean",
scale=3.0,
start_frame=0,
fps=5,
):
self._width = width
self._height = height
self._title = title
self._scale = scale
self._frame_gap = ceil(VISUAL_FREQ / fps)
self._next_frame = start_frame + self._frame_gap
self._window = None
self._renderer = None
self.build()
def build(self):
init_sdl()
self._window = Window(self._title, size=(self._width, self._height))
self._window = Window(
self._title,
size=(int(self._width * self._scale), int(self._height * self._scale)),
)
self._window.show()
self._renderer = Renderer(self._window)
def should_render(self, frame_index) -> bool:
return frame_index >= self._next_frame
def render_frame(self, frame_buffer: bytes):
if not self._window:
raise RuntimeError("Window not initialized")
......@@ -49,7 +65,7 @@ class Display:
# we consider that every time there's a request for a new
# frame draw the queue of SDL events should be flushed
events = get_events()
for event in events:
for _ in events:
pass
surface = SDL_CreateRGBSurfaceFrom(
......@@ -58,9 +74,9 @@ class Display:
DISPLAY_HEIGHT,
24,
DISPLAY_WIDTH * 3,
0x000000ff,
0x0000ff00,
0x00ff0000,
0x000000FF,
0x0000FF00,
0x00FF0000,
0x0,
)
texture = SDL_CreateTextureFromSurface(
......@@ -72,9 +88,11 @@ class Display:
self._renderer.sdlrenderer,
texture,
None,
SDL_Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT),
None,
)
self._renderer.present()
finally:
SDL_DestroyTexture(texture)
SDL_FreeSurface(surface)
self._next_frame += self._frame_gap
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment