Example #1
0
        //no$gbaの場合は、BATTERYフォルダの下にある.
        bool CollectNoDollSaveData(string tempdir, string needExt)
        {
            string emudir = Program.Config.at("emulator");

            if (emudir == "")
            {
                return(false);
            }
            emudir = Path.GetDirectoryName(emudir);
            string dir = Path.Combine(emudir, "BATTERY");

            if (!Directory.Exists(dir))
            {
                return(false);
            }

            string file = Path.GetFileNameWithoutExtension(Program.ROM.Filename);

            string savFilename = Path.Combine(dir, file + needExt);

            if (!File.Exists(savFilename))
            {
                return(false);
            }
            string destFilename = Path.Combine(tempdir, file + needExt);

            InputFormRef.DoEvents(this, "=>" + Path.GetFileName(savFilename));
            File.Copy(savFilename, destFilename, true);

            return(true);
        }
Example #2
0
        string MakeReport(string fullfilename)
        {
            //少し時間がかかるので、しばらくお待ちください表示.
            using (InputFormRef.AutoPleaseWait pleaseWait = new InputFormRef.AutoPleaseWait(this))
                //テンポラリディレクトリを利用する
                using (U.MakeTempDirectory tempdir = new U.MakeTempDirectory())
                {
                    string orignalFilename = OrignalFilename.Text;
                    byte[] s = File.ReadAllBytes(orignalFilename);

                    //セーブデータの回収
                    CollectSaveData(tempdir.Dir);

                    //現在のROMのUPSデータの回収
                    CollectUPSsCurrentROM(tempdir.Dir, s);

                    //動作しないUPSと動作するUPSデータの回収
                    CollectOldUPSs(tempdir.Dir, s);

                    //ログとユーザの説明を書き込む
                    string log = Path.Combine(tempdir.Dir, "log.txt");
                    U.WriteAllText(log, MakeReportLog());

                    //etcの内容をコピー
                    //lintやコメントなどの設定がほしい
                    CopyEtcData(tempdir.Dir);

                    //添付データ
                    AttachData(tempdir.Dir);

                    //7z圧縮
                    InputFormRef.DoEvents(this, R._("7z圧縮中"));
                    return(ArchSevenZip.Compress(fullfilename, tempdir.Dir));
                }
        }
Example #3
0
        public static void MakeLZ77DataList(List <Address> list)
        {
            string name   = R._("圧縮データ");
            uint   length = (uint)Program.ROM.Data.Length - 4;

            for (uint addr = 0x100; addr < length; addr += 4)
            {
                uint a = (uint)Program.ROM.Data[addr + 3];
                if (a != 0x08 && a != 0x09)
                {//ポインタ以外無視する.
                    continue;
                }
                a = Program.ROM.p32(addr);
                if (!U.isSafetyOffset(a))
                {//危険なポインタは無視
                    continue;
                }
                if (a < Program.ROM.RomInfo.compress_image_borderline_address())
                {
                    continue;
                }

                //ポインタ先は圧縮されているか?
                uint imageDataSize = LZ77.getUncompressSize(Program.ROM.Data, a);
                if (IsBadImageSize(imageDataSize))
                {
                    continue;
                }

                //ポインタは連続してあらわれるのでそのチェックをする.
                if (!IsContinuousPointer(addr, length))
                {
                    continue;
                }

                //解凍して中身を見てみる.
                byte[] image = LZ77.decompress(Program.ROM.Data, a);
                if (image.Length != imageDataSize)
                {//解凍したらデータ容量が違う
                    continue;
                }
                uint getcompsize = LZ77.getCompressedSize(Program.ROM.Data, a);
                if (getcompsize == 0)
                {
                    continue;
                }

                //たぶん画像だと判断する.
                FEBuilderGBA.Address.AddAddress(list, a, getcompsize, addr, name + U.To0xHexString(a), Address.DataTypeEnum.LZ77IMG);
                if (InputFormRef.DoEvents(null, "MakeLZ77DataList " + U.ToHexString(addr)))
                {
                    return;
                }
            }
        }
Example #4
0
        //フリー領域と思われる部分を検出.
        public static void MakeFreeDataList(List <Address> list, uint addr, byte filldata, uint needSize, byte[] data, uint length)
        {
            string name = "FREEAREA:" + filldata.ToString("X02");

            addr = U.Padding4(addr);
            for (; addr < length; addr += 4)
            {
                if (data[addr] == filldata)
                {
                    uint start = addr;
                    addr++;
                    for (; ; addr++)
                    {
                        if (addr >= length)
                        {
                            uint matchsize = addr - start;
                            if (matchsize >= needSize)
                            {
                                if (InputFormRef.DoEvents(null, "MakeFreeDataList " + U.ToHexString(addr)))
                                {
                                    return;
                                }
                                FEBuilderGBA.Address.AddAddress(list
                                                                , start
                                                                , matchsize
                                                                , U.NOT_FOUND
                                                                , name
                                                                , Address.DataTypeEnum.FFor00);
                            }
                            break;
                        }
                        if (data[addr] != filldata)
                        {
                            uint matchsize = addr - start;
                            if (matchsize >= needSize)
                            {
                                if (InputFormRef.DoEvents(null, "MakeFreeDataList " + U.ToHexString(addr)))
                                {
                                    return;
                                }
                                FEBuilderGBA.Address.AddAddress(list
                                                                , start
                                                                , matchsize
                                                                , U.NOT_FOUND
                                                                , name
                                                                , Address.DataTypeEnum.FFor00);
                            }
                            break;
                        }
                    }

                    addr = U.Padding4(addr);
                }
            }
        }
