-
Notifications
You must be signed in to change notification settings - Fork 0
/
_ranger.asm
317 lines (257 loc) · 6.63 KB
/
_ranger.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
////////////////////////////////////////////////////////////////////////////////
//
// Project : ForestSaver - https://github.com/intoinside/ForestSaver
// Target : Commodore 64
// Author : Raffaele Intorcia - raffaele.intorcia@gmail.com
//
// Ranger sprite handler
//
////////////////////////////////////////////////////////////////////////////////
#importonce
.filenamespace Ranger
* = * "Ranger Init"
Init: {
clc
lda ScreenMemoryAddress
adc #$03
sta ScreenMemoryAddress
// Self modify code to use current screen memotry address, update hibyte
sta Init.LoadSprite1 + 2
sta UpdateRangerFrame.LoadSprite1 + 2
sta UpdateRangerFrame.LoadSprite2 + 2
sta UpdateRangerFrame.LoadSprite3 + 2
sta UpdateRangerFrame.LoadSprite4 + 2
sta UpdateRangerFrame.StoreSprite1 + 2
sta UpdateRangerFrame.StoreSprite2 + 2
sta UpdateRangerFrame.StoreSprite3 + 2
sta UpdateRangerFrame.StoreSprite4 + 2
sta FiningInAction.FiningSprite + 2
// No need to update lobyte because ranger is always sprite 0
lda #SPRITES.RANGER_STANDING
LoadSprite1:
sta SPRITES.SPRITE_0
lda c64lib.SPRITE_0_X
sta HandleRangerMove.OLDX0
lda c64lib.SPRITE_0_Y
sta HandleRangerMove.OLDY0
lda c64lib.SPRITE_MSB_X
and #%00000001
sta HandleRangerMove.OLDXBIT
rts
}
* = * "Ranger StartNewLevel"
StartNewLevel: {
lda #0
sta c64lib.SPRITE_MSB_X
lda #80
sta c64lib.SPRITE_0_X
lda #64
sta c64lib.SPRITE_0_Y
rts
}
* = * "Ranger HandleRangerMove"
HandleRangerMove: {
jsr GetOnlyFirePress
lda FirePressed
cmp #$ff
bne !+
lda #0
sta IsFining
!:
lda IsFining
beq !+
jsr FiningInAction
jmp Done
!:
jsr BackgroundCollision
lda BackgroundCollision.Collision
beq NoCollision
lda FirePressed
cmp #$ff
bne !+
jsr Hud.IsScoreBiggerThanZero
lda Hud.IsScoreBiggerThanZero.BiggerThanZero
beq !+
SubPoints(0, 0, 0, 1)
jmp NoCollision
!:
// If there is collision, revert ranger position
lda OLDX0
sta c64lib.SPRITE_0_X
lda c64lib.SPRITE_MSB_X
ora OLDXBIT
sta c64lib.SPRITE_MSB_X
lda OLDY0
sta c64lib.SPRITE_0_Y
NoCollision:
// If there is no collision, save position
lda c64lib.SPRITE_0_X
sta OLDX0
lda c64lib.SPRITE_MSB_X
and #%00000001
sta OLDXBIT
lda c64lib.SPRITE_0_Y
sta OLDY0
lda Direction
beq CheckDirectionY
// Handle horizontal move
lda Direction
cmp #$ff
beq MoveToLeft
MoveToRight:
ldx c64lib.SPRITE_0_X // Moving to right
inx // Calculate new sprite x position
beq ToggleExtraBit // If zero then should toggle extra bit
lda c64lib.SPRITE_MSB_X // If non zero, check extra bit
and #$01
beq UpdateSpriteXPos // If extra bit not set, then update position
cpx #LIMIT_RIGHT
bcs CheckDirectionY // If extra bit set and new position is over right
jmp UpdateSpriteXPos // border, no movement allowed
ToggleExtraBit:
lda c64lib.SPRITE_MSB_X
eor #$01
sta c64lib.SPRITE_MSB_X
UpdateSpriteXPos:
stx c64lib.SPRITE_0_X
jmp CheckDirectionY
MoveToLeft:
lda c64lib.SPRITE_MSB_X // Moving to right, check extra bit
and #$01
bne TryToMoveLeft // If extra bit is set, then move allowed
ldx c64lib.SPRITE_0_X // Check if position is on left border
cpx #LIMIT_LEFT
bcc CheckDirectionY // If extra bit not set and x-position is not on
dex // left border, then move allowed
jmp UpdateSpriteXPos
TryToMoveLeft:
ldx c64lib.SPRITE_0_X // Calculate new position
dex
cpx #$ff
bne UpdateSpriteXPos // If position is $ff then extra bit must be
jmp ToggleExtraBit // toggled
CheckDirectionY:
lda DirectionY
beq UpdateRangerFrame
ldy c64lib.SPRITE_0_Y // Calculate new position
lda DirectionY
cmp #$ff
beq MoveToUp
MoveToDown:
iny
cpy #LIMIT_DOWN
bcs UpdateFrame
sty c64lib.SPRITE_0_Y
jmp UpdateFrame
MoveToUp:
dey
cpy #LIMIT_UP
bcc UpdateFrame
sty c64lib.SPRITE_0_Y
UpdateFrame:
jsr UpdateRangerFrame
Done:
rts
OLDX0: .byte $00
OLDXBIT: .byte $00
OLDY0: .byte $00
}
* = * "Ranger FiningInAction"
FiningInAction: {
dec IsFining
beq StopFining
lda #SPRITES.RANGER_FINING
jmp FiningSprite
StopFining:
lda #SPRITES.RANGER_STANDING
FiningSprite:
sta SPRITES.SPRITE_0
rts
}
* = * "Ranger UpdateRangerFrame"
UpdateRangerFrame: {
inc RangerFrame
lda RangerFrame
lsr
lsr
lsr
lsr
bcc NoMove
lda #$00
sta RangerFrame
lda Direction
beq CheckVerticalMove
cmp #$ff
beq Left
Right:
ldx #SPRITES.RANGER_STANDING + 5
LoadSprite1:
lda SPRITES.SPRITE_0
cmp #SPRITES.RANGER_STANDING + 6
beq RightUpdate
inx
jsr Sfx.Walkstep
RightUpdate:
// If right frame edit occours, no other frame switch will be performed
StoreSprite1:
stx SPRITES.SPRITE_0
jmp NoMove
Left:
ldx #SPRITES.RANGER_STANDING + 7
LoadSprite2:
lda SPRITES.SPRITE_0
cmp #SPRITES.RANGER_STANDING + 8
beq LeftUpdate
inx
jsr Sfx.Walkstep
LeftUpdate:
// If left frame edit occours, no other frame switch will be performed
StoreSprite2:
stx SPRITES.SPRITE_0
jmp NoMove
CheckVerticalMove:
lda DirectionY
beq NoMove
cmp #$ff
beq Up
Down:
ldx #SPRITES.RANGER_STANDING + 1
LoadSprite3:
lda SPRITES.SPRITE_0
cmp #SPRITES.RANGER_STANDING + 2
beq UpUpdate
inx
jsr Sfx.Walkstep
DownUpdate:
StoreSprite3:
stx SPRITES.SPRITE_0
jmp NoMove
Up:
ldx #SPRITES.RANGER_STANDING + 3
LoadSprite4:
lda SPRITES.SPRITE_0
cmp #SPRITES.RANGER_STANDING + 4
beq UpUpdate
inx
jsr Sfx.Walkstep
UpUpdate:
StoreSprite4:
stx SPRITES.SPRITE_0
NoMove:
rts
RangerFrame: .byte $ff
}
// If > 0 indicates that fining is in progress (remaining time)
// If == 0 indicates fining is done or never happened
IsFining: .byte $00
.label LIMIT_UP = $32
.label LIMIT_DOWN = $e0
.label LIMIT_LEFT = $16
.label LIMIT_RIGHT = $46
ScreenMemoryAddress: .byte $be
#import "_label.asm"
#import "_joystick.asm"
#import "_hud.asm"
#import "_utils.asm"
#import "_sounds.asm"
#import "chipset/lib/vic2.asm"