-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathjetpac.ctl
3141 lines (3141 loc) · 134 KB
/
jetpac.ctl
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
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
> $5CCB ; SkoolKit disassembly for JETPAC (cartridge)
> $5CCB ; (https://github.com/mrcook/jetpac-disassembly)
> $5CCB ;
> $5CCB ; Copyright (c) 2020 Michael R. Cook (this disassembly)
> $5CCB ; Copyright (c) 1983 Ultimate Play the Game (JETPAC)
> $5CCB ; JETPAC was designed and developed by Tim Stamper and Chris Stamper
> $5CCB @start=$6000
> $5CCB
> $5CCB ; Frame counter.
> $5CCB ;
> $5CCB ; These lower two bytes of frame counter are incremented every 20 ms.
> $5CCB @equ=SYSVAR_FRAMES=$5c78
@ $5CCB org
s $5CCB Stack: 37 bytes of memory allocated for use as the system stack.
@ $5CCB label=stack_memory
S $5CCB,37,$25
b $5CF0 High score for current game session.
D $5CF0 A 3-byte decimal representation of the score. Maximum value is 999999.
@ $5CF0 label=hi_score
S $5CF0,3,$03
b $5CF3 Game options.
D $5CF3 #TABLE(default,centre,:w) { =h Bits(n) | =h Option } { 0 | Players (reset=1, set=2) } { 1 | Input Type (reset=Keyboard, set=Joystick) } TABLE#
@ $5CF3 label=game_options
B $5CF3,1,1
b $5CF4 Player one score.
D $5CF4 A 3-byte decimal representation of the score. Maximum value is 999999.
@ $5CF4 label=p1_score
S $5CF4,3,$03
b $5CF7 Player two score.
D $5CF7 A 3-byte decimal representation of the score. Maximum value is 999999.
@ $5CF7 label=p2_score
S $5CF7,3,$03
s $5CFA Padding to make block from hi_score to here 16 bytes in length.
S $5CFA,6,$06
b $5D00 Jetman direction.
D $5D00 Indicates the direction that Jetman is travelling/facing. #TABLE(default,centre,:w) { =h Byte | =h Bits | =h Direction } { 82 | 10000010 | WALK RIGHT } { C2 | 11000010 | WALK LEFT } { 01 | 00000001 | FLY UP RIGHT (default) } { 41 | 01000001 | FLY UP LEFT } { 81 | 10000001 | FLY DOWN RIGHT } { C1 | 11000001 | FLY DOWN LEFT } TABLE#
@ $5D00 label=jetman_direction
B $5D00,1,1
b $5D01 Jetman X position.
D $5D01 Default start position is $80.
@ $5D01 label=jetman_pos_x
B $5D01,1,1
b $5D02 Jetman Y position.
D $5D02 Default start position is $B7.
@ $5D02 label=jetman_pos_y
B $5D02,1,1
b $5D03 Jetman sprite colour attribute.
D $5D03 Initialised to $47 on new player.
@ $5D03 label=jetman_colour
B $5D03,1,1
b $5D04 Jetman moving direction.
D $5D04 Indicates the direction in which Jetman is moving. #TABLE(default,centre,:w) { =h Bits(n) | =h Direction } { 6 | 0=right, 1=left } { 7 | 0=up/standing still, 1=down } { 1 | ? } { 0 | 0=horizontal, 1=vertical } TABLE#
@ $5D04 label=jetman_moving
B $5D04,1,1
b $5D05 Jetman Speed: Horizontal.
D $5D05 Max Walking: $20. Max Flying: $40.
@ $5D05 label=jetman_speed_x
B $5D05,1,1
b $5D06 Jetman Speed: Vertical.
D $5D06 Max: $3F.
@ $5D06 label=jetman_speed_y
B $5D06,1,1
b $5D07 Jetman sprite height, which is always $24, as set by the defaults.
@ $5D07 label=jetman_height
B $5D07,1,1
b $5D08 Laser beams
D $5D08 #TABLE(default,centre,:w) { =h Bytes(n) | =h Variable } { 0 | Unused=$00, Used=$10 } { 1 | Y Position } { 2 | X position pulse #1 } { 3 | X position pulse #2 } { 4 | X position pulse #3 } { 5 | X position pulse #4 } { 6 | Beam length } { 7 | Colour attribute } TABLE#
@ $5D08 label=laser_beam_params
B $5D08,8,8 laser beam #1
B $5D10,8,8 laser beam #2
B $5D18,8,8 laser beam #3
B $5D20,8,8 laser beam #4
b $5D28 Sound type parameters for explosions.
D $5D28 Byte 1=Frequency, byte 2=Duration.
@ $5D28 label=explosion_sfx_params
B $5D28,1,1 Frequency is $0C or $0D
B $5D29,1,1 Length is always set to $04
b $5D2A Explosion params padding, making 8 bytes total. Unused.
S $5D2A,6,$06
b $5D30 Rocket object attributes.
D $5D30 #TABLE(default,centre,:w) { =h Bytes(n) | =h Variable } { 0 | Movement: $09=on pad, $0A=up, $0B=down } { 1 | X Position (pixels) } { 2 | Y Position (pixels) (base module) } { 3 | Colour Attribute } { 4 | Modules on Pad: $01 (new level default) to $03 } { 5 | Fuel Pods collected: 0-6 } { 6 | Unused } { 7 | Always $1C } TABLE#
@ $5D30 label=rocket_state
B $5D30,8,8
b $5D38 Rocket module state (fuel/part).
D $5D38 NOTE: Used for top module at level start, then only fuel pods. #TABLE(default,centre,:w) { =h Bytes(n) | =h Variable } { 0 | Type: $00=Unused, $04=Ship/Fuel Pod } { 1 | X Position (pixels) } { 2 | Y Position (pixels) } { 3 | Colour Attribute } { 4 | State: 1=new, 3=collected, 5=free-fall, 7=dropped } { 5 | Unused } { 6 | Sprite jump table offset } { 7 | Sprite Height } TABLE#
@ $5D38 label=rocket_module_state
B $5D38,8,8
b $5D40 Current Collectible object.
D $5D40 Used for the middle ship module at level start, then only collectibles. The "state" field is not used for collectibles (remains $00). #TABLE(default,centre,:w) { =h Bytes(n) | =h Variable } { 0 | Type: $00=Unused, $04=Rocket, $0E=Collectible } { 1 | X Position (pixels) } { 2 | Y Position (pixels) } { 3 | Colour Attribute } { 4 | State: 1=new, 3=collected, 5=free-fall, 7=dropped } { 5 | Unused } { 6 | Sprite jump table offset } { 7 | Sprite Height } TABLE#
@ $5D40 label=item_state
B $5D40,8,8
b $5D48 Thruster/Explosion animation sprite state.
D $5D48 Holds the sprite state for the current animation frame being displayed for Jetman's jetpac thruster "smoke". Note: each animation loop uses a (random) two colour pair from the 4 possible colours. #TABLE(default,centre,:w) { =h Bytes(n) | =h Variable } { 0 | Animating: 00=no, 03=anim done, 08=animating } { 1 | Last Jetman X location } { 2 | Last Jetman Y location } { 3 | Colour: Red, Magenta, Yellow, White } { 4 | Frame: 0-7 } { 5 | Unused } { 6 | Unknown (set to $03 on first use) } { 7 | Unused } TABLE#
@ $5D48 label=jetman_thruster_anim_state
B $5D48,8,8
b $5D50 Alien state objects.
D $5D50 There are a maximum of 6 aliens on the screen at one time, and those states are stored here in this data block. See Jetman object for more details. #TABLE(default,centre,:w) { =h Bytes(n) | =h Variable } { 00 | Direction } { 01 | X location (pixels) } { 02 | Y location (pixels) } { 03 | Colour attribute } { 04 | Moving direction } { 05 | X Speed (default: $04) } { 06 | Y Speed } { 07 | Sprite Height } TABLE#
@ $5D50 label=alien_states
B $5D50,8,8 slot #1
B $5D58,8,8 slot #2
B $5D60,8,8 slot #3
B $5D68,8,8 slot #4
B $5D70,8,8 slot #5
B $5D78,8,8 slot #6
b $5D80 Jetman exploding animation object.
D $5D80 Holds the sprite state for the current animation frame being displayed for the explosion sprite when Jetman is killed. Note: each animation loop uses a (random) two colour pair from the 4 possible colours. #TABLE(default,centre,:w) { =h Bytes(n) | =h Variable } { 0 | Animating: 00=no, 08=yes } { 1 | Jetman X location (pixels) } { 2 | Jetman Y location (pixels) } { 3 | Colour: Red, Magenta, Yellow, White } { 4 | Frame: 0-7 } { 5 | State (set=animating) } { 6 | Jetman direction } { 7 | Unused } TABLE#
@ $5D80 label=jetman_exploding_anim_state
B $5D80,8,8
b $5D88 Jetman object backup for the inactive player.
@ $5D88 label=inactive_jetman_state
B $5D88,8,8
@ $5D90 defs=$5D90:$08,$00
s $5D90 Unused padding.
S $5D90,8,$08
b $5D98 Rocket/collectible object backup for the inactive player.
@ $5D98 label=inactive_rocket_state
B $5D98,8,8 Rocket object
B $5DA0,8,8 Rocket module (fuel/part)
B $5DA8,8,8 Collectible/Rocket middle
@ $5DB0 defs=$5DB0:$06,$00
s $5DB0 Unused padding.
S $5DB0,8,$08
@ $5DB8 defs=$5DB8:$06,$00
s $5DB8 Unused padding.
S $5DB8,8,$08
b $5DC0 Temporary actor state.
D $5DC0 Many actor routines use this to hold state temporarily during updates. #TABLE(default,centre,:w) { =h Bytes(n) | =h Variable } { 0 | X location } { 1 | Y location } { 2 | Movement direction } { 3 | Height (pixels) } { 4 | Width (tiles) } { 5 | Current sprite height value (?) } { 6 | Sprite GFX data height value (?) } { 7 | Unknown flying movement/direction (used only for Jetman?) } TABLE#
@ $5DC0 label=actor
B $5DC0,8,8
b $5DC8 Value only changes while Jetman is moving up/down - has no obvious pattern.
@ $5DC8 label=jetman_fly_counter
B $5DC8,1,1
b $5DC9 Alien direction update flag for: Squidgy, UFO, Sphere, Crossed Ship.
D $5DC9 Each alien update routine first resets the value, then after the first check, increments the value, which triggers the draw alien routine.
@ $5DC9 label=alien_new_dir_flag
B $5DC9,1,1
b $5DCA Jetman speed modifier.
D $5DCA Initialised to $04 by initialise game routine, otherwise value is $00 during game play.
@ $5DCA label=jetman_speed_modifier
B $5DCA,1,1
b $5DCB Current alien ID being updated?
D $5DCB Values are $00 (no alien update?) up to the max number of aliens: $01 to $06. Used by all alien update routines and in a few other places.
@ $5DCB label=current_alien_number
B $5DCB,1,1
w $5DCC Game timer.
D $5DCC 16-bit counter starting at 0x0000 and counting +1 (each time a sprite is moved or redrawn?), although sometimes it will increment +2. This continues until the whole game is over - for both 1 and 2 player games. Counter loops around after reaching 0xFFFF.
@ $5DCC label=game_timer
W $5DCC,2,2
b $5DCE Random Number.
D $5DCE Value is calculated using the 16-bit game timer LSB value, which is used to fetch a byte from the ROM (between addresses $00 and $FF), then by adding the current #REGr.
@ $5DCE label=random_number
B $5DCE,1,1
b $5DCF Temporary actor coordinates.
D $5DCF Coordinates (Y,X) used when colouring a sprite. Set by the Actor, along with being inc/decremented during the Rocket launch/land phase.
@ $5DCF label=actor_coords
B $5DCF,1,1 Y location (pixels)
B $5DD0,1,1 X location (pixels)
b $5DD1 Current active player.
D $5DD1 $00=player #1, $FF=player #2.
@ $5DD1 label=current_player_number
B $5DD1,1,1
b $5DD2 Jetman Rocket module attached success.
D $5DD2 Set to $01 at the start of each new life/level. When one of the two modules becomes attached to the Rocket (top or middle, but not fuel) then this is changed to $00.
@ $5DD2 label=jetman_rocket_mod_connected
B $5DD2,1,1
b $5DD3 Rocket modules attached.
D $5DD3 Set to $04 at the start of each new level. When one of the two modules becomes attached to the Rocket (top or middle, but not fuel) then this is changed to $02.
@ $5DD3 label=rocket_mod_attached
B $5DD3,1,1
b $5DD4 Holds a copy of the last SYSVAR_FRAMES counter.
@ $5DD4 label=last_frame
B $5DD4,1,1
b $5DD5 Has a frame ticked over.
D $5DD5 $00=no, $01=yes.
@ $5DD5 label=frame_ticked
B $5DD5,1,1
b $5DD6 Current menu item colour attribute.
@ $5DD6 label=current_colour_attr
B $5DD6,1,1
b $5DD7 "Get Ready" delay timer.
D $5DD7 At the beginning of each player turn there is a delay to allow the player to be ready for play. Values are $80 for a 1 player game, $FF for a two player game. The larger delay is useful for swapping players controls.
@ $5DD7 label=begin_play_delay_counter
B $5DD7,1,1
@ $5DD8 defs=$5DD8:$06,$00
s $5DD8 Unused padding.
S $5DD8,24,$18
b $5DF0 Game level for current player.
D $5DF0 Level #1 starts at $00.
@ $5DF0 label=player_level
B $5DF0,1,1
b $5DF1 Current player lives remaining.
@ $5DF1 label=player_lives
B $5DF1,1,1
@ $5DF2 defs=$5DF2:$08,$00
s $5DF2 Unused padding for player level/lives object (8 bytes total).
S $5DF2,6,$06
b $5DF8 Game level for inactive player.
D $5DF8 Level #1 starts at $00.
@ $5DF8 label=inactive_player_level
B $5DF8,1,1
b $5DF9 Inactive player lives remaining.
@ $5DF9 label=inactive_player_lives
B $5DF9,1,1
@ $5DFA defs=$5DFA:$08,$00
s $5DFA Unused padding for inactive player level/lives object (8 bytes total).
S $5DFA,6,$06
b $5E00 Buffers for Alien sprites.
D $5E00 4 buffers representing left/right facing aliens, with 2 animation frames each. #TABLE(default,centre,:w) { =h Bytes(n) | =h Meaning } { $00 | Header byte - always NULL? } { $01 | Width value - always $03 } { $02 | Height value } { $03-$33 | Pixel data } TABLE#
@ $5E00 label=buffers_aliens_R1
S $5E00,51,$33 right facing, anim frame 1
@ $5E33 label=buffers_aliens_R2
S $5E33,51,$33 right facing, anim frame 2
@ $5E66 label=buffers_aliens_L1
S $5E66,51,$33 left facing, anim frame 1
@ $5E99 label=buffers_aliens_L2
S $5E99,51,$33 left facing, anim frame 2
b $5ECC Buffers for Collectible/Rocket sprites.
D $5ECC Buffer to hold 4 item sprites. #TABLE(default,centre,:w) { =h Bytes(n) | =h Meaning } { $00 | Header byte } { $01 | Width value - always $03? } { $02 | Height value } { $03-$33 | Pixel data } TABLE#
@ $5ECC label=buffers_item_1
S $5ECC,51,$33 sprite 1
@ $5EFF label=buffers_item_2
S $5EFF,51,$33 sprite 2
@ $5F32 label=buffers_item_3
S $5F32,51,$33 sprite 3
@ $5F65 label=buffers_item_4
S $5F65,51,$33 sprite 4
@ $5F98 defs=$5F98:$68,$00
s $5F98 Unused padding.
S $5F98,104,$68
c $6000 #REGpc starts here, after game load.
@ $6000 label=EntryPoint
b $6003 Platform GFX location and size.
D $6003 #TABLE(default,centre,:w) { =h Bytes(n) | =h Variable } { 1 | Colour Attribute } { 2 | X location (pixels) } { 3 | Y location (pixels) } { 4 | Width } TABLE#
@ $6003 label=gfx_params_platforms
B $6003,4,4 Middle
B $6007,4,4 Bottom
B $600B,4,4 Left
B $600F,4,4 Right
b $6013 Default player object state.
@ $6013 label=default_player_state
B $6013,8,8
b $601B Default Rocket and module objects state.
@ $601B label=default_rocket_state
B $601B,8,8 Rocket state
B $6023,8,8 Top module state
B $602B,8,8 Middle module state
b $6033 Default Rocket module state is a Fuel Pod.
@ $6033 label=default_rocket_module_state
B $6033,8,8
b $603B Default collectible item state.
@ $603B label=default_item_state
B $603B,8,8
b $6043 Main menu copyright message.
@ $6043 label=menu_copyright
B $6043,1,1 Text colour attribute
B $6044,1,1 Font code for © symbol
T $6045,30,30
B $6063,1,1 ASCII "D" & $80 (EOL)
c $6064 Reset the screen to its default state.
D $6064 Used by the routines at #R$6094, #R$60b7 and #R$61c9.
@ $6064 label=ResetScreen
C $6065,2 Set screen border to black
C $6067,3 Clear the screen
C $606A,3 Reset the screen colours
C $606D,3 Display score labels
N $6070 Display score labels text at the top of the screen.
C $6070,3 #REGhl=attribute file location
C $6073,3 #REGb=tile count, and #REGc=yellow colour
C $6076,4 Now set the tile colours
C $607A,3 Update display with player 1 score
C $607D,3 Update display with player 2 score
C $6080,3 Update display with high score
c $6083 Initialises a new level.
D $6083 A new Rocket is generated every 4 levels, otherwise it's a normal fuel collecting level. Used by the routines at #R$62fe and #R$6690.
@ $6083 label=LevelNew
C $6083,5 Check if player level is a MOD of 4?
C $6088,2 If not, initialise the level normally
N $608A Initialisation for a new rocket level.
C $608A,3 Reset all rocket modules with defaults
C $608D,4 Jetman has boarded the rocket; increment lives count. Used for display purposes only
C $6091,3 Initialise the player for the next level
c $6094 Initialise the level.
D $6094 Used by the routines at #R$6083 and #R$60b7.
@ $6094 label=LevelInit
C $6094,3 Initialise alien buffers
C $6097,3 Initialise the screen
C $609A,3 Draw the platforms
C $609D,3 Display all player lives
C $60A0,6 Set last_frame to current SYSVAR_FRAMES
c $60A7 Reset all rocket module states to their defaults.
D $60A7 Set object data to their defaults and copy to buffers. Used by the routines at #R$6083 and #R$62da.
@ $60A7 label=RocketReset
C $60A7,3 #REGhl=default rocket data
C $60AA,3 #REGde=start of rocket structs
C $60AD,3 24 bytes of rocket data to copy
C $60B4,3 Copy sprite data to the buffers.
c $60B7 End of turn for the current player.
D $60B7 Resets level states/buffers, and checks if it's game over for a player. Used by the routine at #R$687a.
@ $60B7 label=PlayerTurnEnds
C $60B7,3 #REGhl=Jetman thruster animation object
C $60BA,5 Reset all object states to be inactive
@ $60BF ssub=ld hl,$5d38+$04 ; #REGhl=Rocket module "state" field
C $60C2,2 Set to unused state
@ $60C4 ssub=ld hl,$5d40+$04 ; #REGhl=Collectible item "state" field
C $60C7,2 Set to unused state
N $60C9 Check if current and inactive player has lives, if not it is game over.
C $60C9,3 Game Options
C $60CE,2 Jump if two player
C $60D0,3 Current player lives
C $60D4,3 Game over if no lives remaining
C $60D7,3 Initialise a new level
C $60DA,3 Initialise next player
C $60DD,3 Inactive player lives
C $60E1,2 Game over if no lives remaining
C $60E3,3 Current player lives
C $60E7,3 Game over if no lives remaining
C $60EA,3 Switch players
C $60ED,7 Change current player (flip bits between $00 and $FF)
N $60F4 Switch rocket objects data for this new player
@ $60F4 ssub=ld a,($5d30+$04) ; Rocket module "state" field
C $60F7,5 Calculate the offset
C $60FC,3 Copy rocket sprite to buffer
C $60FF,3 Initialise level
C $6102,3 Initialise player
N $6105 Display the GAME OVER message for a player.
C $6105,2 ASCII character for the number "1" + EOL bit
@ $6107 ssub=ld ($6161+$12),a ; Append the number to game over text
C $610A,3 Initialise level screen
C $610D,3 Game Over message
@ $6110 keep
C $6110,3 Y,X coords in the display file
C $6113,3 Draw text to the screen
N $6116 After displaying the text, pause for a while.
N $6123 Handle message for player #2.
C $6123,2 ASCII character for the number "2" + EOL bit
C $6125,2 Append the number to the text, the display it
N $6127 Choose which player to show Game Over message for.
C $6127,6 Jump if current player is #1
C $612D,2 else, player is #2.
N $612F Game Over: update scores, show game over message, and initialise system.
C $612F,3 Update the high score
C $6132,6 Jump if current player is #2
C $6138,3 Display game over for player #1
C $613B,3 Reset the game
C $613E,3 Display game over for player #2
C $6141,3 Reset the game
c $6144 Swap current/inactive player/rocket states.
D $6144 Used by the routines at #R$60b7 and #R$62da.
@ $6144 label=PlayersSwap
C $6144,3 Current player level/lives
C $6147,3 Inactive player level/lives
C $614C,3 Swap 2 bytes
N $614F Now swap the current/inactive rocket states.
C $614F,3 Current player rocker state
C $6152,3 Inactive player rocker state
C $6155,2 We will be swapping 24 bytes
N $6157 Sub-routine for swapping HL/DE bytes.
b $6161 Text for game over message.
@ $6161 label=game_over_text
B $6161,1,1 Colour attribute
T $6162,17,17
B $6173,1,1 Player # (ASCII $31/$32) + $80 (EOL)
c $6174 Initialise player for new turn.
D $6174 Player has died, or started a new level, so Jetman object should be updated with default values. Used by the routines at #R$6083, #R$60b7 and #R$66b4.
@ $6174 label=PlayerInit
C $6174,3 Default Jetman values
C $6177,3 Jetman object
N $617F Set default "begin play" delay period.
C $617F,2 1 player delay
C $6181,3 Game options
C $6186,2 Jump if one player game
C $6188,2 else, double delay for 2 player game
C $618A,3 Update delay: 1 Player=$80, 2 Player=$FF
N $618D Decrement current player lives and update display.
C $618D,3 Current player lives
C $6194,3 Display player lives
c $6197 Flash 1UP or 2UP score label for active player.
D $6197 Used by the routine at #R$737d.
@ $6197 label=ScoreLabelFlash
C $6197,3 Current player number
C $619B,2 If player #2, flash 2UP text
C $619D,3 else #REGhl=1UP column position in attr file
c $61A0 Set flash state for the 3-attributes of the score label.
D $61A0 Used by the routine at #R$61ba.
R $61A0 Input:HL screen coordinate.
@ $61A0 label=FlashText
C $61A0,3 #REGhl=coord to attribute file address (using #REGhl)
C $61A3,2 Loop counter for 3 characters
C $61A5,7 Set FLASH on for each attribute
c $61AD Turn off flashing of 1UP or 2UP score label for active player.
D $61AD Used by the routine at #R$737d.
R $61AD Input:HL screen coordinate.
@ $61AD label=ScoreLabelUnflash
C $61AD,3 #REGhl=coord to attribute file address (using #REGhl)
C $61B0,2 Loop counter for 3 characters
C $61B2,7 Set FLASH=off on for each attribute
c $61BA Flash 2UP score label.
D $61BA Used by the routine at #R$6197.
@ $61BA label=FlashScoreLabel2UP
C $61BA,3 2UP column position in attribute file
c $61BF Game initialisation for first run.
D $61BF Reset all scores, sets the SP, initialises the screen, and displays the main menu. Used by the routine at #R$6000.
@ $61BF label=StartGame
C $61BF,10 Reset all scores
c $61C9 Reset system and show menu screen.
D $61C9 Used by the routine at #R$60b7.
@ $61C9 label=ResetGame
C $61C9,1 Interrupts are disabled for the core engine code
@ $61CA ssub=ld sp,$5ccb+$25 ; Set the stack pointer
C $61CD,3 Reset the screen
C $61D2,3 Reset Speed modifier to its default
c $61D5 Show menu screen and handle menu selection.
@ $61D5 label=MenuScreen
C $61D5,3 Draw the menu entries
C $61D8,4 #REGd=Game options
N $61DC Read the keyboard and perform menu selection.
C $61DC,2 Row: 1,2,3,4,5
C $61DE,2 Set port for reading keyboard
C $61E0,2 ...and read that row of keys
C $61E2,1 Flip bits so a `1` means a key is pressed.
C $61E3,2 Key #1 pressed? ("1 PLAYER GAME")
C $61E5,2 No key pressed? Jump
C $61E7,2 else, Player count = 1
C $61E9,2 Key #2 pressed? ("2 PLAYER GAME")
C $61EB,2 No key pressed? Jump
C $61ED,2 else, Player count = 2
C $61EF,2 Key #3 pressed? ("KEYBOARD")
C $61F1,2 No key pressed? Jump
C $61F3,2 else, Input type = keyboard
C $61F5,2 Key #4 pressed? ("JOYSTICK")
C $61F7,2 No key pressed? Jump
C $61F9,2 else, Input type = joystick
C $61FB,5 Key #5 pressed? ("START GAME")
C $6200,4 Update the Game options
N $6204 Update flashing state of the menu items.
@ $6204 ssub=ld hl,$6261+$01
C $6204,3 Point #REGhl to main menu colour attributes list.
C $6207,4 #REGc=Game options
C $620B,4 Jump if player count = 2
C $620F,3 Set flashing state for a one player game
C $6212,4 Jump if input type = joystick
C $6216,3 Set flashing state for keyboard input
C $6219,3 Loop and process again main menu input
C $621C,3 Set flashing state for a two player game
C $621F,2 Check input type
C $6221,3 Set flashing state for joystick input
C $6224,2 Loop and process again menu selection
N $6226 Set flashing state for "1 PLAYER GAME" and "KEYBOARD" menu items.
N $622D Set "2 PLAYER GAME" and "JOYSTICK" menu items flashing.
c $6234 Display the main menu items to the screen.
D $6234 Used by the routine at #R$61d5.
@ $6234 label=MenuDrawEntries
C $6234,3 Point #REGde to main menu colour attributes
C $6238,3 #REGhl'=Y (y-position of the menu item)
C $623B,3 #REGde'=to the beginning of the menu strings
C $623E,2 #REGb'=loop counter for the 6 colour attribute bytes
N $6240 Flip-flop between normal/shadow registers: meaning one time we hit this EXX we are using the shadow registers, the next the normal registers.
C $6241,1 #REGa=current colour attribute
C $6242,3 Store menu colour attribute
C $624C,2 #REGl'=indentation
C $624E,3 Write line of text to screen
C $6255,2 Duel purpose loop: both colour attrs and menu items
@ $6257 keep
C $6257,3 Note: address is past 7FFF limit of 16K ZX Spectrum
C $625A,3 Point #REGde to the copyright string
C $625D,3 Now display the copyright message
b $6261 Colour attributes for main menu.
D $6261 #TABLE(default,centre,:w) { =h Bytes(n) | =h Menu Item } { 1 | Jetpac Game Selection } { 2 | 1 Player Game } { 3 | 2 Player Game } { 4 | Keyboard } { 5 | Joystick } { 6 | Start Game } TABLE#
@ $6261 label=menu_colour_table
B $6261,6,6
b $6267 Vertical position of each line of text in the main menu.
D $6267 #TABLE(default,centre,:w) { =h Byte(n) | =h Menu Item } { 1 | Jetpac Game Selection } { 2 | 1 Player Game } { 3 | 2 Player Game } { 4 | Keyboard } { 5 | Joystick } { 6 | Start Game } TABLE#
@ $6267 label=menu_position_table
B $6267,6,6
t $626D Text displayed on the main menu screen
@ $626D label=menu_text
T $626D,20,20
B $6281,1,1 ASCII "N" & $80 (EOL)
T $6282,16,16
B $6292,1,1 ASCII "E" & $80 (EOL)
T $6293,16,16
B $62A3,1,1 ASCII "E" & $80 (EOL)
T $62A4,11,11
B $62AF,1,1 ASCII "D" & $80 (EOL)
T $62B0,11,11
B $62BB,1,1 ASCII "K" & $80 (EOL)
T $62BC,13,13
B $62C9,1,1 ASCII "E" & $80 (EOL)
c $62CA Write a single line of text on the main menu screen.
D $62CA Used by the routine at #R$6234.
R $62CA Input:HL Coordinate on the screen to display the string.
@ $62CA label=MenuWriteText
C $62CA,1 Backup coordinate
C $62CB,3 #REGhl=coord to screen address (using #REGhl)
C $62CE,3 Current colour attribute
C $62D3,1 Restore coordinate
C $62D4,3 #REGhl=coord to attribute file address (using #REGhl)
C $62D7,3 Display text string at #REGhl, using #REGa' colour
c $62DA Reset current and inactive player data on new game.
D $62DA Used by the routine at #R$62fe.
@ $62DA label=ResetPlayerData
C $62DA,2 Loop counter: current then inactive player
C $62DE,3 Reset player level
C $62E3,3 First player has 4 "remaining" lives
C $62E6,3 Reset the rocket modules
C $62E9,3 Swap player game states
C $62ED,2 Repeat again for inactive player
C $62EF,5 But now update inactive player to have 5 "remaining" lives, not 4
C $62F4,3 Game options
C $62F9,1 Return if two player game
C $62FA,3 else one player game, so inactive player has no lives
c $62FE Start a new game.
D $62FE Resets all player, alien, and level data, then start a new game. Used by the routine at #R$61d5.
@ $62FE label=NewGame
C $62FE,3 Starting at the Player 1 score
@ $6301 nowarn
@ $6301 keep
C $6301,3 #REGb = counter, #REGc = fill byte
C $6304,3 Clear memory, with null byte
C $6307,3 Reset the player data
C $630A,3 Reset the self-modifying code
C $630D,3 Initialise a new level
c $6310 Reset stack pointer and enable interrupts before running main loop.
D $6310 If new item/alien was generated, this routine is called instead of MainLoop.
D $6310 Used by the routine at #R$6971.
@ $6310 label=MainLoopResetStack
@ $6310 ssub=ld sp,$5ccb+$25 ; Set the stack pointer
C $6314,4 #REGix=Rocket object
C $6319,3 Reset current alien number
c $631C The main game loop.
D $631C This routine is called until a new item/alien is generated, then #R$6310 is called.
D $631C Used by the routines at #R$6310, #R$692e and #R$6971.
R $631C Input:IX address of main jump table
@ $631C label=MainLoop
C $631C,8 Compare SYSVAR_FRAMES and last_frame
N $6324 Note: if we have EI here, then #R$692e will be called and DI executed.
C $6324,3 If they're not equal, do frame update
N $6327 When one of the `main_jump_table` update routines RETurns, the new game actor routine will be called.
@ $6327 nowarn
C $6327,3 #REGhl=generate new actor routine
C $632A,1 ...and push `ret` address to the stack.
N $632B Execute one of the update routines using the value in IX.
C $632B,3 #REGhl=main jump table
C $632E,6 Calculate the jump table offset
c $6334 Performs a main loop update jump.
D $6334 Used by the routines at #R$631c and #R$648b.
R $6334 Input:A Offset for jump table address.
R $6334 HL Address to the jump table.
@ $6334 label=PerformJump
C $6335,2 #REGbc=offset: 34 max (size of jump table)
C $6337,1 Set #REGhl to jump table address using offset
C $6338,4 Assign the jump address back to #REGhl
C $633C,1 Use `jp` so `ret` calls the new actor/timer routine
w $633D Main game loop jump table.
D $633D Addresses for all the main routines to be updated per game loop.
@ $633D label=main_jump_table
W $633D,2,2 Frame rate limiter
W $633F,2,2 Jetman Fly
W $6341,2,2 Jetman Walk
W $6343,2,2 Meteor Update
W $6345,2,2 Collision Detection
W $6347,2,2 Crossed Space Ship Update
W $6349,2,2 Sphere Alien Update
W $634B,2,2 Jet Fighter Update
W $634D,2,2 Animate Explosion
W $634F,2,2 Rocket Update
W $6351,2,2 Rocket Take off
W $6353,2,2 Rocket Landing
W $6355,2,2 SFX Death: Enemy
W $6357,2,2 SFX Death: Player
W $6359,2,2 Check Item Collected
W $635B,2,2 UFO Update
W $635D,2,2 Animate Laser Beam
W $635F,2,2 Squidgy Alien Update
c $6361 Update the high score.
D $6361 If one of the players score is a new max score, then update the high score with that of the player with the highest score. Used by the routine at #R$60b7.
@ $6361 label=UpdateHiScore
C $6361,3 #REGhl=player 1 score
C $6364,4 #REGde=player 2 score
C $6368,3 Swap the P1 LSB/MSB values so we can perform calculations on them.
C $636B,3 Swap the P2 LSB/MSB values so we can perform calculations on them
C $636E,1 Reset the Carry flag
C $6371,2 Jump if score P2 > P1, else
C $6373,2 Jump if score P1 > P2, else P1==P2, so no jump
@ $6375 ssub=ld a,($5cf4+$02)
C $6375,4 #REGe=3rd byte of the P1 score
@ $6379 ssub=ld a,($5cf7+$02) ; P2 score
C $6379,3 #REGa=3rd byte of the P2 score
C $637D,2 Jump if score of P2 < P1 (set's #REGhl to P1 score)
N $637F Inactive player has the highest score.
C $637F,3 #REGhl=P2 score
N $6382 Update the high score if the player score has beaten it.
C $6383,3 #REGde=high score
C $6386,2 Loop counter (all 3 score bytes)
C $6388,1 #REGa = hi-score byte
C $6389,1 Compare with player
C $638A,2 If hi-score < player, update highscore score
C $638C,2 If hi-score != player (not equal), then RET
C $638E,1 else hi-score == player: next player byte
C $638F,1 next high score byte
C $6390,2 Repeat
C $6392,1 Restores #REGhl to the highest player score
N $6394 Sets the bytes for the high score with those from the player.
C $6395,3 High Score
N $639E Player 1 has the highest score.
C $639E,3 #REGhl=P1 score
C $63A1,2 Update HI score
c $63A3 Update Jet Fighter.
R $63A3 Input:IX Alien object for one of the Jet Fighters.
@ $63A3 label=JetFighterUpdate
C $63A3,4 Increment current alien number
C $63A7,3 Update Alien direction
C $63AA,3 Alien "moving" field
C $63B0,4 Move if bit-1 is set
C $63B4,3 Check and update speed
C $63B7,3 #REGa=Jetman Y position
C $63BC,6 Update Alien speed if Jetman Y position-12 equals Alien Y position
C $63C2,3 #REGa=LSB of game timer
C $63C7,2 Move vertically if bit-6 is reset
C $63CF,2 Move vertically +2 or -2
N $63D1 Decide if speed should be updated.
C $63D1,3 #REGa=random number
C $63D6,1 Return if not zero
N $63D7 Update speed.
C $63D7,4 Alien "moving" field
C $63DB,1 #REGc=Jetman Y position-12 ?
C $63DC,3 #REGa=LSB of game timer
C $63E4,3 Set new X speed value
C $63E7,4 Set "colour" to White
N $63EC Move Jet Fighter horizontally.
C $63EC,3 Decrement alien X speed
C $63EF,2 Jet Fighter killed if X speed is zero
C $63F1,2 #REGa=default speed
C $63F3,4 Check bit-6 of Alien "direction"
C $63FB,1 #REGl=$FC or $04?
N $63FC Target the player and move towards them.
C $63FC,8 Move upwards if Jetman Y position higher than Alien Y position
C $6404,2 else, move down
N $6406 Move Jet Fighter vertically and horizontally.
C $6406,3 Alien "direction"
C $6409,2 Reset FLY and WALK bits
C $640D,3 Update "direction" value
C $6410,7 Update Alien X position (#REGl is probably 3 or 4)
C $6417,7 Update Alien Y position
C $641E,3 Update Actor Position X and draw
C $6421,3 Colourize the sprite
C $6424,7 Kill Fighter if Y position < $28
C $642B,3 Fire laser beam - returns #REGc
C $642E,4 Kill if a laser hit the Alien
C $6432,3 Platform collision - returns #REGe
C $6435,4 Kill if Alien hit a platform
C $6439,3 Alien collision - returns #REGde
C $643D,2 Alien killed by collision
C $643F,10 Update Alien "direction"
N $644A Jet Fighter is dead. Added score and make exploding sound.
C $644A,3 55 points for a dead jet fighter (decimal value)
C $644D,3 Add points to score
C $6450,3 Exploding jet fighter SFX - actually Thruster SFX!
C $6453,3 Update current alien state
c $6456 Alien SFX when killed by collision.
D $6456 Reset anim state and set SFX params #2.
D $6456 Used by the routines at #R$63a3, #R$6a35, #R$6ab8, #R$6bf8, #R$6cbe and #R$6d9c.
@ $6456 label=AlienCollisionAnimSfx
C $6456,3 Update actor state
C $6459,5 Play explosion sound with SFX type #2
C $645E,3 Animate explosion
c $6461 Jetman collects a collectible item.
R $6461 Input:IX Collectible item object
@ $6461 label=ItemCheckCollect
C $6461,3 Update Actor position direction
C $6464,3 Platform collision - returns #REGe
C $6467,10 Increment item Y position if bit-2 is set
C $6471,3 Alien collision - returns #REGe
C $6475,2 Drop new collectible item if #REGe > 0
C $6477,1 Reset #REGa
C $6478,3 #REGhl=sprite address
C $647B,3 Destroy the collected item
C $647E,4 Set type as unused
C $6482,3 250 points to add to score (decimal value)
C $6485,3 Add points to score
C $6488,3 SFX for item collect (and return)
c $648B Drop a new collectible item.
D $648B Used by the routine at #R$6461.
R $648B Input:IX Collectible item object
@ $648B label=ItemDropNew
C $648B,3 Jump table offset
C $648E,2 Values: 0, 2, 4, 6, or 8
C $6490,3 #REGhl=item drop jump table
C $6493,3 Execute the jump using #REGhl address
w $6496 Item drop jump table.
@ $6496 label=item_drop_jump_table
W $6496,2,2 Drop Gold bar collectible
W $6498,2,2 Drop chemical based collectible
W $649A,2,2 Drop chemical based collectible
W $649C,2,2 Drop green coloured collectible
W $649E,2,2 Drop collectible with random colour
c $64A0 Drop a gold bar collectible item.
R $64A0 Input:IX Collectible item object
@ $64A0 label=ItemDropGoldBar
C $64A0,4 Set colour to GOLD
c $64A4 Display a collectible sprite.
D $64A4 Used by the routines at #R$64bc, #R$64c2 and #R$64d7.
@ $64A4 label=ItemDisplaySprite
C $64A5,3 #REGde=item sprite address
C $64A8,3 Update the item sprite
C $64AB,3 Colourize the sprite
c $64AE Sprite offset using colour attribute.
D $64AE Used by the routines at #R$6461, #R$64a4 and #R$6514.
@ $64AE label=ItemGetSpriteAddressAttrOffset
c $64B1 Get address for collectible sprite.
D $64B1 Used by the routine at #R$66fc.
R $64B1 Input:A Offset for the desired sprite.
R $64B1 Output:DE Address for a sprite.
@ $64B1 label=ItemGetSpriteAddress
C $64B1,3 Sprite lookup table
C $64B4,4 Add offset to base address
C $64B8,3 Assign sprite address to #REGde
c $64BC Drop a Plutonium collectible item.
R $64BC Input:IX Collectible item object.
@ $64BC label=ItemDropPlutonium
C $64BC,4 Set the colour to green
C $64C0,2 Display item sprite
c $64C2 Drop a chemical based item, flashing items radiation and plutonium.
R $64C2 Input:IX Collectible item object.
@ $64C2 label=ItemDropChemical
C $64C2,3 Game timer
C $64C9,2 Use cyan colour and display sprite
N $64CB Flashing items: hidden.
C $64CB,4 Set the colour to black
C $64CF,2 Display the item sprite
N $64D1 Flashing items: visible.
C $64D1,4 Set the colour to cyan
C $64D5,2 Display the item sprite
c $64D7 Drop a random coloured collectible item.
D $64D7 Set the sprite to a random colour based on it's ID, which means colour values will be between $41 and $47.
R $64D7 Input:IX Collectible item object.
@ $64D7 label=ItemDropRandomColour
C $64D7,3 Game timer
C $64DE,2 Jump if #REGa is now 1-7
C $64E1,2 Make sure colour value is > $40
C $64E3,3 Set the colour to between $41 and $47
C $64E6,2 Display the item sprite
c $64E8 Collision detection for collectible items / rocket modules.
R $64E8 Input:IX Collectible item object.
@ $64E8 label=CollisionDetection
C $64E8,3 Update Actor position direction
C $64EB,3 #REGa=item "state"
C $64EE,5 Pick up rocket module if bit-2 set
C $64F3,4 Carrying rocket module/fuel if bit-1 set
C $64F7,4 Draw sprite if bit-0 reset
C $64FB,3 Check for alien collision - returns #REGe
C $64FE,3 Collect rocket module if #REGe == 0
C $6501,3 Platform collision - returns #REGe
C $6504,4 Draw sprite if bit-2 set
c $6508 Increment Y position and draw sprite.
D $6508 Used by the routine at #R$6565.
@ $6508 label=IncYRedrawSprite
c $650E Redraw a sprite.
D $650E Used by the routines at #R$64e8, #R$6523 and #R$6541.
@ $650E label=RedrawSprite
C $650E,3 Update actor and draw sprite
C $6511,3 Colourize the sprite
c $6514 Gets collectible ID based on the current user level.
D $6514 Used by the routine at #R$64e8.
@ $6514 label=GetCollectibleID
C $6514,3 Current player level
C $6518,2 There are only 6 collectibles?
C $651A,3 #REGde=collectible item sprite address
C $651D,3 Erase an item sprite
C $6520,3 Colourize the sprite
c $6523 Collect Rocket module or fuel pod.
D $6523 Module is collected after player collides with it. Used by the routine at #R$64e8.
R $6523 Input:IX Rocket module object.
@ $6523 label=CollectRocketItem
C $6523,4 Module "state"
C $6527,3 Find and destroy the sprite (returns #REGde)
C $652A,3 100 points to add to score (decimal value)
C $652D,3 Add points to score
C $6530,3 SFX for collecting fuel
C $6533,9 Update module position so it becomes attached to the player via the Jetman Y,X positions
C $653C,3 Update sprite X position
C $653F,2 Colourize the sprite
c $6541 Carry a collected rocket module/fuel pod.
D $6541 Ensure the rocket module/fuel pod remains attached to the foot of the Jetman sprite. Used by the routine at #R$64e8.
R $6541 Input:IX Rocket module object.
@ $6541 label=CarryRocketItem
C $6541,9 Update module position so it becomes attached to the player via the Jetman Y,X positions
@ $654A ssub=ld a,($5d30+$01) ; Rocket X position
C $654D,3 Subtract module X position
C $6550,3 If already negative, jump
C $6553,2 else make a negative value
C $6555,4 Draw sprite if #REGa >= 6
C $6559,4 Set module "state" to collected
@ $655D ssub=ld a,($5d30+$01) ; Rocket: X position
C $6560,3 Update module X position to be same as Rocket position
C $6563,2 Update module and draw sprite
c $6565 Pick up and carry a rocket module/fuel pod.
D $6565 Used by the routine at #R$64e8.
R $6565 Input:IX Collectible item object - rocket module or fuel pod.
@ $6565 label=PickupRocketItem
C $6565,3 Item sprite jump table offset
C $656A,2 Jump to delivery check if a fuel pod?
C $656E,3 Add item Y position
C $6573,3 Increment item Y position and draw sprite if < 183
@ $6576 ssub=ld a,($5d38+$04) ;
@ $657B ssub=ld ($5d38+$04),a ; Set module "state" to collected
@ $657E ssub=ld a,($5d30+$04) ; #REGa=Rocket "state" value
@ $6582 ssub=ld ($5d30+$04),a ; Update rocket "state" value
C $6585,3 Item sprite jump table offset
C $658A,3 Copy rocket sprite to buffers
C $658D,3 Find and destroy current sprite
C $6590,4 Set item type to unused
C $6594,3 SFX for rocket building
N $6597 Check if fuel pod delivered to ship, and increment count if so.
C $6597,3 Item Y position of fuel pod
C $659A,2 Has it reached the rocket yet?
C $659C,3 Move the fuel cell down one pixel if not
@ $659F ssub=ld a,($5d30+$05) ; #REGa=rocket fuel pod count
@ $65A3 ssub=ld ($5d30+$05),a ; Increment rocket fuel pod count
C $65A6,2 Loop back and repeat
c $65A8 Release new collectible item.
D $65A8 Used by the routine at #R$6971.
@ $65A8 label=ItemNewCollectible
C $65A8,3 Jetman direction
C $65AD,1 Return if not one of the 6 directions
C $65B0,1 Return if >= 3 (all movement except up right?)
C $65B1,3 #REGhl=default item state
C $65B4,3 #REGde=collectible object
C $65BA,1 #REGa=item type
C $65BC,1 Return if currently in use
C $65BD,3 Game timer
C $65C2,1 Return if between 1-127
C $65C5,3 #REGa=column to drop item
@ $65C8 ssub=ld ($5d40+$01),a ; Update item X position
C $65CB,2 Get random number
C $65CD,2 #REGa=2, 4, 6, 8, 10, 12, or 14
C $65CF,4 Jump if bit-3 is already reset
C $65D3,2 else set bit-3
C $65D5,2 Make sure bit-5 (32) is set
@ $65D7 ssub=ld ($5d40+$06),a ; Update item with new jump table offset
c $65DB Calculate column on which to drop a new collectible item/fuel pod.
D $65DB Used by the routines at #R$65a8 and #R$65f9.
R $65DB Ouput:A Column position.
@ $65DB label=ItemCalcDropColumn
C $65DB,3 #REGhl=item drop position table
C $65DE,3 #REGa=random number
C $65E3,3 #REGbc = byte offset (0-15)
C $65E6,1 Add offset
C $65E7,1 Set #REGa to position
b $65E9 Horizontal column positions for dropping collectibles.
@ $65E9 label=item_drop_positions_table
B $65E9,16,8
c $65F9 Drop a new fuel pod collectible.
D $65F9 Used by the routine at #R$6971.
@ $65F9 label=ItemNewFuelPod
C $65F9,3 Jetman direction
C $65FE,1 Return if not one of the 6 directions
C $6601,1 Return if >= 3 (all movement except up right?)
C $6602,3 #REGhl=default rocket module state
C $6605,3 #REGde=rocket module object
C $660B,3 Return if currently in use
@ $660E ssub=ld a,($5d30+$05) ; #REGa=Rocket fuel Pod count
C $6613,1 Return if fuel collected >= 6
C $6614,3 Game timer
C $661A,1 Return if #REGa is between 1-15
C $661D,3 #REGa=column to drop item
@ $6620 ssub=ld ($5d38+$01),a ; Update fuel pod X position
c $6624 Reset the Rocket modules state data ready for next level.
D $6624 After the rocket hits top of screen this routine resets all the collectibles, aliens, and player states for that level. Used by the routine at #R$6690.
@ $6624 label=RocketModulesReset
C $6624,3 #REGhl=rocket module
C $6627,2 Loop counter
c $6629 Set objects as inactive.
D $6629 Used by the routines at #R$60b7 and #R$6624.
R $6629 Input:B Loop counter: either $0A or $0C.
R $6629 HL Object to be updated: fuel pod or thruster animation.
@ $6629 label=SetObjectInactive
C $6629,3 Increment value
C $662C,2 Reset first byte of object
C $662E,1 Set #REGhl to beginning of next object
c $6632 Animate the rocket flame sprites.
D $6632 Used by the routines at #R$6690 and #R$66b4.
R $6632 Input:IX Rocket object
@ $6632 label=RocketAnimateFlames
C $6632,8 Add 21 to rocket Y position
@ $663A ssub=ld hl,$5dc0+$01 ; #REGhl=Actor Y position
C $663D,4 Add 21 to actor Y position
C $6641,7 If near ground, turn off flame sprites
C $6648,2 If >= 184, just update flame sprite vars
C $664A,3 Game timer
C $664F,2 #REGde=flame sprite #1 if bit-3 is set
C $6651,3 else #REGde=flame sprite #2
N $6654 Draw the flame sprites.
C $6655,6 Destroy flame sprite #1
C $665B,6 Destroy flame sprite #2
C $6662,3 Erase and animate actor sprite
C $6665,4 Set flame sprite colour to Red
C $6669,3 Colourize the sprite
N $666C Update Rocket and Actor Y positions.
C $666C,8 Subtract $15 from rocket Y position
@ $6674 ssub=ld hl,$5dc0+$01 ; #REGhl=Actor Y position
C $6677,4 Subtract 21 from actor Y position
N $667C Set first rocket flame sprite to be displayed.
C $667C,3 Rocket flame sprite #1
C $667F,2 Draw flame sprite
N $6681 Turn off the rocket flame sprites and update sprite variables.
C $6681,6 Destroy flame sprite #1
C $6687,6 Destroy flame sprite #2
C $668D,3 Update sprite variables
c $6690 Rocket ship is taking off.
R $6690 Input:IX Rocket object.
@ $6690 label=RocketTakeoff
C $6690,3 Update Actor position direction
C $6693,3 Decrement Y position
C $6696,3 Thruster SFX
C $6699,3 Animate rocket flame sprites
C $669C,5 Check if rocket has reached top of screen
C $66A1,2 Update rocket colour if not
N $66A3 Rocket has reached top of screen - set up next level.
C $66A3,4 Increment current player level
C $66A7,3 Reset rocket ready for next level
C $66AA,3 Set Rocket "move" state to down
C $66AD,4 Reset fuel pod counter
C $66B1,3 New level
c $66B4 Rocket ship is landing.
R $66B4 Input:IX Rocket object.
@ $66B4 label=RocketLanding
C $66B4,3 Update Actor position direction
C $66B7,3 Increment Y position
C $66BA,3 Thruster SFX
C $66BD,3 Animate rocket flame sprites
C $66C0,5 Check if rocket has landed
C $66C5,2 Update rocket colour if not (and RET)
N $66C7 Rocket has landed!
C $66C7,4 Set Rocket "move" state to default (on pad)
C $66CB,3 Initialise the player state
C $66CE,2 Update rocket colour (and RET)
c $66D0 Update the rocket ship.
R $66D0 Input:IX Rocket object.
@ $66D0 label=RocketUpdate
C $66D0,3 Update Actor position direction
C $66D3,3 #REGe=Alien collision result: $00 or $01
C $66D6,3 Update rocket colour if not zero (and RET)
C $66D9,7 Update rocket colour if fuel pod counter < 6 (and RET)
C $66E0,3 Set Rocket "move" state to up
C $66E5,4 #REGix=Jetman object
C $66E9,3 Update Jetman position direction
C $66EC,3 Jetman, find and destroy
C $66EF,4 Reset Jetman direction
C $66F3,2 Restore #REGix to be the rocket object
C $66F5,4 Increment current player lives
C $66F9,3 Display player lives (and RET)
c $66FC Update Rocket ship colour.
D $66FC Colouring is based on the number of fuel pods collected. This routine is never CALLed (only via JR), so the last RET forces the calling routine to return. Used by the routines at #R$6690, #R$66b4 and #R$66d0.
R $66FC Input:IX Rocket object.
@ $66FC label=UpdateRocketColour
C $66FC,3 Rocket X position
C $66FF,3 Rocket Y position
C $6703,3 #REGa=colour attribute
C $6706,3 Set loop counter
N $6709 Draw all collected rocket modules.
C $670A,3 #REGa=player level
C $670D,7 Calculate which sprite to use for the current level
C $6714,3 #REGde=item address from lookup table using #REGa
C $6717,3 Update actor position using #REGde
C $671A,1 Restore loop counter
C $671B,8 Subtract 16 from a rocket Y position
@ $6723 ssub=ld a,($5dc0+$01) ; #REGa=Actor Y position
C $6726,2 Subtract 16 from Actor Y position
@ $6728 ssub=ld ($5dc0+$01),a ; Update Actor Y position
C $672F,2 Loop and update rocket/actor again
@ $6733 ssub=ld ($5dc0+$04),a ; Actor width = 2
@ $6737 ssub=ld ($5dc0+$03),a ; Actor height = 0 (?)
C $673B,3 Update rocket Y position: only Y changed in loop above
C $673E,3 Update current Actor Y,X coords
N $6741 Colour the rocket modules based on collected fuel pod count.
C $6741,6 Rocket "state"
C $6747,10 if value < 6, or the fuel pod counter is zero, then set rocket colour to white and redraw
C $6751,2 Check if all fuel collected (is checked at 6760)
C $6753,1 Preserve Carry (no care for #REGa)
C $6754,3 Game timer
C $675E,1 Restore Carry value (from 6751 check above)
C $6760,2 Colour all sprites if all fuel has been collected
C $6762,3 else use fuel pod count as loop counter
C $6765,4 Set colour to Magenta
C $6769,3 Update sprite colour
N $676C Set part of rocket back to white based on amount of uncollected fuel pods.
C $676C,2 #REGa=max possible fuel pods
C $676E,3 Subtract remaining fuel pod count
C $6771,1 Set loop counter
C $6772,5 Set Rocket colour to white
C $6777,3 Redundant JP!
C $677B,3 Colourize the sprite
C $677F,3 #REGhl=current rocket sprite coords
C $6782,4 Update Y position
C $6786,3 Update current rocket sprite coords
C $6789,2 Loop and continue colouring
w $678C Rocket and collectible sprite address lookup table.
@ $678C label=collectible_sprite_table
W $678C,2,2 Offset: $00 - Rocket #1: Bottom