commit 428d668537ed59492e5961b64c5c280aed64e8ea Author: Jake Walker Date: Thu Nov 7 19:28:13 2024 +0000 initial commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c1e2c64 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba0b1d9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,266 @@ + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +### Python Patch ### +# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration +poetry.toml + +# ruff +.ruff_cache/ + +# LSP config files +pyrightconfig.json + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + + diff --git a/tildagon-app/.vscode/launch.json b/tildagon-app/.vscode/launch.json new file mode 100644 index 0000000..764307b --- /dev/null +++ b/tildagon-app/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Run simulator", + "type": "debugpy", + "request": "launch", + "program": "/Users/jakew/Projects/badge-2024-software/sim/run.py", + "console": "integratedTerminal", + "python": "/Users/jakew/.local/share/virtualenvs/sim-Yv4Q9tV7/bin/python" + } + ] +} diff --git a/tildagon-app/.vscode/settings.json b/tildagon-app/.vscode/settings.json new file mode 100644 index 0000000..785d768 --- /dev/null +++ b/tildagon-app/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "python.autoComplete.extraPaths": [ + "/Users/jakew/Projects/badge-2024-software/modules" + ], + "python.analysis.extraPaths": [ + "/Users/jakew/Projects/badge-2024-software/modules" + ] +} diff --git a/tildagon-app/LICENSE b/tildagon-app/LICENSE new file mode 100644 index 0000000..32f544a --- /dev/null +++ b/tildagon-app/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + For more information, please refer to diff --git a/tildagon-app/README.md b/tildagon-app/README.md new file mode 100644 index 0000000..af19013 --- /dev/null +++ b/tildagon-app/README.md @@ -0,0 +1,3 @@ +```bash +mpremote mip install "github:peterhinch/micropython_ir/ir_rx" +``` diff --git a/tildagon-app/app.py b/tildagon-app/app.py new file mode 100644 index 0000000..9e42fe7 --- /dev/null +++ b/tildagon-app/app.py @@ -0,0 +1,182 @@ +import time + +from app_components import Menu, clear_background +from app_components.tokens import button_labels +from events.input import BUTTON_TYPES, Buttons +from perf_timer import PerfTimer + +import app + +WHITE_COLOR = (255, 255, 255) +BLACK_COLOR = (0, 0, 0) +TEAM_A_COLOR = (255, 107, 107) +TEAM_B_COLOR = (51, 154, 240) + +BTN_LABEL_MODE = "Mode" +BTN_LABEL_RESET = "Reset" +BTN_LABEL_TEAM_A = "<-" +BTN_LABEL_TEAM_B = "->" +BTN_LABEL_SETTINGS = "..." + +MENU_ITEM_SET_WIN_COND_11 = "Win pts = 11" +MENU_ITEM_SET_WIN_COND_21 = "Win pts = 21" +MENU_ITEM_QUIT = "Quit" + +MODE_INCREMENT = "Increment" +MODE_DECREMENT = "Decrement" + + +class Scoreboard(app.App): + win_points = 11 + a_score = 18 + b_score = 18 + mode = MODE_INCREMENT + settings_menu = None + winner = None + + def __init__(self): + super().__init__() + self.button_states = Buttons(self) + + def select_handler(self, item, index): + if item == MENU_ITEM_QUIT: + self.back_handler() + self.minimise() + self.button_states.clear() + elif item == MENU_ITEM_SET_WIN_COND_11: + self.win_points = 11 + elif item == MENU_ITEM_SET_WIN_COND_21: + self.win_points = 21 + + # close menu + self.back_handler() + + def back_handler(self): + if self.settings_menu is not None: + self.settings_menu._cleanup() + + self.settings_menu = None + self.button_states.clear() + + async def run(self, render_update): + last_time = time.ticks_ms() + while True: + cur_time = time.ticks_ms() + delta_ticks = time.ticks_diff(cur_time, last_time) + with PerfTimer(f"Updating {self}"): + self.update(delta_ticks) + await render_update() + last_time = cur_time + + def check_win_condition(self): + diff = abs(self.a_score - self.b_score) + + if ( + self.a_score >= self.win_points + and self.a_score > self.b_score + and diff >= 2 + ): + self.winner = "a" + elif ( + self.b_score >= self.win_points + and self.b_score > self.a_score + and diff >= 2 + ): + self.winner = "b" + else: + self.winner = None + + def update(self, delta): + if self.settings_menu is not None: + self.settings_menu.update(delta) + return + + if self.button_states.get(BUTTON_TYPES["UP"]): + if self.mode == MODE_INCREMENT: + self.mode = MODE_DECREMENT + else: + self.mode = MODE_INCREMENT + self.button_states.clear() + + if self.button_states.get(BUTTON_TYPES["DOWN"]): + self.a_score = 0 + self.b_score = 0 + self.mode = MODE_INCREMENT + self.winner = None + self.button_states.clear() + + if self.button_states.get(BUTTON_TYPES["LEFT"]): + if self.mode == MODE_INCREMENT: + self.a_score += 1 + elif self.mode == MODE_DECREMENT and self.a_score > 0: + self.a_score -= 1 + + self.check_win_condition() + self.button_states.clear() + + if self.button_states.get(BUTTON_TYPES["RIGHT"]): + if self.mode == MODE_INCREMENT: + self.b_score += 1 + elif self.mode == MODE_DECREMENT and self.b_score > 0: + self.b_score -= 1 + + self.check_win_condition() + self.button_states.clear() + + if self.button_states.get(BUTTON_TYPES["CONFIRM"]): + self.settings_menu = Menu( + self, + menu_items=[ + MENU_ITEM_SET_WIN_COND_11, + MENU_ITEM_SET_WIN_COND_21, + MENU_ITEM_QUIT, + ], + select_handler=self.select_handler, + back_handler=self.back_handler, + ) + self.button_states.clear() + + def draw(self, ctx): + clear_background(ctx) + + if self.settings_menu is not None: + self.settings_menu.draw(ctx) + return + + bg_color = BLACK_COLOR + fg_color = WHITE_COLOR + team_a_fg = TEAM_A_COLOR + team_b_fg = TEAM_B_COLOR + + if self.winner is not None: + bg_color = TEAM_A_COLOR if self.winner == "a" else TEAM_B_COLOR + fg_color = BLACK_COLOR + team_a_fg = TEAM_A_COLOR if self.winner == "b" else fg_color + team_b_fg = TEAM_B_COLOR if self.winner == "a" else fg_color + + ctx.rgb(*bg_color).rectangle(-120, -120, 240, 240).fill() + + button_labels( + ctx, + up_label=self.mode, + down_label=BTN_LABEL_RESET, + left_label=BTN_LABEL_TEAM_A, + right_label=BTN_LABEL_TEAM_B, + confirm_label=BTN_LABEL_SETTINGS, + ) + + ctx.text_align = ctx.CENTER + + ctx.font_size = 20 + ctx.font = "Arimo Bold" + ctx.rgb(*fg_color).move_to(0, 60).text(f"w={self.win_points}") + + ctx.font_size = 96 + ctx.font = "Arimo Bold" + ctx.rgb(*team_a_fg).move_to(-50, 0).text(self.a_score) + ctx.rgb(*team_b_fg).move_to(50, 0).text(self.b_score) + + self.draw_overlays(ctx) + + +__app_export__ = Scoreboard diff --git a/tildagon-app/tildagon.toml b/tildagon-app/tildagon.toml new file mode 100644 index 0000000..e5d5edb --- /dev/null +++ b/tildagon-app/tildagon.toml @@ -0,0 +1,14 @@ +[app] +name = "Scoreboard" +category = "Apps" +wifi_preference = false + +[entry] +class = "Scoreboard" + +[metadata] +author = "jake-walker" +license = "Unlicense" +url = "https://github.com/jake-walker/tildagon-scoreboard" +description = "A simple scoreboard" +version = "0.0.1"