diff --git a/sim/fakes/_sim.py b/sim/fakes/_sim.py index 68101a8cb4c433c8d3e4e644d82ae3a87b39edbe..fe54b5cb31003644f8732f531fbf605cfcc6af14 100644 --- a/sim/fakes/_sim.py +++ b/sim/fakes/_sim.py @@ -7,17 +7,23 @@ import sys import pygame +SCREENSHOT = False +SCREENSHOT_DELAY = 5 +FULL_SCREEN = os.environ.get("SIM_FULL_SCREEN", "0") == "1" + + pygame.init() -screen_w = 814 -screen_h = 854 -screen = pygame.display.set_mode(size=(screen_w, screen_h)) +if FULL_SCREEN: + screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN) +else: + screen = pygame.display.set_mode(size=(814, 854)) +screen_w = screen.get_width() +screen_h = screen.get_height() simpath = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) bgpath = os.path.join(simpath, "background.png") background = pygame.image.load(bgpath) - -SCREENSHOT = False -SCREENSHOT_DELAY = 5 +OLED_SIZE = screen_h // 2 if FULL_SCREEN else 240 class Input: @@ -297,7 +303,9 @@ class Simulation: ) self._petal_surface_dirty = True self._full_surface = pygame.Surface((screen_w, screen_h), flags=pygame.SRCALPHA) - self._oled_surface = pygame.Surface((240, 240), flags=pygame.SRCALPHA) + self._oled_surface = pygame.Surface( + (OLED_SIZE, OLED_SIZE), flags=pygame.SRCALPHA + ) # Calculate OLED per-row offset. # @@ -313,8 +321,12 @@ class Simulation: # that is True if the pixel corresponding to this mask's bit is part of # the OLED disc, and false otherwise. mask = [ - [math.sqrt((x - 120) ** 2 + (y - 120) ** 2) <= 120 for x in range(240)] - for y in range(240) + [ + math.sqrt((x - OLED_SIZE // 2) ** 2 + (y - OLED_SIZE // 2) ** 2) + <= OLED_SIZE // 2 + for x in range(OLED_SIZE) + ] + for y in range(OLED_SIZE) ] # Now, we iterate the mask row-by-row and find the first True bit in # it. The offset within that row is our per-row offset for the @@ -354,14 +366,14 @@ class Simulation: surface.fill((0, 0, 0, 0)) buf = surface.get_buffer() - fb = fb[: 240 * 240 * 4] - for y in range(240): + fb = fb[: OLED_SIZE * OLED_SIZE * 4] + for y in range(OLED_SIZE): # Use precalculated row offset to turn OLED disc into square # bounded plane. offset = self._oled_offset[y] - start_offs_bytes = y * 240 * 4 + start_offs_bytes = y * OLED_SIZE * 4 start_offs_bytes += offset * 4 - end_offs_bytes = (y + 1) * 240 * 4 + end_offs_bytes = (y + 1) * OLED_SIZE * 4 end_offs_bytes -= offset * 4 buf.write(bytes(fb[start_offs_bytes:end_offs_bytes]), start_offs_bytes) @@ -378,28 +390,38 @@ class Simulation: need_overlays = False if self._led_surface_dirty or self._petal_surface_dirty: full.fill((0, 0, 0, 255)) - full.blit(background, (0, 0)) + if not FULL_SCREEN: + full.blit(background, (0, 0)) need_overlays = True if self._led_surface_dirty: - self._render_leds(self._led_surface) + if not FULL_SCREEN: + self._render_leds(self._led_surface) self._led_surface_dirty = False if need_overlays: full.blit(self._led_surface, (0, 0), special_flags=pygame.BLEND_ADD) if self._petal_surface_dirty: - self._render_petal_markers(self._petal_surface) + if not FULL_SCREEN: + self._render_petal_markers(self._petal_surface) self._petal_surface_dirty = False if need_overlays: - full.blit(self._petal_surface, (0, 0)) + if not FULL_SCREEN: + full.blit(self._petal_surface, (0, 0)) # Always blit oled. Its' alpha blending is designed in a way that it # can be repeatedly applied to a dirty _full_surface without artifacts. - center_x = 408 - center_y = 426 - off_x = center_x - (240 // 2) - off_y = center_y - (240 // 2) - full.blit(self._oled_surface, (off_x, off_y)) + center_x = screen_w // 2 + center_y = screen_h // 2 + if FULL_SCREEN: + off_x = center_x - (screen_h // 2) + off_y = center_y - (screen_h // 2) + new = pygame.transform.scale(self._oled_surface, (screen_h, screen_h)) + full.blit(new, (off_x, off_y)) + else: + off_x = center_x - (OLED_SIZE // 2) + off_y = center_y - (OLED_SIZE // 2) + full.blit(self._oled_surface, (off_x, off_y)) screen.blit(full, (0, 0)) pygame.display.flip() @@ -447,8 +469,19 @@ class FramebufferManager: def __init__(self): self._free = [] for _ in range(2): - fb, c = ctx._wasm.ctx_new_for_framebuffer(240, 240) - ctx._wasm.ctx_apply_transform(c, 1, 0, 120, 0, 1, 120, 0, 0, 1) + fb, c = ctx._wasm.ctx_new_for_framebuffer(OLED_SIZE, OLED_SIZE) + ctx._wasm.ctx_apply_transform( + c, + OLED_SIZE / 240, + 0, + OLED_SIZE / 2, + 0, + OLED_SIZE / 240, + OLED_SIZE / 2, + 0, + 0, + 1, + ) self._free.append((fb, c)) def get(self): diff --git a/sim/run.py b/sim/run.py index 3c4c285a0c672a3bf506426a9e4f726f216a0b48..02212fc92853f70f98819b5e6dee91111ced3f9b 100644 --- a/sim/run.py +++ b/sim/run.py @@ -112,9 +112,13 @@ os.stat = _stat def sim_main(): parser = argparse.ArgumentParser() parser.add_argument("--screenshot", action="store_true", default=False) + parser.add_argument( + "--full-screen", dest="full_screen", action="store_true", default=False + ) parser.add_argument("override_app", nargs="?") args = parser.parse_args() + os.environ["SIM_FULL_SCREEN"] = "1" if args.full_screen else "0" import _sim _sim.SCREENSHOT = args.screenshot