static bool IsWarpChapterFE8(uint chapterID) { PatchUtil.mnc2_fix_enum use_mnc2 = PatchUtil.SearchSkipWorldMapPatch(); if (use_mnc2 == PatchUtil.mnc2_fix_enum.NO) { if (MapLoadFunctionForm.IsEnterChapterAlways(chapterID)) { return(true); } } return(true); }
public static bool CheckAndShowPopupDialog(TYPE type) { Func <bool> checkFunc = null; string reason = ""; string patchName1 = ""; string patchName2 = ""; string patchShowName = null; string patchCombo = ""; if (type == TYPE.Anti_Huffman_By_Translate) { checkFunc = PatchUtil.SearchAntiHuffmanPatch; reason = R._("翻訳された文章がハフマン符号化テーブルを超えている可能性があります。\r\nAntiHuffmanPatchを適応しておくことをお勧めします。"); patchName1 = "Anti-Huffman";///No Translate } if (type == TYPE.Anti_Huffman_By_English) { checkFunc = PatchUtil.SearchAntiHuffmanPatch; reason = R._("英語版で、テキストを変更するためには、Anti-Huffman Patchが必要です。"); patchName1 = "Anti-Huffman";///No Translate } else if (type == TYPE.C01Hack_By_ImageBattleAnimation) { checkFunc = PatchUtil.SearchC01HackPatch; reason = R._("このアニメーションには、C01 命令が使われています。\r\n現在、C01ハックパッチは、まだインストールされていません。\r\nアニメーションを再生するためには、\r\nC01ハックを有効にした方がいいと思われますが、どうしますか?\r\n"); patchName1 = "01command_hack"; ///No Translate patchName2 = "01コマンドハック"; ///No Translate } else if (type == TYPE.C48Hack_By_ImageBattleAnimation) { checkFunc = PatchUtil.SearchC48HackPatch; reason = R._("このアニメーションには、C48 命令(or Sxx命令)が使われています。\r\n現在、C48ハックパッチは、まだインストールされていません。\r\nアニメーションを再生するためには、\r\nC48ハックを有効にした方がいいと思われますが、どうしますか?\r\n"); patchName1 = "48command_hack"; ///No Translate patchName2 = "48コマンドハック"; ///No Translate } else if (type == TYPE.NIMAP_By_SongTrack) { checkFunc = PatchUtil.SearchNIMAP; reason = R._("Midi楽器はFE楽器と並び順が違うので、\r\nNIMAPを利用することをお勧めします。"); if (Program.ROM.RomInfo.version() == 8) { //FE8用には更新されたバージョンを利用する. patchName1 = "SOUND_NIMAP2(Native Instrument Map)"; ///No Translate patchName2 = "SOUND_NIMAP2"; ///No Translate } else { patchName1 = "SOUND_NIMAP(Native Instrument Map)"; ///No Translate patchName2 = "SOUND_NIMAP"; ///No Translate } } else if (type == TYPE.Track12_Over_By_SongTrack) { checkFunc = PatchUtil.Search16tracks12soundsPatch; reason = R._("この楽曲の楽譜は、12以上のトラックが存在しています。\r\nこの曲をゲームで再生するには、16_tracks_12_soundsが必要です。\r\nこのパッチを適応しますか?"); patchName1 = "16_tracks_12_sounds";///No Translate } else if (type == TYPE.MeleeAndMagicFix_By_Unit) { checkFunc = PatchUtil.SearchMeleeAndMagicFixPatch; reason = R._("武器と魔法を同時に利用するにはMeleeAndMagicPatchが必要です。\r\n有効にしますか?"); patchName1 = "MeleeAndMagicFix";///No Translate } else if (type == TYPE.ItemIconExpands) { checkFunc = PatchUtil.SearchIconExpandsPatch; reason = R._("アイコンを拡張するには、テーブルを拡張する前にパッチを適応する必要があります。\r\n有効にしますか?"); patchName1 = "Extended to item icon 0xFE"; ///No Translate patchName2 = "Extend Item Icon List Length"; ///No Translate patchCombo = "fix"; } else if (type == TYPE.MagicPatch_By_Menu) { return(HowDoYouLikePatch2Form.CheckAndShowPopupDialog(HowDoYouLikePatch2Form.TYPE.MagicPatch_By_Menu)); } else if (type == TYPE.Skill) { if (Program.ROM.RomInfo.version() != 8) { return(false); } if (Program.ROM.RomInfo.is_multibyte()) { checkFunc = () => { PatchUtil.skill_system_enum a = PatchUtil.SearchSkillSystem(); return(a == PatchUtil.skill_system_enum.FE8N || a == PatchUtil.skill_system_enum.FE8N_ver2 || a == PatchUtil.skill_system_enum.yugudora ); }; reason = R._("スキル拡張 FE8N が必要です。\r\n有効にしますか?"); patchName1 = "Skill Extension FE8N 2019_02_19"; ///No Translate patchName2 = "skill_2019_02_19"; ///No Translate } else { checkFunc = () => { return(PatchUtil.SearchSkillSystem() == PatchUtil.skill_system_enum.SkillSystem); }; reason = R._("スキル拡張 SkillSystems が必要です。\r\n有効にしますか?"); patchName1 = "Skill20200223"; ///No Translate patchName2 = "Skill20200223"; ///No Translate } } else if (type == TYPE.SkipWorldmapFix) { if (Program.ROM.RomInfo.version() != 8) { return(false); } checkFunc = () => { return(PatchUtil.SearchSkipWorldMapPatch() != PatchUtil.mnc2_fix_enum.NO); }; reason = R._("FE8のマップをワールドマップを経由しないで移動させるには、パッチが必要です。\r\n有効にしますか?"); patchName1 = "MNC2Fix"; ///No Translate patchName2 = "MNC2Fix"; ///No Translate patchShowName = "Skip Worldmap"; patchCombo = "fix"; } else if (type == TYPE.CAMERA_Event_OutOfBand_Fix) { if (Program.ROM.RomInfo.version() != 8) { return(false); } checkFunc = () => { return(PatchUtil.SearchCAMERA_Event_OutOfBand_FixPatch()); }; reason = R._("カメラを移動する命令で、画面外に飛び出してしまうバグを修正するパッチをインストールしますか?"); patchName1 = "Fix CAM1_CAMERA2 going out of bounds"; ///No Translate patchName2 = "Fix CAM1_CAMERA2 going out of bounds"; ///No Translate patchShowName = "Fix CAM1_CAMERA2 going out of bounds"; patchCombo = "Fix"; } else if (type == TYPE.CAMERA_Event_NotExistsUnit_Fix) { if (Program.ROM.RomInfo.version() != 8) { return(false); } checkFunc = () => { return(PatchUtil.SearchCAMERA_Event_NotExistsUnit_FixPatch()); }; reason = R._("存在しないユニットを指定した時にフリーズするバグを修正するパッチをインストールしますか?"); patchName1 = "Event26_CameraControlMaybe_Fix not to freeze even nonexistent units"; ///No Translate patchName2 = "Event26_CameraControlMaybe_Fix not to freeze even nonexistent units"; ///No Translate patchShowName = "Event26_CameraControlMaybe_Fix not to freeze even nonexistent units"; patchCombo = "Fix"; } else if (type == TYPE.UnitStateEvent_0x34_Fix) { if (Program.ROM.RomInfo.version() != 8) { return(false); } checkFunc = () => { return(PatchUtil.SearchUnitStateEvent_0x34_FixPatch()); }; reason = R._("存在しないユニットを指定した時にフリーズするバグを修正するパッチをインストールしますか?"); patchName1 = "Event34_MessWithUnitState_Fix not to freeze even nonexistent units"; ///No Translate patchName2 = "Event34_MessWithUnitState_Fix not to freeze even nonexistent units"; ///No Translate patchShowName = "Event34_MessWithUnitState_Fix not to freeze even nonexistent units"; patchCombo = "Fix"; } else if (type == TYPE.WakuEvent_0x3B_Fix) { if (Program.ROM.RomInfo.version() != 8) { return(false); } checkFunc = () => { return(PatchUtil.SearchWakuEvent_0x3B_FixPatch()); }; reason = R._("存在しないユニットを指定した時にフリーズするバグを修正するパッチをインストールしますか?"); patchName1 = "Event3B_frame_Fix not to freeze even nonexistent units"; ///No Translate patchName2 = "Event3B_frame_Fix not to freeze even nonexistent units"; ///No Translate patchShowName = "Event3B_frame_Fix not to freeze even nonexistent units"; patchCombo = "Fix"; } Debug.Assert(checkFunc != null); Debug.Assert(patchName1 != ""); Debug.Assert(reason != ""); if (checkFunc()) {//すでに適応されている. return(true); } if (patchShowName == null) { patchShowName = patchName1; } HowDoYouLikePatchForm f = (HowDoYouLikePatchForm)InputFormRef.JumpFormLow <HowDoYouLikePatchForm>(); string tile = R._("{0}パッチを有効にしますか?", patchShowName); f.Text = tile; f.ReasonLabel.Text = R._("{0}\r\n\r\n{1}", tile, reason); f.EnableButton.Text = R._("{0}パッチを有効にする", patchShowName); f.EnableButton.Click += (sender, e) => { f.Close(); PatchForm patchF = (PatchForm)InputFormRef.JumpForm <PatchForm>(); bool r = patchF.ApplyPatch(patchName1, patchName2, patchCombo); ///No Translate if (!r) { R.ShowStopError("パッチの自動適応に失敗しました。\r\nパッチ画面にエラーが表示されていないか確認してください。\r\n必須パッチの適応に失敗したということは、FEBuilderGBAの解凍に失敗している可能性があります。\r\nFEBuilderGBAを再インストールしてください。\r\nそれでも問題が解決しない場合は、バグとして報告してください。\r\n"); } f.Close(); }; if (Program.IsCommandLine) {//コマンドラインモードだったら自動適応するしかないね。 U.FireOnClick(f.EnableButton); return(checkFunc()); } f.ShowDialog(); return(checkFunc()); }
public static void CHEAT_WARP_FE8(EmulatorMemoryForm form, uint warp_chapter, uint edtion, uint worldmap_node) { Debug.Assert(Program.ROM.RomInfo.version() == 8); uint work_address = Program.ROM.RomInfo.workmemory_last_string_address() - 0x70; //テキストバッファの一番下をデータ置き場として利用する. uint gSomeWMEventRelatedStruct; uint eventExecuteFucntion; uint endAllMenusFunction; uint deletePlayerPhaseInterface6CsFunction; if (Program.ROM.RomInfo.is_multibyte()) {//FE8J gSomeWMEventRelatedStruct = 0x03005270; eventExecuteFucntion = 0x0800D340; endAllMenusFunction = 0x0804FCAC; deletePlayerPhaseInterface6CsFunction = 0x0808F44C; } else {//FE8U gSomeWMEventRelatedStruct = 0x03005280; eventExecuteFucntion = 0x0800D07C; endAllMenusFunction = 0x0804ef20; deletePlayerPhaseInterface6CsFunction = 0x0808d150; } //Search MAPTASK Procs uint maptask = SearchMapTaskProcsAddr(); if (maptask == U.NOT_FOUND) { R.ShowStopError("MAPTASK Procsの位置を特定できませんでした。\r\n章に入っていますか?\r\nこの機能を使うには章の中に入らないといけません。"); return; } byte[] warpCode = { //ASM 0x00, 0xB5, 0x12, 0x4A, 0x42, 0x60, 0x12, 0x4B, 0x9E, 0x46, 0x00, 0xF8, 0x11, 0x4B, 0x9E, 0x46, 0x00, 0xF8, 0x78, 0x46, 0x0E, 0x30, 0x01, 0x21, 0x0F, 0x4B, 0x9E, 0x46, 0x00, 0xF8, 0x01, 0xBC, 0x00, 0x47, 0xC0, 0x46, //Event +24 0x22, 0x2A, 0xFF, 0xFF, //MNC2 0x28, 0x02, 0x07, 0x00, 0x20, 0x01, 0x00, 0x00, //NoFade+Term 0x00, 0x00, 0x00, 0x00, //padding //hook procs +34 0x02, 0x00, 0x00, 0x00, 0x61, 0xB6, 0x02, 0x02, 0x0E, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x5E, 0x5C, 0x08, //backCode 0xAC, 0xFC, 0x04, 0x08, 0x4C, 0xF4, 0x08, 0x08, 0x40, 0xD3, 0x00, 0x08 //eventExecuteFucntion }; PatchUtil.mnc2_fix_enum use_mnc2 = PatchUtil.SearchSkipWorldMapPatch(); if (use_mnc2 != PatchUtil.mnc2_fix_enum.NO || MapLoadFunctionForm.IsEnterChapterAlways(warp_chapter)) {//MNC2でワープ可能 //章ID U.write_u16(warpCode, 0x26, warp_chapter); } else {//MNCHが必要 uint worldmap_node_minus1 = 0; if (worldmap_node > 0) { worldmap_node_minus1 = worldmap_node - 1; } byte[] mnch_code = { 0x40, 0xA6, 0x00, 0x00, 0x00, 0x00, (byte)worldmap_node_minus1, 0x00, 0x21, 0x2A, (byte)warp_chapter, 0x00, 0x20, 0x01, 0x00, 0x00, }; U.write_range(warpCode, 0x24, mnch_code); } //Procsで実行を指定するASMコードの位置 U.write_u32(warpCode, 0x38, work_address + 1); //メニューがあれば閉じる命令 U.write_u32(warpCode, 0x50, endAllMenusFunction); //TI PIなどのプレイヤーUIがあれば閉じる命令 U.write_u32(warpCode, 0x54, deletePlayerPhaseInterface6CsFunction); //イベント命令を実行する命令 U.write_u32(warpCode, 0x58, eventExecuteFucntion); //復帰するProcsのコード uint backCode = Program.RAM.u32(maptask + 4); U.write_u32(warpCode, 0x4C, backCode); Program.RAM.write_range(work_address, warpCode); uint procs_jump_addr = work_address + 0x34; Program.RAM.write_u32(maptask + 4, procs_jump_addr); //Edition uint stageStructAddr = Program.ROM.RomInfo.workmemory_mapid_address() - 0xE; Program.RAM.write_u8(stageStructAddr + 0x1b, edtion); //拠点 Program.RAM.write_u8(gSomeWMEventRelatedStruct + 0x11, worldmap_node); InputFormRef.ShowWriteNotifyAnimation(form, procs_jump_addr); return; }
public static bool CheckAndShowPopupDialog(TYPE type) { Func <bool> checkFunc = null; string title = ""; string reason = ""; string patchName1 = ""; string patchName2 = ""; string patchShowName = null; string patchCombo1 = ""; string patchName3 = ""; string patchName4 = ""; string patchShowName3 = null; string patchCombo3 = ""; if (type == TYPE.MagicPatch_By_Menu) { checkFunc = () => { return(ImageUtilMagic.SearchMagicSystem() != ImageUtilMagic.magic_system_enum.NO); }; title = R._("魔法を追加するには、魔法システムパッチが必要です。"); string version = Program.ROM.RomInfo.VersionToFilename(); if (version == "FE6") { //FE6 //patchName1 = "FEditorMagicCSASystem_FE6";///No Translate patchName3 = "CSA_Creator_For_FE6_ver2"; ///No Translate } else if (version == "FE7J") { //FE7J patchName1 = "Custom Spell Animation Engine"; ///No Translate //patchName3 = "CSA_Creator_For_FE7U";///No Translate // string no_patch = R._("残念ながら、FE7J用の魔法システムパッチは存在しません。\r\n"); // R.ShowStopError(title + "\r\n" + no_patch); // return false; } else if (version == "FE7U") { //FE7U //patchName1 = "FEditorMagicCSASystem_FE7U";///No Translate patchName3 = "CSA_Creator_For_FE7U_ver2"; ///No Translate } else if (version == "FE8J") { //FE8J patchName1 = "magic patch (FeditorAdvMagicSystem)"; ///No Translate patchName3 = "CSA_Creator_For_FE8J_ver2"; ///No Translate } else if (version == "FE8U") { //FE8U patchName1 = "FEditorMagicCSASystem_FE8U"; ///No Translate patchName3 = "CSA_Creator_For_FE8U_ver2"; ///No Translate } if (patchName1 != "" && patchName3 != "") { reason = R._("魔法システムパッチは2つあるので、どちらかを選んでください。\r\n"); reason += R._("FEditorMagicCSASystemは、長い動作実績のある魔法システムです。\r\n"); reason += R._("CSA_Creatorは、より解像度をサポートする、新進気鋭の魔法システムです。\r\n"); } else { reason = R._("魔法システムパッチを適用してください。"); } } else if (type == TYPE.DrawFont_By_Translate) { checkFunc = () => { return(PatchUtil.draw_font_enum.NO != PatchUtil.SearchDrawFontPatch()); }; title = R._("他の言語を表示するにはDrawFontパッチが必要です。"); if (Program.ROM.RomInfo.is_multibyte()) { patchName3 = "DrawSingleByte";///No Translate } else { patchName1 = "DrawMultiByte"; ///No Translate patchName3 = "DrawUTF8"; ///No Translate reason += R._("日本語へ翻訳する場合は、DrawMultiByte を選択してください。\r\n"); reason += R._("日本語以外へ翻訳する場合は、DrawUTF8 を選択してください\r\n"); } } else if (type == TYPE.SkipWorldmapFix) { if (Program.ROM.RomInfo.version() != 8) { return(false); } checkFunc = () => { return(PatchUtil.SearchSkipWorldMapPatch() != PatchUtil.mnc2_fix_enum.NO); }; title = R._("FE8のマップをワールドマップを経由しないで移動させるには、パッチが必要です。\r\n有効にしますか?"); reason = R._("フリーマップを無効にしてよいならば、強力なEliminateを選択してください。\r\n"); reason += R._("フリーマップを使いたい場合は、MNC2Fix を選択してください。\r\n"); patchName1 = "Eliminate"; ///No Translate patchName2 = "Eliminate the constraint of freezing unless it enters from the world map."; ///No Translate patchCombo1 = "fix"; ///No Translate patchName3 = "MNC2Fix"; ///No Translate patchName4 = "MNC2Fix"; ///No Translate } Debug.Assert(checkFunc != null); Debug.Assert(title != ""); if (checkFunc()) {//すでに適応されている. return(true); } if (IgnorePatchs.IndexOf(type) >= 0) { return(true); } if (patchShowName == null) { patchShowName = patchName1; } if (patchShowName3 == null) { patchShowName3 = patchName3; } HowDoYouLikePatch2Form f = (HowDoYouLikePatch2Form)InputFormRef.JumpFormLow <HowDoYouLikePatch2Form>(); f.CurrentType = type; f.Text = title; f.ReasonLabel.Text = R._("{0}\r\n\r\n{1}", title, reason); if (patchName1 == "") { f.EnableButton.Hide(); } else { f.EnableButton.Text = R._("{0}パッチを有効にする", patchShowName); f.EnableButton.Click += (sender, e) => { f.Close(); PatchForm patchF = (PatchForm)InputFormRef.JumpForm <PatchForm>(); patchF.ApplyPatch(patchName1, patchName2, patchCombo1); ///No Translate }; } if (patchName3 == "") { f.EnableButton3.Hide(); } else { f.EnableButton3.Text = R._("{0}パッチを有効にする", patchShowName3); f.EnableButton3.Click += (sender, e) => { f.Close(); PatchForm patchF = (PatchForm)InputFormRef.JumpForm <PatchForm>(); patchF.ApplyPatch(patchName3, patchName4, patchCombo3); ///No Translate }; } if (Program.IsCommandLine) {//コマンドラインモードだったら自動適応するしかないね。 f.CommandLineClick(patchName1, patchName3); return(checkFunc()); } f.ShowDialog(); return(checkFunc()); }