pmd-red/src/code_804AFAC_1.c
2024-11-08 14:29:12 +01:00

3073 lines
76 KiB
C

#include "global.h"
#include "file_system.h"
#include "tile_types.h"
#include "dungeon_map_access.h"
#include "dungeon_random.h"
#include "constants/direction.h"
#include "structs/str_dungeon.h"
#include "structs/map.h"
extern const u8 gUnknown_80F6DCC[];
extern struct FileArchive gDungeonFileArchive;
extern u8 gUnknown_202F1AA;
extern u8 gUnknown_202F1AB;
extern u8 gUnknown_202F1AC;
extern u8 gUnknown_202F1A8;
extern u8 gUnknown_202F1B4;
extern u8 gUnknown_202F1AE;
extern u8 gUnknown_202F1AD;
extern u8 gUnknown_202F1A9;
extern s16 gUnknown_202F1B0;
extern s16 gUnknown_202F1B2;
extern s32 gUnknown_202F1C8;
extern s32 gUnknown_202F1D0;
extern s32 gUnknown_202F1CC;
extern Position gUnknown_202F1D8;
struct UnkStruct_202F1B8
{
s32 unk0;
s32 unk4;
s32 unk8;
s32 unkC;
};
extern struct UnkStruct_202F1B8 gUnknown_202F1B8;
extern void sub_804FD30(void);
extern void sub_804FD30(void);
extern void sub_80518F0(void);
extern void sub_804FCCC(void);
extern void GenerateOneRoomMonsterHouseFloor(void);
extern void sub_804FBE8(void);
extern void sub_804FC74(void);
extern void sub_804E9DC(void);
extern void GenerateTwoRoomsWithMonsterHouseFloor(void);
extern u8 sub_8043D10();
extern bool8 sub_8050C30(s32 a0, s32 a1, u8 a2);
extern void sub_806C330(s32 a0, s32 a1, s16 a2, u8 a3);
extern const Position gAdjacentTileOffsets[];
void sub_804B534(s32 a0, s32 a1, s32 a2, s32 a3);
bool8 sub_804C70C(s32, UnkDungeonGlobal_unk1C574 *);
void GenerateStandardFloor(s32 a0, s32 a1, UnkDungeonGlobal_unk1C574 *a2);
void sub_804B72C(UnkDungeonGlobal_unk1C574 *a0);
void sub_804BC80(UnkDungeonGlobal_unk1C574 *a0);
void GenerateLineFloor(UnkDungeonGlobal_unk1C574 *a0);
void GenerateCrossFloor(UnkDungeonGlobal_unk1C574 *a0);
void GenerateBeetleFloor(UnkDungeonGlobal_unk1C574 *a0);
void GenerateOuterRoomsFloor(s32 sizeX_, s32 sizeY_, UnkDungeonGlobal_unk1C574 *unkPtr);
void sub_8051654(UnkDungeonGlobal_unk1C574 *a0);
void sub_80506F0(s32 a0, UnkDungeonGlobal_unk1C574 *a1);
void sub_804FF08(UnkDungeonGlobal_unk1C574 *a0, bool8 a1);
void sub_8050438(UnkDungeonGlobal_unk1C574 *a0, bool8 a1);
struct FileFixedmapPosStruct
{
u8 x;
u8 y;
};
static inline void SetTerrainNormal(Tile *tile)
{
tile->terrainType &= ~(TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY);
tile->terrainType |= TERRAIN_TYPE_NORMAL;
}
static inline u32 GetTerrain(Tile *tile)
{
return tile->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY);
}
// Some weird-ass regswap prevents the function from being matched - https://decomp.me/scratch/9SUV3
#ifdef NONMATCHING
void sub_804AFAC(void)
{
s32 x, y;
s32 i, j, k;
bool8 r10 = FALSE;
UnkDungeonGlobal_unk1C574 *unkPtr = &gDungeon->unk1C574;
gDungeon->unk13568 = OpenFileAndGetFileDataPtr(gUnknown_80F6DCC, &gDungeonFileArchive);
gUnknown_202F1AA = 0;
gUnknown_202F1AB = 0;
gUnknown_202F1AC = 0;
gUnknown_202F1A8 = (gDungeonWaterType[gDungeon->tileset] == DUNGEON_WATER_TYPE_WATER);
gUnknown_202F1B4 = 0xFF;
gUnknown_202F1AE = 0;
gUnknown_202F1B0 = unkPtr->unk7;
gUnknown_202F1B2 = unkPtr->unk8;
gUnknown_202F1AD = 1;
gUnknown_202F1B8.unk0 = -1;
gUnknown_202F1B8.unk8 = -1;
gUnknown_202F1B8.unk4 = -1;
gUnknown_202F1B8.unkC = -1;
sub_804FD30();
gDungeon->unk664 = unkPtr->unk6;
gDungeon->unk3A09 = 0;
gDungeon->unk3A0A = 0;
gUnknown_202F1C8 = unkPtr->unkC;
for (i = 0; i < 10; i++) {
bool32 r4 = 0;
gDungeon->unkE218.x = -1;
gDungeon->unkE218.y = -1;
gDungeon->unkE21C.x = -1;
gDungeon->unkE21C.y = -1;
for (j = 0; j < 10; j++) {
gDungeon->unk3A16 = j;
if (j > 0) {
gUnknown_202F1C8 = 0;
}
gUnknown_202F1A9 = 0;
gUnknown_202F1D8.x = -1;
gUnknown_202F1D8.y = -1;
sub_804FD30();
gDungeon->unkE218.x = -1;
gDungeon->unkE218.y = -1;
gDungeon->unk3A08 = 0;
if (gDungeon->bossBattleIndex != 0) {
if (sub_804C70C(gDungeon->bossBattleIndex, unkPtr)) {
break;
}
}
else {
u8 r7 = unkPtr->unk0;
k = 32;
while (1) {
if (r7 != 8) {
x = DungeonRandRange(2, 9);
y = DungeonRandRange(2, 8);
}
else {
x = DungeonRandRange(2, 5);
y = DungeonRandRange(2, 4);
}
if (x <= 6 && y <= 4) {
break;
}
if (--k == 0) {
x = 4;
y = 4;
break;
}
}
if (DUNGEON_MAX_SIZE_X / x < 8) {
x = 1;
}
if (DUNGEON_MAX_SIZE_Y / y < 8) {
y = 1;
}
gDungeon->unk3A08 = 0;
gDungeon->unk3A0C = 0xFF;
gUnknown_202F1D0 = r7;
switch (r7 & 0xF) {
case 1:
y = DungeonRandInt(2) + 2;
gUnknown_202F1AE = 1;
GenerateStandardFloor(4, y, unkPtr);
r10 = TRUE;
break;
case 11:
y = DungeonRandInt(2) + 2;
gUnknown_202F1AE = 2;
GenerateStandardFloor(4, y, unkPtr);
r10 = TRUE;
break;
case 0:
default:
GenerateStandardFloor(x, y, unkPtr);
r10 = TRUE;
break;
case 2:
GenerateOneRoomMonsterHouseFloor();
gDungeon->unk3A08 = 1;
break;
case 3:
sub_804B72C(unkPtr);
r10 = TRUE;
break;
case 4:
sub_804BC80(unkPtr);
r10 = TRUE;
break;
case 5:
GenerateTwoRoomsWithMonsterHouseFloor();
gDungeon->unk3A08 = 1;
break;
case 6:
GenerateLineFloor(unkPtr);
r10 = TRUE;
break;
case 7:
GenerateCrossFloor(unkPtr);
break;
case 9:
GenerateBeetleFloor(unkPtr);
break;
case 10:
GenerateOuterRoomsFloor(x, y, unkPtr);
r10 = TRUE;
break;
}
}
sub_80518F0();
sub_804FCCC();
if (gUnknown_202F1A9 == 0) {
s32 countSp = 0;
u8 spArray[64];
s32 countRooms = 0;
for (k = 0; k < 64; k++) {
spArray[k] = 0;
}
for (x = 0; x < DUNGEON_MAX_SIZE_X; x++) {
for (y = 0; y < DUNGEON_MAX_SIZE_Y; y++) {
Tile *tile = GetTile(x, y);
if ((tile->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY)) == TERRAIN_TYPE_NORMAL && tile->room <= 240) {
countRooms++;
if (tile->room < 64) {
spArray[tile->room] = 1;
}
}
}
}
countSp = 0;
// In order to match, 'y' had to be re-used as an iterator var
for (y = 0; y < 64; y++) {
if (spArray[y]) {
countSp++;
}
}
if (countRooms >= 30 && countSp > 1) {
break;
}
}
}
if (j == 10) {
gUnknown_202F1D8.x = -1;
gUnknown_202F1D8.y = -1;
GenerateOneRoomMonsterHouseFloor();
gDungeon->unk3A08 = 1;
}
sub_804E9DC();
if (r10) {
sub_80506F0(1, unkPtr);
}
r4 = (DungeonRandInt(100) < unkPtr->connectedToTop);
sub_804FF08(unkPtr, r4);
sub_8050438(unkPtr, r4);
sub_804FBE8();
if (gDungeon->unkE218.x != -1 && gDungeon->unkE218.y != -1)
{
if (sub_8043D10() == 1)
break;
if (gDungeon->unkE21C.x != -1 && gDungeon->unkE21C.y != -1 && sub_8050C30(gDungeon->unkE21C.x, gDungeon->unkE21C.y, 0))
break;
}
}
if (i == 10) {
gUnknown_202F1D8.x = -1;
gUnknown_202F1D8.y = -1;
sub_804FD30();
GenerateOneRoomMonsterHouseFloor();
gDungeon->unk3A08 = 1;
sub_804E9DC();
sub_804FF08(unkPtr, FALSE);
sub_8050438(unkPtr, FALSE);
sub_804FBE8();
}
if (gUnknown_202F1D8.x >= 0 && gUnknown_202F1D8.y >= 0) {
sub_806C330(gUnknown_202F1D8.x, gUnknown_202F1D8.y, 380, 0);
}
if (gUnknown_202F1B8.unk0 >= 0) {
sub_8051654(unkPtr);
gDungeon->unk3A0A = 1;
}
else {
gDungeon->unk3A0A = 0;
}
sub_804B534(0, 0, DUNGEON_MAX_SIZE_X, DUNGEON_MAX_SIZE_Y);
if (gUnknown_202F1A8 != 0) {
sub_804FC74();
}
CloseFile(gDungeon->unk13568);
}
#else
void NAKED sub_804AFAC(void)
{
asm_unified(" push {r4-r7,lr}\n"
" mov r7, r10\n"
" mov r6, r9\n"
" mov r5, r8\n"
" push {r5-r7}\n"
" sub sp, 0x44\n"
" movs r0, 0\n"
" mov r10, r0\n"
" ldr r4, _0804B0E8\n"
" ldr r0, [r4]\n"
" ldr r1, _0804B0EC\n"
" adds r1, r0\n"
" mov r8, r1\n"
" ldr r0, _0804B0F0\n"
" ldr r1, _0804B0F4\n"
" bl OpenFileAndGetFileDataPtr\n"
" ldr r2, [r4]\n"
" ldr r3, _0804B0F8\n"
" adds r1, r2, r3\n"
" str r0, [r1]\n"
" ldr r0, _0804B0FC\n"
" mov r6, r10\n"
" strb r6, [r0]\n"
" ldr r0, _0804B100\n"
" strb r6, [r0]\n"
" ldr r0, _0804B104\n"
" strb r6, [r0]\n"
" ldr r5, _0804B108\n"
" movs r3, 0\n"
" ldr r1, _0804B10C\n"
" ldr r0, _0804B110\n"
" adds r2, r0\n"
" movs r6, 0\n"
" ldrsh r0, [r2, r6]\n"
" adds r0, r1\n"
" ldrb r0, [r0]\n"
" cmp r0, 0x2\n"
" bne _0804AFFC\n"
" movs r3, 0x1\n"
"_0804AFFC:\n"
" strb r3, [r5]\n"
" ldr r1, _0804B114\n"
" movs r0, 0xFF\n"
" strb r0, [r1]\n"
" ldr r0, _0804B118\n"
" mov r1, r10\n"
" strb r1, [r0]\n"
" ldr r1, _0804B11C\n"
" mov r2, r8\n"
" ldrb r0, [r2, 0x7]\n"
" strh r0, [r1]\n"
" ldr r1, _0804B120\n"
" ldrb r0, [r2, 0x8]\n"
" strh r0, [r1]\n"
" ldr r1, _0804B124\n"
" movs r0, 0x1\n"
" strb r0, [r1]\n"
" ldr r1, _0804B128\n"
" movs r0, 0x1\n"
" negs r0, r0\n"
" str r0, [r1]\n"
" str r0, [r1, 0x8]\n"
" str r0, [r1, 0x4]\n"
" str r0, [r1, 0xC]\n"
" bl sub_804FD30\n"
" ldr r3, [r4]\n"
" mov r6, r8\n"
" ldrb r2, [r6, 0x6]\n"
" ldr r1, _0804B12C\n"
" adds r0, r3, r1\n"
" movs r1, 0\n"
" strh r2, [r0]\n"
" ldr r2, _0804B130\n"
" adds r0, r3, r2\n"
" strb r1, [r0]\n"
" ldr r0, [r4]\n"
" ldr r3, _0804B134\n"
" adds r0, r3\n"
" strb r1, [r0]\n"
" ldr r1, _0804B138\n"
" mov r6, r8\n"
" ldrb r0, [r6, 0xC]\n"
" str r0, [r1]\n"
" movs r0, 0\n"
" str r0, [sp, 0x40]\n"
"_0804B058:\n"
" ldr r0, _0804B0E8\n"
" ldr r2, [r0]\n"
" ldr r3, _0804B13C\n"
" adds r1, r2, r3\n"
" ldr r0, _0804B140\n"
" strh r0, [r1]\n"
" ldr r6, _0804B144\n"
" adds r1, r2, r6\n"
" movs r0, 0x1\n"
" negs r0, r0\n"
" strh r0, [r1]\n"
" ldr r0, _0804B148\n"
" adds r1, r2, r0\n"
" movs r0, 0x1\n"
" negs r0, r0\n"
" strh r0, [r1]\n"
" ldr r1, _0804B14C\n"
" adds r2, r1\n"
" strh r0, [r2]\n"
" movs r2, 0\n"
" mov r9, r2\n"
"_0804B082:\n"
" ldr r4, _0804B0E8\n"
" ldr r0, [r4]\n"
" ldr r3, _0804B150\n"
" adds r0, r3\n"
" movs r5, 0\n"
" movs r1, 0\n"
" mov r6, r9\n"
" strh r6, [r0]\n"
" mov r0, r9\n"
" cmp r0, 0\n"
" ble _0804B09C\n"
" ldr r0, _0804B138\n"
" str r1, [r0]\n"
"_0804B09C:\n"
" ldr r0, _0804B154\n"
" strb r5, [r0]\n"
" ldr r1, _0804B158\n"
" ldr r0, _0804B140\n"
" strh r0, [r1]\n"
" movs r0, 0x1\n"
" negs r0, r0\n"
" strh r0, [r1, 0x2]\n"
" bl sub_804FD30\n"
" ldr r1, [r4]\n"
" ldr r3, _0804B13C\n"
" adds r2, r1, r3\n"
" movs r0, 0x1\n"
" negs r0, r0\n"
" strh r0, [r2]\n"
" ldr r6, _0804B144\n"
" adds r2, r1, r6\n"
" strh r0, [r2]\n"
" ldr r0, _0804B15C\n"
" adds r1, r0\n"
" strb r5, [r1]\n"
" ldr r0, [r4]\n"
" ldr r2, _0804B160\n"
" adds r1, r0, r2\n"
" movs r3, 0\n"
" ldrsh r0, [r1, r3]\n"
" cmp r0, 0\n"
" beq _0804B164\n"
" mov r1, r8\n"
" bl sub_804C70C\n"
" lsls r0, 24\n"
" cmp r0, 0\n"
" beq _0804B0E4\n"
" b _0804B376\n"
"_0804B0E4:\n"
" b _0804B2F6\n"
" .align 2, 0\n"
"_0804B0E8: .4byte gDungeon\n"
"_0804B0EC: .4byte 0x0001c574\n"
"_0804B0F0: .4byte gUnknown_80F6DCC\n"
"_0804B0F4: .4byte gDungeonFileArchive\n"
"_0804B0F8: .4byte 0x00013568\n"
"_0804B0FC: .4byte gUnknown_202F1AA\n"
"_0804B100: .4byte gUnknown_202F1AB\n"
"_0804B104: .4byte gUnknown_202F1AC\n"
"_0804B108: .4byte gUnknown_202F1A8\n"
"_0804B10C: .4byte gDungeonWaterType\n"
"_0804B110: .4byte 0x00003a0e\n"
"_0804B114: .4byte gUnknown_202F1B4\n"
"_0804B118: .4byte gUnknown_202F1AE\n"
"_0804B11C: .4byte gUnknown_202F1B0\n"
"_0804B120: .4byte gUnknown_202F1B2\n"
"_0804B124: .4byte gUnknown_202F1AD\n"
"_0804B128: .4byte gUnknown_202F1B8\n"
"_0804B12C: .4byte 0x00000664\n"
"_0804B130: .4byte 0x00003a09\n"
"_0804B134: .4byte 0x00003a0a\n"
"_0804B138: .4byte gUnknown_202F1C8\n"
"_0804B13C: .4byte 0x0000e218\n"
"_0804B140: .4byte 0x0000ffff\n"
"_0804B144: .4byte 0x0000e21a\n"
"_0804B148: .4byte 0x0000e21c\n"
"_0804B14C: .4byte 0x0000e21e\n"
"_0804B150: .4byte 0x00003a16\n"
"_0804B154: .4byte gUnknown_202F1A9\n"
"_0804B158: .4byte gUnknown_202F1D8\n"
"_0804B15C: .4byte 0x00003a08\n"
"_0804B160: .4byte 0x00003a14\n"
"_0804B164:\n"
" mov r0, r8\n"
" ldrb r7, [r0]\n"
" movs r6, 0x20\n"
"_0804B16A:\n"
" cmp r7, 0x8\n"
" beq _0804B17E\n"
" movs r0, 0x2\n"
" movs r1, 0x9\n"
" bl DungeonRandRange\n"
" adds r5, r0, 0\n"
" movs r0, 0x2\n"
" movs r1, 0x8\n"
" b _0804B18C\n"
"_0804B17E:\n"
" movs r0, 0x2\n"
" movs r1, 0x5\n"
" bl DungeonRandRange\n"
" adds r5, r0, 0\n"
" movs r0, 0x2\n"
" movs r1, 0x4\n"
"_0804B18C:\n"
" bl DungeonRandRange\n"
" adds r4, r0, 0\n"
" cmp r5, 0x6\n"
" bgt _0804B19A\n"
" cmp r4, 0x4\n"
" ble _0804B1A4\n"
"_0804B19A:\n"
" subs r6, 0x1\n"
" cmp r6, 0\n"
" bne _0804B16A\n"
" movs r5, 0x4\n"
" movs r4, 0x4\n"
"_0804B1A4:\n"
" movs r0, 0x38\n"
" adds r1, r5, 0\n"
" bl __divsi3\n"
" cmp r0, 0x7\n"
" bgt _0804B1B2\n"
" movs r5, 0x1\n"
"_0804B1B2:\n"
" movs r0, 0x20\n"
" adds r1, r4, 0\n"
" bl __divsi3\n"
" cmp r0, 0x7\n"
" bgt _0804B1C0\n"
" movs r4, 0x1\n"
"_0804B1C0:\n"
" ldr r2, _0804B1EC\n"
" ldr r0, [r2]\n"
" ldr r1, _0804B1F0\n"
" adds r0, r1\n"
" movs r1, 0\n"
" strb r1, [r0]\n"
" ldr r0, [r2]\n"
" ldr r2, _0804B1F4\n"
" adds r0, r2\n"
" movs r1, 0xFF\n"
" strb r1, [r0]\n"
" ldr r0, _0804B1F8\n"
" str r7, [r0]\n"
" movs r0, 0xF\n"
" ands r0, r7\n"
" cmp r0, 0xB\n"
" bhi _0804B274\n"
" lsls r0, 2\n"
" ldr r1, _0804B1FC\n"
" adds r0, r1\n"
" ldr r0, [r0]\n"
" mov pc, r0\n"
" .align 2, 0\n"
"_0804B1EC: .4byte gDungeon\n"
"_0804B1F0: .4byte 0x00003a08\n"
"_0804B1F4: .4byte 0x00003a0c\n"
"_0804B1F8: .4byte gUnknown_202F1D0\n"
"_0804B1FC: .4byte _0804B200\n"
" .align 2, 0\n"
"_0804B200:\n"
" .4byte _0804B274\n"
" .4byte _0804B230\n"
" .4byte _0804B280\n"
" .4byte _0804B298\n"
" .4byte _0804B2A4\n"
" .4byte _0804B2B0\n"
" .4byte _0804B2CC\n"
" .4byte _0804B2D8\n"
" .4byte _0804B274\n"
" .4byte _0804B2E0\n"
" .4byte _0804B2E8\n"
" .4byte _0804B250\n"
"_0804B230:\n"
" movs r0, 0x2\n"
" bl DungeonRandInt\n"
" adds r4, r0, 0x2\n"
" ldr r1, _0804B24C\n"
" movs r0, 0x1\n"
" strb r0, [r1]\n"
" movs r0, 0x4\n"
" adds r1, r4, 0\n"
" mov r2, r8\n"
" bl GenerateStandardFloor\n"
" b _0804B2AA\n"
" .align 2, 0\n"
"_0804B24C: .4byte gUnknown_202F1AE\n"
"_0804B250:\n"
" movs r0, 0x2\n"
" bl DungeonRandInt\n"
" adds r4, r0, 0x2\n"
" ldr r1, _0804B270\n"
" movs r0, 0x2\n"
" strb r0, [r1]\n"
" movs r0, 0x4\n"
" adds r1, r4, 0\n"
" mov r2, r8\n"
" bl GenerateStandardFloor\n"
" movs r6, 0x1\n"
" mov r10, r6\n"
" b _0804B2F6\n"
" .align 2, 0\n"
"_0804B270: .4byte gUnknown_202F1AE\n"
"_0804B274:\n"
" adds r0, r5, 0\n"
" adds r1, r4, 0\n"
" mov r2, r8\n"
" bl GenerateStandardFloor\n"
" b _0804B2D2\n"
"_0804B280:\n"
" bl GenerateOneRoomMonsterHouseFloor\n"
" ldr r0, _0804B290\n"
" ldr r0, [r0]\n"
" ldr r1, _0804B294\n"
" adds r0, r1\n"
" b _0804B2BC\n"
" .align 2, 0\n"
"_0804B290: .4byte gDungeon\n"
"_0804B294: .4byte 0x00003a08\n"
"_0804B298:\n"
" mov r0, r8\n"
" bl sub_804B72C\n"
" movs r2, 0x1\n"
" mov r10, r2\n"
" b _0804B2F6\n"
"_0804B2A4:\n"
" mov r0, r8\n"
" bl sub_804BC80\n"
"_0804B2AA:\n"
" movs r3, 0x1\n"
" mov r10, r3\n"
" b _0804B2F6\n"
"_0804B2B0:\n"
" bl GenerateTwoRoomsWithMonsterHouseFloor\n"
" ldr r0, _0804B2C4\n"
" ldr r0, [r0]\n"
" ldr r6, _0804B2C8\n"
" adds r0, r6\n"
"_0804B2BC:\n"
" movs r1, 0x1\n"
" strb r1, [r0]\n"
" b _0804B2F6\n"
" .align 2, 0\n"
"_0804B2C4: .4byte gDungeon\n"
"_0804B2C8: .4byte 0x00003a08\n"
"_0804B2CC:\n"
" mov r0, r8\n"
" bl GenerateLineFloor\n"
"_0804B2D2:\n"
" movs r0, 0x1\n"
" mov r10, r0\n"
" b _0804B2F6\n"
"_0804B2D8:\n"
" mov r0, r8\n"
" bl GenerateCrossFloor\n"
" b _0804B2F6\n"
"_0804B2E0:\n"
" mov r0, r8\n"
" bl GenerateBeetleFloor\n"
" b _0804B2F6\n"
"_0804B2E8:\n"
" adds r0, r5, 0\n"
" adds r1, r4, 0\n"
" mov r2, r8\n"
" bl GenerateOuterRoomsFloor\n"
" movs r1, 0x1\n"
" mov r10, r1\n"
"_0804B2F6:\n"
" bl sub_80518F0\n"
" bl sub_804FCCC\n"
" ldr r0, _0804B4B4\n"
" ldrb r0, [r0]\n"
" cmp r0, 0\n"
" bne _0804B36A\n"
" movs r7, 0\n"
" movs r1, 0\n"
" mov r0, sp\n"
" adds r0, 0x3F\n"
"_0804B30E:\n"
" strb r1, [r0]\n"
" subs r0, 0x1\n"
" cmp r0, sp\n"
" bge _0804B30E\n"
" movs r5, 0\n"
"_0804B318:\n"
" movs r4, 0\n"
" adds r6, r5, 0x1\n"
"_0804B31C:\n"
" adds r0, r5, 0\n"
" adds r1, r4, 0\n"
" bl GetTile\n"
" adds r1, r0, 0\n"
" ldrh r0, [r1]\n"
" movs r2, 0x3\n"
" ands r2, r0\n"
" cmp r2, 0x1\n"
" bne _0804B340\n"
" ldrb r0, [r1, 0x9]\n"
" cmp r0, 0xF0\n"
" bhi _0804B340\n"
" adds r7, 0x1\n"
" cmp r0, 0x3F\n"
" bhi _0804B340\n"
" add r0, sp\n"
" strb r2, [r0]\n"
"_0804B340:\n"
" adds r4, 0x1\n"
" cmp r4, 0x1F\n"
" ble _0804B31C\n"
" adds r5, r6, 0\n"
" cmp r5, 0x37\n"
" ble _0804B318\n"
" movs r1, 0\n"
" movs r4, 0\n"
"_0804B350:\n"
" mov r2, sp\n"
" adds r0, r2, r4\n"
" ldrb r0, [r0]\n"
" cmp r0, 0\n"
" beq _0804B35C\n"
" adds r1, 0x1\n"
"_0804B35C:\n"
" adds r4, 0x1\n"
" cmp r4, 0x3F\n"
" ble _0804B350\n"
" cmp r7, 0x1D\n"
" ble _0804B36A\n"
" cmp r1, 0x1\n"
" bgt _0804B376\n"
"_0804B36A:\n"
" movs r3, 0x1\n"
" add r9, r3\n"
" mov r6, r9\n"
" cmp r6, 0x9\n"
" bgt _0804B376\n"
" b _0804B082\n"
"_0804B376:\n"
" mov r0, r9\n"
" cmp r0, 0xA\n"
" bne _0804B398\n"
" ldr r1, _0804B4B8\n"
" ldr r0, _0804B4BC\n"
" strh r0, [r1]\n"
" movs r0, 0x1\n"
" negs r0, r0\n"
" strh r0, [r1, 0x2]\n"
" bl GenerateOneRoomMonsterHouseFloor\n"
" ldr r0, _0804B4C0\n"
" ldr r0, [r0]\n"
" ldr r1, _0804B4C4\n"
" adds r0, r1\n"
" movs r1, 0x1\n"
" strb r1, [r0]\n"
"_0804B398:\n"
" bl sub_804E9DC\n"
" mov r2, r10\n"
" cmp r2, 0\n"
" beq _0804B3AA\n"
" movs r0, 0x1\n"
" mov r1, r8\n"
" bl sub_80506F0\n"
"_0804B3AA:\n"
" movs r0, 0x64\n"
" bl DungeonRandInt\n"
" movs r4, 0\n"
" mov r3, r8\n"
" ldrb r3, [r3, 0x19]\n"
" cmp r0, r3\n"
" bge _0804B3BC\n"
" movs r4, 0x1\n"
"_0804B3BC:\n"
" mov r0, r8\n"
" adds r1, r4, 0\n"
" bl sub_804FF08\n"
" mov r0, r8\n"
" adds r1, r4, 0\n"
" bl sub_8050438\n"
" bl sub_804FBE8\n"
" ldr r5, _0804B4C0\n"
" ldr r1, [r5]\n"
" ldr r6, _0804B4C8\n"
" adds r0, r1, r6\n"
" movs r2, 0\n"
" ldrsh r0, [r0, r2]\n"
" movs r4, 0x1\n"
" negs r4, r4\n"
" cmp r0, r4\n"
" beq _0804B42A\n"
" ldr r3, _0804B4CC\n"
" adds r0, r1, r3\n"
" movs r6, 0\n"
" ldrsh r0, [r0, r6]\n"
" cmp r0, r4\n"
" beq _0804B42A\n"
" bl sub_8043D10\n"
" lsls r0, 24\n"
" lsrs r0, 24\n"
" cmp r0, 0x1\n"
" beq _0804B436\n"
" ldr r1, [r5]\n"
" ldr r0, _0804B4D0\n"
" adds r2, r1, r0\n"
" movs r3, 0\n"
" ldrsh r0, [r2, r3]\n"
" cmp r0, r4\n"
" beq _0804B42A\n"
" ldr r6, _0804B4D4\n"
" adds r1, r6\n"
" movs r3, 0\n"
" ldrsh r0, [r1, r3]\n"
" cmp r0, r4\n"
" beq _0804B42A\n"
" movs r6, 0\n"
" ldrsh r0, [r2, r6]\n"
" movs r2, 0\n"
" ldrsh r1, [r1, r2]\n"
" movs r2, 0\n"
" bl sub_8050C30\n"
" lsls r0, 24\n"
" cmp r0, 0\n"
" bne _0804B436\n"
"_0804B42A:\n"
" ldr r3, [sp, 0x40]\n"
" adds r3, 0x1\n"
" str r3, [sp, 0x40]\n"
" cmp r3, 0x9\n"
" bgt _0804B436\n"
" b _0804B058\n"
"_0804B436:\n"
" ldr r6, [sp, 0x40]\n"
" cmp r6, 0xA\n"
" bne _0804B474\n"
" ldr r1, _0804B4B8\n"
" ldr r0, _0804B4BC\n"
" strh r0, [r1]\n"
" movs r0, 0x1\n"
" negs r0, r0\n"
" strh r0, [r1, 0x2]\n"
" bl sub_804FD30\n"
" bl GenerateOneRoomMonsterHouseFloor\n"
" ldr r0, _0804B4C0\n"
" ldr r0, [r0]\n"
" ldr r1, _0804B4C4\n"
" adds r0, r1\n"
" movs r1, 0x1\n"
" strb r1, [r0]\n"
" bl sub_804E9DC\n"
" mov r0, r8\n"
" movs r1, 0\n"
" bl sub_804FF08\n"
" mov r0, r8\n"
" movs r1, 0\n"
" bl sub_8050438\n"
" bl sub_804FBE8\n"
"_0804B474:\n"
" ldr r1, _0804B4B8\n"
" movs r2, 0\n"
" ldrsh r0, [r1, r2]\n"
" cmp r0, 0\n"
" blt _0804B498\n"
" movs r3, 0x2\n"
" ldrsh r0, [r1, r3]\n"
" cmp r0, 0\n"
" blt _0804B498\n"
" movs r6, 0\n"
" ldrsh r0, [r1, r6]\n"
" movs r2, 0x2\n"
" ldrsh r1, [r1, r2]\n"
" movs r2, 0xBE\n"
" lsls r2, 1\n"
" movs r3, 0\n"
" bl sub_806C330\n"
"_0804B498:\n"
" ldr r0, _0804B4D8\n"
" ldr r0, [r0]\n"
" cmp r0, 0\n"
" blt _0804B4E0\n"
" mov r0, r8\n"
" bl sub_8051654\n"
" ldr r0, _0804B4C0\n"
" ldr r0, [r0]\n"
" ldr r3, _0804B4DC\n"
" adds r0, r3\n"
" movs r1, 0x1\n"
" b _0804B4EA\n"
" .align 2, 0\n"
"_0804B4B4: .4byte gUnknown_202F1A9\n"
"_0804B4B8: .4byte gUnknown_202F1D8\n"
"_0804B4BC: .4byte 0x0000ffff\n"
"_0804B4C0: .4byte gDungeon\n"
"_0804B4C4: .4byte 0x00003a08\n"
"_0804B4C8: .4byte 0x0000e218\n"
"_0804B4CC: .4byte 0x0000e21a\n"
"_0804B4D0: .4byte 0x0000e21c\n"
"_0804B4D4: .4byte 0x0000e21e\n"
"_0804B4D8: .4byte gUnknown_202F1B8\n"
"_0804B4DC: .4byte 0x00003a0a\n"
"_0804B4E0:\n"
" ldr r0, _0804B524\n"
" ldr r0, [r0]\n"
" ldr r6, _0804B528\n"
" adds r0, r6\n"
" movs r1, 0\n"
"_0804B4EA:\n"
" strb r1, [r0]\n"
" movs r0, 0\n"
" movs r1, 0\n"
" movs r2, 0x38\n"
" movs r3, 0x20\n"
" bl sub_804B534\n"
" ldr r0, _0804B52C\n"
" ldrb r0, [r0]\n"
" cmp r0, 0\n"
" beq _0804B504\n"
" bl sub_804FC74\n"
"_0804B504:\n"
" ldr r0, _0804B524\n"
" ldr r0, [r0]\n"
" ldr r1, _0804B530\n"
" adds r0, r1\n"
" ldr r0, [r0]\n"
" bl CloseFile\n"
" add sp, 0x44\n"
" pop {r3-r5}\n"
" mov r8, r3\n"
" mov r9, r4\n"
" mov r10, r5\n"
" pop {r4-r7}\n"
" pop {r0}\n"
" bx r0\n"
" .align 2, 0\n"
"_0804B524: .4byte gDungeon\n"
"_0804B528: .4byte 0x00003a0a\n"
"_0804B52C: .4byte gUnknown_202F1A8\n"
"_0804B530: .4byte 0x00013568\n");
}
#endif // NONMATCHING
void sub_804B534(s32 xStart, s32 yStart, s32 maxX, s32 maxY)
{
s32 x, y;
for (x = xStart; x < maxX; x++) {
for (y = yStart; y < maxY; y++) {
s32 unkCount = 0;
Tile *tile = GetTileSafe(x, y);
tile->terrainType &= ~(TERRAIN_TYPE_UNK_2);
if (tile->room == CORRIDOR_ROOM && (GetTerrain(tile) == TERRAIN_TYPE_NORMAL)) {
if (x > 0 && (GetTerrain(GetTile(x - 1, y)) == TERRAIN_TYPE_NORMAL))
unkCount++;
if (y > 0 && (GetTerrain(GetTile(x, y - 1)) == TERRAIN_TYPE_NORMAL))
unkCount++;
if (x < DUNGEON_MAX_SIZE_X - 2 && (GetTerrain(GetTile(x + 1, y)) == TERRAIN_TYPE_NORMAL))
unkCount++;
// BUG: It should check for y and not x. Not sure if it has any effect, because this function is called only once with maxY equal to DUNGEON_MAX_SIZE_Y
if (x < DUNGEON_MAX_SIZE_Y - 2 && (GetTerrain(GetTile(x, y + 1)) == TERRAIN_TYPE_NORMAL))
unkCount++;
if (unkCount > 2) {
tile->terrainType |= TERRAIN_TYPE_NATURAL_JUNCTION;
}
}
}
}
}
struct GridCell
{
Position start;
Position end;
bool8 isInvalid;
bool8 unk9;
bool8 isRoom;
bool8 isConnected;
bool8 unk12;
bool8 unk13;
bool8 unk14;
bool8 unk15;
bool8 isMazeRoom;
bool8 hasBeenMerged;
bool8 isMerged;
bool8 connectedToTop;
bool8 connectedToBottom;
bool8 connectedToLeft;
bool8 connectedToRight;
bool8 unk23;
bool8 unk24;
bool8 unk25;
bool8 unk26;
bool8 unk27;
bool8 unk28;
bool8 unk29;
bool8 unk30;
bool8 unk31;
};
#define GRID_CELL_LEN 15
void GetGridPositions(s32 *listX, s32 *listY, s32 sizeX, s32 sizeY);
void InitDungeonGrid(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY);
void GenerateRoomImperfections(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY);
void GenerateSecondaryStructures(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY);
void AssignRooms(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 roomsNumber);
void CreateRoomsAndAnchors(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 *listX, s32 *listY, u32 roomFlags);
void CreateGridCellConnections(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 *listX, s32 *listY, bool8 disableRoomMerging);
void EnsureConnectedGrid(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 *listX, s32 *listY);
void sub_804D5B0(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 x, s32 y, UnkDungeonGlobal_unk1C574 *unkPtr);
void GenerateMazeRoom(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 chance);
void GenerateKecleonShop(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 chance);
void GenerateMonsterHouse(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 chance);
void GenerateExtraHallways(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 numExtraHallways);
static void MergeRoomsVertically(s32 roomX, s32 room_y1, s32 room_dy, struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN]);
/*
* GenerateStandardFloor - Generates a standard, typical floor layout.
*
* Overview:
* 1. Determine the grid based on sizeX, sizeY
* 2. Assign and create rooms and hallway anchors to each grid cell
* 3. Assign and create connections between grid cells (these are traditional hallways connecting the map together)
* 4. Fix any unconnected grid cells by adding more connections or removing their rooms/hallway anchors
* 5. Generate special rooms like a Maze Room (unused in vanilla?), Kecleon Shop, or Monster House
* 6. Create additional "extra hallways" with random walks outside of existing rooms
* 7. Finalize extra room details with imperfections (unused in vanilla?), and structures with secondary terrain
*/
void GenerateStandardFloor(s32 sizeX, s32 sizeY, UnkDungeonGlobal_unk1C574 *unkPtr)
{
struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN];
s32 listX[GRID_CELL_LEN];
s32 listY[GRID_CELL_LEN];
GetGridPositions(listX, listY, sizeX, sizeY);
InitDungeonGrid(grid, sizeX, sizeY);
AssignRooms(grid, sizeX, sizeY, unkPtr->unk1);
CreateRoomsAndAnchors(grid, sizeX, sizeY, listX, listY, unkPtr->unkD);
sub_804D5B0(grid, sizeX, sizeY, unkPtr);
CreateGridCellConnections(grid, sizeX, sizeY, listX, listY, FALSE);
EnsureConnectedGrid(grid, sizeX, sizeY, listX, listY);
GenerateMazeRoom(grid, sizeX, sizeY, unkPtr->unk9);
GenerateKecleonShop(grid, sizeX, sizeY, gUnknown_202F1B0);
GenerateMonsterHouse(grid, sizeX, sizeY, gUnknown_202F1B2);
GenerateExtraHallways(grid, sizeX, sizeY, unkPtr->unk13);
GenerateRoomImperfections(grid, sizeX, sizeY);
GenerateSecondaryStructures(grid, sizeX, sizeY);
}
// Decompile once data structure is better understood
#ifdef NONMATCHING
void sub_804B72C(UnkDungeonGlobal_unk1C574 *unkPtr)
{
struct GridCell grid[15][15];
sp.listX[0] = 0;
sp.listX[1] = 5;
sp.listX[3] = 28;
sp.listX[5] = 51
sp.listX[6] = 56;
sp.listX[2] = 16;
sp.listX[4] = 29;
sp.listY[0] = 2;
sp.listY[1] = 7;
sp.listY[2] = 16;
sp.listY[3] = 25;
sp.listY[4] = 30;
InitDungeonGrid(grid, 6, 4);
}
#else
NAKED void sub_804B72C(UnkDungeonGlobal_unk1C574 *unkPtr)
{
asm_unified("push {r4-r7,lr}\n"
" mov r7, r10\n"
" mov r6, r9\n"
" mov r5, r8\n"
" push {r5-r7}\n"
" ldr r4, _0804B9AC\n"
" add sp, r4\n"
" movs r1, 0xE5\n"
" lsls r1, 5\n"
" add r1, sp\n"
" str r0, [r1]\n"
" movs r5, 0\n"
" movs r6, 0x1\n"
" ldr r1, _0804B9B0\n"
" add r1, sp\n"
" str r5, [r1]\n"
" movs r0, 0x5\n"
" str r0, [r1, 0x4]\n"
" movs r0, 0x1C\n"
" str r0, [r1, 0xC]\n"
" movs r0, 0x33\n"
" str r0, [r1, 0x14]\n"
" movs r0, 0x38\n"
" str r0, [r1, 0x18]\n"
" movs r2, 0x10\n"
" str r2, [r1, 0x8]\n"
" movs r0, 0x27\n"
" str r0, [r1, 0x10]\n"
" ldr r1, _0804B9B4\n"
" add r1, sp\n"
" movs r0, 0x2\n"
" str r0, [r1]\n"
" movs r0, 0x7\n"
" str r0, [r1, 0x4]\n"
" str r2, [r1, 0x8]\n"
" movs r0, 0x19\n"
" str r0, [r1, 0xC]\n"
" movs r0, 0x1E\n"
" str r0, [r1, 0x10]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x6\n"
" movs r2, 0x4\n"
" bl InitDungeonGrid\n"
" mov r2, sp\n"
" adds r2, 0x3B\n"
" ldr r3, _0804B9B8\n"
" add r3, sp\n"
" str r2, [r3]\n"
" mov r4, sp\n"
" adds r4, 0x3C\n"
" ldr r0, _0804B9BC\n"
" add r0, sp\n"
" str r4, [r0]\n"
" mov r1, sp\n"
" adds r1, 0x5B\n"
" ldr r2, _0804B9C0\n"
" add r2, sp\n"
" str r1, [r2]\n"
" mov r3, sp\n"
" adds r3, 0x5C\n"
" movs r4, 0xE6\n"
" lsls r4, 5\n"
" add r4, sp\n"
" str r3, [r4]\n"
" mov r0, sp\n"
" adds r0, 0x7B\n"
" ldr r1, _0804B9C4\n"
" add r1, sp\n"
" str r0, [r1]\n"
" mov r2, sp\n"
" adds r2, 0x7E\n"
" ldr r3, _0804B9C8\n"
" add r3, sp\n"
" str r2, [r3]\n"
" add r1, sp, 0x68\n"
" add r0, sp, 0x8\n"
" movs r2, 0xF0\n"
" lsls r2, 1\n"
" movs r4, 0x6\n"
"_0804B7CC:\n"
" strb r5, [r0, 0xA]\n"
" strb r5, [r1, 0xA]\n"
" adds r1, r2\n"
" adds r0, r2\n"
" subs r4, 0x1\n"
" cmp r4, 0\n"
" bne _0804B7CC\n"
" movs r2, 0x6\n"
" subs r2, 0x1\n"
" movs r4, 0x4\n"
" cmp r4, 0\n"
" beq _0804B80C\n"
" lsls r0, r2, 4\n"
" subs r0, r2\n"
" lsls r0, 5\n"
" add r0, sp\n"
" adds r0, 0x8\n"
" add r1, sp, 0x8\n"
" ldr r3, _0804B9CC\n"
" add r3, sp\n"
" str r4, [r3]\n"
"_0804B7F6:\n"
" strb r5, [r1, 0xA]\n"
" strb r5, [r0, 0xA]\n"
" adds r0, 0x20\n"
" adds r1, 0x20\n"
" ldr r3, _0804B9CC\n"
" add r3, sp\n"
" ldr r4, [r3]\n"
" subs r4, 0x1\n"
" str r4, [r3]\n"
" cmp r4, 0\n"
" bne _0804B7F6\n"
"_0804B80C:\n"
" movs r4, 0x1\n"
" cmp r4, r2\n"
" bge _0804B848\n"
" movs r1, 0x3\n"
"_0804B814:\n"
" adds r5, r4, 0x1\n"
" mov r8, r5\n"
" cmp r1, 0x1\n"
" ble _0804B842\n"
" lsls r0, r4, 4\n"
" subs r0, r4\n"
" lsls r0, 5\n"
" add r0, sp\n"
" adds r0, 0x8\n"
" adds r0, 0x20\n"
" subs r3, r1, 0x1\n"
" ldr r4, _0804B9CC\n"
" add r4, sp\n"
" str r3, [r4]\n"
"_0804B830:\n"
" strb r6, [r0, 0xA]\n"
" adds r0, 0x20\n"
" ldr r3, _0804B9CC\n"
" add r3, sp\n"
" ldr r5, [r3]\n"
" subs r5, 0x1\n"
" str r5, [r3]\n"
" cmp r5, 0\n"
" bne _0804B830\n"
"_0804B842:\n"
" mov r4, r8\n"
" cmp r4, r2\n"
" blt _0804B814\n"
"_0804B848:\n"
" movs r4, 0\n"
" ldr r5, _0804B9D0\n"
" add r5, sp\n"
" str r4, [r5]\n"
" ldr r0, _0804B9CC\n"
" add r0, sp\n"
" str r4, [r0]\n"
" cmp r4, 0x4\n"
" blt _0804B85C\n"
" b _0804BA8C\n"
"_0804B85C:\n"
" movs r4, 0\n"
" ldr r2, _0804B9CC\n"
" add r2, sp\n"
" ldr r1, [r2]\n"
" adds r1, 0x1\n"
" ldr r2, _0804B9D4\n"
" add r2, sp\n"
" str r1, [r2]\n"
" cmp r4, 0x6\n"
" blt _0804B872\n"
" b _0804BA7A\n"
"_0804B872:\n"
" ldr r3, _0804B9B0\n"
" add r3, sp\n"
" ldr r5, _0804B9D8\n"
" add r5, sp\n"
" str r3, [r5]\n"
" ldr r0, _0804B9B4\n"
" add r0, sp\n"
" ldr r1, _0804B9DC\n"
" add r1, sp\n"
" str r0, [r1]\n"
" ldr r2, _0804B9CC\n"
" add r2, sp\n"
" ldr r2, [r2]\n"
" lsls r0, r2, 2\n"
" ldr r3, [r1]\n"
" adds r0, r3, r0\n"
" ldr r3, _0804B9E0\n"
" add r3, sp\n"
" str r0, [r3]\n"
"_0804B898:\n"
" lsls r0, r4, 4\n"
" subs r0, r4\n"
" ldr r5, _0804B9CC\n"
" add r5, sp\n"
" ldr r5, [r5]\n"
" adds r0, r5\n"
" lsls r0, 5\n"
" mov r7, sp\n"
" adds r7, r0\n"
" adds r7, 0x8\n"
" ldrb r0, [r7, 0xA]\n"
" cmp r0, 0\n"
" bne _0804B8B4\n"
" b _0804B9F4\n"
"_0804B8B4:\n"
" lsls r0, r4, 2\n"
" ldr r1, _0804B9D8\n"
" add r1, sp\n"
" ldr r1, [r1]\n"
" adds r0, r1, r0\n"
" ldr r1, [r0]\n"
" adds r2, r1, 0x2\n"
" mov r10, r2\n"
" ldr r3, _0804B9E0\n"
" add r3, sp\n"
" ldr r3, [r3]\n"
" ldr r2, [r3]\n"
" adds r5, r2, 0x2\n"
" ldr r0, _0804B9E4\n"
" add r0, sp\n"
" str r5, [r0]\n"
" adds r4, 0x1\n"
" mov r9, r4\n"
" lsls r0, r4, 2\n"
" ldr r3, _0804B9D8\n"
" add r3, sp\n"
" ldr r3, [r3]\n"
" adds r0, r3, r0\n"
" ldr r4, [r0]\n"
" subs r4, r1\n"
" subs r4, 0x3\n"
" ldr r5, _0804B9D4\n"
" add r5, sp\n"
" ldr r5, [r5]\n"
" lsls r0, r5, 2\n"
" ldr r1, _0804B9DC\n"
" add r1, sp\n"
" ldr r1, [r1]\n"
" adds r0, r1, r0\n"
" ldr r5, [r0]\n"
" subs r5, r2\n"
" subs r5, 0x3\n"
" movs r0, 0x5\n"
" adds r1, r4, 0\n"
" bl DungeonRandRange\n"
" mov r8, r0\n"
" movs r0, 0x4\n"
" adds r1, r5, 0\n"
" bl DungeonRandRange\n"
" adds r6, r0, 0\n"
" mov r2, r8\n"
" subs r4, r2\n"
" adds r0, r4, 0\n"
" bl DungeonRandInt\n"
" adds r4, r0, 0\n"
" add r4, r10\n"
" subs r5, r6\n"
" adds r0, r5, 0\n"
" bl DungeonRandInt\n"
" ldr r5, _0804B9E4\n"
" add r5, sp\n"
" ldr r3, [r5]\n"
" adds r3, r0\n"
" mov r10, r3\n"
" mov r0, r8\n"
" adds r3, r4, r0\n"
" add r6, r10\n"
" strh r4, [r7]\n"
" strh r3, [r7, 0x4]\n"
" mov r1, r10\n"
" strh r1, [r7, 0x2]\n"
" strh r6, [r7, 0x6]\n"
" mov r8, r9\n"
" ldr r5, _0804B9D0\n"
" add r5, sp\n"
" ldr r2, [r5]\n"
" adds r2, 0x1\n"
" ldr r5, _0804B9E8\n"
" add r5, sp\n"
" str r2, [r5]\n"
" cmp r4, r3\n"
" bge _0804B99E\n"
"_0804B956:\n"
" mov r5, r10\n"
" adds r7, r4, 0x1\n"
" cmp r5, r6\n"
" bge _0804B998\n"
" ldr r0, _0804B9EC\n"
" mov r9, r0\n"
"_0804B962:\n"
" adds r0, r4, 0\n"
" adds r1, r5, 0\n"
" ldr r2, _0804B9F0\n"
" add r2, sp\n"
" str r3, [r2]\n"
" bl GetTileSafe\n"
" ldrh r1, [r0]\n"
" mov r2, r9\n"
" ands r1, r2\n"
" movs r2, 0x1\n"
" orrs r1, r2\n"
" strh r1, [r0]\n"
" adds r0, r4, 0\n"
" adds r1, r5, 0\n"
" bl GetTileSafe\n"
" ldr r1, _0804B9D0\n"
" add r1, sp\n"
" ldrb r1, [r1]\n"
" strb r1, [r0, 0x9]\n"
" adds r5, 0x1\n"
" ldr r2, _0804B9F0\n"
" add r2, sp\n"
" ldr r3, [r2]\n"
" cmp r5, r6\n"
" blt _0804B962\n"
"_0804B998:\n"
" adds r4, r7, 0\n"
" cmp r4, r3\n"
" blt _0804B956\n"
"_0804B99E:\n"
" ldr r3, _0804B9E8\n"
" add r3, sp\n"
" ldr r3, [r3]\n"
" ldr r4, _0804B9D0\n"
" add r4, sp\n"
" str r3, [r4]\n"
" b _0804BA72\n"
" .align 2, 0\n"
"_0804B9AC: .4byte 0xffffe320\n"
"_0804B9B0: .4byte 0x00001c28\n"
"_0804B9B4: .4byte 0x00001c64\n"
"_0804B9B8: .4byte 0x00001cd4\n"
"_0804B9BC: .4byte 0x00001cd8\n"
"_0804B9C0: .4byte 0x00001cbc\n"
"_0804B9C4: .4byte 0x00001cc4\n"
"_0804B9C8: .4byte 0x00001cc8\n"
"_0804B9CC: .4byte 0x00001ca4\n"
"_0804B9D0: .4byte 0x00001ca8\n"
"_0804B9D4: .4byte 0x00001ccc\n"
"_0804B9D8: .4byte 0x00001cac\n"
"_0804B9DC: .4byte 0x00001cb4\n"
"_0804B9E0: .4byte 0x00001cb8\n"
"_0804B9E4: .4byte 0x00001cb0\n"
"_0804B9E8: .4byte 0x00001cd0\n"
"_0804B9EC: .4byte 0x0000fffc\n"
"_0804B9F0: .4byte 0x00001cdc\n"
"_0804B9F4:\n"
" lsls r0, r4, 2\n"
" ldr r5, _0804BBE8\n"
" add r5, sp\n"
" ldr r5, [r5]\n"
" adds r0, r5, r0\n"
" ldr r2, [r0]\n"
" adds r0, r2, 0x1\n"
" ldr r1, _0804BBEC\n"
" add r1, sp\n"
" ldr r1, [r1]\n"
" ldr r3, [r1]\n"
" adds r6, r3, 0x1\n"
" adds r4, 0x1\n"
" mov r8, r4\n"
" lsls r1, r4, 2\n"
" adds r1, r5, r1\n"
" ldr r1, [r1]\n"
" subs r1, r2\n"
" subs r1, 0x3\n"
" ldr r5, _0804BBF0\n"
" add r5, sp\n"
" ldr r5, [r5]\n"
" lsls r2, r5, 2\n"
" ldr r4, _0804BBF4\n"
" add r4, sp\n"
" ldr r4, [r4]\n"
" adds r2, r4, r2\n"
" ldr r4, [r2]\n"
" subs r4, r3\n"
" subs r4, 0x3\n"
" adds r1, r0, r1\n"
" bl DungeonRandRange\n"
" adds r5, r0, 0\n"
" adds r4, r6, r4\n"
" adds r0, r6, 0\n"
" adds r1, r4, 0\n"
" bl DungeonRandRange\n"
" adds r4, r0, 0\n"
" strh r5, [r7]\n"
" adds r0, r5, 0x1\n"
" strh r0, [r7, 0x4]\n"
" strh r4, [r7, 0x2]\n"
" adds r0, r4, 0x1\n"
" strh r0, [r7, 0x6]\n"
" adds r0, r5, 0\n"
" adds r1, r4, 0\n"
" bl GetTileSafe\n"
" ldrh r1, [r0]\n"
" ldr r3, _0804BBF8\n"
" adds r2, r3, 0\n"
" ands r1, r2\n"
" movs r2, 0x1\n"
" orrs r1, r2\n"
" strh r1, [r0]\n"
" adds r0, r5, 0\n"
" adds r1, r4, 0\n"
" bl GetTileSafe\n"
" movs r1, 0xFF\n"
" strb r1, [r0, 0x9]\n"
"_0804BA72:\n"
" mov r4, r8\n"
" cmp r4, 0x6\n"
" bge _0804BA7A\n"
" b _0804B898\n"
"_0804BA7A:\n"
" ldr r4, _0804BBF0\n"
" add r4, sp\n"
" ldr r4, [r4]\n"
" ldr r5, _0804BBFC\n"
" add r5, sp\n"
" str r4, [r5]\n"
" cmp r4, 0x4\n"
" bge _0804BA8C\n"
" b _0804B85C\n"
"_0804BA8C:\n"
" add r1, sp, 0x8\n"
" movs r6, 0\n"
" movs r0, 0x1\n"
" strb r0, [r1, 0x16]\n"
" ldr r1, _0804BC00\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" movs r1, 0xFF\n"
" lsls r1, 1\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC04\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC08\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC0C\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC10\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC14\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC18\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC1C\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" add r1, sp, 0x8\n"
" strb r0, [r1, 0x14]\n"
" ldr r5, _0804BC20\n"
" add r5, sp\n"
" ldr r5, [r5]\n"
" strb r0, [r5]\n"
" ldr r1, _0804BC24\n"
" add r1, sp\n"
" ldr r1, [r1]\n"
" strb r0, [r1]\n"
" ldr r2, _0804BC28\n"
" add r2, sp\n"
" ldr r2, [r2]\n"
" strb r0, [r2]\n"
" movs r3, 0xE6\n"
" lsls r3, 5\n"
" add r3, sp\n"
" ldr r3, [r3]\n"
" strb r0, [r3]\n"
" ldr r4, _0804BC2C\n"
" add r4, sp\n"
" ldr r4, [r4]\n"
" strb r0, [r4]\n"
" ldr r5, _0804BC30\n"
" add r5, sp\n"
" ldr r5, [r5]\n"
" strb r0, [r5]\n"
" ldr r1, _0804BC34\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC38\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC3C\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC40\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC44\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC48\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC4C\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC50\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC54\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC58\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC5C\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC60\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC64\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC68\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" ldr r1, _0804BC6C\n"
" add r1, sp\n"
" strb r0, [r1]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x6\n"
" movs r2, 0x4\n"
" movs r4, 0xE5\n"
" lsls r4, 5\n"
" add r4, sp\n"
" ldr r3, [r4]\n"
" bl sub_804D5B0\n"
" ldr r5, _0804BC70\n"
" add r5, sp\n"
" ldr r4, _0804BC74\n"
" add r4, sp\n"
" str r4, [sp]\n"
" str r6, [sp, 0x4]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x6\n"
" movs r2, 0x4\n"
" adds r3, r5, 0\n"
" bl CreateGridCellConnections\n"
" str r4, [sp]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x6\n"
" movs r2, 0x4\n"
" adds r3, r5, 0\n"
" bl EnsureConnectedGrid\n"
" ldr r0, _0804BC78\n"
" movs r5, 0\n"
" ldrsh r3, [r0, r5]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x6\n"
" movs r2, 0x4\n"
" bl GenerateKecleonShop\n"
" ldr r0, _0804BC7C\n"
" movs r1, 0\n"
" ldrsh r3, [r0, r1]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x6\n"
" movs r2, 0x4\n"
" bl GenerateMonsterHouse\n"
" movs r2, 0xE5\n"
" lsls r2, 5\n"
" add r2, sp\n"
" ldr r2, [r2]\n"
" ldrb r3, [r2, 0x13]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x6\n"
" movs r2, 0x4\n"
" bl GenerateExtraHallways\n"
" add r0, sp, 0x8\n"
" movs r1, 0x6\n"
" movs r2, 0x4\n"
" bl GenerateRoomImperfections\n"
" movs r3, 0xE7\n"
" lsls r3, 5\n"
" add sp, r3\n"
" pop {r3-r5}\n"
" mov r8, r3\n"
" mov r9, r4\n"
" mov r10, r5\n"
" pop {r4-r7}\n"
" pop {r0}\n"
" bx r0\n"
" .align 2, 0\n"
"_0804BBE8: .4byte 0x00001cac\n"
"_0804BBEC: .4byte 0x00001cb8\n"
"_0804BBF0: .4byte 0x00001ccc\n"
"_0804BBF4: .4byte 0x00001cb4\n"
"_0804BBF8: .4byte 0x0000fffc\n"
"_0804BBFC: .4byte 0x00001ca4\n"
"_0804BC00: .4byte 0x000001fd\n"
"_0804BC04: .4byte 0x000003dd\n"
"_0804BC08: .4byte 0x000003de\n"
"_0804BC0C: .4byte 0x000005bd\n"
"_0804BC10: .4byte 0x000005be\n"
"_0804BC14: .4byte 0x0000079d\n"
"_0804BC18: .4byte 0x0000079e\n"
"_0804BC1C: .4byte 0x0000097d\n"
"_0804BC20: .4byte 0x00001cd4\n"
"_0804BC24: .4byte 0x00001cd8\n"
"_0804BC28: .4byte 0x00001cbc\n"
"_0804BC2C: .4byte 0x00001cc4\n"
"_0804BC30: .4byte 0x00001cc8\n"
"_0804BC34: .4byte 0x0000025d\n"
"_0804BC38: .4byte 0x0000025e\n"
"_0804BC3C: .4byte 0x0000043d\n"
"_0804BC40: .4byte 0x0000043e\n"
"_0804BC44: .4byte 0x0000061d\n"
"_0804BC48: .4byte 0x0000061e\n"
"_0804BC4C: .4byte 0x000007fd\n"
"_0804BC50: .4byte 0x000007fe\n"
"_0804BC54: .4byte 0x000009dd\n"
"_0804BC58: .4byte 0x0000097c\n"
"_0804BC5C: .4byte 0x0000099b\n"
"_0804BC60: .4byte 0x0000099c\n"
"_0804BC64: .4byte 0x000009bb\n"
"_0804BC68: .4byte 0x000009bc\n"
"_0804BC6C: .4byte 0x000009db\n"
"_0804BC70: .4byte 0x00001c28\n"
"_0804BC74: .4byte 0x00001c64\n"
"_0804BC78: .4byte gUnknown_202F1B0\n"
"_0804BC7C: .4byte gUnknown_202F1B2");
}
#endif // NONMATCHING
#ifdef NONMATCHING
void sub_804BC80(UnkDungeonGlobal_unk1C574 *a0)
{
}
#else
NAKED void sub_804BC80(UnkDungeonGlobal_unk1C574 *a0)
{
asm_unified("push {r4-r7,lr}\n"
" mov r7, r10\n"
" mov r6, r9\n"
" mov r5, r8\n"
" push {r5-r7}\n"
" ldr r4, _0804BED0\n"
" add sp, r4\n"
" movs r1, 0xE5\n"
" lsls r1, 5\n"
" add r1, sp\n"
" str r0, [r1]\n"
" movs r4, 0x1\n"
" movs r5, 0\n"
" ldr r1, _0804BED4\n"
" add r1, sp\n"
" str r5, [r1]\n"
" movs r0, 0xB\n"
" str r0, [r1, 0x4]\n"
" movs r0, 0x16\n"
" str r0, [r1, 0x8]\n"
" movs r0, 0x21\n"
" str r0, [r1, 0xC]\n"
" movs r0, 0x2C\n"
" str r0, [r1, 0x10]\n"
" movs r0, 0x38\n"
" str r0, [r1, 0x14]\n"
" ldr r1, _0804BED8\n"
" add r1, sp\n"
" str r4, [r1]\n"
" movs r0, 0x9\n"
" str r0, [r1, 0x4]\n"
" movs r0, 0x10\n"
" str r0, [r1, 0x8]\n"
" movs r0, 0x17\n"
" str r0, [r1, 0xC]\n"
" movs r0, 0x1F\n"
" str r0, [r1, 0x10]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x5\n"
" movs r2, 0x4\n"
" bl InitDungeonGrid\n"
" add r6, sp, 0x70\n"
" add r1, sp, 0x68\n"
" add r0, sp, 0x8\n"
" movs r3, 0xF0\n"
" lsls r3, 1\n"
" movs r2, 0x5\n"
"_0804BCE0:\n"
" strb r4, [r0, 0xA]\n"
" strb r4, [r1, 0xA]\n"
" adds r1, r3\n"
" adds r0, r3\n"
" subs r2, 0x1\n"
" cmp r2, 0\n"
" bne _0804BCE0\n"
" movs r3, 0x5\n"
" subs r3, 0x1\n"
" movs r2, 0x4\n"
" cmp r2, 0\n"
" beq _0804BD1A\n"
" lsls r0, r3, 4\n"
" subs r0, r3\n"
" lsls r0, 5\n"
" add r0, sp\n"
" adds r0, 0x8\n"
" add r1, sp, 0x8\n"
" mov r10, r2\n"
"_0804BD06:\n"
" strb r4, [r1, 0xA]\n"
" strb r4, [r0, 0xA]\n"
" adds r0, 0x20\n"
" adds r1, 0x20\n"
" movs r2, 0x1\n"
" negs r2, r2\n"
" add r10, r2\n"
" mov r2, r10\n"
" cmp r2, 0\n"
" bne _0804BD06\n"
"_0804BD1A:\n"
" movs r2, 0x1\n"
" cmp r2, r3\n"
" bge _0804BD58\n"
" movs r1, 0x3\n"
"_0804BD22:\n"
" adds r4, r2, 0x1\n"
" ldr r0, _0804BEDC\n"
" add r0, sp\n"
" str r4, [r0]\n"
" cmp r1, 0x1\n"
" ble _0804BD4E\n"
" lsls r0, r2, 4\n"
" subs r0, r2\n"
" lsls r0, 5\n"
" add r0, sp\n"
" adds r0, 0x8\n"
" adds r0, 0x20\n"
" subs r2, r1, 0x1\n"
" mov r10, r2\n"
"_0804BD3E:\n"
" strb r5, [r0, 0xA]\n"
" adds r0, 0x20\n"
" movs r4, 0x1\n"
" negs r4, r4\n"
" add r10, r4\n"
" mov r2, r10\n"
" cmp r2, 0\n"
" bne _0804BD3E\n"
"_0804BD4E:\n"
" ldr r4, _0804BEDC\n"
" add r4, sp\n"
" ldr r2, [r4]\n"
" cmp r2, r3\n"
" blt _0804BD22\n"
"_0804BD58:\n"
" add r0, sp, 0x8\n"
" movs r1, 0x1\n"
" strb r1, [r0, 0x8]\n"
" movs r0, 0xF2\n"
" lsls r0, 3\n"
" add r0, sp\n"
" strb r1, [r0]\n"
" strb r1, [r6]\n"
" movs r0, 0xFE\n"
" lsls r0, 3\n"
" add r0, sp\n"
" strb r1, [r0]\n"
" movs r5, 0\n"
" ldr r6, _0804BEE0\n"
" add r6, sp\n"
" str r5, [r6]\n"
" mov r10, r5\n"
" cmp r5, 0x4\n"
" blt _0804BD80\n"
" b _0804BFAC\n"
"_0804BD80:\n"
" movs r0, 0x4\n"
" movs r1, 0xE6\n"
" lsls r1, 5\n"
" add r1, sp\n"
" str r0, [r1]\n"
"_0804BD8A:\n"
" movs r2, 0\n"
" cmp r2, 0x5\n"
" blt _0804BD92\n"
" b _0804BF94\n"
"_0804BD92:\n"
" ldr r3, _0804BED4\n"
" add r3, sp\n"
" ldr r4, _0804BEE4\n"
" add r4, sp\n"
" str r3, [r4]\n"
" ldr r5, _0804BED8\n"
" add r5, sp\n"
" ldr r6, _0804BEE8\n"
" add r6, sp\n"
" str r5, [r6]\n"
" mov r1, r10\n"
" lsls r0, r1, 2\n"
" adds r0, r5, r0\n"
" ldr r3, _0804BEEC\n"
" add r3, sp\n"
" str r0, [r3]\n"
"_0804BDB2:\n"
" lsls r0, r2, 4\n"
" subs r0, r2\n"
" add r0, r10\n"
" lsls r0, 5\n"
" mov r7, sp\n"
" adds r7, r0\n"
" adds r7, 0x8\n"
" ldrb r0, [r7, 0x8]\n"
" adds r4, r2, 0x1\n"
" ldr r5, _0804BEDC\n"
" add r5, sp\n"
" str r4, [r5]\n"
" cmp r0, 0\n"
" beq _0804BDD0\n"
" b _0804BF88\n"
"_0804BDD0:\n"
" ldrb r0, [r7, 0xA]\n"
" cmp r0, 0\n"
" bne _0804BDD8\n"
" b _0804BF00\n"
"_0804BDD8:\n"
" lsls r0, r2, 2\n"
" ldr r6, _0804BEE4\n"
" add r6, sp\n"
" ldr r6, [r6]\n"
" adds r0, r6, r0\n"
" ldr r1, [r0]\n"
" adds r0, r1, 0x2\n"
" mov r9, r0\n"
" ldr r3, _0804BEEC\n"
" add r3, sp\n"
" ldr r3, [r3]\n"
" ldr r2, [r3]\n"
" adds r4, r2, 0x2\n"
" ldr r5, _0804BEF0\n"
" add r5, sp\n"
" str r4, [r5]\n"
" ldr r6, _0804BEDC\n"
" add r6, sp\n"
" ldr r6, [r6]\n"
" lsls r0, r6, 2\n"
" ldr r3, _0804BEE4\n"
" add r3, sp\n"
" ldr r3, [r3]\n"
" adds r0, r3, r0\n"
" ldr r4, [r0]\n"
" subs r4, r1\n"
" subs r4, 0x3\n"
" ldr r5, _0804BEE8\n"
" add r5, sp\n"
" ldr r5, [r5]\n"
" movs r6, 0xE6\n"
" lsls r6, 5\n"
" add r6, sp\n"
" ldr r6, [r6]\n"
" adds r0, r5, r6\n"
" ldr r5, [r0]\n"
" subs r5, r2\n"
" subs r5, 0x3\n"
" movs r0, 0x5\n"
" adds r1, r4, 0\n"
" bl DungeonRandRange\n"
" mov r8, r0\n"
" movs r0, 0x4\n"
" adds r1, r5, 0\n"
" bl DungeonRandRange\n"
" adds r6, r0, 0\n"
" mov r0, r8\n"
" subs r4, r0\n"
" adds r0, r4, 0\n"
" bl DungeonRandInt\n"
" adds r4, r0, 0\n"
" add r4, r9\n"
" subs r5, r6\n"
" adds r0, r5, 0\n"
" bl DungeonRandInt\n"
" ldr r2, _0804BEF0\n"
" add r2, sp\n"
" ldr r1, [r2]\n"
" adds r1, r0\n"
" mov r9, r1\n"
" mov r5, r8\n"
" adds r3, r4, r5\n"
" add r6, r9\n"
" strh r4, [r7]\n"
" strh r3, [r7, 0x4]\n"
" strh r1, [r7, 0x2]\n"
" strh r6, [r7, 0x6]\n"
" ldr r1, _0804BEE0\n"
" add r1, sp\n"
" ldr r0, [r1]\n"
" adds r0, 0x1\n"
" ldr r1, _0804BEF4\n"
" add r1, sp\n"
" str r0, [r1]\n"
" cmp r4, r3\n"
" bge _0804BEC0\n"
"_0804BE78:\n"
" mov r5, r9\n"
" adds r7, r4, 0x1\n"
" cmp r5, r6\n"
" bge _0804BEBA\n"
" ldr r2, _0804BEF8\n"
" mov r8, r2\n"
"_0804BE84:\n"
" adds r0, r4, 0\n"
" adds r1, r5, 0\n"
" ldr r2, _0804BEFC\n"
" add r2, sp\n"
" str r3, [r2]\n"
" bl GetTileSafe\n"
" ldrh r1, [r0]\n"
" mov r2, r8\n"
" ands r1, r2\n"
" movs r2, 0x1\n"
" orrs r1, r2\n"
" strh r1, [r0]\n"
" adds r0, r4, 0\n"
" adds r1, r5, 0\n"
" bl GetTileSafe\n"
" ldr r1, _0804BEE0\n"
" add r1, sp\n"
" ldrb r1, [r1]\n"
" strb r1, [r0, 0x9]\n"
" adds r5, 0x1\n"
" ldr r2, _0804BEFC\n"
" add r2, sp\n"
" ldr r3, [r2]\n"
" cmp r5, r6\n"
" blt _0804BE84\n"
"_0804BEBA:\n"
" adds r4, r7, 0\n"
" cmp r4, r3\n"
" blt _0804BE78\n"
"_0804BEC0:\n"
" ldr r3, _0804BEF4\n"
" add r3, sp\n"
" ldr r3, [r3]\n"
" ldr r4, _0804BEE0\n"
" add r4, sp\n"
" str r3, [r4]\n"
" b _0804BF88\n"
" .align 2, 0\n"
"_0804BED0: .4byte 0xffffe338\n"
"_0804BED4: .4byte 0x00001c28\n"
"_0804BED8: .4byte 0x00001c64\n"
"_0804BEDC: .4byte 0x00001cb8\n"
"_0804BEE0: .4byte 0x00001ca4\n"
"_0804BEE4: .4byte 0x00001ca8\n"
"_0804BEE8: .4byte 0x00001cb0\n"
"_0804BEEC: .4byte 0x00001cb4\n"
"_0804BEF0: .4byte 0x00001cac\n"
"_0804BEF4: .4byte 0x00001cbc\n"
"_0804BEF8: .4byte 0x0000fffc\n"
"_0804BEFC: .4byte 0x00001cc4\n"
"_0804BF00:\n"
" lsls r0, r2, 2\n"
" ldr r4, _0804C080\n"
" add r4, sp\n"
" ldr r4, [r4]\n"
" adds r0, r4, r0\n"
" ldr r2, [r0]\n"
" adds r0, r2, 0x1\n"
" ldr r5, _0804C084\n"
" add r5, sp\n"
" ldr r5, [r5]\n"
" ldr r3, [r5]\n"
" adds r6, r3, 0x1\n"
" mov r8, r6\n"
" ldr r4, _0804C088\n"
" add r4, sp\n"
" ldr r4, [r4]\n"
" lsls r1, r4, 2\n"
" ldr r5, _0804C080\n"
" add r5, sp\n"
" ldr r5, [r5]\n"
" adds r1, r5, r1\n"
" ldr r1, [r1]\n"
" subs r1, r2\n"
" subs r1, 0x3\n"
" ldr r6, _0804C08C\n"
" add r6, sp\n"
" ldr r6, [r6]\n"
" movs r4, 0xE6\n"
" lsls r4, 5\n"
" add r4, sp\n"
" ldr r4, [r4]\n"
" adds r2, r6, r4\n"
" ldr r4, [r2]\n"
" subs r4, r3\n"
" subs r4, 0x3\n"
" adds r1, r0, r1\n"
" bl DungeonRandRange\n"
" adds r5, r0, 0\n"
" add r4, r8\n"
" mov r0, r8\n"
" adds r1, r4, 0\n"
" bl DungeonRandRange\n"
" adds r4, r0, 0\n"
" strh r5, [r7]\n"
" adds r0, r5, 0x1\n"
" strh r0, [r7, 0x4]\n"
" strh r4, [r7, 0x2]\n"
" adds r0, r4, 0x1\n"
" strh r0, [r7, 0x6]\n"
" adds r0, r5, 0\n"
" adds r1, r4, 0\n"
" bl GetTileSafe\n"
" ldrh r1, [r0]\n"
" ldr r6, _0804C090\n"
" adds r2, r6, 0\n"
" ands r1, r2\n"
" movs r2, 0x1\n"
" orrs r1, r2\n"
" strh r1, [r0]\n"
" adds r0, r5, 0\n"
" adds r1, r4, 0\n"
" bl GetTileSafe\n"
" movs r1, 0xFF\n"
" strb r1, [r0, 0x9]\n"
"_0804BF88:\n"
" ldr r0, _0804C088\n"
" add r0, sp\n"
" ldr r2, [r0]\n"
" cmp r2, 0x5\n"
" bge _0804BF94\n"
" b _0804BDB2\n"
"_0804BF94:\n"
" movs r2, 0xE6\n"
" lsls r2, 5\n"
" add r2, sp\n"
" ldr r1, [r2]\n"
" adds r1, 0x4\n"
" str r1, [r2]\n"
" movs r3, 0x1\n"
" add r10, r3\n"
" mov r4, r10\n"
" cmp r4, 0x4\n"
" bge _0804BFAC\n"
" b _0804BD8A\n"
"_0804BFAC:\n"
" movs r2, 0x1\n"
" movs r1, 0x1\n"
" movs r3, 0xF\n"
" add r4, sp, 0x1C\n"
"_0804BFB4:\n"
" movs r5, 0\n"
" mov r10, r5\n"
" lsls r0, r3, 5\n"
" adds r0, r4\n"
"_0804BFBC:\n"
" strb r1, [r0]\n"
" strb r1, [r0, 0x1F]\n"
" adds r0, 0x20\n"
" movs r6, 0x1\n"
" add r10, r6\n"
" mov r5, r10\n"
" cmp r5, 0x2\n"
" ble _0804BFBC\n"
" movs r0, 0xF0\n"
" lsls r0, 1\n"
" adds r3, 0xF\n"
" adds r2, 0x1\n"
" cmp r2, 0x3\n"
" ble _0804BFB4\n"
" mov r10, r6\n"
" movs r5, 0x1\n"
" adds r4, r0, 0\n"
" mov r6, sp\n"
" adds r6, r4\n"
" adds r6, 0x8\n"
"_0804BFE4:\n"
" movs r2, 0\n"
" mov r1, r10\n"
" lsls r0, r1, 5\n"
" mov r3, r10\n"
" adds r3, 0x1\n"
" adds r1, r0, r6\n"
" add r0, sp\n"
" adds r0, 0x8\n"
"_0804BFF4:\n"
" strb r5, [r0, 0x16]\n"
" strb r5, [r1, 0x15]\n"
" adds r1, r4\n"
" adds r0, r4\n"
" adds r2, 0x1\n"
" cmp r2, 0x3\n"
" ble _0804BFF4\n"
" mov r10, r3\n"
" cmp r3, 0x2\n"
" ble _0804BFE4\n"
" ldr r5, _0804C094\n"
" add r5, sp\n"
" ldr r4, _0804C098\n"
" add r4, sp\n"
" str r4, [sp]\n"
" movs r0, 0x1\n"
" str r0, [sp, 0x4]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x5\n"
" movs r2, 0x4\n"
" adds r3, r5, 0\n"
" bl CreateGridCellConnections\n"
" str r4, [sp]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x5\n"
" movs r2, 0x4\n"
" adds r3, r5, 0\n"
" bl EnsureConnectedGrid\n"
" ldr r0, _0804C09C\n"
" movs r2, 0\n"
" ldrsh r3, [r0, r2]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x5\n"
" movs r2, 0x4\n"
" bl GenerateKecleonShop\n"
" ldr r0, _0804C0A0\n"
" movs r4, 0\n"
" ldrsh r3, [r0, r4]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x5\n"
" movs r2, 0x4\n"
" bl GenerateMonsterHouse\n"
" movs r5, 0xE5\n"
" lsls r5, 5\n"
" add r5, sp\n"
" ldr r5, [r5]\n"
" ldrb r3, [r5, 0x13]\n"
" add r0, sp, 0x8\n"
" movs r1, 0x5\n"
" movs r2, 0x4\n"
" bl GenerateExtraHallways\n"
" add r0, sp, 0x8\n"
" movs r1, 0x5\n"
" movs r2, 0x4\n"
" bl GenerateRoomImperfections\n"
" ldr r3, _0804C0A4\n"
" add sp, r3\n"
" pop {r3-r5}\n"
" mov r8, r3\n"
" mov r9, r4\n"
" mov r10, r5\n"
" pop {r4-r7}\n"
" pop {r0}\n"
" bx r0\n"
" .align 2, 0\n"
"_0804C080: .4byte 0x00001ca8\n"
"_0804C084: .4byte 0x00001cb4\n"
"_0804C088: .4byte 0x00001cb8\n"
"_0804C08C: .4byte 0x00001cb0\n"
"_0804C090: .4byte 0x0000fffc\n"
"_0804C094: .4byte 0x00001c28\n"
"_0804C098: .4byte 0x00001c64\n"
"_0804C09C: .4byte gUnknown_202F1B0\n"
"_0804C0A0: .4byte gUnknown_202F1B2\n"
"_0804C0A4: .4byte 0x00001cc8");
}
#endif // NONMATCHING
// GenerateLineFloor - Generates a floor layout with 5 grid cells in a horizontal line.
void GenerateLineFloor(UnkDungeonGlobal_unk1C574 *unkPtr)
{
struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN];
s32 listX[GRID_CELL_LEN];
s32 listY[GRID_CELL_LEN];
s32 sizeX, sizeY;
bool8 disableRoomMerging;
listX[0] = 0;
listX[1] = 11;
listX[2] = 22;
listX[3] = 33;
listX[4] = 44;
listX[5] = 56;
listY[0] = 4;
listY[1] = 15;
disableRoomMerging = 1;
sizeX = 5, sizeY = 1;
InitDungeonGrid(grid, sizeX, sizeY);
AssignRooms(grid, sizeX, sizeY, unkPtr->unk1);
CreateRoomsAndAnchors(grid, sizeX, sizeY, listX, listY, unkPtr->unkD);
sub_804D5B0(grid, sizeX, sizeY, unkPtr);
CreateGridCellConnections(grid, sizeX, sizeY, listX, listY, disableRoomMerging);
EnsureConnectedGrid(grid, sizeX, sizeY, listX, listY);
GenerateKecleonShop(grid, sizeX, sizeY, gUnknown_202F1B0);
GenerateMonsterHouse(grid, sizeX, sizeY, gUnknown_202F1B2);
GenerateExtraHallways(grid, sizeX, sizeY, unkPtr->unk13);
GenerateRoomImperfections(grid, sizeX, sizeY);
}
// GenerateCrossFloor - Generates a floor layout with 5 rooms arranged in a "plus" or "cross" configuration.
void GenerateCrossFloor(UnkDungeonGlobal_unk1C574 *unkPtr)
{
struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN];
s32 listX[GRID_CELL_LEN];
s32 listY[GRID_CELL_LEN];
s32 x, y, sizeX, sizeY;
listX[0] = 11;
listX[1] = 22;
listX[2] = 33;
listX[3] = 44;
listY[0] = 2;
listY[1] = 11;
listY[2] = 20;
listY[3] = 30;
sizeX = 3, sizeY = 3;
InitDungeonGrid(grid, sizeX, sizeY);
// Set all cells as rooms
for (x = 0; x < sizeX; x++) {
for (y = 0; y < sizeY; y++) {
grid[x][y].isRoom = TRUE;
}
}
// Invalidate the corners
grid[0][0].isInvalid = TRUE;
grid[2][0].isInvalid = TRUE;
grid[0][2].isInvalid = TRUE;
grid[2][2].isInvalid = TRUE;
CreateRoomsAndAnchors(grid, sizeX, sizeY, listX, listY, unkPtr->unkD);
grid[0][1].connectedToRight = TRUE;
grid[1][1].connectedToLeft = TRUE;
grid[1][1].connectedToRight = TRUE;
grid[2][1].connectedToLeft = TRUE;
grid[1][0].connectedToBottom = TRUE;
grid[1][1].connectedToTop = TRUE;
grid[1][1].connectedToBottom = TRUE;
grid[1][2].connectedToTop = TRUE;
CreateGridCellConnections(grid, sizeX, sizeY, listX, listY, TRUE);
EnsureConnectedGrid(grid, sizeX, sizeY, listX, listY);
GenerateKecleonShop(grid, sizeX, sizeY, gUnknown_202F1B0);
GenerateMonsterHouse(grid, sizeX, sizeY, gUnknown_202F1B2);
GenerateExtraHallways(grid, sizeX, sizeY, unkPtr->unk13);
GenerateRoomImperfections(grid, sizeX, sizeY);
}
// GenerateBeetleFloor - Generates a floor layout in a "beetle" shape, with a
// 3x3 grid of rooms, a merged center column, and hallways along each row
void GenerateBeetleFloor(UnkDungeonGlobal_unk1C574 *unkPtr)
{
struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN];
s32 listX[GRID_CELL_LEN];
s32 listY[GRID_CELL_LEN];
s32 x, y, sizeX, sizeY;
listX[0] = 5;
listX[1] = 15;
listX[2] = 35;
listX[3] = 50;
listY[0] = 2;
listY[1] = 11;
listY[2] = 20;
listY[3] = 30;
sizeX = 3, sizeY = 3;
InitDungeonGrid(grid, sizeX, sizeY);
// Set all cells as rooms
for (x = 0; x < sizeX; x++) {
for (y = 0; y < sizeY; y++) {
grid[x][y].isRoom = TRUE;
}
}
CreateRoomsAndAnchors(grid, sizeX, sizeY, listX, listY, unkPtr->unkD);
// Connect rooms in the same row together
for (y = 0; y < 3; y++) {
grid[0][y].connectedToRight = TRUE;
grid[1][y].connectedToLeft = TRUE;
grid[1][y].connectedToRight = TRUE;
grid[2][y].connectedToLeft = TRUE;
}
CreateGridCellConnections(grid, sizeX, sizeY, listX, listY, TRUE);
// Merge the center column into one large room
MergeRoomsVertically(1, 0, 1, grid);
MergeRoomsVertically(1, 0, 2, grid);
EnsureConnectedGrid(grid, sizeX, sizeY, listX, listY);
GenerateKecleonShop(grid, sizeX, sizeY, gUnknown_202F1B0);
GenerateMonsterHouse(grid, sizeX, sizeY, gUnknown_202F1B2);
GenerateExtraHallways(grid, sizeX, sizeY, unkPtr->unk13);
GenerateRoomImperfections(grid, sizeX, sizeY);
}
// MergeRoomsVertically - Merges two vertically stacked rooms into one larger room.
static void MergeRoomsVertically(s32 roomX, s32 room_y1, s32 room_dy, struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN])
{
s32 x, y;
s32 xStart = min(grid[roomX][room_y1].start.x, grid[roomX][room_y1+room_dy].start.x);
s32 yStart = grid[roomX][room_y1].start.y;
s32 xEnd = max(grid[roomX][room_y1].end.x, grid[roomX][room_y1+room_dy].end.x);
s32 yEnd = grid[roomX][room_y1 + room_dy].end.y;
// Carve out the new larger room, retaining the index of the first room
u8 roomId = GetTile(grid[roomX][room_y1].start.x, grid[roomX][room_y1].start.y)->room;
for (x = xStart; x < xEnd; x++) {
for (y = yStart; y < yEnd; y++) {
Tile *tile = GetTileSafe(x, y);
SetTerrainNormal(tile);
tile->room = roomId;
}
}
grid[roomX][room_y1].start.x = xStart;
grid[roomX][room_y1].end.x = xEnd;
grid[roomX][room_y1].start.y = yStart;
grid[roomX][room_y1].end.y = yEnd;
grid[roomX][room_y1 + room_dy].isMerged = TRUE;
grid[roomX][room_y1].isMerged = TRUE;
grid[roomX][room_y1 + room_dy].isConnected = FALSE;
grid[roomX][room_y1 + room_dy].hasBeenMerged = TRUE;
}
// GenerateOuterRoomsFloor - Generates a floor layout with a ring of rooms and nothing on the interior.
// This layout is bugged and will not properly connect rooms for sizeX < 3.
void GenerateOuterRoomsFloor(s32 sizeX_, s32 sizeY_, UnkDungeonGlobal_unk1C574 *unkPtr)
{
struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN];
s32 listX[GRID_CELL_LEN];
s32 listY[GRID_CELL_LEN];
s32 x, y;
s32 sizeX = sizeX_;
s32 sizeY = sizeY_;
GetGridPositions(listX, listY, sizeX, sizeY);
InitDungeonGrid(grid, sizeX, sizeY);
// Make all cells rooms
for (x = 0; x < sizeX; x++) {
for (y = 0; y < sizeY; y++) {
grid[x][y].isRoom = TRUE;
}
}
// Invalidate all interior cells
for (x = 1; x < sizeX - 1; x++) {
for (y = 1; y < sizeY - 1; y++) {
grid[x][y].isInvalid = TRUE;
}
}
CreateRoomsAndAnchors(grid, sizeX, sizeY, listX, listY, unkPtr->unkD);
// Maybe Todo: Add EpicYoshiMaster's fixed implementation of this function
// The original implementation fails for sizeX <= 2, as one of the branches
// is never taken, and the other branch does not provide a backup connection, leaving the two sides unconnected.
// Additionally, there is a minor issue for top/bottom connections which results in hallways being connected from the bottom
// instead of from the top, but this does not affect the connectivity of the map.
for (x = 0; x < sizeX - 1; x++) {
if (x != 0) {
grid[x][0].connectedToRight = TRUE;
grid[x][sizeY-1].connectedToRight = TRUE;
}
// Bug: if sizeX <= 2, this branch will never be run.
// Additionally, because the branch above this has no meaningful hallways produced for
// sizeX == 1, no connections will be made between columns here.
// This results in an unconnected map for sizeX <= 2.
if (x < sizeX - 2) {
grid[x+1][0].connectedToLeft = TRUE;
grid[x+1][sizeY-1].connectedToLeft = TRUE;
}
}
for (y = 0; y < sizeY - 1; y++) {
if (y != 0) {
grid[0][y].connectedToTop = TRUE;
grid[sizeX-1][y].connectedToTop = TRUE;
}
// This connection ends up not being set for the bottom row, but this is fine because the other
// connection to this room is still correct. The result is that hallways here will be using the opposing end
// of the grid cell boundary for their turns compared to top/bottom hallways between other rows.
if (y < sizeY - 2) {
grid[0][y].connectedToBottom = TRUE;
grid[sizeX-1][y].connectedToBottom = TRUE;
}
}
CreateGridCellConnections(grid, sizeX, sizeY, listX, listY, FALSE);
EnsureConnectedGrid(grid, sizeX, sizeY, listX, listY);
GenerateMazeRoom(grid, sizeX, sizeY, unkPtr->unk9);
GenerateKecleonShop(grid, sizeX, sizeY, gUnknown_202F1B0);
GenerateMonsterHouse(grid, sizeX, sizeY, gUnknown_202F1B2);
GenerateExtraHallways(grid, sizeX, sizeY, unkPtr->unk13);
GenerateRoomImperfections(grid, sizeX, sizeY);
GenerateSecondaryStructures(grid, sizeX, sizeY);
}
void sub_804C790(s32 x1, s32 y1, s32 x2, s32 y2, s32 a4, UnkDungeonGlobal_unk1C574 *unkPtr);
extern void sub_8051288(s32 a0);
bool8 sub_804C70C(s32 a0, UnkDungeonGlobal_unk1C574 *unkPtr)
{
struct FileFixedmapPosStruct **fileData = (void *) gDungeon->unk13568->data;
s32 x1 = fileData[a0]->x;
s32 y1 = fileData[a0]->y;
s32 x2, y2;
if (x1 == 0 || y1 == 0) {
GenerateOneRoomMonsterHouseFloor();
return FALSE;
}
else if (a0 < 50) {
sub_8051288(a0);
return TRUE;
}
else {
x2 = DUNGEON_MAX_SIZE_X / (x1 + 4);
if (x2 <= 1)
x2 = 1;
y2 = DUNGEON_MAX_SIZE_Y / (y1 + 4);
if (y2 <= 1)
y2 = 1;
sub_804C790(x2, y2, x1, y1, a0, unkPtr);
return FALSE;
}
}
void sub_8050F90(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 x1, s32 y1, s32 *a3, s32 *a4, s32 a5, s32 x2, s32 y2);
void sub_804D5F0(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 x, s32 y, s32 x2, s32 y2, UnkDungeonGlobal_unk1C574 *unkPtr);
void sub_8051438(struct GridCell *cell, s32 a1);
void sub_804C790(s32 x1, s32 y1, s32 x2, s32 y2, s32 a4, UnkDungeonGlobal_unk1C574 *unkPtr)
{
s32 tries;
struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN];
s32 listX[GRID_CELL_LEN];
s32 listY[GRID_CELL_LEN];
s32 r10 = 0;
s32 x3 = 0, y3 = 0;
GetGridPositions(listX, listY, x1, y1);
InitDungeonGrid(grid, x1, y1);
AssignRooms(grid, x1, y1, unkPtr->unk1);
for (x3 = 0; x3 < x1; x3++) {
for (y3 = 0; y3 < y1; y3++) {
grid[x3][y3].unk27 = 1;
}
}
for (tries = 0; tries < 64; tries++) {
x3 = DungeonRandInt(x1);
y3 = DungeonRandInt(y1);
r10 = y3 * x1 + x3;
if (grid[x3][y3].isRoom)
break;
}
sub_8050F90(grid, x1, y1, listX, listY, r10, x2, y2);
if (x1 != 1 || y1 != 1) {
sub_804D5F0(grid, x1, y1, x3, y3, unkPtr);
CreateGridCellConnections(grid, x1, y1, listX, listY, TRUE);
EnsureConnectedGrid(grid, x1, y1, listX, listY);
}
sub_8051438(&grid[x3][y3], a4);
}
/*
* GenerateOneRoomMonsterHouseFloor - Generates a floor layout with just one large room which is a Monster House.
* This generator is used as a fallback in the event generation fails too many times.
*/
void GenerateOneRoomMonsterHouseFloor(void)
{
s32 x, y;
struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN];
InitDungeonGrid(grid, 1, 1);
grid[0][0].start.x = 2;
grid[0][0].end.x = DUNGEON_MAX_SIZE_X - 2;
grid[0][0].start.y = 2;
grid[0][0].end.y = DUNGEON_MAX_SIZE_Y - 2;
grid[0][0].isRoom = TRUE;
grid[0][0].isConnected = TRUE;
grid[0][0].isInvalid = FALSE;
for (x = grid[0][0].start.x; x < grid[0][0].end.x; x++) {
for (y = grid[0][0].start.y; y < grid[0][0].end.y; y++) {
SetTerrainNormal(GetTileSafe(x, y));
GetTileSafe(x, y)->room = 0;
}
}
GenerateMonsterHouse(grid, 1, 1, 999);
}
// GenerateTwoRoomsWithMonsterHouseFloor - Generates a floor layout with two rooms (left and right), with one being a Monster House.
void GenerateTwoRoomsWithMonsterHouseFloor(void)
{
struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN];
s32 listX[GRID_CELL_LEN];
s32 listY[GRID_CELL_LEN];
const s32 sizeX = 2;
const s32 sizeY = 1;
s32 currRoomId = 0;
s32 x, y;
listX[0] = 2;
listX[1] = 28;
listX[2] = 54;
listY[0] = 2;
listY[1] = 30;
InitDungeonGrid(grid, sizeX, sizeY);
for (y = 0; y < sizeY; y++) {
for (x = 0; x < sizeX; x++) {
s32 currX, currY;
s32 minX = listX[x] + 1;
s32 minY = listY[y] + 1;
s32 rangeX = listX[x + 1] - listX[x] - 3;
s32 rangeY = listY[y + 1] - listY[y] - 3;
s32 roomSizeX = DungeonRandRange(10, rangeX);
s32 roomSizeY = DungeonRandRange(16, rangeY);
s32 startX = DungeonRandInt(rangeX - roomSizeX) + minX;
s32 startY = DungeonRandInt(rangeY - roomSizeY) + minY;
s32 endX = startX + roomSizeX;
s32 endY = startY + roomSizeY;
grid[x][y].isRoom = TRUE;
grid[x][y].start.x = startX;
grid[x][y].end.x = endX;
grid[x][y].start.y = startY;
grid[x][y].end.y = endY;
for (currX = startX; currX < endX; currX++) {
for (currY = startY; currY < endY; currY++) {
SetTerrainNormal(GetTileSafe(currX, currY));
GetTileSafe(currX, currY)->room = currRoomId;
}
}
currRoomId++;
}
}
grid[0][0].connectedToRight = TRUE;
grid[1][0].connectedToLeft = TRUE;
CreateGridCellConnections(grid, sizeX, sizeY, listX, listY, FALSE);
GenerateMonsterHouse(grid, sizeX, sizeY, 999);
}
/*
* GenerateExtraHallways - Generate extra hallways on the floor via a series of random walks.
*
* These paths are often visibly dead-end hallways, or hallways which loop on themselves.
*
* Each walk begin at a random tile in a random room, leaving in a random cardinal direction, tunneling
* through obstacles until it reaches open terrain, is out of bounds, or reaches an impassable obstruction.
*
* For each hallway the following steps are done:
*
* 1. Select a room, tile, and cardinal direction (specific conditions documented below)
*
* 2. Walk from the tile in that direction until we are out of the room, and reach an obstacle (could traverse hallways on the way)
*
* 3. Check we're safe to proceed (not at map borders, counterclockwise/clockwise tiles are not open)
*
* Begin our random-length walk strides:
*
* 4. Check we're safe to proceed (not at borders, not open tile, not impassable wall, will not make a 2x2 open square)
*
* 5. Place Open Terrain at this tile
*
* 6. Check we're safe to proceed (counterclockwise/clockwise tiles are not open)
*
* 7. Check if we've reached the end of the current stride (steps at 0), if so, turn left or right at random and start a new stride.
*
* 8. Move in the current direction.
*
* Repeat 4-8 until a check fails.
*/
void GenerateExtraHallways(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 numExtraHallways)
{
s32 i, j;
if (numExtraHallways == 0)
return;
for (i = 0; i < numExtraHallways; i++) {
s32 currX, currY;
s32 direction;
u8 roomId;
bool8 invalid;
s32 checkX, checkY, checkX2, checkY2;
s32 xLoop, yLoop;
// Select a random grid cell
s32 x = DungeonRandInt(sizeX);
s32 y = DungeonRandInt(sizeY);
// To generate extra hallways the cell must be:
// - a room
// - connected
// - valid
// - not a maze room
if (!grid[x][y].isRoom || !grid[x][y].isConnected || grid[x][y].isInvalid || grid[x][y].isMazeRoom) continue;
// Choose a random tile in the room
currX = DungeonRandRange(grid[x][y].start.x, grid[x][y].end.x);
currY = DungeonRandRange(grid[x][y].start.y, grid[x][y].end.y);
// Choose a random cardinal direction
direction = DungeonRandInt(4) * 2;
// If invalid, rotate counter-clockwise until one works
for (j = 0; j < 3; j++) {
if (direction == DIRECTION_SOUTH && y >= sizeY - 1) {
direction = DIRECTION_EAST;
}
if (direction == DIRECTION_EAST && x >= sizeX - 1) {
direction = DIRECTION_NORTH;
}
if (direction == DIRECTION_NORTH && y <= 0) {
direction = DIRECTION_WEST;
}
if (direction == DIRECTION_WEST && x <= 0) {
direction = DIRECTION_SOUTH;
}
}
roomId = GetTile(currX, currY)->room;
// Walk in the random direction until out of the room
while (1) {
if (roomId != GetTile(currX, currY)->room)
break;
// gAdjacentTileOffsets gives us the proper (x,y) offset to move one tile in the given direction.
currX += gAdjacentTileOffsets[direction].x;
currY += gAdjacentTileOffsets[direction].y;
}
// Keep walking until an obstacle is encountered
while (1) {
if (GetTerrain(GetTile(currX, currY)) != TERRAIN_TYPE_NORMAL)
break;
currX += gAdjacentTileOffsets[direction].x;
currY += gAdjacentTileOffsets[direction].y;
}
// Abort if we reached secondary terrain
if (GetTerrain(GetTile(currX, currY)) == TERRAIN_TYPE_SECONDARY)
continue;
// Check that the current tile is at least 2 away from the map border
invalid = FALSE;
for (xLoop = currX - 2; xLoop <= currX + 2; xLoop++) {
for (yLoop = currY - 2; yLoop <= currY + 2; yLoop++) {
if (xLoop < 0 || xLoop >= DUNGEON_MAX_SIZE_X || yLoop < 0 || yLoop >= DUNGEON_MAX_SIZE_Y) {
invalid = TRUE;
break;
}
}
if (invalid) break;
}
if (invalid) continue;
// Make sure the direction 90 degrees counterclockwise isn't an open tile
checkX = gAdjacentTileOffsets[(direction + 2) & DIRECTION_MASK_CARDINAL].x;
checkY = gAdjacentTileOffsets[(direction + 2) & DIRECTION_MASK_CARDINAL].y;
if (GetTerrain(GetTile(currX + checkX, currY + checkY)) == TERRAIN_TYPE_NORMAL)
continue;
// Do the same for 90 degrees clockwise (or 270 counterclockwise) and make sure it's not an open tile
checkX2 = gAdjacentTileOffsets[(direction - 2) & DIRECTION_MASK_CARDINAL].x;
checkY2 = gAdjacentTileOffsets[(direction - 2) & DIRECTION_MASK_CARDINAL].y;
if (GetTerrain(GetTile(currX + checkX2, currY + checkY2)) == TERRAIN_TYPE_NORMAL)
continue;
// Number of steps to walk in one direction before turning
j = DungeonRandInt(3) + 3;
while (TRUE) {
s32 checkX, checkY, checkX2, checkY2;
bool8 willNotMakeSquare;
// Check for stopping conditions:
// - Out of bounds or on the 1-tile border of impassable walls
// - Reached an open tile
// - Reached an impassable wall
// - Would result in carving out a 2x2 square (not a hallway at that point)
if (currX <= 1 || currY <= 1 || currX >= DUNGEON_MAX_SIZE_X - 1 || currY >= DUNGEON_MAX_SIZE_Y - 1)
break;
if (GetTerrain(GetTile(currX, currY)) == TERRAIN_TYPE_NORMAL)
break;
if (GetTile(currX, currY)->terrainType & TERRAIN_TYPE_IMPASSABLE_WALL)
break;
willNotMakeSquare = TRUE;
// Check Bottom to Right
if ((GetTerrain(GetTile(currX + 1, currY)) == TERRAIN_TYPE_NORMAL) &&
(GetTerrain(GetTile(currX + 1, currY + 1)) == TERRAIN_TYPE_NORMAL) &&
(GetTerrain(GetTile(currX, currY + 1)) == TERRAIN_TYPE_NORMAL))
{
willNotMakeSquare = FALSE;
}
// Check Top to Right
if ((GetTerrain(GetTile(currX + 1, currY)) == TERRAIN_TYPE_NORMAL) &&
(GetTerrain(GetTile(currX + 1, currY - 1)) == TERRAIN_TYPE_NORMAL) &&
(GetTerrain(GetTile(currX, currY - 1)) == TERRAIN_TYPE_NORMAL))
{
willNotMakeSquare = FALSE;
}
// Check Bottom to Left
if ((GetTerrain(GetTile(currX - 1, currY)) == TERRAIN_TYPE_NORMAL) &&
(GetTerrain(GetTile(currX - 1, currY + 1)) == TERRAIN_TYPE_NORMAL) &&
(GetTerrain(GetTile(currX, currY + 1)) == TERRAIN_TYPE_NORMAL))
{
willNotMakeSquare = FALSE;
}
// Check Top to Left
if ((GetTerrain(GetTile(currX - 1, currY)) == TERRAIN_TYPE_NORMAL) &&
(GetTerrain(GetTile(currX - 1, currY - 1)) == TERRAIN_TYPE_NORMAL) &&
(GetTerrain(GetTile(currX, currY - 1)) == TERRAIN_TYPE_NORMAL))
{
willNotMakeSquare = FALSE;
}
// If TRUE, make the tile open, it will not produce a 2x2 opening
// If FALSE, it will abort from neighbor checks so we don't break here
if (willNotMakeSquare) {
SetTerrainNormal(GetTileSafe(currX, currY));
}
// Make sure the direction 90 degrees counterclockwise isn't an open tile
checkX = gAdjacentTileOffsets[(direction + 2) & DIRECTION_MASK_CARDINAL].x;
checkY = gAdjacentTileOffsets[(direction + 2) & DIRECTION_MASK_CARDINAL].y;
if (GetTerrain(GetTile(currX + checkX, currY + checkY)) == TERRAIN_TYPE_NORMAL)
break;
// Do the same for 90 degrees clockwise (or 270 counterclockwise) and make sure it's not an open tile
checkX2 = gAdjacentTileOffsets[(direction - 2) & DIRECTION_MASK_CARDINAL].x;
checkY2 = gAdjacentTileOffsets[(direction - 2) & DIRECTION_MASK_CARDINAL].y;
if (GetTerrain(GetTile(currX + checkX2, currY + checkY2)) == TERRAIN_TYPE_NORMAL)
break;
j--;
if (j == 0) {
j = DungeonRandInt(3) + 3;
// Turn left or right with an equal chance
if (DungeonRandInt(100) < 50) {
direction += 2;
}
else {
direction -= 2;
}
// If we'd step into an invalid grid cell, stop
// (We don't always utilize the entire floor space)
direction &= DIRECTION_MASK_CARDINAL;
if (currX >= 32 && gUnknown_202F1AE == 1 && direction == DIRECTION_EAST) break;
if (currX >= 48 && gUnknown_202F1AE == 2 && direction == DIRECTION_EAST) break;
}
// Move in the current direction
currX += gAdjacentTileOffsets[direction].x;
currY += gAdjacentTileOffsets[direction].y;
}
}
}
// GetGridPositions - Determines the starting positions of grid cells based on the given floor grid dimensions
void GetGridPositions(s32 *listX, s32 *listY, s32 sizeX, s32 sizeY)
{
s32 i, sum;
for (i = 0, sum = 0; i < sizeX; i++) {
listX[i] = sum;
sum += DUNGEON_MAX_SIZE_X / sizeX;
}
listX[sizeX] = sum;
for (i = 0, sum = 0; i < sizeY; i++) {
listY[i] = sum;
sum += DUNGEON_MAX_SIZE_Y / sizeY;
}
listY[sizeY] = sum;
}
/*
* InitDungeonGrid - Initializes the default state of the dungeon grid
*
* The dungeon grid is an array of grid cells stored in column-major order
* (to give contiguous storage to cells with the same x value), with a fixed column size of 15.
*/
void InitDungeonGrid(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY)
{
s32 x, y;
for (x = 0; x < sizeX; x++) {
for (y = 0; y < sizeY; y++) {
if (gUnknown_202F1AE == 1 && x >= sizeX / 2) {
grid[x][y].isInvalid = TRUE;
}
else if (gUnknown_202F1AE == 2 && x >= (sizeX * 3) / 4) {
grid[x][y].isInvalid = TRUE;
}
else {
grid[x][y].isInvalid = FALSE;
}
grid[x][y].isRoom = TRUE;
grid[x][y].isConnected = FALSE;
grid[x][y].unk15 = FALSE;
grid[x][y].unk14 = FALSE;
grid[x][y].unk12 = FALSE;
grid[x][y].connectedToRight = FALSE;
grid[x][y].connectedToLeft = FALSE;
grid[x][y].connectedToBottom = FALSE;
grid[x][y].connectedToTop = FALSE;
grid[x][y].unk26 = FALSE;
grid[x][y].unk25 = FALSE;
grid[x][y].unk24 = FALSE;
grid[x][y].unk23 = FALSE;
grid[x][y].unk9 = FALSE;
grid[x][y].hasBeenMerged = FALSE;
grid[x][y].isMazeRoom = FALSE;
grid[x][y].isMerged = FALSE;
grid[x][y].unk28 = FALSE;
grid[x][y].unk29 = FALSE;
}
}
}
/*
* AssignRooms - Randomly selects a subset of grid cells to become rooms
*
* If number_of_rooms is positive, number_of_rooms + [0..2] will become rooms
* If the selected cells for rooms are invalid, less rooms will be generated.
* The number of rooms assigned will always be at least 2 and always <= MAX_ROOM_COUNT (32).
*
* Any cells which aren't marked as rooms will become hallway anchors (those single 1x1 "rooms")
* which will be connected as hallways later, to "anchor" hallway generation
*
* Primarily Modifies: grid to assign certain grid cells to have isRoom TRUE.
*/
void AssignRooms(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 sizeX, s32 sizeY, s32 roomsNumber)
{
bool8 randomRoomBits[256];
s32 i, nShuffles;
s32 x, y;
s32 attempts;
s32 maxRooms;
// Extra Rooms
i = DungeonRandInt(3);
// A negative # for room count requests an exact number of rooms
if (roomsNumber < 0) {
roomsNumber = -roomsNumber;
}
else {
roomsNumber += i;
}
for (i = 0; i < roomsNumber; i++) {
randomRoomBits[i] = TRUE;
}
for (; i < 256; i++) {
randomRoomBits[i] = FALSE;
}
// Shuffle around the acceptable rooms
maxRooms = sizeX * sizeY;
for (nShuffles = 0; nShuffles < 64; nShuffles++) {
bool8 temp;
s32 a = DungeonRandInt(maxRooms);
s32 b = DungeonRandInt(maxRooms);
SWAP(randomRoomBits[a], randomRoomBits[b], temp);
}
// Counter for randomRoomBits
i = 0;
gUnknown_202F1CC = 0;
for (x = 0; x < sizeX; x++) {
for (y = 0; y < sizeY; y++) {
if (grid[x][y].isInvalid)
continue;
// There are too many rooms, remove
if (gUnknown_202F1CC >= MAX_ROOM_COUNT) {
grid[x][y].isRoom = FALSE;
}
// Using the randomly shuffled bits, create or remove the room
if (randomRoomBits[i]) {
grid[x][y].isRoom = TRUE;
gUnknown_202F1CC++;
// Don't make a room at (x_mid, 1)
if (sizeX % 2 != 0 && x == (sizeX - 1) / 2 && y == 1 ) {
grid[x][y].isRoom = FALSE;
}
}
else {
grid[x][y].isRoom = FALSE;
}
i++;
}
}
// We have at least 2 rooms, we're done.
if (gUnknown_202F1CC >= 2)
return;
for (attempts = 0; attempts < 200; attempts++) {
bool8 enoughRooms = FALSE;
for (x = 0; x < sizeX; x++) {
for (y = 0; y < sizeY; y++) {
if (grid[x][y].isInvalid)
continue;
if (DungeonRandInt(100) < 60) {
grid[x][y].isRoom = TRUE;
enoughRooms = TRUE;
// This goto is needed to match, it's used to break from two nested loops.
goto LOOP_BREAK;
}
}
}
LOOP_BREAK:
if (enoughRooms)
break;
}
gUnknown_202F1AD = FALSE;
}
//