def parse_ramscript_line(l): l_tx = l l = [x.strip() for x in l.strip().replace(",","").replace(" "," ").split(" ")] try: args = [const_int(x) for x in l[1:]] except: args = [] if l[0] == "rs_write_1": return [ 0x00 | ((args[0] >> 8) & 0x1f), args[0] & 0xff, args[1] ] if l[0] == "rs_write_2": return [ 0x20 | ((args[0] >> 8) & 0x1f), args[0] & 0xff, args[1], args[2] ] if l[0] == "rs_write_3": return [ 0x40 | ((args[0] >> 8) & 0x1f), args[0] & 0xff, args[1], args[2], args[3] ] if l[0] == "rs_write_term": return [ 0x60 | ((args[0] >> 8) & 0x1f), args[0] & 0xff ] if l[0] == "rs_fill_2": return [ 0x80 | ((args[0] >> 8) & 0x1f), args[0] & 0xff ] if l[0] == "rs_fill_3": return [ 0xa0 | ((args[0] >> 8) & 0x1f), args[0] & 0xff ] if l[0] == "rs_fill_len": return [ 0xc0 | ((args[0] >> 8) & 0x1f), args[0] & 0xff, args[1] ] if l[0] == "rs_fill_byte": return [ 0xe0, args[0] ] if l[0] == "rs_end": return [0xff] if l[0] == "db": seq = [const_int(x) for x in l_tx.replace("db ","").strip().split(",")] return seq return []
def load_script(identifier, player_data=SAMPLE_PLAYER): fname = find_script_file(identifier) out = [] symbols = {"SCRIPT_ID": identifier} current_offset = 0 mode = "script" cur_txt = [] filtered_lines = [] ignore = False depth = 0 with open(fname, "r") as fp: lines = [ x.replace("%SCRIPT_ID%", "%.4X" % identifier) for x in fp.readlines() ] for l in lines: args = l.strip().split(" ") if args[-1].endswith("{"): depth += 1 if args[0] == "cond": inv = False if args[1].startswith("!"): args[1] = args[1][1:] inv = True if args[1] == "event": ignore = args[2] in player_data["events"] if args[1] == "item": ignore = args[2] in player_data["inventory"] if args[1] == "fun": ignore = int(args[2]) < player_data["fun"] < int( args[3]) if args[1] == "random": ignore = random.random() < (float(args[2]) / 100) if not inv: ignore = not ignore mode = "cond" continue elif args[0].endswith("}"): depth -= 1 if depth == 0 and mode in ("cond", "effects"): ignore = False mode = "script" continue if not ignore: filtered_lines.append(l) lines = filtered_lines for l in lines: args = l.strip().split(" ") if mode == "script": if args[0].endswith(":"): symbols[args[0].replace(":", "")] = SCRIPT_BASE + current_offset elif args[-1].endswith("{"): mode = args[0] cur_txt = [] symbols[args[1]] = SCRIPT_BASE + current_offset elif args[-1].endswith("{"): continue elif args[0] == "": continue else: if args[0] not in commands: raise RuntimeError("undefined script cmd %s" % args[0]) current_offset += sum(commands[args[0]][1:]) + 1 elif mode == "effects": if args[0] == "setevent": player_data["events"].append(args[1]) if args[0] == "clearevent": if args[1] in player_data["events"]: player_data["events"].remove(args[1]) if args[0] == "giveitem": if args[1] not in player_data["inventory"]: player_data["inventory"][args[1]] = 0 player_data["inventory"][args[1]] += 1 if args[0] == "takeitem": if args[1] in player_data["inventory"]: player_data["inventory"][args[1]] -= 1 if player_data["inventory"][args[1]] <= 0: del player_data["inventory"][args[1]] if args[0] == "newfun": player_data["fun"] = random.randrange(0, 255) if args[0].endswith("}"): mode = "script" elif mode == "textbox": if args[0].endswith("}"): mode = "script" current_offset += len(parse_textbox(cur_txt)) else: cur_txt.append(l.strip()) else: raise RuntimeError("unknown scripting mode %s" % mode) for l in lines: args = l.strip().split(" ") # print(args, mode) if mode == "script": if args[0].endswith(":") or args[0] == "": continue elif args[-1].endswith("{"): mode = args[0] cur_txt = [] else: if args[0] not in commands: raise RuntimeError("undefined script cmd %s" % args[0]) cmd = commands[args[0]] out.append(cmd[0]) for i in range(1, len(args)): if i >= len(cmd): raise RuntimeError("extra argument in '%s'" % l) if args[i] in symbols: args[i] = symbols[args[i]] if cmd[i] == 1: out.append(lobyte(const_int(args[i]))) elif cmd[i] == 2: out.append(lobyte(const_int(args[i]))) out.append(hibyte(const_int(args[i]))) else: raise RuntimeError("unsupported size %i" % cmd[i]) elif mode == "effects": if args[0].endswith("}"): mode = "script" elif mode == "textbox": if args[0].endswith("}"): mode = "script" out += parse_textbox(cur_txt) else: cur_txt.append(l.strip()) else: raise RuntimeError("unknown scripting mode %s" % mode) print(out) return out
def load_map(identifier, player_data): fname = find_map_file(identifier) config = configparser.ConfigParser() config.read(fname) num_warps = len([i for i in config.sections() if i.startswith("Warp_")]) num_signs = len([i for i in config.sections() if i.startswith("Sign_")]) num_objs = len([i for i in config.sections() if i.startswith("Object_")]) compiled_warps = [] compiled_signs = [] compiled_objs = [] compiled_connection_data = [] compiled_textptrs = [] compiled_blockdata = [0] compiled_ramscript = [] for i in range(0, num_warps): compiled_warps += [ const_int(config["Warp_%i" % i]["Y"]), const_int(config["Warp_%i" % i]["X"]) ] for i in range(0, num_warps): compiled_warps += [ const_int(config["Warp_%i" % i]["TargetY"]), const_int(config["Warp_%i" % i]["TargetX"]), lobyte(const_int(config["Warp_%i" % i]["ConnectedMapID"])) ] for i in range(0, num_signs): compiled_signs += [ const_int(config["Sign_%i" % i]["Y"]), const_int(config["Sign_%i" % i]["X"]) ] for i in range(0, num_signs): compiled_signs += [ const_int(config["Sign_%i" % i]["TextID"]) ] for i in range(0, num_objs): compiled_objs += [ const_int(config["Object_%i" % i]["PictureID"]), const_int(config["Object_%i" % i]["Y"]) + 4, const_int(config["Object_%i" % i]["X"]) + 4, const_int(config["Object_%i" % i]["Movement"]) ] for i in range(0, num_objs): compiled_objs += [ const_int(config["Object_%i" % i]["MovementPattern"]), const_int(config["Object_%i" % i]["TextID"]) ] print("TBOX", i, const_int(config["Object_%i" % i]["TextID"]), len(compiled_objs)) for direction in ("North", "South", "West", "East"): if direction not in config["Connections"]: continue current_conn = config["Connections"][direction].split(",") data = [const_int(x.strip()) for x in current_conn] compiled_connection_data += [ lobyte(data[0]), hibyte(data[0]), data[1], data[2] ] for i in range(0, len(config["TextPointers"])): tid = const_int(config["TextPointers"]["Text%i" % (i+1)]) compiled_textptrs += [ lobyte(tid), hibyte(tid) ] print("TPTR", i, const_int(config["TextPointers"]["Text%i" % (i+1)])) if "Blocks" in config["Sources"]: with open(MAP_PATH + config["Sources"]["Blocks"], "rb") as f: compiled_blockdata = list(f.read()) if "ConnectionPreview" in config["Sources"]: with open(MAP_PATH + config["Sources"]["ConnectionPreview"], "r") as f: for l in f.readlines(): compiled_ramscript += parse_ramscript_line(l) compiled_ramscript.append(0xff) map_data = [ const_int(config["MapHeader"]["Tileset"]), const_int(config["MapHeader"]["Height"]), const_int(config["MapHeader"]["Width"]), const_int(config["MapHeader"]["BorderBlock"]), const_int(config["MapHeader"]["Palette"]) ] map_data += [num_warps] + compiled_warps map_data += [num_signs] + compiled_signs map_data += [num_objs] + compiled_objs map_data += [ const_int(config["MapHeader"]["MusicID"]), const_int(config["MapHeader"]["MusicBank"]) ] map_data += compiled_connection_data + [0xff] map_data += compiled_blockdata + [0xff] map_data += compiled_textptrs + [0xff] map_data += compiled_ramscript print(len(map_data)) return map_data