2 |
3 | # Pinkie Run
4 |
5 |

6 |
7 | > A small pony endless runner for [Varvara](https://wiki.xxiivv.com/site/varvara.html)
8 |
9 |
10 |
11 | - 💨 Press `A` (default bind: `Left Ctrl`), or `Left Click` to Jump!
12 | - 🎈 Avoid hitting the balloons!
13 | - 🔢 Get a high score!
14 |
15 | # 📃 TODO
16 | - Persistent high score
17 | - Menu
18 | - SFX
19 |
--------------------------------------------------------------------------------
/REAL_LICENSE.md:
--------------------------------------------------------------------------------
1 | THE UNICORN LICENSE, VERSION 1
2 |
3 | Copyright (c) 2023 Jaezmien Naejara
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | 1. The source code of the Software shall be reviewed by a unicorn, who swears upon the Unicorn Law that it is reviewing the software with full honesty and integrity, ensuring that the software does not contain any harmful or malicious code.
8 |
9 | 2. The unicorn's review shall indicate that the source code is original and not plagiarized, and that the software is safe to use.
10 |
11 | 3. The Software shall not be used for any illegal or unethical purposes.
12 |
13 | 4. The source code of the Software must be disclosed along with the binary or compiled version of the software.
14 |
15 | 5. Redistributions of the Software in any form must retain the above copyright notice and this license.
16 |
17 | 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 or copyright holders 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.
18 |
19 | By utilizing the software, the user hereby agrees to be bound by the terms and conditions outlined in this license agreement. If the user does not accept and abide by these terms and conditions, they shall not have the right or authorization to use the software, and must immediately discontinue any usage of the software.
--------------------------------------------------------------------------------
/pinkie.rom:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jaezmien/pinkie-run/b4a6d5a61a5a56da589908141dcf9fb39e34676d/pinkie.rom
--------------------------------------------------------------------------------
/pinkie.tal:
--------------------------------------------------------------------------------
1 | (
2 | pinkie.tal - Pinkie Run
3 | A Pony-Themed Endless Runner // Jaezmien Naejara [https://jaezmien.github.io]
4 | )
5 |
6 | |00 @System [ &vector $2 &expansion $2 &title $2 &pad $2 &r $2 &g $2 &b $2 &debug $1 &state $1 ]
7 | |20 @Screen [ &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
8 | |80 @Controller [ &vector $2 &button $1 &key $1 ]
9 | |90 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &pad $3 &scrollx $2 &scrolly $2 ]
10 |
11 | %DISPLAY-WIDTH { #0050 }
12 | %DISPLAY-HEIGHT { #0050 }
13 | (
14 | "why?"
15 | well, I don't want to deal with the headaches of unsigned integer and positions
16 | so i'm shifting the screen left 8 pixels to the left
17 | )
18 | %SCREEN-WIDTH { DISPLAY-WIDTH #0008 ADD2 }
19 | %SCREEN-HEIGHT { DISPLAY-HEIGHT #0008 ADD2 }
20 | %GROUND-HEIGHT { SCREEN-HEIGHT #0020 SUB2 }
21 | %STAND-POS { GROUND-HEIGHT #0010 SUB2 }
22 | %RTN { JMP2r }
23 | %DEBUG { #01 .System/debug DEO }
24 | %8MOD { #07 AND } ( a -- a%8 )
25 | %MOD { DUP2 DIV MUL SUB } ( a b -- a%b )
26 | %BTS { #00 SWP } ( byte -- short )
27 |
28 | |0000
29 | @death-timer $1
30 | @score $1
31 |
32 | @pinkie [
33 | &timer $1
34 | &x $2 &y $2
35 | &velDir $1
36 | &velVal $1
37 | &jump $1
38 | ]
39 | @balloon [
40 | &timer $1
41 | &x $2 &y $2
42 | &active $1
43 | &activeTimer $1
44 | ¤t $1
45 | ]
46 |
47 | |0100
48 | DISPLAY-WIDTH .Screen/width DEO2
49 | DISPLAY-HEIGHT .Screen/height DEO2
50 |
51 | ;title .System/title DEO2
52 |
53 | #6fe7 .System/r DEO2
54 | #0b4d .System/g DEO2
55 | #3d8e .System/b DEO2
56 |
57 | ;draw-ground JSR2
58 |
59 | SCREEN-WIDTH #02 SFT #0008 SUB2 .pinkie/x STZ2
60 | ;reset-variables JSR2
61 |
62 | ;on-controller-input .Controller/vector DEO2
63 | ;on-mouse-input .Mouse/vector DEO2
64 | ;on-update .Screen/vector DEO2
65 | BRK
66 |
67 | ( -- uxn funcs -- )
68 |
69 | @on-update
70 | ;clear-sprites JSR2
71 |
72 | .death-timer LDZ #00 NEQ ,&skip-update JCN
73 | ;update-pinkie JSR2
74 | ;update-balloon JSR2
75 |
76 | ;handle-collision JSR2
77 | &skip-update
78 | .death-timer LDZ #00 EQU ,&skip-increment JCN
79 | .death-timer LDZ #01 SUB DUP .death-timer STZ
80 | ( .death-timer ) #00 NEQ ,&skip-increment JCN
81 | ;reset-variables JSR2 ( reset game )
82 | &skip-increment
83 |
84 | ;draw-score JSR2
85 |
86 | ;draw-balloon JSR2
87 | #4a ;draw-pinkie JSR2
88 | BRK
89 |
90 | @on-controller-input ( -> )
91 | ( Exit when user presses 'ESC' )
92 | .Controller/key DEI
93 | #1b EQU ;exit-game JCN2
94 |
95 | ( Is A pressed? )
96 | .Controller/button DEI
97 | #01 AND #01 NEQ ,&continue-a-btn JCN
98 | ;handle-a-press JSR2
99 | &continue-a-btn
100 | BRK
101 |
102 | @on-mouse-input ( -> )
103 | .Mouse/state DEI
104 | #01 NEQ ,&continue-mouse1 JCN
105 | ;handle-a-press JSR2
106 | &continue-mouse1
107 | BRK
108 |
109 | ( -- funcs -- )
110 |
111 | @reset-variables
112 | #00 .death-timer STZ
113 | #00 .score STZ
114 | STAND-POS .pinkie/y STZ2
115 | #00 .pinkie/velDir STZ
116 | #00 .pinkie/velVal STZ
117 | #00 .pinkie/jump STZ
118 | SCREEN-WIDTH .balloon/x STZ2
119 | STAND-POS .balloon/y STZ2
120 | #00 .balloon/active STZ
121 | #40 .balloon/activeTimer STZ
122 | #00 .balloon/current STZ
123 | RTN
124 |
125 | @get-pinkie-timer ( -> sTimer )
126 | .pinkie/timer LDZ #02 SFT #03 AND
127 | RTN
128 |
129 | @get-jumping ( -> bJumping )
130 | .pinkie/y LDZ2 STAND-POS LTH2
131 | RTN
132 |
133 | @get-pinkie-bottom-sprite ( -> sOffset )
134 | ;get-jumping JSR2 ,&set-walk1 JCN
135 | ;get-pinkie-timer JSR2
136 |
137 | DUP #00 EQU OVR #02 EQU ORA ,&set-walk0 JCN
138 | ( timer ) #01 EQU ,&set-walk1 JCN
139 | ,&set-walk2 JMP
140 |
141 | &set-walk0 POP #0000 JMP2r ( 0 || 2 )
142 | &set-walk1 #0010 JMP2r ( 1 )
143 | &set-walk2 #0020 JMP2r ( 3 )
144 | BRK
145 |
146 | @get-pinkie-offset ( -> sOffset )
147 | ;get-pinkie-timer JSR2
148 |
149 | DUP #00 EQU OVR #02 EQU ORA ( timer offset )
150 | NIP BTS
151 | RTN
152 |
153 | @get-pinkie-visual-y ( -> sPosition )
154 | .pinkie/y LDZ2
155 | ;get-jumping JSR2 ,&ignore-offset JCN
156 | ;get-pinkie-offset JSR2 ADD2
157 | &ignore-offset
158 | RTN
159 |
160 | @get-pinkie-sprite-flag ( bCurFlag bDeathTimer -> bFlag )
161 | #00 EQU ,&no-flip-y-top JCN
162 | #20 ADD
163 | &no-flip-y-top
164 | RTN
165 |
166 | @get-balloon-bottom-sprite ( -> sOffset )
167 | .balloon/timer LDZ #04 SFT #01 AND
168 | RTN
169 |
170 | @handle-a-press ( -> )
171 | ;get-jumping JSR2 ,&ignore-jump JCN
172 | #01 .pinkie/velDir STZ
173 | #0b .pinkie/velVal STZ
174 | #01 .pinkie/jump STZ
175 | &ignore-jump
176 |
177 | .death-timer LDZ #02 LTH ,&ignore-timer JCN
178 | #01 .death-timer STZ
179 | &ignore-timer
180 | RTN
181 |
182 | @update-pinkie ( -> )
183 | ( update sprite timer )
184 | .pinkie/timer DUP LDZ INC SWP STZ
185 |
186 | ( update sprite position )
187 | .pinkie/jump LDZ #00 EQU ,&after-frame-jump JCN
188 | .pinkie/y DUP LDZ2 #0001 SUB2 ROT STZ2
189 | #00 .pinkie/jump STZ
190 | &after-frame-jump
191 |
192 | ;get-jumping JSR2 #00 EQU ,&after-jumping JCN
193 | .pinkie/velVal LDZ .pinkie/velDir LDZ ,&move-up JCN ,&move-down JMP
194 | &move-up
195 | #01 SUB
196 | DUP .pinkie/velVal STZ
197 | DUP BTS .pinkie/y LDZ2 SWP2 #01 SFT2 SUB2 .pinkie/y STZ2
198 | ( .pinkie/velVal ) #00 EQU ,&set-moving-down JCN ,&after-jumping JMP
199 | &set-moving-down
200 | #00 .pinkie/velDir STZ
201 | ,&after-jumping JMP
202 | &move-down
203 | #01 ADD
204 | DUP .pinkie/velVal STZ
205 | ( .pinkie/velVal ) BTS .pinkie/y LDZ2 SWP2 #01 SFT2 ADD2 .pinkie/y STZ2
206 | ;get-jumping JSR2 #00 EQU ,&set-grounded JCN ,&after-jumping JMP
207 | &set-grounded
208 | #00 .pinkie/velDir STZ
209 | #00 .pinkie/velVal STZ
210 | STAND-POS .pinkie/y STZ2
211 | ,&after-jumping JMP
212 | &after-jumping
213 | RTN
214 |
215 | @update-balloon ( -> )
216 | .balloon/timer DUP LDZ INC SWP STZ
217 |
218 | .balloon/active LDZ ,&move-balloon JCN
219 | ( &update-timer )
220 | .balloon/activeTimer LDZ #01 SUB DUP .balloon/activeTimer STZ
221 | ( .balloon/activeTimer ) #00 NEQ ,&continue JCN
222 | ( &spawn-balloon )
223 | #01 .balloon/active STZ
224 | .balloon/current LDZ INC .balloon/current STZ
225 | ,&continue JMP
226 | &move-balloon
227 | .balloon/x LDZ2 DUP2 #0002 SUB2 DUP2 .balloon/x STZ2
228 | ( prevVal newVal ) GTH2 ( a > b ) ,&continue JCN
229 | SCREEN-WIDTH .balloon/x STZ2
230 | #00 .balloon/active STZ
231 |
232 | ( randomize spawn time )
233 | .balloon/current LDZ #07 MUL #0a MOD #02 MUL #05 ADD
234 | .balloon/activeTimer STZ
235 |
236 | &continue
237 | RTN
238 |
239 | @handle-collision ( -> )
240 | .balloon/active #00 EQU ,&no-collision JCN ( balloon is not active, don't bother checking )
241 |
242 | ( check x collision )
243 | .balloon/x LDZ2 [ .pinkie/x LDZ2 #0009 ADD2 ] LTH2 ( Pinkie - Right )
244 | #00 EQU ,&no-collision JCN
245 | [ .balloon/x LDZ2 #0008 ADD2 ] .pinkie/x LDZ2 LTH2 ( Pinkie - Left )
246 | #01 EQU ,&update-score JCN
247 |
248 | ( check y coord )
249 | .pinkie/y LDZ2 #000b ADD2 .balloon/y LDZ2 GTH2
250 | #00 EQU ,&no-collision JCN
251 |
252 | ( we have collided! )
253 | #50 .death-timer STZ
254 |
255 | ,&no-collision JMP
256 | &update-score
257 | .balloon/current LDZ .score STZ
258 | &no-collision
259 | RTN
260 |
261 | @hex-to-decimal ( bHex - bOnes bTens bHundreds )
262 | ( #00 STH )
263 | DUP #64 DIV STH ( floor(x / 100) )
264 | DUP #64 MOD #0a DIV STH ( floor(x % 100) / 10 )
265 | #0a MOD STH ( x % 10 )
266 |
267 | ( STHr )
268 | STHr STHr STHr
269 | RTN
270 |
271 | ( -- draw funcs -- )
272 |
273 | @clear-sprites ( -> )
274 | ( Pinkie Pie )
275 | #40 ;draw-pinkie JSR2
276 |
277 | ( Balloon )
278 | #06 .Screen/auto DEO
279 | .balloon/x LDZ2 #0008 SUB2 .Screen/x DEO2
280 | .balloon/y LDZ2 .Screen/y DEO2
281 | ;sprite-balloon/t .Screen/addr DEO2
282 | #40 .Screen/sprite DEOk
283 | ;sprite-balloon/b #00 ;get-balloon-bottom-sprite JSR2 #08 MUL ADD2 .Screen/addr DEO2
284 | DEO
285 | RTN
286 |
287 | @draw-ground ( -> )
288 | GROUND-HEIGHT
289 | &loop-y
290 | DUP2 .Screen/y DEO2
291 |
292 | SCREEN-WIDTH #0000
293 | &loop-x
294 | DUP2 .Screen/x DEO2
295 | #01 .Screen/pixel DEO
296 | INC2 NEQ2k ,&loop-x JCN
297 | POP2 POP2
298 |
299 | INC2 DUP2 SCREEN-HEIGHT NEQ2 ,&loop-y JCN
300 | POP2
301 | RTN
302 |
303 | @draw-pinkie ( bSpriteFlag -> )
304 | STH
305 |
306 | ( Set auto )
307 | #05 .Screen/auto DEO
308 |
309 | .death-timer LDZ #00 GTH STH
310 |
311 | ( Draw top half )
312 | .pinkie/x LDZ2 #0008 SUB2 DUP2 .Screen/x DEO2
313 | ;get-pinkie-visual-y JSR2
314 | DUPr STHr #00 EQU ,&continue-pinkie-y-top JCN
315 | #0008 ADD2
316 | &continue-pinkie-y-top
317 | DUP2 .Screen/y DEO2
318 | ;sprite-pinkie/t .Screen/addr DEO2
319 |
320 | DUP2r STH2r ;get-pinkie-sprite-flag JSR2
321 | .Screen/sprite DEOk DEO
322 |
323 | ( Draw bottom half )
324 | ( .pinkie/y ) #0008
325 | DUPr STHr #00 NEQ ,&offset-y-bottom JCN
326 | ADD2 ,&continue-pinkie-y-bottom JMP
327 | &offset-y-bottom SUB2
328 | &continue-pinkie-y-bottom
329 | .Screen/y DEO2
330 | ( .pinkie/x ) .Screen/x DEO2
331 | ;sprite-pinkie/b ;get-pinkie-bottom-sprite JSR2 ADD2 .Screen/addr DEO2
332 |
333 | DUP2r STH2r ;get-pinkie-sprite-flag JSR2
334 | .Screen/sprite DEOk DEO
335 |
336 | POPr ( death-timer )
337 | POPr ( sprite flag )
338 | RTN
339 |
340 | @draw-balloon ( -> )
341 | .balloon/active #00 EQU ,&stop-draw JCN
342 | ( Set auto )
343 | #06 .Screen/auto DEO
344 |
345 | ( Draw top half )
346 | .balloon/x LDZ2 #0008 SUB2 .Screen/x DEO2
347 | .balloon/y LDZ2 .Screen/y DEO2
348 | ;sprite-balloon/t .Screen/addr DEO2
349 | #43 .Screen/sprite DEOk
350 |
351 | ( Draw bottom half )
352 | ;sprite-balloon/b #00 ;get-balloon-bottom-sprite JSR2 #08 MUL ADD2 .Screen/addr DEO2
353 | DEO
354 | &stop-draw
355 | RTN
356 |
357 | @draw-score ( -> )
358 | #05 .Screen/auto DEO
359 | SCREEN-WIDTH #0024 SUB2 .Screen/x DEO2
360 | #0004 .Screen/y DEO2
361 |
362 | .score LDZ
363 | ;hex-to-decimal JSR2
364 | #03
365 | &loop
366 | OVR
367 | #10 ADD BTS #0008 MUL2 ;font ADD2 .Screen/addr DEO2
368 | #01 .Screen/sprite DEO
369 | NIP
370 | #01 SUB DUP #00 NEQ ,&loop JCN
371 | POP
372 | RTN
373 |
374 | ( -- end -- )
375 |
376 | @exit-game LIT 01 .System/state DEO BRK
377 |
378 | ( -- game assets -- )
379 |
380 | @title "Pinkie 20 "Run 00
381 |
382 | @sprite-pinkie [
383 | &t 0000 0001 0101 397c 385e af63 7aa9 bcbc
384 | &b 7067 2b25 ac6c 0c00 5090 f0f0 3030 3000
385 | 7067 2b25 9c38 3000 5090 f0f0 381c 0c00 ( jumping )
386 | 7067 2b25 b762 0100 5090 f0f0 70e0 c000
387 | ]
388 |
389 | @sprite-balloon [
390 | &t 3c76 7a7e 7a7e 3c00
391 | &b 1800 1010 1008 0808 1800 0808 0810 1010
392 | ]
393 |
394 | @font ( bbcmicro )
395 | 0000 0000 0000 0000 1818 1818 1800 1800
396 | 6c6c 6c00 0000 0000 3636 7f36 7f36 3600
397 | 0c3f 683e 0b7e 1800 6066 0c18 3066 0600
398 | 386c 6c38 6d66 3b00 0c18 3000 0000 0000
399 | 0c18 3030 3018 0c00 3018 0c0c 0c18 3000
400 | 0018 7e3c 7e18 0000 0018 187e 1818 0000
401 | 0000 0000 0018 1830 0000 007e 0000 0000
402 | 0000 0000 0018 1800 0006 0c18 3060 0000
403 | 3c66 6e7e 7666 3c00 1838 1818 1818 7e00
404 | 3c66 060c 1830 7e00 3c66 061c 0666 3c00
405 | 0c1c 3c6c 7e0c 0c00 7e60 7c06 0666 3c00
406 | 1c30 607c 6666 3c00 7e06 0c18 3030 3000
407 | 3c66 663c 6666 3c00 3c66 663e 060c 3800
408 | 0000 1818 0018 1800 0000 1818 0018 1830
409 | 0c18 3060 3018 0c00 0000 7e00 7e00 0000
410 | 3018 0c06 0c18 3000 3c66 0c18 1800 1800
411 | 3c66 6e6a 6e60 3c00 3c66 667e 6666 6600
412 | 7c66 667c 6666 7c00 3c66 6060 6066 3c00
413 | 786c 6666 666c 7800 7e60 607c 6060 7e00
414 | 7e60 607c 6060 6000 3c66 606e 6666 3c00
415 | 6666 667e 6666 6600 7e18 1818 1818 7e00
416 | 3e0c 0c0c 0c6c 3800 666c 7870 786c 6600
417 | 6060 6060 6060 7e00 6377 7f6b 6b63 6300
418 | 6666 767e 6e66 6600 3c66 6666 6666 3c00
419 | 7c66 667c 6060 6000 3c66 6666 6a6c 3600
420 | 7c66 667c 6c66 6600 3c66 603c 0666 3c00
421 | 7e18 1818 1818 1800 6666 6666 6666 3c00
422 | 6666 6666 663c 1800 6363 6b6b 7f77 6300
423 | 6666 3c18 3c66 6600 6666 663c 1818 1800
424 | 7e06 0c18 3060 7e00 7c60 6060 6060 7c00
425 | 0060 3018 0c06 0000 3e06 0606 0606 3e00
426 | 183c 6642 0000 0000 0000 0000 0000 00ff
427 | 1c36 307c 3030 7e00 0000 3c06 3e66 3e00
428 | 6060 7c66 6666 7c00 0000 3c66 6066 3c00
429 | 0606 3e66 6666 3e00 0000 3c66 7e60 3c00
430 | 1c30 307c 3030 3000 0000 3e66 663e 063c
431 | 6060 7c66 6666 6600 1800 3818 1818 3c00
432 | 1800 3818 1818 1870 6060 666c 786c 6600
433 | 3818 1818 1818 3c00 0000 367f 6b6b 6300
434 | 0000 7c66 6666 6600 0000 3c66 6666 3c00
435 | 0000 7c66 667c 6060 0000 3e66 663e 0607
436 | 0000 6c76 6060 6000 0000 3e60 3c06 7c00
437 | 3030 7c30 3030 1c00 0000 6666 6666 3e00
438 | 0000 6666 663c 1800 0000 636b 6b7f 3600
439 | 0000 663c 183c 6600 0000 6666 663e 063c
440 | 0000 7e0c 1830 7e00 0c18 1870 1818 0c00
441 | 1818 1800 1818 1800 3018 180e 1818 3000
442 | 316b 4600 0000 0000 ffff ffff ffff ffff
443 |
--------------------------------------------------------------------------------