StringBuilder ExportALL(InputFormRef.AutoPleaseWait pleaseWait, string basedir, bool isItemFont) { List <Address> list = new List <Address>(); MakeAllDataLengthInner(isItemFont, ref list); PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); Color bgcolor = GetFontColor(isItemFont); StringBuilder sb = new StringBuilder(); foreach (Address a in list) { if (a.DataType != FEBuilderGBA.Address.DataTypeEnum.FONT) { continue; } if (a.Addr <= Program.ROM.RomInfo.font_default_end()) {//規定のフォント continue; } int out_width; byte[] fontbyte = ReadFontData(a.Addr, out out_width); Bitmap bitmap = ImageUtil.ByteToImage4(16, 16, fontbyte, 0, bgcolor); ImageUtil.BlackOutUnnecessaryColors(bitmap, 1); string font_filename = Path.Combine(basedir, a.Info + ".png"); U.BitmapSave(bitmap, font_filename); bitmap.Dispose(); sb.AppendLine(a.Info + ".png"); } return(sb); }
public static Bitmap DrawFont(string one, bool IsItemFont, out int out_width) { PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); uint search_char = U.ConvertMojiCharToUnitFast(one, priorityCode); return(DrawFont(search_char, IsItemFont, out out_width)); }
//検索して表示 private void SearchButton_Click(object sender, EventArgs e) { PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); uint search_char = U.ConvertMojiCharToUnitFast(this.SearchChar.Text, priorityCode); uint fontlist_pointer = GetFontPointer(this.FontType.SelectedIndex == 0); uint prevaddr; uint fontaddr = FindFontDataZH(fontlist_pointer, search_char, out prevaddr); if (fontaddr == U.NOT_FOUND) { U.ForceUpdate(this.FontWidth, 0); this.SelectFontBitmapByte = null; this.Address.Value = 0; R.ShowWarning(R._("フォント:{0} が見つかりませんでした。"), this.SearchChar.Text); } else { int width; this.SelectFontBitmapByte = ReadFontDataZH(fontaddr, out width); if (width >= 30) {//たまにでかい値が来る時があるらしい. width = 30; } U.ForceUpdate(this.FontWidth, width); this.Address.Value = U.toPointer(fontaddr); } DrawFonts(); }
public FETextDecode() { this.ROM = Program.ROM; this.SystemTextEncoder = Program.SystemTextEncoder; this.PriorityCode = PatchUtil.SearchPriorityCode(); this.HasAutoNewLine = PatchUtil.SearchAutoNewLinePatch(); }
private void WriteButton_Click(object sender, EventArgs e) { if (this.SelectFontBitmapByte == null || this.SelectFontBitmapByte.Length != 40) { return; } string undo_name = "FONT " + this.SearchChar.Text; PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); uint search_char = U.ConvertMojiCharToUnitFast(this.SearchChar.Text, priorityCode); uint fontlist_pointer = GetFontPointer(this.FontType.SelectedIndex == 0); uint width = (uint)this.FontWidth.Value; bool isItemFont = this.FontType.SelectedIndex == 0; if (isItemFont) {//なぜか中国語フォントでは、アイテムフォントは幅+1しないといけない width = width - 1; } uint prevaddr; uint fontaddr = FindFontDataZH(fontlist_pointer, search_char, out prevaddr); if (fontaddr == U.NOT_FOUND) { //末尾に追加. if (prevaddr == U.NOT_FOUND) { //このフォントはルールにより登録できない.. return; } byte[] newFontData = MakeNewFontDataZH(search_char , width , this.SelectFontBitmapByte ); Undo.UndoData undodata = Program.Undo.NewUndoData(undo_name); uint newaddr = InputFormRef.AppendBinaryData(newFontData, undodata); if (newaddr == U.NOT_FOUND) {//エラー return; } //ひとつ前のフォントリストのポインタを、現在追加した最後尾にすげかえる. Program.ROM.write_u32(prevaddr, U.toPointer(newaddr), undodata); fontaddr = newaddr; } else {//更新 Program.Undo.Push(undo_name, fontaddr, 4 + 40); Program.ROM.write_u8(fontaddr + 1, width); Program.ROM.write_range(fontaddr + 8, this.SelectFontBitmapByte); //40バイト書き込み } this.Address.Value = U.toPointer(fontaddr); InputFormRef.ShowWriteNotifyAnimation(this, fontaddr); }
//フォントの描画 void DrawFonts() { if (SearchChar.Text.Length <= 0) { return; } Bitmap fontSampleBitmap; uint fontlist_pointer = GetFontPointer(this.FontType.SelectedIndex == 0); Color bgcolor = GetFontColor(this.FontType.SelectedIndex == 0); fontSampleBitmap = ImageUtil.Blank(FontPictureBox.Width, FontPictureBox.Height); PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); int drawwidth = 0; for (int i = 0; i < this.FontSample.Text.Length; i++) { uint search_char; if (this.FontSample.Text[i] == '@') { search_char = U.ConvertMojiCharToUnitFast(this.SearchChar.Text, priorityCode); } else { search_char = U.ConvertMojiCharToUnitFast(this.FontSample.Text.Substring(i, 1), priorityCode); } uint fontaddr = FindFontData(fontlist_pointer, search_char, priorityCode); if (fontaddr == U.NOT_FOUND) { continue; } int width; byte[] fontbyte; if (this.FontSample.Text[i] == '@') { width = (int)this.FontWidth.Value; fontbyte = this.SelectFontBitmapByte; } else { fontbyte = ReadFontData(fontaddr, out width); } if (width <= 0 || fontbyte == null) { continue; } Bitmap bitmap = ImageUtil.ByteToImage4(16, 16, fontbyte, 0, bgcolor); fontSampleBitmap.Palette = bitmap.Palette; ImageUtil.BitBlt(fontSampleBitmap, drawwidth, 0, width, 16, bitmap, 0, 0); drawwidth += width; } FontPictureBox.Image = U.Zoom(fontSampleBitmap, ZoomComboBox.SelectedIndex); }
string ConvertASCII(byte[] byte16) { PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); SystemTextEncoder encoder = Program.SystemTextEncoder; StringBuilder sb = new StringBuilder(); for (int i = 0; i < 16; i++) { if (i >= byte16.Length) { break; } if (priorityCode == PatchUtil.PRIORITY_CODE.UTF8) { sb.Append((char)byte16[i]); continue; } else if (i < 15 && U.isSJIS1stCode(byte16[i]) && U.isSJIS2ndCode(byte16[i + 1])) { if (priorityCode == PatchUtil.PRIORITY_CODE.LAT1) { //SJISと 1バイトUnicodeは範囲が重複するので、どちらかを優先しないといけない. if (byte16[i] >= 0x81 && byte16[i] < 0xFE) { //英語版FEにはUnicodeの1バイトだけ表記があるらしい. sb.Append((char)byte16[i]); sb.Append((char)byte16[i + 1]); i++; continue; } } sb.Append(encoder.Decode(byte16, i, 2)); i++; continue; } if (U.isAscii(byte16[i])) { sb.Append((char)byte16[i]); continue; } if (byte16[i] >= 0x81 && byte16[i] < 0xFE) {//FE独自フォントの可能性. if (priorityCode == PatchUtil.PRIORITY_CODE.LAT1) { sb.Append((char)byte16[i]); continue; } } //不明なコード sb.Append('.'); } return(sb.ToString()); }
private void WriteButton_Click(object sender, EventArgs e) { if (this.SelectFontBitmapByte == null || this.SelectFontBitmapByte.Length != 64) { return; } string undo_name = "FONT " + this.SearchChar.Text; PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); string target = this.SearchChar.Text; target = TextForm.ConvertFEditorToEscape(target); uint search_char = U.ConvertMojiCharToUnitFast(target, priorityCode); uint fontlist_pointer = GetFontPointer(this.FontType.SelectedIndex == 0); uint prevaddr; uint fontaddr = FindFontData(fontlist_pointer, search_char, out prevaddr, priorityCode); if (fontaddr == U.NOT_FOUND) { //末尾に追加. if (prevaddr == U.NOT_FOUND) { //このフォントはルールにより登録できない.日本語フォントで 0x100以下とか. return; } byte[] newFontData = MakeNewFontData(search_char , (uint)this.FontWidth.Value , this.SelectFontBitmapByte , Program.ROM , priorityCode ); Undo.UndoData undodata = Program.Undo.NewUndoData(undo_name); uint newaddr = InputFormRef.AppendBinaryData(newFontData, undodata); if (newaddr == U.NOT_FOUND) {//エラー return; } //ひとつ前のフォントリストのポインタを、現在追加した最後尾にすげかえる. Program.ROM.write_u32(prevaddr + 0, U.toPointer(newaddr), undodata); fontaddr = newaddr; } else {//更新 Program.Undo.Push(undo_name, fontaddr, 8 + 64); Program.ROM.write_u8(fontaddr + 5, (uint)this.FontWidth.Value); Program.ROM.write_range(fontaddr + 8, this.SelectFontBitmapByte); //64バイト書き込み } this.Address.Value = U.toPointer(fontaddr); InputFormRef.ShowWriteNotifyAnimation(this, fontaddr); }
private void AddressList_SelectedIndexChanged(object sender, EventArgs e) { uint addr = InputFormRef.SelectToAddr(this.AddressList); PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); //アイテム ItemFontPictureBox.Image = FontForm.DrawFont(Program.ROM.u16(addr), true, priorityCode); //セリフ SerifFontPictureBox.Image = FontForm.DrawFont(Program.ROM.u16(addr), false, priorityCode); }
public FETextDecode(ROM rom, SystemTextEncoder encoder) { this.ROM = rom; this.SystemTextEncoder = encoder; if (rom == Program.ROM) { this.PriorityCode = PatchUtil.SearchPriorityCode(); } else { this.PriorityCode = PatchUtil.SearchPriorityCode(rom); } }
public static Bitmap DrawFontString(string str, bool IsItemFont) { //フォントで描画した場合の幅と高さを求める. Size size = MeasureTextMultiLine(str, IsItemFont); if (size.Width <= 0 || size.Height <= 0) { return(ImageUtil.BlankDummy()); } uint fontlist_pointer = GetFontPointer(IsItemFont); PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); Bitmap bitmap = ImageUtil.Blank(size.Width, size.Height); string[] lines = str.Split(new string[] { "\r\n" }, StringSplitOptions.None); for (int n = 0; n < lines.Length; n++) { string line = lines[n]; int totalwidth = 0; for (int i = 0; i < line.Length; i++) { string one = str[i].ToString(); uint search_char = U.ConvertMojiCharToUnitFast(one, priorityCode); int width; Bitmap oneBitmap = DrawFont(search_char, IsItemFont, out width, priorityCode); if (oneBitmap == null) { continue; } if (n == 0) {//最初ならパレット設定. bitmap.Palette = oneBitmap.Palette; } ImageUtil.BitBlt(bitmap, totalwidth, n * 16, width, 16, oneBitmap, 0, 0, 0, 0); totalwidth += width; } } return(bitmap); }
public static string ConvertSPMoji(string str) { PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); str = str.Replace("\r\n", "@0001"); if (priorityCode == PatchUtil.PRIORITY_CODE.UTF8) { return(str); } //日本語版は一部入りきらない文字を特殊フォント化しているので変換する. if (Program.ROM.RomInfo.version() >= 8) { str = str.Replace("(サンダーストーム)", "нопр"); ///No Translate str = str.Replace("(フォレストナイト)", "⊂⊃┌┐"); ///No Translate str = str.Replace("(ドラゴンマスター)", "абвг"); ///No Translate str = str.Replace("(ワイバーンナイト)", "шщъы"); ///No Translate str = str.Replace("(ファルコンナイト)", "жзий"); ///No Translate str = str.Replace("(モーサドゥーグ)", "∞┴∠∧"); ///No Translate str = str.Replace("(デスガーゴイル)", "∇∈∋├"); ///No Translate str = str.Replace("(ドラゴンゾンビ)", "≠≡≦≧"); ///No Translate str = str.Replace("(ゴーゴンの卵)", "∪∫∬∴"); ///No Translate } else if (Program.ROM.RomInfo.version() >= 7) { //FE7 str = str.Replace("(サンダーストーム)", "⑮⑯⑰⑱⑲⑳α"); ///No Translate str = str.Replace("(ファルコンナイト)", "⑧⑨⑩⑪⑫⑬⑭"); ///No Translate str = str.Replace("(ドラゴンマスター)", "①②③④⑤⑥⑦"); ///No Translate } else if (Program.ROM.RomInfo.version() >= 6) { //FE6 str = str.Replace("(サンダーストーム)", "①②③④⑤⑥⑦"); ///No Translate str = str.Replace("(ファルコンナイト)", "ⅠⅡⅢⅣⅤⅥⅦ"); ///No Translate str = str.Replace("(ドラゴンマスター)", "⑪⑫⑬⑭⑮⑯⑰"); ///No Translate } //英語版FEにはUnicodeの1バイトだけ表記があるらしい. { for (int c = 0x82; c <= 0xff; c++) { str = str.Replace(((char)c).ToString(), "@00" + c.ToString("X02")); } } return(str); }
private void SEARCH_CHAR_BUTTON_Click(object sender, EventArgs e) { PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); uint code = U.ConvertMojiCharToUnit(SEARCH_CHAR.Text, priorityCode); //リストから検索して選択する uint addr = (uint)InputFormRef.BaseAddress; int limitsize = (int)InputFormRef.DataCount; for (int i = 0; i < limitsize; i++) { if (Program.ROM.u16(addr) == code) { AddressList.SelectedIndex = i; break; } addr += InputFormRef.BlockSize; } }
private void ExportButton_Click(object sender, EventArgs e) { if (this.SearchChar.Text.Length <= 0) { return; } PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); if (this.FontType.SelectedIndex == 0) { //アイテム Bitmap bitmap = FontForm.DrawFont(this.SearchChar.Text, true, priorityCode); ImageFormRef.ExportImage(this, bitmap, InputFormRef.MakeSaveImageFilename(this, "Item_" + this.SearchChar.Text), 8); } else { //セリフ Bitmap bitmap = FontForm.DrawFont(this.SearchChar.Text, false, priorityCode); ImageFormRef.ExportImage(this, bitmap, InputFormRef.MakeSaveImageFilename(this, "Serif_" + this.SearchChar.Text), 8); } }
public void Build(OptionForm.textencoding_enum textencoding, ROM rom) { bool r = LoadTBL(textencoding, rom); if (r) {//TBLを利用. return; } if (textencoding == OptionForm.textencoding_enum.Auto) {//自動選択 PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(rom); if (priorityCode == PatchUtil.PRIORITY_CODE.UTF8) { this.Encoder = System.Text.Encoding.GetEncoding("UTF-8"); } else if (priorityCode == PatchUtil.PRIORITY_CODE.LAT1) { this.Encoder = System.Text.Encoding.GetEncoding("iso-8859-1"); } else { //ディフォルトは日本語. this.Encoder = System.Text.Encoding.GetEncoding("Shift_JIS"); } } else if (textencoding == OptionForm.textencoding_enum.LAT1) { this.Encoder = System.Text.Encoding.GetEncoding("iso-8859-1"); } else if (textencoding == OptionForm.textencoding_enum.UTF8) { this.Encoder = System.Text.Encoding.GetEncoding("UTF-8"); } else if (textencoding == OptionForm.textencoding_enum.Shift_JIS) { this.Encoder = System.Text.Encoding.GetEncoding("Shift_JIS"); } this.TBLEncode = null; }
public static string ConvertSPMoji(ROM rom, string str) { PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); str = str.Replace("@0001", "\r\n"); if (priorityCode == PatchUtil.PRIORITY_CODE.UTF8) { return(str); } //日本語版は一部入りきらない文字を特殊フォント化しているので変換する. if (rom.RomInfo.version() >= 8) { str = str.Replace("нопр", "(サンダーストーム)"); ///No Translate str = str.Replace("⊂⊃┌┐", "(フォレストナイト)"); ///No Translate str = str.Replace("абвг", "(ドラゴンマスター)"); ///No Translate str = str.Replace("шщъы", "(ワイバーンナイト)"); ///No Translate str = str.Replace("жзий", "(ファルコンナイト)"); ///No Translate str = str.Replace("∞┴∠∧", "(モーサドゥーグ)"); ///No Translate str = str.Replace("∇∈∋├", "(デスガーゴイル)"); ///No Translate str = str.Replace("≠≡≦≧", "(ドラゴンゾンビ)"); ///No Translate str = str.Replace("∪∫∬∴", "(ゴーゴンの卵)"); ///No Translate } else if (rom.RomInfo.version() >= 7) { //FE7 str = str.Replace("⑮⑯⑰⑱⑲⑳α", "(サンダーストーム)"); ///No Translate str = str.Replace("⑧⑨⑩⑪⑫⑬⑭", "(ファルコンナイト)"); ///No Translate str = str.Replace("①②③④⑤⑥⑦", "(ドラゴンマスター)"); ///No Translate } else if (rom.RomInfo.version() >= 6) { //FE6 str = str.Replace("①②③④⑤⑥⑦", "(サンダーストーム)"); ///No Translate str = str.Replace("ⅠⅡⅢⅣⅤⅥⅦ", "(ファルコンナイト)"); ///No Translate str = str.Replace("⑪⑫⑬⑭⑮⑯⑰", "(ドラゴンマスター)"); ///No Translate } //英語版FEにはUnicodeの1バイトだけ表記があるらしい. { str = U.table_replace(str, rom.EnglishUTF8ReplaceTable); } return(str); }
//フォントで描画した場合の幅を求める. public static uint[] MeasureTextWidthOneLineInts(string str, bool IsItemFont) { uint fontlist_pointer = GetFontPointer(IsItemFont); PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); uint[] widths = new uint[str.Length]; for (int i = 0; i < str.Length; i++) { string one = str[i].ToString(); uint search_char = U.ConvertMojiCharToUnitFast(one, priorityCode); uint fontaddr = FindFontData(fontlist_pointer, search_char, priorityCode); if (fontaddr == U.NOT_FOUND) {//フォントがない. continue; } widths[i] = ReadFontDataWidthOnly(fontaddr); } return(widths); }
public void ImportFont(Form self, string FontROMTextBox, bool FontAutoGenelateCheckBox, Font ttf) { string filename = FontROMTextBox; this.YourROM = new ROM(); this.ProcessedFont = new Dictionary <string, bool>(); this.MyselfPriorityCode = PatchUtil.SearchPriorityCode(); string version; if (this.YourROM.Load(filename, out version)) {//フォントを取るようのROM this.YourPriorityCode = PatchUtil.SearchPriorityCode(this.YourROM); } else { this.YourROM = null; } if (FontAutoGenelateCheckBox) {//自動生成する this.UseAutoGenFont = ttf; } else {//自動生成しない this.UseAutoGenFont = null; } FETextDecode decode = new FETextDecode(); //少し時間がかかるので、しばらくお待ちください表示. using (InputFormRef.AutoPleaseWait pleaseWait = new InputFormRef.AutoPleaseWait(self)) { this.UndoData = Program.Undo.NewUndoData("FONT Import"); //文字列からフォントを探索 { List <U.AddrResult> list = TextForm.MakeItemList(); for (int i = 0; i < list.Count; i++) { string text = decode.Decode((uint)i); pleaseWait.DoEvents("String:" + U.To0xHexString((uint)i)); FontImporter(text); } } //メニュー1 if (Program.ROM.RomInfo.is_multibyte()) { List <U.AddrResult> menuDefineList = MenuDefinitionForm.MakeListAll(); for (int n = 0; n < menuDefineList.Count; n++) { if (!U.isSafetyOffset(menuDefineList[n].addr + 8)) { continue; } uint p = menuDefineList[n].addr + 8; if (!U.isSafetyOffset(Program.ROM.p32(p))) { continue; } List <U.AddrResult> list = MenuCommandForm.MakeListPointer(p); for (int i = 0; i < list.Count; i++) { if (!U.isSafetyOffset(list[i].addr)) { continue; } uint textid = Program.ROM.u32(list[i].addr + 0); string str = FETextDecode.Direct(textid); pleaseWait.DoEvents("Menu:" + U.To0xHexString(textid)); FontImporter(str); } } } //地形 if (Program.ROM.RomInfo.is_multibyte()) { List <U.AddrResult> list = MapTerrainNameForm.MakeList(); for (int i = 0; i < list.Count; i++) { if (!U.isSafetyOffset(list[i].addr)) { continue; } uint textid = Program.ROM.u32(list[i].addr + 0); string str = FETextDecode.Direct(textid); pleaseWait.DoEvents("Terrain:" + U.To0xHexString(textid)); FontImporter(str); } } //サウンドルーム //FE7のサウンドルームは、日本語直地 if (Program.ROM.RomInfo.is_multibyte() && Program.ROM.RomInfo.version() == 7) { List <U.AddrResult> list = SoundRoomForm.MakeList(); for (int i = 0; i < list.Count; i++) { if (!U.isSafetyOffset(list[i].addr)) { continue; } uint textid = Program.ROM.u32(list[i].addr + 12); string str = FETextDecode.Direct(textid); pleaseWait.DoEvents("SoundRoom:" + U.To0xHexString(textid)); FontImporter(str); } } //その他文字列 { List <U.AddrResult> list = OtherTextForm.MakeList(); for (int i = 0; i < list.Count; i++) { if (!U.isSafetyOffset(list[i].addr)) { continue; } uint p_str = Program.ROM.p32(list[i].addr); string str = Program.ROM.getString(p_str); pleaseWait.DoEvents("Other:" + U.To0xHexString(p_str)); FontImporter(str); } } Program.Undo.Push(this.UndoData); } }
static void MakeRepalceSPCode() { g_RepalceSPCode = new List <string>(); g_RepalceSPCode.Add("\r\n"); g_RepalceSPCode.Add("@0001"); if (Program.ROM.RomInfo.is_multibyte) { if (Program.ROM.RomInfo.version == 8) { g_RepalceSPCode.Add("(サンダーストーム)"); g_RepalceSPCode.Add("нопр"); ///No Translate g_RepalceSPCode.Add("(フォレストナイト)"); g_RepalceSPCode.Add("⊂⊃┌┐"); ///No Translate g_RepalceSPCode.Add("(ドラゴンマスター)"); g_RepalceSPCode.Add("абвг"); ///No Translate g_RepalceSPCode.Add("(ワイバーンナイト)"); g_RepalceSPCode.Add("шщъы"); ///No Translate g_RepalceSPCode.Add("(ファルコンナイト)"); g_RepalceSPCode.Add("жзий"); ///No Translate g_RepalceSPCode.Add("(モーサドゥーグ)"); g_RepalceSPCode.Add("∞┴∠∧"); ///No Translate g_RepalceSPCode.Add("(デスガーゴイル)"); g_RepalceSPCode.Add("∇∈∋├"); ///No Translate g_RepalceSPCode.Add("(ドラゴンゾンビ)"); g_RepalceSPCode.Add("≠≡≦≧"); ///No Translate g_RepalceSPCode.Add("(ゴーゴンの卵)"); g_RepalceSPCode.Add("∪∫∬∴"); ///No Translate } else if (Program.ROM.RomInfo.version == 7) { g_RepalceSPCode.Add("(サンダーストーム)"); g_RepalceSPCode.Add("⑮⑯⑰⑱⑲⑳α"); ///No Translate g_RepalceSPCode.Add("(ファルコンナイト)"); g_RepalceSPCode.Add("⑧⑨⑩⑪⑫⑬⑭"); ///No Translate g_RepalceSPCode.Add("(ドラゴンマスター)"); g_RepalceSPCode.Add("①②③④⑤⑥⑦"); ///No Translate } else if (Program.ROM.RomInfo.version == 6) { g_RepalceSPCode.Add("(サンダーストーム)"); g_RepalceSPCode.Add("①②③④⑤⑥⑦"); ///No Translate g_RepalceSPCode.Add("(ファルコンナイト)"); g_RepalceSPCode.Add("ⅠⅡⅢⅣⅤⅥⅦ"); ///No Translate g_RepalceSPCode.Add("(ドラゴンマスター)"); g_RepalceSPCode.Add("⑪⑫⑬⑭⑮⑯⑰"); ///No Translate } } else { PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); if (priorityCode != PatchUtil.PRIORITY_CODE.UTF8) { // g_RepalceSPCode.Add("\u0090"); g_RepalceSPCode.Add("@0090");///No Translate // g_RepalceSPCode.Add("\u0091"); g_RepalceSPCode.Add("@0091");///No Translate // g_RepalceSPCode.Add("\u0092"); g_RepalceSPCode.Add("@0092");///No Translate // g_RepalceSPCode.Add("\u0093"); g_RepalceSPCode.Add("@0093");///No Translate g_RepalceSPCode.Add("¡"); g_RepalceSPCode.Add("@00A1"); ///No Translate g_RepalceSPCode.Add("ª"); g_RepalceSPCode.Add("@00AA"); ///No Translate g_RepalceSPCode.Add("«"); g_RepalceSPCode.Add("@00AB"); ///No Translate g_RepalceSPCode.Add("»"); g_RepalceSPCode.Add("@00BB"); ///No Translate g_RepalceSPCode.Add("¿"); g_RepalceSPCode.Add("@00BF"); ///No Translate g_RepalceSPCode.Add("À"); g_RepalceSPCode.Add("@00C0"); ///No Translate g_RepalceSPCode.Add("Á"); g_RepalceSPCode.Add("@00C1"); ///No Translate g_RepalceSPCode.Add("Â"); g_RepalceSPCode.Add("@00C2"); ///No Translate g_RepalceSPCode.Add("Ä"); g_RepalceSPCode.Add("@00C4"); ///No Translate g_RepalceSPCode.Add("Ç"); g_RepalceSPCode.Add("@00C7"); ///No Translate g_RepalceSPCode.Add("È"); g_RepalceSPCode.Add("@00C8"); ///No Translate g_RepalceSPCode.Add("É"); g_RepalceSPCode.Add("@00C9"); ///No Translate g_RepalceSPCode.Add("Ê"); g_RepalceSPCode.Add("@00CA"); ///No Translate g_RepalceSPCode.Add("Ë"); g_RepalceSPCode.Add("@00CB"); ///No Translate g_RepalceSPCode.Add("Ì"); g_RepalceSPCode.Add("@00CC"); ///No Translate g_RepalceSPCode.Add("Í"); g_RepalceSPCode.Add("@00CD"); ///No Translate g_RepalceSPCode.Add("Î"); g_RepalceSPCode.Add("@00CE"); ///No Translate g_RepalceSPCode.Add("Ï"); g_RepalceSPCode.Add("@00CF"); ///No Translate g_RepalceSPCode.Add("Ñ"); g_RepalceSPCode.Add("@00D1"); ///No Translate g_RepalceSPCode.Add("Ò"); g_RepalceSPCode.Add("@00D2"); ///No Translate g_RepalceSPCode.Add("Ó"); g_RepalceSPCode.Add("@00D3"); ///No Translate g_RepalceSPCode.Add("Ô"); g_RepalceSPCode.Add("@00D4"); ///No Translate g_RepalceSPCode.Add("Ö"); g_RepalceSPCode.Add("@00D6"); ///No Translate g_RepalceSPCode.Add("Ù"); g_RepalceSPCode.Add("@00D9"); ///No Translate g_RepalceSPCode.Add("Ú"); g_RepalceSPCode.Add("@00DA"); ///No Translate g_RepalceSPCode.Add("Û"); g_RepalceSPCode.Add("@00DB"); ///No Translate g_RepalceSPCode.Add("Ü"); g_RepalceSPCode.Add("@00DC"); ///No Translate g_RepalceSPCode.Add("ß"); g_RepalceSPCode.Add("@00DF"); ///No Translate g_RepalceSPCode.Add("à"); g_RepalceSPCode.Add("@00E0"); ///No Translate g_RepalceSPCode.Add("á"); g_RepalceSPCode.Add("@00E1"); ///No Translate g_RepalceSPCode.Add("â"); g_RepalceSPCode.Add("@00E2"); ///No Translate g_RepalceSPCode.Add("ä"); g_RepalceSPCode.Add("@00E4"); ///No Translate g_RepalceSPCode.Add("ç"); g_RepalceSPCode.Add("@00E7"); ///No Translate g_RepalceSPCode.Add("è"); g_RepalceSPCode.Add("@00E8"); ///No Translate g_RepalceSPCode.Add("é"); g_RepalceSPCode.Add("@00E9"); ///No Translate g_RepalceSPCode.Add("ê"); g_RepalceSPCode.Add("@00EA"); ///No Translate g_RepalceSPCode.Add("ë"); g_RepalceSPCode.Add("@00EB"); ///No Translate g_RepalceSPCode.Add("ì"); g_RepalceSPCode.Add("@00EC"); ///No Translate g_RepalceSPCode.Add("í"); g_RepalceSPCode.Add("@00ED"); ///No Translate g_RepalceSPCode.Add("î"); g_RepalceSPCode.Add("@00EE"); ///No Translate g_RepalceSPCode.Add("ï"); g_RepalceSPCode.Add("@00EF"); ///No Translate g_RepalceSPCode.Add("ñ"); g_RepalceSPCode.Add("@00F1"); ///No Translate g_RepalceSPCode.Add("ò"); g_RepalceSPCode.Add("@00F2"); ///No Translate g_RepalceSPCode.Add("ó"); g_RepalceSPCode.Add("@00F3"); ///No Translate g_RepalceSPCode.Add("ô"); g_RepalceSPCode.Add("@00F4"); ///No Translate g_RepalceSPCode.Add("ö"); g_RepalceSPCode.Add("@00F6"); ///No Translate g_RepalceSPCode.Add("ù"); g_RepalceSPCode.Add("@00F9"); ///No Translate g_RepalceSPCode.Add("ú"); g_RepalceSPCode.Add("@00FA"); ///No Translate g_RepalceSPCode.Add("û"); g_RepalceSPCode.Add("@00FB"); ///No Translate g_RepalceSPCode.Add("ü"); g_RepalceSPCode.Add("@00FC"); ///No Translate } } }
byte[] convert_unHuffman_code_to_binary(byte[] sjisstr) { PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); PatchUtil.TextEngineRework_enum textEngineRework = PatchUtil.SearchTextEngineReworkPatch(); List <byte> ret = new List <byte>(); for (int i = 0; i < sjisstr.Length;) { if (sjisstr[i] == '@') { uint code1 = at_code_to_binary(sjisstr, i, out i); //unHuffman patchでは可変長デコードらしい. //@0009 -> 0x09 //@0080@000d -> 0x80 0x0d //@0010@0102 -> 0x10 0x02 0x01 または、0x10 0x02 0x01 0xFF(昔のルーチン?) // //0x10だけ別処理が必要. //0x10の後、+2バイト後に 終端0xFFがあることがある. if (code1 == 0x80) { uint code2 = 0x1C; if (i < sjisstr.Length && sjisstr[i] == '@') { code2 = at_code_to_binary(sjisstr, i, out i); } else { //一番無害な、 0x1C 目を開ける で補正しよう Log.Error("@0080の後に、@命令が続いていません。@001Cで補正します。"); } ret.Add((byte)(code1)); //@0080 ret.Add((byte)(code2)); //@0000 if (textEngineRework == PatchUtil.TextEngineRework_enum.TeqTextEngineRework) { i += TeqTextEngineRework(ret, code2, sjisstr, i); } } else if (code1 == 0x10) { uint code2 = 0x0101; if (i < sjisstr.Length && sjisstr[i] == '@') { code2 = at_code_to_binary(sjisstr, i, out i); if (code2 < 0x100) {//@0010 の次のコードが 0x0003 みたいに 0x100以下 R.Debug("@0010の次のコードが 0x100以下です。危険なので、+0x100補正します。 code2:{0}", code2); code2 += 0x100; } } else { //一番 無害な 0x0101で補正. R.Debug("@0010の後に、@命令が続いていません。@0010@0101@0001で補正します。"); } uint code3 = 0x0; if (i < sjisstr.Length && sjisstr[i] == '@') { code3 = at_code_to_binary(sjisstr, i, out i); } else {//@0010@0101??? R.Debug("@0010命令が途中で終わってしまいました。"); } ret.Add((byte)(code1)); //@0010 ret.Add((byte)(code2 & 0xFF)); //@0000 //@0102 みたいなのは、リトルエンディアン化する必要がある ret.Add((byte)((code2 >> 8) & 0xFF)); //@0000 if (code3 > 0) { ret.Add((byte)(code3)); //@0010終端に謎のコード 大昔は 0xFFでも入れていたのかなあ・・・? } } else {//@0080 と @0010 以外は1バイトで格納 ret.Add((byte)(code1 & 0xFF)); } continue; } if (i + 1 >= sjisstr.Length) {//もう余白がないので1バイト文字列 ret.Add(sjisstr[i]); i++; } else { byte code1 = sjisstr[i]; byte code2 = sjisstr[i + 1]; if (priorityCode == PatchUtil.PRIORITY_CODE.UTF8 && code1 >= 0xC0 && code1 >= 0x80) { i += U.AppendUTF8(ret, sjisstr, i); } else if (priorityCode == PatchUtil.PRIORITY_CODE.SJIS && U.isSJIS1stCode(code1) && U.isSJIS2ndCode(code2)) { ret.Add(sjisstr[i]); i++; ret.Add(sjisstr[i]); i++; } else {//1バイト ret.Add(sjisstr[i]); i++; } } } //0終端 ret.Add(0); ret.Add(0); //終端が2つないとダメ?らしい. return(ret.ToArray()); }
StringBuilder ExportALL(InputFormRef.AutoPleaseWait pleaseWait, string basedir, bool isItemFont, bool isUserFontOnly, Dictionary <uint, string> codeBMap) { List <Address> list = new List <Address>(); MakeAllDataLengthInner(isItemFont, ref list, codeBMap); PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); Color bgcolor = GetFontColor(isItemFont); StringBuilder sb = new StringBuilder(); foreach (Address a in list) { if (a.DataType != FEBuilderGBA.Address.DataTypeEnum.FONTCN) { continue; } if (isUserFontOnly && a.Addr <= Program.ROM.RomInfo.font_default_end) {//規定のフォント continue; } int width; byte[] fontbyte = ReadFontDataZH(a.Addr, out width); if (width == 0) { continue; } string ch = GetFontCharFromExportName(a.Info); if (ch == "") { continue; } uint hex = U.ConvertMojiCharToUnitFast(ch, priorityCode); string type = (isItemFont ? "item" : "text"); Bitmap bitmap; if (isItemFont) { bitmap = ImageUtil.ByteToImage4ZH(width + 1, 0xD, fontbyte, 0, bgcolor); bitmap = ConvertVanillaFontSizeBitmap(bitmap, 2); } else { bitmap = ImageUtil.ByteToImage4ZH(width, 0xD, fontbyte, 0, bgcolor); bitmap = ConvertVanillaFontSizeBitmap(bitmap, 1); } ImageUtil.BlackOutUnnecessaryColors(bitmap, 1); string name = U.escape_filename(a.Info) + "_" + U.ToHexString(hex); string font_filename = Path.Combine(basedir, name + ".png"); try { U.BitmapSave(bitmap, font_filename); } catch (Exception) {//このOSではこの文字のファイル名は使えないので削ります string trimName = U.substr(a.Info, 0, a.Info.Length - 2); name = trimName + "_" + U.ToHexString(hex); font_filename = Path.Combine(basedir, name + ".png"); U.BitmapSave(bitmap, font_filename); } bitmap.Dispose(); sb.Append(ch); sb.Append("\t"); sb.Append(type); sb.Append("\t"); sb.Append(width); sb.Append("\t"); sb.AppendLine(Path.GetFileName(font_filename)); } return(sb); }
static void MakeAllDataLengthInner(bool isItemFont, ref List <Address> list) { string name = isItemFont ? "FontItem" : "FontText"; uint topaddress = GetFontPointer(isItemFont); PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); if (Program.ROM.RomInfo.is_multibyte()) {//日本語版 FEBuilderGBA.Address.AddAddress(list, topaddress , 4 * (0xff - 0x1f) , U.NOT_FOUND , name , FEBuilderGBA.Address.DataTypeEnum.POINTER); for (uint moji1 = 0x1f; moji1 <= 0xff; moji1++) { //リストの元になるポインタへ移動. uint fontlist = topaddress + (moji1 << 2) - 0x100; if (!U.isSafetyOffset(fontlist)) { continue; } uint p = Program.ROM.p32(fontlist); if (!U.isSafetyOffset(p)) { continue; } uint before_pointer = fontlist; //同一ハッシュキーがあるため、リストをたどりながら目的のフォントを探します. //struct{ // void* next; // byte moji2 // byte width // byte nazo1 // byte nazo2 //} //sizeof()==8 //+64byte bitmap(4pp) while (p > 0) { uint moji2 = Program.ROM.u8(p + 4); FEBuilderGBA.Address.AddAddress(list , p, 8 + 64 , before_pointer , name + FontChar(moji2, moji1, priorityCode) , FEBuilderGBA.Address.DataTypeEnum.FONT); uint next = Program.ROM.p32(p); if (next == 0) {//リスト終端. break; } if (!U.isSafetyOffset(next)) {//リストが壊れている. break; } before_pointer = p; //次のリストへ進む. p = next; } } } else {//英語版 FEBuilderGBA.Address.AddAddress(list, topaddress , 4 * (0xff) , U.NOT_FOUND , name , FEBuilderGBA.Address.DataTypeEnum.POINTER); for (uint moji2 = 0x0; moji2 <= 0xff; moji2++) { uint fontlist = topaddress + (moji2 << 2); if (!U.isSafetyOffset(fontlist)) { continue; } uint p = Program.ROM.p32(fontlist); if (!U.isSafetyOffset(p)) { continue; } uint before_pointer = fontlist; //同一ハッシュキーがあるため、リストをたどりながら目的のフォントを探します. //struct{ // void* next; // byte moji2 // byte width // byte nazo1 // byte nazo2 //} //sizeof()==8 //+64byte bitmap(4pp) while (p > 0) { FEBuilderGBA.Address.AddAddress(list, p , 8 + 64 , before_pointer , name + FontChar(0, moji2, priorityCode) , FEBuilderGBA.Address.DataTypeEnum.FONT); uint next = Program.ROM.p32(p); if (next == 0) {//リスト終端. break; } if (!U.isSafetyOffset(next)) {//リストが壊れている. break; } before_pointer = p; //次のリストへ進む. p = next; } } } }
public ToolTranslateROMWipeJPFont(Undo.UndoData undoData) { this.UndoData = undoData; this.PriorityCode = PatchUtil.SearchPriorityCode(); }