示例#1
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);
        }
示例#2
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);
        }
示例#3
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);
//            }
        }
示例#4
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("");
        }
示例#5
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);
        }
示例#6
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));
        }
示例#7
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);
            }
        }