예제 #1
0
        static InputFormRef Init(Form self)
        {
            return(new InputFormRef(self
                                    , ""
                                    , Program.ROM.RomInfo.mask_pointer()
                                    , 4
                                    , (int i, uint addr) =>
            {
                return Program.ROM.u8(addr) != 255;
            }
                                    , (int i, uint addr) =>
            {
                uint c = Program.ROM.u16(addr);

                string str = Program.ROM.getString(addr, 2);
                if (!Program.ROM.RomInfo.is_multibyte())
                {
                    if (c >= 0x81 && c <= 0xFF)
                    {    //英語版FEにはUnicodeの1バイトだけ表記があるらしい.
                        str = "@00" + c.ToString("X02");
                    }
                }

                str = FETextEncode.RevConvertSPMoji(str);
                return i.ToString("X04") + " " + c.ToString("X04") + " " + str;
            }
                                    ));
        }
예제 #2
0
        static uint CheckMoveToUnuseSpaceTop(
            uint index_start_addr                                                       //indexの開始
            , uint index_end_addr                                                       //indexの終端
            , uint data_start_addr                                                      //データの開始
            , uint data_end_addr                                                        //データの終端
            , Func <uint, bool, MoveToUnuseSpace.ADDR_AND_LENGTH> get_data_pos_callback //データサイズを求める.
            )
        {
            uint free_size = 0;

            for (uint addr = index_start_addr; addr < index_end_addr; addr += 4)
            {
                //uHuffman patchを使っているかどうか.
                bool useUnHuffmanPatch = false;

                uint data_s = Program.ROM.u32(addr);
                if (!U.isPointer(data_s))
                {     //ポインタではない
                    if (!FETextEncode.IsUnHuffmanPatchPointer(data_s))
                    { //不明
                        continue;
                    }
                    //unHuffman patch適応データ
                    useUnHuffmanPatch = true;
                    data_s            = FETextEncode.ConvertUnHuffmanPatchToPointer(data_s);
                }
                data_s = U.toOffset(data_s);

                ADDR_AND_LENGTH aal = get_data_pos_callback(data_s, useUnHuffmanPatch);
                if (aal.addr < data_start_addr || aal.addr + aal.length > data_end_addr)
                {            //独自拡張され、データ領域以外に設置されている.
                    continue;
                }
                if (aal.length >= 0x00200000)
                {//長すぎる.
                    continue;
                }
                uint aaladdr = aal.addr + aal.length;

                //次のデータのポインタを取得
                uint next_addr = Program.ROM.u32(addr + 4);
                if (FETextEncode.IsUnHuffmanPatchPointer(next_addr))
                {
                    next_addr = FETextEncode.ConvertUnHuffmanPatchToPointer(next_addr);
                }
                next_addr = U.toOffset(next_addr);
                if (next_addr == aaladdr)
                {//ちょうど利用している.空き領域なし.次に行ってみよう.
                    continue;
                }
                if (next_addr < aaladdr)
                {//アドレスが逆転している...放置
                    continue;
                }

                //フリーサイズ
                free_size += (next_addr - aaladdr);
            }
            return(free_size);
        }