Example #5
0
        private void UpdateThreadCallBackEvent(object sender, EventArgs e)
        {
            this.IsSlientMode = false;
            //ダイアログを表示して、更新ボタンを押す.
            this.Show();
            InputFormRef.DoEvents();

            DialogResult dr = R.ShowYesNo("このゲームの新しいバージョンが公開されています。\r\n最新版に自動アップデートしますか?");

            if (dr != System.Windows.Forms.DialogResult.No)
            {
                this.UpdateButton.PerformClick();
            }
        }
        public void DesignStringConvert(string source_path)
        {
            string resoucefilename = System.IO.Path.Combine(Program.BaseDirectory, "config", "translate", this.Lang + ".txt");

            this.TranslateResource.LoadResource(resoucefilename);

            //デザインのソースコードスキャンして日本語文字列を置き換え.
            {
                string[] files = U.Directory_GetFiles_Safe(source_path, "*.Designer.cs", SearchOption.TopDirectoryOnly);
                foreach (string fullfilename in files)
                {
                    InputFormRef.DoEvents(null, fullfilename);
                    ScanStringForSourceCodeAndReplace(fullfilename);
                }
            }
        }
        public void ScanCS(string source_path)
        {
            TranslateTargetFiles.Clear();

            //ソースコードスキャン
            {
                string[] files = U.Directory_GetFiles_Safe(source_path, "*.cs", SearchOption.TopDirectoryOnly);
                foreach (string fullfilename in files)
                {
                    InputFormRef.DoEvents(null, fullfilename);
                    ScanStringForSourceCode(fullfilename);
                }
            }
            //翻訳して書き込み
            TransFileWriter();
        }
        string MakeFeedBack(string fullfilename)
        {
            //テンポラリディレクトリを利用する
            using (U.MakeTempDirectory tempdir = new U.MakeTempDirectory())
            {
                //セーブデータの回収
                ToolProblemReportForm.CollectSaveData(tempdir.Dir);

                //フィードバックコメント
                File.WriteAllText(Path.Combine(tempdir.Dir, "log.txt"), MakeFeedBackInfo());

                //7z圧縮
                InputFormRef.DoEvents(this, R._("7z圧縮中"));
                return(ArchSevenZip.Compress(fullfilename, tempdir.Dir));
            }
        }
Example #9
0
        void CopyEtcData(string tempdir)
        {
            string tempEtcDir = Path.Combine(tempdir, "etc");

            U.mkdir(tempEtcDir);

            string[] etcFiles = new string[] { "lint_", "comment_", "flag_" };
            foreach (var name in etcFiles)
            {
                string src = U.ConfigEtcFilename(name);
                if (!File.Exists(src))
                {
                    continue;
                }

                string dest = Path.Combine(tempEtcDir, Path.GetFileName(src));
                InputFormRef.DoEvents(this, "=>" + Path.GetFileName(dest));
                File.Copy(src, dest);
            }
        }
Example #10
0
        bool MakeUPS(string tempdir, byte[] s, string targetFilename)
        {
            string filename_only = Path.GetFileName(targetFilename);

            if (filename_only.IndexOf(".backup.") <= -1)
            {
                return(false);
            }
            InputFormRef.DoEvents(this, "=>" + Path.GetFileName(targetFilename));

            string orignalFilename = OrignalFilename.Text;

            byte[] d   = MainFormUtil.OpenROMToByte(targetFilename, orignalFilename);
            string ups = Path.Combine(tempdir, Path.GetFileNameWithoutExtension(targetFilename) + ".ups");

            UPSUtil.MakeUPS(s, d, ups);
            U.CopyTimeStamp(targetFilename, ups); //タイムスタンプを元のファイルに合わせる.

            return(true);
        }
