├── .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 |
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 |
--------------------------------------------------------------------------------