Merge branch 'master' into mstratford-dialogs

master
Matthew Stratford 2018-09-14 23:34:22 +01:00 committed by GitHub
commit 705167983d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 1094 additions and 143 deletions

View File

@ -61,6 +61,7 @@ def main():
cmd_parser.add_argument('-b', '--baudrate', default=115200, help='the baud rate of the serial device')
cmd_parser.add_argument('-v', '--verbose', action='store_true', help='adds more output')
cmd_parser.add_argument('--skip-wifi', action='store_true', help='does not sync wifi.json')
cmd_parser.add_argument('--bootstrapped-apps', action='store_true', help='[Sync] only bootstrapped apps by default')
cmd_parser.add_argument('--print_resources', action='store_true', help='prints resources in json')
cmd_parser.add_argument('--boot', help='defines which app to boot into after reboot')
cmd_parser.add_argument('--run', help='like run, but after a sync')
@ -120,9 +121,17 @@ def main():
pyboard_util.hard_reset(args)
if command == "sync":
paths = args.paths if len(args.paths) else None
if args.bootstrapped_apps:
for k,val in list(resources.items()):
if val.get("type", None) == "app":
if not k in paths and not val.get("bootstrapped", False):
if args.verbose:
print("Removing app '{0}' from sync list".format(k))
del resources[k]
if args.clean:
sync.clean(args)
paths = args.paths if len(args.paths) else None
synced_resources = sync.sync(args, paths, resources, args.verbose, args.skip_wifi)
if (command in ["reset", "sync"]) or run_tests:

View File

@ -1,9 +1,9 @@
"""3d rotating polyhedra. 2016 badge competition winner, ported for 2018!"""
___name___ = "3D Spin"
___title___ = "3D Spin"
___license___ = "MIT"
___categories___ = ["Demo"]
___dependencies___ = ["app", "ugfx_helper", "random", "sleep", "buttons"]
___dependencies___ = ["app", "ugfx_helper", "sleep", "buttons"]
import ugfx
from tilda import Buttons

View File

@ -1,6 +1,6 @@
""" starts an LED party on your badge
"""
___name___ = "LED Party (Party Party)"
___title___ = "LED Party (Party Party)"
___license___ = "MIT"
___dependencies___ = ["wifi", "http", "ugfx_helper", "sleep"]
___categories___ = ["LEDs"]

View File

