def run(firstgame): infolder = "data/extract/data/script/" outfolder = "data/repack/data/script/" infile = "data/wsb_input.txt" fontfile = "data/replace/data/font/lcfont12.NFTR" if not os.path.isfile(infile): common.logError("Input file", infile, "not found") return encoding = "shift_jis" if firstgame else "shift_jisx0213" common.logMessage("Repacking WSB from", infile, "...") # Read the glyph size from the font if not os.path.isfile(fontfile): fontfile = fontfile.replace("replace/", "extract/") glyphs = nitro.readNFTR(fontfile).glyphs wordwrap = game.wordwrap[0] if firstgame else game.wordwrap[1] fixchars = game.getFixChars() with codecs.open(infile, "r", "utf-8") as wsb: commonsection = common.getSection(wsb, "COMMON", fixchars=fixchars) chartot, transtot = common.getSectionPercentage(commonsection) files = common.getFiles(infolder, ".wsb") for file in common.showProgress(files): section = common.getSection(wsb, file, fixchars=fixchars) chartot, transtot = common.getSectionPercentage( section, chartot, transtot) # Repack the file pointerdiff = {} pointers = {} common.logDebug(" Processing", file, "...") insize = os.path.getsize(infolder + file) with common.Stream(infolder + file, "rb") as fin: with common.Stream(outfolder + file, "wb") as f: # Copy header fin.seek(4) # 0x10 codeoffset = fin.readUInt() if codeoffset == 0 and not firstgame: fin.seek(0) f.write(fin.read()) continue fin.seek(8, 1) # all 0xFF unk = fin.readUInt() textoffset = fin.readUInt() codeoffset2 = fin.readUInt() fin.seek(0) f.write(fin.read(32)) # Write new strings while fin.tell() < codeoffset: pos = fin.tell() fpos = f.tell() b1 = fin.readByte() b2 = fin.readByte() f.writeByte(b1) f.writeByte(b2) if (b1 == 0x55 and b2 == 0x08) or (b1 == 0x95 and b2 == 0x10): sjis, oldlen = game.readShiftJIS( fin, b1 == 0x95, False, encoding) # Fix a bugged line with wrong speaker code if file == "event/ev_mou/mou_10.wsb" and sjis == "そうじゃな。|わっちの直感が申すには……>>": f.seek(fpos - 12) f.writeByte(0x53) f.seek(fpos + 2) strreplaced = False if sjis != "" and sjis != ">>": sjissplit = sjis.split(">>") for i in range(len(sjissplit)): newsjis = sjisline = sjissplit[i] if sjisline in commonsection: newsjis = commonsection[sjisline][0] elif sjisline in section: newsjis = section[sjisline].pop(0) if len(section[sjisline]) == 0: del section[sjisline] if newsjis != "": # Disable wordwrap for strings that contain replace codes if newsjis.count("@<") > 0: sjissplit[i] = newsjis # Check for automatic centering elif newsjis.count("<<") > 0: sjissplit[i] = common.centerLines( newsjis, glyphs, wordwrap, centercode="<<") else: sjissplit[i] = common.wordwrap( newsjis, glyphs, wordwrap) if sjissplit[i].count("|") > 2: common.logError( "Sub-line too long:", sjissplit[i]) cutsplit = sjissplit[i].split( "|") sjissplit[i] = cutsplit[ 0] + "|" + cutsplit[ 1] + "|" + cutsplit[2] newsjis = ">>".join(sjissplit) if newsjis != sjis and newsjis != "" and newsjis != ">>": common.logDebug("Repacking", newsjis, "at", common.toHex(pos)) strreplaced = True if newsjis == "!": newsjis = "" newlen = game.writeShiftJIS( f, newsjis, b1 == 0x95, False, 0, encoding, firstgame) lendiff = newlen - oldlen if newlen > (0x80 if firstgame else 0x70) and b1 == 0x55: common.logDebug( "String is too long", newlen, "changing to 0x95") f.seek(fpos) f.writeByte(0x95) f.writeByte(0x10) game.writeShiftJIS( f, newsjis, True, False, 0, encoding, firstgame) lendiff += 2 if lendiff != 0: common.logDebug( "Adding", lendiff, "at", pos) pointerdiff[pos - 16] = lendiff if not strreplaced: fin.seek(pos + 2) f.write( fin.read(oldlen + (4 if b1 == 0x95 else 2))) elif (b1, b2) in game.wsbcodes: if (b1, b2) in game.wsbpointers: if b1 == 0x81 and b2 == 0xB9: f.write(fin.read(2)) pointer = fin.readUInt() pointers[f.tell()] = pointer f.writeUInt(pointer) else: f.write(fin.read(game.wsbcodes[(b1, b2)])) # Write code section if codeoffset > 0: newcodeoffset = f.tell() codediff = 0 codenum = fin.readUInt() f.writeUInt(codenum) for i in range(codenum): fin.seek(codeoffset + 4 + 4 * i) f.seek(newcodeoffset + 4 + 4 * i) codepointer = fin.readUInt() f.writeUInt(codepointer + codediff) fin.seek(codeoffset + codepointer) f.seek(newcodeoffset + codepointer + codediff) sjis, codelen = game.readShiftJIS( fin, False, True, encoding) strreplaced = False if sjis in section or sjis in commonsection: if sjis in commonsection: newsjis = commonsection[sjis][0] else: newsjis = section[sjis].pop(0) if len(section[sjis]) == 0: del section[sjis] if newsjis != "": strreplaced = True newcodelen = game.writeShiftJIS( f, newsjis, False, True, 0, encoding, firstgame) if codelen != newcodelen: codediff += newcodelen - codelen if not strreplaced: fin.seek(codeoffset + codepointer) f.write(fin.read(codelen)) f.writeZero(insize - fin.tell()) # Write new header offsets f.seek(4) f.writeUInt(common.shiftPointer(codeoffset, pointerdiff)) f.seek(8, 1) f.writeUInt(common.shiftPointer(unk, pointerdiff)) f.writeUInt(common.shiftPointer(textoffset, pointerdiff)) f.writeUInt(common.shiftPointer(codeoffset2, pointerdiff)) # Shift pointers for k, v in pointers.items(): f.seek(k) f.writeUInt(common.shiftPointer(v, pointerdiff)) common.logMessage("Done! Translation is at {0:.2f}%".format( (100 * transtot) / chartot))
def gen(font, text, out, vert, fw, spacing, color, bg, width, height, center, wwrap, no_crop): """FONT is the font file, .NFTR extension can be omitted. TEXT is the text to write. "\\n" can be used for a line break. Can be the name of a UTF-8 file to read the text from.""" if not os.path.isfile(font): if not font.lower().endswith(".nftr"): font = font + ".NFTR" if not os.path.isfile(font): common.logMessage("[ERROR] Font", font, "not found") return None if os.path.isfile(text): with codecs.open(text, "r", "utf-8") as f: text = f.read().replace("\r\n", "\\n").replace("\n", "\\n") text = text.replace("\\n", "\n") # Add an additional line break to center the last line if not text.endswith("\n"): text += "\n" # Read the font data nftr = nitro.readNFTR(font, True) if wwrap: # Extract the glyphs for wordwrapping glyphs = {} for char in nftr.glyphs: glyph = nftr.glyphs[char] glyphs[char] = common.FontGlyph(glyph.start, glyph.width, glyph.length, glyph.char, glyph.code, glyph.index) if fw > 0: glyphs[char].length = fw else: glyphs[char].length += spacing # Wordwrap the text text = common.wordwrap(text, glyphs, width, default=nftr.width, linebreak="\n", sectionsep="") # Create the empty image img = Image.new("RGBA", (width, height), (0, 0, 0, 0)) if center: clearline = Image.new("RGBA", (width, nftr.height + vert), (0, 0, 0, 0)) # Generate the text currentx = 0 currenty = 0 for i in range(len(text)): c = text[i] if c == "\n": # Center the line if center: line = img.crop( (0, currenty, width, currenty + nftr.height + vert)) bbox = line.getbbox() line = line.crop(bbox) img.paste(clearline, (0, currenty)) img.paste(line, ((width - line.width) // 2, currenty)) # Reset the x position and increase y currentx = 0 currenty += nftr.height + vert continue if c not in nftr.glyphs: common.logMessage("[WARNING] Glyph", hex(ord(c)), "not found.") c = " " glyph = nftr.glyphs[c] glyphdata = nftr.plgc[glyph.index] img.paste(glyphdata, (currentx + glyph.start, currenty)) if fw > 0: currentx += fw + spacing else: currentx += glyph.length + spacing # Tint the image if color != "black": alpha = img.getchannel("A") img = Image.new("RGBA", (img.width, img.height), color) img.putalpha(alpha) # Crop and save the image if not no_crop: bbox = img.getbbox() img = img.crop(bbox) if bg == "transparent": final = img else: final = Image.new("RGBA", (img.width, img.height), bg if bg != "transparent" else (0, 0, 0, 0)) final.paste(img, (0, 0), img) if out != "": final.save(out, "PNG") return final
def run(data): infolder = data + "extract/" outfolder = data + "repack/" files = ["bank_11.bin", "bank_12.bin"] binfile = outfolder + "bank_14.bin" debugfile = outfolder + "bank_1e.bin" infile = data + "script_input.txt" chartot = transtot = 0 table, invtable, ccodes, glyphs = game.getFontData(data) if not os.path.isfile(infile): common.logError("Input file", infile, "not found") return pointers = {} pointerdiff = {} common.logMessage("Repacking script from", infile, "...") with codecs.open(infile, "r", "utf-8") as script: for file in common.showProgress(files): section = common.getSection(script, file) pointers[file] = [] pointerdiff[file] = {} if len(section) == 0: continue chartot, transtot = common.getSectionPercentage( section, chartot, transtot) # Repack the file common.logMessage("Processing", file, "...") size = os.path.getsize(infolder + file) with common.Stream(infolder + file, "rb") as fin: with common.Stream(outfolder + file, "wb") as f: while fin.tell() < size: opcode = fin.readByte() if opcode == 0x0a: f.writeByte(opcode) strpos2 = f.tell() strpos = fin.tell() readstr = game.readString(fin, table) newstr = "" if readstr != "": addend = "" if readstr[-2:] == ">>": addend = ">>" readstr = readstr[:-2] if readstr in section: newstr = section[readstr].pop(0) if len(section[readstr]) == 0: del section[readstr] strend = fin.tell() if newstr != "": newstr = common.wordwrap( newstr, glyphs, game.wordwrap, game.detectTextCode) if newstr == "!": newstr = "" newstr += addend common.logDebug("Writing string at", common.toHex(strpos), common.toHex(strpos2), newstr) game.writeString(f, newstr, invtable, ccodes) f.writeUShort(0xffff) strend2 = f.tell() lendiff = (strend2 - strpos2) - (strend - strpos) if lendiff != 0: common.logDebug("Adding", lendiff, "at", common.toHex(strpos)) pointerdiff[file][strpos + 1] = lendiff else: fin.seek(strpos) f.write(fin.read(strend - strpos)) elif opcode in game.repopcodes: if opcode in game.ptropcodes: pointers[file].append(f.tell()) f.writeByte(opcode) replen = 0 while True: loopbyte = fin.readByte() f.writeByte(loopbyte) replen += 1 if loopbyte == 0xff and (opcode not in game.ptropcodes or replen > 2): break else: if opcode in game.ptropcodes: pointers[file].append(f.tell()) f.writeByte(opcode) f.write(fin.read(game.opcodes[opcode])) if opcode == 0xff: check = fin.readUInt() check2 = fin.readUInt() fin.seek(-8, 1) if check == 0xffffffff and check2 == 0xffffffff: break # Pad with 0xffff f.writeBytes(0xff, 0xffff - f.tell() + 1) common.logMessage("Shifting script pointers ...") for file in common.showProgress(files): with common.Stream(outfolder + file, "rb+") as f: for pointerpos in pointers[file]: f.seek(pointerpos) opcode = f.readByte() for pointeroff in game.ptropcodes[opcode]: pointerfile = file if type(pointeroff) == tuple: f.seek(pointerpos + 1 + pointeroff[1]) bankid = f.readUShort() pointerfile = files[0] if bankid == 0x00f1 else files[1] pointeroff = pointeroff[0] f.seek(pointerpos + 1 + pointeroff) pointer = f.readUShort() if pointer != 0xffff: newpointer = common.shiftPointer( pointer, pointerdiff[pointerfile]) else: newpointer = pointer f.seek(-2, 1) f.writeUShort(newpointer) common.logMessage("Shifting bin pointers ...") # Read pointer tables in the bin file with common.Stream(binfile.replace("/repack/", "/extract/"), "rb+") as f: f.seek(0x23b0) while f.tell() < 0x2740: pos1 = f.tell() ptr1 = f.readUShort() bank1 = f.readUShort() pos2 = f.tell() ptr2 = f.readUShort() bank2 = f.readUShort() game.binptrs.append((pos1, ptr1, bank1)) game.binptrs.append((pos2, ptr2, bank2)) f.seek(8, 1) for binrange in [(0x2ff7, 0x3027), (0x3063, 0x309b), (0x480f, 0x481f), (0x496b, 0x499b), (0x4a01, 0x4a39)]: f.seek(binrange[0]) while f.tell() < binrange[1]: pos = f.tell() ptr = f.readUShort() bank = f.readUShort() game.binptrs.append((pos, ptr, bank)) f.seek(0x902e) while f.tell() < 0x9106: pos = f.tell() ptr = f.readUShort() game.binptrs.append((pos, ptr, 0xf2)) game.binptrs.append((0x26b8, 0x3d7b, 0xf2)) shiftPointers(binfile, game.binptrs, pointerdiff) # Shift debug pointers debugptrs = [] with common.Stream(debugfile.replace("/repack/", "/extract/"), "rb+") as f: f.seek(0xcd92) while f.tell() < 0xd420: pos1 = f.tell() ptr1 = f.readUShort() bank1 = f.readUShort() debugptrs.append((pos1, ptr1, bank1)) f.seek(12, 1) shiftPointers(debugfile, debugptrs, pointerdiff) common.logMessage("Done! Translation is at {0:.2f}%".format( (100 * transtot) / chartot))
def run(): infolder = "data/extract/data/Rom/event/script/" outfolder = "data/repack/data/Rom/event/script/" infile = "data/cnut_input.txt" fontfile = "data/repack/data/Rom/font/font0.NFTR" replacefontfile = "data/replace/data/Rom/font/font0.NFTR" chartot = transtot = 0 if not os.path.isfile(infile): common.logError("Input file", infile, "not found") return common.logMessage("Repacking CNUT from", infile, "...") if os.path.isfile(replacefontfile): glyphs = nitro.readNFTR(replacefontfile).glyphs else: glyphs = nitro.readNFTR(fontfile).glyphs with codecs.open(infile, "r", "utf-8") as cnut: files = common.getFiles(infolder, ".cnut") for file in common.showProgress(files): section = common.getSection(cnut, file, "//") if len(section) == 0: common.makeFolders(outfolder + file) common.copyFile(infolder + file, outfolder + file) continue chartot, transtot = common.getSectionPercentage( section, chartot, transtot) # Repack the file common.logDebug("Processing", file, "...") size = os.path.getsize(infolder + file) lastpos = 0 with common.Stream(infolder + file, "rb") as fin: common.makeFolders(infolder + file) with common.Stream(outfolder + file, "wb") as f: while fin.tell() < size - 4: pos = fin.tell() b1 = fin.readByte() b2 = fin.readByte() b3 = fin.readByte() b4 = fin.readByte() if b1 == 0x10 and b2 == 0x00 and b3 == 0x00 and b4 == 0x08: # Found a string check = game.readShiftJIS(fin) pre = post = "" # Add back some codes that are removed from extracted lines if check.startswith("#CLR()"): pre = "#CLR()" check = check[6:] if check.startswith("#ARW("): pre += check[:7] check = check[7:] if check.endswith("#INP()"): post = "#INP()" check = check[:-6] # Check if the line is translated and replace it if check in section: newsjis = section[check].pop(0) if len(section[check]) == 0: del section[check] if newsjis != "": newsjis = pre + newsjis + post if newsjis != check: newsjis = common.wordwrap( newsjis, glyphs, 205, game.detectTextCode) newsjis = newsjis.replace( ">>", "#INP()" + pre).replace( "|", "<0A>") # Copy data up to here endpos = fin.tell() fin.seek(lastpos) f.write(fin.read(pos + 4 - lastpos)) lastpos = endpos common.logDebug(" Repacking at", pos) game.writeShiftJIS(f, newsjis) else: fin.seek(pos + 1) fin.seek(lastpos) f.write(fin.read(size - lastpos)) common.logMessage("Done! Translation is at {0:.2f}%".format( (100 * transtot) / chartot))
def run(firstgame, no_redirect): infolder = "data/extract/data/data/" outfolder = "data/repack/data/data/" infile = "data/dat_input.txt" redfile = "data/redirects.asm" fontfile = "data/replace/data/font/lcfont12.NFTR" if not os.path.isfile(infile): common.logError("Input file", infile, "not found") return common.makeFolder(outfolder) chartot = transtot = 0 monthsection, skipsection = game.monthsection, game.skipsection game.monthsection = game.skipsection = None encoding = "shift_jis" if firstgame else "shift_jisx0213" common.logMessage("Repacking DAT from", infile, "...") # Read the glyph size from the font if not os.path.isfile(fontfile): fontfile = fontfile.replace("replace/", "extract/") glyphs = nitro.readNFTR(fontfile).glyphs fixchars = game.getFixChars() # Copy this txt file if not firstgame and os.path.isfile(infolder + "facilityhelp.txt"): common.copyFile(infolder + "facilityhelp.txt", outfolder + "facilityhelp.txt") redirects = [] with codecs.open(infile, "r", "utf-8") as dat: files = common.getFiles(infolder, ".dat") for file in common.showProgress(files): section = common.getSection(dat, file, fixchars=fixchars) # If there are no lines, just copy the file if len(section) == 0: common.copyFile(infolder + file, outfolder + file) # Part of the AP patch if not firstgame and file == "route.dat": with common.Stream(outfolder + file, "rb+") as f: f.seek(0x5ee8) f.writeByte(0x0) continue i = 0 chartot, transtot = common.getSectionPercentage( section, chartot, transtot) common.logDebug("Processing", file, "...") size = os.path.getsize(infolder + file) with common.Stream(infolder + file, "rb") as fin: with common.Stream(outfolder + file, "wb") as f: f.write(fin.read()) fin.seek(0) # Loop the file and replace strings as needed while fin.tell() < size - 2: pos = fin.tell() check = game.detectShiftJIS(fin, encoding) if check != "": if file == "entrance_icon.dat": # For entrance_icon, just write the string and update the pointer if check in section: # For the first one, seek to the correct position in the output file if i == 0: f.seek(pos) # Write the string newsjis = check if check in section and section[check][ 0] != "": common.logDebug( "Replacing string at", pos) newsjis = section[check][0] startpos = f.tell() game.writeShiftJIS(f, newsjis, False, True, 0, encoding) endpos = f.tell() # Update the pointer f.seek(0x1c98 + 4 * i) f.writeUInt(startpos - 0x1c98) f.seek(endpos) i += 1 else: # Found a SJIS string, check if we have to replace it if check in section and section[check][0] != "": common.logDebug("Replacing string at", pos) f.seek(pos) newsjis = section[check][0] maxlen = 0 if file == "goods.dat": newsjis = common.wordwrap( newsjis, glyphs, 170) maxlen = 60 elif file == "gossip.dat": newsjis = common.wordwrap( newsjis, glyphs, 190) if newsjis.count("<<") > 0: newsjis = common.centerLines( newsjis, glyphs, 190, centercode="<<") if fin.tell() - pos < 35: maxlen = 35 else: maxlen = 160 elif file == "scenarioguide.dat": newsjis = common.wordwrap( newsjis, glyphs, 165) maxlen = 60 if newsjis.count("|") > 1: common.logError( "scenarioguide line", newsjis, "too long") newlen = game.writeShiftJIS( f, newsjis, False, True, maxlen, encoding) if newlen < 0: if file != "gossip.dat" or no_redirect or maxlen != 160: common.logError( "String {} is too long ({}/{})." .format( newsjis, len(newsjis), maxlen)) else: common.logWarning( "String {} is too long ({}/{})." .format( newsjis, len(newsjis), maxlen)) # Doesn't fit, write it shorter f.seek(pos) cutat = 155 if firstgame else 150 while ord(newsjis[cutat]) > 127: cutat -= 1 stringfit = newsjis[:cutat] stringrest = newsjis[cutat:] game.writeShiftJIS( f, stringfit, False, True, maxlen, encoding) f.seek(-1, 1) f.writeByte(0x1f) f.writeByte(len(redirects)) redirects.append(stringrest) # Pad with 0s if the line is shorter while f.tell() < fin.tell(): f.writeByte(0x00) pos = fin.tell() - 1 fin.seek(pos + 1) with codecs.open(redfile, "w", "utf-8") as f: f.write(".ascii \"NDSC\"\n\n") f.write("REDIRECT_START:\n\n") for i in range(len(redirects)): f.write(".dh REDIRECT_{} - REDIRECT_START\n".format(i)) for i in range(len(redirects)): f.write("\nREDIRECT_{}:\n".format(i)) redirect = redirects[i].replace("\"", "\\\"") redirect = redirect.replace("|", "\" :: .db 0xa :: .ascii \"") redirectascii = "" for c in redirect: if ord(c) > 127: sjisc = common.toHex( int.from_bytes(c.encode(encoding), "big")) redirectascii += "\" :: .db 0x" + sjisc[:2] + " :: .db 0x" + sjisc[ 2:] + " :: .ascii \"" else: redirectascii += c f.write(".ascii \"{}\" :: .db 0\n".format(redirectascii)) game.monthsection, game.skipsection = monthsection, skipsection common.logMessage("Done! Translation is at {0:.2f}%".format( (100 * transtot) / chartot))
def run(data, allfile=False): infolder = data + "extract/" outfolder = data + "repack/" infile = data + "bin_input.txt" infilename = data + "name_input.txt" chartot = transtot = 0 table, invtable, ccodes, glyphs = game.getFontData(data) with codecs.open(infile, "r", "utf-8") as bin: common.logMessage("Repacking bin from", infile, "...") for file in common.showProgress(game.fileranges): section = common.getSection(bin, file) if len(section) == 0: continue chartot, transtot = common.getSectionPercentage( section, chartot, transtot) # Repack the file common.logMessage("Processing", file, "...") common.copyFile(infolder + file, outfolder + file) with common.Stream(outfolder + file, "rb+") as f: if file != "bank_1d.bin": for binrange in game.fileranges[file]: f.seek(binrange[0]) while f.tell() < binrange[1]: if (len(binrange) >= 3): f.seek(binrange[2], 1) strpos = f.tell() readstr = game.readString(f, table, True) if allfile and len(readstr) > 50: f.seek(strpos + 2) continue if readstr.startswith("|"): f.seek(strpos + 2) continue if readstr != "": newstr = "" if readstr in section: newstr = section[readstr].pop(0) if len(section[readstr]) == 0: del section[readstr] strend = f.tell() if newstr != "": if newstr == "!": newstr = "" common.logDebug("Repacking", newstr, "at", common.toHex(strpos)) f.seek(strpos) game.writeString(f, newstr, invtable, ccodes, strend - strpos - 2, True) while f.tell() < strend: f.writeByte(int(ccodes[" "][0], 16)) f.seek(strend - 2) f.writeUShort(0xffff) else: # String pointers are stored starting at 0xcd00 f.seek(0xcd00) ptrs = [] for i in range(23): ptrs.append(f.readUShort()) f.seek(14, 1) strings = [] for ptr in ptrs: f.seek(ptr) strings.append(game.readString(f, table, True)) newptrs = [] f.seek(0xce70) for i in range(len(strings)): if strings[i] in section: newstr = section[strings[i]].pop(0) else: newstr = strings[i] newstr = common.wordwrap(newstr, glyphs, game.wordwrap_angel, game.detectTextCode) common.logDebug("Repacking", newstr, "at", common.toHex(f.tell())) newstr = newstr.split("|") if len(newstr) > 8: common.logError("Line too long", str(len(newstr)) + "/8", newstr[0]) newstr = newstr[:8] while len(newstr) < 8: newstr.append("") for binstr in newstr: if not binstr.startswith("▼"): binstr = " " + binstr newptrs.append(f.tell()) game.writeString(f, binstr, invtable, ccodes, -1, True) f.writeUShort(0xffff) f.seek(0xcd00) for newptr in newptrs: f.writeUShort(newptr) # Set the name input selection glyphs in bank 14 newglyphs = {} with codecs.open(infilename, "r", "utf-8") as name: nameglyphs = name.read().replace("\r", "").replace("\n", "").replace("#", "") with common.Stream(outfolder + "bank_14.bin", "rb+") as f: # Write the new name input values f.seek(0xc250) for nameglyph in nameglyphs: if nameglyph in invtable and invtable[nameglyph][:2] != 'ff': f.writeUShort(int(invtable[nameglyph], 16)) else: glyphcode = int(ccodes[nameglyph][0], 16) - 0x20 glyphcode <<= 6 glyphcode += 0xa300 newglyphs[nameglyph] = glyphcode f.writeUShort(glyphcode) # Write "Adam", but using the long glyphs f.seek(0x296c + 3) f.writeUShort(int(invtable["A"], 16)) f.seek(3, 1) f.writeUShort(newglyphs["d"]) f.seek(3, 1) f.writeUShort(newglyphs["a"]) f.seek(3, 1) f.writeUShort(newglyphs["m"]) common.logMessage("Done! Translation is at {0:.2f}%".format( (100 * transtot) / chartot)) nasm.run(common.bundledFile("bin_patch.asm"))