Example #11
0
        void AppendList(List <Address> list, uint start, uint matchsize, byte[] data)
        {
            uint checkData = U.u32(data, start);

            if (!(checkData == 0x00 || checkData == 0xFFFFFFFF))
            {
                Debug.Assert(false);
                return;
            }

            if (InputFormRef.DoEvents(null, "MakeFreeDataList " + U.ToHexString(start)))
            {
                return;
            }
            FEBuilderGBA.Address.AddAddress(list
                                            , start
                                            , matchsize
                                            , U.NOT_FOUND
                                            , ""
                                            , Address.DataTypeEnum.FFor00);
        }
        private void UpdateThreadCallBackEvent(object sender, EventArgs e)
        {
            bool wasSlientMode = this.IsSlientMode;

            this.IsSlientMode = false;
            //ダイアログを表示して、更新ボタンを押す.
            this.Show();
            InputFormRef.DoEvents();

            string msg = R._("このゲームの新しいバージョンが公開されています。\r\n最新版に自動アップデートしますか?");

            if (wasSlientMode)
            {
                msg += "\r\n\r\n" + R._("自動更新をキャンセルした後に、手動で更新したい場合は、「メニュー」->「実行」->「作品支援」を利用してください。");
            }
            DialogResult dr = R.ShowYesNo(msg);

            if (dr != System.Windows.Forms.DialogResult.No)
            {
                this.UpdateButton.PerformClick();
            }
        }
Example #13
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("");
        }