@ -1,25 +1,40 @@
"""Accidentally created etcher sketch..."""
___name___ = "Sketchy Etch"
___title___ = "Sketchy Etch"
___name___ = "Sketchy-Etch"
___title___ = "Sketchy-Etch"
___license___ = "MIT"
___dependencies___ = ["ugfx_helper"]
___dependencies___ = ["ugfx_helper", "dialogs"]
___categories___ = ["Games"]
import ugfx, ugfx_helper, app
import ugfx, ugfx_helper, app, dialogs
from tilda import Buttons
from time import sleep
i = 0
j = 0
def reset():
global i
global j
i = int(ugfx.width() / 2)
j = int(ugfx.height() / 2)
ugfx.area(0, 0, ugfx.width(), ugfx.height(), ugfx.BLACK)
ugfx.area((i - 1) if i > 0 else 0, (j - 1) if j > 0 else 0, 3 if (i > 0 and i < (ugfx.width() - 1)) else 2, 3 if (j > 0 and j < (ugfx.height() - 1)) else 2, ugfx.GREY)
ugfx_helper.init()
ugfx.clear()
ugfx.area(0, 0, ugfx.width(), ugfx.height(), ugfx.BLACK)
dialogs.notice("Draw with joystick arrows\nHold joystick centre for circle\nA to clear\nB to exit", title="Sketchy-Etch")
i = int(ugfx.width() / 2)
j = int(ugfx.height() / 2)
while (not Buttons.is_pressed(Buttons.BTN_A)) and (not Buttons.is_pressed(Buttons.BTN_B)) and (not Buttons.is_pressed(Buttons.BTN_Menu)):
ugfx.area(0, 0, ugfx.width(), ugfx.height(), ugfx.BLACK)
circleSize = 3
reset()
while not Buttons.is_pressed(Buttons.BTN_B):
changed = False
oldI = i
oldJ = j
if Buttons.is_pressed(Buttons.JOY_Right) and (i < (ugfx.width() - 1)):
i += 1
@ -34,9 +49,20 @@ while (not Buttons.is_pressed(Buttons.BTN_A)) and (not Buttons.is_pressed(Button
elif Buttons.is_pressed(Buttons.JOY_Up) and (j > 0):
j -= 1
changed = True
if Buttons.is_pressed(Buttons.JOY_Center):
circleSize += 1
ugfx.fill_circle(i, j, circleSize, ugfx.WHITE)
changed = True
else:
circleSize = 3
if Buttons.is_pressed(Buttons.BTN_A):
reset()
if changed:
ugfx.area((i - 1) if i > 0 else 0, (j - 1) if j > 0 else 0, 3 if (i > 0 and i < (ugfx.width() - 1)) else 2, 3 if (j > 0 and j < (ugfx.height() - 1)) else 2, ugfx.WHITE)
ugfx.area((oldI - 1) if oldI > 0 else 0, (oldJ - 1) if oldJ > 0 else 0, 3 if (oldI > 0 and oldI < (ugfx.width() - 1)) else 2, 3 if (oldJ > 0 and oldJ < (ugfx.height() - 1)) else 2, ugfx.WHITE)
ugfx.area((i - 1) if i > 0 else 0, (j - 1) if j > 0 else 0, 3 if (i > 0 and i < (ugfx.width() - 1)) else 2, 3 if (j > 0 and j < (ugfx.height() - 1)) else 2, ugfx.GREY)
sleep(0.05)

View File

@ -1,6 +1,6 @@
"""A simple homescreen diplaying an avatar from an url and the user's name"""
___name___ = "Avatar Homescreen"
___title___ = "Avatar Homescreen"
___license___ = "WTFPL"
___categories___ = ["Homescreens"]
___dependencies___ = ["homescreen", "wifi", "http", "sleep", "app", "buttons"]

View File

@ -66,7 +66,7 @@ def show_app(a,c):
if install:
app_text = "App:\n{}\n\n".format(name)
with WaitingMessage(title="Installing App...", text="%sGetting ready..." % app_text) as message:
installers = store.install(_get_current_apps() + [a])
installers = store.install([a])
n = len(installers)
for i, installer in enumerate(installers):
message.text = "%s%s (%s/%s)" % (app_text + "Downloading files...\n\n", installer.path, i + 1, n)

View File

@ -1,6 +1,6 @@
"""This app creates a real EMF badge experience"""
___name___ = "EMF 2018 badge simulator"
___title___ = "EMF 2018 badge simulator"
___license___ = "MIT"
___categories___ = ["EMF"]
___dependencies___ = ["sleep", "app"]

View File

@ -1,5 +1,6 @@
"""An NTP time app"""
___name___ = "NTP time"
___title___ = "NTP time"
___license___ = "MIT"
___dependencies___ = ["ntp", "wifi", "app"]
___categories___ = ["EMF"]

View File

@ -2,7 +2,7 @@
Get up to date information on what's in stock at The Robot Arms!
"""
___name___ = "beer"
___title___ = "beer"
___license___ = "MIT"
___dependencies___ = ["app", "sleep", "wifi", "http", "ugfx_helper"]
___categories___ = ["EMF"]

141
bluetooth_speaker/main.py Normal file
View File

@ -0,0 +1,141 @@
"""App to use the badge as a (handset profile only) bluetooth speaker"""
___name___ = "Bluetooth Speaker"
___license___ = "MIT"
___dependencies___ = ["ugfx_helper", "sim800", "dialogs", "buttons", "app"]
___categories___ = ["Sound"]
import ugfx_helper, ugfx
import app
import sim800
from dialogs import *
import buttons
BLUETOOTH_NAME = "BadgeSpeaker"
g_paired = False
def pairing_dialog(scan_timeout_s=10):
''' Show BLE devices to pair with and connect. Returns True if paired, False if failed '''
waiting_message = WaitingMessage("Scanning for bluetooth devices for %s seconds"%scan_timeout_s, "Scanning")
devices = sim800.btscan(int(scan_timeout_s * 1000))
waiting_message.destroy()
# List format is [id, name, addr, rssi]. FIXME: Only returns 1 item?
try:
devices_prompts = [{'title': v[1], 'id': v[0]} for v in devices]
except TypeError: #Only one device found. #TODO: Not very neat
devices_prompts = [{'title':devices[1] ,'id':devices[0]},]
#TODO: Fix non printable chars in device names
option = prompt_option(devices_prompts, title="Devices Found", select_text="Select", none_text="Rescan")
if option:
sim800.btpair(option['id'])
passcode = sim800.btparingpasscode()
correct_passcode = prompt_boolean(passcode, title="Started connection from other device?", font=FONT_MEDIUM_BOLD)
if correct_passcode:
sim800.btpairconfirm() #TODO: 4 number passcodes?
return True
else:
sim800.btpairreject()
return False
else:
return False
def pairing_callback(param):
''' Callback for incoming pairing request '''
global g_paired
accept = prompt_boolean("Accept pairing request from %s"%param, title="Incoming pairing")
if accept:
sim800.btpairconfirm(0000)
# Check if we did pair
if len(sim800.btpaired()) > 1:
g_paired = True
else:
sim800.btpairreject()
def set_simple_pairing():
''' Set pairing mode to 4 digit pin, default 0000 '''
sim800.command("AT+BTPAIRCFG=1,0000", 1000, "OK") # TODO: Error checking?
#Initialise
ugfx_helper.init()
ugfx.init()
ugfx.clear()
ugfx.text(5,5, "Powering Up SIM800", ugfx.BLACK)
sim800.poweron()
ugfx.clear()
ugfx.text(5,5, "Enabling Bluetooth", ugfx.BLACK)
sim800.btpoweron()
sim800.btname(BLUETOOTH_NAME)
sim800.poweroff()
sim800.poweron()
sim800.btpoweron() # Needs a full cycle to have an effect
sim800.btvisible(True)
# Set pairing mode
set_simple_pairing()
ugfx.text(5,20, "Addr: %s " % sim800.btaddress(), ugfx.BLACK)
ugfx.text(5,35, "Name: %s " % sim800.btname(), ugfx.BLACK)
ugfx.clear()
# Register pairings callback
sim800.registercallback("+BTPAIRING:", pairing_callback)
clear_pairing = prompt_boolean("Delete all bluetooth pairings?",title="Clear Pairings?", true_text="Yes", false_text="No")
if clear_pairing:
sim800.btunpair(0) #0 = clear every pairing
# Start main loop
ugfx.clear()
ugfx.Label(5,5, 220, 200, "Connect to %s \n Passcode = 0000 \n Press menu to exit" % BLUETOOTH_NAME)
connected = True
while(True):
# Check for pairing button
if (buttons.is_triggered(buttons.Buttons.BTN_1)):
pairing_dialog()
# Check for exit button
if (buttons.is_triggered(buttons.Buttons.BTN_Menu)):
sim800.btpoweroff()
app.restart_to_default()
num_connections = len(sim800.btconnected())
if (connected == False) and (num_connections > 0): # Gained connection
ugfx.area(0,220,240,320, ugfx.BLACK) #Blank bottom of screen
print(sim800.btconnected())
sim800.speakervolume(100)
sim800.btvoicevolume(100)
ugfx.set_default_font(ugfx.FONT_TITLE)
ugfx.text(5,230,"CONNECTED!", ugfx.GREEN)
ugfx.set_default_font(ugfx.FONT_SMALL)
connected = True
elif (connected == True) and (num_connections == 0): # Lost connection
ugfx.area(0,220,240,320, ugfx.BLACK) #Blank bottom of screen
ugfx.set_default_font(ugfx.FONT_TITLE)
ugfx.text(5,230,"DISCONNECTED", ugfx.RED)
ugfx.set_default_font(ugfx.FONT_SMALL)
connected = False
sleep.wfi()

View File

@ -1,9 +1,9 @@
"""Breakout!"""
___name___ = "Breakout"
___title___ = "Breakout"
___license___ = "MIT"
___categories___ = ["Games"]
___dependencies___ = ["app", "ugfx_helper", "random", "buttons"]
___dependencies___ = ["app", "ugfx_helper", "buttons"]
from tilda import Buttons
import ugfx, ugfx_helper, dialogs

View File

@ -1,6 +1,6 @@
"""Scan for and display nearby bluetooth devices"""
___name___ = "Bluetooth Scan"
___title___ = "Bluetooth Scan"
___license___ = "MIT"
___dependencies___ = ["sleep", "app", "sim800"]
___categories___ = ["Other", "System"]

View File

@ -3,7 +3,7 @@ Clone of the default homescreen for the Tilda Mk4.
Shows the EMF homescreen and a picture loaded on the badge alternately.
"""
___name___ = "Custom Image Home"
___title___ = "Custom Image Home"
___license___ = "MIT"
___categories___ = ["Homescreens"]
___dependencies___ = ["homescreen", "shared/logo.png", "shared/sponsors.png"]

View File

@ -1,6 +1,6 @@
"""This is a dowsing rod for WiFi APs"""
___name___ = "Dowsing Rod"
___title___ = "Dowsing Rod"
___license___ = "MIT"
___dependencies___ = ["sleep", "app", "wifi", "sim800"]
___categories___ = ["EMF", "System"]

View File

@ -2,7 +2,7 @@
emfcampqueer theme by ganbariley
"""
___name___ = "EMFCamp Rainbow Homescreen"
___title___ = "EMFCamp Rainbow Homescreen"
___license___ = "MIT"
___categories___ = ["Homescreens"]
___dependencies___ = ["homescreen"]
@ -12,6 +12,12 @@ ___bootstrapped___ = False
import ugfx
from homescreen import *
import time
from tilda import Buttons
from machine import Pin
from machine import Neopix
torch = Pin(Pin.GPIO_FET)
neo = Neopix()
# Padding for name
intro_height = 30
@ -26,6 +32,8 @@ logo_width = 56
# Maximum length of name before downscaling
max_name = 8
torch_on = False
# Background stuff
init()
ugfx.clear(ugfx.html_color(0x800080))
@ -82,4 +90,13 @@ while True:
if value_battery:
text += "Battery: %s%%" % int(value_battery)
status.text(text)
if Buttons.is_pressed(Buttons.BTN_Star):
if torch_on:
torch_on = False
torch.off()
neo.display([0,0])
else:
torch_on = True
torch.on()
neo.display([0xffffff,0xffffff])
sleep_or_exit(0.5)

View File

@ -4,7 +4,7 @@ Similar to the default homescreen, but the
background is the enby flag. Based on Pride Flag Homescreen by marekventur
"""
___name___ = "Enby"
___title___ = "Enby"
___license___ = "MIT"
___categories___ = ["Homescreens"]
___dependencies___ = ["homescreen", "app"]

View File

@ -1,9 +1,9 @@
"""Game of Life"""
___name___ = "Conway game of life"
___title___ = "Conway game of life"
___license___ = "MIT"
___categories___ = ["Games"]
___dependencies___ = ["app", "ugfx_helper", "random", "sleep", "buttons"]
___dependencies___ = ["app", "ugfx_helper", "sleep", "buttons"]
import app, ugfx, ugfx_helper, buttons, sleep, time, random
from tilda import Buttons

View File

@ -1,6 +1,6 @@
"""This is a simple hello world app"""
___name___ = "Hello World"
___title___ = "Hello World"
___license___ = "MIT"
___dependencies___ = ["sleep", "app"]
___categories___ = ["EMF"]

View File

@ -1,6 +1,6 @@
"""Camp Holland app
"""
___name___ = "Holland"
"""Camp Holland app"""
___title___ = "Holland"
___license___ = "MIT"
___dependencies___ = ["app", "sim800", "ugfx_helper"]
___categories___ = ["Villages"]

View File

@ -5,7 +5,7 @@ It gets automatically installed when a badge is
newly activated or reset.
"""
___name___ = "Homescreen (Default)"
___title___ = "Homescreen (Default)"
___license___ = "MIT"
___categories___ = ["Homescreens"]
___dependencies___ = ["homescreen", "shared/logo.png", "shared/sponsors.png"]

View File

@ -3,7 +3,7 @@
This is a modified version of the default homescreen that allows you to set a callsign
"""
___name___ = "Amateur Radio Homescreen"
___title___ = "Amateur Radio Homescreen"
___license___ = "MIT"
___categories___ = ["Homescreens"]
___dependencies___ = ["homescreen"]

View File

@ -3,7 +3,7 @@
This is the Stratum 0 flavored homescreen for the Tilda Mk4.
"""
___name___ = "Homescreen (Stratum 0)"
___title___ = "Homescreen (Stratum 0)"
___license___ = "MIT"
___categories___ = ["Homescreens"]
___dependencies___ = ["homescreen"]

View File

@ -5,7 +5,7 @@ Press 0 to go back to normal or 8 to show the flag.
Hold * to activate all LEDs for use as a torch.
"""
___name___ = "Homescreen (Trans)"
___title___ = "Homescreen (Trans)"
___license___ = "MIT"
___categories___ = ["Homescreens"]
___dependencies___ = ["homescreen", "shared/logo.png"]

View File

@ -1,6 +1,6 @@
"""Launcher for apps currently installed"""
___name___ = "Launcher"
___title___ = "Launcher"
___license___ = "MIT"
___categories___ = ["System"]
___dependencies___ = ["dialogs", "app", "ugfx_helper"]

View File

@ -129,7 +129,7 @@ def handle_keypad(edit, numeric):
buttons.Buttons.BTN_6: ["m", "n", "o", "6"],
buttons.Buttons.BTN_7: ["p", "q", "r", "s", "7"],
buttons.Buttons.BTN_8: ["t", "u", "v", "8"],
buttons.Buttons.BTN_9: ["w", "x", "y", "9"],
buttons.Buttons.BTN_9: ["w", "x", "y", "z", "9"],
buttons.Buttons.BTN_Hash: ["#"],
buttons.Buttons.BTN_Star: ["*", "+"],
}
@ -183,11 +183,20 @@ def prompt_option(options, index=0, text = None, title=None, select_text="OK", n
options_list = ugfx.List(5, list_y, ugfx.width() - 24, 265 - list_y, parent = window)
options_list.disable_draw()
optnum = 1
for option in options:
if isinstance(option, dict) and option["title"]:
options_list.add_item(option["title"])
title = option["title"]
else:
options_list.add_item(str(option))
title = str(option)
if optnum < 11:
# mod 10 to make 10th item numbered 0
options_list.add_item("{}: {}".format((optnum % 10),title))
else:
options_list.add_item(" {}".format(title))
optnum = optnum + 1
options_list.enable_draw()
options_list.selected_index(index)

View File

@ -17,7 +17,7 @@ They also *may*:
"""
___license___ = "MIT"
___dependencies___ = ["database", "buttons", "random", "app", "sleep", "ugfx_helper", "wifi", "sim800"]
___dependencies___ = ["database", "buttons", "app", "sleep", "ugfx_helper", "wifi", "sim800"]
import database, ugfx, random, buttons, tilda, sleep, ugfx_helper, wifi, time, sim800
from app import App

View File

@ -12,7 +12,7 @@ import machine
# (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
NTP_DELTA = 3155673600
# With Mk3 Firmware an IP address string works 5%, hangs at socket.socket(..) 95%, could be a bug in 2016 upython?
NTP_HOSTS = ["ntp-gps.emf.camp", "0.emfbadge.pool.ntp.org", "1.emfbadge.pool.ntp.org", "2.emfbadge.pool.ntp.org", "3.emfbadge.pool.ntp.org"]
NTP_HOSTS = ["0.emfbadge.pool.ntp.org", "1.emfbadge.pool.ntp.org", "2.emfbadge.pool.ntp.org", "3.emfbadge.pool.ntp.org"]
NTP_PORT = 123
def get_NTP_time():

View File

@ -1,41 +0,0 @@
"""Library to generate random numbers
Warning! Don't use this for anything important, it's probably biased
"""
___license___ = "MIT"
# todo: simplify this by using "urandom"
import os
_bigrand_bytes = 10
_bigrand_max = pow(256, _bigrand_bytes)
def _bigrand():
"""generates a random number between 0 (incl) and _bigrand_max (excl)"""
base = 0
for b in os.urandom(_bigrand_bytes):
base = (base << 8) + b
return base
def random():
"""Return the next random floating point number in the range [0.0, 1.0)."""
return _bigrand() / _bigrand_max
def randrange(start, stop=None):
"""Return a randomly selected element from range(start, stop)"""
if stop is None:
stop = start
start = 0
return start + (_bigrand() * (stop - start) // _bigrand_max)
def randint(start, stop):
"""Return a random integer N such that a <= N <= b."""
return randrange(start, stop + 1)
def shuffle(seq):
"""Shuffle the sequence x in place."""
l = len(seq)
for i in range(l):
j = randrange(l)
seq[i], seq[j] = seq[j], seq[i]

View File

@ -1,7 +1,7 @@
"""Tests for random lib"""
___license___ = "MIT"
___dependencies___ = ["upip:unittest", "random"]
___dependencies___ = ["upip:unittest"]
import unittest
from random import *

View File

@ -1,6 +1,6 @@
"""View images from the EMF 2018 time-lapse camera
"""
___name___ = "Lobster Vision"
___title___ = "Lobster Vision"
___license___ = "MIT"
___dependencies___ = ["app", "dialogs", "wifi", "buttons", "http", "ugfx_helper"]
___categories___ = ["Other"]

View File

@ -2,7 +2,7 @@
Learn your personal lucky melody.
"""
___name___ = "lucky_melody_machine"
___title___ = "Lucky Melody Machine"
___license___ = "WTFPL"
___dependencies___ = ["app", "buttons", "dialogs", "speaker", "sleep", "ugfx_helper"]
___categories___ = ["Sound"]

View File

@ -5,7 +5,7 @@ Gracefully reboot into main menu on Menu Press.
Replay Track when user pushes a button.
"""
___name___ = "Mario Theme"
___title___ = "Mario Theme"
___license___ = ""
___categories___ = ["Sound"]
___dependencies___ = ["speaker", "buttons", "ugfx_helper", "app", "wifi", "http", "sleep" ]

View File

@ -1,6 +1,6 @@
"""Enables mass storage mode in a safe way"""
___name___ = "Mass Storage Enabler"
___title___ = "Mass Storage Enabler"
___license___ = "MIT"
___dependencies___ = ["dialogs", "ugfx_helper"]
___categories___ = ["EMF"]

View File

@ -1,6 +1,6 @@
"""This app tests all the onboard sensors and system info"""
___name___ = "Memobadge"
___title___ = "Memobadge"
___license___ = "MIT"
___dependencies___ = ["app", "sim800", "sleep", "ugfx_helper"]
___categories___ = ["Sound"]

39
nyan/main.py Normal file
View File

@ -0,0 +1,39 @@
"""Nyan Cat Animation! Rotate the screen with 'A'."""
___name___ = "nyan"
___license___ = "MIT"
___dependencies___ = ["sleep", "app", "ugfx_helper",
"shared/nyan/0.png",
"shared/nyan/1.png",
"shared/nyan/2.png",
"shared/nyan/3.png",
"shared/nyan/4.png",
"shared/nyan/5.png"]
___categories___ = ["Homescreens", "Other"]
import ugfx_helper, os, wifi, ugfx, http, time, sleep, app
from tilda import Buttons
# initialize screen
ugfx_helper.init()
ugfx.clear(ugfx.BLACK)
ugfx.backlight(100)
n = 0
r = 270
while True:
ugfx.display_image( 0, 90, "shared/nyan/{}.png".format(n) )
n = (n+1) % 6
sleep.sleep_ms(10)
if Buttons.is_pressed(Buttons.BTN_B):
break
elif Buttons.is_pressed(Buttons.BTN_A):
r = (r + 180) % 360
ugfx.clear(ugfx.BLACK)
ugfx.orientation(r)
ugfx.clear()
app.restart_to_default()

View File

@ -2,7 +2,7 @@
'''
___author___ = 'Skybound - ECS'
___name___ = 'Party'
___title___ = 'Party'
___license___ = 'MIT'
___categories___ = ['LEDs']
___bootstrapped___ = False

View File

@ -1,6 +1,6 @@
"""Phone app for baic calling functions
"""
___name___ = "Phone"
___title___ = "Phone"
___license___ = "MIT"
___dependencies___ = ["app", "dialogs", "sim800", "ugfx_helper"]
___categories___ = ["System"]

220
pong/main.py Normal file
View File

@ -0,0 +1,220 @@
"""Pong!"""
___name___ = "Pong"
___license___ = "WTFPL"
___categories___ = ["Games"]
___dependencies___ = ["dialogs", "app", "ugfx_helper", "sleep", "buttons"]
import math, ugfx, ugfx_helper, random, sleep, buttons, time
from tilda import Buttons
ugfx_helper.init()
SCREEN_WIDTH = ugfx.width()
SCREEN_HEIGHT = ugfx.height()
bgColor = ugfx.BLACK
ballColor = ugfx.html_color(0x00FF00)
paddleColor = ugfx.html_color(0x00FF00)
netColor = ugfx.html_color(0x00FF00)
class Paddle():
height = 6
width = 60
moveSpeed = 4
needsRedraw = True
def __init__(self, type):
self.type = type
self.x = SCREEN_WIDTH/2
self.previousX = self.x
if type == 0:
self.y = self.height/2
else:
self.y = SCREEN_HEIGHT - (self.height/2)
def draw(self):
if self.needsRedraw:
ugfx.area(int(self.previousX-self.width/2),int(self.y-self.height/2),int(self.width),int(self.height),bgColor)
self.needsRedraw = False
ugfx.area(int(self.x-self.width/2),int(self.y-self.height/2),int(self.width),int(self.height),paddleColor)
def update(self):
if self.type == 1:
if Buttons.is_pressed(Buttons.BTN_Hash):
self.needsRedraw = True
self.previousX = self.x
self.x += self.moveSpeed
if Buttons.is_pressed(Buttons.BTN_Star):
self.needsRedraw = True
self.previousX = self.x
self.x -= self.moveSpeed
if self.type == 0:
if Buttons.is_pressed(Buttons.BTN_3):
self.needsRedraw = True
self.previousX = self.x
self.x += self.moveSpeed
if Buttons.is_pressed(Buttons.BTN_1):
self.needsRedraw = True
self.previousX = self.x
self.x -= self.moveSpeed
if self.x + self.width/2 > SCREEN_WIDTH:
self.x = SCREEN_WIDTH - self.width/2
if self.x -self.width/2 < 0:
self.x = self.width/2
class Ball():
size = 10
x = 0
y = 0
yDeathOffset = 5+3
def __init__(self):
self.x = random.randint(30,SCREEN_WIDTH-30)
self.y = SCREEN_HEIGHT/2
self.vX = 3
if random.randrange(2) == 1:
self.vY = 3
else:
self.vY = -3
self.previousX = self.x
self.previousY = self.y
self.dead = False
def draw(self):
ugfx.area(int(self.previousX-self.size/2),int(self.previousY-self.size/2),int(self.size),int(self.size),bgColor)
ugfx.area(int(self.x-self.size/2),int(self.y-self.size/2),int(self.size),int(self.size),ballColor)
def update(self, topPaddle, bottomPaddle):
self.previousX = self.x
self.previousY = self.y
self.x += self.vX
self.y += self.vY
if self.x > SCREEN_WIDTH:
self.x = SCREEN_WIDTH
self.vX = -self.vX
if self.x < 0:
self.x = 0
self.vX = -self.vX
if self.y > (SCREEN_HEIGHT - self.yDeathOffset):
if (self.x > (bottomPaddle.x - bottomPaddle.width/2)) and (self.x < (bottomPaddle.x + bottomPaddle.width/2)):
self.y = SCREEN_HEIGHT - self.yDeathOffset
self.vY = -self.vY
bottomPaddle.needsRedraw = True
else:
self.dead = True
if self.y < self.yDeathOffset:
if (self.x > (topPaddle.x - topPaddle.width/2)) and (self.x < (topPaddle.x + topPaddle.width/2)):
self.y = self.yDeathOffset
self.vY = -self.vY
topPaddle.needsRedraw = True
else:
self.dead = True
def isDead(self):
return self.dead
def one_round():
ball = Ball()
topPaddle = Paddle(0)
bottomPaddle = Paddle(1)
ugfx.clear(bgColor)
ugfx.backlight(100)
ugfx.set_default_font(ugfx.FONT_TITLE)
while True:
topPaddle.update()
bottomPaddle.update()
ball.update(topPaddle, bottomPaddle)
if ball.isDead():
if(ball.y > SCREEN_HEIGHT/2):
return [1,0]
else:
return [0,1]
topPaddle.draw()
bottomPaddle.draw()
ball.draw()
#draw the net
for i in range(0,7):
ugfx.area(int(i*2*SCREEN_WIDTH/13), int(SCREEN_HEIGHT/2-1), int(SCREEN_WIDTH/13), 3, netColor)
ugfx.orientation(0)
ugfx.text(130, 0, "%d " % (points[0]),netColor)
ugfx.text(170, 0, "%d " % (points[1]),netColor)
ugfx.orientation(270)
time.sleep_ms(1)
minScore = 9
points = [0,0]
playing = 1
while playing:
points[0] = 0
points[1] = 0
while (points[0] < minScore) and (points[1] < minScore):
score = one_round()
points[0] = points[0] + score[0]
points[1] = points[1] + score[1]
ugfx.area(0,0,ugfx.width(),ugfx.height(),0)
ugfx.orientation(90)
ugfx.set_default_font(ugfx.FONT_TITLE)
ugfx.text(30, 138, "GAME ",ballColor)
ugfx.text(30, 158, "OVER ",ballColor)
ugfx.set_default_font(ugfx.FONT_SMALL)
ugfx.text(70, 220, "Score: %d - %d " % (points[0], points[1]), ballColor)
ugfx.text(36, 260, "Press A to play again ", ballColor)
ugfx.text(40, 280, "Press MENU to quit " , ballColor)
ugfx.orientation(270)
ugfx.set_default_font(ugfx.FONT_TITLE)
ugfx.text(30, 138, "GAME ",ballColor)
ugfx.text(30, 158, "OVER ",ballColor)
ugfx.set_default_font(ugfx.FONT_SMALL)
ugfx.text(70, 220, "Score: %d - %d " % (points[1], points[0]), ballColor)
ugfx.text(36, 260, "Press A to play again ", ballColor)
ugfx.text(40, 280, "Press MENU to quit ", ballColor)
while True:
sleep.wfi()
if buttons.is_triggered(Buttons.BTN_A):
break
if buttons.is_triggered(Buttons.BTN_Menu):
playing = 0
break
app.restart_to_default()

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,58 @@
"""Praise the Horse or Worship the Melon, directly from your badge
"""
___name___ = "Praise Horse! Worship Melon!"
___license___ = "MIT"
___dependencies___ = ["app","wifi", "buttons", "ugfx_helper"]
___categories___ = ["Other"]
import ugfx, wifi, utime, ugfx_helper, buttons
from tilda import Buttons
import random
from app import App
def loading_screen():
logo = 'praise_horse_worship_melon/loading.gif'
ugfx.area(0,0,ugfx.width(),ugfx.height(),0xFFFF)
ugfx.display_image(2,2,logo)
ugfx.set_default_font(ugfx.FONT_SMALL)
ugfx.text(60, 145, "Praise Horse (A)", ugfx.GREY)
ugfx.text(55, 305, "Worship Melon (B)", ugfx.GREY)
def show_screen(type=None):
if type == "horse":
img = "praise_horse_worship_melon/horse.gif"
color = ugfx.RED
text = "HORSE!"
elif type == "melon":
img = "praise_horse_worship_melon/melon.gif"
color = ugfx.BLUE
text = "MELON!"
else:
return
ugfx.area(0,0,ugfx.width(),ugfx.height(), color)
ugfx.display_image(0, 0,img)
ugfx.set_default_font(ugfx.FONT_MEDIUM_BOLD)
for y_offset in range(8):
ugfx.Label(0, 42 * y_offset, ugfx.width(), 20, text, parent=None, style=None, justification=ugfx.Label.CENTER)
utime.sleep_ms(100)
utime.sleep_ms(1000)
loading_screen()
def start():
ugfx_helper.init()
loading_screen()
utime.sleep_ms(2000)
return True
running = start()
while running:
if buttons.is_triggered(Buttons.BTN_A):
show_screen(type='horse')
if buttons.is_triggered(Buttons.BTN_B):
show_screen(type='melon')
if buttons.is_triggered(Buttons.BTN_Menu):
App("launcher").boot()
utime.sleep_ms(30)

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -4,15 +4,17 @@ Similar to the default homescreen, but the
background is the pride flag.
"""
___name___ = "Pride"
___title___ = "Pride"
___license___ = "MIT"
___categories___ = ["Homescreens"]
___dependencies___ = ["homescreen", "app"]
___dependencies___ = ["homescreen", "app", "buttons"]
from app import restart_to_default
import ugfx
import homescreen
from tilda import Buttons
import buttons
homescreen.init()
@ -25,56 +27,94 @@ info_height = 20
# Maximum length of name before downscaling
max_name = 8
# Orientation for other people to see
ugfx.orientation(90)
flags = {
'LGBT': [0xE70000, 0xFF8C00, 0xFFEF00, 0x00811F, 0x0044FF, 0x760089],
'Non-Binary': [0xFFF433, 0xFFFFFF, 0x9B59D0, 0x000000],
'Trans': [0x5BCEFA, 0xF5A9B8, 0xFFFFFF, 0xF5A9B8, 0x5BCEFA],
'Asexual': [0x000000, 0xA3A3A3, 0xFFFFFF, 0x800080],
'Bisexual': [0xFF0080, 0xFF0080, 0xA349A4, 0x0000FF, 0x0000FF],
'Pansexual': [0xFF218E, 0xFCD800, 0x0194FC]
}
# Pride flag colours
colours = [0xE70000, 0xFF8C00, 0xFFEF00, 0x00811F, 0x0044FF, 0x760089]
# Draw each "band" of colour in the flag
colour_width = ugfx.width() / len(colours)
for num, colour in enumerate(colours):
width_loc = int(num * colour_width)
ugfx.area(width_loc, 0, int(colour_width), 320, ugfx.html_color(colour))
def draw_flag(colours):
# Orientation for other people to see
ugfx.orientation(90)
# Message to display
prefix_message = "Hi I'm"
# Draw each "band" of colour in the flag
colour_width = ugfx.width() / len(colours)
for num, colour in enumerate(colours):
width_loc = int(num * colour_width)
flag_height = ugfx.height() - (name_height + info_height)
ugfx.area(width_loc, info_height, int(colour_width), flag_height, ugfx.html_color(colour))
ugfx.set_default_font(ugfx.FONT_NAME)
# Calc center of screen
center = (int(ugfx.width() / 2), int(ugfx.height() / 2))
# Can't use label since the background covers the flag
ugfx.text(50, center[1] + name_height, prefix_message, ugfx.WHITE)
def draw_name():
# Orientation for other people to see
ugfx.orientation(90)
# Process name
given_name = homescreen.name("Set your name in the settings app")
if len(given_name) <= max_name:
ugfx.set_default_font(ugfx.FONT_NAME)
else:
ugfx.set_default_font(ugfx.FONT_MEDIUM_BOLD)
# Draw name
ugfx.Label(0, ugfx.height() - name_height, ugfx.width(), name_height, given_name, justification=ugfx.Label.CENTER)
# Process name
given_name = homescreen.name("Set your name in the settings app")
if len(given_name) <= max_name:
ugfx.set_default_font(ugfx.FONT_NAME)
else:
ugfx.set_default_font(ugfx.FONT_MEDIUM_BOLD)
# Draw name
ugfx.Label(0, ugfx.height() - name_height, ugfx.width(), name_height, given_name, justification=ugfx.Label.CENTER)
# Draw for the user to see
ugfx.orientation(270)
ugfx.set_default_font(ugfx.FONT_SMALL)
def draw_user_info():
# Draw for the user to see
ugfx.orientation(270)
# Calc width center of screen
center_width = int(ugfx.width() / 2)
ugfx.set_default_font(ugfx.FONT_SMALL)
# WiFi/Battery update loop
while True:
ugfx.area(0, ugfx.height() - info_height, ugfx.width(), info_height, ugfx.WHITE)
wifi_strength_value = homescreen.wifi_strength()
if wifi_strength_value:
wifi_message = 'WiFi: %s%%' % int(wifi_strength_value)
wifi_text = ugfx.text(center[0], ugfx.height() - info_height, wifi_message, ugfx.BLACK)
ugfx.text(center_width, ugfx.height() - info_height, wifi_message, ugfx.BLACK)
battery_value = homescreen.battery()
if battery_value:
battery_message = 'Battery: %s%%' % int(battery_value)
battery_text = ugfx.text(0, ugfx.height() - info_height, battery_message, ugfx.BLACK)
ugfx.text(0, ugfx.height() - info_height, battery_message, ugfx.BLACK)
# Set variables for WiFi/Battery loop
selection_change = True
flag_names = list(flags.keys())
selection = flag_names.index('LGBT')
# WiFi/Battery update loop
draw_name()
while True:
# Buttons will cycle when it reaches either side of the list
if buttons.is_pressed(Buttons.JOY_Left):
if selection > 0:
selection -= 1
else:
selection = len(flags) - 1
selection_change = True
elif buttons.is_pressed(Buttons.JOY_Right):
if selection < len(flags) - 1:
selection += 1
else:
selection = 0
selection_change = True
# Only triggers if the selection has changed
if selection_change:
draw_flag(flags[flag_names[selection]])
selection_change = False
# Redraw time-sensitive info on each iteration
draw_user_info()
homescreen.sleep_or_exit(1.5)
restart_to_default()

92
pybcdc.inf Normal file
View File

@ -0,0 +1,92 @@
; Windows USB CDC ACM Setup File
; Based on INF files which were:
; Copyright (c) 2000 Microsoft Corporation
; Copyright (C) 2007 Microchip Technology Inc.
; Likely to be covered by the MLPL as found at:
; <http://msdn.microsoft.com/en-us/cc300389.aspx#MLPL>.
[Version]
Signature="$Windows NT$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%MFGNAME%
LayoutFile=layout.inf
DriverVer=03/11/2010,5.1.2600.3
[Manufacturer]
%MFGNAME%=DeviceList, NTamd64
[DestinationDirs]
DefaultDestDir=12
;---------------------------------------------------------------------
; Windows 2000/XP/Server2003/Vista/Server2008/7 - 32bit Sections
[DriverInstall.nt]
include=mdmcpq.inf
CopyFiles=DriverCopyFiles.nt
AddReg=DriverInstall.nt.AddReg
[DriverCopyFiles.nt]
usbser.sys,,,0x20
[DriverInstall.nt.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.nt.Services]
AddService=usbser, 0x00000002, DriverService.nt
[DriverService.nt]
DisplayName=%SERVICE%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\usbser.sys
;---------------------------------------------------------------------
; Windows XP/Server2003/Vista/Server2008/7 - 64bit Sections
[DriverInstall.NTamd64]
include=mdmcpq.inf
CopyFiles=DriverCopyFiles.NTamd64
AddReg=DriverInstall.NTamd64.AddReg
[DriverCopyFiles.NTamd64]
usbser.sys,,,0x20
[DriverInstall.NTamd64.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.NTamd64.Services]
AddService=usbser, 0x00000002, DriverService.NTamd64
[DriverService.NTamd64]
DisplayName=%SERVICE%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\usbser.sys
;---------------------------------------------------------------------
; Vendor and Product ID Definitions
[SourceDisksFiles]
[SourceDisksNames]
[DeviceList]
%DESCRIPTION%=DriverInstall, USB\VID_f055&PID_9800&MI_00, USB\VID_f055&PID_9800&MI_01
[DeviceList.NTamd64]
%DESCRIPTION%=DriverInstall, USB\VID_f055&PID_9800&MI_00, USB\VID_f055&PID_9800&MI_01
;---------------------------------------------------------------------
; String Definitions
[Strings]
MFGFILENAME="pybcdc"
MFGNAME="Micro Python"
DESCRIPTION="Pyboard USB Comm Port"
SERVICE="USB Serial Driver"

View File

@ -1,6 +1,6 @@
"""Helps to test incoming PRs"""
___name___ = "PR Review Helper"
___title___ = "PR Review Helper"
___license___ = "MIT"
___categories___ = ["System"]
___dependencies___ = ["dialogs", "app", "ugfx_helper", "badge_store", "http", "stack_nav", "wifi"]

View File

@ -1,9 +1,9 @@
""" Flashes random colours on your screen
"" By Pez (@Pezmc)
"""
___name___ = "Screen Party"
___title___ = "Screen Party"
___license___ = "MIT"
___dependencies___ = ["ugfx_helper", "sleep", "random"]
___dependencies___ = ["ugfx_helper", "sleep"]
___categories___ = ["Homescreens"]
___bootstrapped___ = False

View File

@ -3,7 +3,7 @@
Annoy your friends! Annoy your enemies! Annoy yourself! Maybe (maybe) make music!
"""
___name___ = "Sequencer"
___title___ = "Sequencer"
___license___ = "MIT"
___categories___ = ["Sound"]
___dependencies___ = ["speaker", "buttons", "ugfx_helper", "app", "shared/sequencer_info.png"]

32
serendipity/main.py Normal file
View File

@ -0,0 +1,32 @@
"""Happy accidents or unplanned, fortunate discoveries."""
___name___ = "serendipity"
___license___ = "MIT"
___dependencies___ = ["sleep", "app", "ugfx_helper"]
___categories___ = ["Villages"]
import ugfx_helper, os, wifi, ugfx, http, time, sleep, app
from tilda import Buttons
# initialize screen
ugfx_helper.init()
ugfx.clear(ugfx.BLACK)
img = [ugfx.Image("serendipity/sun.png"),
ugfx.Image("serendipity/world.png")]
ugfx.backlight(100)
n = 0
ugfx.display_image( 0, 0, img[n] )
while True:
if Buttons.is_pressed(Buttons.BTN_B):
break
elif Buttons.is_pressed(Buttons.BTN_A):
n = (n+1) % 2
ugfx.display_image( 0, 0, img[n] )
ugfx.clear()
app.restart_to_default()

BIN
serendipity/sun.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
serendipity/world.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -11,7 +11,7 @@ Todo:
"""
___name___ = "Settings"
___title___ = "Settings"
___license___ = "MIT"
___dependencies___ = ["dialogs", "ugfx_helper", "database", "app", "stack_nav", "wifi"]
___categories___ = ["System"]

187
settlers/main.py Normal file
View File

@ -0,0 +1,187 @@
"""Settlers of Catan game board generator"""
___name___ = "settlers"
___license___ = "MIT"
___dependencies___ = ["ugfx_helper", "sleep"]
___categories___ = ["Games"]
___bootstrapped___ = False
import random, ugfx, ugfx_helper, math, time, buttons
from app import App, restart_to_default
from tilda import Buttons
ugfx_helper.init()
ugfx.clear(ugfx.BLACK)
"""
This was an experiment in drawing hexagons. Some notes:
Screen coords are x,y values that locate pixels on the physical display:
0,0 240,0
0,320 240,320
Hex coords are x,y,z values that locate the relative positions of hexagons:
0,1,-1
-1,1,0 1,0,-1
0,0,0
-1,0,1 1,-1,0
0,-1,1
Converting between the two systems can be done by multiplying the x and y
coordinates against a matrix. When converting to hex coords, the z value
can be computed from the new x and y values because x + y + z must always
equal zero.
"""
class Hex:
# Constant matrix used to convert from hex coords to screen coords
matrix = [3.0 * 0.5, 0.0, math.sqrt(3.0) * 0.5, math.sqrt(3.0)]
# The screen coordinate to use as the origin for hex coordinates,
# the centre of hex 0,0,0 will be at this coordinate
origin = [math.ceil(ugfx.width() / 2), math.ceil(ugfx.height() / 2)]
# Size in pixels of the hex, from the centre point to each corner
size = 22
# Possible kinds of resource and the colour it should be rendered
kinds = {
0: ugfx.html_color(0xd4e157), # Sheep
1: ugfx.html_color(0xffc107), # Wheat
2: ugfx.html_color(0x993300), # Wood
3: ugfx.html_color(0xff0000), # Brick
4: ugfx.html_color(0x757575), # Ore
5: ugfx.html_color(0xffee55), # Desert (nothing)
}
# Transformations for how to get to the neighbouring hexes
directions = {
0: [-1, 1, 0], # South West
1: [0, 1, -1], # South
2: [1, 0, -1], # South East
3: [1, -1, 0], # North East
4: [0, -1, 1], # North
5: [-1, 0, 1], # North West
}
def __init__(self, coords, kind, number, robber):
"""Create a new hex at the given hex coordinates, of the given kind of resource"""
# Validate coords
assert len(coords) == 3, 'Invalid number of hexagon coordinates'
assert coords[0] + coords[1] + coords[2] == 0, 'Invalid hexagon coordinate values'
self.coords = coords
# The kind of resource hosted by this hex
self.kind = kind
# The dice roll required to win this resource
self.number = number
# Whether this hex contains the robber
self.robber = robber
# Compute the screen coordinates of the centre of the hex
self.centre = Hex.to_screen_coords(self.coords[0], self.coords[1])
# Generate screen coordinates for each of the corners of the hex
self.corners = []
for i in range(0, 6):
angle = 2.0 * math.pi * (0 - i) / 6
offset = [Hex.size * math.cos(angle), Hex.size * math.sin(angle)]
self.corners.append([round(self.centre[0] + offset[0]), round(self.centre[1] + offset[1])])
@staticmethod
def to_screen_coords(x, y):
"""Returns screen coordinates computed from the given hex coordinates"""
newX = (Hex.matrix[0] * x + Hex.matrix[1] * y) * Hex.size
newY = (Hex.matrix[2] * x + Hex.matrix[3] * y) * Hex.size
return [newX + Hex.origin[0], newY + Hex.origin[1]]
@staticmethod
def get_neighbouring_hex_coords(coords, direction):
return [a + b for a, b in zip(coords, Hex.directions[direction])]
def draw(self):
"""Draw the hexagon to the screen"""
ugfx.fill_polygon(0, 0, self.corners, Hex.kinds[self.kind])
text_offset = Hex.size * 0.5
if self.robber:
ugfx.text(round(self.centre[0] - text_offset), round(self.centre[1] - text_offset), "Rb ", ugfx.BLACK)
else:
if self.kind != 5:
ugfx.text(round(self.centre[0] - text_offset), round(self.centre[1] - text_offset), "{} ".format(self.number), ugfx.BLACK)
def clear(self):
ugfx.fill_polygon(0, 0, self.corners, ugfx.BLACK)
def board_setup(resources, numbers):
"""Generate a random game board"""
# Two rings of hexes around the centre
radius = 2
# Choose a starting hex on the outermost ring of hexes
choice = random.randrange(0, 6)
coords = [0, 0, 0]
for i in range(radius):
coords = [a + b for a, b in zip(coords, Hex.directions[choice])]
# Copy lists so we can edit them with impunity
r_copy = resources.copy()
n_copy = numbers.copy()
hexes = []
while radius > 0:
# From the starting hex, go radius hexes in each of the 6 directions
for i in list(range((choice + 2) % 6, 6)) + list(range(0, (choice + 2) % 6)):
for j in range(radius):
# The resources are picked at random from the list
resource = r_copy.pop(random.randrange(0, len(r_copy)))
# But the dice roll numbers are picked in order, unless it's
# the desert in which case that is always 7
if resource == 5:
number = 7
else:
number = n_copy.pop(0)
hexes.append(Hex(coords, resource, number, number == 7))
coords = Hex.get_neighbouring_hex_coords(coords, i)
# Go into the next ring of hexes (opposite direction of starting choice)
coords = Hex.get_neighbouring_hex_coords(coords, (choice + 3) % 6)
radius = radius - 1
resource = r_copy.pop()
if resource == 5:
number = 7
else:
number = n_copy.pop(0)
hexes.append(Hex(coords, resource, number, number == 7))
return hexes
# List of resources (pre-randomised to combat the not-very random number
# generator) and dice rolls (these have a strict order) for 2-4 player games
resources = [4, 0, 1, 4, 4, 2, 5, 3, 2, 1, 2, 2, 1, 0, 3, 0, 3, 1, 0]
numbers = [5, 2, 6, 3, 8, 10, 9, 12, 11, 4, 8, 10, 9, 4, 5, 6, 3, 11]
def draw():
hexes = board_setup(resources, numbers)
for h in hexes:
h.clear()
time.sleep_ms(100)
h.draw()
ugfx.text(5, 5, 'Press A to generate another ', ugfx.WHITE)
draw()
# Main Loop
while True:
if buttons.is_triggered(tilda.Buttons.BTN_A):
draw()
elif buttons.is_triggered(tilda.Buttons.BTN_Menu):
break
time.sleep_ms(5)
restart_to_default()

BIN
shared/nyan/0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

BIN
shared/nyan/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

BIN
shared/nyan/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

BIN
shared/nyan/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

BIN
shared/nyan/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

BIN
shared/nyan/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

View File

@ -1,6 +1,6 @@
"""SMS app for reading and sending messages
"""
___name___ = "SMS"
___title___ = "SMS"
___license___ = "MIT"
___dependencies___ = ["app", "dialogs", "sim800", "ugfx_helper"]
___categories___ = ["System"]

View File

@ -1,11 +1,11 @@
"""Snake!"""
___name___ = "Snake"
___title___ = "Snake"
___license___ = "MIT"
___categories___ = ["Games"]
___dependencies___ = ["dialogs", "app", "ugfx_helper", "random", "sleep", "buttons"]
___dependencies___ = ["dialogs", "app", "ugfx_helper", "sleep", "buttons"]
import math, ugfx, ugfx_helper, random, sleep, buttons
import app, math, ugfx, ugfx_helper, random, sleep, buttons
from tilda import Buttons
ugfx_helper.init()

118
speedlauncher/main.py Normal file
View File

@ -0,0 +1,118 @@
"""Launcher for apps currently installed"""
___name___ = "Speed Launcher"
___license___ = "WTFPL"
___categories___ = ["System"]
___dependencies___ = ["app", "ugfx_helper"]
___launchable___ = False
___bootstrapped___ = False
import ugfx_helper, ugfx, math, buttons
from app import *
from tilda import Buttons
APPS_PER_PAGE = 12
EMF_PURPLE = 0x800080
ugfx_helper.init()
ugfx.clear(ugfx.html_color(EMF_PURPLE))
ugfx.set_default_font(ugfx.FONT_SMALL)
style = ugfx.Style()
style.set_enabled([ugfx.WHITE, ugfx.html_color(EMF_PURPLE), ugfx.html_color(EMF_PURPLE), ugfx.html_color(EMF_PURPLE)])
style.set_background(ugfx.html_color(EMF_PURPLE))
ugfx.set_default_style(style)
loadMsg = ugfx.Label(0, 90, ugfx.width(), 20, "Loading apps...", justification=ugfx.Label.CENTER)
# Load apps in a colourList
all_apps = [{"title": a.title, "app": a} for a in get_apps()]
# Sort apps by alphabetical order
all_apps.sort(key=lambda a: a['title'])
total_pages = math.ceil(len(all_apps) / APPS_PER_PAGE)
ugfx.clear(ugfx.html_color(EMF_PURPLE))
keypad = [
Buttons.BTN_1,
Buttons.BTN_2,
Buttons.BTN_3,
Buttons.BTN_4,
Buttons.BTN_5,
Buttons.BTN_6,
Buttons.BTN_7,
Buttons.BTN_8,
Buttons.BTN_9,
Buttons.BTN_Star,
Buttons.BTN_0,
Buttons.BTN_Hash
]
keypadLabels = [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"*",
"0",
"#"
]
def showPage():
global current_page
# avoid out of bounds errors
current_page = max(1, min(current_page, total_pages))
start = (current_page - 1) * APPS_PER_PAGE
end = start + APPS_PER_PAGE
apps_on_current_page = all_apps[start:end]
# Refresh page
ugfx.clear(ugfx.html_color(EMF_PURPLE))
# Write current page number and arrows
ugfx.Label(0, 20, ugfx.width(), 20, "Page {} of {}".format(current_page, total_pages), justification=ugfx.Label.CENTER)
if current_page > 1:
ugfx.fill_polygon(10, 16, [[0, 10], [15, 20], [15, 0]], ugfx.WHITE)
if current_page < total_pages:
ugfx.fill_polygon(ugfx.width() - 30, 16, [[0, 0], [15, 10], [0, 20]], ugfx.WHITE)
# Write app numbers and names
i = 0
yOffset = 45
xOffset = 0
for a in apps_on_current_page:
# xOffset = (i % 3) * 8 # offset lines to match the physical layout of the keypad
ugfx.area(20 + xOffset, yOffset + 2, 20, 20, ugfx.WHITE)
ugfx.text(23 + xOffset, yOffset + 3, keypadLabels[i] + " ", EMF_PURPLE)
ugfx.Label(46 + xOffset, yOffset + 3, ugfx.width(), 20, a['title'], justification=ugfx.Label.LEFT)
yOffset = yOffset + 22
i = i + 1
while True:
for key in keypad:
keyIndex = keypad.index(key)
if buttons.is_pressed(key) and (keyIndex < len(apps_on_current_page)):
apps_on_current_page[keyIndex]['app'].boot()
break
if buttons.is_triggered(Buttons.JOY_Right) and (current_page is not total_pages):
current_page = current_page + 1
return
if buttons.is_triggered(Buttons.JOY_Left) and (current_page is not 1):
current_page = current_page - 1
return
current_page = 1
while True:
showPage()

View File

@ -1,6 +1,6 @@
"""A big "thank you" to all our Sponsors who made this year's badge possible!"""
___name___ = "Sponsors"
___title___ = "Sponsors"
___license___ = "MIT"
___dependencies___ = ["wifi", "http", "ugfx_helper", "sleep", "app"]
___categories___ = ["EMF"]

View File

@ -1,6 +1,6 @@
"""A home screen with squares that spin"""
___name___ = "Squares home"
___title___ = "Squares home"
___license___ = "MIT"
___dependencies___ = ["sleep", "app", "ugfx_helper", "buttons", "homescreen"]
___categories___ = ["Homescreens"]

View File

@ -3,7 +3,7 @@
Will play music, maybe
"""
___name___ = "Play Music"
___title___ = "Star Wars Music"
___license___ = "MIT"
___categories___ = ["Sound"]
___dependencies___ = ["speaker", "shared/sw.png", "buttons"]

View File

@ -1,6 +1,6 @@
"""Read stories from twentythreemillionstories.org"""
___name___ = "twenty-three million stories"
___title___ = "twenty-three million stories"
___license___ = "MIT"
___categories___ = ["Other"]
___dependencies___ = [ "app", "dialogs", "http", "ugfx_helper", "sleep" ]

View File

@ -3,7 +3,7 @@
Todo: fix this, it doesn't work at at the moment
"""
___name___ = "Synthesizers"
___title___ = "Synthesizers"
___license___ = "MIT"
___categories___ = ["Sound"]
___dependencies___ = ["speaker", "buttons", "ugfx_helper", "app"]

View File

@ -1,6 +1,6 @@
"""This app tests all the onboard sensors and system info"""
___name___ = "System Info"
___title___ = "System Info"
___license___ = "MIT"
___dependencies___ = ["sleep", "app", "sim800"]
___categories___ = ["EMF", "System"]
@ -9,6 +9,7 @@ ___bootstrapped___ = True
#import ugfx, os, time, sleep, app, sim800
import ugfx, app, sim800
import os
from tilda import Buttons
from tilda import Sensors
from machine import ADC
@ -38,6 +39,8 @@ else:
ugfx.Label(5, 185, 240, 15, simversion)
ugfx.Label(5, 215, 240, 30, "Badge firmware version:\n{}".format(os.uname().version))
ugfx.Label(5, 300, 240, 15, "** Hold A or B or MENU to exit **")

View File

@ -1,6 +1,6 @@
"""This app goes with the Torch Tutorial"""
___name___ = "Tilda Torch"
___title___ = "Tilda Torch"
___license___ = "MIT"
___dependencies___ = ["sleep", "app"]
___categories___ = ["EMF"]

View File

@ -1,6 +1,6 @@
""" Tildr Dating
"""
___name___ = "Tildr Dating"
___title___ = "Tildr Dating"
___license___ = "MIT"
___dependencies___ = ["wifi", "http", "ugfx_helper", "sleep", "dialogs", "sim800", "database"]
___categories___ = ["Other"]

View File

@ -4,7 +4,7 @@ import database, ujson, sim800, dialogs, http
def get_profile():
profile_json = database.get("tildr_profile")
if profile_json is None:
return {}
return None
profile = ujson.loads(profile_json)
return profile

View File

@ -1,7 +1,7 @@
"""
TiNDA: A dating app for TiLDA. Find your perfect EMF match!
"""
___name___ = "tinda"
___title___ = "TiNDA"
___license___ = "WTFPL"
___dependencies___ = ["app", "buttons", "database", "dialogs", "http", "sleep", "ugfx_helper"]
___categories___ = ["Other", "EMF"]

View File

@ -1,6 +1,6 @@
""" <your description>
"""
___name___ = "my_app"
___title___ = "Warm and Wet"
___license___ = "MIT"
___dependencies___ = ["dialogs", "ugfx_helper", "app", "sleep"]
___categories___ = ["Other"]