public static RecycleAddress MakeRecycleSongAndInst(uint songtable_address) { //今回の楽曲リサイクル List <FEBuilderGBA.Address> recycle = new List <FEBuilderGBA.Address>(); MakeAllDataLength_Song_And_Inst(recycle, 0, songtable_address); //ポインタを共有しているといけないので調べる List <FEBuilderGBA.Address> list = new List <FEBuilderGBA.Address>(); InputFormRef InputFormRef = Init(null); uint songpointer = InputFormRef.BaseAddress; for (int i = 0; i < InputFormRef.DataCount; i++, songpointer += InputFormRef.BlockSize) { if (songtable_address == songpointer) {//自分自身 continue; } MakeAllDataLength_Song_And_Inst(list, i, songpointer); } RecycleAddress ra = new RecycleAddress(recycle); ra.SubRecycle(list); return(ra); }
//変更するアニメデータから、他のアニメーションでも使っているものを除外する public static void MakeAllDataLength(RecycleAddress ra, uint Now_baseaddress) { InputFormRef N_InputFormRef = N_Init(null); //戦闘アニメーションはlz77圧縮の中にポインタがある特殊形式です uint addr = N_InputFormRef.BaseAddress; for (int i = 0; i < N_InputFormRef.DataCount; i++, addr += N_InputFormRef.BlockSize) { if (!U.isSafetyOffset(12 + addr + 4)) { break; } uint section = Program.ROM.p32(12 + addr); if (!U.isSafetyOffset(section)) { break; } if (addr == Now_baseaddress) { continue; } List <Address> list = new List <Address>(); ImageUtilOAM.RecycleOldAnime(ref list, addr); ra.SubRecycle(list); } }
void WriteText(uint id, string text, RecycleAddress ra, Undo.UndoData undodata) { //無効なID if (id <= 0) { return; } //最後の改行の削除. if (text.Length < 2) { return; } string writetext = U.substr(text, 0, text.Length - 2); writetext = TextForm.ConvertFEditorToEscape(writetext); if (id < this.MaxTextCount) { WriteTextUnHffman(id, writetext, ra, undodata); } else if (U.isSafetyPointer(id)) { WriteCString(id, writetext, ra, undodata); } else { Log.Error("不明な文字列", id.ToString(), writetext); return; } }
public void WriteBackFont(RecycleAddress ra) { foreach (KeepFont kf in KeepFontList) { WriteBackFontKF(kf, ra); } }
//変更するアニメデータから、他のアニメーションでも使っているものを除外する public static void SubConfilctArea(RecycleAddress ra, uint Now_baseaddress) { InputFormRef InputFormRef; uint baseaddr, dimaddr, no_dimaddr; if (ImageUtilMagic.SearchMagicSystem(out baseaddr, out dimaddr, out no_dimaddr) != ImageUtilMagic.magic_system_enum.FEDITOR_ADV) { return; } { uint spellDataCount = ImageUtilMagicFEditor.SpellDataCount(); uint csaSpellTable = ImageUtilMagic.GetCSASpellTableAddr(); if (csaSpellTable == U.NOT_FOUND) { return; } Dictionary <uint, string> effectDic = new Dictionary <uint, string>(); InputFormRef = Init(null, dimaddr, no_dimaddr, spellDataCount, csaSpellTable, effectDic); uint addr = InputFormRef.BaseAddress; for (int i = 0; i < InputFormRef.DataCount; i++, addr += InputFormRef.BlockSize) { uint baseaddress = Program.ROM.p32(Program.ROM.RomInfo.magic_effect_pointer); uint csaaddress = (uint)(csaSpellTable + (20 * i)); uint dataaddr = Program.ROM.p32(addr); if (dataaddr == 0) { continue; } if (csaaddress == Now_baseaddress) { continue; } if ( dataaddr == dimaddr || dataaddr == no_dimaddr) { List <Address> list = new List <Address>(); ImageUtilMagicFEditor.RecycleOldAnime(ref list, "", false, csaaddress); ra.SubRecycle(list); } } } }
void WriteBackFontKF(KeepFont kf, RecycleAddress ra) { uint topaddress = FontForm.GetFontPointer(kf.IsItemFont); uint prevaddr; uint fontaddr = FontForm.FindFontData(topaddress, kf.MojiCode, out prevaddr, this.PriorityCode); if (fontaddr != U.NOT_FOUND) {//知ってるらしい return; } if (prevaddr == U.NOT_FOUND) {//追加不可能 return; } byte[] newFontData = FontForm.MakeNewFontData(kf.MojiCode , kf.Width , kf.Data , Program.ROM , this.PriorityCode); U.write_u32(newFontData, 0, 0); //NULL リストの末尾に追加するので. uint newaddr = ra.Write(newFontData, this.UndoData); if (newaddr == U.NOT_FOUND) {//エラー return; } //ひとつ前のフォントリストのポインタを、現在追加した最後尾にすげかえる. Program.ROM.write_u32(prevaddr + 0, U.toPointer(newaddr), this.UndoData); if (kf.rewitePointer != U.NOT_FOUND) { Program.ROM.write_u32(kf.rewitePointer, U.toPointer(newaddr), this.UndoData); } }
void WriteCString(uint pointer, string text, RecycleAddress ra, Undo.UndoData undodata) { Debug.Assert(U.isSafetyPointer(pointer)); uint p_text_pointer = U.toOffset(pointer); uint text_pointer = Program.ROM.u32(p_text_pointer); if (!U.isSafetyPointer(text_pointer)) { Log.Error("ポインタではありません", U.To0xHexString(pointer), text); return; } byte[] stringbyte = Program.SystemTextEncoder.Encode(text); stringbyte = U.ArrayAppend(stringbyte, new byte[] { 0x00 }); string undoname = "CString:" + U.ToHexString(pointer); uint newaddr = ra.Write(stringbyte, undodata); if (newaddr == U.NOT_FOUND) { return; } Program.ROM.write_p32(p_text_pointer, newaddr, undodata); }
void WriteTextUnHffman(uint id, string text, RecycleAddress ra, Undo.UndoData undodata) { uint addr = this.TextBaseAddress + (id * 4); uint paddr = Program.ROM.u32(addr); if (TextForm.Is_RAMPointerArea(paddr)) {//iw-ram / ew-ram にデータをおいている人がいるらしい return; } byte[] encode; Program.FETextEncoder.UnHuffmanEncode(text, out encode); string undoname = "Text:" + U.ToHexString(id); uint newaddr = ra.Write(encode, undodata); if (newaddr == U.NOT_FOUND) { return; } newaddr = U.toPointer(newaddr); newaddr = FETextEncode.ConvertPointerToUnHuffmanPatchPointer(newaddr); Program.ROM.write_u32(addr, newaddr, undodata); }
public static string Import(string filename, uint anime_pointer) { string basename = Path.GetFileNameWithoutExtension(filename) + "_"; string basedir = Path.GetDirectoryName(filename); //同じアニメを何度も入力しないように記録する. List <anime> anime_list = new List <anime>(); List <byte> frames = new List <byte>(); string[] lines = File.ReadAllLines(filename); uint sound_id = 0x3d1; AnimeType animeType = AnimeType.None; for (uint lineCount = 0; lineCount < lines.Length; lineCount++) { string line = lines[lineCount]; if (U.IsComment(line) || U.OtherLangLine(line)) { continue; } line = U.ClipComment(line); if (line.Length <= 0) { continue; } InputFormRef.DoEvents(null, "Line:" + lineCount); line = line.Replace("\t", " "); string[] sp = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); string command = sp[0]; if (command.Length <= 0) { continue; } if (command[0] == 'S') { sound_id = U.atoh(command.Substring(1)); continue; } if (command[0] == 'D') { animeType = AnimeType.D; continue; } if (!(U.isNumString(command) && sp.Length >= 2)) { continue; } if (sp.Length <= 1) { Debug.Assert(false); continue; } uint wait = U.atoi(command); string image = sp[1]; uint id = FindImage(anime_list, image); if (id == U.NOT_FOUND) { id = (uint)anime_list.Count; string fullfilename = Path.Combine(basedir, image); Bitmap bitmap = ImageUtil.OpenBitmap(fullfilename); if (bitmap == null) { return(R.Error("ファイル名が見つかりませんでした。\r\nFile: {0} line:{1}\r\n\r\nエラー内容:\r\n{2}", filename, lineCount, line)); } if (bitmap.Width != SCREEN_WIDTH || bitmap.Height != SCREEN_HEIGHT) { bitmap = ImageUtil.Copy(bitmap, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); } anime a = new anime(); string error = ImageUtil.ImageToBytePackedTSA(bitmap, SCREEN_WIDTH, SCREEN_HEIGHT, 0, out a.image, out a.tsa); if (error != "") { return(R.Error("画像をインポートできません。\r\nFile: {0} line:{1}\r\n\r\nエラー内容:\r\n{2}", filename, lineCount, error)); } a.image = LZ77.compress(a.image); a.tsa = LZ77.compress(a.tsa); a.pal = ImageUtil.ImageToPalette(bitmap, 1); a.filename = image; anime_list.Add(a); } U.append_u16(frames, id); U.append_u16(frames, wait); } //term U.append_u16(frames, 0xFFFF); U.append_u16(frames, 0xFFFF); anime_pointer = U.toOffset(anime_pointer); if (!U.isSafetyOffset(anime_pointer)) { return(R._("アドレスが無効です")); } uint anime_address = Program.ROM.p32(anime_pointer); List <Address> recycle = new List <Address>(); RecycleOldAnime(ref recycle, basename, false, anime_address); RecycleAddress ra = new RecycleAddress(recycle); Undo.UndoData undodata = Program.Undo.NewUndoData("ImageUtilSkillSystemsAnimeCreator.Import"); List <byte> image_list = new List <byte>(); List <byte> tsa_list = new List <byte>(); List <byte> pal_list = new List <byte>(); for (int i = 0; i < anime_list.Count; i++) { uint p; p = ra.Write(anime_list[i].image, undodata); U.append_u32(image_list, U.toPointer(p)); p = ra.Write(anime_list[i].tsa, undodata); U.append_u32(tsa_list, U.toPointer(p)); p = ra.Write(anime_list[i].pal, undodata); U.append_u32(pal_list, U.toPointer(p)); } List <byte> mainData = new List <byte>(); if (Program.ROM.RomInfo.is_multibyte()) {//FE8J //FE8Jには、スキルごとにプログラムは存在しない. } else {//FE8U //信じられないが、スキルアニメ毎にプログラムコードが設定される. if (animeType == AnimeType.D) { string prog = Path.Combine(Program.BaseDirectory, "config", "patch2", "FE8U", "skill", "skillanimtemplate_defender_2017_01_24.dmp"); mainData.AddRange(File.ReadAllBytes(prog)); } else { string prog = Path.Combine(Program.BaseDirectory, "config", "patch2", "FE8U", "skill", "skillanimtemplate_2016_11_04.dmp"); mainData.AddRange(File.ReadAllBytes(prog)); } } //プログラムの下にデータがある. { uint p; p = ra.Write(frames.ToArray(), undodata); U.append_u32(mainData, U.toPointer(p)); p = ra.Write(tsa_list.ToArray(), undodata); U.append_u32(mainData, U.toPointer(p)); p = ra.Write(image_list.ToArray(), undodata); U.append_u32(mainData, U.toPointer(p)); p = ra.Write(pal_list.ToArray(), undodata); U.append_u32(mainData, U.toPointer(p)); U.append_u32(mainData, sound_id); } //アニメポインタの書き換え. ra.WriteAndWritePointer(anime_pointer, mainData.ToArray(), undodata); Program.Undo.Push(undodata); return(""); }
public static string Import( string filename //読み込むファイル名 , uint magic_baseaddress //魔法アニメの書き換えるアドレス ) { string basename = Path.GetFileNameWithoutExtension(filename) + "_"; string basedir = Path.GetDirectoryName(filename); List <byte> frameData = new List <byte>(); List <ImageUtilOAM.image_data> bgImagesData = new List <ImageUtilOAM.image_data>(); //変換したアニメの記録 Dictionary <string, ImageUtilOAM.animedata> animeDic = new Dictionary <string, ImageUtilOAM.animedata>(); int lineCount = 0; string[] lines = File.ReadAllLines(filename); uint image_bg_number = 0; uint image_obj_number = 0; ImageUtilOAM.ImportOAM oam = new ImageUtilOAM.ImportOAM(); oam.SetBaseDir(Path.GetDirectoryName(filename)); oam.SetIsMagicOAM(true); BGScaleMode bgScaleMode = BGScaleMode.NO; while (lineCount < lines.Length) { string line = lines[lineCount]; if (U.IsComment(line) || U.OtherLangLine(line)) { lineCount++; continue; } line = U.ClipComment(line); if (line == "") { lineCount++; continue; } InputFormRef.DoEvents(null, "Line:" + lineCount); if (line[0] == '~') { U.append_u32(frameData, 0x80000100); lineCount++; continue; } if (line[0] == 'C') {//85コマンド uint command = U.atoh(line.Substring(1)); if ((command & 0xFF) == 0x53) {//スクリプト側で自動拡大命令を入れている場合 ツールは何もしてはいけないので記録する. bgScaleMode = BGScaleMode.SCRIPT_SCALE_MODE; } uint a = (command & 0x00FFFFFF) | 0x85000000; U.append_u32(frameData, a); lineCount++; continue; } if (line[0] == 'S') {//音楽再生 uint music = U.atoh(line.Substring(1)); uint a = ((music & 0xFFFF) << 8) | 0x85000048; U.append_u32(frameData, a); lineCount++; continue; } if (line[0] != 'O' && line[0] != 'B') { //不明な命令なので無視する. lineCount++; continue; } //O objblank.png //B bg3.png //1 ImageUtilOAM.animedata objAnimeData = null; ImageUtilOAM.animedata bgAnimeData = null; uint frameSec = U.NOT_FOUND; for (int n = 1; n <= 3;) { line = lines[lineCount]; if (U.IsComment(line) || U.OtherLangLine(line)) { lineCount++; continue; } line = U.ClipComment(line); if (line == "") { lineCount++; continue; } if (U.isnum(line[0])) { if (frameSec != U.NOT_FOUND) { return(R.Error("時間指定が連続しています。\r\nO filename\r\nB filename\r\ntime\r\n\r\nFile:{0} Line:{1}\r\n", filename, lineCount + 1)); } frameSec = U.atoi(line); lineCount++; n++; continue; } string imagefilename = ImageUtilOAM.parsePFilename(line); if (imagefilename.Length <= 0) { return(R.Error("ファイル名が見つかりませんでした。\r\nFile: {0} line:{1}\r\n\r\nエラー内容:\r\n{2}", filename, lineCount, oam.ErrorMessage)); } if (line[0] == 'O') { if (objAnimeData != null) { return(R.Error("OBJ指定が連続しています。\r\nO filename\r\nB filename\r\ntime\r\n\r\nFile:{0} Line:{1}\r\n", filename, lineCount + 1)); } string errormessage; objAnimeData = ImportObjImageToData(imagefilename , basedir , animeDic , oam , ref image_obj_number , out errormessage ); if (objAnimeData == null) { return(R.Error("OBJ画像をロードできません。 \r\n{2}\r\nFile:{0} Line:{1}", filename, lineCount + 1, errormessage)); } lineCount++; n++; continue; } if (line[0] == 'B') { if (bgAnimeData != null) { return(R.Error("BG指定が連続しています。\r\nO filename\r\nB filename\r\ntime\r\n\r\nFile:{0} Line:{1}\r\n", filename, lineCount + 1)); } string errormessage; bgAnimeData = ImportBGImageToData(imagefilename , basedir , animeDic , bgImagesData , out errormessage ); if (bgAnimeData == null) { return(R.Error("BG画像をロードできません。 \r\n{2}\r\nFile:{0} Line:{1}", filename, lineCount + 1, errormessage)); } lineCount++; n++; continue; } } if (objAnimeData == null) { return(R.Error("OBJ画像がありません。 \r\nO filename\r\nB filename\r\ntime\r\n\r\nみたいに、セットで登録する必要があります。\r\nFile:{0} Line:{1}", filename, lineCount + 1)); } if (bgAnimeData == null) { return(R.Error(("IMAGE_POINTER or ZIMAGE_POINTER の指定が必要です。BG画像がありません。 \r\nO filename\r\nB filename\r\n"), filename, lineCount + 1)); } if (frameSec == U.NOT_FOUND) { return(R.Error("時間指定がありません。 \r\nO filename\r\nB filename\r\ntime\r\n\r\nみたいに、セットで登録する必要があります。\r\nFile:{0} Line:{1}", filename, lineCount + 1)); } //BGがFEditorの小さい形式だった場合、自動的に拡大命令を追加する. if (bgAnimeData.height == 64) { if (bgScaleMode == BGScaleMode.NO) {//拡大命令を付与. uint a = (0x00000153) | 0x85000000; U.append_u32(frameData, a); bgScaleMode = BGScaleMode.AUTO_SCALE_MODE; } } //0x86コマンド { uint a = (frameSec & 0xFFFF) | ((image_bg_number & 0xFF) << 16) | 0x86000000; U.append_u32(frameData, a); //+0 U.append_u32(frameData, objAnimeData.image_pointer); //+4 U.append_u32(frameData, objAnimeData.oam_pos); //+8 OBJ OAM U.append_u32(frameData, objAnimeData.oam2_pos); //+12 OBJ BG OAM U.append_u32(frameData, bgAnimeData.image_pointer); //+16 U.append_u32(frameData, objAnimeData.palette_pointer); //+20 U.append_u32(frameData, bgAnimeData.palette_pointer); //+24 U.append_u32(frameData, bgAnimeData.tsa_pointer); //+28 TSA image_bg_number++; } } InputFormRef.DoEvents(null, "Term"); if (bgScaleMode == BGScaleMode.AUTO_SCALE_MODE) {//拡大命令を自動付与していた場合、解除する. 解除しないと経験値バーが表示されない. uint a = (0x00000053) | 0x85000000; U.append_u32(frameData, a); } //終端. U.append_u32(frameData, 0x80000000); //登録完了処理 oam.Term(); Undo.UndoData undodata = Program.Undo.NewUndoData("import ", Path.GetFileName(filename)); //上書きされるアニメデータ領域を使いまわす List <Address> recycle = new List <Address>(); RecycleOldAnime(ref recycle, "", false, magic_baseaddress); RecycleAddress ra = new RecycleAddress(recycle); //書き込みます.(魔法アニメはなぜか無圧縮) ra.WriteAndWritePointer(magic_baseaddress + 4, oam.GetRightToLeftOAM(), undodata); ra.WriteAndWritePointer(magic_baseaddress + 8, oam.GetLeftToRightOAM(), undodata); //BG用にダミーのOAMを作成 //byte[] dummyOAM = ImageUtilMagicFEditor.MakeDummyOAM(image_bg_number); ra.WriteAndWritePointer(magic_baseaddress + 12, oam.GetRightToLeftOAMBG(), undodata); ra.WriteAndWritePointer(magic_baseaddress + 16, oam.GetLeftToRightOAMBG(), undodata); //BG for (int i = 0; i < bgImagesData.Count; i++) { bgImagesData[i].write_addr = ra.Write(bgImagesData[i].data, undodata); } //OBJ List <ImageUtilOAM.image_data> objImages = oam.GetImages(); for (int i = 0; i < objImages.Count; i++) { objImages[i].write_addr = ra.Write(objImages[i].data, undodata); } //画像の書き込みアドレスが決定したら、画像ポインタをかかないといけないFrameDataを更新します。 byte[] frameDataUZ = frameData.ToArray(); string errorFrame = updateFrameDataAddress(frameDataUZ, bgImagesData, objImages); if (errorFrame != "") { return(R.Error("OAMフレーム更新中にエラーが発生しました。\r\nこのエラーが頻繁に出る場合は、アニメデータと一緒にreport7zを送ってください。") + "\r\n" + errorFrame); } ra.WriteAndWritePointer(magic_baseaddress + 0, frameDataUZ, undodata); //端数の再利用的ない古いデータは0x00クリア. ra.BlackOut(undodata); Program.Undo.Push(undodata); return(""); }
string Import( string filename //読込むファイル名 ) { string basename = Path.GetFileNameWithoutExtension(filename) + "_"; string basedir = Path.GetDirectoryName(filename); //同じアニメを何度も入力しないように記録する. List <anime> anime_list = new List <anime>(); int imageWidth = this.ImageWidth * 8; int imageHeight = 8 * 16; List <byte> frames = new List <byte>(); string[] lines = File.ReadAllLines(filename); for (uint lineCount = 0; lineCount < lines.Length; lineCount++) { string line = lines[lineCount++]; if (U.IsComment(line) || U.OtherLangLine(line)) { continue; } line = U.ClipComment(line); if (line.Length <= 0) { continue; } InputFormRef.DoEvents(null, "Line:" + lineCount); line = line.Replace("\t", " "); string[] sp = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); string command = sp[0]; if (command.Length <= 0) { continue; } if (!(U.isNumString(command) && sp.Length >= 2)) { continue; } uint wait = U.atoi(command); string image = sp[1]; uint id = FindImage(anime_list, image); if (id == U.NOT_FOUND) { id = (uint)anime_list.Count; string fullfilename = Path.Combine(basedir, image); Bitmap bitmap = ImageUtil.OpenBitmap(fullfilename); if (bitmap == null) { return(R.Error("ファイル名が見つかりませんでした。\r\nFile: {0} line:{1}\r\n\r\nエラー内容:\r\n{2}", filename, lineCount, line)); } if (bitmap.Width != imageWidth || bitmap.Height != imageHeight) { bitmap = ImageUtil.Copy(bitmap, 0, 0, imageWidth, imageHeight); } anime a = new anime(); string error = ImageUtil.ImageToBytePackedTSA(bitmap, imageWidth, imageHeight, 0, out a.image, out a.tsa); if (error != "") { return(R.Error("画像をインポートできません。\r\nFile: {0} line:{1}\r\n\r\nエラー内容:\r\n{2}", filename, lineCount, error)); } a.image = LZ77.compress(a.image); a.tsa = LZ77.compress(a.tsa); a.pal = ImageUtil.ImageToPalette(bitmap, 1); a.filename = image; anime_list.Add(a); } U.append_u16(frames, id); U.append_u16(frames, wait); } //term U.append_u16(frames, 0xFFFF); U.append_u16(frames, 0x0); if (anime_list.Count <= 0) { return(R._("書き込むアニメーションがありません")); } Undo.UndoData undodata = Program.Undo.NewUndoData(""); List <Address> recycle = new List <FEBuilderGBA.Address>(); MakeRecycleList(ref recycle, "", false); RecycleAddress ra = new RecycleAddress(recycle); uint p; if (!U.isSafetyOffset(this.FramePointer)) {//固定フレームのアニメ if (this.FramePointer != anime_list.Count) { return(R._("このアニメーションは固定アニメーションです。フレームが{0}個必要です。指定されたアニメには{1}のフレームがあり、数が一致していません。", this.FramePointer, anime_list.Count)); } if (this.TSAList.Count == 1 && this.PaletteList.Count >= 2) {//パレットアニメ List <byte> pal_list = new List <byte>(); for (int i = 0; i < anime_list.Count; i++) { p = ra.Write(anime_list[i].pal, undodata); U.append_u32(pal_list, U.toPointer(p)); } ra.WriteAndWritePointer(this.TSAPointer, anime_list[0].tsa, undodata); ra.WriteAndWritePointer(this.ImagePointer, anime_list[0].image, undodata); ra.WriteAndWritePointer(this.PalettePointer, pal_list.ToArray(), undodata); } else { List <byte> image_list = new List <byte>(); List <byte> tsa_list = new List <byte>(); List <byte> pal_list = new List <byte>(); for (int i = 0; i < anime_list.Count; i++) { p = ra.Write(anime_list[i].image, undodata); U.append_u32(image_list, U.toPointer(p)); p = ra.Write(anime_list[i].tsa, undodata); U.append_u32(tsa_list, U.toPointer(p)); p = ra.Write(anime_list[i].pal, undodata); U.append_u32(pal_list, U.toPointer(p)); } ra.WriteAndWritePointer(this.TSAPointer, tsa_list.ToArray(), undodata); ra.WriteAndWritePointer(this.ImagePointer, image_list.ToArray(), undodata); ra.WriteAndWritePointer(this.PalettePointer, pal_list.ToArray(), undodata); } } else { //フレームを利用するアニメ if (this.TSAList.Count >= 2 && this.PaletteList.Count == 1) { //共通パレット List <byte> image_list = new List <byte>(); List <byte> tsa_list = new List <byte>(); for (int i = 0; i < anime_list.Count; i++) { p = ra.Write(anime_list[i].image, undodata); U.append_u32(image_list, U.toPointer(p)); p = ra.Write(anime_list[i].tsa, undodata); U.append_u32(tsa_list, U.toPointer(p)); } ra.WriteAndWritePointer(this.FramePointer, frames.ToArray(), undodata); ra.WriteAndWritePointer(this.TSAPointer, tsa_list.ToArray(), undodata); ra.WriteAndWritePointer(this.ImagePointer, image_list.ToArray(), undodata); ra.WriteAndWritePointer(this.PalettePointer, anime_list[0].pal, undodata); } else {//複数パレット List <byte> image_list = new List <byte>(); List <byte> tsa_list = new List <byte>(); List <byte> pal_list = new List <byte>(); for (int i = 0; i < anime_list.Count; i++) { p = ra.Write(anime_list[i].image, undodata); U.append_u32(image_list, U.toPointer(p)); p = ra.Write(anime_list[i].tsa, undodata); U.append_u32(tsa_list, U.toPointer(p)); p = ra.Write(anime_list[i].pal, undodata); U.append_u32(pal_list, U.toPointer(p)); } ra.WriteAndWritePointer(this.FramePointer, frames.ToArray(), undodata); ra.WriteAndWritePointer(this.TSAPointer, tsa_list.ToArray(), undodata); ra.WriteAndWritePointer(this.ImagePointer, image_list.ToArray(), undodata); ra.WriteAndWritePointer(this.PalettePointer, pal_list.ToArray(), undodata); } } ra.BlackOut(undodata); Program.Undo.Push(undodata); return(""); }
public static string Import(string filename, uint anime_pointer) { string basename = Path.GetFileNameWithoutExtension(filename) + "_"; string basedir = Path.GetDirectoryName(filename); //他のアニメーションとはデータ構造が違うので注意 List <anime> poolList = new List <anime>(); List <byte> frames = new List <byte>(); string[] lines = File.ReadAllLines(filename); for (uint lineCount = 0; lineCount < lines.Length; lineCount++) { string line = lines[lineCount]; if (U.IsComment(line) || U.OtherLangLine(line)) { continue; } line = U.ClipComment(line); if (line.Length <= 0) { continue; } InputFormRef.DoEvents(null, "Line:" + lineCount); string[] sp = line.Split(new string[] { "\t" }, StringSplitOptions.RemoveEmptyEntries); if (sp.Length <= 1) { sp = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); } if (sp.Length <= 1) { continue; } string command = sp[0]; uint wait = U.atoi0x(command); string image = sp[1]; uint song = 0; if (sp.Length >= 2 + 1) { song = U.atoi0x(sp[2]); } string fullfilename = Path.Combine(basedir, image); Bitmap bitmap = ImageUtil.OpenBitmap(fullfilename); if (bitmap == null) { return(R.Error("ファイル名が見つかりませんでした。\r\nFile: {0} line:{1}\r\n\r\nエラー内容:\r\n{2}", filename, lineCount, line)); } if (bitmap.Width != SCREEN_WIDTH || bitmap.Height != SCREEN_HEIGHT) { bitmap = ImageUtil.Copy(bitmap, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); } anime a = new anime(); a.image = ImageUtil.ImageToByte16Tile(bitmap, SCREEN_WIDTH, SCREEN_HEIGHT); a.image = LZ77.compress(a.image); a.pal = ImageUtil.ImageToPalette(bitmap, 1); poolList.Add(a); U.append_u16(frames, wait); U.append_u16(frames, song); U.append_u32(frames, 0x0); U.append_u32(frames, 0x0); } //term U.append_u32(frames, 0x0); U.append_u32(frames, 0x0); U.append_u32(frames, 0x0); byte[] mainData = frames.ToArray(); anime_pointer = U.toOffset(anime_pointer); if (!U.isSafetyOffset(anime_pointer)) { return(R._("アドレスが無効です")); } uint anime_address = Program.ROM.p32(anime_pointer); List <Address> recycle = new List <Address>(); RecycleOldAnime(ref recycle, basename, false, anime_address); RecycleAddress ra = new RecycleAddress(recycle); Undo.UndoData undodata = Program.Undo.NewUndoData("ImageUtilMapActionAnimation.Import"); uint n = 0; for (int i = 0; i < poolList.Count; i++, n += 12) { uint image_addr = CheckDupImage(poolList, i); if (image_addr == U.NOT_FOUND) { image_addr = ra.Write(poolList[i].image, undodata); poolList[i].image_addr = image_addr; } uint pal_addr = CheckDupPal(poolList, i); if (pal_addr == U.NOT_FOUND) { pal_addr = ra.Write(poolList[i].pal, undodata); poolList[i].pal_addr = pal_addr; } U.write_p32(mainData, n + 4, image_addr); U.write_p32(mainData, n + 8, pal_addr); } //アニメポインタの書き換え. ra.WriteAndWritePointer(anime_pointer, mainData, undodata); //名前の設定 MakeImportDataName(anime_pointer, filename, lines); Program.Undo.Push(undodata); return(""); }
public void ImportFont(Form self, string FontROMTextBox, bool FontAutoGenelateCheckBox, Font ttf, RecycleAddress recycle, Undo.UndoData undodata) { string filename = FontROMTextBox; this.YourROM = new ROM(); this.Recycle = recycle; this.UndoData = undodata; 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)) { //文字列からフォントを探索 { 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); } } //エイリアス AliasFont(); } }
static string ImportAll(string filename, uint pointer, InputFormRef ifr) { List <Address> recycle = new List <Address>(); //古いデータをリサイクルリストに入れる. FEBuilderGBA.Address.AddAddress(recycle , ifr , "" , new uint[] { 0 }); uint addr = ifr.BaseAddress; if (U.isSafetyOffset(addr)) { for (int i = 0; i < ifr.DataCount; i++, addr += ifr.BlockSize) { uint p0 = Program.ROM.p32(addr + 0); uint wait = Program.ROM.u8(addr + 4); uint count = Program.ROM.u8(addr + 5); uint startindex = Program.ROM.u8(addr + 6); if (!U.isSafetyOffset(p0)) { continue; } FEBuilderGBA.Address.AddPointer(recycle , addr + 0 , count * 2 , "" , FEBuilderGBA.Address.DataTypeEnum.BIN); } } RecycleAddress ra = new RecycleAddress(recycle); string dir = Path.GetDirectoryName(filename); Undo.UndoData undodata = Program.Undo.NewUndoData("TileAnimation2"); List <byte> writedata = new List <byte>(); string[] lines = File.ReadAllLines(filename); for (int i = 0; i < lines.Length; i++) { string line = lines[i]; if (U.IsComment(line) || U.OtherLangLine(line)) { continue; } line = U.ClipComment(line); if (line == "") { continue; } string[] sp = line.Split('\t'); if (sp.Length < 2) { continue; } uint wait = U.atoi(sp[0]); uint startindex = U.atoi(sp[1]); uint count = 0; List <byte> palByte = new List <byte>(); for (int n = 2; n < sp.Length; n++, count++) { string pal = sp[n]; string[] rgbarray = pal.Split(','); int r = (int)U.atoi0x(U.at(rgbarray, 0)); int g = (int)U.atoi0x(U.at(rgbarray, 1)); int b = (int)U.atoi0x(U.at(rgbarray, 2)); uint gbaRGB = ImageUtil.ColorToGBARGB(Color.FromArgb(r, g, b)); U.append_u16(palByte, gbaRGB); } uint newaddr = ra.Write(palByte.ToArray(), undodata); if (newaddr == U.NOT_FOUND) { return(R.Error("タイルアニメーション2を書き込めませんでした。\r\n\r\nスクリプト:{1}\r\n行数:{2}" , filename, i)); } U.append_u32(writedata, U.toPointer(newaddr)); //パレットポインタ U.append_u8(writedata, wait); //wait U.append_u8(writedata, count); //count U.append_u8(writedata, startindex); //startindex U.append_u8(writedata, 0); //0 } //終端データ U.append_u32(writedata, 0); //パレットポインタ U.append_u8(writedata, 0); //wait U.append_u8(writedata, 0); //count U.append_u8(writedata, 0); //startindex U.append_u8(writedata, 0); //0 uint newpointer = ra.WriteAndWritePointer(pointer, writedata.ToArray(), undodata); if (newpointer == U.NOT_FOUND) { return(R.Error("タイルアニメーションのポインタを書き込めませんでした。\r\n\r\nスクリプト:{0}" , filename)); } ra.BlackOut(undodata); Program.Undo.Push(undodata); return(""); }
static string ImportAll(string filename, uint pointer, InputFormRef ifr) { List <Address> recycle = new List <Address>(); //古いデータをリサイクルリストに入れる. FEBuilderGBA.Address.AddAddress(recycle , ifr , "" , new uint[] { 4 }); uint addr = ifr.BaseAddress; if (U.isSafetyOffset(addr)) { for (int i = 0; i < ifr.DataCount; i++, addr += ifr.BlockSize) { uint length = Program.ROM.u16(addr + 2); uint p4 = Program.ROM.p32(addr + 4); if (!U.isSafetyOffset(p4)) { continue; } FEBuilderGBA.Address.AddPointer(recycle , addr + 4 , length , "" , FEBuilderGBA.Address.DataTypeEnum.BIN); } } RecycleAddress ra = new RecycleAddress(recycle); string dir = Path.GetDirectoryName(filename); Undo.UndoData undodata = Program.Undo.NewUndoData("TileAnimation1"); List <byte> writedata = new List <byte>(); string[] lines = File.ReadAllLines(filename); for (int i = 0; i < lines.Length; i++) { string line = lines[i]; if (U.IsComment(line) || U.OtherLangLine(line)) { continue; } line = U.ClipComment(line); if (line == "") { continue; } string[] sp = line.Split('\t'); if (sp.Length < 2) { continue; } uint wait = U.atoi(sp[0]); string imgFilename = Path.Combine(dir, sp[1]); Bitmap bitmap = ImageUtil.OpenBitmap(imgFilename); if (bitmap == null) { return(R.Error("タイルアニメーション({0})が見つかりません。\r\n\r\nスクリプト:{1}\r\n行数:{2}" , imgFilename, filename, i)); } byte[] bitmapByte = ImageUtil.ImageToByte16Tile(bitmap, bitmap.Width, bitmap.Height); uint length = (uint)bitmapByte.Length; if (sp.Length >= 3) { length = U.atoi(sp[2]); bitmapByte = U.subrange(bitmapByte, 0, length); } uint newaddr = ra.Write(bitmapByte, undodata); if (newaddr == U.NOT_FOUND) { return(R.Error("タイルアニメーション({0})を書き込めませんでした。\r\n\r\nスクリプト:{1}\r\n行数:{2}" , imgFilename, filename, i)); } bitmap.Dispose(); U.append_u16(writedata, wait); //wait U.append_u16(writedata, length); //length U.append_u32(writedata, U.toPointer(newaddr)); //画像ポインタ } //終端データ U.append_u16(writedata, 0); //term U.append_u16(writedata, 0); //length U.append_u32(writedata, 0); //画像ポインタ uint newpointer = ra.WriteAndWritePointer(pointer, writedata.ToArray(), undodata); if (newpointer == U.NOT_FOUND) { return(R.Error("タイルアニメーションのポインタを書き込めませんでした。\r\n\r\nスクリプト:{0}" , filename)); } ra.BlackOut(undodata); Program.Undo.Push(undodata); return(""); }
public void ImportAllText(Form self, string filename) { //少し時間がかかるので、しばらくお待ちください表示. using (InputFormRef.AutoPleaseWait pleaseWait = new InputFormRef.AutoPleaseWait(self)) { Undo.UndoData undodata = Program.Undo.NewUndoData("ImportAllText" + Path.GetFileName(filename) ); uint id = U.NOT_FOUND; string[] lines = File.ReadAllLines(filename); //上書きするテキスト領域を再利用リストに突っ込む List <Address> recycle = new List <FEBuilderGBA.Address>(); for (int i = 0; i < lines.Length; i++) { string line = lines[i]; if (U.IsCommentSlashOnly(line) || U.OtherLangLine(line)) { continue; } line = U.ClipComment(line); if (line.Length <= 0) { continue; } if (!TranslateTextUtil.IsTextIDCode(line)) { continue; } AddRecycle(id, recycle); //次のテキスト id = U.atoh(U.substr(line, 1)); } RecycleAddress ra = new RecycleAddress(recycle); id = U.NOT_FOUND; string text = ""; for (int i = 0; i < lines.Length; i++) { string line = lines[i]; if (U.IsCommentSlashOnly(line) || U.OtherLangLine(line)) { continue; } line = U.ClipComment(line); if (line.Length <= 0) { continue; } if (!TranslateTextUtil.IsTextIDCode(line)) { text += line + "\r\n"; continue; } //次の数字があったので、現在のテキストの書き込み. pleaseWait.DoEvents("Write:" + U.To0xHexString(id)); WriteText(id, text, ra, undodata); //次のテキスト id = U.atoh(U.substr(line, 1)); text = ""; } //最後のデータ WriteText(id, text, ra, undodata); ra.BlackOut(undodata); Program.Undo.Push(undodata); } }