summaryrefslogtreecommitdiff
path: root/tools/script_extractor.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/script_extractor.py')
-rw-r--r--tools/script_extractor.py88
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),