-
Notifications
You must be signed in to change notification settings - Fork 53
/
utilities.asm
446 lines (408 loc) · 14.4 KB
/
utilities.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
;================================================================================
; Utility Functions
;================================================================================
; GetSpriteTile
; in: A - Loot ID
; out: A - Sprite GFX ID
;--------------------------------------------------------------------------------
GetSpriteID:
JSL.l AttemptItemSubstitution
JSR.w ResolveLootID
CMP.b #$6D : BEQ .server_F0 ; Server Request F0
CMP.b #$6E : BEQ .server_F1 ; Server Request F1
CMP.b #$6F : BEQ .server_F2 ; Server Request F2
BRA .normal
.server_F0
JSL.l ItemVisualServiceRequest_F0
BRA .normal
.server_F1
JSL.l ItemVisualServiceRequest_F1
BRA .normal
.server_F2
JSL.l ItemVisualServiceRequest_F2
.normal
PHX
TAX : LDA.l ItemReceipts_graphics, X ; look up item gfx
PLX
RTL
;--------------------------------------------------------------------------------
; GetSpritePalette
; in: A - Loot ID
; out: A - Palette
;--------------------------------------------------------------------------------
GetSpritePalette:
JSL.l AttemptItemSubstitution
JSR.w ResolveLootID
.resolved
TAX
LDA.l SpriteProperties_standing_palette, X : BIT #$80 : BNE .load_palette
ASL
RTL
.load_palette
JSL.l LoadItemPalette
ASL
RTL
;--------------------------------------------------------------------------------
; PrepDynamicTile
; in: SpriteID,X - Loot ID
;-------------------------------------------------------------------------------- 20/8477
PrepDynamicTile:
PHX : PHY : PHB
JSR.w ResolveLootID
-
JSR.w LoadDynamicTileOAMTable
JSL TransferItemReceiptToBuffer_using_ReceiptID
SEP #$30
PLB : PLY : PLX
RTL
.loot_resolved
PHX : PHY : PHB
BRA -
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; LoadDynamicTileOAMTable
; in: SpriteID,X - Loot ID
; out: A - Loot ID
;-------------------------------------------------------------------------------- 20/847B
LoadDynamicTileOAMTable:
PHP
REP #$20
LDA.w #$0000 : STA.l SpriteOAM : STA.l SpriteOAM+2
LDA.w #$0200 : STA.l SpriteOAM+6
SEP #$20
LDA.b #$24 : STA.l SpriteOAM+4
LDA.w SpriteID,X
JSL.l GetSpritePalette_resolved
STA.l SpriteOAM+5 : STA.l SpriteOAM+13
PHX
LDA.l SpriteProperties_standing_width,X : BEQ .narrow
BRA .done
.narrow
REP #$20
LDA.w #$0400 : STA.l SpriteOAM+7 : STA.l SpriteOAM+14
LDA.w #$0000 : STA.l SpriteOAM+14
LDA.w #$0800 : STA.l SpriteOAM+9
LDA.w #$3400 : STA.l SpriteOAM+11
SEP #$20
LDA.b #$04 : STA.l SpriteOAM
.done
TXA
PLX
PLP
RTS
;--------------------------------------------------------------------------------
; DrawDynamicTile
; in: A - Loot ID
; out: A - OAM Slots Taken
;--------------------------------------------------------------------------------
; This wastes two OAM slots if you don't want a shadow - fix later - I wrote "fix later" over a year ago and it's still not fixed (Aug 6, 2017) - lol (May 25th, 2019)
;-------------------------------------------------------------------------------- 2084B8
DrawDynamicTile:
PHX
TAX
LDA.l SpriteProperties_standing_width,X : BEQ .narrow
.full
PLX
LDA.b #$01 : STA.b Scrap06
LDA.b #$0C : JSL.l OAM_AllocateFromRegionC
LDA.b #$02 : PHA
BRA .draw
.narrow
PLX
LDA.b #$02 : STA.b Scrap06
LDA.b #$10 : JSL.l OAM_AllocateFromRegionC
LDA.b #$03 : PHA
.draw
LDA.b #SpriteOAM>>0 : STA.b Scrap08
LDA.b #SpriteOAM>>8 : STA.b Scrap09
STZ.b Scrap07
LDA.b #$7E : PHB : PHA : PLB
LDA.b #$01 : STA.l SpriteSkipEOR
JSL Sprite_DrawMultiple_quantity_preset
LDA.b #$00 : STA.l SpriteSkipEOR
PLB
LDA.b OAMPtr : !ADD.b #$08 : STA.b OAMPtr ; leave the pointer in the right spot to draw the shadow, if desired
LDA.b OAMPtr+2 : INC #2 : STA.b OAMPtr+2
PLA
RTL
;--------------------------------------------------------------------------------
DrawDynamicTileNoShadow:
PHX
TAX
LDA.l SpriteProperties_standing_width,X : BEQ .narrow
.full
PLX
LDA.b #$01 : STA.b Scrap06
LDA.b #$04 : JSL.l OAM_AllocateFromRegionC
BRA .draw
.narrow
PLX
LDA.b #$02 : STA.b Scrap06
LDA.b #$08 : JSL.l OAM_AllocateFromRegionC
.draw
LDA.b #SpriteOAM>>0 : STA.b Scrap08
LDA.b #SpriteOAM>>8 : STA.b Scrap09
STZ.b Scrap07
LDA.b #$7E : PHB : PHA : PLB
LDA.b #$01 : STA.l SpriteSkipEOR
JSL Sprite_DrawMultiple_quantity_preset
LDA.l Bob : BNE + : LDA.b #$00 : STA.l SpriteSkipEOR : + ; Bob fix is conditional
PLB
LDA.b OAMPtr : !ADD.b #$08 : STA.b OAMPtr
LDA.b OAMPtr+2 : INC #2 : STA.b OAMPtr+2
RTL
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
LoadModifiedTileBufferAddress:
PHA
LDA.l TileUploadOffsetOverride : BEQ +
TAX
LDY.w #$0002
LDA.w #$0000 : STA.l TileUploadOffsetOverride
BRA .done
+
LDX.w #$2D40
LDY.w #$0002
.done
PLA
RTL
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; Sprite_IsOnscreen
; in: X - Sprite Slot
; out: Carry - 1 = On Screen, 0 = Off Screen
;--------------------------------------------------------------------------------
Sprite_IsOnscreen:
JSR .check_sprite
BCS +
REP #$20
LDA.b BG2H : PHA : !SUB.w #$0F : STA.b BG2H
LDA.b BG2V : PHA : !SUB.w #$0F : STA.b BG2V
SEP #$20
JSR .check_sprite
REP #$20
PLA : STA.b BG2V
PLA : STA.b BG2H
SEP #$20
+
RTL
.check_sprite
LDA.w SpritePosXLow, X : CMP.b BG2H
LDA.w SpritePosXHigh, X : SBC.b BG2H+1 : BNE .offscreen
LDA.w SpritePosYLow, X : CMP.b BG2V
LDA.w SpritePosYHigh, X : SBC.b BG2V+1 : BNE .offscreen
SEC
RTS
.offscreen
CLC
RTS
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; Sprite_GetScreenRelativeCoords:
; out: $00.w Sprite Y
; out: $02.w Sprite X
; out: $06.b Sprite Y Relative
; out: $07.b Sprite X Relative
;--------------------------------------------------------------------------------
; Copied from bank $06
;--------------------------------------------------------------------------------
Sprite_GetScreenRelativeCoords:
STY.b Scrap0B
STA.b Scrap08
LDA.w SpritePosYLow, X : STA.b Scrap00
!SUB.b BG2V : STA.b Scrap06
LDA.w SpritePosYHigh, X : STA.b Scrap01
LDA.w SpritePosXLow, X : STA.b Scrap02
!SUB.b BG2H : STA.b Scrap07
LDA.w SpritePosXHigh, X : STA.b Scrap03
RTL
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; SkipDrawEOR - Shims in Bank05.asm : 2499
;--------------------------------------------------------------------------------
SkipDrawEOR:
LDA.l SpriteSkipEOR : BEQ .normal
LDA.w #$0000 : STA.l SpriteSkipEOR
LDA.w #$0F00 : TRB.b Scrap04
.normal
LDA.b ($08), Y : EOR.w Scrap04 ; thing we wrote over
RTL
;--------------------------------------------------------------------------------
; WriteVRAMStripe
; in: A(w) - VRAM Destination
; in: X(w) - Length in Tiles
; in: Y(w) - Word to Write
;--------------------------------------------------------------------------------
WriteVRAMStripe:
PHX
LDX.w GFXStripes ; get pointer
AND.w #$7F : STA.w GFXStripes+2, X : INX #2 ; set destination
PLA : ASL : AND.w #$7FFF : ORA.w #$7000 : STA.w GFXStripes+2, X : INX #2 ; set length and enable RLE
TYA : STA.w GFXStripes+2, X : INX #2 ; set tile
SEP #$20 ; set 8-bit accumulator
LDA.b #$FF : STA.w GFXStripes+2, X
STX.w GFXStripes
LDA.b #01 : STA.b NMISTRIPES
REP #$20 ; set 16-bit accumulator
RTL
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; WriteVRAMBlock
; in: A(w) - VRAM Destination
; in: X(w) - Length in Tiles
; in: Y(w) - Address of Data to Copy
;--------------------------------------------------------------------------------
WriteVRAMBlock:
PHX
LDX.w GFXStripes ; get pointer
AND.w #$7F : STA.w GFXStripes+2, X : INX #2 ; set destination
PLA : ASL : AND.w #$3FFF : STA.w GFXStripes+2, X : INX #2 ; set length
PHX
TYX ; set X to source
PHA
TXA : !ADD #$1002 : TAY ; set Y to dest
PLA
;A is already the value we need for mvn
MVN $7F7E ; currently we transfer from our buffers in 7F to the vram buffer in 7E
!ADD 1, s ; add the length in A to the stack pointer on the top of the stack
PLX : TAX ; pull and promptly ignore, copying the value we just got over it
SEP #$20 ; set 8-bit accumulator
LDA.b #$FF : STA.w GFXStripes+$02, X
STX.w GFXStripes
LDA.b #01 : STA.w NMISTRIPES
REP #$20 ; set 16-bit accumulator
RTL
;--------------------------------------------------------------------------------
;Byte 1 byte 2 Byte 3 byte 4
;Evvvvvvv vvvvvvv DRllllll llllllll
;
;E if set indicates that this is not a header, but instead is the terminator byte. Only the topmost bit matters in that case.
;The v's form a vram address.
;if D is set, the dma will increment the vram address by a row per word, instead of incrementing by a column (1).
;R if set enables a run length encoding feature
;the l's are the number of bytes to upload minus 1 (don't forget this -1, it is important)
;
;This is then followed by the bytes to upload, in normal format.
;RLE feature:
;This feature makes it easy to draw the same tile repeatedly. If this bit is set, the length bits should be set to 2 times the number of copies of the tile to upload. (Without subtracting 1!)
;It is followed by a single tile (word). Combining this this with the D bit makes it easy to draw large horizontal or vertical runs of a tile without using much space. Geat for erasing or drawing horizontal or verical box edges.
;================================================================================
DynamicDrawCleanup:
PHA
REP #$20
LDA.w #$F000
STA.w OAMBuffer
STA.w OAMBuffer+$04
STA.w OAMBuffer+$08
STA.w OAMBuffer+$0C
STZ.w OAMBuffer+$02
STZ.w OAMBuffer+$06
STZ.w OAMBuffer+$0A
STZ.w OAMBuffer+$0E
SEP #$20
PLA
RTL
;------------------------------------------------------------------------------
CheckReceivedItemPropertiesBeforeLoad:
PHX
LDX.w CurrentSpriteSlot
LDA.w AncillaID,X : CMP.b #$29 : BEQ .falling_sprite
PLX
LDA.b RoomIndex : BEQ .normalCode
LDA.l RoomFade : BNE .load_palette
.normalCode
LDA.l SpriteProperties_chest_palette,X : BIT #$80 : BNE .load_palette
RTL
.load_palette
JSL.l LoadItemPalette
RTL
.falling_sprite
PLX
LDA.l SpriteProperties_standing_palette,X : BIT #$80 : BNE .load_palette
RTL
;------------------------------------------------------------------------------
LoadItemPalette:
; In: X - Loot ID
; Out: A - Sprite palette index
PHX : PHY : PHB
LDA.b #PalettesVanillaBank>>16 : STA.b Scrap0C
PEA $7E00
PLB : PLB
REP #$30
TXA : ASL : TAX
LDA.l SpriteProperties_palette_addr,X : STA.b Scrap0A
LDY.w #$000E
JSR.w AuxPaletteCheck : BCS .aux
LDA.w TransparencyFlag : BNE .SP05
-
LDA.b [Scrap0A], Y
STA.w PaletteBuffer+$0170,Y
DEY #2
BPL -
LDA.w #$0003
BRA .done
.SP05
-
LDA.b [Scrap0A], Y
STA.w PaletteBuffer+$01B0,Y
DEY #2
BPL -
LDA.w #$0005
.done
SEP #$30
PLB : PLY : PLX
INC.b NMICGRAM
RTL
.aux
LDA.w TransparencyFlag : BNE .SP05_aux
-
LDA.b [Scrap0A], Y
STA.w PaletteBufferAux+$0170,Y
DEY #2
BPL -
LDA.w #$0003
BRA .done
.SP05_aux
-
LDA.b [Scrap0A], Y
STA.w PaletteBufferAux+$01B0,Y
DEY #2
BPL -
LDA.w #$0005
BRA .done
TransferVRAMStripes:
JSL.l TransferNewNameStripes
JSL.l DoDungeonMapBossIcon
LDA.b NMISTRIPES : CMP.b #$01 ; What we wrote over
RTL
ItemReceiptWidthCheck:
PHX
LDX.w CurrentSpriteSlot
LDA.w AncillaID,X : CMP.b #$29 : BEQ .falling_sprite
PLX
LDA.l SpriteProperties_chest_width, X
RTL
.falling_sprite
PLX
LDA.l SpriteProperties_standing_width, X
RTL
AuxPaletteCheck:
; Out: c - write to aux palette buffer if set, main buffer if unset.
;
; We have to put an item's palette in the aux buffer in rooms where standing
; item gfx are loaded in the middle of a fade-in/out such as the spiral staircase
; fade for GT torch room and the Hera cage.
PHX
SEP #$30
LDA.w ItemReceiptMethod : BNE .main_buffer ; Never use aux if we're actually receiving an item
LDA.w RoomIndex : CMP.b #$8C : BEQ .aux_buffer ; GT torch/Hope room
LDA.w RoomIndex : CMP.b #$87 : BEQ .aux_buffer ; Hera cage/basement
.main_buffer
REP #$31
PLX
RTS
.aux_buffer
SEC
REP #$30
PLX
RTS