예제 #3
0
        static bool RunMoveToUnuseSpaceTop(
            uint index_start_addr                                                       //indexの開始
            , uint index_end_addr                                                       //indexの終端
            , uint data_start_addr                                                      //データの開始
            , uint data_end_addr                                                        //データの終端
            , Func <uint, bool, MoveToUnuseSpace.ADDR_AND_LENGTH> get_data_pos_callback //データサイズを求める.
            , List <Undo.UndoPostion> undolist
            )
        {
            uint use_data_addr = data_start_addr;
            uint addr;

            for (addr = index_start_addr; addr < index_end_addr; addr += 4)
            {
                //uHuffman patchを使っているかどうか.
                bool useUnHuffmanPatch = false;

                uint data_s = Program.ROM.u32(addr);
                if (!U.isPointer(data_s))
                {     //ポインタではない
                    if (!FETextEncode.IsUnHuffmanPatchPointer(data_s))
                    { //不明
                        continue;
                    }
                    //unHuffman patch適応データ
                    useUnHuffmanPatch = true;
                    data_s            = FETextEncode.ConvertUnHuffmanPatchToPointer(data_s);
                }
                data_s = U.toOffset(data_s);

                ADDR_AND_LENGTH aal = get_data_pos_callback(data_s, useUnHuffmanPatch);
                if (aal.addr < data_start_addr || aal.addr + aal.length > data_end_addr)
                {//独自拡張され、データ領域以外に設置されている.
                    //無視して次行ってみよう.
                    continue;
                }

                //空き領域を作るためにデータを移動 movemem
                byte[] original = Program.ROM.getBinaryData(aal.addr, aal.length);
                undolist.Add(new Undo.UndoPostion(aal.addr, original));
                Program.ROM.write_range(use_data_addr, original);

                //移動したので挿げ替え.
                undolist.Add(new Undo.UndoPostion(addr, 4));
                if (useUnHuffmanPatch)
                {
                    Program.ROM.write_u32(addr, FETextEncode.ConvertPointerToUnHuffmanPatchPointer(U.toPointer(use_data_addr)));
                }
                else
                {
                    Program.ROM.write_p32(addr, use_data_addr);
                }

                use_data_addr += aal.length;
            }

            return(true);
        }
예제 #4
0
        void AddRecycle(uint id, List <Address> list)
        {
            //無効なID
            if (id <= 0)
            {
                return;
            }
            if (id < this.MaxTextCount)
            {
                uint addr  = this.TextBaseAddress + (id * 4);
                uint paddr = Program.ROM.u32(addr);
                if (TextForm.Is_RAMPointerArea(paddr))
                {
                    return;
                }
                uint data_addr;

                int length;
                if (FETextEncode.IsUnHuffmanPatchPointer(paddr))
                {//un-huffman patch?
                    uint unhuffman_addr = U.toOffset(FETextEncode.ConvertUnHuffmanPatchToPointer(paddr));
                    data_addr = unhuffman_addr;
                    TextDecode.UnHffmanPatchDecode(unhuffman_addr, out length);
                }
                else if (U.isPointer(paddr))
                {
                    data_addr = U.toOffset(paddr);
                    TextDecode.huffman_decode(data_addr, out length);
                }
                else
                {
                    return;
                }

                if (length <= 0)
                {
                    return;
                }
                if (data_addr == this.TextID0Addr)
                {
                    return;
                }
                FEBuilderGBA.Address.AddAddress(list
                                                , data_addr
                                                , (uint)length
                                                , U.NOT_FOUND
                                                , "text " + U.ToHexString(id)
                                                , FEBuilderGBA.Address.DataTypeEnum.BIN);
            }
//CStringに対しては、リサイクルバッファを利用する方式を利用しない
//なぜなら、FE6には大量のポインタ参照があるためです。
//容量も大きくないので、メリットよりデメリットの方が上回る
//            else if (U.isSafetyPointer(id))
//            {
//                uint p = U.toOffset(id);
//                FEBuilderGBA.Address.AddCString(list, p);
//            }
        }
예제 #5
0
        public String DecodeAddr(uint addr, out int out_DataSize)
        {
            addr = U.toOffset(addr);
            if (!U.isSafetyOffset(addr, this.ROM))
            {
                out_DataSize = 0;
                return("");
            }
            uint paddr = this.ROM.u32(addr);

            if (FETextEncode.IsUnHuffmanPatchPointer(paddr))
            {//un-huffman patch?
                uint unhuffman_addr = U.toOffset(FETextEncode.ConvertUnHuffmanPatchToPointer(paddr));
                return(UnHffmanPatchDecode(unhuffman_addr, out out_DataSize));
            }
            else if (U.isPointer(paddr))
            {
                return(huffman_decode(U.toOffset(paddr), out out_DataSize));
            }
            out_DataSize = 0;
            return("");
        }
예제 #6
0
        //改造ROMだとデータを共有している場合があるので、本当にそのサイズは正しいのか、
        //すべての文字列データから再検証します。
        //遅くなるけど、これは必須です。
        static uint ConvertSafetyLength(
            uint length
            , uint index_start_addr  //indexの開始
            , uint index_end_addr    //indexの終端
            , uint data_s            //入れたいデータのアドレス
            )
        {
            //念のため、その範囲からスタートするポインタがないか確認します.
            //tlpとか、途中からアドレスが逆転していることがあるらしいので。
            for (uint p = index_start_addr; p < index_end_addr; p += 4)
            {
                uint data_s_dupcheck = Program.ROM.u32(p);
                if (!U.isPointer(data_s_dupcheck))
                {
                    if (!FETextEncode.IsUnHuffmanPatchPointer(data_s_dupcheck))
                    {//ポインタが不明
                        continue;
                    }
                    data_s_dupcheck = FETextEncode.ConvertUnHuffmanPatchToPointer(data_s_dupcheck);
                }
                data_s_dupcheck = U.toOffset(data_s_dupcheck);
                if (data_s_dupcheck == data_s)
                {//自分自身
                    continue;
                }

                if (data_s_dupcheck >= data_s && data_s_dupcheck < data_s + length)
                {//データを共有しているらしいので、サイズを切り詰めないとダメだ.
                    uint new_length = data_s_dupcheck - data_s;
                    if (new_length < length)
                    {//より小さくなる場合は、縮める.
                        length = new_length;
                    }
                }
            }

            return(length);
        }
예제 #7
0
        void WriteTextUnHffman(uint id, string text, 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  = this.Recycle.Write(encode, undodata);

            if (newaddr == U.NOT_FOUND)
            {
                return;
            }
            newaddr = U.toPointer(newaddr);
            newaddr = FETextEncode.ConvertPointerToUnHuffmanPatchPointer(newaddr);
            Program.ROM.write_u32(addr, newaddr, undodata);
        }
예제 #8
0
        public static uint OriginalDataSize(
            uint index_start_addr                                                       //indexの開始
            , uint index_end_addr                                                       //indexの終端
            , uint data_start_addr                                                      //データの開始
            , uint data_end_addr                                                        //データの終端
            , uint now_index                                                            //データを入れたいindex場所
            , Func <uint, bool, MoveToUnuseSpace.ADDR_AND_LENGTH> get_data_pos_callback //データサイズを求める.
            )
        {
            //uHuffman patchを使っているかどうか.
            bool useUnHuffmanPatch = false;

            uint addr   = index_start_addr + (now_index * 4);
            uint data_s = Program.ROM.u32(addr);

            //他と共有していないか調べる.
            for (uint p = index_start_addr; p < index_end_addr; p += 4)
            {
                uint data_s2 = Program.ROM.u32(p);
                if (p == addr)
                {
                    continue;
                }
                if (data_s2 == data_s)
                {//他と共有しているのでリサイクルしてはいけません.
                    return(0);
                }
            }

            if (!U.isPointer(data_s))
            {//ポインタではない 単体データ
                if (!FETextEncode.IsUnHuffmanPatchPointer(data_s))
                {
                    MoveToUnuseSpace.ADDR_AND_LENGTH aal = get_data_pos_callback(data_s, false);
                    return(ConvertSafetyLength(aal.length, index_start_addr, index_end_addr, data_s));
                }
                //unHuffman patch適応データ
                useUnHuffmanPatch = true;
                data_s            = FETextEncode.ConvertUnHuffmanPatchToPointer(data_s);
            }

            data_s = U.toOffset(data_s);
            if (data_s < data_start_addr || data_s >= data_end_addr)
            {//拡張領域にあるらしいので基底サイズは不明. 自サイズしかわからない.
                MoveToUnuseSpace.ADDR_AND_LENGTH aal = get_data_pos_callback(data_s, useUnHuffmanPatch);
                return(ConvertSafetyLength(aal.length, index_start_addr, index_end_addr, data_s));
            }

            uint i = 1;
            uint data_s_next;

            do
            {
                uint next_addr = index_start_addr + ((now_index + i) * 4);
                data_s_next = Program.ROM.u32(next_addr);

                if (!U.isPointer(data_s_next))
                {
                    if (!FETextEncode.IsUnHuffmanPatchPointer(data_s_next))
                    {//次のポインタが不明なので自サイズしかわからない.
                        MoveToUnuseSpace.ADDR_AND_LENGTH aal = get_data_pos_callback(data_s, useUnHuffmanPatch);
                        return(ConvertSafetyLength(aal.length, index_start_addr, index_end_addr, data_s));
                    }
                    //unHuffman patch適応データ
                    useUnHuffmanPatch = true;
                    data_s_next       = FETextEncode.ConvertUnHuffmanPatchToPointer(data_s_next);
                }
                data_s_next = U.toOffset(data_s_next);
                if (data_s_next < data_start_addr || data_s_next >= data_end_addr)
                {//拡張領域にあるらしいので次のデータを参照したい
                    i++;
                    continue;
                }
                if (data_s_next < data_s)
                {
                    //アドレスが逆転してます. 危険なので自分のデータの長さだけを求めます.input
                    MoveToUnuseSpace.ADDR_AND_LENGTH aal = get_data_pos_callback(data_s, useUnHuffmanPatch);
                    return(ConvertSafetyLength(aal.length, index_start_addr, index_end_addr, data_s));
                }
                break;
            }while(true);

            uint length = data_s_next - data_s;

            return(ConvertSafetyLength(length, index_start_addr, index_end_addr, data_s));
        }
예제 #9
0
        String CString(uint p, out int out_DataSize)
        {
            string str = this.ROM.getString(p, out out_DataSize);

            return(FETextEncode.RevConvertSPMoji(str));
        }
예제 #10
0
        String listbyte_to_string_low(byte[] str, int len)
        {
            string r = this.SystemTextEncoder.Decode(str, 0, len);

            return(FETextEncode.RevConvertSPMoji(r));
        }
예제 #11
0
 static void ReBuildFETextEncoder()
 {
     FETextEncoder = new FETextEncode();
 }
예제 #12
0
        void AddRecycle(uint id, List <Address> recycle)
        {
            //無効なID
            if (id <= 0)
            {
                return;
            }
            if (id < this.MaxTextCount)
            {
                uint addr  = this.TextBaseAddress + (id * 4);
                uint paddr = Program.ROM.u32(addr);
                if (TextForm.Is_RAMPointerArea(paddr))
                {
                    return;
                }
                uint data_addr;

                int length;
                if (FETextEncode.IsUnHuffmanPatchPointer(paddr))
                {//un-huffman patch?
                    uint unhuffman_addr = U.toOffset(FETextEncode.ConvertUnHuffmanPatchToPointer(paddr));
                    data_addr = unhuffman_addr;
                    TextDecode.UnHffmanPatchDecode(unhuffman_addr, out length);
                }
                else if (U.isPointer(paddr))
                {
                    data_addr = U.toOffset(paddr);
                    TextDecode.huffman_decode(data_addr, out length);
                }
                else
                {
                    return;
                }

                if (length <= 0)
                {
                    return;
                }
                if (data_addr == this.TextID0Addr)
                {
                    return;
                }
                FEBuilderGBA.Address.AddAddress(recycle
                                                , data_addr
                                                , (uint)length
                                                , U.NOT_FOUND
                                                , "text " + U.ToHexString(id)
                                                , FEBuilderGBA.Address.DataTypeEnum.BIN);
            }
            else if (U.isSafetyPointer(id))
            {
                uint data_addr = Program.ROM.p32(U.toOffset(id));
                if (!U.isSafetyOffset(id))
                {
                    return;
                }

                int    length = 0;
                string str    = Program.ROM.getString(data_addr, out length);

                FEBuilderGBA.Address.AddAddress(recycle
                                                , data_addr
                                                , (uint)length
                                                , U.NOT_FOUND
                                                , "CString " + U.To0xHexString(id)
                                                , FEBuilderGBA.Address.DataTypeEnum.BIN);
            }
        }