public static magic_system_enum SearchMagicSystem()
 {
     if (g_Cache_magic_system_enum == magic_system_enum.NoCache)
     {
         g_Cache_magic_system_enum = SearchMagicSystemLow();
     }
     return(g_Cache_magic_system_enum);
 }
        //魔法拡張は大量の0x00地帯が生れるので、フリー領域と誤認しないように確認する.
        public static bool IsMagicArea(ref uint addr)
        {
            magic_system_enum magicType = SearchMagicSystem();

            if (magicType == magic_system_enum.NO)
            {
                return(false);
            }
            uint csaSpellTable, csaSpellTablePointer;

            if (magicType == magic_system_enum.CSA_CREATOR)
            {
                csaSpellTable = ImageUtilMagic.FindCSASpellTable("SCA_Creator", out csaSpellTablePointer);
            }
            else if (magicType == magic_system_enum.FEDITOR_ADV)
            {
                csaSpellTable = ImageUtilMagic.FindCSASpellTable("FEditor", out csaSpellTablePointer);
            }
            else
            {
                Debug.Assert(false);
                return(false);
            }

            uint effect_table_addr = Program.ROM.p32(Program.ROM.RomInfo.magic_effect_pointer());

            if (!U.isSafetyOffset(effect_table_addr))
            {
                return(false);
            }

            uint end = effect_table_addr + (0x4 * 0xff);

            if (addr >= effect_table_addr && addr < end)
            {
                addr = end;
                return(true);
            }
            end = csaSpellTable + (0x4 * 0x5 * 0xff);
            if (addr >= csaSpellTable && addr < end)
            {
                addr = end;
                return(true);
            }
            return(false);
        }
        //魔法拡張は大量の0x00地帯が生れるので、フリー領域と誤認しないように確認する.
        public static bool IsMagicArea(ref uint addr)
        {
            magic_system_enum magicType = SearchMagicSystem();

            if (magicType == magic_system_enum.NO)
            {
                return(false);
            }
            uint csaSpellTable = ImageUtilMagic.GetCSASpellTableAddr();

            if (csaSpellTable == U.NOT_FOUND)
            {
                return(false);
            }

            uint effect_table_addr = Program.ROM.p32(Program.ROM.RomInfo.magic_effect_pointer);

            if (!U.isSafetyOffset(effect_table_addr))
            {
                return(false);
            }

            uint end = effect_table_addr + (0x4 * 0xff);

            if (addr >= effect_table_addr && addr < end)
            {
                addr = end;
                return(true);
            }
            end = csaSpellTable + (0x4 * 0x5 * 0xff);
            if (addr >= csaSpellTable && addr < end)
            {
                addr = end;
                return(true);
            }
            return(false);
        }
        public static magic_system_enum SearchMagicSystem(out uint baseaddr, out uint dimaddr, out uint nodimaddr)
        {
            MagicPatchTableSt[] table = new MagicPatchTableSt[] {
                new MagicPatchTableSt {
                    name = "SCA_Creator", ver = "FE8U", addr = 0x95d780, data = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x90, 0xD7, 0x95, 0x08, 0x03, 0x00, 0x00, 0x00, 0xD9, 0xD8, 0x95, 0x08 }, dim = 0x95d7ed, no_dim = 0x95d899
                },
                new MagicPatchTableSt {
                    name = "FEditor", ver = "FE8U", addr = 0x95d780, data = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x90, 0xD7, 0x95, 0x08, 0x03, 0x00, 0x00, 0x00, 0x39, 0xD9, 0x95, 0x08 }, dim = 0x95D7ED, no_dim = 0x95D8EF
                },
                new MagicPatchTableSt {
                    name = "SCA_Creator", ver = "FE8J", addr = 0x9cd3bc, data = new byte[] { 0x01, 0x00, 0x00, 0x00, 0xCC, 0xD3, 0x9C, 0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xD5, 0x9C, 0x08 }, dim = 0x9CD429, no_dim = 0x9CD4D5
                },
                new MagicPatchTableSt {
                    name = "SCA_Creator", ver = "FE8J", addr = 0x5BDC80, data = new byte[] { 0x01, 0x00, 0x00, 0x00, 0xCC, 0xD3, 0x9C, 0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xD5, 0x9C, 0x08 }, dim = 0x5BDCED, no_dim = 0x5BDD99
                },                                                                                                                                                                                                                                      //fixed version
                new MagicPatchTableSt {
                    name = "FEditor", ver = "FE8J", addr = 0xEFBE00, data = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x10, 0xBE, 0xEF, 0x08, 0x03, 0x00, 0x00, 0x00, 0xB9, 0xBF, 0xEF, 0x08 }, dim = 0xEFBE6D, no_dim = 0xEFBF6F
                },
                new MagicPatchTableSt {
                    name = "SCA_Creator", ver = "FE7U", addr = 0xCB680, data = new byte[] { 0x19, 0x00, 0x00, 0x00, 0x90, 0xB6, 0x0C, 0x08, 0x03, 0x00, 0x00, 0x00, 0xD9, 0xB7, 0x0C, 0x08 }, dim = 0xCB6ED, no_dim = 0xCB799
                },
                new MagicPatchTableSt {
                    name = "FEditor", ver = "FE7U", addr = 0xCB680, data = new byte[] { 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xD9, 0xB7, 0x0C, 0x08 }, dim = 0xCB699, no_dim = 0xCB787
                },
                new MagicPatchTableSt {
                    name = "FEditor", ver = "FE7J", addr = 0xC69B4, data = new byte[] { 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x29, 0x6B, 0x0C, 0x08 }, dim = 0xC69CD, no_dim = 0xC69CD
                },
                new MagicPatchTableSt {
                    name = "SCA_Creator", ver = "FE6", addr = 0x2DC078, data = new byte[] { 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x61, 0xC1, 0x2D, 0x08 }, dim = 0x2DC091, no_dim = 0x2dc129
                },
                new MagicPatchTableSt {
                    name = "FEditor", ver = "FE6", addr = 0x2DC078, data = new byte[] { 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC5, 0xC1, 0x2D, 0x08 }, dim = 0x2dc091, no_dim = 0x2DC17F
                },
            };

            string version = Program.ROM.RomInfo.VersionToFilename;

            foreach (MagicPatchTableSt t in table)
            {
                if (t.ver != version)
                {
                    continue;
                }

                byte[] data = Program.ROM.getBinaryData(t.addr, t.data.Length);
                if (U.memcmp(t.data, data) != 0)
                {
                    continue;
                }
                if (t.name == "FEditor")
                {
                    g_Cache_CSASpellTableAddr = FindCSASpellTableLow("FEditor", out g_Cache_CSASpellTablePointer);
                    if (g_Cache_CSASpellTablePointer == U.NOT_FOUND)
                    {//テーブルが見つからないので、ぶっ壊れている
                        continue;
                    }

                    baseaddr  = t.addr;
                    dimaddr   = t.dim;
                    nodimaddr = t.no_dim;
                    g_Cache_magic_system_enum = magic_system_enum.FEDITOR_ADV;
                    return(g_Cache_magic_system_enum);
                }
                if (t.name == "SCA_Creator")
                {
                    g_Cache_CSASpellTableAddr = FindCSASpellTableLow("SCA_Creator", out g_Cache_CSASpellTablePointer);
                    if (g_Cache_CSASpellTablePointer == U.NOT_FOUND)
                    {//テーブルが見つからないので、ぶっ壊れている
                        continue;
                    }

                    baseaddr  = t.addr;
                    dimaddr   = t.dim;
                    nodimaddr = t.no_dim;
                    g_Cache_magic_system_enum = magic_system_enum.CSA_CREATOR;
                    return(g_Cache_magic_system_enum);
                }
            }
            baseaddr  = U.NOT_FOUND;
            dimaddr   = U.NOT_FOUND;
            nodimaddr = U.NOT_FOUND;
            g_Cache_magic_system_enum = magic_system_enum.NO;
            return(g_Cache_magic_system_enum);
        }
 public static void ClearCache()
 {
     g_Cache_magic_system_enum    = magic_system_enum.NoCache;
     g_Cache_CSASpellTableAddr    = U.NOT_FOUND;
     g_Cache_CSASpellTablePointer = U.NOT_FOUND;
 }