Example #14
0
        public static List <uint> SearchPointer(uint moveAddress, bool isSilent = false)
        {
            List <uint> ret = new List <uint>();

            if (IsBadBaseAddress(moveAddress))
            {//新規確保だけ
                return(ret);
            }

            moveAddress = U.toPointer(moveAddress);
            if (!U.isSafetyOffset(U.toOffset(moveAddress)))
            {
                string text  = R.Error("空き領域のポインタまたはサイズが正しくありません。\r\n0x0 - 0x100までの領域は危険なので移動できません");
                string title = R._("エラー");
                if (!isSilent)
                {
                    MessageBox.Show(text
                                    , title
                                    , MessageBoxButtons.OK
                                    , MessageBoxIcon.Error);
                }
                return(ret);
            }
            bool isFixedASM = Program.AsmMapFileAsmCache.IsFixedASM(moveAddress);

            if (isFixedASM)
            {
                if (!isSilent)
                {
                    DialogResult dr = R.ShowNoYes("このアドレス({0})は、プログラムコードを指しているようです。\r\n通常プログラムコードの領域をリポイントすることはありえません。\r\n本当にリポイントを継続してもよろしいですか?\r\n", U.ToHexString8(moveAddress));
                    if (dr != DialogResult.Yes)
                    {
                        return(ret);
                    }
                }
            }

            InputFormRef.DoEvents(null, "U.GrepPointerAllOnLDR");
            ret = U.GrepPointerAllOnLDR(Program.ROM.Data, moveAddress);

            InputFormRef.DoEvents(null, "U.GrepPointerAllOnEvent");
            ret.AddRange(GrepPointerAllOnEvent(moveAddress));

            if (ret.Count <= 0)
            {
                InputFormRef.DoEvents(null, "U.GrepPointerAll");
                ret = U.GrepPointerAll(Program.ROM.Data, U.toPointer(moveAddress));
                if (ret.Count >= 2)
                {
                    if (!isSilent)
                    {
                        DialogResult dr = R.ShowYesNo("LDRとイベントでは、該当するポインタ値が見つかりませんでした。\r\nROMをバイナリ検索をしたら、値が見つかりましたが、誤爆の可能性もあります。\r\nこの処理を続行してもよろしいですか?\r\n\r\n「はい」の場合、バイナリ検索でヒットした値を利用します。 \r\nそれ以外の場合は、見つからなかったとして処理します。");
                        if (dr != DialogResult.Yes)
                        {
                            ret = new List <uint>();
                            return(ret);
                        }
                    }
                }
            }

            ret = U.Uniq(ret);
            return(ret);
        }
        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("");
        }
        void AppendCustomFreeList(List <Address> list, uint RebuildAddress, uint start, uint end)
        {
            start = U.toOffset(start);
            if (!U.isPadding4(start))
            {//4で割り切れないの補正
                start = U.SubPadding4(start) + 4;
            }

            end = U.toOffset(end);
            end = U.SubPadding4(end);
            if (start <= 0x100 || end <= 0x100 || end <= start)
            {//アドレスが変
                return;
            }
            if (start >= RebuildAddress || end >= RebuildAddress)
            {//リビルドアドレスより上なので無視
                return;
            }
            if (end - start >= FreeAreaMinimumSize)
            {//自動探索する領域よりも大きいから無視しておいた方が無難
                return;
            }

            uint d = Program.ROM.u32(start);

            if (!(d == 0x0 || d == 0xFFFFFFFF))
            {//空いてない
                return;
            }

            d = Program.ROM.u32(end - 4);
            if (!(d == 0x0 || d == 0xFFFFFFFF))
            {//空いてない
                //終端が割り込まれるのはよくあることなので4バイト削る
                end -= 4;
                if (end <= start + 4)
                {//小さすぎる
                    return;
                }
                d = Program.ROM.u32(end - 4);
                if (!(d == 0x0 || d == 0xFFFFFFFF))
                {//それでも空いてない
                    //もう一回削る
                    end -= 4;
                    if (end <= start + 4)
                    {//小さすぎる
                        return;
                    }
                    d = Program.ROM.u32(end - 4);
                    if (!(d == 0x0 || d == 0xFFFFFFFF))
                    {//それでも空いてないなら無理
                        return;
                    }
                }
            }
            if (end - start <= 0xF)
            {//あまりに小さすぎる
                return;
            }

            foreach (Address a in list)
            {
                uint AddrEnd = a.Addr + a.Length;
                if (a.Addr >= start && AddrEnd < start && AddrEnd < end)
                {//既に知ってる
                    return;
                }
            }

            if (InputFormRef.DoEvents(null, "AppendCustomFreeList " + U.ToHexString(start)))
            {
                return;
            }
            FEBuilderGBA.Address.AddAddress(list
                                            , start
                                            , end - start
                                            , U.NOT_FOUND
                                            , ""
                                            , Address.DataTypeEnum.FFor00);
        }
        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 static uint ImportAllLow(string filename, Undo.UndoData undodata)
        {
            string dir = Path.GetDirectoryName(filename);

            //まずはデータ数を知らないといけない.
            List <byte>            bin  = new List <byte>();
            List <DataWriteHelper> data = new List <DataWriteHelper>();

            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;
                }
                InputFormRef.DoEvents(null, filename + ":" + i);

                string[] sp = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
                if (sp.Length < 4 + 2)
                {
                    R.ShowStopError("データの形式が正しくありません。\r\n少なくとも{1}個のデータが必要です。\r\n{0}行目", i + 1, 6);
                    return(U.NOT_FOUND);
                }
                uint type = U.atoh(sp[0]);
                U.append_u8(bin, type);
                U.append_u8(bin, U.atoh(sp[1]));
                U.append_u8(bin, U.atoh(sp[2]));
                U.append_u8(bin, U.atoh(sp[3]));

                if (type == 0x00 ||
                    type == 0x08 ||
                    type == 0x10 ||
                    type == 0x18
                    )
                {
                    if (sp.Length < 4 + 1 + 4)
                    {
                        R.ShowStopError("データの形式が正しくありません。\r\n少なくとも{1}個のデータが必要です。\r\n{0}行目", i + 1, 9);
                        return(U.NOT_FOUND);
                    }

                    string file = Path.Combine(dir, sp[4]);
                    if (!File.Exists(file))
                    {
                        R.ShowStopError("楽器データ({1})がありません。\r\n{0}行目", i + 1, file);
                        return(U.NOT_FOUND);
                    }
                    byte[] wav   = File.ReadAllBytes(file);
                    uint   found = U.Grep(Program.ROM.Data, wav, 0x100, 0, 4);
                    if (found == U.NOT_FOUND)
                    {                         //既存のROMにないので追加
                        data.Add(new DataWriteHelper(wav, bin.Count));
                        U.append_u32(bin, 0); //後でこの位置にアドレスを書く.
                    }
                    else
                    {//既にあるので使いまわす.
                        U.append_u32(bin, U.toPointer(found));
                    }
                    U.append_u8(bin, U.atoh(sp[5]));
                    U.append_u8(bin, U.atoh(sp[6]));
                    U.append_u8(bin, U.atoh(sp[7]));
                    U.append_u8(bin, U.atoh(sp[8]));
                }
                else if (type == 0x03 ||
                         type == 0x0B
                         )
                {
                    if (sp.Length < 4 + 1 + 4)
                    {
                        R.ShowStopError("データの形式が正しくありません。\r\n少なくとも{1}個のデータが必要です。\r\n{0}行目", i + 1, 9);
                        return(U.NOT_FOUND);
                    }

                    string file = Path.Combine(dir, sp[4]);
                    if (!File.Exists(file))
                    {
                        R.ShowStopError("楽器データ({1})がありません。\r\n{0}行目", i + 1, file);
                        return(U.NOT_FOUND);
                    }
                    byte[] wav   = File.ReadAllBytes(file);
                    uint   found = U.Grep(Program.ROM.Data, wav, 0x100, 0, 4);
                    if (found == U.NOT_FOUND)
                    {                         //既存のROMにないので追加
                        data.Add(new DataWriteHelper(wav, bin.Count));
                        U.append_u32(bin, 0); //後でこの位置にアドレスを書く.
                    }
                    else
                    {//既にあるので使いまわす.
                        U.append_u32(bin, U.toPointer(found));
                    }
                    U.append_u8(bin, U.atoh(sp[5]));
                    U.append_u8(bin, U.atoh(sp[6]));
                    U.append_u8(bin, U.atoh(sp[7]));
                    U.append_u8(bin, U.atoh(sp[8]));
                }
                else if (type == 0x80)
                {
                    if (sp.Length < 4 + 1 + 4)
                    {
                        R.ShowStopError("データの形式が正しくありません。\r\n少なくとも{1}個のデータが必要です。\r\n{0}行目", i + 1, 9);
                        return(U.NOT_FOUND);
                    }

                    string file = Path.Combine(dir, sp[4]);
                    if (!File.Exists(file))
                    {
                        if (file.IndexOf("@SELF+") >= 0)
                        {
                            uint relativeAddress = U.atoh(file.Substring(6));
                            data.Add(new DataWriteHelper(relativeAddress, bin.Count));
                            U.append_u32(bin, 0); //後でこの位置にアドレスを書く.
                        }
                        else if (file.IndexOf("@BROKENDATA") >= 0)
                        {//ドラム内でドラムがあるような変なデータ
                            uint relativeAddress = 0;
                            data.Add(new DataWriteHelper(relativeAddress, bin.Count));
                            U.append_u32(bin, 0); //とりあえず @SELF+0として扱う.
                        }
                        else
                        {
                            R.ShowStopError("楽器データ({1})がありません。\r\n{0}行目", i + 1, file);
                            return(U.NOT_FOUND);
                        }
                    }
                    else
                    {
                        uint wav = ImportAllLow(file, undodata);
                        if (wav == U.NOT_FOUND)
                        {
                            R.ShowStopError("ネストする楽器データ({1})を登録できません。\r\n{0}行目", i + 1, file);
                            return(U.NOT_FOUND);
                        }
                        U.append_u32(bin, U.toPointer(wav));
                    }
                    U.append_u8(bin, U.atoh(sp[5]));
                    U.append_u8(bin, U.atoh(sp[6]));
                    U.append_u8(bin, U.atoh(sp[7]));
                    U.append_u8(bin, U.atoh(sp[8]));
                }
                else if (type == 0x40)
                {
                    string file = Path.Combine(dir, sp[4]);
                    if (!File.Exists(file))
                    {
                        if (file.IndexOf("@SELF+") < 0)
                        {
                            R.ShowStopError("楽器データ({1})がありません。\r\n{0}行目", i + 1, file);
                            return(U.NOT_FOUND);
                        }
                        uint relativeAddress = U.atoh(file.Substring(6));
                        data.Add(new DataWriteHelper(relativeAddress, bin.Count));
                        U.append_u32(bin, 0); //後でこの位置にアドレスを書く.
                    }
                    else
                    {
                        uint wav = ImportAllLow(file, undodata);
                        if (wav == U.NOT_FOUND)
                        {
                            R.ShowStopError("ネストする楽器データ({1})を登録できません。\r\n{0}行目", i + 1, file);
                            return(U.NOT_FOUND);
                        }
                        U.append_u32(bin, U.toPointer(wav));
                    }

                    file = Path.Combine(dir, sp[5]);
                    if (!File.Exists(file))
                    {
                        R.ShowStopError("楽器データ({1})がありません。\r\n{0}行目", i + 1, file);
                    }

                    //データは後で入れましょう.
                    byte[] multi = File.ReadAllBytes(file);
                    uint   found = U.Grep(Program.ROM.Data, multi, 0x100, 0, 4);
                    if (found == U.NOT_FOUND)
                    {                         //既存のROMにないので追加
                        data.Add(new DataWriteHelper(multi, bin.Count));
                        U.append_u32(bin, 0); //後でこの位置にアドレスを書く.
                    }
                    else
                    {//既にあるので使いまわす.
                        U.append_u32(bin, U.toPointer(found));
                    }
                }
                else
                {
                    if (sp.Length < 4 + 4 + 4)
                    {
                        R.ShowStopError("データの形式が正しくありません。\r\n少なくとも{1}個のデータが必要です。\r\n{0}行目", i + 1, 12);
                        return(U.NOT_FOUND);
                    }
                    U.append_u8(bin, U.atoh(sp[4]));
                    U.append_u8(bin, U.atoh(sp[5]));
                    U.append_u8(bin, U.atoh(sp[6]));
                    U.append_u8(bin, U.atoh(sp[7]));
                    U.append_u8(bin, U.atoh(sp[8]));
                    U.append_u8(bin, U.atoh(sp[9]));
                    U.append_u8(bin, U.atoh(sp[10]));
                    U.append_u8(bin, U.atoh(sp[11]));
                }
            }
            //終端データ.
            U.append_u32(bin, 0);
            U.append_u32(bin, 0);
            U.append_u32(bin, 0);

            uint startaddr = InputFormRef.AppendBinaryData(bin.ToArray(), undodata);

            if (startaddr == U.NOT_FOUND)
            {
                return(U.NOT_FOUND);
            }
            for (int i = 0; i < data.Count; i++)
            {
                if (data[i].Data == null)
                {
                    uint writeAddress = startaddr + data[i].WriteOffset;
                    Program.ROM.write_p32(writeAddress, data[i].RelativeAddress + startaddr);
                }
                else
                {
                    uint dataAddress = InputFormRef.AppendBinaryData(data[i].Data, undodata);
                    if (dataAddress == U.NOT_FOUND)
                    {
                        return(U.NOT_FOUND);
                    }

                    uint writeAddress = startaddr + data[i].WriteOffset;
                    Program.ROM.write_p32(writeAddress, dataAddress);
                }
            }

            return(startaddr);
        }
