Merge pull request #429 from octorock/vram

This commit is contained in:
notyourav 2022-03-06 03:07:55 -08:00 committed by GitHub
commit 1724325cb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 861 additions and 33 deletions

View File

@ -0,0 +1,91 @@
.syntax unified
.ifdef EU
push {r4, r5, r6, lr}
adds r6, r0, #0
adds r5, r1, #0
adds r4, r2, #0
cmp r4, #0
bne _080AD79C
adds r0, r5, #0
bl FindFreeGFXSlots
adds r4, r0, #0
cmp r4, #0
beq _080AD7C4
_080AD79C:
ldr r0, _080AD7D0 @ =gGFXSlots
lsls r1, r4, #1
adds r1, r1, r4
lsls r1, r1, #2
adds r1, r1, r0
ldrb r0, [r1, #4]
lsls r0, r0, #0x1c
lsrs r2, r0, #0x1c
cmp r2, #6
beq _080AD7BC
adds r0, r4, #0
movs r1, #0
adds r2, r5, #0
bl ReserveGFXSlots
movs r2, #5
_080AD7BC:
adds r0, r4, #0
adds r1, r6, #0
bl sub_080AE0C8
_080AD7C4:
adds r0, r4, #0
cmp r0, #0
beq _080AD7CC
movs r0, #1
_080AD7CC:
pop {r4, r5, r6, pc}
.align 2, 0
_080AD7D0: .4byte gGFXSlots
.else
push {r4, r5, r6, lr}
adds r6, r0, #0
adds r5, r1, #0
adds r4, r2, #0
cmp r4, #0
bne _080AE030
adds r0, r5, #0
bl FindFreeGFXSlots
adds r4, r0, #0
cmp r4, #0
bne _080AE030
bl CleanUpGFXSlots
adds r0, r5, #0
bl FindFreeGFXSlots
adds r4, r0, #0
cmp r4, #0
beq _080AE058
_080AE030:
ldr r0, _080AE064 @ =gGFXSlots
lsls r1, r4, #1
adds r1, r1, r4
lsls r1, r1, #2
adds r1, r1, r0
ldrb r0, [r1, #4]
lsls r0, r0, #0x1c
lsrs r2, r0, #0x1c
cmp r2, #6
beq _080AE050
adds r0, r4, #0
movs r1, #0
adds r2, r5, #0
bl ReserveGFXSlots
movs r2, #5
_080AE050:
adds r0, r4, #0
adds r1, r6, #0
bl sub_080AE0C8
_080AE058:
adds r0, r4, #0
cmp r0, #0
beq _080AE060
movs r0, #1
_080AE060:
pop {r4, r5, r6, pc}
.align 2, 0
_080AE064: .4byte gGFXSlots
.endif
.syntax divided

View File

@ -0,0 +1,39 @@
.syntax unified
push {lr}
adds r2, r1, #0
lsls r1, r0, #1
adds r1, r1, r0
lsls r1, r1, #2
ldr r0, _080ADDFC @ =gUnk_02024494
adds r3, r1, r0
ldr r0, _080ADE00 @ =0x00FFFFFC
ands r0, r2
ldr r1, _080ADE04 @ =gGlobalGfxAndPalettes
adds r0, r0, r1
str r0, [r3, #8]
movs r0, #1
ands r0, r2
cmp r0, #0
beq _080ADE0C
ldr r0, _080ADE08 @ =0x0000FFFF
b _080ADE14
.align 2, 0
_080ADDFC: .4byte gUnk_02024494
_080ADE00: .4byte 0x00FFFFFC
_080ADE04: .4byte gGlobalGfxAndPalettes
_080ADE08: .4byte 0x0000FFFF
_080ADE0C:
movs r0, #0xfe
lsls r0, r0, #0x17
ands r0, r2
lsrs r0, r0, #0x14
_080ADE14:
strh r0, [r3, #6]
ldrb r0, [r3]
movs r1, #0xf
ands r1, r0
movs r0, #0x30
orrs r1, r0
strb r1, [r3]
pop {pc}
.syntax divided

View File

@ -0,0 +1,135 @@
.syntax unified
push {r4, r5, r6, lr}
adds r2, r0, #0
lsls r0, r2, #1
adds r0, r0, r2
lsls r0, r0, #2
ldr r1, _080ADF00 @ =gUnk_02024494
adds r3, r0, r1
ldrb r1, [r3]
movs r0, #0xf0
ands r0, r1
cmp r0, #0
beq _080ADF7C
movs r0, #0xf
ands r0, r1
movs r1, #0x10
orrs r0, r1
strb r0, [r3]
ldrh r1, [r3, #6]
ldr r0, _080ADF04 @ =0x0000FFFF
cmp r1, r0
beq _080ADF18
ldrb r0, [r3, #3]
cmp r0, #0
beq _080ADF18
lsls r0, r0, #6
ldr r1, _080ADF08 @ =gUnk_020000C0
adds r4, r0, r1
movs r5, #4
movs r6, #9
rsbs r6, r6, #0
_080ADEB0:
ldrb r1, [r4]
movs r0, #4
ands r0, r1
cmp r0, #0
beq _080ADEF6
ldr r0, _080ADF0C @ =gGFXSlots
ldrb r0, [r0, #3]
cmp r0, #0
bne _080ADECA
movs r0, #8
ands r0, r1
cmp r0, #0
beq _080ADEF6
_080ADECA:
adds r0, r6, #0
ands r0, r1
strb r0, [r4]
ldrb r0, [r4, #9]
lsls r2, r0, #5
cmp r2, #0
beq _080ADEF6
ldrh r0, [r4, #0xa]
lsls r0, r0, #5
ldr r3, _080ADF10 @ =0x06010000
adds r1, r0, r3
ldr r3, _080ADF14 @ =0x040000D4
ldr r0, [r4, #0xc]
str r0, [r3]
str r1, [r3, #4]
adds r0, r2, #0
asrs r0, r0, #2
movs r1, #0x84
lsls r1, r1, #0x18
orrs r0, r1
str r0, [r3, #8]
ldr r0, [r3, #8]
_080ADEF6:
adds r4, #0x10
subs r5, #1
cmp r5, #0
bgt _080ADEB0
b _080ADF7C
.align 2, 0
_080ADF00: .4byte gUnk_02024494
_080ADF04: .4byte 0x0000FFFF
_080ADF08: .4byte gUnk_020000C0
_080ADF0C: .4byte gGFXSlots
_080ADF10: .4byte 0x06010000
_080ADF14: .4byte 0x040000D4
_080ADF18:
lsls r0, r2, #9
ldr r2, _080ADF4C @ =0x06012800
adds r1, r0, r2
ldrh r2, [r3, #6]
cmp r2, #0
beq _080ADF58
ldr r0, _080ADF50 @ =0x0000FFFF
cmp r2, r0
beq _080ADF62
ldr r2, _080ADF54 @ =0x040000D4
ldr r0, [r3, #8]
str r0, [r2]
str r1, [r2, #4]
ldrh r0, [r3, #6]
lsls r0, r0, #3
movs r1, #0x84
lsls r1, r1, #0x18
orrs r0, r1
str r0, [r2, #8]
ldr r0, [r2, #8]
ldrh r2, [r3, #6]
subs r2, #0x10
cmp r2, #0
ble _080ADF7C
b _080ADF70
.align 2, 0
_080ADF4C: .4byte 0x06012800
_080ADF50: .4byte 0x0000FFFF
_080ADF54: .4byte 0x040000D4
_080ADF58:
ldrb r1, [r3]
movs r0, #0xf
ands r0, r1
strb r0, [r3]
b _080ADF7C
_080ADF62:
ldrb r0, [r3, #3]
cmp r0, #0
bne _080ADF7C
ldr r0, [r3, #8]
bl LZ77UnCompVram
b _080ADF7C
_080ADF70:
adds r3, #0xc
movs r0, #0
strh r0, [r3, #6]
subs r2, #0x10
cmp r2, #0
bgt _080ADF70
_080ADF7C:
pop {r4, r5, r6, pc}
.align 2, 0
.syntax divided

View File

@ -0,0 +1,138 @@
.syntax unified
push {r4, r5, r6, r7, lr}
mov r7, sl
mov r6, sb
mov r5, r8
push {r5, r6, r7}
mov sl, r0
mov r8, r1
lsls r0, r1, #4
movs r1, #0xa0
lsls r1, r1, #1
adds r0, r0, r1
mov ip, r0
mov r2, sl
lsls r0, r2, #4
adds r3, r0, r1
ldr r1, _080AE30C @ =gGFXSlots
lsls r0, r2, #1
add r0, sl
lsls r0, r0, #2
adds r0, r0, r1
ldrb r0, [r0, #5]
lsls r0, r0, #4
adds r7, r3, r0
movs r4, #0
ldr r6, _080AE310 @ =gUnk_020000C0
mov sb, r6
ldr r0, _080AE314 @ =gPlayerEntity
adds r2, r0, #0
adds r2, #0x26
adds r5, r0, #0
_080AE254:
ldr r0, [r5, #4]
cmp r0, #0
beq _080AE276
ldrb r0, [r2]
cmp sl, r0
bne _080AE264
mov r1, r8
strb r1, [r2]
_080AE264:
ldrh r0, [r2, #0x3a]
cmp r3, r0
bhi _080AE276
cmp r7, r0
bls _080AE276
subs r0, r0, r3
mov r6, ip
adds r1, r0, r6
strh r1, [r2, #0x3a]
_080AE276:
adds r2, #0x88
adds r5, #0x88
adds r4, #1
cmp r4, #0x4f
bls _080AE254
movs r0, #0
_080AE282:
movs r4, #0
adds r1, r0, #1
mov r8, r1
lsls r5, r0, #6
_080AE28A:
lsls r0, r4, #4
add r0, sb
adds r2, r5, r0
ldrb r1, [r2]
movs r0, #1
ands r0, r1
cmp r0, #0
beq _080AE2B4
movs r0, #2
ands r0, r1
cmp r0, #0
bne _080AE2B4
ldrh r1, [r2, #0xa]
cmp r3, r1
bhi _080AE2B4
cmp r7, r1
bls _080AE2B4
subs r0, r1, r3
mov r6, ip
adds r1, r0, r6
strh r1, [r2, #0xa]
_080AE2B4:
adds r4, #1
cmp r4, #3
bls _080AE28A
mov r0, r8
cmp r0, #0x2f
bls _080AE282
movs r4, #0
ldr r0, _080AE318 @ =0xFFFFFC00
mov sl, r0
ldr r5, _080AE31C @ =gOAMControls
adds r5, #0x24
ldr r1, _080AE320 @ =0x000003FF
mov sb, r1
movs r2, #1
mov r8, r2
_080AE2D2:
ldrh r2, [r5]
lsls r0, r2, #0x16
lsrs r1, r0, #0x16
cmp r3, r1
bhi _080AE2F8
cmp r7, r1
bls _080AE2F8
subs r0, r1, r3
mov r6, ip
adds r1, r0, r6
mov r0, sb
ands r1, r0
mov r0, sl
ands r0, r2
orrs r0, r1
strh r0, [r5]
mov r2, r8
ldr r1, _080AE31C @ =gOAMControls
strb r2, [r1]
_080AE2F8:
adds r5, #8
adds r4, #1
cmp r4, #0x7f
bls _080AE2D2
pop {r3, r4, r5}
mov r8, r3
mov sb, r4
mov sl, r5
pop {r4, r5, r6, r7, pc}
.align 2, 0
_080AE30C: .4byte gGFXSlots
_080AE310: .4byte gUnk_020000C0
_080AE314: .4byte gPlayerEntity
_080AE318: .4byte 0xFFFFFC00
_080AE31C: .4byte gOAMControls
_080AE320: .4byte 0x000003FF
.syntax divided

View File

@ -0,0 +1,50 @@
.syntax unified
push {r4, r5, r6, r7, lr}
mov r7, r8
push {r7}
adds r3, r1, #0
ldr r2, _080AE380 @ =gGFXSlots
lsls r1, r0, #1
adds r1, r1, r0
lsls r1, r1, #2
adds r5, r1, r2
ldrb r4, [r5, #5]
subs r4, #1
movs r0, #1
rsbs r0, r0, #0
cmp r4, r0
beq _080AE372
lsls r0, r3, #1
adds r0, r0, r3
lsls r0, r0, #2
adds r0, r0, r2
mov r8, r0
adds r0, r1, #4
adds r6, r0, r2
_080AE350:
mov r0, r8
adds r0, #4
adds r1, r5, #4
ldm r1!, {r2, r3, r7}
stm r0!, {r2, r3, r7}
adds r0, r6, #0
movs r1, #0xc
bl MemClear
adds r6, #0xc
adds r5, #0xc
movs r0, #0xc
add r8, r0
subs r4, #1
subs r0, #0xd
cmp r4, r0
bne _080AE350
_080AE372:
ldr r1, _080AE380 @ =gGFXSlots
movs r0, #1
strb r0, [r1, #3]
pop {r3}
mov r8, r3
pop {r4, r5, r6, r7, pc}
.align 2, 0
_080AE380: .4byte gGFXSlots
.syntax divided

View File

@ -395,7 +395,7 @@ _080AD72C:
ands r0, r7 ands r0, r7
lsrs r6, r0, #0x18 lsrs r6, r0, #0x18
adds r0, r6, #0 adds r0, r6, #0
bl FindFreeGFXSlot bl FindFreeGFXSlots
adds r4, r0, #0 adds r4, r0, #0
cmp r4, #0 cmp r4, #0
beq _080AD77C beq _080AD77C
@ -450,13 +450,13 @@ _080ADF94:
ands r0, r1 ands r0, r1
lsrs r6, r0, #0x18 lsrs r6, r0, #0x18
adds r0, r6, #0 adds r0, r6, #0
bl FindFreeGFXSlot bl FindFreeGFXSlots
adds r5, r0, #0 adds r5, r0, #0
cmp r5, #0 cmp r5, #0
bne _080ADFDC bne _080ADFDC
bl CleanUpGFXSlots bl CleanUpGFXSlots
adds r0, r6, #0 adds r0, r6, #0
bl FindFreeGFXSlot bl FindFreeGFXSlots
adds r5, r0, #0 adds r5, r0, #0
cmp r5, #0 cmp r5, #0
bne _080ADFDC bne _080ADFDC
@ -500,7 +500,7 @@ LoadSwapGFX: @ 0x080AE008
cmp r4, #0 cmp r4, #0
bne _080AD79C bne _080AD79C
adds r0, r5, #0 adds r0, r5, #0
bl FindFreeGFXSlot bl FindFreeGFXSlots
adds r4, r0, #0 adds r4, r0, #0
cmp r4, #0 cmp r4, #0
beq _080AD7C4 beq _080AD7C4
@ -542,13 +542,13 @@ _080AD7D0: .4byte gGFXSlots
cmp r4, #0 cmp r4, #0
bne _080AE030 bne _080AE030
adds r0, r5, #0 adds r0, r5, #0
bl FindFreeGFXSlot bl FindFreeGFXSlots
adds r4, r0, #0 adds r4, r0, #0
cmp r4, #0 cmp r4, #0
bne _080AE030 bne _080AE030
bl CleanUpGFXSlots bl CleanUpGFXSlots
adds r0, r5, #0 adds r0, r5, #0
bl FindFreeGFXSlot bl FindFreeGFXSlots
adds r4, r0, #0 adds r4, r0, #0
cmp r4, #0 cmp r4, #0
beq _080AE058 beq _080AE058
@ -583,8 +583,8 @@ _080AE060:
_080AE064: .4byte gGFXSlots _080AE064: .4byte gGFXSlots
.endif .endif
thumb_func_start sub_080AE068 thumb_func_start UnloadGFXSlots
sub_080AE068: @ 0x080AE068 UnloadGFXSlots: @ 0x080AE068
push {r4, r5, lr} push {r4, r5, lr}
adds r0, #0x26 adds r0, #0x26
ldrb r2, [r0] ldrb r2, [r0]
@ -664,7 +664,7 @@ sub_080AE0C8: @ 0x080AE0C8
_080AE0F6: _080AE0F6:
adds r0, r1, #0 adds r0, r1, #0
adds r1, r4, #0 adds r1, r4, #0
bl sub_080AE134 bl SetGFXSlotStatus
pop {r4, pc} pop {r4, pc}
.align 2, 0 .align 2, 0
_080AE100: .4byte gUnk_02024494 _080AE100: .4byte gUnk_02024494
@ -688,13 +688,13 @@ ReserveGFXSlots: @ 0x080AE104
strh r6, [r4, #4] strh r6, [r4, #4]
adds r0, r4, #0 adds r0, r4, #0
movs r1, #4 movs r1, #4
bl sub_080AE134 bl SetGFXSlotStatus
pop {r4, r5, r6, pc} pop {r4, r5, r6, pc}
.align 2, 0 .align 2, 0
_080AE130: .4byte gUnk_02024494 _080AE130: .4byte gUnk_02024494
thumb_func_start sub_080AE134 thumb_func_start SetGFXSlotStatus
sub_080AE134: @ 0x080AE134 SetGFXSlotStatus: @ 0x080AE134
push {r4, r5, r6, lr} push {r4, r5, r6, lr}
adds r3, r0, #0 adds r3, r0, #0
adds r4, r1, #0 adds r4, r1, #0
@ -731,8 +731,8 @@ _080AE170:
pop {r4, r5, r6, pc} pop {r4, r5, r6, pc}
.align 2, 0 .align 2, 0
thumb_func_start FindFreeGFXSlot thumb_func_start FindFreeGFXSlots
FindFreeGFXSlot: @ 0x080AE174 FindFreeGFXSlots: @ 0x080AE174
push {r4, lr} push {r4, lr}
adds r4, r0, #0 adds r4, r0, #0
movs r1, #0 movs r1, #0
@ -807,7 +807,7 @@ CleanUpGFXSlots: @ 0x080AE1D8
.align 2, 0 .align 2, 0
_080AE1E8: .4byte gGFXSlots _080AE1E8: .4byte gGFXSlots
_080AE1EC: _080AE1EC:
bl sub_080AE3B8 bl FindFirstFreeGFXSlot
adds r4, r0, #0 adds r4, r0, #0
cmp r4, r5 cmp r4, r5
bhi _080AE208 bhi _080AE208
@ -822,7 +822,7 @@ _080AE208:
adds r5, #1 adds r5, #1
_080AE20A: _080AE20A:
adds r0, r5, #0 adds r0, r5, #0
bl sub_080AE384 bl FindNextOccupiedGFXSlot
adds r5, r0, #0 adds r5, r0, #0
cmp r5, #0 cmp r5, #0
bne _080AE1EC bne _080AE1EC
@ -1019,8 +1019,8 @@ _080AE372:
.align 2, 0 .align 2, 0
_080AE380: .4byte gGFXSlots _080AE380: .4byte gGFXSlots
thumb_func_start sub_080AE384 thumb_func_start FindNextOccupiedGFXSlot
sub_080AE384: @ 0x080AE384 FindNextOccupiedGFXSlot: @ 0x080AE384
push {lr} push {lr}
adds r2, r0, #0 adds r2, r0, #0
cmp r2, #0x2a cmp r2, #0x2a
@ -1052,8 +1052,8 @@ _080AE3B4:
_080AE3B6: _080AE3B6:
pop {pc} pop {pc}
thumb_func_start sub_080AE3B8 thumb_func_start FindFirstFreeGFXSlot
sub_080AE3B8: @ 0x080AE3B8 FindFirstFreeGFXSlot: @ 0x080AE3B8
push {lr} push {lr}
movs r1, #4 movs r1, #4
ldr r0, _080AE3D4 @ =gGFXSlots ldr r0, _080AE3D4 @ =gGFXSlots

View File

@ -25,6 +25,7 @@ typedef struct {
union SplitWord unk_08; union SplitWord unk_08;
u32 unk_0C; u32 unk_0C;
} struct_gUnk_020000C0_1; } struct_gUnk_020000C0_1;
typedef struct { typedef struct {
struct_gUnk_020000C0_1 unk_00[4]; struct_gUnk_020000C0_1 unk_00[4];
} struct_gUnk_020000C0; } struct_gUnk_020000C0;

View File

@ -241,7 +241,7 @@ extern void sub_080A57F4(void);
extern void sub_080A71C4(u32, u32, u32, u32); extern void sub_080A71C4(u32, u32, u32, u32);
extern void sub_080A7C18(u32, u32, u32); extern void sub_080A7C18(u32, u32, u32);
extern void sub_080ADD70(void); extern void sub_080ADD70(void);
extern void sub_080AE068(Entity*); extern void UnloadGFXSlots(Entity*);
extern bool32 sub_080AE4CC(Entity*, u32, u32, u32); extern bool32 sub_080AE4CC(Entity*, u32, u32, u32);
extern void sub_080AE58C(Entity*, u32, u32); extern void sub_080AE58C(Entity*, u32, u32);
extern void sub_080AF284(void); extern void sub_080AF284(void);

View File

@ -56,10 +56,45 @@ typedef struct {
} struct_0200AF00; } struct_0200AF00;
extern struct_0200AF00 gUnk_0200AF00; extern struct_0200AF00 gUnk_0200AF00;
#define MAX_GFX_SLOTS 44
typedef enum {
GFX_SLOT_FREE,
GFX_SLOT_UNLOADED, // some sort of free? no longer in use?
GFX_SLOT_STATUS2, // some sort of free?
GFX_SLOT_FOLLOWER, // Set by SetGFXSlotStatus for the following slots
GFX_SLOT_RESERVED, // maybe ready to be loaded?
GFX_SLOT_GFX,
GFX_SLOT_PALETTE
} GfxSlotStatus;
typedef enum {
GFX_VRAM_0,
GFX_VRAM_1, // uploaded to vram?
GFX_VRAM_2,
GFX_VRAM_3, // not yet uploaded to vram?
} GfxSlotVramStatus;
typedef struct {
u8 status : 4;
u8 vramStatus : 4; // Whether the gfx was uploaded to the vram?
u8 slotCount;
u8 referenceCount; /**< How many entities use this gfx slot */
u8 unk_3;
u16 gfxIndex;
u16 paletteIndex;
const void* palettePointer;
} GfxSlot;
typedef struct { typedef struct {
u8 unk0; u8 unk0;
} struct_02024490; u8 unk_1;
extern struct_02024490 gGFXSlots; u8 unk_2;
u8 unk_3;
GfxSlot slots[MAX_GFX_SLOTS];
} GfxSlotList;
extern GfxSlotList gGFXSlots;
static_assert(sizeof(GfxSlotList) == 0x214);
typedef struct { typedef struct {
u16 unk_00; u16 unk_00;

View File

@ -879,7 +879,7 @@ SECTIONS {
src/title.o(.text); src/title.o(.text);
src/affine.o(.text); src/affine.o(.text);
src/playerItem/playerItemGustJar.o(.text); src/playerItem/playerItemGustJar.o(.text);
asm/vram.o(.text); src/vram.o(.text);
src/movement.o(.text); src/movement.o(.text);
/* library functions */ /* library functions */
asm/lib/m4a_asm.o(.text); asm/lib/m4a_asm.o(.text);

View File

@ -419,7 +419,7 @@ void sub_08028FFC(Entity* this) {
this->action = 1; this->action = 1;
COLLISION_OFF(this); COLLISION_OFF(this);
this->spritePriority.b1 = 0; this->spritePriority.b1 = 0;
sub_080AE068(this); UnloadGFXSlots(this);
UnloadOBJPalette(this); UnloadOBJPalette(this);
this->spriteVramOffset = 0xe8; this->spriteVramOffset = 0xe8;
this->palette.b.b0 = 2; this->palette.b.b0 = 2;

View File

@ -263,7 +263,7 @@ void OctorokBoss_Hit_SubAction1(Entity* this) {
if (GET_TIMER(this) == 0) { if (GET_TIMER(this) == 0) {
this->subAction = 2; this->subAction = 2;
GET_BOSS_PHASE(this)++; GET_BOSS_PHASE(this)++;
sub_080AE068(this); UnloadGFXSlots(this);
if (IS_FROZEN(this) == FALSE) { if (IS_FROZEN(this) == FALSE) {
this->hitType = 0x5f; this->hitType = 0x5f;
LoadFixedGFX(this, 0x108); LoadFixedGFX(this, 0x108);

View File

@ -280,7 +280,7 @@ void sub_080297F0(Entity* this) {
COLLISION_ON(this); COLLISION_ON(this);
this->spriteSettings.draw = TRUE; this->spriteSettings.draw = TRUE;
this->hitType = 0x8e; this->hitType = 0x8e;
sub_080AE068(this); UnloadGFXSlots(this);
#ifdef EU #ifdef EU
this->spriteIndex = 0x142; this->spriteIndex = 0x142;
#else #else

View File

@ -574,7 +574,7 @@ void sub_08041BE8(Entity* this) {
entity = ((VaatiWrathHeapStruct*)this->myHeap)->type2; entity = ((VaatiWrathHeapStruct*)this->myHeap)->type2;
entity->updatePriority = PRIO_NO_BLOCK; entity->updatePriority = PRIO_NO_BLOCK;
sub_080AE068(entity); UnloadGFXSlots(entity);
LoadFixedGFX(entity, 0x1f5); LoadFixedGFX(entity, 0x1f5);
ChangeObjPalette(entity, 0x16b); ChangeObjPalette(entity, 0x16b);
InitializeAnimation(entity, 0x1a); InitializeAnimation(entity, 0x1a);

View File

@ -341,7 +341,7 @@ void DeleteEntityAny(Entity* ent) {
void DeleteEntity(Entity* ent) { void DeleteEntity(Entity* ent) {
if (ent->next) { if (ent->next) {
sub_080AE068(ent); UnloadGFXSlots(ent);
UnloadOBJPalette(ent); UnloadOBJPalette(ent);
sub_0806FE84(ent); sub_0806FE84(ent);
sub_080788E0(ent); sub_080788E0(ent);

View File

@ -30,7 +30,7 @@ void sub_08082EB4(BlockPushedEntity* this) {
u32 pos; u32 pos;
if (gRoomControls.area == 0x11) { if (gRoomControls.area == 0x11) {
sub_080AE068(super); UnloadGFXSlots(super);
if (LoadFixedGFX(super, 0x1c1) == 0) { if (LoadFixedGFX(super, 0x1c1) == 0) {
super->spriteSettings.draw = 0; super->spriteSettings.draw = 0;
return; return;

View File

@ -16,7 +16,7 @@ void sub_08090EC0(Entity* this) {
this->frameIndex = this->type2; this->frameIndex = this->type2;
if (AreaIsDungeon()) { if (AreaIsDungeon()) {
this->frameIndex += 4; this->frameIndex += 4;
sub_080AE068(this); UnloadGFXSlots(this);
LoadFixedGFX(this, 0x184); LoadFixedGFX(this, 0x184);
} }
} }

View File

@ -36,7 +36,7 @@ void WaterfallOpening(Entity* this) {
this->field_0xf = 0; this->field_0xf = 0;
this->subAction = 1; this->subAction = 1;
this->type = 1; this->type = 1;
sub_080AE068(this); UnloadGFXSlots(this);
LoadFixedGFX(this, 0x18c); LoadFixedGFX(this, 0x18c);
#ifndef EU #ifndef EU
SoundReq(SFX_EVAPORATE); SoundReq(SFX_EVAPORATE);
@ -49,7 +49,7 @@ void WaterfallOpening(Entity* this) {
this->actionDelay = 1; this->actionDelay = 1;
this->subAction = 2; this->subAction = 2;
this->type = 2; this->type = 2;
sub_080AE068(this); UnloadGFXSlots(this);
LoadFixedGFX(this, 0x18d); LoadFixedGFX(this, 0x18d);
} }
break; break;

339
src/vram.c Normal file
View File

@ -0,0 +1,339 @@
#include "global.h"
#include "common.h"
#include "structures.h"
#include "fileselect.h"
extern u32 gFixedTypeGfxData[];
void ReserveGFXSlots(u32, u32, u32);
void sub_080ADE74(u32);
void sub_080ADE24(void);
u32 FindFreeGFXSlots(u32);
void CleanUpGFXSlots(void);
void sub_080ADDD8(u32, u32);
void sub_080AE0C8(u32, Entity*, u32);
void SetGFXSlotStatus(GfxSlot*, u32);
u32 FindNextOccupiedGFXSlot(u32);
u32 FindFirstFreeGFXSlot(void);
void sub_080AE218(u32, u32);
void sub_080AE324(u32, u32);
void ResetPalettes(void) {
GfxSlot* slots;
GfxSlot* slot;
u32 index;
MemClear(&gGFXSlots, sizeof(gGFXSlots));
// Reserve the first four slots for palettes.
for (index = 0; index < 4; index++) {
slots = gGFXSlots.slots;
slot = &slots[index];
ReserveGFXSlots(index, 0, 1);
slot->status = GFX_SLOT_PALETTE;
slot->referenceCount = 0x80;
}
}
void sub_080ADD70(void) {
u32 index;
GfxSlot* slot;
if (gGFXSlots.unk0 != 0) {
#ifndef EU
if (gGFXSlots.unk_3 != 0) {
sub_080ADE24();
} else {
#endif
index = 0;
for (index = 0; index < MAX_GFX_SLOTS; index++) {
slot = &gGFXSlots.slots[index];
switch (slot->status) {
case GFX_SLOT_STATUS2:
slot->status = GFX_SLOT_UNLOADED;
break;
case GFX_SLOT_RESERVED:
case GFX_SLOT_GFX:
case GFX_SLOT_PALETTE:
if (slot->vramStatus == GFX_VRAM_3) {
sub_080ADE74(index);
}
break;
}
}
#ifndef EU
}
#endif
}
}
NONMATCH("asm/non_matching/vram/sub_080ADDD8.inc", void sub_080ADDD8(u32 index, u32 paletteIndex)) {
GfxSlot* slot = &gGFXSlots.slots[index];
slot->palettePointer = gGlobalGfxAndPalettes + (paletteIndex & 0xfffffc);
if ((paletteIndex & 1) != 0) {
slot->paletteIndex = 0xffff;
} else {
// TODO some cast here?
slot->paletteIndex = ((paletteIndex)&0x7f00) >> 4;
}
slot->vramStatus = GFX_VRAM_3;
}
END_NONMATCH
void sub_080ADE24(void) {
u32 index;
GfxSlot* slot;
gGFXSlots.unk_3 = 1;
for (index = 0; index < MAX_GFX_SLOTS; index++) {
slot = &gGFXSlots.slots[index];
switch (slot->status) {
case GFX_SLOT_FOLLOWER:
break;
case GFX_SLOT_RESERVED:
case GFX_SLOT_GFX:
case GFX_SLOT_PALETTE:
sub_080ADE74(index);
break;
default:
MemClear(slot, sizeof(GfxSlot));
break;
}
}
gGFXSlots.unk_3 = 0;
}
// Transfer gfx slot data to vram?
ASM_FUNC("asm/non_matching/vram/sub_080ADE74.inc", void sub_080ADE74(u32 index))
bool32 LoadFixedGFX(Entity* entity, u32 gfxIndex) {
#ifdef EU
GfxSlot* slot;
u32 index;
u32 count;
u32 result;
u32 data;
if (gfxIndex == 0) {
result = TRUE;
} else {
for (index = 4; index < MAX_GFX_SLOTS; index++) {
if (gfxIndex == gGFXSlots.slots[index].gfxIndex) {
// Gfx is already loaded to a slot.
sub_080AE0C8(index, entity, GFX_SLOT_RESERVED);
result = TRUE;
return result;
}
}
data = gFixedTypeGfxData[gfxIndex];
count = (data & 0x7f000000) >> 0x18;
index = FindFreeGFXSlots(count);
if (index != 0) {
ReserveGFXSlots(index, gfxIndex, count);
sub_080ADDD8(index, data);
_080ADFF2:
sub_080AE0C8(index, entity, GFX_SLOT_RESERVED);
result = TRUE;
} else {
result = FALSE;
}
}
return result;
#else
GfxSlot* slot;
u32 index;
u32 count;
if (gfxIndex != 0) {
for (index = 4; index < MAX_GFX_SLOTS; index++) {
if (gfxIndex == gGFXSlots.slots[index].gfxIndex) {
// Gfx is already loaded to a slot.
goto _080ADFF2;
}
}
count = (gFixedTypeGfxData[gfxIndex] & 0x7f000000) >> 0x18;
index = FindFreeGFXSlots(count);
if (index == 0) {
CleanUpGFXSlots();
index = FindFreeGFXSlots(count);
if (index == 0) {
return 0;
}
}
ReserveGFXSlots(index, gfxIndex, count);
sub_080ADDD8(index, gFixedTypeGfxData[gfxIndex]);
_080ADFF2:
sub_080AE0C8(index, entity, GFX_SLOT_RESERVED);
}
return TRUE;
#endif
}
// If slotIndex != 0 the gfx loaded starting from that slot, else in the first fitting free one.
NONMATCH("asm/non_matching/vram/LoadSwapGFX.inc", u32 LoadSwapGFX(Entity* entity, u32 count, u32 slotIndex)) {
u32 status;
if ((slotIndex == 0) && (slotIndex = FindFreeGFXSlots(count), slotIndex == 0)) {
#ifndef EU
CleanUpGFXSlots();
#endif
slotIndex = FindFreeGFXSlots(count);
if (slotIndex == 0) {
goto _080AE058;
}
}
status = gGFXSlots.slots[slotIndex].status;
if (status != GFX_SLOT_PALETTE) {
ReserveGFXSlots(slotIndex, 0, count);
status = GFX_SLOT_GFX;
}
sub_080AE0C8(slotIndex, entity, status);
_080AE058:
if (slotIndex != 0) {
slotIndex = 1;
}
return slotIndex;
}
END_NONMATCH
void UnloadGFXSlots(Entity* param_1) {
u32 slotIndex;
GfxSlot* slot;
s32 slotCount;
slotIndex = param_1->spriteAnimation[0];
param_1->spriteAnimation[0] = 0;
if (slotIndex != 0) {
slot = &gGFXSlots.slots[slotIndex];
switch (slot->status) {
case GFX_SLOT_RESERVED:
case GFX_SLOT_GFX:
if (slot->referenceCount != 0) {
if (--slot->referenceCount == 0) {
slotCount = slot->slotCount;
while (slotCount-- > 0) {
slot->status = GFX_SLOT_UNLOADED;
slot++;
}
}
}
break;
}
}
}
void sub_080AE0C8(u32 index, Entity* entity, u32 status) {
GfxSlot* slot;
entity->spriteVramOffset = index * 0x10 + 0x140;
entity->spriteAnimation[0] = index;
slot = &gGFXSlots.slots[index];
if (*(s8*)&slot->referenceCount >= 0) {
slot->referenceCount++;
}
SetGFXSlotStatus(slot, status);
}
void ReserveGFXSlots(u32 index, u32 gfxIndex, u32 slotCount) {
GfxSlot* slot = &gGFXSlots.slots[index];
MemClear(slot, slotCount * sizeof(GfxSlot));
slot->slotCount = slotCount;
slot->gfxIndex = gfxIndex;
SetGFXSlotStatus(slot, GFX_SLOT_RESERVED);
}
void SetGFXSlotStatus(GfxSlot* slot, u32 status) {
s32 index;
slot->status = status;
index = slot->slotCount;
if (status != GFX_SLOT_PALETTE) {
status = GFX_SLOT_FOLLOWER;
}
for (index--; index > 0; index--) {
slot++;
slot->status = status;
}
}
/**
* Finds slotCount continous free slots and returns the index of the first slot or 0 if not enough free slots could be
* found.
*/
u32 FindFreeGFXSlots(u32 slotCount) {
u32 index;
u32 continuousFreeSlots = 0;
// First search for enough continous free slots.
for (index = 4; index < MAX_GFX_SLOTS; index++) {
if (gGFXSlots.slots[index].status == GFX_SLOT_FREE) {
continuousFreeSlots++;
if (slotCount <= continuousFreeSlots) {
return (index - continuousFreeSlots) + 1;
}
} else {
continuousFreeSlots = 0;
}
}
// Now also search for enough continous free or unused slots.
continuousFreeSlots = 0;
index = 4;
for (index = 4; index < MAX_GFX_SLOTS; index++) {
#ifdef EU
if (gGFXSlots.slots[index].status == GFX_SLOT_UNLOADED) {
#else
if (gGFXSlots.slots[index].status == GFX_SLOT_FREE || gGFXSlots.slots[index].status == GFX_SLOT_UNLOADED) {
#endif
continuousFreeSlots++;
if (slotCount <= continuousFreeSlots) {
return (index - continuousFreeSlots) + 1;
}
} else {
continuousFreeSlots = 0;
}
}
return 0;
}
#ifndef EU
void CleanUpGFXSlots(void) {
u32 occupiedIndex;
u32 firstFreeIndex;
if (gGFXSlots.unk0 != 0) {
for (occupiedIndex = 4; (occupiedIndex = FindNextOccupiedGFXSlot(occupiedIndex)) != 0; occupiedIndex++) {
firstFreeIndex = FindFirstFreeGFXSlot();
if (firstFreeIndex <= occupiedIndex) {
sub_080AE218(occupiedIndex, firstFreeIndex);
sub_080AE324(occupiedIndex, firstFreeIndex);
occupiedIndex = firstFreeIndex;
}
}
}
}
// Swap gfx
ASM_FUNC("asm/non_matching/vram/sub_080AE218.inc", void sub_080AE218(u32 a, u32 b))
// Swap palettes
ASM_FUNC("asm/non_matching/vram/sub_080AE324.inc", void sub_080AE324(u32 a, u32 b))
u32 FindNextOccupiedGFXSlot(u32 index) {
for (; index < MAX_GFX_SLOTS - 1; index++) {
switch (gGFXSlots.slots[index].status) {
case GFX_SLOT_RESERVED:
case GFX_SLOT_GFX:
return index;
}
}
return 0;
}
u32 FindFirstFreeGFXSlot(void) {
u32 index;
for (index = 4; index < MAX_GFX_SLOTS; index++) {
switch (gGFXSlots.slots[index].status) {
case GFX_SLOT_FREE:
case GFX_SLOT_UNLOADED:
return index;
default:
break;
}
}
return 0;
}
#endif