dump anim-scr and anim-sprites

This commit is contained in:
MokhaLeee 2024-01-16 09:30:54 +00:00
parent 3646dbcc12
commit 2dbbd64423
11 changed files with 1566 additions and 944 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -31,6 +31,24 @@ ANFMT_INS_TYPE_FRAME = (ANIM_INS_TYPE_FRAME << 24)
.short 0
.endm
.macro ANIM_SPRITE_XFLIP oam0, oam1, oam2, x, y
.short \oam0
.short \oam1 + ATTR1_FLIP_X
.short \oam2
.short \x
.short \y
.short 0
.endm
.macro ANIM_SPRITE_AFFIN cnt, pa, pb, pc, pd
.short \cnt
.short 0xFFFF
.short \pa
.short \pb
.short \pc
.short \pd
.endm
.macro ANIM_SPRITE_END
ANIM_SPRITE 0x1, 0, 0, 0, 0
.endm

View File

@ -969,16 +969,16 @@ extern u16 Img_SpellJavelinGenerial[];
extern u16 Pal_SpellJavelinGenerial[];
extern u16 Img_SpellJavelinUnk[];
extern u16 Pal_SpellJavelinUnk[];
extern u32 AnimScr_085DC244[];
extern u32 AnimScr_085DC498[];
extern u32 AnimScr_085DC6F8[];
extern u32 AnimScr_085DC958[];
extern u32 gUnknown_085DCA5C[];
extern u32 gUnknown_085DCAF8[];
extern u16 gUnknown_085DCB10[];
extern u16 gUnknown_085DCC84[];
extern u32 gUnknown_085DD484[];
extern u32 gUnknown_085DD4B4[];
extern u32 AnimScr_EfxTeyariObjType0Right[];
extern u32 AnimScr_EfxTeyariObjType0Left[];
extern u32 AnimScr_EfxTeyariObjType1Right[];
extern u32 AnimScr_EfxTeyariObjType1Left[];
extern u32 AnimScr_085DCA5C[];
extern u32 AnimScr_085DCAF8[];
extern u16 Img_EfxDanceObj[];
extern u16 Pal_EfxDanceObj[];
extern u32 AnimScr_EfxDanceObj[];
extern u32 AnimScr_EfxSongObj2[];
extern u16 Img_BreathSprites[];
extern u16 Pal_FireBreathSprites[];
extern u16 gUnknown_085DE984[];
@ -2439,9 +2439,9 @@ extern u16 Tsa_08755E94[];
extern u16 Tsa_08755F3C[];
extern u16 Img_SongSprites[];
extern u32 gUnknown_08758134[];
extern u16 gUnknown_08758218[];
extern u32 gUnknown_087584B8[];
extern u32 gUnknown_087585DC[];
extern u16 Img_EfxLokmsunaObj[];
extern u32 AnimScr_EfxLokmsunaObjLeft[];
extern u32 AnimScr_EfxLokmsunaObjRight[];
// extern ??? gEkrDracoZombiTsaSetLut
extern struct ProcCmd ProcScr_EkrDracoZombie[];
extern struct ProcCmd ProcScr_ekrDragonQuake[];

View File

@ -1,3 +1,8 @@
OBJ_ROT_SCALE_ON = (1<<8)
OBJ_DISABLE = (1<<9)
OBJ_MODE_1 = (1<<10)
OBJ_MODE_2 = (2<<10)
OBJ_MODE_3 = (3<<10)
ATTR0_MOSAIC = (1<<12)
ATTR0_COLOR_256 = (1<<13)
ATTR0_COLOR_16 = (0<<13)

121
scripts/dump_anim_scr.py Executable file
View File

@ -0,0 +1,121 @@
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import sys
import elf2sym
import symbols
# ========================================================================
elf = "fireemblem8.elf"
with open(elf, 'rb') as f:
_symbols = { addr: name for addr, name in symbols.from_elf(f) }
def try_get_ptr_symbol(val):
is_symbol = False
ptr = val
if ptr > 0x08000000 and ptr < 0x09000000:
is_symbol = True
if ptr > 0x02000000 and ptr < 0x02040000:
is_symbol = True
if ptr > 0x03000000 and ptr < 0x03008000:
is_symbol = True
if ptr not in _symbols:
is_symbol = False
if is_symbol == True:
return _symbols[ptr]
else:
return None
# ========================================================================
def dump_one_part(rom_data, off):
while True:
data = int.from_bytes(rom_data[off + 0:off + 4], 'little')
off = off + 4
if (data & 0x80000000) == 0:
time1 = data & 3
time2 = (data >> 26) & 0x1C
time = time1 | time2
sprite_ptr = data & 0x08FFFFFC
ANIM_SPRITE = try_get_ptr_symbol(sprite_ptr)
if ANIM_SPRITE == 0:
ANIM_SPRITE = f"{data + 0x08000000:08X}"
print(f" ANIMSCR_FORCE_SPRITE {ANIM_SPRITE}, {time}")
if (data & 0x80000000):
ins = (0x7F000000 & data) >> 24
match ins:
case 0: # ANFMT_INS_TYPE_STOP
print(" ANIMSCR_BLOCKED")
break
case 1: # ANFMT_INS_TYPE_END
print("[ERROR]: ANFMT_INS_TYPE_END")
case 2: # ANFMT_INS_TYPE_LOOP
print("[ERROR]: ANFMT_INS_TYPE_LOOP")
case 3: # ANFMT_INS_TYPE_MOVE
print("[ERROR]: ANFMT_INS_TYPE_MOVE")
case 4: # ANFMT_INS_TYPE_WAIT
time = data & 0x00FFFFFF
print(f" ANIMSCR_WAIT {time}")
case 5: # ANIM_INS_TYPE_COMMAND
print("[ERROR]: ANIM_INS_TYPE_COMMAND")
case 6: # ANIM_INS_TYPE_FRAME
print("[ERROR]: ANIM_INS_TYPE_FRAME")
case _:
print("[ERROR] {ins}")
if data == 0x80000000:
print(" ANIMSCR_BLOCKED")
break
return off
def main(args):
rom = "baserom.gba"
try:
start = eval(args[1])
except IndexError:
sys.exit(f"Usage: {args[0]} START [END]")
try:
end = eval(args[2])
except IndexError:
end = 0
off = start & 0x01FFFFFF
off_end = end & 0x01FFFFFF
with open(rom, 'rb') as f:
rom_data = f.read()
while True:
name = try_get_ptr_symbol(off + 0x08000000)
if name == None:
name = f"AnimScr_{off + 0x08000000:08X}"
print(f".global {name}")
print(f"{name}: @ 0x{off:06X}")
off = dump_one_part(rom_data, off)
print("")
if off_end <= off:
break
print(f"// End at: {off + 0x08000000:08X}")
if __name__ == '__main__':
main(sys.argv)

108
scripts/dump_anim_sprite.py Executable file
View File

@ -0,0 +1,108 @@
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import sys, ctypes
def dump_one_part(rom_data, off):
while True:
oam0 = int.from_bytes(rom_data[off + 0:off + 2], 'little')
oam1 = int.from_bytes(rom_data[off + 2:off + 4], 'little')
oam2 = int.from_bytes(rom_data[off + 4:off + 6], 'little')
x = ctypes.c_int16(int.from_bytes(rom_data[off + 6:off + 8], 'little')).value
y = ctypes.c_int16(int.from_bytes(rom_data[off + 8:off + 10], 'little')).value
_0 = ctypes.c_int16(int.from_bytes(rom_data[off + 10:off + 12], 'little')).value
# print(f"@ [debug]: {hex(oam0)} {hex(oam1)} {hex(oam2)} {hex(x)} {hex(y)} {hex(_0)}")
if oam1 == 0xFFFF:
# affin
cnt = int.from_bytes(rom_data[off + 0:off + 2], 'little')
pa = ctypes.c_int16(int.from_bytes(rom_data[off + 4:off + 6], 'little')).value
pb = ctypes.c_int16(int.from_bytes(rom_data[off + 6:off + 8], 'little')).value
pc = ctypes.c_int16(int.from_bytes(rom_data[off + 8:off + 10], 'little')).value
pd = ctypes.c_int16(int.from_bytes(rom_data[off + 10:off + 12], 'little')).value
PREFIX = "ANIM_SPRITE_AFFIN"
print(f"\t{PREFIX} {cnt}, {hex(pa)}, {hex(pb)}, {hex(pc)}, {hex(pd)}")
off = off + 12
continue
if _0 != 0:
print(f"@ [ERROR]: at hex{off}!")
PREFIX = "ANIM_SPRITE"
OAM0 = f"0x{oam0:04X}"
if (oam0 & (3 << 14)) == (0 << 14):
OAM0 = "ATTR0_SQUARE"
if (oam0 & (3 << 14)) == (1 << 14):
OAM0 = "ATTR0_WIDE"
if (oam0 & (3 << 14)) == (2 << 14):
OAM0 = "ATTR0_TALL"
if oam0 & (1 << 8):
OAM0 = OAM0 + " + OBJ_ROT_SCALE_ON"
if oam1 & (1 << 12): # ATTR1_FLIP_X
PREFIX = "ANIM_SPRITE_XFLIP"
oam1 = oam1 & ~(1 << 12)
OAM1 = f"0x{oam1:04X}"
if oam1 == (0 << 14):
OAM1 = "ATTR1_SIZE_8"
if oam1 == (1 << 14):
OAM1 = "ATTR1_SIZE_16"
if oam1 == (2 << 14):
OAM1 = "ATTR1_SIZE_32"
if oam1 == (3 << 14):
OAM1 = "ATTR1_SIZE_64"
OAM2 = f"0x{oam2:04X}"
off = off + 12
# end
if oam0 == 1:
if oam1 != 0 or oam2 != 0 or x != 0 or y != 0:
print(f"@ [ERROR]: at hex{off}!")
print("\tANIM_SPRITE_END")
break;
print(f"\t{PREFIX} {OAM0}, {OAM1}, {OAM2}, {x}, {y}")
return off
def main(args):
rom = "baserom.gba"
elf = "fireemblem8u.elf"
try:
start = eval(args[1])
except IndexError:
sys.exit(f"Usage: {args[0]} START [END]")
try:
end = eval(args[2])
except IndexError:
end = 0
off = start & 0x01FFFFFF
off_end = end & 0x01FFFFFF
with open(rom, 'rb') as f:
rom_data = f.read()
while True:
print(f".global AnimSprite_{off + 0x08000000:08X}")
print(f"AnimSprite_{off + 0x08000000:08X}:")
off = dump_one_part(rom_data, off)
# print("")
if off_end <= off:
break
print(f"@ End at: {off + 0x08000000:08X}")
if __name__ == '__main__':
main(sys.argv)

49
scripts/elf2sym.py Normal file
View File

@ -0,0 +1,49 @@
import sys
from datetime import date
class SymInfo:
def __init__(self, name, addr, is_func):
self.name = name
self.addr = addr
self.is_func = is_func
def iter_elf_symbols(f):
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection
elf = ELFFile(f)
section = elf.get_section_by_name('.symtab')
if section == None or not isinstance(section, SymbolTableSection):
return
for sym in section.iter_symbols():
name = sym.name
if (len(name) == 0) or ('$' in name) or ('.' in name):
continue
yield SymInfo(name, sym.entry.st_value, sym.entry.st_info.type == 'STT_FUNC')
def main(args):
try:
elfname = args[0]
except IndexError:
sys.exit("Usage: {} ELF".format(sys.argv[0]))
with open(elfname, 'rb') as f:
elf_symbols = { sym.addr: sym for sym in iter_elf_symbols(f) }
addr_list = sorted(elf_symbols.keys())
for addr in addr_list:
if addr < 0x02000000:
continue
sym = elf_symbols[addr]
print(f"{(addr & 0xFFFFFFFE if sym.is_func else addr):08X} {sym.name}")
if __name__ == '__main__':
main(sys.argv[1:])

View File

@ -126,7 +126,7 @@ void StartSubSpell_efxShooterOBJ(struct Anim * anim)
proc->anim = anim;
proc->timer = 0;
frontAnim = EfxCreateFrontAnim(anim, gUnknown_085DCA5C, gUnknown_085DCAF8, gUnknown_085DCA5C, gUnknown_085DCAF8);
frontAnim = EfxCreateFrontAnim(anim, AnimScr_085DCA5C, AnimScr_085DCAF8, AnimScr_085DCA5C, AnimScr_085DCAF8);
proc->anim2 = frontAnim;
frontAnim->yPosition += 16;

View File

@ -599,13 +599,13 @@ void NewEfxTeyariOBJ(struct Anim * anim, int type)
if (type == 0)
{
scr2 = AnimScr_085DC244;
scr1 = AnimScr_085DC498;
scr2 = AnimScr_EfxTeyariObjType0Right;
scr1 = AnimScr_EfxTeyariObjType0Left;
}
else
{
scr2 = AnimScr_085DC6F8;
scr1 = AnimScr_085DC958;
scr2 = AnimScr_EfxTeyariObjType1Right;
scr1 = AnimScr_EfxTeyariObjType1Left;
}
anim2 = EfxCreateFrontAnim(anim, scr1, scr2, scr1, scr2);

View File

@ -590,8 +590,8 @@ void NewEfxLokmsunaOBJ(struct Anim *anim)
proc->anim = anim;
proc->timer = 0;
scr1 = gUnknown_087584B8;
scr2 = gUnknown_087585DC;
scr1 = AnimScr_EfxLokmsunaObjLeft;
scr2 = AnimScr_EfxLokmsunaObjRight;
anim2 = EfxCreateFrontAnim(anim, scr2, scr1, scr2, scr1);
proc->anim2 = anim2;
@ -603,7 +603,7 @@ void NewEfxLokmsunaOBJ(struct Anim *anim)
else
anim2->oam2Base |= 0x9000;
SpellFx_RegisterObjGfx(gUnknown_08758218, 0x1000);
SpellFx_RegisterObjGfx(Img_EfxLokmsunaObj, 0x1000);
}
void EfxLokmsunaIOBJMain(struct ProcEfxOBJ *proc)
@ -694,9 +694,9 @@ void NewEfxSongOBJ2(struct Anim *anim)
proc->anim = anim;
proc->timer = 0;
proc->terminator = 0x28;
proc->anim2 = EfxCreateFrontAnim(anim, gUnknown_085DD4B4, gUnknown_085DD4B4, gUnknown_085DD4B4, gUnknown_085DD4B4);
SpellFx_RegisterObjPal(gUnknown_085DCC84, 0x20);
SpellFx_RegisterObjGfx(gUnknown_085DCB10, 0x1000);
proc->anim2 = EfxCreateFrontAnim(anim, AnimScr_EfxSongObj2, AnimScr_EfxSongObj2, AnimScr_EfxSongObj2, AnimScr_EfxSongObj2);
SpellFx_RegisterObjPal(Pal_EfxDanceObj, 0x20);
SpellFx_RegisterObjGfx(Img_EfxDanceObj, 0x1000);
PlaySFX(0xEE, 0x100, proc->anim->xPosition, 0x1);
}
@ -721,9 +721,9 @@ void NewEfxDanceOBJ(struct Anim *anim)
proc->anim = anim;
proc->timer = 0;
proc->terminator = 0x19;
proc->anim2 = EfxCreateFrontAnim(anim, gUnknown_085DD484, gUnknown_085DD484, gUnknown_085DD484, gUnknown_085DD484);
SpellFx_RegisterObjPal(gUnknown_085DCC84, 0x20);
SpellFx_RegisterObjGfx(gUnknown_085DCB10, 0x1000);
proc->anim2 = EfxCreateFrontAnim(anim, AnimScr_EfxDanceObj, AnimScr_EfxDanceObj, AnimScr_EfxDanceObj, AnimScr_EfxDanceObj);
SpellFx_RegisterObjPal(Pal_EfxDanceObj, 0x20);
SpellFx_RegisterObjGfx(Img_EfxDanceObj, 0x1000);
PlaySFX(0xE1, 0x100, proc->anim->xPosition, 0x1);
}