-
Notifications
You must be signed in to change notification settings - Fork 0
/
blender.asm
269 lines (228 loc) · 4.38 KB
/
blender.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
.export BlenderConstructor
.export BlenderExecute
.export BlenderDraw
.include "include.branch-macros.asm"
.include "include.mov-macros.asm"
.include "include.sprites.asm"
.include "include.tiles.asm"
.include "object_list.h.asm"
.include "sprite_space.h.asm"
.include "trash_gunk.h.asm"
.include "shared_object_values.asm"
.include "draw_picture.h.asm"
.include "hurt_player.h.asm"
.import parabola_movement
.importzp camera_h, camera_screen
.importzp draw_screen, draw_h, draw_v, draw_frame
.importzp player_v, player_h, player_screen
.importzp player_iframe
.importzp elec_sfx
.importzp values
AGGRO_DISTANCE = $40
BLENDER_STATE_NORMAL = 0
BLENDER_STATE_VOLATILE = 1
BLENDER_STATE_JUMP = 2
BLENDER_STATE_EMPTY = 3
orig_h = values + $00
.import object_data_extend
blender_state = object_data_extend + $00
blender_count = object_data_extend + $10
blender_orig_v = object_data_extend + $30
.segment "CODE"
.proc BlenderConstructor
mov {blender_state,x}, #0
mov {blender_count,x}, _
mov {blender_orig_v,x}, {object_v,x}
rts
.endproc
.proc BlenderExecute
.scope MaybeDespawn
jsr ObjectOffscreenDespawn
bcc Okay
rts
Okay:
.endscope
.scope MaybeBecomeVolatile
; If not in state normal, skip me.
lda blender_state,x
bne Next
; Check distance from player.
lda object_h,x
sec
sbc player_h
sta delta_h
lda object_screen,x
sbc player_screen
bmi Negative
beq HaveDelta
bpl Next
Negative:
lda delta_h
eor #$ff
sta delta_h
HaveDelta:
lda delta_h
cmp #AGGRO_DISTANCE
bge Next
IsClose:
mov {blender_state,x}, #BLENDER_STATE_VOLATILE
mov {blender_count,x}, #0
Next:
.endscope
.scope HandleVolatility
lda blender_state,x
cmp #BLENDER_STATE_VOLATILE
bne Next
inc blender_count,x
lda blender_count,x
cmp #$20
bne Next
; Next state
mov {blender_state,x}, #BLENDER_STATE_JUMP
mov {blender_count,x}, #0
; Create gunk, a bit higher than actual blender position.
lda object_v,x
pha
sec
sbc #$18
sta object_v,x
ldy #0
jsr TrashGunkSpawnTwoInOppositeDirections
pla
sta object_v,x
Next:
.endscope
.scope HandleJump
lda blender_state,x
cmp #BLENDER_STATE_JUMP
bne Next
ldy blender_count,x
inc blender_count,x
lda parabola_movement,y
beq Complete
clc
adc blender_orig_v,x
sta object_v,x
bne Next
Complete:
mov {object_v,x}, {blender_orig_v,x}
mov {blender_state,x}, #BLENDER_STATE_EMPTY
Next:
.endscope
.scope CollisionWithPlayer
lda player_iframe
bne Next
jsr ObjectCollisionWithPlayer
bcc Next
DidCollide:
ldy #2
jsr HurtPlayer
Next:
.endscope
Draw:
; Draw position.
mov draw_v, {object_v,x}
lda object_h,x
sec
sbc camera_h
sta draw_h
lda object_screen,x
sbc camera_screen
sta draw_screen
jne Return
; Handle state drawing differences.
.scope DrawStateChange
lda blender_state,x
beq Next
cmp #BLENDER_STATE_VOLATILE
beq Volatile
; TODO: More states
bne Next
Volatile:
lda blender_count,x
and #$2
beq ShakeLeft
ShakeRight:
; TODO: Screen
inc draw_h
jmp Next
ShakeLeft:
dec draw_h
Next:
.endscope
mov orig_h, draw_h
lda blender_state,x
asl a
tay
; Left side.
jsr SpriteSpaceAllocate
lda draw_v
sta sprite_v,x
lda draw_h
sta sprite_h,x
lda blender_animation,y
sta sprite_tile,x
lda #$02
sta sprite_attr,x
lda draw_h
clc
adc #8
sta draw_h
bcs Return
iny
; Right side.
jsr SpriteSpaceAllocate
lda draw_v
sta sprite_v,x
lda draw_h
sta sprite_h,x
lda blender_animation,y
sta sprite_tile,x
lda #$02
sta sprite_attr,x
mov draw_h, orig_h
lda draw_v
sec
sbc #16
sta draw_v
; If jump or empty state, don't draw the top of the blender.
cpy #4
bge Return
; Top left
jsr SpriteSpaceAllocate
lda draw_v
sta sprite_v,x
lda draw_h
sta sprite_h,x
lda #BLENDER_TOP_TILE
sta sprite_tile,x
lda #$00
sta sprite_attr,x
lda draw_h
clc
adc #8
sta draw_h
bcs Return
; Top right.
jsr SpriteSpaceAllocate
lda draw_v
sta sprite_v,x
lda draw_h
sta sprite_h,x
lda #BLENDER_TOP_TILE
sta sprite_tile,x
lda #$40
sta sprite_attr,x
Return:
rts
.endproc
BlenderDraw = BlenderExecute::Draw
blender_animation:
.byte BLENDER_FULL_TILE_0 ; normal
.byte BLENDER_FULL_TILE_1 ; normal
.byte BLENDER_FULL_TILE_0 ; volatile
.byte BLENDER_FULL_TILE_1 ; volatile
.byte BLENDER_JUMP_TILE_0 ; jump
.byte BLENDER_JUMP_TILE_1 ; jump
.byte BLENDER_EMPTY_TILE_0 ; empty
.byte BLENDER_EMPTY_TILE_1 ; empty