mirror of
https://github.com/zeldaret/oot.git
synced 2024-11-10 19:20:13 +00:00
Update asm_processor and use static variables in En_Torch2 (#740)
* Update asm_processor to current master * Update variables in En_Torch2 to actually be static This is now possible because asm_processor was updated to handle static symbols in GLOBAL_ASM * Update tutorial to reflect changes about static symbol limitations
This commit is contained in:
parent
b863784893
commit
97f80eeb3f
3 changed files with 84 additions and 26 deletions
|
@ -23,8 +23,6 @@ Both approaches have their advantages and disadvantages.
|
||||||
<!-- Fig shows how to do this in his video. -->
|
<!-- Fig shows how to do this in his video. -->
|
||||||
This way is good for smaller actors with little data. It is not really suitable for EnJj, for example, because of the enormous section of data labelled as `D_80A88164`.
|
This way is good for smaller actors with little data. It is not really suitable for EnJj, for example, because of the enormous section of data labelled as `D_80A88164`.
|
||||||
|
|
||||||
An important thing to bear in mind is that data cannot be made static if it is used in an undecompiled file (i.e. one that is `#pragma`'d), so it is best to make everything static only after the whole actor is decompiled.
|
|
||||||
|
|
||||||
### Example: `EnTg`
|
### Example: `EnTg`
|
||||||
|
|
||||||
We give a simple example of this approach with a small NPC actor, EnTg, that is, the spinning couple.
|
We give a simple example of this approach with a small NPC actor, EnTg, that is, the spinning couple.
|
||||||
|
@ -165,10 +163,10 @@ static ColliderCylinderInit sCylinderInit =
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Copy this in below `D_80B18910`, delete the original words of data, and for now, remove `static` (in case it's used in other files that have not been decompiled), change the name back to `D_80B18910`, and put `sCylinderInit` commented out above it:
|
Copy this in below `D_80B18910`, delete the original words of data, change the name back to `D_80B18910`, and put `sCylinderInit` commented out above it:
|
||||||
```C
|
```C
|
||||||
// sCylinderInit
|
// sCylinderInit
|
||||||
ColliderCylinderInit D_80B18910 =
|
static ColliderCylinderInit D_80B18910 =
|
||||||
{
|
{
|
||||||
{ COLTYPE_UNK10, 0x00, 0x00, 0x39, 0x20, COLSHAPE_CYLINDER },
|
{ COLTYPE_UNK10, 0x00, 0x00, 0x39, 0x20, COLSHAPE_CYLINDER },
|
||||||
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, 0x00, 0x00, 0x01 },
|
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, 0x00, 0x00, 0x01 },
|
||||||
|
|
|
@ -66,26 +66,26 @@ const ActorInit En_Torch2_InitVars = {
|
||||||
(ActorFunc)EnTorch2_Draw,
|
(ActorFunc)EnTorch2_Draw,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* static */ f32 sStickTilt = 0.0f;
|
static f32 sStickTilt = 0.0f;
|
||||||
/* static */ s16 sStickAngle = 0;
|
static s16 sStickAngle = 0;
|
||||||
/* static */ f32 sSwordJumpHeight = 0.0f;
|
static f32 sSwordJumpHeight = 0.0f;
|
||||||
/* static */ s32 sHoldShieldTimer = 0;
|
static s32 sHoldShieldTimer = 0;
|
||||||
/* static */ u8 sZTargetFlag = false;
|
static u8 sZTargetFlag = false;
|
||||||
/* static */ u8 sDeathFlag = false;
|
static u8 sDeathFlag = false;
|
||||||
|
|
||||||
/* static */ Input sInput;
|
static Input sInput;
|
||||||
/* static */ u8 sSwordJumpState;
|
static u8 sSwordJumpState;
|
||||||
/* static */ Vec3f sSpawnPoint;
|
static Vec3f sSpawnPoint;
|
||||||
/* static */ u8 sJumpslashTimer;
|
static u8 sJumpslashTimer;
|
||||||
/* static */ u8 sJumpslashFlag;
|
static u8 sJumpslashFlag;
|
||||||
/* static */ u8 sActionState;
|
static u8 sActionState;
|
||||||
/* static */ u8 sSwordJumpTimer;
|
static u8 sSwordJumpTimer;
|
||||||
/* static */ u8 sCounterState;
|
static u8 sCounterState;
|
||||||
/* static */ u8 sDodgeRollState;
|
static u8 sDodgeRollState;
|
||||||
/* static */ u8 sStaggerCount;
|
static u8 sStaggerCount;
|
||||||
/* static */ u8 sStaggerTimer;
|
static u8 sStaggerTimer;
|
||||||
/* static */ s8 sLastSwordAnim;
|
static s8 sLastSwordAnim;
|
||||||
/* static */ u8 sAlpha;
|
static u8 sAlpha;
|
||||||
|
|
||||||
static DamageTable sDamageTable = {
|
static DamageTable sDamageTable = {
|
||||||
/* Deku nut */ DMG_ENTRY(0, 0x1),
|
/* Deku nut */ DMG_ENTRY(0, 0x1),
|
||||||
|
|
|
@ -81,6 +81,9 @@ R_MIPS_26 = 4
|
||||||
R_MIPS_HI16 = 5
|
R_MIPS_HI16 = 5
|
||||||
R_MIPS_LO16 = 6
|
R_MIPS_LO16 = 6
|
||||||
|
|
||||||
|
MIPS_DEBUG_ST_STATIC = 2
|
||||||
|
MIPS_DEBUG_ST_STATIC_PROC = 14
|
||||||
|
|
||||||
|
|
||||||
class ElfHeader:
|
class ElfHeader:
|
||||||
"""
|
"""
|
||||||
|
@ -132,14 +135,19 @@ class Symbol:
|
||||||
} Elf32_Sym;
|
} Elf32_Sym;
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, data, strtab):
|
def __init__(self, data, strtab, name=None):
|
||||||
self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx = struct.unpack('>IIIBBH', data)
|
self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx = struct.unpack('>IIIBBH', data)
|
||||||
assert self.st_shndx != SHN_XINDEX, "too many sections (SHN_XINDEX not supported)"
|
assert self.st_shndx != SHN_XINDEX, "too many sections (SHN_XINDEX not supported)"
|
||||||
self.bind = st_info >> 4
|
self.bind = st_info >> 4
|
||||||
self.type = st_info & 15
|
self.type = st_info & 15
|
||||||
self.name = strtab.lookup_str(self.st_name)
|
self.name = name if name is not None else strtab.lookup_str(self.st_name)
|
||||||
self.visibility = self.st_other & 3
|
self.visibility = self.st_other & 3
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_parts(st_name, st_value, st_size, st_info, st_other, st_shndx, strtab, name):
|
||||||
|
header = struct.pack('>IIIBBH', st_name, st_value, st_size, st_info, st_other, st_shndx)
|
||||||
|
return Symbol(header, strtab, name)
|
||||||
|
|
||||||
def to_bin(self):
|
def to_bin(self):
|
||||||
st_info = (self.bind << 4) | self.type
|
st_info = (self.bind << 4) | self.type
|
||||||
return struct.pack('>IIIBBH', self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx)
|
return struct.pack('>IIIBBH', self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx)
|
||||||
|
@ -913,6 +921,7 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc):
|
||||||
asm_objfile = ElfFile(f.read())
|
asm_objfile = ElfFile(f.read())
|
||||||
|
|
||||||
# Remove some clutter from objdump output
|
# Remove some clutter from objdump output
|
||||||
|
mdebug_section = objfile.find_section('.mdebug')
|
||||||
objfile.drop_irrelevant_sections()
|
objfile.drop_irrelevant_sections()
|
||||||
|
|
||||||
# Unify reginfo sections
|
# Unify reginfo sections
|
||||||
|
@ -1014,7 +1023,7 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc):
|
||||||
# Move over symbols, deleting the temporary function labels.
|
# Move over symbols, deleting the temporary function labels.
|
||||||
# Sometimes this naive procedure results in duplicate symbols, or UNDEF
|
# Sometimes this naive procedure results in duplicate symbols, or UNDEF
|
||||||
# symbols that are also defined the same .o file. Hopefully that's fine.
|
# symbols that are also defined the same .o file. Hopefully that's fine.
|
||||||
# Skip over local symbols that aren't used relocated against, to avoid
|
# Skip over local symbols that aren't relocated against, to avoid
|
||||||
# conflicts.
|
# conflicts.
|
||||||
new_local_syms = [s for s in objfile.symtab.local_symbols() if not is_temp_name(s.name)]
|
new_local_syms = [s for s in objfile.symtab.local_symbols() if not is_temp_name(s.name)]
|
||||||
new_global_syms = [s for s in objfile.symtab.global_symbols() if not is_temp_name(s.name)]
|
new_global_syms = [s for s in objfile.symtab.global_symbols() if not is_temp_name(s.name)]
|
||||||
|
@ -1039,6 +1048,57 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc):
|
||||||
new_local_syms.append(s)
|
new_local_syms.append(s)
|
||||||
else:
|
else:
|
||||||
new_global_syms.append(s)
|
new_global_syms.append(s)
|
||||||
|
|
||||||
|
# Add static symbols from .mdebug, so they can be referred to from GLOBAL_ASM
|
||||||
|
local_sym_replacements = {}
|
||||||
|
if mdebug_section:
|
||||||
|
strtab_index = len(objfile.symtab.strtab.data)
|
||||||
|
new_strtab_data = []
|
||||||
|
ifd_max, cb_fd_offset = struct.unpack('>II', mdebug_section.data[18*4 : 20*4])
|
||||||
|
cb_sym_offset, = struct.unpack('>I', mdebug_section.data[9*4 : 10*4])
|
||||||
|
cb_ss_offset, = struct.unpack('>I', mdebug_section.data[15*4 : 16*4])
|
||||||
|
for i in range(ifd_max):
|
||||||
|
offset = cb_fd_offset + 18*4*i
|
||||||
|
iss_base, _, isym_base, csym = struct.unpack('>IIII', objfile.data[offset + 2*4 : offset + 6*4])
|
||||||
|
for j in range(csym):
|
||||||
|
offset2 = cb_sym_offset + 12 * (isym_base + j)
|
||||||
|
iss, value, st_sc_index = struct.unpack('>III', objfile.data[offset2 : offset2 + 12])
|
||||||
|
st = (st_sc_index >> 26)
|
||||||
|
sc = (st_sc_index >> 21) & 0x1f
|
||||||
|
if st in [MIPS_DEBUG_ST_STATIC, MIPS_DEBUG_ST_STATIC_PROC]:
|
||||||
|
symbol_name_offset = cb_ss_offset + iss_base + iss
|
||||||
|
symbol_name_offset_end = objfile.data.find(b'\0', symbol_name_offset)
|
||||||
|
assert symbol_name_offset_end != -1
|
||||||
|
symbol_name = objfile.data[symbol_name_offset : symbol_name_offset_end + 1]
|
||||||
|
symbol_name_str = symbol_name[:-1].decode('latin1')
|
||||||
|
section_name = ['', '.text', '.data', '.bss'][sc]
|
||||||
|
section = objfile.find_section(section_name)
|
||||||
|
symtype = STT_FUNC if sc == 1 else STT_OBJECT
|
||||||
|
sym = Symbol.from_parts(
|
||||||
|
st_name=strtab_index,
|
||||||
|
st_value=value,
|
||||||
|
st_size=0,
|
||||||
|
st_info=(STB_LOCAL << 4 | symtype),
|
||||||
|
st_other=STV_DEFAULT,
|
||||||
|
st_shndx=section.index,
|
||||||
|
strtab=objfile.symtab.strtab,
|
||||||
|
name=symbol_name_str)
|
||||||
|
local_sym_replacements[symbol_name_str] = len(new_local_syms)
|
||||||
|
strtab_index += len(symbol_name)
|
||||||
|
new_strtab_data.append(symbol_name)
|
||||||
|
new_local_syms.append(sym)
|
||||||
|
objfile.symtab.strtab.data += b''.join(new_strtab_data)
|
||||||
|
|
||||||
|
# To get the linker to use the local symbols, we have to get rid of UNDEF
|
||||||
|
# global ones.
|
||||||
|
newer_global_syms = []
|
||||||
|
for s in new_global_syms:
|
||||||
|
if s.st_shndx == SHN_UNDEF and s.name in local_sym_replacements:
|
||||||
|
s.new_index = local_sym_replacements[s.name]
|
||||||
|
else:
|
||||||
|
newer_global_syms.append(s)
|
||||||
|
new_global_syms = newer_global_syms
|
||||||
|
|
||||||
new_syms = new_local_syms + new_global_syms
|
new_syms = new_local_syms + new_global_syms
|
||||||
for i, s in enumerate(new_syms):
|
for i, s in enumerate(new_syms):
|
||||||
s.new_index = i
|
s.new_index = i
|
||||||
|
|
Loading…
Reference in a new issue