Skip to content

Commit

Permalink
Faster lookup for framebuffer deltas
Browse files Browse the repository at this point in the history
  • Loading branch information
GMH-Code committed Oct 12, 2022
1 parent 6b9c357 commit febba38
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 16 deletions.
2 changes: 1 addition & 1 deletion scchip/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

# App identification
APP_NAME = "SuperChocChip Emulator"
APP_VERSION = "1.3.1"
APP_VERSION = "1.3.2"
APP_COPYRIGHT = "Copyright (C) 2022 Gregory Maynard-Hoare, licensed under GNU Affero General Public License v3.0"
APP_INTRO = "{} V{} -- ".format(APP_NAME, APP_VERSION)

Expand Down
34 changes: 20 additions & 14 deletions scchip/framebuffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,22 +105,19 @@ def xor_pixel(self, x, y, plane):
collision = (pixel != 0)
new_pixel = pixel ^ 0xFF
plane.write(vram_loc, new_pixel)
self._render_pixel(x, y)

self._render_pixel(vram_loc)
return collision

def _render_pixel(self, x, y):
def _render_pixel(self, vram_loc):
# Render the pixel to the display
vram_loc = x + y * self.vid_width
ram_banks = self.ram_banks
colour = 0

for plane_num in range(self.num_planes):
if self.ram_banks[plane_num].read(vram_loc):
if ram_banks[plane_num].read(vram_loc):
colour += 2 ** plane_num

if self.vid_cache.read(vram_loc) != colour:
self.frame_delta[(x, y)] = colour
self.vid_cache.write(vram_loc, colour)
self.frame_delta[vram_loc] = colour

# Half-pixel vertical scrolling is unsupported in 64x32 pixel mode

Expand Down Expand Up @@ -184,17 +181,26 @@ def scroll_down(self, rows):

def _redraw_all(self):
# Redraw whole screen after a scroll. The video cache should take the load off the renderer a bit
for y in range(self.vid_height):
for x in range(self.vid_width):
self._render_pixel(x, y)
render_pixel = self._render_pixel

for vram_loc in range(self.vid_size):
render_pixel(vram_loc)

def refresh_display(self):
# Request the renderer updates altered pixels and then refreshes the display. This method results in a huge
# (around 5x) speed up when using PyPy with graphically-intensive games, and a tiny improvement with CPython.
for xy, colour in self.frame_delta.items():
self.renderer.set_pixel(*xy, colour)
vid_width = self.vid_width
vid_cache_read = self.vid_cache.read
vid_cache_write = self.vid_cache.write
renderer_set_pixel = self.renderer.set_pixel
content_changed = False

for vram_loc, colour in self.frame_delta.items():
if vid_cache_read(vram_loc) != colour:
renderer_set_pixel(vram_loc % vid_width, vram_loc // vid_width, colour)
vid_cache_write(vram_loc, colour)
content_changed = True

content_changed = bool(self.frame_delta)
self.frame_delta.clear()
self.renderer.refresh_display(content_changed)

Expand Down
2 changes: 1 addition & 1 deletion superchocchip.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
__author__ = "Gregory Maynard-Hoare"
__copyright__ = "Copyright (C) 2022 Gregory Maynard-Hoare"
__license__ = "GNU Affero General Public License v3.0"
__version__ = "1.3.1"
__version__ = "1.3.2"

from argparse import ArgumentParser
from scchip import main
Expand Down

0 comments on commit febba38

Please sign in to comment.