def write_btm(filename): out = ['BTM0'] out += [struct.pack('<HH', tile_width, tile_height)] out += [struct.pack('<II', width, height)] out += [struct.pack('<I', len(tilesets))] for tileset in tilesets: out += [struct.pack('<I', len(prefix+tileset[1])), prefix+tileset[1]] # TODO: Animated tile defs out += [struct.pack('<I', 0)] out += [struct.pack('<I', len(objects))] for object in objects: out += [struct.pack('<III', object[0], object[1], object[2])] out += [struct.pack('<I', len(layers))] for layer in layers: out += [struct.pack('<I', len(layer[0])), layer[0]] raw_tiles = [] for y in xrange(height): for x in xrange(width): raw_tiles += [struct.pack('<H', layer[1][x][y])] compr_tiles = lzss.compress(''.join(raw_tiles)) out += [struct.pack('<I', len(compr_tiles)), compr_tiles] ser_col, raw_col = [], [] for y in xrange(height): for x in xrange(width): ser_col.append(col[x][y]) for i in xrange(0, len(ser_col), 8): mask = 0 for b in xrange(8): if i + b == len(ser_col): break if ser_col[i + b] == 1: mask |= 1 << (7-b) raw_col += [struct.pack('B', mask)] compr_col = lzss.compress(''.join(raw_col)) out += [struct.pack('<I', len(compr_col)), compr_col] with open(filename, 'wb') as outfile: data = ''.join(out) outfile.write(data)
def writeToFile(self, fileobj): # Compress the map data cmpData = lzss.compress(str(self.data)) # Write to file fileobj.seek(0) fileobj.truncate() fileobj.write(struct.pack("<L", len(cmpData))) fileobj.write(cmpData)
def __bytes__(self): binaries_added = { } # (bytes, compress): (compressed_bytes, offset, cksum) things = bytearray(self.MAGIC) for prcl in self.prcls: prcl_offset = len(things) things.extend(bytes(len(prcl))) for entry in prcl.entries: dict_lookup = (entry.bytes, entry.compress) try: if not entry.backref_allowed: raise ValueError final_bytes, bytes_offset, cksum = binaries_added[ dict_lookup] except: # Need to use this binary! final_bytes = entry.bytes if entry.compress: final_bytes = lzss.compress(final_bytes) bytes_offset = len(things) cksum = crc32(final_bytes) things.extend(final_bytes) binaries_added[ dict_lookup] = final_bytes, bytes_offset, cksum # Pad to 4-byte boundary. Apple's build tool left pad bytes uninitialised! while len(things) % 4: things.append(0x99) # Tell this structure where it can find its binary data. entry.uncompressed_len = len(entry.bytes) entry.save_cksum = cksum if entry.should_checksum else 0 entry.save_offset = bytes_offset entry.save_len = len(final_bytes) # Then tell it where it can find the next one, if any if prcl is self.prcls[-1]: prcl.save_nextoffset = 0 else: prcl.save_nextoffset = len(things) things[prcl_offset:prcl_offset + len(prcl)] = bytes(prcl) # So now all structs and all data are placed. Phew. return bytes(things)
def writeToFile(self, fileobj): mapData = "" # Create the pointer table pointer = self.basePointer for data in self.sections: mapData += struct.pack("<L", pointer) pointer += len(data) # Append the sections for data in self.sections: mapData += data # Compress the map data cmpData = lzss.compress(mapData) # Write to file fileobj.seek(0) fileobj.truncate() fileobj.write(struct.pack("<L", len(cmpData))) fileobj.write(cmpData)
def compressLzss(data): return lzss.compress(data)
def Pack(src, dst): print ">> Packing g_over.bin" # pack 000.bin with open( os.path.join( src , "000.bin" ), "r+b" ) as fd: path = "asm_g_over_000" fd.seek( 40 ) for i in range( 2 ): with open( os.path.join( path , "%03d.bin" % i ) , "rb" ) as od: data = od.read() addr = fd.tell() fd.write( data ) link = fd.tell() fd.seek( 20 * i ) fd.write( struct.pack("<L", (addr - fd.tell()) ) ) fd.write( struct.pack("<L", len(data)) ) fd.seek( link ) # pack 001.bin with open( os.path.join( src , "001_descomprimido.bin" ), "r+b" ) as fd: print os.path.join( src , "001_descomprimido.bin" ) addr_0 = struct.unpack("<L" , fd.read(4))[0] addr_1 = struct.unpack("<L" , fd.read(4))[0] addr_2 = struct.unpack("<L" , fd.read(4))[0] path = "asm_g_over_001" with open( os.path.join( path , "001_000.bin" ) , "rb" ) as od: fd.seek( addr_0 + 8) #w, h = struct.unpack("<2H", fd.read(4)) #size = w*h*2 fd.write( od.read() ) with open( os.path.join( path , "001_001.bin" ) , "rb" ) as od: fd.seek( addr_1 + 8 ) #w, h = struct.unpack("<2H", fd.read(4)) #size = w*h*2 fd.write( od.read() ) with open( os.path.join( src , "001_descomprimido.bin" ), "rb" ) as fd: ret = lzss.compress( fd ) with open( os.path.join( src , "001.bin" ), "wb" ) as gd: ret.tofile( gd ) with open( dst, "wb" ) as fd: fd.write( struct.pack("<L", 0x000005) ) fd.seek( 0x1c ) ptr_table_1_table = [] for i, f in enumerate(range(5)): addr = fd.tell() input = open( os.path.join(src, "%03d.bin" % f), "rb" ) fd.write( input.read() ) input.close() if ( fd.tell() % 4 != 0 ): fd.write( "\x00" * (4 - (fd.tell() % 4)) ) ptr_table_1_table.append(addr) ptr_table_1_table.append(fd.tell()) fd.seek( 0x04 ) for i, p in enumerate(ptr_table_1_table): fd.write( struct.pack( "<L", p | COMPRESSION_FLAG[i] ))
def generate(): global error # global curline # global curerror # global errorlog # infile = getPaletteFile() #get input file (path, infile) = os.path.split(infile) os.chdir(path) #change current directory to that of the input file folds = ['./_palettes'] for fold in folds: #make folders for comrpessed palettes if (not os.path.exists(fold)): try: os.mkdir(fold) except: print("this isn't working") return with open(infile, 'r') as file: data = file.read() output = "" setup = "" entries = removeComments(data) entries = entries.split('#') #entries = list(filter(None, entries)) meta = [] if (len(entries) == 0): print("the input file seems empty") return for e in range(1, len(entries)): #(e = 1; e < len(entries); e++) curerror = False z = entries[e].find('\n') n = entries[e][:z] m = data.find(n) curline = lineNumber(m, data) m = getinfo(n) meta.append(m) entry = entries[e][z:] if (entry.strip()): #attempt to convert into bytes entry = palette_hex(entry, m[2], m[1][1]) else: #do nothing if empty entry = bytearray() addWarning("Empty Entry") outfile = '' if (len(entry) and (not error and not curerror)): #skip this entry if it is empty setup += ('\n// ' + m[0] + '\n') outfile = (folds[0] + '/' + m[0] + compext) #generate palette file try: if (m[1][1]): #check if palette should be compressed lzss.compress(entry, open(outfile, 'wb')) else: with open(outfile, 'wb') as f: f.seek(0) f.write(entry) print(m[0]) except: #print("palette file generation error") addError("Output", "could not make palette file") #print macros for setup file if (curerror): error = True elif (m[1][0] == 'gen' and m[1][2]): #outfile = (folds[0] + '/' + m[0] + compext) for z in range(2, len(m[1])): setup += ('\t' + 'setGenericPalette(' + m[1][z] + ',' + m[0] + ')\n') elif (m[1][0] == 'char' and m[1][2]): #outfile = (folds[0] + '/' + m[0] + compext) for z in range(2, len(m[1])): setup += ('\t' + 'setPalette(' + m[1][z] + ',' + m[0] + ')\n') x = int(len(m[3])) for z in range(0, x, 3): setup += ('\t' + 'setCBSP(' + m[1][2] + ',' + m[3][z] + ',' + m[3][z + 1] + ',' + m[3][z + 2] + ')\n') if (outfile and (not error)): outfile = '\t#incbin "' + outfile + '" \n' if (m[4] and (not error)): output += ('PUSH \n' + 'ORG ' + m[4] + '\n' + m[0] + ':\n' + outfile + 'POP \n\n') else: output += m[0] + ':\n' + outfile + '\n' if (not error): setup = ("//Palette Setup \n" + "//Generated by Pal2EA v2.x\n\n" + '#include "' + macrofile + '"\n' + '#include "' + EAfile + '"\n' + setup) output = "//Palette Installer \n" + "//Generated by Pal2EA v2.x\n\n" + output try: with open(EAfile, 'w') as ofile: ofile.write(output) with open(setupfile, 'w') as sfile: sfile.write(setup) z = glob.glob('./' + macrofile, recursive=False) if (not z): #create file if it doesn't exist z = paldef() print('Generating ' + macrofile) with open('./' + macrofile, 'w') as dfile: dfile.write(z) except: #file generation error error = True print("could not generate files") #print error/warning log here if (warnlog): print('') print(warnlog) if (error): print('') print(errorlog) print("error(s) detected; no files written") else: print("no errors detected") return
def generate(): infile = getPaletteFile(); #get input file (path, infile) = os.path.split(infile) os.chdir(path) #change current directory to that of the input file folds = ['./_palettes'] for fold in folds: #make folders for comrpessed palettes if(not os.path.exists(fold)): try: os.mkdir(fold) except: print("this isn't working") return with open(infile, 'r') as file: data = file.read() output = "" setup = "" entries = removeComments(data) entries = entries.split('#') #entries = list(filter(None, entries)) meta = [] if(len(entries) == 0): print("the input file seems empty") return for e in range(1, len(entries)):#(e = 1; e < len(entries); e++) z = entries[e].find('\n') n = entries[e][:z] m = getinfo(n) meta.append(m) entry = entries[e][z:] if(m[3] and (m[2][0] != '')): entry = palette_hex(entry, m[2][1], m[2][0], m[2][2]) else: entry = re.sub(r'\s+','',entry) try: entry = bytearray().fromhex(entry) except: print('Hex Conversion Error2') print(entry) print(m) entry = bytearray() #decide output directory if (len(entry)): #skip this entry if it is empty setup += ('\n// ' + m[0] +'\n') if(m[1][0] == 'gen' and m[1][1]): outfile = (folds[0] + '/' + m[0] + compext) for z in range(1, len(m[1])): setup += ('\t' + 'setGenericPalette(' + m[1][z] + ',' + m[0] + ')\n') elif(m[1][0] == 'char' and m[1][1]): outfile = (folds[0] + '/' + m[0] + compext) setup += ('\t' + 'setPalette(' + m[1][1] + ',' + m[0] + ')\n') if(m[1][2]): setup += ('\t' + 'setCBSP(' + m[1][1] + ',' + m[1][2] + ',' + m[1][3] + ',' + m[1][4] + ')\n') else: outfile = folds[0] + '/' + m[0] + compext if(m[3]): lzss.compress(entry, open(outfile, 'wb')) output += m[0] + ':\n' + '\t#incbin "' + outfile + '"' + '\n\n' print(m[0]) #output += m[0] + ':\n' + '\t#incbin "' + outfile + '"' + '\n\n' setup = ("//Palette Setup \n" + "//Generated by Pal2EA v2.0\n\n" + '#include "' + macrofile + '"\n' + '#include "' + EAfile + '"\n' + setup) output = "//Palette Installer \n" + "//Generated by Pal2EA v2.0\n\n" + output with open(EAfile, 'w') as ofile: ofile.write(output) with open(setupfile, 'w') as sfile: sfile.write(setup) z = glob.glob('./' + macrofile, recursive = False) if (not z): #create file if it doesn't exist z = paldef() print('Generating ' + macrofile) with open('./' + macrofile, 'w') as dfile: dfile.write(z) return
def write_map_data_bytes(self, output): data = [self.mapWidth + (self.mapHeight << 8)] data.extend(self.mainData) lzss.compress(b''.join([(x).to_bytes(2, 'little') for x in data]), output)
if __name__ == "__main__": import argparse os.chdir( sys.path[0] ) #os.system( 'cls' ) parser = argparse.ArgumentParser() parser.add_argument( '-m', dest = "mode", type = str, required = True ) parser.add_argument( '-t', dest = "type", type = str, required = True ) parser.add_argument( '-i', dest = "src", type = str, nargs = "?", required = True ) parser.add_argument( '-o', dest = "dst", type = str, nargs = "?", required = True ) args = parser.parse_args() if args.mode == "d": with open( args.src, "rb" ) as fd: if args.type == "lz10": ret = lzss.uncompress( fd, 0 ) with open( args.dst, "wb" ) as fd: ret.tofile( fd ) elif args.mode == "c": with open( args.src, "rb" ) as fd: if args.type == "lz10": ret = lzss.compress( fd ) with open( args.dst, "wb" ) as fd: ret.tofile( fd )
index = 4 else: index = -1 if (palnum < index): contents = bytearray() for i in range(0, palnum): inFile.seek(i * 0x20) contents += bytearray(inFile.read(32)) for i in range(palnum, index): inFile.seek(0) contents += bytearray(inFile.read(32)) else: contents = inFile.read() lzss.compress(contents, open(outputFile, 'wb')) fileName = os.path.basename(outputFile) fileName = os.path.splitext(fileName)[0] fileName = fileName.replace(" ", "_") if fileName[0].isdigit(): fileName = '_' + fileName #check if label was already made for label in labelList: if fileName in labelList: n = 1 while fileName in labelList: n = n + 1 fileName = fileName + str(n) labelList.append(fileName)
monbook_en = load_monbook_translations( f"{TRANSLATIONS_PATH}/en.{args.filename}.txt") except ValueError as e: too_many_bytes = True too_many_bytes_reason = str(e) if too_many_bytes: print(too_many_bytes_reason) else: with open(f"{GAME_DATA_IN_DIR}/BATTLE/MONBOOK.TIM", "rb") as f: data = decompress(f.read()) for i in range(len(monbook_en)): data = data.replace(monbook_ja[i], monbook_en[i]) compressed_data = compress(data) with open(f"{GAME_DATA_OUT_DIR}/BATTLE/MONBOOK.TIM", "wb") as f: f.write(compressed_data) else: if args.filename == "slps": with open(f"{GAME_DATA_IN_DIR}/SLPS_014.68", "rb") as f: rawdata = f.read() elif args.filename == "fdevent": with open(f"{GAME_DATA_IN_DIR}/FIELD/FDEVENT.ACB", "rb") as f: rawdata = f.read() elif args.filename == "opendemo": # Run this after running dialogue scripts. This will translate mostly menu items. with open(f"{GAME_DATA_IN_DIALOGUE_DIR}/{args.filename}.BIN", "rb") as f: rawdata = f.read()
def process(tmxFilename, eventFilename, dmpFilename, boolAddHeader): """ Generates eventFilename and dmpFilename from tmxFilename """ feMap = FeMap.makeFromTiledMap(tmx.TileMap.load(tmxFilename)) feMap.genMissingMapChangeIds() feMap.normalizeProperties(TMX2EA_PROPERTY_DICT) if len(feMap.mapChanges) == 0: feMap.properties[KEY_PROPERTY_MAPCID] = "0" # WRITE DMP FILE with open(dmpFilename, 'wb') as f: lzss.compress(feMap.getMapDataBytes(), f) # WRITE EVENT FILE with open(eventFilename, 'w') as f: if boolAddHeader: f.writelines(genHeaderLines()) f.write("// Map Data Installer Generated by tmx2ea\n") f.write('\n{\n') f.write("\nALIGN 4\nMapData:\n #incbin \"{}\"\n".format( os.path.relpath(dmpFilename, os.path.dirname(eventFilename)))) f.write( "\nSetChapterData({}, {}, {}, {}, {}, {}, MapData, {}, {}, {})\n". format(feMap.properties[KEY_PROPERTY_CHAPTER], feMap.properties[KEY_PROPERTY_IMAGE1], feMap.properties[KEY_PROPERTY_IMAGE2], feMap.properties[KEY_PROPERTY_PALETTE], feMap.properties[KEY_PROPERTY_CONFIG], feMap.properties[KEY_PROPERTY_MAPID], feMap.properties[KEY_PROPERTY_ANIMS1], feMap.properties[KEY_PROPERTY_ANIMS2], feMap.properties[KEY_PROPERTY_MAPCID])) if len(feMap.mapChanges) != 0: for mapChange in feMap.mapChanges: f.write("\nALIGN 4\n") f.write("{}:\n".format(mapChange.name)) f.write(" SHORT {}\n".format(' '.join( '${:X}'.format(tile) for tile in mapChange.tiles))) f.write("\nALIGN 4\nMapChangesData:\n") for mapChange in feMap.mapChanges: f.write(' TileMap({}, {}, {}, {}, {}, {})\n'.format( mapChange.number, mapChange.x, mapChange.y, mapChange.width, mapChange.height, mapChange.name)) f.write(' TileMapEnd\n') f.write("\nEventPointerTable({}, MapChangesData)\n".format( feMap.properties[KEY_PROPERTY_MAPCID])) f.write('\n}\n')