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(""); }
public static bool ImportBorder(Form self, uint origin_x, uint origin_y, out byte[] out_image, out byte[] out_oam) { out_image = null; out_oam = null; string imagefilename = ImageFormRef.OpenFilenameDialogFullColor(self); if (imagefilename == "") { R.ShowStopError("ファイルがありません。\r\nファイル名:{0}", imagefilename); return(false); } string name_filename = MakeBorderNameImageFileName(imagefilename); if (!File.Exists(name_filename)) { R.ShowStopError("ファイルがありません。\r\nファイル名:{0}", name_filename); return(false); } string basedir = Path.GetDirectoryName(imagefilename); List <uint> battleOAMSplit = new List <uint>(); ImageUtilOAM.ImportOAM oam = new ImageUtilOAM.ImportOAM(); oam.SetIsBorderAPOAM(true); oam.SetBaseDir(basedir); oam.MakeBorderAP(imagefilename); battleOAMSplit.Add(oam.GetOAMByteCount()); oam.MakeBorderAP(name_filename); oam.Term(); battleOAMSplit.Add(oam.GetOAMByteCount()); List <ImageUtilOAM.image_data> images = oam.GetImages(); if (images.Count >= 2) { R.ShowStopError("画像が大きすぎて、256x160のシートに入りきりませんでした"); return(false); } byte[] battleOAM = oam.GetRightToLeftOAM(); List <uint> apOAMSplit = new List <uint>(); byte[] apOAM = BattleOAMToAPOAM(battleOAM, battleOAMSplit, origin_x, origin_y, apOAMSplit); if (apOAM == null) { return(false); } List <byte> newOam = new List <byte>(); //ap_data header U.append_u16(newOam, 4); //ap_data header SHORT (frame_list - ap_data) U.append_u16(newOam, 8); //ap_data header SHORT (anim_list - ap_data) //frame_list uint addr_frame_list = (uint)newOam.Count; U.append_u16(newOam, 0); //SHORT (frame_0 - frame_list) U.append_u16(newOam, 0); //SHORT (frame_1 - frame_list) //anim_list uint addr_anim_list = (uint)newOam.Count; U.append_u16(newOam, 0); //SHORT (anim_0 - anim_list) U.append_u16(newOam, 0); //SHORT (anim_1 - anim_list) //frame_0 uint addr_frame_0 = (uint)newOam.Count; U.append_u16(newOam, apOAMSplit[0] / 6); // oam entries for (uint i = 0; i < apOAMSplit[0]; i++) { U.append_u8(newOam, apOAM[i]); // oam entries } //frame_1 uint addr_frame_1 = (uint)newOam.Count; U.append_u16(newOam, (apOAMSplit[1] - apOAMSplit[0]) / 6); // oam entries for (uint i = apOAMSplit[0]; i < apOAMSplit[1]; i++) { U.append_u8(newOam, apOAM[i]); // oam entries } //anim_0: uint addr_anim_0 = (uint)newOam.Count; U.append_u16(newOam, 4); U.append_u16(newOam, 0); U.append_u16(newOam, 0); U.append_u16(newOam, 0xffff);// loop back to start //anim_1: uint addr_anim_1 = (uint)newOam.Count; U.append_u16(newOam, 4); U.append_u16(newOam, 1); U.append_u16(newOam, 0); U.append_u16(newOam, 0xffff);// loop back to start out_oam = newOam.ToArray(); //フレームの位置を書き込む U.write_u16(out_oam, 4, addr_frame_0 - addr_frame_list); //SHORT (frame_0 - frame_list) U.write_u16(out_oam, 6, addr_frame_1 - addr_frame_list); //SHORT (frame_1 - frame_list) U.write_u16(out_oam, 8, addr_anim_0 - addr_anim_list); //SHORT (anim_0 - anim_list) U.write_u16(out_oam, 10, addr_anim_1 - addr_anim_list); //SHORT (anim_1 - anim_list) out_image = LZ77.decompress(images[0].data, 0); return(true); }