├── .gitattributes ├── .gitignore ├── .gitmodules ├── Chapters ├── CCBlitz │ ├── CCBlitzChapter27.event │ ├── CCBlitzChapter27Asmcs.c │ └── CCBlitzChapter27Map.tmx ├── Chapters.event ├── CommBlitz │ ├── CommBlitzCh10.event │ ├── CommBlitzCh10Asmcs.c │ └── CommBlitzCh10Map.tmx ├── Demo │ ├── Alusq_FE8_01000203_you deserve a vacation.png │ ├── Demo.event │ └── DemoMap.tmx ├── FE6Ch1 │ ├── FE6Chapter1.event │ └── FE6Chapter1Map.tmx ├── PeerBlitz │ ├── PeerBlitzCh9.event │ └── PeerBlitzCh9Map.tmx └── Tilesets │ ├── 01000203.png │ ├── 01003803.png │ ├── 01004c03.png │ ├── 01005b03.png │ ├── 0e000f10.png │ ├── 0e007210.png │ ├── 0e00ea10.png │ ├── 1800191a.png │ ├── 1800481a.png │ ├── 1800571a.png │ ├── 1800b91a.png │ ├── 2e002f30.png │ ├── 2e003430.png │ ├── 3c003d3e.png │ ├── 3c00683e.png │ ├── 3c00ce3e.png │ ├── 42004344.png │ ├── 50005152.png │ ├── 5f006061.png │ ├── 6c006d6e.png │ ├── 6c00a36e.png │ ├── 79007a7b.png │ ├── 7900e67b.png │ └── 8800898a.png ├── GameData ├── .gitignore ├── Constants.event ├── GameData.event ├── Indices.event ├── Lists │ └── ForceDeplyList.event └── Tables │ ├── Character.csv │ ├── Character.nmm │ ├── Class.csv │ ├── Class.nmm │ ├── Item.csv │ ├── Item.nmm │ ├── _CharacterEditorList.txt │ ├── _ClassEditorList.txt │ └── _ItemEditorList.txt ├── Main.event ├── Makefile ├── README.md ├── Songs ├── DrumFix.event ├── Midis │ ├── FE5Attack.s │ └── MPlayDef.s ├── NIMap.bin ├── SongHelpers.event └── Songs.event ├── Spritans ├── PortraitList.txt └── Portraits │ └── Florina.png ├── Tools ├── .gitignore └── py-old │ ├── .limbo │ └── unit-reallocator.py │ ├── blfind.py │ ├── c2ea.py │ ├── c2s.py │ ├── dumpers │ ├── aidump.py │ ├── apdump.py │ └── fontdump.py │ ├── genmugs.py │ ├── n2c.py │ ├── nightmare.py │ ├── pfind.py │ ├── pfinder.py │ ├── stop_using_spaces_in_filenames.py │ ├── textprocess.py │ └── tmx2ea │ ├── lzss.py │ ├── six.py │ ├── tmx.py │ └── tmx2ea.py ├── Wizardry ├── .Limbo │ ├── AForge │ │ ├── AForge.event │ │ ├── AForgeScreen.event │ │ └── Src │ │ │ ├── Af.h │ │ │ ├── AfCore.c │ │ │ ├── AfHooks.s │ │ │ └── AfScreen.c │ ├── AMSS │ │ ├── AMSS.event │ │ ├── Data │ │ │ └── DbgTiles.png │ │ ├── Modules │ │ │ ├── Pages │ │ │ │ ├── AmssPage.event │ │ │ │ └── Src │ │ │ │ │ ├── AmssPage.c │ │ │ │ │ ├── AmssPage.h │ │ │ │ │ └── AmssPageName.c │ │ │ └── Portrait │ │ │ │ ├── AmssPortrait.event │ │ │ │ └── Src │ │ │ │ └── AmssPortrait.c │ │ └── Src │ │ │ ├── AmssCore.c │ │ │ ├── AmssDebug.c │ │ │ ├── AmssHelp.c │ │ │ ├── AmssInternal.h │ │ │ └── AmssUnitChange.c │ ├── CSS │ │ ├── CSS.event │ │ ├── Res │ │ │ ├── DebugPal.s │ │ │ ├── LeftPanelBgFace.png │ │ │ ├── LeftPanelGrid.png │ │ │ ├── MugFrameSmall.png │ │ │ ├── MugFrameSmall.xcf │ │ │ ├── NumbersFont.png │ │ │ ├── NumbersFont.xcf │ │ │ ├── StatTextDummy.png │ │ │ └── StatTextDummyOriginal.png │ │ └── Src │ │ │ ├── CSS.h │ │ │ ├── CSSCommon.c │ │ │ ├── CSSCore.c │ │ │ ├── CSSLeftPanel.c │ │ │ ├── CSSMugFrameSmall.c │ │ │ └── CSSObjText.c │ ├── CSummonStaff │ │ ├── Src │ │ │ ├── FreeSelect.h │ │ │ ├── SummonStaff.c │ │ │ └── SummonStaffHooks.s │ │ └── SummonStaff.event │ ├── Misc │ │ ├── Src │ │ │ ├── ASMC_ForgetSkill.s │ │ │ ├── Armsthrift.s │ │ │ ├── AuraSkillChecker.c │ │ │ ├── CanLunge.c │ │ │ ├── FOMTDecomp.c │ │ │ └── asm_tricks.s │ │ └── nu-evcodes.txt │ ├── MovingTrap │ │ ├── ThingSmall.event │ │ └── src │ │ │ ├── effect.s │ │ │ ├── handle_trap.c │ │ │ ├── hidden.s │ │ │ ├── init.s │ │ │ ├── unit_mover.c │ │ │ ├── unit_mover.h │ │ │ ├── utility.c │ │ │ └── utility.h │ ├── Nm │ │ ├── Nm.event │ │ └── Src │ │ │ ├── Nm.h │ │ │ └── NmMain.c │ ├── README.md │ ├── UnlockHack │ │ ├── UnlockHack.event │ │ └── src │ │ │ └── UnlockHack.c │ └── ValentianExpShare │ │ ├── Src │ │ ├── VES.h │ │ ├── VESMain.c │ │ └── VESUnitDisplay.c │ │ └── ValentianExpShare.event ├── .Research │ ├── BattleMapMain.event │ ├── DrawGlyph.s │ └── TmApplyTsa.s ├── 3rdParty │ ├── CSAEngine │ │ ├── CSAEngine.event │ │ ├── CSANotes.txt │ │ └── src │ │ │ ├── CSALyn.s │ │ │ └── CSAOld.s │ ├── HpBars │ │ ├── HpBars.event │ │ ├── res │ │ │ └── BattleMapObjGfx.png │ │ └── src │ │ │ └── _warning_and_hpbars.s │ ├── KirbDebug │ │ ├── KirbDebug.event │ │ └── src │ │ │ ├── KDStatPage.c │ │ │ ├── KirbDebug.c │ │ │ └── KirbDebug.h │ └── MMB │ │ └── MMBStan.event ├── AiPerformExtension │ ├── AiPerformExt.event │ ├── AiScrDefinitions.event │ └── Src │ │ └── PerformHook.s ├── Autolevels │ ├── FixedAutolevels.event │ └── NoBonusLevels.event ├── AverageLevelEnemies │ ├── Ale.event │ └── Src │ │ ├── Ale.c │ │ └── AleHooks.s ├── BriefBwl │ ├── BriefBwl.event │ └── Src │ │ └── BriefBwl.c ├── CBattleCalc │ ├── CBattleCalc.event │ └── src │ │ └── BattleCalcCore.c ├── CFreeSelect │ ├── FreeSelect.event │ └── src │ │ ├── FreeSelect.c │ │ └── FreeSelect.h ├── CIconDisplay │ ├── IconDisplay.event │ └── src │ │ ├── IconDisplay.h │ │ ├── IconDisplayCore.c │ │ └── IconDisplayUser.c ├── CLolStats │ ├── LolStats.event │ └── Src │ │ └── LolStats.c ├── CPopupRework │ ├── Extensions │ │ └── PopupDefinitions.txt │ ├── PopupRework.event │ ├── PopupReworkInternal.event │ └── Src │ │ ├── PopRAnimsOff.c │ │ ├── PopRAnimsOn.c │ │ ├── PopRComponents.c │ │ ├── PopRCore.c │ │ ├── PopupRework.h │ │ └── VanillaPopupInits.c ├── CRewarp │ ├── Rewarp.event │ └── src │ │ ├── FreeSelect.h │ │ ├── Rewarp.c │ │ ├── Rewarp.h │ │ └── RewarpAnim.c ├── CUnitAction │ ├── UnitAction.event │ └── src │ │ └── ActionRework.c ├── CustomGameSpeed │ ├── CustomGameSpeed.event │ └── Src │ │ └── CustomGameSpeed.s ├── DanceAi │ ├── DanceAi.event │ └── src │ │ ├── DanceAi.c │ │ └── DanceAiStaffHook.s ├── DeathDropFix │ ├── DeathDropFix.event │ └── Src │ │ ├── DropFix.c │ │ └── DropHook.s ├── DecideMonitor │ ├── DecideMonitor.event │ └── Src │ │ └── DecideMonitor.c ├── DecompressFix │ └── DecompressFix.event ├── DoubleDouble │ ├── DoubleDouble.event │ └── Src │ │ └── DoubleDouble.c ├── Dumb │ ├── NoBattleAnimations.event │ └── RemoveSupports.event ├── EvilRN │ ├── EvilRN.event │ └── src │ │ └── evilrn.c ├── ExpandedModularSave │ ├── ExModularSave.event │ ├── ExModularSaveInternals.event │ └── Src │ │ ├── MSBWLHook.s │ │ ├── MSCore.c │ │ ├── MSSizeHook.s │ │ ├── MSaFuncs.c │ │ ├── MSuFuncs.c │ │ └── ModularSave.h ├── FerryAi │ ├── AiScrDefinitions.event │ ├── FerryAi.event │ └── Src │ │ └── FerryAi.c ├── FixDifficulty │ └── FixDifficulty.event ├── IncorrectBlitzInput │ ├── IncorrectBlitzInput.event │ ├── res │ │ └── Window.png │ └── src │ │ ├── IBIHook.s │ │ └── IBIMain.c ├── LazberianBattleFlow │ ├── LazberianBattleFlow.event │ └── Src │ │ └── LBF.c ├── LazberianMercenaries │ ├── Data │ │ └── CoinBit.png │ ├── LazberianMercenaries.event │ └── Src │ │ ├── GetUnitDeployCost.s │ │ ├── LM.c │ │ └── LMHooks.s ├── LazberianTurnFlow │ ├── Data │ │ ├── TurnSwitchSheet-Test.png │ │ └── TurnSwitchSheet.png │ ├── Extensions │ │ └── ProcDefinitions.txt │ ├── LTF-Internals.event │ ├── LazberianTurnFlow.event │ ├── Src │ │ ├── LTF-Toggleable-Hooks.s │ │ ├── LTF-Toggleable.c │ │ ├── LTF.h │ │ ├── LTFAi.c │ │ ├── LTFAutocursor.c │ │ ├── LTFCore.c │ │ ├── LTFDisplay.c │ │ ├── LTFEndPlayerPhase.c │ │ ├── LTFHooks.s │ │ ├── LTFMapSprite.c │ │ ├── LTFPhaseSwitch.c │ │ └── LTFTurnSwitchFx.c │ └── SrcUser │ │ └── IsLtfEnabled.s ├── LazberianWeaponry │ ├── Data │ │ └── DurabilityIcons.png │ ├── LazberianWeaponry.event │ └── Src │ │ ├── LW.c │ │ └── LWHooks.s ├── M7 │ ├── M7.event │ └── Src │ │ ├── M7.h │ │ ├── M7Core.c │ │ └── M7RamFunc.c ├── MapAuraFx │ ├── Data │ │ └── fx.png │ ├── MapAuraFx.event │ └── Src │ │ ├── MapAuraFx.c │ │ └── MapAuraFx.h ├── Mimic │ ├── Mimic.event │ └── src │ │ ├── Mimic.c │ │ ├── Mimic.h │ │ ├── MimicEffect.c │ │ └── MimicSelection.c ├── Misc │ ├── FcukTanks.event │ ├── Nice.event │ └── SetMoveBonus.event ├── MiscFixes │ ├── CounterFix.event │ ├── LeadAiFix.event │ └── MNC2FixTest.event ├── PerChapterBattleQuotes │ ├── PerChapterBattleQuotes.event │ └── Src │ │ └── PerChapterBattleQuotes.c ├── StatScreenBlink │ ├── SSBlink.event │ └── Src │ │ └── SSBlink.c ├── TalkAi │ ├── Src │ │ └── TalkAi.c │ └── TalkAi.event ├── TextScrollSpeed.event ├── TileChangeTrap │ ├── TileChangeTrap.c │ └── TileChangeTrap.event ├── TradeCheck │ ├── TradeCheck.event │ └── src │ │ ├── TradeCheckHook.s │ │ ├── TradeCheckLoop.c │ │ └── TradeCheckVanilla.c ├── UnitMenu.event ├── Utility │ ├── CanUnitBeOnPosition.event │ ├── ShopLike.event │ └── Src │ │ ├── CanUnitBeOnPosition.c │ │ └── ShopLike.c ├── VeninSleepWeapons │ ├── Src │ │ └── VswHook.s │ └── Vsw.event ├── VeryCustomItems │ ├── Src │ │ ├── Vci.h │ │ ├── VciCore.c │ │ └── VciVanilla.c │ └── VeryCustomItems.event ├── _FE8EssentialFixes.event └── _WizardryMain.event ├── Writans ├── ParseDefinitions.txt ├── PeerBlitzCh9Text.txt ├── TextMain.txt ├── TextMimic.txt └── TextRewarp.txt ├── game-data.mk ├── make_ready_install.sh ├── spritans.mk ├── tools.mk ├── wizardry.mk └── writans.mk /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .cache_dir 2 | 3 | *.gba 4 | *.sav 5 | *.ss* 6 | *.sym 7 | *.sym.event 8 | FE8U-*.png 9 | HACK-*.png 10 | CHaxInstallReady-* 11 | 12 | *.lyn.event 13 | *.asm 14 | *.o 15 | *.dmp 16 | 17 | *.lz 18 | *.4bpp 19 | *.gbapal 20 | 21 | *Map.event 22 | 23 | Spritans/Portraits.event 24 | Writans/Text.event 25 | Writans/TextDefinitions.event 26 | Writans/.TextEntries* 27 | 28 | .vscode* 29 | 30 | # Object files 31 | *.o 32 | *.ko 33 | *.obj 34 | *.elf 35 | 36 | # Precompiled Headers 37 | *.gch 38 | *.pch 39 | 40 | # Libraries 41 | *.lib 42 | *.a 43 | *.la 44 | *.lo 45 | 46 | # Shared objects (inc. Windows DLLs) 47 | *.dll 48 | *.so 49 | *.so.* 50 | *.dylib 51 | 52 | # Executables 53 | *.exe 54 | *.out 55 | *.app 56 | *.i*86 57 | *.x86_64 58 | *.hex 59 | 60 | # Debug files 61 | *.dSYM/ 62 | 63 | # ========================= 64 | # Operating System Files 65 | # ========================= 66 | 67 | # OSX 68 | # ========================= 69 | 70 | .DS_Store 71 | .AppleDouble 72 | .LSOverride 73 | 74 | # Thumbnails 75 | ._* 76 | 77 | # Files that might appear in the root of a volume 78 | .DocumentRevisions-V100 79 | .fseventsd 80 | .Spotlight-V100 81 | .TemporaryItems 82 | .Trashes 83 | .VolumeIcon.icns 84 | 85 | # Directories potentially created on remote AFP share 86 | .AppleDB 87 | .AppleDesktop 88 | Network Trash Folder 89 | Temporary Items 90 | .apdisk 91 | 92 | # Windows 93 | # ========================= 94 | 95 | # Windows image file caches 96 | Thumbs.db 97 | ehthumbs.db 98 | 99 | # Folder config file 100 | Desktop.ini 101 | 102 | # Recycle Bin used on file shares 103 | $RECYCLE.BIN/ 104 | 105 | # Windows Installer files 106 | *.cab 107 | *.msi 108 | *.msm 109 | *.msp 110 | 111 | # Windows shortcuts 112 | *.lnk 113 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Wizardry/ModularGetters"] 2 | path = Wizardry/ModularGetters 3 | url = https://github.com/StanHash/FE8ModularStatGetters.git 4 | [submodule "Tools/CLib"] 5 | path = Tools/CLib 6 | url = https://github.com/StanHash/FE-CLib 7 | [submodule "Tools/PyTools"] 8 | path = Tools/PyTools 9 | url = https://github.com/StanHash/FE-PyTools.git 10 | [submodule "Tools/EventAssembler"] 11 | path = Tools/EventAssembler 12 | url = https://github.com/StanHash/EventAssembler.git 13 | -------------------------------------------------------------------------------- /Chapters/Chapters.event: -------------------------------------------------------------------------------- 1 | #ifndef CHAPTERS 2 | #define CHAPTERS 3 | 4 | // Putting each chapter in their own symbol scope 5 | // That way, label names can be reused between chapters 6 | // (Which would be useful if I had more than one at a time) 7 | 8 | { 9 | // #include "PeerBlitz/PeerBlitzCh9.event" 10 | // #include "PeerBlitz/PeerBlitzCh9Map.event" 11 | } 12 | 13 | { 14 | #include "FE6Ch1/FE6Chapter1.event" 15 | #include "FE6Ch1/FE6Chapter1Map.event" 16 | } 17 | 18 | { 19 | // #include "CCBlitz/CCBlitzChapter27.event" 20 | // #include "CCBlitz/CCBlitzChapter27Map.event" 21 | } 22 | 23 | { 24 | // #include "CommBlitz/CommBlitzCh10.event" 25 | // #include "CommBlitz/CommBlitzCh10Map.event" 26 | } 27 | 28 | { 29 | // #include "Demo/Demo.event" 30 | } 31 | 32 | #endif // CHAPTERS 33 | -------------------------------------------------------------------------------- /Chapters/CommBlitz/CommBlitzCh10Asmcs.c: -------------------------------------------------------------------------------- 1 | 2 | #include "gbafe.h" 3 | 4 | /* 5 | * ASMC parameters: 6 | * s2 = address of trap data 7 | */ 8 | void ASMC_LoadTraps(struct Proc* proc) 9 | { 10 | // TODO: add to CLib 11 | extern void LoadTrapData(const void* data); 12 | 13 | const void* data = (const void*)(gEventSlot[2]); 14 | 15 | if (data) 16 | LoadTrapData(data); 17 | } 18 | 19 | /* 20 | * ASMC result: 21 | * sC = game total turn count up until now 22 | */ 23 | void ASMC_GetGameTotalTurnCount(struct Proc* proc) 24 | { 25 | // TODO: add to CLib 26 | extern int GetGameTotalTurnCount(void); 27 | 28 | gEventSlot[0xC] = 1 + GetGameTotalTurnCount(); 29 | } 30 | 31 | void ASMC_FixActiveUnit(struct Proc* proc) 32 | { 33 | gActiveUnit->state = gActiveUnit->state &~ (US_HIDDEN | US_HAS_MOVED | US_HAS_MOVED_AI); 34 | } 35 | 36 | void ASMC_FixDanGoyle(struct Proc* proc) 37 | { 38 | extern const u8 gDanGoyleCharId; 39 | 40 | struct Unit* unit = GetUnitByCharId(gDanGoyleCharId); 41 | 42 | if (unit) 43 | unit->movBonus = 1; 44 | } 45 | 46 | static 47 | int IsRescuingChar(int charId) 48 | { 49 | extern const u8 gFleetCharList[]; 50 | 51 | for (const u8* it = gFleetCharList; *it; ++it) 52 | { 53 | if (*it == charId) 54 | return TRUE; 55 | } 56 | 57 | return FALSE; 58 | } 59 | 60 | int ASME_CheckRescues(void* unk) 61 | { 62 | for (unsigned i = FACTION_RED + 1; i < FACTION_RED + 0x40; ++i) 63 | { 64 | struct Unit* unit = GetUnit(i); 65 | 66 | if (!UNIT_IS_VALID(unit)) 67 | continue; 68 | 69 | if (unit->state & (US_UNAVAILABLE | US_RESCUED)) 70 | continue; 71 | 72 | if (IsRescuingChar(unit->pCharacterData->number) && !(unit->state & US_RESCUING)) 73 | return TRUE; 74 | } 75 | 76 | return FALSE; 77 | } 78 | 79 | int AiTransformMoveIntoTalk(const u8* charId) 80 | { 81 | AiUpdateDecision( 82 | AI_DECISION_TALK, 0, 83 | gActiveUnit->index, 84 | GetUnitByCharId(*charId)->index, 85 | 0xFF); 86 | 87 | return TRUE; 88 | } 89 | -------------------------------------------------------------------------------- /Chapters/Demo/Alusq_FE8_01000203_you deserve a vacation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Demo/Alusq_FE8_01000203_you deserve a vacation.png -------------------------------------------------------------------------------- /Chapters/Demo/Demo.event: -------------------------------------------------------------------------------- 1 | #ifndef CHAPTER_DEMO 2 | #define CHAPTER_DEMO 3 | 4 | #include "EAstdlib.event" 5 | 6 | // This `DemoMap.event` file will be automatically generated/updated: 7 | // The file `DemoMap.tmx` exists in this folder, and make knows how to 8 | // build `.event` files out of `.tmx` files (there's a rule for that) 9 | 10 | #include "DemoMap.event" 11 | 12 | EventPointerTable(0x7, ThisChapter) 13 | 14 | ALIGN 4 15 | ThisChapter: 16 | POIN TurnEventList 17 | POIN CharacterEventList 18 | POIN LocationEventList 19 | POIN ActionEventList 20 | POIN DunnoList DunnoList DunnoList 21 | POIN TutorialList 22 | POIN TrapList TrapList2 23 | POIN unPlayerList unPlayerList 24 | WORD 0 0 0 0 0 0 25 | POIN scBeginning scEnding 26 | 27 | ALIGN 4 28 | TurnEventList: 29 | END_MAIN 30 | 31 | ALIGN 4 32 | CharacterEventList: 33 | END_MAIN 34 | 35 | ALIGN 4 36 | LocationEventList: 37 | END_MAIN 38 | 39 | ALIGN 4 40 | ActionEventList: 41 | CauseGameOverIfLordDies 42 | END_MAIN 43 | 44 | ALIGN 4 45 | DunnoList: 46 | END_MAIN 47 | 48 | ALIGN 4 49 | TutorialList: 50 | WORD 0 51 | 52 | ALIGN 4 53 | TrapList: 54 | BLST [8, 10] 0x35 55 | TrapList2: 56 | ENDTRAP 57 | 58 | ALIGN 4 59 | unPlayerList: 60 | UNIT Eirika PegasusKnight 0 Level(10, Ally, True) [7, 6] 0 0 1 SumREDA [IronLance, ElysianWhip, Vulnerary] NoAI 61 | UNIT Moulder Priest Eirika Level(10, Ally, True) [8, 8] 0 0 0 0 [Heal] NoAI 62 | UNIT Innes Sniper Eirika Level(1, Ally, True) [7, 9] 0 0 0 0 [IronBow, SteelBow, IronSword] NoAI 63 | UNIT 64 | 65 | ALIGN 4 66 | unEnemyList: 67 | UNIT 0x80 Soldier 0 Level(1, Enemy, False) [12, 7] 0 0 0 0 [IronLance] NoAI 68 | UNIT 0x80 Soldier 0 Level(1, Enemy, False) [11, 8] 0 0 0 0 [IronLance] NoAI 69 | UNIT 0x80 Dancer 0 Level(1, Enemy, False) [14, 9] 0 0 0 0 [Elixir] HealUnits 70 | UNIT 71 | 72 | SumREDA: 73 | REDA [9, 7] 0 0 0 0 74 | 75 | ALIGN 4 76 | scBeginning: 77 | CALL $591F40 78 | 79 | // ASMC $048281 80 | 81 | EVBIT_T 9 82 | 83 | LOAD1 0 unEnemyList 84 | ENUN 85 | 86 | LOAD1 0 unPlayerList 87 | ENUN 88 | 89 | EVBIT_F 9 90 | 91 | ENDA 92 | 93 | ALIGN 4 94 | scEnding: 95 | ENDA 96 | 97 | #endif // CHAPTER_DEMO 98 | -------------------------------------------------------------------------------- /Chapters/Demo/DemoMap.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 214,214,214,214,214,277,214,214,214,214,214,214,214,214,214,214,214,278,213,245,214, 18 | 214,214,214,214,214,213,277,214,214,214,214,214,214,214,214,214,214,246,245,214,214, 19 | 214,214,214,214,278,213,213,214,214,214,214,214,214,214,278,277,214,214,214,214,214, 20 | 214,214,214,214,213,213,213,277,214,214,214,214,214,214,278,245,214,214,214,214,214, 21 | 214,214,214,278,213,85,87,23,22,284,277,214,278,316,284,277,214,214,214,214,214, 22 | 214,214,278,213,125,721,569,164,131,473,216,316,215,317,317,216,284,214,214,214,214, 23 | 214,214,246,213,23,597,630,806,395,164,501,317,317,504,473,317,248,214,214,214,214, 24 | 214,214,214,125,131,601,783,131,363,131,199,317,177,721,229,503,216,277,214,214,214, 25 | 214,214,214,246,470,565,708,198,131,163,145,317,317,264,270,471,317,283,277,214,214, 26 | 214,214,214,214,247,283,215,146,264,263,317,317,317,317,317,317,317,315,245,214,214, 27 | 214,214,214,214,246,213,247,317,317,317,317,248,314,247,317,317,248,214,214,214,214, 28 | 214,214,214,214,214,246,213,349,247,248,314,213,213,215,248,282,245,214,214,214,214, 29 | 214,214,214,214,214,278,213,278,213,309,310,284,213,282,245,214,214,214,214,214,214, 30 | 214,214,214,278,213,213,213,213,213,341,342,314,245,214,214,214,214,214,214,214,214, 31 | 278,278,213,213,213,213,245,214,214,214,214,214,214,214,214,214,214,214,214,278,213, 32 | 246,245,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,278,213,213,213, 33 | 214,214,214,214,214,214,214,214,214,214,214,214,214,214,278,213,213,213,213,213,213 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Chapters/Tilesets/01000203.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/01000203.png -------------------------------------------------------------------------------- /Chapters/Tilesets/01003803.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/01003803.png -------------------------------------------------------------------------------- /Chapters/Tilesets/01004c03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/01004c03.png -------------------------------------------------------------------------------- /Chapters/Tilesets/01005b03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/01005b03.png -------------------------------------------------------------------------------- /Chapters/Tilesets/0e000f10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/0e000f10.png -------------------------------------------------------------------------------- /Chapters/Tilesets/0e007210.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/0e007210.png -------------------------------------------------------------------------------- /Chapters/Tilesets/0e00ea10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/0e00ea10.png -------------------------------------------------------------------------------- /Chapters/Tilesets/1800191a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/1800191a.png -------------------------------------------------------------------------------- /Chapters/Tilesets/1800481a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/1800481a.png -------------------------------------------------------------------------------- /Chapters/Tilesets/1800571a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/1800571a.png -------------------------------------------------------------------------------- /Chapters/Tilesets/1800b91a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/1800b91a.png -------------------------------------------------------------------------------- /Chapters/Tilesets/2e002f30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/2e002f30.png -------------------------------------------------------------------------------- /Chapters/Tilesets/2e003430.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/2e003430.png -------------------------------------------------------------------------------- /Chapters/Tilesets/3c003d3e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/3c003d3e.png -------------------------------------------------------------------------------- /Chapters/Tilesets/3c00683e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/3c00683e.png -------------------------------------------------------------------------------- /Chapters/Tilesets/3c00ce3e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/3c00ce3e.png -------------------------------------------------------------------------------- /Chapters/Tilesets/42004344.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/42004344.png -------------------------------------------------------------------------------- /Chapters/Tilesets/50005152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/50005152.png -------------------------------------------------------------------------------- /Chapters/Tilesets/5f006061.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/5f006061.png -------------------------------------------------------------------------------- /Chapters/Tilesets/6c006d6e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/6c006d6e.png -------------------------------------------------------------------------------- /Chapters/Tilesets/6c00a36e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/6c00a36e.png -------------------------------------------------------------------------------- /Chapters/Tilesets/79007a7b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/79007a7b.png -------------------------------------------------------------------------------- /Chapters/Tilesets/7900e67b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/7900e67b.png -------------------------------------------------------------------------------- /Chapters/Tilesets/8800898a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Chapters/Tilesets/8800898a.png -------------------------------------------------------------------------------- /GameData/.gitignore: -------------------------------------------------------------------------------- 1 | Tables/*.event 2 | -------------------------------------------------------------------------------- /GameData/GameData.event: -------------------------------------------------------------------------------- 1 | #ifndef GAMEDATA 2 | #define GAMEDATA 3 | 4 | #include "EAstdlib.event" 5 | 6 | #include "Constants.event" 7 | #include "Indices.event" 8 | 9 | #include "Tables/Class.event" 10 | #include "Tables/Character.event" 11 | #include "Tables/Item.event" 12 | 13 | #endif // GAMEDATA 14 | -------------------------------------------------------------------------------- /GameData/Lists/ForceDeplyList.event: -------------------------------------------------------------------------------- 1 | #ifndef DATA_LIST_FORCEDEPLOY 2 | #define DATA_LIST_FORCEDEPLOY 3 | 4 | { 5 | 6 | #ifndef ForceDeployedDefined 7 | #define ForceDeployedDefined 8 | 9 | #define ForceDeployed(aCharacter) "SHORT (aCharacter); BYTE 0xFF 0xFF" 10 | #define ForceDeployed(aCharacter, aChapter) "SHORT (aCharacter); BYTE 0xFF (aChapter)" 11 | #define ForceDeployed(aCharacter, aChapter, aMode) "SHORT (aCharacter); BYTE (aMode) (aChapter)" 12 | #define ForceDeployedEnd "SHORT 0xFFFF 0" 13 | #endif // ForceDeployedDefined 14 | 15 | // Repointing the Force Deploy Table 16 | 17 | PUSH; ORG $8483C 18 | POIN ForceDeployList 19 | POP 20 | 21 | ALIGN 4 22 | ForceDeployList: 23 | ForceDeployed(Eirika) 24 | 25 | ForceDeployedEnd 26 | 27 | } 28 | 29 | #endif // DATA_LIST_FORCEDEPLOY 30 | -------------------------------------------------------------------------------- /GameData/Tables/Character.nmm: -------------------------------------------------------------------------------- 1 | #FE8 Character Editor by SpyroDi 2 | # 3 | 4 | 1 5 | FE8 Character Editor 6 | 0x803D64 7 | 255 8 | 52 9 | _CharacterEditorList.txt 10 | NULL 11 | 12 | Name 13 | 0 14 | 2 15 | NEHU 16 | NULL 17 | 18 | Description 19 | 2 20 | 2 21 | NEHU 22 | NULL 23 | 24 | Number 25 | 4 26 | 1 27 | NEHU 28 | NULL 29 | 30 | Default Class 31 | 5 32 | 1 33 | NEHU 34 | NULL 35 | 36 | Portrait 37 | 6 38 | 2 39 | NEHU 40 | NULL 41 | 42 | Mini Portrait 43 | 8 44 | 1 45 | NEHU 46 | NULL 47 | 48 | Affinity 49 | 9 50 | 1 51 | NEDU 52 | NULL 53 | 54 | Base Level 55 | 11 56 | 1 57 | NEDU 58 | NULL 59 | 60 | Base HP 61 | 12 62 | 1 63 | NEDS 64 | NULL 65 | 66 | Base Pwr 67 | 13 68 | 1 69 | NEDS 70 | NULL 71 | 72 | Base Skl 73 | 14 74 | 1 75 | NEDS 76 | NULL 77 | 78 | Base Spd 79 | 15 80 | 1 81 | NEDS 82 | NULL 83 | 84 | Base Lck 85 | 18 86 | 1 87 | NEDS 88 | NULL 89 | 90 | Base Def 91 | 16 92 | 1 93 | NEDS 94 | NULL 95 | 96 | Base Res 97 | 17 98 | 1 99 | NEDS 100 | NULL 101 | 102 | Base Con 103 | 19 104 | 1 105 | NEDS 106 | NULL 107 | 108 | Sword Rank 109 | 20 110 | 1 111 | NEDU 112 | NULL 113 | 114 | Lance Rank 115 | 21 116 | 1 117 | NEDU 118 | NULL 119 | 120 | Axe Rank 121 | 22 122 | 1 123 | NEDU 124 | NULL 125 | 126 | Bow Rank 127 | 23 128 | 1 129 | NEDU 130 | NULL 131 | 132 | Staff Rank 133 | 24 134 | 1 135 | NEDU 136 | NULL 137 | 138 | Anima Rank 139 | 25 140 | 1 141 | NEDU 142 | NULL 143 | 144 | Light Rank 145 | 26 146 | 1 147 | NEDU 148 | NULL 149 | 150 | Dark Rank 151 | 27 152 | 1 153 | NEDU 154 | NULL 155 | 156 | HP Growth 157 | 28 158 | 1 159 | NEDU 160 | NULL 161 | 162 | Pwr Growth 163 | 29 164 | 1 165 | NEDU 166 | NULL 167 | 168 | Skl Growth 169 | 30 170 | 1 171 | NEDU 172 | NULL 173 | 174 | Spd Growth 175 | 31 176 | 1 177 | NEDU 178 | NULL 179 | 180 | Lck Growth 181 | 34 182 | 1 183 | NEDU 184 | NULL 185 | 186 | Def Growth 187 | 32 188 | 1 189 | NEDU 190 | NULL 191 | 192 | Res Growth 193 | 33 194 | 1 195 | NEDU 196 | NULL 197 | 198 | Attributes 199 | 40 200 | 4 201 | NEHU 202 | NULL 203 | 204 | Support Data Pointer 205 | 44 206 | 4 207 | NEHU 208 | NULL 209 | -------------------------------------------------------------------------------- /GameData/Tables/Item.nmm: -------------------------------------------------------------------------------- 1 | #FE8 Item Editor by SpyroDi 2 | # 3 | 4 | 1 5 | FE8 Item Editor 6 | 0x809B10 7 | 206 8 | 36 9 | _ItemEditorList.txt 10 | NULL 11 | 12 | Name 13 | 0 14 | 2 15 | NEHU 16 | NULL 17 | 18 | Description 19 | 2 20 | 2 21 | NEHU 22 | NULL 23 | 24 | Use Description 25 | 4 26 | 2 27 | NEHU 28 | NULL 29 | 30 | Item Number 31 | 6 32 | 1 33 | NEHU 34 | NULL 35 | 36 | Weapon Type 37 | 7 38 | 1 39 | NEHU 40 | NULL 41 | 42 | Attributes 43 | 8 44 | 4 45 | NEHU 46 | NULL 47 | 48 | Stat Bonuses Pointer 49 | 12 50 | 4 51 | NEHU 52 | NULL 53 | 54 | Effectiveness Pointer 55 | 16 56 | 4 57 | NEHU 58 | NULL 59 | 60 | Durability 61 | 20 62 | 1 63 | NEDU 64 | NULL 65 | 66 | Might 67 | 21 68 | 1 69 | NEDU 70 | NULL 71 | 72 | Hit 73 | 22 74 | 1 75 | NEDU 76 | NULL 77 | 78 | Weight 79 | 23 80 | 1 81 | NEDU 82 | NULL 83 | 84 | Crit 85 | 24 86 | 1 87 | NEDU 88 | NULL 89 | 90 | Range (Min-Max) 91 | 25 92 | 1 93 | NEHU 94 | NULL 95 | 96 | Cost Per Use 97 | 26 98 | 2 99 | NEDU 100 | NULL 101 | 102 | Weapon Rank 103 | 28 104 | 1 105 | NEDU 106 | NULL 107 | 108 | Item Icon Index 109 | 29 110 | 1 111 | NEHU 112 | NULL 113 | 114 | Staff/Use Effect 115 | 30 116 | 1 117 | NEHU 118 | NULL 119 | 120 | Weapon Effect 121 | 31 122 | 1 123 | NEDU 124 | NULL 125 | 126 | Weapon Experience 127 | 32 128 | 1 129 | NEDU 130 | NULL 131 | -------------------------------------------------------------------------------- /GameData/Tables/_ClassEditorList.txt: -------------------------------------------------------------------------------- 1 | Lord (Ephraim) 2 | Lord (Eirika) 3 | Great Lord (Ephraim) 4 | Great Lord (Eirika) 5 | Cavalier 6 | Cavalier (F) 7 | Paladin 8 | Paladin (F) 9 | Knight 10 | Knight (F) 11 | General 12 | General (F) 13 | Thief 14 | Manakete 15 | Mercenary 16 | Mercenary (F) 17 | Hero 18 | Hero (F) 19 | Myrmidon 20 | Myrmidon (F) 21 | Swordmaster 22 | Swordmaster (F) 23 | Assassin 24 | Assassin (F) 25 | Archer 26 | Archer (F) 27 | Sniper 28 | Sniper (F) 29 | Ranger 30 | Ranger (F) 31 | Wyvern Rider 32 | Wyvern Rider (F) 33 | Wyvern Lord 34 | Wyvern Lord (F) 35 | Wyvern Knight 36 | Wyvern Knight (F) 37 | Mage 38 | Mage (F) 39 | Sage 40 | Sage (F) 41 | Mage Knight 42 | Mage Knight (F) 43 | Bishop 44 | Bishop (F) 45 | Shaman 46 | Shaman (F) 47 | Druid 48 | Druid (F) 49 | Summoner 50 | Summoner (F) 51 | Rogue 52 | Gorgon Egg 53 | Great Knight 54 | Great Knight (F) 55 | Recruit (2) 56 | Journeyman (3) 57 | Pupil (3) 58 | Recruit (3) 59 | Manakete 60 | Manakete (F) 61 | Journeyman (1) 62 | Pupil (1) 63 | Fighter 64 | Warrior 65 | Brigand 66 | Pirate 67 | Berserker 68 | Monk 69 | Priest 70 | Bard 71 | Recruit (1) 72 | Pegasus Knight 73 | Falcoknight 74 | Cleric 75 | Troubadour 76 | Valkyrie 77 | Dancer 78 | Soldier 79 | Necromancer 80 | Fleet 81 | Ghost Fighter 82 | Revenant 83 | Entombed 84 | Bonewalker 85 | Bonewalker (Bow) 86 | Wight 87 | Wight (Bow) 88 | Bael 89 | Elder Bael 90 | Cyclops 91 | Mauthedoog 92 | Gwyllgi 93 | Tarvos 94 | Maelduin 95 | Mogall 96 | ArchMogall 97 | Gorgon 98 | Gorgon Egg 99 | Gargoyle 100 | Deathgoyle 101 | Dracozombie 102 | Demon King 103 | Archer on Ballista 104 | Archer on Iron Ballista 105 | Archer on Killer Ballista 106 | Ballista 107 | Iron Ballista 108 | Killer Ballista 109 | Civilian 110 | Civilian (F) 111 | Civilian 112 | Civilian (F) 113 | Civilian 114 | Civilian (F) 115 | Peer 116 | Queen 117 | Prince 118 | Queen 119 | -- 120 | Fallen Prince 121 | Tent 122 | Pontifex 123 | Dead Peer 124 | Cyclops 125 | Elder Bael 126 | Journeyman (2) 127 | Pupil (2) -------------------------------------------------------------------------------- /Main.event: -------------------------------------------------------------------------------- 1 | #ifndef MAIN 2 | #define MAIN 3 | 4 | #define DEBUG 5 | #define CHAX 6 | 7 | #include "Extensions/Hack Installation.txt" 8 | #include "EAstdlib.event" 9 | 10 | #define FreeSpace 0xB2A610 11 | #define FreeSpaceEnd 0xC00000 12 | 13 | #define FreeSpace_BLRange 0x1C1EC0 14 | 15 | ORG FreeSpace_BLRange 16 | // Nothing ! 17 | 18 | ORG FreeSpace 19 | ALIGN 4 20 | #include "Writans/Text.event" 21 | 22 | ALIGN 4 23 | #include "GameData/GameData.event" 24 | 25 | ALIGN 4 26 | #include "Wizardry/_WizardryMain.event" 27 | 28 | ALIGN 4 29 | #include "Spritans/Portraits.event" 30 | 31 | /* 32 | ALIGN 4 33 | #include "Spritans/Spells.event" 34 | */ 35 | 36 | ALIGN 4 37 | #include "Songs/Songs.event" 38 | 39 | { 40 | #include "Chapters/Chapters.event" 41 | } 42 | 43 | // If the following assertion fails, it means we ran out of free space. 44 | // If that happens, we want to either split out our data between different 45 | // sections, or start writing after the end of the ROM (offset 0x1000000+) 46 | 47 | ASSERT (FreeSpaceEnd - CURRENTOFFSET) 48 | 49 | #else // MAIN 50 | MESSAGE wat are u doin 51 | #endif // MAIN 52 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | .SUFFIXES: 3 | .PHONY: 4 | 5 | # EA Input File 6 | EVENT_MAIN := Main.event 7 | 8 | # ROMs 9 | ROM_SOURCE := FE8U.gba 10 | ROM_TARGET := HACK.gba 11 | 12 | include tools.mk 13 | 14 | # Common cache directory 15 | # Used to generate dependency files in 16 | CACHE_DIR := .cache_dir 17 | $(shell mkdir -p $(CACHE_DIR) > /dev/null) 18 | 19 | CLEAN_FILES := 20 | CLEAN_DIRS := 21 | 22 | # =============== 23 | # = MAIN TARGET = 24 | # =============== 25 | 26 | hack: $(ROM_TARGET) 27 | 28 | .PHONY: hack 29 | 30 | # ================= 31 | # = THE BUILDFILE = 32 | # ================= 33 | 34 | # EA depends 35 | EVENT_DEPENDS := $(shell $(EADEP) $(EVENT_MAIN) -I $(realpath .)/Tools/EventAssembler --add-missings) 36 | 37 | # Additional EA commandline flags 38 | # EAFLAGS := -raws:Tools/EA-Raws --nocash-sym 39 | EAFLAGS := 40 | 41 | $(ROM_TARGET): $(EVENT_MAIN) $(EVENT_DEPENDS) $(ROM_SOURCE) 42 | $(NOTIFY_PROCESS) 43 | @cp -f $(ROM_SOURCE) $(ROM_TARGET) 44 | @$(EA) A FE8 -output:$(ROM_TARGET) -input:$(EVENT_MAIN) $(EAFLAGS) || (rm $(ROM_TARGET) && false) 45 | @cat "$(ROM_SOURCE:.gba=.sym)" >> "$(ROM_TARGET:.gba=.sym)" || true 46 | 47 | ifeq ($(MAKECMDGOALS),clean) 48 | CLEAN_FILES += $(ROM_TARGET) $(ROM_TARGET:.gba=.sym) $(EVENT_SYMBOLS) 49 | endif 50 | 51 | # =================== 52 | # = COMPONENT RULES = 53 | # =================== 54 | 55 | include spritans.mk 56 | include writans.mk 57 | include game-data.mk 58 | include wizardry.mk 59 | 60 | # ============== 61 | # = MAKE CLEAN = 62 | # ============== 63 | 64 | clean: 65 | @rm -f $(CLEAN_FILES) 66 | @rm -rf $(CLEAN_DIRS) 67 | @rm -rf $(CACHE_DIR) 68 | 69 | @echo all clean! 70 | 71 | .PHONY: clean 72 | 73 | # ======================== 74 | # = INCLUDE DEPENDENCIES = 75 | # ======================== 76 | 77 | ifneq ($(MAKECMDGOALS),clean) 78 | -include $(wildcard $(CACHE_DIR)/*.d) 79 | endif 80 | -------------------------------------------------------------------------------- /Songs/NIMap.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Songs/NIMap.bin -------------------------------------------------------------------------------- /Songs/SongHelpers.event: -------------------------------------------------------------------------------- 1 | #ifndef SONG_HELPERS 2 | #define SONG_HELPERS 3 | 4 | #ifndef SetSymbolDefined 5 | // SetSymbol macro as an alternative to "Name = Value" (for backwards/ColorzCore compatibility) 6 | 7 | #define SetSymbolDefined 8 | #define SetSymbol(__aName, __aValue) "PUSH; ORG (__aValue); __aName:; POP" 9 | #endif // SetSymbolDefined 10 | 11 | SetSymbol(SongTable, 0x224470) 12 | 13 | #define SG_FIGHTBGM 0 14 | #define SG_MAPBGM 1 15 | #define SG_SFX 6 16 | 17 | #define SetSongEntry(aIndex, aSong, aGroup) "PUSH; ORG SongTable + 8*(aIndex); POIN (aSong); SHORT (aGroup) (aGroup); POP" 18 | 19 | #endif // SONG_HELPERS 20 | -------------------------------------------------------------------------------- /Songs/Songs.event: -------------------------------------------------------------------------------- 1 | #ifndef SONGS 2 | #define SONGS 3 | 4 | #include "SongHelpers.event" 5 | 6 | #include "DrumFix.event" 7 | 8 | voicegroup000: 9 | #incbin "NIMap.bin" 10 | 11 | #include "Midis/FE5Attack.lyn.event" 12 | SetSongEntry(0x19, FE5_Attack, SG_FIGHTBGM) 13 | 14 | #endif // SONGS 15 | -------------------------------------------------------------------------------- /Spritans/PortraitList.txt: -------------------------------------------------------------------------------- 1 | 2 | # Index MouthX MouthY EyesX EyesY IndexDefinition 3 | "Portraits/Florina.png" 0x02 2 7 3 5 MUG_FLORINA 4 | -------------------------------------------------------------------------------- /Spritans/Portraits/Florina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Spritans/Portraits/Florina.png -------------------------------------------------------------------------------- /Tools/.gitignore: -------------------------------------------------------------------------------- 1 | ParseFile* 2 | PortraitFormatter* 3 | lyn* 4 | ea-dep* 5 | midi2agb* 6 | gbagfx* 7 | bin2ea* 8 | EventAssembler/* 9 | libevent/* 10 | StanR* 11 | *__pycache__* 12 | -------------------------------------------------------------------------------- /Tools/py-old/blfind.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | 3 | # like Pointer Finder, but for BLs/function calls 4 | 5 | # Authored by Colorz 6 | def memoize(func): 7 | cache = {} 8 | 9 | def wrapper(*args): 10 | if args in cache: 11 | return cache[args] 12 | 13 | else: 14 | result = func(*args) 15 | cache[args] = result 16 | 17 | return result 18 | 19 | return wrapper 20 | 21 | @memoize 22 | def read_rom_halfwords(romFileName): 23 | hwords = [] 24 | 25 | with open(romFileName, 'rb') as rom: 26 | while True: 27 | hword = rom.read(2) 28 | 29 | if hword == b'': 30 | break 31 | 32 | hwords.append(hword) 33 | 34 | return hwords 35 | 36 | def make_bls(co, to): 37 | op = (to - co - 4) >> 1 38 | bl1 = (((op>>11)&0x7ff)|0xf000) 39 | bl2 = ((op&0x7ff)|0xf800) 40 | 41 | return (bl1, bl2) 42 | 43 | def bl_iter(romFileName, targetOffset): 44 | hwords = read_rom_halfwords(romFileName) 45 | 46 | last = None 47 | 48 | for i, hword in enumerate(hwords): 49 | if last != None: 50 | co = (i-1) * 2 51 | bls = make_bls(co, targetOffset) 52 | 53 | if last == bls[0].to_bytes(2, 'little') and hword == bls[1].to_bytes(2, 'little'): 54 | yield co 55 | 56 | last = hword 57 | 58 | @memoize 59 | def bl_offsets(romFileName, targetOffset): 60 | return tuple(bl_iter(romFileName, targetOffset)) 61 | 62 | def main(args): 63 | target = int(args[2], base = 0) & 0x1FFFFFF 64 | 65 | for offset in bl_offsets(args[0], int(args[1], base = 0) & 0x1FFFFFF): 66 | bl = make_bls(offset, target) 67 | 68 | print('ORG ${:X}'.format(offset)) 69 | print('\tSHORT ${:X} ${:X}'.format(bl[0], bl[1])) 70 | 71 | if __name__ == '__main__': 72 | main(sys.argv[1:]) 73 | -------------------------------------------------------------------------------- /Tools/py-old/c2s.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python3 2 | 3 | import sys, csv, os 4 | import nightmare 5 | 6 | # This is experimental, do not use 7 | # Takes a csv and a nmm and throws out asm 8 | # like c2ea, but without the ea part 9 | # well, without a lot of things actually 10 | 11 | def gen_lines(csvName, nmmName): 12 | nmm = nightmare.NightmareTable(nmmName) 13 | 14 | with open(csvName, 'r') as csvFile: 15 | table = csv.reader(csvFile) 16 | 17 | tableName = next(table)[0] 18 | 19 | yield '.global {}'.format(tableName) 20 | yield '{}:'.format(tableName) 21 | 22 | for row in table: 23 | if len(row) < (nmm.colNum + 1): 24 | sys.exit("{} contains a row with not enough entries!".format(csvName)) 25 | 26 | for entry, data in zip(nmm.columns, row[1:]): 27 | if (data == None) or (data == ''): 28 | sys.exit("{} contains a blank cell!".format(csvName)) 29 | 30 | if entry.length == 4: 31 | yield '.4byte {}'.format(data) 32 | 33 | elif entry.length == 2: 34 | yield '.2byte {}'.format(data) 35 | 36 | elif entry.length == 1: 37 | yield '.byte {}'.format(data) 38 | 39 | else: 40 | # Handle arbitrary field size 41 | 42 | bytelist = int(data, 0).to_bytes(entry.length, 'little', signed = entry.signed) 43 | yield '.byte {}'.format(', '.join(map(lambda x: '0x{:X}'.format(x), bytelist))) 44 | 45 | if __name__ == '__main__': 46 | csvFile = sys.argv[1] 47 | nmmFile = sys.argv[2] 48 | 49 | for line in gen_lines(csvFile, nmmFile): 50 | print(line) 51 | -------------------------------------------------------------------------------- /Tools/py-old/n2c.py: -------------------------------------------------------------------------------- 1 | import nightmare, csv, sys, glob, os 2 | 3 | def show_exception_and_exit(exc_type, exc_value, tb): 4 | import traceback 5 | 6 | traceback.print_exception(exc_type, exc_value, tb) 7 | sys.exit(-1) 8 | 9 | def process(nmm, rom, filename): 10 | headers = [ hex(nmm.offset) ] 11 | 12 | for col in nmm.columns: 13 | headers.append(col.description) 14 | 15 | table = [ headers ] 16 | 17 | for row in range(nmm.rowNum): 18 | rowOffset = nmm.offset + row*nmm.rowLength 19 | 20 | try: 21 | thisRow = [nmm.entryNames[row]] 22 | 23 | except IndexError: 24 | thisRow = [hex(row)] 25 | 26 | for col in range(nmm.colNum): 27 | entry = nmm.columns[col] 28 | currentOffset = rowOffset + entry.offset 29 | dt = int.from_bytes(rom[currentOffset:currentOffset+entry.length], 'little', signed=entry.signed) 30 | 31 | if (entry.base==16): 32 | dt = hex(dt) 33 | 34 | thisRow.append(dt) 35 | 36 | table.append(thisRow) 37 | # rom.close() 38 | 39 | with open(filename, 'w') as myfile: 40 | wr = csv.writer(myfile, quoting=csv.QUOTE_ALL, lineterminator='\n') 41 | wr.writerows(table) 42 | print("Wrote to " + filename) 43 | 44 | def main(): 45 | sys.excepthook = show_exception_and_exit 46 | 47 | try: 48 | inputROM = sys.argv[1] 49 | 50 | except IndexError: 51 | pass 52 | # root = tk.Tk() 53 | # root.withdraw() 54 | # inputROM = filedialog.askopenfilename(filetypes=[("GBA files",".gba"),("All files",".*")],initialdir=os.getcwd(),title="Select ROM to rip data from") 55 | 56 | (dirname, filename) = os.path.split(inputROM) 57 | 58 | # if (dirname): 59 | # moduleList = glob.glob(dirname + '/**/*.nmm',recursive=True) #a list of all nightmare modules in the directory 60 | # else: 61 | # moduleList = glob.glob('**/*.nmm',recursive=True) 62 | 63 | moduleList = glob.glob('**/*.nmm',recursive=True) 64 | for inputNMM in moduleList: 65 | outputname = inputNMM.replace(".nmm",".csv") #let's just keep the same file name for now 66 | # print("Module:\t" + inputNMM) 67 | # print("Output:\t" + outputname) 68 | try: 69 | nmm = nightmare.NightmareTable(inputNMM) 70 | 71 | with open(inputROM, 'rb') as rom_file: 72 | rom = bytes(rom_file.read()) 73 | 74 | process(nmm, rom, outputname) 75 | except AssertionError as e: 76 | print("Error in " + inputNMM+":\n" + str(e)) 77 | 78 | if __name__ == '__main__': 79 | main() 80 | -------------------------------------------------------------------------------- /Tools/py-old/pfind.py: -------------------------------------------------------------------------------- 1 | # Module providing pointer-finding facilities 2 | # Used by pfinder & c2ea 3 | 4 | # Authored by Colorz 5 | def memoize(func): 6 | cache = {} 7 | 8 | def wrapper(*args): 9 | if args in cache: 10 | return cache[args] 11 | 12 | else: 13 | result = func(*args) 14 | cache[args] = result 15 | 16 | return result 17 | 18 | return wrapper 19 | 20 | @memoize 21 | def read_rom_words(romFileName): 22 | words = [] 23 | 24 | with open(romFileName, 'rb') as rom: 25 | while True: 26 | word = rom.read(4) 27 | 28 | if word == b'': 29 | break 30 | 31 | words.append(word) 32 | 33 | return words 34 | 35 | def pointer_iter(romFileName, value): 36 | target = value.to_bytes(4, 'little') 37 | words = read_rom_words(romFileName) 38 | 39 | return (i * 4 for i, word in enumerate(words) if word == target) 40 | 41 | @memoize 42 | def pointer_offsets(romFileName, value): 43 | return tuple(pointer_iter(romFileName, value)) 44 | -------------------------------------------------------------------------------- /Tools/py-old/pfinder.py: -------------------------------------------------------------------------------- 1 | # Pointer Finder finds pointers 2 | # Given Rom, Pointer, New Pointer 3 | # prints event format to stdout 4 | 5 | import os, sys 6 | import pfind 7 | 8 | def parseNum(num): 9 | """0x or $ is hex, 0b is binary, 0 is octal. Otherwise assume decimal.""" 10 | 11 | num = str(num).strip() 12 | base = 10 13 | 14 | if (num[0] == '0') & (len(num) > 1): 15 | if num[1] == 'x': 16 | base = 16 17 | 18 | elif num[1] == 'b': 19 | base = 2 20 | 21 | else: 22 | base = 8 23 | 24 | elif num[0]=='$': 25 | base = 16 26 | 27 | return int(num, base) 28 | 29 | def main(): 30 | hwOffset = 0x8000000 31 | 32 | if len(sys.argv) < 4: 33 | sys.exit("Usage: {0} [--to-stdout (ignored)]".format(sys.argv[0])) 34 | 35 | rom = sys.argv[1] # rom file name 36 | target = (parseNum(sys.argv[2]) | hwOffset) # pointer (int) 37 | replacement = "POIN " + sys.argv[3] # offset or label 38 | 39 | print("PUSH") 40 | 41 | for offset in pfind.pointer_offsets(rom, target): 42 | print("ORG {}".format(hex(offset))) 43 | print(replacement) 44 | 45 | print("POP") 46 | 47 | if __name__ == '__main__': 48 | main() 49 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/AForge/AForge.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_AFORGE_INCLUDED 2 | #define HAX_AFORGE_INCLUDED 3 | 4 | #ifndef HAX_VCI_INCLUDED 5 | ERROR "A Forge requires VCI to be included." 6 | #endif // HAX_VCI_INCLUDED 7 | 8 | #define AF_ITEM SlimSword 9 | #define AF_DATA_ADDR 0x203F800 10 | 11 | #include "Src/AfCore.lyn.event" 12 | 13 | #include "Src/AfHooks.lyn.event" 14 | 15 | gAfItemId: 16 | BYTE AF_ITEM 17 | 18 | ALIGN 4 19 | gpAfErr: 20 | // Af error flags pointer 21 | WORD AF_DATA_ADDR 22 | 23 | ALIGN 4 24 | gpAfData: 25 | // Forge & Ref data pointer 26 | WORD AF_DATA_ADDR + 4 27 | 28 | ALIGN 4 29 | gAfItemInfo: 30 | VciBlankInfo 31 | 32 | VciInjectFunc(gAfItemInfo, VciFuncGetIndex, AfGetItemIndex) 33 | VciInjectFunc(gAfItemInfo, VciFuncGetName, AfGetItemName) 34 | VciInjectFunc(gAfItemInfo, VciFuncGetUses, AfGetItemUses) 35 | VciInjectFunc(gAfItemInfo, VciFuncGetMight, AfGetItemMight) 36 | VciInjectFunc(gAfItemInfo, VciFuncGetHit, AfGetItemHit) 37 | VciInjectFunc(gAfItemInfo, VciFuncGetCrit, AfGetItemCrit) 38 | VciInjectFunc(gAfItemInfo, VciFuncGetAfterUse, AfGetItemAfterUse) 39 | 40 | VciInjectInfo(AF_ITEM, gAfItemInfo) 41 | 42 | #ifndef HookProtectDefined 43 | #define HookProtectDefined 44 | 45 | #ifdef DEBUG 46 | #ifdef __COLORZ_CORE__ 47 | #define HookProtect(aFrom, aTo) "PROTECT (aFrom) (aTo); ASSERT (aTo) - CURRENTOFFSET" 48 | #else 49 | // Stan!Core breaks PROTECT, and there's no proper way of reckognizing a Stan!Core from a legacy Core 50 | #define HookProtect(aFrom, aTo) "ASSERT (aTo) - CURRENTOFFSET" 51 | #endif 52 | #else 53 | #define HookProtect(aFrom, aTo) " " 54 | #endif 55 | #endif // HookProtectDefined 56 | 57 | PUSH 58 | 59 | // Calling AfGc at relevant points (avoid ref overflows caused by repeated calls to GetItemAfterUse) 60 | 61 | ORG $02A1F6 // At the end of BattleGenerateSimulationInternal 62 | SHORT $46C0; WORD $47184B00; POIN AfHook_BGSI_Gc 63 | HookProtect($02A1F6, $02A204) 64 | 65 | POP 66 | 67 | #include "AForgeScreen.event" 68 | 69 | #endif // HAX_AFORGE_INCLUDED 70 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/AForge/AForgeScreen.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_AFORGE_SCREEN_INCLUDED 2 | #define HAX_AFORGE_SCREEN_INCLUDED 3 | 4 | #include "Src/AfScreen.lyn.event" 5 | 6 | #endif // HAX_AFORGE_SCREEN_INCLUDED 7 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/AForge/Src/Af.h: -------------------------------------------------------------------------------- 1 | #ifndef AF_INCLUDED 2 | #define AF_INCLUDED 3 | 4 | #include "gbafe.h" 5 | #include "assert.h" 6 | 7 | // types 8 | 9 | enum 10 | { 11 | AF_FORGED_MAX = 0x20, 12 | AF_REF_MAX = AF_FORGED_MAX + 0x10, 13 | 14 | AF_NAME_BYTES = 13, 15 | 16 | AF_MIGHT_BITS = 4, 17 | AF_HIT_BITS = 4, 18 | AF_CRIT_BITS = 4, 19 | 20 | AF_MIGHT_STEP = 1, 21 | AF_HIT_STEP = 5, 22 | AF_CRIT_STEP = 3, 23 | 24 | AF_ERR_NONE = 0, 25 | AF_ERR_BADSAVE = 1, 26 | AF_ERR_REFOVERFLOW = 2, 27 | AF_ERR_FORGEOVERFLOW = 3, 28 | }; 29 | 30 | struct ForgedItemData 31 | { 32 | u8 item; 33 | char name[AF_NAME_BYTES]; 34 | 35 | u16 rawMight : AF_MIGHT_BITS; 36 | u16 rawHit : AF_HIT_BITS; 37 | u16 rawCrit : AF_CRIT_BITS; 38 | u16 gcBit : 1; 39 | }; 40 | 41 | struct AfDataGlobal 42 | { 43 | static_assert(sizeof(struct ForgedItemData) <= 0x10, "ForgedItemData takes more space than expected!"); 44 | 45 | // here hold the actual forge data (which is: the underlying item id, the forge name and the stat bonuses) 46 | // They don't hold the forge's *uses* for efficiency reasons. 47 | struct ForgedItemData items[AF_FORGED_MAX]; 48 | 49 | // here hold forge references: they hold the id of the forged item, and the item uses. 50 | // The reason refs hold uses is because item copying is trivial, but use depletion should only reflect one copy 51 | // So each time an item loses an use, we need to copy the item's data before updating its uses 52 | // Using an extra layer of references here is more efficient as it requires less space overall 53 | u16 refs[AF_REF_MAX]; 54 | 55 | // A forged item (as in: the value that's held by inventories) holds the global forged item id (constant), and a ref id 56 | }; 57 | 58 | // functions 59 | 60 | // Forged item functions 61 | int AfCanForgeItem(int item); 62 | int AfMakeForgedItem(int baseItem); 63 | void AfSetMightBonus(int item, int mightLevel); 64 | void AfSetHitBonus(int item, int hitLevel); 65 | void AfSetHitBonus(int item, int critLevel); 66 | void AfSetName(int item, const char* name); 67 | 68 | // Important core system functions 69 | void AfInit(void); 70 | void AfGc(void); 71 | 72 | // objects 73 | 74 | extern struct AfDataGlobal* const gpAfData; 75 | extern u32* const gpAfErr; 76 | 77 | extern const u8 gAfItemId; 78 | 79 | #endif // AF_INCLUDED 80 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/AForge/Src/AfHooks.s: -------------------------------------------------------------------------------- 1 | 2 | .thumb @ do not forget! (well actually because of hashtag lyn I could forget and have it work just fine :) ) 3 | 4 | .global AfHook_BGSI_Gc 5 | .type AfHook_BGSI_Gc, function 6 | 7 | AfHook_BGSI_Gc: 8 | @ call AfGc 9 | 10 | ldr r3, =AfGc 11 | bl call_via_r3 12 | 13 | @ replaced (lol) 14 | pop {r3-r4} 15 | mov r8, r3 16 | mov r9, r4 17 | pop {r4-r7} 18 | pop {r3} 19 | 20 | call_via_r3: 21 | bx r3 22 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/AMSS/AMSS.event: -------------------------------------------------------------------------------- 1 | #ifndef AMSS_INCLUDED 2 | #define AMSS_INCLUDED 3 | 4 | // Actually Modular Stat Screen 5 | // hack by Stan, inspired by circleseverywhere's MSS 6 | 7 | // This is like MSS, but it 8 | // 1. is in C 9 | // 2. is actually modular (with real modules, not just "you can edit the source" kind of modular) (also better help text) 10 | 11 | PUSH 12 | 13 | ORG $08899C 14 | POIN AmssMainProcScr 15 | 16 | // ORG $088670 // Replace stat screen drawing routine 17 | // WORD $46C04778 $E59FC000 $E12FFF1C; POIN NuDrawStatScreen 18 | 19 | // ORG $0878CC 20 | // WORD $46C04778 $E59FC000 $E12FFF1C; POIN NuDrawStatScreenPage 21 | 22 | // ORG $0889A0 23 | // WORD $46C04778 $E59FC000 $E12FFF1C; POIN NuStartStatScreenHelp 24 | 25 | POP 26 | 27 | #define AmssModule(aXX, aYY, aWidth, aHeight, aAddr) "BYTE (aXX) (aYY) (aWidth) (aHeight); WORD 0; POIN (aAddr)" 28 | #define AmssModule(aXX, aYY, aWidth, aHeight, aAddr, aUser) "BYTE (aXX) (aYY) (aWidth) (aHeight); WORD (aUser); POIN (aAddr)" 29 | #define AmssModuleEnd "WORD 0 0 0" 30 | 31 | #include "Src/AmssDebug.lyn.event" 32 | #include "Src/AmssHelp.lyn.event" 33 | #include "Src/AmssUnitChange.lyn.event" 34 | #include "Src/AmssCore.lyn.event" 35 | 36 | #include "Modules/Portrait/AmssPortrait.event" 37 | #include "Modules/Pages/AmssPage.event" 38 | 39 | ALIGN 4 40 | AmssCoreModules: 41 | AmssModule(1, 1, 10, 9, AmssMiniPortraitModule, 0x000B0410) 42 | AmssModule(11, 2, 19, 18, AmssPageModule, 0x08000000 + AmssPages) 43 | // AmssModule(11, 1, 0, 0, AmssPortraitModule) 44 | // AmssModule(11, 11, 0, 0, AmssPortraitModule) 45 | AmssModuleEnd 46 | 47 | ALIGN 4 48 | AmssPages: 49 | POIN AmssPage1Modules 50 | POIN AmssPage2Modules 51 | POIN AmssPage3Modules 52 | WORD 0 53 | 54 | ALIGN 4 55 | AmssPage1Modules: 56 | AmssModule(1, 1, 10, 9, AmssPortraitModule) 57 | AmssModuleEnd 58 | 59 | ALIGN 4 60 | AmssPage2Modules: 61 | AmssModuleEnd 62 | 63 | ALIGN 4 64 | AmssPage3Modules: 65 | AmssModule(4, 4, 10, 9, AmssPortraitModule) 66 | AmssModuleEnd 67 | 68 | #endif // AMSS_INCLUDED 69 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/AMSS/Data/DbgTiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/.Limbo/AMSS/Data/DbgTiles.png -------------------------------------------------------------------------------- /Wizardry/.Limbo/AMSS/Modules/Pages/AmssPage.event: -------------------------------------------------------------------------------- 1 | #ifndef AMSS_PAGE_INCLUDED 2 | #define AMSS_PAGE_INCLUDED 3 | 4 | // Page modules for AMSS 5 | // hack by Stan 6 | 7 | #include "Src/AmssPage.lyn.event" 8 | 9 | #endif // AMSS_PAGE_INCLUDED 10 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/AMSS/Modules/Pages/Src/AmssPage.h: -------------------------------------------------------------------------------- 1 | #ifndef AMSS_PAGE_INCLUDED 2 | #define AMSS_PAGE_INCLUDED 3 | 4 | #include "Amss.h" 5 | 6 | #endif // AMSS_PAGE_INCLUDED 7 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/AMSS/Modules/Pages/Src/AmssPageName.c: -------------------------------------------------------------------------------- 1 | 2 | #include "AmssPage.h" 3 | 4 | struct AmssPageNameItem 5 | { 6 | const void* img; 7 | const void* palette; 8 | const void* obj; 9 | }; 10 | 11 | struct AmssPageNameInfo 12 | { 13 | const struct AmssPageNameItem back; 14 | const struct AmssPageNameItem items[]; 15 | }; 16 | 17 | struct AmssPageNameProc 18 | { 19 | /* 00 */ PROC_HEADER; 20 | 21 | /* 2C */ unsigned cnt; 22 | /* 30 */ unsigned tileid; 23 | /* 34 */ unsigned palid; 24 | /* 38 */ unsigned affineid; 25 | 26 | /* 3C */ struct AmssGeometry rect; 27 | /* 40 */ const struct AmssPageNameInfo* info; 28 | }; 29 | 30 | static void AmssPageName_OnIdle(struct AmssPageNameProc* proc); 31 | static void AmssPageName_ChangeOutLoop(struct AmssPageNameProc* proc); 32 | static void AmssPageName_ChangeInLoop(struct AmssPageNameProc* proc); 33 | 34 | static 35 | const struct ProcInstruction sPageNameProcScr[] = 36 | { 37 | PROC_SET_NAME("StanScreen PageName Module"), 38 | PROC_YIELD, 39 | 40 | PROC_LABEL(0), // Idle 41 | PROC_LOOP_ROUTINE(AmssPageName_OnIdle), 42 | 43 | PROC_LABEL(1), // Change page 44 | PROC_LOOP_ROUTINE(AmssPageName_ChangeOutLoop), 45 | PROC_LOOP_ROUTINE(AmssPageName_ChangeInLoop), 46 | 47 | PROC_GOTO(0), 48 | 49 | PROC_END, 50 | }; 51 | 52 | static 53 | void AmssPageName_Display(struct AmssPageNameProc* proc) 54 | { 55 | ObjInsertSafe( 56 | 4, 57 | proc->rect.x*16, 58 | proc->rect.y*16, 59 | proc->info->items[gStatScreenData.page].obj, 60 | TILEREF(proc->tileid, proc->palid)); 61 | } 62 | 63 | static void AmssPageName_OnIdle(struct AmssPageNameProc* proc) 64 | { 65 | 66 | } 67 | 68 | static void AmssPageName_ChangeOutLoop(struct AmssPageNameProc* proc) 69 | { 70 | 71 | } 72 | 73 | static void AmssPageName_ChangeInLoop(struct AmssPageNameProc* proc) 74 | { 75 | 76 | } 77 | 78 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/AMSS/Modules/Portrait/AmssPortrait.event: -------------------------------------------------------------------------------- 1 | #ifndef AMSS_PORTRAIT_INCLUDED 2 | #define AMSS_PORTRAIT_INCLUDED 3 | 4 | // Portrait modules for AMSS 5 | // hack by Stan 6 | 7 | /* INCLUDED MODULES: 8 | * 9 | * AmssPortraitModule: 10 | * * Size: Fixed [10, 9], please use that 11 | * * User (optional): TILEREF* for graphics 12 | * * Displays unit portrait as it would have been in the vanilla stat screen 13 | * 14 | * Note: a TILEREF here means a value encoding a tile id and pal id in the way it would be on a tilemap 15 | * Which means: low 10 bits are tile id, next 2 bits unused and next 4 bits are pal id 16 | */ 17 | 18 | #include "Src/AmssPortrait.lyn.event" 19 | 20 | #endif // AMSS_PORTRAIT_INCLUDED 21 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/AMSS/Modules/Portrait/Src/AmssPortrait.c: -------------------------------------------------------------------------------- 1 | 2 | #include "Amss.h" // TODO: fix 3 | 4 | // TODO: update reference and add to CLib 5 | static void(*DisplayBgFace)(struct Proc* proc, u16* map, unsigned portrait, unsigned tileId, unsigned palId) = (const void*)(0x08005E98+1); 6 | static const void(*DrawMiniMug)(unsigned portrait, u16* map, int tileId, int palId, int side) = (const void*)(0x08005988+1); 7 | 8 | static void AmssPortraitInit(u16* fg, u16* bg, u32 user, struct AmssGeometry rect, struct AmssMainProc* proc); 9 | // static void AmssPortraitIdle(u16* fg, u16* bg, u32 user, const struct AmssGeometry* geometry, struct Proc* proc); 10 | 11 | //* 12 | 13 | static 14 | const struct AmssHelpInfo sTestHelpInfo[] = { 15 | { { 0, 0, 4, 4 }, 2, NULL }, 16 | { { 0, 5, 4, 4 }, 7, NULL }, 17 | { { 6, 0, 4, 4 }, 12, NULL }, 18 | { { 6, 5, 4, 4 }, 13, NULL }, 19 | {} 20 | }; 21 | 22 | // */ 23 | 24 | const struct AmssModule AmssPortraitModule = { 25 | .onInit = AmssPortraitInit, 26 | .helpInfo = sTestHelpInfo 27 | }; 28 | 29 | static void AmssPortraitInit(u16* fg, u16* bg, u32 user, struct AmssGeometry rect, struct AmssMainProc* proc) 30 | { 31 | unsigned portrait = GetUnitPortraitId(gStatScreenData.unit); 32 | 33 | if (gStatScreenData.unit->state & US_BIT23) 34 | portrait += 1; 35 | 36 | if (!user) 37 | user = 0x000B04E0; 38 | 39 | DisplayBgFace((struct Proc*) proc, bg + TILEMAP_INDEX(rect.x, rect.y), portrait, user & 0xFFFF, (user >> 16) & 0xF); 40 | } 41 | 42 | static void AmssMiniPortraitInit(u16* fg, u16* bg, u32 user, struct AmssGeometry rect, struct AmssMainProc* proc); 43 | 44 | const struct AmssModule AmssMiniPortraitModule = { 45 | .onInit = AmssMiniPortraitInit, 46 | }; 47 | 48 | static void AmssMiniPortraitInit(u16* fg, u16* bg, u32 user, struct AmssGeometry rect, struct AmssMainProc* proc) 49 | { 50 | unsigned portrait = GetUnitPortraitId(gStatScreenData.unit); 51 | 52 | if (gStatScreenData.unit->state & US_BIT23) 53 | portrait += 1; 54 | 55 | if (!user) 56 | user = 0x000B04E0; 57 | 58 | DrawMiniMug(portrait, bg + TILEMAP_INDEX(rect.x, rect.y), user & 0xFFFF, user >> 16, 0); 59 | } 60 | 61 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/AMSS/Src/AmssDebug.c: -------------------------------------------------------------------------------- 1 | 2 | #include "AmssInternal.h" 3 | 4 | void AmssDebugClear(void) 5 | { 6 | FillBgMap(gBg3MapBuffer, TILEREF(1, 12)); 7 | EnableBgSyncByMask(BG3_SYNC_BIT); 8 | } 9 | 10 | void AmssDebugInit(void) 11 | { 12 | CpuFastFill16(0, VRAM + 0x8000, 0x20); 13 | 14 | for (unsigned i = 0; i < 4; ++i) 15 | { 16 | u16 val = 0x1111 + (i + (i << 4) + (i << 8) + (i << 12)); 17 | CpuFastFill16(val, VRAM + 0x8020 + i*0x20, 0x20); 18 | 19 | gPaletteBuffer[0x10*12 + i+1] = COLOR_RGB(i*6, i*6, i*6); // Regular 20 | gPaletteBuffer[0x10*13 + i+1] = COLOR_RGB(i*2, i*5, i*8); // Selected 21 | gPaletteBuffer[0x10*14 + i+1] = COLOR_RGB(i*2, i*8, i*5); // Neighbor 22 | } 23 | 24 | EnablePaletteSync(); 25 | AmssDebugClear(); 26 | } 27 | 28 | void AmssDebugDisplayRect(struct AmssGeometry rect) 29 | { 30 | for (unsigned iy = rect.y; iy < rect.y + rect.h; ++iy) 31 | for (unsigned ix = rect.x; ix < rect.x + rect.w; ++ix) 32 | gBg3MapBuffer[TILEMAP_INDEX(ix, iy)] += TILEREF(1, 0); 33 | 34 | EnableBgSyncByMask(BG3_SYNC_BIT); 35 | } 36 | 37 | void AmssDebugColorRect(struct AmssGeometry rect, int color) 38 | { 39 | for (unsigned iy = rect.y; iy < rect.y + rect.h; ++iy) 40 | { 41 | for (unsigned ix = rect.x; ix < rect.x + rect.w; ++ix) 42 | { 43 | gBg3MapBuffer[TILEMAP_INDEX(ix, iy)] &= 0x0FFF; 44 | gBg3MapBuffer[TILEMAP_INDEX(ix, iy)] += TILEREF(0, 12 + color); 45 | } 46 | } 47 | } 48 | 49 | static 50 | void AmssDebugDisplayHelp(const struct AmssHelpInfo* info, void* _) 51 | { 52 | AmssDebugDisplayRect(info->rect); 53 | } 54 | 55 | void AmssDebugDisplayHelps(void) 56 | { 57 | AmssForEachHelp(AmssDebugDisplayHelp, NULL); 58 | } 59 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/AMSS/Src/AmssInternal.h: -------------------------------------------------------------------------------- 1 | #ifndef AMSS_INTERNAL_INCLUDED 2 | #define AMSS_INTERNAL_INCLUDED 3 | 4 | #include "Amss.h" 5 | 6 | extern const struct AmssModuleEntry AmssCoreModules[]; 7 | 8 | extern const struct ProcInstruction AmssMainProcScr[]; 9 | 10 | struct AmssMainProc* AmssGetMain(void); 11 | 12 | void AmssChangeUnit(struct AmssMainProc* proc, struct Unit* unit); 13 | 14 | void AmssStartUnitChange(int direction, struct Unit* next, struct AmssMainProc* parent); 15 | 16 | void AmssDebugClear(void); 17 | void AmssDebugInit(void); 18 | void AmssDebugDisplayRect(struct AmssGeometry rect); 19 | void AmssDebugColorRect(struct AmssGeometry rect, int color); 20 | void AmssDebugDisplayHelps(void); 21 | 22 | #endif // AMSS_INTERNAL_INCLUDED 23 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/CSS.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_CSS 2 | #define HAX_CSS 3 | 4 | PUSH 5 | ORG 0x087E24 6 | POIN proc_css 7 | 8 | ORG 0x08899C 9 | POIN proc_css 10 | POP 11 | 12 | ALIGN 4 13 | 14 | // Code 15 | 16 | #include "Src/CSSCommon.lyn.event" 17 | #include "Src/CSSCore.lyn.event" 18 | #include "Src/CSSLeftPanel.lyn.event" 19 | #include "Src/CSSObjText.lyn.event" 20 | #include "Src/CSSMugFrameSmall.lyn.event" 21 | 22 | // Resources 23 | 24 | ALIGN 4 25 | css_stattext_pal: 26 | #incbin "Res/StatTextDummy.gbapal" 27 | 28 | // Debug palette 29 | // #incbin "Res/DebugPal.dmp" 30 | 31 | ALIGN 4 32 | css_lpbg_face_img: 33 | #incbin "Res/LeftPanelBgFace.4bpp.lz" 34 | 35 | ALIGN 4 36 | css_lpbg_face_pal: 37 | #incbin "Res/LeftPanelBgFace.gbapal" 38 | 39 | /* 40 | ALIGN 4 41 | css_mugframe_small_gfx: 42 | #incbin "Res/MugFrameSmall.4bpp.lz" 43 | 44 | ALIGN 4 45 | css_mugframe_small_pal: 46 | #incbin "Res/MugFrameSmall.gbapal" 47 | */ 48 | 49 | #endif // HAX_CSS 50 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/Res/DebugPal.s: -------------------------------------------------------------------------------- 1 | .macro gba_color r, g, b 2 | .short ((\r & 0x1F) | ((\g & 0x1F) << 5) | ((\b & 0x1F) << 10)) 3 | .endm 4 | 5 | .global css_debug_pal 6 | .type css_debug_pal, %object 7 | 8 | css_debug_pal: 9 | gba_color 0, 0, 0 @ 0 | none 10 | 11 | gba_color 30, 0, 0 @ 1 | red 12 | gba_color 0, 30, 0 @ 2 | green 13 | gba_color 0, 0, 30 @ 3 | blue 14 | 15 | gba_color 0, 30, 30 @ 4 | cyan 16 | gba_color 30, 0, 30 @ 5 | magenta 17 | gba_color 30, 30, 0 @ 6 | yellow 18 | 19 | gba_color 15, 0, 0 @ 7 | dark red 20 | gba_color 0, 15, 0 @ 8 | dark green 21 | gba_color 0, 0, 15 @ 9 | dark blue 22 | 23 | gba_color 0, 15, 15 @ A | dark cyan 24 | gba_color 15, 0, 15 @ B | dark magenta 25 | gba_color 15, 15, 0 @ C | dark yellow 26 | 27 | gba_color 10, 10, 10 @ D | dark grey 28 | gba_color 20, 20, 20 @ E | grey 29 | gba_color 30, 30, 30 @ F | white (actually still grey) 30 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/Res/LeftPanelBgFace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/.Limbo/CSS/Res/LeftPanelBgFace.png -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/Res/LeftPanelGrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/.Limbo/CSS/Res/LeftPanelGrid.png -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/Res/MugFrameSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/.Limbo/CSS/Res/MugFrameSmall.png -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/Res/MugFrameSmall.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/.Limbo/CSS/Res/MugFrameSmall.xcf -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/Res/NumbersFont.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/.Limbo/CSS/Res/NumbersFont.png -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/Res/NumbersFont.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/.Limbo/CSS/Res/NumbersFont.xcf -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/Res/StatTextDummy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/.Limbo/CSS/Res/StatTextDummy.png -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/Res/StatTextDummyOriginal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/.Limbo/CSS/Res/StatTextDummyOriginal.png -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/Src/CSSCommon.c: -------------------------------------------------------------------------------- 1 | #include "CSS.h" 2 | 3 | char* css_num2str(char* out, int number) { 4 | // TODO: better 5 | out[0] = '0' + Div(number, 10); 6 | out[1] = '0' + Mod(number, 10); 7 | out[2] = 0; 8 | 9 | return (out[0] == '0') ? out+1 : out; 10 | } 11 | 12 | void css_text_append_number(struct TextHandle* text, int number) { 13 | char buf[0x10]; 14 | 15 | if (number == 0xFF) { 16 | Text_DrawString(text, "--"); 17 | } else { 18 | char* str = css_num2str(buf, number); 19 | Text_DrawString(text, str); 20 | } 21 | } 22 | 23 | void css_text_append_number_2digit(struct TextHandle* text, int number) { 24 | char buf[0x10]; 25 | 26 | if (number == 0xFF) { 27 | Text_DrawString(text, "--"); 28 | } else { 29 | css_num2str(buf, number); 30 | Text_DrawString(text, buf); 31 | } 32 | } 33 | 34 | void css_display_hp_exp_line(u16* bgOut) { 35 | struct TextHandle text; 36 | 37 | /* Drawing HP / */ 38 | 39 | Text_InitClear(&text, 6); 40 | 41 | Text_SetColorId(&text, 3); 42 | Text_DrawString(&text, "HP "); 43 | 44 | Text_SetColorId(&text, 0); 45 | css_text_append_number(&text, gpStatScreenUnit->curHP); 46 | 47 | Text_SetColorId(&text, 3); 48 | Text_DrawString(&text, "/"); 49 | 50 | Text_SetColorId(&text, 0); 51 | css_text_append_number(&text, gpStatScreenUnit->maxHP); 52 | 53 | Text_Display(&text, BG_LOCATED_TILE(bgOut, 0, 0)); 54 | 55 | /* Drawing L */ 56 | 57 | Text_InitClear(&text, 3); 58 | 59 | Text_SetXCursor(&text, 22 - Text_GetStringTextWidth("L00")); 60 | 61 | Text_SetColorId(&text, 3); 62 | Text_DrawString(&text, "L"); 63 | 64 | Text_Advance(&text, 1); 65 | 66 | Text_SetColorId(&text, 0); 67 | css_text_append_number_2digit(&text, gpStatScreenUnit->level); 68 | 69 | Text_Display(&text, BG_LOCATED_TILE(bgOut, 7, 0)); 70 | 71 | /* Drawing E */ 72 | // TODO: align right 73 | 74 | Text_InitClear(&text, 4); 75 | 76 | Text_SetXCursor(&text, 22 - Text_GetStringTextWidth("E00")); 77 | 78 | Text_SetColorId(&text, 3); 79 | Text_DrawString(&text, "E"); 80 | 81 | Text_Advance(&text, 1); 82 | 83 | Text_SetColorId(&text, 0); 84 | css_text_append_number_2digit(&text, gpStatScreenUnit->exp); 85 | 86 | Text_Display(&text, BG_LOCATED_TILE(bgOut, 10, 0)); 87 | } 88 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/Src/CSSCore.c: -------------------------------------------------------------------------------- 1 | #include "CSS.h" 2 | 3 | void css_disable_game_gfx(struct CSSCoreProc* proc); 4 | void css_load_gfx(struct CSSCoreProc* proc); 5 | void css_disable_gfx(struct CSSCoreProc* proc); 6 | 7 | const ProcCode proc_css[] = { 8 | PROC_SET_NAME(CSS_PREFIX":Core"), 9 | 10 | // Clearing game graphics 11 | PROC_CALL_ROUTINE(LockGameGraphicsLogic), 12 | PROC_CALL_ROUTINE(css_disable_game_gfx), 13 | 14 | // 2 frames because this might get executed twice on first frame 15 | // Or something 16 | PROC_SLEEP(2), 17 | 18 | // Loading graphics (while lcd is not displaying) 19 | PROC_CALL_ROUTINE(css_load_gfx), 20 | PROC_SLEEP(0x20), 21 | 22 | // For testing 23 | PROC_BLOCK, 24 | 25 | PROC_CALL_ROUTINE(css_disable_gfx), 26 | 27 | // Restoring game graphics 28 | PROC_CALL_ROUTINE(UnlockGameGraphicsLogic), 29 | 30 | PROC_END 31 | }; 32 | 33 | static const uint16_t css_bg_config[] = { 34 | 0x0000, // bg0 tile data offset 35 | 0x6000, // bg0 map data offset 36 | 0x0000, // bg0 screen size 37 | 38 | 0x0000, 39 | 0x6800, 40 | 0x0000, 41 | 42 | 0x8000, 43 | 0x7000, 44 | 0x0000, 45 | 46 | 0x8000, 47 | 0x7800, 48 | 0x0000 49 | }; 50 | 51 | void css_disable_game_gfx(struct CSSCoreProc* proc) { 52 | // disabling every layer 53 | gLCDIOBuffer.dispControl.enableBg0 = 0; 54 | gLCDIOBuffer.dispControl.enableBg1 = 0; 55 | gLCDIOBuffer.dispControl.enableBg2 = 0; 56 | gLCDIOBuffer.dispControl.enableBg3 = 0; 57 | gLCDIOBuffer.dispControl.enableObj = 0; 58 | 59 | // resetting color effects? 60 | SetColorEffectsParameters(3, 0, 0, 0x10); 61 | 62 | SetColorEffectsFirstTarget(0, 0, 0, 0, 0); 63 | SetColorEffectBackdropFirstTarget(1); 64 | SetColorEffectBackdropSecondTarget(0); 65 | 66 | // resetting palette? 67 | gPaletteBuffer[0] = 0; 68 | EnablePaletteSync(); 69 | } 70 | 71 | void css_load_gfx(struct CSSCoreProc* proc) { 72 | LoadBgConfig(css_bg_config); 73 | 74 | Text_InitFont(); 75 | 76 | const struct Vec2 zeroVec = { 0, 0 }; 77 | 78 | proc->pLPanel = css_lpanel_start(zeroVec, (Proc*)(proc)); 79 | 80 | // enable every layer 81 | gLCDIOBuffer.dispControl.enableBg0 = 1; 82 | gLCDIOBuffer.dispControl.enableBg1 = 1; 83 | gLCDIOBuffer.dispControl.enableBg2 = 1; 84 | gLCDIOBuffer.dispControl.enableBg3 = 1; 85 | gLCDIOBuffer.dispControl.enableObj = 1; 86 | } 87 | 88 | void css_disable_gfx(struct CSSCoreProc* proc) { 89 | css_lpanel_end(proc->pLPanel); 90 | } 91 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSS/Src/CSSMugFrameSmall.c: -------------------------------------------------------------------------------- 1 | #include "CSS.h" 2 | 3 | static void css_mugframe_small_on_update(struct CSSMugFrameSmallProc*); 4 | 5 | static const ProcCode sProc_CSSMugFrameSmall[] = { 6 | PROC_SET_NAME(CSS_PREFIX":MugFrameSmall"), 7 | PROC_LOOP_ROUTINE(css_mugframe_small_on_update), 8 | PROC_END 9 | }; 10 | 11 | struct CSSMugFrameSmallProc* css_mugframe_small_start(uint16_t* pBgOut, uint16_t rootTileIndex) { 12 | struct CSSMugFrameSmallProc* proc; 13 | 14 | proc = (struct CSSMugFrameSmallProc*) Proc_Create(sProc_CSSMugFrameSmall, ROOT_PROC_3); 15 | 16 | proc->rootTileIndex = rootTileIndex; 17 | proc->pBgOutput = pBgOut; 18 | 19 | css_mugframe_small_redraw(proc); 20 | 21 | return proc; 22 | } 23 | 24 | void css_mugframe_small_end(struct CSSMugFrameSmallProc* proc) { 25 | Proc_Delete((Proc*)(proc)); 26 | } 27 | 28 | void css_mugframe_small_on_update(struct CSSMugFrameSmallProc* proc) { 29 | // nothing (yet?) 30 | } 31 | 32 | void css_mugframe_small_redraw(struct CSSMugFrameSmallProc* proc) { 33 | // void DrawMiniMug(int index, uint16_t* targetBg, int tileIndex, int bgIndex, int flipped); 34 | static const void(*DrawMiniMug)(int, uint16_t*, int, int, int) = (void (*)(int, uint16_t*, int, int, int))(0x08005989); 35 | 36 | DrawMiniMug( 37 | GetUnitMiniPortraitId(gpStatScreenUnit), // TODO: gStatScreenUnit 38 | BG_LOCATED_TILE(proc->pBgOutput, 1, 1), 39 | proc->rootTileIndex, 40 | CSS_PAL_BG_MUG, 41 | FALSE 42 | ); 43 | 44 | Text_SetFont(NULL); 45 | 46 | // TODO: draw actual information 47 | DrawTextInline(NULL, BG_LOCATED_TILE(proc->pBgOutput, 6, 1), 0, 0, 0x10, GetStringFromIndex(gpStatScreenUnit->pCharacterData->nameTextId)); 48 | DrawTextInline(NULL, BG_LOCATED_TILE(proc->pBgOutput, 6, 3), 0, 0, 0x10, GetStringFromIndex(gpStatScreenUnit->pClassData->nameTextId)); 49 | 50 | css_display_hp_exp_line(BG_LOCATED_TILE(proc->pBgOutput, 1, 5)); 51 | } 52 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSummonStaff/Src/FreeSelect.h: -------------------------------------------------------------------------------- 1 | #ifndef FREE_SELECT_H 2 | #define FREE_SELECT_H 3 | 4 | #include "gbafe.h" 5 | 6 | struct FSProc; 7 | 8 | typedef int(*FSHandlerFunc)(struct FSProc*, int, int); 9 | 10 | struct FSDefinition { 11 | FSHandlerFunc onInit; 12 | FSHandlerFunc onEnd; 13 | FSHandlerFunc onAPress; 14 | FSHandlerFunc onBPress; 15 | FSHandlerFunc onRPress; 16 | FSHandlerFunc onPosChange; 17 | }; 18 | 19 | struct FSProc { 20 | PROC_HEADER; 21 | 22 | const struct FSDefinition* pDefinition; 23 | APHandle* pCursorAp; 24 | }; 25 | 26 | enum FSResultCode { 27 | // TODO: FS_PAUSE, FS_RESUME? 28 | 29 | FS_END = 0x02, // Ends selection when set 30 | FS_SND_BEEP = 0x04, // Plays beep sound (sound Id 0x6A) when set 31 | FS_SND_BOOP = 0x08, // Plays boop sound (sound Id 0x6B) when set 32 | FS_SND_GURR = 0x10, // Plays gurr sound (sound Id 0x6C) when set 33 | FS_GFX_VALID = 0x20, // Sets cursor gfx to valid 34 | FS_GFX_INVALID = 0x40, // Sets cursor gfx to invalid 35 | }; 36 | 37 | struct FSProc* StartFreeSelection(const struct FSDefinition* pDefinition); 38 | 39 | #endif // FREE_SELECT_H -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSummonStaff/Src/SummonStaff.c: -------------------------------------------------------------------------------- 1 | #include "FreeSelect.h" 2 | 3 | static int SumOnSelect(struct FSProc* proc, int x, int y); 4 | static int SumOnCancel(struct FSProc* proc, int x, int y); 5 | 6 | static const struct FSDefinition sSummonFSD = { 7 | .onAPress = SumOnSelect, 8 | .onBPress = SumOnCancel, 9 | }; 10 | 11 | void SumStartPosSelection(void) { 12 | StartFreeSelection(&sSummonFSD); 13 | } 14 | 15 | static int SumOnSelect(struct FSProc* proc, int x, int y) { 16 | Text_ResetTileAllocation(); 17 | HideMoveRangeGraphics(); 18 | EndBottomHelpText(); 19 | 20 | gActionData.xOther = x; 21 | gActionData.yOther = y; 22 | 23 | gActionData.unitActionType = UNIT_ACTION_SUMMON; 24 | 25 | EnsureCameraOntoPosition( 26 | (Proc*)(proc), 27 | 28 | gActiveUnit->xPos, 29 | gActiveUnit->yPos 30 | ); 31 | 32 | return FS_END | FS_SND_BEEP; 33 | } 34 | 35 | static int SumOnCancel(struct FSProc* proc, int x, int y) { 36 | Text_ResetTileAllocation(); 37 | HideMoveRangeGraphics(); 38 | EndBottomHelpText(); 39 | 40 | SetCursorMapPosition( 41 | gActiveUnit->xPos, 42 | gActiveUnit->yPos 43 | ); 44 | 45 | ProcStart(gProc_GoBackToUnitMenu, ROOT_PROC_3); 46 | 47 | return FS_END | FS_SND_BOOP; 48 | } 49 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSummonStaff/Src/SummonStaffHooks.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | .global SumStaffUsability 4 | .type SumStaffUsability, %function 5 | 6 | .global SumStaffEffect 7 | .type SumStaffEffect, %function 8 | 9 | SumStaffUsability: 10 | mov r0, #1 11 | 12 | ldr r3, =(0x08028C06+1) 13 | bx r3 14 | 15 | .pool 16 | .align 17 | 18 | SumStaffEffect: 19 | bl SumStartPosSelection 20 | 21 | ldr r3, =(0x08029062+1) 22 | bx r3 23 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/CSummonStaff/SummonStaff.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_SUMMON_STAFF 2 | #define HAX_SUMMON_STAFF 3 | 4 | #ifndef _FE8_ 5 | ERROR "CSummonStaff is for FE8 only" 6 | #endif // _FE8_ 7 | 8 | #ifndef HAX_FREESELECT 9 | ERROR "please include CFreeSelect before CSummonStaff" 10 | #endif // HAX_FREESELECT 11 | 12 | #ifndef SummonStaffItemId 13 | #define SummonStaffItemId Physic 14 | #endif 15 | 16 | #include "Src/SummonStaff.lyn.event" 17 | #include "Src/SummonStaffHooks.lyn.event" 18 | 19 | // TODO: ifdef item effect rework 20 | 21 | PUSH 22 | 23 | ORG ($0288B0 + 4*((SummonStaffItemId)-0x4B)) 24 | POIN SumStaffUsability 25 | 26 | ORG ($028E8C + 4*((SummonStaffItemId)-0x4B)) 27 | POIN SumStaffEffect 28 | 29 | ORG $01DA66 30 | // Fix Graphical glitchiness 31 | BYTE 0x13 32 | 33 | POP 34 | 35 | #endif // HAX_SUMMON_STAFF 36 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/Misc/Src/ASMC_ForgetSkill.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | @ This is for circles' skill system 4 | 5 | gBWLTable = 0x0203E884 @ Where the skills are stored 6 | gEventSlot = 0x030004B8 @ Where the event slot values are stored 7 | 8 | GetUnitFromEventParam = 0x0800BC50+1 @ Given an event parameter (either a char id or -1/-2/-3 special values), gets a Unit* 9 | 10 | ASMC_ForgetSkill: 11 | push {r4-r6, lr} 12 | 13 | @ PUT SKILL ID IN SLOT 1 14 | @ PUT CHAR ID IN SLOT 2 15 | 16 | @ r0 = char id 17 | ldr r1, =gEventSlot 18 | ldr r0, [r1, #(0x02 * 4)] @ Load unit from event slot 2 19 | 20 | ldr r3, =GetUnitFromEventParam 21 | bl BXR3 22 | 23 | ldr r0, [r0] @ CharData 24 | ldrb r0, [r0, #4] @ CharId 25 | 26 | @ r1 = skill id 27 | ldr r1, =gEventSlot 28 | ldr r1, [r1, #(0x01 * 4)] @ Load skill from event slot 1 29 | 30 | @ r3 = Learned Skill List for Active Char 31 | ldr r3, =gBWLTable 32 | lsl r0, #4 @ CharId * sizeof(BWLEntry) 33 | add r3, r0 34 | add r3, #1 @ Learned Skills start at byte 1 in BWL Entry 35 | 36 | @ r2 = current slot 37 | mov r2, #0 38 | 39 | loop_find_slot: 40 | @ r0 = learned skill in slot #r2 41 | ldrb r0, [r3, r2] 42 | 43 | @ compare skill 44 | cmp r0, r1 45 | beq found_slot 46 | 47 | @ add current slot (check next slot next iteration) 48 | add r2, #1 49 | 50 | @ loop back if we haven't done all skill slots yet 51 | cmp r2, #4 52 | blt loop_find_slot 53 | 54 | @ we reached end of learned skill list 55 | @ we didn't find the skill we want to forget 56 | @ so we end, bye 57 | b end 58 | 59 | found_slot: 60 | loop_remove: 61 | add r0, r2, #1 @ r0 = next slot id 62 | 63 | ldrb r0, [r3, r0] @ load skill after current slot 64 | strb r0, [r3, r2] @ store into current slot 65 | 66 | add r2, #1 67 | 68 | cmp r2, #4 69 | blt loop_remove 70 | 71 | @ set last skill as zero 72 | @ otherwise it would have been whatever is after the skill list in memory 73 | @ aka unwanted garbage 74 | mov r0, #0 75 | strb r0, [r3, #3] 76 | 77 | end: 78 | pop {r4-r6} 79 | 80 | pop {r3} 81 | BXR3: 82 | bx r3 83 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/Misc/Src/Armsthrift.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | GetItemAfterUse = 0x08016AEC+1 4 | RollBattleRN = 0x0802A52C+1 5 | _ReturnLocation = 0x0802B828+1 6 | 7 | LUnitHasSkill = EALiterals+0x00 8 | LArmsthriftSkillID = EALiterals+0x04 9 | 10 | @ Hook from 0802B7F8 11 | ArmsthriftHook: 12 | @ r0 is Current Round Data (first word) 13 | @ r5 is Attacker 14 | @ Nothing needs to be saved (we branch back to the function epilogue) 15 | 16 | mov r1, #2 @ Miss flag 17 | 18 | tst r0, r1 @ = CurrentRound & 2 19 | beq NonMiss @ goto NonMiss if zero (Miss flag is not set) 20 | 21 | ldr r1, [r5, #0x4C] @ BattleUnit.weaponAttributes 22 | mov r2, #(0x02 | 0x80) @ IA_MAGIC | IA_UNCOUNTERABLE 23 | 24 | tst r1, r2 @ = BattleUnit.weaponAttributes & (IA_MAGIC | IA_UNCOUNTERABLE) 25 | beq End @ goto End if zero (weapon is neither magic or uncounterable) 26 | 27 | NonMiss: 28 | @ ACTUAL ARMSTHRIFT CHECK BEGIN 29 | 30 | mov r0, r5 @ arg r0 = (Battle) Unit 31 | ldr r1, LArmsthriftSkillID @ arg r1 = Skill Index 32 | 33 | ldr r3, LUnitHasSkill 34 | bl BXR3 35 | 36 | cmp r0, #0 @ compare result 37 | beq NonArmsthrift @ goto NonArmsthrift if zero (unit doesn't have armsthrift) 38 | 39 | @ Getting Armsthrift proc chance (=luck) 40 | ldrb r0, [r5, #0x19] @ BattleUnit.luck 41 | @ lsl r0, #1 @ multiply by 2 42 | 43 | @ ROLL 44 | ldr r3, =RollBattleRN 45 | bl BXR3 46 | 47 | cmp r0, #0 @ compare result 48 | bne End @ goto End if non-zero (Armsthrift proc) 49 | 50 | NonArmsthrift: 51 | @ ACTUAL ARMSTHRIFT CHECK END 52 | 53 | mov r4, #0x48 @ offsetof(BattleUnit.weaponAfter) 54 | 55 | ldrh r0, [r5, r4] @ Load weapon 56 | 57 | ldr r3, =GetItemAfterUse 58 | bl BXR3 59 | 60 | strh r0, [r5, r4] @ Store used weapon 61 | 62 | cmp r0, #0 @ Compare weapon 63 | bne End @ goto End if weapon != 0 64 | 65 | mov r1, #0x7D @ BattleUnit.weaponBroke 66 | mov r0, #1 67 | 68 | strb r0, [r5, r1] @ BattleUnit.weaponBroke = true 69 | 70 | End: 71 | ldr r3, =_ReturnLocation 72 | BXR3: 73 | bx r3 74 | 75 | .ltorg 76 | .align 77 | 78 | EALiterals: 79 | @ POIN SkillTester|1 80 | @ WORD ArmsthriftID 81 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/Misc/Src/AuraSkillChecker.c: -------------------------------------------------------------------------------- 1 | #include "gbafe.h" 2 | 3 | extern int SkillTester(Unit*, int) __attribute__((long_call)); 4 | 5 | extern int AreAllegiancesAllied(int, int) __attribute__((long_call)); 6 | extern int AreAllegiancesEqual(int, int) __attribute__((long_call)); // forgive the typo 7 | 8 | extern uint8_t gAuraUnitListOut[]; 9 | 10 | static int absolute(int value) { return value < 0 ? -value : value; } 11 | 12 | static int AuraSkillTest(Unit* unit, Unit* other, int skill, int param); 13 | 14 | long long AuraSkillCheck(Unit* unit, int skill, int param, int maxRange) { 15 | int count = 0; 16 | 17 | for (int i = 0; i < 0x100; ++i) { 18 | Unit* other = gUnitLookup[i]; 19 | 20 | if (!other) 21 | continue; 22 | 23 | if (unit->index == i) 24 | continue; 25 | 26 | if (!other->pCharacterData) 27 | continue; 28 | 29 | if (other->state & (US_RESCUED | US_NOT_DEPLOYED | US_DEAD | 0x00010000)) 30 | continue; 31 | 32 | int distance = absolute(other->xPos - unit->xPos) 33 | + absolute(other->yPos - unit->yPos); 34 | 35 | if ((distance <= maxRange) && AuraSkillTest(unit, other, skill, param)) 36 | gAuraUnitListOut[count++] = i; 37 | } 38 | 39 | gAuraUnitListOut[count] = 0; 40 | 41 | union { 42 | long long asLongLong; 43 | struct { 44 | int count; 45 | uint8_t* pList; 46 | }; 47 | } result; 48 | 49 | result.count = count; 50 | result.pList = gAuraUnitListOut; 51 | 52 | return result.asLongLong; 53 | } 54 | 55 | int AuraSkillTest(Unit* unit, Unit* other, int skill, int param) { 56 | const int(*pAllegianceChecker)(int, int) = ((param & 1) ? AreAllegiancesAllied : AreAllegiancesEqual); 57 | 58 | if (param == 4) 59 | return SkillTester(other, skill); 60 | 61 | if (param > 4) 62 | return 0; 63 | 64 | int check = pAllegianceChecker(unit->index, other->index); 65 | 66 | if (param & 2) 67 | check = !check; 68 | 69 | return check && SkillTester(other, skill); 70 | } 71 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/Misc/Src/CanLunge.c: -------------------------------------------------------------------------------- 1 | #include "gbafe.h" 2 | 3 | extern int SkillTester(Unit*, int) __attribute__((long_call)); 4 | extern const unsigned LungeID; 5 | 6 | int CanUnitLunge(Unit* a, Unit* b) { 7 | 8 | } 9 | 10 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/Misc/Src/asm_tricks.s: -------------------------------------------------------------------------------- 1 | @ logical not (0 becomes 1, anything else becomes 0) 2 | not: 3 | neg r1, r0 @ r1 = -r0; C = 1 if r0 is zero 4 | adc r0, r1 5 | 6 | @ return 7 | bx lr 8 | 9 | @ signed divition by 2 that rounds towards zero (rather than down) 10 | signed_div_by_2: 11 | @ add 1 to r0 if r0 is negative 12 | lsr r1, r0, #31 13 | add r0, r1 14 | 15 | @ divide by 2 16 | asr r0, #1 17 | 18 | @ return 19 | bx lr 20 | 21 | @ r0 becomes its absolute value 22 | abs: 23 | asr r1, r0, #31 24 | add r0, r1 25 | eor r0, r1 26 | 27 | @ return 28 | bx lr 29 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/MovingTrap/ThingSmall.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_TRAP_SMALL_THING_THING 2 | #define HAX_TRAP_SMALL_THING_THING 3 | 4 | #include "Extensions/Hack Installation.txt" 5 | #include "Extensions/6CDefinitions.txt" 6 | 7 | #include "EAstdlib.event" 8 | 9 | #define THINGTRAP(aX, aY, aDir) "BYTE 0x2 aX aY aDir 0 0" 10 | 11 | { 12 | 13 | PUSH 14 | ORG 0x037868 // second entry in trap initialization pointer array 15 | POIN (prThingTrapInitialization) 16 | 17 | ORG 0x01A1B6 // making so that when stepping on one, you stop (unless you're a thief, which is neat) 18 | #include "src/hidden.lyn.event" 19 | 20 | ORG 0x037660 // this check is for when things actually happen 21 | jumpToHack(prThingEffectCheck) 22 | POP 23 | 24 | ALIGN 4 25 | prThingTrapInitialization: 26 | #include "src/init.lyn.event" 27 | WORD 0x20 // trap id 28 | 29 | ALIGN 4 30 | prThingEffectCheck: 31 | #include "src/effect.lyn.event" 32 | WORD 0x20 // trap id 33 | 34 | // p6C_TrapHandler: 35 | // _6C_YIELD 36 | 37 | // _6C_LABEL(0) 38 | // _6C_CALL_ROUTINE(TrapHandlerCheck) 39 | // _6C_WHILE_ROUTINE(0x078720+1) // Blocking MoveUnit 6C Exists 40 | // _6C_GOTO(0) 41 | 42 | // _6C_LABEL(1) 43 | // _6C_END 44 | 45 | // ALIGN 4 46 | // pFacingRotTable: 47 | // right, down, left, up 48 | // BYTE 1 2 0 3 49 | 50 | // ALIGN 4 51 | // pDirectionStepTable: 52 | // Daily reminder to put parenthesis around this kind of stuff 53 | // SHORT (-1) (0) // left 54 | // SHORT (+1) (0) // right 55 | // SHORT (0) (+1) // down 56 | // SHORT (0) (-1) // up 57 | 58 | // ALIGN 4 59 | // pOppositeDirectionTable: 60 | // BYTE 1 // left -> right 61 | // BYTE 0 // right -> left 62 | // BYTE 3 // down -> up 63 | // BYTE 2 // up -> down 64 | 65 | ALIGN 4 66 | #include "src/utility.lyn.event" 67 | #include "src/unit_mover.lyn.event" 68 | #include "src/handle_trap.lyn.event" 69 | 70 | } 71 | 72 | #endif // HAX_TRAP_SMALL_THING_THING 73 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/MovingTrap/src/effect.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | .set Return, (0x08037668+1) 4 | 5 | .set GetTriggeredTrapType, (0x080375E8+1) 6 | 7 | Start: 8 | @ REPLACED (08037660) 9 | push {r4-r6, lr} 10 | mov r6, r0 11 | mov r5, r1 12 | mov r4, r2 13 | 14 | @ CONTINUED 15 | mov r0, r5 16 | ldr r3, =#GetTriggeredTrapType 17 | bl BXR3 18 | 19 | ldr r3, EAL_TRAPINDEX 20 | cmp r0, r3 21 | beq HandleMySuperTrap 22 | 23 | @ Dirty but idc 24 | ldr r3, =#Return 25 | BXR3: 26 | bx r3 27 | 28 | HandleMySuperTrap: 29 | mov r0, r6 30 | mov r1, r5 31 | mov r2, r4 32 | 33 | bl HandleTrap 34 | 35 | End: 36 | mov r0, #0 37 | pop {r4-r6} 38 | pop {r1} 39 | bx r1 40 | 41 | .ltorg 42 | .align 43 | 44 | EAL_TRAPINDEX: 45 | @ WORD trap id 46 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/MovingTrap/src/hidden.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | .set Continue, (. + 0x0801A1DE - 0x0801A1B6) 4 | 5 | cmp r0, #0x0B 6 | beq Yes 7 | 8 | cmp r0, #0x20 9 | bne Continue 10 | 11 | Yes: 12 | 13 | ldr r0, [r6] @ r0 = Unit Raws 14 | ldrb r1, [r3, #1] @ r1 = trap y 15 | lsl r1, #2 @ r1 = trap y * sizeof(void*) 16 | ldrb r4, [r3, #0] @ r4 = trap x 17 | ldr r0, [r0, r1] @ r0 = Row 18 | ldrb r0, [r0, r4] @ r0 = Tile 19 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/MovingTrap/src/init.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | .set AddTrap, (0x0802E2B8+1) 4 | .set Return, (0x08037900+1) 5 | 6 | hi: 7 | @ r5 is pointer to trap data 8 | 9 | ldrb r0, [r5, #1] 10 | ldrb r1, [r5, #2] 11 | ldrb r3, [r5, #3] 12 | 13 | ldr r2, EAL_TRAPINDEX 14 | 15 | push {r4} 16 | 17 | ldr r4, =#AddTrap 18 | bl BXR4 19 | 20 | pop {r4} 21 | 22 | ldr r0, =#Return 23 | bx r0 24 | 25 | BXR4: 26 | bx r4 27 | 28 | .ltorg 29 | .align 30 | 31 | EAL_TRAPINDEX: 32 | @ WORD trap id 33 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/MovingTrap/src/unit_mover.c: -------------------------------------------------------------------------------- 1 | #include "unit_mover.h" 2 | 3 | extern const uint8_t pFacingTable[]; 4 | 5 | const ProcInstruction ProcCode_UnitMoveAnim[] = { 6 | PROC_SET_DESTRUCTOR(UnitMoveAnim_OnDestruct), // Delet 7 | PROC_YIELD, // Yielding to ensure everything is set up properly 8 | PROC_LOOP_ROUTINE(UnitMoveAnim_OnLoop), // Move that sprite 9 | PROC_END // End 10 | }; 11 | 12 | UnitMoveAnimProc* NewUnitMoveAnim(MoveUnitState* moveunit, struct Vec2 from, struct Vec2 to, Proc* parent) { 13 | UnitMoveAnimProc* moveAnimProc = 0; 14 | 15 | // making 6C 16 | if (parent) { 17 | moveAnimProc = (UnitMoveAnimProc*) ProcStartBlocking(ProcCode_UnitMoveAnim, parent); 18 | moveAnimProc->locks = 0; 19 | } else { 20 | moveAnimProc = (UnitMoveAnimProc*) ProcStart(ProcCode_UnitMoveAnim, ROOT_PROC_3); 21 | 22 | moveAnimProc->locks = 1; 23 | LockGameLogic(); 24 | } 25 | 26 | // making linked MOVEUNIT 27 | // MoveUnitProc* moveunit = NewMoveUnitForMapUnit(unit); 28 | // MU_SetFacing(moveunit, facing); 29 | 30 | MU_SetDisplayPosition(moveunit, from.x, from.y); 31 | 32 | // writing fields to the proc struct 33 | moveAnimProc->pMoveUnit = moveunit; 34 | moveAnimProc->from = from; 35 | moveAnimProc->to = to; 36 | moveAnimProc->clock = 0; 37 | 38 | // Returning 39 | return moveAnimProc; 40 | } 41 | 42 | void UnitMoveAnim_OnDestruct(UnitMoveAnimProc* proc) { 43 | if (proc->locks) 44 | UnlockGameLogic(); 45 | } 46 | 47 | void UnitMoveAnim_OnLoop(UnitMoveAnimProc* proc) { 48 | // TODO: check for fast/slow speed option 49 | if (!MoveMoveUnitTowards(proc->pMoveUnit, proc->to.x, proc->to.y, 5)) 50 | BreakProcLoop((Proc*) proc); 51 | // else { 52 | // int localTime = (proc->timer++) % 4; 53 | 54 | // if (!localTime) { // localTime == 0 55 | // int facing = pFacingTable[((proc->timer++) / 4) % 4]; 56 | // MU_SetFacing(proc->pMoveUnit, facing); 57 | // } 58 | // } 59 | } 60 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/MovingTrap/src/unit_mover.h: -------------------------------------------------------------------------------- 1 | #ifndef UNIT_MOVER_H 2 | #define UNIT_MOVER_H 3 | 4 | #include "gbafe.h" 5 | #include "utility.h" 6 | 7 | typedef struct _UnitMoveAnimProc UnitMoveAnimProc; 8 | struct _UnitMoveAnimProc { 9 | PROC_FIELDS 10 | 11 | MoveUnitState* pMoveUnit; 12 | 13 | struct Vec2 from; 14 | struct Vec2 to; 15 | 16 | int clock; 17 | 18 | uint8_t locks; 19 | }; 20 | 21 | UnitMoveAnimProc* NewUnitMoveAnim(MoveUnitState* moveunit, struct Vec2 from, struct Vec2 to, Proc* parent); 22 | 23 | void UnitMoveAnim_OnDestruct(UnitMoveAnimProc* proc); 24 | void UnitMoveAnim_OnLoop(UnitMoveAnimProc* proc); 25 | 26 | #endif // UNIT_MOVER_H 27 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/MovingTrap/src/utility.c: -------------------------------------------------------------------------------- 1 | #include "utility.h" 2 | 3 | static int sign(int value) { return (value>>31) - (-value>>31); } 4 | static int abs(int value) { return value < 0 ? -value : value; } 5 | static int sqr(int value) { return value * value; } 6 | 7 | int MoveMoveUnitTowards(MoveUnitState* moveunit, int x, int y, int speed) { 8 | x = x << 8; 9 | y = y << 8; 10 | 11 | int xSign = sign(x - moveunit->xPosition); 12 | int ySign = sign(y - moveunit->yPosition); 13 | 14 | moveunit->xPosition += xSign << speed; 15 | moveunit->yPosition += ySign << speed; 16 | 17 | return xSign | ySign; 18 | } 19 | 20 | // needs testing 21 | int MoveUnitUnitTowards2(MoveUnitProc* moveunit, int x, int y, int speed) { 22 | int xDistance = (0x100 * x) - moveunit->xPosition; 23 | int yDistance = (0x100 * y) - moveunit->yPosition; 24 | 25 | int distance = Sqrt(sqr(abs(xDistance)) + sqr(abs(yDistance))); 26 | 27 | int factor = Div(speed, distance); 28 | 29 | int xStep = (xDistance * factor) / 0x10; 30 | int yStep = (yDistance * factor) / 0x10; 31 | 32 | if (abs(xDistance) < abs(xStep) || abs(yDistance) < abs(yStep)) { 33 | moveunit->xPosition = x * 0x100; 34 | moveunit->yPosition = y * 0x100; 35 | 36 | return FALSE; // movement ended (destination reached) 37 | } else { 38 | moveunit->xPosition += xStep; 39 | moveunit->yPosition += yStep; 40 | 41 | return TRUE; // the adventure continues... 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/MovingTrap/src/utility.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILITY_H 2 | #define UTILITY_H 3 | 4 | #include "gbafe.h" 5 | 6 | int MoveMoveUnitTowards(MoveUnitState* moveunit, int x, int y, int speed); 7 | 8 | #endif // UTILITY_H 9 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/Nm/Nm.event: -------------------------------------------------------------------------------- 1 | #ifndef NM_INCLUDED 2 | #define NM_INCLUDED 3 | 4 | #include "Src/NmMain.lyn.event" 5 | 6 | #endif // NM_INCLUDED 7 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/Nm/Src/Nm.h: -------------------------------------------------------------------------------- 1 | #ifndef NM_INCLUDED 2 | #define NM_INCLUDED 3 | 4 | #include "gbafe.h" 5 | #include "../../../M7/Src/M7.h" // FIXME 6 | 7 | #endif // NM_INCLUDED 8 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/README.md: -------------------------------------------------------------------------------- 1 | # CHAX Limbo 2 | 3 | This is where most of my unfinished and/or broken stuff resides. This is public as there may be interesting stuff lying in here but be warned. 4 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/UnlockHack/UnlockHack.event: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "src/UnlockHack.lyn.event" 4 | 5 | PUSH 6 | 7 | ORG $0262F8 8 | // This is to add chests to the target list along with doors 9 | POIN TryAddPosToUnlockList 10 | 11 | ORG $9A3EA4 12 | // This extends the proc to also wait for the event engine to stop existing 13 | PROC_JUMP(UnlockEffectProcExtension) 14 | 15 | ORG $9A4C84 16 | // Replace 140 tick sleep by a wait for the effect proc to die 17 | PROC_WHILE_EXISTS($9A3E6C) 18 | 19 | POP 20 | 21 | #include "Extensions/ProcDefinitions.txt" 22 | 23 | ALIGN 4 24 | UnlockEffectProcExtension: 25 | PROC_CALL_ROUTINE(UnlockSaveBattleUnitInTarget) 26 | PROC_CALL_ROUTINE(UnlockTrueEffect) // This opens both doors and chests! 27 | PROC_WHILE_ROUTINE($00D198+1) // MapEventEngineExists 28 | PROC_CALL_ROUTINE(UnlockRestoreBattleUnit) 29 | PROC_JUMP($9A3EAC) // go back! 30 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/UnlockHack/src/UnlockHack.c: -------------------------------------------------------------------------------- 1 | #include "gbafe.h" 2 | 3 | int IsThereClosedDoorAt(u8 x, u8 y) __attribute__((long_call)); 4 | int IsThereClosedChestAt(u8 x, u8 y) __attribute__((long_call)); 5 | 6 | static const void(*a)(u8 x, u8 y) = (void(*)(u8, u8))(0x808320C+1); 7 | static const void(*b)(u8 x, u8 y) = (void(*)(u8, u8))(0x80831C8+1); 8 | 9 | extern struct BattleUnit gBattleActor; 10 | extern struct BattleUnit gBattleTarget; 11 | 12 | void TryAddPosToUnlockList(u8 x, u8 y) { 13 | if (IsThereClosedChestAt(x, y)) 14 | AddTarget(x, y, 0, 0); 15 | 16 | else if (IsThereClosedDoorAt(x, y)) 17 | AddTarget(x, y, 0, 0); 18 | } 19 | 20 | void UnlockSaveBattleUnitInTarget(struct Proc* proc) { 21 | // Copy subject battle unit in target battle unit 22 | // That way, we will be able to restore it later 23 | // since the item box in the send to convoy menu re-initializes the subject 24 | 25 | memcpy(&gBattleActor, &gBattleTarget, sizeof(struct BattleUnit)); 26 | } 27 | 28 | void UnlockTrueEffect(struct Proc* proc) { 29 | GetUnit(gActionData.subjectIndex)->state |= US_HIDDEN; 30 | 31 | a(gActionData.xOther, gActionData.yOther); 32 | b(gActionData.xOther, gActionData.yOther); 33 | } 34 | 35 | void UnlockRestoreBattleUnit(struct Proc* proc) { 36 | // Restore subject from target 37 | 38 | memcpy(&gBattleTarget, &gBattleActor, sizeof(struct BattleUnit)); 39 | 40 | // Update items in subject battle unit from the "real" unit 41 | // the "real" unit is where the event wrote items to 42 | 43 | struct Unit* realUnit = GetUnit(gBattleActor.unit.index); 44 | 45 | for (unsigned i = 0; i < 5; ++i) 46 | gBattleActor.unit.items[i] = realUnit->items[i]; 47 | } 48 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/ValentianExpShare/Src/VES.h: -------------------------------------------------------------------------------- 1 | #ifndef VES_H 2 | #define VES_H 3 | 4 | #include "gbafe.h" 5 | 6 | #pragma long_calls 7 | 8 | void MakeUIWindowTileMap_BG0BG1(int x, int y, int width, int height, int style); 9 | char* GetStringFromIndex(short index); 10 | 11 | #pragma long_calls_off 12 | 13 | #define VES_PREFIX "Stan:ValentianExpShare" 14 | 15 | struct VESProc { 16 | PROC_HEADER; 17 | }; 18 | 19 | struct VESUnitDisplayProc { 20 | PROC_HEADER; 21 | 22 | unsigned char lineId; 23 | 24 | const Unit* pUnit; 25 | struct VESProc* pVESMain; 26 | 27 | TextHandle text; 28 | }; 29 | 30 | struct VESUnitDisplayProc* VESStartUnitDisplay(struct VESProc* proc, unsigned lineId, const Unit* unit); 31 | 32 | #endif // VES_H 33 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/ValentianExpShare/Src/VESUnitDisplay.c: -------------------------------------------------------------------------------- 1 | #include "VES.h" 2 | 3 | static void VESUnitDisplayDrawBase(struct VESUnitDisplayProc* proc); 4 | static void VESUnitDisplayLoop(struct VESUnitDisplayProc* proc); 5 | 6 | static const void(*SMS_DisplayOne2)(int, int, int, int, const Unit*) = (void(*)(int, int, int, int, const Unit*))(0x8027E4D); 7 | 8 | static const ProcCode sVESUnitDisplayProcScr[] = { 9 | PROC_SET_NAME(VES_PREFIX":UnitDisplay"), 10 | PROC_YIELD, 11 | 12 | PROC_LABEL(0), // Disabled State 13 | // PROC_BLOCK, 14 | 15 | PROC_LABEL(1), // Enabled State 16 | PROC_CALL_ROUTINE(VESUnitDisplayDrawBase), 17 | PROC_LOOP_ROUTINE(VESUnitDisplayLoop), 18 | 19 | PROC_LABEL(2), // End 20 | PROC_END 21 | }; 22 | 23 | void VESUnitDisplayDrawBase(struct VESUnitDisplayProc* proc) { 24 | uint16_t* baseTile = gBg1MapBuffer + 4 + 0x20 * (4 + proc->lineId); 25 | 26 | Text_DrawString(&proc->text, GetStringFromIndex(proc->pUnit->pCharacterData->nameTextId)); 27 | Text_Display(&proc->text, baseTile + 3); 28 | } 29 | 30 | void VESUnitDisplayLoop(struct VESUnitDisplayProc* proc) { 31 | unsigned yBase = 32 + 16 * proc->lineId; 32 | 33 | SMS_DisplayOne2(0, 32, yBase, 0, GetUnit(0x01)); 34 | } 35 | 36 | struct VESUnitDisplayProc* VESStartUnitDisplay(struct VESProc* proc, unsigned lineId, const Unit* unit) { 37 | struct VESUnitDisplayProc* newProc = (struct VESUnitDisplayProc*)(ProcStart(sVESUnitDisplayProcScr, (Proc*)(proc))); 38 | 39 | newProc->lineId = lineId; 40 | 41 | newProc->pVESMain = proc; 42 | newProc->pUnit = unit; 43 | 44 | Text_InitClear(&newProc->text, 7); 45 | 46 | return newProc; 47 | } 48 | -------------------------------------------------------------------------------- /Wizardry/.Limbo/ValentianExpShare/ValentianExpShare.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_STAN_GROUP_EXP 2 | #define HAX_STAN_GROUP_EXP 3 | 4 | #include "Src/VESMain.lyn.event" 5 | #include "Src/VESUnitDisplay.lyn.event" 6 | 7 | #endif // HAX_STAN_GROUP_EXP 8 | -------------------------------------------------------------------------------- /Wizardry/.Research/TmApplyTsa.s: -------------------------------------------------------------------------------- 1 | 2 | .arm 3 | 4 | .global TmApplyTsa 5 | .type TmApplyTsa, function 6 | 7 | TmApplyTsa: 8 | @ arg r0 = target tilemap 9 | @ arg r1 = source "TSA", see below 10 | @ arg r2 = tile base (added to each tile entry) 11 | 12 | push {r4-r7} 13 | 14 | ldrb r3, [r1, #0] @ var r3 = WIDTH-1 15 | ldrb r4, [r1, #1] @ var r4 = HEIGHT-1 16 | 17 | add r1, #2 @ increment source ptr by 2 (past header) 18 | 19 | lsl r7, r4, #6 @ get (HEIGHT-1)*0x20, the tilemap offset of the last row 20 | add r0, r7 @ move the target ptr to the last row 21 | 22 | mov r6, r4 @ var r6 = HEIGHT-1 (r6 will count down to 0) 23 | 24 | lop_y: 25 | mov r5, r3 @ var r5 = WIDTH-1 (r5 will count down to 0) 26 | 27 | lop_x: 28 | ldrh r7, [r1] @ load tile entry from source 29 | add r7, r2 @ add tile base 30 | strh r7, [r0] @ store final tile entry to tilemap 31 | 32 | add r0, #2 @ increment target ptr 33 | add r1, #2 @ increment source ptr 34 | 35 | subs r5, #1 @ decrement x counter 36 | bpl lop_x @ if x counter >= 0, continue 37 | 38 | sub r0, r3, lsl #1 @ move target ptr back to one tile past start of row 39 | sub r0, #0x42 @ move target ptr back one row and one tile 40 | 41 | subs r6, #1 @ decrement y counter 42 | bpl lop_y @ if y counter >= 0, continue 43 | 44 | pop {r4-r7} 45 | bx lr 46 | 47 | @ """TSA""" format: 48 | @ first, 2 byte header, then array of rows 49 | 50 | @ header: 51 | @ +00 | byte | WIDTH-1 52 | @ +01 | byte | HEIGHT-1 53 | 54 | @ rows: 55 | @ each row is an array of WIDTH 2-byte tile entries. 56 | @ tile entries within rows are arranged left-to-right 57 | @ rows are in reverse order (bottom-to-top) 58 | @ there's no padding between rows 59 | -------------------------------------------------------------------------------- /Wizardry/3rdParty/CSAEngine/CSAEngine.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_CSA_ENGINE 2 | #define HAX_CSA_ENGINE 3 | 4 | // Original CSA engine hack by Hextator 5 | // Enhanced and fixed by circleseverywhere 6 | // Ported to CHAX by me 7 | 8 | #define SetCSATable(index, framedata, RTLFG, LTRFG, RTLBG, LTRBG) "PUSH; ORG CSATable+(index*20); POIN framedata RTLFG LTRFG RTLBG LTRBG; POP" 9 | #define SetCustomSpellDim(index) "PUSH; ORG SpellTable+(index*4); POIN CSAStartDim; POP" 10 | #define SetCustomSpellNoDim(index) "PUSH; ORG SpellTable+(index*4); POIN CSAStartNoDim; POP" 11 | 12 | // uglier aliases for compat 13 | #define setCSATable(index, framedata, RTLFG, LTRFG, RTLBG, LTRBG) "PUSH; ORG CSATable+(index*20); POIN framedata RTLFG LTRFG RTLBG LTRBG; POP" 14 | #define setCustomSpell_dim(index) "PUSH; ORG SpellTable+(index*4); POIN CSAStartDim; POP" 15 | #define setCustomSpell_nodim(index) "PUSH; ORG SpellTable+(index*4); POIN CSAStartNoDim; POP" 16 | 17 | SpellTable = $5D4E60 18 | 19 | ALIGN 4 20 | CSATable: 21 | // #incbin BlankCSATable.dmp 22 | ORG (CSATable + 0xFF * 20) 23 | 24 | #include "src/CSALyn.lyn.event" 25 | 26 | // Backwards Compatibility 27 | CSAEngine_Dim = CSAStartDim - 1 28 | CSAEngine_NoDim = CSAStartNoDim - 1 29 | 30 | #endif // HAX_CSA_ENGINE 31 | -------------------------------------------------------------------------------- /Wizardry/3rdParty/CSAEngine/CSANotes.txt: -------------------------------------------------------------------------------- 1 | 0203FF34 is multiple things: 2 | + 00 is some "dummy" frame data 3 | + 10 is also some "dummy" frame data 4 | + 20 is some "dummy" oam data 5 | + 2C is an AIS 6 | + 74 is also an AIS 7 | 0203FFFC is "FRAME_DATA_STREAM_PTR" 8 | 9 | If those AIS are getting linked into the array no wonder CSAs breaks with things that re-sort it 10 | (like, say, for example: front dodges) 11 | 12 | CSA table entry: 13 | + 00 is frame data 14 | + 04 is right-to-left foreground 15 | + 08 is left-to-right foreground 16 | + 0C is right-to-left background 17 | + 10 is left-to-right background 18 | -------------------------------------------------------------------------------- /Wizardry/3rdParty/HpBars/HpBars.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_HPBARS 2 | #define HAX_HPBARS 3 | 4 | // Original HpBars hack by circleseverywhere 5 | // Ported to CHAX by me 6 | 7 | #ifndef _FE8_ 8 | ERROR _file_ is for FE8 9 | #endif 10 | 11 | #include "Extensions/Hack Installation.txt" 12 | 13 | { 14 | 15 | PUSH 16 | ORG $0276B4 17 | jumpToHack(HPBars) 18 | 19 | ORG $015690 // Change width of loaded image 20 | BYTE $18 21 | 22 | ORG $0156AC // Repoint loaded image 23 | POIN HPBarGraphic 24 | 25 | ORG $035718 // Force Subtitle Help (option replaced by hp bars toggle) 26 | SHORT $46C0 27 | 28 | POP 29 | 30 | ALIGN 4 31 | HPFrames: 32 | SHORT 1 $400F $01FF $0812 33 | SHORT 1 $400F $01FF $0814 34 | SHORT 1 $400F $01FF $0816 35 | 36 | SHORT 1 $400F $01FF $0832 37 | SHORT 1 $400F $01FF $0834 38 | SHORT 1 $400F $01FF $0836 39 | 40 | SHORT 1 $400F $01FF $0852 41 | SHORT 1 $400F $01FF $0854 42 | SHORT 1 $400F $01FF $0856 43 | 44 | SHORT 1 $400F $01FF $0872 45 | SHORT 1 $400F $01FF $0874 46 | SHORT 1 $400F $01FF $0876 47 | 48 | ALIGN 4 49 | HPFramePointers: 50 | // Unnecessary??? 51 | POIN HPFrames 52 | POIN HPFrames + 8 53 | POIN HPFrames + 16 54 | POIN HPFrames + 24 55 | POIN HPFrames + 32 56 | POIN HPFrames + 40 57 | POIN HPFrames + 48 58 | POIN HPFrames + 56 59 | POIN HPFrames + 64 60 | POIN HPFrames + 72 61 | POIN HPFrames + 80 62 | POIN HPFrames + 88 63 | 64 | ALIGN 4 65 | HPBars: 66 | #incbin "src/_warning_and_hpbars.dmp" 67 | POIN HPFramePointers 68 | 69 | ALIGN 4 70 | HPBarGraphic: 71 | #incbin "res/BattleMapObjGfx.4bpp.lz" 72 | 73 | } 74 | 75 | #endif // HAX_HPBARS 76 | -------------------------------------------------------------------------------- /Wizardry/3rdParty/HpBars/res/BattleMapObjGfx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/3rdParty/HpBars/res/BattleMapObjGfx.png -------------------------------------------------------------------------------- /Wizardry/3rdParty/KirbDebug/KirbDebug.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_KIRB_DEBUG 2 | #define HAX_KIRB_DEBUG 3 | 4 | // Original 'Kirb-o-matic' at-runtime-unit-stat-editor-debug-tool hack by Kirb 5 | // Ported to CHAX and improved a bit by me 6 | 7 | #include "src/KirbDebug.lyn.event" 8 | 9 | #include "src/KDStatPage.lyn.event" 10 | 11 | // Replace Guide 12 | PUSH; ORG $59CEC0 13 | POIN GetOne+1 0 KribDebugMenuEffect 14 | POP 15 | 16 | GetOne: 17 | SHORT $2001 $4770 18 | 19 | #endif // HAX_KIRB_DEBUG 20 | -------------------------------------------------------------------------------- /Wizardry/3rdParty/KirbDebug/src/KirbDebug.h: -------------------------------------------------------------------------------- 1 | #ifndef KIRB_DEBUG_H 2 | #define KIRB_DEBUG_H 3 | 4 | #include "gbafe.h" 5 | 6 | enum { UnitEditor_PAGE1ENTRIES = 12 }; 7 | enum { UnitEditor_PAGE2ENTRIES = 5 }; 8 | 9 | enum { // General Config 10 | // (inner) frame size (aka the area where pages should draw in) 11 | KD_PAGE_FRAME_X = 1, 12 | KD_PAGE_FRAME_Y = 3, 13 | KD_PAGE_FRAME_WIDTH = 28, 14 | KD_PAGE_FRAME_HEIGHT = 16, 15 | 16 | // frame "style" (0-3) 17 | KD_PAGE_FRAME_STYLE = 0, 18 | }; 19 | 20 | typedef struct { 21 | PROC_HEADER; 22 | 23 | u8 CursorIndex; 24 | u8 StatsPage1[UnitEditor_PAGE1ENTRIES]; 25 | u8 StatsPage2[UnitEditor_PAGE2ENTRIES]; 26 | u8 KonamiCodeCounter; 27 | u8 PageIndex; 28 | 29 | struct Unit* pUnit; 30 | struct Proc* pPageProc; 31 | } UnitEditorProc; 32 | 33 | typedef struct { 34 | u32 x; 35 | u32 y; 36 | } LocationTable; 37 | 38 | struct KDPageDefinition { 39 | struct Proc* (*start) (UnitEditorProc*); // starts the page proc 40 | 41 | void (*onLoadUnit) (struct Proc*, UnitEditorProc*, struct Unit*); // notifies page proc of unit switch in 42 | void (*onSaveUnit) (struct Proc*, UnitEditorProc*, struct Unit*); // notifies page proc of unit switch out 43 | }; 44 | 45 | extern const struct KDPageDefinition gKDStatPageDefinition; 46 | 47 | extern const struct ProcInstruction Debug6C[]; 48 | extern const LocationTable CursorLocationTable[]; 49 | extern const u16 ButtonCombo[]; 50 | 51 | u8 KribDebugMenuEffect(void); 52 | 53 | void KDSwitchPage(UnitEditorProc*, unsigned id); 54 | void KDSwitchUnit(UnitEditorProc*, struct Unit* unit); 55 | void KDClearPage(UnitEditorProc*); 56 | void KDClearHeader(UnitEditorProc*); 57 | 58 | void DebugScreenSetup(UnitEditorProc* CurrentProc); 59 | void DebugScreenLoop(UnitEditorProc* CurrentProc); 60 | void GenerateBGTsa(u16* MapOffset, u32 NumberOfTiles, u8 PaletteId); 61 | void SetupDebugUnitEditorPage1(UnitEditorProc* CurrentProc); 62 | void UpdateDebugUnitEditorPage1(UnitEditorProc* CurrentProc); 63 | void CheckKonamiCode(UnitEditorProc* CurrentProc); 64 | void PrintConstantsPage1(); 65 | void PrintConstantsPage2(); 66 | void SetupDebugUnitEditorPage2(UnitEditorProc* CurrentProc); 67 | void UpdateDebugUnitEditorPage2(UnitEditorProc* CurrentProc); 68 | 69 | #endif // KIRB_DEBUG_H 70 | -------------------------------------------------------------------------------- /Wizardry/AiPerformExtension/AiPerformExt.event: -------------------------------------------------------------------------------- 1 | #ifndef AIPERFORMEXT_INCLUDED 2 | #define AIPERFORMEXT_INCLUDED 3 | 4 | // Extends the number of AI actions ("performs") the game can handle, and provide convenient ways of injecting new handlers 5 | // hack by Stan 6 | 7 | #ifndef PERFORM_EXTENSION_COUNT 8 | #define PERFORM_EXTENSION_COUNT 10 9 | #endif // PERFORM_EXTENSION_COUNT 10 | 11 | #define InjectAiPerformer(aId, apFunc) "PUSH; ORG AiPerfomExtensionTable+4*((aId)-14); POIN (apFunc); POP" 12 | 13 | ALIGN 4 14 | AiPerfomExtensionTable: 15 | ORG AiPerfomExtensionTable + 4*(PERFORM_EXTENSION_COUNT) 16 | 17 | #include "Src/PerformHook.lyn.event" 18 | 19 | PUSH 20 | 21 | ORG $03A504 // Allow for extended performs 22 | WORD $47184B00; POIN PerformHook 23 | 24 | ORG $03A3E6 // Don't have the target cursor explode for this kind of stuff 25 | BYTE $77 26 | 27 | POP 28 | 29 | #endif // AIPERFORMEXT_INCLUDED 30 | -------------------------------------------------------------------------------- /Wizardry/AiPerformExtension/Src/PerformHook.s: -------------------------------------------------------------------------------- 1 | 2 | .thumb 3 | 4 | .global PerformHook 5 | .type PerformHook, function 6 | 7 | PerformHook: 8 | ldr r0, =gAiData+0x90 @ gAiData.decision 9 | ldrb r0, [r0] 10 | 11 | cmp r0, #13 12 | bls return_vanilla 13 | 14 | sub r0, #14 15 | lsl r0, #2 16 | 17 | ldr r1, =AiPerfomExtensionTable 18 | ldr r3, [r0, r1] 19 | 20 | mov r0, r4 21 | 22 | bl BXR3 23 | 24 | cmp r0, #0 25 | beq set_dummy 26 | 27 | set: 28 | str r0, [r4, #0x2C] 29 | 30 | pop {r4} 31 | pop {r0} 32 | bx r0 33 | 34 | set_dummy: 35 | adr r0, dummy 36 | add r0, #1 37 | b set 38 | 39 | return_vanilla: 40 | ldr r3, =0x0803A50E+1 41 | BXR3: bx r3 42 | 43 | .align 44 | 45 | dummy: 46 | mov r0, #1 47 | bx lr 48 | -------------------------------------------------------------------------------- /Wizardry/Autolevels/FixedAutolevels.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_FIXEDAUTOLEVELS 2 | #define HAX_FIXEDAUTOLEVELS 3 | 4 | // Make autoleveled stats fixed, following the formula ((growth * level_count) + 50) / 100 5 | // hack by Stan 6 | 7 | PUSH 8 | 9 | // replace GetAutoleveledStatIncrease with asm below 10 | ORG $02B9C4 11 | WORD $30324348 $4B012164 $46C04718 $80D167D 12 | 13 | POP 14 | 15 | /* 16 | 17 | Source: 18 | 19 | .thumb 20 | 21 | mul r0, r1 22 | add r0, #50 23 | mov r1, #100 24 | ldr r3, =Div 25 | bx r3 26 | 27 | .align 28 | .pool 29 | 30 | */ 31 | 32 | #endif // HAX_FIXEDAUTOLEVELS 33 | -------------------------------------------------------------------------------- /Wizardry/Autolevels/NoBonusLevels.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_NOBONUSLEVELS 2 | #define HAX_NOBONUSLEVELS 3 | 4 | // Removes difficulty-dependant bonus level logic 5 | // hack by Stan 6 | 7 | // This makes it so that all loaded units follow the same autolevel logic: 8 | // no difficulty-dependant bonuses. Promoted units all have +19 levels. 9 | 10 | PUSH 11 | 12 | // replace UnitApplyBonusLevels with nothing 13 | ORG $0180CC 14 | SHORT $4770 // bx lr 15 | 16 | // always 19 extra levels for promoted units 17 | ORG $037B44 18 | SHORT $2013 $4770 // mov r0, #19; bx lr 19 | 20 | POP 21 | 22 | #endif // HAX_NOBONUSLEVELS 23 | -------------------------------------------------------------------------------- /Wizardry/AverageLevelEnemies/Ale.event: -------------------------------------------------------------------------------- 1 | // Makes units with level set to 31 instead load with the average level of the player party 2 | // hack by stan 3 | 4 | #include "Src/Ale.lyn.event" 5 | #include "Src/AleHooks.lyn.event" 6 | 7 | PUSH 8 | 9 | ORG $017D7C 10 | // ldr r3, target ; bx r3 ; target: .word target 11 | WORD $47184B00; POIN AleHook 12 | 13 | POP 14 | -------------------------------------------------------------------------------- /Wizardry/AverageLevelEnemies/Src/Ale.c: -------------------------------------------------------------------------------- 1 | 2 | #include "gbafe.h" 3 | 4 | int AleGetBlueAverageLevel(void) 5 | { 6 | int sum = 0; 7 | int amt = 0; 8 | 9 | for (int i = 1; i < 0x40; ++i) 10 | { 11 | struct Unit* const unit = GetUnit(i); 12 | 13 | if (unit == NULL) 14 | continue; 15 | 16 | if (unit->pCharacterData == NULL) 17 | continue; 18 | 19 | if (unit->state & (US_DEAD | US_BIT16)) 20 | continue; 21 | 22 | if (unit->level == 0) 23 | continue; 24 | 25 | sum += unit->level; 26 | 27 | if (UNIT_ATTRIBUTES(unit) & CA_PROMOTED) 28 | sum += 20; 29 | 30 | amt += 1; 31 | } 32 | 33 | return Div(sum, amt); 34 | } 35 | 36 | void AleApplyLoadUnitLevel(struct Unit* unit, struct UnitDefinition* def) 37 | { 38 | int level = AleGetBlueAverageLevel(); 39 | 40 | if (UNIT_ATTRIBUTES(unit) & CA_PROMOTED) 41 | level = level - 20; 42 | 43 | if (level < 0) 44 | level = 0; 45 | 46 | if (level > 20) 47 | level = 20; 48 | 49 | unit->level = level; 50 | } 51 | -------------------------------------------------------------------------------- /Wizardry/AverageLevelEnemies/Src/AleHooks.s: -------------------------------------------------------------------------------- 1 | 2 | .thumb 3 | 4 | .global AleHook 5 | .type AleHook, function 6 | 7 | AleHook: 8 | ldrb r0, [r6, #0x03] 9 | lsr r0, #3 10 | 11 | cmp r0, #31 12 | beq do_ale_thing 13 | 14 | strb r0, [r5, #0x08] 15 | 16 | continue: 17 | @ replaced 18 | mov r1, r5 19 | 20 | @ go back 21 | ldr r3, =0x08017D84+1 22 | bxr3: bx r3 23 | 24 | do_ale_thing: 25 | ldr r3, =AleApplyLoadUnitLevel 26 | 27 | mov r0, r5 @ arg r0 = unit 28 | mov r1, r6 @ arg r1 = info 29 | 30 | bl bxr3 31 | 32 | b continue 33 | -------------------------------------------------------------------------------- /Wizardry/BriefBwl/Src/BriefBwl.c: -------------------------------------------------------------------------------- 1 | 2 | #include "gbafe.h" 3 | 4 | enum 5 | { 6 | MAX_BWL_CHAR = 0x46 7 | }; 8 | 9 | struct NewBwlData 10 | { 11 | /* 00+00bit */ unsigned losses : 8; 12 | /* 00+08bit */ unsigned wins : 10; 13 | /* 00+18bit */ unsigned battles : 12; 14 | /* 00+30bit */ unsigned deathSkirm : 1; 15 | /* 00+31bit */ unsigned : 0; /* needs to stay 0 for logic to work */ 16 | 17 | /* 04+00bit */ unsigned deathLoc : 6; 18 | /* 04+06bit */ unsigned : 0; /* do what you want with those 2 bits */ 19 | 20 | /* there's 11 full bytes free starting at +05 */ 21 | 22 | /* 08 */ u32 pad[2]; 23 | }; 24 | 25 | extern struct NewBwlData gBWLDataStorage[]; 26 | 27 | static inline 28 | struct NewBwlData* GetBwlData(unsigned charId) 29 | { 30 | charId = charId - 1; 31 | return gBWLDataStorage + charId; 32 | } 33 | 34 | static inline 35 | int HasBwl(unsigned charId) 36 | { 37 | return (charId < MAX_BWL_CHAR) && GetCharacterData(charId)->affinity; 38 | } 39 | 40 | void BBwl_SetDeathStats(int charId, int killerId, int cause) 41 | { 42 | if (HasBwl(charId)) 43 | { 44 | struct NewBwlData* bwl = GetBwlData(charId); 45 | 46 | if (GetBattleMapType() == 2) // skirmish 47 | { 48 | bwl->deathSkirm = TRUE; 49 | bwl->deathLoc = gGMData.units[0].location; 50 | } 51 | else 52 | { 53 | bwl->deathSkirm = FALSE; 54 | bwl->deathLoc = gChapterData.chapterIndex; 55 | } 56 | } 57 | } 58 | 59 | int BBwl_GetTotalBattles(void) 60 | { 61 | int result = 0; 62 | 63 | for (unsigned i = 1; i < MAX_BWL_CHAR; ++i) 64 | result += GetBwlData(i)->battles; 65 | 66 | return result; 67 | } 68 | 69 | int BBwl_GetTotalWins(void) 70 | { 71 | int result = 0; 72 | 73 | for (unsigned i = 1; i < MAX_BWL_CHAR; ++i) 74 | result += GetBwlData(i)->wins; 75 | 76 | return result; 77 | } 78 | 79 | int BBwl_GetTotalLosses(void) 80 | { 81 | int result = 0; 82 | 83 | for (unsigned i = 1; i < MAX_BWL_CHAR; ++i) 84 | result += GetBwlData(i)->losses; 85 | 86 | return result; 87 | } 88 | 89 | int BBwl_GetFavor(int charId) 90 | { 91 | if (HasBwl(charId)) 92 | { 93 | struct NewBwlData* bwl = GetBwlData(charId); 94 | int result = bwl->battles * 4 + bwl->wins * 0x10 - bwl->losses * 0x80; 95 | 96 | if (result > 4000) 97 | return 4000; 98 | 99 | if (result < 0) 100 | return 0; 101 | 102 | return result; 103 | } 104 | 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /Wizardry/CBattleCalc/CBattleCalc.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_BATTLECALC 2 | #define HAX_BATTLECALC 3 | 4 | #ifndef _FE8_ 5 | ERROR FE8 Battle Calc Loop 6 | #endif // _FE8_ 7 | 8 | #include "Extensions/Hack Installation.txt" 9 | #include "EAstdlib.event" 10 | 11 | #define BCalcDefRes "($2AA44+1)" 12 | #define BCalcPower "($2AABC+1)" 13 | #define BCalcASpd "($2AB74+1)" 14 | #define BCalcHit "($2ABAC+1)" 15 | #define BCalcAvo "($2ABE4+1)" 16 | #define BCalcCrit "($2AC18+1)" 17 | #define BCalcDodge "($2AC54+1)" 18 | #define BCalcSupport "($2A9D0+1)" 19 | #define BCalcWRank "($2AD54+1)" 20 | #define BCalcStatus "($2AD90+1)" 21 | 22 | { 23 | 24 | PUSH; ORG 0x2A95C 25 | replaceWithHack(ComputeBattleStats) 26 | POP 27 | 28 | #include "src/BattleCalcCore.lyn.event" 29 | 30 | #ifndef BattleStatCalcListDeclared 31 | 32 | ALIGN 4 33 | BattleStatCalcList: 34 | POIN BCalcDefRes 35 | POIN BCalcPower 36 | POIN BCalcASpd 37 | POIN BCalcHit 38 | POIN BCalcAvo 39 | POIN BCalcCrit 40 | POIN BCalcDodge 41 | POIN BCalcSupport 42 | POIN BCalcWRank 43 | POIN BCalcStatus 44 | 45 | WORD 0 46 | 47 | #endif // BattleStatCalcListDeclared 48 | 49 | } 50 | 51 | #endif // HAX_BATTLECALC 52 | -------------------------------------------------------------------------------- /Wizardry/CBattleCalc/src/BattleCalcCore.c: -------------------------------------------------------------------------------- 1 | #include "gbafe.h" 2 | 3 | typedef void (*BCFunc) (struct BattleUnit*, struct BattleUnit*); 4 | 5 | extern const BCFunc BattleStatCalcList[]; 6 | 7 | void ComputeBattleStats(struct BattleUnit* subject, struct BattleUnit* target) { 8 | const BCFunc* it = &BattleStatCalcList[0]; 9 | 10 | while (*it) 11 | (*it++)(subject, target); 12 | } 13 | -------------------------------------------------------------------------------- /Wizardry/CFreeSelect/FreeSelect.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_FREESELECT 2 | #define HAX_FREESELECT 3 | 4 | #include "src/FreeSelect.lyn.event" 5 | 6 | #endif // HAX_FREESELECT 7 | -------------------------------------------------------------------------------- /Wizardry/CFreeSelect/src/FreeSelect.h: -------------------------------------------------------------------------------- 1 | #ifndef FREE_SELECT_H 2 | #define FREE_SELECT_H 3 | 4 | #include "gbafe.h" 5 | 6 | struct FSProc; 7 | 8 | typedef int(*FSHandlerFunc)(struct FSProc*, int, int); 9 | 10 | struct FSDefinition { 11 | FSHandlerFunc onInit; 12 | FSHandlerFunc onEnd; 13 | FSHandlerFunc onAPress; 14 | FSHandlerFunc onBPress; 15 | FSHandlerFunc onRPress; 16 | FSHandlerFunc onPosChange; 17 | }; 18 | 19 | struct FSProc { 20 | PROC_HEADER; 21 | 22 | const struct FSDefinition* pDefinition; 23 | APHandle* pCursorAp; 24 | }; 25 | 26 | enum FSResultCode { 27 | // TODO: FS_PAUSE, FS_RESUME? 28 | 29 | FS_END = 0x02, // Ends selection when set 30 | FS_SND_BEEP = 0x04, // Plays beep sound (sound Id 0x6A) when set 31 | FS_SND_BOOP = 0x08, // Plays boop sound (sound Id 0x6B) when set 32 | FS_SND_GURR = 0x10, // Plays gurr sound (sound Id 0x6C) when set 33 | FS_GFX_VALID = 0x20, // Sets cursor gfx to valid 34 | FS_GFX_INVALID = 0x40, // Sets cursor gfx to invalid 35 | }; 36 | 37 | struct FSProc* StartFreeSelection(const struct FSDefinition* pDefinition); 38 | 39 | #endif // FREE_SELECT_H -------------------------------------------------------------------------------- /Wizardry/CIconDisplay/IconDisplay.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_ICONDISPLAY 2 | #define HAX_ICONDISPLAY 3 | 4 | #ifndef _FE8_ 5 | ERROR this is for FE8 etc 6 | #endif 7 | 8 | #include "Extensions/Hack Installation.txt" 9 | #include "EAstdlib.event" 10 | 11 | #ifndef FreeSpace 12 | #define FreeSpace 0xB2A610 13 | ORG FreeSpace 14 | #endif 15 | 16 | // ================= 17 | // ICON DISPLAY CORE 18 | // ================= 19 | 20 | { 21 | 22 | #include "src/IconDisplayCore.lyn.event" 23 | 24 | IDRIconUsageLookup: 25 | WORD $02026A90 26 | 27 | } 28 | 29 | // ================= 30 | // ICON DISPLAY USER 31 | // ================= 32 | 33 | // The "User" system by default works with a sheet system: 34 | // Each icon identifier has two parts: an index (first 8 bits), and a sheet index (first 8 bits) 35 | 36 | // The sheet index defines which graphical sheet the icon graphics are to be found 37 | // (for example, the item icon sheet, or the skill icon sheet) 38 | 39 | // The index is for which icon in the sheet 40 | // (or, more precisely, the offset of the graphics in the sheet step 0x80 bytes) 41 | 42 | // The sheet #0 is the standard item icon sheet 43 | // (this way, "old" icon indices don't break compat) 44 | 45 | #include "src/IconDisplayUser.lyn.event" 46 | 47 | #ifndef ICON_SHEET_COUNT 48 | #define ICON_SHEET_COUNT 1 49 | #endif 50 | 51 | #define InjectIconSheet(aSheetIndex, apSheetGraphics) "PUSH; ORG IDRIconSheets + 4 * (aSheetIndex); POIN (apSheetGraphics); POP" 52 | 53 | IDRIconSheets: 54 | POIN $5926F4 // Sheet #0, the default one 55 | 56 | ORG (IDRIconSheets + 4 * ICON_SHEET_COUNT) 57 | 58 | #endif // HAX_ICONDISPLAY 59 | -------------------------------------------------------------------------------- /Wizardry/CIconDisplay/src/IconDisplay.h: -------------------------------------------------------------------------------- 1 | #ifndef ICON_DISPLAY_H 2 | #define ICON_DISPLAY_H 3 | 4 | #include "gbafe.h" 5 | 6 | #define MAX_SIMULTANEOUS_ICONS 0x20 7 | 8 | // Core functions 9 | u16 GetIconTileIndex(int icon); 10 | void LoadIconObjectGraphics(int icon, int tile); 11 | void ClearIcons(void); 12 | void ClearIcon(unsigned icon); 13 | 14 | // User function 15 | const void* GetIconGfx(unsigned icon); 16 | 17 | #endif // ICON_DISPLAY_H 18 | -------------------------------------------------------------------------------- /Wizardry/CIconDisplay/src/IconDisplayCore.c: -------------------------------------------------------------------------------- 1 | #include "IconDisplay.h" 2 | 3 | extern u16* const IDRIconUsageLookup; 4 | 5 | static unsigned GetIconUsedSlot(unsigned icon); 6 | static unsigned GetIconNewSlot(unsigned icon); 7 | 8 | u16 GetIconTileIndex(int icon) { 9 | unsigned slot, tile; 10 | 11 | // Check if icon is already loaded 12 | 13 | if ((slot = GetIconUsedSlot(icon))) 14 | return GetIconGfxTileIndex(slot); 15 | 16 | // Register new icon 17 | 18 | slot = GetIconNewSlot(icon); 19 | tile = GetIconGfxTileIndex(slot); 20 | 21 | // Register icon graphics 22 | 23 | RegisterTileGraphics( 24 | GetIconGfx(icon), 25 | (void*) (VRAM + tile * 0x20), 26 | 0x80 27 | ); 28 | 29 | return tile; 30 | } 31 | 32 | void LoadIconObjectGraphics(int icon, int tile) { 33 | void* target = VRAM_OBJ + (tile * 0x20); 34 | 35 | if (icon >= 0) { 36 | const void* source = GetIconGfx(icon); 37 | 38 | RegisterTileGraphics(source, target, 0x40); 39 | RegisterTileGraphics(source + 0x40, target + 0x400, 0x40); 40 | } else { 41 | // no icon, we clear the target graphics 42 | 43 | RegisterFillTile(0, target, 0x40); 44 | RegisterFillTile(0, target + 0x400, 0x40); 45 | } 46 | } 47 | 48 | void ClearIcons(void) { 49 | CpuFill32(-1, IDRIconUsageLookup, MAX_SIMULTANEOUS_ICONS * sizeof(u16)); 50 | } 51 | 52 | void ClearIcon(unsigned icon) { 53 | u16* it = IDRIconUsageLookup; 54 | u16* end = IDRIconUsageLookup + MAX_SIMULTANEOUS_ICONS; 55 | 56 | for (; it != end; ++it) { 57 | if (*it == icon) { 58 | *it = -1; 59 | break; 60 | } 61 | } 62 | } 63 | 64 | unsigned GetIconUsedSlot(unsigned icon) { 65 | u16* it = IDRIconUsageLookup; 66 | u16* end = IDRIconUsageLookup + MAX_SIMULTANEOUS_ICONS; 67 | 68 | for (; it != end; ++it) 69 | if (*it == icon) 70 | return (it - IDRIconUsageLookup) + 1; 71 | 72 | return 0; 73 | } 74 | 75 | unsigned GetIconNewSlot(unsigned icon) { 76 | u16* it = IDRIconUsageLookup; 77 | u16* end = IDRIconUsageLookup + MAX_SIMULTANEOUS_ICONS; 78 | 79 | for (; it != end; ++it) { 80 | if (*it == (u16)(-1)) { 81 | *it = icon; 82 | return (it - IDRIconUsageLookup) + 1; 83 | } 84 | } 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /Wizardry/CIconDisplay/src/IconDisplayUser.c: -------------------------------------------------------------------------------- 1 | #include "IconDisplay.h" 2 | 3 | #define ICON_SHEET(icon) (((icon) >> 8) & 0xFF) 4 | #define ICON_INDEX(icon) ((icon) & 0xFF) 5 | 6 | extern const void* const IDRIconSheets[]; 7 | 8 | const void* GetIconGfx(unsigned icon) { 9 | return IDRIconSheets[ICON_SHEET(icon)] + 0x80 * ICON_INDEX(icon); 10 | } 11 | -------------------------------------------------------------------------------- /Wizardry/CLolStats/LolStats.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_LOLSTATS 2 | #define HAX_LOLSTATS 3 | 4 | #ifndef _FE8_ 5 | ERROR LOLSTATS is for FE8 6 | #endif 7 | 8 | #include "Extensions/Hack Installation.txt" 9 | 10 | { 11 | 12 | PUSH 13 | 14 | ORG 0x2B9A0 15 | jumpToHack(NuggetStatIncrease) 16 | 17 | ORG 0x02B9C4 18 | jumpToHack(NuggetAutoleveledStatIncrease) 19 | 20 | POP 21 | 22 | #include "Src/LolStats.lyn.event" 23 | 24 | } 25 | 26 | // TODO: investigate further the crazy side effects this has on enemy autolevelling 27 | 28 | #endif // HAX_LOLSTATS 29 | -------------------------------------------------------------------------------- /Wizardry/CLolStats/Src/LolStats.c: -------------------------------------------------------------------------------- 1 | #include "gbafe.h" 2 | 3 | int NuggetStatIncrease(int growth) 4 | { 5 | int stat = 0; 6 | 7 | while ((growth -= NextRN_100()) >= 0) 8 | stat++; 9 | 10 | return stat; 11 | } 12 | 13 | int NuggetAutoleveledStatIncrease(int growth, int level) 14 | { 15 | int effGrowth = 0; 16 | 17 | // Here we just go for an approx that assumes growth < 100 18 | // It's probably also wrong but probably good enough 19 | 20 | effGrowth += 10000 * (growth * level + 50); // chances of getting stat 1 21 | effGrowth += 100 * (growth * growth * level + 5000) / 2; // chances of getting stat 2 22 | effGrowth += (growth * growth * growth * level + 500000) / 4; // chances of getting stat 3 23 | 24 | return Div(effGrowth, 1000000); 25 | } 26 | -------------------------------------------------------------------------------- /Wizardry/CPopupRework/Extensions/PopupDefinitions.txt: -------------------------------------------------------------------------------- 1 | #ifndef POPUP_DEFINITIONS 2 | #define POPUP_DEFINITIONS 3 | 4 | #define Popup_End "WORD 0x00 0" 5 | #define Popup_Space(aSize) "WORD 0x01 aSize" 6 | #define Popup_ItemName "WORD 0x02 0" 7 | #define Popup_ItemNameWithArticle_Capitalized "WORD 0x03 0" 8 | #define Popup_ItemNameWithArticle "WORD 0x04 0" 9 | #define Popup_UnitName "WORD 0x05 0" 10 | #define Popup_StringId(aTextId) "WORD 0x06 aTextId" 11 | #define Popup_StringPtr(apsStr) "WORD 0x07; POIN apsStr" 12 | #define Popup_SetColor(aColor) "WORD 0x08 aColor" 13 | #define Popup_ItemIcon "WORD 0x09 0" 14 | #define Popup_WTypeIcon "WORD 0x0A 0" 15 | #define Popup_Number "WORD 0x0B 0" 16 | #define Popup_SetSound(aSoundId) "WORD 0x0C aSoundId" 17 | 18 | // Example (Actual example from the game) 19 | 20 | // ORG 0x592230 21 | // Popup_SetSound(0x5A) 22 | // Popup_SetColor(0) 23 | // Popup_StringId(8) // "Got [X]" 24 | // Popup_SetColor(2) 25 | // Popup_ItemNameWithArticle 26 | // Popup_Space(1) 27 | // Popup_ItemIcon 28 | // Popup_SetColor(0) 29 | // Popup_Space(1) 30 | // Popup_StringId(0x22) // ".[X]" 31 | // Popup_End 32 | 33 | #endif // POPUP_DEFINITIONS 34 | -------------------------------------------------------------------------------- /Wizardry/CPopupRework/Src/PopRCore.c: -------------------------------------------------------------------------------- 1 | #include "PopupRework.h" 2 | 3 | unsigned PopR_GetLength(struct PopupReworkProc* proc) { 4 | const u32* defintion = proc->pop.pDefinition; 5 | 6 | unsigned result = 0; 7 | 8 | if (defintion) { 9 | while (defintion[0] && gPopupComponentTypes[defintion[0]]) { 10 | const struct PopupComponentType* type = gPopupComponentTypes[defintion[0]]; 11 | 12 | if (type->getLength) 13 | result += type->getLength(proc, defintion[1]); 14 | 15 | defintion += 2; 16 | } 17 | } 18 | 19 | return result; 20 | } 21 | 22 | void PopR_DisplayComponents(struct PopupReworkProc* proc, struct TextHandle* text) { 23 | const u32* defintion = proc->pop.pDefinition; 24 | 25 | if (defintion) { 26 | while (defintion[0] && gPopupComponentTypes[defintion[0]]) { 27 | const struct PopupComponentType* type = gPopupComponentTypes[defintion[0]]; 28 | 29 | if (type->display) 30 | type->display(proc, text, defintion[1]); 31 | 32 | defintion += 2; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Wizardry/CPopupRework/Src/PopupRework.h: -------------------------------------------------------------------------------- 1 | #ifndef FE8_POPUP_REWORK_H 2 | #define FE8_POPUP_REWORK_H 3 | 4 | #include "gbafe.h" 5 | 6 | struct PopupReworkCallTable; 7 | 8 | struct PopupReworkProc { 9 | /* 00 */ struct PopupProc pop; 10 | 11 | /* 4C */ void (*addIcon) (struct PopupReworkProc* proc, unsigned iconId, unsigned xOffset); 12 | }; 13 | 14 | struct PopupComponentType { 15 | int (*getLength) (struct PopupReworkProc* proc, u32 argument); 16 | void (*display) (struct PopupReworkProc* proc, struct TextHandle* text, u32 argument); 17 | }; 18 | 19 | struct BattlePopupType { 20 | int (*tryInit) (void); 21 | const u32* definition; 22 | int time; 23 | }; 24 | 25 | extern const struct PopupComponentType* const gPopupComponentTypes[]; 26 | 27 | extern const struct BattlePopupType gBattlePopupTable[]; 28 | extern const struct BattlePopupType gPromotionPopupTable[]; 29 | 30 | #pragma long_calls 31 | 32 | unsigned PopR_GetLength(struct PopupReworkProc* proc); 33 | void PopR_DisplayComponents(struct PopupReworkProc* proc, struct TextHandle* text); 34 | 35 | #pragma long_calls_off 36 | 37 | #endif // FE8_POPUP_REWORK_H 38 | -------------------------------------------------------------------------------- /Wizardry/CPopupRework/Src/VanillaPopupInits.c: -------------------------------------------------------------------------------- 1 | #include "PopupRework.h" 2 | 3 | static int PopR_InitWRankNewCommon(unsigned wType) { 4 | extern struct BattleUnit* gpUnitLeft_BattleStruct; 5 | extern struct BattleUnit* gpUnitRight_BattleStruct; 6 | 7 | // Check if had wrank before promotion 8 | if (gpUnitRight_BattleStruct->unit.ranks[wType]) 9 | return FALSE; 10 | 11 | // Check if has not wrank even after promotion 12 | if (!gpUnitLeft_BattleStruct->unit.ranks[wType]) 13 | return FALSE; 14 | 15 | SetPopupWType(wType); 16 | return TRUE; 17 | } 18 | 19 | #define POPR_INIT_WRANK_DECL(WRankName, WRankId) \ 20 | int PopR_Init ## WRankName ## RankNew (void) { \ 21 | return PopR_InitWRankNewCommon((WRankId)); \ 22 | } 23 | 24 | POPR_INIT_WRANK_DECL(Sword, 0) 25 | POPR_INIT_WRANK_DECL(Lance, 1) 26 | POPR_INIT_WRANK_DECL(Axe, 2) 27 | POPR_INIT_WRANK_DECL(Bow, 3) 28 | POPR_INIT_WRANK_DECL(Staff, 4) 29 | POPR_INIT_WRANK_DECL(Anima, 5) 30 | POPR_INIT_WRANK_DECL(Light, 6) 31 | POPR_INIT_WRANK_DECL(Elder, 7) 32 | 33 | #undef POPR_INIT_WRANK_DECL 34 | 35 | int PopR_InitWRankUp(void) { 36 | // Check Active Unit 37 | if (BattleUnit_ShouldDisplayWRankUp(&gBattleActor)) { 38 | SetPopupWType(gBattleActor.weaponType); 39 | return TRUE; 40 | } 41 | 42 | // Check Target Unit 43 | if (BattleUnit_ShouldDisplayWRankUp(&gBattleTarget)) { 44 | SetPopupWType(gBattleTarget.weaponType); 45 | return TRUE; 46 | } 47 | 48 | return FALSE; 49 | } 50 | 51 | int PopR_InitWeaponBroke(void) { 52 | // Check Active Unit 53 | if (BattleUnit_ShouldDisplayWpnBroke(&gBattleActor)) { 54 | SetPopupItem(gBattleActor.weaponBefore); 55 | return TRUE; 56 | } 57 | 58 | // Check Target Unit 59 | if (BattleUnit_ShouldDisplayWpnBroke(&gBattleTarget)) { 60 | SetPopupItem(gBattleTarget.weaponBefore); 61 | return TRUE; 62 | } 63 | 64 | return FALSE; 65 | } 66 | 67 | const u32 gPopup_PopR_NewWType[] = { 68 | 0x0C, 0x5A, // set_sound 0x5A 69 | 0x08, 0x00, // set_color 0x00 70 | 0x06, 0x0D, // string_id 0x0D @ "You can now use [X]" 71 | 0x0A, 0, // wtype_icon 72 | 0x00, 0, // end 73 | }; 74 | -------------------------------------------------------------------------------- /Wizardry/CRewarp/Rewarp.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_REWARP_COMMAND 2 | #define HAX_REWARP_COMMAND 3 | 4 | #ifndef _FE8_ 5 | ERROR CRewarp is for FE8 only 6 | #endif // _FE8_ 7 | 8 | #ifndef HAX_FREESELECT 9 | ERROR please include CFreeSelect before CRewarp 10 | #endif // HAX_FREESELECT 11 | 12 | #ifndef HAX_AAR 13 | ERROR please include CUnitAction before CRewarp 14 | #endif // HAX_AAR 15 | 16 | #ifndef ACTION_REWARP 17 | #define ACTION_REWARP 0x27 18 | #endif // ACTION_REWARP 19 | 20 | InjectUnitAction(ACTION_REWARP, ActionRoutine(RCAction)) 21 | 22 | #include "src/Rewarp.lyn.event" 23 | #include "src/RewarpAnim.lyn.event" 24 | 25 | ALIGN 4 26 | RewarpActionId: 27 | WORD ACTION_REWARP 28 | 29 | #endif // HAX_REWARP_COMMAND 30 | -------------------------------------------------------------------------------- /Wizardry/CRewarp/src/FreeSelect.h: -------------------------------------------------------------------------------- 1 | #ifndef FREE_SELECT_H 2 | #define FREE_SELECT_H 3 | 4 | #include "gbafe.h" 5 | 6 | struct FSProc; 7 | 8 | typedef int(*FSHandlerFunc)(struct FSProc*, int, int); 9 | 10 | struct FSDefinition { 11 | FSHandlerFunc onInit; 12 | FSHandlerFunc onEnd; 13 | FSHandlerFunc onAPress; 14 | FSHandlerFunc onBPress; 15 | FSHandlerFunc onRPress; 16 | FSHandlerFunc onPosChange; 17 | }; 18 | 19 | struct FSProc { 20 | PROC_HEADER; 21 | 22 | const struct FSDefinition* pDefinition; 23 | APHandle* pCursorAp; 24 | }; 25 | 26 | enum FSResultCode { 27 | // TODO: FS_PAUSE, FS_RESUME? 28 | 29 | FS_END = 0x02, // Ends selection when set 30 | FS_SND_BEEP = 0x04, // Plays beep sound (sound Id 0x6A) when set 31 | FS_SND_BOOP = 0x08, // Plays boop sound (sound Id 0x6B) when set 32 | FS_SND_GURR = 0x10, // Plays gurr sound (sound Id 0x6C) when set 33 | FS_GFX_VALID = 0x20, // Sets cursor gfx to valid 34 | FS_GFX_INVALID = 0x40, // Sets cursor gfx to invalid 35 | }; 36 | 37 | struct FSProc* StartFreeSelection(const struct FSDefinition* pDefinition); 38 | 39 | #endif // FREE_SELECT_H -------------------------------------------------------------------------------- /Wizardry/CRewarp/src/Rewarp.c: -------------------------------------------------------------------------------- 1 | #include "Rewarp.h" 2 | 3 | extern const int RewarpActionId; 4 | 5 | static int RCOnSelect(struct FSProc*, int, int); 6 | static int RCOnCancel(struct FSProc*, int, int); 7 | 8 | static const struct FSDefinition sRewarpFSDefinition = { 9 | .onInit = NULL, 10 | .onEnd = NULL, 11 | .onAPress = RCOnSelect, 12 | .onBPress = RCOnCancel, 13 | .onRPress = NULL, 14 | .onPosChange = NULL 15 | }; 16 | 17 | int RCUsability(const struct MenuCommandDefinition* def, int index) { 18 | return MCA_USABLE; 19 | } 20 | 21 | int RCEffect(struct MenuProc* menu, struct MenuCommandProc* command) { 22 | StartFreeSelection(&sRewarpFSDefinition); 23 | return ME_DISABLE | ME_END | ME_PLAY_BEEP | ME_CLEAR_GFX; 24 | } 25 | 26 | int RCAction(Proc* proc) { 27 | StartRewarpEffect( 28 | gActiveUnit, 29 | 30 | gActionData.xMove = gActionData.xOther, 31 | gActionData.yMove = gActionData.yOther 32 | ); 33 | 34 | return 0; 35 | } 36 | 37 | int RCOnSelect(struct FSProc* proc, int x, int y) { 38 | Text_ResetTileAllocation(); 39 | HideMoveRangeGraphics(); 40 | EndBottomHelpText(); 41 | 42 | gActionData.xOther = x; 43 | gActionData.yOther = y; 44 | 45 | gActionData.unitActionType = RewarpActionId; 46 | 47 | EnsureCameraOntoPosition( 48 | (Proc*)(proc), 49 | 50 | gActiveUnit->xPos, 51 | gActiveUnit->yPos 52 | ); 53 | 54 | return FS_END | FS_SND_BEEP; 55 | } 56 | 57 | int RCOnCancel(struct FSProc* proc, int x, int y) { 58 | Text_ResetTileAllocation(); 59 | HideMoveRangeGraphics(); 60 | EndBottomHelpText(); 61 | 62 | SetCursorMapPosition( 63 | gActiveUnit->xPos, 64 | gActiveUnit->yPos 65 | ); 66 | 67 | ProcStart(gProc_GoBackToUnitMenu, ROOT_PROC_3); 68 | 69 | return FS_END | FS_SND_BOOP; 70 | } 71 | -------------------------------------------------------------------------------- /Wizardry/CRewarp/src/Rewarp.h: -------------------------------------------------------------------------------- 1 | #ifndef REWARP_H 2 | #define REWARP_H 3 | 4 | #include "gbafe.h" 5 | #include "FreeSelect.h" 6 | 7 | int RCUsability(const struct MenuCommandDefinition* def, int index); 8 | int RCEffect(struct MenuProc* menu, struct MenuCommandProc* command); 9 | int RCAction(Proc* proc); 10 | 11 | void StartRewarpEffect(Unit* unit, int xTarget, int yTarget); 12 | 13 | #endif // REWARP_H 14 | -------------------------------------------------------------------------------- /Wizardry/CUnitAction/src/ActionRework.c: -------------------------------------------------------------------------------- 1 | #include "gbafe.h" 2 | 3 | int ActionStaffDoorChestUseItem(Proc*); 4 | 5 | typedef int (*ActionFunc) (struct Proc*); 6 | 7 | extern const ActionFunc UnitActionCallTable[]; 8 | 9 | static int RequiresProcYield(ActionFunc func) 10 | { 11 | const u32 raw = (u32)(func); 12 | return (raw >> 28) ? 1 : 0; 13 | } 14 | 15 | static ActionFunc FilterFunc(ActionFunc func) 16 | { 17 | const u32 raw = (u32)(func); 18 | const ActionFunc result = (ActionFunc)(raw & 0xFFFFFFF); 19 | 20 | return result; 21 | } 22 | 23 | int ApplyUnitAction(struct Proc* proc) 24 | { 25 | gActiveUnit = GetUnit(gActionData.subjectIndex); 26 | 27 | #ifndef NO_NIGHTMARE_HARDCODED_CHECK 28 | 29 | if (gActionData.unitActionType == UNIT_ACTION_COMBAT) 30 | { 31 | if (GetItemIndex(gActiveUnit->items[gActionData.itemSlotIndex]) == 0xA6) 32 | { 33 | ActionStaffDoorChestUseItem(proc); 34 | return 0; 35 | } 36 | } 37 | 38 | #endif // NO_NIGHTMARE_HARDCODED_CHECK 39 | 40 | ActionFunc func = UnitActionCallTable[gActionData.unitActionType]; 41 | 42 | if (func) 43 | { 44 | if (RequiresProcYield(func)) 45 | { 46 | func = FilterFunc(func); 47 | func(proc); 48 | 49 | return 0; 50 | } 51 | 52 | return func(proc); 53 | } 54 | 55 | return 1; 56 | } 57 | 58 | int WaitAction(struct Proc* proc) 59 | { 60 | gActiveUnit->state |= US_HAS_MOVED; 61 | return 1; 62 | } 63 | -------------------------------------------------------------------------------- /Wizardry/CustomGameSpeed/CustomGameSpeed.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_CUSTOM_GAME_SPEED 2 | #define HAX_CUSTOM_GAME_SPEED 3 | 4 | // Change default game speed option values 5 | // hack by StanH_ 6 | 7 | // Options 8 | // Copy-paste the following block into your custom definitions file or somewhere 9 | // And edit to your heart's content! 10 | 11 | #ifndef CustomGameSpeedConfig 12 | #define CustomGameSpeedConfig 13 | 14 | #define GameSpeedNormalValue 5 15 | #define GameSpeedNormalCheckSlow True 16 | #define GameSpeedNormalCheckAPress False 17 | 18 | #define GameSpeedFastValue 6 19 | #define GameSpeedFastCheckSlow False 20 | #define GameSpeedFastCheckAPress True 21 | #endif // CustomGameSpeedConfig 22 | 23 | { 24 | 25 | #ifndef LynJumpDefined 26 | #define LynJumpDefined 27 | #define LynJump(aTarget) "WORD $46C04778 $E59FC000 $E12FFF1C; POIN aTarget" 28 | #endif // LynJumpDefined 29 | 30 | PUSH; ORG $794E8 31 | LynJump(CustomGameSpeedHook) 32 | POP 33 | 34 | #include "Src/CustomGameSpeed.lyn.event" 35 | 36 | } 37 | 38 | #endif // HAX_CUSTOM_GAME_SPEED 39 | -------------------------------------------------------------------------------- /Wizardry/CustomGameSpeed/Src/CustomGameSpeed.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | .global CustomGameSpeedHook 4 | .type CustomGameSpeedHook, %function 5 | 6 | GetClassData = (0x08019444+1) 7 | 8 | gChapterData = 0x0202BCF0 9 | gKeyState = 0x02024CC0 10 | 11 | @ Config struct definitions 12 | Config.value = 0 13 | Config.checkSlow = 1 14 | Config.checkAPress = 2 15 | 16 | CustomGameSpeedHook: 17 | @ KNOWN STATE: 18 | @ r4 = Active MU 19 | 20 | @ Get Class Data 21 | 22 | mov r0, #0x41 @ MU.displayedClassId 23 | ldrb r0, [r4, r0] 24 | 25 | ldr r1, =GetClassData 26 | bl BXR1 27 | 28 | @ r4 = Slow Walking option 29 | ldrb r4, [r0, #7] 30 | 31 | @ r0 = Walking Speed option 32 | ldr r0, =gChapterData 33 | mov r1, #0x40 @ ChapterData.option1 34 | ldrb r0, [r0, r1] 35 | lsr r0, #7 36 | 37 | @ r0 *= (sizeof(Config) = 4) 38 | lsl r0, #2 39 | 40 | @ r3 = Current Config data pointer 41 | adr r3, CGS.ConfigArray 42 | add r3, r0 43 | 44 | @ r2 = Base speed value 45 | ldrb r2, [r3, #Config.value] 46 | 47 | @ r0 = Check A Press? 48 | ldrb r0, [r3, #Config.checkAPress] 49 | 50 | cmp r0, #0 51 | beq CGS.skipCheckAPress 52 | 53 | ldr r0, =gKeyState 54 | ldrh r0, [r0, #4] @ Pressed Keys 55 | 56 | mov r1, #1 @ A Button 57 | 58 | @ Test A Button 59 | tst r0, r1 60 | beq CGS.skipCheckAPress 61 | 62 | @ Increment speed 63 | add r2, #1 64 | 65 | CGS.skipCheckAPress: 66 | @ r0 = Check Slow Walking? 67 | ldrb r0, [r3, #Config.checkSlow] 68 | 69 | cmp r0, #0 70 | beq CGS.skipSlowWalking 71 | 72 | cmp r4, #0 73 | beq CGS.skipSlowWalking 74 | 75 | @ Decrement speed 76 | sub r2, #1 77 | 78 | CGS.skipSlowWalking: 79 | @ return (1 << speedValue) 80 | mov r0, #1 81 | lsl r0, r2 82 | 83 | pop {r4} 84 | 85 | pop {r1} 86 | BXR1: bx r1 87 | 88 | .pool 89 | .align 90 | 91 | CGS.ConfigArray: 92 | .byte GameSpeedNormalValue 93 | .byte GameSpeedNormalCheckSlow 94 | .byte GameSpeedNormalCheckAPress 95 | .byte 0 @ pad 96 | 97 | .byte GameSpeedFastValue 98 | .byte GameSpeedFastCheckSlow 99 | .byte GameSpeedFastCheckAPress 100 | .byte 0 @ pad 101 | 102 | .align 103 | -------------------------------------------------------------------------------- /Wizardry/DanceAi/DanceAi.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_DANCEAI 2 | #define HAX_DANCEAI 3 | 4 | #ifndef _FE8_ 5 | ERROR DanceAi is for FE8 6 | #endif // _FE8_ 7 | 8 | #include "Extensions/Hack Installation.txt" 9 | 10 | { 11 | 12 | PUSH 13 | ORG $03A5AC // Dance Action Handler Pointer (replaces dummy handler) 14 | POIN DanceAiDoAction 15 | 16 | ORG $03FACA // At the end of the Staff Ai decision routine 17 | SHORT $46C0 // align with nop 18 | jumpToHack(DanceAiStaffHook) 19 | POP 20 | 21 | #include "src/DanceAi.lyn.event" 22 | #include "src/DanceAiStaffHook.lyn.event" 23 | 24 | } 25 | 26 | #endif // HAX_DANCEAI 27 | -------------------------------------------------------------------------------- /Wizardry/DanceAi/src/DanceAiStaffHook.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | .global DanceAiStaffHook 4 | .type DanceAiStaffHook, %function 5 | 6 | @ jumpToHack from $03FACA 7 | DanceAiStaffHook: 8 | ldr r0, =(gAiData + 0x90) @ gAiData.decision 9 | ldrb r0, [r0, #0x0A] 10 | 11 | @ If a decision was already taken, don't do dance decision checking 12 | cmp r0, #0 13 | bne end 14 | 15 | mov r0, r7 16 | ldr r3, =DanceAiTryDecide 17 | 18 | bl BXR3 19 | 20 | @ Replaced function end 21 | 22 | ldr r0, =(gAiData + 0x90) @ gAiData.decision 23 | ldrb r0, [r0, #0x0A] 24 | 25 | end: 26 | pop {r3} 27 | mov r8, r3 28 | pop {r4-r7} 29 | pop {r3} 30 | BXR3: 31 | bx r3 32 | -------------------------------------------------------------------------------- /Wizardry/DeathDropFix/DeathDropFix.event: -------------------------------------------------------------------------------- 1 | #ifndef DEATHDROPFIX_INCLUDED 2 | #define DEATHDROPFIX_INCLUDED 3 | 4 | // makes enemy rescued units not drop (and die) when their holder dies on terrain they can't cross 5 | // hack by Stan 6 | 7 | #include "Src/DropFix.lyn.event" 8 | #include "Src/DropHook.lyn.event" 9 | 10 | PUSH 11 | 12 | ORG $032690 13 | WORD $47184B00; POIN DropHook 14 | 15 | POP 16 | 17 | #endif // DEATHDROPFIX_INCLUDED 18 | -------------------------------------------------------------------------------- /Wizardry/DeathDropFix/Src/DropFix.c: -------------------------------------------------------------------------------- 1 | 2 | #include "gbafe.h" 3 | 4 | int CheckDeathDrop(struct Unit* unit) 5 | { 6 | int x = unit->xPos; 7 | int y = unit->yPos; 8 | 9 | struct Unit* other = GetUnit(unit->rescueOtherUnit); 10 | 11 | if (other && ((gMapHidden[y][x] & 1) || !CanUnitCrossTerrain(other, gMapTerrain[y][x]))) 12 | { 13 | UnitDrop(unit, x, y); 14 | UnitKill(other); 15 | 16 | return TRUE; 17 | } 18 | 19 | return FALSE; // a hidden unit is occupying this position 20 | } 21 | -------------------------------------------------------------------------------- /Wizardry/DeathDropFix/Src/DropHook.s: -------------------------------------------------------------------------------- 1 | 2 | .thumb 3 | 4 | .global DropHook 5 | .type DropHook, function 6 | 7 | DropHook: 8 | @ KNOWN STATE: 9 | @ r4 is proc 10 | @ r5 is unit 11 | 12 | ldrb r0, [r5, #0x0B] @ Unit.id 13 | mov r1, #0xC0 14 | 15 | tst r0, r1 16 | beq finish 17 | 18 | mov r0, r5 @ arg r0 = unit 19 | bl CheckDeathDrop 20 | 21 | cmp r0, #0 22 | beq finish 23 | 24 | pop {r4-r6} 25 | pop {r0} 26 | bx r0 27 | 28 | finish: 29 | @ replaced 30 | 31 | ldr r3, =ProcStartBlocking 32 | 33 | ldr r0, =gProc_SMSJumpAnimation @ arg r0 = proc scr 34 | mov r1, r4 @ arg r1 = parent proc 35 | 36 | bl BXR3 37 | 38 | ldr r3, =0x08032698+1 39 | BXR3: bx r3 40 | -------------------------------------------------------------------------------- /Wizardry/DecideMonitor/DecideMonitor.event: -------------------------------------------------------------------------------- 1 | #ifndef DECIDEMONI_INCLUDED 2 | #define DECIDEMONI_INCLUDED 3 | 4 | // Stupid hack that displays how long it took the AI to (try to) make and apply a decision 5 | // hack by Stan 6 | 7 | #include "Extensions/ProcDefinitions.txt" 8 | 9 | #include "Src/DecideMonitor.lyn.event" 10 | 11 | PUSH 12 | 13 | ORG $5A7FCC 14 | // replaces one instruction (name) and moves label up 15 | PROC_LABEL(0) 16 | PROC_CALL_ROUTINE_2(StartDecideMonitor) 17 | 18 | POP 19 | 20 | #endif // DECIDEMONI_INCLUDED 21 | -------------------------------------------------------------------------------- /Wizardry/DecideMonitor/Src/DecideMonitor.c: -------------------------------------------------------------------------------- 1 | 2 | #include "gbafe.h" 3 | 4 | struct DecideMonitorProc 5 | { 6 | PROC_HEADER; 7 | 8 | unsigned startTime; 9 | }; 10 | 11 | static 12 | void DecideMonitorDisplay(struct DecideMonitorProc* proc); 13 | 14 | static const 15 | struct ProcInstruction sProc_DecideMonitor[] = 16 | { 17 | PROC_SET_NAME("Decide Monitor"), 18 | 19 | PROC_SET_DESTRUCTOR(DecideMonitorDisplay), 20 | PROC_BLOCK, 21 | 22 | PROC_END, 23 | }; 24 | 25 | static 26 | void DecideMonitorDisplay(struct DecideMonitorProc* proc) 27 | { 28 | static const 29 | unsigned sPopupTime = 45; 30 | 31 | static const 32 | u32 pop[] = 33 | { 34 | 0x07, (u32)("CpDecide took "), 35 | 0x0B, 0, // number 36 | 0x07, (u32)(" frames."), 37 | 0x00, 0, // end 38 | }; 39 | 40 | static const 41 | struct ProcInstruction sDummy[] = 42 | { 43 | PROC_CALL_ROUTINE(LockGameLogic), 44 | PROC_YIELD, 45 | PROC_CALL_ROUTINE(UnlockGameLogic), 46 | PROC_END, 47 | }; 48 | 49 | SetPopupNumber(GetGameClock() - proc->startTime - sPopupTime); 50 | Popup_Create(pop, sPopupTime, 0, ProcStart(sDummy, ROOT_PROC_3)); 51 | } 52 | 53 | int StartDecideMonitor(struct Proc* proc) 54 | { 55 | EndEachProc(sProc_DecideMonitor); 56 | 57 | struct DecideMonitorProc* monitor = (void*) ProcStart(sProc_DecideMonitor, proc); 58 | monitor->startTime = GetGameClock(); 59 | 60 | return FALSE; 61 | } 62 | -------------------------------------------------------------------------------- /Wizardry/DoubleDouble/DoubleDouble.event: -------------------------------------------------------------------------------- 1 | 2 | // Require double opponent's speed to follow up attack 3 | // hack by stan 4 | 5 | #include "Src/DoubleDouble.lyn.event" 6 | -------------------------------------------------------------------------------- /Wizardry/DoubleDouble/Src/DoubleDouble.c: -------------------------------------------------------------------------------- 1 | 2 | #include "gbafe.h" 3 | 4 | //! Should Replace fe8u:0802AF90 5 | int BattleGetFollowUpOrder(struct BattleUnit** attacker, struct BattleUnit** defender) 6 | { 7 | if (gBattleActor.battleSpeed > 250) 8 | return FALSE; 9 | 10 | if (gBattleActor.battleSpeed >= gBattleTarget.battleSpeed*2) 11 | { 12 | *attacker = &gBattleActor; 13 | *defender = &gBattleTarget; 14 | 15 | if (GetItemWeaponEffect((*attacker)->weaponBefore) == 3) 16 | return FALSE; 17 | 18 | return TRUE; 19 | } 20 | 21 | if (gBattleTarget.battleSpeed >= gBattleActor.battleSpeed*2) 22 | { 23 | *attacker = &gBattleTarget; 24 | *defender = &gBattleActor; 25 | 26 | if (GetItemWeaponEffect((*attacker)->weaponBefore) == 3) 27 | return FALSE; 28 | 29 | return TRUE; 30 | } 31 | 32 | return FALSE; 33 | } -------------------------------------------------------------------------------- /Wizardry/Dumb/NoBattleAnimations.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_NOBATTLEANIMS 2 | #define HAX_NOBATTLEANIMS 3 | 4 | PUSH 5 | ORG $057C98 6 | SHORT $2000 // mov r0, #0 7 | POP 8 | 9 | #endif // HAX_NOBATTLEANIMS 10 | -------------------------------------------------------------------------------- /Wizardry/Dumb/RemoveSupports.event: -------------------------------------------------------------------------------- 1 | #ifndef RS_INCLUDED 2 | #define RS_INCLUDED 3 | 4 | // Removes supports in a stupid hardcoded way 5 | // hack by Stan 6 | 7 | // Frees a whole 6(7) saved bytes + 1 suspended byte inside every unit structs 8 | // (Hopefully) 9 | 10 | PUSH 11 | 12 | ORG $0281C8 13 | // mov r0, #0 ; bx lr 14 | SHORT $2000 $4770 15 | 16 | POP 17 | 18 | #endif // RS_INCLUDED 19 | -------------------------------------------------------------------------------- /Wizardry/EvilRN/EvilRN.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_EVILRN_EVENT 2 | #define HAX_EVILRN_EVENT 3 | 4 | #ifndef _FE8_ 5 | ERROR EVILRN is for FE8 6 | #endif 7 | 8 | #include "Extensions/Hack Installation.txt" 9 | 10 | { 11 | 12 | PUSH; ORG 0x000CB8 13 | jumpToHack(RollRNForHit) 14 | POP 15 | 16 | ALIGN 4 17 | 18 | #include "src/evilrn.lyn.event" 19 | 20 | } 21 | 22 | #endif // HAX_EVILRN_EVENT 23 | -------------------------------------------------------------------------------- /Wizardry/EvilRN/src/evilrn.c: -------------------------------------------------------------------------------- 1 | #include "gbafe.h" 2 | 3 | // thanks to SEVA for the formula 4 | // (3*(A^2)) - ((2*(A^3))/100) = TrueRN*100 5 | 6 | int RollRNForHit(int chance) { 7 | int rn = NextRN_100(); 8 | 9 | int rn2 = rn*rn; 10 | int rn3 = rn*rn*rn; 11 | 12 | return (chance*10000) > ((300*rn2) - (2*rn3)); 13 | } 14 | -------------------------------------------------------------------------------- /Wizardry/ExpandedModularSave/Src/MSBWLHook.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | .global MS_BWLSaveHook 4 | .type MS_BWLSaveHook, %function 5 | 6 | ReturnLocation = (0x080A4662+1) 7 | 8 | MS_BWLSaveHook: 9 | @ nop then LynJump from FE8U:080A460E 10 | 11 | @ KNOWN STATE: 12 | @ r0-r4 free 13 | @ r5 = RAM BWL entry 14 | @ r6 = BWL offset (aka CharID*$10) 15 | @ r7 = gChapterData 16 | @ r8 = CharID 17 | 18 | @ STEP 1 : SUSPEND SAVE 19 | 20 | mov r0, #3 21 | ldr r3, =GetSaveTargetAddress 22 | bl BXR3 23 | 24 | @ var r4 = Suspend Save target address 25 | mov r4, r0 26 | 27 | @ arg r0 = Chunk Id 28 | ldr r0, =gMS_BWLChunkId 29 | ldrb r0, [r0] 30 | 31 | ldr r3, =MS_FindSuspendSaveChunk 32 | bl BXR3 33 | 34 | @ r1 = save target 35 | ldrh r1, [r0, #0x00] @ +00 | offset 36 | sub r1, #0x10 37 | add r1, r6 38 | add r1, r4 39 | 40 | mov r0, r5 @ arg r0 = src 41 | @ @ arg r1 = dst 42 | mov r2, #1 @ arg r2 = len 43 | 44 | ldr r3, =WriteAndVerifySramFast 45 | bl BXR3 46 | 47 | mov r0, sp @ arg r0 = $10 byte buffer 48 | mov r1, #3 @ arg r1 = block id 49 | 50 | ldr r3, =SaveMetadata_Load 51 | bl BXR3 52 | 53 | mov r0, sp @ arg r0 = $10 byte buffer 54 | mov r1, #3 @ arg r1 = block id 55 | 56 | ldr r3, =SaveMetadata_Save 57 | bl BXR3 58 | 59 | @ STEP 2 : GAME SAVE 60 | 61 | ldrb r0, [r7, #0x0C] @ ChapterSate.saveSlot 62 | ldr r3, =GetSaveTargetAddress 63 | bl BXR3 64 | 65 | @ var r4 = Game Save target address 66 | mov r4, r0 67 | 68 | @ arg r0 = Chunk Id 69 | ldr r0, =gMS_BWLChunkId 70 | ldrb r0, [r0] 71 | 72 | ldr r3, =MS_FindGameSaveChunk 73 | bl BXR3 74 | 75 | @ r1 = save target 76 | ldrh r1, [r0, #0x00] @ +00 | offset 77 | sub r1, #0x10 78 | add r1, r6 79 | add r1, r4 80 | 81 | mov r0, r5 @ arg r0 = src 82 | @ @ arg r1 = dst 83 | mov r2, #1 @ arg r2 = len 84 | 85 | @ Saving only 1 byte because skill system compat 86 | @ (originally saved 3, but that overlaps with skills) 87 | 88 | ldr r3, =WriteAndVerifySramFast 89 | bl BXR3 90 | 91 | mov r0, sp @ arg r0 = $10 byte buffer 92 | ldrb r1, [r7, #0x0C] @ arg r1 = block id 93 | 94 | ldr r3, =SaveMetadata_Load 95 | bl BXR3 96 | 97 | mov r0, sp @ arg r0 = $10 byte buffer 98 | ldrb r1, [r7, #0x0C] @ arg r1 = block id 99 | 100 | ldr r3, =SaveMetadata_Save 101 | bl BXR3 102 | 103 | ldr r3, =ReturnLocation 104 | BXR3: bx r3 105 | -------------------------------------------------------------------------------- /Wizardry/ExpandedModularSave/Src/MSSizeHook.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | .global MS_SaveSizeHook 4 | .type MS_SaveSizeHook, %function 5 | 6 | SaveMetadata_Save.end = (0x080A301A+1) 7 | SaveMetadata_Save.continue = (0x080A3002+1) 8 | 9 | MS_SaveSizeHook: 10 | @ LynJump from FE8U:080A2FB0 11 | 12 | @ Known State: 13 | @ r0 = type 14 | @ r4 = metadata 15 | @ r5 = 0 16 | @ r6 = slot id 17 | @ r7 = 0 18 | 19 | @ Check for the blank block type 20 | cmp r0, #0xFF 21 | beq blank_block 22 | 23 | @ Not too much please 24 | cmp r0, #3 25 | bhi end 26 | 27 | @ Load size from external lookup 28 | 29 | ldr r1, =gSaveBlockTypeSizeLookup 30 | lsl r0, #1 31 | ldrh r0, [r1, r0] 32 | 33 | strh r0, [r4, #0xA] @ size 34 | 35 | b continue 36 | 37 | blank_block: 38 | strh r5, [r4, #0x4] @ magic2 39 | strh r5, [r4, #0x8] @ offset 40 | strh r5, [r4, #0xA] @ size 41 | 42 | continue: 43 | ldr r3, =SaveMetadata_Save.continue 44 | bx r3 45 | 46 | end: 47 | ldr r3, =SaveMetadata_Save.end 48 | bx r3 49 | 50 | -------------------------------------------------------------------------------- /Wizardry/ExpandedModularSave/Src/MSaFuncs.c: -------------------------------------------------------------------------------- 1 | #include "ModularSave.h" 2 | 3 | // This contains Save functions suitables for MS save chunks 4 | // In case there's no vanilla function that fit the bill 5 | // If a Suspend chunk function is also used in a Save chunk, it will be here 6 | 7 | void MSa_SaveChapterState(void* target, unsigned size) { 8 | gChapterData._u00 = GetGameClock(); 9 | WriteAndVerifySramFast(&gChapterData, target, size); 10 | } 11 | 12 | void MSa_LoadChapterState(void* source, unsigned size) { 13 | ReadSramFast(source, &gChapterData, size); 14 | SetGameClock(gChapterData._u00); 15 | } 16 | 17 | void MSa_SaveUnits(void* target, unsigned size) { 18 | struct SaveGlobalMetadata sgm; 19 | LoadGeneralGameMetadata(&sgm); 20 | 21 | for (unsigned i = 0; i < 51; ++i) { 22 | struct Unit* unit = GetUnit(i+1); 23 | 24 | // Save unit 25 | SaveUnit(unit, target + (0x24*i)); 26 | 27 | // Register it to be known 28 | if (unit->pCharacterData) 29 | SGM_SetCharacterKnown(unit->pCharacterData->number, &sgm); 30 | } 31 | 32 | SaveGeneralGameMetadata(&sgm); 33 | } 34 | 35 | void MSa_LoadUnits(void* source, unsigned size) { 36 | for (unsigned i = 0; i < 51; ++i) 37 | LoadSavedUnit(source + (0x24*i), GetUnit(i+1)); 38 | } 39 | 40 | void MSa_SaveBonusClaim(void* target, unsigned size) { 41 | WriteAndVerifySramFast((void*)(0x0203EDB4), target, size); 42 | } 43 | 44 | void MSa_LoadBonusClaim(void* source, unsigned size) { 45 | ReadSramFast(source, (void*)(0x0203EDB4), size); 46 | } 47 | 48 | void MSa_SaveWMStuff(void* target, unsigned size) { 49 | SaveWMStuff(target, &gGMData); 50 | } 51 | 52 | void MSa_LoadWMStuff(void* source, unsigned size) { 53 | LoadWMStuff(source, &gGMData); 54 | } 55 | 56 | void MSa_SaveDungeonState(void* target, unsigned size) { 57 | WriteAndVerifySramFast((void*)(0x30017AC), target, size); 58 | } 59 | 60 | void MSa_LoadDungeonState(void* source, unsigned size) { 61 | ReadSramFast(source, (void*)(0x30017AC), size); 62 | } 63 | -------------------------------------------------------------------------------- /Wizardry/ExpandedModularSave/Src/ModularSave.h: -------------------------------------------------------------------------------- 1 | #ifndef MODULAR_SAVE_H 2 | #define MODULAR_SAVE_H 3 | 4 | #include "gbafe.h" 5 | 6 | struct SaveBlockDecl { 7 | /* 00 */ u16 offset; 8 | /* 02 */ u16 type; 9 | }; 10 | 11 | struct SaveChunkDecl { 12 | /* 00 */ u16 offset; 13 | /* 02 */ u16 size; 14 | 15 | /* 04 */ void (*save)(void* target, unsigned size); 16 | /* 08 */ void (*load)(void* source, unsigned size); 17 | 18 | /* 0C */ u16 identifier; 19 | }; 20 | 21 | extern const u8 gMS_ChapterStateChunkId; 22 | extern const u8 gMS_BWLChunkId; 23 | extern const u8 gMS_PermanentEidsChunkId; 24 | extern const u8 gMS_ClaimFlagsChunkId; 25 | extern const u8 gMS_WMDataChunkId; 26 | 27 | extern const struct SaveBlockDecl gSaveBlockDecl[]; 28 | extern const u16 gSaveBlockTypeSizeLookup[]; 29 | 30 | extern const struct SaveChunkDecl gGameSaveChunks[]; 31 | extern const struct SaveChunkDecl gSuspendSaveChunks[]; 32 | 33 | void* MS_GetSaveAddressBySlot(unsigned slot); 34 | const struct SaveChunkDecl* MS_FindGameSaveChunk(unsigned chunkId); 35 | const struct SaveChunkDecl* MS_FindSuspendSaveChunk(unsigned chunkId); 36 | void MS_LoadChapterStateFromGameSave(unsigned slot, struct ChapterState* target); 37 | u32 MS_GetClaimFlagsFromGameSave(unsigned slot); 38 | 39 | // TODO: add to libgbafe 40 | 41 | void SaveUnit(struct Unit* unit, void* target) __attribute__((long_call)); 42 | void LoadSavedUnit(void* source, struct Unit* unit) __attribute__((long_call)); 43 | 44 | void SaveWMStuff(void*, void*) __attribute__((long_call)); 45 | void LoadWMStuff(void*, void*) __attribute__((long_call)); 46 | 47 | void StoreRNStateToActionStruct(void) __attribute__((long_call)); 48 | void LoadRNStateFromActionStruct(void) __attribute__((long_call)); 49 | 50 | // Those aren't consistent: 51 | // the packing function works with a buffer 52 | // But the unpacking functions loads from SRAM directly 53 | void PackUnitStructForSuspend(struct Unit* unit, void* target) __attribute__((long_call)); 54 | void UnpackUnitStructFromSuspend(void* source, struct Unit* unit) __attribute__((long_call)); 55 | 56 | void SetBonusContentClaimFlags(u32 value) __attribute__((long_call)); 57 | 58 | int GetNextSuspendSaveId(void); 59 | void UpdateNextSuspendSaveId(void); 60 | 61 | #endif // MODULAR_SAVE_H 62 | -------------------------------------------------------------------------------- /Wizardry/FerryAi/FerryAi.event: -------------------------------------------------------------------------------- 1 | #ifndef FERRYAI_INCLUDED 2 | #define FERRYAI_INCLUDED 3 | 4 | // Ferrying Ai 5 | // hack by Stan 6 | 7 | // HOW IT WORKS: 8 | // A unit with "Ferry Ai1" will seek (allied) units that are rescuing some other unit, and take that unit from them 9 | // Once the ferry unit is rescuing a unit, they will seek the closest unobstructed "drop point" and try to drop their rescued unit there 10 | // "drop points" are definied dynamically at runtime (it's stored in trap data). The following functions are provided to the user for that purpose: 11 | 12 | /* 13 | * void FerryAddDropTile(int x, int y) :: registers drop tile at given coordinates 14 | * ASMC_AddFerryDropTile :: for use with ASMC: adds drop tile at coordinates in sB 15 | * ASMC_AddFerryDropTiles :: for use with ASMC: adds drop tiles given list of short pairs at address in s2 (list is terminated when x < 0) 16 | */ 17 | 18 | #ifndef AIPERFORMEXT_INCLUDED 19 | 20 | ERROR "FerryAi requires AiPerformExtension!" 21 | 22 | #else 23 | 24 | #ifndef FERRY_TAKE_PERFORM 25 | #define FERRY_TAKE_PERFORM 14 26 | #endif // FERRY_TAKE_PERFORM 27 | 28 | #ifndef FERRY_DROP_PERFORM 29 | #define FERRY_DROP_PERFORM 15 30 | #endif 31 | 32 | #ifndef FERRY_TRAP_ID 33 | #define FERRY_TRAP_ID 0xEF 34 | #endif // FERRY_TRAP_ID 35 | 36 | #ifndef FERRY_AI1 37 | #define FERRY_AI1 10 38 | #endif // FERRY_AI1 39 | 40 | #include "AiScrDefinitions.event" 41 | 42 | gFerryTakePerformId: BYTE FERRY_TAKE_PERFORM 43 | gFerryDropPerformId: BYTE FERRY_DROP_PERFORM 44 | 45 | gFerryDataTrapId: BYTE FERRY_TRAP_ID 46 | 47 | gFerryAi1: BYTE FERRY_AI1 48 | 49 | #include "Src/FerryAi.lyn.event" 50 | 51 | InjectAiPerformer(FERRY_TAKE_PERFORM, FerryPerformTake) 52 | InjectAiPerformer(FERRY_DROP_PERFORM, FerryPerformDrop) 53 | 54 | ALIGN 4 55 | FerryAiScr: 56 | { 57 | AiFunc(FerryCheckIsRescuing) 58 | AiGotoIfEQ(1, 0) 59 | AiGotoIfEQ(2, 1) 60 | AiRestart 61 | 62 | AiLabel(1) 63 | AiFunc(FerryTryTakeInRangeOrMove) 64 | AiRestart 65 | 66 | AiLabel(2) 67 | AiFunc(FerryTryDropInRangeOrMove) 68 | AiRestart 69 | 70 | } 71 | 72 | InjectAi1(FERRY_AI1, FerryAiScr) 73 | 74 | #endif // AIPERFORMEXT_INCLUDED 75 | 76 | #endif // FERRYAI_INCLUDED 77 | -------------------------------------------------------------------------------- /Wizardry/FixDifficulty/FixDifficulty.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_FIXDIFFICULTY 2 | #define HAX_FIXDIFFICULTY 3 | 4 | // Skip difficulty select screen and use fixed difficulty instead 5 | // hack by Stan 6 | 7 | // Usage: 8 | // define DIFFICULTY as either 0 (easy), 1 (normal) or 2 (difficult) before including this file 9 | // If not defined, DIFFICULTY will default to 1 (normal). 10 | 11 | // For details, see also the original thread: 12 | // https://feuniverse.us/t/fe8-skip-the-difficulty-selection-defaulting-to-a-set-one/2927?u=stanh 13 | 14 | #ifndef DIFFICULTY 15 | #define DIFFICULTY 1 16 | #endif // DIFFICULTY 17 | 18 | PUSH 19 | 20 | // Replace called routine in savemenu proc 21 | ORG 0xA20164 22 | POIN FixDifficultyHook|1 23 | 24 | POP 25 | 26 | ALIGN 4 27 | FixDifficultyHook: 28 | SHORT (0x2200 | DIFFICULTY) // Difficulty: 0 for easy, 1 for normal, 2 for hard 29 | SHORT (0x2300 | 0) // This may be starting mode? 30 | WORD 0x5442212A 0x5443213D 0x46C04770 31 | 32 | #endif // HAX_FIXDIFFICULTY 33 | -------------------------------------------------------------------------------- /Wizardry/IncorrectBlitzInput/IncorrectBlitzInput.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_SABINMEME 2 | #define HAX_SABINMEME 3 | 4 | { 5 | 6 | PUSH; ORG $58C60 7 | POIN IBIHook 8 | POP 9 | 10 | #include "src/IBIHook.lyn.event" 11 | #include "src/IBIMain.lyn.event" 12 | 13 | BlitzerCharacterIndices: 14 | BYTE Eirika 0 15 | 16 | ALIGN 4 17 | gGfx_FF6Window: 18 | #incbin "res/Window.4bpp.lz" 19 | 20 | ALIGN 4 21 | gPal_FF6Window: 22 | #incbin "res/Window.gbapal" 23 | 24 | } 25 | 26 | #endif // HAX_SABINMEME 27 | -------------------------------------------------------------------------------- /Wizardry/IncorrectBlitzInput/res/Window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/IncorrectBlitzInput/res/Window.png -------------------------------------------------------------------------------- /Wizardry/IncorrectBlitzInput/src/IBIHook.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | .global IBIHook 4 | .type IBIHook, %function 5 | 6 | ReturnLocation = 0x08059048 + 1 7 | 8 | IBIHook: 9 | mov r0, r7 10 | 11 | ldr r3, =IBICheck 12 | bl BXR3 13 | 14 | ldr r3, =ReturnLocation 15 | 16 | BXR3: 17 | bx r3 18 | -------------------------------------------------------------------------------- /Wizardry/LazberianBattleFlow/LazberianBattleFlow.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_LBF 2 | #define HAX_LBF 3 | 4 | #include "Src/LBF.lyn.event" 5 | 6 | #ifdef BattleBufferWidth 7 | gLbfBattleHitLen: BYTE BattleBufferWidth 8 | #else 9 | gLbfBattleHitLen: BYTE 4 10 | #endif 11 | 12 | ALIGN 4 13 | gPlusItemAttribute: 14 | WORD WA_LBF_PLUS 15 | 16 | PUSH 17 | // I'm too lazy to manage displaying x2/x4 in preview differently so I'll just disable all of that 18 | ORG $036F4C 19 | SHORT $4770 // bx lr 20 | POP 21 | 22 | #endif // HAX_LBF 23 | -------------------------------------------------------------------------------- /Wizardry/LazberianBattleFlow/Src/LBF.c: -------------------------------------------------------------------------------- 1 | 2 | #include "gbafe.h" 3 | 4 | void ClearBattleHits(void); 5 | void BattleGetBattleUnitOrder(struct BattleUnit** outAttacker, struct BattleUnit** outDefender); 6 | s8 BattleGenerateRoundHits(struct BattleUnit* attacker, struct BattleUnit* defender); 7 | 8 | static int CheckNonMiss(struct BattleHit const* begin, struct BattleHit const* end); 9 | static int GetPlus(struct BattleUnit const* attacker, struct BattleUnit const* defender); 10 | static struct BattleHit const* IncBattleHitIt(struct BattleHit const* it); 11 | 12 | extern u32 const gPlusItemAttribute; 13 | extern u8 const gLbfBattleHitLen; 14 | 15 | //! Should replace function at FE8U:0802AED0 16 | void BattleUnwind(void) 17 | { 18 | ClearBattleHits(); 19 | 20 | struct BattleUnit* attacker; 21 | struct BattleUnit* defender; 22 | 23 | BattleGetBattleUnitOrder(&attacker, &defender); 24 | 25 | gBattleHitIterator->info |= BATTLE_HIT_INFO_BEGIN; 26 | 27 | int attackerPlus = GetPlus(attacker, defender); 28 | int defenderPlus = GetPlus(defender, attacker); 29 | 30 | while (attackerPlus > 0) 31 | { 32 | struct BattleHit* it = gBattleHitIterator; 33 | 34 | if (BattleGenerateRoundHits(attacker, defender)) 35 | break; 36 | 37 | if (defenderPlus > 0) 38 | { 39 | if (!CheckNonMiss(it, gBattleHitIterator)) 40 | { 41 | gBattleHitIterator->attributes |= BATTLE_HIT_ATTR_RETALIATE; 42 | 43 | if (BattleGenerateRoundHits(defender, attacker)) 44 | break; 45 | } 46 | 47 | defenderPlus--; 48 | } 49 | 50 | attackerPlus--; 51 | } 52 | 53 | gBattleHitIterator->info |= BATTLE_HIT_INFO_END; 54 | } 55 | 56 | static int CheckNonMiss(struct BattleHit const* begin, struct BattleHit const* end) 57 | { 58 | for (struct BattleHit const* it = begin; it != end; it = IncBattleHitIt(it)) 59 | { 60 | if (it->attributes & BATTLE_HIT_ATTR_MISS) 61 | continue; 62 | 63 | return TRUE; 64 | } 65 | 66 | return FALSE; 67 | } 68 | 69 | static int GetPlus(struct BattleUnit const* attacker, struct BattleUnit const* defender) 70 | { 71 | return (attacker->weaponAttributes & gPlusItemAttribute) && (attacker->battleSpeed > defender->battleSpeed) ? 2 : 1; 72 | } 73 | 74 | static struct BattleHit const* IncBattleHitIt(struct BattleHit const* it) 75 | { 76 | return it + (gLbfBattleHitLen/4); 77 | } 78 | -------------------------------------------------------------------------------- /Wizardry/LazberianMercenaries/Data/CoinBit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/LazberianMercenaries/Data/CoinBit.png -------------------------------------------------------------------------------- /Wizardry/LazberianMercenaries/LazberianMercenaries.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_LM 2 | #define HAX_LM 3 | 4 | // Definitions 5 | 6 | #ifndef US_LM_HIRED 7 | // Unit State Flag defintion 8 | #define US_LM_HIRED 0x40000000 9 | #endif // US_LM_HIRED 10 | 11 | #ifndef CA_LM_MERCENARY 12 | // Unit Class/Char Attribute flag deftinion 13 | #define CA_LM_MERCENARY 0x40000000 14 | #endif // CA_LM_MERCENARY 15 | 16 | // Graphics 17 | 18 | ALIGN 4 19 | gPal_LmCoinBit: 20 | #incbin "Data/CoinBit.gbapal" 21 | 22 | ALIGN 4 23 | gImg_LmCoinBit: 24 | #incbin "Data/CoinBit.4bpp" 25 | 26 | // ======================== 27 | // = INTERNALS START HERE = 28 | // ======================== 29 | 30 | // (it means avoid touching unless you know what you're doing) 31 | 32 | #ifndef LynJumpDefined 33 | #define LynJumpDefined 34 | #define LynJump(aTarget) "WORD $46C04778 $E59FC000 $E12FFF1C; POIN aTarget; " 35 | #endif // LynJumpDefined 36 | 37 | #include "Src/LM.lyn.event" 38 | #include "Src/LMHooks.lyn.event" 39 | 40 | ALIGN 4 41 | PUSH; ORG CURRENTOFFSET+1; GetUnitDeployCost:; POP 42 | #incbin "Src/GetUnitDeployCost.dmp" 43 | 44 | ALIGN 4 45 | gUsHiredFlag: 46 | WORD US_LM_HIRED 47 | 48 | ALIGN 4 49 | gCaMercenary: 50 | WORD CA_LM_MERCENARY 51 | 52 | { 53 | 54 | ALIGN 4 55 | gProcHook_PrepScreen: 56 | PROC_SET_DESTRUCTOR(LM_OnPrepScreenEnd) 57 | PROC_SLEEP(0x10) 58 | PROC_JUMP($59DBCC) 59 | 60 | PUSH 61 | 62 | ORG $09ACB8 // select unit in prep screen hook 63 | LynJump(LMHook0809ACB8) 64 | 65 | ORG $59DBC4 66 | PROC_JUMP(gProcHook_PrepScreen) 67 | 68 | // ORG $09A5F0 // display unit name in prep screen hook 69 | // LynJump(LMHook0809A5F0) 70 | 71 | ORG $09A874 // load coin graphics 72 | LynJump(LMHook0809A874) 73 | 74 | ORG $09A68C // display for hire icon in prep screen hook 75 | LynJump(LMHook0809A68C) 76 | 77 | ORG $0957D8 // overwrite automatic deployment to only deploy force deployed units 78 | LynJump(LMHook080957D8) 79 | 80 | ORG $0854E0 // do not clear hired status here (otherwise you could hire a unit, save, reload and it clean the hired status) 81 | WORD (0x671E00C | US_LM_HIRED) 82 | 83 | // ORG $09AAF0 84 | // LynJump(LMReplace_809AAF0) 85 | 86 | // ORG $09A85A // may not need that 87 | // BYTE 16 // more room for more text 88 | 89 | POP 90 | 91 | } 92 | 93 | #endif // HAX_LM 94 | -------------------------------------------------------------------------------- /Wizardry/LazberianMercenaries/Src/GetUnitDeployCost.s: -------------------------------------------------------------------------------- 1 | 2 | .thumb 3 | 4 | GetUnitDeployCost: 5 | @ arg r0 = unit 6 | 7 | @ this currently returns 8 | @ unit->pow*4 + unit->res*4 + unit->spd*4 + unit->def*4 + unit->hpMax*2 + unit->lck*2 + unit->skl*2 9 | 10 | @ feel free to edit as you see fit 11 | 12 | mov r1, #0x12 13 | ldsb r1, [r0, r1] @ r1 = unit->hpMax 14 | lsl r2, r1, #1 @ result = unit->hpMax*2 15 | 16 | mov r1, #0x14 17 | ldsb r1, [r0, r1] @ r1 = unit->str 18 | lsl r1, #2 @ r1 = unit->str*4 19 | add r2, r1 @ result += unit->str*4 20 | 21 | mov r1, #0x15 22 | ldsb r1, [r0, r1] @ r1 = unit->skl 23 | lsl r1, #1 @ r1 = unit->skl*2 24 | add r2, r1 @ result += unit->skl*2 25 | 26 | mov r1, #0x16 27 | ldsb r1, [r0, r1] @ r1 = unit->spd 28 | lsl r1, #2 @ r1 = unit->spd*4 29 | add r2, r1 @ result += unit->spd*4 30 | 31 | mov r1, #0x17 32 | ldsb r1, [r0, r1] @ r1 = unit->def 33 | lsl r1, #2 @ r1 = unit->def*4 34 | add r2, r1 @ result += unit->def*4 35 | 36 | mov r1, #0x18 37 | ldsb r1, [r0, r1] @ r1 = unit->res 38 | lsl r1, #2 @ r1 = unit->res*4 39 | add r2, r1 @ result += unit->res*4 40 | 41 | mov r1, #0x19 42 | ldsb r1, [r0, r1] @ r1 = unit->lck 43 | lsl r1, #1 @ r1 = unit->lck*2 44 | add r2, r1 @ result += unit->lck*2 45 | 46 | mov r0, r2 @ result r0 = result 47 | bx lr @ return 48 | 49 | .pool 50 | .align 51 | -------------------------------------------------------------------------------- /Wizardry/LazberianTurnFlow/Data/TurnSwitchSheet-Test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/LazberianTurnFlow/Data/TurnSwitchSheet-Test.png -------------------------------------------------------------------------------- /Wizardry/LazberianTurnFlow/Data/TurnSwitchSheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/LazberianTurnFlow/Data/TurnSwitchSheet.png -------------------------------------------------------------------------------- /Wizardry/LazberianTurnFlow/Extensions/ProcDefinitions.txt: -------------------------------------------------------------------------------- 1 | #ifndef HAX_PROC_DEFINITIONS_EVENT 2 | #define HAX_PROC_DEFINITIONS_EVENT 3 | 4 | // proc Definitions for writing proc code 5 | 6 | #define PROC_END "SHORT 0x00 0 0 0" 7 | #define PROC_SET_NAME(apsNamePointer) "SHORT 0x01 0; POIN apsNamePointer" 8 | #define PROC_CALL_ROUTINE(aprRoutine) "SHORT 0x02 0; POIN aprRoutine" 9 | #define PROC_LOOP_ROUTINE(aprRoutine) "SHORT 0x03 0; POIN aprRoutine" 10 | #define PROC_SET_DESTRUCTOR(aprRoutine) "SHORT 0x04 0; POIN aprRoutine" 11 | #define PROC_NEW_CHILD(ap6CChild) "SHORT 0x05 0; POIN ap6CChild" 12 | #define PROC_NEW_CHILD_BLOCKING(ap6CChild) "SHORT 0x06 1; POIN ap6CChild" 13 | #define PROC_NEW_MAIN_BUGGED(ap6CMain) "SHORT 0x07 0; POIN ap6CMain" 14 | #define PROC_WHILE_EXISTS(ap6CToCheck) "SHORT 0x08 0; POIN ap6CToCheck" 15 | #define PROC_END_ALL(ap6CToCheck) "SHORT 0x09 0; POIN ap6CToCheck" 16 | #define PROC_BREAK_ALL_LOOP(ap6CToCheck) "SHORT 0x0A 0; POIN ap6CToCheck" 17 | #define PROC_LABEL(aLabelId) "SHORT 0x0B aLabelId 0 0" 18 | #define PROC_GOTO(aLabelId) "SHORT 0x0C aLabelId 0 0" 19 | #define PROC_JUMP(ap6CCode) "SHORT 0x0D 0; POIN ap6CCode" 20 | #define PROC_SLEEP(aTime) "SHORT 0x0E aTime 0 0" 21 | #define PROC_SET_MARK(aMark) "SHORT 0x0F aMark 0 0" 22 | #define PROC_BLOCK "SHORT 0x10 0 0 0" 23 | #define PROC_END_IF_DUPLICATE "SHORT 0x11 0 0 0" 24 | #define PROC_SET_BIT4 "SHORT 0x12 0 0 0" 25 | #define PROC_13 "SHORT 0x13 0 0 0" 26 | #define PROC_WHILE_ROUTINE(aprRoutine) "SHORT 0x14 0; POIN aprRoutine" 27 | #define PROC_15 "SHORT 0x15 0 0 0" 28 | #define PROC_CALL_ROUTINE_2(aprRoutine) "SHORT 0x16 0; POIN aprRoutine" 29 | #define PROC_END_DUPLICATES "SHORT 0x17 0 0 0" 30 | #define PROC_CALL_ROUTINE_ARG(aprRoutine, aArgument) "SHORT 0x18 aArgument; POIN aprRoutine" 31 | #define PROC_19 "SHORT 0x19 0 0 0" 32 | 33 | #define PROC_YEILD "PROC_SLEEP(0)" 34 | 35 | #endif // HAX_PROC_DEFINITIONS_EVENT 36 | -------------------------------------------------------------------------------- /Wizardry/LazberianTurnFlow/LazberianTurnFlow.event: -------------------------------------------------------------------------------- 1 | #ifndef LTF_INCLUDED 2 | #define LTF_INCLUDED 3 | 4 | #include "LTF-Internals.event" 5 | 6 | // Edit this file if you want LTF enabling logic to be different 7 | // By default, it checks if the current chapter id is in gLTFChapterEnableList. 8 | 9 | #include "SrcUser/IsLtfEnabled.lyn.event" 10 | 11 | gLTFChapterEnableList: 12 | BYTE 0 13 | BYTE 0xFF // end 14 | 15 | // Those are the graphics for the turn change effect 16 | // Feel free to edit those (you probably should) 17 | 18 | ALIGN 4 19 | gLTFTurnSwitchSheetImg: 20 | #incbin "Data/TurnSwitchSheet.4bpp.lz" 21 | 22 | ALIGN 4 23 | gLTFTurnSwitchSheetPal: 24 | #incbin "Data/TurnSwitchSheet.gbapal" 25 | 26 | // BIG-STUFF-TO-DO-AND-TO-FIX-LIST-THING: 27 | 28 | // Done: Only one action per player phase 29 | // Done: Have CPPHASE only do one unit 30 | // Done: Not reset unit state on phase switch 31 | // Done: Phase switch depends on units left to move 32 | // Done: Redo the AI to do things in a less stupid order 33 | // Fixed: Player phase leaves active unit map sprite hidden for a few frames too long 34 | // Done: Not display phase switch screen effect unless this is new turn 35 | // Done: Display the things! 36 | // WontDo: Display "E"s instead of graying the units out (ala Berwick) 37 | // Done: Allow holding (R) to display non-grayed out map sprites 38 | // Done: Wait command ends the turn of every player unit 39 | // Done: Turn events always trigger regarless of phase 40 | // Done: Update status effects for *everyone* on turn change 41 | // Done: Properly update traps on turn change 42 | // Fixed: Cursor jumps around after AI phase 43 | // Done: Account for Berserk Phase somehow 44 | // Done: Redo the Berserk AI in the same way the regular AI was redone 45 | // Done: Autocursor takes the first unit *that hasn't moved yet* 46 | // Fixed: Autocursor Off is broken 47 | // Done: Restore the additional AI behaviors (escaping/lockpicking) 48 | // Fixed: some AI2 seem broken 49 | // Done: Not display predictions sometimes (during cutscenes/menus/etc?) 50 | // Done: Not move camera to enemy before each enemy move 51 | // Done: Change phase switch screen effect to show something like "TURN xyz" instead of "PLAYER PHASE" 52 | // Fixed: Turn switch blend doesn't work on sprites, resulting in weirdities. (fixed by using bg1 for blend instead of objs). 53 | // Fixed: Turn starts at 0 54 | // Fixed: Turn order display doesn't update during turn transition 55 | // Done: LTF is now toggleable on a per chapter basis 56 | 57 | // Todo: Test 58 | 59 | // KNOWN ISSUES: 60 | // AI can take its time to make a decision 61 | 62 | #endif // LTF_INCLUDED 63 | -------------------------------------------------------------------------------- /Wizardry/LazberianTurnFlow/Src/LTF-Toggleable.c: -------------------------------------------------------------------------------- 1 | 2 | #include "LTF.h" 3 | 4 | // I'm just borrowing padding between sections 5 | #define gLTFEnableFlag (*((u8*)(0x03000006))) 6 | 7 | extern const struct ProcInstruction LTFPlayerPhaseProcHook[]; 8 | 9 | extern const u8 gLTFChapterEnableList[]; 10 | 11 | void LTFT_UpdateLTFEnable(void) 12 | { 13 | gLTFEnableFlag = IsLtfEnabled(); 14 | } 15 | 16 | int LTFT_IsActiveNow(void) 17 | { 18 | return !!gLTFEnableFlag; //return !!CheckEventId(gLTFEnableFlag); 19 | } 20 | 21 | void LTFT_PlayerPhaseEndHook(struct Proc* proc) 22 | { 23 | if (LTFT_IsActiveNow()) 24 | Proc_JumpToPointer(proc, LTFPlayerPhaseProcHook); 25 | else 26 | ProcGoto(proc, 0); 27 | } 28 | 29 | void LTFT_CpDecideLoopCheck(struct Proc* proc) 30 | { 31 | if (!LTFT_IsActiveNow()) 32 | ProcGoto(proc, 0); 33 | } 34 | -------------------------------------------------------------------------------- /Wizardry/LazberianTurnFlow/Src/LTF.h: -------------------------------------------------------------------------------- 1 | #ifndef LTF_H 2 | #define LTF_H 3 | 4 | #include "gbafe.h" 5 | 6 | // TODO: I can't believe I don't have that in CLib 7 | s8 CheckEventId(int id); 8 | 9 | // config 10 | 11 | enum 12 | { 13 | // maximum number of moves to predict 14 | LTF_DISPLAY_MAX_COUNT = 5, 15 | 16 | // display offsets relative to right of screen and transition speed 17 | LTF_DISPLAY_XOFF = 5, // (offset / speed) 18 | LTF_DISPLAY_XOFF_STEP = 2, // speed 19 | }; 20 | 21 | // provided by user 22 | 23 | int IsLtfEnabled(void); 24 | 25 | // in LTFCore.c 26 | 27 | unsigned LTF_IsUnitReadyToMove(const struct Unit*); 28 | unsigned LTF_IsUnitAbleToMove(const struct Unit*); 29 | 30 | unsigned LTF_GetPhaseEffectiveUnitCount(unsigned phase); 31 | unsigned LTF_GetPhaseAbleUnitCount(unsigned phase); 32 | 33 | unsigned LTF_GetBerserkEffectiveUnitCount(void); 34 | unsigned LTF_GetBerserkAbleUnitCount(void); 35 | 36 | unsigned LTF_PredictNextPhase(const unsigned ableCounts[4], const unsigned maxCounts[4]); 37 | 38 | // in LTFPhaseSwitch.c 39 | 40 | void LTF_ResetUnitsStateForTurnSwitch(void); 41 | int LTF_GotoNextTurn(struct Proc* mapMainProc); 42 | int LTF_MapMainPhaseSwitch(struct Proc* mapMainProc); 43 | 44 | // in LTFDisplay.c 45 | 46 | void LTF_StartPredictionDisplay(struct Proc* parent); 47 | void LTF_UpdatePredictionDisplay(void); 48 | 49 | void LTF_EnablePredictionDisplay(void); 50 | void LTF_DisablePredictionDisplay(void); 51 | 52 | // in LTFTurnSwitchFx.c 53 | 54 | extern 55 | const struct ProcInstruction gProc_TurnSwitchFx[]; 56 | 57 | #endif // LTF_H 58 | -------------------------------------------------------------------------------- /Wizardry/LazberianTurnFlow/Src/LTFAutocursor.c: -------------------------------------------------------------------------------- 1 | #include "LTF.h" 2 | 3 | static struct Unit* LTF_GetAutocursorUnit(unsigned phase) 4 | { 5 | for (unsigned index = (phase + 1); index < (phase + 0x40); ++index) 6 | { 7 | struct Unit* unit = GetUnit(index); 8 | 9 | if (!UNIT_IS_VALID(unit)) 10 | continue; 11 | 12 | if (unit->statusIndex == UNIT_STATUS_BERSERK) 13 | continue; 14 | 15 | if (LTF_IsUnitReadyToMove(unit)) 16 | return unit; 17 | } 18 | 19 | return NULL; 20 | } 21 | 22 | void LTF_InitCursorMemory(void) 23 | { 24 | struct Unit* unit = LTF_GetAutocursorUnit(UA_BLUE); 25 | 26 | if (unit) 27 | { 28 | gChapterData.xCursorSaved = unit->xPos; 29 | gChapterData.yCursorSaved = unit->yPos; 30 | } 31 | else 32 | { 33 | gChapterData.xCursorSaved = gMapSize.x / 2; 34 | gChapterData.yCursorSaved = gMapSize.y / 2; 35 | } 36 | } 37 | 38 | // NOTE: REPLACES VANILLA FUNCTION 39 | void GetPlayerStartCursorPosition(int* xOut, int* yOut) 40 | { 41 | if (!gChapterData.autocursorOption) // autocursorOption == 1 => autocursor OFF 42 | { 43 | struct Unit* unit = LTF_GetAutocursorUnit(gChapterData.currentPhase); 44 | 45 | if (unit) 46 | { 47 | *xOut = unit->xPos; 48 | *yOut = unit->yPos; 49 | 50 | return; 51 | } 52 | } 53 | 54 | *xOut = gChapterData.xCursorSaved; 55 | *yOut = gChapterData.yCursorSaved; 56 | } 57 | -------------------------------------------------------------------------------- /Wizardry/LazberianTurnFlow/Src/LTFEndPlayerPhase.c: -------------------------------------------------------------------------------- 1 | #include "LTF.h" 2 | 3 | // NOTE: REPLACES VANILLA FUNCTION 4 | int MapMenuCommnd_EndEffect(struct MenuProc* menu, struct MenuCommandProc* command) 5 | { 6 | unsigned phase = gChapterData.currentPhase; // Not hardcoding to PlayerPhase in case of enemy control 7 | 8 | for (unsigned index = phase + 1; index < phase + 0x40; ++index) 9 | { 10 | struct Unit* unit = GetUnit(index); 11 | 12 | if (UNIT_IS_VALID(unit) && (unit->statusIndex != UNIT_STATUS_BERSERK)) 13 | unit->state |= (US_UNSELECTABLE | US_HAS_MOVED); 14 | } 15 | 16 | EndEachProc(gProc_PlayerPhase); 17 | 18 | return (ME_CLEAR_GFX | ME_DISABLE | ME_PLAY_BEEP | ME_END); 19 | } 20 | -------------------------------------------------------------------------------- /Wizardry/LazberianTurnFlow/Src/LTFHooks.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | @ This file contains any LTF hacks that doesn't involve simply replacing pointers to functions 4 | @ Aka complex hooks; Aka the hard part 5 | 6 | .global LTFHook_InDisableBattleMapGfx 7 | 8 | LTFHook_InDisableBattleMapGfx: 9 | @ Hook with jumpToHack at FE8U:08030198 10 | 11 | @ known state: 12 | @ r0 = 0 13 | @ r1 = gGameState 14 | 15 | ldr r1, =gPaletteBuffer 16 | strh r0, [r1] @ gPaletteBuffer[0] = 0; 17 | 18 | @ implicit @ arg r0 = func ptr 19 | 20 | ldr r3, =SetSecondaryHBlankCallback 21 | bl BXR3 22 | 23 | ldr r3, =EnablePaletteSync 24 | bl BXR3 25 | 26 | mov r0, #1 @ arg r0 = Mark 27 | 28 | ldr r3, =ProcHaltEachMarked 29 | bl BXR3 30 | 31 | ldr r3, =LTF_DisablePredictionDisplay 32 | bl BXR3 33 | 34 | pop {r3} 35 | BXR3: 36 | bx r3 37 | 38 | .global LTFHook_InRestoreBattleMapGfx 39 | 40 | LTFHook_InRestoreBattleMapGfx: 41 | @ Hook with jumpToHack at FE8U:080301D0 42 | 43 | mov r0, #1 44 | 45 | ldr r3, =ProcResumeEachMarked 46 | bl BXR3 47 | 48 | ldr r0, =gProc_VBlankHandler 49 | 50 | ldr r3, =ProcFind 51 | bl BXR3 52 | 53 | cmp r0, #0 54 | beq LTFHook_InRestoreBattleMapGfx.end 55 | 56 | ldr r3, =EndProc 57 | bl BXR3 58 | 59 | ldr r3, =StartGameVBlankProc 60 | bl BXR3 61 | 62 | ldr r3, =LTF_EnablePredictionDisplay 63 | bl BXR3 64 | 65 | LTFHook_InRestoreBattleMapGfx.end: 66 | pop {r0} 67 | bx r0 68 | -------------------------------------------------------------------------------- /Wizardry/LazberianTurnFlow/Src/LTFMapSprite.c: -------------------------------------------------------------------------------- 1 | #include "gbafe.h" 2 | 3 | static void LTFMapSprite_UpdateAllMapSpritePalettes(void); 4 | 5 | // NOTE: REPLACES VANILLA FUNCTION 6 | unsigned GetUnitBattleMapSpritePaletteIndex(struct Unit* unit) 7 | { 8 | if (unit->state & 0x8000000) 9 | return 0xB; // Link Arena palette 10 | 11 | if (!(gKeyState.heldKeys & KEY_BUTTON_R) && (unit->state & US_UNSELECTABLE)) 12 | return 0xF; 13 | 14 | return GetUnitMapSpritePaletteIndex(unit); 15 | } 16 | 17 | void LTFMapSprite_UpdateAllMapSpritePalettes(void) 18 | { 19 | for (unsigned index = 1; index < 0x100; ++index) 20 | { 21 | struct Unit* unit = GetUnit(index); 22 | 23 | if (!unit || !unit->pCharacterData) 24 | continue; 25 | 26 | if (!unit->pMapSpriteHandle) 27 | continue; 28 | 29 | struct SMSHandle* handle = unit->pMapSpriteHandle; 30 | 31 | handle->oam2Base &= ~(0xF000); 32 | handle->oam2Base |= GetUnitBattleMapSpritePaletteIndex(unit) << 12; 33 | } 34 | } 35 | 36 | void LTFMapSprite_UpdateAll(void) 37 | { 38 | if ((gKeyState.heldKeys ^ gKeyState.prevKeys) & (KEY_BUTTON_R)) 39 | LTFMapSprite_UpdateAllMapSpritePalettes(); 40 | 41 | SMS_DisplayAllFromInfoStructs(); 42 | } 43 | -------------------------------------------------------------------------------- /Wizardry/LazberianTurnFlow/Src/LTFPhaseSwitch.c: -------------------------------------------------------------------------------- 1 | #include "LTF.h" 2 | 3 | extern unsigned GetPhaseAbleUnitCount(unsigned phase) __attribute__((long_call)); 4 | extern void ProcessSupportGains(void) __attribute__((long_call)); 5 | extern s8 RunPhaseSwitchEvents(void) __attribute__((long_call)); 6 | 7 | void LTF_ResetUnitsStateForTurnSwitch(void) 8 | { 9 | for (unsigned index = 1; index < 0x100; ++index) 10 | { 11 | struct Unit* unit = GetUnit(index); 12 | 13 | if (UNIT_IS_VALID(unit)) 14 | unit->state &= ~(US_UNSELECTABLE | US_HAS_MOVED | US_HAS_MOVED_AI); 15 | } 16 | } 17 | 18 | int LTF_GotoNextTurn(struct Proc* mapMainProc) 19 | { 20 | if (gChapterData.turnNumber < 999) 21 | gChapterData.turnNumber++; 22 | 23 | SMS_UpdateFromGameData(); 24 | 25 | ProcGoto(mapMainProc, 9); // goto turn start 26 | 27 | if (RunPhaseSwitchEvents()) 28 | return 0; // Events are running, proc yield 29 | 30 | return 1; 31 | } 32 | 33 | int LTF_MapMainPhaseSwitch(struct Proc* mapMainProc) 34 | { 35 | const unsigned maxCounts[4] = 36 | { 37 | LTF_GetPhaseEffectiveUnitCount(UA_BLUE), 38 | LTF_GetPhaseEffectiveUnitCount(UA_GREEN), 39 | LTF_GetPhaseEffectiveUnitCount(UA_RED), 40 | LTF_GetBerserkEffectiveUnitCount(), 41 | }; 42 | 43 | const unsigned ableCounts[4] = 44 | { 45 | LTF_GetPhaseAbleUnitCount(UA_BLUE), 46 | LTF_GetPhaseAbleUnitCount(UA_GREEN), 47 | LTF_GetPhaseAbleUnitCount(UA_RED), 48 | LTF_GetBerserkAbleUnitCount(), 49 | }; 50 | 51 | LTF_UpdatePredictionDisplay(); 52 | 53 | if ((ableCounts[0] == 0) && (ableCounts[1] == 0) && (ableCounts[2] == 0) && (ableCounts[3] == 0)) 54 | return LTF_GotoNextTurn(mapMainProc); 55 | 56 | SMS_UpdateFromGameData(); 57 | 58 | unsigned nextPhase = LTF_PredictNextPhase(ableCounts, maxCounts); 59 | 60 | if (nextPhase == 3) 61 | ProcGoto(mapMainProc, 12); // goto berserk phase (new label! see LazberianTurnFlow.event) 62 | else 63 | gChapterData.currentPhase = nextPhase << 6; 64 | 65 | return 1; 66 | } 67 | -------------------------------------------------------------------------------- /Wizardry/LazberianTurnFlow/SrcUser/IsLtfEnabled.s: -------------------------------------------------------------------------------- 1 | 2 | .thumb 3 | 4 | .global IsLtfEnabled 5 | .type IsLtfEnabled, function 6 | 7 | IsLtfEnabled: 8 | @ INTERFACE: 9 | @ arguments: none 10 | @ returns: r0 = non-zero if LTF is enabled for the current chapter 11 | 12 | @ NOTE: this function is called when starting a chapter 13 | @ but also when resuming from a suspend save 14 | 15 | @ DEFAULT BEHAVIOR: checks if the current chapterid is in the 0xFF-terminated list of chapter ids at gLTFChapterEnableList. 16 | 17 | @ var r1 = current chapter id 18 | ldr r1, =gChapterData 19 | ldrb r1, [r1, #0x0E] @ ChapterState.chapterId 20 | 21 | @ var r3 = chapter list it 22 | ldr r3, =gLTFChapterEnableList 23 | 24 | lop: 25 | @ var r0 = chapter in list 26 | ldrb r0, [r3] 27 | 28 | @ return false if we reach terminator (0xFF) 29 | cmp r0, #0xFF 30 | beq return_false 31 | 32 | @ return true if chapter in list 33 | cmp r0, r1 34 | beq return_true 35 | 36 | @ increment it and lop 37 | add r3, #1 38 | b lop 39 | 40 | return_false: 41 | @ return 0 42 | movs r0, #0 43 | bx lr 44 | 45 | return_true: 46 | @ return 1 47 | movs r0, #1 48 | bx lr 49 | -------------------------------------------------------------------------------- /Wizardry/LazberianWeaponry/Data/DurabilityIcons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/LazberianWeaponry/Data/DurabilityIcons.png -------------------------------------------------------------------------------- /Wizardry/LazberianWeaponry/LazberianWeaponry.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_LW 2 | #define HAX_LW 3 | 4 | #ifndef HAX_ICONDISPLAY 5 | ERROR Lazberian Weaponry requires CIconDisplay 6 | #endif // HAX_ICONDISPLAY 7 | 8 | #ifndef LynJumpDefined 9 | #define LynJumpDefined 10 | #define LynJump(aTarget) "WORD $46C04778 $E59FC000 $E12FFF1C; POIN aTarget; " 11 | #endif // LynJumpDefined 12 | 13 | #include "Src/LW.lyn.event" 14 | #include "Src/LWHooks.lyn.event" 15 | 16 | PUSH 17 | 18 | ORG $09AAA8 19 | LynJump(LWHook0809AAA8) 20 | 21 | ORG $09A050 22 | LynJump(LWHook0809A050) 23 | 24 | ORG $09B7E4 25 | LynJump(LWHook0809B7E4) 26 | 27 | ORG $09D3DC 28 | LynJump(LWHook0809D3DC) 29 | 30 | ORG $034D00 31 | LynJump(LWHook08034D00) 32 | 33 | ORG $034DFC 34 | LynJump(LWHook08034DFC) 35 | 36 | ORG $034F1C 37 | LynJump(LWHook08034F1C) 38 | 39 | ORG $09D50C 40 | LynJump(LWHook0809D50C) 41 | 42 | POP 43 | 44 | gLwIconSheet: 45 | WORD LW_ICON_SHEET 46 | 47 | ALIGN 4 48 | gImg_DurabilityIcons: 49 | #incbin "Data/DurabilityIcons.4bpp" 50 | 51 | InjectIconSheet(LW_ICON_SHEET, gImg_DurabilityIcons) 52 | 53 | #endif // HAX_LW 54 | -------------------------------------------------------------------------------- /Wizardry/LazberianWeaponry/Src/LWHooks.s: -------------------------------------------------------------------------------- 1 | 2 | .thumb 3 | 4 | .global LWHook0809AAA8 5 | .type LWHook0809AAA8, function 6 | 7 | LWHook0809AAA8: 8 | ldr r3, =LW_DrawDurabilityRaw 9 | 10 | @ implied @ arg r0 = item 11 | mov r1, r5 @ arg r1 = color 12 | mov r2, r10 @ arg r2 = mapOut 13 | sub r2, #1 14 | 15 | bl BXR3 16 | 17 | @ replaced 18 | mov r0, #0x80 19 | 20 | ldr r3, =0x0809AAB8+1 21 | BXR3: 22 | bx r3 23 | 24 | .global LWHook0809A050 25 | .type LWHook0809A050, function 26 | 27 | LWHook0809A050: 28 | ldr r3, =LW_DrawDurabilityRaw 29 | 30 | mov r0, r5 @ arg r0 = item 31 | mov r1, r4 @ arg r1 = color 32 | ldr r2, [sp, #8] @ arg r2 = mapOut 33 | sub r2, #1 34 | 35 | bl BXR3 36 | 37 | ldr r3, =0x0809A060+1 38 | bx r3 39 | 40 | .global LWHook0809B7E4 41 | .type LWHook0809B7E4, function 42 | 43 | LWHook0809B7E4: 44 | ldr r3, =LW_DrawDurabilityRaw 45 | 46 | mov r0, r6 47 | mov r1, r7 48 | sub r2, r4, #1 49 | 50 | bl BXR3 51 | 52 | ldr r3, =0x0809B7F4+1 53 | bx r3 54 | 55 | .global LWHook0809D3DC 56 | .type LWHook0809D3DC, function 57 | 58 | LWHook0809D3DC: 59 | ldr r3, =LW_DrawDurabilityRaw 60 | 61 | mov r0, r7 62 | mov r1, r5 63 | sub r2, r4, #1 64 | 65 | bl BXR3 66 | 67 | ldr r3, =0x0809D3EC+1 68 | bx r3 69 | 70 | .global LWHook08034D00 71 | .type LWHook08034D00, function 72 | 73 | LWHook08034D00: 74 | ldr r3, =LW_DrawDurabilityRaw 75 | 76 | mov r0, r4 77 | mov r1, #2 78 | sub r2, r7, #1 79 | 80 | bl BXR3 81 | 82 | ldr r3, =0x08034D10+1 83 | bx r3 84 | 85 | .global LWHook08034DFC 86 | .type LWHook08034DFC, function 87 | 88 | LWHook08034DFC: 89 | ldr r3, =LW_DrawDurabilityRaw 90 | 91 | @ implied 92 | mov r1, r5 93 | sub r2, r4, #1 94 | 95 | bl BXR3 96 | 97 | @ replaced 98 | ldr r4, [sp, #0x1C] 99 | 100 | ldr r3, =0x08034E0C+1 101 | bx r3 102 | 103 | .global LWHook08034F1C 104 | .type LWHook08034F1C, function 105 | 106 | LWHook08034F1C: 107 | ldr r3, =LW_DrawDurabilityRaw 108 | 109 | mov r0, r6 110 | mov r1, r5 111 | sub r2, r4, #1 112 | 113 | bl BXR3 114 | 115 | ldr r3, =0x08034F2C+1 116 | bx r3 117 | 118 | .global LWHook0809D50C 119 | .type LWHook0809D50C, function 120 | 121 | LWHook0809D50C: 122 | ldr r3, =LW_DrawDurabilityRaw 123 | 124 | mov r0, r6 125 | mov r1, r5 126 | sub r2, r4, #1 127 | 128 | bl BXR3 129 | 130 | ldr r3, =0x0809D51C+1 131 | bx r3 132 | -------------------------------------------------------------------------------- /Wizardry/M7/M7.event: -------------------------------------------------------------------------------- 1 | #ifndef M7_INCLUDED 2 | #define M7_INCLUDED 3 | 4 | // Helper functions and procs for creating "mode 7" style effects within GBAFE. 5 | // Based the amazing GBA M7 demos and guides featured in tonc (https://www.coranac.com/tonc/text/) 6 | // hack by Stan 7 | 8 | /* 9 | * NOTE ABOUT USED RAM AREA 10 | * 11 | * This hack makes use of the "free" IWRAM area located at 03003750. 12 | * 13 | * Why is it "free"? Well, this area is normally part of where ARM functions are being copied to at startup, 14 | * but only a few of those copies are actually managed and called by the engine. 15 | * The other functions are not unused tho, but it's the *original* ROM functions that are called instead. 16 | * 17 | * The source area starts at 08000228, but the first relevant copied function starts at 08000490 (it's PushToHiOAM). 18 | * This means that we have 08000490 - 08000228 = 0x268 (616) bytes to play with starting at 03003750! 19 | */ 20 | 21 | #include "Src/M7RamFunc.lyn.event" 22 | ALIGN 4; SetSymbol(M7HBlank_Size, CURRENTOFFSET - M7HBlank) 23 | 24 | m7RamFuncRom: POIN M7HBlank 25 | m7RamFuncSize: WORD M7HBlank_Size 26 | m7RamFunc: WORD 0x03003750 27 | m7World: WORD 0x03003750 + M7HBlank_Size 28 | 29 | #include "Src/M7Core.lyn.event" 30 | 31 | #endif // M7_INCLUDED 32 | -------------------------------------------------------------------------------- /Wizardry/M7/Src/M7.h: -------------------------------------------------------------------------------- 1 | #ifndef M7_INCLUDED 2 | #define M7_INCLUDED 3 | 4 | #include "gbafe.h" 5 | 6 | // TODO: add to CLib 7 | enum 8 | { 9 | SCREEN_HEIGHT = 160, 10 | SCREEN_WIDTH = 240, 11 | }; 12 | 13 | enum 14 | { 15 | M7_D = 256, //!< Focal length 16 | M7_D_SHIFT = 8, //!< Focal shift 17 | M7O_NORM = 2, //!< Object renormalization shift (by /4) 18 | 19 | // View frustrum limits 20 | M7_LEFT = -120, //!< Viewport left 21 | M7_RIGHT = +120, //!< Viewport right 22 | M7_TOP = +80, //!< Viewport top (y-axis up) 23 | M7_BOTTOM = -80, //!< Viewport bottom (y-axis up!) 24 | M7_NEAR = 24, //!< Near plane (objects) 25 | M7_FAR = 512, //!< Far plane (objects) 26 | 27 | M7_FAR_BG = 768, //!< Far plane (floor) 28 | }; 29 | 30 | struct M7Vector 31 | { 32 | int x, y, z; 33 | }; 34 | 35 | struct M7Sprite 36 | { 37 | /* 00 */ struct M7Vector pos; //!< world position 38 | /* 0C */ struct M7Vector camPos; //!< camera position 39 | /* 18 */ u16 oam0, oam1, oam2; //!< oam data 40 | /* 1E */ u16 config; //!< config bits 41 | /* 20 */ s8 xAnchor, yAnchor; //!< position anchor point within sprite image 42 | /* 24 */ struct M7Sprite* next; //!< next element in linked list 43 | }; 44 | 45 | struct M7Camera 46 | { 47 | /* 00 */ struct M7Vector pos; 48 | /* 0C */ int theta, phi; 49 | /* 18 */ struct M7Vector u, v, w; 50 | /* 3C */ /* end */ 51 | }; 52 | 53 | struct M7CameraProc 54 | { 55 | /* 00 */ PROC_HEADER; 56 | /* 2C */ struct M7Camera data; 57 | /* 68 */ /* this barely fits into the proc */ 58 | }; 59 | 60 | struct M7Super3dWorld 61 | { 62 | struct M7CameraProc* cam; 63 | struct M7Sprite* sprite; 64 | struct BgControl bg2cnt; 65 | short horizon; 66 | 67 | short lam[SCREEN_HEIGHT]; 68 | }; 69 | 70 | extern struct M7Super3dWorld* const m7World; 71 | 72 | void m7Init(void); 73 | void m7End(void); 74 | void m7Indentity(void); 75 | void m7Rotate(unsigned phi, unsigned theta); 76 | void m7TranslateLevel(int x, int y, int z); 77 | void m7TranslateLocal(int x, int y, int z); 78 | void m7TranslateGlobal(int x, int y, int z); 79 | 80 | #define M7_GET_CF (m7World->cam->data.u.x) 81 | #define M7_GET_SF (m7World->cam->data.u.z) 82 | #define M7_GET_CT (m7World->cam->data.v.y) 83 | #define M7_GET_ST (m7World->cam->data.w.y) 84 | 85 | #endif // M7_INCLUDED 86 | -------------------------------------------------------------------------------- /Wizardry/M7/Src/M7RamFunc.c: -------------------------------------------------------------------------------- 1 | 2 | #include "M7.h" 3 | 4 | __attribute__((target("arm"))) 5 | void M7HBlank(void) 6 | { 7 | int vc = VCOUNT; 8 | 9 | if (vc >= SCREEN_HEIGHT || vc < m7World->horizon) 10 | return; 11 | 12 | if (vc == m7World->horizon) 13 | { 14 | DISPCNT.bgMode = 1; 15 | BG2CNT = m7World->bg2cnt; 16 | } 17 | 18 | int lam = m7World->lam[vc+1]; 19 | 20 | int lcf = lam*M7_GET_CF >> 8; 21 | int lsf = lam*M7_GET_SF >> 8; 22 | 23 | int zb = (vc-M7_TOP)*M7_GET_ST - M7_D*M7_GET_CT; 24 | 25 | BG2PA = lcf >> 4; 26 | BG2PC = lsf >> 4; 27 | BG2X = m7World->cam->data.pos.x + (lcf >> 4)*M7_LEFT - (lsf*zb >> 12); 28 | BG2Y = m7World->cam->data.pos.z + (lsf >> 4)*M7_LEFT + (lcf*zb >> 12); 29 | 30 | // A distance fogging with high marks for hack-value 31 | // Remember that we used pb to store the scale in, 32 | // so the blend is basically lambda/64 = distance * 2 33 | // which will do nicely 34 | // unsigned ey = lam*6>>12; 35 | 36 | // if (ey > 16) 37 | // ey = 16; 38 | 39 | // BLDY = ey; 40 | } 41 | -------------------------------------------------------------------------------- /Wizardry/MapAuraFx/Data/fx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanHash/FE-CHAX/4cfc053a20548d067551de71c8f536a4b67d1be0/Wizardry/MapAuraFx/Data/fx.png -------------------------------------------------------------------------------- /Wizardry/MapAuraFx/MapAuraFx.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_MAP_AURA_FX 2 | #define HAX_MAP_AURA_FX 3 | 4 | #include "Src/MapAuraFx.lyn.event" 5 | 6 | #endif // HAX_MAP_AURA_FX 7 | -------------------------------------------------------------------------------- /Wizardry/MapAuraFx/Src/MapAuraFx.h: -------------------------------------------------------------------------------- 1 | #ifndef MAP_AURA_FX_INCLUDED 2 | #define MAP_AURA_FX_INCLUDED 3 | 4 | #include "gbafe.h" 5 | 6 | void StartMapAuraFx(void); 7 | void EndMapAuraFx(void); 8 | int IsMapAuraFxActive(void); 9 | void SetMapAuraFxSpeed(int speed); 10 | void SetMapAuraFxBlend(unsigned blend); 11 | void SetMapAuraFxPalette(const u16 palette[]); 12 | void AddMapAuraFxUnit(struct Unit* unit); 13 | 14 | #endif // MAP_AURA_FX_INCLUDED 15 | -------------------------------------------------------------------------------- /Wizardry/Mimic/Mimic.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_MIMIC 2 | #define HAX_MIMIC 3 | 4 | #ifndef HAX_AAR 5 | ERROR please include CUnitAction before Mimic 6 | #endif // HAX_AAR 7 | 8 | #ifndef CHARACTER_MIMIC 9 | #define CHARACTER_MIMIC 0xC0 10 | #endif // CHARACTER_MIMIC 11 | 12 | #ifndef ACTION_MIMIC 13 | #define ACTION_MIMIC 0x28 14 | #endif // ACTION_MIMIC 15 | 16 | #include "src/Mimic.lyn.event" 17 | #include "src/MimicSelection.lyn.event" 18 | #include "src/MimicEffect.lyn.event" 19 | 20 | InjectUnitAction(ACTION_MIMIC, ActionRoutine(MimicAction)) 21 | 22 | ALIGN 4 23 | MimicCharacterId: 24 | WORD CHARACTER_MIMIC 25 | 26 | ALIGN 4 27 | MimicCommandActionId: 28 | WORD ACTION_MIMIC 29 | 30 | ALIGN 4 31 | MimicUnitSelectHelpTextId: 32 | #ifdef textMimicUnitSelectHelp 33 | WORD textMimicUnitSelectHelp 34 | #else 35 | WORD 0 36 | #endif 37 | 38 | ALIGN 4 39 | MimicPositionSelectHelpTextId: 40 | #ifdef textMimicPositionSelectHelp 41 | WORD textMimicPositionSelectHelp 42 | #else 43 | WORD 0 44 | #endif 45 | 46 | #endif // HAX_MIMIC 47 | -------------------------------------------------------------------------------- /Wizardry/Mimic/src/Mimic.c: -------------------------------------------------------------------------------- 1 | #include "Mimic.h" 2 | 3 | int IsUnitMimic(const struct Unit* unit) { 4 | return unit->pCharacterData->number == MimicCharacterId; 5 | } 6 | 7 | int AreNeitherUnitMimics(const struct Unit* self, const struct Unit* other) { 8 | return !IsUnitMimic(self) && !IsUnitMimic(other); 9 | } 10 | 11 | int MimicCmdUsability(const struct MenuCommandDefinition* def, int index) { 12 | // No Mimic command on canto 13 | if (gActiveUnit->state & US_CANTOING) 14 | return MCA_NONUSABLE; 15 | 16 | // Check if any existing mimic unit exists 17 | for (unsigned index = 1; index < 0x40; ++index) { 18 | const struct Unit* unit = GetUnit(index); 19 | 20 | if (unit && unit->pCharacterData && IsUnitMimic(unit)) 21 | return MCA_NONUSABLE; 22 | } 23 | 24 | // Check if we can mimic anyone 25 | if (MimicSetupTargets(gActiveUnit), GetTargetListSize() == 0) 26 | return MCA_NONUSABLE; 27 | 28 | return MCA_USABLE; 29 | } 30 | 31 | int MimicCmdEffect(struct MenuProc* menu, struct MenuCommandProc* command) { 32 | MimicSetupTargets(gActiveUnit); 33 | MimicStartTargetSelection(); 34 | 35 | return ME_DISABLE | ME_END | ME_PLAY_BEEP | ME_CLEAR_GFX; 36 | } 37 | -------------------------------------------------------------------------------- /Wizardry/Mimic/src/Mimic.h: -------------------------------------------------------------------------------- 1 | #ifndef MIMIC_H 2 | #define MIMIC_H 3 | 4 | #include "gbafe.h" 5 | 6 | // Mimic.c 7 | int IsUnitMimic(const struct Unit* unit); 8 | int AreNeitherUnitMimics(const struct Unit* self, const struct Unit* other); 9 | 10 | // MimicSelection.c 11 | void MimicSetupTargets(const struct Unit* unit); 12 | void MimicStartTargetSelection(void); 13 | 14 | // 15 | extern const unsigned MimicCharacterId; 16 | extern const unsigned MimicCommandActionId; 17 | extern const unsigned MimicUnitSelectHelpTextId; 18 | extern const unsigned MimicPositionSelectHelpTextId; 19 | 20 | #endif // MIMIC_H 21 | -------------------------------------------------------------------------------- /Wizardry/Mimic/src/MimicEffect.c: -------------------------------------------------------------------------------- 1 | #include "Mimic.h" 2 | 3 | struct MimicEffectProc { 4 | PROC_HEADER; 5 | 6 | Unit* pSummonedUnit; 7 | }; 8 | 9 | static void MECreateSummonUnit(struct MimicEffectProc*); 10 | 11 | extern void New6C_SummonGfx_FromActionPos(struct Proc*); 12 | 13 | static const struct ProcInstruction sProc_MimicEffect[] = { 14 | PROC_SET_NAME("Stan:Mimic:Effect"), 15 | PROC_YIELD, 16 | 17 | PROC_CALL_ROUTINE(MECreateSummonUnit), 18 | PROC_CALL_ROUTINE(New6C_SummonGfx_FromActionPos), 19 | PROC_YIELD, 20 | 21 | PROC_END 22 | }; 23 | 24 | int MimicAction(struct Proc* parent) { 25 | struct MimicEffectProc* proc = (struct MimicEffectProc*) ProcStartBlocking(sProc_MimicEffect, parent); 26 | 27 | proc->pSummonedUnit = NULL; 28 | 29 | return 0; 30 | } 31 | 32 | static void MECreateSummonUnit(struct MimicEffectProc* proc) { 33 | const struct Unit* subject = GetUnit(gActionData.subjectIndex); 34 | const struct Unit* toMimic = GetUnit(gActionData.targetIndex); 35 | 36 | struct UnitDefinition eUnit = { 37 | .charIndex = MimicCharacterId, 38 | .classIndex = toMimic->pClassData->number, 39 | .leaderCharIndex = subject->pCharacterData->number, // unnecessary/useless but whatever 40 | 41 | .allegiance = 0, 42 | .autolevel = FALSE, 43 | .level = toMimic->level, 44 | 45 | .xPosition = gActionData.xOther, 46 | .yPosition = gActionData.yOther, 47 | 48 | .redaCount = 0, 49 | .redas = NULL, 50 | 51 | .items[0] = 0, 52 | .items[1] = 0, 53 | .items[2] = 0, 54 | .items[3] = 0, 55 | }; 56 | 57 | proc->pSummonedUnit = LoadUnit(&eUnit); 58 | 59 | proc->pSummonedUnit->curHP = 1; 60 | proc->pSummonedUnit->maxHP = toMimic->curHP; 61 | 62 | proc->pSummonedUnit->pow = toMimic->pow; 63 | proc->pSummonedUnit->skl = toMimic->skl; 64 | proc->pSummonedUnit->spd = toMimic->spd; 65 | proc->pSummonedUnit->def = toMimic->def; 66 | proc->pSummonedUnit->res = toMimic->res; 67 | 68 | proc->pSummonedUnit->lck = 0; 69 | 70 | for (unsigned i = 0; i < ITEM_SLOT_COUNT; ++i) 71 | proc->pSummonedUnit->items[i] = toMimic->items[i]; 72 | 73 | for (unsigned i = 0; i < 8; ++i) 74 | proc->pSummonedUnit->ranks[i] = toMimic->ranks[i]; 75 | } 76 | -------------------------------------------------------------------------------- /Wizardry/Misc/FcukTanks.event: -------------------------------------------------------------------------------- 1 | #ifndef FCUKTANKS_INCLUDED 2 | #define FCUKTANKS_INCLUDED 3 | 4 | // Simple hack that makes AI-controlled units not attack if they can't deal damage 5 | // hack by Stan 6 | 7 | // Note that this doesn't account for any cool special mechanic that affects damage 8 | // It just check for (attack - defense) to be more than 0 9 | 10 | ALIGN 4 11 | FcukTanksHook: 12 | WORD $205A4B06 $4B065E18 $5E59215C $20001A41 $DC002900 $4B032001 $47182800 $203A4EC $203A56C $803DF19 13 | 14 | PUSH 15 | ORG $03DF10 16 | WORD $47184B00; POIN FcukTanksHook|1 17 | POP 18 | 19 | /* SOURCE: 20 | 21 | .thumb 22 | 23 | FcukTanksHook: 24 | @ Jump from FE8U:0803DF10 25 | 26 | @ We are just after a battle simulation 27 | @ So the battle actor and target are still fresh and up-to-date 28 | @ Which allows us to load battle stats from them 29 | 30 | ldr r3, =gBattleActor 31 | mov r0, #0x5A 32 | ldsh r0, [r3, r0] @ r0 = actor battle attack 33 | 34 | ldr r3, =gBattleTarget 35 | mov r1, #0x5C 36 | ldsh r1, [r3, r1] @ r1 = target battle defense 37 | 38 | sub r1, r0, r1 @ r1 = attack - defense = damage per hit 39 | 40 | mov r0, #0 @ default to 0 (can battle) 41 | 42 | cmp r1, #0 43 | bgt end 44 | 45 | mov r0, #1 @ if attack - defense <= 0, get 1 (cannot battle) 46 | 47 | end: 48 | ldr r3, =0x0803DF18+1 49 | 50 | cmp r0, #0 @ compare (replaced) 51 | 52 | bx r3 53 | 54 | */ 55 | 56 | #endif // FCUKTANKS_INCLUDED 57 | -------------------------------------------------------------------------------- /Wizardry/Misc/Nice.event: -------------------------------------------------------------------------------- 1 | #ifndef NICE_INCLUDED 2 | #define NICE_INCLUDED 3 | 4 | // Make 69% hit chance always hit 5 | // hack by Stan 6 | 7 | ALIGN 4 8 | NuBattleRoll2RN: 9 | WORD $881B4B07 $79BB510 $2101D406 $D0032845 $F0004B04 $1F809 $BC100008 $4708BC02 $203A4D4 $8000CB9 $46C04718 10 | 11 | PUSH 12 | 13 | ORG $2A558 // Replace BattleRoll2RN 14 | WORD $46C04778 $E59FC000 $E12FFF1C; POIN NuBattleRoll2RN|1 15 | 16 | POP 17 | 18 | /* // Source: 19 | 20 | int NuBattleRoll2RN(int chance, int simDefault) 21 | { 22 | if (gBattleStats.config & BATTLE_CONFIG_SIMULATE) 23 | return simDefault; 24 | 25 | if (chance == 69) 26 | return TRUE; 27 | 28 | return Roll2RN(chance); 29 | } 30 | 31 | // */ 32 | 33 | #endif // NICE_INCLUDED 34 | -------------------------------------------------------------------------------- /Wizardry/Misc/SetMoveBonus.event: -------------------------------------------------------------------------------- 1 | 2 | ALIGN 4 3 | ASMC_SetMoveBonus: 4 | WORD $4B05B500 $68804805 $F805F000 $68D24A03 $5442211D $4718BC08 $801829D $30004B8 5 | 6 | /* example usage: 7 | 8 | // set a 2 move malus to Eirika 9 | SVAL r2 Eirika 10 | SVAL r3 (-2) 11 | ASMC ASMC_SetMoveBonus|1 12 | 13 | */ 14 | -------------------------------------------------------------------------------- /Wizardry/MiscFixes/CounterFix.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_COUNTER_LOAD_FIX 2 | #define HAX_COUNTER_LOAD_FIX 3 | 4 | // Fix COUNTER_SET to be able to load value from s2 5 | // Allows for example SVAL s2 10; COUNTER_SET 2 (-1) 6 | 7 | // hack by StanH_ 8 | 9 | #include "Extensions/Hack Installation.txt" 10 | 11 | { 12 | 13 | PUSH; ORG $00DC38 14 | jumpToHack(CounterLoadFromS2) 15 | POP 16 | 17 | ALIGN 4 18 | CounterLoadFromS2: 19 | WORD $16030428 $4B02D501 $4C02689B $47104A02 $30004B8 $3000568 $800DC79 20 | 21 | /* SOURCE: 22 | 23 | .thumb 24 | 25 | return_location = 0x0800DC78+1 26 | 27 | @ Replaced stuff 28 | lsl r0, r5, #0x10 29 | asr r3, r0, #0x18 30 | 31 | @ branch if N flag not set (non negative) 32 | bpl end 33 | 34 | ldr r3, =gEventSlot 35 | ldr r3, [r3, #8] 36 | 37 | @ EPILOGUE 38 | 39 | end: 40 | ldr r4, =gEventCounter 41 | 42 | ldr r2, =return_location 43 | bx r2 44 | 45 | */ 46 | 47 | } 48 | 49 | #endif // HAX_COUNTER_LOAD_FIX 50 | -------------------------------------------------------------------------------- /Wizardry/MiscFixes/LeadAiFix.event: -------------------------------------------------------------------------------- 1 | #ifndef LEAD_AI_FIX 2 | #define LEAD_AI_FIX 3 | 4 | // Fix lead Ai issues caused by multiple groups (and other things) 5 | // hack by Stan 6 | 7 | PUSH 8 | ORG $03F51C 9 | WORD $47184B00; POIN (LeaderAiFix|1) 10 | POP 11 | 12 | ALIGN 4 13 | LeaderAiFix: 14 | WORD $4647B5F0 $2500B480 $701D4B01 $47184B01 $203AA8B $803F525 15 | 16 | /* SOURCE: 17 | 18 | @ replaced 19 | 20 | push {r4-r7, lr} 21 | mov r7, r8 22 | push {r7} 23 | mov r5, #0 24 | 25 | ldr r3, =0x0203AA04+0x87 26 | strb r5, [r3] 27 | 28 | ldr r3, =0x0803F524+1 29 | bx r3 30 | 31 | */ 32 | 33 | #endif // LEAD_AI_FIX 34 | -------------------------------------------------------------------------------- /Wizardry/MiscFixes/MNC2FixTest.event: -------------------------------------------------------------------------------- 1 | #ifndef FIX_MNC2_MAYBE 2 | #define FIX_MNC2_MAYBE 3 | 4 | PUSH 5 | 6 | ORG $00F464 7 | POIN MoveToChapter2Hook 8 | 9 | POP 10 | 11 | ALIGN 4 12 | MoveToChapter2Hook: 13 | WORD $1C16B4F4 $27032400 $4B094D08 $F0001C20 $42B0F80B $782BD102 $702B433B $35043401 $D1F22C1D $4B03BCF4 $4718 $30052B0 $80BB5B1 $800F499 14 | 15 | /* Source: 16 | 17 | .thumb 18 | 19 | .global MoveToChapter2Hook 20 | .type MoveToChapter2Hook, function 21 | 22 | MoveToChapter2Hook: 23 | push {r2, r4-r7} 24 | 25 | mov r6, r2 @ var r6 = chapter id 26 | 27 | mov r4, #0 @ var r4 = i 28 | mov r7, #2 @ var r7 = 2 (flag) 29 | 30 | ldr r5, =gGMData+48 @ var r5 = it 31 | 32 | .lop: 33 | ldr r3, =WMLocation_GetChapterId 34 | 35 | mov r0, r4 @ arg r0 = node id 36 | 37 | bl BXR3 38 | 39 | cmp r0, r6 40 | bne .continue 41 | 42 | @ set flag for the chapter node 43 | 44 | ldrb r3, [r5] 45 | orr r3, r7 46 | strb r3, [r5] 47 | 48 | .continue: 49 | add r4, #1 @ i++ 50 | add r5, #4 @ it++ 51 | 52 | cmp r4, #29 53 | bne .lop 54 | 55 | pop {r2, r4-r7} 56 | 57 | ldr r3, =0x0800F498+1 58 | 59 | BXR3: 60 | bx r3 61 | 62 | .pool 63 | .align 64 | 65 | */ 66 | 67 | #endif // FIX_MNC2_MAYBE 68 | -------------------------------------------------------------------------------- /Wizardry/StatScreenBlink/SSBlink.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_SSBLINK_INCLUDED 2 | #define HAX_SSBLINK_INCLUDED 3 | 4 | // Makes portraits drawn on bgs (as opposed to as objects) be able to blink. 5 | // Portraits are drawn on bgs in the stat screen as well as in places such as the support menus. 6 | // hack by Stan 7 | 8 | // The functionality was already in the game, it just was unused. 9 | 10 | #include "Src/SSBlink.lyn.event" 11 | 12 | PUSH 13 | 14 | ORG $005C24 // portraits shouldn't be smol (because it breaks) 15 | SHORT $2000 $4770 16 | 17 | ORG $005E98 // Make portraits on backgrounds blink 18 | // (t)bx pc; (a)ldr ip, =NuDisplayBgFace; (a)bx ip 19 | WORD $46C04778 $E59FC000 $E12FFF1C; POIN NuDisplayBgFace 20 | 21 | POP 22 | 23 | #endif // HAX_SSBLINK_INCLUDED 24 | -------------------------------------------------------------------------------- /Wizardry/StatScreenBlink/Src/SSBlink.c: -------------------------------------------------------------------------------- 1 | 2 | #include "gbafe.h" 3 | 4 | // Portrait drawn on backgrounds now blink 5 | 6 | // The functionnaly is already in the game, only unused 7 | // This makes it used. 8 | 9 | // TODO: update reference and add to CLib 10 | static const struct ProcInstruction* spProc_BgFaceBlinkProc = (const void*)(0x08591204); 11 | static void(*DisplayBgFaceCore)(u16* bgOut, unsigned portrait, unsigned tileId, unsigned palId) = (const void*)(0x08005CA4+1); 12 | 13 | void NuDisplayBgFace(struct Proc* proc, u16* bgOut, unsigned portrait, unsigned tileId, unsigned palId) 14 | { 15 | EndEachProc(spProc_BgFaceBlinkProc); 16 | DisplayBgFaceCore(bgOut, portrait, tileId, palId); 17 | 18 | if (proc) 19 | { 20 | const struct PortraitData* data = GetPortraitData(portrait); 21 | 22 | if (!data->pPortraitGraphics) 23 | return; 24 | 25 | struct FaceBlinkProc* blink = START_PROC(spProc_BgFaceBlinkProc, proc); 26 | 27 | blink->output = ShouldPortraitBeSmol(portrait) ? bgOut + TILEMAP_INDEX(0, -1) : bgOut; 28 | blink->tileId = tileId; 29 | blink->paletteId = palId; 30 | blink->portraitId = portrait; 31 | blink->blinkControl = data->blinkBehaviorKind; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Wizardry/TalkAi/Src/TalkAi.c: -------------------------------------------------------------------------------- 1 | 2 | #include "gbafe.h" 3 | 4 | void ASMC_FixTalkUnit(struct Proc* proc) 5 | { 6 | gActiveUnit->state = gActiveUnit->state &~ (US_HIDDEN | US_HAS_MOVED | US_HAS_MOVED_AI); 7 | } 8 | 9 | int AiTransformMoveIntoTalk(const u8* charId) 10 | { 11 | AiUpdateDecision( 12 | AI_DECISION_TALK, 0, 13 | gActiveUnit->index, 14 | GetUnitByCharId(*charId)->index, 15 | 0xFF); 16 | 17 | return TRUE; 18 | } 19 | -------------------------------------------------------------------------------- /Wizardry/TalkAi/TalkAi.event: -------------------------------------------------------------------------------- 1 | #ifndef TALKAI_INCLUDED 2 | #define TALKAI_INCLUDED 3 | 4 | // TalkAi 5 | // hack by Stan 6 | 7 | // This provides the necessary elements to define your own "approach and talk to character" ai through a macro 8 | 9 | /* Example: 10 | 11 | ALIGN 4 12 | DanAi: 13 | AiTryTalkToCharacter(Eirika) 14 | 15 | InjectAi2(CH10_DAN_AI2, DanAi) // Use whatever macro you use to inject AIs 16 | 17 | */ 18 | 19 | /* Note: 20 | 21 | The AiTryTalkToCharacter(aCharacter) macro is equivalent to: 22 | { 23 | AiMoveUntilAdjacentTo(aCharacter) 24 | AiGotoIfNE(0, 2) 25 | 26 | // moved adjacent 27 | AiFunc(AiTransformMoveIntoTalk, TalkAiCharacterParam) 28 | 29 | AiRestart 30 | 31 | TalkAiCharacterParam: 32 | BYTE aCharacter 33 | } 34 | 35 | If you need more complex ai behavior from your unit, you can instead of using the macro edit this above to fit your needs. 36 | 37 | */ 38 | 39 | #include "Src/TalkAi.lyn.event" 40 | 41 | #define AiTryTalkToCharacter(aCharacter) "{ BYTE 0x0D 100 0xFF 0; WORD (aCharacter) 0 0; BYTE 0x00 5 0xFF 0; WORD 2 0x0203AA8A 0; BYTE 0x01 0 0xFF 0; WORD 0; POIN (AiTransformMoveIntoTalk) (TalkAiCharacterParam); BYTE 0x03 0 0xFF 0; WORD 0 0 0; TalkAiCharacterParam: BYTE (aCharacter); }" 42 | 43 | #endif // TALKAI_INCLUDED 44 | -------------------------------------------------------------------------------- /Wizardry/TextScrollSpeed.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_TEXTSCROLLSPEED 2 | #define HAX_TEXTSCROLLSPEED 3 | 4 | #ifndef TextScrollSpeed 5 | #define TextScrollSpeed 1 6 | #endif // TextScrollSpeed 7 | 8 | PUSH; ORG $007FE6 9 | BYTE (TextScrollSpeed) 10 | POP 11 | 12 | // TODO: fix scroll speed not applying for [2NL] (?) 13 | 14 | #endif // HAX_TEXTSCROLLSPEED 15 | -------------------------------------------------------------------------------- /Wizardry/TileChangeTrap/TileChangeTrap.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_TILE_CHANGE_TRAP 2 | #define HAX_TILE_CHANGE_TRAP 3 | 4 | SINGLE_TILE_CHANGE_TRAP_TYPE: 5 | WORD 0x30 // whatever 6 | 7 | #include "TileChangeTrap.lyn.event" 8 | 9 | /* 10 | 11 | This implements these: 12 | void ChangeSingleTile(int x, int y, int tileID, Proc* parent) 13 | void ChangeSingleTileExt(int x, int y, int tileID, int display, Proc* parent) 14 | 15 | in other words, the "ChangeSingleTile" points to a routine that takes the following arguments: 16 | r0 = tile x position 17 | r1 = tile y position 18 | r2 = tile ID short 19 | r3 = parent 6C for fade display (0 for instant gfx change) 20 | 21 | and the "ChangeSingleTileExt" label points to a routine that takes those: 22 | r0 = tile x position 23 | r1 = tile y position 24 | r2 = tile ID short 25 | r3 = 0 for instant, 1 for display fade change 26 | [sp] = parent 6C for fade display (0 for none) 27 | 28 | ChangeSingleTile calls ChangeSingleTileExt, and exists so that you don't have to mess with the stack for simple & straighforward applications. 29 | 30 | HOW DOES THIS WORK: 31 | Each tile changed by one of those 2 routines creates a trap of type id 0x30 that holds the data for the tile change. 32 | It using traps for holding data means that those changes *will* be saved properly. 33 | I am hooking into the same routine that applies standard map changes to apply the changes on load, so this shouldn't be an issue either. 34 | 35 | */ 36 | 37 | #endif // HAX_TILE_CHANGE_TRAP 38 | -------------------------------------------------------------------------------- /Wizardry/TradeCheck/TradeCheck.event: -------------------------------------------------------------------------------- 1 | #ifndef HAX_TRADECHECK 2 | #define HAX_TRADECHECK 3 | 4 | { 5 | 6 | PUSH; ORG $25224 7 | #include "src/TradeCheckHook.lyn.event" 8 | POP 9 | 10 | #include "src/TradeCheckLoop.lyn.event" 11 | 12 | #ifndef TradeCheckListDeclared 13 | 14 | TradeCheckList: 15 | POIN AreUnitsSameAllegiance 16 | POIN AreNeitherUnitPhantomClass 17 | WORD 0 18 | 19 | #endif // TradeCheckListDeclared 20 | 21 | } 22 | 23 | #include "src/TradeCheckVanilla.lyn.event" 24 | 25 | #endif // HAX_TRADECHECK 26 | -------------------------------------------------------------------------------- /Wizardry/TradeCheck/src/TradeCheckHook.s: -------------------------------------------------------------------------------- 1 | .thumb 2 | 3 | @ REPLACED: 4 | @ $08025224 5 | 6 | @ LDRB R0, [R0,#UnitStruct.index] 7 | 8 | @ LSLS R0, R0, #0x18 9 | @ ASRS R0, R0, #0x18 10 | 11 | @ MOVS R1, #UnitStruct.index 12 | @ LDRSB R1, [R4,R1] 13 | 14 | @ BL AreAllegiancesEqual 15 | 16 | @ LSLS R0, R0, #0x18 17 | 18 | @ CMP R0, #0 19 | @ BEQ End 20 | 21 | @ LDR R2, [R5] 22 | @ LDR R0, [R2,#UnitStruct.pClassData] 23 | @ LDRB R0, [R0,#ROMClassEntry.number] 24 | 25 | @ CMP R0, #ClassPhantom 26 | @ BEQ End 27 | 28 | @ LDR R3, [R4,#UnitStruct.pClassData] 29 | @ LDRB R0, [R3,#ROMClassEntry.number] 30 | 31 | @ CMP R0, #ClassPhantom 32 | @ BEQ End 33 | 34 | Origin = 0x08025224 35 | End = . + (0x080252C4 - Origin) 36 | Continue = . + (0x0802524A - Origin) 37 | 38 | @ r4 is other 39 | @ r0 is subject 40 | 41 | Start: 42 | mov r1, r4 43 | 44 | ldr r3, =CanUnitTradeWith 45 | bl BXR3 46 | 47 | cmp r0, #0 48 | beq End 49 | 50 | ldr r2, [r5] 51 | ldr r3, [r4, #4] 52 | 53 | b Continue 54 | 55 | BXR3: 56 | bx r3 57 | -------------------------------------------------------------------------------- /Wizardry/TradeCheck/src/TradeCheckLoop.c: -------------------------------------------------------------------------------- 1 | #include "gbafe.h" 2 | 3 | typedef int(*TradeCheckFunc)(const struct Unit*, const struct Unit*); 4 | 5 | extern const TradeCheckFunc TradeCheckList[]; 6 | 7 | int CanUnitTradeWith(const struct Unit* self, const struct Unit* other) { 8 | const TradeCheckFunc* it = &TradeCheckList[0]; 9 | 10 | while (*it) 11 | if (!((*it++)(self, other))) 12 | return FALSE; 13 | 14 | return TRUE; 15 | } 16 | -------------------------------------------------------------------------------- /Wizardry/TradeCheck/src/TradeCheckVanilla.c: -------------------------------------------------------------------------------- 1 | #include "gbafe.h" 2 | 3 | int AreUnitsSameAllegiance(const struct Unit* self, const struct Unit* other) { 4 | extern int AreAllegiancesEqual(int, int) __attribute__((long_call)); 5 | 6 | return AreAllegiancesEqual(self->index, other->index); 7 | } 8 | 9 | int AreNeitherUnitPhantomClass(const struct Unit* self, const struct Unit* other) { 10 | static const unsigned ClassPhantom = 0x51; 11 | 12 | if (self->pClassData->number == ClassPhantom) 13 | return FALSE; 14 | 15 | if (other->pClassData->number == ClassPhantom) 16 | return FALSE; 17 | 18 | return TRUE; 19 | } 20 | -------------------------------------------------------------------------------- /Wizardry/Utility/CanUnitBeOnPosition.event: -------------------------------------------------------------------------------- 1 | #ifndef CANUNITBEONPOSITION_INCLUDED 2 | #define CANUNITBEONPOSITION_INCLUDED 3 | 4 | // bool CanUnitBeOnPosition(struct Unit* unit, int x, int y); 5 | // hack by Stan 6 | 7 | #include "Src/CanUnitBeOnPosition.lyn.event" 8 | 9 | #endif // CANUNITBEONPOSITION_INCLUDED 10 | -------------------------------------------------------------------------------- /Wizardry/Utility/ShopLike.event: -------------------------------------------------------------------------------- 1 | #ifndef SHOPLIKE_INCLUDED 2 | #define SHOPLIKE_INCLUDED 3 | 4 | // Set of utility functions for making screens that look like shops/arena 5 | // hack by Stan 6 | 7 | #include "Src/ShopLike.lyn.event" 8 | 9 | #endif // SHOPLIKE_INCLUDED 10 | -------------------------------------------------------------------------------- /Wizardry/Utility/Src/CanUnitBeOnPosition.c: -------------------------------------------------------------------------------- 1 | #include "gbafe.h" 2 | 3 | int CanUnitBeOnPosition(struct Unit* unit, int x, int y) 4 | { 5 | if (x < 0 || y < 0) 6 | return FALSE; // position out of bounds 7 | 8 | if (x >= gMapSize.x || y >= gMapSize.y) 9 | return FALSE; // position out of bounds 10 | 11 | if (gMapUnit[y][x]) 12 | return FALSE; // a unit is occupying this position 13 | 14 | if (gMapHidden[y][x] & 1) 15 | return FALSE; // a hidden unit is occupying this position 16 | 17 | return CanUnitCrossTerrain(unit, gMapTerrain[y][x]); 18 | } 19 | -------------------------------------------------------------------------------- /Wizardry/VeninSleepWeapons/Src/VswHook.s: -------------------------------------------------------------------------------- 1 | 2 | .thumb 3 | 4 | continue_location = 0x0802B058+1 5 | return_location = 0x0802B06E+1 6 | 7 | gBattleHitIt = 0x0203A608 8 | 9 | .global VswHook_0802B044 10 | .type VswHook_0802B044, function 11 | 12 | @ hook at fe8u:0802B044 13 | 14 | VswHook_0802B044: 15 | @ attacker in r6 16 | @ defender in r8 17 | 18 | @ load attacker output status 19 | 20 | mov r0, #0x6F 21 | ldrb r0, [r6, r0] 22 | 23 | @ compare to sleep, and return false if equal 24 | 25 | cmp r0, #2 26 | beq return_false 27 | 28 | @ replaced code 29 | ldr r0, =gBattleHitIt 30 | ldr r3, [r0] 31 | ldr r2, [r3] 32 | lsl r1, r2, #13 33 | lsr r1, r1, #13 34 | orr r1, r7 35 | ldr r0, =0xFFF80000 36 | and r0, r2 37 | orr r0, r1 38 | str r0, [r3] 39 | 40 | ldr r3, =continue_location 41 | bx r3 42 | 43 | return_false: 44 | mov r0, #0 45 | ldr r3, =return_location 46 | bx r3 47 | -------------------------------------------------------------------------------- /Wizardry/VeninSleepWeapons/Vsw.event: -------------------------------------------------------------------------------- 1 | 2 | // makes venin weapons put opponent to sleep instead of poisoning them 3 | // proof of concept hack by stan 4 | 5 | #include "Src/VswHook.lyn.event" 6 | 7 | PUSH 8 | 9 | ORG $02B044 10 | WORD $47184B00; POIN VswHook_0802B044 11 | 12 | ORG $02B644 13 | SHORT $2002 // movs r0, #2 @ sleep status 14 | SHORT $216F // movs r1, #0x6F 15 | SHORT $5460 // strb r0, [r4, r1] 16 | 17 | POP 18 | -------------------------------------------------------------------------------- /Wizardry/VeryCustomItems/Src/Vci.h: -------------------------------------------------------------------------------- 1 | #ifndef VCI_INCLUDED 2 | #define VCI_INCLUDED 3 | 4 | #include "gbafe.h" 5 | 6 | struct VciInfo 7 | { 8 | // basic getters 9 | int (*getIndex) (int item); 10 | char* (*getName) (int item); 11 | int (*getDescId) (int item); 12 | int (*getUseDescId) (int item); 13 | int (*getType) (int item); 14 | int (*getAttributes) (int item); 15 | int (*getUses) (int item); 16 | int (*getMaxUses) (int item); 17 | int (*getMight) (int item); 18 | int (*getHit) (int item); 19 | int (*getWeight) (int item); 20 | int (*getCrit) (int item); 21 | int (*getCost) (int item); 22 | int (*getMinRange) (int item); 23 | int (*getMaxRange) (int item); 24 | int (*getEncodedRange) (int item); 25 | int (*getRequiredExp) (int item); 26 | const u8* (*getEffectiveness) (int item); 27 | const struct ItemStatBonuses* (*getEquipBonuses) (int item); 28 | int (*getIconId) (int item); 29 | int (*getWeaponEffect) (int item); 30 | int (*getUseEffect) (int item); 31 | int (*getCostPerUse) (int item); 32 | int (*getMaxCost) (int item); 33 | int (*getAwardedExp) (int item); 34 | 35 | // extended getters 36 | int (*clone) (int item); 37 | int (*canUnitUseWeapon) (int item, struct Unit* unit); 38 | int (*canUnitUseStaff) (int item, struct Unit* unit); 39 | int (*getAfterUse) (int item); 40 | int (*isEffectiveAgainst) (int item, struct Unit* unit); 41 | char* (*getDisplayRangeString) (int item); 42 | char* (*getDisplayRankString) (int item); 43 | int (*isDisplayUsable) (int item, struct Unit* unit); 44 | int (*getHealAmount) (int item, struct Unit* unit); 45 | int (*isStealable) (int item); 46 | int (*isHammernable) (int item); 47 | 48 | // display functions 49 | void (*drawMenuItem) (int item, struct TextHandle* text, u16* mapOut, int isUsable); 50 | void (*drawMenuItemLong) (int item, struct TextHandle* text, u16* mapOut, int isUsable); 51 | void (*drawMenuItemNoColor) (int item, struct TextHandle* text, u16* mapOut); 52 | void (*drawStatScreenItem) (int item, struct TextHandle* text, u16* mapOut, int nameColor); 53 | 54 | // stat bonuses getters 55 | int (*getEquipHpBonus) (int item); 56 | int (*getEquipPowBonus) (int item); 57 | int (*getEquipSklBonus) (int item); 58 | int (*getEquipSpdBonus) (int item); 59 | int (*getEquipDefBonus) (int item); 60 | int (*getEquipResBonus) (int item); 61 | int (*getEquipLckBonus) (int item); 62 | }; 63 | 64 | // functions 65 | 66 | int VciIsLockpick(int item); 67 | int VciIsNightmare(int item); 68 | 69 | // objects 70 | 71 | extern const struct VciInfo* const gVciInfoTable[0x100]; 72 | extern const struct VciInfo gVciDefaultInfo; 73 | 74 | #endif // VCI_INCLUDED 75 | -------------------------------------------------------------------------------- /Writans/ParseDefinitions.txt: -------------------------------------------------------------------------------- 1 | [N] = [NL] 2 | [AN] = [A][N] 3 | -------------------------------------------------------------------------------- /Writans/TextMain.txt: -------------------------------------------------------------------------------- 1 | // # 0x0212 textFlorinaName 2 | // Florina[X] 3 | 4 | # 0x003A textDummy 5 | This is a placeholder[X] 6 | 7 | #include "TextRewarp.txt" 8 | #include "TextMimic.txt" 9 | 10 | // #include "PeerBlitzCh9Text.txt" 11 | -------------------------------------------------------------------------------- /Writans/TextMimic.txt: -------------------------------------------------------------------------------- 1 | 2 | ## textMimicCommandName 3 | Mimic[X] 4 | 5 | ## textMimicCommandDesc 6 | Summons a copy of[NL] 7 | another unit.[X] 8 | 9 | ## textMimicUnitSelectHelp 10 | Choose a unit to make a copy of.[X] 11 | 12 | ## textMimicPositionSelectHelp 13 | Choose where to spawn the copy.[X] 14 | -------------------------------------------------------------------------------- /Writans/TextRewarp.txt: -------------------------------------------------------------------------------- 1 | 2 | ## textRewarpCommandName 3 | Rewarp[X] 4 | 5 | ## textRewarpCommandDesc 6 | Rewarp![X] 7 | -------------------------------------------------------------------------------- /game-data.mk: -------------------------------------------------------------------------------- 1 | 2 | # ========== 3 | # = TABLES = 4 | # ========== 5 | 6 | # Convert CSV+NMM to event 7 | %.event: %.csv %.nmm 8 | $(NOTIFY_PROCESS) 9 | @echo | $(C2EA) -csv $*.csv -nmm $*.nmm -out $*.event $(ROM_SOURCE) > /dev/null 10 | 11 | # ======== 12 | # = MAPS = 13 | # ======== 14 | 15 | # TMX to event + dmp 16 | %.event %_data.dmp: %.tmx 17 | $(NOTIFY_PROCESS) 18 | @$(TMX1EA) $< --output-event $*.event --output-data $*_data.dmp 19 | 20 | # ============== 21 | # = MAKE CLEAN = 22 | # ============== 23 | 24 | ifeq ($(MAKECMDGOALS),clean) 25 | 26 | # NMMs and generated events 27 | NMMS := $(shell find -type f -name '*.nmm') 28 | TABLE_EVENTS := $(NMMS:.nmm=.event) 29 | 30 | # TMXs and generated files 31 | TMXS := $(shell find -type f -name '*.tmx') 32 | MAP_GENERATED := $(TMXS:.tmx=.event) $(TMXS:.tmx=_data.dmp) 33 | 34 | CLEAN_FILES += $(TABLE_EVENTS) $(MAP_GENERATED) 35 | 36 | endif 37 | -------------------------------------------------------------------------------- /make_ready_install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | VERSION=$(date +"%Y%m%d") 4 | DIR=CHaxInstallReady-$VERSION 5 | 6 | make hack 7 | rm -rf $DIR 8 | mkdir $DIR 9 | cp -r Wizardry $DIR 10 | cd $DIR 11 | find -type f -name '*.o' -delete 12 | rm -rf Wizardry/.Limbo Wizardry/.Research Wizardry/3rdParty 13 | -------------------------------------------------------------------------------- /spritans.mk: -------------------------------------------------------------------------------- 1 | 2 | # ============= 3 | # = PORTRAITS = 4 | # ============= 5 | 6 | PORTRAIT_LIST := Spritans/PortraitList.txt 7 | PORTRAIT_INSTALLER := Spritans/Portraits.event 8 | 9 | # Make the portrait installer 10 | $(PORTRAIT_INSTALLER): $(PORTRAIT_LIST) $(shell $(PORTRAIT_PROCESS) $(PORTRAIT_LIST) --list-files) 11 | $(NOTIFY_PROCESS) 12 | @$(PORTRAIT_PROCESS) $< --output $@ 13 | 14 | # Convert a png to portrait components 15 | %_mug.dmp %_palette.dmp %_frames.dmp %_minimug.dmp: %.png 16 | $(NOTIFY_PROCESS) 17 | @$(PORTRAITFORMATTER) $< 18 | 19 | # ========================== 20 | # = GRAPHICS & COMPRESSION = 21 | # ========================== 22 | 23 | # PNG to 4bpp rule 24 | %.4bpp: %.png 25 | $(NOTIFY_PROCESS) 26 | @$(PNG2DMP) $< -o $@ 27 | 28 | # PNG to gbapal rule 29 | %.gbapal: %.png 30 | $(NOTIFY_PROCESS) 31 | @$(PNG2DMP) $< -po $@ --palette-only 32 | 33 | # Anything to lz rule 34 | %.lz: % 35 | $(NOTIFY_PROCESS) 36 | @$(COMPRESS) $< $@ 37 | 38 | ifeq ($(MAKECMDGOALS),clean) 39 | 40 | # Portraits and generated files 41 | PORTRAITS := $(wildcard Spritans/Portraits/*.png) 42 | 43 | PORTRAIT_GENERATED := \ 44 | $(PORTRAITS:.png=_mug.dmp) $(PORTRAITS:.png=_palette.dmp) \ 45 | $(PORTRAITS:.png=_frames.dmp) $(PORTRAITS:.png=_minimug.dmp) 46 | 47 | CLEAN_FILES += $(PORTRAIT_INSTALLER) $(PORTRAIT_GENERATED) 48 | 49 | endif 50 | -------------------------------------------------------------------------------- /tools.mk: -------------------------------------------------------------------------------- 1 | ifeq ($(OS),Windows_NT) 2 | EXE := .exe 3 | else 4 | EXE := 5 | endif 6 | 7 | TOOLCHAIN ?= $(DEVKITARM) 8 | 9 | ifneq (,$(TOOLCHAIN)) 10 | export PATH := $(TOOLCHAIN)/bin:$(PATH) 11 | endif 12 | 13 | PREFIX := arm-none-eabi- 14 | 15 | CC := $(PREFIX)gcc 16 | AS := $(PREFIX)as 17 | OBJCOPY := $(PREFIX)objcopy 18 | 19 | # Making sure we are using python 3 20 | ifeq ($(shell python -c 'import sys; print(int(sys.version_info[0] > 2))'),1) 21 | export PYTHON3 := python 22 | else 23 | export PYTHON3 := python3 24 | endif 25 | 26 | EA := $(realpath .)/Tools/EventAssembler/ColorzCore$(EXE) 27 | 28 | # additional tools 29 | export PARSEFILE := $(realpath .)/Tools/EventAssembler/Tools/ParseFile$(EXE) 30 | export PORTRAITFORMATTER := $(realpath .)/Tools/EventAssembler/Tools/PortraitFormatter$(EXE) 31 | export PNG2DMP := $(realpath .)/Tools/EventAssembler/Tools/Png2Dmp$(EXE) 32 | export COMPRESS := $(realpath .)/Tools/EventAssembler/Tools/compress$(EXE) 33 | export LYN := $(realpath .)/Tools/EventAssembler/Tools/lyn$(EXE) 34 | export EADEP := $(realpath .)/Tools/EventAssembler/ea-dep$(EXE) 35 | 36 | export PORTRAIT_PROCESS := $(PYTHON3) $(realpath .)/Tools/PyTools/portrait-process.py 37 | export TEXT_PROCESS := $(PYTHON3) $(realpath .)/Tools/PyTools/text-process-classic.py 38 | export C2EA := $(PYTHON3) $(realpath .)/Tools/PyTools/NMM2CSV/c2ea.py 39 | export TMX1EA := $(PYTHON3) $(realpath .)/Tools/PyTools/tmx1ea.py 40 | 41 | NOTIFY_PROCESS = @echo "$(notdir $<) => $(notdir $@)" 42 | -------------------------------------------------------------------------------- /wizardry.mk: -------------------------------------------------------------------------------- 1 | 2 | # ================== 3 | # = OBJECTS & DMPS = 4 | # ================== 5 | 6 | LYN_REFERENCE := Tools/CLib/reference/FE8U-20190316.o 7 | 8 | # OBJ to event 9 | %.lyn.event: %.o $(LYN_REFERENCE) 10 | $(NOTIFY_PROCESS) 11 | @$(LYN) $< $(LYN_REFERENCE) > $@ 12 | 13 | # OBJ to DMP rule 14 | %.dmp: %.o 15 | $(NOTIFY_PROCESS) 16 | @$(OBJCOPY) -S $< -O binary $@ 17 | 18 | # ======================== 19 | # = ASSEMBLY/COMPILATION = 20 | # ======================== 21 | 22 | # Setting C/ASM include directories up (there is none yet) 23 | INCLUDE_DIRS := Tools/CLib/include Wizardry/Include 24 | INCFLAGS := $(foreach dir, $(INCLUDE_DIRS), -I "$(dir)") 25 | 26 | # setting up compilation flags 27 | ARCH := -mcpu=arm7tdmi -mthumb -mthumb-interwork 28 | CFLAGS := $(ARCH) $(INCFLAGS) -Wall -Wextra -Wno-unused -O2 -mtune=arm7tdmi -ffreestanding -mlong-calls 29 | ASFLAGS := $(ARCH) $(INCFLAGS) 30 | 31 | # defining dependency flags 32 | CDEPFLAGS = -MMD -MT "$*.o" -MT "$*.asm" -MF "$(CACHE_DIR)/$(notdir $*).d" -MP 33 | SDEPFLAGS = --MD "$(CACHE_DIR)/$(notdir $*).d" 34 | 35 | # ASM to OBJ rule 36 | %.o: %.s 37 | $(NOTIFY_PROCESS) 38 | @$(AS) $(ASFLAGS) $(SDEPFLAGS) -I $(dir $<) $< -o $@ $(ERROR_FILTER) 39 | 40 | # C to ASM rule 41 | # I would be fine with generating an intermediate .s file but this breaks dependencies 42 | %.o: %.c 43 | $(NOTIFY_PROCESS) 44 | @$(CC) $(CFLAGS) $(CDEPFLAGS) -g -c $< -o $@ $(ERROR_FILTER) 45 | 46 | # C to ASM rule 47 | %.asm: %.c 48 | $(NOTIFY_PROCESS) 49 | @$(CC) $(CFLAGS) $(CDEPFLAGS) -S $< -o $@ -fverbose-asm $(ERROR_FILTER) 50 | 51 | # Avoid make deleting objects it thinks it doesn't need anymore 52 | # Without this make may fail to detect some files as being up to date 53 | .PRECIOUS: %.o; 54 | 55 | # ============== 56 | # = MAKE CLEAN = 57 | # ============== 58 | 59 | ifeq ($(MAKECMDGOALS),clean) 60 | 61 | # ASM/C and generated files 62 | CFILES := $(shell find -type f -name '*.c') 63 | SFILES := $(shell find -type f -name '*.s') 64 | 65 | ASM_C_GENERATED := $(CFILES:.c=.o) $(SFILES:.s=.o) $(CFILES:.c=.asm) 66 | ASM_C_GENERATED += $(ASM_C_GENERATED:.o=.dmp) $(ASM_C_GENERATED:.o=.lyn.event) 67 | 68 | CLEAN_FILES += $(ASM_C_GENERATED) 69 | 70 | endif 71 | -------------------------------------------------------------------------------- /writans.mk: -------------------------------------------------------------------------------- 1 | 2 | # ======== 3 | # = TEXT = 4 | # ======== 5 | 6 | # Variable listing all text files in the writans directory 7 | # The text installer depends on them (in case there was any change) 8 | # (Too lazy to code a dependency thingy for that too) 9 | WRITANS_ALL_TEXT := $(wildcard Writans/*.txt) 10 | 11 | # Main input text file 12 | WRITANS_TEXT_MAIN := Writans/TextMain.txt 13 | WRITANS_PARSEDEFS := Writans/ParseDefinitions.txt 14 | 15 | # textprocess outputs 16 | WRITANS_INSTALLER := Writans/Text.event 17 | WRITANS_DEFINITIONS := Writans/TextDefinitions.event 18 | 19 | # Make text installer and definitions from text 20 | $(WRITANS_INSTALLER) $(WRITANS_DEFINITIONS): $(WRITANS_TEXT_MAIN) $(WRITANS_ALL_TEXT) 21 | $(NOTIFY_PROCESS) 22 | @$(TEXT_PROCESS) $(WRITANS_TEXT_MAIN) --parse-definitions $(WRITANS_PARSEDEFS) --installer $(WRITANS_INSTALLER) --definitions $(WRITANS_DEFINITIONS) --parser-exe $(PARSEFILE) 23 | 24 | # Convert formatted text to insertable binary 25 | # Nulling output because it's annoying 26 | %.fetxt.dmp: %.fetxt 27 | $(NOTIFY_PROCESS) 28 | @$(PARSEFILE) $< -o $@ > /dev/null 29 | 30 | # ============== 31 | # = MAKE CLEAN = 32 | # ============== 33 | 34 | ifeq ($(MAKECMDGOALS),clean) 35 | 36 | CLEAN_FILES += $(WRITANS_INSTALLER) $(WRITANS_DEFINITIONS) 37 | CLEAN_DIRS += Writans/Text/.TextEntries 38 | 39 | endif 40 | --------------------------------------------------------------------------------