diff --git a/python_payload/apps/graphics_mode/__init__.py b/python_payload/apps/graphics_mode/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..14b50772f6d8e9fb3d0d7bd61c7418bdc8a735dd --- /dev/null +++ b/python_payload/apps/graphics_mode/__init__.py @@ -0,0 +1,231 @@ +from st3m.application import Application +import math, random, sys_display + + +class App(Application): + def __init__(self, app_ctx): + super().__init__(app_ctx) + + self.x = 23 + self.x_vel = 40 / 1000.0 + + self.y = -53 + self.font_size = 18 + self.delta_ms = 0 + self.right_pressed = False + self.left_pressed = False + self.select_pressed = False + self.angle = 0 + self.focused_widget = 2 + self.active = False + + def draw_widget(self, label): + ctx = self.ctx + self.widget_no += 1 + if not self.active: + if self.select_pressed and self.focused_widget > 0: + self.active = True + self.select_pressed = False + elif self.left_pressed: + self.focused_widget -= 1 + if self.focused_widget < 2: + self.focused_widget = 2 + self.left_pressed = False + elif self.right_pressed: + self.focused_widget += 1 + if self.focused_widget > 8: + self.focused_widget = 8 + self.right_pressed = False + if self.widget_no == self.focused_widget and not self.active: + ctx.rectangle(-130, int(self.y - self.font_size * 0.8), 260, self.font_size) + ctx.line_width = 2.0 + ctx.rgba(0.8, 0.6, 0.1, 1.0) + ctx.stroke() + ctx.gray(1) + ctx.move_to(-95, self.y) + self.y += self.font_size + ctx.text(label + ": ") + + def draw_choice(self, label, choices, no): + ctx = self.ctx + self.draw_widget(label) + if self.widget_no == self.focused_widget and self.active: + if self.left_pressed: + no -= 1 + if no < 0: + no = 0 + elif self.right_pressed: + no += 1 + if no >= len(choices): + no = len(choices) - 1 + elif self.select_pressed: + self.active = False + self.select_pressed = False + + for a in range(len(choices)): + if a == no and self.active and self.widget_no == self.focused_widget: + ctx.save() + ctx.rgba(0.8, 0.6, 0.1, 1.0) + ctx.rectangle( + ctx.x - 1, + ctx.y - self.font_size * 0.8, + ctx.text_width(choices[a]) + 2, + self.font_size, + ).stroke() + ctx.restore() + ctx.text(choices[a] + " ") + elif a == no: + ctx.save() + ctx.gray(1) + ctx.rectangle( + ctx.x - 1, + ctx.y - self.font_size * 0.8, + ctx.text_width(choices[a]) + 2, + self.font_size, + ).fill() + ctx.gray(0) + ctx.text(choices[a] + " ") + ctx.restore() + else: + ctx.text(choices[a] + " ") + return no + + def draw_boolean(self, label, value): + ctx = self.ctx + self.draw_widget(label) + if self.widget_no == self.focused_widget and self.active: + value = not value + self.active = False + + if value: + ctx.text(" on") + else: + ctx.text(" off") + return value + + def draw_bg(self): + ctx = self.ctx + ctx.gray(1.0) + ctx.font_size = self.font_size + ctx.move_to(-100, -50) + self.y = -50 + self.widget_no = 0 + ctx.rectangle(-120, -120, 240, 240) + ctx.gray(0) + ctx.fill() + ctx.save() + ctx.translate(self.x, -80) + ctx.logo(0, 0, 40) + ctx.restore() + self.x += self.delta_ms * self.x_vel + if self.x < -50 or self.x > 50: + self.x_vel *= -1 + self.x += self.delta_ms * self.x_vel + + def draw(self, ctx: Context): + curmode = sys_display.get_mode() + low_latency = (curmode & sys_display.low_latency) != 0 + direct_ctx = (curmode & sys_display.direct_ctx) != 0 + lock = (curmode & sys_display.force) != 0 + osd = (curmode & sys_display.osd) != 0 + scale = 0 + if (curmode & sys_display.x4) == sys_display.x2: + scale = 1 + elif (curmode & sys_display.x4) == sys_display.x3: + scale = 2 + elif (curmode & sys_display.x4) == sys_display.x4: + scale = 3 + + bpp = curmode & 63 + palette = 0 + if bpp == 9: + palette = 0 + bpp = 0 + elif bpp == 8: + palette = 1 + bpp = 0 + elif bpp == 10: + palette = 2 + bpp = 0 + elif bpp == 11: + palette = 3 + bpp = 0 + elif bpp == 16: + bpp = 1 + elif bpp == 24: + bpp = 2 + else: + bpp = 0 + + self.ctx = ctx + self.draw_bg() + + self.draw_widget("mode") + ctx.text(str(curmode)) + + bpp = self.draw_choice("bpp", ["8", "16", "24"], bpp) + palette = self.draw_choice("palette", ["RGB", "gray", "sepia", "cool"], palette) + scale = self.draw_choice("scale", ["1x", "2x", "3x", "4x"], scale) + low_latency = self.draw_boolean("low latency", low_latency) + direct_ctx = self.draw_boolean("direct ctx", direct_ctx) + osd = self.draw_boolean("osd", osd) + lock = self.draw_boolean("lock", lock) + if direct_ctx: + low_latency = True + bpp = 8 + if palette < 1: + palette = 2 + if palette != 0: + bpp = 0 + + if bpp == 0: + if palette == 0: + mode = 9 + elif palette == 1: + mode = 8 + elif palette == 2: + mode = 10 + elif palette == 3: + mode = 11 + elif bpp == 1: + mode = 16 + elif bpp == 2: + mode = 24 + + mode += osd * sys_display.osd + mode += low_latency * sys_display.low_latency + mode += direct_ctx * sys_display.direct_ctx + mode += lock * sys_display.force + + if scale == 1: + mode += sys_display.x2 + elif scale == 2: + mode += sys_display.x3 + elif scale == 3: + mode += sys_display.x4 + + if mode != curmode: + sys_display.set_default_mode(mode) + + ################################################################ + + self.delta_ms = 0 + self.select_pressed = False + self.left_pressed = False + self.right_pressed = False + + def think(self, ins, delta_ms): + super().think(ins, delta_ms) + self.delta_ms += delta_ms + if self.input.buttons.app.right.pressed: + self.right_pressed = True + if self.input.buttons.app.left.pressed: + self.left_pressed = True + if self.input.buttons.app.middle.pressed: + self.select_pressed = True + + +if __name__ == "__main__": + from st3m.run import run_app + + run_app(App) diff --git a/python_payload/apps/graphics_mode/flow3r.toml b/python_payload/apps/graphics_mode/flow3r.toml new file mode 100644 index 0000000000000000000000000000000000000000..449a2791a526761f3498715d256261b88b7188a8 --- /dev/null +++ b/python_payload/apps/graphics_mode/flow3r.toml @@ -0,0 +1,8 @@ +[app] +name = "Graphics Mode" +menu = "Hidden" + +[metadata] +author = "Flow3r Badge Authors" +license = "LGPL-3.0-only" +url = "https://git.flow3r.garden/flow3r/flow3r-firmware" diff --git a/python_payload/st3m/run.py b/python_payload/st3m/run.py index e36f7cf76900307dfd0e37a58904e25f93b398cd..38e18aad4926e28f9d7a291f50dc1f0a96a45164 100644 --- a/python_payload/st3m/run.py +++ b/python_payload/st3m/run.py @@ -165,78 +165,11 @@ def run_main() -> None: log.error(f"Failed to set hostname {e}") menu_settings = settings.build_menu() - menu_gfx = SimpleMenu( - [ - MenuItemBack(), - MenuItemAction("RGB565_BS", lambda: sys_display.set_default_mode(16)), - MenuItemAction("RGB888", lambda: sys_display.set_default_mode(24)), - MenuItemAction( - "RGB332", - lambda: sys_display.set_default_mode(sys_display.rgb332), - ), - MenuItemAction("gray 8bit", lambda: sys_display.set_default_mode(8)), - MenuItemAction( - "sepia 8bit", - lambda: sys_display.set_default_mode(sys_display.sepia), - ), - MenuItemAction( - "cool 8bit", - lambda: sys_display.set_default_mode(sys_display.cool), - ), - MenuItemAction( - "1x", - lambda: sys_display.set_default_mode( - sys_display.unset + sys_display.x4 - ), - ), - MenuItemAction("2x", lambda: sys_display.set_default_mode(sys_display.x2)), - MenuItemAction("3x", lambda: sys_display.set_default_mode(sys_display.x3)), - MenuItemAction("4x", lambda: sys_display.set_default_mode(sys_display.x4)), - MenuItemAction( - "osd on", lambda: sys_display.set_default_mode(sys_display.osd) - ), - MenuItemAction( - "osd off", - lambda: sys_display.set_default_mode( - sys_display.unset + sys_display.osd - ), - ), - MenuItemAction( - "high fps", - lambda: sys_display.set_default_mode( - sys_display.unset + sys_display.low_latency - ), - ), - MenuItemAction( - "low-latency", - lambda: sys_display.set_default_mode(sys_display.low_latency), - ), - MenuItemAction( - "drawlists", - lambda: sys_display.set_default_mode( - sys_display.unset + sys_display.direct_ctx - ), - ), - MenuItemAction( - "direct ctx", - lambda: sys_display.set_default_mode(sys_display.direct_ctx), - ), - MenuItemAction( - "forced mode", lambda: sys_display.set_default_mode(sys_display.force) - ), - MenuItemAction( - "apps can set mode", - lambda: sys_display.set_default_mode( - sys_display.unset + sys_display.force - ), - ), - ], - ) menu_system = SimpleMenu( [ MenuItemBack(), MenuItemForeground("Settings", menu_settings), - MenuItemForeground("Graphics Mode", menu_gfx), + MenuItemAppLaunch(BundleMetadata("/flash/sys/apps/graphics_mode")), MenuItemAppLaunch(BundleMetadata("/flash/sys/apps/gr33nhouse")), MenuItemAction("Disk Mode (Flash)", machine.disk_mode_flash), MenuItemAction("Disk Mode (SD)", machine.disk_mode_sd),