Example #19
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("");
        }
        string MakeTranslate(string target)
        {
            if (U.isAsciiString(target))
            {//日本語の特権アルファベットだけの文字列なら無視.
                return(target);
            }
            if (U.IsComment(target))
            {//コメントなので不要
                return(target);
            }

            string test = target;
            string t    = this.TranslateResource.str(test);

            if (t != test)
            {//翻訳がある
                return(t);
            }
            if (this.Lang == "zh")
            {     //中国語への翻訳の場合、漢字だけの文章は同一の文章になることがある.
                if (this.TranslateResource.Exist(test))
                { //翻訳があるらしい
                    return(t);
                }
            }

            test = target.Replace("\\r\\n", "\r\n");
            t    = this.TranslateResource.str(test);
            if (t != test)
            {//翻訳がある
                return(t);
            }

            test = target.Replace("\\\r\\\n", "\r\n");
            t    = this.TranslateResource.str(test);
            if (t != test)
            {//翻訳がある
                return(t);
            }
            test = target.Replace("\\\\r\\\\n", "\r\n");
            t    = this.TranslateResource.str(test);
            if (t != test)
            {//翻訳がある
                return(t);
            }


            if (t == "♪" || ///No Translate
                t == "↑" || ///No Translate
                t == "↓" || ///No Translate
                t == "←" || ///No Translate
                t == "→" || ///No Translate
                t == "~" || ///No Translate
                t == " " || ///No Translate
                t == "。" ///No Translate
                )
            {            //特殊指定
                return(t);
            }

            //翻訳がない
            InputFormRef.DoEvents(null, target);
            if (this.IsEnglishBase())
            {
                string tempT = this.TranslateResourceEN.str(target);
                if (tempT == target)
                {
                    t = Translate(target, "ja");
                }
                else
                {
                    t = Translate(tempT, "en");
                }
            }
            else
            {
                t = Translate(target, "ja");
            }
            Log.Debug("->", target, t);
            return(t);
        }
Example #21
0
        public static void MakeAllDataLength(List <Address> list, List <Address> listoam12, List <DisassemblerTrumb.LDRPointer> ldrmap)
        {
            Dictionary <uint, string> oamName = U.LoadDicResource(U.ConfigDataFilename("oam_name_"));

            Dictionary <uint, bool> alreadyMatch   = new Dictionary <uint, bool>();
            Dictionary <uint, bool> alreadyMatch12 = new Dictionary <uint, bool>();

            for (int i = 0; i < ldrmap.Count; i++)
            {
                uint addr = ldrmap[i].ldr_data;
                if (!U.isSafetyPointer(addr))
                {
                    continue;
                }
                addr = U.toOffset(addr);
                if (addr < Program.ROM.RomInfo.compress_image_borderline_address)
                {
                    continue;
                }

                if (alreadyMatch.ContainsKey(addr))
                {//既に知っている.
                    continue;
                }

                string name = U.at(oamName, ldrmap[i].ldr_data_address);
                if (name == "")
                {
                    name = U.at(oamName, ldrmap[i].ldr_address);
                }
                if (name == "")
                {
                    name = U.ToHexString8(ldrmap[i].ldr_data);
                }
                name = "OAMSP " + name;
                List <Address> listoam12_local = new List <Address>();
                uint           length          = CalcLengthAndCheck(addr, name, ref listoam12_local, ref alreadyMatch12);
                if (U.NOT_FOUND == length)
                {
                    alreadyMatch.Add(addr, false); //ダメだったということを記録しておこう
                    continue;
                }
                if (length < 4 * 3)
                {
                    alreadyMatch.Add(addr, false); //ダメだったということを記録しておこう
                    continue;
                }

                FEBuilderGBA.Address.AddAddress(list, addr, length, ldrmap[i].ldr_data_address, name, FEBuilderGBA.Address.DataTypeEnum.OAMSP);
                listoam12.AddRange(listoam12_local);
                alreadyMatch.Add(addr, true);

                if (InputFormRef.DoEvents(null, "OAMSP " + U.ToHexString(addr)))
                {
                    return;
                }
            }
            foreach (var pair in oamName)
            {
                uint addr = U.toOffset(pair.Key);
                if (alreadyMatch.ContainsKey(addr))
                {//既に知っている.
                    continue;
                }

                string         name            = "OAMSP_ " + pair.Value;
                List <Address> listoam12_local = new List <Address>();
                uint           length          = CalcLengthAndCheck(addr, name, ref listoam12_local, ref alreadyMatch12);
                if (U.NOT_FOUND == length)
                {
                    alreadyMatch.Add(addr, false); //ダメだったということを記録しておこう
                    continue;
                }
                if (length < 4)
                {
                    alreadyMatch.Add(addr, false); //ダメだったということを記録しておこう
                    continue;
                }

                FEBuilderGBA.Address.AddAddress(list, addr, length, U.NOT_FOUND, name, FEBuilderGBA.Address.DataTypeEnum.OAMSP);
                listoam12.AddRange(listoam12_local);
                alreadyMatch.Add(addr, true);

                if (InputFormRef.DoEvents(null, "OAMSP " + U.ToHexString(addr)))
                {
                    return;
                }
            }
        }
Example #22
0
        static List <FELint.ErrorSt> ScanMAPLow(uint mapid, List <DisassemblerTrumb.LDRPointer> ldrmap)
        {
            List <FELint.ErrorSt> errors = new List <ErrorSt>();

            if (mapid == SYSTEM_MAP_ID)
            {
                ScanSystem(errors, ldrmap);
                return(errors);
            }

            if (InputFormRef.DoEvents(null, "Scan Map " + U.ToHexString(mapid)))
            {
                return(errors);
            }
            EventCondForm.MakeCheckErrors(mapid, errors);

            if (InputFormRef.DoEvents(null, null))
            {
                return(errors);
            }
            MapSettingForm.MakeCheckErrors(mapid, errors);

            if (InputFormRef.DoEvents(null, null))
            {
                return(errors);
            }
            MapChangeForm.MakeCheckError(mapid, errors);

            if (InputFormRef.DoEvents(null, null))
            {
                return(errors);
            }
            MapExitPointForm.MakeCheckError(mapid, errors);

            if (Program.ROM.RomInfo.version() == 8)
            {
                if (InputFormRef.DoEvents(null, null))
                {
                    return(errors);
                }
                WorldMapEventPointerForm.MakeCheckErrors(mapid, errors);

                if (mapid == 0)
                {
                    if (InputFormRef.DoEvents(null, null))
                    {
                        return(errors);
                    }
                    //FELint.CheckPrologeEventPointer(0, errors);
                }
            }
            else if (Program.ROM.RomInfo.version() == 7)
            {
                if (InputFormRef.DoEvents(null, null))
                {
                    return(errors);
                }
                WorldMapEventPointerFE7Form.MakeCheckErrors(mapid, errors);

                if (mapid == 0)
                {
                    if (InputFormRef.DoEvents(null, null))
                    {
                        return(errors);
                    }
                    //FELint.CheckPrologeEventPointer(0, errors);
                }
            }
            else
            {//ver6
                if (InputFormRef.DoEvents(null, null))
                {
                    return(errors);
                }
                WorldMapEventPointerFE6Form.MakeCheckErrors(mapid, errors);

                if (mapid == 1)
                {
                    if (InputFormRef.DoEvents(null, null))
                    {
                        return(errors);
                    }
                    //FELint.CheckPrologeEventPointer(1, errors);
                }
            }

            return(errors);
        }
Example #23
0
        static void ScanSystem(List <FELint.ErrorSt> errors, List <DisassemblerTrumb.LDRPointer> ldrmap)
        {
            ROMCheck(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem ImageBattleAnimeForm"))
            {
                return;
            }
            ImageBattleAnimeForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem ImageBGForm"))
            {
                return;
            }
            ImageBGForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem UnitForm"))
            {
                return;
            }
            UnitForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem ClassForm"))
            {
                return;
            }
            ClassForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem ItemForm"))
            {
                return;
            }
            ItemForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem MoveCostForm"))
            {
                return;
            }
            MoveCostForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem PatchForm"))
            {
                return;
            }
            PatchForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem ImageUnitMoveIconFrom"))
            {
                return;
            }
            ImageUnitMoveIconFrom.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem ImageUnitWaitIconFrom"))
            {
                return;
            }
            ImageUnitWaitIconFrom.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem ItemEffectPointerForm"))
            {
                return;
            }
            ItemEffectPointerForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem ImageUnitPaletteForm"))
            {
                return;
            }
            ImageUnitPaletteForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem ImageBattleScreen"))
            {
                return;
            }
            ImageBattleScreenForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem ImageMagic"))
            {
                return;
            }
            ImageMagicFEditorForm.MakeCheckError(errors);
            ImageMagicCSACreatorForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem Procs"))
            {
                return;
            }
            ProcsScriptForm.MakeCheckError(errors, ldrmap);

            if (InputFormRef.DoEvents(null, "ScanSystem MenuDefinition"))
            {
                return;
            }
            MenuDefinitionForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem EventUnit"))
            {
                return;
            }
            EventUnitForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem AIScript"))
            {
                return;
            }
            AIScriptForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem SongTable"))
            {
                return;
            }
            SongTableForm.MakeCheckError(errors);

            if (InputFormRef.DoEvents(null, "ScanSystem ItemWeaponEffect"))
            {
                return;
            }
            ItemWeaponEffectForm.MakeCheckError(errors);

            if (Program.ROM.RomInfo.version() == 8)
            {
                if (InputFormRef.DoEvents(null, "ScanSystem SoundFootStepsForm"))
                {
                    return;
                }
                SoundFootStepsForm.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem ImagePortraitForm"))
                {
                    return;
                }
                ImagePortraitForm.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem EventHaikuForm"))
                {
                    return;
                }
                EventHaikuForm.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem EventBattleTalkForm"))
                {
                    return;
                }
                EventBattleTalkForm.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem SupportTalkForm"))
                {
                    return;
                }
                SupportTalkForm.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem SupportUnitForm"))
                {
                    return;
                }
                SupportUnitForm.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem SoundRoomForm"))
                {
                    return;
                }
                SoundRoomForm.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem EDForm"))
                {
                    return;
                }
                EDForm.MakeCheckError(errors);
            }
            else if (Program.ROM.RomInfo.version() == 7)
            {
                if (InputFormRef.DoEvents(null, "ScanSystem ImagePortraitForm"))
                {
                    return;
                }
                ImagePortraitForm.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem EventHaikuFE7Form"))
                {
                    return;
                }
                EventHaikuFE7Form.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem EventBattleTalkFE7Form"))
                {
                    return;
                }
                EventBattleTalkFE7Form.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem SupportTalkFE7Form"))
                {
                    return;
                }
                SupportTalkFE7Form.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem SupportUnitForm"))
                {
                    return;
                }
                SupportUnitForm.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem SoundRoomForm"))
                {
                    return;
                }
                SoundRoomForm.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem EDForm"))
                {
                    return;
                }
                EDFE7Form.MakeCheckError(errors);
            }
            else
            {
                if (InputFormRef.DoEvents(null, "ScanSystem ImagePortraitFE6Form"))
                {
                    return;
                }
                ImagePortraitFE6Form.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem EventHaikuFE6Form"))
                {
                    return;
                }
                EventHaikuFE6Form.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem EventBattleTalkFE6Form"))
                {
                    return;
                }
                EventBattleTalkFE6Form.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem SupportTalkFE6Form"))
                {
                    return;
                }
                SupportTalkFE6Form.MakeCheckError(errors);

                if (InputFormRef.DoEvents(null, "ScanSystem EDForm"))
                {
                    return;
                }
                EDFE6Form.MakeCheckError(errors);
            }
        }
Example #24
0
        public static void MakeLZ77DataList(List <Address> list)
        {
            //誤爆すると面倒なことになるフレームとOAMのデータ群
            Dictionary <uint, bool> ignoreDic = new Dictionary <uint, bool>();

            ImageBattleAnimeForm.MakeBattleFrameAndOAMDictionary(ignoreDic);
            SoundFootStepsForm.MakeIgnoreDictionary(ignoreDic);
            WorldMapPointForm.MakeIgnoreDictionary(ignoreDic);
            MakeIgnoreDictionnaryFromList(ignoreDic, list);

            string name   = R._("圧縮データ");
            uint   length = (uint)Program.ROM.Data.Length - 4;

            for (uint addr = 0x100; addr < length; addr += 4)
            {
                uint a = (uint)Program.ROM.Data[addr + 3];
                if (a != 0x08 && a != 0x09)
                {//ポインタ以外無視する.
                    continue;
                }
                a = Program.ROM.p32(addr);
                if (!U.isSafetyOffset(a))
                {//危険なポインタは無視
                    continue;
                }
                if (a < Program.ROM.RomInfo.compress_image_borderline_address)
                {
                    continue;
                }
                if (!U.isPadding4(a))
                {//4バイトパディングされていないlz77データはありえないとする.
                    continue;
                }

                if (ignoreDic.ContainsKey(a))
                {//戦闘アニメのフレーム,OAM等のlz77で圧縮されているデータ
                    continue;
                }

                //ポインタ先は圧縮されているか?
                uint imageDataSize = LZ77.getUncompressSize(Program.ROM.Data, a);
                if (IsBadImageSize(imageDataSize))
                {
                    continue;
                }

                //ポインタは連続してあらわれるのでそのチェックをする.
                if (!IsContinuousPointer(addr, length))
                {
                    continue;
                }

                uint getcompsize = LZ77.getCompressedSize(Program.ROM.Data, a);
                if (getcompsize == 0)
                {
                    continue;
                }

                //たぶん画像だと判断する.
                FEBuilderGBA.Address.AddAddress(list, a, getcompsize, addr, name + U.To0xHexString(a), Address.DataTypeEnum.LZ77IMG);
                if (InputFormRef.DoEvents(null, "MakeLZ77DataList " + U.ToHexString(addr)))
                {
                    return;
                }
            }
        }