initial commit
This commit is contained in:
commit
428d668537
8 changed files with 525 additions and 0 deletions
12
.editorconfig
Normal file
12
.editorconfig
Normal file
|
@ -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
|
266
.gitignore
vendored
Normal file
266
.gitignore
vendored
Normal file
|
@ -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
|
||||||
|
|
||||||
|
|
16
tildagon-app/.vscode/launch.json
vendored
Normal file
16
tildagon-app/.vscode/launch.json
vendored
Normal file
|
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
8
tildagon-app/.vscode/settings.json
vendored
Normal file
8
tildagon-app/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"python.autoComplete.extraPaths": [
|
||||||
|
"/Users/jakew/Projects/badge-2024-software/modules"
|
||||||
|
],
|
||||||
|
"python.analysis.extraPaths": [
|
||||||
|
"/Users/jakew/Projects/badge-2024-software/modules"
|
||||||
|
]
|
||||||
|
}
|
24
tildagon-app/LICENSE
Normal file
24
tildagon-app/LICENSE
Normal file
|
@ -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 <https://unlicense.org/>
|
3
tildagon-app/README.md
Normal file
3
tildagon-app/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
```bash
|
||||||
|
mpremote mip install "github:peterhinch/micropython_ir/ir_rx"
|
||||||
|
```
|
182
tildagon-app/app.py
Normal file
182
tildagon-app/app.py
Normal file
|
@ -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
|
14
tildagon-app/tildagon.toml
Normal file
14
tildagon-app/tildagon.toml
Normal file
|
@ -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"
|
Loading…
Reference in a new issue