mirror of
https://github.com/zeldaret/tmc
synced 2026-08-18 05:38:50 -04:00
Merge pull request #429 from octorock/vram
This commit is contained in:
@@ -419,7 +419,7 @@ void sub_08028FFC(Entity* this) {
|
||||
this->action = 1;
|
||||
COLLISION_OFF(this);
|
||||
this->spritePriority.b1 = 0;
|
||||
sub_080AE068(this);
|
||||
UnloadGFXSlots(this);
|
||||
UnloadOBJPalette(this);
|
||||
this->spriteVramOffset = 0xe8;
|
||||
this->palette.b.b0 = 2;
|
||||
|
||||
@@ -263,7 +263,7 @@ void OctorokBoss_Hit_SubAction1(Entity* this) {
|
||||
if (GET_TIMER(this) == 0) {
|
||||
this->subAction = 2;
|
||||
GET_BOSS_PHASE(this)++;
|
||||
sub_080AE068(this);
|
||||
UnloadGFXSlots(this);
|
||||
if (IS_FROZEN(this) == FALSE) {
|
||||
this->hitType = 0x5f;
|
||||
LoadFixedGFX(this, 0x108);
|
||||
|
||||
@@ -280,7 +280,7 @@ void sub_080297F0(Entity* this) {
|
||||
COLLISION_ON(this);
|
||||
this->spriteSettings.draw = TRUE;
|
||||
this->hitType = 0x8e;
|
||||
sub_080AE068(this);
|
||||
UnloadGFXSlots(this);
|
||||
#ifdef EU
|
||||
this->spriteIndex = 0x142;
|
||||
#else
|
||||
|
||||
@@ -574,7 +574,7 @@ void sub_08041BE8(Entity* this) {
|
||||
|
||||
entity = ((VaatiWrathHeapStruct*)this->myHeap)->type2;
|
||||
entity->updatePriority = PRIO_NO_BLOCK;
|
||||
sub_080AE068(entity);
|
||||
UnloadGFXSlots(entity);
|
||||
LoadFixedGFX(entity, 0x1f5);
|
||||
ChangeObjPalette(entity, 0x16b);
|
||||
InitializeAnimation(entity, 0x1a);
|
||||
|
||||
+1
-1
@@ -341,7 +341,7 @@ void DeleteEntityAny(Entity* ent) {
|
||||
|
||||
void DeleteEntity(Entity* ent) {
|
||||
if (ent->next) {
|
||||
sub_080AE068(ent);
|
||||
UnloadGFXSlots(ent);
|
||||
UnloadOBJPalette(ent);
|
||||
sub_0806FE84(ent);
|
||||
sub_080788E0(ent);
|
||||
|
||||
@@ -30,7 +30,7 @@ void sub_08082EB4(BlockPushedEntity* this) {
|
||||
u32 pos;
|
||||
|
||||
if (gRoomControls.area == 0x11) {
|
||||
sub_080AE068(super);
|
||||
UnloadGFXSlots(super);
|
||||
if (LoadFixedGFX(super, 0x1c1) == 0) {
|
||||
super->spriteSettings.draw = 0;
|
||||
return;
|
||||
|
||||
@@ -16,7 +16,7 @@ void sub_08090EC0(Entity* this) {
|
||||
this->frameIndex = this->type2;
|
||||
if (AreaIsDungeon()) {
|
||||
this->frameIndex += 4;
|
||||
sub_080AE068(this);
|
||||
UnloadGFXSlots(this);
|
||||
LoadFixedGFX(this, 0x184);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ void WaterfallOpening(Entity* this) {
|
||||
this->field_0xf = 0;
|
||||
this->subAction = 1;
|
||||
this->type = 1;
|
||||
sub_080AE068(this);
|
||||
UnloadGFXSlots(this);
|
||||
LoadFixedGFX(this, 0x18c);
|
||||
#ifndef EU
|
||||
SoundReq(SFX_EVAPORATE);
|
||||
@@ -49,7 +49,7 @@ void WaterfallOpening(Entity* this) {
|
||||
this->actionDelay = 1;
|
||||
this->subAction = 2;
|
||||
this->type = 2;
|
||||
sub_080AE068(this);
|
||||
UnloadGFXSlots(this);
|
||||
LoadFixedGFX(this, 0x18d);
|
||||
}
|
||||
break;
|
||||
|
||||
+339
@@ -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
|
||||
Reference in New Issue
Block a user