mirror of
https://github.com/zeldaret/tmc
synced 2026-06-03 10:31:58 -04:00
225 lines
9.3 KiB
C
225 lines
9.3 KiB
C
/**
|
|
* @file hyruleTownTileSetManager.c
|
|
* @ingroup Managers
|
|
*
|
|
* @brief Swap tileSet data in hyrule town depending on the position.
|
|
*/
|
|
#include "manager/hyruleTownTileSetManager.h"
|
|
#include "area.h"
|
|
#include "asm.h"
|
|
#include "flags.h"
|
|
#include "main.h"
|
|
#include "room.h"
|
|
#include "tiles.h"
|
|
#include "game.h"
|
|
#include "assets/gfx_offsets.h"
|
|
#include "functions.h"
|
|
|
|
void HyruleTownTileSetManager_UpdateLoadGfxGroups(HyruleTownTileSetManager*);
|
|
void HyruleTownTileSetManager_OnEnterRoom(HyruleTownTileSetManager*);
|
|
|
|
// clang-format off
|
|
static const u16 gHyruleTownTileSetManager_regions0[] = {
|
|
0, 0x000, 0x000, 0x3f0, 0x200,
|
|
1, 0x000, 0x280, 0x3f0, 0x140,
|
|
0xff
|
|
};
|
|
static const u16 gHyruleTownTileSetManager_regions1[] = {
|
|
2, 0x000, 0x000, 0x180, 0x3c0,
|
|
3, 0x280, 0x000, 0x170, 0x3c0,
|
|
0xff
|
|
};
|
|
static const u16 gHyruleTownTileSetManager_regions2[] = {
|
|
5, 0x130, 0x1b0, 0x190, 0x140,
|
|
4, 0x000, 0x000, 0x3f0, 0x3c0,
|
|
0xff
|
|
};
|
|
static const u16 gHyruleTownTileSetManager_festivalRegions0[] = {
|
|
0, 0x000, 0x000, 0x190, 0x1d0,
|
|
1, 0x000, 0x2a0, 0x190, 0x120,
|
|
0xff
|
|
};
|
|
static const u16 gHyruleTownTileSetManager_festivalRegions1[] = {
|
|
0xff
|
|
};
|
|
static const u16 gHyruleTownTileSetManager_festivalRegions2[] = {
|
|
5, 0x000, 0x1b0, 0x190, 0x140,
|
|
4, 0x000, 0x000, 0x190, 0x3c0,
|
|
0xff
|
|
};
|
|
// clang-format on
|
|
|
|
void HyruleTownTileSetManager_LoadGfxGroup(u32, u32);
|
|
void HyruleTownTileSetManager_BuildSecondOracleHouse(void);
|
|
|
|
bool32 HyruleTownTileSetManager_UpdateRoomGfxGroup(HyruleTownTileSetManager*, u32, u8*, const u16*);
|
|
|
|
extern u32 gUnk_086E8460;
|
|
|
|
typedef struct {
|
|
u32 gfx1;
|
|
void* dest1;
|
|
u32 gfx2;
|
|
void* dest2;
|
|
} HyruleTownTileSetManagerGfxInfo;
|
|
|
|
static const HyruleTownTileSetManagerGfxInfo gHyruleTownTileSetManagerGfxInfos[] = {
|
|
{ offset_gUnk_086D4460 + 0x8000, BG_SCREEN_ADDR(0), offset_gUnk_086D4460 + 0xE000, BG_SCREEN_ADDR(16) },
|
|
{ offset_gUnk_086D4460 + 0xB000, BG_SCREEN_ADDR(0), offset_gUnk_086D4460 + 0x11000, BG_SCREEN_ADDR(16) },
|
|
{ offset_gUnk_086D4460 + 0x9000, BG_SCREEN_ADDR(2), offset_gUnk_086D4460 + 0xF000, BG_SCREEN_ADDR(18) },
|
|
{ offset_gUnk_086D4460 + 0xC000, BG_SCREEN_ADDR(2), offset_gUnk_086D4460 + 0x12000, BG_SCREEN_ADDR(18) },
|
|
{ offset_gUnk_086D4460 + 0xA000, BG_SCREEN_ADDR(4), offset_gUnk_086D4460 + 0x10000, BG_SCREEN_ADDR(20) },
|
|
{ offset_gUnk_086D4460 + 0xD000, BG_SCREEN_ADDR(4), offset_gUnk_086D4460 + 0x13000, BG_SCREEN_ADDR(20) }
|
|
};
|
|
static const HyruleTownTileSetManagerGfxInfo gHyruleTownTileSetManagerGfxInfosFestival[] = {
|
|
{ offset_gUnk_086E8460 + 0x800, BG_SCREEN_ADDR(0), offset_gUnk_086E8460 + 0x6800, BG_SCREEN_ADDR(16) },
|
|
{ offset_gUnk_086E8460 + 0x3800, BG_SCREEN_ADDR(0), offset_gUnk_086E8460 + 0x9800, BG_SCREEN_ADDR(16) },
|
|
{ offset_gUnk_086E8460 + 0x1800, BG_SCREEN_ADDR(2), offset_gUnk_086E8460 + 0x7800, BG_SCREEN_ADDR(18) },
|
|
{ offset_gUnk_086E8460 + 0x4800, BG_SCREEN_ADDR(2), offset_gUnk_086E8460 + 0xA800, BG_SCREEN_ADDR(18) },
|
|
{ offset_gUnk_086E8460 + 0x2800, BG_SCREEN_ADDR(4), offset_gUnk_086E8460 + 0x8800, BG_SCREEN_ADDR(20) },
|
|
{ offset_gUnk_086E8460 + 0x5800, BG_SCREEN_ADDR(4), offset_gUnk_086E8460 + 0xB800, BG_SCREEN_ADDR(20) },
|
|
};
|
|
extern const u8 gGlobalGfxAndPalettes[];
|
|
|
|
void HyruleTownTileSetManager_Main(HyruleTownTileSetManager* this) {
|
|
if (super->action == 0) {
|
|
super->action = 1;
|
|
this->gfxGroup2 = 0xff;
|
|
this->gfxGroup1 = 0xff;
|
|
this->gfxGroup0 = 0xff;
|
|
RegisterTransitionHandler(this, HyruleTownTileSetManager_OnEnterRoom, NULL);
|
|
SetEntityPriority((Entity*)this, PRIO_PLAYER_EVENT);
|
|
}
|
|
HyruleTownTileSetManager_UpdateLoadGfxGroups(this);
|
|
}
|
|
|
|
void HyruleTownTileSetManager_OnEnterRoom(HyruleTownTileSetManager* this) {
|
|
gRoomVars.graphicsGroups[2] = 0xff;
|
|
gRoomVars.graphicsGroups[1] = 0xff;
|
|
gRoomVars.graphicsGroups[0] = 0xff;
|
|
this->gfxGroup2 = 0xff;
|
|
this->gfxGroup1 = 0xff;
|
|
this->gfxGroup0 = 0xff;
|
|
HyruleTownTileSetManager_UpdateLoadGfxGroups(this);
|
|
}
|
|
|
|
void HyruleTownTileSetManager_UpdateLoadGfxGroups(HyruleTownTileSetManager* this) {
|
|
if (gRoomControls.area != AREA_FESTIVAL_TOWN) {
|
|
if (HyruleTownTileSetManager_UpdateRoomGfxGroup(this, 0, &this->gfxGroup0,
|
|
gHyruleTownTileSetManager_regions0) != 0) {
|
|
HyruleTownTileSetManager_LoadGfxGroup(0, this->gfxGroup0);
|
|
}
|
|
if (HyruleTownTileSetManager_UpdateRoomGfxGroup(this, 1, &this->gfxGroup1,
|
|
gHyruleTownTileSetManager_regions1) != 0) {
|
|
HyruleTownTileSetManager_LoadGfxGroup(1, this->gfxGroup1);
|
|
if (this->gfxGroup1 == 2) {
|
|
HyruleTownTileSetManager_BuildSecondOracleHouse();
|
|
}
|
|
}
|
|
if (HyruleTownTileSetManager_UpdateRoomGfxGroup(this, 2, &this->gfxGroup2,
|
|
gHyruleTownTileSetManager_regions2) != 0) {
|
|
HyruleTownTileSetManager_LoadGfxGroup(2, this->gfxGroup2);
|
|
}
|
|
} else {
|
|
if (HyruleTownTileSetManager_UpdateRoomGfxGroup(this, 0, &this->gfxGroup0,
|
|
gHyruleTownTileSetManager_festivalRegions0) != 0) {
|
|
HyruleTownTileSetManager_LoadGfxGroup(0, this->gfxGroup0);
|
|
}
|
|
if (HyruleTownTileSetManager_UpdateRoomGfxGroup(this, 2, &this->gfxGroup2,
|
|
gHyruleTownTileSetManager_festivalRegions2) != 0) {
|
|
HyruleTownTileSetManager_LoadGfxGroup(2, this->gfxGroup2);
|
|
}
|
|
}
|
|
}
|
|
|
|
void HyruleTownTileSetManager_BuildSecondOracleHouse(void) {
|
|
u32 loopVar;
|
|
u32 innerLoopVar;
|
|
|
|
if (CheckGlobalFlag(TATEKAKE_HOUSE) != 0) {
|
|
for (loopVar = 0; loopVar < 4; ++loopVar) {
|
|
for (innerLoopVar = 0; innerLoopVar < 4; ++innerLoopVar) {
|
|
SetTileByIndex(loopVar * 0x10 + TILE_TYPE_1195 + innerLoopVar,
|
|
TILE_LOCAL(0x28 + innerLoopVar * 0x10, 0x188 + loopVar * 0x10), 1);
|
|
}
|
|
}
|
|
|
|
for (loopVar = 0; loopVar < 3; ++loopVar) {
|
|
for (innerLoopVar = 0; innerLoopVar < 4; ++innerLoopVar) {
|
|
SetTileByIndex(loopVar * 0x10 + TILE_TYPE_1088 + innerLoopVar,
|
|
TILE_LOCAL(0x28 + innerLoopVar * 0x10, 0x188 + loopVar * 0x10), 2);
|
|
}
|
|
}
|
|
SetTileByIndex(TILE_TYPE_214, TILE_POS(2, 23), LAYER_TOP);
|
|
SetTileByIndex(TILE_TYPE_215, TILE_POS(3, 23), LAYER_TOP);
|
|
LoadResourceAsync(&gUnk_086E8460, BG_SCREEN_ADDR(3), BG_SCREEN_SIZE);
|
|
} else {
|
|
if (CheckGlobalFlag(TATEKAKE_TOCHU) != 0) {
|
|
for (loopVar = 0; loopVar < 5; ++loopVar) {
|
|
for (innerLoopVar = 0; innerLoopVar < 4; ++innerLoopVar) {
|
|
SetTileByIndex(loopVar * 0x10 + TILE_TYPE_1190 + innerLoopVar,
|
|
TILE_LOCAL(0x28 + innerLoopVar * 0x10, 0x188 + loopVar * 0x10), 1);
|
|
}
|
|
}
|
|
SetTileByIndex(TILE_TYPE_1092, TILE_POS(2, 24), LAYER_TOP);
|
|
SetTileByIndex(TILE_TYPE_1093, TILE_POS(5, 24), LAYER_TOP);
|
|
SetTileByIndex(TILE_TYPE_1108, TILE_POS(2, 25), LAYER_TOP);
|
|
SetTileByIndex(TILE_TYPE_1109, TILE_POS(5, 25), LAYER_TOP);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool32 HyruleTownTileSetManager_UpdateRoomGfxGroup(HyruleTownTileSetManager* this, u32 gfxIndex, u8* pGfxGroup,
|
|
const u16* regions) {
|
|
*pGfxGroup = CheckRegionsOnScreen(regions);
|
|
if ((*pGfxGroup != 0xff) && (gRoomVars.graphicsGroups[gfxIndex] != *pGfxGroup)) {
|
|
gRoomVars.graphicsGroups[gfxIndex] = *pGfxGroup;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void HyruleTownTileSetManager_LoadGfxGroup(u32 gfxIndex, u32 gfxGroup) {
|
|
const HyruleTownTileSetManagerGfxInfo* gfxInfo;
|
|
|
|
gRoomVars.graphicsGroups[gfxIndex] = gfxGroup;
|
|
if (gRoomControls.area != AREA_FESTIVAL_TOWN) {
|
|
gfxInfo = &gHyruleTownTileSetManagerGfxInfos[gfxGroup];
|
|
} else {
|
|
gfxInfo = &gHyruleTownTileSetManagerGfxInfosFestival[gfxGroup];
|
|
}
|
|
LoadResourceAsync(&gGlobalGfxAndPalettes[gfxInfo->gfx1], gfxInfo->dest1, BG_SCREEN_SIZE * 2);
|
|
LoadResourceAsync(&gGlobalGfxAndPalettes[gfxInfo->gfx2], gfxInfo->dest2, BG_SCREEN_SIZE * 2);
|
|
}
|
|
|
|
void TryLoadPrologueHyruleTown(void) {
|
|
u32 gfxGroup;
|
|
|
|
if (gRoomControls.area != AREA_FESTIVAL_TOWN) {
|
|
gfxGroup = CheckRegionsOnScreen(gHyruleTownTileSetManager_regions0);
|
|
if (gfxGroup != 0xff) {
|
|
HyruleTownTileSetManager_LoadGfxGroup(0, gfxGroup);
|
|
}
|
|
gfxGroup = CheckRegionsOnScreen(gHyruleTownTileSetManager_regions1);
|
|
if (gfxGroup != 0xff) {
|
|
HyruleTownTileSetManager_LoadGfxGroup(1, gfxGroup);
|
|
if (gfxGroup == 2) {
|
|
HyruleTownTileSetManager_BuildSecondOracleHouse();
|
|
}
|
|
}
|
|
gfxGroup = CheckRegionsOnScreen(gHyruleTownTileSetManager_regions2);
|
|
if (gfxGroup != 0xff) {
|
|
HyruleTownTileSetManager_LoadGfxGroup(2, gfxGroup);
|
|
}
|
|
} else {
|
|
gfxGroup = CheckRegionsOnScreen(gHyruleTownTileSetManager_festivalRegions0);
|
|
if (gfxGroup != 0xff) {
|
|
HyruleTownTileSetManager_LoadGfxGroup(0, gfxGroup);
|
|
}
|
|
gfxGroup = CheckRegionsOnScreen(gHyruleTownTileSetManager_festivalRegions2);
|
|
if (gfxGroup != 0xff) {
|
|
HyruleTownTileSetManager_LoadGfxGroup(2, gfxGroup);
|
|
}
|
|
}
|
|
}
|