diff options
Diffstat (limited to 'tools/script_extractor.py')
-rw-r--r-- | tools/script_extractor.py | 88 |
1 files changed, 63 insertions, 25 deletions
diff --git a/tools/script_extractor.py b/tools/script_extractor.py index c55b8cd..69d4ccd 100644 --- a/tools/script_extractor.py +++ b/tools/script_extractor.py @@ -9,7 +9,7 @@ ###### Script list is a work in progress. The following arguments are ###### ###### accepted and accounted for. ###### ###### b - byte w - word j - jump (within script) t - text (tx) ###### -###### f - flag d - direction i - decimal byte ###### +###### f - flag d - direction i - decimal byte m - npc move ptr ###### ###### q - Used when the script's arguments have not been determined yet ###### ############################################################################### import argparse @@ -21,7 +21,39 @@ QUIT_JUMP = 2 QUIT_SPECIAL = 3 QUIT_DEBUG = -1 -def decodeLine(scriptList, game_data, loc, ignore_broken, branchList): +dir_list = ["NORTH","EAST","SOUTH","WEST"] + +def printHeader(loc, prefix): + ls = format(loc,"04x") + lsa = format(loc-0x8000,"04x") + print(prefix + ls + ": ; " + ls + " (3:" + lsa + ")" ) + +def extractMovement(game_data, loc, errQuit): + printHeader(loc, "NPCMovement_") + loc -= 1 # so we can continue without breaking things + while game_data[loc+1] != 0xff: + loc += 1 + dirLow = game_data[loc] & 0x0f + if dirLow > 3: + print("ERROR: [" + format(loc,"04x") + "] was not a valid direction. Got: " + format(game_data[loc],"02x")) + if errQuit: + return QUIT_DEBUG + continue + lineStr = "\tdb " + dir_list[dirLow] + dirHigh = game_data[loc] & 0xf0 + if dirHigh == 0x80: + lineStr += " | NO_MOVE" + elif dirHigh != 0x00: + print("ERROR: [" + format(loc,"04x") + "] was not a valid direction. Got: " + format(game_data[loc],"02x")) + if errQuit: + return QUIT_DEBUG + continue + print(lineStr) + print("\tdb $ff") + print("; " + format(loc+2,"04x")) + return DO_NOT_QUIT + +def decodeLine(scriptList, game_data, loc, ignore_broken, locList): currLine = scriptList[game_data[loc]] ret = "\trun_script " + currLine[0] + "\n" loc+=1 @@ -42,7 +74,7 @@ def decodeLine(scriptList, game_data, loc, ignore_broken, branchList): ret += "\tdw NO_JUMP\n" else: ret += "\tdw .ows_" + format(wordLoc+0x8000,"04x") + "\n" - branchList.append(wordLoc) + locList.append(wordLoc) loc += 2 elif c == "t": addr = (game_data[loc] + (game_data[loc+1]<<8)) @@ -55,9 +87,12 @@ def decodeLine(scriptList, game_data, loc, ignore_broken, branchList): ret += "\tdb EVENT_FLAG_" + format(game_data[loc],"02X") + "\n" loc += 1 elif c == "d": - dir_list = ["NORTH","EAST","SOUTH","WEST"] ret += "\tdb " + dir_list[game_data[loc]] + "\n" loc += 1 + elif c == "m": + wordLoc = (game_data[loc] + (game_data[loc+1]<<8)) + ret += "\tdw NPCMovement_" + format(wordLoc + 0x8000, "04x") + "\n" + loc += 2 elif c == "q": print("haven't updated data for this yet") if not ignore_broken: @@ -68,19 +103,21 @@ def decodeLine(scriptList, game_data, loc, ignore_broken, branchList): def main(): scriptList = createList() - branchList = [] + locList = [] parser = argparse.ArgumentParser(description='Pokemon TCG Script Extractor') parser.add_argument('--noauto', action='store_true', help='turns off automatic script parsing') parser.add_argument('--error', action='store_true', help='stops execution if an error occurs') + parser.add_argument('-m', '--movement', action='store_true', help='interprets bytes as a movement script rather than an OWSequence') parser.add_argument('-r', '--rom', default="baserom.gbc", help='rom file to extract script from') - parser.add_argument('location', help='location to extract from. May be local to bank or global.') + parser.add_argument('locations', nargs="+", help='locations to extract from. May be local to bank or global.') args = parser.parse_args() - loc = int(args.location,0) - if loc > 0x7fff: - # Must be a global location - loc -= 0x8000 - branchList.append(loc) + for locStr in args.locations: + loc = int(locStr,0) + if loc > 0x7fff: + # Must be a global location + loc -= 0x8000 + locList.append(loc) # this is a list of every start location we've read to avoid infinite loops exploredList = [] @@ -91,14 +128,17 @@ def main(): auto = not args.noauto end = DO_NOT_QUIT ignore_broken = not args.error - while (len(branchList) > 0 and end != QUIT_DEBUG): - branchList.sort() # export parts in order somewhat - loc = branchList.pop(0) + 0x8000 - end = printScript(game_data, loc, auto, ignore_broken, scriptList,\ - branchList, exploredList) + while (len(locList) > 0 and end != QUIT_DEBUG): + locList.sort() # export parts in order somewhat + loc = locList.pop(0) + 0x8000 + if args.movement: + end = extractMovement(game_data,loc, args.error) + else: + end = printScript(game_data, loc, auto, ignore_broken, scriptList,\ + locList, exploredList) def printScript(game_data, loc, auto, ignore_broken, scriptList, \ - branchList, exploredList): + locList, exploredList): if loc in exploredList: return exploredList.append(loc) @@ -110,13 +150,11 @@ def printScript(game_data, loc, auto, ignore_broken, scriptList, \ else: # TODO this is hacky please don't do this - ls = format(loc,"04x") - lsa = format(loc-0x8000,"04x") - print("OWSequence_" + ls + ": ; " + ls + " (3:" + lsa + ")" ) + printHeader(loc, "OWSequence_") loc += 1 print("\tstart_script") while end == DO_NOT_QUIT: - loc, outstr, end = decodeLine(scriptList,game_data,loc,ignore_broken,branchList) + loc, outstr, end = decodeLine(scriptList,game_data,loc,ignore_broken,locList) outstr = outstr[:-1] # [:-1] strips the newline at the end if auto: print(outstr) @@ -176,7 +214,7 @@ def createList(): # this is a func just so all this can go at the bottom ("OWScript_DoFrames", "b", DO_NOT_QUIT), ("Func_d0d9", "bbw", DO_NOT_QUIT), # jumps but still needs args ("OWScript_JumpIfPlayerCoordMatches", "iij", DO_NOT_QUIT), # jumps but still needs args - ("Func_ce4a", "bb", DO_NOT_QUIT), + ("OWScript_MoveActiveNPC", "m", DO_NOT_QUIT), ("OWScript_GiveOneOfEachTrainerBooster", "", DO_NOT_QUIT), ("Func_d103", "q", DO_NOT_QUIT), ("Func_d125", "b", DO_NOT_QUIT), @@ -197,12 +235,12 @@ def createList(): # this is a func just so all this can go at the bottom ("Func_d271", "q", DO_NOT_QUIT), ("OWScript_EnterMap", "bbood", DO_NOT_QUIT), ("Func_ce6f", "bd", DO_NOT_QUIT), - ("Func_d209", "q", DO_NOT_QUIT), - ("Func_d38f", "q", DO_NOT_QUIT), + ("Func_d209", "", DO_NOT_QUIT), + ("Func_d38f", "b", DO_NOT_QUIT), ("Func_d396", "b", DO_NOT_QUIT), ("Func_cd76", "", DO_NOT_QUIT), ("Func_d39d", "b", DO_NOT_QUIT), - ("Func_d3b9", "q", DO_NOT_QUIT), + ("Func_d3b9", "", DO_NOT_QUIT), ("OWScript_TryGivePCPack", "b", DO_NOT_QUIT), ("OWScript_nop", "", DO_NOT_QUIT), ("Func_d3d4", "q", DO_NOT_QUIT), |