Skip to content

Commit ea28ef4

Browse files
committed
codal_port/modantigravity: Add antigravity module from micro:bit v1.
Taken from ahttps://github.com/bbcmicrobit/micropython commit a92ca9b1f907c07a01116b0eb464ca4743a28bf1 Signed-off-by: Damien George <[email protected]>
1 parent b7a76e4 commit ea28ef4

File tree

3 files changed

+215
-0
lines changed

3 files changed

+215
-0
lines changed

src/codal_port/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ SRC_C += \
7474
microbit_speaker.c \
7575
microbit_spi.c \
7676
microbit_uart.c \
77+
modantigravity.c \
7778
modaudio.c \
7879
modmachine.c \
7980
modmicrobit.c \

src/codal_port/modantigravity.c

+212
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2015 Damien P. George
7+
* Copyright (c) 2016 Joe Glancy
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#include "py/runtime.h"
29+
#include "py/mphal.h"
30+
31+
#define GET_PIXEL(x, y) microbit_hal_display_get_pixel(x, y)
32+
#define SET_PIXEL(x, y, v) microbit_hal_display_set_pixel(x, y, v)
33+
34+
STATIC void antigravity_output_char(char c) {
35+
MP_PLAT_PRINT_STRN((char *)&c, 1);
36+
}
37+
38+
// NOTE: string has to be plain ASCII
39+
STATIC void antigravity_print_rle(const char *s) {
40+
/* RLE encoding format (2 characters, [0] (first) and [1] (second)):
41+
* [0] the amount of times to output the specified character (max 127),
42+
* bitwise or'ed with 0x80 (to set the last bit, ie: bit 7)
43+
* [1] the character to output
44+
*/
45+
char reps; // how many times to output the specified character
46+
while (*s != '\0') {
47+
if ((*s & 0x80) == 0x80) {
48+
// seventh bit set
49+
reps = *s ^ 0x80;
50+
s++;
51+
if (*s == '\0') {
52+
return;
53+
}
54+
while (reps--) {
55+
antigravity_output_char(*s);
56+
}
57+
}
58+
else {
59+
antigravity_output_char(*s);
60+
}
61+
s++;
62+
}
63+
}
64+
65+
/* uncomment the following line if you want to build the antigravity module with
66+
* the full comic instead of the micro one
67+
*/
68+
//#define ANTIGRAVITY_COMIC_LARGE
69+
70+
STATIC void antigravity(uint8_t interval_ms) {
71+
/* move all of the LEDs upwards (we can move them in other directions in the
72+
* future).
73+
* first, output the traditional XKCD comic (either in full or micro:size :)
74+
*/
75+
#ifndef ANTIGRAVITY_COMIC_LARGE
76+
/* micro comic (157 bytes):
77+
+-xkcd.com/353---------------------------------------------------+
78+
| |
79+
| \0/ |
80+
| / \ |
81+
| You're flying! MicroPython! /| |
82+
| How? \ \ |
83+
| / |
84+
| 0 |
85+
| /|\ |
86+
| | |
87+
|-----____/_\______________________________----------------------|
88+
| |
89+
+----------------------------------------------------------------+
90+
*/
91+
static const char *antigravity_comic_str =
92+
"+-xkcd.com/353\xb3-+\n"
93+
"|\xc0 |\n"
94+
"|\xb4 \\0/\x89 |\n"
95+
"|\xb2 /\x83 \\\x89 |\n"
96+
"|\x88 You're flying!\x92 MicroPython! /|\x88 |\n"
97+
"|\x8c How?\xa6 \\ \\\x87 |\n"
98+
"|\x8c /\xb3 |\n"
99+
"|\x8a 0\xb5 |\n"
100+
"|\x89 /|\\\xb4 |\n"
101+
"|\x8a |\xb5 |\n"
102+
"|\x85-\x84_/_\\\x9e_\x96-|\n"
103+
"|\xc0 |\n"
104+
"+\xc0-+\n";
105+
#else
106+
/* full comic (922 bytes):
107+
+-xkcd.com/353-----------------------------------------------------------------+
108+
| |
109+
| \0/ |
110+
| / \ |
111+
| You're flying! MicroPython! /| |
112+
| How? \ \ |
113+
| / |
114+
| 0 |
115+
| /|\ |
116+
| | |
117+
|--------------____/_\_______________________________--------------------------|
118+
| |
119+
| |
120+
+------------------------------------------------------------------------------+
121+
+-----------------------+ +-------------------------+ +------------------------+
122+
| | | I dunno... | | | I just typed |
123+
| 0 | | Dynamic typing? / | | import antigravity |
124+
| _/\\_ | | Whitespace? / | | | |
125+
| / \// | | / / | | That's it? / |
126+
| I learned it last | | | Come join us! | | / / |
127+
| night! Everything | | | Programming | | / ...I also |
128+
| is so simple! | | | is fun again! | | / sampled |
129+
| / | | | It's a whole | | | everything in the |
130+
| / | | | new world | | | medicine cabinet |
131+
| Hello world is | | | up here! | | | for comparison. |
132+
| just | | 0 | | 0 | |
133+
| | | /|\/ | | /|\ But I think |
134+
| print("Hello, world!")| | | \_ But how are | | | this is the |
135+
| | | / \ you flying? | | / \ Python. |
136+
+-----------------------+ +-------------------------+ +------------------------+
137+
*/
138+
static const char *antigravity_comic_str =
139+
"+-xkcd.com/353\xc1-+\n"
140+
"|\xce |\n"
141+
"|\xbe \\0/\x8d |\n"
142+
"|\xbc /\x83 \\\x8d |\n"
143+
"|\x91 You're flying!\x93 MicroPython! /|\x8c |\n"
144+
"|\x95 How?\xa7 \\ \\\x8b |\n"
145+
"|\x95 /\xb8 |\n"
146+
"|\x93 0\xba |\n"
147+
"|\x92 /|\\\xb9 |\n"
148+
"|\x93 |\xba |\n"
149+
"|\x8e-\x84_/_\\\x9f_\x9a-|\n"
150+
"|\xce |\n"
151+
"|\xce |\n"
152+
"+\xce-+\n"
153+
"+\x97-+ +\x99-+ +\x98-+\n"
154+
"|\x97 | |\x84 I dunno\x83.\x87 |\x83 | |\x86 I just typed\x86 |\n"
155+
"|\x89 0\x8d | | Dynamic typing?\x83 /\x84 | |\x83 import antigravity\x83 |\n"
156+
"|\x88 _/\\\\_\x8a | |\x84 Whitespace?\x84 /\x85 | |\x92 |\x85 |\n"
157+
"|\x85 /\x85 \\//\x89 | |\x84 /\x8d /\x86 | |\x85 That's it? /\x86 |\n"
158+
"|\x83 I learned it last\x83 | |\x83 |\x86 Come join us! | |\x85 /\x8a /\x87 |\n"
159+
"|\x83 night! Everything\x83 | |\x83 |\x87 Programming\x83 | |\x84 /\x84 \x83.I also\x86 |\n"
160+
"|\x85 is so simple!\x85 | |\x83 |\x86 is fun again! | |\x83 /\x86 sampled\x87 |\n"
161+
"|\x8c /\x8a | |\x83 |\x86 It's a whole | | | everything in the |\n"
162+
"|\x8b /\x8b | |\x83 |\x87 new world\x84 | | | medicine cabinet\x83 |\n"
163+
"|\x85 Hello world is\x84 | |\x83 |\x88 up here!\x85 | | |\x83 for comparison.\x83 |\n"
164+
"|\x89 just\x8a | |\x83 0\x95 | |\x83 0\x89 |\x8a |\n"
165+
"|\x97 | | /|\\/\x93 | | /|\\\x84 But I think\x84 |\n"
166+
"| print(\"Hello, world!\")| |\x83 |\x83 \\_ But how are\x84 | |\x83 |\x85 this is the\x84 |\n"
167+
"|\x97 | | / \\\x85 you flying?\x84 | | / \\\x86 Python.\x86 |\n"
168+
"+\x97-+ +\x99-+ +\x98-+\n";
169+
#endif /* ANTIGRAVITY_COMIC_LARGE */
170+
171+
antigravity_print_rle(antigravity_comic_str);
172+
173+
for (uint8_t iteration = 0; iteration < 5; iteration++) {
174+
mp_hal_delay_ms(interval_ms);
175+
bool wait = false;
176+
for (uint8_t row = 1; row < 5 - iteration; row++) {
177+
for (uint8_t col = 0; col < 5; col++) {
178+
// move this bit down if possible
179+
uint8_t val = GET_PIXEL(col, row);
180+
if (val) {
181+
// this is why the row for loop starts at one
182+
if (!GET_PIXEL(col, row - 1)) {
183+
SET_PIXEL(col, row, 0);
184+
SET_PIXEL(col, row - 1, val);
185+
wait = true;
186+
}
187+
} // we don't care if the LED is off
188+
}
189+
}
190+
191+
if (!wait) {
192+
continue;
193+
}
194+
}
195+
}
196+
197+
STATIC mp_obj_t antigravity__init__(void) {
198+
antigravity(200);
199+
return mp_const_none;
200+
}
201+
STATIC MP_DEFINE_CONST_FUN_OBJ_0(antigravity___init___obj, antigravity__init__);
202+
203+
STATIC const mp_rom_map_elem_t antigravity_module_globals_table[] = {
204+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_antigravity) },
205+
{ MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&antigravity___init___obj) },
206+
};
207+
STATIC MP_DEFINE_CONST_DICT(antigravity_module_globals, antigravity_module_globals_table);
208+
209+
const mp_obj_module_t antigravity_module = {
210+
.base = { &mp_type_module },
211+
.globals = (mp_obj_dict_t *)&antigravity_module_globals,
212+
};

src/codal_port/mpconfigport.h

+2
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100

101101
#define MP_STATE_PORT MP_STATE_VM
102102

103+
extern const struct _mp_obj_module_t antigravity_module;
103104
extern const struct _mp_obj_module_t audio_module;
104105
extern const struct _mp_obj_module_t machine_module;
105106
extern const struct _mp_obj_module_t microbit_module;
@@ -110,6 +111,7 @@ extern const struct _mp_obj_module_t speech_module;
110111
extern const struct _mp_obj_module_t utime_module;
111112

112113
#define MICROPY_PORT_BUILTIN_MODULES \
114+
{ MP_ROM_QSTR(MP_QSTR_antigravity), MP_ROM_PTR(&antigravity_module) }, \
113115
{ MP_ROM_QSTR(MP_QSTR_audio), MP_ROM_PTR(&audio_module) }, \
114116
{ MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&machine_module) }, \
115117
{ MP_ROM_QSTR(MP_QSTR_microbit), MP_ROM_PTR(&microbit_module) }, \

0 commit comments

Comments
 (0)