forked from VilleKrumlinde/VectrexThrust
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathThrust.asm
3880 lines (3263 loc) · 68.4 KB
/
Thrust.asm
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
; Vectrex Thrust main program
; Copyright (C) 2004 Ville Krumlinde
;----------------------------------------
; THRUST.ASM
;----------------------------------------
opt ;optimizations on
include "def.asm"
code
org 0
;ROM-header
db $67,$20
db "GCE 2004",$80
dw $FD0D ;ptr to execrom-music
db $FC,$30, $72,$A8, "THRUST FOR VECTREX 1.2",$80
db $FC,$30, $60,$A8, "BY VILLE ",$6a,$80
db $0
Boot:
jsr eeprom_load
ldd #$0103 ;init joystick
std $c81f
; jsr Zzap_Start ;uncomment while debugging bonusgame
Start:
mDptoD0
jsr eeprom_save ;save to eeprom if changed (options and highscores)
jsr ShowTitleScreen
mDptoC8 ;Set DP to C8 for game logic code
clra
jsr InitNewGame
jsr PrepareLevel
MainLoop:
mDptoC8 ;Set DP to C8 for game logic code
jsr Ship_Update
jsr UpdateFx
jsr UpdateGuns
jsr UpdateShipShots
jsr UpdateGunShots
jsr UpdateDoors
jsr AdjustFuel
jsr UpdateFrameCounter
jsr UpdateSound
mTestFlag GameOverFlag
bne GameOver
jsr SetView
jsr RefreshDrawList
;Wait for screen sync
;DP is D0 after call to waitrecal
;Keep DP at D0 for draw vector code
jsr waitrecal
jsr UpdateSoundChip
jsr DrawLevel
jsr Ship_Draw
jsr DrawShipShots
jsr DrawGuns
jsr DrawFuel
jsr DrawFx
jsr DrawGunShots
jsr DrawOrb
jsr DrawPowerplant
jsr DrawStars
jsr DrawDoors
jsr DrawSwitches
jsr DrawDisplay
bra MainLoop
GameOver:
lda DemoMode ;do not display 'game over' in demo mode
bmi maiIsDemo
jsr Text_GameOver
maiIsDemo:
direct -1
bra Start
direct $c8
include "clip.asm"
direct -1
include "Thrust_Sound.asm"
include "Thrust_Fx.asm"
include "Thrust_Ship.asm"
;*****************
UpdateFrameCounter:
direct $c8
lda FrameCounter
bpl ufcOkCnt3
ora #$40
ufcOkCnt3:
adda #$40
sta FrameCounter
anda #$3f
bne ufcOkCnt64
lda #$3f
bra ufcDoAdd
ufcOkCnt64:
lda #$ff
ufcDoAdd:
adda FrameCounter
sta FrameCounter
if false
;Atari 2600 code
lda FrameCnt ; 3
sta FrameCnt1
bpl .okCnt3 ; 2³
ora #$40 ; 2 reset Cnt3
.okCnt3:
clc ; 2
adc #$40 ; 2 increase Cnt3
sta FrameCnt ; 3
and #$3f ; 2
bne .okCnt64 ; 2³
lda #$3f ; 2 reset Cnt64
BIT_W ; 2
.okCnt64:
lda #$ff ; 2 increase Cnt64
clc ; 2
adc FrameCnt ; 3
sta FrameCnt ; 3 = 28-32
endif
direct -1
rts
;*****************
DrawDisplay: ;Draw status panel. Copy to buffer and print as a single string.
lda DemoMode ;no display in demomode
bpl ddGoOn
rts
ddGoOn:
mDecLocals 0,0,20
leau LocalBuffer,s
lda GameMode
cmpa #TimeAttackGame
bne ddNoTimeAttack
ldd #'TI'
std ,u++
ldd #'ME'
std ,u++
ldd #': '
std ,u++
ldb TimeAttackTime ;time, flash if low
cmpb #10
bge ddDoTime
lda LoopCounterLow
anda #8
bne ddDoTime
ldd #' '
std ,u
std 2,u
bra ddTimeFin
ddDoTime:
clra
tfr d,x
jsr Text_ConvertX
ddTimeFin:
ldb #$80 ;end byte
stb 4,u
bra ddDoDraw
ddNoTimeAttack: ;normal game
ldx #PlayerScore ;copy score to buffer
ldb #' '
bsr CopyScoreFromXtoU
leau 7,u ;Nr of ships left
stb ,u
lda ShipLives
adda #'0'
std 1,u
leau 3,u ;Fuel, flash if low
lda GameMode
cmpa #BonusGame
bne ddNotBonus
;In bonusgame, draw current level instead of fuel
ldb CurLevel
clra
tfr d,x
bra ddDrawFuel
ddNotBonus
ldx ShipFuel
cmpx #300
bge ddDrawFuel
lda LoopCounterLow
anda #8
bne ddDrawFuel
ddSkipFuel:
ldd #' '
std ,u
std 2,u
bra ddFuelFin
ddDrawFuel:
jsr Text_ConvertX
ddFuelFin:
ldb #$80 ;End byte
stb 4,u
ddDoDraw:
lda #114
ldb #-127 + 50
leax LocalBuffer,s
jsr Text_Print
mFreeLocals
rts
CopyScoreFromXtoU: ;u=destination buffer, b=end byte
stb -1,s
ldd ,x
std ,u
ldd 2,x
std 2,u
ldd 4,x
std 4,u
lda #$30 ;extra zero + end byte
ldb -1,s
std 6,u
rts
;*****************
GiveScoreA:
MAX_LIVES = 9
ldb DemoMode ;no score in demomode
bpl gsaGoOn
rts
gsaGoOn:
pshs x,u
ldx #PlayerScore
ldy 2,x
jsr convert_a_to_bcd_and_add
tfr y,d
cmpa 2,x ;extra life each 10000 points
beq gsaExit
lda GameMode
cmpa #HardGame ;every 20000 for hard mode
bne gsaExtra
lda 2,x
anda #1
bne gsaExit
gsaExtra:
lda ShipLives
cmpa #MAX_LIVES
beq gsaExit
inc ShipLives
mEmitSound ExtraLifeSoundId
gsaExit:
puls x,u
rts
;*****************
AdjustFuel: ;Update ship fuel amount
direct $c8
mDecLocals 1,0,0
lda FrameCounter
anda #FRAME3MASK
bne afExit
tst CheatLives
bne afExit
mTestFlag InactiveFlag
bne afExit
;if refueling, inc 1
;else
; if shield -1
; if thrust -1 (if hasorb extra -1)
clr LocalB1,s
mTestFlag RefuelFlag
bne afRefueling
mTestFlag ThrustFlag
beq afTestShield
dec LocalB1,s
; mTestFlag HasOrbFlag
; beq afTestShield
; dec LocalB1,s
afTestShield:
mTestFlag ShieldFlag
beq afStore
dec LocalB1,s
bra afStore
afRefueling:
lda #16
sta LocalB1,s
afStore:
ldb LocalB1,s
beq afExit
sex
addd ShipFuel
bpl afOk
clra
clrb
afOk:
std ShipFuel
afExit:
mFreeLocals
direct -1
rts
;***************** ;See if it's time to emit a new gun shot.
;List of center angle for each gun type
;NE,NW,SE,SW
GunShotAngles: db -8,8,-24,24
UpdateGuns:
mDecLocals 2,2
LocalAngle = LocalB2
LocalGun = LocalW2
MaxGunDistance = 120 ;Minimum distance from firing gun to ship
direct $c8
lda GunShotTimer ;Check delay timer
beq ugTimeOk
deca
sta GunShotTimer
lbra ugFin
ugTimeOk:
lda GunShotActive ;Exit if no empty slot
cmpa #GunShotAllActive
lbeq ugFin
tst PowerShot ;Exit if guns are disabled (powerplant recently shot)
lbne ugFin
ldu CurLevelEntry ;Find a gun that can fire
ldu leGuns,u
lbeq ugFin ;exit if no guns
ldb ,u+ ;load guncount
stb LocalB1,s
ldd GunsActive
ugGunLoop:
asra
rorb
bcc ugGunNotActive
std LocalW1,s
ldd geGunX,u
subd ShipX
mTestRangeD -MaxGunDistance,MaxGunDistance,ugNextGun
ldd geGunY,u
subd ShipY
mTestRangeD -MaxGunDistance,MaxGunDistance,ugNextGun
;Gun can shoot, throw a dice to see if choose this gun
;Otherwise the first closest gun would always fire
mRandomToA
anda #3
bne ugNextGun
stu LocalGun,s
bra ugGunFound
ugNextGun:
ldd LocalW1,s
ugGunNotActive:
leau GunEntry,u
dec LocalB1,s
bne ugGunLoop
jmp ugFin ;No gun was found, exit
ugGunFound:
lda #0 ;Find a free gunshot-slot
ldb GunShotActive
ldu #GunShots
ugLoop:
asrb ;test active
bcs ugAlreadyActive
std LocalW1,s
ldx LocalGun,s ;Slot found, emit shot
ldd geGunX,x
std gsShotX,u
ldd geGunY,x
std gsShotY,u
lda geGunSprite,x
ldx #GunShotAngles
ldb a,x
;16 is 90 deg
;gun can shoot in 135 deg (0..23)
;repeat until we have a random value 0..23
ldx #0
ugRndAngle:
leax 1,x
cmpx #5 ;bailout after 5 iterations
bne ugRndAngle1
lda #12
bra ugRndAngle2
ugRndAngle1:
mRandomToA
;improve randomness by xoring loopcounter
eora LoopCounterLow
anda #31
cmpa #23
bhi ugRndAngle
ugRndAngle2:
suba #12 ;a is -12..11
sta -1,s
addb -1,s ;final angle is gun center + random
stb LocalAngle,s
ldb LocalAngle,s ;Calc rise & run
lda GunShotSpeed ;scale
jsr convert_angle_to_rise_run ;dp must be c8
nega ;Y axis points down in our world
sta gsShotVelocY,u
stb gsShotVelocX,u
lda LocalW1,s ;Set shot active
mSetBitA GunShotActive
mRandomToA ;Reset delay for next shot
anda GunShotMask
adda GunShotDelay
sta GunShotTimer
;mEmitSound GunFireSoundId
ldu CurLevelEntry ;Get index of firing gun, use for fx
ldu leGuns,u
ldb ,u
subb LocalB1,s
mEmitFx FxTargetGun,FxTypeGunFire,b
bra ugFin ;Exit
ugNext:
ldd LocalW1,s
ugAlreadyActive:
leau GunShotEntry,u
inca
cmpa #MaxGunShots
bne ugLoop
ugFin:
direct -1
mFreeLocals
rts
;***************** ;Update active gun shots.
UpdateGunShots
mDecLocals 0,1
direct $c8
lda #0 ;loop from 0 to MaxGunShots
ldb GunShotActive
ldu #GunShots
gsMoveLoop:
asrb ;test active
lbcc gsNotActive
std LocalW1,s
;Move
mUpdateXCoord gsShotX, gsShotVelocX
mUpdateYCoord gsShotY, gsShotVelocY, gsRemoveShot
mTestFlag HomingGunShotsFlag
beq gsNoHoming
;Try to make the homing missiles move unpredictably
;Skip homingness a while each second to avoid them constantly circling ship
lda LoopCounterLow
cmpa #32
blo gsNoHoming
anda #1
beq gsNoHoming
lda LocalW1,s
anda #1
bne gsNoHoming
ShotVelocXMax=12
ldd ShipX
cmpd gsShotX,u
blo gsHomeXDec
lda gsShotVelocX,u
cmpa #ShotVelocXMax
bge gsHomeXFin
inca
sta gsShotVelocX,u
; inc gsShotVelocX,u
bra gsHomeXFin
gsHomeXDec:
lda gsShotVelocX,u
cmpa #-ShotVelocXMax
ble gsHomeXFin
deca
sta gsShotVelocX,u
; dec gsShotVelocX,u
gsHomeXFin
ShotVelocYMax=12
ldd ShipY
cmpd gsShotY,u
blo gsHomeYDec
lda gsShotVelocY,u
cmpa #ShotVelocYMax
bge gsHomeYFin
inca
sta gsShotVelocY,u
bra gsHomeYFin
gsHomeYDec:
lda gsShotVelocY,u
cmpa #-ShotVelocYMax
ble gsHomeYFin
deca
sta gsShotVelocY,u
gsHomeYFin
gsNoHoming:
ldy #ShipX ;Collision gunshots vs ship
mPointVsArea ShipArea,gsShipOk, gsShotX,gsShotY, 0,2
mTestFlag ShieldFlag ;if shield, just remove shot
bne gsShipSkipExplode
jsr ExplodeShip
gsShipSkipExplode:
bra gsRemoveShot
gsShipOk:
mTestFlag HasOrbFlag ;Collision gunshots vs pod
beq gsPodOk
ldy #PodX
mPointVsArea PodArea,gsPodOk, gsShotX,gsShotY, 0,2
jsr ExplodeShip
bra gsRemoveShot
gsPodOk:
ldy gsShotY,u ;Collision shots vs level
ldx gsShotX,u
jsr PointVsLevel
bcc gsNoHit
bra gsRemoveShot
gsNoHit:
bra gsMoveNext
gsRemoveShot:
lda LocalW1,s ;a is current loop index, clear this bit to remove shot
mClearBitA GunShotActive
gsMoveNext:
ldd LocalW1,s
gsNotActive:
leau GunShotEntry,u
inca
cmpa #MaxGunShots
bne gsMoveLoop
direct -1
mFreeLocals
rts
;*****************
DrawGunShots:
;DP must be D0
mDecLocals 0,2,4
mSetScale $7f ;Scale $7f is required for move_pen_d to reach whole screen
ldx #GunShots ;Draw all active shots.
lda #MaxGunShots
ldb GunShotActive
dgsLoop:
asrb ;test active
bcc dgsNotActive
std LocalW1,s
mTestFlag HomingGunShotsFlag
bne dgsHoming
dgsNormal:
stx LocalW2,s
leau LocalBuffer,s
ldd gsShotX,x
std ,u
ldd gsShotY,x
std 2,u
lda #$7f
jsr DrawDot
ldx LocalW2,s
bra dgsNext
dgsHoming:
lda LocalW1,s
anda #1
beq dgsNormal
stx LocalW2,s
leau LocalBuffer,s
ldd gsShotX,x
std ,u
ldd gsShotY,x
std 2,u
lda #$7f
jsr DrawBullet
ldx LocalW2,s
;Draw a 'tail' on the homing shots by subtracting velocity to draw a dot at the previous position
leau LocalBuffer,s
ldb gsShotVelocX,x
negb
asrb
asrb
sex
addd ,u
std ,u
ldb gsShotVelocY,x
negb
asrb
asrb
sex
addd 2,u
std 2,u
lda #$34
jsr DrawBullet
ldx LocalW2,s
dgsNext:
ldd LocalW1,s
dgsNotActive:
leax GunShotEntry,x
deca
bne dgsLoop
mFreeLocals
rts
;*****************
DrawFuel: ;Draw active fuel pods on level
FrameSize set 2 ;Size of stack frame
Local1 set 0
;DP must be D0
leas -FrameSize,s
mSetIntensity $5f
ldu CurLevelEntry
ldu leFuel,u
beq dfExit ;exit if no fuel pods
ldb FuelActive
lda ,u+ ;load count
dfLoop:
asrb ;test active
bcc dfNext
std Local1,s
ldx #SpriteFuelCell
jsr DrawSprite
ldd Local1,s
dfNext:
leau FuelEntry,u
deca
bne dfLoop
dfExit:
leas FrameSize,s
rts
;*****************
DrawOrb: ;Draw stationary orb + platform on level
;DP must be D0
mTestFlag HasOrbFlag ;Exit if ship is carrying orb
bne doExit
mSetIntensity $5f
ldu CurLevelEntry
leau leOrbX,u
ldx #SpriteStationaryPod
jsr DrawSprite
doExit:
rts
;*****************
DrawPowerplant: ;Draw powerplant on level
;DP must be D0
mDecLocals 0,1,10
ldb PowerShot ;Decrease gun disabled timer
beq dpSkip
lda LoopCounterLow
anda #31
bne dpSkip
decb
stb PowerShot
dpSkip:
lda PowerLife ;Flash if about to explode
bpl dpDraw
leax LocalBuffer,s
nega ;Display countdown
adda #'0'-1
ldb #' ' ;ROM display must print at least 2 characters
stb ,x
ldb #$80
std 1,x
lda LoopCounterLow
anda #63
nega
adda #64
sta LocalW1,s
lsra
lsra
nega
ldb #$70
std $C82A ;Specify height and width
jsr reset0ref
mCombine d,-30,-30
adda LocalW1,s
jsr move_pen_d
; lda #$40
; suba LocalW1,s
mTicToc 64
adda #32
mSetIntensity
tfr x,u
jsr display_string
lda LoopCounterLow
anda #63
bne dpNoAdjustCounter
mEmitSound CountdownSoundId
inc PowerLife
lda PowerLife
cmpa #-1
bne dpNoAdjustCounter
;Planet exploded
mEmitFx FxTargetShip,FxTypePlanetExplode,0
jsr ExplodeShip
bra dpExit
dpNoAdjustCounter:
lda LoopCounterLow
anda #8
beq dpExit
dpDraw:
mSetIntensity $5f
ldu CurLevelEntry
leau lePowerX,u
stu LocalW1,s
ldx #SpritePowerplant
jsr DrawSprite
tst PowerShot ;draw rising dot if active
bne dpExit
ldx LocalW1,s
leau LocalBuffer,s
ldd ,x
addd #9
std ,u
ldd 2,x
subd #12
std -2,s
ldb LoopCounterLow
andb #15
lsrb
negb
sex
addd -2,s
std 2,u
lda #$60
; jsr DrawDot
jsr DrawBullet
dpExit:
mFreeLocals
rts
;*****************
DrawGuns: ;Draw active guns on level
mDecLocals 1,1
;DP must be D0
mSetIntensity $5f
ldu CurLevelEntry
ldu leGuns,u
beq dgExit ;exit if no guns
lda ,u+ ;load guncount
sta LocalB1,s
ldd GunsActive
dgLoop:
asra
rorb
bcc dgNext
std LocalW1,s
lda geGunSprite,u ;sprite entry
asla
ldx #GunSpriteTable
ldx a,x
jsr DrawSprite
ldd LocalW1,s
dgNext:
leau GunEntry,u
dec LocalB1,s
bne dgLoop
dgExit:
mFreeLocals
rts
GunSpriteTable:
dw SpriteGunNE,SpriteGunNW,SpriteGunSE,SpriteGunSW
;*****************
DrawSwitches: ;Draw door switches
;DP must be D0
mDecLocals 1,0,0
mSetIntensity $5f
ldu CurLevelEntry
ldu leSwitches,u
lda ,u+ ;load count
beq dswExit ;exit if no switches
dswLoop:
sta LocalB1,s
lda seSwitchDir,u
beq dswDrawLeft
ldx #SpriteSwitchRight
bra dswDraw
dswDrawLeft:
ldx #SpriteSwitchLeft
dswDraw:
jsr DrawSprite
lda LocalB1,s
dswNext:
leau SwitchEntry,u
deca
bne dswLoop
dswExit:
mFreeLocals
rts
;*****************
UpdateDoors:
; DoorCounter
; 0 : stängd, exit
; bit 7
; 0 : opening
; öka med 1, om max sätt bit 7
; 1 : closing
; minska med 1, om noll clear bit 7
; >=DoorSize : fully open
direct $c8
lda LoopCounterLow
anda #4
beq udoExit
lda DoorCounter
beq udoExit
bmi udoClosing
inca
bvs udoSetClose
sta DoorCounter
bra udoExit
udoSetClose:
lda #DoorSize
ora #%10000000
sta DoorCounter
bra udoExit
udoClosing:
anda #%01111111
deca
beq udoSetOpen
ora #%10000000
sta DoorCounter
bra udoExit
udoSetOpen:
lda #0
sta DoorCounter
udoExit:
direct -1
rts
;*****************
;Lines for doors are generated on stack, then drawn with clipdraw
DrawDoors:
DoorLineSize = 25 ;Size of buffer to hold lines
DoorListSize = 25 ;Size of buffer to hold drawlist for lines (5*linecount)
mDecLocals 3,0,DoorLineSize+DoorListSize
LocalDoorLines = LocalBuffer
LocalDoorList = LocalBuffer+DoorLineSize
LocalOpen = LocalB2
LocalTmp = LocalB3
lda DoorCounter
anda #%01111111
; cmpa #DoorSize
; lbge dorExit ;doors are fully opened, exit
sta LocalOpen,s ;amount to open door
mSetIntensity WallIntensity
ldu CurLevelEntry
ldu leDoors,u
lda ,u+ ;load count
lbeq dorExit
dorLoop:
sta LocalB1,s
leax LocalDoorLines,s
leay LocalDoorList,s
sty ,x++
ldd deDoorY,u
std ,x++
ldd deDoorX,u
std ,x++
lda deDoorDir,u
asla
ldy #dorTable
jmp [a,y]
dorTable:
dw dorRightDoor,dorUpDoor,dorInvertRightDoor,dorUpDoorWalls
dorRightDoor: ;draw door closing right, 1*2 tiles
;--
; |
;--
;positive y is down, positive x is right