mirror of
https://github.com/zeldaret/oot.git
synced 2024-11-11 03:39:59 +00:00
New tool: sfxconvert (#514)
* Darkmeiro decompilation Bg_Gnd_Darkmeiro decompiled, matched, and documented. * give this a shot * fix conflict * one more try * could be useful * whoops * ZAP2 stuff * ZAP why * ZAP again * new tool * python function conventions * new name * new error handling * whoops comments
This commit is contained in:
parent
96512ee3ab
commit
0c2b92125f
5 changed files with 185 additions and 9 deletions
|
@ -245,7 +245,7 @@ void BgGanonOtyuka_Fall(BgGanonOtyuka* this, GlobalContext* globalCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func_80033DB8(globalCtx, 10, 15);
|
func_80033DB8(globalCtx, 10, 15);
|
||||||
Audio_PlaySoundAtPosition(globalCtx, &this->dyna.actor.posRot.pos, 0x28, 0x2839);
|
Audio_PlaySoundAtPosition(globalCtx, &this->dyna.actor.posRot.pos, 0x28, NA_SE_EV_BOX_BREAK);
|
||||||
}
|
}
|
||||||
Actor_Kill(&this->dyna.actor);
|
Actor_Kill(&this->dyna.actor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1444,7 +1444,7 @@ void func_809818FC(DemoGt* this, GlobalContext* globalCtx) {
|
||||||
u16 frames = globalCtx->csCtx.frames;
|
u16 frames = globalCtx->csCtx.frames;
|
||||||
|
|
||||||
if (frames == 845) {
|
if (frames == 845) {
|
||||||
func_80078914(&this->dyna.actor.projectedPos, 0x20DE);
|
func_80078914(&this->dyna.actor.projectedPos, NA_SE_EV_TOWER_PARTS_BROKEN - SFX_FLAG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void func_80981930(DemoGt* this, GlobalContext* globalCtx) {
|
void func_80981930(DemoGt* this, GlobalContext* globalCtx) {
|
||||||
|
@ -1626,7 +1626,7 @@ void func_809820AC(DemoGt* this, GlobalContext* globalCtx) {
|
||||||
u16 frames = globalCtx->csCtx.frames;
|
u16 frames = globalCtx->csCtx.frames;
|
||||||
|
|
||||||
if (frames == 154) {
|
if (frames == 154) {
|
||||||
func_80078914(&this->dyna.actor.projectedPos, 0x20DE);
|
func_80078914(&this->dyna.actor.projectedPos, NA_SE_EV_TOWER_PARTS_BROKEN - SFX_FLAG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -585,7 +585,7 @@ void func_80AEBAFC(EnRu1* this) {
|
||||||
|
|
||||||
void func_80AEBB3C(EnRu1* this) {
|
void func_80AEBB3C(EnRu1* this) {
|
||||||
if (func_800A56C8(&this->skelAnime, 5.0f)) {
|
if (func_800A56C8(&this->skelAnime, 5.0f)) {
|
||||||
func_80078914(&this->actor.projectedPos, 0x863);
|
func_80078914(&this->actor.projectedPos, NA_SE_PL_FACE_UP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,13 +595,13 @@ void func_80AEBB78(EnRu1* this) {
|
||||||
if ((((func_800A56C8(skelAnime, 4.0f)) || (func_800A56C8(skelAnime, 13.0f))) ||
|
if ((((func_800A56C8(skelAnime, 4.0f)) || (func_800A56C8(skelAnime, 13.0f))) ||
|
||||||
(func_800A56C8(skelAnime, 22.0f))) ||
|
(func_800A56C8(skelAnime, 22.0f))) ||
|
||||||
(func_800A56C8(skelAnime, 31.0f))) {
|
(func_800A56C8(skelAnime, 31.0f))) {
|
||||||
func_80078914(&this->actor.projectedPos, 0x839);
|
func_80078914(&this->actor.projectedPos, NA_SE_PL_SWIM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_80AEBBF4(EnRu1* this) {
|
void func_80AEBBF4(EnRu1* this) {
|
||||||
if (func_800A56C8(&this->skelAnime, 8.0f)) {
|
if (func_800A56C8(&this->skelAnime, 8.0f)) {
|
||||||
func_80078914(&this->actor.projectedPos, 0x873);
|
func_80078914(&this->actor.projectedPos, NA_SE_PL_SUBMERGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -856,7 +856,7 @@ void func_80AEC650(EnRu1* this) {
|
||||||
s32 pad[2];
|
s32 pad[2];
|
||||||
if (this->unk_280 == 0) {
|
if (this->unk_280 == 0) {
|
||||||
if ((func_800A56C8(&this->skelAnime, 2.0f)) || (func_800A56C8(&this->skelAnime, 7.0f))) {
|
if ((func_800A56C8(&this->skelAnime, 2.0f)) || (func_800A56C8(&this->skelAnime, 7.0f))) {
|
||||||
func_80078914(&this->actor.projectedPos, 0x803);
|
func_80078914(&this->actor.projectedPos, NA_SE_PL_WALK_DIRT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1926,7 +1926,7 @@ void func_80AEF40C(EnRu1* this) {
|
||||||
|
|
||||||
if ((func_800A56C8(skelAnime, 2.0f)) || (func_800A56C8(skelAnime, 7.0f)) || (func_800A56C8(skelAnime, 12.0f)) ||
|
if ((func_800A56C8(skelAnime, 2.0f)) || (func_800A56C8(skelAnime, 7.0f)) || (func_800A56C8(skelAnime, 12.0f)) ||
|
||||||
(func_800A56C8(skelAnime, 18.0f)) || (func_800A56C8(skelAnime, 25.0f)) || (func_800A56C8(skelAnime, 33.0f))) {
|
(func_800A56C8(skelAnime, 18.0f)) || (func_800A56C8(skelAnime, 25.0f)) || (func_800A56C8(skelAnime, 33.0f))) {
|
||||||
func_80078914(&this->actor.projectedPos, 0x803);
|
func_80078914(&this->actor.projectedPos, NA_SE_PL_WALK_DIRT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -212,7 +212,7 @@ void ObjKibako_Idle(ObjKibako* this, GlobalContext* globalCtx) {
|
||||||
void ObjKibako_SetupHeld(ObjKibako* this) {
|
void ObjKibako_SetupHeld(ObjKibako* this) {
|
||||||
this->actionFunc = ObjKibako_Held;
|
this->actionFunc = ObjKibako_Held;
|
||||||
this->actor.room = -1;
|
this->actor.room = -1;
|
||||||
func_8002F7DC(&this->actor, 0x878);
|
func_8002F7DC(&this->actor, NA_SE_PL_PULL_UP_WOODBOX);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjKibako_Held(ObjKibako* this, GlobalContext* globalCtx) {
|
void ObjKibako_Held(ObjKibako* this, GlobalContext* globalCtx) {
|
||||||
|
|
176
tools/sfxconvert.py
Normal file
176
tools/sfxconvert.py
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
AudioFunctions = {}
|
||||||
|
Verbose = False
|
||||||
|
Verbose2 = False
|
||||||
|
|
||||||
|
def set_verbose(v):
|
||||||
|
global Verbose
|
||||||
|
global Verbose2
|
||||||
|
|
||||||
|
Verbose = v
|
||||||
|
Verbose2 = v
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def make_audio_dict(AudioFunctions, repo):
|
||||||
|
with open(repo + os.sep + 'include' + os.sep + 'functions.h','r') as funcfile:
|
||||||
|
funcdata = funcfile.readlines()
|
||||||
|
for i, line in enumerate(funcdata):
|
||||||
|
if(line.count('sfxId')):
|
||||||
|
funcname, argnum = get_func_data(funcdata,i)
|
||||||
|
if(funcname != None):
|
||||||
|
AudioFunctions[funcname] = argnum
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def get_func_data(funcdata,i):
|
||||||
|
j = i
|
||||||
|
while(funcdata[j - 1].count(';') == 0):
|
||||||
|
j -= 1
|
||||||
|
k = i + 1
|
||||||
|
while(funcdata[k - 1].count(';') == 0):
|
||||||
|
k += 1
|
||||||
|
prototype = "".join(funcdata[j:k])
|
||||||
|
argdata = prototype.replace('(',',').replace(')',',').split(',')
|
||||||
|
funcname = argdata[0].split(' ')[1]
|
||||||
|
for x in range(len(argdata)):
|
||||||
|
if(argdata[x].count('sfxId')):
|
||||||
|
break;
|
||||||
|
if(x == len(argdata) - 1):
|
||||||
|
print('sfxId not found in ', funcname)
|
||||||
|
return None,-1
|
||||||
|
return funcname, x - 1
|
||||||
|
|
||||||
|
def lookup_sfx(idnum, repo):
|
||||||
|
if(type(idnum) is int):
|
||||||
|
id = '0x' + format(idnum,'X')
|
||||||
|
elif(idnum.isnumeric()):
|
||||||
|
id = '0x' + format(int(idnum),'X')
|
||||||
|
else:
|
||||||
|
id = idnum
|
||||||
|
idfix,sfxFlag = fix_sfx_flag(id)
|
||||||
|
with open(repo + os.sep + 'include' + os.sep + 'sfx.h','r') as sfxfile:
|
||||||
|
for line in sfxfile:
|
||||||
|
if(line.count(idfix)):
|
||||||
|
return line.split(' ')[1] + sfxFlag
|
||||||
|
return 'INVALID_ID'
|
||||||
|
|
||||||
|
def fix_sfx_flag(id):
|
||||||
|
if(id.endswith(' - SFX_FLAG')):
|
||||||
|
splitdata = id.split('-')
|
||||||
|
return splitdata[0].strip(), ' -' + splitdata[1]
|
||||||
|
if not(int(id,16) & 0x800):
|
||||||
|
newid = '0x' + format(int(id,16) + 0x800,'X')
|
||||||
|
sfxFlag = ' - SFX_FLAG'
|
||||||
|
else :
|
||||||
|
newid = id
|
||||||
|
sfxFlag = ''
|
||||||
|
return newid,sfxFlag
|
||||||
|
|
||||||
|
def fix_sfx_func(sourcedata, i, j, repo):
|
||||||
|
data = ''.join(sourcedata[i:j])
|
||||||
|
func = find_audio_func(data)
|
||||||
|
if(not func):
|
||||||
|
print('Function parse error at line', i)
|
||||||
|
return -3
|
||||||
|
index = data.find(func)
|
||||||
|
argnum = AudioFunctions.get(func,-1)
|
||||||
|
if(argnum == -1 or index == -1):
|
||||||
|
print('Function lookup error at line', i, 'in', func)
|
||||||
|
return -1
|
||||||
|
args = data[index:].replace('(',',').replace(')',',').split(',')
|
||||||
|
sfxId = args[argnum + 1].strip()
|
||||||
|
if(sfxId.count('NA_SE') != 0):
|
||||||
|
return 0
|
||||||
|
newId = lookup_sfx(sfxId, repo)
|
||||||
|
if(newId == 'INVALID_ID'):
|
||||||
|
print('ID parse error at line', i, 'in', func)
|
||||||
|
return -2
|
||||||
|
for k in range(i, j):
|
||||||
|
sourcedata[k] = sourcedata[k].replace(sfxId,newId)
|
||||||
|
if Verbose:
|
||||||
|
print('Replaced', sfxId, 'with', newId, 'in', func, 'at line', i + 1)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def find_audio_func(line):
|
||||||
|
audiofuncs = list(AudioFunctions.keys())
|
||||||
|
for func in audiofuncs:
|
||||||
|
if(line.count(func)):
|
||||||
|
return func
|
||||||
|
return False
|
||||||
|
|
||||||
|
def fix_sfx_all(repo):
|
||||||
|
global Verbose2
|
||||||
|
|
||||||
|
tv = Verbose2
|
||||||
|
Verbose2 = False
|
||||||
|
|
||||||
|
for subdir, dirs, files in os.walk(repo + os.sep + 'src'):
|
||||||
|
for filename in files:
|
||||||
|
if(filename.endswith('.c')):
|
||||||
|
file = subdir + os.sep + filename
|
||||||
|
fix_sfx(file, repo)
|
||||||
|
|
||||||
|
Verbose2 = tv
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def fix_sfx(file, repo, outfile = None):
|
||||||
|
if(outfile == None):
|
||||||
|
outfile = file
|
||||||
|
make_audio_dict(AudioFunctions, repo)
|
||||||
|
with open(file,'r',encoding='utf-8') as sourcefile:
|
||||||
|
sourcedata = sourcefile.readlines()
|
||||||
|
replacements = set()
|
||||||
|
j = 0
|
||||||
|
lookuperrors = 0
|
||||||
|
funcerrors = 0
|
||||||
|
iderrors = 0
|
||||||
|
fixes = 0
|
||||||
|
for i, line in enumerate(sourcedata):
|
||||||
|
if(i < j):
|
||||||
|
continue
|
||||||
|
if(find_audio_func(line)):
|
||||||
|
if(line.count(';')):
|
||||||
|
j = i + 1
|
||||||
|
else:
|
||||||
|
j = i
|
||||||
|
while(sourcedata[j].count(';') == 0):
|
||||||
|
j += 1
|
||||||
|
status = fix_sfx_func(sourcedata, i, j + 1, repo)
|
||||||
|
if(status == -3):
|
||||||
|
funcerrors += 1
|
||||||
|
elif(status == -2):
|
||||||
|
iderrors += 1
|
||||||
|
elif(status == -1):
|
||||||
|
lookuperrors += 1
|
||||||
|
elif(status > 0):
|
||||||
|
fixes += 1
|
||||||
|
if(fixes > 0):
|
||||||
|
with open(outfile,'w',encoding ='utf-8',newline='\n') as outfile:
|
||||||
|
outfile.writelines(sourcedata)
|
||||||
|
if Verbose:
|
||||||
|
print(file, 'updated')
|
||||||
|
elif Verbose2:
|
||||||
|
print('No changes made to', file)
|
||||||
|
if(lookuperrors > 0):
|
||||||
|
print('Problem with function lookup. Try formatting functions.h')
|
||||||
|
if(funcerrors > 0):
|
||||||
|
print('Problem with function parsing. Encountering this message should be impossible, so please report that you did.')
|
||||||
|
if(iderrors > 0):
|
||||||
|
print('Problem with id parsing. Make sure your SFX ids are in hex.')
|
||||||
|
return 1
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Convert hex SFX ids to macros')
|
||||||
|
parser.add_argument('file', help="source file to be processed")
|
||||||
|
parser.add_argument('repo', help="directory of the decomp repo")
|
||||||
|
parser.add_argument('-o', metavar='outfile',dest='outfile',help='file to write to instead of original')
|
||||||
|
parser.add_argument('-v', action='store_true',help='show what changes are made')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = parser.parse_args()
|
||||||
|
set_verbose(args.v)
|
||||||
|
fix_sfx(args.file, args.repo, outfile=args.outfile)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue