Skip to content
Snippets Groups Projects

BIG flow3r

Merged rahix requested to merge rahix/big-flow3r into main
2 unresolved threads
2 files
+ 61
24
Compare changes
  • Side-by-side
  • Inline
Files
2
+ 57
24
@@ -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:
@@ -300,7 +306,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.
#
@@ -316,8 +324,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
@@ -357,14 +369,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)
@@ -381,28 +393,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()
@@ -450,8 +472,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):
Loading