Skip to content

Commit 9ad6b5d

Browse files
committed
Revert to sept18 pre-inheritance and keep new nodes
1 parent 45d78d6 commit 9ad6b5d

96 files changed

Lines changed: 997 additions & 3943 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@ filesystem/splash
66
filesystem/Saves
77
filesystem/lib
88

9-
production_files
10-
119
doc/build
1210
.vscode
1311
**/desktop.ini
14-
filesystem/system/settings.txt
15-
firmware_date.h
16-
filesystem/lib
17-
filesystem/Games/TempGames

README.md

Lines changed: 35 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,54 @@
11
# TinyCircuits-Tiny-Game-Engine
2+
This is a game engine for embedded devices that can run MicroPython.
23

3-
This is a 2D/3D game engine for MicroPython. Core engine features are written in C and integrated into MicroPython as external C modules. The engine API is exposed through Python modules.
4-
5-
<p align="center">
6-
<img width="65%" src="images/games.png">
7-
</p>
8-
9-
### **Engine Features**:
10-
* Node API with hierarchy format (parent/child) to render rectangles, circles, lines, text, GUI buttons, sprites, and 3D meshes.
11-
* All nodes can be rotated and scaled
12-
* Resource API for loading and holding data like 1/4/8/16-bit bitmap textures, .wav sound files, RTTTL ringtone tracks, fonts, and 2D/3D noise
13-
* Basic button API
14-
* Audio API for 4 audio channels to play .wav, RTTTL, or tones
15-
* Basic 2D physics engine with rotated rectangle and circle colliders exposed as nodes
16-
* Math API for `Vector2` and `Vector3` types
17-
* Tween/animation API to animate attributes of nodes
18-
* Saves API for reading and writing certain common types of data
19-
* Time API for utilizing hardware real-time-clock (RTC) for keeping persistent time across device power-downs
20-
* Link API for connecting two devices together to make local multiplayer games
21-
22-
You can also read the engine documentation, visit the arcade to download games, or make your own games using the Code Editor Web App:
23-
* [Engine Documentation](https://color.thumby.us/doc/landing.html)
24-
* [Arcade](https://color.thumby.us/code/arcade)
25-
* [MicroPython Code Editor](https://color.thumby.us/code/)
26-
27-
28-
# Platforms
29-
The engine can run on most platforms that run [MicroPython](https://github.com/TinyCircuits/micropython/tree/engine). However, some drivers may need to be implemented for buttons, screen, and audio.
30-
31-
The engine has been tested on and ported to the following platforms:
32-
* Linux/Unix
33-
* RP2350 with 16MiB flash
34-
* Webassembly
35-
36-
37-
# Building on Linux for RP2350
38-
1. Update package list: `sudo apt update`
39-
2. Install build chain dependencies (https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf#page=33): `sudo apt install git python3 cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential g++ libstdc++-arm-none-eabi-newlib`
40-
3. Clone TinyCircuits MicroPython: `git https://github.com/TinyCircuits/micropython.git mp-thumby`
41-
4. `cd` into MicroPython: `cd mp-thumby`
42-
5. Checkout engine branch: `git checkout engine`
43-
6. Init the engine submodule: `git submodule update --init --recursive`
44-
7. Setup cross compiler:
45-
1. cd `mpy-cross` (folder is inside `mp-thumby`)
46-
2. `make -j8`
47-
8. Go back to MicroPython root folder: `cd ..`
48-
9. Setup `rp2` port:
49-
1. `cd ports/rp2`
50-
2. `make submodules`
51-
3. `make clean`
52-
10. Go back to MicroPython root folder: `cd ../..`
53-
11. Go into engine folder: `cd TinyCircuits-Tiny-Game-Engine`
54-
12. Run the custom Python build and upload script: `python3 build_and_upload.py`
55-
56-
(NOTE: you may need to install `pyserial`: `python3 -m pip install pyserial` and the .uf2 will be output to `mp-thumby/ports/rp2/build-THUMBY_COLOR/firmware.uf2` once you see the message `Finding drive letter...`)
57-
58-
# Building on Linux for Linux
4+
# Building on Linux
595
These instructions assume that you are cloning MicroPython from the TinyCircuits Fork that has been pre-modified
606
1. Install SDL2: `sudo apt install libsdl2-dev`
61-
2. Install FFI: `sudo apt install libffi-dev`
62-
3. Install build tools: `sudo apt install build-essential`
63-
4. Clone TinyCircuits MicroPython: `git clone https://github.com/TinyCircuits/micropython.git mp-thumby`
64-
5. `cd` into MicroPython: `cd mp-thumby`
65-
6. Checkout engine branch: `git checkout engine`
66-
7. Init the engine submodule: `git submodule update --init --recursive`
67-
8. Setup UNIX port:
7+
2. Install build tools: `sudo apt install build-essential`
8+
3. Clone TinyCircuits MicroPython: `git clone https://github.com/TinyCircuits/micropython.git mp-thumby`
9+
4. `cd` into MicroPython: `cd mp-thumby`
10+
5. Checkout engine branch: `git checkout engine-1.23.0`
11+
6. Clone latest engine module code with `lib` submodules: `git clone --recurse-submodules https://github.com/TinyCircuits/TinyCircuits-Tiny-Game-Engine.git`
12+
7. Setup UNIX port:
6813
1. `cd ports/unix`
6914
2. `make submodules`
70-
9. `cd` to engine file system to build and run MicroPython and the engine
15+
8. `cd` to engine file system to build and run MicroPython and the engine
7116
1. `cd`: `cd ../../TinyCircuits-Tiny-Game-Engine/filesystem`
7217
2. build: `(cd ../../ports/unix && make -j8 USER_C_MODULES=../../TinyCircuits-Tiny-Game-Engine DEBUG=1)`
73-
3. run: `../micropython_loop ../../ports/unix/build-standard/micropython -X heapsize=2617152 main.py`
18+
3. run: `../micropython_loop ../../ports/unix/build-standard/micropython -X heapsize=532480 main.py`
7419

7520
Use `(cd ../../ports/unix && make clean)` to make clean if needed
7621

77-
# Building and Running On Linux Quickly
78-
If you followed the one of two methods to setup everythign above, you can run the following from `micropython/TinyCircuits-Tiny-Game-Engine/filesystem` to build and run a MicroPython script on Linux quickly:
79-
80-
`(cd ../../ports/unix && make -j8 DEBUG=1 USER_C_MODULES=../../TinyCircuits-Tiny-Game-Engine) && (../../ports/unix/build-standard/micropython main.py)`
81-
82-
# Diagnosing HARD_FAULT
83-
If a hard fault blue screen occurs on the device, it will also usually occur in the Linux build too. It likely still won't be easy to solve, but you can see exactly where in MicroPython or the engine C code where the fault occurs using `gdb`. Using Linux is easier, but `gdb` can be used with the device as well but it is harder to setup.
84-
85-
Refer to the above section where MicroPython and the engine are built on Linux for Linux. Make sure the `DEBUG=1` flag is added to the `make` command as shown above and then run MicroPython using `gdb` like so:
86-
1. Navigate filesystem: `cd TinyCircuits-Tiny-Game-Engine/filesystem`
87-
2. Build and run with `gdb`: `(cd ../../ports/unix && make -j8 DEBUG=1 USER_C_MODULES=../../TinyCircuits-Tiny-Game-Engine) && (gdb ../../ports/unix/build-standard/micropython main.py)`
88-
3. In the `gdb` prompt, execute `run main.py` and do it again after launching game when the window closes
89-
4. Play the game until it crashes and see the line in the C code where the fault occurred. In the `gdb` prompt, execute `bt` to see a stacktrace for the steps up to this point
22+
# Building on Linux, from Scratch
23+
These instructions assume that you are cloning MicroPython from the official MicroPython repository and not the TinyCircuits Fork
9024

91-
The above steps will get you started, you will likely need to understand the code and use other `gdb` tools to investigate the issue. For example, to see the value of a memory address, use `x <hex address>` in the `gdb` prompt.
92-
93-
# Building on Linux for WebAssembly
94-
1. Follow instructions here https://emscripten.org/docs/getting_started/downloads.html and finish after executing `source ./emsdk_env.sh` (will need to execute this last command in `emsdk` in every new terminal/session)
95-
2. `git clone https://github.com/TinyCircuits/micropython/tree/engine micropython`
96-
3. `cd micropython/ports/webassembly`
97-
4. `make -j8 USER_C_MODULES=../../TinyCircuits-Tiny-Game-Engine`
25+
1. Install SDL2: `sudo apt install libsdl2-dev`
26+
2. Install build tools: `sudo apt install build-essential`
27+
3. Clone MicroPython: `git clone https://github.com/micropython/micropython.git`
28+
4. `cd` into MicroPython: `cd micropython`
29+
5. Reset to MicroPython version 1.23.0: `git reset --hard a61c446`
30+
6. Clone latest engine module code with `lib` submodules: `git clone --recurse-submodules https://github.com/TinyCircuits/TinyCircuits-Tiny-Game-Engine.git`
31+
7. Setup UNIX port:
32+
1. `cd ports/unix`
33+
2. `make submodules`
34+
8. Inside `micropython/ports/unix/variants/mpconfigvariant_common.h` do:
35+
1. Change `#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE)` -> `#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)`
36+
2. Change `#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)` -> `#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG)`
37+
3. Add `#define MICROPY_TRACKED_ALLOC (1)` anywhere
38+
9. UGLY: inside `micropython/tools/mpy-tool.py`
39+
1. Change line 1784 to `default="longlong"` (don't know where this tool is used and how to pass it a different value, will just set it for now)
40+
10. `cd` to filesystem root: `cd micropython/TinyCircuits-Tiny-Game-Engine/filesystem`
41+
11. Build MicroPython UNIX port: `(cd ../../ports/unix && make -j8 USER_C_MODULES=../../TinyCircuits-Tiny-Game-Engine DEBUG=1)`
42+
12. Run MicroPython port: `../micropython_loop ../../ports/unix/build-standard/micropython -X heapsize=532480 main.py`
9843

99-
# Linux and Webassembly heap size
100-
To mimic the hardware, the heap needs to be `520kB` SRAM + `2MiB` of FLASH scratch = `520*1000 + 2*1024*1024 = 2617152`
44+
Use `(cd ../../ports/unix && make clean)` to make clean if needed
10145

10246
# Updating MicroPython version
10347
Make sure to check that the copied structures in src/utility/engine_mp.h are still the same in the version of MicroPython you're updating to. Some structures are not exposed so they had to be copied to where the engine can use them.
10448

10549
# How UF2s are made
10650
1. Download and compile https://github.com/raspberrypi/picotool (requires pico-sdk be installed in default known location or pass `-DPICO_SDK_PATH=` to `cmake`)
107-
2. Upload a firmware and all files that should be included to Thumby Color (run the `collect_files_for_image.py` and copy files using Thonny from the `production_files/tree` folder)
108-
3. Connect Thumby Color to computer with picotool installed in and the device in BOOTSEL mode (turn off, press and hold down DPAD direction, turn back on)
109-
4. Run: `sudo ./picotool save -r 0x10000000 0x11000000 thumby_color_full_image_00_00_0000.bin` (saves from `XIP_BASE` to `16MiB`s after to bin file)
110-
5. Run: `sudo ./picotool uf2 convert thumby_color_full_image_00_00_0000.bin thumby_color_full_image_00_00_0000.uf2`
51+
2. Upload a firmware and all files that should be included to Thumby Color
52+
3. Connect Thumby Color to computer with picotool installed in BOOTSEL mode (turn off, press and hold down DPAD direction, turn back on)
53+
4. Run: `sudo ./picotool save -r 0x10000000 0x11000000 thumby_color_dev_kit_full_image_08_20_2024.bin` (saves from `XIP_BASE` to `16MiB`s after to bin file)
54+
5. Run: `sudo ./picotool uf2 convert thumby_color_dev_kit_full_image_08_20_2024.bin thumby_color_dev_kit_full_image_08_20_2024.uf2`

build_and_upload.py

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -38,44 +38,20 @@ def get_drives():
3838

3939
# ### Step 1: Get arguments
4040
arguments = sys.argv[1:]
41-
upload = True
4241

4342
if len(arguments) > 0 and arguments[0] == "clean":
4443
execute(['make', '-C', '../ports/rp2', 'clean', 'BOARD=THUMBY_COLOR'])
4544
print("\n\nSUCCESS: Done cleaning rp2 port!\n")
4645
exit(1)
47-
elif len(arguments) > 0 and arguments[0] == "no_upload":
48-
upload = False
49-
50-
51-
# ### Step 2: Get the date of the last commit and bake into firmware
52-
firmware_date_file = open("src/firmware_date.h", "w")
53-
commit_id = os.popen('git rev-parse --short HEAD').read()
54-
commit_date = os.popen('git log -1 --format="%cd" --date=iso').read()
55-
commit_date = commit_date.splitlines()
56-
commit_date = commit_date[0]
57-
commit_date = commit_date.split(' ')
58-
commit_date = commit_date[0] + "_" + commit_date[1]
59-
firmware_date_file.write(f"""
60-
#ifndef FIRMWARE_DATE_H
61-
#define FIRMWARE_DATE_H
62-
63-
#define FIRMWARE_DATE "{commit_date}"
64-
65-
#endif
66-
""")
67-
firmware_date_file.close()
68-
69-
# ### Step 3: Build the firmware (which will freeze everything in `modules`)
46+
47+
48+
# ### Step 2: Build the firmware (which will freeze everything in `modules`)
7049
print("\n\nBuilding rp2 port...\n")
7150
execute(['make', '-C', '../ports/rp2', '-j8', 'BOARD=THUMBY_COLOR', 'USER_C_MODULES=../../TinyCircuits-Tiny-Game-Engine/src/micropython.cmake'])
7251
print("\n\nDone building rp2 port!\n")
7352

74-
# Rename UF2 if want to
75-
firmware_path = f"../ports/rp2/build-THUMBY_COLOR/firmware_{commit_id}.uf2"
76-
shutil.move("../ports/rp2/build-THUMBY_COLOR/firmware.uf2", firmware_path)
7753

78-
# ### Step 4: Make sure output binary isn't larger than 1 MiB
54+
# ### Step 3: Make sure output binary isn't larger than 1 MiB
7955
# as the flash is partitioned as FIRMWARE | SCRATCH | FILESYSTEM
8056
# and only 1MiB is assumed for the max size of the binary
8157
# (see resources/engine_resource_manager.c)
@@ -84,11 +60,7 @@ def get_drives():
8460
if output_bin_size >= 1 * 1024 * 1024:
8561
raise Exception("ERROR: Output binary size is too large! It can only be upto 1Mib in size. See: https://github.com/TinyCircuits/TinyCircuits-Tiny-Game-Engine/issues/66")
8662

87-
# Exit if told not to upload
88-
if(upload is False):
89-
exit(0)
90-
91-
# ### Step 5: Assume that the port is plugged in and may be running a program, connect to it
63+
# ### Step 4: Assume that the port is plugged in and may be running a program, connect to it
9264
# end program with ctrl-c, and put into BOOTLOADER mode for upload
9365
print("Looking for serial port to reset...")
9466
for port, desc, hwid in sorted(serial.tools.list_ports.comports()):
@@ -118,7 +90,7 @@ def get_drives():
11890
print("\nConnected and reset!\n")
11991

12092

121-
# ### Step 6: Find the BOOTSEL device and copy over the firmware
93+
# ### Step 5: Find the BOOTSEL device and copy over the firmware
12294
print("Finding drive letter... (may need to manually put into BOOTSEL mode)")
12395
mount = None
12496
done = False
@@ -134,7 +106,7 @@ def get_drives():
134106
print("Found drive! " + mount)
135107

136108
print("Copying firmware to device...")
137-
execute(['sudo', 'cp', firmware_path, mount + "/firmware.uf2"])
109+
execute(['sudo', 'cp', '../ports/rp2/build-THUMBY_COLOR/firmware.uf2', mount + "/firmware.uf2"])
138110
print("SUCCESS: Copied firmware to device!\n")
139111

140112
# Wait for logo to end if calling in succession with run.py

collect_files_for_image.py

Lines changed: 0 additions & 61 deletions
This file was deleted.

doc/landing.html

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,43 @@ <h3>Importable Modules:</h3>
2222
<a href="build/engine_save.html">engine_save</a><br>
2323
<a href="build/engine_time.html">engine_time</a><br>
2424
<a href="build/engine_link.html">engine_link</a><br>
25+
26+
<hr>
27+
28+
<h3>Launcher Folder Structure:</h3>
29+
Games have to be in subdirectories of <code>/Games</code>. They can be organised in any directory structure.
30+
31+
<h4>Minimal example:</h4>
32+
<pre>
33+
─ /Games/mygame
34+
├─ main.py
35+
</pre>
36+
This type of format will show up with a question mark as the icon and the folder name as the game name.
37+
38+
<h4>Minimal example with icon:</h4>
39+
<pre>
40+
─ /Games/mygame
41+
├─ main.py
42+
├─ icon.bmp
43+
</pre>
44+
Instead of a question mark, the game will show up with <code>icon.bmp</code> as the icon. For now, the only supported resolution is 64x64.
45+
46+
<h4>Full example:</h4>
47+
<pre>
48+
─ /Games/mygame
49+
├─ manifest.ini
50+
├─ game.py
51+
├─ game_icon.bmp
52+
</pre>
53+
In this example, the names of all the assets are configured in <code>manifest.ini</code>. In the manifest the following lines can be present:
54+
<pre>
55+
name = Any Name I Want
56+
version = 0.3
57+
main = game.py
58+
icon = game_icon.bmp
59+
</pre>
60+
This format is recommended, and at least the version entry should appear in the manifest. The other entries are optional, defaulting
61+
to directory name, main.py and icon.bmp.
62+
2563
</body>
2664
</html>

filesystem/Games/TestGames/Collision/main.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ def tick(self, dt):
7979
elif engine_io.RB.is_pressed:
8080
self.rotation -= 0.0045
8181

82-
def on_collide(self, contact):
82+
def collision(self, contact):
8383
self.count = self.count + 1
84-
print("Collision!", self.count)
85-
Circle2DNode(position=contact.position, radius=1)
84+
# print("Collision!", self.count)
85+
# Circle2DNode(position=contact.position, radius=1)
8686

8787
camera = CameraNode()
8888

-2.13 KB
Binary file not shown.

0 commit comments

Comments
 (0)