Example #1
0
        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);
            }
        }
Example #3
0
        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);
            }
        }
Example #7
0
        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);
        }
Example #8
0
        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);
        }
Example #9
0
        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("");
        }
Example #11
0
        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("");
        }
Example #13
0
        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("");
        }
Example #15
0
        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("");
        }
Example #16
0
        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);
            }
        }