public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); if (InputFormRef.DataCount < 10) { errors.Add(new FELint.ErrorSt(FELint.Type.PORTRAIT, U.NOT_FOUND , R._("顔画像が極端に少ないです。破損している可能性があります。"))); } uint portrait_addr = InputFormRef.BaseAddress; for (int i = 0; i < InputFormRef.DataCount; i++, portrait_addr += InputFormRef.BlockSize) { uint id = (uint)i; uint a0 = Program.ROM.p32(portrait_addr + 0); uint a4 = Program.ROM.p32(portrait_addr + 4); //uint a8 = Program.ROM.p32(portrait_addr + 8); //顔画像は圧縮されている. if (U.isSafetyOffset(a0)) { FELint.CheckLZ77(a0, errors, FELint.Type.PORTRAIT, portrait_addr, id); } } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); bool isFE6 = (Program.ROM.RomInfo.version == 6); uint table_addr = InputFormRef.BaseAddress; uint limit_count = Math.Min(InputFormRef.DataCount, Program.ROM.RomInfo.magic_effect_original_data_count); for (int i = 0; i < limit_count; i++, table_addr += InputFormRef.BlockSize) { uint id = (uint)i; uint asm = Program.ROM.u32(table_addr + 0); if (asm == 0) { if (isFE6) {//FE6 if (id == 0x0C || id == 0x0D) { continue; } } if (id == 0x32) {//CCアイテムは、0x00が設定されているため無視する continue; } } FELint.CheckASMPointer(asm, errors, FELint.Type.ITEM_EEFECT_POINTER, table_addr, id); } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); if (InputFormRef.DataCount < 10) { errors.Add(new FELint.ErrorSt(FELint.Type.BATTTLE_TALK, U.NOT_FOUND , R._("交戦会話が極端に少ないです。破損している可能性があります。"))); } List <uint> tracelist = new List <uint>(); uint battletalk_addr = InputFormRef.BaseAddress; for (uint i = 0; i < InputFormRef.DataCount; i++, battletalk_addr += InputFormRef.BlockSize) { uint flag = Program.ROM.u16(battletalk_addr + 6); FELint.CheckFlag(flag, errors, FELint.Type.BATTTLE_TALK, battletalk_addr, i); uint textid = Program.ROM.u16(battletalk_addr + 8); FELint.DeathQuoteTextMessage(textid, errors, FELint.Type.BATTTLE_TALK, battletalk_addr, i); if (textid <= 0) { uint event_addr = Program.ROM.u32(battletalk_addr + 12); FELint.CheckEventPointer(event_addr, errors, FELint.Type.BATTTLE_TALK, battletalk_addr, false, tracelist); } } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); if (InputFormRef.DataCount < 10) { errors.Add(new FELint.ErrorSt(FELint.Type.SONGTABLE, U.NOT_FOUND , R._("ソングテーブルが極端に少ないです。破損している可能性があります。"))); } uint songtable_addr = InputFormRef.BaseAddress; for (uint i = 0; i < InputFormRef.DataCount; i++, songtable_addr += InputFormRef.BlockSize) { uint song_header = Program.ROM.u32(songtable_addr + 0); if (song_header == 0) { continue; } FELint.CheckPointerAlien4(song_header, errors, FELint.Type.SONGTABLE, songtable_addr, i); uint song_priority = Program.ROM.u32(songtable_addr + 4); bool isMapBGM = (song_priority == 0x00010001); SongTrackForm.MakeCheckError(errors, i, U.toOffset(song_header), isMapBGM); } }
//FELintスキャン(スレッドで実行する) void ScanFELintByThread(List <DisassemblerTrumb.LDRPointer> ldrmap) { Dictionary <uint, List <FELint.ErrorSt> > newFELintCache = new Dictionary <uint, List <FELint.ErrorSt> >(); //システム全体の問題 { List <FELint.ErrorSt> errorList = FELint.ScanMAP(FELint.SYSTEM_MAP_ID, ldrmap); errorList = FELint.HiddenErrorFilter(errorList); newFELintCache[FELint.SYSTEM_MAP_ID] = errorList; } uint mapCount = MapSettingForm.GetDataCount(); for (int i = 0; i < mapCount; i++) { if (IsStopFlag) { return; } uint mapid = (uint)i; //このマップのエラースキャン List <FELint.ErrorSt> errorList = FELint.ScanMAP(mapid, ldrmap); errorList = FELint.HiddenErrorFilter(errorList); newFELintCache[mapid] = errorList; } UpdateFELintCache(newFELintCache); }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); if (InputFormRef.DataCount < 2) { errors.Add(new FELint.ErrorSt(FELint.Type.SUPPORT_TALK, U.NOT_FOUND , R._("支援会話が極端に少ないです。破損している可能性があります。"))); } uint battletalk_addr = InputFormRef.BaseAddress; for (int i = 0; i < InputFormRef.DataCount; i++, battletalk_addr += InputFormRef.BlockSize) { uint id = (uint)i; uint textid = Program.ROM.u32(battletalk_addr + 4); FELint.ConversationTextMessage(textid, errors, FELint.Type.SUPPORT_TALK, battletalk_addr, (uint)i); textid = Program.ROM.u32(battletalk_addr + 8); FELint.ConversationTextMessage(textid, errors, FELint.Type.SUPPORT_TALK, battletalk_addr, (uint)i); textid = Program.ROM.u32(battletalk_addr + 12); FELint.ConversationTextMessage(textid, errors, FELint.Type.SUPPORT_TALK, battletalk_addr, (uint)i); } }
//エラー検出 public static void MakeCheckErrors(uint mapid, List <FELint.ErrorSt> errors) { List <uint> tracelist = new List <uint>(); uint wmapid = MapSettingForm.GetWorldMapEventIDWhereMapID(mapid); if (wmapid == 0) {//存在しない return; } //FE7はINDEX uint p; InputFormRef InputFormRef = N_Init(null); p = InputFormRef.IDToAddr(wmapid); if (p == U.NOT_FOUND) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_WORLDMAP, U.NOT_FOUND , R._("対応するワールドマップイベント({0})が存在しません。", U.To0xHexString(wmapid)))); } else { uint event_addr = Program.ROM.u32(p); FELint.CheckEventPointer(event_addr, errors, FELint.Type.WORLDMAP_EVENT, p, true, tracelist); } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); ReInit(InputFormRef); FELint.CheckInputFormRefASM(InputFormRef, errors, true, FELint.Type.SOUND_FOOT_STEPS); }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { { InputFormRef ifr = N1_Init(null); uint addr = ifr.BaseAddress; for (uint i = 0; i < ifr.DataCount; i++, addr += ifr.BlockSize) { uint name = Program.ROM.u32(addr + 4); FELint.CheckText(name, "EDTITLE1", errors, FELint.Type.ED, addr, i); } } { InputFormRef ifr = N2_Init(null); uint addr = ifr.BaseAddress; for (uint i = 0; i < ifr.DataCount; i++, addr += ifr.BlockSize) { uint unitid1 = Program.ROM.u8(addr + 1); if (unitid1 == 0) { continue; } uint name = Program.ROM.u32(addr + 4); FELint.CheckText(name, "EDAFTER5", errors, FELint.Type.ED, addr, i); } } }
public static void MakeCheckErrorAddr(List <FELint.ErrorSt> errors, uint support_pointer, FELint.Type type, uint parentAddr, uint tag) { if (Program.ROM.RomInfo.version() == 6) { return; } FELint.CheckPointerOrNull(support_pointer, errors, type, parentAddr, tag); if (!U.isSafetyPointer(support_pointer)) { return; } uint addr = U.toOffset(support_pointer); if (!U.isSafetyOffset(addr + 24)) { errors.Add(new FELint.ErrorSt(type, parentAddr , R._("支援データの構造体サイズが足りません。\r\n不正なアドレス({0})を指定しています。", U.To0xHexString(support_pointer)), tag)); return; } uint support_partners = Program.ROM.u8(addr + 21); if (support_partners > SUPPORT_LIMIT) { errors.Add(new FELint.ErrorSt(type, parentAddr , R._("支援で登録できる人数は7人までです。それを上回る({0})人を、データ({1})で、指定しています。", support_partners, U.To0xHexString(support_pointer)), tag)); return; } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { PatchUtil.skill_system_enum skill = PatchUtil.SearchSkillSystem(); if (skill != PatchUtil.skill_system_enum.SkillSystem) { return; } InputFormRef ifr; uint baseiconP = FindIconPointer(); uint basetextP = FindTextPointer(); uint baseanimeP = FindAnimePointer(); if (baseiconP == U.NOT_FOUND) { return; } if (basetextP == U.NOT_FOUND) { return; } if (baseanimeP == U.NOT_FOUND) { return; } ifr = Init(null, basetextP); uint skill_addr = ifr.BaseAddress; for (uint i = 0; i < ifr.DataCount; i++, skill_addr += ifr.BlockSize) { uint name = Program.ROM.u16(skill_addr + 0); if (name == 0 || name == 0xFFFF) { continue; } FELint.CheckText(name, "DETAIL3", errors, FELint.Type.SKILL_CONFIG, skill_addr, i); } uint anime = Program.ROM.p32(baseanimeP); for (uint i = 0; i < ifr.DataCount; i++, anime += 4) { if (!U.isSafetyOffset(anime)) { break; } uint addr = Program.ROM.p32(anime); if (!U.isSafetyOffset(addr)) { continue; } ImageUtilSkillSystemsAnimeCreator.MakeCheckError(errors, addr, i); } }
//エラーチェック public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); uint addr = InputFormRef.BaseAddress; for (int i = 0; i < InputFormRef.DataCount; i++, addr += InputFormRef.BlockSize) { FELint.CheckLZ77ImagePointerOrNull(addr + 4 , errors, FELint.Type.IMAGE_UNIT_WAIT_ICON, addr, 32, 0, (uint)i); } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); if (InputFormRef.DataCount < 10) { errors.Add(new FELint.ErrorSt(FELint.Type.UNIT, U.NOT_FOUND , R._("ユニットデータが極端に少ないです。破損している可能性があります。"))); } uint base_pointer = Program.ROM.u32(Program.ROM.RomInfo.support_unit_pointer()); if (!U.isSafetyPointer(base_pointer)) { errors.Add(new FELint.ErrorSt(FELint.Type.UNIT, U.NOT_FOUND , R._("ユニット0x01の支援ポインタが無効です。この値は支援の起点となる値です。バニラの値から変更しないでください。"))); return; } //武器魔法混在パッチを適応しているか bool is_melee_range_fix = PatchUtil.SearchMeleeAndMagicFixPatch(); uint unit_addr = InputFormRef.BaseAddress; for (uint i = 0; i < InputFormRef.DataCount; i++, unit_addr += InputFormRef.BlockSize) { uint name = Program.ROM.u16(unit_addr + 0); FELint.CheckText(name, "NAME1", errors, FELint.Type.UNIT, unit_addr, i); uint info = Program.ROM.u16(unit_addr + 2); FELint.CheckText(info, "DETAIL3", errors, FELint.Type.UNIT, unit_addr, i); uint id = Program.ROM.u8(unit_addr + 4); if (name == 0 && id == 0) {//ただの使っていないデータ } else { FELint.CheckID(id, i + 1, errors, FELint.Type.UNIT, unit_addr, i); } if (is_melee_range_fix == false) {//武器魔法混在パッチがないので、混在のチェックをします if (isMeleeMagicMixAddr(unit_addr)) { errors.Add(new FELint.ErrorSt(FELint.Type.UNIT, unit_addr , R._("武器レベルで、近接と魔法を混在させています。\r\n混在を可能にするパッチを当てていない状態で、近接と魔法を混在すると、戦闘アニメが正しく動作しません。"), i)); } } uint support_pointer = Program.ROM.u32(unit_addr + 44); SupportUnitForm.MakeCheckErrorAddr(errors, support_pointer, FELint.Type.UNIT, unit_addr, i); } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); if (InputFormRef.DataCount < 10) { errors.Add(new FELint.ErrorSt(FELint.Type.ITEM, U.NOT_FOUND , R._("アイテムデータが極端に少ないです。破損している可能性があります。"))); } Dictionary <uint, U.AddrResult> itemWeaponEffectDic = ItemWeaponEffectForm.MakeDic(); uint item_addr = InputFormRef.BaseAddress; for (uint i = 0; i < InputFormRef.DataCount; i++, item_addr += InputFormRef.BlockSize) { uint name = Program.ROM.u16(item_addr + 0); FELint.CheckText(name, "NAME1", errors, FELint.Type.ITEM, item_addr, i); uint id = Program.ROM.u8(item_addr + 6); if (id == 0) {//ただの使っていないデータ continue; } if (i > 0) { uint info = Program.ROM.u16(item_addr + 2); uint info2 = Program.ROM.u16(item_addr + 4); uint type = Program.ROM.u8(item_addr + 7); uint attr1 = Program.ROM.u8(item_addr + 8); bool isEquip = (attr1 & 0x01) == 0x01; string errorMessage = ChcekTextItem1ErrorMessage(id, FETextDecode.Direct(info), info, type, isEquip); if (errorMessage != "") { errors.Add(new FELint.ErrorSt(FELint.Type.ITEM, U.toOffset(item_addr) , R._("TextID:{0}\r\n{1}", U.To0xHexString(info), errorMessage), i)); } errorMessage = ChcekTextItem2ErrorMessage(id, FETextDecode.Direct(info2), info2, type, isEquip); if (errorMessage != "") { errors.Add(new FELint.ErrorSt(FELint.Type.ITEM, U.toOffset(item_addr) , R._("TextID:{0}\r\n{1}", U.To0xHexString(info2), errorMessage), i)); } } //武器攻撃範囲のチェック MakeCheckErrorWeaponRange(itemWeaponEffectDic, item_addr, i, errors); } }
public static void CkeckMagicLZ77Pointer(uint pointer, ref List <FELint.ErrorSt> errors, uint magic_baseaddress, string name, uint magicindex) { uint imageOffset = U.u32(Program.ROM.Data, pointer); if (U.isPointer(imageOffset)) { imageOffset = U.toOffset(imageOffset); if (imageOffset == 0) { return; } FELint.CheckLZ77(imageOffset, errors, FELint.Type.MAGIC_ANIME_EXTENDS, magic_baseaddress, magicindex); } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { uint[] image_pos = new uint[] { Program.ROM.RomInfo.battle_screen_image1_pointer() , Program.ROM.RomInfo.battle_screen_image2_pointer() , Program.ROM.RomInfo.battle_screen_image3_pointer() , Program.ROM.RomInfo.battle_screen_image4_pointer() , Program.ROM.RomInfo.battle_screen_image5_pointer() }; for (int i = 0; i < image_pos.Length; i++) { FELint.CheckLZ77ImagePointer(image_pos[i], errors, FELint.Type.IMAGE_BATTLE_SCREEN, U.NOT_FOUND, 32, 8, (uint)i); } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); uint table_addr = InputFormRef.BaseAddress; uint limit_count = Math.Min(InputFormRef.DataCount, Program.ROM.RomInfo.magic_effect_original_data_count()); for (int i = 0; i < InputFormRef.DataCount; i++, table_addr += InputFormRef.BlockSize) { uint id = (uint)i; uint p = Program.ROM.p32(table_addr + 0xC); FELint.CheckLZ77(p, errors, FELint.Type.IMAGE_UNIT_PALETTE, table_addr, id); } }
//エラーチェック public static void MakeCheckError(List <FELint.ErrorSt> errors) { uint[] pointers = GetPointers(); InputFormRef InputFormRef = Init(null); for (int n = 0; n < pointers.Length; n++) { if (pointers[n] == 0) { continue; } InputFormRef.ReInitPointer(pointers[n]); uint p = InputFormRef.BaseAddress; for (uint i = 0; i < InputFormRef.DataCount; i++, p += InputFormRef.BlockSize) { string name = "MenuDef" + i + "_"; uint paddr; paddr = Program.ROM.p32(8 + p); if (!U.isSafetyOffset(paddr)) { continue; } FELint.CheckPointer(U.toPointer(paddr), errors, FELint.Type.MENU_DEFINE, p, i); MenuCommandForm.MakeCheckError(errors, 8 + p); paddr = Program.ROM.u32(12 + p); FELint.CheckASMPointerOrNull(paddr, errors, FELint.Type.MENU_DEFINE, p, i); paddr = Program.ROM.u32(16 + p); FELint.CheckASMPointerOrNull(paddr, errors, FELint.Type.MENU_DEFINE, p, i); paddr = Program.ROM.u32(20 + p); FELint.CheckASMPointerOrNull(paddr, errors, FELint.Type.MENU_DEFINE, p, i); paddr = Program.ROM.u32(24 + p); FELint.CheckASMPointerOrNull(paddr, errors, FELint.Type.MENU_DEFINE, p, i); paddr = Program.ROM.u32(28 + p); FELint.CheckASMPointerOrNull(paddr, errors, FELint.Type.MENU_DEFINE, p, i); paddr = Program.ROM.u32(32 + p); FELint.CheckASMPointerOrNull(paddr, errors, FELint.Type.MENU_DEFINE, p, i); } } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { { InputFormRef ifr = N2_Init(null); uint addr = ifr.BaseAddress; for (uint i = 0; i < ifr.DataCount; i++, addr += ifr.BlockSize) { uint name = Program.ROM.u16(addr + 0); FELint.CheckText(name, "FE6EDAFTER6", errors, FELint.Type.ED, addr, i); name = Program.ROM.u16(addr + 2); FELint.CheckText(name, "FE6EDAFTER6", errors, FELint.Type.ED, addr, i); name = Program.ROM.u16(addr + 6); FELint.CheckText(name, "EDTITLE1", errors, FELint.Type.ED, addr, i); } } }
public static void MakeCheckError(List <FELint.ErrorSt> errors, uint pointer) { InputFormRef InputFormRef = Init(null); InputFormRef.ReInitPointer(pointer); uint p = InputFormRef.BaseAddress; for (uint i = 0; i < InputFormRef.DataCount; i++, p += InputFormRef.BlockSize) { uint paddr; paddr = Program.ROM.u32(0 + p); FELint.CheckPointerOrNull(paddr, errors, FELint.Type.MENU, p, i); if (Program.ROM.RomInfo.is_multibyte() == false) { uint name = Program.ROM.u16(4 + p); FELint.CheckText(name, "MENUNAME1", errors, FELint.Type.MENU, p, i); } uint detail = Program.ROM.u16(6 + p); FELint.CheckText(detail, "MENUDETAIL3", errors, FELint.Type.MENU, p, i); paddr = Program.ROM.u32(12 + p); FELint.CheckASMPointerOrNull(paddr, errors, FELint.Type.MENU, p, i); paddr = Program.ROM.u32(16 + p); FELint.CheckASMPointerOrNull(paddr, errors, FELint.Type.MENU, p, i); paddr = Program.ROM.u32(20 + p); FELint.CheckASMPointerOrNull(paddr, errors, FELint.Type.MENU, p, i); paddr = Program.ROM.u32(24 + p); FELint.CheckASMPointerOrNull(paddr, errors, FELint.Type.MENU, p, i); paddr = Program.ROM.u32(28 + p); FELint.CheckASMPointerOrNull(paddr, errors, FELint.Type.MENU, p, i); paddr = Program.ROM.u32(32 + p); FELint.CheckASMPointerOrNull(paddr, errors, FELint.Type.MENU, p, i); } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); if (InputFormRef.DataCount < 10) { errors.Add(new FELint.ErrorSt(FELint.Type.UNIT, U.NOT_FOUND , R._("ユニットデータが極端に少ないです。破損している可能性があります。"))); } //武器魔法混在パッチを適応しているか bool is_melee_range_fix = PatchUtil.SearchMeleeAndMagicFixPatch(); uint unit_addr = InputFormRef.BaseAddress; for (uint i = 0; i < InputFormRef.DataCount; i++, unit_addr += InputFormRef.BlockSize) { uint name = Program.ROM.u16(unit_addr + 0); FELint.CheckText(name, "NAME1", errors, FELint.Type.UNIT, unit_addr, i); uint info = Program.ROM.u16(unit_addr + 2); FELint.CheckText(info, "DETAIL3", errors, FELint.Type.UNIT, unit_addr, i); uint id = Program.ROM.u8(unit_addr + 4); if (name == 0 && id == 0) {//ただの使っていないデータ } else { FELint.CheckID(id, i + 1, errors, FELint.Type.UNIT, unit_addr, i); } if (is_melee_range_fix == false) {//武器魔法混在パッチがないので、混在のチェックをします if (isMeleeMagicMixAddr(unit_addr)) { errors.Add(new FELint.ErrorSt(FELint.Type.UNIT, unit_addr , R._("武器レベルで、近接と魔法を混在させています。\r\n混在を可能にするパッチを当てていない状態で、近接と魔法を混在すると、戦闘アニメが正しく動作しません。"), i)); } } } }
//エラーチェック public static void MakeCheckError(List <FELint.ErrorSt> errors, uint anime_address, uint index = U.NOT_FOUND) { anime_address = U.toOffset(anime_address); if (!U.isSafetyOffset(anime_address)) { return; } string basename = "MapActionAnimation:" + U.To0xHexString(index) + " " + R._("行動アニメーションが破損しています。\r\n"); anime_address = U.toOffset(anime_address); if (!U.isSafetyOffset(anime_address)) { return; } //圧縮されていないデータなので、事故防止のため リミッターをかける. uint limitter = anime_address + 1024 * 1024; //1MBサーチしたらもうあきらめる. limitter = (uint)Math.Min(limitter, Program.ROM.Data.Length); uint n = anime_address; for (; n < limitter; n += 12) { uint term1 = Program.ROM.u32(n); uint imgOffset = Program.ROM.p32(n + 4); uint palOffset = Program.ROM.p32(n + 8); if (term1 == 0 && imgOffset == 0) { break; } FELint.CheckLZ77(imgOffset, errors, FELint.Type.MAP_ACTION_ANIMATION, anime_address, index); } if (n >= limitter) { errors.Add(new FELint.ErrorSt(FELint.Type.MAP_ACTION_ANIMATION, anime_address, basename + R._("データ終端がありませんでした。"), index)); return; } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); if (InputFormRef.DataCount < 10) { errors.Add(new FELint.ErrorSt(FELint.Type.BG, U.NOT_FOUND , R._("BGが極端に少ないです。破損している可能性があります。"))); } uint addr = InputFormRef.BaseAddress; for (int i = 0; i < InputFormRef.DataCount; i++, addr += InputFormRef.BlockSize) { uint image = Program.ROM.p32(0 + addr); if (U.isSafetyOffset(image)) { FELint.CheckLZ77(image, errors, FELint.Type.BG, addr, (uint)i); } } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { { InputFormRef InputFormRef = Init(null); if (InputFormRef.DataCount < 2) { errors.Add(new FELint.ErrorSt(FELint.Type.BATTTLE_TALK, U.NOT_FOUND , R._("交戦会話が極端に少ないです。破損している可能性があります。"))); } uint battletalk_addr = InputFormRef.BaseAddress; for (uint i = 0; i < InputFormRef.DataCount; i++, battletalk_addr += InputFormRef.BlockSize) { uint flag = Program.ROM.u16(battletalk_addr + 8); FELint.CheckFlagErrors(flag, errors, FELint.Type.BATTTLE_TALK, battletalk_addr, i); uint textid = Program.ROM.u16(battletalk_addr + 4); FELint.DeathQuoteTextMessage(textid, errors, FELint.Type.BATTTLE_TALK, battletalk_addr, i); } } { InputFormRef InputFormRef = N_Init(null); if (InputFormRef.DataCount < 2) { errors.Add(new FELint.ErrorSt(FELint.Type.BATTTLE_TALK, U.NOT_FOUND , R._("交戦会話が極端に少ないです。破損している可能性があります。"))); } uint battletalk_addr = InputFormRef.BaseAddress; for (uint i = 0; i < InputFormRef.DataCount; i++, battletalk_addr += InputFormRef.BlockSize) { uint flag = Program.ROM.u16(battletalk_addr + 8); FELint.CheckFlagErrors(flag, errors, FELint.Type.BATTTLE_TALK, battletalk_addr, i); uint textid = Program.ROM.u16(battletalk_addr + 4); FELint.DeathQuoteTextMessage(textid, errors, FELint.Type.BATTTLE_TALK, battletalk_addr, i); } } }
public static void MakeCheckError(List <FELint.ErrorSt> errors, List <DisassemblerTrumb.LDRPointer> ldrmap) { List <Address> procs = new List <Address>(); FindProc find = new FindProc(procs, ldrmap); //Procsに付属するデータを発見する foreach (Address a in procs) { uint addr = a.Addr; uint end = addr + a.Length; for (; addr < end; addr += 8) { uint code = Program.ROM.u8(addr); if (ProcsScriptForm.hasASMRoutine(code)) {//呼び出しているASM関数 uint arg = Program.ROM.u32(addr + 4); if (arg != 0) { FELint.CheckASMPointer(arg, errors, FELint.Type.PROCS, a.Addr, addr); } } else if (ProcsScriptForm.hasChildProcs(code)) {//子Procsの確認 uint arg = Program.ROM.u32(addr + 4); if (arg != 0) { FELint.CheckProcsPointer(arg, errors, FELint.Type.PROCS, a.Addr, addr); } } else if (code == 0x01) {//Set name uint name = Program.ROM.u32(addr + 4); FELint.CheckText(name, "PROCS", errors, FELint.Type.SOUNDROOM, a.Addr, addr); } } } }
public static void MakeCheckErrorAddr(List <FELint.ErrorSt> errors, uint support_pointer, FELint.Type type, uint parentAddr, uint tag) { if (Program.ROM.RomInfo.version == 6) { return; } FELint.CheckPointerOrNull(support_pointer, errors, type, parentAddr, tag); if (!U.isSafetyPointer(support_pointer)) { return; } uint addr = U.toOffset(support_pointer); if (!U.isSafetyOffset(addr + 24)) { errors.Add(new FELint.ErrorSt(type, parentAddr , R._("支援データの構造体サイズが足りません。\r\n不正なアドレス({0})を指定しています。", U.To0xHexString(support_pointer)), tag)); return; } if (!CheckIfSupportDataToStrangePointer(addr)) { errors.Add(new FELint.ErrorSt(type, parentAddr , R._("支援データにめちゃくちゃな値({0})が格納されています。\r\n支援ポインタが正しくない値を指しているようです。\r\nこのユニットの支援ポインタを0に変更し、設定し直すことを推奨します。", U.ToHexString(support_pointer)) , tag)); return; } uint support_partners = Program.ROM.u8(addr + 21); if (support_partners > SUPPORT_LIMIT) { errors.Add(new FELint.ErrorSt(type, parentAddr , R._("支援で登録できる人数は7人までです。それを上回る({0})人を、データ({1})で、指定しています。", support_partners, U.To0xHexString(support_pointer)), tag)); return; } }
//エラー検出 public static void MakeCheckErrors(uint mapid, List <FELint.ErrorSt> errors) { List <uint> tracelist = new List <uint>(); uint wmapid = MapSettingForm.GetWorldMapEventIDWhereMapID(mapid); if (wmapid == 0) {//存在しない return; } //FE6はPLISTが格納されている. uint p; uint event_addr = MapPointerForm.PlistToOffsetAddrFast(MapPointerForm.PLIST_TYPE.WORLDMAP_FE6ONLY, wmapid, out p); if (event_addr == U.NOT_FOUND) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_WORLDMAP, U.NOT_FOUND , R._("対応するワールドマップイベント({0})が存在しません。", U.To0xHexString(wmapid)))); } else { FELint.CheckEvent(event_addr, errors, FELint.Type.WORLDMAP_EVENT, p, true, tracelist); } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); if (InputFormRef.DataCount < 10) { errors.Add(new FELint.ErrorSt(FELint.Type.SOUNDROOM, U.NOT_FOUND , R._("サウンドルームが極端に少ないです。破損している可能性があります。"))); } uint soundroom_addr = InputFormRef.BaseAddress; for (uint i = 0; i < InputFormRef.DataCount; i++, soundroom_addr += InputFormRef.BlockSize) { uint name = Program.ROM.u32(soundroom_addr + 12); FELint.CheckText(name, "SOUND1", errors, FELint.Type.SOUNDROOM, soundroom_addr, i); uint asm = Program.ROM.u32(soundroom_addr + 8); if (asm != 0) { FELint.CheckASMPointer(asm, errors, FELint.Type.SOUNDROOM, soundroom_addr); } } }
public static void MakeCheckError(List <FELint.ErrorSt> errors) { InputFormRef InputFormRef = Init(null); if (InputFormRef.DataCount < 10) { errors.Add(new FELint.ErrorSt(FELint.Type.HAIKU, U.NOT_FOUND , R._("死亡セリフが極端に少ないです。破損している可能性があります。"))); } uint haiku_addr = InputFormRef.BaseAddress; for (uint i = 0; i < InputFormRef.DataCount; i++, haiku_addr += InputFormRef.BlockSize) { uint flag = Program.ROM.u16(haiku_addr + 8); FELint.CheckFlag(flag, errors, FELint.Type.HAIKU, haiku_addr, i); uint textid = Program.ROM.u16(haiku_addr + 4); FELint.DeathQuoteTextMessage(textid, errors, FELint.Type.HAIKU, haiku_addr, i); textid = Program.ROM.u16(haiku_addr + 12); FELint.ConversationTextMessage(textid, errors, FELint.Type.HAIKU, haiku_addr, i); } }
void Scan() { using (InputFormRef.AutoPleaseWait pleaseWait = new InputFormRef.AutoPleaseWait(this)) { List <DisassemblerTrumb.LDRPointer> ldrmap = Program.AsmMapFileAsmCache.GetLDRMapCache(); this.ErrorList = FELint.ScanMAP(this.MapID, ldrmap); if (!this.ShowAllError.Checked) { this.ErrorList = FELint.HiddenErrorFilter(this.ErrorList); } this.EventList.DummyAlloc(this.ErrorList.Count, -1); if (this.ErrorList.Count > 0) { if (this.ShowAllError.Checked) { this.Explain.Text = R._("すべてのエラーを表示しています。非表示にしたエラーを再表示する場合、右クリックしてください。"); } else { this.Explain.Text = R._("ダブルクリックでエラーに移動します。誤検出の場合は、右クリックして、エラーを非表示にできます。"); } } else { this.Explain.Text = R._("すべてのエラーが解決されました。"); if (Program.AsmMapFileAsmCache != null) {//まれにすべてのエラーを解決しても、メインフォームが更新されない時があるので、喝入れを行う. Program.AsmMapFileAsmCache.UpdateFELintCache_NoError(); } } } }