Skip to content

Instantly share code, notes, and snippets.

@SiD3W4y
Last active August 21, 2019 17:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SiD3W4y/298cfe4b1477b5dcd19b9373111e3886 to your computer and use it in GitHub Desktop.
Save SiD3W4y/298cfe4b1477b5dcd19b9373111e3886 to your computer and use it in GitHub Desktop.
Entity spawning logic for Zelda a Link to the past
// Function setting the position and id properties during spawn
void entity_spawn(u8* bindata, u8 entity_id)
{
// Globals
const u8* unk_arr_1 = (const u8*)0x8227c73; // ROM ptr
u8* unk_arr_2 = (u8*)0x2006b80; // RAM ptr
u8* entity_class = (u8*)0x30031d2; // Entity class array
u8* unk_arr_4 = (u8*)0x3003322;
u8* entity_low_y_pos = (u8*)0x3003102; // entity_low_y_pos
u8* entity_high_y_pos = (u8*)0x3003122; // entity_high_y_pos
u8* entity_low_x_pos = (u8*)0x3003112; // entity_low_x_pos
u8* entity_high_x_pos = (u8*)0x3003132; // entity_high_x_pos
u8* entity_ids = (u8*)0x3003222; // Entity id array
u8* unk_arr_10 = (u8*)0x3003232;
u16* unk_arr_11 = (u16*)0x30033c2;
u8* unk_arr_12 = (u8*)0x30030b5;
u16* unk_glob_1 = (u16*)0x3002d66;
u8* current_entity_idx = (u8*)0x3002b94; // current entity index
u8* current_entity_y = (u8*)0x3003829; // current entity y
u8* map_y_offset = (u8*)0x3003825; // y map offset
u8* current_entity_x = (u8*)0x300382a; // current entity x
u8* map_x_offset = (u8*)0x3003824; // x map offset
if(unk_arr_1[entity_id] & 0x1) {
u8 unk_loc_1 = unk_arr_2[*unk_glob_1 << 1] >> *current_entity_idx;
if((unk_loc_1 & 0x1) != 0)
return;
}
// Extracting coordinates from the bindata buffer
// bindata[0] is the current entity_id
u8 spawn_y = bindata[-2];
u8 spawn_x = bindata[-1];
entity_class[*current_entity_idx] = 0x8;
unk_arr_4[*current_entity_idx] = (spawn_y << 0x18) >> 0x1f; // 1 only if 7th bit set
*current_entity_y = spawn_y;
// Write y coord
u8 spawn_y_low = (spawn_y & 0x0f) << 4;
u8 spawn_y_high = (spawn_y & 0xf0) >> 4;
entity_low_y_pos[*current_entity_idx] = spawn_y_low;
entity_high_y_pos[*current_entity_idx] = (spawn_y_high & 0x1) + *map_y_offset;
// Write x coord
u8 spawn_x_low = (spawn_x & 0x0f) << 4;
u8 spawn_y_high = (spawn_x & 0xf0) >> 4;
entity_low_x_pos[*current_entity_idx] = spawn_x_low;
entity_high_x_pos[*current_entity_idx] = (spawn_y_high & 0x1) + *map_x_offset;
entity_ids[*current_entity_idx] = entity_id;
*current_entity_y = (*current_entity_y & 0x60) >> 2;
unk_arr_10[*current_entity_idx] = (*current_entity_x >> 5) | *current_entity_y;
unk_arr_11[*current_entity_idx] = *current_entity_idx;
unk_arr_12[*current_entity_idx] = 0;
}
// 0x80cb6b4
void entity_spawn_dirty(u8* bindata, u8 entity_id)
{
/*
push {r4, r5, r6, r7, lr}
mov r7, r8
push {r7}
adds r7, r0, #0 // r7 = bindata
lsls r1, r1, #0x18
lsrs r1, r1, #0x18
adds r4, r1, #0 // r4 = entity type
// unk_arr_1[entity_type] -> special properties ?
ldr r0, [pc, #0xec] {data_80cb7b0}
adds r0, r4, r0
ldrb r1, [r0]
movs r0, #1
mov r12, r0
ands r0, r1 // entity_type has lsb set
// r6 = unk_arr_2
ldr r6, [pc, #0xe4] {data_80cb7b4}
cmp r0, #0
bne #0x80cb6f2
*/
const u8* unk_arr_1 = (const u8*)0x8227c73; // ROM ptr
u8* unk_arr_2 = (u8*)0x2006b80; // RAM ptr
u8* unk_arr_3 = (u8*)0x30031d2; // Entity class array
u8* unk_arr_4 = (u8*)0x3003322;
u8* unk_arr_5 = (u8*)0x3003102; // entity_low_y_pos
u8* unk_arr_6 = (u8*)0x3003122; // entity_high_y_pos
u8* unk_arr_7 = (u8*)0x3003112; // entity_low_x_pos
u8* unk_arr_8 = (u8*)0x3003132; // entity_high_x_pos
u8* unk_arr_9 = (u8*)0x3003222; // Entity id array
u8* unk_arr_10 = (u8*)0x3003232;
u16* unk_arr_11 = (u16*)0x30033c2;
u8* unk_arr_12 = (u8*)0x30030b5;
u16* unk_glob_1 = (u16*)0x3002d66;
u8* unk_glob_2 = (u8*)0x3002b94; // current entity index
u8* unk_glob_3 = (u8*)0x3003829; // current entity y
u8* unk_glob_4 = (u8*)0x3003825; // y map offset
u8* unk_glob_5 = (u8*)0x300382a; // current entity x
u8* unk_glob_6 = (u8*)0x3003824; // x map offset
const u32 unk_cst_1 = 0xb36;
const u32 unk_cst_2 = 0x964;
r7 = bindata;
r4 = entity_type;
r1 = unk_arr_1[entity_type];
r0 = 1;
r12 = r0;
r0 &= r1;
if(r0 == 0) {
/*
ldr r1, [pc, #0xe0] {data_80cb7b8}
adds r0, r6, r1 {data_3002d66}
ldrh r0, [r0] {data_3002d66}
lsls r0, r0, #1
*/
r0 = *unk_glob_1 // because array is u16
r0 <<= 1; // r0 u16
/*
ldr r2, [pc, #0xdc] {data_80cb7bc}
adds r0, r0, r2
ldrb r0, [r0]
*/
r0 = unk_arr_2[r0]; // r0 u8
/*
ldr r5, [pc, #0xdc] {data_80cb7c0}
adds r1, r6, r5 {data_3002b94}
ldrb r1, [r1] {data_3002b94}
*/
r1 = *unk_glob_2; // because array is u16
/*
asrs r0, r1
mov r1, r12
ands r0, r1
cmp r0, #0
bne #0x80cb7a6
*/
r0 >>= r1;
r1 = r12;
r0 &= r1;
if(r0 != 0)
return;
}
// Now the actual meat of the program
/*
ldr r2, [pc, #0xcc] {data_80cb7c0}
adds r0, r6, r2 {data_3002b94}
ldrb r3, [r0] {data_3002b94}
*/
r3 = *unk_glob_2;
/*
subs r7, #2
ldr r5, [pc, #0xc8] {data_80cb7c4}
adds r0, r6, r5 // r0 arr_ptr = 0x30031d2
adds r0, r3, r0
movs r1, #0
mov r8, r1
movs r1, #8
strb r1, [r0] {0x8}
*/
r1 = 0;
r8 = r1;
r1 = 8;
r7 -= 2;
unk_arr_3[r3] = r1;
/*
ldrb r0, [r7] // extract data from bindata
ldr r2, [pc, #0xbc] {data_3003829} {data_80cb7c8}
strb r0, [r2] {data_3003829}
*/
r0 = *(u8*)r7;
*unk_glob_3 = r0;
/*
ldr r5, [pc, #0xbc] {data_80cb7cc} // r5 = 0x10f2
adds r1, r6, r5
adds r1, r3, r1
lsls r0, r0, #0x18
lsrs r0, r0, #0x1f
strb r0, [r1]
*/
unk_arr_4[r3] = (r0 << 0x18) >> 0x1f; // Matches only if the 7th bit is set
/*
ldr r0, [pc, #0xb4] {data_80cb7d0}
adds r1, r6, r0
adds r1, r3, r1
ldrb r0, [r7]
lsls r0, r0, #4
strb r0, [r1]
*/
// Set y_low_byte
unk_arr_5[r3] = *(u8*)r7 << 4;
/*
ldr r2, [pc, #0xac] {data_80cb7d4}
adds r1, r6, r2
adds r1, r3, r1
ldr r5, [pc, #0xa8] {data_80cb7d8}
adds r2, r6, r5 {data_3003825}
ldrb r0, [r7]
lsrs r0, r0, #4
mov r5, r12
ands r0, r5
ldrb r2, [r2] {data_3003825}
adds r0, r0, r2
strb r0, [r1]
*/
r0 = *(u8*)r7 >> 4; // Extract high nibble
r5 = r12;
r0 &= r5;
r2 = *unk_glob_4;
unk_arr_6[r3] = r0 + r2;
/*
adds r7, #1 // get to xpos byte
ldrb r1, [r7]
ldr r0, [pc, #0x98] {data_80cb7dc}
adds r5, r6, r0 {data_300382a}
strb r1, [r5] {data_300382a}
*/
(u8*)r7++;
r1 = *(u8*)r7;
*unk_glob_5 = r1;
/*
ldr r2, [pc, #0x94] {data_80cb7e0}
adds r0, r6, r2
adds r0, r3, r0
lsls r1, r1, #4
strb r1, [r0]
*/
unk_arr_7[r3] = r1 << 4;
/*
ldr r0, [pc, #0x90] {data_80cb7e4}
adds r1, r6, r0
adds r1, r3, r1
ldr r0, [pc, #0x8c] {data_80cb7e8}
adds r2, r6, r0 {data_3003824}
ldrb r0, [r7]
lsrs r0, r0, #4
mov r7, r12
ands r0, r7
ldrb r2, [r2] {data_3003824}
adds r0, r0, r2
strb r0, [r1]
*/
r0 = *(u8*)r7 >> 4;
r7 = r12;
r0 &= r7;
r2 = *unk_glob_6;
unk_arr_8[r3] = r0 + r2;
/*
ldr r1, [pc, #0x80] {data_80cb7ec}
adds r0, r6, r1
adds r0, r3, r0
strb r4, [r0] // write to entity type array
*/
unk_arr_9[r3] = entity_type;
/*
ldr r7, [pc, #0x7c] {data_80cb7f0}
adds r2, r6, r7 // 0x3003232
adds r2, r3, r2
mov r0, r8
strb r0, [r2] {0x0}
*/
unk_arr_10[r3] = r8; // r8 is constant 0
/*
ldr r1, [pc, #0x48] {data_3003829} {data_80cb7c8}
ldrb r0, [r1] {data_3003829}
movs r1, #0x60
ands r1, r0
lsrs r1, r1, #2
ldr r7, [pc, #0x40] {data_3003829} {data_80cb7c8}
strb r1, [r7] {data_3003829}
ldrb r0, [r5] {data_300382a}
lsrs r0, r0, #5
orrs r1, r0
strb r1, [r2]
*/
r0 = *unk_glob_3;
r1 = (r0 & 0x60) >> 2;
*unk_glob_3 = r1;
unk_arr_10[r3] = (*unk_glob_5 >> 5) | r1;
/*
lsls r0, r3, #1
ldr r2, [pc, #0x5c] {data_80cb7f4}
adds r1, r6, r2
adds r0, r0, r1
movs r1, #0
strh r3, [r0]
*/
r1 = 0;
unk_arr_11[r3] = r3; // array is u16
/*
ldr r5, [pc, #0x58] {data_80cb7f8}
adds r0, r6, r5 // 0x30030b5
adds r3, r3, r0
strb r1, [r3] {0x0}
*/
unk_arr_12[r3] = r1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment