mirror of
https://github.com/FireEmblemUniverse/fireemblem8u.git
synced 2024-11-23 05:10:00 +00:00
dump anim-scr and anim-sprites
This commit is contained in:
parent
3646dbcc12
commit
2dbbd64423
2155
data/data_banim.s
2155
data/data_banim.s
File diff suppressed because it is too large
Load Diff
BIN
graphics/efxmagic/Gfx_EfxDanceObj.png
Normal file
BIN
graphics/efxmagic/Gfx_EfxDanceObj.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
@ -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
|
||||
|
@ -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[];
|
||||
|
@ -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
121
scripts/dump_anim_scr.py
Executable 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
108
scripts/dump_anim_sprite.py
Executable 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
49
scripts/elf2sym.py
Normal 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:])
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user