diff --git a/asm/code_804AFAC.s b/asm/code_804AFAC.s index 5ba7d6944..be57e660a 100644 --- a/asm/code_804AFAC.s +++ b/asm/code_804AFAC.s @@ -5,792 +5,7 @@ .text - thumb_func_start GenerateMazeRoom -GenerateMazeRoom: - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - sub sp, 0x104 - str r0, [sp, 0x100] - mov r10, r1 - mov r9, r2 - adds r4, r3, 0 - ldr r0, _0804F244 - ldr r5, [r0] - cmp r4, 0 - bne _0804F0EE - b _0804F266 -_0804F0EE: - movs r0, 0x64 - bl DungeonRandInt - cmp r4, r0 - bgt _0804F0FA - b _0804F266 -_0804F0FA: - ldr r1, _0804F248 - adds r0, r5, r1 - movs r3, 0 - ldrsh r0, [r0, r3] - cmp r0, 0 - blt _0804F108 - b _0804F266 -_0804F108: - movs r5, 0 - movs r6, 0 - cmp r6, r10 - bge _0804F184 -_0804F110: - adds r7, r6, 0x1 - mov r4, r9 - cmp r4, 0 - ble _0804F17E - lsls r0, r6, 4 - subs r0, r6 - lsls r0, 5 - ldr r6, [sp, 0x100] - adds r2, r0, r6 -_0804F122: - ldrb r0, [r2, 0x8] - cmp r0, 0 - bne _0804F176 - ldrb r0, [r2, 0x11] - cmp r0, 0 - bne _0804F176 - ldrb r0, [r2, 0xB] - cmp r0, 0 - beq _0804F176 - ldrb r0, [r2, 0xA] - cmp r0, 0 - beq _0804F176 - ldrb r0, [r2, 0xC] - cmp r0, 0 - bne _0804F176 - ldrb r0, [r2, 0xF] - cmp r0, 0 - bne _0804F176 - ldrb r0, [r2, 0xE] - cmp r0, 0 - bne _0804F176 - ldrb r0, [r2, 0x9] - cmp r0, 0 - bne _0804F176 - movs r1, 0x4 - ldrsh r0, [r2, r1] - movs r3, 0 - ldrsh r1, [r2, r3] - subs r0, r1 - movs r3, 0x1 - ands r0, r3 - cmp r0, 0 - beq _0804F176 - movs r6, 0x6 - ldrsh r0, [r2, r6] - movs r6, 0x2 - ldrsh r1, [r2, r6] - subs r0, r1 - ands r0, r3 - cmp r0, 0 - beq _0804F176 - adds r5, 0x1 -_0804F176: - adds r2, 0x20 - subs r4, 0x1 - cmp r4, 0 - bne _0804F122 -_0804F17E: - adds r6, r7, 0 - cmp r6, r10 - blt _0804F110 -_0804F184: - cmp r5, 0 - beq _0804F266 - movs r1, 0 - mov r0, sp - adds r0, 0xFF -_0804F18E: - strb r1, [r0] - subs r0, 0x1 - cmp r0, sp - bge _0804F18E - mov r1, sp - movs r0, 0x1 - strb r0, [r1] - movs r7, 0x3F - mov r8, r7 -_0804F1A0: - adds r0, r5, 0 - bl DungeonRandInt - adds r4, r0, 0 - adds r0, r5, 0 - bl DungeonRandInt - mov r1, sp - adds r2, r1, r4 - ldrb r3, [r2] - adds r1, r0 - ldrb r0, [r1] - strb r0, [r2] - strb r3, [r1] - movs r3, 0x1 - negs r3, r3 - add r8, r3 - mov r4, r8 - cmp r4, 0 - bge _0804F1A0 - movs r6, 0 - mov r8, r6 - cmp r6, r10 - bge _0804F266 - ldr r7, [sp, 0x100] - mov r12, r7 -_0804F1D4: - movs r4, 0 - cmp r4, r9 - bge _0804F25A - mov r2, r12 - mov r5, r12 -_0804F1DE: - ldrb r0, [r2, 0x8] - cmp r0, 0 - bne _0804F250 - ldrb r0, [r2, 0x11] - cmp r0, 0 - bne _0804F250 - ldrb r0, [r2, 0xB] - cmp r0, 0 - beq _0804F250 - ldrb r0, [r2, 0xA] - cmp r0, 0 - beq _0804F250 - ldrb r0, [r2, 0xC] - cmp r0, 0 - bne _0804F250 - ldrb r0, [r2, 0xF] - cmp r0, 0 - bne _0804F250 - ldrb r0, [r2, 0xE] - cmp r0, 0 - bne _0804F250 - ldrb r0, [r2, 0x9] - cmp r0, 0 - bne _0804F250 - movs r1, 0x4 - ldrsh r0, [r2, r1] - movs r3, 0 - ldrsh r1, [r2, r3] - subs r0, r1 - movs r3, 0x1 - ands r0, r3 - cmp r0, 0 - beq _0804F250 - movs r7, 0x6 - ldrsh r0, [r2, r7] - movs r7, 0x2 - ldrsh r1, [r2, r7] - subs r0, r1 - ands r0, r3 - cmp r0, 0 - beq _0804F250 - mov r0, sp - add r0, r8 - ldrb r0, [r0] - cmp r0, 0 - beq _0804F24C - adds r0, r5, 0 - movs r1, 0 - bl sub_804F278 - b _0804F266 - .align 2, 0 -_0804F244: .4byte gDungeon -_0804F248: .4byte 0x00003a16 -_0804F24C: - movs r0, 0x1 - add r8, r0 -_0804F250: - adds r2, 0x20 - adds r5, 0x20 - adds r4, 0x1 - cmp r4, r9 - blt _0804F1DE -_0804F25A: - movs r1, 0xF0 - lsls r1, 1 - add r12, r1 - adds r6, 0x1 - cmp r6, r10 - blt _0804F1D4 -_0804F266: - add sp, 0x104 - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r0} - bx r0 - thumb_func_end GenerateMazeRoom - thumb_func_start sub_804F278 -sub_804F278: - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - sub sp, 0x10 - adds r4, r0, 0 - lsls r1, 24 - lsrs r1, 24 - mov r8, r1 - ldr r1, _0804F2B0 - movs r0, 0x1 - strb r0, [r1] - movs r0, 0x1 - strb r0, [r4, 0x10] - movs r1, 0 - ldrsh r0, [r4, r1] - movs r2, 0x2 - ldrsh r1, [r4, r2] - bl GetTile - ldrb r0, [r0, 0x9] - mov r9, r0 - movs r5, 0 - ldrsh r0, [r4, r5] - adds r6, r0, 0x1 - b _0804F2F0 - .align 2, 0 -_0804F2B0: .4byte gUnknown_202F1AC -_0804F2B4: - movs r2, 0x2 - ldrsh r1, [r4, r2] - subs r1, 0x1 - adds r0, r6, 0 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x1 - beq _0804F2EE - movs r5, 0x2 - ldrsh r3, [r4, r5] - subs r1, r3, 0x1 - movs r0, 0 - ldrsh r2, [r4, r0] - movs r5, 0x4 - ldrsh r0, [r4, r5] - str r0, [sp] - movs r5, 0x6 - ldrsh r0, [r4, r5] - str r0, [sp, 0x4] - mov r0, r8 - str r0, [sp, 0x8] - mov r5, r9 - str r5, [sp, 0xC] - adds r0, r6, 0 - bl sub_804F494 -_0804F2EE: - adds r6, 0x2 -_0804F2F0: - movs r1, 0x4 - ldrsh r0, [r4, r1] - subs r0, 0x1 - cmp r6, r0 - blt _0804F2B4 - movs r2, 0x2 - ldrsh r0, [r4, r2] - adds r5, r0, 0x1 - movs r6, 0x6 - ldrsh r0, [r4, r6] - b _0804F342 -_0804F306: - movs r1, 0x4 - ldrsh r0, [r4, r1] - adds r1, r5, 0 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x1 - beq _0804F33C - movs r2, 0x4 - ldrsh r0, [r4, r2] - movs r6, 0 - ldrsh r2, [r4, r6] - movs r1, 0x2 - ldrsh r3, [r4, r1] - str r0, [sp] - movs r6, 0x6 - ldrsh r1, [r4, r6] - str r1, [sp, 0x4] - mov r1, r8 - str r1, [sp, 0x8] - mov r6, r9 - str r6, [sp, 0xC] - adds r1, r5, 0 - bl sub_804F494 -_0804F33C: - adds r5, 0x2 - movs r1, 0x6 - ldrsh r0, [r4, r1] -_0804F342: - subs r0, 0x1 - cmp r5, r0 - blt _0804F306 - movs r2, 0 - ldrsh r0, [r4, r2] - adds r6, r0, 0x1 - movs r5, 0x4 - ldrsh r0, [r4, r5] - b _0804F392 -_0804F354: - movs r0, 0x6 - ldrsh r1, [r4, r0] - adds r0, r6, 0 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x1 - beq _0804F38C - movs r2, 0x6 - ldrsh r1, [r4, r2] - movs r5, 0 - ldrsh r2, [r4, r5] - movs r0, 0x2 - ldrsh r3, [r4, r0] - movs r5, 0x4 - ldrsh r0, [r4, r5] - str r0, [sp] - adds r0, r1, 0 - str r0, [sp, 0x4] - mov r0, r8 - str r0, [sp, 0x8] - mov r5, r9 - str r5, [sp, 0xC] - adds r0, r6, 0 - bl sub_804F494 -_0804F38C: - adds r6, 0x2 - movs r1, 0x4 - ldrsh r0, [r4, r1] -_0804F392: - subs r0, 0x1 - cmp r6, r0 - blt _0804F354 - movs r2, 0x2 - ldrsh r0, [r4, r2] - adds r5, r0, 0x1 - movs r6, 0x6 - ldrsh r0, [r4, r6] - b _0804F3E4 -_0804F3A4: - movs r1, 0 - ldrsh r0, [r4, r1] - subs r0, 0x1 - adds r1, r5, 0 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x1 - beq _0804F3DE - movs r6, 0 - ldrsh r2, [r4, r6] - subs r0, r2, 0x1 - movs r1, 0x2 - ldrsh r3, [r4, r1] - movs r6, 0x4 - ldrsh r1, [r4, r6] - str r1, [sp] - movs r6, 0x6 - ldrsh r1, [r4, r6] - str r1, [sp, 0x4] - mov r1, r8 - str r1, [sp, 0x8] - mov r6, r9 - str r6, [sp, 0xC] - adds r1, r5, 0 - bl sub_804F494 -_0804F3DE: - adds r5, 0x2 - movs r1, 0x6 - ldrsh r0, [r4, r1] -_0804F3E4: - subs r0, 0x1 - cmp r5, r0 - blt _0804F3A4 - movs r2, 0 - ldrsh r0, [r4, r2] - adds r6, r0, 0x3 - b _0804F478 -_0804F3F2: - movs r1, 0x2 - ldrsh r0, [r4, r1] - adds r5, r0, 0x3 - movs r2, 0x6 - ldrsh r0, [r4, r2] - subs r0, 0x3 - adds r1, r6, 0x2 - mov r10, r1 - cmp r5, r0 - bge _0804F476 - ldr r2, _0804F434 - adds r7, r2, 0 -_0804F40A: - adds r0, r6, 0 - adds r1, r5, 0 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x1 - bne _0804F46A - mov r0, r8 - cmp r0, 0 - beq _0804F438 - subs r0, r6, 0x1 - adds r1, r5, 0 - bl GetTileSafe - ldrh r1, [r0] - ands r1, r7 - movs r2, 0x2 - orrs r1, r2 - b _0804F444 - .align 2, 0 -_0804F434: .4byte 0x0000fffc -_0804F438: - subs r0, r6, 0x1 - adds r1, r5, 0 - bl GetTileSafe - ldrh r1, [r0] - ands r1, r7 -_0804F444: - strh r1, [r0] - movs r1, 0 - ldrsh r2, [r4, r1] - movs r0, 0x2 - ldrsh r3, [r4, r0] - movs r1, 0x4 - ldrsh r0, [r4, r1] - str r0, [sp] - movs r1, 0x6 - ldrsh r0, [r4, r1] - str r0, [sp, 0x4] - mov r0, r8 - str r0, [sp, 0x8] - mov r1, r9 - str r1, [sp, 0xC] - adds r0, r6, 0 - adds r1, r5, 0 - bl sub_804F494 -_0804F46A: - adds r5, 0x2 - movs r2, 0x6 - ldrsh r0, [r4, r2] - subs r0, 0x3 - cmp r5, r0 - blt _0804F40A -_0804F476: - mov r6, r10 -_0804F478: - movs r5, 0x4 - ldrsh r0, [r4, r5] - subs r0, 0x3 - cmp r6, r0 - blt _0804F3F2 - add sp, 0x10 - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r0} - bx r0 - thumb_func_end sub_804F278 - - thumb_func_start sub_804F494 -sub_804F494: - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - sub sp, 0x8 - adds r5, r0, 0 - adds r4, r1, 0 - str r2, [sp] - str r3, [sp, 0x4] - ldr r0, [sp, 0x30] - ldr r1, [sp, 0x34] - lsls r0, 24 - lsrs r0, 24 - mov r9, r0 - lsls r1, 24 - mov r8, r1 - movs r0, 0x3 - mov r10, r0 -_0804F4BA: - movs r0, 0x4 - bl DungeonRandInt - adds r6, r0, 0 - movs r7, 0 - adds r0, r5, 0 - adds r1, r4, 0 - bl GetTileSafe - mov r1, r9 - mov r3, r8 - lsrs r2, r3, 24 - bl SetTerrainObstacleChecked -_0804F4D6: - adds r0, r6, 0 - mov r1, r10 - ands r0, r1 - cmp r0, 0x1 - beq _0804F4F6 - cmp r0, 0x1 - bgt _0804F4EA - cmp r0, 0 - beq _0804F4F0 - b _0804F506 -_0804F4EA: - cmp r0, 0x2 - beq _0804F4FE - b _0804F506 -_0804F4F0: - movs r0, 0x2 - movs r1, 0 - b _0804F50A -_0804F4F6: - movs r0, 0 - movs r1, 0x2 - negs r1, r1 - b _0804F50A -_0804F4FE: - movs r0, 0x2 - negs r0, r0 - movs r1, 0 - b _0804F50A -_0804F506: - movs r0, 0 - movs r1, 0x2 -_0804F50A: - adds r0, r5, r0 - ldr r2, [sp] - cmp r2, r0 - bgt _0804F534 - ldr r3, [sp, 0x28] - cmp r3, r0 - ble _0804F534 - adds r1, r4, r1 - ldr r2, [sp, 0x4] - cmp r2, r1 - bgt _0804F534 - ldr r3, [sp, 0x2C] - cmp r3, r1 - ble _0804F534 - bl GetTile - ldrh r1, [r0] - mov r0, r10 - ands r0, r1 - cmp r0, 0x1 - beq _0804F53E -_0804F534: - adds r6, 0x1 - adds r7, 0x1 - cmp r7, 0x3 - bgt _0804F5B2 - b _0804F4D6 -_0804F53E: - mov r0, r10 - ands r0, r6 - cmp r0, 0x1 - beq _0804F570 - cmp r0, 0x1 - bgt _0804F550 - cmp r0, 0 - beq _0804F55A - b _0804F4BA -_0804F550: - cmp r0, 0x2 - beq _0804F586 - cmp r0, 0x3 - beq _0804F59C - b _0804F4BA -_0804F55A: - adds r0, r5, 0x1 - adds r1, r4, 0 - bl GetTileSafe - mov r1, r9 - mov r3, r8 - lsrs r2, r3, 24 - bl SetTerrainObstacleChecked - adds r5, 0x2 - b _0804F4BA -_0804F570: - subs r1, r4, 0x1 - adds r0, r5, 0 - bl GetTileSafe - mov r1, r9 - mov r3, r8 - lsrs r2, r3, 24 - bl SetTerrainObstacleChecked - subs r4, 0x2 - b _0804F4BA -_0804F586: - subs r0, r5, 0x1 - adds r1, r4, 0 - bl GetTileSafe - mov r1, r9 - mov r3, r8 - lsrs r2, r3, 24 - bl SetTerrainObstacleChecked - subs r5, 0x2 - b _0804F4BA -_0804F59C: - adds r1, r4, 0x1 - adds r0, r5, 0 - bl GetTileSafe - mov r1, r9 - mov r3, r8 - lsrs r2, r3, 24 - bl SetTerrainObstacleChecked - adds r4, 0x2 - b _0804F4BA -_0804F5B2: - add sp, 0x8 - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r0} - bx r0 - thumb_func_end sub_804F494 - - thumb_func_start sub_804F5C4 -sub_804F5C4: - ldrh r3, [r0] - ldr r2, _0804F5D4 - ands r2, r3 - movs r3, 0x2 - orrs r2, r3 - orrs r2, r1 - strh r2, [r0] - bx lr - .align 2, 0 -_0804F5D4: .4byte 0x0000fffc - thumb_func_end sub_804F5C4 - - thumb_func_start sub_804F5D8 -sub_804F5D8: - push {r4-r7,lr} - adds r5, r0, 0 - movs r0, 0 - ldrsh r6, [r5, r0] - b _0804F60C -_0804F5E2: - movs r0, 0x2 - ldrsh r4, [r5, r0] - movs r1, 0x6 - ldrsh r0, [r5, r1] - adds r7, r6, 0x1 - cmp r4, r0 - bge _0804F60A -_0804F5F0: - adds r0, r6, 0 - adds r1, r4, 0 - bl GetTileSafe - ldrh r2, [r0, 0x4] - movs r1, 0x20 - orrs r1, r2 - strh r1, [r0, 0x4] - adds r4, 0x1 - movs r1, 0x6 - ldrsh r0, [r5, r1] - cmp r4, r0 - blt _0804F5F0 -_0804F60A: - adds r6, r7, 0 -_0804F60C: - movs r1, 0x4 - ldrsh r0, [r5, r1] - cmp r6, r0 - blt _0804F5E2 - pop {r4-r7} - pop {r0} - bx r0 - thumb_func_end sub_804F5D8 - - thumb_func_start sub_804F61C -sub_804F61C: - push {r4-r7,lr} - mov r7, r9 - mov r6, r8 - push {r6,r7} - mov r9, r0 - mov r8, r1 - movs r7, 0x1 - negs r7, r7 - b _0804F67A -_0804F62E: - movs r5, 0x1 - negs r5, r5 - b _0804F666 -_0804F634: - cmp r7, 0 - beq _0804F63C - cmp r5, 0 - bne _0804F660 -_0804F63C: - adds r0, r6, 0 - adds r1, r4, 0 - bl GetTile - ldrh r1, [r0] - movs r0, 0x3 - ands r0, r1 - cmp r0, 0x1 - bne _0804F660 - adds r0, r6, 0 - adds r1, r4, 0 - bl GetTile - ldrb r0, [r0, 0x9] - cmp r0, 0xFF - bne _0804F660 - movs r0, 0x1 - b _0804F686 -_0804F660: - adds r5, 0x1 - cmp r5, 0x1 - bgt _0804F672 -_0804F666: - mov r0, r8 - adds r4, r0, r5 - cmp r4, 0 - blt _0804F660 - cmp r4, 0x1F - ble _0804F634 -_0804F672: - adds r7, 0x1 - cmp r7, 0x1 - bgt _0804F684 - mov r0, r9 -_0804F67A: - adds r6, r0, r7 - cmp r6, 0 - blt _0804F672 - cmp r6, 0x37 - ble _0804F62E -_0804F684: - movs r0, 0 -_0804F686: - pop {r3,r4} - mov r8, r3 - mov r9, r4 - pop {r4-r7} - pop {r1} - bx r1 - thumb_func_end sub_804F61C thumb_func_start GenerateSecondaryStructure GenerateSecondaryStructure: @@ -832,7 +47,7 @@ _0804F6DE: subs r0, 0x1 str r0, [r1] adds r0, r7, 0 - bl sub_804F5D8 + bl SetSpawnFlag5 movs r0, 0x2 bl DungeonRandInt cmp r0, 0 @@ -861,7 +76,7 @@ _0804F712: bge _0804F72A mov r0, r8 adds r1, r4, 0 - bl sub_804F61C + bl IsNextToHallway lsls r0, 24 cmp r0, 0 beq _0804F710 @@ -943,7 +158,7 @@ _0804F7AA: bge _0804F7C2 adds r0, r4, 0 mov r1, r8 - bl sub_804F61C + bl IsNextToHallway lsls r0, 24 cmp r0, 0 beq _0804F7A8 @@ -1040,7 +255,7 @@ _0804F864: subs r0, 0x1 str r0, [r1] adds r0, r7, 0 - bl sub_804F5D8 + bl SetSpawnFlag5 ldr r5, [sp] subs r5, 0x2 ldr r0, [sp, 0x4] @@ -1243,7 +458,7 @@ _0804FA46: subs r0, 0x1 str r0, [r1] adds r0, r7, 0 - bl sub_804F5D8 + bl SetSpawnFlag5 cmp r4, r9 ble _0804FA5A adds r0, r4, 0 @@ -1313,7 +528,7 @@ _0804FAC8: subs r0, 0x1 str r0, [r1] adds r0, r7, 0 - bl sub_804F5D8 + bl SetSpawnFlag5 movs r6, 0x3F _0804FAD4: movs r4, 0x4 @@ -1426,10 +641,10 @@ _0804FBAE: _0804FBC0: .4byte gUnknown_202F1C8 _0804FBC4: adds r0, r7, 0 - bl sub_804F5D8 + bl SetSpawnFlag5 adds r0, r7, 0 movs r1, 0x1 - bl sub_804F278 + bl GenerateMaze _0804FBD2: movs r0, 0x1 strb r0, [r7, 0x9] diff --git a/src/code_804AFAC_1.c b/src/code_804AFAC_1.c index 06992aad3..635a4a6b5 100644 --- a/src/code_804AFAC_1.c +++ b/src/code_804AFAC_1.c @@ -13,7 +13,7 @@ extern struct FileArchive gDungeonFileArchive; extern bool8 gUnknown_202F1AA; extern u8 gUnknown_202F1AB; -extern u8 gUnknown_202F1AC; +extern bool8 gUnknown_202F1AC; extern u8 gUnknown_202F1A8; extern u8 gUnknown_202F1B4; extern u8 gUnknown_202F1AE; @@ -103,7 +103,7 @@ void sub_804AFAC(void) gDungeon->unk13568 = OpenFileAndGetFileDataPtr(gUnknown_80F6DCC, &gDungeonFileArchive); gUnknown_202F1AA = FALSE; gUnknown_202F1AB = 0; - gUnknown_202F1AC = 0; + gUnknown_202F1AC = FALSE; gUnknown_202F1A8 = (gDungeonWaterType[gDungeon->tileset] == DUNGEON_WATER_TYPE_WATER); gUnknown_202F1B4 = 0xFF; gUnknown_202F1AE = 0; @@ -1035,11 +1035,12 @@ struct GridCell void sub_804C790(s32 gridSizeX, s32 gridSizeY, s32 x2, s32 y2, s32 a4, UnkDungeonGlobal_unk1C574 *unkPtr); void sub_8050F90(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 *listX, s32 *listY, s32 a5, s32 x2, s32 y2); -void sub_8051438(struct GridCell *cell, s32 a1); +void sub_8051438(struct GridCell *gridCell, s32 a1); extern void sub_8051288(s32 a0); void GetGridPositions(s32 *listX, s32 *listY, s32 gridSizeX, s32 gridSizeY); void InitDungeonGrid(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY); void GenerateRoomImperfections(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY); +void GenerateSecondaryStructure(struct GridCell *gridCell); void GenerateSecondaryStructures(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY); void AssignRooms(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 roomsNumber); void CreateRoomsAndAnchors(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 *listX, s32 *listY, u32 roomFlags); @@ -1048,6 +1049,8 @@ void EnsureConnectedGrid(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 static void AssignRandomGridCellConnections(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, UnkDungeonGlobal_unk1C574 *unkPtr); void AssignGridCellConnections(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 cursorX, s32 cursorY, UnkDungeonGlobal_unk1C574 *unkPtr); void GenerateMazeRoom(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 chance); +void GenerateMaze(struct GridCell *gridCell, bool8 useSecondaryTerrain); +void GenerateMazeLine(s32 x0, s32 y0, s32 xMin, s32 yMin, s32 xMax, s32 yMax, bool8 useSecondaryTerrain, u32 roomIndex); void GenerateKecleonShop(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 chance); void GenerateMonsterHouse(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 chance); void GenerateExtraHallways(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 numExtraHallways); @@ -2312,8 +2315,6 @@ void CreateRoomsAndAnchors(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s } } -void GenerateSecondaryStructure(struct GridCell *cell); - void GenerateSecondaryStructures(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY) { s32 x, y; @@ -3885,4 +3886,346 @@ void GenerateMonsterHouse(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s3 } } +/* + * GenerateMazeRoom - Determines and calls for whether to generate a maze room on the floor. + * + * A maze room can be generated by the probability specified in the maze_chance parameter, usually in vanilla + * this parameter is set to either 0 or 1, giving a 0-1% chance for trying to spawn a maze room. + * + * Then, a strange check occurs for whether the floor_generation_attempts is < 0, which will always fail, resulting + * in no maze rooms ever being generated under normal conditions. + * + * Candidate maze rooms have to be valid, connected, have odd dimensions, and not have any other features. + * If any candidates are found, the game will select one of these rooms and call GenerateMaze. + */ +void GenerateMazeRoom(struct GridCell grid[GRID_CELL_LEN][GRID_CELL_LEN], s32 gridSizeX, s32 gridSizeY, s32 chance) +{ + bool8 values[256]; + s32 i; + s32 x, y; + s32 numValid; + Dungeon *dungeon = gDungeon; + if (chance == 0) // No chance for maze, stop + return; + if (chance <= DungeonRandInt(100)) // Need to roll the probability chance (which is usually 0-1%...) + return; + if (dungeon->unk3A16 >= 0) // This bizarre check prevents maze rooms from ever being created + return; + + // Count the number of rooms that can be mazified: + // - Valid + // - Not a Merged Room + // - Connected + // - Not a Monster House + // - Both Dimensions are Odd + + numValid = 0; + for (x = 0; x < gridSizeX; x++) { + for (y = 0; y < gridSizeY; y++) { + if (grid[x][y].isInvalid) + continue; + if (grid[x][y].hasBeenMerged) + continue; + if (!grid[x][y].isConnected) + continue; + if (!grid[x][y].isRoom) + continue; + if (grid[x][y].isKecleonShop) + continue; + if (grid[x][y].unk15) + continue; + if (grid[x][y].isMonsterHouse) + continue; + if (grid[x][y].hasSecondaryStructure) + continue; + + if ((grid[x][y].end.x - grid[x][y].start.x) % 2 != 0 && (grid[x][y].end.y - grid[x][y].start.y) % 2 != 0) { + numValid++; + } + } + } + + if (numValid == 0) + return; + + // Have a single 1, the rest as 0's + for (i = 0; i < 256; i++) { + values[i] = FALSE; + } + values[0] = TRUE; + + // Shuffle values + for (i = 0; i < 64; i++) { + s32 temp; + s32 a = DungeonRandInt(numValid); + s32 b = DungeonRandInt(numValid); + + SWAP(values[a], values[b], temp); + } + + // Counter + i = 0; + for (x = 0; x < gridSizeX; x++) { + for (y = 0; y < gridSizeY; y++) { + if (grid[x][y].isInvalid) + continue; + if (grid[x][y].hasBeenMerged) + continue; + if (!grid[x][y].isConnected) + continue; + if (!grid[x][y].isRoom) + continue; + if (grid[x][y].isKecleonShop) + continue; + if (grid[x][y].unk15) + continue; + if (grid[x][y].isMonsterHouse) + continue; + if (grid[x][y].hasSecondaryStructure) + continue; + + if ((grid[x][y].end.x - grid[x][y].start.x) % 2 != 0 && (grid[x][y].end.y - grid[x][y].start.y) % 2 != 0) { + // This room can be mazified + if (values[i]) { + GenerateMaze(&grid[x][y], FALSE); + return; + } + + i++; + } + } + } +} + +/* + * GenerateMaze - Generate a maze room within the given grid cell. + * + * A "maze" is generated using a series of random walks whiich place obstacle terrain (walls / secondary terrain) + * in a maze-like arrangement. "Maze lines" (see: GenerateMazeLine) are generated using every other tile around the + * room's border, and every other interior tile as a starting point, ensuring there are stripes of walkable open terrain + * surrounded by striples of obstacles (maze walls). + * + */ +void GenerateMaze(struct GridCell *gridCell, bool8 useSecondaryTerrain) +{ + s32 curX, curY; + u8 roomIndex; + + gUnknown_202F1AC = TRUE; + gridCell->isMazeRoom = TRUE; + + roomIndex = GetTile(gridCell->start.x, gridCell->start.y)->room; + + // Random walks from upper border + for (curX = gridCell->start.x + 1; curX < gridCell->end.x - 1; curX += 2) { + if (GetTerrainType(GetTile(curX, gridCell->start.y - 1)) != TERRAIN_TYPE_NORMAL) { + GenerateMazeLine(curX, + gridCell->start.y - 1, + gridCell->start.x, + gridCell->start.y, + gridCell->end.x, + gridCell->end.y, + useSecondaryTerrain, + roomIndex + ); + } + } + + // Random walks from right border + for (curY = gridCell->start.y + 1; curY < gridCell->end.y - 1; curY += 2) { + if (GetTerrainType(GetTile(gridCell->end.x, curY)) != TERRAIN_TYPE_NORMAL) { + GenerateMazeLine(gridCell->end.x, curY, gridCell->start.x, gridCell->start.y, gridCell->end.x, gridCell->end.y, useSecondaryTerrain, roomIndex); + } + } + + // Random walks from lower border + for (curX = gridCell->start.x + 1; curX < gridCell->end.x - 1; curX += 2) { + if (GetTerrainType(GetTile(curX, gridCell->end.y)) != TERRAIN_TYPE_NORMAL) { + GenerateMazeLine(curX, gridCell->end.y, gridCell->start.x, gridCell->start.y, gridCell->end.x, gridCell->end.y, useSecondaryTerrain, roomIndex); + } + } + + // Random walks from left border + for (curY = gridCell->start.y + 1; curY < gridCell->end.y - 1; curY += 2) { + if (GetTerrainType(GetTile(gridCell->start.x - 1, curY)) != TERRAIN_TYPE_NORMAL) { + GenerateMazeLine(gridCell->start.x - 1, + curY, + gridCell->start.x, + gridCell->start.y, + gridCell->end.x, + gridCell->end.y, + useSecondaryTerrain, + roomIndex); + } + } + + // Fill in all the inner tiles with a stride of 2 + for (curX = gridCell->start.x + 3; curX < gridCell->end.x - 3; curX += 2) { + for (curY = gridCell->start.y + 3; curY < gridCell->end.y - 3; curY += 2) { + if (GetTerrainType(GetTile(curX, curY)) == TERRAIN_TYPE_NORMAL) { + if (useSecondaryTerrain) { + SetTerrainSecondary(GetTileSafe(curX - 1, curY)); + } + else { + SetTerrainWall(GetTileSafe(curX - 1, curY)); + } + + // More random walks + GenerateMazeLine(curX, curY, gridCell->start.x, gridCell->start.y, gridCell->end.x, gridCell->end.y, useSecondaryTerrain, roomIndex); + } + } + } +} + +/* + * GenerateMazeLine - Generates a "maze line" from the given start point, within the given bounds. + * + * A "maze line" is a random walk starting from (x0, y0). The random walk moves in strides of 2 + * in a random direction, placing down obstacles as it goes. + * + * The walk will terminate when the random walk has no available open tiles it can walk to. + * + * [ ^ ] [ ] [ ] [ o ] [ - ] [ > ] + * [ | ] [ ] [ ] => [ W ] [ ] [ ] => etc. + * [ o ] [ ] [ W ] [ W ] [ ] [ W ] + * + * First, an obstacle is placed at the given position (see: SetTerrainObstacleChecked) + * + * Then, a random direction is selected, searching for an open tile distance 2 away from (x0, y0). + * Each direction is attempted rotating counter-clockwise until an open tile is found or all directions are exhausted. + * + * If an open tile is found, an obstacle is placed between the two tiles, and (x0, y0) moves to the new open tile. + * This process continues until no valid open tile can be found. + */ +void GenerateMazeLine(s32 x0, s32 y0, s32 xMin, s32 yMin, s32 xMax, s32 yMax, bool8 useSecondaryTerrain, u32 roomIndex) +{ + while (1) { + s32 direction = DungeonRandInt(NUM_CARDINAL_DIRECTIONS); + s32 i = 0; + + SetTerrainObstacleChecked(GetTileSafe(x0, y0), useSecondaryTerrain, roomIndex); + + while (1) { + s32 offsetX, offsetY; + s32 posX, posY; + + // Offset from our current position to look 2 tiles in a given direction + switch (direction & CARDINAL_DIRECTION_MASK) { + case CARDINAL_DIR_RIGHT: + offsetX = 2; + offsetY = 0; + break; + case CARDINAL_DIR_UP: + offsetX = 0; + offsetY = -2; + break; + case CARDINAL_DIR_LEFT: + offsetX = -2; + offsetY = 0; + break; + default: + case CARDINAL_DIR_DOWN: + offsetX = 0; + offsetY = 2; + break; + } + + posX = x0 + offsetX; + + // Check that this position is in-bounds + if (xMin <= posX && xMax > posX) { + posY = y0 + offsetY; + if (yMin <= posY && yMax > posY) { + // Check that this tile is open ground + if (GetTerrainType(GetTile(posX, posY)) == TERRAIN_TYPE_NORMAL) { + // We found open ground, we're done! + break; + } + } + } + + // We didn't find any, try a different direction + direction++; + if (++i >= 4) + return; + } + + // If we found some open terrain, set an obstacle for the terrain in between those two, + // then move to the open terrain we found. + switch (direction & CARDINAL_DIRECTION_MASK) { + case CARDINAL_DIR_RIGHT: + SetTerrainObstacleChecked(GetTileSafe(x0 + 1, y0), useSecondaryTerrain, roomIndex); + + x0 += 2; + break; + case CARDINAL_DIR_UP: + SetTerrainObstacleChecked(GetTileSafe(x0, y0 - 1), useSecondaryTerrain, roomIndex); + + y0 -= 2; + break; + case CARDINAL_DIR_LEFT: + SetTerrainObstacleChecked(GetTileSafe(x0 - 1, y0), useSecondaryTerrain, roomIndex); + + x0 -= 2; + break; + case CARDINAL_DIR_DOWN: + SetTerrainObstacleChecked(GetTileSafe(x0, y0 + 1), useSecondaryTerrain, roomIndex); + + y0 += 2; + break; + } + } +} + +void sub_804F5C4(Tile *tile, u32 terrainFlag) +{ + SetTerrainSecondary(tile); + tile->terrainType |= terrainFlag; +} + +/* + * SetSpawnFlag5 - Sets unknown spawn flag 0x5 on all tiles in a room + */ +void SetSpawnFlag5(struct GridCell *gridCell) { + s32 x, y; + + for (x = gridCell->start.x; x < gridCell->end.x; x++) { + for (y = gridCell->start.y; y < gridCell->end.y; y++) { + GetTileSafe(x, y)->unk4 |= 0x20; + } + } +} + +/* + * IsNextToHallway - Checks if a tile position is either in a hallway or next to one. + */ +bool8 IsNextToHallway(s32 x, s32 y) +{ + s32 offsetX, offsetY; + s32 posX, posY; + + for (offsetX = -1; offsetX <= 1; offsetX++) { + posX = x + offsetX; + if (posX < 0) + continue; + if (posX >= DUNGEON_MAX_SIZE_X) + break; + + for (offsetY = -1; offsetY <= 1; offsetY++) { + posY = y + offsetY; + if (posY < 0) + continue; + if (posY >= DUNGEON_MAX_SIZE_Y) + break; + if (offsetX != 0 && offsetY != 0) + continue; + + if (GetTerrainType(GetTile(posX, posY)) == TERRAIN_TYPE_NORMAL && GetTile(posX, posY)->room == CORRIDOR_ROOM) + return TRUE; + } + } + + return FALSE; +} + //