all repos — soulgrind @ d2a300b7e6fdb7f1d1ca39149da1bb431a788736

arcade-style rollerblading game in uxntal with xrxs multiplayer

soulgrind.tal (raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
( Soul Grind - a game about infinite aggressive skating,
    featuring solo and (via xrxs) head-to-head modes
  MIT license
  Derek Stevens <nilix@nilfm.cc> ) 

%DEBUG  { ;print-hex JSR2 #0a .Console/write DEO }
%DEBUG2 { SWP ;print-hex JSR2 ;print-hex JSR2 #0a .Console/write DEO }

%TOS  { #00 SWP }  %TOB { SWP POP }

%MOD { DIVk MUL SUB }
%MOD2 { DIV2k MUL2 SUB2 }

%2**  { #10 SFT2 } %2// { #01 SFT2 }
%8**  { #30 SFT2 } %8// { #03 SFT2 }

%INC-X { .Screen/x DEI2 #0008 ADD2 .Screen/x DEO2 } ( -- )
%INC-Y { .Screen/y DEI2 #0008 ADD2 .Screen/y DEO2 }

%NEXT-TILE { DUP2 #0010 ADD2 }

%RTN { JMP2r }

( devices )

|00 @System     [ &vector $2 &wst      $1 &rst    $1 &pad   $4 &r      $2 &g      $2 &b    $2 &debug  $1 &halt $1 ]
|10 @Console    [ &vector $2 &read     $1 &pad    $5 &write $1 &error  $1 ]
|20 @Screen     [ &vector $2 &width    $2 &height $2 &pad   $2 &x      $2 &y      $2 &addr $2 &pixel  $1 &sprite $1 ]
|30 @Audio0     [ &vector $2 &position $2 &output $1 &pad   $3 &adsr   $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|40 @Audio1     [ &vector $2 &position $2 &output $1 &pad   $3 &adsr   $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|50 @Audio2     [ &vector $2 &position $2 &output $1 &pad   $3 &adsr   $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|60 @Audio3     [ &vector $2 &position $2 &output $1 &pad   $3 &adsr   $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
|80 @Controller [ &vector $2 &button   $1 &key    $1 ]
|90 @Mouse      [ &vector $2 &x        $2 &y      $2 &state $1 &wheel  $1 ]
|a0 @File0      [ &vector $2 &success  $2 &stat   $2 &delete $1 &append $1 &name  $2 &length $2 &read $2 &write $2 ]
|b0 @File1      [ &vector $2 &success  $2 &stat   $2 &delete $1 &append $1 &name  $2 &length $2 &read $2 &write $2 ]
|c0 @DateTime   [ &year   $2 &month    $1 &day    $1 &hour  $1 &minute $1 &second $1 &dotw $1 &doty   $2 &isdst $1 ]

( variables )

|0000

@xrxs $1

@state $1
@ticker $1

@blader [
  &x $2
  &y $2
  &z $2
  &dx $1
  &dy $1
  &dz $1
  &stance $1
  &frame $1
  &anim-speed $1
  &trick $1
  &score $2
  &bailed $1
]

@map [
  &edge $1
  &tile-offset $1
]

@row1 [
  $40
  &mode $1
  &run $1
]
@row2 [
  $40
  &mode $1
  &run $1
]
@row3 [
  $40
  &mode $1
  &run $1
]

@rival [
  &last-trick $1
  &score $2
  &bailed $1
]

@center [
  &x $2
  &y $2
]

( program )

|0100 ( -> )

	( theme ) 
	#7459 .System/r DEO2 
	#a4cd .System/g DEO2 
	#84aa .System/b DEO2

  #0200 .Screen/width DEO2
  #0110 .Screen/height DEO2

  .Screen/width DEI2 #01 SFT2 .center/x STZ2k
  .Screen/height DEI2 #01 SFT2 .center/y STZ2k

  POP .blader/y STZ2
  POP .blader/x STZ2
  #0000 .blader/z STZ2
  #20 .blader/anim-speed STZ
  #0000 .blader/score STZ2
  #00 .blader/stance STZ
  #00 .blader/frame STZ

  #00 .state STZ
  #00 .ticker STZ

  #00 .map/edge STZ

  ;file-chr-title .File0/name DEO2
  #bc00 .File0/length DEO2

  ;titlescreen .File0/read DEO2

  ;file-xrxs-version .File0/name DEO2
  #0010 .File0/length DEO2

  ;buffer .File0/read DEO2
  .File0/success DEI2 #0000 NEQ2 .xrxs STZ

  ;prng-init JSR2

  ;main-loop .Screen/vector DEO2
  ;key-listen-press-start .Controller/vector DEO2
BRK

@clear-screen ( -> )
 
  .Screen/width DEI2 #0000 &whilex EQU2k ,&endx JCN
    DUP2 ,&x STR2
    .Screen/height DEI2 #0000 &whiley EQU2k ,&endy JCN
      DUP2 ,&y STR2
      ,&x LDR2 .Screen/x DEO2
      ,&y LDR2 .Screen/y DEO2
      ;blank .Screen/addr DEO2
      #10 .Screen/sprite DEO
      #40 .Screen/sprite DEO
    #0008 ADD2 ,&whiley JMP &endy POP2 POP2
  #0008 ADD2 ,&whilex JMP &endx POP2 POP2
  
RTN

&x $2
&y $2

@key-listen-mode-select ( -> )

  .Controller/button DEI
  DUP #c0 AND #00 EQU ,&no-left-right JCN
  
    .state LDZ #01 NEQ ,&no-1p JCN
      #02 .state STZ
      ,&no-left-right JMP
    &no-1p
      #01 .state STZ
  
  &no-left-right
  
  DUP #09 AND #00 EQU ,&no-confirm JCN
  
    .state LDZ #01 NEQ ,&no-1p-go JCN
      #40 .state STZ
      #40 ;map-gen JSR2
      ;key-listen-1p-game .Controller/vector DEO2
      ,&no-confirm JMP
    &no-1p-go
      #10 .state STZ
  &no-confirm
  POP
BRK

@key-listen-1p-game ( -> )

BRK

@key-listen-press-start ( -> )

  .Controller/button DEI
  #08 NEQ ,&no-press-start JCN
  
    ( if xrxs, go to game mode selection )
    .xrxs LDZ #00 EQU ,&no-xrxs JCN
      #01 .state STZ
      ;key-listen-mode-select .Controller/vector DEO2
      BRK
      
    ( if no xrxs, just proceed to single player game )
    &no-xrxs
      #40 .state STZ
      #40 ;map-gen JSR2
      ;key-listen-1p-game .Controller/vector DEO2
      BRK
  &no-press-start
  
BRK

@press-start-screen ( -> )

  ( display title spritemap )
  
  .center/x LDZ2 #0078 #01 SFT2 SUB2 .Screen/x DEO2
  .center/y LDZ2 #0060 #01 SFT2 SUB2 .Screen/y DEO2

  #bc00 #0000 &while EQU2k ,&end JCN
    DUP2 ;titlescreen ADD2 .Screen/addr DEO2
    #81 .Screen/sprite DEO INC-X
    
    NEXT-TILE #00f0 AND2 #0000 NEQ2 ,&no-inc-y JCN
      .center/x LDZ2 #0078 #01 SFT2 SUB2 .Screen/x DEO2
      INC-Y
    &no-inc-y
  #0010 ADD2 ,&while JMP &end POP2 POP2

  
  ( flash "press start" )
  .ticker LDZk INC
  DUP .ticker STZ

  DUP #20 GTH ,&flash-text JCN
    ( draw text )
    [ ;txt-press-start
      .center/x LDZ2 OVR2 ;strlen JSR2 #20 SFT2 SUB2
      .Screen/height DEI2 #0010 SUB2
      #01 ] ;draw-string JSR2
  &flash-text
  #40 GTH ,&reset-ticker JCN
    RTN
  &reset-ticker
  #00 .ticker STZ

RTN

@mode-select-screen ( -> )
  ( display title spritemap )

  .center/x LDZ2 #0078 #01 SFT2 SUB2 .Screen/x DEO2
  .center/y LDZ2 #0060 #01 SFT2 SUB2 .Screen/y DEO2

  #bc00 #0000 &while EQU2k ,&end JCN
    DUP2 ;titlescreen ADD2 .Screen/addr DEO2
    #81 .Screen/sprite DEO INC-X
    
    NEXT-TILE #00f0 AND2 #0000 NEQ2 ,&no-inc-y JCN
      .center/x LDZ2 #0078 #01 SFT2 SUB2 .Screen/x DEO2
      INC-Y
    &no-inc-y
  #0010 ADD2 ,&while JMP &end POP2 POP2

  ( display Single Player/Multiplayer )

  [ ;txt-1p
    .center/x LDZ2 OVR2 ;strlen JSR2 #30 SFT2 #0010 ADD2 SUB2
    .Screen/height DEI2 #0010 SUB2
    #01 ] ;draw-string JSR2
    
  [ ;txt-2p
    .center/x LDZ2 #0010 ADD2
    .Screen/height DEI2 #0010 SUB2
    #01 ] ;draw-string JSR2

  ( display selection arrow )
  
  ;arrow .Screen/addr DEO2
  .Screen/height DEI2 #0010 SUB2 .Screen/y DEO2
  .state LDZ #01 NEQ ,&no-1p-arrow JCN
    .center/x LDZ2 ;txt-1p ;strlen JSR2 #30 SFT2 #0018 ADD2 SUB2 .Screen/x DEO2
    ,&draw-arrow JMP
  &no-1p-arrow
    .center/x LDZ2 #0008 ADD2 .Screen/x DEO2
  &draw-arrow
  
  #01 .Screen/sprite DEO

RTN

@check-run ( length -- invert )

  #08 LTH ,&no JCN
  ;prng JSR2 #7f GTH ,&no JCN
  ( yes )
    #01 RTN
  &no
    #00

RTN

@invert-run ( row -- row )
  DUP #40 ADD LDZ #00 EQU ,&to-yes JCN
    DUP #40 ADD #00 SWP STZ ,&to-reset JMP
  &to-yes
    DUP #40 ADD #01 SWP STZ
  &to-reset
    DUP #41 ADD #00 SWP STZ
RTN

@set-tile ( width row -- width )

  ( increase run )
  DUP #41 ADD LDZk INC SWP STZ

  ( get mode )
  DUP #41 ADD LDZ STH

  ( set at row edge - width )
  OVR .map/edge LDZ SWP SUB ADD STHr SWP STZ

RTN

@map-gen ( width -- )

  ( width is measured from the right edge,
    using the left-shift passed from map-scroll )
  
  ( manage runs )
  #00 SWP &loop EQUk ,&done JCN
    .row1/run LDZ ;check-run JSR2 #00 ,&row1-set JCN
      .row1 ;invert-run JSR2
      &row1-set .row1 ;set-tile JSR2
    .row2/run LDZ ;check-run JSR2 #00 ,&row2-set JCN
      .row2 ;invert-run
      &row2-set .row2 ;set-tile JSR2
    .row3/run LDZ ;check-run #00 ,&row3-set JCN
      .row3 ;invert-run JSR2
      &row3-set .row3 ;set-tile JSR2
  #01 SUB ,&loop JMP &done POP2
  
RTN

@map-scroll ( -> )

  ( add dx to tile-offset )
  .blader/dx LDZ .map/tile-offset LDZ ADD
  DUP .map/tile-offset STZ

  ( left-shift = tile-offset/8 )
  DUP #03 SFT ,&left-shift STR

  ( tile-offset = tile-offset mod 8 )
  #08 MOD
  .map/tile-offset STZ
  
  ( move map edge pointer )
  ,&left-shift LDR .map/edge LDZ ADD

  DUP LTH #40 ,&no-overflow JCN
    #40 SUB 
  &no-overflow
  
  .map/edge STZ
  
  ( generate left-shift new map tiles on right edge for each row )
  ,&left-shift LDR ;map-gen JSR2
  
RTN

&left-shift $1

@single-play
  ;map-scroll JSR2
RTN

@main-loop ( -> )

  ;clear-screen JSR2

  .state LDZ

  DUP #00 NEQ ,&no-press-start JCN
    ;press-start-screen JSR2
    POP BRK
  &no-press-start
  DUP #02 GTH ,&no-menu JCN
    ;mode-select-screen JSR2
    POP BRK
  &no-menu
  DUP #1f GTH ,&no-realm-menu JCN
    POP BRK
  &no-realm-menu
  DUP #2f GTH ,&no-realm-create JCN
    POP BRK
  &no-realm-create 
  DUP #3f GTH ,&no-realm-select JCN
    POP BRK
  &no-realm-select
  DUP #4f GTH ,&no-single-play JCN
    ;single-play JSR2
    POP BRK
  &no-single-play
  DUP #5f GTH ,&no-multi-play JCN
    POP BRK
  &no-multi-play
  POP

BRK

@draw-string ( addr x y color -- )
	
	STH ( save color )
	.Screen/y DEO2 ( set y )
	.Screen/x DEO2 ( set x )

  ( now the string address is at the top of the stack )
  &loop
    LDAk DUP #00 NEQ #20 MUL SUB TOS 8** ;font ADD2 .Screen/addr DEO2 
    STHkr .Screen/sprite DEO
    INC-X
    INC2
    LDAk #00 NEQ ,&loop JCN
  POP2
  POPr

RTN

@strlen ( addr -- len )

  DUP2
  &loop
    INC2 LDAk ,&loop JCN
  SWP2 SUB2
  
RTN

( random )

@prng-init ( -- )

  ( seed )
  #00 .DateTime/second DEI
  #00 .DateTime/minute DEI #60 SFT2 EOR2
  #00 .DateTime/hour   DEI #c0 SFT2 EOR2 ,prng/x STR2
  #00 .DateTime/hour   DEI #04 SFT2
  #00 .DateTime/day    DEI #10 SFT2 EOR2
  #00 .DateTime/month  DEI #60 SFT2 EOR2
      .DateTime/year  DEI2 #a0 SFT2 EOR2 ,prng/y STR2

RTN

@prng ( -- number* )

  LIT2 &x $2
  DUP2 #50 SFT2 EOR2
  DUP2 #03 SFT2 EOR2
  LIT2 &y $2 DUP2 ,&x STR2
  DUP2 #01 SFT2 EOR2 EOR2
  ,&y STR2k POP

RTN

@print-hex ( value -- )
	
	STHk #04 SFT ,&parse JSR .Console/write DEO
	STHr #0f AND ,&parse JSR .Console/write DEO
	RTN
	&parse ( value -- char )
		DUP #09 GTH ,&above JCN #30 ADD RTN &above #09 SUB #60 ADD RTN

RTN

@blank [ 0000 0000 0000 0000 ]

@buffer $10

( string constants )
@txt-press-start "Press 20 "Start 00
@txt-1p "Single 20 "Player 00
@txt-2p "Network 20 "Play 00

( file path string constants )
@file-xrxs-version "n/version 00
@file-chr-title "title.chr 00

( sprites )
@arrow [ 1018 1c1e 1c18 1000 ]
@cursor [ 80c0 e0f0 f8e0 1000 ]

@font [
  00 00 00 00 00 00 00 00 00 18 18 18 08 00 08 00    00 14 14 00 00 00 00 00 00 24 7e 24 24 7e 24 00 
  00 10 3c 50 38 14 78 10 00 00 44 08 10 20 44 00    00 18 20 32 2c 24 1a 00 00 18 10 20 00 00 00 00 
  00 04 08 08 08 08 04 00 00 20 10 10 10 10 20 00    00 00 44 28 10 28 44 00 00 00 10 10 7c 10 10 00 
  00 00 00 00 00 0c 08 10 00 00 00 00 3e 00 00 00    00 00 00 00 00 0c 0c 00 00 02 04 08 10 20 40 00 
  00 38 44 54 54 44 38 00 00 30 10 10 10 10 38 00    00 38 44 04 38 40 7c 00 00 38 44 18 04 44 38 00 
  00 08 18 28 48 7c 08 00 00 7c 40 78 04 44 38 00    00 38 40 78 44 44 38 00 00 7c 04 08 10 10 10 00 
  00 38 44 38 44 44 38 00 00 38 44 44 3c 04 38 00    00 18 18 00 00 18 18 00 00 18 18 00 00 18 10 20 
  00 00 08 10 20 10 08 00 00 00 00 3e 00 3e 00 00    00 00 10 08 04 08 10 00 00 38 44 1c 10 00 10 00 
  00 38 44 5c 58 40 3c 00 00 10 28 44 7c 44 44 00    00 78 44 78 44 44 78 00 00 38 44 40 40 44 38 00 
  00 78 44 44 44 44 78 00 00 7c 40 7c 40 40 7c 00    00 7c 40 7c 40 40 40 00 00 38 44 40 4c 44 3c 00 
  00 44 44 7c 44 44 44 00 00 7c 10 10 10 10 7c 00    00 7c 08 08 48 48 30 00 00 44 48 70 48 44 44 00 
  00 40 40 40 40 40 7c 00 00 44 6c 7c 54 44 44 00    00 44 64 74 5c 4c 44 00 00 38 44 44 44 44 38 00 
  00 78 44 44 78 40 40 00 00 38 44 44 4c 4c 3e 00    00 78 44 44 78 44 44 00 00 3c 40 38 04 04 78 00 
  00 7c 10 10 10 10 10 00 00 44 44 44 44 44 3c 00    00 44 44 28 28 10 10 00 00 44 44 44 54 6c 44 00 
  00 44 44 38 38 44 44 00 00 44 44 28 10 10 10 00    00 7c 04 18 30 40 7c 00 00 3c 30 30 30 30 3c 00 
  00 40 20 10 08 04 02 00 00 3c 0c 0c 0c 0c 3c 00    00 10 38 6c 00 00 00 00 00 00 00 00 00 00 7e 00 
  00 18 08 04 00 00 00 00 00 00 38 04 3c 44 3c 00    00 40 40 78 44 44 78 00 00 00 38 44 40 44 38 00 
  00 04 04 3c 44 44 3c 00 00 00 38 44 7c 40 3c 00    00 1c 20 78 20 20 20 00 00 00 3c 44 3c 04 44 38 
  00 40 40 78 44 44 44 00 00 30 00 70 10 10 18 00    00 0c 00 3c 04 04 44 38 00 00 44 48 70 48 44 00 
  00 70 10 10 10 10 1c 00 00 00 44 6c 7c 54 44 00    00 00 78 44 44 44 44 00 00 00 38 44 44 44 38 00 
  00 00 78 44 44 78 40 40 00 00 3c 44 44 3d 06 04    00 00 4c 50 60 40 40 00 00 00 3c 40 38 04 78 00 
  00 20 78 20 20 24 38 00 00 00 44 44 44 44 3c 00    00 00 44 44 28 28 10 00 00 00 44 44 54 7c 28 00 
  00 00 44 28 10 28 44 00 00 00 44 44 3c 04 78 00    00 00 7c 04 38 40 7c 00 00 1e 10 10 10 00 00 00 
  00 10 10 10 10 10 10 00 00 00 00 08 08 08 78 00    00 00 00 32 4c 00 00 00 3c 42 99 a1 a1 99 42 3c 
]

@rail-start [ 0000 0000 0f10 0000 0000 000f 1f3f 3c38
              0000 0000 0000 0000 3838 3838 3838 0000 ]
@rail-mid   [ 0000 0000 ff00 0000 0000 00ff ffff 0000
              0000 0000 0000 0000 0000 0000 0000 0000 ]
@rail-end   [ 0000 0000 f000 0000 0000 00f0 f8f8 3c1c
              0000 0000 0000 0000 1c1c 1c1c 1c1c 1c00 ]

@blader-placeholder
            [ ffff ffff ffff 0000 0000 0705 0507 ffff
              ffff ffff ffff 0000 0000 e0a0 e0a0 ffff
              00e0 e0e0 e0ff ffff ffff ffff ff00 0000
              0007 0707 07ff ffff ffff ffff ff00 0000
              ffff ffff ff93 93ff 0000 0000 006c 6c00
              ffff ffff ffc9 c9ff 0000 0000 0036 3600 ]

@titlescreen $bc00