Repository: UnclePunch/Training-Mode Branch: master Commit: fa0b9ef4ecb5 Files: 475 Total size: 243.6 MB Directory structure: gitextract_cp2hs4__/ ├── .gitattributes ├── .gitignore ├── ASM/ │ ├── Additional Codes/ │ │ ├── Allow Staling in Develop Mode.asm │ │ ├── Better Camera/ │ │ │ ├── C-Stick Pans Camera.asm │ │ │ ├── CStickPanOffscreen/ │ │ │ │ ├── Bottom.asm │ │ │ │ ├── Left.asm │ │ │ │ ├── Right.asm │ │ │ │ └── Top.asm │ │ │ ├── SnapToOffscreenPlayers/ │ │ │ │ ├── Always Onscreen.asm │ │ │ │ └── Snap.asm │ │ │ └── Unrestricted Camera.asm │ │ ├── Boot to CSS/ │ │ │ └── Boot to Main Menu Or CSS.s │ │ ├── Boot to Event Mode/ │ │ │ ├── Boot to Main Menu Or CSS.asm │ │ │ └── Main Menu Starts at Event Mode.asm │ │ ├── CSS KO Star Codes/ │ │ │ ├── Calculate KO Stars Upon Exiting Dairantou.asm │ │ │ └── Disable KO Star Deletion When Leaving CSS.asm │ │ ├── Collision Link Draw Order Fix [Punkline]/ │ │ │ ├── New Draw Location.asm │ │ │ └── Remove Original Draw.asm │ │ ├── DEBUGLOG.s │ │ ├── DPad Down to Random Stage.s │ │ ├── Debug Mode Codes/ │ │ │ ├── Debug Language is English by Default.asm │ │ │ ├── Exiting Debug Goes to Main Menu.asm │ │ │ └── Tournament Mode Goes to Debug.asm │ │ ├── Default Tournament Settings/ │ │ │ ├── 4 Stocks.asm │ │ │ ├── 8 Minutes.asm │ │ │ ├── No Items.asm │ │ │ ├── Stock Mode.asm │ │ │ └── Tournament Stages.asm │ │ ├── Delete Bootup OSReports.asm │ │ ├── Disable CSS Anim Loop.s │ │ ├── Disable FoD Reflection.asm │ │ ├── Disable FoD in Doubles.asm │ │ ├── Disable Item Spawn in Develop Mode.asm │ │ ├── Disable Item Spawn in Develop Mode.s │ │ ├── Disable Rumble on Unplug.asm │ │ ├── Disable Special Records/ │ │ │ ├── Disable Special Messages.asm │ │ │ └── Disable Trophy Messages.asm │ │ ├── Display Animation Name for Special Moves in Develop Mode/ │ │ │ └── Display Animation Name for Special Moves in Develop Mode.asm │ │ ├── Display Ungrabbable Hurtboxes/ │ │ │ └── Main.asm │ │ ├── Enable 1P in VS Mode No Time.asm │ │ ├── Enable C Stick Always/ │ │ │ ├── Enable CStick for CPU in Debug.asm │ │ │ ├── Rotate Camera with Dpad Down and C Stick - Initiate.asm │ │ │ ├── Rotate Camera with Dpad Down and C Stick.asm │ │ │ ├── Single Player Always Returns False.asm │ │ │ └── Spoof Debug Level as 0 for Human C Stick Inputs.asm │ │ ├── Faster CSS Load.asm │ │ ├── Frame Advance Audio.s │ │ ├── GX Draw/ │ │ │ └── Main.s │ │ ├── Game Modes/ │ │ │ ├── All Star Test/ │ │ │ │ ├── Disable Invisible Melee.s │ │ │ │ └── Initialize Lineups.s │ │ │ ├── Chess Melee.asm │ │ │ ├── Chess Melee.s │ │ │ ├── Iron Man/ │ │ │ │ ├── Disable Invisible Melee.asm │ │ │ │ ├── Initialize Lineups.asm │ │ │ │ └── Load Next Match.asm │ │ │ ├── Rotations Melee.asm │ │ │ ├── Rotations Melee.s │ │ │ ├── Tag Melee.asm │ │ │ └── Tag Melee.s │ │ ├── Hide Nametag When Invisible.asm │ │ ├── Hide Player GFX When Hitboxes Enabled/ │ │ │ ├── Hide GFX When Hitboxes Enabled.asm │ │ │ ├── Hide OnHit GFX When Hitboxes Enabled 2.asm │ │ │ └── Hide OnHit GFX When Hitboxes Enabled.asm │ │ ├── Hitbox Color Changes Based On Damage.asm │ │ ├── Hold A+B for Salty Runback + Hold A+X for Random Stage + Skip Result Screen.asm │ │ ├── Hold Z for Rapid Frame Advance/ │ │ │ ├── New Inputs Don't Reset Rapid Timer.s │ │ │ ├── P1 - Check Rapid Fire Input.asm │ │ │ ├── P2 - Check Rapid Fire Input.asm │ │ │ ├── P3 - Check Rapid Fire Input.asm │ │ │ └── P4 - Check Rapid Fire Input.asm │ │ ├── Idle Screen/ │ │ │ └── Main.asm │ │ ├── Initialize Stage Data.asm │ │ ├── Kill Zoom/ │ │ │ ├── Main.s │ │ │ └── Rumble During MH Zoom.s │ │ ├── L+R+A Returns to CSS During SSS.asm │ │ ├── Lag Reduction Prompt/ │ │ │ └── Main.asm │ │ ├── Last Unplug Closes All CSS Doors.asm │ │ ├── Longer Nametags/ │ │ │ ├── 8 Letter Tags/ │ │ │ │ ├── 8Characters1.asm │ │ │ │ ├── 8Characters2.asm │ │ │ │ ├── 8Characters3.asm │ │ │ │ ├── 8Characters4.asm │ │ │ │ ├── Adjust Cursor Position.asm │ │ │ │ ├── Character Spacing.asm │ │ │ │ ├── Copy 8 Characters1.asm │ │ │ │ ├── Copy 8 Characters2.asm │ │ │ │ ├── Disable Tag Rumble - Ignore Tag Rumble.asm │ │ │ │ ├── Disable Tag Rumble - Init.asm │ │ │ │ ├── Disable Tag Rumble - RumbleLoad.asm │ │ │ │ ├── Disable Tag Rumble - RumbleThink.asm │ │ │ │ └── ZeroNametagText.asm │ │ │ └── Scale Nametag BG/ │ │ │ └── Main.asm │ │ ├── Misc Hitbox Visualizer/ │ │ │ ├── Always Draw TopN For Items.asm │ │ │ ├── Display Chain ECBs - GObj 7.asm │ │ │ └── Main.asm │ │ ├── Neutral Respawn.asm │ │ ├── Neutral Respawn.s │ │ ├── Neutral Spawn.asm │ │ ├── On Crash/ │ │ │ ├── Clear Bootup OSReports.asm │ │ │ ├── Disable Brinstar OSReport.asm │ │ │ ├── Disable Effect AnimList OSReport.asm │ │ │ ├── Disable Fourside OSReport.asm │ │ │ ├── Disable Fourside OSReport2.asm │ │ │ ├── Disable PS OSReport.asm │ │ │ ├── Disable YoshisIsland OSReport.asm │ │ │ ├── Disable mpcoll OSReport.asm │ │ │ ├── Dont Output Compile Date on Assert.asm │ │ │ ├── Dont Output Compile Date on Invalid Read.asm │ │ │ ├── Enable OSReport Print to Screen.asm │ │ │ ├── LRZ Shows Advanced Details/ │ │ │ │ ├── Any Debug Level Displays Advanced Details.s │ │ │ │ └── Check for LRZ.s │ │ │ ├── Only Show First 8 Lines of Stack.asm │ │ │ └── Reboot With LRAStart.asm │ │ ├── Output File Load Times/ │ │ │ ├── Output Load Time.s │ │ │ └── Save Tick.s │ │ ├── PRIM LITE/ │ │ │ ├── PRIM (1).asm │ │ │ ├── PRIM (10).asm │ │ │ ├── PRIM (11).asm │ │ │ ├── PRIM (12).asm │ │ │ ├── PRIM (13).asm │ │ │ ├── PRIM (14).asm │ │ │ ├── PRIM (15).asm │ │ │ ├── PRIM (16).asm │ │ │ ├── PRIM (17).asm │ │ │ ├── PRIM (18).asm │ │ │ ├── PRIM (19).asm │ │ │ ├── PRIM (2).asm │ │ │ ├── PRIM (20).asm │ │ │ ├── PRIM (3).asm │ │ │ ├── PRIM (4).asm │ │ │ ├── PRIM (5).asm │ │ │ ├── PRIM (6).asm │ │ │ ├── PRIM (7).asm │ │ │ ├── PRIM (8).asm │ │ │ └── PRIM (9).asm │ │ ├── Pad - Update During Frame Advance.asm │ │ ├── Pause During Game Start/ │ │ │ ├── Check to Pause.asm │ │ │ ├── Check to Pause.s │ │ │ ├── Check to Unpause.asm │ │ │ └── Check to Unpause.s │ │ ├── Physics Display/ │ │ │ ├── Main.asm │ │ │ └── Main.s │ │ ├── QWERTY Keyboard.s │ │ ├── Random CSS Music v2/ │ │ │ ├── random music modification.asm │ │ │ ├── roll on bootup.asm │ │ │ └── roll on match end.asm │ │ ├── Randomize Hitboxes Each Stock/ │ │ │ └── Randomize Hitbox Values.s │ │ ├── Rumble Off/ │ │ │ └── Rumble Off.asm │ │ ├── Skip Memcard Prompt/ │ │ │ └── Skip Memcard Prompt.asm │ │ ├── Stage Music = 50 50.asm │ │ ├── Toggle Focused Player in Develop Mode Camera/ │ │ │ ├── Switch Focused Player in Develop Mode.asm │ │ │ └── WIP/ │ │ │ └── Init CameraMode Struct When Develop is Enabled.s │ │ ├── Toggle Rumble From CSS/ │ │ │ └── Toggle Rumble From CSS.asm │ │ ├── Unlock Everything/ │ │ │ ├── Unlock All Characters/ │ │ │ │ ├── Spoof All Characters as Unlocked.asm │ │ │ │ └── Spoof Individual Characters as Unlocked.asm │ │ │ ├── Unlock All Rules/ │ │ │ │ ├── Unlock Random Stage Select.asm │ │ │ │ └── Unlock Score Display.asm │ │ │ ├── Unlock All Special Messages/ │ │ │ │ ├── Special Messages 1.asm │ │ │ │ ├── Special Messages 2.asm │ │ │ │ ├── Spoof No Pending Messages 2.asm │ │ │ │ └── Spoof No Pending Messages.asm │ │ │ ├── Unlock All Stages/ │ │ │ │ ├── Spoof All Stages Unlocked.asm │ │ │ │ └── Spoof Individual Stage Unlocked.asm │ │ │ ├── Unlock All Trophies/ │ │ │ │ ├── Fill Save Data.asm │ │ │ │ ├── Have 99 of Every Trophy.asm │ │ │ │ └── Spoof All Trophies as Unlocked.asm │ │ │ ├── Unlock All-Star.asm │ │ │ └── Unlock Sound Test.asm │ │ ├── Unplugging Closes CSS Door.asm │ │ ├── Use Save Banner #1.asm │ │ ├── Winners Names are Gold on CSS/ │ │ │ ├── Change Name Color.asm │ │ │ └── Remember Who LRA Started.asm │ │ └── XYDisablesStart/ │ │ └── Main.asm │ ├── Globals.s │ ├── m-ex/ │ │ ├── Custom Playerdata Variables/ │ │ │ ├── Adjust Size.asm │ │ │ ├── Initialize Extended Playerblock Values (Result Screen).asm │ │ │ ├── Initialize Extended Playerblock Values.asm │ │ │ └── OwnsAnim/ │ │ │ ├── Check Animation Owner.s │ │ │ └── Store Animation Owner.s │ │ ├── Header.s │ │ ├── Standalone Functions/ │ │ │ ├── Audio_RequestFileLoad_Rewrite.asm │ │ │ ├── Get MxDt Data.asm │ │ │ ├── Get grFunction.asm │ │ │ ├── GetFtItemID.asm │ │ │ ├── GetGrItemID.asm │ │ │ ├── GetKirbyCpData.asm │ │ │ ├── GetMEXItemID.asm │ │ │ ├── GetMEXPlaylist.asm │ │ │ ├── Index Fighter Item.asm │ │ │ ├── Init itFunction.asm │ │ │ ├── KirbyStateChange.asm │ │ │ ├── LoadRELDAT.asm │ │ │ ├── MenuThink.asm │ │ │ ├── Reloc.asm │ │ │ ├── SFX_PlayStageSFX.asm │ │ │ ├── SpawnMEXEffect.s │ │ │ ├── SpawnMEXItem.asm │ │ │ ├── Stock Icon Get Frame.asm │ │ │ └── calloc.asm │ │ └── UCF 0.8/ │ │ ├── Codes.txt │ │ ├── UCF DB.asm │ │ ├── UCF SD.asm │ │ ├── UCF Store Inputs CPU.asm │ │ ├── UCF Store Inputs.asm │ │ ├── UCF Text.asm │ │ └── UCF Tumble.asm │ └── training-mode/ │ ├── Custom Events/ │ │ ├── A+B to Reset Event/ │ │ │ ├── Check for Reset on Game End.asm │ │ │ └── Check for Reset on LRAStart.asm │ │ ├── CSS and SSS/ │ │ │ ├── Add SSS To Event Match Scene List.asm │ │ │ ├── Backup HMN And CPU Choices/ │ │ │ │ ├── Backup Event CPU.asm │ │ │ │ └── Restore Event CPU.asm │ │ │ ├── Display Event Name on CSS.asm │ │ │ ├── Load CSS + Preload CPU.asm │ │ │ ├── Load SSS For Certain Events.asm │ │ │ └── Toggle CSS Icon Vibibility/ │ │ │ └── Toggle CSS Icon Vibibility.asm │ │ ├── Credits Codes/ │ │ │ ├── Don't Display Info In TM Credits.asm │ │ │ ├── Don't Display Titles In Training Mode Credits.asm │ │ │ └── Swap Out Credit Names in TM Credits.asm │ │ ├── Custom Event Code - Legacy.s │ │ ├── Custom Event Code - Rewrite.asm │ │ ├── Custom Event Preload Behavior/ │ │ │ ├── Disable Event Preload - CSS Enter.asm │ │ │ ├── Disable Event Preload - Match Enter.asm │ │ │ ├── Disable Event Preload.asm │ │ │ ├── Dont Adjust CPU Color in Event Mode When Its Already in Use.asm │ │ │ └── Load Character ssm Files.asm │ │ ├── Event Select Screen/ │ │ │ ├── Backup FDD Backup on Event Choose.asm │ │ │ ├── Better X and Y Event Jump/ │ │ │ │ ├── Jump Down - Update Cursor.asm │ │ │ │ ├── Jump Down.asm │ │ │ │ ├── Jump Up - Update Cursor.asm │ │ │ │ └── Jump Up.asm │ │ │ ├── Change ESS Proc To Pri 1.asm │ │ │ ├── Choose Any Character for Events/ │ │ │ │ ├── Always Copy CSS Character Info.asm │ │ │ │ ├── Always Show Select Character Texture.asm │ │ │ │ └── Always Spoof AnyCharacter.asm │ │ │ ├── Custom ESS Button Actions.asm │ │ │ ├── Event High Scores/ │ │ │ │ ├── Load Event High Scores.asm │ │ │ │ └── Save Event High Scores.asm │ │ │ ├── Event Text/ │ │ │ │ ├── CannotScrollPastEventsOnPage.asm │ │ │ │ ├── Custom Event Highscore Types.asm │ │ │ │ ├── Display Custom Event Descriptions.asm │ │ │ │ ├── Display Custom Event Names on ESS.asm │ │ │ │ ├── Get Custom Event Description.asm │ │ │ │ ├── Get Custom Event Description.s │ │ │ │ ├── Get Custom Event Name.asm │ │ │ │ ├── Get Custom Event Name.s │ │ │ │ ├── Get Custom Event Page Name.asm │ │ │ │ ├── Get Custom Event Page Name.s │ │ │ │ ├── GetNumOfEventsOnCurrentPage.asm │ │ │ │ ├── GetNumOfEventsOnCurrentPage.s │ │ │ │ ├── Never Scroll If Less than 9 Events on Page.asm │ │ │ │ ├── OnlyDisplayEventsOnPage.asm │ │ │ │ └── SkipDisplayingEventNames.asm │ │ │ ├── GetEventTutorialFileName.asm │ │ │ ├── Restore FDD Backup on Main Menu Load.asm │ │ │ ├── Spoof All Events as Not Played.asm │ │ │ └── Version Indicator/ │ │ │ ├── Event Code Version Indicator.asm │ │ │ ├── Remove Event Texture.asm │ │ │ ├── Remove Version Indicator 1.asm │ │ │ ├── Remove Version Indicator 2.asm │ │ │ └── Toggle Tutorial Text.asm │ │ └── Unlock All Events/ │ │ ├── Unlock Event 1.asm │ │ └── Unlock Event 2.asm │ ├── Globals.s │ ├── Hooks/ │ │ ├── OnBoot.asm │ │ ├── OnCSSLoad.asm │ │ ├── OnSceneChange.asm │ │ └── OnStartMelee.asm │ ├── Misc/ │ │ ├── Adjust Pad Params/ │ │ │ ├── Adjust Menu Navigation Deadzone Boot.asm │ │ │ ├── Adjust Menu Navigation Deadzone.asm │ │ │ └── Increase Rapid Fire Timer.s │ │ ├── Better VS Mode Frame Counter/ │ │ │ ├── Inc Counter.asm │ │ │ └── Init Counter.asm │ │ ├── Boot Up Tasks.asm │ │ ├── CSS - Increase SIS Text Heap.asm │ │ ├── Corneria - Move Ship on Stage Init.asm │ │ ├── Count NonExistant Player Kills.asm │ │ ├── Disable Calls to ScoreDisplay_Remove.asm │ │ ├── Disable USB Screenshot.asm │ │ ├── Display Stick Info When Paused/ │ │ │ ├── Create Text on Pause.asm │ │ │ └── Remove Text on UnPause.asm │ │ ├── Display Tweet Message And Version Number.asm │ │ ├── Do Not Save Nametag Region to Memcard for GALE01.asm │ │ ├── Edit Carrot Texture.s │ │ ├── Edit Hyphen Texture.s │ │ ├── Frame Advance Rewrite.asm │ │ ├── GObj_Destory Exits When Input = 0.asm │ │ ├── HSD_Update Tweak/ │ │ │ ├── Allow Z in VS While Paused.asm │ │ │ ├── Always Run Debug Update.asm │ │ │ ├── Check for DBLevel.asm │ │ │ ├── Clear HSDUpdate for no Debug Melee.asm │ │ │ └── Clear HSDUpdate for no Debug.asm │ │ ├── Load .gct on Boot.s │ │ ├── Load TmDt.asm │ │ ├── Never Play Movies in Archives.asm │ │ ├── OSReport Match Load Time/ │ │ │ ├── Output Time Since Last Tick.asm │ │ │ └── Store Starting Tick.asm │ │ ├── On No Save.asm │ │ ├── Overwrite Compile Date.s │ │ ├── PAL Changes/ │ │ │ ├── Character DAT Patcher.asm │ │ │ ├── DK - Keep Up B Charge After Getting Hit out of Up B/ │ │ │ │ ├── Keep Charge Aerial Up B.asm │ │ │ │ └── Keep Charge Grounded Up B.asm │ │ │ ├── Detection Hitboxes Does Not Skip Hurtbox Collision Check.asm │ │ │ ├── Fix Freeze Glitch.asm │ │ │ ├── PAL CSS Indicator.asm │ │ │ ├── PAL Stock Icons.asm │ │ │ ├── Samus - Disable Extender/ │ │ │ │ ├── Disable Initial Extender Polling.asm │ │ │ │ └── Disable Secondary Extender Polling.asm │ │ │ └── Samus Cant Bomb Jump Out of Grapple.asm │ │ ├── Save File Renaming.asm │ │ ├── ScoreDisplay - Change GXLink Pri.asm │ │ ├── SearchStringTable.asm │ │ ├── Skip Assert for Respawn Platform.asm │ │ ├── Skip Assert for no_reaction_always.asm │ │ ├── Skip SetGroundStateAssert For Restore States.asm │ │ ├── Store Version Number.s │ │ ├── Text - Increment Max Size.asm.asm │ │ └── Text Modifications/ │ │ ├── Add Symbols to ASCII-Menu Text Lookup Table.asm │ │ ├── Make Spaces Not Store 00s.asm │ │ ├── Make Spaces Store 0x1A.asm │ │ └── Parse Numbers Correctly.asm │ └── Onscreen Display/ │ ├── Act OOS Frame Display/ │ │ ├── Count During GuardOff.asm │ │ ├── Count During ShieldWait.asm │ │ ├── Display OOS Frame Count Standalone.asm │ │ ├── GuardOff - Display OOS Frame Count.asm │ │ ├── GuardWait - Display OOS Frame Count.asm │ │ └── Init Frame Count.asm │ ├── Act OOTumble/ │ │ ├── DamageFall - Check For Interrupt.asm │ │ ├── DamageFlyTop - CheckForInterrupt.asm │ │ ├── DamageLightHit - Check For Animation Interrupt.asm │ │ ├── DamageLightHit - Check For Interrupt - Aerial Jump.asm │ │ ├── DamageLightHit - Check ForInterrupt.asm │ │ ├── Increment Post Hitstun Count.asm │ │ ├── Original Counters and Variable Initializers/ │ │ │ ├── DamageFall - Increment Counter.asm │ │ │ ├── DamageFlyRoll - Increment Counter.asm │ │ │ ├── DamageFlyRoll - Init DamageFallCounter.asm │ │ │ ├── DamageFlyTop - Increment Counter.asm │ │ │ ├── DamageFlyTop - Init DamageFallCounter.asm │ │ │ ├── DamageLightHit - Increment Counter.asm │ │ │ ├── DamageLightHit - Init DamageFallCounter.asm │ │ │ └── MissFoot - Init Counter.asm │ │ └── Static Function - Display Frames Spent Post Hitstun.asm │ ├── Act OoWait/ │ │ ├── Act OOWait- Standalone.asm │ │ ├── Act OoWait - From Crouch.asm │ │ ├── Act OoWait - From Landing.asm │ │ └── Act OoWait - From Wait.asm │ ├── Additional Playerblock Variables/ │ │ ├── Fastfall Timer/ │ │ │ ├── Display FF Timing.asm │ │ │ ├── Increment Fastfall Variable.asm │ │ │ └── Initialize Fastfall Variable.asm │ │ ├── Frame Advantage/ │ │ │ ├── Initialize Frame Advantage Think.asm │ │ │ └── Save Pointer to Shield Owner On Hit.asm │ │ ├── Previous Move Instance Hit By/ │ │ │ └── Backup Previous Move Instance Player was Hit By.asm │ │ └── StatesAndTimers/ │ │ ├── IncFrameCounts.asm │ │ └── ShiftStates.asm │ ├── Check For IC's Static Function.asm │ ├── Combo Counter/ │ │ ├── Better Combo Counter/ │ │ │ ├── Custom Function Blrl + Keep Combo Counter Going For Missed Techs+Getups.asm │ │ │ ├── Disregard Projectile Hitboxes w Same Move ID.asm │ │ │ ├── Disregard Throw Hitboxes.asm.bak │ │ │ ├── Interrupting Move with Same Move Gives a Unique ID.asm │ │ │ ├── Keep Combo Counter Going For Missed Techs+Getups.asm │ │ │ ├── Pummels and Multi-Hits Increment Total Damage But Not Combo Counter.asm │ │ │ ├── Skip Original Combo End Check.asm │ │ │ └── Throw Hitboxes Update (Last Damage Source) Variable in Playerblock.asm │ │ └── Combo Counter - On Combo Increment.asm │ ├── Dashback/ │ │ ├── Dashback Display - Static Function.asm │ │ ├── Grab Out of Tilt Turn.asm.bak │ │ └── Run Out of Tilt Turn.asm │ ├── Fox Training Codes/ │ │ └── Side B Shorten Display.asm │ ├── L Cancel Display NEW.asm │ ├── Ledge Codes/ │ │ ├── Frames Spent in CliffWait.asm │ │ ├── GALINT/ │ │ │ ├── GALINT Aerail Interrupt.asm │ │ │ ├── GALINT Laser Land.asm │ │ │ ├── GALINT Ledgedash.asm │ │ │ ├── GALINT No Impact Land.asm │ │ │ └── Standalaone - GALINT Display.asm │ │ └── Ledgestall/ │ │ └── Ledgestall Display.asm │ ├── Message Display System/ │ │ ├── Create Message Struct.asm │ │ ├── Disable Hiding Score on Pause.asm │ │ ├── Disable Showing Score on Unpause.asm │ │ └── Display Message 2.0.asm │ ├── SDI Display/ │ │ ├── Initialize Total SDI Inputs Variable.asm │ │ └── SDI Display Main.asm │ ├── Template.s │ ├── Toggle UI/ │ │ ├── Can Disable All Toggles in Custom RSS.asm │ │ ├── Disable Save to Bitfield Every Change.asm │ │ ├── Load Alt Text When Loaded With L.asm │ │ ├── Load Random Stage Select On L Press.asm │ │ ├── Load Toggles When Loaded With L .asm │ │ ├── Press L for OSD Indicator.asm │ │ ├── Remove Press L for OSD Indicator.asm │ │ ├── Remove Text When Leaving Custom RSS.asm │ │ ├── Return to Event Screen When Pressing Start.asm │ │ ├── Return to First Page When Loaded With L.asm │ │ ├── Save Toggles When Loaded With L.asm │ │ ├── Set Flag on Leaving Custom RSS.asm │ │ └── XY To Adjust Max OSD.asm │ └── Wavedash Display/ │ ├── Save Airdodge Y Angle.asm │ └── Wavedash Timing Display.asm ├── Additional ISO Files/ │ ├── TvAmsTc.mth │ ├── TvLC.mth │ ├── TvLedDa.mth │ ├── TvLedTc.mth │ ├── TvPowSh.mth │ ├── TvRvrsl.mth │ ├── TvSDI.mth │ ├── TvShDrp.mth │ └── audio/ │ ├── TvAmsTc.hps │ ├── TvLC.hps │ ├── TvLedDa.hps │ ├── TvLedTc.hps │ ├── TvPowSh.hps │ ├── TvRvrsl.hps │ ├── TvSDI.hps │ └── TvShDrp.hps ├── Build TM Codeset/ │ ├── Build Training Mode Codeset.bat │ ├── codes.json │ └── mac/ │ ├── codes.json │ └── modifyStartDol.sh ├── Build TM Start.dol/ │ ├── Drag Melee v1.02 Start.dol Here.bat │ └── patch.xdelta ├── MexTK/ │ ├── MexTK.exe.config │ ├── cssFunction.txt │ ├── evFunction.txt │ ├── ftFunction.txt │ ├── grFunction.txt │ ├── include/ │ │ ├── archive.h │ │ ├── audio.h │ │ ├── boneset.h │ │ ├── collision.h │ │ ├── color.h │ │ ├── css.h │ │ ├── datatypes.h │ │ ├── devtext.h │ │ ├── effects.h │ │ ├── fighter.h │ │ ├── hsd.h │ │ ├── inline.h │ │ ├── item.h │ │ ├── kirby.h │ │ ├── match.h │ │ ├── math.h │ │ ├── memcard.h │ │ ├── mex.h │ │ ├── obj.h │ │ ├── offsets.h │ │ ├── preload.h │ │ ├── result.h │ │ ├── scene.h │ │ ├── stage.h │ │ ├── structs.h │ │ ├── text.h │ │ └── useful.h │ ├── itFunction.txt │ ├── kbFunction.txt │ ├── melee.link │ ├── mex.h │ ├── mjFunction.txt │ ├── mnFunction.txt │ └── tmFunction.txt ├── README.md └── patch/ ├── events/ │ ├── lab/ │ │ ├── build.bat │ │ ├── notes.txt │ │ └── source/ │ │ ├── lab.c │ │ ├── lab.h │ │ └── lab_css.c │ ├── lcancel/ │ │ ├── build.bat │ │ └── source/ │ │ ├── lcancel.c │ │ └── lcancel.h │ ├── ledgedash/ │ │ ├── build.bat │ │ └── source/ │ │ ├── ledgedash.c │ │ └── ledgedash.h │ └── wavedash/ │ ├── build.bat │ └── source/ │ ├── wavedash.c │ └── wavedash.h └── tmdata/ ├── build.bat └── source/ ├── events.c └── events.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto # Custom for Visual Studio *.cs diff=csharp # Standard to msysgit *.doc diff=astextplain *.DOC diff=astextplain *.docx diff=astextplain *.DOCX diff=astextplain *.dot diff=astextplain *.DOT diff=astextplain *.pdf diff=astextplain *.PDF diff=astextplain *.rtf diff=astextplain *.RTF diff=astextplain ================================================ FILE: .gitignore ================================================ # Windows thumbnail cache files Thumbs.db ehthumbs.db ehthumbs_vista.db # Folder config file Desktop.ini # Recycle Bin used on file shares $RECYCLE.BIN/ # Windows Installer files *.cab *.msi *.msm *.msp # Windows shortcuts *.lnk # ========================= # Operating System Files # ========================= ASM/Misc/Store Version Number.asm ASM/Misc/Overwrite Compile Date.asm # ========================== # Project files # ========================== Build\ TM\ Codeset/mac/gecko Additional\ ISO\ Files/codes.gct Additional\ ISO\ Files/Start.dol # Mac files .DS_Store ================================================ FILE: ASM/Additional Codes/Allow Staling in Develop Mode.asm ================================================ #To be inserted at 80089250 b 0x8 ================================================ FILE: ASM/Additional Codes/Better Camera/C-Stick Pans Camera.asm ================================================ #To be inserted at 8002cb30 .include "../../Globals.s" .set Player,5 .set FloatPointer,6 #Float regs .set Deadzone,5 .set DeadzoneNeg,6 .set PlayerY,7 .set PlayerX,8 #Get Float Pointer bl Floats mflr FloatPointer #Get Player Input Struct load r3,0x804C1FAC lbz r4, 0x02C5 (r31) mulli Player, r4, 0x44 add Player, r3, Player #Get Deadzone Value from PlCo lwz r3, -0x514C (r13) lfs Deadzone, 0(r3) fneg DeadzoneNeg, Deadzone CheckYDeadzone: #Check Y Value lfs PlayerY, 0x2C(Player) fcmpo cr0, PlayerY, DeadzoneNeg ble- StoreY fcmpo cr0, PlayerY, Deadzone blt- CheckXDeadzone StoreY: lfs f1, 0x318(r31) #Get X lfs f2, 0x330(r31) #Get zoom level lfs f3, 0x0(FloatPointer) #Get multiplier fdivs f3,f2,f3 #Zoom * var fmuls PlayerY,PlayerY,f3 #Stick axis * zoomed fadds f1,f1,PlayerY #Add to X stfs f1, 0x318(r31) #Store CheckXDeadzone: lfs PlayerY, 0x28(Player) fcmpo cr0, PlayerY, DeadzoneNeg ble- StoreX fcmpo cr0, PlayerY, Deadzone blt- Exit StoreX: lfs f1, 0x314(r31) lfs f2, 0x330(r31) #Get zoom level lfs f3, 0x0(FloatPointer) #Get multiplier fdivs f3,f2,f3 #Zoom * var fmuls PlayerY,PlayerY,f3 #Stick axis * zoomed fadds f1,f1,PlayerY #Add to Y stfs f1, 0x314(r31) b Exit Floats: blrl .float 125 Exit: lbz r0, 0x02C5 (r31) ================================================ FILE: ASM/Additional Codes/Better Camera/CStickPanOffscreen/Bottom.asm ================================================ #To be inserted at 8002c6e4 nop ================================================ FILE: ASM/Additional Codes/Better Camera/CStickPanOffscreen/Left.asm ================================================ #To be inserted at 8002c6bc nop ================================================ FILE: ASM/Additional Codes/Better Camera/CStickPanOffscreen/Right.asm ================================================ #To be inserted at 8002c6a8 nop ================================================ FILE: ASM/Additional Codes/Better Camera/CStickPanOffscreen/Top.asm ================================================ #To be inserted at 8002c6d0 nop ================================================ FILE: ASM/Additional Codes/Better Camera/SnapToOffscreenPlayers/Always Onscreen.asm ================================================ #To be inserted at 8002cf34 .include "../../../Globals.s" .set REG_Pauser,31 .set REG_Count,30 backup #Get player port who paused load r3,0x8046b6a0 lbz REG_Pauser,0x1(r3) #Search all players for this port li REG_Count,0 Loop: mr r3,REG_Count branchl r12,PlayerBlock_LoadMainCharDataOffset cmpwi r3,0 beq IncLoop #Check their port to see if it matches mr r3,REG_Count branchl r12,0x8003345c cmpw r3,REG_Pauser beq FoundPauser IncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,4 blt Loop b Dead FoundPauser: #Check if player is alive mr r3,REG_Count branchl r12,PlayerBlock_LoadMainCharDataOffset lwz r3,0x2C(r3) lbz r3,0x221F(r3) rlwinm. r3,r3,0,25,25 bne Dead Alive: li r3,0 b Exit Dead: li r3,1 Exit: restore ================================================ FILE: ASM/Additional Codes/Better Camera/SnapToOffscreenPlayers/Snap.asm ================================================ #To be inserted at 8002c5f0 .include "../../../Globals.s" .set REG_Pauser,31 .set REG_Count,30 backup #Get player port who paused load r3,0x8046b6a0 lbz REG_Pauser,0x1(r3) #Search all players for this port li REG_Count,0 Loop: mr r3,REG_Count branchl r12,PlayerBlock_LoadMainCharDataOffset cmpwi r3,0 beq IncLoop #Check their port to see if it matches mr r3,REG_Count branchl r12,0x8003345c cmpw r3,REG_Pauser beq FoundPauser IncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,4 blt Loop b Dead FoundPauser: #Check if player is alive mr r3,REG_Count branchl r12,PlayerBlock_LoadMainCharDataOffset lwz r3,0x2C(r3) lbz r3,0x221F(r3) rlwinm. r3,r3,0,25,25 bne Dead Alive: restore branch r12,0x8002c644 Dead: Exit: restore lfs f0, 0x000C (r26) ================================================ FILE: ASM/Additional Codes/Better Camera/Unrestricted Camera.asm ================================================ #To be inserted at 8002f5bc loc_0x0: lis r3, 0x8048 lbz r3, -25240(r3) rlwinm. r3, r3, 0, 30, 30 beq- loc_0x48 lis r3, 0x8048 lbz r3, -25296(r3) cmpwi r3, 0x1C beq- loc_0x48 li r3, 0x0 stw r3, 760(r31) lis r3, 0x4700 stw r3, 744(r31) stw r3, 748(r31) stw r3, 752(r31) stw r3, 756(r31) stw r3, 764(r31) lis r3, 0x8003 b loc_0x50 loc_0x48: lis r3, 0x8003 stfs f1, 764(r31) loc_0x50: ================================================ FILE: ASM/Additional Codes/Boot to CSS/Boot to Main Menu Or CSS.s ================================================ #To be inserted at 801BFA20 .include "../../Globals.s" li r3,2 ================================================ FILE: ASM/Additional Codes/Boot to Event Mode/Boot to Main Menu Or CSS.asm ================================================ #To be inserted at 801BFA20 .include "../../Globals.s" .set LoopCount,12 .set InputStruct,11 #Check if any player is pressing Z li LoopCount,0 load InputStruct,InputStructStart #Loop through inputs InputLoop: mulli r0, LoopCount, 68 add r3, r0, InputStruct lwz r3, 0 (r3) rlwinm. r0,r3,0,21,21 #Check For X bne LoadCSS addi LoopCount,LoopCount,1 cmpwi LoopCount,4 blt InputLoop b LoadEventMenu LoadCSS: #Play SFX li r3,1 branchl r12,SFX_MenuCommonSound li r3,2 b Exit #Boot to Event Menu LoadEventMenu: li r3, 1 Exit: ================================================ FILE: ASM/Additional Codes/Boot to Event Mode/Main Menu Starts at Event Mode.asm ================================================ #To be inserted at 801b02dc .include "../../Globals.s" .set entity,31 .set player,31 .set playerdata,31 #Spoof current (soon to be previous) screen li r3,Scene.EventMode load r4,SceneController stb r3,Scene.CurrentMajor(r4) li r3,0x00 ================================================ FILE: ASM/Additional Codes/CSS KO Star Codes/Calculate KO Stars Upon Exiting Dairantou.asm ================================================ #To be inserted at 8016ebac .include "../../Globals.s" #Check if VS Mode load r3,SceneController lbz r3,Scene.CurrentMajor(r3) cmpwi r3,Scene.VSMode bne Exit #Init Struct? load r3,0x803dda00 #Get Some Scene Struct branchl r12,0x801a5f00 #Wipe and Copy Match Info #Update KO Star Count load r3,0x803dda00 #Get Some Scene Struct lwz r4, -0x77C0 (r13) #Get SSS Struct addi r4, r4, 1424 li r5,0 #Next Minor Scene branchl r12,0x801a5f64 #Update KO Stars #Update VS Records load r3,0x8047c028 #Get Match Info branchl r12,0x801623a4 #Update VS Records Exit: lwz r0, 0x001C (sp) lwz r31, 0x0014 (sp) ================================================ FILE: ASM/Additional Codes/CSS KO Star Codes/Disable KO Star Deletion When Leaving CSS.asm ================================================ #To be inserted at 801a5600 .include "../../Globals.s" nop ================================================ FILE: ASM/Additional Codes/Collision Link Draw Order Fix [Punkline]/New Draw Location.asm ================================================ #To be inserted at 80030288 .include "../../Globals.s" branchl r12,0x80030A78 cmpwi r3, 0 beq- _return # checks for collision link display flag _if_drawing_stage_collisions: branchl r12, 0x80059e60 # moves post-process drawing call to before player draw # causes geometry to be drawn on black/white screen, if enabled simultaneously _return: lbz r0, 0 (r31) ================================================ FILE: ASM/Additional Codes/Collision Link Draw Order Fix [Punkline]/Remove Original Draw.asm ================================================ #To be inserted at 8005a2ec .include "../../Globals.s" nop ================================================ FILE: ASM/Additional Codes/DEBUGLOG.s ================================================ #To be inserted at 801a4cb4 .include "../Globals.s" .set GObj_Create,0x803901f0 .set GObj_AddUserData,0x80390b68 .set GObj_AddProc,0x8038fd54 .set HSD_MemAlloc,0x8037f1e4 .set DevelopText_CreateDataTable,0x80302834 .set DevelopText_Activate,0x80302810 .set DevelopText_AddString,0x80302be4 .set DevelopText_EraseAllText,0x80302bb0 .set DevelopMode_Text_ResetCursorXY,0x80302a3c .set sprintf,0x80323cf4 .set REG_DevelopText,31 .set REG_GObjData,30 .set REG_GObj,29 backup #Create Rectangle li r3,0x348 branchl r12,HSD_MemAlloc mr r8,r3 li r3,6 li r4,0 li r5,0 li r6,20 li r7,7 branchl r12,DevelopText_CreateDataTable mr REG_DevelopText,r3 #Activate Text lwz r3, -0x4884 (r13) mr r4,REG_DevelopText branchl r12,DevelopText_Activate #Hide blinking cursor li r3,0 stb r3,0x26(REG_DevelopText) #Create Background GObj li r3,0 li r4,0 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Allocate Space li r3,64 branchl r12,HSD_MemAlloc mr REG_GObjData,r3 #Zero li r4,64 branchl r12,ZeroAreaLength #Initialize mr r6,REG_GObjData mr r3,REG_GObj li r4,4 load r5,HSD_Free branchl r12,GObj_AddUserData #Add Process mr r3,REG_GObj bl DebugLogThink mflr r4 li r5,0 branchl r12,GObj_AddProc #Store pointer to dev text stw REG_DevelopText,0x0(REG_GObjData) b Exit ######################################## DebugLogThink: blrl .set REG_GObjData,31 backup lwz REG_GObjData,0x2C(r3) #/* #Erase all text lwz r3,0x0(REG_GObjData) branchl r12,DevelopText_EraseAllText lwz r3,0x0(REG_GObjData) li r4,0 li r5,0 branchl r12,DevelopMode_Text_ResetCursorXY #*/ #Check heap lwz r3, -0x58A0 (r13) branchl r12,0x80344168 mr r5,r3 #Display lwz r3,0x0(REG_GObjData) bl String mflr r4 branchl r12,0x80302d4c#DevelopText_AddString DebugLogThink_Exit: restore blr ######################################### String: blrl .string "%d\n bytes free" #08X\n .align 2 Exit: restore li r0, 0 /* load r4,0xCC002002 lhz r3,0x0(r4) ori r3,r3,0x4 sth r3,0x0(r4) li r3, 1 */ ================================================ FILE: ASM/Additional Codes/DPad Down to Random Stage.s ================================================ #To be inserted at 8026325c .include "../Globals.s" #Get Random Stage Byte load r4,0x8045BF17 #Check for DPad Down rlwinm. r0, r7, 0, 29, 29 beq CheckForStart li r3,0x1 stb r3,0x0(r4) branch r12,0x80263264 CheckForStart: #Check for Start rlwinm. r0, r7, 0, 19, 19 beq Exit li r3,0x0 stb r3,0x0(r4) #Original Codeline Exit: rlwinm. r0, r7, 0, 19, 19 ================================================ FILE: ASM/Additional Codes/Debug Mode Codes/Debug Language is English by Default.asm ================================================ #To be inserted at 803fa258 .long 0x00000001 ================================================ FILE: ASM/Additional Codes/Debug Mode Codes/Exiting Debug Goes to Main Menu.asm ================================================ #To be inserted at 801B0A14 li r3, 1 ================================================ FILE: ASM/Additional Codes/Debug Mode Codes/Tournament Mode Goes to Debug.asm ================================================ #To be inserted at 8022D638 li r0, 6 ================================================ FILE: ASM/Additional Codes/Default Tournament Settings/4 Stocks.asm ================================================ #To be inserted at 803D4A4C .long 0x04000A00 ================================================ FILE: ASM/Additional Codes/Default Tournament Settings/8 Minutes.asm ================================================ #To be inserted at 803D4A50 .long 0x08010100 ================================================ FILE: ASM/Additional Codes/Default Tournament Settings/No Items.asm ================================================ #To be inserted at 803D4A60 .long 0xFF000000 ================================================ FILE: ASM/Additional Codes/Default Tournament Settings/Stock Mode.asm ================================================ #To be inserted at 803D4A48 .long 0x00340000 ================================================ FILE: ASM/Additional Codes/Default Tournament Settings/Tournament Stages.asm ================================================ #To be inserted at 803D4A78 .long 0xE70000B0 ================================================ FILE: ASM/Additional Codes/Delete Bootup OSReports.asm ================================================ #To be inserted at 80160154 .include "../Globals.s" # Remove all previous OSReports load r3,0x804cf7e8 li r4,0 stw r4,0xC(r3) li r0, 0 ================================================ FILE: ASM/Additional Codes/Disable CSS Anim Loop.s ================================================ #To be inserted at 80263384 b 0x10 ================================================ FILE: ASM/Additional Codes/Disable FoD Reflection.asm ================================================ #To be inserted at 8008114c .include "../Globals.s" .set REG_ReflectCallback,31 #Save reflection callback mr r3,r0 backup mr REG_ReflectCallback,r3 #Count player gobjs branchl r12,0x800860c4 #CountPlayers #Check if 4 or more cmpwi r3,4 blt ShowReflect #Dont draw reflection li r3,0 b Exit ShowReflect: mr r3,REG_ReflectCallback b Exit Exit: restore mr r0,r3 lwz r4,GObj_Lists(r13) lwz r3, 0x0020 (r4) ================================================ FILE: ASM/Additional Codes/Disable FoD in Doubles.asm ================================================ #To be inserted at 80266ce0 .include "../Globals.s" ####################################### ## Runs During CSS -> SSS Transition ## ####################################### .set REG_RandomStageField,5 .set REG_RulesPointer,6 #Ensure only all other legal stages are enabled #Get Random Stage Select Bitflags lwz REG_RulesPointer, -0x77C0 (r13) addi REG_RulesPointer, REG_RulesPointer, 7344 lwz REG_RandomStageField,0x18(REG_RulesPointer) #Check if only all legal stages are on load r3,0xE70000B0 xor. r3,r3,REG_RandomStageField beq CheckForTeams #Check if the only other stage off is FoD cmpwi r3,0x20 beq CheckForTeams b Exit CheckForTeams: #Get Teams On/Off Bool lwz r3, -0x49F0 (r13) lbz r3,0x18(r3) #Check If Teams is On or Off cmpwi r3,0x1 beq Doubles Singles: #Flip FoD Bit On in Random Stage Bitflag (FoD is bit #26) li r3,0x1 rlwimi REG_RandomStageField,r3,5,26,26 stw REG_RandomStageField,0x18(REG_RulesPointer) b Exit Doubles: #Flip FoD Bit Off in Random Stage Bitflag (FoD is bit #26) li r3,0x0 rlwimi REG_RandomStageField,r3,5,26,26 stw REG_RandomStageField,0x18(REG_RulesPointer) b Exit Exit: li r3, 1 ================================================ FILE: ASM/Additional Codes/Disable Item Spawn in Develop Mode.asm ================================================ #To be inserted at 80226530 .include "../Globals.s" nop ================================================ FILE: ASM/Additional Codes/Disable Item Spawn in Develop Mode.s ================================================ #To be inserted at 80226530 .include "../Globals.s" nop ================================================ FILE: ASM/Additional Codes/Disable Rumble on Unplug.asm ================================================ #To be inserted at 803775a4 .include "../Globals.s" #Check if unplugged lbz r3, 0x000A (r25) #current read extsb r3,r3 cmpwi r3,-1 bne Original lbz r3, 0x0041 (r26) #prev read extsb. r3,r3 bne Original #Disable rumble mr r3,r24 li r4,0 branchl r12,Rumble_StoreRumbleFlag Original: lbz r0, 0x000A (r25) ================================================ FILE: ASM/Additional Codes/Disable Special Records/Disable Special Messages.asm ================================================ #To be inserted at 80173eec blr ================================================ FILE: ASM/Additional Codes/Disable Special Records/Disable Trophy Messages.asm ================================================ #To be inserted at 80172898 blr ================================================ FILE: ASM/Additional Codes/Display Animation Name for Special Moves in Develop Mode/Display Animation Name for Special Moves in Develop Mode.asm ================================================ #To be inserted at 80226acc .include "../../Globals.s" .set entity,31 .set playerdata,28 .set player,29 #Get Animation Data Pointer mr r3,playerdata lwz r4,0x14(playerdata) branchl r12,0x80085fd4 #Get Move Name String lwz r3,0x0(r3) #Get Start of Move Name StringSearchLoop: lbzu r4,0x1(r3) cmpwi r4,0x4E #Check For "N" bne StringSearchLoop lbzu r4,0x1(r3) cmpwi r4,0x5F #Check for Underscore bne StringSearchLoop addi r3,r3,0x1 #Start of Move Name in r3 #Copy Move Name To Cut Off "fiagtree" Text bl StringSpace mflr r5 subi r4,r5,0x1 subi r3,r3,0x1 StringCopyLoop: lbzu r6,0x1(r3) cmpwi r6,0x5F #Check for Underscore beq ExitCopyLoop stbu r6,0x1(r4) b StringCopyLoop ExitCopyLoop: li r3,0x0 stbu r3,0x1(r4) mr r4,r5 b exit StringSpace: blrl .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 exit: mr r3,r31 crclr 6 ================================================ FILE: ASM/Additional Codes/Display Ungrabbable Hurtboxes/Main.asm ================================================ #To be inserted at 8000a284 .include "../../Globals.s" #Check if vuln cmpwi r6,0 bne Exit #Check if this is an ungrabbable hurtbox lwz r0,0x48(r28) cmpwi r0,0 bne Exit #Override color bl Color mflr r3 b Skip Color: blrl .long 0xAB27FF80 Exit: lwz r3, 0 (r3) Skip: ================================================ FILE: ASM/Additional Codes/Enable 1P in VS Mode No Time.asm ================================================ #To be inserted at 80263064 .include "../Globals.s" .set REG_ReadyPlayers,31 backup #Backup players mr REG_ReadyPlayers,r4 #Check if mode is set to time branchl r12,LoadRulesSettingsPointer1 lbz r4,0x2(r3) cmpwi r4,0 bne Check2Players #Check if time is set to none lbz r4,0x3(r3) cmpwi r4,0 bne Check2Players Check1Player: #Check for 1 players cmpwi REG_ReadyPlayers,1 b Exit Check2Players: #Check for 2 players cmpwi REG_ReadyPlayers,2 Exit: restore ================================================ FILE: ASM/Additional Codes/Enable C Stick Always/Enable CStick for CPU in Debug.asm ================================================ #To be inserted at 8006ae00 nop ================================================ FILE: ASM/Additional Codes/Enable C Stick Always/Rotate Camera with Dpad Down and C Stick - Initiate.asm ================================================ #To be inserted at 802274f0 .include "../../Globals.s" #Get Inputs load r4,0x804c1fac mulli r3,r30,68 add r3,r3,r4 #Check for dpad down lwz r3,0x0(r3) rlwinm. r3,r3,0,29,29 bne Original #Exit branch r12,0x802275f4 Original: lfs f0, -0x3CA4 (rtoc) ================================================ FILE: ASM/Additional Codes/Enable C Stick Always/Rotate Camera with Dpad Down and C Stick.asm ================================================ #To be inserted at 80227b70 .include "../../Globals.s" #Get Inputs load r4,0x804c1fac add r4,r4,r5 #Check for dpad down lwz r4,0x0(r4) rlwinm. r4,r4,0,29,29 bne Original #Exit branch r12,0x80227b98 Original: lfs f0, -0x3CA4 (rtoc) ================================================ FILE: ASM/Additional Codes/Enable C Stick Always/Single Player Always Returns False.asm ================================================ #To be inserted at 8016B480 nop ================================================ FILE: ASM/Additional Codes/Enable C Stick Always/Spoof Debug Level as 0 for Human C Stick Inputs.asm ================================================ #To be inserted at 8006AE90 li r0, 0 ================================================ FILE: ASM/Additional Codes/Faster CSS Load.asm ================================================ #To be inserted at 802641B0 li r0, 1 ================================================ FILE: ASM/Additional Codes/Frame Advance Audio.s ================================================ #To be inserted at 80359750 .include "../Globals.s" load r5,0x80479d48 # If game unpaused, play sound lbz r3,0x20(r5) rlwinm. r0,r3,0,0x1 beq Original # Game is paused, check if advancing this frame lbz r3,0x22(r5) rlwinm. r0,r3,0,0x1 bne Original # Skip audio update branch r12,0x80359830 Original: mr r3, r30 ================================================ FILE: ASM/Additional Codes/GX Draw/Main.s ================================================ #To be inserted at 80080e40 .include "../../Globals.s" .set REG_PlayerData,30 .set REG_Interrupt,28 backup #check for renderpass 2 cmpwi r29,2 bne Exit bl FirefoxTrajectory bl DIDraw b Exit #region Firefox Trajectory FirefoxTrajectory_Constants: blrl .set ECB_TopY,0x0 #scale * value .set ECB_BottomY,0x4 #neg(scale * vlaue) .set ECB_LeftX,0x8 #neg(scale * vlaue) .set ECB_LeftY,0xC #0 .set ECB_RightX,0x10 #scale * value .set ECB_RightY,0x14 #0 .set FinalAnimYDifference,0x18 .set Float2,0x1C .set FirefoxDrawZ,0x20 .set LineColor,0x24 .set LeftWallColor,0x28 .set RightWallColor,0x2C .set CeilingColor,0x30 .set GroundColor,0x34 .float 9 .float 2.5 .float -3.3 .float 5.7 .float 3.3 .float 5.7 .float 0.4 .float 2 .float 10 .byte 0, 138, 255, 255 .byte 12, 255, 41, 255 .byte 12, 255, 41, 255 .byte 255, 55, 55, 255 .byte 255, 255, 255, 255 .set StackSize,0x300 .set Stack_BackedUpReg,0x8 .set Stack_BackedUpReg_Length,0x30 .set Stack_BackedUpFloats, (Stack_BackedUpReg+Stack_BackedUpReg_Length) .set Stack_BackedUpFloats_Length,0x14 .set Stack_ECBBoneStruct, (Stack_BackedUpFloats+Stack_BackedUpFloats_Length) .set Stack_ECBBoneStruct_Length,0x18 .set Stack_ECBStruct, (Stack_ECBBoneStruct+Stack_ECBBoneStruct_Length) .set Stack_ECBStruct_Length,0x1AC .set Stack_MiscSpace, (Stack_ECBStruct+Stack_ECBStruct_Length) #gprs .set REG_EventConstants,31 .set REG_ECBStruct,20 .set REG_ECBBoneStruct,21 .set REG_LoopCount,22 .set REG_GX,23 .set REG_CObjBackup,24 #fprs .set REG_arctan,31 .set REG_XComp,30 .set REG_YComp,31 .set REG_XPerFrame,29 .set REG_YPerFrame,28 .set REG_CurrXPos,27 .set REG_CurrYPos,26 #constants .set RandomAngleRange,20 FirefoxTrajectory: mflr r0 stw r0, 0x4(r1) stwu r1,-StackSize(r1) # make space for 12 registers stmw r20,Stack_BackedUpReg(r1) #Check for firefox trajectory lwz r3,0x4(REG_PlayerData) cmpwi r3,Fox.Int beq FirefoxTrajectory_isSpacie cmpwi r3,Falco.Int beq FirefoxTrajectory_isSpacie b FirefoxTrajectory_Exit FirefoxTrajectory_isSpacie: #Check if in up b hold lwz r3,0x10(REG_PlayerData) cmpwi r3,353 beq FirefoxTrajectory_isFirefoxHold cmpwi r3,354 beq FirefoxTrajectory_isFirefoxHold b FirefoxTrajectory_Exit FirefoxTrajectory_isFirefoxHold: #Get Floats bl FirefoxTrajectory_Constants mflr REG_EventConstants #If frame advance && HMN, use HW inputs li r3,0 branchl r12,0x801a45e8 cmpwi r3,1 bne FirefoxTrajectory_PBInputs lbz r3,0xC(REG_PlayerData) branchl r12,0x8003241c cmpwi r3,0x0 bne FirefoxTrajectory_PBInputs FirefoxTrajectory_HWInputs: load r3,HSD_InputStructStart lbz r4,0x618(REG_PlayerData) mulli r4,r4,68 add r3,r3,r4 lfs REG_XComp,InputStruct_LeftAnalogXFloat(r3) lfs REG_YComp,InputStruct_LeftAnalogYFloat(r3) #If Holding A, override and use PB Inputs lwz r0,InputStruct_HeldButtons(r3) rlwinm. r0,r0,0,0x100 bne FirefoxTrajectory_PBInputs #Now apply deadzone lfs f0, -0x778C (rtoc) lwz r3, -0x514C (r13) lfs f1, 0 (r3) fmr f2,REG_XComp fcmpo cr0,f2,f0 bge 0x8 fneg f2,f2 fcmpo cr0,f2,f1 bge 0x8 lfs REG_XComp, -0x778C (rtoc) fmr f2,REG_YComp fcmpo cr0,f2,f0 bge 0x8 fneg f2,f2 fcmpo cr0,f2,f1 bge 0x8 lfs REG_YComp, -0x778C (rtoc) b FirefoxTrajectory_GetInputsEnd FirefoxTrajectory_PBInputs: lfs REG_XComp,0x620(REG_PlayerData) lfs REG_YComp,0x624(REG_PlayerData) FirefoxTrajectory_GetInputsEnd: #Get atan2 fmr f1,REG_YComp lfs f2,0x2C(REG_PlayerData) fmuls f2,f2,REG_XComp branchl r12,0x80022c30 fmr REG_arctan,f1 #Get XComp fmr f1,REG_arctan branchl r12,0x80326240 fmr REG_XComp,f1 fmr f1,REG_arctan branchl r12,0x803263d4 fmr REG_YComp,f1 #Get Firefox distance per frame lwz r3, 0x02D4 (REG_PlayerData) lfs f1, 0x0074 (r3) lfs f0, 0x002C (REG_PlayerData) fmuls f1,f1,REG_XComp fmuls REG_XPerFrame,f1,f0 lfs f1, 0x0074 (r3) fmuls REG_YPerFrame,f1,REG_YComp #Create an ECB struct on the stack addi REG_ECBBoneStruct,sp,Stack_ECBBoneStruct addi REG_ECBStruct,sp,Stack_ECBStruct mr r3,REG_ECBStruct branchl r12,0x80041ee4 #Create ECB Bone struct /* 0x00 = ECB Current Top Y Offset scale * value 0x04 = ECB Current Bottom Y Offset neg(scale * vlaue) 0x08 = ECB Current Left X Offset neg(scale * vlaue) 0x0C = ECB Current Left Y Offset 0 0x10 = ECB Current Right X Offset scale * value 0x14 = ECB Current Right Y Offset 0 */ #Copy Struct mr r3,REG_ECBBoneStruct addi r4,REG_EventConstants,ECB_TopY li r5,0x18 branchl r12,memcpy #Place Current XY into struct lfs REG_CurrXPos,0xB0(REG_PlayerData) lfs REG_CurrYPos,0xB4(REG_PlayerData) #Subtract 0.4 to account for the frame of animation left in this state lfs f1,FinalAnimYDifference(REG_EventConstants) fsubs REG_CurrYPos,REG_CurrYPos,f1 lfs f1,0xB8(REG_PlayerData) stfs f1,0x24(REG_ECBStruct) #Init Loop li REG_LoopCount,0 #Init GX Prim lwz r5, 0x02D4 (REG_PlayerData) lfs f1, 0x0068 (r5) fctiwz f1,f1 stfd f1,Stack_MiscSpace(sp) lwz r3,Stack_MiscSpace+4(sp) load r4,0x001F1305 load r5,0x00001455 branchl r12,prim.new mr REG_GX,r3 FirefoxTrajectory_CollisionLoop: #Store current position stfs REG_CurrXPos,0x4(REG_ECBStruct) stfs REG_CurrYPos,0x8(REG_ECBStruct) lfs f1, -0x778C (rtoc) stfs f1,0xC(REG_ECBStruct) #Check if frame X or greater lwz r5, 0x02D4 (REG_PlayerData) lfs f1,0x70(r5) fctiwz f1,f1 stfd f1,Stack_MiscSpace(sp) lwz r3,Stack_MiscSpace+4(sp) cmpw REG_LoopCount,r3 blt FirefoxTrajectory_CollisionLoop_SkipDecay FirefoxTrajectory_CollisionLoop_Decay: lfs f1,0x78(r5) fmuls f1,f1,REG_XComp lfs f2, 0x002C (REG_PlayerData) fmuls f1,f1,f2 fsubs REG_XPerFrame,REG_XPerFrame,f1 lfs f1,0x78(r5) fmuls f1,f1,REG_YComp fsubs REG_YPerFrame,REG_YPerFrame,f1 FirefoxTrajectory_CollisionLoop_SkipDecay: #Shift previous positions down lfs f1,0x4(REG_ECBStruct) lfs f2,0x8(REG_ECBStruct) lfs f3,0xC(REG_ECBStruct) stfs f1,0x1C(REG_ECBStruct) stfs f2,0x20(REG_ECBStruct) stfs f3,0x24(REG_ECBStruct) #Store next position fadds f1,REG_CurrXPos,REG_XPerFrame stfs f1,0x4(REG_ECBStruct) fadds f1,REG_CurrYPos,REG_YPerFrame stfs f1,0x8(REG_ECBStruct) lfs f1, -0x778C (rtoc) stfs f1,0xC(REG_ECBStruct) #Run collision mr r3,REG_ECBStruct mr r4,REG_ECBBoneStruct branchl r12,0x800475f4#0x800473cc #Drop through platforms cmpwi r3,0 beq FirefoxTrajectory_CollisionLoop_SkipPlatform mr r3,REG_ECBStruct branchl r12,0x8004cbc0 cmpwi r3,0 beq FirefoxTrajectory_CollisionLoop_SkipPlatform lwz r0, 0x014C (REG_ECBStruct) stw r0, 0x003C (REG_ECBStruct) FirefoxTrajectory_CollisionLoop_SkipPlatform: #Get new position lfs REG_CurrXPos,0x4(REG_ECBStruct) lfs REG_CurrYPos,0x8(REG_ECBStruct) #Inc Collision ID lwz r3,0x38(REG_ECBStruct) addi r3,r3,1 stw r3,0x38(REG_ECBStruct) #Determine line color lwz r3,0x134(REG_ECBStruct) rlwinm. r0,r3,0,0x8000 bne FirefoxTrajectory_CollisionLoop_TouchingGround rlwinm. r0,r3,0,0x6000 bne FirefoxTrajectory_CollisionLoop_TouchingCeiling rlwinm. r0,r3,0,0x20 bne FirefoxTrajectory_CollisionLoop_TouchingLeftWall rlwinm. r0,r3,0,0x40 bne FirefoxTrajectory_CollisionLoop_TouchingLRightWall FirefoxTrajectory_CollisionLoop_TouchingNothing: lwz r4,LineColor(REG_EventConstants) b FirefoxTrajectory_CollisionLoop_GetColorEnd FirefoxTrajectory_CollisionLoop_TouchingGround: lwz r4,GroundColor(REG_EventConstants) b FirefoxTrajectory_CollisionLoop_GetColorEnd FirefoxTrajectory_CollisionLoop_TouchingCeiling: lwz r4,CeilingColor(REG_EventConstants) b FirefoxTrajectory_CollisionLoop_GetColorEnd FirefoxTrajectory_CollisionLoop_TouchingLeftWall: lwz r4,LeftWallColor(REG_EventConstants) b FirefoxTrajectory_CollisionLoop_GetColorEnd FirefoxTrajectory_CollisionLoop_TouchingLRightWall: lwz r4,RightWallColor(REG_EventConstants) b FirefoxTrajectory_CollisionLoop_GetColorEnd FirefoxTrajectory_CollisionLoop_GetColorEnd: #Draw this point lfs f1,0x84(REG_ECBStruct) fadds f1,REG_CurrXPos,f1 lfs f2,0x88(REG_ECBStruct) lfs f3,Float2(REG_EventConstants) fdivs f2,f2,f3 fadds f2,REG_CurrYPos,f2 lfs f3,FirefoxDrawZ(REG_EventConstants) mr r3,REG_GX stfs f1,0x0(r3) stfs f2,0x0(r3) stfs f3,0x0(r3) stw r4,0x0(r3) #Inc Loop addi REG_LoopCount,REG_LoopCount,1 lwz r5, 0x02D4 (REG_PlayerData) lfs f1, 0x0068 (r5) fctiwz f1,f1 stfd f1,Stack_MiscSpace(sp) lwz r3,Stack_MiscSpace+4(sp) cmpw REG_LoopCount,r3 blt FirefoxTrajectory_CollisionLoop #End Loop branchl r12,prim.close FirefoxTrajectory_Exit: lmw r20,Stack_BackedUpReg(r1) lwz r0, StackSize+4(r1) addi r1,r1,StackSize # release the space mtlr r0 blr #################################################### #endregion #region DI Draw DIDraw_Constants: blrl .set ECB_TopY,0x0 #scale * value .set ECB_BottomY,0x4 #neg(scale * vlaue) .set ECB_LeftX,0x8 #neg(scale * vlaue) .set ECB_LeftY,0xC #0 .set ECB_RightX,0x10 #scale * value .set ECB_RightY,0x14 #0 .set FirefoxDrawZ,0x18 .set AliveLineColor,0x1C .set DeadLineColor,0x20 .set LeftWallColor,0x24 .set RightWallColor,0x28 .set CeilingColor,0x2C .set GroundColor,0x30 .set ASDIColor,0x34 .float 9 .float 2.5 .float -3.3 .float 5.7 .float 3.3 .float 5.7 .float 10 .byte 0, 138, 255, 255 .byte 255, 55, 55, 255 .byte 12, 255, 41, 255 .byte 12, 255, 41, 255 .byte 255, 0, 255, 255 .byte 255, 255, 255, 255 .byte 255, 86, 20, 255 .set StackSize,0x300 .set Stack_BackedUpReg,0x8 .set Stack_BackedUpReg_Length,0x30 .set Stack_BackedUpFloats, (Stack_BackedUpReg+Stack_BackedUpReg_Length) .set Stack_BackedUpFloats_Length,0x14 .set Stack_ECBBoneStruct, (Stack_BackedUpFloats+Stack_BackedUpFloats_Length) .set Stack_ECBBoneStruct_Length,0x18 .set Stack_ECBStruct, (Stack_ECBBoneStruct+Stack_ECBBoneStruct_Length) .set Stack_ECBStruct_Length,0x1AC .set Stack_ASDIBackup, (Stack_ECBStruct+Stack_ECBStruct_Length) .set Stack_ASDIBackup_Length,0x8 .set Stack_MiscSpace, (Stack_ASDIBackup+Stack_ASDIBackup_Length) #gprs .set REG_EventConstants,31 .set REG_ECBStruct,20 .set REG_ECBBoneStruct,21 .set REG_LoopCount,22 .set REG_GX,23 .set REG_HeldInputs,24 .set REG_GroundState,24 .set REG_CollisionInfo,25 .set REG_Temp,26 #this register is used for the draw loop, make sure to change both .set REG_OverrideRemainingFrames,27 #fprs .set REG_arctan,31 .set REG_XComp,30 .set REG_YComp,29 .set REG_KnockbackX,28 .set REG_KnockbackY,27 .set REG_CurrXPos,26 .set REG_CurrYPos,25 .set REG_DIInput,24 .set REG_KnockbackMag,23 .set REG_CStickX,22 .set REG_CStickY,21 .set REG_ASDIX,22 .set REG_ASDIY,21 .set REG_Gravity,30 #constants .set MaxColl,40 DIDraw: mflr r0 stw r0, 0x4(r1) stwu r1,-StackSize(r1) # make space for 12 registers stmw r20,Stack_BackedUpReg(r1) #Check for DI Draw lbz r3,0x221A(REG_PlayerData) #Check If in Hitlag rlwinm. r3,r3,0,0x20 beq DIDraw_Exit lbz r3, 0x221C (REG_PlayerData) rlwinm. r0,r3,0,0x2 beq DIDraw_Exit #Get Floats bl DIDraw_Constants mflr REG_EventConstants #region GetInputs #If frame advance && HMN, use HW inputs li r3,0 branchl r12,0x801a45e8 cmpwi r3,1 bne DIDraw_PBInputs lbz r3,0xC(REG_PlayerData) branchl r12,0x8003241c cmpwi r3,0x0 bne DIDraw_PBInputs DIDraw_HWInputs: load r3,HSD_InputStructStart lbz r4,0x618(REG_PlayerData) mulli r4,r4,68 add r3,r3,r4 #If Holding A, override and use PB Inputs lwz r0,InputStruct_HeldButtons(r3) rlwinm. r0,r0,0,0x100 bne DIDraw_PBInputs lfs REG_XComp,InputStruct_LeftAnalogXFloat(r3) lfs REG_YComp,InputStruct_LeftAnalogYFloat(r3) lfs REG_CStickX,InputStruct_RightAnalogXFloat(r3) lfs REG_CStickY,InputStruct_RightAnalogYFloat(r3) #Get L/R input lwz REG_HeldInputs,InputStruct_HeldButtons(r3) rlwinm. r0,REG_HeldInputs,0,0x20 bne DIDraw_HWInputs_PressingLR rlwinm. r0,REG_HeldInputs,0,0x40 bne DIDraw_HWInputs_PressingLR DIDraw_HWInputs_NoLR: li REG_HeldInputs,0 b 0x8 DIDraw_HWInputs_PressingLR: lis REG_HeldInputs,0x8000 #Now apply analog deadzone lfs f0, -0x778C (rtoc) lwz r3, -0x514C (r13) lfs f1, 0 (r3) fmr f2,REG_XComp fcmpo cr0,f2,f0 bge 0x8 fneg f2,f2 fcmpo cr0,f2,f1 bge 0x8 lfs REG_XComp, -0x778C (rtoc) fmr f2,REG_YComp fcmpo cr0,f2,f0 bge 0x8 fneg f2,f2 fcmpo cr0,f2,f1 bge 0x8 lfs REG_YComp, -0x778C (rtoc) #Now apply cstick deadzone lfs f0, -0x778C (rtoc) lwz r3, -0x514C (r13) lfs f1, 0 (r3) fmr f2,REG_CStickX fcmpo cr0,f2,f0 bge 0x8 fneg f2,f2 fcmpo cr0,f2,f1 bge 0x8 lfs REG_CStickX, -0x778C (rtoc) fmr f2,REG_CStickY fcmpo cr0,f2,f0 bge 0x8 fneg f2,f2 fcmpo cr0,f2,f1 bge 0x8 lfs REG_CStickY, -0x778C (rtoc) b DIDraw_GetInputsEnd DIDraw_PBInputs: lfs REG_XComp,0x620(REG_PlayerData) lfs REG_YComp,0x624(REG_PlayerData) lwz REG_HeldInputs,0x65C(REG_PlayerData) lfs REG_CStickX,0x638(REG_PlayerData) lfs REG_CStickY,0x63C(REG_PlayerData) DIDraw_GetInputsEnd: #endregion #Get original KB vector lfs REG_KnockbackX,0x8C(REG_PlayerData) lfs REG_KnockbackY,0x90(REG_PlayerData) #Calculate player's influence over trajectory #region GetArctan DIDraw_GetArctan: #Get atan2 fmr f1,REG_KnockbackY fmr f2,REG_KnockbackX branchl r12,0x80022c30 fmr REG_arctan,f1 #Do something fmuls f1,REG_KnockbackY,REG_KnockbackY fmadds REG_KnockbackMag,REG_KnockbackX,REG_KnockbackX,f1 lfs f0, -0x750C (rtoc) fcmpo cr0,REG_KnockbackMag,f0 ble DIDraw_SkipUnk #Do a bunch of stuff frsqrte f2,REG_KnockbackMag lfd f4, -0x74E0 (rtoc) lfd f3, -0x74D8 (rtoc) fmul f0,f2,f2 fmul f2,f4,f2 fnmsub f0,REG_KnockbackMag,f0,f3 fmul f2,f2,f0 fmul f0,f2,f2 fmul f2,f4,f2 fnmsub f0,REG_KnockbackMag,f0,f3 fmul f2,f2,f0 fmul f0,f2,f2 fmul f2,f4,f2 fnmsub f0,REG_KnockbackMag,f0,f3 fmul f0,f2,f0 fmul f0,REG_KnockbackMag,f0 frsp f0,f0 fmr REG_KnockbackMag,f0 DIDraw_SkipUnk: #endregion #region CalculateASDI DIDraw_CalculateASDI: #CStick has priority #Check if cstick magnitude > 0.7 fmuls f1,REG_CStickX,REG_CStickX fmuls f0,REG_CStickY,REG_CStickY lwz r3, -0x514C (r13) lfs f2, 0x04B0 (r3) fadds f1,f1,f0 fmuls f0,f2,f2 fcmpo cr0,f1,f0 bge DIDraw_CalculateASDICStickApply #Now check left stick fmuls f1,REG_YComp,REG_YComp fmuls f2,REG_XComp,REG_XComp lwz r3, -0x514C (r13) lfs f0, 0x04B0 (r3) fmuls f0,f0,f0 fadds f1,f1,f2 fcmpo cr0,f1,f0 blt DIDraw_CalculateASDINone DIDraw_CalculateASDILeftStickApply: #Multiply by 3 lfs f1, 0x04BC (r3) fmuls REG_ASDIX,REG_XComp,f1 fmuls REG_ASDIY,REG_YComp,f1 b DIDraw_CalculateASDIEnd DIDraw_CalculateASDINone: #Null ASDI lfs REG_ASDIX, -0x750C (rtoc) lfs REG_ASDIY, -0x750C (rtoc) b DIDraw_CalculateASDIEnd DIDraw_CalculateASDICStickApply: #Multiply by 3 lfs f1, 0x04BC (r3) fmuls REG_ASDIX,REG_CStickX,f1 fmuls REG_ASDIY,REG_CStickY,f1 DIDraw_CalculateASDIEnd: #Save these values for later stfs REG_ASDIX,Stack_ASDIBackup+0(sp) stfs REG_ASDIY,Stack_ASDIBackup+4(sp) #endregion #region CalculateKBReduction DIDraw_CalculateKBReduction: #Check if holding L/R/Z rlwinm. r0,REG_HeldInputs,0,0x80000000 beq DIDraw_CalculateKBReductionEnd lwz r3, -0x514C (r13) lfs f0, 0x01AC (r3) fmuls REG_KnockbackMag,f0,REG_KnockbackMag fmr f1,REG_arctan branchl r12,cos fmuls REG_KnockbackX,f1,REG_KnockbackMag fmr f1,REG_arctan branchl r12,sin fmuls REG_KnockbackY,f1,REG_KnockbackMag #Get new atan2 fmr f1,REG_KnockbackY fmr f2,REG_KnockbackX branchl r12,0x80022c30 fmr REG_arctan,f1 DIDraw_CalculateKBReductionEnd: #endregion #region CalculateDI DIDraw_CalculateDI: #If grounded, skip DI lwz r3,0xE0(REG_PlayerData) cmpwi r3,0 beq DIDraw_CalculateDIEnd #If both inputting nothing, skip DI lfs f1, -0x750C (rtoc) fcmpo cr0,f1,REG_XComp bne DIDraw_IsInputting fcmpo cr0,f1,REG_YComp beq DIDraw_CalculateDIEnd DIDraw_IsInputting: #If some condition is met, skip DI lfs f0, -0x74E8 (rtoc) fneg f1,REG_KnockbackX fmuls f1,f1,f1 fmuls f2,REG_KnockbackY,REG_KnockbackY fadds f1,f1,f2 fcmpo cr0,f1,f0 blt DIDraw_CalculateDIEnd #Get DI value fneg f2,REG_KnockbackX fmuls f2,f2,REG_YComp fmuls f3,REG_KnockbackY,REG_XComp fadds f2,f2,f3 fmuls f2,f2,f2 fdivs REG_DIInput,f2,f1 lfs f4, -0x750C (rtoc) #Cross product stfs REG_XComp,Stack_MiscSpace+0(sp) stfs REG_YComp,Stack_MiscSpace+4(sp) lfs f0, -0x750C (rtoc) stfs f0,Stack_MiscSpace+8(sp) addi r3,REG_PlayerData,0x8C addi r4,sp,Stack_MiscSpace+0 addi r5,sp,Stack_MiscSpace+12 branchl r12,0x80342e58 #Check if over 0 lfs f0, -0x750C (rtoc) lfs f1,Stack_MiscSpace+20(sp) fcmpo cr0,f1,f0 bge 0x8 fneg REG_DIInput,REG_DIInput #Apply new angle lwz r3, -0x514C (r13) lfs f2, -0x7510 (rtoc) lfs f0, 0x01A8 (r3) fmuls f0,f2,f0 fmadds REG_arctan,f0,REG_DIInput,REG_arctan fmr f1,REG_arctan branchl r12,cos fmuls REG_KnockbackX,REG_KnockbackMag,f1 fmr f1,REG_arctan branchl r12,sin fmuls REG_KnockbackY,REG_KnockbackMag,f1 DIDraw_CalculateDIEnd: #endregion #Perform collision checks for each frame of hitstun #region DIDraw_Collision #region DIDraw_CollisionLoop_Init DIDraw_CollisionLoop_Init: #Create an ECB struct on the stack addi REG_ECBBoneStruct,sp,Stack_ECBBoneStruct addi REG_ECBStruct,sp,Stack_ECBStruct mr r3,REG_ECBStruct branchl r12,0x80041ee4 #Get Current XY lfs REG_CurrXPos,0xB0(REG_PlayerData) lfs REG_CurrYPos,0xB4(REG_PlayerData) #Init Loop li REG_LoopCount,0 lfs REG_Gravity,-0x750C (rtoc) lwz REG_GroundState,0xE0(REG_PlayerData) li REG_OverrideRemainingFrames,0 #Allocate collision info struct lfs f1,0x2340(REG_PlayerData) fctiwz f1,f1 stfd f1,Stack_MiscSpace(sp) lwz r3,Stack_MiscSpace+4(sp) mulli r3,r3,CollInfo_Length #backing up X bytes per collision check addi r3,r3,0x4 #small header containing the amount of collision checks branchl r12,HSD_MemAlloc mr REG_CollisionInfo,r3 #Init collision info struct li r3,-1 #init as 0 checks stw r3,0x0(REG_CollisionInfo) #If grounded, copy over ground ECB data cmpwi REG_GroundState,0 bne DIDraw_DrawTrajectory_SkipCopyGroundData addi r3,REG_ECBStruct,0x130 addi r4,REG_PlayerData,0x820 li r5,0x28 branchl r12,memcpy DIDraw_DrawTrajectory_SkipCopyGroundData: #endregion #region DIDraw_CollisionLoop_Start DIDraw_CollisionLoop: #region Initalize ECB Bone Positions #Create ECB Bone struct #If loop count < noECBUpdate-remaining hitlag fraes, use current ECB bottom Y offset lwz r3,0x88C(REG_PlayerData) lfs f1,0x195C(REG_PlayerData) fctiwz f1,f1 stfd f1,Stack_MiscSpace(sp) lwz r4,Stack_MiscSpace+0x4(sp) sub r3,r3,r4 cmpw REG_LoopCount,r3 blt DIDraw_CollisionLoop_ECBBonesUseCurrent #Copy Struct mr r3,REG_ECBBoneStruct addi r4,REG_EventConstants,ECB_TopY li r5,0x18 branchl r12,memcpy #If the player is grounded, ECB bottom is 0 cmpwi REG_GroundState,0 bne DIDraw_CollisionLoop_ECBBonesEnd lfs f1, -0x750C (rtoc) stfs f1,0x04(REG_ECBBoneStruct) b DIDraw_CollisionLoop_ECBBonesEnd DIDraw_CollisionLoop_ECBBonesUseCurrent: #Use Current Bone Positions lfs f1,0x778(REG_PlayerData) stfs f1,0x00(REG_ECBBoneStruct) lfs f1,0x780(REG_PlayerData) stfs f1,0x04(REG_ECBBoneStruct) lfs f1,0x78C(REG_PlayerData) stfs f1,0x08(REG_ECBBoneStruct) lfs f1,0x790(REG_PlayerData) stfs f1,0x0C(REG_ECBBoneStruct) lfs f1,0x784(REG_PlayerData) stfs f1,0x10(REG_ECBBoneStruct) lfs f1,0x788(REG_PlayerData) stfs f1,0x14(REG_ECBBoneStruct) b DIDraw_CollisionLoop_ECBBonesEnd DIDraw_CollisionLoop_ECBBonesEnd: #Store current position lfs f1, -0x750C (rtoc) stfs REG_CurrXPos,0x4(REG_ECBStruct) stfs REG_CurrYPos,0x8(REG_ECBStruct) stfs f1,0xC(REG_ECBStruct) stfs REG_CurrXPos,0x10(REG_ECBStruct) stfs REG_CurrYPos,0x14(REG_ECBStruct) stfs f1,0x18(REG_ECBStruct) #endregion #region Apply ASDI DIDraw_CollisionLoop_ApplyASDI: #Apply ASDI X fadds REG_CurrXPos,REG_CurrXPos,REG_ASDIX #Only apply ASDI Y if in the air cmpwi REG_GroundState,0 beq 0x8 fadds REG_CurrYPos,REG_CurrYPos,REG_ASDIY #Null ASDI lfs REG_ASDIX, -0x750C (rtoc) lfs REG_ASDIY, -0x750C (rtoc) #endregion #region Decay Knockback #Apply either gravity or traction cmpwi REG_GroundState,1 bne DIDraw_CollisionLoop_DecayGrounded DIDraw_CollisionLoop_DecayAerial: #Account for gravity lfs f1, 0x016C (REG_PlayerData) lfs f2, 0x0170 (REG_PlayerData) fneg f2,f2 fsubs REG_Gravity,REG_Gravity,f1 fcmpo cr0,REG_Gravity,f2 bge 0x8 fmr REG_Gravity,f2 #Decay KB Vector fmr f1,REG_KnockbackY fmr f2,REG_KnockbackX branchl r12,0x80022c30 #Get arctan of the KB vector fmr REG_arctan,f1 #Decay X KB branchl r12,cos lwz r3, -0x514C (r13) lfs f2, 0x0204 (r3) fnmsubs REG_KnockbackX,f2,f1,REG_KnockbackX #Decay Y KB fmr f1,REG_arctan branchl r12,sin lwz r3, -0x514C (r13) lfs f2, 0x0204 (r3) fnmsubs REG_KnockbackY,f2,f1,REG_KnockbackY b DIDraw_CollisionLoop_DecayEnd DIDraw_CollisionLoop_DecayGrounded: #Get Ground Friction's multipllier lwz r3,0x4(REG_PlayerData) cmpwi r3,Popo.Int beq DIDraw_CollisionLoop_DecayGrounded_isICs cmpwi r3,Nana.Int beq DIDraw_CollisionLoop_DecayGrounded_isICs #Get grounds friction multiplier lfs f1, -0x7A38 (rtoc) lwz r0, 0x014C (REG_ECBStruct) cmpwi r0,-1 beq DIDraw_CollisionLoop_DecayGrounded_isICs lwz r3,0x150(REG_ECBStruct) branchl r12,0x800569ec #Get ground's friction multiplier b 0x8 DIDraw_CollisionLoop_DecayGrounded_isICs: lfs f1, -0x7A38 (rtoc) #Account for friction lfs f0, 0x128 (REG_PlayerData) fmuls f1,f0,f1 lwz r4, -0x514C (r13) lfs f0, 0x0200 (r4) fmuls f0,f1,f0 #Apply Friction to knockback lfs f2, -0x76B0 (rtoc) fcmpo cr0,REG_KnockbackX,f2 bge DIDraw_CollisionLoop_DecayGrounded_Subtract fadds f0,f0,REG_KnockbackX fmr REG_KnockbackX,f0 fcmpo cr0,f0,f2 ble DIDraw_CollisionLoop_DecayGroundedEnd fmr REG_KnockbackX,f2 b DIDraw_CollisionLoop_DecayGroundedEnd DIDraw_CollisionLoop_DecayGrounded_Subtract: fsubs f0,REG_KnockbackX,f0 fmr REG_KnockbackX,f0 fcmpo cr0,f0,f2 bge DIDraw_CollisionLoop_DecayGroundedEnd fmr REG_KnockbackX,f2 b DIDraw_CollisionLoop_DecayGroundedEnd DIDraw_CollisionLoop_DecayGroundedEnd: DIDraw_CollisionLoop_DecayEnd: #endregion #region Shift Positions #Shift previous positions down lfs f1,0x4(REG_ECBStruct) lfs f2,0x8(REG_ECBStruct) lfs f3,0xC(REG_ECBStruct) stfs f1,0x1C(REG_ECBStruct) stfs f2,0x20(REG_ECBStruct) stfs f3,0x24(REG_ECBStruct) #Store next position fadds f1,REG_CurrXPos,REG_KnockbackX stfs f1,0x4(REG_ECBStruct) fadds f1,REG_CurrYPos,REG_KnockbackY fadds f1,f1,REG_Gravity stfs f1,0x8(REG_ECBStruct) lfs f1, -0x778C (rtoc) stfs f1,0xC(REG_ECBStruct) #endregion #region Run Collision Check .if MaxColl>=0 #Only run X collision checks because theyre expensive cmpwi REG_LoopCount,MaxColl blt DIDraw_CollisionLoop_DetermineCollision #Spoof as not touching anything li r3,0 stw r3,0x134(REG_ECBStruct) lfs REG_CurrXPos,0x4(REG_ECBStruct) lfs REG_CurrYPos,0x8(REG_ECBStruct) #If grounded and max collision checks, just stop updating position cmpwi REG_GroundState,0 bne DIDraw_CollisionLoop_StageBehaviorEnd li REG_OverrideRemainingFrames,1 b DIDraw_CollisionLoop_StageBehaviorEnd .endif DIDraw_CollisionLoop_DetermineCollision: #Run collision cmpwi REG_GroundState,1 beq DIDraw_CollisionLoop_AerialCollision DIDraw_CollisionLoop_GroundCollision: #Grounded Collision mr r3,REG_ECBStruct mr r4,REG_ECBBoneStruct branchl r12,0x8004b21c xori REG_GroundState,r3,0x1 b DIDraw_CollisionLoop_CollisionEnd DIDraw_CollisionLoop_AerialCollision: #Aerial Collision mr r3,REG_ECBStruct mr r4,REG_ECBBoneStruct branchl r12,0x800475f4 DIDraw_CollisionLoop_CollisionEnd: #endregion #region Stage Collision Behavior #Get new position lfs REG_CurrXPos,0x4(REG_ECBStruct) lfs REG_CurrYPos,0x8(REG_ECBStruct) #Inc Collision ID lwz r3,0x38(REG_ECBStruct) addi r3,r3,1 stw r3,0x38(REG_ECBStruct) #Determine line collision behavior lwz r3,0x134(REG_ECBStruct) rlwinm. r0,r3,0,0x8000 bne DIDraw_CollisionLoop_TouchingGround rlwinm. r0,r3,0,0x6000 bne DIDraw_CollisionLoop_TouchingCeiling rlwinm. r0,r3,0,0x20 bne DIDraw_CollisionLoop_TouchingWall rlwinm. r0,r3,0,0x40 bne DIDraw_CollisionLoop_TouchingWall DIDraw_CollisionLoop_TouchingNothing: b DIDraw_CollisionLoop_StageBehaviorEnd #region Touching Ground DIDraw_CollisionLoop_TouchingGround: #If grounded, dont run KB manip code cmpwi REG_GroundState,0 beq DIDraw_CollisionLoop_StageBehaviorEnd #Check if over max horizontal velocity lwz r4, -0x514C (r13) lfs f1, 0x0164 (r4) fcmpo cr0,REG_KnockbackX,f1 ble 0x8 fmr REG_KnockbackX,f1 fneg f1,f1 fcmpo cr0,REG_KnockbackX,f1 bge 0x8 fmr REG_KnockbackX,f1 #Adjust KB lfs f1,0x158(REG_ECBStruct) fmuls REG_KnockbackX,REG_KnockbackX,f1 lfs f1,0x154(REG_ECBStruct) fneg f1,f1 fmuls REG_KnockbackY,REG_KnockbackX,f1 #REMOVE ALL Y KB? lfs REG_KnockbackY, -0x750C (rtoc) #Set as grounded li REG_GroundState,0 b DIDraw_CollisionLoop_StageBehaviorEnd #endregion #region Touching Ceiling DIDraw_CollisionLoop_TouchingCeiling: #If grounded, dont run KB manip code cmpwi REG_GroundState,0 beq DIDraw_CollisionLoop_StageBehaviorEnd #Self-Induced velocity lfs f1, -0x750C (rtoc) stfs f1,Stack_MiscSpace+0x0(sp) stfs REG_Gravity,Stack_MiscSpace+0x4(sp) #KB-Induced stfs REG_KnockbackX,Stack_MiscSpace+0x8(sp) stfs REG_KnockbackY,Stack_MiscSpace+0xC(sp) #Add vectors addi r3,sp,Stack_MiscSpace+0x0 addi r4,sp,Stack_MiscSpace+0x8 branchl r12,0x8000d4a0 #Unk addi r3,sp,Stack_MiscSpace+0x0 addi r4,REG_ECBStruct,0x190 branchl r12,0x8000dc6c #Decay KB lwz r3, -0x514C (r13) lfs f1, 0x01BC (r3) lfs f2,Stack_MiscSpace+0x0(sp) lfs f3,Stack_MiscSpace+0x4(sp) fmuls REG_KnockbackX,f1,f2 fmuls REG_KnockbackY,f1,f3 b DIDraw_CollisionLoop_StageBehaviorEnd #endregion #region Touching Wall DIDraw_CollisionLoop_TouchingWall: #If grounded, dont run KB manip code cmpwi REG_GroundState,0 beq DIDraw_CollisionLoop_StageBehaviorEnd #Get walls data lwz r3,0x134(REG_ECBStruct) rlwinm. r0,r3,0,0x20 bne DIDraw_CollisionLoop_LeftWallsData rlwinm. r0,r3,0,0x40 bne DIDraw_CollisionLoop_RightWallsData DIDraw_CollisionLoop_RightWallsData: addi REG_Temp,REG_ECBStruct,380 b 0x8 DIDraw_CollisionLoop_LeftWallsData: addi REG_Temp,REG_ECBStruct,360 #Self-Induced velocity lfs f1, -0x750C (rtoc) stfs f1,Stack_MiscSpace+0x0(sp) stfs REG_Gravity,Stack_MiscSpace+0x4(sp) #KB-Induced stfs REG_KnockbackX,Stack_MiscSpace+0x8(sp) stfs REG_KnockbackY,Stack_MiscSpace+0xC(sp) #Add vectors addi r3,sp,Stack_MiscSpace+0x0 addi r4,sp,Stack_MiscSpace+0x8 branchl r12,0x8000d4a0 #Unk addi r3,sp,Stack_MiscSpace+0x0 mr r4,REG_Temp branchl r12,0x8000dc6c #Decay KB lwz r3, -0x514C (r13) lfs f1, 0x01BC (r3) lfs f2,Stack_MiscSpace+0x0(sp) lfs f3,Stack_MiscSpace+0x4(sp) fmuls REG_KnockbackX,f1,f2 fmuls REG_KnockbackY,f1,f3 lfs REG_Gravity, -0x6DA0 (rtoc) b DIDraw_CollisionLoop_StageBehaviorEnd #endregion DIDraw_CollisionLoop_StageBehaviorEnd: #endregion #region Ground to Air Check .if MaxColl>=0 DIDraw_CollisionLoop_GroundToAirCheck: .set GroundToAirRemainingFrames,5 #Ensure not touching ground this frame lwz r3,0x134(REG_ECBStruct) rlwinm. r0,r3,0,0x8000 bne DIDraw_CollisionLoop_GroundToAirCheckEnd #Ensure was touching ground last frame lwz r3,0x138(REG_ECBStruct) rlwinm. r0,r3,0,0x8000 beq DIDraw_CollisionLoop_GroundToAirCheckEnd #Check if over MaxColl cmpwi REG_LoopCount,MaxColl blt DIDraw_CollisionLoop_GroundToAirCheckEnd #Check if REG_OverrideRemainingFrames is already set cmpwi REG_OverrideRemainingFrames,0 bgt DIDraw_CollisionLoop_GroundToAirCheckEnd #Set REG_OverrideRemainingFrames li REG_OverrideRemainingFrames,GroundToAirRemainingFrames DIDraw_CollisionLoop_GroundToAirCheckEnd: .endif #endregion #region Save Collision Info .set CollInfo_Length,0x18 .set CollInfo_XPos,0x0 .set CollInfo_YPos,0x4 .set CollInfo_EnvBitfield,0x8 .set CollInfo_ECBTopY,0xC .set CollInfo_ECBLeftY,0x10 .set CollInfo_KnockbackY,0x14 #Update collision check count stw REG_LoopCount,0x0(REG_CollisionInfo) #Get this frames offset in info struct addi r3,REG_CollisionInfo,0x4 #skip past header mulli r4,REG_LoopCount,CollInfo_Length add r3,r3,r4 #Store data stfs REG_CurrXPos,CollInfo_XPos(r3) stfs REG_CurrYPos,CollInfo_YPos(r3) lwz r4,0x134(REG_ECBStruct) stw r4,CollInfo_EnvBitfield(r3) lfs f1,0x88(REG_ECBStruct) stfs f1,CollInfo_ECBTopY(r3) lfs f1,0xA0(REG_ECBStruct) stfs f1,CollInfo_ECBLeftY(r3) stfs REG_KnockbackY,CollInfo_KnockbackY(r3) #endregion DIDraw_CollisionLoop_IncLoop: #Check override frames first cmpwi REG_OverrideRemainingFrames,0 ble DIDraw_CollisionLoop_IncLoopNoOverride #Decrement override frames subi REG_OverrideRemainingFrames,REG_OverrideRemainingFrames,1 cmpwi REG_OverrideRemainingFrames,0 bgt DIDraw_CollisionLoop_IncLoopNoOverride #Override and exit loop prematurely b DIDraw_CollisionLoop_IncLoopEnd DIDraw_CollisionLoop_IncLoopNoOverride: #Inc Loop addi REG_LoopCount,REG_LoopCount,1 lfs f1,0x2340(REG_PlayerData) fctiwz f1,f1 stfd f1,Stack_MiscSpace(sp) lwz r3,Stack_MiscSpace+4(sp) cmpw REG_LoopCount,r3 blt DIDraw_CollisionLoop DIDraw_CollisionLoop_IncLoopEnd: /* .if MaxColl>=0 #Output collision checks count bl DIDraw_CollisionLoop_Text mflr r3 lwz r4,TM_GameFrameCounter(r13) mr r5,REG_LoopCount branchl r12,OSReport b DIDraw_CollisionLoop_TextEnd DIDraw_CollisionLoop_Text: blrl .string "frame %d performed %d collision checks\n" .align 2 DIDraw_CollisionLoop_TextEnd: .endif */ #endregion #endregion #Draw out each frame of hitstun #region DIDraw_Draw .set REG_FramesCollisionInfo,26 .set REG_LineColor,27 #region DIDraw_DrawLoop_Init DIDraw_DrawLoop_Init: #Init Loop li REG_LoopCount,0 #Init GX Prim lwz r3,0x0(REG_CollisionInfo) addi r3,r3,2 #collision frames + 2 for ASDI frames load r4,0x001F1306 load r5,0x00000C55 branchl r12,prim.new mr REG_GX,r3 #Get line color (check if results in death) .set REG_DeathLoopCount,28 li REG_DeathLoopCount,0 DIDraw_DrawLoop_Init_DeathLoop: addi r3,REG_CollisionInfo,0x4 mulli r4,REG_DeathLoopCount,CollInfo_Length add r3,r3,r4 #get last frames info lfs REG_CurrXPos,CollInfo_XPos(r3) lfs REG_CurrYPos,CollInfo_YPos(r3) lfs REG_KnockbackY,CollInfo_KnockbackY(r3) branchl r12,0x80224b38 #right blastzone fcmpo cr0,REG_CurrXPos,f1 bgt DIDraw_DrawLoop_Init_Dead branchl r12,0x80224b50 #left blastzone fcmpo cr0,REG_CurrXPos,f1 blt DIDraw_DrawLoop_Init_Dead branchl r12,0x80224b80 #bottom blastzone fcmpo cr0,REG_CurrYPos,f1 blt DIDraw_DrawLoop_Init_Dead branchl r12,0x80224b68 #top blastzone fcmpo cr0,REG_CurrYPos,f1 ble DIDraw_DrawLoop_Init_DeathLoop_Inc cmpwi REG_GroundState,0 beq DIDraw_DrawLoop_Init_Dead lwz r3, -0x514C (r13) lfs f0, 0x04F0 (r3) fcmpo cr0,REG_KnockbackY,f0 ble DIDraw_DrawLoop_Init_DeathLoop_Inc DIDraw_DrawLoop_Init_Dead: lwz REG_LineColor,DeadLineColor(REG_EventConstants) b DIDraw_DrawLoop_Init_DeathLoop_Exit DIDraw_DrawLoop_Init_DeathLoop_Inc: addi REG_DeathLoopCount,REG_DeathLoopCount,1 lwz r3,0x0(REG_CollisionInfo) cmpw REG_DeathLoopCount,r3 blt DIDraw_DrawLoop_Init_DeathLoop #Is alive, make blue lwz REG_LineColor,AliveLineColor(REG_EventConstants) DIDraw_DrawLoop_Init_DeathLoop_Exit: #Draw the ASDI #Get original ASDI values lfs REG_ASDIX,Stack_ASDIBackup+0(sp) lfs REG_ASDIY,Stack_ASDIBackup+4(sp) #If no ASDI, use blue lfs f0, -0x750C (rtoc) fcmpo cr0,REG_ASDIX,f0 bne DIDraw_DrawLoop_Init_HasASDI lfs f0, -0x750C (rtoc) fcmpo cr0,REG_ASDIY,f0 bne DIDraw_DrawLoop_Init_HasASDI mr r4,REG_LineColor b 0x8 DIDraw_DrawLoop_Init_HasASDI: lwz r4,ASDIColor(REG_EventConstants) #Draw starting point lfs f1,0x6F4(REG_PlayerData) #X = TopN X lfs f2,0x790(REG_PlayerData) #Y = ECBLeftY + TopN Y lfs f3,0x6F8(REG_PlayerData) fadds f2,f2,f3 lfs f3,FirefoxDrawZ(REG_EventConstants) stfs f1,0x0(REG_GX) stfs f2,0x0(REG_GX) stfs f3,0x0(REG_GX) stw r4,0x0(REG_GX) #Draw end point lfs f1,0x6F4(REG_PlayerData) #X = TopN X fadds f1,f1,REG_ASDIX lfs f2,0x790(REG_PlayerData) #Y = ECBLeftY + TopN Y lfs f3,0x6F8(REG_PlayerData) fadds f2,f2,f3 fadds f2,f2,REG_ASDIY lfs f3,FirefoxDrawZ(REG_EventConstants) stfs f1,0x0(REG_GX) stfs f2,0x0(REG_GX) stfs f3,0x0(REG_GX) stw r4,0x0(REG_GX) #endregion #region DIDraw_DrawLoop_Start DIDraw_DrawLoop: #Get this frames offset in info struct addi r3,REG_CollisionInfo,0x4 #skip past header mulli r4,REG_LoopCount,CollInfo_Length add REG_FramesCollisionInfo,r3,r4 #region DIDraw_DrawLoop_DetermineColor #Determine line collision behavior lwz r3,CollInfo_EnvBitfield(REG_FramesCollisionInfo) rlwinm. r0,r3,0,0x8000 bne DIDraw_DrawLoop_TouchingGround rlwinm. r0,r3,0,0x6000 bne DIDraw_DrawLoop_TouchingCeiling rlwinm. r0,r3,0,0x20 bne DIDraw_DrawLoop_TouchingLeftWall rlwinm. r0,r3,0,0x40 bne DIDraw_DrawLoop_TouchingRightWall DIDraw_DrawLoop_TouchingNothing: mr r4,REG_LineColor b DIDraw_DrawLoop_GetColorEnd DIDraw_DrawLoop_TouchingGround: lwz r4,GroundColor(REG_EventConstants) b DIDraw_DrawLoop_GetColorEnd DIDraw_DrawLoop_TouchingCeiling: lwz r4,CeilingColor(REG_EventConstants) b DIDraw_DrawLoop_GetColorEnd DIDraw_DrawLoop_TouchingLeftWall: lwz r4,LeftWallColor(REG_EventConstants) b DIDraw_DrawLoop_GetColorEnd DIDraw_DrawLoop_TouchingRightWall: lwz r4,RightWallColor(REG_EventConstants) b DIDraw_DrawLoop_GetColorEnd DIDraw_DrawLoop_GetColorEnd: #endregion #Draw this point lfs f1,CollInfo_XPos(REG_FramesCollisionInfo) #X = TopN X /* lfs f2,CollInfo_ECBLeftY(REG_FramesCollisionInfo) #Y = ECBLeftY + TopN Y lfs f3,CollInfo_YPos(REG_FramesCollisionInfo) fadds f2,f2,f3 */ lfs f2,0x790(REG_PlayerData) lfs f3,CollInfo_YPos(REG_FramesCollisionInfo) fadds f2,f2,f3 lfs f3,FirefoxDrawZ(REG_EventConstants) mr r3,REG_GX stfs f1,0x0(r3) stfs f2,0x0(r3) stfs f3,0x0(r3) stw r4,0x0(r3) #Inc Loop addi REG_LoopCount,REG_LoopCount,1 lwz r3,0x0(REG_CollisionInfo) cmpw REG_LoopCount,r3 blt DIDraw_DrawLoop #Free collision struct mr r3,REG_CollisionInfo branchl r12,HSD_Free #End Loop branchl r12,prim.close #endregion #endregion DIDraw_Exit: lmw r20,Stack_BackedUpReg(r1) lwz r0, StackSize+4(r1) addi r1,r1,StackSize # release the space mtlr r0 blr #################################################### #endregion Exit: #Return restore mr r3, r28 ================================================ FILE: ASM/Additional Codes/Game Modes/All Star Test/Disable Invisible Melee.s ================================================ #To be inserted at 801ba5d0 .include "../../../Globals.s" .set REG_MinorData,31 .set REG_IronManData,30 .set REG_MatchData,29 .set IronManData,0x8040a5e0 backup mr REG_MinorData,r3 #Get Match Data lwz REG_MatchData, -0x77C0 (r13) addi REG_MatchData, REG_MatchData, 4624 load REG_IronManData,IronManData #Destroy Existing Heap #Reset cache branchl r12,0x80018c6c branchl r12,0x80018254 li r3,4 branchl r12,0x80017700 IronMan_SetupMatchInit: .set REG_Count,20 .set REG_PlayerCount,21 .set REG_Port,22 #Init li REG_PlayerCount,0 li REG_Count,0 IronMan_SetupMatchLoop: mr r3,REG_MatchData mr r4,REG_Count bl GetPlayersMatchInfo #Get the players data cmpwi r3,-1 beq IronMan_SetupMatchEnd #Set the first character as the current character mr REG_Port,r4 mulli r5,REG_PlayerCount,0x1C add r5,r5,REG_IronManData lbz r6,0x0(r5) #Get the next iron man character addi r5,r5,1 lbzx r5,r6,r5 stb r5,0x0(r3) #Store character to match data stb REG_PlayerCount,0x3(r3) #Store costume to match data #Get Prelod Table load r3,0x8043208c mulli r4,REG_Port,0x8 add r4,r3,r4 stw r5,0x0(r4) #Store to preload table stb REG_PlayerCount,0x4(r4) #Store costume addi REG_PlayerCount,REG_PlayerCount,1 IronMan_SetupMatchIncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,6 blt IronMan_SetupMatchLoop IronMan_SetupMatchEnd: #Now get a random stage branchl r12,0x8025bbd4 sth r3,0x16(REG_MatchData) load r4,0x80432088 stw r3,0x0(r4) #Store to prelaod #Request preload branchl r12,0x80018254 #Store Pointer to onStartMelee function lwz r4, -0x77C0 (r13) addi r4, r4, 4624 bl IronMan_Init mflr r5 stw r5,0x4C(r4) b InjectionExit #region IronMan_Init IronMan_Init: blrl .set REG_GObj,31 .set REG_Data,30 .set DataSize,64 backup #Create GObj li r3,22 li r4,0 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Alloc Mem li r3,DataSize branchl r12,HSD_MemAlloc mr REG_Data,r3 #Zero Data mr r3,REG_Data li r4,DataSize branchl r12,ZeroAreaLength #Attach Data mr r3,REG_GObj li r4,14 load r5,HSD_Free mr r6,REG_Data branchl r12,GObj_AddUserData #Attach Process mr r3,REG_GObj bl IronMan_Think mflr r4 li r5,23 branchl r12,GObj_AddProc #Create Text .set REG_Count,20 .set REG_IronManData,21 .set REG_PlayerCount,22 .set REG_Temp,23 .set REG_Text,24 #Init li REG_PlayerCount,0 li REG_Count,0 load REG_IronManData,IronManData IronMan_Init_AdjustStocksLoop: #Check if exists mr r3,REG_Count branchl r12,PlayerBlock_LoadMainCharDataOffset cmpwi r3,0 beq IronMan_Init_AdjustStocksIncLoop #Increment player count addi REG_PlayerCount,REG_PlayerCount,1 subi r4,REG_PlayerCount,1 mulli r4,r4,0x1C add REG_Temp,r4,REG_IronManData #Create Text li r3,2 load r4,0x804a1f58 lwz r4,0x0(r4) branchl r12,Text_CreateTextStruct mr REG_Text,r3 addi r3,REG_GObjData,OFST_TextPointers mulli r4,REG_Count,4 stwx REG_Text,r3,r4 #SET TEXT SPACING TO TIGHT li r4,0x1 stb r4,0x49(REG_Text) #SET TEXT TO CENTER AROUND X LOCATION li r4,0x1 stb r4,0x4A(REG_Text) #Update Text Contents load r4,0x804a0ff0 mulli r3,REG_Count,0xC #HUD Info is 0xC Long Per Player lfsx f1,r3,r4 #Get This Players HUD Info bl ScorePosition mflr r5 lfs f2,0x0(r5) mr r3,REG_Text bl ScoreText mflr r4 lbz r5,0x0(REG_Temp) extsb r5,r5 addi r5,r5,1 branchl r12,Text_InitializeSubtext #Update Size mr r3,REG_Text li r4,0 lfs f1, -0x1DB4 (rtoc) lfs f2, -0x1DB4 (rtoc) branchl r12,Text_UpdateSubtextSize IronMan_Init_AdjustStocksIncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,6 blt IronMan_Init_AdjustStocksLoop IronMan_InitExit: restore blr #endregion #region IronMan_Think IronMan_Think: blrl #Registers .set REG_GObj,31 .set REG_GObjData,30 .set REG_IronManData,29 #Offsets .set OFST_TextPointers,0x0 .set OFST_IsSpawning,0x18 .set OFST_IsSpawningLength,0x2 #Constants .set EndTimer,60 backup #Init Pointers mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) load REG_IronManData,IronManData #Set match bits to not declare player defeated branchl r12,0x8016ae38 li r4,0 stb r4,0x5(r3) #Check if match is pending a character load .set REG_Count,20 #Init li REG_Count,0 #Check if pending a load IronMan_Think_CheckForPendingSpawnLoop: addi r3,REG_GObjData,OFST_IsSpawning mulli r4,REG_Count,OFST_IsSpawningLength add r4,r3,r4 lhz r3,0x0(r4) cmpwi r3,0 beq IronMan_Think_CheckForPendingSpawnIncLoop #Check if load is finished subi r3,r3,1 sth r3,0x0(r4) cmpwi r3,0 bgt IronMan_Think_CheckForPendingSpawnIncLoop #Spawn in player load r3,0x80480590 #Match info mulli r4,REG_Count,0x24 add r4,r3,r4 mr r3,REG_Count branchl r12,0x8016eddc #Enter in Rebirth mr r3,REG_Count branchl r12,PlayerBlock_LoadMainCharDataOffset li r4,0x1 branchl r12,0x800bfd9c IronMan_Think_CheckForPendingSpawnIncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,6 blt IronMan_Think_CheckForPendingSpawnLoop IronMan_Think_CheckForPendingSpawnEnd: IronMan_Think_DeathCheckInit: .set REG_Count,20 .set REG_SomeoneDied,21 .set REG_PlayerCount,22 .set REG_PlayerData,23 .set REG_IronManLineup,24 #Init li REG_PlayerCount,0 li REG_Count,0 li REG_SomeoneDied,0 IronMan_Think_DeathCheckLoop: #Check if exists mr r3,REG_Count branchl r12,PlayerBlock_LoadMainCharDataOffset mr. REG_PlayerData,r3 beq IronMan_Think_DeathCheckIncLoop #Increment player count addi REG_PlayerCount,REG_PlayerCount,1 #Update stock counter in ironman data mr r3,REG_Count branchl r12,PlayerBlock_LoadStocksLeft subi r4,REG_PlayerCount,1 mulli r4,r4,0x1C add REG_IronManLineup,r4,REG_IronManData stb r3,0x1B(REG_IronManLineup) #Check if no stocks left cmpwi r3,0 bgt IronMan_Think_DeathCheckIncLoop #Decrement their ironman index lbz r3,0x0(REG_IronManLineup) subi r3,r3,1 stb r3,0x0(REG_IronManLineup) #Check if theyre completely dead extsb r3,r3 cmpwi r3,0 blt IronMan_Think_DeathCheckEndGame #Give them max stocks lwz r3, -0x77C0 (r13) lbz r3,6228(r3) stb r3,0x1B(REG_IronManLineup) #Despawn this player mr r3,REG_Count branchl r12,0x8016ef98 #Remove all of their items #Kill all of their SFX #Setup spawn struct lbz r3,0x0(REG_IronManLineup) addi r4,REG_IronManLineup,1 lbzx r5,r3,r4 load r3,0x80480590 #Match info mulli r4,REG_Count,0x24 add r4,r3,r4 stb r5,0x0(r4) #Store character to match data stb REG_Count,0x3(r4) #Store costume to match data #Begin Preloading next character mr r3,r5 mr r4,REG_Count bl LoadCharacter #Start Preload #Set isSpawning flag addi r3,REG_GObjData,OFST_IsSpawning mulli r4,REG_Count,OFST_IsSpawningLength add r4,r3,r4 li r3,3*60 sth r3,0x0(r4) #Update Text #Get text pointer addi r3,REG_GObjData,OFST_TextPointers mulli r4,REG_Count,4 lwzx r3,r3,r4 li r4,0 bl ScoreText mflr r5 lbz r6,0x0(REG_IronManLineup) extsb r6,r6 addi r6,r6,1 branchl r12,Text_UpdateSubtextContents b IronMan_Think_DeathCheckIncLoop IronMan_Think_DeathCheckEndGame: #This player is out of characters, display GAME li r3,5 branchl r12,0x8016b33c #Delay li r3,40 branchl r12,0x8016b378 #End game branchl r12,0x8016b328 #Destroy GObj mr r3,REG_GObj branchl r12,GObj_Destroy b IronMan_ThinkExit IronMan_Think_DeathCheckIncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,6 blt IronMan_Think_DeathCheckLoop IronMan_ThinkExit: restore blr #endregion ############################################################### ScoreText: blrl .string "%d Left" .align 2 ScorePosition: blrl .float -15.5 ############################################################### GetPlayersMatchInfo: .set REG_LoopCount,9 .set REG_Count,10 .set REG_MatchData,11 .set REG_Player,12 #Backup addi REG_MatchData,r3,0x68 mr REG_Player,r4 li REG_Count,0 li REG_LoopCount,0 GetPlayersMatchInfo_Loop: lbz r3,0x1(REG_MatchData) cmpwi r3,0x3 beq GetPlayersMatchInfo_IncLoop #Check if this is the desired player cmpw REG_Count,REG_Player beq GetPlayersMatchInfo_Exit addi REG_Count,REG_Count,1 GetPlayersMatchInfo_IncLoop: addi REG_MatchData,REG_MatchData,0x24 addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt GetPlayersMatchInfo_Loop #Not Found li r3,-1 b GetPlayersMatchInfo_Blr GetPlayersMatchInfo_Exit: mr r3,REG_MatchData mr r4,REG_LoopCount GetPlayersMatchInfo_Blr: blr ############################################################### LoadCharacter: .set REG_ExtCharID,31 .set REG_CostumeID,30 #Init backup mr REG_ExtCharID,r3 mr REG_CostumeID,r4 #Store to preload table load r3,0x8043209c mulli r4,REG_CostumeID,0x8 add r4,r3,r4 stw REG_ExtCharID,0x0(r4) #Store to preload table stb REG_CostumeID,0x4(r4) #Store costume branchl r12,0x80018254 #Load present characters SFX LoadCharacter_DeathCheckSFXLoad: .set REG_SFXLoopCount,25 .set REG_SFXMatchInfo,26 .set REG_AudioBit1,27 .set REG_AudioBit2,28 li REG_SFXLoopCount,0 li REG_AudioBit1,0 li REG_AudioBit2,0 load REG_SFXMatchInfo,0x80480590 #Match info LoadCharacter_DeathCheckSFXLoadLoop: mulli r3,REG_SFXLoopCount,0x24 add r3,r3,REG_SFXMatchInfo lbz r3,0x0(r3) extsb r3,r3 branchl r12,0x80026e84 or REG_AudioBit1,REG_AudioBit1,r3 or REG_AudioBit2,REG_AudioBit2,r4 LoadCharacter_DeathCheckSFXLoadIncLoop: addi REG_SFXLoopCount,REG_SFXLoopCount,1 cmpwi REG_SFXLoopCount,6 blt LoadCharacter_DeathCheckSFXLoadLoop #Unk li r3,28 branchl r12,0x80026f2c #Request the SFX load li r3,4 mr r5,REG_AudioBit1 mr r6,REG_AudioBit2 branchl r12,0x8002702c branchl r12,0x80027168 LoadCharacter_Exit: restore blr ############################################################### InjectionExit: mr r3,REG_MinorData restore li r5,0 li r6,0 ================================================ FILE: ASM/Additional Codes/Game Modes/All Star Test/Initialize Lineups.s ================================================ #To be inserted at 801ba544 .include "../../../Globals.s" .set REG_MinorData,31 .set REG_IronManData,30 .set REG_MatchData,29 .set IronManData,0x8040a5e0 backup #Save r3, cant get it otherwise mr REG_MinorData,r3 #Get iron man data load REG_IronManData,IronManData #Get Match data lwz REG_MatchData,0x14(REG_MinorData) IronMan_InitLineupInit: .set REG_Count,20 #Init li REG_Count,0 IronMan_InitLineupLoop: mr r3,REG_MatchData mr r4,REG_Count bl GetPlayersMatchInfo #Get the players data cmpwi r3,-1 beq IronMan_InitLineupEnd #Create Lineup mulli r3,REG_Count,0x1C add r3,r3,REG_IronManData bl CreateLineupArray IronMan_InitLineupIncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,6 blt IronMan_InitLineupLoop IronMan_InitLineupEnd: #Set match bits to skip game end checks (doing this myself) li r3,0x80 stb r3,0x15(REG_MatchData) #Next Minor in-game load r3,SceneController li r4,1 stb r4,Scene.CurrentMinor(r3) b Exit ############################################################### CreateLineupArray: .set REG_Array,31 .set REG_BaseArray,30 .set REG_Index,29 #backup backup mr REG_Array,r3 #Initialize Runtime Index li r3,25 stb r3,0x0(REG_Array) #Initialzie Stock Counter lwz r3, -0x77C0 (r13) lbz r3,6228(r3) stb r3,0x1B(REG_Array) addi REG_Array,REG_Array,1 #Get base array bl IronManArray mflr REG_BaseArray #Copy Lineup Array mr r3,REG_Array mr r4,REG_BaseArray li r5,26 branchl r12,memcpy #Initialize Shuffle Index li REG_Index,25 CreateLineupArray_Loop: #Get random number between 0-25 li r3,26 branchl r12,HSD_Randi #Swap the current index with this element lbzx r4,r3,REG_Array lbzx r5,REG_Index,REG_Array stbx r4,REG_Index,REG_Array stbx r5,r3,REG_Array #Decrement index subi REG_Index,REG_Index,1 cmpwi REG_Index,0 bge CreateLineupArray_Loop CreateLineupArray_Exit: restore blr ############################################################### GetPlayersMatchInfo: .set REG_LoopCount,9 .set REG_Count,10 .set REG_MatchData,11 .set REG_Player,12 #Backup addi REG_MatchData,r3,0x70 mr REG_Player,r4 li REG_Count,0 li REG_LoopCount,0 GetPlayersMatchInfo_Loop: lbz r3,0x1(REG_MatchData) cmpwi r3,0x3 beq GetPlayersMatchInfo_IncLoop #Check if this is the desired player cmpw REG_Count,REG_Player beq GetPlayersMatchInfo_Exit addi REG_Count,REG_Count,1 GetPlayersMatchInfo_IncLoop: addi REG_MatchData,REG_MatchData,0x24 addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt GetPlayersMatchInfo_Loop #Not Found li r3,-1 b GetPlayersMatchInfo_Blr GetPlayersMatchInfo_Exit: mr r3,REG_MatchData mr r4,REG_LoopCount GetPlayersMatchInfo_Blr: blr ############################################################### IronManArray: blrl .byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 .align 2 ############################################################### Exit: mr r3,REG_MinorData restore lwz r4, -0x77C0 (r13) ================================================ FILE: ASM/Additional Codes/Game Modes/Chess Melee.asm ================================================ #To be inserted at 801b8c74 .include "../../Globals.s" #Store Pointer to onStartMelee function lwz r4, -0x77C0 (r13) addi r4, r4, 1752 bl ChessMelee_Init mflr r5 stw r5,0x44(r4) b InjectionExit #region ChessMelee_Init ChessMelee_Init: blrl .set REG_GObj,31 .set REG_Data,30 .set DataSize,64 backup #Create GObj li r3,22 li r4,23 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Alloc Mem li r3,DataSize branchl r12,HSD_MemAlloc mr REG_Data,r3 #Zero Data mr r3,REG_Data li r4,DataSize branchl r12,ZeroAreaLength #Attach Data mr r3,REG_GObj li r4,14 load r5,HSD_Free mr r6,REG_Data branchl r12,GObj_AddUserData #Attach Process mr r3,REG_GObj bl ChessMelee_Think mflr r4 li r5,23 branchl r12,GObj_AddProc ChessMelee_InitExit: restore blr #endregion #region ChessMelee_Think ChessMelee_Think: blrl #Registers .set REG_GObj,31 .set REG_GObjData,30 #Data Offsets .set GameState,0x0 #byte .set FrozenTimer,0x1 #half #Definitions #GameState .set InProgress,0x0 .set Frozen,0x1 #Constants .set FreezeFrames, 1 * 60 backup #Init Pointers mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) #Check state of game lbz r3,GameState(REG_GObjData) cmpwi r3,InProgress beq ChessMelee_Think_InProgress cmpwi r3,Frozen beq ChessMelee_Think_Frozen b ChessMelee_ThinkExit #region InProgress ChessMelee_Think_InProgress: .set REG_LoopCount,29 #Check For Dead Players li REG_LoopCount,0 ChessMelee_Think_InProgressLoop: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne ChessMelee_Think_InProgressIncLoop #Get Players Data mr r3,REG_LoopCount branchl r12,0x80034110 lwz r3,0x2C(r3) #Check If Player is still active (not sleep) lbz r4,0x221F(r3) rlwinm. r4,r4,0,27,27 bne ChessMelee_Think_InProgressIncLoop #Check if READY,GO is over lbz r4,0x221D(r3) rlwinm. r4,r4,0,28,28 bne ChessMelee_Think_InProgressIncLoop #Check if Blastzone code is being skipped lbz r4,0x2219(r3) rlwinm. r4,r4,0,25,25 beq ChessMelee_Think_InProgressIncLoop #Rebirth gets here too, check if NOT rebirth/rebirthWait lwz r4,0x10(r3) cmpwi r4,ASID_Rebirth beq ChessMelee_Think_InProgressIncLoop cmpwi r4,ASID_RebirthWait beq ChessMelee_Think_InProgressIncLoop #If in any Star KO State, enter them into DeadUp cmpwi r4,ASID_DeadUpStar beq ChessMelee_Think_InProgressEnterDeadUp cmpwi r4,ASID_DeadUpStarIce beq ChessMelee_Think_InProgressEnterDeadUp cmpwi r4,ASID_DeadUpFall beq ChessMelee_Think_InProgressEnterDeadUp b ChessMelee_Think_FreezeOtherPlayers ChessMelee_Think_InProgressEnterDeadUp: #Enter DeadUp lwz r3,0x0(r3) branchl r12,0x800d3e40 b ChessMelee_Think_FreezeOtherPlayers ChessMelee_Think_InProgressIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt ChessMelee_Think_InProgressLoop #No players dead, exit think function b ChessMelee_ThinkExit ChessMelee_Think_FreezeOtherPlayers: #Freeze all other players .set REG_DeadPlayer,29 .set REG_LoopCount,28 .set REG_PlayerGObj,27 .set REG_PlayerData,26 #Check For Dead Players li REG_LoopCount,0 ChessMelee_Think_FreezeOtherPlayersLoop: #Check if this is the dead player cmpw REG_LoopCount,REG_DeadPlayer bne ChessMelee_Think_FreezeOtherPlayers_NotDeadPlayer ChessMelee_Think_FreezeOtherPlayers_NotDeadPlayer: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne ChessMelee_Think_FreezeOtherPlayersIncLoop #Get Players Data mr r3,REG_LoopCount branchl r12,0x80034110 mr REG_PlayerGObj,r3 lwz REG_PlayerData,0x2C(REG_PlayerGObj) #Check If Player is still active (not sleep) lbz r4,0x221F(REG_PlayerData) rlwinm. r4,r4,0,27,27 bne ChessMelee_Think_FreezeOtherPlayersIncLoop #Freeze Player li r5,1 lbz r4,0x2219(REG_PlayerData) rlwimi r4,r5,2,29,29 stb r4,0x2219(REG_PlayerData) #Remove any hitlag li r4,0 stw r4,0x195C(REG_PlayerData) stw r4,0x1958(REG_PlayerData) #Skip Blastzone and Hitbox Collision Detection Code lbz r3,0x2219(REG_PlayerData) li r4,1 rlwimi r3,r4,6,25,25 stb r3,0x2219(REG_PlayerData) #Freeze GFX if not dead lbz r3,0x221E(REG_PlayerData) rlwinm. r0,r3,0,24,24 bne ChessMelee_Think_FreezeOtherPlayersIncLoop mr r3,REG_PlayerGObj branchl r12,0x8005ba40 ChessMelee_Think_FreezeOtherPlayersIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt ChessMelee_Think_FreezeOtherPlayersLoop #Start Frozen Timer li r3,FreezeFrames sth r3,FrozenTimer(REG_GObjData) #Change State li r3,Frozen stb r3,GameState(REG_GObjData) b ChessMelee_ThinkExit #endregion #region Frozen ChessMelee_Think_Frozen: #Decrement timer lhz r3,FrozenTimer(REG_GObjData) subi r3,r3,1 sth r3,FrozenTimer(REG_GObjData) #Check if up cmpwi r3,0 bne ChessMelee_ThinkExit #Timer up, enter everyone into rebirth .set REG_LoopCount,29 .set REG_PlayerGObj,28 #Check For Dead Players li REG_LoopCount,0 ChessMelee_Think_FrozenLoop: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne ChessMelee_Think_FrozenIncLoop #Get Players GObj mr r3,REG_LoopCount branchl r12,0x80034110 mr REG_PlayerGObj,r3 #Check If Player is still active (not sleep) lbz r4,0x221F(r3) rlwinm. r4,r4,0,27,27 bne ChessMelee_Think_FrozenIncLoop #Remove Items + Etc mr r3,REG_PlayerGObj branchl r12,0x800d331c #Enter into Sleep mr r3,REG_PlayerGObj li r4,0x1 branchl r12,0x800bfd9c ChessMelee_Think_FrozenIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt ChessMelee_Think_FrozenLoop #Enter InProgress Game State li r3,InProgress stb r3,GameState(REG_GObjData) b ChessMelee_ThinkExit #endregion ChessMelee_ThinkExit: restore blr #endregion InjectionExit: li r6,0 ================================================ FILE: ASM/Additional Codes/Game Modes/Chess Melee.s ================================================ #To be inserted at 801b8c74 .include "../../Globals.s" #Store Pointer to onStartMelee function lwz r4, -0x77C0 (r13) addi r4, r4, 1752 bl ChessMelee_Init mflr r5 stw r5,0x44(r4) b InjectionExit #region ChessMelee_Init ChessMelee_Init: blrl .set REG_GObj,31 .set REG_Data,30 .set DataSize,64 backup #Create GObj li r3,22 li r4,23 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Alloc Mem li r3,DataSize branchl r12,HSD_MemAlloc mr REG_Data,r3 #Zero Data mr r3,REG_Data li r4,DataSize branchl r12,ZeroAreaLength #Attach Data mr r3,REG_GObj li r4,14 load r5,HSD_Free mr r6,REG_Data branchl r12,GObj_AddUserData #Attach Process mr r3,REG_GObj bl ChessMelee_Think mflr r4 li r5,23 branchl r12,GObj_AddProc ChessMelee_InitExit: restore blr #endregion #region ChessMelee_Think ChessMelee_Think: blrl #Registers .set REG_GObj,31 .set REG_GObjData,30 #Data Offsets .set GameState,0x0 #byte .set FrozenTimer,0x1 #half #Definitions #GameState .set InProgress,0x0 .set Frozen,0x1 #Constants .set FreezeFrames, 1 * 60 backup #Init Pointers mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) #Check state of game lbz r3,GameState(REG_GObjData) cmpwi r3,InProgress beq ChessMelee_Think_InProgress cmpwi r3,Frozen beq ChessMelee_Think_Frozen b ChessMelee_ThinkExit #region InProgress ChessMelee_Think_InProgress: .set REG_LoopCount,29 #Check For Dead Players li REG_LoopCount,0 ChessMelee_Think_InProgressLoop: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne ChessMelee_Think_InProgressIncLoop #Get Players Data mr r3,REG_LoopCount branchl r12,0x80034110 lwz r3,0x2C(r3) #Check If Player is still active (not sleep) lbz r4,0x221F(r3) rlwinm. r4,r4,0,27,27 bne ChessMelee_Think_InProgressIncLoop #Check if READY,GO is over lbz r4,0x221D(r3) rlwinm. r4,r4,0,28,28 bne ChessMelee_Think_InProgressIncLoop #Check if Blastzone code is being skipped lbz r4,0x2219(r3) rlwinm. r4,r4,0,25,25 beq ChessMelee_Think_InProgressIncLoop #Rebirth gets here too, check if NOT rebirth/rebirthWait lwz r4,0x10(r3) cmpwi r4,ASID_Rebirth beq ChessMelee_Think_InProgressIncLoop cmpwi r4,ASID_RebirthWait beq ChessMelee_Think_InProgressIncLoop #If in any Star KO State, enter them into DeadUp cmpwi r4,ASID_DeadUpStar beq ChessMelee_Think_InProgressEnterDeadUp cmpwi r4,ASID_DeadUpStarIce beq ChessMelee_Think_InProgressEnterDeadUp cmpwi r4,ASID_DeadUpFall beq ChessMelee_Think_InProgressEnterDeadUp b ChessMelee_Think_FreezeOtherPlayers ChessMelee_Think_InProgressEnterDeadUp: #Enter DeadUp lwz r3,0x0(r3) branchl r12,0x800d3e40 b ChessMelee_Think_FreezeOtherPlayers ChessMelee_Think_InProgressIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt ChessMelee_Think_InProgressLoop #No players dead, exit think function b ChessMelee_ThinkExit ChessMelee_Think_FreezeOtherPlayers: #Freeze all other players .set REG_DeadPlayer,29 .set REG_LoopCount,28 .set REG_PlayerGObj,27 .set REG_PlayerData,26 #Check For Dead Players li REG_LoopCount,0 ChessMelee_Think_FreezeOtherPlayersLoop: #Check if this is the dead player cmpw REG_LoopCount,REG_DeadPlayer bne ChessMelee_Think_FreezeOtherPlayers_NotDeadPlayer ChessMelee_Think_FreezeOtherPlayers_NotDeadPlayer: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne ChessMelee_Think_FreezeOtherPlayersIncLoop #Get Players Data mr r3,REG_LoopCount branchl r12,0x80034110 mr REG_PlayerGObj,r3 lwz REG_PlayerData,0x2C(REG_PlayerGObj) #Check If Player is still active (not sleep) lbz r4,0x221F(REG_PlayerData) rlwinm. r4,r4,0,27,27 bne ChessMelee_Think_FreezeOtherPlayersIncLoop #Freeze Player li r5,1 lbz r4,0x2219(REG_PlayerData) rlwimi r4,r5,2,29,29 stb r4,0x2219(REG_PlayerData) #Remove any hitlag li r4,0 stw r4,0x195C(REG_PlayerData) stw r4,0x1958(REG_PlayerData) #Skip Blastzone and Hitbox Collision Detection Code lbz r3,0x2219(REG_PlayerData) li r4,1 rlwimi r3,r4,6,25,25 stb r3,0x2219(REG_PlayerData) #Freeze GFX if not dead lbz r3,0x221E(REG_PlayerData) rlwinm. r0,r3,0,24,24 bne ChessMelee_Think_FreezeOtherPlayersIncLoop mr r3,REG_PlayerGObj branchl r12,0x8005ba40 ChessMelee_Think_FreezeOtherPlayersIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt ChessMelee_Think_FreezeOtherPlayersLoop #Start Frozen Timer li r3,FreezeFrames sth r3,FrozenTimer(REG_GObjData) #Change State li r3,Frozen stb r3,GameState(REG_GObjData) b ChessMelee_ThinkExit #endregion #region Frozen ChessMelee_Think_Frozen: #Decrement timer lhz r3,FrozenTimer(REG_GObjData) subi r3,r3,1 sth r3,FrozenTimer(REG_GObjData) #Check if up cmpwi r3,0 bne ChessMelee_ThinkExit #Timer up, enter everyone into rebirth .set REG_LoopCount,29 .set REG_PlayerGObj,28 #Check For Dead Players li REG_LoopCount,0 ChessMelee_Think_FrozenLoop: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne ChessMelee_Think_FrozenIncLoop #Get Players GObj mr r3,REG_LoopCount branchl r12,0x80034110 mr REG_PlayerGObj,r3 #Check If Player is still active (not sleep) lbz r4,0x221F(r3) rlwinm. r4,r4,0,27,27 bne ChessMelee_Think_FrozenIncLoop #Remove Items + Etc mr r3,REG_PlayerGObj branchl r12,0x800d331c #Enter into Sleep mr r3,REG_PlayerGObj li r4,0x1 branchl r12,0x800bfd9c ChessMelee_Think_FrozenIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt ChessMelee_Think_FrozenLoop #Enter InProgress Game State li r3,InProgress stb r3,GameState(REG_GObjData) b ChessMelee_ThinkExit #endregion ChessMelee_ThinkExit: restore blr #endregion InjectionExit: li r6,0 ================================================ FILE: ASM/Additional Codes/Game Modes/Iron Man/Disable Invisible Melee.asm ================================================ #To be inserted at 801ba3d4 .include "../../../Globals.s" .set REG_MinorData,31 .set REG_IronManData,30 .set REG_MatchData,29 .set IronManData,0x8040a5e0 backup mr REG_MinorData,r3 #Get Match Data lwz REG_MatchData, -0x77C0 (r13) addi REG_MatchData, REG_MatchData, 2064 load REG_IronManData,IronManData #Reset cache branchl r12,0x80018c6c branchl r12,0x80018254 li r3,4 branchl r12,0x80017700 IronMan_SetupMatchInit: .set REG_Count,20 .set REG_PlayerCount,21 .set REG_Port,22 #Init li REG_PlayerCount,0 li REG_Count,0 IronMan_SetupMatchLoop: mr r3,REG_MatchData mr r4,REG_Count bl GetPlayersMatchInfo #Get the players data cmpwi r3,-1 beq IronMan_SetupMatchEnd #Set the first character as the current character mr REG_Port,r4 mulli r5,REG_PlayerCount,0x1C add r5,r5,REG_IronManData lbz r6,0x0(r5) #Get the next iron man character addi r5,r5,1 lbzx r5,r6,r5 stb r5,0x0(r3) #Store character to match data stb REG_PlayerCount,0x3(r3) #Store costume to match data #Get Prelod Table load r3,0x8043208c mulli r4,REG_Port,0x8 add r4,r3,r4 stw r5,0x0(r4) #Store to preload table stb REG_PlayerCount,0x4(r4) #Store costume addi REG_PlayerCount,REG_PlayerCount,1 IronMan_SetupMatchIncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,6 blt IronMan_SetupMatchLoop IronMan_SetupMatchEnd: #Now get a random stage branchl r12,0x8025bbd4 sth r3,0x16(REG_MatchData) load r4,0x80432088 stw r3,0x0(r4) #Store to prelaod #Request preload branchl r12,0x80018254 #Store Pointer to onStartMelee function lwz r4, -0x77C0 (r13) addi r4, r4, 2064 bl IronMan_Init mflr r5 stw r5,0x4C(r4) b InjectionExit #region IronMan_Init IronMan_Init: blrl .set REG_GObj,31 .set REG_Data,30 .set DataSize,64 backup #Create GObj li r3,22 li r4,0 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Alloc Mem li r3,DataSize branchl r12,HSD_MemAlloc mr REG_Data,r3 #Zero Data mr r3,REG_Data li r4,DataSize branchl r12,ZeroAreaLength #Attach Data mr r3,REG_GObj li r4,14 load r5,HSD_Free mr r6,REG_Data branchl r12,GObj_AddUserData #Attach Process mr r3,REG_GObj bl IronMan_Think mflr r4 li r5,23 branchl r12,GObj_AddProc IronMan_InitExit: restore blr #endregion #region IronMan_Think IronMan_Think: blrl #Registers .set REG_GObj,31 .set REG_GObjData,30 .set REG_IronManData,29 #Offsets .set OFST_EndTimer,0x0 .set OFST_FirstFrame,0x1 .set OFST_TextPointers,0x4 #Constants .set EndTimer,60 backup #Init Pointers mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) load REG_IronManData,IronManData #Restore stocks on the first frame lbz r3,OFST_FirstFrame(REG_GObjData) cmpwi r3,0 bne IronMan_Think_SkipFirstFrame IronMan_Think_AdjustStocksInit: .set REG_Count,20 .set REG_SomeoneDied,21 .set REG_PlayerCount,22 .set REG_Temp,23 .set REG_Text,24 #Init li REG_PlayerCount,0 li REG_Count,0 li REG_SomeoneDied,0 IronMan_Think_AdjustStocksLoop: #Check if exists mr r3,REG_Count branchl r12,PlayerBlock_LoadMainCharDataOffset cmpwi r3,0 beq IronMan_Think_AdjustStocksIncLoop #Increment player count addi REG_PlayerCount,REG_PlayerCount,1 #Update stocks subi r4,REG_PlayerCount,1 mulli r4,r4,0x1C add REG_Temp,r4,REG_IronManData lbz r4,0x1B(REG_Temp) mr r3,REG_Count branchl r12,0x80033c60 #Create Text li r3,2 load r4,0x804a1f58 lwz r4,0x0(r4) branchl r12,Text_CreateTextStruct mr REG_Text,r3 addi r3,REG_GObjData,OFST_TextPointers mulli r4,REG_Count,4 stwx REG_Text,r3,r4 #SET TEXT SPACING TO TIGHT li r4,0x1 stb r4,0x49(REG_Text) #SET TEXT TO CENTER AROUND X LOCATION li r4,0x1 stb r4,0x4A(REG_Text) #Update Text Contents load r4,0x804a0ff0 mulli r3,REG_Count,0xC #HUD Info is 0xC Long Per Player lfsx f1,r3,r4 #Get This Players HUD Info bl ScorePosition mflr r5 lfs f2,0x0(r5) mr r3,REG_Text bl ScoreText mflr r4 lbz r5,0x0(REG_Temp) extsb r5,r5 addi r5,r5,1 branchl r12,Text_InitializeSubtext #Update Size mr r3,REG_Text li r4,0 lfs f1, -0x1DB4 (rtoc) lfs f2, -0x1DB4 (rtoc) branchl r12,Text_UpdateSubtextSize IronMan_Think_AdjustStocksIncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,6 blt IronMan_Think_AdjustStocksLoop #Set as not first frame li r3,1 stb r3,OFST_FirstFrame(REG_GObjData) IronMan_Think_SkipFirstFrame: #Check if match is frozen lbz r3,OFST_EndTimer(REG_GObjData) cmpwi r3,0 beq IronMan_Think_NotFrozen #Subtract by 1 subi r3,r3,1 stb r3,OFST_EndTimer(REG_GObjData) cmpwi r3,0 bgt IronMan_ThinkExit #Fade screen li r3,60 branchl r12,0x8002063c #Destroy GObj mr r3,REG_GObj branchl r12,GObj_Destroy b IronMan_ThinkExit IronMan_Think_NotFrozen: IronMan_Think_DeathCheckInit: .set REG_Count,20 .set REG_SomeoneDied,21 .set REG_PlayerCount,22 #Init li REG_PlayerCount,0 li REG_Count,0 li REG_SomeoneDied,0 IronMan_Think_DeathCheckLoop: #Check if exists mr r3,REG_Count branchl r12,PlayerBlock_LoadMainCharDataOffset cmpwi r3,0 beq IronMan_Think_DeathCheckIncLoop #Increment player count addi REG_PlayerCount,REG_PlayerCount,1 #Update stock counter in ironman data mr r3,REG_Count branchl r12,PlayerBlock_LoadStocksLeft subi r4,REG_PlayerCount,1 mulli r4,r4,0x1C add r4,r4,REG_IronManData stb r3,0x1B(r4) #Check if no stocks left cmpwi r3,0 bgt IronMan_Think_DeathCheckIncLoop #Set someonedied flag li REG_SomeoneDied,1 #Decrement their ironman index lbz r3,0x0(r4) subi r3,r3,1 stb r3,0x0(r4) #Give them max stocks lwz r3, -0x77C0 (r13) lbz r3,6228(r3) stb r3,0x1B(r4) #Update Text #Get text pointer addi r3,REG_GObjData,OFST_TextPointers mulli r4,REG_Count,4 lwzx r3,r3,r4 #Get iron man index subi r4,REG_PlayerCount,1 mulli r4,r4,0x1C add REG_Temp,r4,REG_IronManData li r4,0 bl ScoreText mflr r5 lbz r6,0x0(REG_Temp) extsb r6,r6 addi r6,r6,1 branchl r12,Text_UpdateSubtextContents #Check if theyre completely dead lbz r3,0x0(REG_Temp) extsb r3,r3 cmpwi r3,0 bge IronMan_Think_DeathCheckIncLoop #This player is out of characters, display GAME li r3,5 branchl r12,0x8016b33c #Delay li r3,40 branchl r12,0x8016b378 #End game branchl r12,0x8016b328 #Destroy GObj mr r3,REG_GObj branchl r12,GObj_Destroy b IronMan_ThinkExit IronMan_Think_DeathCheckIncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,6 blt IronMan_Think_DeathCheckLoop #Check if someone died cmpwi REG_SomeoneDied,0 beq IronMan_ThinkExit #Start ending this match now li r3,EndTimer stb r3,OFST_EndTimer(REG_GObjData) #Freeze Game li r3,8 branchl r12,0x8016b33c branchl r12,0x8016b328 IronMan_ThinkExit: restore blr #endregion ############################################################### ScoreText: blrl .string "%d Left" .align 2 ScorePosition: blrl .float -15.5 ############################################################### GetPlayersMatchInfo: .set REG_LoopCount,9 .set REG_Count,10 .set REG_MatchData,11 .set REG_Player,12 #Backup addi REG_MatchData,r3,0x68 mr REG_Player,r4 li REG_Count,0 li REG_LoopCount,0 GetPlayersMatchInfo_Loop: lbz r3,0x1(REG_MatchData) cmpwi r3,0x3 beq GetPlayersMatchInfo_IncLoop #Check if this is the desired player cmpw REG_Count,REG_Player beq GetPlayersMatchInfo_Exit addi REG_Count,REG_Count,1 GetPlayersMatchInfo_IncLoop: addi REG_MatchData,REG_MatchData,0x24 addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt GetPlayersMatchInfo_Loop #Not Found li r3,-1 b GetPlayersMatchInfo_Blr GetPlayersMatchInfo_Exit: mr r3,REG_MatchData mr r4,REG_LoopCount GetPlayersMatchInfo_Blr: blr ############################################################### InjectionExit: mr r3,REG_MinorData restore li r6,0 ================================================ FILE: ASM/Additional Codes/Game Modes/Iron Man/Initialize Lineups.asm ================================================ #To be inserted at 801ba344 .include "../../../Globals.s" .set REG_MinorData,31 .set REG_IronManData,30 .set REG_MatchData,29 .set IronManData,0x8040a5e0 backup #Save r3, cant get it otherwise mr REG_MinorData,r3 #Get iron man data load REG_IronManData,IronManData #Get Match data lwz REG_MatchData,0x14(REG_MinorData) IronMan_InitLineupInit: .set REG_Count,20 #Init li REG_Count,0 IronMan_InitLineupLoop: mr r3,REG_MatchData mr r4,REG_Count bl GetPlayersMatchInfo #Get the players data cmpwi r3,-1 beq IronMan_InitLineupEnd #Create Lineup mulli r3,REG_Count,0x1C add r3,r3,REG_IronManData bl CreateLineupArray IronMan_InitLineupIncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,6 blt IronMan_InitLineupLoop IronMan_InitLineupEnd: #Set match bits to skip game end checks (doing this myself) li r3,0x80 stb r3,0x5(REG_MatchData) #Set score display on #Next Minor in-game load r3,SceneController li r4,1 stb r4,Scene.CurrentMinor(r3) b Exit ############################################################### CreateLineupArray: .set REG_Array,31 .set REG_BaseArray,30 .set REG_Index,29 #backup backup mr REG_Array,r3 #Initialize Runtime Index li r3,25 stb r3,0x0(REG_Array) #Initialzie Stock Counter lwz r3, -0x77C0 (r13) lbz r3,6228(r3) stb r3,0x1B(REG_Array) addi REG_Array,REG_Array,1 #Get base array bl IronManArray mflr REG_BaseArray #Copy Lineup Array mr r3,REG_Array mr r4,REG_BaseArray li r5,26 branchl r12,memcpy #Initialize Shuffle Index li REG_Index,25 CreateLineupArray_Loop: #Get random number between 0-25 li r3,26 branchl r12,HSD_Randi #Swap the current index with this element lbzx r4,r3,REG_Array lbzx r5,REG_Index,REG_Array stbx r4,REG_Index,REG_Array stbx r5,r3,REG_Array #Decrement index subi REG_Index,REG_Index,1 cmpwi REG_Index,0 bge CreateLineupArray_Loop CreateLineupArray_Exit: restore blr ############################################################### GetPlayersMatchInfo: .set REG_LoopCount,9 .set REG_Count,10 .set REG_MatchData,11 .set REG_Player,12 #Backup addi REG_MatchData,r3,0x70 mr REG_Player,r4 li REG_Count,0 li REG_LoopCount,0 GetPlayersMatchInfo_Loop: lbz r3,0x1(REG_MatchData) cmpwi r3,0x3 beq GetPlayersMatchInfo_IncLoop #Check if this is the desired player cmpw REG_Count,REG_Player beq GetPlayersMatchInfo_Exit addi REG_Count,REG_Count,1 GetPlayersMatchInfo_IncLoop: addi REG_MatchData,REG_MatchData,0x24 addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt GetPlayersMatchInfo_Loop #Not Found li r3,-1 b GetPlayersMatchInfo_Blr GetPlayersMatchInfo_Exit: mr r3,REG_MatchData mr r4,REG_LoopCount GetPlayersMatchInfo_Blr: blr ############################################################### IronManArray: blrl .byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 .align 2 ############################################################### Exit: mr r3,REG_MinorData restore lwz r4, -0x77C0 (r13) ================================================ FILE: ASM/Additional Codes/Game Modes/Iron Man/Load Next Match.asm ================================================ #To be inserted at 801ba410 .include "../../../Globals.s" .set REG_MatchData,31 .set REG_IronManData,30 .set IronManData,0x8040a5e0 backup #Get Match Data lwz REG_MatchData,-0x20(r3) load REG_IronManData,IronManData #Check if LRAStarted lwz r3,0x14(r3) lbz r3,0x10(r3) cmpwi r3,7 beq ReturnToCSS #Set the first character as the current character addi r5,REG_IronManData,0x0 lbz r6,0x0(r5) #Get the next iron man character extsb r0,r6 cmpwi r0,-1 beq ReturnToCSS #Now do p2 addi r5,REG_IronManData,0x1C lbz r6,0x0(r5) #Get the next iron man character extsb r0,r6 cmpwi r0,-1 beq ReturnToCSS #Load match scene again li r3,2 branchl r12,0x801a42a0 b InjectionExit ReturnToCSS: li r3,0 branchl r12,0x801a42a0 b InjectionExit InjectionExit: restore ================================================ FILE: ASM/Additional Codes/Game Modes/Rotations Melee.asm ================================================ #To be inserted at 801b9090 .include "../../Globals.s" #Store Pointer to onStartMelee function lwz r4, -0x77C0 (r13) addi r4, r4, 3992 bl Rotations_Init mflr r5 stw r5,0x44(r4) b InjectionExit #region Rotations_Init Rotations_Init: blrl .set REG_GObj,31 .set REG_Data,30 .set DataSize,64 backup #Create GObj li r3,22 li r4,23 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Alloc Mem li r3,DataSize branchl r12,HSD_MemAlloc mr REG_Data,r3 #Zero Data mr r3,REG_Data li r4,DataSize branchl r12,ZeroAreaLength #Attach Data mr r3,REG_GObj li r4,14 load r5,HSD_Free mr r6,REG_Data branchl r12,GObj_AddUserData #Attach Process mr r3,REG_GObj bl Rotations_Think mflr r4 li r5,23 branchl r12,GObj_AddProc Rotations_InitExit: restore blr #endregion #region Rotations_Think Rotations_Think: blrl #Registers .set REG_GObj,31 .set REG_GObjData,30 #Data Offsets .set GameState,0x0 #byte .set P1Slot,0x1 #byte .set P2Slot,0x2 #byte .set LastPlayerSpawned,0x3 #byte #Definitions #GameState .set FirstFrame,0x0 .set InProgress,0x1 #Constants .set FreezeFrames, 1 * 60 backup #Init Pointers mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) #Check state of game lbz r3,GameState(REG_GObjData) cmpwi r3,FirstFrame beq Rotations_Think_FirstFrame cmpwi r3,InProgress beq Rotations_Think_InProgress #region FirstFrame Rotations_Think_FirstFrame: #Ensure over 2 players are present branchl r12,0x8016b558 cmpwi r3,3 bge Rotations_Think_FirstFrameContinue #Destroy Think Function mr r3,REG_GObj branchl r12,0x80390228 b Rotations_ThinkExit Rotations_Think_FirstFrameContinue: .set REG_LoopCount,29 .set REG_PlayerSlotIndex,28 #Init Loop li REG_LoopCount,0 li REG_PlayerSlotIndex,0 Rotations_Think_FirstFrameLoop: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne Rotations_Think_FirstFrameIncLoop #Player exists, store to data addi r3,REG_GObjData,P1Slot stbx REG_LoopCount,REG_PlayerSlotIndex,r3 #Store as last player spawned stb REG_LoopCount,LastPlayerSpawned(REG_GObjData) #Now do next player addi REG_PlayerSlotIndex,REG_PlayerSlotIndex,1 #Check if finished doing both players cmpwi REG_PlayerSlotIndex,2 bge Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop Rotations_Think_FirstFrameIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt Rotations_Think_FirstFrameLoop #Now sleep the other players Rotations_Think_FirstFrameSleepRemainingPlayersLoop: .set REG_PlayerGObj,27 #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop #Get players GObj mr r3,REG_LoopCount branchl r12,0x80034110 mr REG_PlayerGObj,r3 #Sleep player branchl r12,0x800bfd04 #Check if they have a follower lwz r3,0x2C(REG_PlayerGObj) lbz r3,0x2222(r3) rlwinm. r0, r3, 30, 31, 31 beq Rotations_Think_FirstFrameSleepRemainingPlayers_DestroyHUD #Get Follower GObj mr r3,REG_LoopCount li r4,1 branchl r12,0x8003418c #SLeep them as well branchl r12,0x800bfd04 Rotations_Think_FirstFrameSleepRemainingPlayers_DestroyHUD: #Destroy their percent HUD load r3,0x804a10c8 mulli r4,REG_LoopCount,100 add r3,r3,r4 lbz r4, 0x0010 (r3) li r5,1 rlwimi r4,r5,7,24,24 rlwimi r4,r5,6,25,25 stb r4, 0x0010 (r3) Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt Rotations_Think_FirstFrameSleepRemainingPlayersLoop #Change state to every frame li r3,InProgress stb r3,GameState(REG_GObjData) b Rotations_ThinkExit #endregion #region InProgress Rotations_Think_InProgress: #Check For Dead Players .set REG_PlayerSlot,29 .set REG_PlayerSlotIndex,28 .set REG_PlayerGObj,27 #Init Loop li REG_PlayerSlotIndex,0 ################################# ## Check For Dead Players Loop ## ################################# Rotations_Think_InProgressLoop: #Get Players Slot addi r3,REG_GObjData,P1Slot lbzx REG_PlayerSlot,REG_PlayerSlotIndex,r3 #Get Players GObj mr r3,REG_PlayerSlot branchl r12,0x80034110 mr REG_PlayerGObj,r3 lwz r3,0x2C(r3) #Check If Player is still active (not sleep) lbz r4,0x221F(r3) rlwinm. r4,r4,0,27,27 bne Rotations_Think_InProgressIncLoop #Check if READY,GO is over lbz r4,0x221D(r3) rlwinm. r4,r4,0,28,28 bne Rotations_Think_InProgressIncLoop #Check if Blastzone code is being skipped lbz r4,0x2219(r3) rlwinm. r4,r4,0,25,25 beq Rotations_Think_InProgressIncLoop #Rebirth gets here too, check if NOT rebirth/rebirthWait lwz r4,0x10(r3) cmpwi r4,ASID_Rebirth beq Rotations_Think_InProgressIncLoop cmpwi r4,ASID_RebirthWait beq Rotations_Think_InProgressIncLoop #If in any Star KO State, enter them into DeadUp cmpwi r4,ASID_DeadUpStar beq Rotations_Think_InProgressEnterDeadUp cmpwi r4,ASID_DeadUpStarIce beq Rotations_Think_InProgressEnterDeadUp cmpwi r4,ASID_DeadUpFall beq Rotations_Think_InProgressEnterDeadUp b Rotations_Think_InProgressCheckDeadFrame Rotations_Think_InProgressEnterDeadUp: #Enter DeadUp mr r3,REG_PlayerGObj branchl r12,0x800d3e40 b Rotations_Think_InProgressIncLoop Rotations_Think_InProgressCheckDeadFrame: #Here we know the player is in a dead state #Ensure he is in frame X of the dead animation lwz r3,0x2C(REG_PlayerGObj) lwz r4,0x2340(r3) cmpwi r4,1 bgt Rotations_Think_InProgressIncLoop ################################# ## Search For Next Player Loop ## ################################# Rotations_Think_InProgressSearchForNextPlayer: .set REG_LoopCount,26 .set REG_OtherPlayerSlot,25 .set REG_LastPlayerSpawned,24 #Get other player xori r3,REG_PlayerSlotIndex,0x1 addi r4,REG_GObjData,P1Slot lbzx REG_OtherPlayerSlot,r3,r4 #Loop starts at LastPlayerSpawned+1 lbz REG_LastPlayerSpawned,LastPlayerSpawned(REG_GObjData) mr REG_LoopCount,REG_LastPlayerSpawned b Rotations_Think_InProgressSearchForNextPlayerIncLoop Rotations_Think_InProgressSearchForNextPlayerLoop: #Player who just died is in REG_PlayerSlot #Player who is alive is in REG_OtherPlayerSlot #Check if player is present mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne Rotations_Think_InProgressSearchForNextPlayerIncLoop #Ensure this isnt the player who just died cmpw REG_LoopCount,REG_PlayerSlot beq Rotations_Think_InProgressSearchForNextPlayerIncLoop #Ensure this isnt the other player cmpw REG_LoopCount,REG_OtherPlayerSlot beq Rotations_Think_InProgressSearchForNextPlayerIncLoop #This is a unique player, check if they have stock remainings mr r3,REG_LoopCount branchl r12,0x80033bd8 cmpwi r3,0 ble Rotations_Think_InProgressSearchForNextPlayerIncLoop #Get GObj First mr r3,REG_LoopCount branchl r12,0x80034110 #Respawn li r4,0x1 branchl r12,0x800bfd9c #Save their slot to the GObjData addi r3,REG_GObjData,P1Slot stbx REG_LoopCount,REG_PlayerSlotIndex,r3 #Save this as the last player spawned stb REG_LoopCount,LastPlayerSpawned(REG_GObjData) #Now enter the recently deceased player into perm sleep mr r3,REG_PlayerGObj branchl r12,0x800bfd04 #Check if they have a follower lwz r4,0x2C(REG_PlayerGObj) lbz r3,0x2222(r4) rlwinm. r0, r3, 30, 31, 31 beq Rotations_Think_InProgressIncLoop #Get Follower GObj lbz r3,0xC(r4) li r4,1 branchl r12,0x8003418c #SLeep them as well branchl r12,0x800bfd04 b Rotations_Think_InProgressIncLoop Rotations_Think_InProgressSearchForNextPlayerIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt Rotations_Think_InProgressSearchForNextPlayerIncLoopCheckIfDone #Player count is over 6, loop back to 0 li REG_LoopCount,0 Rotations_Think_InProgressSearchForNextPlayerIncLoopCheckIfDone: #Now check if we did a full loop cmpw REG_LoopCount,REG_LastPlayerSpawned bne Rotations_Think_InProgressSearchForNextPlayerLoop #If we get here, no other players are reported as alive, so do nothing for normal respawn behvior Rotations_Think_InProgressIncLoop: addi REG_PlayerSlotIndex,REG_PlayerSlotIndex,1 cmpwi REG_PlayerSlotIndex,2 blt Rotations_Think_InProgressLoop #Neither player is dead, exit think function b Rotations_ThinkExit #endregion Rotations_ThinkExit: restore blr #endregion InjectionExit: li r6,0 ================================================ FILE: ASM/Additional Codes/Game Modes/Rotations Melee.s ================================================ #To be inserted at 801b9090 .include "../../Globals.s" #Store Pointer to onStartMelee function lwz r4, -0x77C0 (r13) addi r4, r4, 3992 bl Rotations_Init mflr r5 stw r5,0x44(r4) b InjectionExit #region Rotations_Init Rotations_Init: blrl .set REG_GObj,31 .set REG_Data,30 .set DataSize,64 backup #Create GObj li r3,22 li r4,23 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Alloc Mem li r3,DataSize branchl r12,HSD_MemAlloc mr REG_Data,r3 #Zero Data mr r3,REG_Data li r4,DataSize branchl r12,ZeroAreaLength #Attach Data mr r3,REG_GObj li r4,14 load r5,HSD_Free mr r6,REG_Data branchl r12,GObj_AddUserData #Attach Process mr r3,REG_GObj bl Rotations_Think mflr r4 li r5,23 branchl r12,GObj_AddProc Rotations_InitExit: restore blr #endregion #region Rotations_Think Rotations_Think: blrl #Registers .set REG_GObj,31 .set REG_GObjData,30 #Data Offsets .set GameState,0x0 #byte .set P1Slot,0x1 #byte .set P2Slot,0x2 #byte .set LastPlayerSpawned,0x3 #byte #Definitions #GameState .set FirstFrame,0x0 .set InProgress,0x1 #Constants .set FreezeFrames, 1 * 60 backup #Init Pointers mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) #Check state of game lbz r3,GameState(REG_GObjData) cmpwi r3,FirstFrame beq Rotations_Think_FirstFrame cmpwi r3,InProgress beq Rotations_Think_InProgress #region FirstFrame Rotations_Think_FirstFrame: #Ensure over 2 players are present branchl r12,0x8016b558 cmpwi r3,3 bge Rotations_Think_FirstFrameContinue #Destroy Think Function mr r3,REG_GObj branchl r12,0x80390228 b Rotations_ThinkExit Rotations_Think_FirstFrameContinue: .set REG_LoopCount,29 .set REG_PlayerSlotIndex,28 #Init Loop li REG_LoopCount,0 li REG_PlayerSlotIndex,0 Rotations_Think_FirstFrameLoop: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne Rotations_Think_FirstFrameIncLoop #Player exists, store to data addi r3,REG_GObjData,P1Slot stbx REG_LoopCount,REG_PlayerSlotIndex,r3 #Store as last player spawned stb REG_LoopCount,LastPlayerSpawned(REG_GObjData) #Now do next player addi REG_PlayerSlotIndex,REG_PlayerSlotIndex,1 #Check if finished doing both players cmpwi REG_PlayerSlotIndex,2 bge Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop Rotations_Think_FirstFrameIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt Rotations_Think_FirstFrameLoop #Now sleep the other players Rotations_Think_FirstFrameSleepRemainingPlayersLoop: .set REG_PlayerGObj,27 #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop #Get players GObj mr r3,REG_LoopCount branchl r12,0x80034110 mr REG_PlayerGObj,r3 #Sleep player branchl r12,0x800bfd04 #Check if they have a follower lwz r3,0x2C(REG_PlayerGObj) lbz r3,0x2222(r3) rlwinm. r0, r3, 30, 31, 31 beq Rotations_Think_FirstFrameSleepRemainingPlayers_DestroyHUD #Get Follower GObj mr r3,REG_LoopCount li r4,1 branchl r12,0x8003418c #SLeep them as well branchl r12,0x800bfd04 Rotations_Think_FirstFrameSleepRemainingPlayers_DestroyHUD: #Destroy their percent HUD load r3,0x804a10c8 mulli r4,REG_LoopCount,100 add r3,r3,r4 lbz r4, 0x0010 (r3) li r5,1 rlwimi r4,r5,7,24,24 rlwimi r4,r5,6,25,25 stb r4, 0x0010 (r3) Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt Rotations_Think_FirstFrameSleepRemainingPlayersLoop #Change state to every frame li r3,InProgress stb r3,GameState(REG_GObjData) b Rotations_ThinkExit #endregion #region InProgress Rotations_Think_InProgress: #Check For Dead Players .set REG_PlayerSlot,29 .set REG_PlayerSlotIndex,28 .set REG_PlayerGObj,27 #Init Loop li REG_PlayerSlotIndex,0 ################################# ## Check For Dead Players Loop ## ################################# Rotations_Think_InProgressLoop: #Get Players Slot addi r3,REG_GObjData,P1Slot lbzx REG_PlayerSlot,REG_PlayerSlotIndex,r3 #Get Players GObj mr r3,REG_PlayerSlot branchl r12,0x80034110 mr REG_PlayerGObj,r3 lwz r3,0x2C(r3) #Check If Player is still active (not sleep) lbz r4,0x221F(r3) rlwinm. r4,r4,0,27,27 bne Rotations_Think_InProgressIncLoop #Check if READY,GO is over lbz r4,0x221D(r3) rlwinm. r4,r4,0,28,28 bne Rotations_Think_InProgressIncLoop #Check if Blastzone code is being skipped lbz r4,0x2219(r3) rlwinm. r4,r4,0,25,25 beq Rotations_Think_InProgressIncLoop #Rebirth gets here too, check if NOT rebirth/rebirthWait lwz r4,0x10(r3) cmpwi r4,ASID_Rebirth beq Rotations_Think_InProgressIncLoop cmpwi r4,ASID_RebirthWait beq Rotations_Think_InProgressIncLoop #If in any Star KO State, enter them into DeadUp cmpwi r4,ASID_DeadUpStar beq Rotations_Think_InProgressEnterDeadUp cmpwi r4,ASID_DeadUpStarIce beq Rotations_Think_InProgressEnterDeadUp cmpwi r4,ASID_DeadUpFall beq Rotations_Think_InProgressEnterDeadUp b Rotations_Think_InProgressCheckDeadFrame Rotations_Think_InProgressEnterDeadUp: #Enter DeadUp mr r3,REG_PlayerGObj branchl r12,0x800d3e40 b Rotations_Think_InProgressIncLoop Rotations_Think_InProgressCheckDeadFrame: #Here we know the player is in a dead state #Ensure he is in frame X of the dead animation lwz r3,0x2C(REG_PlayerGObj) lwz r4,0x2340(r3) cmpwi r4,1 bgt Rotations_Think_InProgressIncLoop ################################# ## Search For Next Player Loop ## ################################# Rotations_Think_InProgressSearchForNextPlayer: .set REG_LoopCount,26 .set REG_OtherPlayerSlot,25 .set REG_LastPlayerSpawned,24 #Get other player xori r3,REG_PlayerSlotIndex,0x1 addi r4,REG_GObjData,P1Slot lbzx REG_OtherPlayerSlot,r3,r4 #Loop starts at LastPlayerSpawned+1 lbz REG_LastPlayerSpawned,LastPlayerSpawned(REG_GObjData) mr REG_LoopCount,REG_LastPlayerSpawned b Rotations_Think_InProgressSearchForNextPlayerIncLoop Rotations_Think_InProgressSearchForNextPlayerLoop: #Player who just died is in REG_PlayerSlot #Player who is alive is in REG_OtherPlayerSlot #Check if player is present mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne Rotations_Think_InProgressSearchForNextPlayerIncLoop #Ensure this isnt the player who just died cmpw REG_LoopCount,REG_PlayerSlot beq Rotations_Think_InProgressSearchForNextPlayerIncLoop #Ensure this isnt the other player cmpw REG_LoopCount,REG_OtherPlayerSlot beq Rotations_Think_InProgressSearchForNextPlayerIncLoop #This is a unique player, check if they have stock remainings mr r3,REG_LoopCount branchl r12,0x80033bd8 cmpwi r3,0 ble Rotations_Think_InProgressSearchForNextPlayerIncLoop #Get GObj First mr r3,REG_LoopCount branchl r12,0x80034110 #Respawn li r4,0x1 branchl r12,0x800bfd9c #Save their slot to the GObjData addi r3,REG_GObjData,P1Slot stbx REG_LoopCount,REG_PlayerSlotIndex,r3 #Save this as the last player spawned stb REG_LoopCount,LastPlayerSpawned(REG_GObjData) #Now enter the recently deceased player into perm sleep mr r3,REG_PlayerGObj branchl r12,0x800bfd04 #Check if they have a follower lwz r4,0x2C(REG_PlayerGObj) lbz r3,0x2222(r4) rlwinm. r0, r3, 30, 31, 31 beq Rotations_Think_InProgressIncLoop #Get Follower GObj lbz r3,0xC(r4) li r4,1 branchl r12,0x8003418c #SLeep them as well branchl r12,0x800bfd04 b Rotations_Think_InProgressIncLoop Rotations_Think_InProgressSearchForNextPlayerIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt Rotations_Think_InProgressSearchForNextPlayerIncLoopCheckIfDone #Player count is over 6, loop back to 0 li REG_LoopCount,0 Rotations_Think_InProgressSearchForNextPlayerIncLoopCheckIfDone: #Now check if we did a full loop cmpw REG_LoopCount,REG_LastPlayerSpawned bne Rotations_Think_InProgressSearchForNextPlayerLoop #If we get here, no other players are reported as alive, so do nothing for normal respawn behvior Rotations_Think_InProgressIncLoop: addi REG_PlayerSlotIndex,REG_PlayerSlotIndex,1 cmpwi REG_PlayerSlotIndex,2 blt Rotations_Think_InProgressLoop #Neither player is dead, exit think function b Rotations_ThinkExit #endregion Rotations_ThinkExit: restore blr #endregion InjectionExit: li r6,0 ================================================ FILE: ASM/Additional Codes/Game Modes/Tag Melee.asm ================================================ #To be inserted at 801b8e80 .include "../../Globals.s" #Store Pointer to onStartMelee function lwz r4, -0x77C0 (r13) addi r4, r4, 3672 bl TagMelee_Init mflr r5 stw r5,0x44(r4) b InjectionExit #region TagMelee_Init TagMelee_Init: blrl .set REG_GObj,31 .set REG_Data,30 .set DataSize,64 backup #Create GObj li r3,22 li r4,23 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Alloc Mem li r3,DataSize branchl r12,HSD_MemAlloc mr REG_Data,r3 #Zero Data mr r3,REG_Data li r4,DataSize branchl r12,ZeroAreaLength #Attach Data mr r3,REG_GObj li r4,14 load r5,HSD_Free mr r6,REG_Data branchl r12,GObj_AddUserData #Attach Process mr r3,REG_GObj bl TagMelee_Think mflr r4 li r5,23 branchl r12,GObj_AddProc TagMelee_InitExit: restore blr #endregion #region TagMelee_Think TagMelee_Think: blrl #Registers .set REG_GObj,31 .set REG_GObjData,30 #Data Offsets .set GameState,0x0 #byte .set ItSlot,0x1 #byte .set Timer,0x2 #half #Definitions #GameState .set Start,0x0 .set InProgress,0x1 .set Frozen,0x2 #Constants .set FreezeFrames, 1 * 60 backup #Init Pointers mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) #Check state of game lbz r3,GameState(REG_GObjData) cmpwi r3,Start beq TagMelee_Think_Start cmpwi r3,InProgress beq TagMelee_Think_InProgress cmpwi r3,Frozen beq TagMelee_Think_Frozen #region Start TagMelee_Think_Start: .set REG_LoopCount,29 .set REG_TotalPlayerCount,28 ######################################### ## Start by counting all alive players ## ######################################### #Init Loop li REG_LoopCount,0 li REG_TotalPlayerCount,0 TagMelee_Think_StartCountAllPlayers: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne TagMelee_Think_StartCountAllPlayersIncLoop #Check if player has stocks remaining mr r3,REG_LoopCount branchl r12,0x80033bd8 cmpwi r3,0 ble TagMelee_Think_StartCountAllPlayersIncLoop #Get Players GObj mr r3,REG_LoopCount branchl r12,0x80034110 lwz r3,0x2C(r3) #Check if READY,GO is over lbz r4,0x221D(r3) rlwinm. r4,r4,0,28,28 bne TagMelee_ThinkExit #Player exists, increment total count addi REG_TotalPlayerCount,REG_TotalPlayerCount,1 TagMelee_Think_StartCountAllPlayersIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt TagMelee_Think_StartCountAllPlayers ############################# ## Now get a random player ## ############################# .set REG_RandomPlayer,27 mr r3,REG_TotalPlayerCount branchl r12,HSD_Randi mr REG_RandomPlayer,r3 ####################################### ## Get the corresponding player slot ## ####################################### #Init Loop li REG_LoopCount,0 li REG_TotalPlayerCount,0 TagMelee_Think_StartGetItSlot: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne TagMelee_Think_StartGetItSlotIncLoop #Check if player has stocks remaining mr r3,REG_LoopCount branchl r12,0x80033bd8 cmpwi r3,0 ble TagMelee_Think_StartGetItSlotIncLoop #Is this who im looking for? cmpw REG_RandomPlayer,REG_TotalPlayerCount beq TagMelee_Think_StartFoundIt #Player exists, increment total count addi REG_TotalPlayerCount,REG_TotalPlayerCount,1 TagMelee_Think_StartGetItSlotIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt TagMelee_Think_StartGetItSlot ################### ## Store as "it" ## ################### TagMelee_Think_StartFoundIt: stb REG_LoopCount,ItSlot(REG_GObjData) .set TimerMin, 10 * 60 .set TimerMax, 30 * 60 #Start random timer li r3,TimerMax-TimerMin branchl r12,HSD_Randi addi r3,r3,TimerMin sth r3,Timer(REG_GObjData) #Change state to InProgress li r3,InProgress stb r3,GameState(REG_GObjData) b TagMelee_Think_InProgress #endregion #region InProgress TagMelee_Think_InProgress: .set REG_LoopCount,29 .set REG_TotalPlayerCount,28 #Init Loop li REG_LoopCount,0 li REG_TotalPlayerCount,0 TagMelee_Think_PunishPlayers: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne TagMelee_Think_PunishPlayersIncLoop #Check if player has stocks remaining mr r3,REG_LoopCount branchl r12,0x80033bd8 cmpwi r3,0 ble TagMelee_Think_PunishPlayersIncLoop #Ensure this player os not it lbz r3,ItSlot(REG_GObjData) cmpw r3,REG_LoopCount beq TagMelee_Think_PunishPlayersIncLoop #Get this players gobj mr r3,REG_LoopCount branchl r12,PlayerBlock_LoadMainCharDataOffset mr REG_PlayerGObj,r3 lwz REG_PlayerData,0x2C(REG_PlayerGObj) #Check if they have a victim lwz r3,0x2094(REG_PlayerData) cmpwi r3,0 beq TagMelee_Think_PunishPlayersIncLoop #If victim is not it, give the damage they just dealt lwz r4,0x2C(r3) TagMelee_Think_PunishPlayersIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt TagMelee_Think_PunishPlayers ################## ## Monitor "It" ## ################## TagMelee_Think_InProgressMonitorIt: #Get Players GObj lbz r3,ItSlot(REG_GObjData) branchl r12,0x80034110 mr REG_PlayerGObj,r3 #Check if player died #Check if Blastzone code is being skipped lwz r3,0x2C(REG_PlayerGObj) lbz r4,0x2219(r3) rlwinm. r4,r4,0,25,25 beq TagMelee_Think_InProgressMonitorItCheckForVictim #Rebirth gets here too, check if NOT rebirth/rebirthWait lwz r4,0x10(r3) cmpwi r4,ASID_Rebirth beq TagMelee_Think_InProgressMonitorItCheckForVictim cmpwi r4,ASID_RebirthWait beq TagMelee_Think_InProgressMonitorItCheckForVictim #If in any Star KO State, enter them into DeadUp cmpwi r4,ASID_DeadUpStar beq TagMelee_Think_InProgressEnterDeadUp cmpwi r4,ASID_DeadUpStarIce beq TagMelee_Think_InProgressEnterDeadUp cmpwi r4,ASID_DeadUpFall beq TagMelee_Think_InProgressEnterDeadUp b TagMelee_Think_InProgressFreezeAllPlayers TagMelee_Think_InProgressEnterDeadUp: #Enter DeadUp lwz r3,0x0(r3) branchl r12,0x800d3e40 b TagMelee_Think_InProgressFreezeAllPlayers TagMelee_Think_InProgressMonitorItCheckForVictim: #Check if player has a victim lwz r3,0x2C(REG_PlayerGObj) lwz r4,0x2094(r3) cmpwi r4,0 beq TagMelee_Think_InProgressNoTag #Ensure there is no hitbox exception (this should catch Thrown hitboxes) lwz r5,0x1198(r3) cmpwi r5,0 bne TagMelee_Think_InProgressRemoveVictim #Get the victims damage source lwz r5,0x2C(r4) lwz r5,0x1868(r5) #Check if source pointer exists cmpwi r5,0x0 beq TagMelee_Think_InProgressRemoveVictim #Check if source pointer is live (check userdata pointer) lwz r6,0x2C(r5) cmpwi r6,0 #if not, item most likely was removed on hit, so assume it was an item beq TagMelee_Think_InProgressRemoveVictim #Check if they were hit by an "item" lhz r6,0x0(r5) cmpwi r6,6 beq TagMelee_Think_InProgressNoTag b TagMelee_Think_InProgressSetNewIt /* bne TagMelee_Think_InProgressSetNewIt #Check if hitbox is still active lwz r6,0x2C(r5) addi r6,r6,0x5D4 #Start of hitbox struct lwz r5,0x0(r6) #check if hitbox is active cmpwi r5,0x0 beq TagMelee_Think_InProgressSetNewIt #Ensure it was non reflectable lbz r5,0x42(r6) #get collision bools rlwinm. r5, r5, 29, 31, 31 bne TagMelee_Think_InProgressNoTag */ TagMelee_Think_InProgressRemoveVictim: li r4,0 stw r4,0x2094(r3) b TagMelee_Think_InProgressNoTag TagMelee_Think_InProgressSetNewIt: #Set this as new "it" mr REG_PlayerGObj,r4 lwz r3,0x2C(r4) lbz r4,0xC(r3) stb r4,ItSlot(REG_GObjData) TagMelee_Think_InProgressNoTag: #Apply GFX to "it" lwz r3,0x2C(REG_PlayerGObj) li r4,0x23 # darkness body aura li r5,0 branchl r12,0x800bffd0 lwz r4,0x2C(REG_PlayerGObj) li r3,0 stw r3,0x430(r4) lhz r3,Timer(REG_GObjData) subi r3,r3,1 sth r3,Timer(REG_GObjData) #Check if up cmpwi r3,0 bgt TagMelee_ThinkExit #Timer up, kill "it" addi r3,REG_PlayerGObj,0 branchl r12,0x800d3e40 ######################## ## Freeze All Players ## ######################## .set REG_LoopCount,29 .set REG_TotalPlayerCount,28 .set REG_PlayerGObj,27 .set REG_PlayerData,26 TagMelee_Think_InProgressFreezeAllPlayers: #Init Loop li REG_LoopCount,0 li REG_TotalPlayerCount,0 TagMelee_Think_InProgressFreezeAllPlayersLoop: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne TagMelee_Think_InProgressFreezeAllPlayersIncLoop #Check if player has stocks remaining mr r3,REG_LoopCount branchl r12,0x80033bd8 cmpwi r3,0 ble TagMelee_Think_InProgressFreezeAllPlayersIncLoop #Player exists, get pointers mr r3,REG_LoopCount branchl r12,0x80034110 mr REG_PlayerGObj,r3 lwz REG_PlayerData,0x2C(REG_PlayerGObj) #Freeze bool li r5,1 lbz r4,0x2219(REG_PlayerData) rlwimi r4,r5,2,29,29 stb r4,0x2219(REG_PlayerData) #Remove any hitlag li r4,0 stw r4,0x195C(REG_PlayerData) stw r4,0x1958(REG_PlayerData) #Skip Blastzone and Hitbox Collision Detection Code lbz r3,0x2219(REG_PlayerData) li r4,1 rlwimi r3,r4,6,25,25 stb r3,0x2219(REG_PlayerData) #Freeze GFX if not dead lbz r3,0x221E(REG_PlayerData) rlwinm. r0,r3,0,24,24 bne TagMelee_Think_InProgressFreezeAllPlayersIncLoop mr r3,REG_PlayerGObj branchl r12,0x8005ba40 TagMelee_Think_InProgressFreezeAllPlayersIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt TagMelee_Think_InProgressFreezeAllPlayersLoop #Set timer li r3,60 sth r3,Timer(REG_GObjData) #Change state to frozen li r3,Frozen stb r3,GameState(REG_GObjData) b TagMelee_ThinkExit #endregion #region Frozen TagMelee_Think_Frozen: #Dec Timer lhz r3,Timer(REG_GObjData) subi r3,r3,1 sth r3,Timer(REG_GObjData) #Check if up cmpwi r3,0 bgt TagMelee_ThinkExit #Respawn all .set REG_LoopCount,29 .set REG_TotalPlayerCount,28 .set REG_PlayerGObj,27 #Init Loop li REG_LoopCount,0 li REG_TotalPlayerCount,0 TagMelee_Think_FrozenRespawnAllPlayersLoop: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne TagMelee_Think_FrozenRespawnAllPlayersIncLoop #Check if player has stocks remaining mr r3,REG_LoopCount branchl r12,0x80033bd8 cmpwi r3,0 ble TagMelee_Think_FrozenRespawnAllPlayersIncLoop #Get data mr r3,REG_LoopCount branchl r12,0x80034110 mr REG_PlayerGObj,r3 #Remove Items + Etc mr r3,REG_PlayerGObj branchl r12,0x800d331c #Enter into Sleep mr r3,REG_PlayerGObj li r4,0x1 branchl r12,0x800bfd9c TagMelee_Think_FrozenRespawnAllPlayersIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt TagMelee_Think_FrozenRespawnAllPlayersLoop #Change state to start li r3,Start stb r3,GameState(REG_GObjData) b TagMelee_ThinkExit #endregion TagMelee_ThinkExit: restore blr #endregion InjectionExit: li r6,0 ================================================ FILE: ASM/Additional Codes/Game Modes/Tag Melee.s ================================================ #To be inserted at 801b8e80 .include "../../Globals.s" #Store Pointer to onStartMelee function lwz r4, -0x77C0 (r13) addi r4, r4, 3672 bl TagMelee_Init mflr r5 stw r5,0x44(r4) b InjectionExit #region TagMelee_Init TagMelee_Init: blrl .set REG_GObj,31 .set REG_Data,30 .set DataSize,64 backup #Create GObj li r3,22 li r4,23 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Alloc Mem li r3,DataSize branchl r12,HSD_MemAlloc mr REG_Data,r3 #Zero Data mr r3,REG_Data li r4,DataSize branchl r12,ZeroAreaLength #Attach Data mr r3,REG_GObj li r4,14 load r5,HSD_Free mr r6,REG_Data branchl r12,GObj_AddUserData #Attach Process mr r3,REG_GObj bl TagMelee_Think mflr r4 li r5,23 branchl r12,GObj_AddProc TagMelee_InitExit: restore blr #endregion #region TagMelee_Think TagMelee_Think: blrl #Registers .set REG_GObj,31 .set REG_GObjData,30 #Data Offsets .set GameState,0x0 #byte .set ItSlot,0x1 #byte .set Timer,0x2 #half #Definitions #GameState .set Start,0x0 .set InProgress,0x1 .set Frozen,0x2 #Constants .set FreezeFrames, 1 * 60 backup #Init Pointers mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) #Check state of game lbz r3,GameState(REG_GObjData) cmpwi r3,Start beq TagMelee_Think_Start cmpwi r3,InProgress beq TagMelee_Think_InProgress cmpwi r3,Frozen beq TagMelee_Think_Frozen #region Start TagMelee_Think_Start: .set REG_LoopCount,29 .set REG_TotalPlayerCount,28 ######################################### ## Start by counting all alive players ## ######################################### #Init Loop li REG_LoopCount,0 li REG_TotalPlayerCount,0 TagMelee_Think_StartCountAllPlayers: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne TagMelee_Think_StartCountAllPlayersIncLoop #Check if player has stocks remaining mr r3,REG_LoopCount branchl r12,0x80033bd8 cmpwi r3,0 ble TagMelee_Think_StartCountAllPlayersIncLoop #Get Players GObj mr r3,REG_LoopCount branchl r12,0x80034110 lwz r3,0x2C(r3) #Check if READY,GO is over lbz r4,0x221D(r3) rlwinm. r4,r4,0,28,28 bne TagMelee_ThinkExit #Player exists, increment total count addi REG_TotalPlayerCount,REG_TotalPlayerCount,1 TagMelee_Think_StartCountAllPlayersIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt TagMelee_Think_StartCountAllPlayers ############################# ## Now get a random player ## ############################# .set REG_RandomPlayer,27 mr r3,REG_TotalPlayerCount branchl r12,HSD_Randi mr REG_RandomPlayer,r3 ####################################### ## Get the corresponding player slot ## ####################################### #Init Loop li REG_LoopCount,0 li REG_TotalPlayerCount,0 TagMelee_Think_StartGetItSlot: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne TagMelee_Think_StartGetItSlotIncLoop #Check if player has stocks remaining mr r3,REG_LoopCount branchl r12,0x80033bd8 cmpwi r3,0 ble TagMelee_Think_StartGetItSlotIncLoop #Is this who im looking for? cmpw REG_RandomPlayer,REG_TotalPlayerCount beq TagMelee_Think_StartFoundIt #Player exists, increment total count addi REG_TotalPlayerCount,REG_TotalPlayerCount,1 TagMelee_Think_StartGetItSlotIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt TagMelee_Think_StartGetItSlot ################### ## Store as "it" ## ################### TagMelee_Think_StartFoundIt: stb REG_LoopCount,ItSlot(REG_GObjData) .set TimerMin, 10 * 60 .set TimerMax, 30 * 60 #Start random timer li r3,TimerMax-TimerMin branchl r12,HSD_Randi addi r3,r3,TimerMin sth r3,Timer(REG_GObjData) #Change state to InProgress li r3,InProgress stb r3,GameState(REG_GObjData) b TagMelee_Think_InProgress #endregion #region InProgress TagMelee_Think_InProgress: .set REG_LoopCount,29 .set REG_TotalPlayerCount,28 #Init Loop li REG_LoopCount,0 li REG_TotalPlayerCount,0 TagMelee_Think_PunishPlayers: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne TagMelee_Think_PunishPlayersIncLoop #Check if player has stocks remaining mr r3,REG_LoopCount branchl r12,0x80033bd8 cmpwi r3,0 ble TagMelee_Think_PunishPlayersIncLoop #Ensure this player os not it lbz r3,ItSlot(REG_GObjData) cmpw r3,REG_LoopCount beq TagMelee_Think_PunishPlayersIncLoop #Get this players gobj mr r3,REG_LoopCount branchl r12,PlayerBlock_LoadMainCharDataOffset mr REG_PlayerGObj,r3 lwz REG_PlayerData,0x2C(REG_PlayerGObj) #Check if they have a victim lwz r3,0x2094(REG_PlayerData) cmpwi r3,0 beq TagMelee_Think_PunishPlayersIncLoop #If victim is not it, give the damage they just dealt lwz r4,0x2C(r3) TagMelee_Think_PunishPlayersIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt TagMelee_Think_PunishPlayers ################## ## Monitor "It" ## ################## TagMelee_Think_InProgressMonitorIt: #Get Players GObj lbz r3,ItSlot(REG_GObjData) branchl r12,0x80034110 mr REG_PlayerGObj,r3 #Check if player died #Check if Blastzone code is being skipped lwz r3,0x2C(REG_PlayerGObj) lbz r4,0x2219(r3) rlwinm. r4,r4,0,25,25 beq TagMelee_Think_InProgressMonitorItCheckForVictim #Rebirth gets here too, check if NOT rebirth/rebirthWait lwz r4,0x10(r3) cmpwi r4,ASID_Rebirth beq TagMelee_Think_InProgressMonitorItCheckForVictim cmpwi r4,ASID_RebirthWait beq TagMelee_Think_InProgressMonitorItCheckForVictim #If in any Star KO State, enter them into DeadUp cmpwi r4,ASID_DeadUpStar beq TagMelee_Think_InProgressEnterDeadUp cmpwi r4,ASID_DeadUpStarIce beq TagMelee_Think_InProgressEnterDeadUp cmpwi r4,ASID_DeadUpFall beq TagMelee_Think_InProgressEnterDeadUp b TagMelee_Think_InProgressFreezeAllPlayers TagMelee_Think_InProgressEnterDeadUp: #Enter DeadUp lwz r3,0x0(r3) branchl r12,0x800d3e40 b TagMelee_Think_InProgressFreezeAllPlayers TagMelee_Think_InProgressMonitorItCheckForVictim: #Check if player has a victim lwz r3,0x2C(REG_PlayerGObj) lwz r4,0x2094(r3) cmpwi r4,0 beq TagMelee_Think_InProgressNoTag #Ensure there is no hitbox exception (this should catch Thrown hitboxes) lwz r5,0x1198(r3) cmpwi r5,0 bne TagMelee_Think_InProgressRemoveVictim #Get the victims damage source lwz r5,0x2C(r4) lwz r5,0x1868(r5) #Check if source pointer exists cmpwi r5,0x0 beq TagMelee_Think_InProgressRemoveVictim #Check if source pointer is live (check userdata pointer) lwz r6,0x2C(r5) cmpwi r6,0 #if not, item most likely was removed on hit, so assume it was an item beq TagMelee_Think_InProgressRemoveVictim #Check if they were hit by an "item" lhz r6,0x0(r5) cmpwi r6,6 beq TagMelee_Think_InProgressNoTag b TagMelee_Think_InProgressSetNewIt /* bne TagMelee_Think_InProgressSetNewIt #Check if hitbox is still active lwz r6,0x2C(r5) addi r6,r6,0x5D4 #Start of hitbox struct lwz r5,0x0(r6) #check if hitbox is active cmpwi r5,0x0 beq TagMelee_Think_InProgressSetNewIt #Ensure it was non reflectable lbz r5,0x42(r6) #get collision bools rlwinm. r5, r5, 29, 31, 31 bne TagMelee_Think_InProgressNoTag */ TagMelee_Think_InProgressRemoveVictim: li r4,0 stw r4,0x2094(r3) b TagMelee_Think_InProgressNoTag TagMelee_Think_InProgressSetNewIt: #Set this as new "it" mr REG_PlayerGObj,r4 lwz r3,0x2C(r4) lbz r4,0xC(r3) stb r4,ItSlot(REG_GObjData) TagMelee_Think_InProgressNoTag: #Apply GFX to "it" lwz r3,0x2C(REG_PlayerGObj) li r4,0x23 # darkness body aura li r5,0 branchl r12,0x800bffd0 lwz r4,0x2C(REG_PlayerGObj) li r3,0 stw r3,0x430(r4) lhz r3,Timer(REG_GObjData) subi r3,r3,1 sth r3,Timer(REG_GObjData) #Check if up cmpwi r3,0 bgt TagMelee_ThinkExit #Timer up, kill "it" addi r3,REG_PlayerGObj,0 branchl r12,0x800d3e40 ######################## ## Freeze All Players ## ######################## .set REG_LoopCount,29 .set REG_TotalPlayerCount,28 .set REG_PlayerGObj,27 .set REG_PlayerData,26 TagMelee_Think_InProgressFreezeAllPlayers: #Init Loop li REG_LoopCount,0 li REG_TotalPlayerCount,0 TagMelee_Think_InProgressFreezeAllPlayersLoop: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne TagMelee_Think_InProgressFreezeAllPlayersIncLoop #Check if player has stocks remaining mr r3,REG_LoopCount branchl r12,0x80033bd8 cmpwi r3,0 ble TagMelee_Think_InProgressFreezeAllPlayersIncLoop #Player exists, get pointers mr r3,REG_LoopCount branchl r12,0x80034110 mr REG_PlayerGObj,r3 lwz REG_PlayerData,0x2C(REG_PlayerGObj) #Freeze bool li r5,1 lbz r4,0x2219(REG_PlayerData) rlwimi r4,r5,2,29,29 stb r4,0x2219(REG_PlayerData) #Remove any hitlag li r4,0 stw r4,0x195C(REG_PlayerData) stw r4,0x1958(REG_PlayerData) #Skip Blastzone and Hitbox Collision Detection Code lbz r3,0x2219(REG_PlayerData) li r4,1 rlwimi r3,r4,6,25,25 stb r3,0x2219(REG_PlayerData) #Freeze GFX if not dead lbz r3,0x221E(REG_PlayerData) rlwinm. r0,r3,0,24,24 bne TagMelee_Think_InProgressFreezeAllPlayersIncLoop mr r3,REG_PlayerGObj branchl r12,0x8005ba40 TagMelee_Think_InProgressFreezeAllPlayersIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt TagMelee_Think_InProgressFreezeAllPlayersLoop #Set timer li r3,60 sth r3,Timer(REG_GObjData) #Change state to frozen li r3,Frozen stb r3,GameState(REG_GObjData) b TagMelee_ThinkExit #endregion #region Frozen TagMelee_Think_Frozen: #Dec Timer lhz r3,Timer(REG_GObjData) subi r3,r3,1 sth r3,Timer(REG_GObjData) #Check if up cmpwi r3,0 bgt TagMelee_ThinkExit #Respawn all .set REG_LoopCount,29 .set REG_TotalPlayerCount,28 .set REG_PlayerGObj,27 #Init Loop li REG_LoopCount,0 li REG_TotalPlayerCount,0 TagMelee_Think_FrozenRespawnAllPlayersLoop: #Check Players Presence mr r3,REG_LoopCount branchl r12,0x800322c0 cmpwi r3,0x2 bne TagMelee_Think_FrozenRespawnAllPlayersIncLoop #Check if player has stocks remaining mr r3,REG_LoopCount branchl r12,0x80033bd8 cmpwi r3,0 ble TagMelee_Think_FrozenRespawnAllPlayersIncLoop #Get data mr r3,REG_LoopCount branchl r12,0x80034110 mr REG_PlayerGObj,r3 #Remove Items + Etc mr r3,REG_PlayerGObj branchl r12,0x800d331c #Enter into Sleep mr r3,REG_PlayerGObj li r4,0x1 branchl r12,0x800bfd9c TagMelee_Think_FrozenRespawnAllPlayersIncLoop: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,6 blt TagMelee_Think_FrozenRespawnAllPlayersLoop #Change state to start li r3,Start stb r3,GameState(REG_GObjData) b TagMelee_ThinkExit #endregion TagMelee_ThinkExit: restore blr #endregion InjectionExit: li r6,0 ================================================ FILE: ASM/Additional Codes/Hide Nametag When Invisible.asm ================================================ #To be inserted at 802fccd8 .include "../Globals.s" #Check if Doubles load r3,0x8046b6a0 lbz r3,0x24D0(r3) cmpwi r3, 0x1 beq Original #Get PLayer lbz r3, 0(r31) branchl r12,0x80034110 #Get Player Data lwz r4,0x2C(r3) #Check if Mewtwo lwz r3,0x4(r4) cmpwi r3,0x10 bne NotMewtwoAridodge #Check if Airdodging lwz r3,0x10(r4) cmpwi r3,0xEC beq HideNametag NotMewtwoAridodge: #Get Invis Bit lbz r3,0x221E(r4) rlwinm. r3, r3, 0, 24, 24 beq- Original HideNametag: #Is Invisible, Hide Tag lis r12, 0x802F ori r12, r12, 0xCCC8 mtctr r12 bctr Original: cmplwi r30, 0 ================================================ FILE: ASM/Additional Codes/Hide Player GFX When Hitboxes Enabled/Hide GFX When Hitboxes Enabled.asm ================================================ #To be inserted at 8005FE30 .include "../../Globals.s" #Check if a GObj was sent as an arg cmpwi r4,0 beq Original #Check if this is a player GObj lhz r8,0x0(r4) cmpwi r8,0x4 beq Fighter cmpwi r8,0x6 beq Item b Original Fighter: #Get player's hitbox visibility flag lwz r8,0x2C(r4) lbz r8,0x21FC(r8) rlwinm. r8,r8,0,30,30 beq Original b Skip Item: #Get item's hitbox visibility flag lwz r8,0x2C(r4) lbz r8,0xDAA(r8) rlwinm. r8,r8,0,30,30 beq Original b Skip Skip: li r3,0 branch r12,0x80061d40 Original: addi r28, r3, 0 ================================================ FILE: ASM/Additional Codes/Hide Player GFX When Hitboxes Enabled/Hide OnHit GFX When Hitboxes Enabled 2.asm ================================================ #To be inserted at 8007a430 .include "../../Globals.s" #Get player's hitbox visibility flag lwz r12, 0x002C (r30) lbz r12,0x21FC(r12) rlwinm. r12,r12,0,30,30 beq Original branch r12,0x8007a6a8 Original: lwz r0, 0x0030 (r17) ================================================ FILE: ASM/Additional Codes/Hide Player GFX When Hitboxes Enabled/Hide OnHit GFX When Hitboxes Enabled.asm ================================================ #To be inserted at 8007a180 .include "../../Globals.s" #Get player's hitbox visibility flag lbz r0,0x21FC(r6) rlwinm. r0,r0,0,30,30 beq Original branch r12,0x8007a6a8 Original: lwz r0, 0x0030 (r4) ================================================ FILE: ASM/Additional Codes/Hitbox Color Changes Based On Damage.asm ================================================ #To be inserted at 80009fa4 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 .set playerdata,31 #r0 is free #r5 is free #18 = 0 #5 = 187 #minimum GB value - (damage * (minimum GB value /max damage) #Get Values lfs f5,0xC(r3) #Get Hitbox Damage bl Floats mflr r5 lfs f6,0x0(r5) #Min GB Value lfs f7,0x4(r5) #Damage Value for Lightest Color lfs f8,0x8(r5) #Damage Value for Darkest Color #Check If Does Over Max Damage Accounted For fcmpo cr0,f5,f8 blt CheckMin li r6,0x0 b StoreGandB CheckMin: #Check If Does Under Min Damage Accounted For fcmpo cr0,f5,f7 bgt Formula lfs f8,0x0(r5) #Value for Lightest Color b ConvertToDecimal #Formula Formula: fsubs f8,f8,f7 fsubs f5,f5,f7 fsubs f7,f7,f7 fdivs f8,f6,f8 #(minimum GB value /max damage) fmuls f8,f5,f8 #(damage * (minimum GB value /damage range) fsubs f8,f6,f8 #minimum GB value - (damage * (minimum GB value /damage range) #Convert To Decimal ConvertToDecimal: fctiwz f5,f8 stfd f5,-0xC(sp) lwz r6,-0x8(sp) #Get Hitbox Damage as Int #Store As G and B Value StoreGandB: subi r5, r13, 32768 #Get Hitbox Color in DOL stb r6,0x1(r5) #G stb r6,0x2(r5) #B b exit Floats: blrl .long 0x43580000 #Min GB Value 187 .long 0x40A00000 #Damage Value for Lightest Color 5 .long 0x41900000 #Damage Value for Darkest Color 18 exit: ================================================ FILE: ASM/Additional Codes/Hold A+B for Salty Runback + Hold A+X for Random Stage + Skip Result Screen.asm ================================================ #To be inserted at 801a5b14 .include "../Globals.s" .set REG_LoopCount,29 #Init loop li REG_LoopCount,0 Loop: #Get players inputs mr r3,REG_LoopCount branchl r12,0x801a3680 #Check Inputs rlwinm. r0, r4, 0, 23, 23 #check A beq- LoopInc rlwinm. r0, r4, 0, 22, 22 #check B bne- Runback rlwinm. r0, r4, 0, 21, 21 #check X bne RandomStage LoopInc: addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,4 blt Loop b LoadCSS Runback: li r27,0x2 #reload match scene b exit RandomStage: branchl r12,0x802599EC #get random stage ID #convert SSS ID to internal stage ID load r4,0x803f06D0 #load stage ID table mulli r3, r3, 28 #stage ID to offset add r4,r4,r3 #add to start of table lbz r3,0xB(r4) #get internal stage ID #Store to match struct load r4,0x8045AC64 #load VS match struct sth r3,0x2(r4) #store stage half to struct #Store to preload table load r4,0x8043207c #Preload Cache stw r3,0xC(r4) #Store to Preload Cache #Request Load branchl r12,0x80018254 li r27,0x2 #reload match scene b exit LoadCSS: li r27,0 # 4 is results exit: Original: li r29, 0 ================================================ FILE: ASM/Additional Codes/Hold Z for Rapid Frame Advance/New Inputs Don't Reset Rapid Timer.s ================================================ #To be inserted at 80377944 .include "../../Globals.s" #Check if nothing is pressed lwz r0, 0x0000 (r26) cmpwi r0,0 beq Exit #If something is pressed, dont reset timer branch r12,0x80377984 Exit: lwz r0, 0x0008 (r26) ================================================ FILE: ASM/Additional Codes/Hold Z for Rapid Frame Advance/P1 - Check Rapid Fire Input.asm ================================================ #To be inserted at 8016bbd4 lwz r0, 0x000C (r4) ================================================ FILE: ASM/Additional Codes/Hold Z for Rapid Frame Advance/P2 - Check Rapid Fire Input.asm ================================================ #To be inserted at 8016bc00 lwz r0, 0x000C (r4) ================================================ FILE: ASM/Additional Codes/Hold Z for Rapid Frame Advance/P3 - Check Rapid Fire Input.asm ================================================ #To be inserted at 8016bc2c lwz r0, 0x000C (r4) ================================================ FILE: ASM/Additional Codes/Hold Z for Rapid Frame Advance/P4 - Check Rapid Fire Input.asm ================================================ #To be inserted at 8016bc58 lwz r0, 0x000C (r4) ================================================ FILE: ASM/Additional Codes/Idle Screen/Main.asm ================================================ #To be inserted at 80302788 .include "../../Globals.s" .set IdleThreshold, (3*60) * 60 .set REG_DevelopText,31 .set REG_GObjData,30 .set REG_GObj,29 .set REG_Floats,28 backup bl Floats mflr REG_Floats #Create Rectangle li r3,32 branchl r12,HSD_MemAlloc mr r8,r3 li r3,20 li r4,-25 li r5,-25 li r6,1 li r7,1 branchl r12,DevelopText_CreateDataTable mr REG_DevelopText,r3 #Activate Text lwz r3, -0x4884 (r13) mr r4,REG_DevelopText branchl r12,DevelopText_Activate #Hide blinking cursor li r3,0 stb r3,0x26(REG_DevelopText) #Change BG Color mr r3,REG_DevelopText addi r4,REG_Floats,TextBG branchl r12,DevelopText_StoreBGColor #Hide Filter mr r3,REG_DevelopText branchl r12,DevelopText_HideBG #Set Stretch lfs f1,TextScale_X(REG_Floats) stfs f1,0x8(REG_DevelopText) lfs f1,TextScale_Y(REG_Floats) stfs f1,0xC(REG_DevelopText) #Create Background GObj li r3,0 li r4,0 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Allocate Space li r3,64 branchl r12,HSD_MemAlloc mr REG_GObjData,r3 #Zero li r4,64 branchl r12,ZeroAreaLength #Initialize mr r6,REG_GObjData mr r3,REG_GObj li r4,4 load r5,HSD_Free branchl r12,GObj_AddUserData #Add Process mr r3,REG_GObj bl IdleThink mflr r4 li r5,0 branchl r12,GObj_AddProc #Store pointer to dev text stw REG_DevelopText,0x0(REG_GObjData) b Injection_Exit IdleThink: blrl .set REG_GObjData,31 .set REG_Floats,30 .set IdleData_Text,0x0 .set IdleData_State,0x4 .set IdleData_VolumeBackup,0x8 .set IdleData_IdleCounter,0xC backup #Init lwz REG_GObjData,0x2C(r3) bl Floats mflr REG_Floats #Check if already muted lwz r3,IdleData_State(REG_GObjData) cmpwi r3,0x0 bne IdleThink_CheckToUnmute IdleThink_CheckToMute: #Check if anyone is inputting on this frame li r3,4 branchl r12,Inputs_GetPlayerHeldInputs cmpwi r4,0 beq IdleThink_CheckToMute_IncTimer IdleThink_CheckToMute_ResetTimer: li r3,0 stw r3,IdleData_IdleCounter(REG_GObjData) b IdleThink_Exit IdleThink_CheckToMute_IncTimer: lwz r3,IdleData_IdleCounter(REG_GObjData) addi r3,r3,1 stw r3,IdleData_IdleCounter(REG_GObjData) cmpwi r3,IdleThreshold blt IdleThink_Exit #Mute Music lwz r4,-0x7E1C(r13) stw r4,IdleData_VolumeBackup(REG_GObjData) li r3,0 branchl r12,cvt_sll_flt lfs f2,VolumeMultiplier(REG_Floats) fmuls f1,f1,f2 branchl r12,cvt_fp2unsigned stw r3,-0x7E1C(r13) #Display filter lwz r3,IdleData_Text(REG_GObjData) branchl r12,DevelopText_ShowBG #Change state li r3,1 stw r3,IdleData_State(REG_GObjData) #Reset Timer li r3,0 stw r3,IdleData_IdleCounter(REG_GObjData) b IdleThink_Exit IdleThink_CheckToUnmute: #Check if anyone is inputting on this frame li r3,4 branchl r12,Inputs_GetPlayerHeldInputs cmpwi r4,0 beq IdleThink_Exit #Unmute music lwz r3,IdleData_VolumeBackup(REG_GObjData) stw r3,-0x7E1C(r13) #Hide Filter lwz r3,IdleData_Text(REG_GObjData) branchl r12,DevelopText_HideBG #Change state li r3,0 stw r3,IdleData_State(REG_GObjData) b IdleThink_Exit IdleThink_Exit: restore blr ###################### Floats: blrl .set TextScale_X,0x0 .set TextScale_Y,0x4 .set TextBG,0x8 .set VolumeMultiplier,0xC .float 1000 .float 1000 .byte 0,0,0,130 .float 0.3 ###################### Injection_Exit: restore mr r3, r31 ================================================ FILE: ASM/Additional Codes/Initialize Stage Data.asm ================================================ #To be inserted at 801c154c .include "../Globals.s" #Initialize data li r4,516 branchl r12,ZeroAreaLength Exit: cmplwi r26, 0 ================================================ FILE: ASM/Additional Codes/Kill Zoom/Main.s ================================================ #To be inserted at 8016e5a8 .include "../../Globals.s" CreateProc: .set REG_Data,31 .set REG_GObj,30 backup #Create GObj li r3,4 #GObj Type (4 is the player type, this should ensure it runs before any player animations) li r4,0 #On-Pause Function (dont run on pause) li r5,0 #object priority branchl r12,GObj_Create mr REG_GObj,r3 #Alloc Mem li r3,32 branchl r12,HSD_MemAlloc mr REG_Data,r3 #Zero Data mr r3,REG_Data li r4,32 branchl r12,ZeroAreaLength #Attach Data mr r3,REG_GObj li r4,14 load r5,HSD_Free mr r6,REG_Data branchl r12,GObj_AddUserData #Create Proc bl KillZoomThink mflr r4 #Function li r5,14 #Priority branchl r12,GObj_AddProc b CreateProc_Exit ############################################################# KillZoomThink: blrl .set REG_GObjData,31 .set REG_PlayerData,30 .set REG_PlayerGObj,29 .set REG_Constants,28 #Init backup lwz REG_GObjData,0x2C(r3) bl Constants mflr REG_Constants #Ensure match type is stock branchl r12,0x8016ae50 lbz r0,0x4(r3) rlwinm. r0,r0,0,0x20 bne KillZoomThink_IsStock branchl r12,0x8016b094 cmpwi r3,0 beq KillZoomThink_Exit KillZoomThink_IsStock: #Check if currently zooming load r3,0x80452c68 lwz r0,0x4(r3) cmpwi r0,6 bne LoopThroughPlayers_GetFirstPlayer #Decrement Freeze Timer lwz r3,0x0(REG_GObjData) subi r3,r3,1 stw r3,0x0(REG_GObjData) cmpwi r3,0 bgt KillZoomThink_Exit #Resume Game Speed li r3,1 branchl r12,0x801a4674 #Restore camera to normal branchl r12,0x8015cc14 b KillZoomThink_Exit #Loop through all players LoopThroughPlayers_GetFirstPlayer: lwz r3, -0x3E74 (r13) lwz REG_PlayerGObj, 0x0020 (r3) b LoopThroughPlayers_CheckIfPlayerExists LoopThroughPlayers_GetNextPlayer: lwz REG_PlayerGObj,0x8(REG_PlayerGObj) LoopThroughPlayers_CheckIfPlayerExists: cmpwi REG_PlayerGObj,0x0 beq KillZoomThink_Exit lwz REG_PlayerData,0x2C(REG_PlayerGObj) #Ensure not in sleep lbz r3, 0x221F(REG_PlayerData) rlwinm. r0,r3,0,0x10 bne LoopThroughPlayers_GetNextPlayer #Ensure not a follower rlwinm. r0, r3, 29, 31, 31 beq FollowerSkip #Check If Follower lbz r3,0xC(REG_PlayerData) branchl r12, PlayerBlock_LoadExternalCharID load r4,0x803bcde0 #pdLoadCommonData table mulli r0, r3, 3 #struct length add r3,r4,r0 #get characters entry lbz r0, 0x2(r3) #get subchar functionality cmpwi r0,0x0 #if a follower, exit beq LoopThroughPlayers_GetNextPlayer FollowerSkip: #Check if in hitstun lbz r3, 0x221C(REG_PlayerData) rlwinm. r0,r3,0,0x2 beq LoopThroughPlayers_GetNextPlayer #Check if in hitlag lbz r3, 0x221A(REG_PlayerData) rlwinm. r0,r3,0,0x20 beq LoopThroughPlayers_GetNextPlayer #Check if last frame of hitlag lfs f1,-0x7418(rtoc) #1fp lfs f2,0x195C(REG_PlayerData) #hitlag frames left fcmpo cr0,f1,f2 bne LoopThroughPlayers_GetNextPlayer #Check if will die from this hit mr r3,REG_PlayerData bl DIDraw cmpwi r3,0 beq LoopThroughPlayers_GetNextPlayer #Check if last stock lbz r3,0xC(REG_PlayerData) branchl r12,PlayerBlock_LoadStocksLeft cmpwi r3,1 beq KillZoomThink_KOZoom b KillZoomThink_KOFlash KillZoomThink_KOZoom: .set ZoomInFrames,6 .set FreezeFrames,ZoomInFrames+20 #Zoom in on this player lwz r3,0x10B0(REG_PlayerData) stw r3,0x80(sp) lwz r3,0x10B4(REG_PlayerData) stw r3,0x84(sp) lwz r3,0x10B8(REG_PlayerData) stw r3,0x88(sp) addi r3,sp,0x80 lwz r4,0x1868(REG_PlayerData) cmpwi r4,0x0 beq KillZoomThink_HitByNonPlayer lhz r5,0x0(r4) cmpwi r5,0x4 beq KillZoomThink_HitByPlayer #Just use the victims sphere KillZoomThink_HitByNonPlayer: addi r3,sp,0x80 b KillZoomThink_ZoomInOnCoordinates KillZoomThink_HitByPlayer: lwz r4,0x2C(r4) addi r4,r4,0x10B0 branchl r12,0x8000d46c #Add vectors lfs f1,Divisor(REG_Constants) lfs f2,0x80(sp) fdivs f2,f2,f1 stfs f2,0x80(sp) lfs f2,0x84(sp) fdivs f2,f2,f1 stfs f2,0x84(sp) lfs f2,0x88(sp) fdivs f2,f2,f1 stfs f2,0x88(sp) addi r3,sp,0x80 KillZoomThink_ZoomInOnCoordinates: #Set coordinates branchl r12,0x8002e818 #Adjust Zoom value lfs f1,ZoomValue(REG_Constants) stfs f1,0x88(sp) addi r3,sp,0x80 branchl r12,0x8002ea64 #Adjust frames to zoom in li r3,ZoomInFrames branchl r12,0x8002f0e4 #Set Freeze Frames li r3,FreezeFrames stw r3,0x0(REG_GObjData) #Freeze Game li r3,1 branchl r12,0x801a4634 #Play SFX li r3,0xDF branchl r12,SFX_PlaySoundAtFullVolume #Spawn GFX lwz r3,0x0(REG_PlayerData) li r4,0x1b3 li r5,3 li r6,0 li r7,0 addi r8,sp,0x80 addi r9,sp,0x8C #Setup stack li r0,0 stw r0,0x0(r8) #z scatter stw r0,0x4(r8) #y scatter stw r0,0x8(r8) #z scatter li r0,0 stw r0,0x0(r9) #X offset stw r0,0x4(r9) #y offset stw r0,0x8(r9) #z offset branchl r12,0x8009f834 #Spawn GFX lwz r3,0x0(REG_PlayerData) li r4,0xd5 li r5,3 li r6,0 li r7,0 addi r8,sp,0x80 addi r9,sp,0x8C #Setup stack li r0,0 stw r0,0x0(r8) #z scatter stw r0,0x4(r8) #y scatter stw r0,0x8(r8) #z scatter li r0,0 stw r0,0x0(r9) #X offset stw r0,0x4(r9) #y offset stw r0,0x8(r9) #z offset branchl r12,0x8009f834 b KillZoomThink_Exit KillZoomThink_KOFlash: #Play SFX li r3,0x122 #12a #122 #0xff branchl r12,SFX_PlaySoundAtFullVolume #Spawn GFX lwz r3,0x0(REG_PlayerData) li r4,0x8e li r5,3 li r6,0 li r7,0 addi r8,sp,0x80 addi r9,sp,0x8C #Setup stack li r0,0 stw r0,0x0(r8) #z scatter stw r0,0x4(r8) #y scatter stw r0,0x8(r8) #z scatter li r0,0 stw r0,0x0(r9) #X offset stw r0,0x4(r9) #y offset stw r0,0x8(r9) #z offset branchl r12,0x8009f834 #Spawn GFX lwz r3,0x0(REG_PlayerData) li r4,0x1e4 li r5,3 li r6,0 li r7,0 addi r8,sp,0x80 addi r9,sp,0x8C #Setup stack li r0,0 stw r0,0x0(r8) #z scatter stw r0,0x4(r8) #y scatter stw r0,0x8(r8) #z scatter li r0,0 stw r0,0x0(r9) #X offset stw r0,0x4(r9) #y offset stw r0,0x8(r9) #z offset branchl r12,0x8009f834 KillZoomThink_Exit: restore blr #region DI Draw DIDraw_Constants: blrl .set ECB_TopY,0x0 #scale * value .set ECB_BottomY,0x4 #neg(scale * vlaue) .set ECB_LeftX,0x8 #neg(scale * vlaue) .set ECB_LeftY,0xC #0 .set ECB_RightX,0x10 #scale * value .set ECB_RightY,0x14 #0 .set FirefoxDrawZ,0x18 .set AliveLineColor,0x1C .set DeadLineColor,0x20 .set LeftWallColor,0x24 .set RightWallColor,0x28 .set CeilingColor,0x2C .set GroundColor,0x30 .set ASDIColor,0x34 .float 9 .float 2.5 .float -3.3 .float 5.7 .float 3.3 .float 5.7 .float 10 .byte 0, 138, 255, 255 .byte 255, 55, 55, 255 .byte 12, 255, 41, 255 .byte 12, 255, 41, 255 .byte 255, 0, 255, 255 .byte 255, 255, 255, 255 .byte 255, 86, 20, 255 .set StackSize,0x300 .set Stack_BackedUpReg,0x8 .set Stack_BackedUpReg_Length,0x30 .set Stack_BackedUpFloats, (Stack_BackedUpReg+Stack_BackedUpReg_Length) .set Stack_BackedUpFloats_Length,0x14 .set Stack_ECBBoneStruct, (Stack_BackedUpFloats+Stack_BackedUpFloats_Length) .set Stack_ECBBoneStruct_Length,0x18 .set Stack_ECBStruct, (Stack_ECBBoneStruct+Stack_ECBBoneStruct_Length) .set Stack_ECBStruct_Length,0x1AC .set Stack_ASDIBackup, (Stack_ECBStruct+Stack_ECBStruct_Length) .set Stack_ASDIBackup_Length,0x8 .set Stack_MiscSpace, (Stack_ASDIBackup+Stack_ASDIBackup_Length) #gprs .set REG_EventConstants,31 .set REG_PlayerData,30 .set REG_ECBStruct,20 .set REG_ECBBoneStruct,21 .set REG_LoopCount,22 .set REG_GX,23 .set REG_HeldInputs,24 .set REG_GroundState,24 .set REG_CollisionInfo,25 .set REG_Temp,26 #this register is used for the draw loop, make sure to change both .set REG_OverrideRemainingFrames,27 #fprs .set REG_arctan,31 .set REG_XComp,30 .set REG_YComp,29 .set REG_KnockbackX,28 .set REG_KnockbackY,27 .set REG_CurrXPos,26 .set REG_CurrYPos,25 .set REG_DIInput,24 .set REG_KnockbackMag,23 .set REG_CStickX,22 .set REG_CStickY,21 .set REG_ASDIX,22 .set REG_ASDIY,21 .set REG_Gravity,30 #constants .set MaxColl,40 DIDraw: mflr r0 stw r0, 0x4(r1) stwu r1,-StackSize(r1) # make space for 12 registers stmw r20,Stack_BackedUpReg(r1) #backup mr REG_PlayerData,r3 #Get Floats bl DIDraw_Constants mflr REG_EventConstants #region GetInputs DIDraw_PBInputs: lfs REG_XComp,0x620(REG_PlayerData) lfs REG_YComp,0x624(REG_PlayerData) lwz REG_HeldInputs,0x65C(REG_PlayerData) lfs REG_CStickX,0x638(REG_PlayerData) lfs REG_CStickY,0x63C(REG_PlayerData) #endregion #Get original KB vector lfs REG_KnockbackX,0x8C(REG_PlayerData) lfs REG_KnockbackY,0x90(REG_PlayerData) #Calculate player's influence over trajectory #region GetArctan DIDraw_GetArctan: #Get atan2 fmr f1,REG_KnockbackY fmr f2,REG_KnockbackX branchl r12,0x80022c30 fmr REG_arctan,f1 #Do something fmuls f1,REG_KnockbackY,REG_KnockbackY fmadds REG_KnockbackMag,REG_KnockbackX,REG_KnockbackX,f1 lfs f0, -0x750C (rtoc) fcmpo cr0,REG_KnockbackMag,f0 ble DIDraw_SkipUnk #Do a bunch of stuff frsqrte f2,REG_KnockbackMag lfd f4, -0x74E0 (rtoc) lfd f3, -0x74D8 (rtoc) fmul f0,f2,f2 fmul f2,f4,f2 fnmsub f0,REG_KnockbackMag,f0,f3 fmul f2,f2,f0 fmul f0,f2,f2 fmul f2,f4,f2 fnmsub f0,REG_KnockbackMag,f0,f3 fmul f2,f2,f0 fmul f0,f2,f2 fmul f2,f4,f2 fnmsub f0,REG_KnockbackMag,f0,f3 fmul f0,f2,f0 fmul f0,REG_KnockbackMag,f0 frsp f0,f0 fmr REG_KnockbackMag,f0 DIDraw_SkipUnk: #endregion #region CalculateASDI DIDraw_CalculateASDI: #CStick has priority #Check if cstick magnitude > 0.7 fmuls f1,REG_CStickX,REG_CStickX fmuls f0,REG_CStickY,REG_CStickY lwz r3, -0x514C (r13) lfs f2, 0x04B0 (r3) fadds f1,f1,f0 fmuls f0,f2,f2 fcmpo cr0,f1,f0 bge DIDraw_CalculateASDICStickApply #Now check left stick fmuls f1,REG_YComp,REG_YComp fmuls f2,REG_XComp,REG_XComp lwz r3, -0x514C (r13) lfs f0, 0x04B0 (r3) fmuls f0,f0,f0 fadds f1,f1,f2 fcmpo cr0,f1,f0 blt DIDraw_CalculateASDINone DIDraw_CalculateASDILeftStickApply: #Multiply by 3 lfs f1, 0x04BC (r3) fmuls REG_ASDIX,REG_XComp,f1 fmuls REG_ASDIY,REG_YComp,f1 b DIDraw_CalculateASDIEnd DIDraw_CalculateASDINone: #Null ASDI lfs REG_ASDIX, -0x750C (rtoc) lfs REG_ASDIY, -0x750C (rtoc) b DIDraw_CalculateASDIEnd DIDraw_CalculateASDICStickApply: #Multiply by 3 lfs f1, 0x04BC (r3) fmuls REG_ASDIX,REG_CStickX,f1 fmuls REG_ASDIY,REG_CStickY,f1 DIDraw_CalculateASDIEnd: #Save these values for later stfs REG_ASDIX,Stack_ASDIBackup+0(sp) stfs REG_ASDIY,Stack_ASDIBackup+4(sp) #endregion #region CalculateKBReduction DIDraw_CalculateKBReduction: #Check if holding L/R/Z rlwinm. r0,REG_HeldInputs,0,0x80000000 beq DIDraw_CalculateKBReductionEnd lwz r3, -0x514C (r13) lfs f0, 0x01AC (r3) fmuls REG_KnockbackMag,f0,REG_KnockbackMag fmr f1,REG_arctan branchl r12,cos fmuls REG_KnockbackX,f1,REG_KnockbackMag fmr f1,REG_arctan branchl r12,sin fmuls REG_KnockbackY,f1,REG_KnockbackMag #Get new atan2 fmr f1,REG_KnockbackY fmr f2,REG_KnockbackX branchl r12,0x80022c30 fmr REG_arctan,f1 DIDraw_CalculateKBReductionEnd: #endregion #region CalculateDI DIDraw_CalculateDI: #If grounded, skip DI lwz r3,0xE0(REG_PlayerData) cmpwi r3,0 beq DIDraw_CalculateDIEnd #If both inputting nothing, skip DI lfs f1, -0x750C (rtoc) fcmpo cr0,f1,REG_XComp bne DIDraw_IsInputting fcmpo cr0,f1,REG_YComp beq DIDraw_CalculateDIEnd DIDraw_IsInputting: #If some condition is met, skip DI lfs f0, -0x74E8 (rtoc) fneg f1,REG_KnockbackX fmuls f1,f1,f1 fmuls f2,REG_KnockbackY,REG_KnockbackY fadds f1,f1,f2 fcmpo cr0,f1,f0 blt DIDraw_CalculateDIEnd #Get DI value fneg f2,REG_KnockbackX fmuls f2,f2,REG_YComp fmuls f3,REG_KnockbackY,REG_XComp fadds f2,f2,f3 fmuls f2,f2,f2 fdivs REG_DIInput,f2,f1 lfs f4, -0x750C (rtoc) #Cross product stfs REG_XComp,Stack_MiscSpace+0(sp) stfs REG_YComp,Stack_MiscSpace+4(sp) lfs f0, -0x750C (rtoc) stfs f0,Stack_MiscSpace+8(sp) addi r3,REG_PlayerData,0x8C addi r4,sp,Stack_MiscSpace+0 addi r5,sp,Stack_MiscSpace+12 branchl r12,0x80342e58 #Check if over 0 lfs f0, -0x750C (rtoc) lfs f1,Stack_MiscSpace+20(sp) fcmpo cr0,f1,f0 bge 0x8 fneg REG_DIInput,REG_DIInput #Apply new angle lwz r3, -0x514C (r13) lfs f2, -0x7510 (rtoc) lfs f0, 0x01A8 (r3) fmuls f0,f2,f0 fmadds REG_arctan,f0,REG_DIInput,REG_arctan fmr f1,REG_arctan branchl r12,cos fmuls REG_KnockbackX,REG_KnockbackMag,f1 fmr f1,REG_arctan branchl r12,sin fmuls REG_KnockbackY,REG_KnockbackMag,f1 DIDraw_CalculateDIEnd: #endregion #Perform collision checks for each frame of hitstun #region DIDraw_Collision #region DIDraw_CollisionLoop_Init DIDraw_CollisionLoop_Init: #Create an ECB struct on the stack addi REG_ECBBoneStruct,sp,Stack_ECBBoneStruct addi REG_ECBStruct,sp,Stack_ECBStruct mr r3,REG_ECBStruct branchl r12,0x80041ee4 #Get Current XY lfs REG_CurrXPos,0xB0(REG_PlayerData) lfs REG_CurrYPos,0xB4(REG_PlayerData) #Init Loop li REG_LoopCount,0 lfs REG_Gravity,-0x750C (rtoc) lwz REG_GroundState,0xE0(REG_PlayerData) li REG_OverrideRemainingFrames,0 #Allocate collision info struct lfs f1,0x2340(REG_PlayerData) fctiwz f1,f1 stfd f1,Stack_MiscSpace(sp) lwz r3,Stack_MiscSpace+4(sp) mulli r3,r3,CollInfo_Length #backing up X bytes per collision check addi r3,r3,0x4 #small header containing the amount of collision checks branchl r12,HSD_MemAlloc mr REG_CollisionInfo,r3 #Init collision info struct li r3,-1 #init as 0 checks stw r3,0x0(REG_CollisionInfo) #If grounded, copy over ground ECB data cmpwi REG_GroundState,0 bne DIDraw_DrawTrajectory_SkipCopyGroundData addi r3,REG_ECBStruct,0x130 addi r4,REG_PlayerData,0x820 li r5,0x28 branchl r12,memcpy DIDraw_DrawTrajectory_SkipCopyGroundData: #endregion #region DIDraw_CollisionLoop_Start DIDraw_CollisionLoop: #region Initalize ECB Bone Positions #Create ECB Bone struct #If loop count < noECBUpdate-remaining hitlag fraes, use current ECB bottom Y offset lwz r3,0x88C(REG_PlayerData) lfs f1,0x195C(REG_PlayerData) fctiwz f1,f1 stfd f1,Stack_MiscSpace(sp) lwz r4,Stack_MiscSpace+0x4(sp) sub r3,r3,r4 cmpw REG_LoopCount,r3 blt DIDraw_CollisionLoop_ECBBonesUseCurrent #Copy Struct mr r3,REG_ECBBoneStruct addi r4,REG_EventConstants,ECB_TopY li r5,0x18 branchl r12,memcpy #If the player is grounded, ECB bottom is 0 cmpwi REG_GroundState,0 bne DIDraw_CollisionLoop_ECBBonesEnd lfs f1, -0x750C (rtoc) stfs f1,0x04(REG_ECBBoneStruct) b DIDraw_CollisionLoop_ECBBonesEnd DIDraw_CollisionLoop_ECBBonesUseCurrent: #Use Current Bone Positions lfs f1,0x778(REG_PlayerData) stfs f1,0x00(REG_ECBBoneStruct) lfs f1,0x780(REG_PlayerData) stfs f1,0x04(REG_ECBBoneStruct) lfs f1,0x78C(REG_PlayerData) stfs f1,0x08(REG_ECBBoneStruct) lfs f1,0x790(REG_PlayerData) stfs f1,0x0C(REG_ECBBoneStruct) lfs f1,0x784(REG_PlayerData) stfs f1,0x10(REG_ECBBoneStruct) lfs f1,0x788(REG_PlayerData) stfs f1,0x14(REG_ECBBoneStruct) b DIDraw_CollisionLoop_ECBBonesEnd DIDraw_CollisionLoop_ECBBonesEnd: #Store current position lfs f1, -0x750C (rtoc) stfs REG_CurrXPos,0x4(REG_ECBStruct) stfs REG_CurrYPos,0x8(REG_ECBStruct) stfs f1,0xC(REG_ECBStruct) stfs REG_CurrXPos,0x10(REG_ECBStruct) stfs REG_CurrYPos,0x14(REG_ECBStruct) stfs f1,0x18(REG_ECBStruct) #endregion #region Apply ASDI DIDraw_CollisionLoop_ApplyASDI: #Apply ASDI X fadds REG_CurrXPos,REG_CurrXPos,REG_ASDIX #Only apply ASDI Y if in the air cmpwi REG_GroundState,0 beq 0x8 fadds REG_CurrYPos,REG_CurrYPos,REG_ASDIY #Null ASDI lfs REG_ASDIX, -0x750C (rtoc) lfs REG_ASDIY, -0x750C (rtoc) #endregion #region Decay Knockback #Apply either gravity or traction cmpwi REG_GroundState,1 bne DIDraw_CollisionLoop_DecayGrounded DIDraw_CollisionLoop_DecayAerial: #Account for gravity lfs f1, 0x016C (REG_PlayerData) lfs f2, 0x0170 (REG_PlayerData) fneg f2,f2 fsubs REG_Gravity,REG_Gravity,f1 fcmpo cr0,REG_Gravity,f2 bge 0x8 fmr REG_Gravity,f2 #Decay KB Vector fmr f1,REG_KnockbackY fmr f2,REG_KnockbackX branchl r12,0x80022c30 #Get arctan of the KB vector fmr REG_arctan,f1 #Decay X KB branchl r12,cos lwz r3, -0x514C (r13) lfs f2, 0x0204 (r3) fnmsubs REG_KnockbackX,f2,f1,REG_KnockbackX #Decay Y KB fmr f1,REG_arctan branchl r12,sin lwz r3, -0x514C (r13) lfs f2, 0x0204 (r3) fnmsubs REG_KnockbackY,f2,f1,REG_KnockbackY b DIDraw_CollisionLoop_DecayEnd DIDraw_CollisionLoop_DecayGrounded: #Get Ground Friction's multipllier lwz r3,0x4(REG_PlayerData) cmpwi r3,Popo.Int beq DIDraw_CollisionLoop_DecayGrounded_isICs cmpwi r3,Nana.Int beq DIDraw_CollisionLoop_DecayGrounded_isICs #Get grounds friction multiplier lfs f1, -0x7A38 (rtoc) lwz r0, 0x014C (REG_ECBStruct) cmpwi r0,-1 beq DIDraw_CollisionLoop_DecayGrounded_isICs lwz r3,0x150(REG_ECBStruct) branchl r12,0x800569ec #Get ground's friction multiplier b 0x8 DIDraw_CollisionLoop_DecayGrounded_isICs: lfs f1, -0x7A38 (rtoc) #Account for friction lfs f0, 0x128 (REG_PlayerData) fmuls f1,f0,f1 lwz r4, -0x514C (r13) lfs f0, 0x0200 (r4) fmuls f0,f1,f0 #Apply Friction to knockback lfs f2, -0x76B0 (rtoc) fcmpo cr0,REG_KnockbackX,f2 bge DIDraw_CollisionLoop_DecayGrounded_Subtract fadds f0,f0,REG_KnockbackX fmr REG_KnockbackX,f0 fcmpo cr0,f0,f2 ble DIDraw_CollisionLoop_DecayGroundedEnd fmr REG_KnockbackX,f2 b DIDraw_CollisionLoop_DecayGroundedEnd DIDraw_CollisionLoop_DecayGrounded_Subtract: fsubs f0,REG_KnockbackX,f0 fmr REG_KnockbackX,f0 fcmpo cr0,f0,f2 bge DIDraw_CollisionLoop_DecayGroundedEnd fmr REG_KnockbackX,f2 b DIDraw_CollisionLoop_DecayGroundedEnd DIDraw_CollisionLoop_DecayGroundedEnd: DIDraw_CollisionLoop_DecayEnd: #endregion #region Shift Positions #Shift previous positions down lfs f1,0x4(REG_ECBStruct) lfs f2,0x8(REG_ECBStruct) lfs f3,0xC(REG_ECBStruct) stfs f1,0x1C(REG_ECBStruct) stfs f2,0x20(REG_ECBStruct) stfs f3,0x24(REG_ECBStruct) #Store next position fadds f1,REG_CurrXPos,REG_KnockbackX stfs f1,0x4(REG_ECBStruct) fadds f1,REG_CurrYPos,REG_KnockbackY fadds f1,f1,REG_Gravity stfs f1,0x8(REG_ECBStruct) lfs f1, -0x778C (rtoc) stfs f1,0xC(REG_ECBStruct) #endregion #region Run Collision Check .if MaxColl>=0 #Only run X collision checks because theyre expensive cmpwi REG_LoopCount,MaxColl blt DIDraw_CollisionLoop_DetermineCollision #Spoof as not touching anything li r3,0 stw r3,0x134(REG_ECBStruct) lfs REG_CurrXPos,0x4(REG_ECBStruct) lfs REG_CurrYPos,0x8(REG_ECBStruct) #If grounded and max collision checks, just stop updating position cmpwi REG_GroundState,0 bne DIDraw_CollisionLoop_StageBehaviorEnd li REG_OverrideRemainingFrames,1 b DIDraw_CollisionLoop_StageBehaviorEnd .endif DIDraw_CollisionLoop_DetermineCollision: #Run collision cmpwi REG_GroundState,1 beq DIDraw_CollisionLoop_AerialCollision DIDraw_CollisionLoop_GroundCollision: #Grounded Collision mr r3,REG_ECBStruct mr r4,REG_ECBBoneStruct branchl r12,0x8004b21c xori REG_GroundState,r3,0x1 b DIDraw_CollisionLoop_CollisionEnd DIDraw_CollisionLoop_AerialCollision: #Aerial Collision mr r3,REG_ECBStruct mr r4,REG_ECBBoneStruct branchl r12,0x800475f4 DIDraw_CollisionLoop_CollisionEnd: #endregion #region Stage Collision Behavior #Get new position lfs REG_CurrXPos,0x4(REG_ECBStruct) lfs REG_CurrYPos,0x8(REG_ECBStruct) #Inc Collision ID lwz r3,0x38(REG_ECBStruct) addi r3,r3,1 stw r3,0x38(REG_ECBStruct) #Determine line collision behavior lwz r3,0x134(REG_ECBStruct) rlwinm. r0,r3,0,0x8000 bne DIDraw_CollisionLoop_TouchingGround rlwinm. r0,r3,0,0x6000 bne DIDraw_CollisionLoop_TouchingCeiling rlwinm. r0,r3,0,0x20 bne DIDraw_CollisionLoop_TouchingWall rlwinm. r0,r3,0,0x40 bne DIDraw_CollisionLoop_TouchingWall DIDraw_CollisionLoop_TouchingNothing: b DIDraw_CollisionLoop_StageBehaviorEnd #region Touching Ground DIDraw_CollisionLoop_TouchingGround: #If grounded, dont run KB manip code cmpwi REG_GroundState,0 beq DIDraw_CollisionLoop_StageBehaviorEnd /* #End check li REG_OverrideRemainingFrames,1 */ #Check if over max horizontal velocity lwz r4, -0x514C (r13) lfs f1, 0x0164 (r4) fcmpo cr0,REG_KnockbackX,f1 ble 0x8 fmr REG_KnockbackX,f1 fneg f1,f1 fcmpo cr0,REG_KnockbackX,f1 bge 0x8 fmr REG_KnockbackX,f1 #Adjust KB lfs f1,0x158(REG_ECBStruct) fmuls REG_KnockbackX,REG_KnockbackX,f1 lfs f1,0x154(REG_ECBStruct) fneg f1,f1 fmuls REG_KnockbackY,REG_KnockbackX,f1 #REMOVE ALL Y KB? lfs REG_KnockbackY, -0x750C (rtoc) #Set as grounded li REG_GroundState,0 b DIDraw_CollisionLoop_StageBehaviorEnd #endregion #region Touching Ceiling DIDraw_CollisionLoop_TouchingCeiling: #If grounded, dont run KB manip code cmpwi REG_GroundState,0 beq DIDraw_CollisionLoop_StageBehaviorEnd #End check li REG_OverrideRemainingFrames,1 /* #Self-Induced velocity lfs f1, -0x750C (rtoc) stfs f1,Stack_MiscSpace+0x0(sp) stfs REG_Gravity,Stack_MiscSpace+0x4(sp) #KB-Induced stfs REG_KnockbackX,Stack_MiscSpace+0x8(sp) stfs REG_KnockbackY,Stack_MiscSpace+0xC(sp) #Add vectors addi r3,sp,Stack_MiscSpace+0x0 addi r4,sp,Stack_MiscSpace+0x8 branchl r12,0x8000d4a0 #Unk addi r3,sp,Stack_MiscSpace+0x0 addi r4,REG_ECBStruct,0x190 branchl r12,0x8000dc6c #Decay KB lwz r3, -0x514C (r13) lfs f1, 0x01BC (r3) lfs f2,Stack_MiscSpace+0x0(sp) lfs f3,Stack_MiscSpace+0x4(sp) fmuls REG_KnockbackX,f1,f2 fmuls REG_KnockbackY,f1,f3 */ b DIDraw_CollisionLoop_StageBehaviorEnd #endregion #region Touching Wall DIDraw_CollisionLoop_TouchingWall: #If grounded, dont run KB manip code cmpwi REG_GroundState,0 beq DIDraw_CollisionLoop_StageBehaviorEnd #End check li REG_OverrideRemainingFrames,1 /* #Get walls data lwz r3,0x134(REG_ECBStruct) rlwinm. r0,r3,0,0x20 bne DIDraw_CollisionLoop_LeftWallsData rlwinm. r0,r3,0,0x40 bne DIDraw_CollisionLoop_RightWallsData DIDraw_CollisionLoop_RightWallsData: addi REG_Temp,REG_ECBStruct,380 b 0x8 DIDraw_CollisionLoop_LeftWallsData: addi REG_Temp,REG_ECBStruct,360 #Self-Induced velocity lfs f1, -0x750C (rtoc) stfs f1,Stack_MiscSpace+0x0(sp) stfs REG_Gravity,Stack_MiscSpace+0x4(sp) #KB-Induced stfs REG_KnockbackX,Stack_MiscSpace+0x8(sp) stfs REG_KnockbackY,Stack_MiscSpace+0xC(sp) #Add vectors addi r3,sp,Stack_MiscSpace+0x0 addi r4,sp,Stack_MiscSpace+0x8 branchl r12,0x8000d4a0 #Unk addi r3,sp,Stack_MiscSpace+0x0 mr r4,REG_Temp branchl r12,0x8000dc6c #Decay KB lwz r3, -0x514C (r13) lfs f1, 0x01BC (r3) lfs f2,Stack_MiscSpace+0x0(sp) lfs f3,Stack_MiscSpace+0x4(sp) fmuls REG_KnockbackX,f1,f2 fmuls REG_KnockbackY,f1,f3 lfs REG_Gravity, -0x6DA0 (rtoc) */ b DIDraw_CollisionLoop_StageBehaviorEnd #endregion DIDraw_CollisionLoop_StageBehaviorEnd: #endregion #region Ground to Air Check .if MaxColl>=0 DIDraw_CollisionLoop_GroundToAirCheck: .set GroundToAirRemainingFrames,5 #Ensure not touching ground this frame lwz r3,0x134(REG_ECBStruct) rlwinm. r0,r3,0,0x8000 bne DIDraw_CollisionLoop_GroundToAirCheckEnd #Ensure was touching ground last frame lwz r3,0x138(REG_ECBStruct) rlwinm. r0,r3,0,0x8000 beq DIDraw_CollisionLoop_GroundToAirCheckEnd #End check li REG_OverrideRemainingFrames,1 /* #Check if over MaxColl cmpwi REG_LoopCount,MaxColl blt DIDraw_CollisionLoop_GroundToAirCheckEnd #Check if REG_OverrideRemainingFrames is already set cmpwi REG_OverrideRemainingFrames,0 bgt DIDraw_CollisionLoop_GroundToAirCheckEnd #Set REG_OverrideRemainingFrames li REG_OverrideRemainingFrames,GroundToAirRemainingFrames */ DIDraw_CollisionLoop_GroundToAirCheckEnd: .endif #endregion #region Save Collision Info .set CollInfo_Length,0x18 .set CollInfo_XPos,0x0 .set CollInfo_YPos,0x4 .set CollInfo_EnvBitfield,0x8 .set CollInfo_ECBTopY,0xC .set CollInfo_ECBLeftY,0x10 .set CollInfo_KnockbackY,0x14 #Update collision check count stw REG_LoopCount,0x0(REG_CollisionInfo) #Get this frames offset in info struct addi r3,REG_CollisionInfo,0x4 #skip past header mulli r4,REG_LoopCount,CollInfo_Length add r3,r3,r4 #Store data stfs REG_CurrXPos,CollInfo_XPos(r3) stfs REG_CurrYPos,CollInfo_YPos(r3) lwz r4,0x134(REG_ECBStruct) stw r4,CollInfo_EnvBitfield(r3) lfs f1,0x88(REG_ECBStruct) stfs f1,CollInfo_ECBTopY(r3) lfs f1,0xA0(REG_ECBStruct) stfs f1,CollInfo_ECBLeftY(r3) stfs REG_KnockbackY,CollInfo_KnockbackY(r3) #endregion DIDraw_CollisionLoop_IncLoop: #Check override frames first cmpwi REG_OverrideRemainingFrames,0 ble DIDraw_CollisionLoop_IncLoopNoOverride #Decrement override frames subi REG_OverrideRemainingFrames,REG_OverrideRemainingFrames,1 cmpwi REG_OverrideRemainingFrames,0 bgt DIDraw_CollisionLoop_IncLoopNoOverride #Override and exit loop prematurely b DIDraw_CollisionLoop_IncLoopEnd DIDraw_CollisionLoop_IncLoopNoOverride: #Inc Loop addi REG_LoopCount,REG_LoopCount,1 #Check if non-meteor cancellable lbz r3,0x235A(REG_PlayerData) cmpwi r3,1 bne DIDraw_CollisionLoop_IncLoopCheckHitstunFrames lwz r3, -0x514C (r13) lwz r3, 0x07F0 (r3) cmpw REG_LoopCount,r3 bgt DIDraw_CollisionLoop_IncLoopEnd DIDraw_CollisionLoop_IncLoopCheckHitstunFrames: lfs f1,0x2340(REG_PlayerData) fctiwz f1,f1 stfd f1,Stack_MiscSpace(sp) lwz r3,Stack_MiscSpace+4(sp) cmpw REG_LoopCount,r3 blt DIDraw_CollisionLoop DIDraw_CollisionLoop_IncLoopEnd: /* .if MaxColl>=0 #Output collision checks count bl DIDraw_CollisionLoop_Text mflr r3 lwz r4,TM_GameFrameCounter(r13) mr r5,REG_LoopCount branchl r12,OSReport b DIDraw_CollisionLoop_TextEnd DIDraw_CollisionLoop_Text: blrl .string "frame %d performed %d collision checks\n" .align 2 DIDraw_CollisionLoop_TextEnd: .endif */ #endregion #endregion #region DIDraw_DeathCheck DIDraw_DrawLoop_Init: .set REG_DeathLoopCount,28 li REG_DeathLoopCount,0 DIDraw_DrawLoop_Init_DeathLoop: addi r3,REG_CollisionInfo,0x4 mulli r4,REG_DeathLoopCount,CollInfo_Length add r3,r3,r4 #get last frames info lfs REG_CurrXPos,CollInfo_XPos(r3) lfs REG_CurrYPos,CollInfo_YPos(r3) lfs REG_KnockbackY,CollInfo_KnockbackY(r3) branchl r12,0x80224b38 #right blastzone fcmpo cr0,REG_CurrXPos,f1 bgt DIDraw_DrawLoop_Init_Dead branchl r12,0x80224b50 #left blastzone fcmpo cr0,REG_CurrXPos,f1 blt DIDraw_DrawLoop_Init_Dead branchl r12,0x80224b80 #bottom blastzone fcmpo cr0,REG_CurrYPos,f1 blt DIDraw_DrawLoop_Init_Dead branchl r12,0x80224b68 #top blastzone fcmpo cr0,REG_CurrYPos,f1 ble DIDraw_DrawLoop_Init_DeathLoop_Inc cmpwi REG_GroundState,0 beq DIDraw_DrawLoop_Init_Dead lwz r3, -0x514C (r13) lfs f0, 0x04F0 (r3) fcmpo cr0,REG_KnockbackY,f0 ble DIDraw_DrawLoop_Init_DeathLoop_Inc DIDraw_DrawLoop_Init_Dead: li r3,1 b DIDraw_DrawLoop_Init_DeathLoop_Exit DIDraw_DrawLoop_Init_DeathLoop_Inc: addi REG_DeathLoopCount,REG_DeathLoopCount,1 lwz r3,0x0(REG_CollisionInfo) cmpw REG_DeathLoopCount,r3 blt DIDraw_DrawLoop_Init_DeathLoop #Is alive, make blue li r3,0 DIDraw_DrawLoop_Init_DeathLoop_Exit: #endregion DIDraw_Exit: lmw r20,Stack_BackedUpReg(r1) lwz r0, StackSize+4(r1) addi r1,r1,StackSize # release the space mtlr r0 blr #################################################### #endregion Constants: blrl .set ZoomValue,0x0 .set Divisor,0x4 .float 100 .float 2 CreateProc_Exit: restore lmw r24, 0x0038 (sp) ================================================ FILE: ASM/Additional Codes/Kill Zoom/Rumble During MH Zoom.s ================================================ #To be inserted at 8002e6e0 .include "../../Globals.s" subi sp,sp,0x30 #Get some camera data addi r3,sp,0x1C load r4,0x80452c7c branchl r12,0x8002958c #Get rumble data addi r3,sp,0x1C branchl r12,0x8002a28c #Apply rumble addi r3,sp,0x1C load r4,0x80452c7c branchl r12,0x8002a0c0 addi sp,sp,0x30 lwz r0, 0x003C (sp) ================================================ FILE: ASM/Additional Codes/L+R+A Returns to CSS During SSS.asm ================================================ #To be inserted at 8025B8BC .include "../Globals.s" #Load first minor of current major load r3,SceneController lbz r3,0x0(r3) ================================================ FILE: ASM/Additional Codes/Lag Reduction Prompt/Main.asm ================================================ #To be inserted at 801bf930 .include "../../Globals.s" #Parameters .set PromptSceneID,8 #0 .set ExitSceneID,40 .set PromptCommonSceneID,10 .set InitialSelection,0 #Function Addresses .set PostRetraceCallback,0x800195fc .set UnkPadStruct,0x804329f0 #region Init New Scenes .set REG_MinorSceneStruct,31 #Init and backup backup #Init LagPrompt major struct li r3,PromptSceneID bl LagPrompt_MinorSceneStruct mflr r4 bl LagPrompt_SceneLoad mflr r5 bl InitializeMajorSceneStruct #Override LagPrompt SceneLoad li r3,PromptCommonSceneID branchl r12,0x801a4ce0 bl LagPrompt_SceneLoad mflr r4 stw r4,0x8(r3) b CheckProgressive #region PointerConvert PointerConvert: lwz r4,0x0(r3) #Load bl instruction rlwinm r5,r4,8,25,29 #extract opcode bits cmpwi r5,0x48 #if not a bl instruction, exit bne PointerConvert_Exit rlwinm r4,r4,0,6,29 #extract offset bits extsh r4,r4 add r4,r4,r3 stw r4,0x0(r3) PointerConvert_Exit: blr #endregion #region InitializeMajorSceneStruct InitializeMajorSceneStruct: .set REG_MajorScene,31 .set REG_MinorStruct,30 .set REG_SceneLoad,29 #Init backup mr REG_MajorScene,r3 mr REG_MinorStruct,r4 mr REG_SceneLoad,r5 #Get major scene struct branchl r12,0x801a50ac GetMajorStruct_Loop: lbz r4, 0x0001 (r3) cmpw r4,REG_MajorScene beq GetMajorStruct_Exit addi r3,r3,20 b GetMajorStruct_Loop GetMajorStruct_Exit: InitMinorSceneStruct: .set REG_MinorStructParse,20 stw REG_MinorStruct,0x10(r3) mr REG_MinorStructParse,REG_MinorStruct InitMinorSceneStruct_Loop: #Check if valid entry lbz r3,0x0(REG_MinorStructParse) extsb r3,r3 cmpwi r3,-1 beq InitMinorSceneStruct_Exit #Convert Pointers addi r3,REG_MinorStructParse,0x4 bl PointerConvert addi r3,REG_MinorStructParse,0x8 bl PointerConvert addi REG_MinorStructParse,REG_MinorStructParse,0x18 b InitMinorSceneStruct_Loop InitMinorSceneStruct_Exit: restore blr #endregion #endregion #region LagPrompt #region LagPrompt_SceneLoad ############################################ #region LagPrompt_SceneLoad_Data LagPrompt_SceneLoad_TextProperties: blrl .set PromptX,0x0 .set PromptY,0x4 .set ZOffset,0x8 .set CanvasScaling,0xC .set Scale,0x10 .set YesX,0x14 .set YesY,0x18 .set YesScale,0x1C .set NoX,0x20 .set NoY,0x24 .set NoScale,0x28 .set HighlightColor,0x2C .set NonHighlightColor,0x30 .float 315 #REG_TextGObj X pos .float 200 #REG_TextGObj Y pos .float 0 #Z offset .float 1 #Canvas Scaling .float 1 #Text scale .float 265 #Yes X pos .float 300 #Yes Y pos .float 1 #Yes scale .float 365 #No X pos .float 300 #No Y pos .float 1 #No scale .byte 251,199,57,255 #highlighted color .byte 170,170,170,255 #nonhighlighted color LagPrompt_SceneLoad_TopText: blrl .ascii "Are you using HDMI" .short 0x8148 .byte 0 .align 2 LagPrompt_SceneLoad_Yes: blrl .string "Yes" .align 2 LagPrompt_SceneLoad_No: blrl .string "No" .align 2 #GObj Offsets .set OFST_TextGObj,0x0 .set OFST_Selection,0x4 #endregion #region LagPrompt_SceneLoad LagPrompt_SceneLoad: blrl #Init backup LagPrompt_SceneLoad_CreateText: .set REG_GObjData,27 .set REG_GObj,28 .set REG_SubtextID,29 .set REG_TextProp,30 .set REG_TextGObj,31 #GET PROPERTIES TABLE bl LagPrompt_SceneLoad_TextProperties mflr REG_TextProp #Create canvas li r3,0 li r4,0 li r5,9 li r6,13 li r7,0 li r8,14 li r9,0 li r10,19 branchl r12,0x803a611c ######################## ## Create Text Object ## ######################## #CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3 li r3,0 li r4,0 branchl r12,Text_CreateTextStruct #BACKUP STRUCT POINTER mr REG_TextGObj,r3 stw REG_TextGObj,0x0(REG_GObjData) #SET TEXT SPACING TO TIGHT li r4,0x1 stb r4,0x49(REG_TextGObj) #SET TEXT TO CENTER AROUND X LOCATION li r4,0x1 stb r4,0x4A(REG_TextGObj) #Store Base Z Offset lfs f1,ZOffset(REG_TextProp) #Z offset stfs f1,0x8(REG_TextGObj) #Scale Canvas Down lfs f1,CanvasScaling(REG_TextProp) stfs f1,0x24(REG_TextGObj) stfs f1,0x28(REG_TextGObj) #Create Prompt #Initialize Subtext mr r3,REG_TextGObj #struct pointer bl LagPrompt_SceneLoad_TopText mflr r4 lfs f1,PromptX(REG_TextProp) lfs f2,PromptY(REG_TextProp) branchl r12,0x803a6b98 mr REG_SubtextID,r3 #Change Text Scale mr r3,REG_TextGObj #struct pointer mr r4,REG_SubtextID lfs f1,Scale(REG_TextProp) #X offset of REG_TextGObj lfs f2,Scale(REG_TextProp) #Y offset of REG_TextGObj branchl r12,Text_UpdateSubtextSize #Create Yes #Initialize Subtext mr r3,REG_TextGObj #struct pointer bl LagPrompt_SceneLoad_Yes mflr r4 lfs f1,YesX(REG_TextProp) lfs f2,YesY(REG_TextProp) branchl r12,0x803a6b98 mr REG_SubtextID,r3 #Change Text Scale mr r3,REG_TextGObj #struct pointer mr r4,REG_SubtextID lfs f1,YesScale(REG_TextProp) #X offset of REG_TextGObj lfs f2,YesScale(REG_TextProp) #Y offset of REG_TextGObj branchl r12,Text_UpdateSubtextSize #Create No #Initialize Subtext mr r3,REG_TextGObj #struct pointer bl LagPrompt_SceneLoad_No mflr r4 lfs f1,NoX(REG_TextProp) lfs f2,NoY(REG_TextProp) branchl r12,0x803a6b98 mr REG_SubtextID,r3 #Change Text Scale mr r3,REG_TextGObj #struct pointer mr r4,REG_SubtextID lfs f1,NoScale(REG_TextProp) #X offset of REG_TextGObj lfs f2,NoScale(REG_TextProp) #Y offset of REG_TextGObj branchl r12,Text_UpdateSubtextSize #Create GObj li r3, 13 li r4,14 li r5,0 branchl r12, GObj_Create mr REG_GObj,r3 #Allocate Space li r3,64 branchl r12,HSD_MemAlloc mr REG_GObjData,r3 #Zero li r4,64 branchl r12,ZeroAreaLength #Initialize mr r6,REG_GObjData mr r3,REG_GObj li r4,4 load r5,0x8037f1b0 branchl r12,GObj_AddUserData #Add Proc mr r3,REG_GObj bl LagPrompt_SceneThink mflr r4 #Function to Run li r5,0 #Priority branchl r12, GObj_AddProc #Store text gobj pointer stw REG_TextGObj,OFST_TextGObj(REG_GObjData) #Init Selection value li r3,InitialSelection stb r3,OFST_Selection(REG_GObjData) #Highlight selection mr r3,REG_TextGObj li r4,InitialSelection+1 addi r5,REG_TextProp,HighlightColor branchl r12,Text_ChangeTextColor LagPrompt_SceneLoad_Exit: restore blr #endregion ############################################ #endregion #region LagPrompt_SceneThink LagPrompt_SceneThink: blrl .set REG_TextProp,28 .set REG_Inputs,29 .set REG_GObjData,30 .set REG_GObj,31 #Init backup mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) bl LagPrompt_SceneLoad_TextProperties mflr REG_TextProp #region Adjust Selection #Adjust Menu Choice #Get all player inputs li r3,4 branchl r12,0x801a36c0 mr REG_Inputs,r3 #Check for movement to the right rlwinm. r0,REG_Inputs,0,0x80 beq LagPrompt_SceneThink_SkipRight #Adjust cursor lbz r3,OFST_Selection(REG_GObjData) addi r3,r3,1 stb r3,OFST_Selection(REG_GObjData) extsb r3,r3 cmpwi r3,1 ble LagPrompt_SceneThink_HighlightSelection li r3,1 stb r3,OFST_Selection(REG_GObjData) b LagPrompt_SceneThink_CheckForA LagPrompt_SceneThink_SkipRight: #Check for movement to the left rlwinm. r0,REG_Inputs,0,0x40 beq LagPrompt_SceneThink_CheckForA #Adjust cursor lbz r3,OFST_Selection(REG_GObjData) subi r3,r3,1 stb r3,OFST_Selection(REG_GObjData) extsb r3,r3 cmpwi r3,0 bge LagPrompt_SceneThink_HighlightSelection li r3,0 stb r3,OFST_Selection(REG_GObjData) b LagPrompt_SceneThink_CheckForA LagPrompt_SceneThink_HighlightSelection: #Unhighlight both options lwz r3,OFST_TextGObj(REG_GObjData) li r4,1 addi r5,REG_TextProp,NonHighlightColor branchl r12,Text_ChangeTextColor lwz r3,OFST_TextGObj(REG_GObjData) li r4,2 addi r5,REG_TextProp,NonHighlightColor branchl r12,Text_ChangeTextColor #Highlight selection lwz r3,OFST_TextGObj(REG_GObjData) lbz r4,OFST_Selection(REG_GObjData) addi r4,r4,1 addi r5,REG_TextProp,HighlightColor branchl r12,Text_ChangeTextColor #Play SFX branchl r12,0x80174380 #endregion #region Check for Confirmation LagPrompt_SceneThink_CheckForA: li r3,4 branchl r12,0x801a36a0 rlwinm. r0,r4,0,0x100 bne LagPrompt_SceneThink_Confirmed rlwinm. r0,r4,0,0x1000 bne LagPrompt_SceneThink_Confirmed b LagPrompt_SceneThink_Exit LagPrompt_SceneThink_Confirmed: #Play Menu Sound branchl r12,0x80174338 #If yes, apply lag reduction lbz r3,OFST_Selection(REG_GObjData) cmpwi r3,0 bne LagPrompt_SceneThink_ExitScene #endregion #region Apply Code .set REG_GeckoCode,12 #Apply lag reduction bl LagReductionGeckoCode mflr r3 bl ApplyGeckoCode #Reset some pad variables to cancel the current alarm load r3,UnkPadStruct li r4,0 stw r4,0x4(r3) stw r4,0x44(r3) #Set new post retrace callback load r3,PostRetraceCallback branchl r12,0x80375934 #Now flush the instruction cache lis r3,0x8000 load r4,0x3b722c #might be overkill but flush the entire dol file branchl r12,0x80328f50 #endregion LagPrompt_SceneThink_ExitScene: branchl r12,0x801a4b60 LagPrompt_SceneThink_Exit: restore blr #endregion #region LagPrompt_SceneDecide LagPrompt_SceneDecide: backup #Exit Scene li r3,ExitSceneID branchl r12,0x801a42e8 #Change Major branchl r12,0x801a42d4 LagPrompt_SceneDecide_Exit: restore blr ############################################ #endregion #region LagReductionGeckoCode LagReductionGeckoCode: blrl .long 0x04019860 .long 0x4BFFFD9D .long 0x041a4c24 .long 0xC0429A7C .long 0xFF000000 #endregion #region ApplyGeckoCode ApplyGeckoCode: .set REG_GeckoCode,12 mr REG_GeckoCode,r3 ApplyGeckoCode_Loop: lbz r3,0x0(REG_GeckoCode) cmpwi r3,0x4 beq ApplyGeckoCode_04 cmpwi r3,0xFF beq ApplyGeckoCode_Exit b ApplyGeckoCode_Exit ApplyGeckoCode_04: lwz r3,0x0(REG_GeckoCode) rlwinm r3,r3,0,8,31 oris r3,r3,0x8000 lwz r4,0x4(REG_GeckoCode) stw r4,0x0(r3) addi REG_GeckoCode,REG_GeckoCode,0x8 b ApplyGeckoCode_Loop ApplyGeckoCode_Exit: blr #endregion #endregion #region MinorSceneStruct LagPrompt_MinorSceneStruct: blrl #Lag Prompt .byte 0 #Minor Scene ID .byte 00 #Amount of persistent heaps .align 2 .long 0x00000000 #ScenePrep bl LagPrompt_SceneDecide #SceneDecide .byte PromptCommonSceneID #Common Minor ID .align 2 .long 0x00000000 #Minor Data 1 .long 0x00000000 #Minor Data 2 #End .byte -1 .align 2 #endregion CheckProgressive: #Check if progressive is enabled branchl r12,0x80349278 cmpwi r3,0 beq NoProgressive IsProgressive: #Load LagPrompt li r3, PromptSceneID b Injection_Exit NoProgressive: #Exit Scene li r3,ExitSceneID Injection_Exit: restore ================================================ FILE: ASM/Additional Codes/Last Unplug Closes All CSS Doors.asm ================================================ #To be inserted at 802605e4 .include "../Globals.s" backup #Check if all controllers are unplugged load r3,HSD_Pad+0x144 li r4,0 UnplugLoop: mulli r5,r4,68 add r5,r5,r3 lbz r5,0x41(r5) extsb. r5,r5 beq Exit addi r4,r4,1 cmpwi r4,4 blt UnplugLoop .set REG_LoopCount,31 .set REG_DoorStruct,30 #All are unplugged, close all doors load REG_DoorStruct,CSS_DoorStructs li REG_LoopCount,0 DoorUpdateLoop: #Change State mulli r3,REG_LoopCount,0x24 add r3,r3,REG_DoorStruct li r4,3 stb r4,CSSDoor_State(r3) #Update Door State mr r3,REG_LoopCount branchl r12,CSS_UpdateCSPInfo #Inc Loop addi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,4 blt DoorUpdateLoop Exit: restore lbz r0, 0x0004 (r31) ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/8Characters1.asm ================================================ #To be inserted at 8023c710 .include "../../../Globals.s" cmplwi r3, 7 ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/8Characters2.asm ================================================ #To be inserted at 8023c320 .include "../../../Globals.s" cmplwi r3, 7 ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/8Characters3.asm ================================================ #To be inserted at 8023c6c4 .include "../../../Globals.s" cmplwi r3, 7 ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/8Characters4.asm ================================================ #To be inserted at 8023cf9c .include "../../../Globals.s" cmpwi r27, 0x8 ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/Adjust Cursor Position.asm ================================================ #To be inserted at 8023E0A4 .include "../../../Globals.s" fsubs f0, f0, f2 bl Floats mflr r4 lfs f1, 0(r4) fdivs f0, f0, f1 b Exit Floats: blrl .float 2 Exit: ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/Character Spacing.asm ================================================ #To be inserted at 8023cf74 .include "../../../Globals.s" nop ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/Copy 8 Characters1.asm ================================================ #To be inserted at 8023cb08 .include "../../../Globals.s" li r10,0 mr r9,r6 b GetTag_Loop GetTag_IncLoop: stb r3,0x0(r7) addi r5,r5,1 addi r7,r7,1 addi r9,r9,1 GetTag_Loop: lbz r3,0x0(r9) cmpwi r3,0 bne GetTag_IncLoop #Check if all 8 letters are read addi r6,r6,3 mr r9,r6 addi r10,r10,1 cmpwi r10,8 blt GetTag_Loop li r4,0 branch r12,0x8023cbec ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/Copy 8 Characters2.asm ================================================ #To be inserted at 8023c02c .include "../../../Globals.s" .set REG_Source,4 .set REG_Dest,7 .set REG_CharCount,8 .set REG_SourceCopied,9 li r10,0 li REG_CharCount,0 addi REG_Dest,r30,408 mr REG_SourceCopied,REG_Source b GetTag_Loop GetTag_IncLoop: stb r3,0x0(REG_Dest) addi REG_CharCount,REG_CharCount,1 addi REG_Dest,REG_Dest,1 addi REG_SourceCopied,REG_SourceCopied,1 GetTag_Loop: lbz r3,0x0(REG_SourceCopied) cmpwi r3,0 bne GetTag_IncLoop #Check if all 8 letters are read addi REG_Source,REG_Source,3 mr REG_SourceCopied,REG_Source addi r10,r10,1 cmpwi r10,8 blt GetTag_Loop mr r7,REG_CharCount branch r12,0x8023c118 ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/Disable Tag Rumble - Ignore Tag Rumble.asm ================================================ #To be inserted at 80167810 .include "../../../Globals.s" nop ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/Disable Tag Rumble - Init.asm ================================================ #To be inserted at 8023c12c .include "../../../Globals.s" nop ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/Disable Tag Rumble - RumbleLoad.asm ================================================ #To be inserted at 80248c8c .include "../../../Globals.s" li r3,0 ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/Disable Tag Rumble - RumbleThink.asm ================================================ #To be inserted at 802477f8 .include "../../../Globals.s" li r3,0 ================================================ FILE: ASM/Additional Codes/Longer Nametags/8 Letter Tags/ZeroNametagText.asm ================================================ #To be inserted at 8023e9e4 .include "../../../Globals.s" li r3,0 subi r4,r31,3 li r5,0 Loop: stbu r3,0x3(r4) Loop_Inc: addi r5,r5,1 cmpwi r5,8 blt Loop mr r3, r15 ================================================ FILE: ASM/Additional Codes/Longer Nametags/Scale Nametag BG/Main.asm ================================================ #To be inserted at 802fcfc8 .include "../../../Globals.s" #Original stfs f0, 0x002C (r28) #Check if HMN mr r3,r27 branchl r12,PlayerBlock_LoadSlotType cmpwi r3,0 bne Exit #Get nametag ID mr r3,r27 branchl r12,PlayerBlock_LoadNameTagSlot #0x8003556c cmpwi r3,120 beq Exit #Get nametag text branchl r12,Nametag_LoadNametagSlotText #0x8023754c #Count letters subi r3,r3,2 li r5,0 CountLetterLoop: lbzu r4,0x2(r3) cmpwi r4,0 beq CountLetterLoop_Exit addi r5,r5,1 b CountLetterLoop CountLetterLoop_Exit: #Normal size if 4 or less cmpwi r5,4 ble Exit #Cast to float li r3,0 subi r4,r5,4 branchl r12,cvt_sll_flt bl Floats mflr r3 lfs f2,0x0(r3) lfs f3,0x2C(r28) fdivs f2,f3,f2 fmuls f1,f1,f2 fadds f1,f1,f3 stfs f1, 0x002C (r28) b Exit Floats: blrl .float 4 Exit: ================================================ FILE: ASM/Additional Codes/Misc Hitbox Visualizer/Always Draw TopN For Items.asm ================================================ #To be inserted at 800593b0 .include "../../Globals.s" backup lwz r31,0x2C(r28) #Draw TopN lwz r10, -0x7920 (rtoc) lwz r9, -0x791C (rtoc) lwz r8, -0x7918 (rtoc) lwz r7, -0x7914 (rtoc) lwz r6, -0x7910 (rtoc) lwz r5, -0x790C (rtoc) lwz r4, -0x7908 (rtoc) lwz r0, -0x7924 (rtoc) stw r10, 0x00DC (sp) stw r9, 0x00D8 (sp) stw r8, 0x00D4 (sp) stw r7, 0x00D0 (sp) stw r6, 0x00CC (sp) stw r5, 0x00C8 (sp) stw r4, 0x00C4 (sp) stw r0, 0x00C0 (sp) branchl r12,0x80058ACC li r3, 168 li r4, 0 li r5, 4 branchl r12,0x8033D0DC lfs f3, 0x4C (r31) #X offset? lfs f2, -0x7964 (rtoc) lfs f4, 0x50 (r31) #Y offset? fsubs f1,f3,f2 lfs f5, 0x54 (r31) #Z Offset fadds f0,f2,f3 fsubs f6,f4,f2 stfs f1, -0x8000 (r30) fadds f1,f2,f4 stfs f4, -0x8000 (r30) stfs f5, -0x8000 (r30) stfs f0, -0x8000 (r30) stfs f4, -0x8000 (r30) stfs f5, -0x8000 (r30) stfs f3, -0x8000 (r30) stfs f6, -0x8000 (r30) stfs f5, -0x8000 (r30) stfs f3, -0x8000 (r30) stfs f1, -0x8000 (r30) stfs f5, -0x8000 (r30) Exit: restore branch r12,0x800593d0 ================================================ FILE: ASM/Additional Codes/Misc Hitbox Visualizer/Display Chain ECBs - GObj 7.asm ================================================ #To be inserted at 800593dc .include "../../Globals.s" .set REG_CurrentGObj,31 .set REG_GX,30 backup lis REG_GX,0xcc01 #Draw location of all chains (0x28) lwz r3, -0x3E74 (r13) lwz REG_CurrentGObj,0x28(r3) b Loop_CheckNext Loop: .set REG_CurrentGObjData,29 #Get Data lwz REG_CurrentGObjData,0x2C(REG_CurrentGObj) /* #Draw TopN lwz r10, -0x7920 (rtoc) lwz r9, -0x791C (rtoc) lwz r8, -0x7918 (rtoc) lwz r7, -0x7914 (rtoc) lwz r6, -0x7910 (rtoc) lwz r5, -0x790C (rtoc) lwz r4, -0x7908 (rtoc) lwz r0, -0x7924 (rtoc) stw r10, 0x00DC (sp) stw r9, 0x00D8 (sp) stw r8, 0x00D4 (sp) stw r7, 0x00D0 (sp) stw r6, 0x00CC (sp) stw r5, 0x00C8 (sp) stw r4, 0x00C4 (sp) stw r0, 0x00C0 (sp) branchl r12,0x80058ACC li r3, 168 li r4, 0 li r5, 4 branchl r12,0x8033D0DC lfs f3, 0x4C (REG_CurrentGObjData) #X offset? lfs f2, -0x7964 (rtoc) lfs f4, 0x50 (REG_CurrentGObjData) #Y offset? fsubs f1,f3,f2 lfs f5, 0x54 (REG_CurrentGObjData) #Z Offset fadds f0,f2,f3 fsubs f6,f4,f2 stfs f1, -0x8000 (r30) fadds f1,f2,f4 stfs f4, -0x8000 (r30) stfs f5, -0x8000 (r30) stfs f0, -0x8000 (r30) stfs f4, -0x8000 (r30) stfs f5, -0x8000 (r30) stfs f3, -0x8000 (r30) stfs f6, -0x8000 (r30) stfs f5, -0x8000 (r30) stfs f3, -0x8000 (r30) stfs f1, -0x8000 (r30) stfs f5, -0x8000 (r30) */ #Check if collision is up to date lwz r0, -0x51F4 (r13) lwz r4, 0x0038+48 (REG_CurrentGObjData) cmpw r0,r4 bne Loop_Inc #Draw ECB addi r3,REG_CurrentGObjData,48 branchl r12,0x80058b5c #Check if more Loop_Inc: lwz REG_CurrentGObj,0x8(REG_CurrentGObj) Loop_CheckNext: cmpwi REG_CurrentGObj,0 bne Loop Exit: restore lmw r26, 0x0118 (sp) ================================================ FILE: ASM/Additional Codes/Misc Hitbox Visualizer/Main.asm ================================================ #To be inserted at 80080638 .include "../../Globals.s" .set REG_PlayerData,31 .set REG_ItemGObj,30 .set REG_ItemData,29 backup #Check char lwz r3,0x4(REG_PlayerData) cmpwi r3,Link.Int beq Link cmpwi r3,Popo.Int beq Nana /* cmpwi r3,Pikachu.Int beq Pikachu cmpwi r3,Pichu.Int beq Pikachu */ b Exit ########################## Link: #Check if boomerang exists lwz REG_ItemGObj,0x2234(REG_PlayerData) cmpwi REG_ItemGObj,0 beq Link_NoBoomerang #Check if in state 3 (returning) lwz REG_ItemData,0x2C(REG_ItemGObj) lwz r3,0x24(REG_ItemData) cmpwi r3,3 bne Link_NoBoomerang #Draw circle of 6 radius around links current position lfs f1,0xB0(REG_PlayerData) stfs f1,0x80(sp) lfs f1,0xB4(REG_PlayerData) lwz r3,0x2D4(REG_PlayerData) lfs f2,0x28(r3) fadds f1,f1,f2 stfs f1,0x84(sp) lfs f1,0xB8(REG_PlayerData) stfs f1,0x88(sp) addi r3,sp,0x80 lwz r4,0xC4(REG_ItemData) lwz r4,0x4(r4) lfs f1,0x2C(r4) bl DrawBubble Link_NoBoomerang: /* #Check if chain exists lwz REG_ItemGObj,0x2238(REG_PlayerData) cmpwi REG_ItemGObj,0 beq Link_NoChain #Check if in state 8 (hangwait) lwz REG_ItemData,0x2C(REG_ItemGObj) lwz r3,0x24(REG_ItemData) cmpwi r3,8 bne Link_NoChain #Draw circle of 6 radius around the end of the hook lfs f1,0xB0(REG_PlayerData) stfs f1,0x80(sp) lfs f1,0xB4(REG_PlayerData) lwz r3,0x2D4(REG_PlayerData) lfs f2,0x28(r3) fadds f1,f1,f2 stfs f1,0x84(sp) lfs f1,0xB8(REG_PlayerData) stfs f1,0x88(sp) addi r3,sp,0x80 lwz r4,0xC4(REG_ItemData) lwz r4,0x4(r4) lfs f1,0x40(r4) bl DrawBubble */ Link_NoChain: b Exit ########################## Nana: #up b nana search radius lwz r3,0x10(REG_PlayerData) cmpwi r3,0x160 beq Nana_UpB cmpwi r3,0x15B beq Nana_UpB b Nana_NoUpB Nana_UpB: #Check if frame 4 li r3,0 li r4,4 branchl r12,cvt_sll_flt lfs f2,0x894(REG_PlayerData) fcmpo cr0,f1,f2 bne Nana_NoUpB #Draw circle addi r3,REG_PlayerData,0xB0 lwz r4,0x2D4(REG_PlayerData) lfs f1,0x7C(r4) bl DrawBubble Nana_NoUpB: b Exit ########################## /* Pikachu: #Check AS lwz r3,0x10(REG_PlayerData) cmpwi r3,0x168 beq Pikachu_DownB cmpwi r3,0x15C beq Pikachu_DownB b Pikachu_NoDownB #Get thunder position lwz r3,0x2340(REG_PlayerData) cmpwi r3,0 beq Pikachu_NoDownB addi r4,sp,0x80 branchl r12,0x802b1fe8 */ Pikachu_NoDownB: b Exit ########################## DrawBubble: backup mr r4,r3 bl BubbleColors mflr r5 addi r6,r5,4 branchl r12,0x80008fc8 restore blr BubbleColors: blrl .byte 255,255,255,128 .byte 128,0,0,128 ########################## Exit: #Return restore lbz r0, 0x221D (r31) ================================================ FILE: ASM/Additional Codes/Neutral Respawn.asm ================================================ #To be inserted at 8016721c .include "../Globals.s" .set PlayerSlot,27 .set StaticBlock,26 .set SpawnTable,25 .set SpawnOrder,24 .set SpawnID,23 backup #Don't run in singleplayer branchl r12,0x8016b41c cmpwi r3,0 bne Original #Don't run for players 5 and 6 cmpwi PlayerSlot,5 bge Original #Get static block mr r3,PlayerSlot branchl r12,Playerblock_LoadStaticBlock mr StaticBlock,r3 #Get Neutral Spawn Table bl NeutralRespawnTable mflr SpawnTable #Get this players spawn order mr r3,PlayerSlot bl GetSpawnOrder mr SpawnOrder,r3 #Get stage ID lwz r6,-0x6CB8 (r13) li r5,0 #Get stage's spawn info StageSearchLoop: mulli r4,r5,0x5 #table length add r4,r4,SpawnTable #get stage start lbz r3,0x0(r4) #get stage ID extsb r3,r3 cmpwi r3,-1 #check for end of table beq Original cmpw r3,r6 #check for matching stage ID addi r5,r5,1 #inc count bne StageSearchLoop #Get ID addi r4,r4,1 #Skip past stage ID lbzx r3,SpawnOrder,r4 b Exit ###################### GetSpawnOrder: .set LoopCount,31 .set SpawnOrder,30 .set PlayerSlot,28 backup #Init variables mr PlayerSlot,r3 li SpawnOrder,0 li LoopCount,0 #Start Loop GetSpawnOrder_Loop: #Load slot type mr r3,LoopCount branchl r12,PlayerBlock_LoadSlotType cmpwi r3,0x1 bgt GetSpawnOrder_IncLoop #If >1, no player present #Player is present, check if this is the one were looking for cmpw PlayerSlot,LoopCount beq GetSpawnOrder_Exit #Increment offset addi SpawnOrder,SpawnOrder,1 GetSpawnOrder_IncLoop: addi LoopCount,LoopCount,1 cmpwi LoopCount,4 ble GetSpawnOrder_Loop GetSpawnOrder_Exit: mr r3,SpawnOrder #Return spawn order restore blr ###################### NeutralRespawnTable: blrl #FD .byte 0x20 #Stage ID .byte 0x00,0x01,0x02,0x03 #Nuetral Spawn Index #Battlefield .byte 0x1F #Stage ID .byte 0x02,0x03,0x00,0x01 #Nuetral Spawn Index #Yoshi's Story .byte 0x08 #Stage ID .byte 0x00,0x01,0x03,0x02 #Nuetral Spawn Index #Dream Land .byte 0x1C #Stage ID .byte 0x01,0x03,0x00,0x02 #Nuetral Spawn Index #FoD .byte 0x02 #Stage ID .byte 0x00,0x01,0x02,0x03 #Nuetral Spawn Index #Pokemon Stadium .byte 0x03 #Stage ID .byte 0x00,0x01,0x02,0x03 #Nuetral Spawn Index #Terminator .byte 0xFF .align 2 ###################### Original: restore addi r3, r27, 0 b Skip Exit: restore Skip: ================================================ FILE: ASM/Additional Codes/Neutral Respawn.s ================================================ #To be inserted at 8016721c .include "../Globals.s" .set PlayerSlot,27 .set StaticBlock,26 .set SpawnTable,25 .set SpawnOrder,24 .set SpawnID,23 backup #Don't run in singleplayer branchl r12,0x8016b41c cmpwi r3,0 bne Original #Don't run for players 5 and 6 cmpwi PlayerSlot,5 bge Original #Get static block mr r3,PlayerSlot branchl r12,Playerblock_LoadStaticBlock mr StaticBlock,r3 #Get Neutral Spawn Table bl NeutralRespawnTable mflr SpawnTable #Get this players spawn order mr r3,PlayerSlot bl GetSpawnOrder mr SpawnOrder,r3 #Get stage ID lwz r6,-0x6CB8 (r13) li r5,0 #Get stage's spawn info StageSearchLoop: mulli r4,r5,0x5 #table length add r4,r4,SpawnTable #get stage start lbz r3,0x0(r4) #get stage ID extsb r3,r3 cmpwi r3,-1 #check for end of table beq Original cmpw r3,r6 #check for matching stage ID addi r5,r5,1 #inc count bne StageSearchLoop #Get ID addi r4,r4,1 #Skip past stage ID lbzx r3,SpawnOrder,r4 b Exit ###################### GetSpawnOrder: .set LoopCount,31 .set SpawnOrder,30 .set PlayerSlot,28 backup #Init variables mr PlayerSlot,r3 li SpawnOrder,0 li LoopCount,0 #Start Loop GetSpawnOrder_Loop: #Load slot type mr r3,LoopCount branchl r12,PlayerBlock_LoadSlotType cmpwi r3,0x1 bgt GetSpawnOrder_IncLoop #If >1, no player present #Player is present, check if this is the one were looking for cmpw PlayerSlot,LoopCount beq GetSpawnOrder_Exit #Increment offset addi SpawnOrder,SpawnOrder,1 GetSpawnOrder_IncLoop: addi LoopCount,LoopCount,1 cmpwi LoopCount,4 ble GetSpawnOrder_Loop GetSpawnOrder_Exit: mr r3,SpawnOrder #Return spawn order restore blr ###################### NeutralRespawnTable: blrl #FD .byte 0x20 #Stage ID .byte 0x00,0x01,0x02,0x03 #Nuetral Spawn Index #Battlefield .byte 0x1F #Stage ID .byte 0x02,0x03,0x00,0x01 #Nuetral Spawn Index #Yoshi's Story .byte 0x08 #Stage ID .byte 0x00,0x01,0x03,0x02 #Nuetral Spawn Index #Dream Land .byte 0x1C #Stage ID .byte 0x01,0x03,0x00,0x02 #Nuetral Spawn Index #FoD .byte 0x02 #Stage ID .byte 0x00,0x01,0x02,0x03 #Nuetral Spawn Index #Pokemon Stadium .byte 0x03 #Stage ID .byte 0x00,0x01,0x02,0x03 #Nuetral Spawn Index #Terminator .byte 0xFF .align 2 ###################### Original: restore addi r3, r27, 0 b Skip Exit: restore Skip: ================================================ FILE: ASM/Additional Codes/Neutral Spawn.asm ================================================ #To be inserted at 8016e510 .include "../Globals.s" .set MatchInfo,31 .set SpawnTable,30 .set REG_PlayerSlot,28 backup #Don't run in singleplayer branchl r12,0x8016b41c cmpwi r3,0 bne Exit #Don't run for players 5 and 6 cmpwi REG_PlayerSlot,5 bge Exit #Check if teams lbz r3, 0x24D0 (MatchInfo) cmpwi r3,1 beq isTeams #region isSingles isSingles: #Get this players spawn order .set LoopCount,26 .set SpawnOrder,25 li SpawnOrder,0 li LoopCount,0 isSingles_Loop: #Load slot type mr r3,LoopCount branchl r12,PlayerBlock_LoadSlotType cmpwi r3,0x3 beq isSingles_IncLoop #If =3, no player present #Player is present, check if this is the one were looking for cmpw REG_PlayerSlot,LoopCount beq isSingles_Exit #Increment offset addi SpawnOrder,SpawnOrder,1 isSingles_IncLoop: addi LoopCount,LoopCount,1 cmpwi LoopCount,4 ble isSingles_Loop isSingles_Exit: mr r3,REG_PlayerSlot mr r4,SpawnOrder lbz r5, 0x24D0 (MatchInfo) bl SetSpawn b Exit #endregion #region isTeams isTeams: CheckIf2v2: .set REG_TeamID,26 li REG_TeamID,0 CheckIf2v2_Loop: #Check how many players are on this team GetTeamCount: .set REG_Count,25 .set REG_TeamMembers,24 li REG_TeamMembers,0 li REG_Count,0 GetTeamCount_Loop: #Load slot type mr r3,REG_Count branchl r12,PlayerBlock_LoadSlotType cmpwi r3,0x3 beq GetTeamCount_IncLoop #If =3, no player present #Get Team mr r3,REG_Count branchl r12,0x80033370 cmpw r3,REG_TeamID bne GetTeamCount_IncLoop #Increment team members addi REG_TeamMembers,REG_TeamMembers,1 GetTeamCount_IncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,4 blt GetTeamCount_Loop #If =1 or >2, exit cmpwi REG_TeamMembers,1 beq Exit cmpwi REG_TeamMembers,2 bgt Exit CheckIf2v2_IncLoop: addi REG_TeamID,REG_TeamID,1 cmpwi REG_TeamID,3 blt CheckIf2v2_Loop #Create an array CreateTeamArray: .set REG_TeamID,25 .set REG_TeamArray,26 .set REG_ArraySize,24 li REG_TeamID,0 addi REG_TeamArray,sp,0x80 li REG_ArraySize,0 CreateTeamArray_Loop: #Check how many players are on this team CheckTeam: .set REG_Count,23 .set REG_TeamMembers,22 li REG_TeamMembers,0 li REG_Count,0 CheckTeam_Loop: #Load slot type mr r3,REG_Count branchl r12,PlayerBlock_LoadSlotType cmpwi r3,0x3 beq CheckTeam_IncLoop #If =3, no player present #Get Team mr r3,REG_Count branchl r12,0x80033370 cmpw r3,REG_TeamID bne CheckTeam_IncLoop #Add to array stbx REG_Count,REG_ArraySize,REG_TeamArray addi REG_ArraySize,REG_ArraySize,1 CheckTeam_IncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,4 blt CheckTeam_Loop CreateTeamArray_IncLoop: addi REG_TeamID,REG_TeamID,1 cmpwi REG_TeamID,3 blt CreateTeamArray_Loop #Now search for this players ID SearchForPlayerID: .set REG_Count,25 li REG_Count,0 SearchForPlayerID_Loop: lbzx r3,REG_Count,REG_TeamArray cmpw r3,REG_PlayerSlot beq SearchForPlayerID_Exit SearchForPlayerID_IncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,4 blt SearchForPlayerID_Loop SearchForPlayerID_Exit: mr r3,REG_PlayerSlot mr r4,REG_Count lbz r5, 0x24D0 (MatchInfo) bl SetSpawn b Exit #endregion #region SetSpawn SetSpawn: .set REG_PlayerSlot,31 .set REG_SpawnID,30 .set REG_IsTeams,29 .set REG_SpawnTable,28 #Init backup mr REG_PlayerSlot,r3 mr REG_SpawnID,r4 mr REG_IsTeams,r5 #Get Neutral Spawn Table bl NeutralSpawnTable mflr REG_SpawnTable #Get stage ID lwz r6,-0x6CB8 (r13) li r5,0 #Get stage's spawn info SetSpawn_StageSearchLoop: lwz r3,StageID(REG_SpawnTable) #get stage ID cmpwi r3,-1 #check for end of table beq SetSpawn_NotFound cmpw r3,r6 #check for matching stage ID beq SetSpawn_FoundStage addi REG_SpawnTable,REG_SpawnTable,EntryLength b SetSpawn_StageSearchLoop SetSpawn_FoundStage: #Get Players Spawn Point and Facing Direction Pointer addi REG_SpawnTable,REG_SpawnTable,SpawnData #Skip past stage ID mulli r3,REG_IsTeams,SpawnDataLength add REG_SpawnTable,REG_SpawnTable,r3 #Get to teams/singles data mulli r3,REG_SpawnID,SpawnDataLengthPerPlayer #Get to this players data add REG_SpawnTable,REG_SpawnTable,r3 #Set players new spawn coordinates addi r4,sp,0x80 lfs f1,SpawnX(REG_SpawnTable) stfs f1,0x0(r4) lfs f1,SpawnY(REG_SpawnTable) stfs f1,0x4(r4) li r3,0 stw r3,0x8(r4) mr r3,REG_PlayerSlot branchl r12,0x80032768 b SetSpawn_UpdateFacingDirection SetSpawn_NotFound: #If singles, use spawn order cmpwi REG_IsTeams,1 beq SetSpawn_NotFound_Teams mr r3,REG_SpawnID b SetSpawn_NotFound_UpdatePosition SetSpawn_NotFound_Teams: bl NeutralSpawnTable_NotFound mflr r3 lbzx r3,r3,REG_SpawnID b SetSpawn_NotFound_UpdatePosition SetSpawn_NotFound_UpdatePosition: #Get XYZ from spawn ID addi r4,sp,0x80 branchl r12,0x80224e64 #Set new XYZ spawn mr r3,REG_PlayerSlot addi r4,sp,0x80 branchl r12,0x80032768 b SetSpawn_UpdateFacingDirection SetSpawn_UpdateFacingDirection: #Load X Position mr r3,REG_PlayerSlot addi r4,sp,0x80 branchl r12,0x800326cc lfs f1,0x80(sp) #Compare to 0 lfs f0, -0x5718 (rtoc) fcmpo cr0,f1,f0 ble SetSpawn_UpdateFacingDirection_FacingRight SetSpawn_UpdateFacingDirection_FacingLeft: lfs f1, -0x5708 (rtoc) b SetSpawn_UpdateFacingDirection_Store SetSpawn_UpdateFacingDirection_FacingRight: lfs f1, -0x5734 (rtoc) SetSpawn_UpdateFacingDirection_Store: #Update Facing Direction mr r3,REG_PlayerSlot branchl r12,0x80033094 SetSpawn_AdjustEntryFrames: mr r3,REG_PlayerSlot mulli r4,REG_SpawnID,5 branchl r12,0x80035fdc SetSpawn_Exit: restore blr #endregion ###################### NeutralSpawnTable: blrl .set EntryLength,0x4 + SpawnDataLength * 2 .set SpawnDataLength,0x8 *4 .set SpawnDataLengthPerPlayer,0x8 .set StageID,0x0 .set SpawnData,0x4 .set SpawnX,0x0 .set SpawnY,0x4 #FD .long 0x20 #Stage ID #Singles Data .float -60,10 .float 60,10 .float -20,10 .float 20,10 #Teams Data .float -20,10 .float -60,10 .float 20,10 .float 60,10 #Battlefield .long 0x1F #Stage ID #Singles Data .float -38.8,35.2 .float 38.8,35.2 .float 0,8 .float 0,62.4 #Teams Data .float -38.8,35.2 .float -38.8,5 .float 38.8,35.2 .float 38.8,5 #Yoshi's Story .long 0x08 #Stage ID #Singles Data .float -42,26.6 .float 42,28 .float 0,46.9 .float 0,4.9 #Teams Data .float -42,26.6 .float -42,5 .float 42,28 .float 42,5 #Dream Land .long 0x1C #Stage ID #Singles Data .float -46.6,37.2 .float 47.4,37.3 .float 0,7 .float 0,58.5 #Teams Data .float -46.6,37.2 .float -46.6,5 .float 47.4,37.3 .float 47.4,5 #FoD .long 0x02 #Stage ID #Singles Data .float -41.25,21 .float 41.25,27 .float 0,5.25 .float 0,48 #Teams Data .float -41.25,21 .float -41.25,5 .float 41.25,27 .float 41.25,5 #Pokemon Stadium .long 0x03 #Stage ID #Singles Data .float -40,32 .float 40,32 .float 70,7 .float -70,7 #Teams Data .float -40,32 .float -40,5 .float 40,32 .float 40,5 #Terminator .long -1 .align 2 NeutralSpawnTable_NotFound: blrl #Doubles .long 0x00030102 .align 2 ###################### Exit: restore lbz r0, 0x24D0 (r31) ================================================ FILE: ASM/Additional Codes/On Crash/Clear Bootup OSReports.asm ================================================ #To be inserted at 80160154 .include "../../Globals.s" # Remove all previous OSReports load r3,0x804cf7e8 li r4,0 stw r4,0xC(r3) li r0, 0 ================================================ FILE: ASM/Additional Codes/On Crash/Disable Brinstar OSReport.asm ================================================ #To be inserted at 801fe738 nop ================================================ FILE: ASM/Additional Codes/On Crash/Disable Effect AnimList OSReport.asm ================================================ #To be inserted at 800a0080 nop ================================================ FILE: ASM/Additional Codes/On Crash/Disable Fourside OSReport.asm ================================================ #To be inserted at 801f3500 nop ================================================ FILE: ASM/Additional Codes/On Crash/Disable Fourside OSReport2.asm ================================================ #To be inserted at 801f35c0 nop ================================================ FILE: ASM/Additional Codes/On Crash/Disable PS OSReport.asm ================================================ #To be inserted at 801c3a84 nop ================================================ FILE: ASM/Additional Codes/On Crash/Disable YoshisIsland OSReport.asm ================================================ #To be inserted at 80202a40 nop ================================================ FILE: ASM/Additional Codes/On Crash/Disable mpcoll OSReport.asm ================================================ #To be inserted at 8005a2f8 b 0x30 ================================================ FILE: ASM/Additional Codes/On Crash/Dont Output Compile Date on Assert.asm ================================================ #To be inserted at 80228aec nop ================================================ FILE: ASM/Additional Codes/On Crash/Dont Output Compile Date on Invalid Read.asm ================================================ #To be inserted at 80228bf0 nop ================================================ FILE: ASM/Additional Codes/On Crash/Enable OSReport Print to Screen.asm ================================================ #To be inserted at 80397878 b 0x20C ================================================ FILE: ASM/Additional Codes/On Crash/LRZ Shows Advanced Details/Any Debug Level Displays Advanced Details.s ================================================ #To be inserted at 80394eac .include "../../../Globals.s" nop ================================================ FILE: ASM/Additional Codes/On Crash/LRZ Shows Advanced Details/Check for LRZ.s ================================================ #To be inserted at 80395704 .include "../../../Globals.s" #Get Held Buttons lwz r3,0xC0(r30) #Check for LRZ cmpwi r3,0x70 beq PressedButtons #Not Pressing LRZ branch r12,0x80395728 PressedButtons: ================================================ FILE: ASM/Additional Codes/On Crash/Only Show First 8 Lines of Stack.asm ================================================ #To be inserted at 80394afc cmpwi r29, 8 ================================================ FILE: ASM/Additional Codes/On Crash/Reboot With LRAStart.asm ================================================ #To be inserted at 80397c10 .include "../../Globals.s" # Get inputs lwz r3,0xC0(r31) rlwinm. r0,r3,0,0x20 beq Exit rlwinm. r0,r3,0,0x40 beq Exit rlwinm. r0,r3,0,0x100 beq Exit rlwinm. r0,r3,0,0x1000 beq Exit #Reboot li r3,0 li r4,0 li r5,0 branchl r12,0x8034844c Exit: lbz r0, 0 (r31) ================================================ FILE: ASM/Additional Codes/Output File Load Times/Output Load Time.s ================================================ #To be inserted at 8001674c .include "../../Globals.s" .set REG_Tick,20 .set REG_FileSize,21 .set REG_FileName,30 backup #Get Prev Tick lwz r3,-8(rtoc) #Get Current Tick mftbl r4 #Find Difference sub r3,r4,r3 #Convert to ms #Get Clock Bus load r4,0x800000f8 lwz r4,0x0(r4) #Clock Bus / 4 li r5,4 divw r4,r4,r5 #Divided by 1000 li r5,1000 divw r4,r4,r5 #divided by ticks divw REG_Tick,r3,r4 #Get file size mr r3,r30 branchl r12,0x800163d8 mr REG_FileSize,r3 #OSReport Difference bl OSReportString mflr r3 mr r4,REG_FileName li r5,1000 divw r5,REG_FileSize,r5 mr r6,REG_Tick branchl r12,0x803456a8 b Exit OSReportString: blrl .string "%s (%dkb) loaded in %dms\n" .align 2 #************************************************* Exit: restore lmw r27, 0x001C (sp) ================================================ FILE: ASM/Additional Codes/Output File Load Times/Save Tick.s ================================================ #To be inserted at 80016714 .include "../../Globals.s" mftbl r4 stw r4,-8(rtoc) lwz r4, 0 (r28) ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (1).asm ================================================ #To be inserted @ 800C2D3C loc_0x0: lis r0, 0x800C ori r0, r0, 0x2690 mtlr r0 blrl addi r5, r24, 0x1 lis r0, 0x800C ori r0, r0, 0x2DA4 mtctr r0 bctr ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (10).asm ================================================ #To be inserted @ 800c26c0 rlwinm r3, r30, 19, 31, 31 ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (11).asm ================================================ #To be inserted @ 800c272c rlwinm r3, r30, 2, 30, 31 ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (12).asm ================================================ #To be inserted @ 800C268C loc_0x0: mflr r0 stw r0, 4(r1) stwu r1, -16384(r1) stmw r30, 16(r1) mr r30, r3 mr r31, r4 lis r0, 0x800C li r3, 0x1 ori r0, r0, 0x2678 mtctr r0 bctr ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (13).asm ================================================ #To be inserted @ 800C2690 loc_0x0: mflr r0 stw r0, 4(r1) stwu r1, -16384(r1) lis r0, 0x8033 ori r0, r0, 0xC3C8 mtlr r0 blrl lis r0, 0x800C ori r0, r0, 0x2D40 mtctr r0 bctr ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (14).asm ================================================ #To be inserted @ 800C2DA0 loc_0x0: lwz r0, 0x4004(r1) addi r1, r1, 0x4000 mtlr r0 blr ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (15).asm ================================================ #To be inserted @ 802EAA38 lfd f1, -32608(r2) ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (16).asm ================================================ #To be inserted @ 802E8D68 lfd f1, -32608(r2) ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (17).asm ================================================ #To be inserted @ 804DD860 .long 0x00101303 ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (18).asm ================================================ #To be inserted @ 804DD864 .long 0x00001455 ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (19).asm ================================================ #To be inserted @ 800C2674 loc_0x0: lwz r3, -8576(r2) lwz r4, -8572(r2) lis r0, 0x800C ori r0, r0, 0x268C mtlr r0 blrl lis r0, 0x800C ori r0, r0, 0x2738 mtctr r0 lbz r0, 8449(r28) bctr ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (2).asm ================================================ #To be inserted @ 802E8B48 lfd f1, -32608(r2) ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (20).asm ================================================ #To be inserted @ 800C2734 loc_0x0: lmw r30, 16(r1) lwz r0, 0x4004(r1) addi r1, r1, 0x4000 mtlr r0 blr ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (3).asm ================================================ #To be inserted @ 804DD848 loc_0x0: lis r0, 0x8036 ori r3, r0, 0x1FC4 mtctr r3 li r3, -1 bctr ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (4).asm ================================================ #To be inserted @ 804DD84C loc_0x0: mflr r0 stw r0, 4(r1) stwu r1, -64(r1) stmw r29, 16(r1) mr r30, r3 mr r31, r4 mr r3, r4 mr r4, r5 lis r0, 0x800C ori r0, r0, 0x268C mtlr r0 blrl lis r0, 0x800C ori r0, r0, 0x2690 mtlr r0 blrl rlwinm r3, r31, 0, 24, 31 cmpwi r3, 0x5 blt+ loc_0x84 cmpwi r3, 0x7 bgt- loc_0x84 rlwinm r3, r31, 16, 22, 31 li r4, 0x5 beq- loc_0x74 lis r0, 0x8033 ori r0, r0, 0xD240 mtlr r0 blrl b loc_0x84 loc_0x74: lis r0, 0x8033 ori r0, r0, 0xD298 mtlr r0 blrl loc_0x84: rlwinm r3, r31, 3, 24, 28 addi r3, r3, 0x80 li r4, 0x0 rlwinm r5, r30, 0, 16, 31 lis r0, 0x8033 ori r0, r0, 0xD0DC mtlr r0 blrl lis r3, 0xCC01 subi r3, r3, 0x8000 lmw r29, 16(r1) lwz r0, 0x44(r1) addi r1, r1, 0x40 mtlr r0 blr ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (5).asm ================================================ #To be inserted @ 800C2684 loc_0x0: rlwinm r3, r31, 20, 30, 31 rlwinm r4, r31, 24, 29, 31 rlwinm r5, r31, 28, 29, 31 rlwinm r6, r31, 0, 28, 31 ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (6).asm ================================================ #To be inserted @ 800c2688 b 0xC ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (7).asm ================================================ #To be inserted @ 800c26b0 rlwinm r3, r30, 20, 31, 31 ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (8).asm ================================================ #To be inserted @ 800c26b4 rlwinm r4, r30, 24, 29, 31 ================================================ FILE: ASM/Additional Codes/PRIM LITE/PRIM (9).asm ================================================ #To be inserted @ 800c26b8 rlwinm r5, r30, 21, 31, 31 ================================================ FILE: ASM/Additional Codes/Pad - Update During Frame Advance.asm ================================================ #To be inserted at 801a4e48 # doing this to make the menu inputs work with the TM menu # while the engine is paused. not sure if there are any # side effects to doing this but it seems to work?? nop ================================================ FILE: ASM/Additional Codes/Pause During Game Start/Check to Pause.asm ================================================ #To be inserted at 8016CA9C nop ================================================ FILE: ASM/Additional Codes/Pause During Game Start/Check to Pause.s ================================================ #To be inserted at 8016CA9C nop ================================================ FILE: ASM/Additional Codes/Pause During Game Start/Check to Unpause.asm ================================================ #To be inserted at 8016CC1C nop ================================================ FILE: ASM/Additional Codes/Pause During Game Start/Check to Unpause.s ================================================ #To be inserted at 8016CC1C nop ================================================ FILE: ASM/Additional Codes/Physics Display/Main.asm ================================================ #To be inserted at 80225554 .include "../../Globals.s" .set GObj_Create,0x803901f0 .set GObj_AddUserData,0x80390b68 .set GObj_AddProc,0x8038fd54 .set HSD_MemAlloc,0x8037f1e4 .set DevelopText_CreateDataTable,0x80302834 .set DevelopText_Activate,0x80302810 .set DevelopText_AddString,0x80302be4 .set DevelopText_FormatAndPrint,0x80302d4c .set DevelopText_EraseAllText,0x80302bb0 .set DevelopMode_Text_ResetCursorXY,0x80302a3c .set DevelopText_StoreBGColor,0x80302b90 .set DevelopText_HideText,0x80302b00 .set DevelopText_HideBG,0x80302ae0 .set DevelopText_ShowText,0x80302af0 .set DevelopText_ShowBG,0x80302ad0 .set DevelopText_StoreTextScale,0x80302b10 .set DevelopText_ResetCursorX,0x80302a88 .set sprintf,0x80323cf4 .set WindowData_Text,0x0 .set WindowData_State,0x4 .set REG_DevelopText,31 .set REG_GObjData,30 .set REG_GObj,29 stw r0, -0x4B7C (r13) backup #Create Rectangle li r3,0x1000 branchl r12,HSD_MemAlloc mr r8,r3 li r3,12 li r4,0 li r5,0 li r6,39 li r7,10 branchl r12,DevelopText_CreateDataTable mr REG_DevelopText,r3 #Activate Text lwz r3, -0x4884 (r13) mr r4,REG_DevelopText branchl r12,DevelopText_Activate #Hide blinking cursor li r3,0 stb r3,0x26(REG_DevelopText) #Change BG Color mr r3,REG_DevelopText bl BGColor mflr r4 branchl r12,DevelopText_StoreBGColor #Hide by default mr r3,REG_DevelopText branchl r12,DevelopText_HideText mr r3,REG_DevelopText branchl r12,DevelopText_HideBG #Change Text Size mr r3,REG_DevelopText bl TextFloats mflr r4 lfs f1,0x0(r4) lfs f2,0x4(r4) branchl r12,DevelopText_StoreTextScale #Create Background GObj li r3,0 li r4,0 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Allocate Space li r3,64 branchl r12,HSD_MemAlloc mr REG_GObjData,r3 #Zero li r4,64 branchl r12,ZeroAreaLength #Initialize mr r6,REG_GObjData mr r3,REG_GObj li r4,4 load r5,HSD_Free branchl r12,GObj_AddUserData #Add Process mr r3,REG_GObj bl DebugLogThink mflr r4 li r5,7 li r6,0 branchl r12,GObj_AddGXLink #branchl r12,GObj_AddProc #Store pointer to dev text stw REG_DevelopText,WindowData_Text(REG_GObjData) #Initialize State li r3,0 stw r3,WindowData_State(REG_GObjData) b Exit ######################################## TextFloats: blrl .float 7.5 .float 10 ######################################## DebugLogThink: blrl .set REG_GObjData,31 .set REG_PlayerData,30 backup #Only run during pass 0 cmpwi r4,0 bne DebugLogThink_Exit lwz REG_GObjData,0x2C(r3) #Check for state change bl GetInputs rlwinm. r0,r3,0,0x200 beq DebugLogThink_StateChangeEnd bl GetInputs rlwinm. r0,r4,0,0x2 beq DebugLogThink_StateChangeEnd #Inc state lwz r3,WindowData_State(REG_GObjData) addi r3,r3,1 stw r3,WindowData_State(REG_GObjData) cmpwi r3,4 ble DebugLogThink_ShowWindow #Loop back to hidden li r3,0 stw r3,WindowData_State(REG_GObjData) #Hide lwz r3,WindowData_Text(REG_GObjData) branchl r12,DevelopText_HideText lwz r3,WindowData_Text(REG_GObjData) branchl r12,DevelopText_HideBG b DebugLogThink_StateChangeEnd DebugLogThink_ShowWindow: #Show lwz r3,WindowData_Text(REG_GObjData) branchl r12,DevelopText_ShowText lwz r3,WindowData_Text(REG_GObjData) branchl r12,DevelopText_ShowBG DebugLogThink_StateChangeEnd: #Check to update text lwz r3,WindowData_State(REG_GObjData) cmpwi r3,0 beq DebugLogThink_Exit #Erase all text lwz r3,WindowData_Text(REG_GObjData) branchl r12,DevelopText_EraseAllText lwz r3,WindowData_Text(REG_GObjData) li r4,0 li r5,0 branchl r12,DevelopMode_Text_ResetCursorXY #Output player number lwz r3,WindowData_Text(REG_GObjData) bl String_Player mflr r4 lwz r5,WindowData_State(REG_GObjData) branchl r12,DevelopText_FormatAndPrint #Get current player data lwz r3,WindowData_State(REG_GObjData) subi r3,r3,1 branchl r12,PlayerBlock_LoadMainCharDataOffset cmpwi r3,0 beq DebugLogThink_Exit #Backup data lwz REG_PlayerData,0x2C(r3) #vprintf string lwz r3,WindowData_Text(REG_GObjData) bl String_LStick mflr r4 lfs f1,0x620(REG_PlayerData) lfs f2,0x624(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #vprintf string lwz r3,WindowData_Text(REG_GObjData) bl String_RStick mflr r4 lfs f1,0x638(REG_PlayerData) lfs f2,0x63C(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #vprintf string lwz r3,WindowData_Text(REG_GObjData) bl String_CVel mflr r4 lfs f1,0x80(REG_PlayerData) lfs f2,0x84(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #vprintf string lwz r3,WindowData_Text(REG_GObjData) bl String_KBVel mflr r4 lfs f1,0x8C(REG_PlayerData) lfs f2,0x90(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #vprintf string lwz r3,WindowData_Text(REG_GObjData) bl String_Pos mflr r4 lfs f1,0xB0(REG_PlayerData) lfs f2,0xB4(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #Output ECB Lock info lwz r3,WindowData_Text(REG_GObjData) bl String_ECBLock mflr r4 lwz r5,0x88C(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #Output ECB Bottom info lwz r3,WindowData_Text(REG_GObjData) li r4,18 branchl r12,DevelopText_ResetCursorX lwz r3,WindowData_Text(REG_GObjData) bl String_ECBBottom mflr r4 lfs f1,0x780(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #Output State info mr r3,REG_PlayerData addi r4,sp,0x88 bl GetStateInfo stfs f1,0x80(sp) stfs f2,0x84(sp) mr r5,r3 lwz r3,WindowData_Text(REG_GObjData) bl String_State mflr r4 crset 6 branchl r12,DevelopText_FormatAndPrint #Move cursor lwz r3,WindowData_Text(REG_GObjData) li r4,25 branchl r12,DevelopText_ResetCursorX #Output frames lwz r3,WindowData_Text(REG_GObjData) bl String_StateFrame mflr r4 lfs f1,0x80(sp) lfs f2,0x84(sp) crset 6 branchl r12,DevelopText_FormatAndPrint DebugLogThink_Exit: restore blr ############################# String_Player: blrl .string "Player %d X Y\n" .align 2 String_LStick: blrl .string "LStick: %1.4f %1.4f\n" .align 2 String_RStick: blrl .string "RStick: %1.4f %1.4f\n" .align 2 String_CVel: blrl .string "SelfVel: %3.4f %3.4f\n" .align 2 String_KBVel: blrl .string "KBVel: %3.4f %3.4f\n" .align 2 String_XVel: blrl .string "XVel: %3.4f %3.4f\n" .align 2 String_Pos: blrl .string "Pos: %3.4f %3.4f\n\n" .align 2 String_State: blrl .string "State: %s" .align 2 String_StateFrame: blrl .string "f: %03.2f/%1.0f" .align 2 String_ECBBottom: blrl .string "ECB_Bot: %03.2f\n\n" .align 2 String_ECBLock: blrl .string "ECB_Lock: %d" .align 2 BGColor: blrl .byte 21,20,59,135 ############################### GetInputs: .set REG_InputStruct,11 .set REG_Count,10 .set REG_HeldInputs,9 .set REG_InstantInputs,8 #Load Input Struct load REG_InputStruct,0x804c1fac #Init loop li REG_Count,0 li REG_HeldInputs,0 li REG_InstantInputs,0 GetInputs_Loop: #Get to inputs mulli r3,REG_Count,68 add r5,r3,REG_InputStruct #Grab Inputs lwz r3,0x0(r5) lwz r4,0xC(r5) #OR all inputs or REG_HeldInputs,REG_HeldInputs,r3 or REG_InstantInputs,REG_InstantInputs,r4 #Inc addi REG_Count,REG_Count,1 cmpwi REG_Count,4 blt GetInputs_Loop GetInputs_Exit: mr r3,REG_HeldInputs mr r4,REG_InstantInputs blr ###################################### GetStateInfo: .set REG_PlayerData,31 .set REG_StateString,30 backup mr REG_PlayerData,r3 mr REG_StateString,r4 #Check if common move lwz r3,0x10(REG_PlayerData) cmpwi r3,341 bge GetStateInfo_SpecialMove GetStateInfo_SharedMove: mulli r3,r3,4 lwz r4, -0x4B78 (r13) lwzx r4,r3,r4 mr r3,REG_StateString branchl r12,strcpy b GetStateInfo_GetRemainingFrames GetStateInfo_SpecialMove: #Get Animation Data Pointer mr r3,REG_PlayerData lwz r4,0x14(REG_PlayerData) branchl r12,0x80085fd4 #Get Move Name String lwz r3,0x0(r3) cmpwi r3,0 beq GetStateInfo_Unknown #Get Start of Move Name GetStateInfo_StringSearchLoop: lbzu r4,0x1(r3) cmpwi r4,0x4E #Check For "N" bne GetStateInfo_StringSearchLoop lbzu r4,0x1(r3) cmpwi r4,0x5F #Check for Underscore bne GetStateInfo_StringSearchLoop addi r3,r3,0x1 #Start of Move Name in r3 #Copy Move Name To Cut Off "fiagtree" Text subi r4,REG_StateString,0x1 subi r3,r3,0x1 GetStateInfo_StringCopyLoop: lbzu r6,0x1(r3) cmpwi r6,0x5F #Check for Underscore beq GetStateInfo_ExitCopyLoop stbu r6,0x1(r4) b GetStateInfo_StringCopyLoop GetStateInfo_ExitCopyLoop: li r3,0x0 stbu r3,0x1(r4) b GetStateInfo_GetRemainingFrames GetStateInfo_Unknown: bl GetStateInfo_UnkString mflr r4 mr r3,REG_StateString branchl r12,strcpy GetStateInfo_GetRemainingFrames: #Get Remaining Frames lwz r3,0x590(REG_PlayerData) #get anim data lfs f2,0x008(r3) #get anim length (float) GetStateInfo_Exit: mr r3,REG_StateString lfs f1,0x894(REG_PlayerData) restore blr ########################################## GetStateInfo_UnkString: blrl .string "UnkState" .align 2 ########################################## Exit: restore ================================================ FILE: ASM/Additional Codes/Physics Display/Main.s ================================================ #To be inserted at 80225554 .include "../../Globals.s" .set GObj_Create,0x803901f0 .set GObj_AddUserData,0x80390b68 .set GObj_AddProc,0x8038fd54 .set HSD_MemAlloc,0x8037f1e4 .set DevelopText_CreateDataTable,0x80302834 .set DevelopText_Activate,0x80302810 .set DevelopText_AddString,0x80302be4 .set DevelopText_FormatAndPrint,0x80302d4c .set DevelopText_EraseAllText,0x80302bb0 .set DevelopMode_Text_ResetCursorXY,0x80302a3c .set DevelopText_StoreBGColor,0x80302b90 .set DevelopText_HideText,0x80302b00 .set DevelopText_HideBG,0x80302ae0 .set DevelopText_ShowText,0x80302af0 .set DevelopText_ShowBG,0x80302ad0 .set DevelopText_StoreTextScale,0x80302b10 .set DevelopText_ResetCursorX,0x80302a88 .set sprintf,0x80323cf4 .set WindowData_Text,0x0 .set WindowData_State,0x4 .set REG_DevelopText,31 .set REG_GObjData,30 .set REG_GObj,29 stw r0, -0x4B7C (r13) backup #Create Rectangle li r3,0x1000 branchl r12,HSD_MemAlloc mr r8,r3 li r3,12 li r4,0 li r5,0 li r6,39 li r7,10 branchl r12,DevelopText_CreateDataTable mr REG_DevelopText,r3 #Activate Text lwz r3, -0x4884 (r13) mr r4,REG_DevelopText branchl r12,DevelopText_Activate #Hide blinking cursor li r3,0 stb r3,0x26(REG_DevelopText) #Change BG Color mr r3,REG_DevelopText bl BGColor mflr r4 branchl r12,DevelopText_StoreBGColor #Hide by default mr r3,REG_DevelopText branchl r12,DevelopText_HideText mr r3,REG_DevelopText branchl r12,DevelopText_HideBG #Change Text Size mr r3,REG_DevelopText bl TextFloats mflr r4 lfs f1,0x0(r4) lfs f2,0x4(r4) branchl r12,DevelopText_StoreTextScale #Create Background GObj li r3,0 li r4,0 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Allocate Space li r3,64 branchl r12,HSD_MemAlloc mr REG_GObjData,r3 #Zero li r4,64 branchl r12,ZeroAreaLength #Initialize mr r6,REG_GObjData mr r3,REG_GObj li r4,4 load r5,HSD_Free branchl r12,GObj_AddUserData #Add Process mr r3,REG_GObj bl DebugLogThink mflr r4 li r5,7 li r6,0 branchl r12,GObj_AddGXLink #branchl r12,GObj_AddProc #Store pointer to dev text stw REG_DevelopText,WindowData_Text(REG_GObjData) #Initialize State li r3,0 stw r3,WindowData_State(REG_GObjData) b Exit ######################################## TextFloats: blrl .float 7.5 .float 10 ######################################## DebugLogThink: blrl .set REG_GObjData,31 .set REG_PlayerData,30 backup #Only run during pass 0 cmpwi r4,0 bne DebugLogThink_Exit lwz REG_GObjData,0x2C(r3) #Check for state change bl GetInputs rlwinm. r0,r3,0,0x200 beq DebugLogThink_StateChangeEnd bl GetInputs rlwinm. r0,r4,0,0x2 beq DebugLogThink_StateChangeEnd #Inc state lwz r3,WindowData_State(REG_GObjData) addi r3,r3,1 stw r3,WindowData_State(REG_GObjData) cmpwi r3,4 ble DebugLogThink_ShowWindow #Loop back to hidden li r3,0 stw r3,WindowData_State(REG_GObjData) #Hide lwz r3,WindowData_Text(REG_GObjData) branchl r12,DevelopText_HideText lwz r3,WindowData_Text(REG_GObjData) branchl r12,DevelopText_HideBG b DebugLogThink_StateChangeEnd DebugLogThink_ShowWindow: #Show lwz r3,WindowData_Text(REG_GObjData) branchl r12,DevelopText_ShowText lwz r3,WindowData_Text(REG_GObjData) branchl r12,DevelopText_ShowBG DebugLogThink_StateChangeEnd: #Check to update text lwz r3,WindowData_State(REG_GObjData) cmpwi r3,0 beq DebugLogThink_Exit #Erase all text lwz r3,WindowData_Text(REG_GObjData) branchl r12,DevelopText_EraseAllText lwz r3,WindowData_Text(REG_GObjData) li r4,0 li r5,0 branchl r12,DevelopMode_Text_ResetCursorXY #Output player number lwz r3,WindowData_Text(REG_GObjData) bl String_Player mflr r4 lwz r5,WindowData_State(REG_GObjData) branchl r12,DevelopText_FormatAndPrint #Get current player data lwz r3,WindowData_State(REG_GObjData) subi r3,r3,1 branchl r12,PlayerBlock_LoadMainCharDataOffset cmpwi r3,0 beq DebugLogThink_Exit #Backup data lwz REG_PlayerData,0x2C(r3) #vprintf string lwz r3,WindowData_Text(REG_GObjData) bl String_LStick mflr r4 lfs f1,0x620(REG_PlayerData) lfs f2,0x624(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #vprintf string lwz r3,WindowData_Text(REG_GObjData) bl String_RStick mflr r4 lfs f1,0x638(REG_PlayerData) lfs f2,0x63C(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #vprintf string lwz r3,WindowData_Text(REG_GObjData) bl String_CVel mflr r4 lfs f1,0x80(REG_PlayerData) lfs f2,0x84(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #vprintf string lwz r3,WindowData_Text(REG_GObjData) bl String_KBVel mflr r4 lfs f1,0x8C(REG_PlayerData) lfs f2,0x90(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #vprintf string lwz r3,WindowData_Text(REG_GObjData) bl String_Pos mflr r4 lfs f1,0xB0(REG_PlayerData) lfs f2,0xB4(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #Output ECB Lock info lwz r3,WindowData_Text(REG_GObjData) bl String_ECBLock mflr r4 lwz r5,0x88C(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #Output ECB Bottom info lwz r3,WindowData_Text(REG_GObjData) li r4,18 branchl r12,DevelopText_ResetCursorX lwz r3,WindowData_Text(REG_GObjData) bl String_ECBBottom mflr r4 lfs f1,0x780(REG_PlayerData) crset 6 branchl r12,DevelopText_FormatAndPrint #Output State info mr r3,REG_PlayerData addi r4,sp,0x88 bl GetStateInfo stfs f1,0x80(sp) stfs f2,0x84(sp) mr r5,r3 lwz r3,WindowData_Text(REG_GObjData) bl String_State mflr r4 crset 6 branchl r12,DevelopText_FormatAndPrint #Move cursor lwz r3,WindowData_Text(REG_GObjData) li r4,25 branchl r12,DevelopText_ResetCursorX #Output frames lwz r3,WindowData_Text(REG_GObjData) bl String_StateFrame mflr r4 lfs f1,0x80(sp) lfs f2,0x84(sp) crset 6 branchl r12,DevelopText_FormatAndPrint DebugLogThink_Exit: restore blr ############################# String_Player: blrl .string "Player %d X Y\n" .align 2 String_LStick: blrl .string "LStick: %1.4f %1.4f\n" .align 2 String_RStick: blrl .string "RStick: %1.4f %1.4f\n" .align 2 String_CVel: blrl .string "SelfVel: %3.4f %3.4f\n" .align 2 String_KBVel: blrl .string "KBVel: %3.4f %3.4f\n" .align 2 String_XVel: blrl .string "XVel: %3.4f %3.4f\n" .align 2 String_Pos: blrl .string "Pos: %3.4f %3.4f\n\n" .align 2 String_State: blrl .string "State: %s" .align 2 String_StateFrame: blrl .string "f: %03.2f/%1.0f" .align 2 String_ECBBottom: blrl .string "ECB_Bot: %03.2f\n\n" .align 2 String_ECBLock: blrl .string "ECB_Lock: %d" .align 2 BGColor: blrl .byte 21,20,59,135 ############################### GetInputs: .set REG_InputStruct,11 .set REG_Count,10 .set REG_HeldInputs,9 .set REG_InstantInputs,8 #Load Input Struct load REG_InputStruct,0x804c1fac #Init loop li REG_Count,0 li REG_HeldInputs,0 li REG_InstantInputs,0 GetInputs_Loop: #Get to inputs mulli r3,REG_Count,68 add r5,r3,REG_InputStruct #Grab Inputs lwz r3,0x0(r5) lwz r4,0xC(r5) #OR all inputs or REG_HeldInputs,REG_HeldInputs,r3 or REG_InstantInputs,REG_InstantInputs,r4 #Inc addi REG_Count,REG_Count,1 cmpwi REG_Count,4 blt GetInputs_Loop GetInputs_Exit: mr r3,REG_HeldInputs mr r4,REG_InstantInputs blr ###################################### GetStateInfo: .set REG_PlayerData,31 .set REG_StateString,30 backup mr REG_PlayerData,r3 mr REG_StateString,r4 #Check if common move lwz r3,0x10(REG_PlayerData) cmpwi r3,341 bge GetStateInfo_SpecialMove GetStateInfo_SharedMove: mulli r3,r3,4 lwz r4, -0x4B78 (r13) lwzx r4,r3,r4 mr r3,REG_StateString branchl r12,strcpy b GetStateInfo_GetRemainingFrames GetStateInfo_SpecialMove: #Get Animation Data Pointer mr r3,REG_PlayerData lwz r4,0x14(REG_PlayerData) branchl r12,0x80085fd4 #Get Move Name String lwz r3,0x0(r3) cmpwi r3,0 beq GetStateInfo_Unknown #Get Start of Move Name GetStateInfo_StringSearchLoop: lbzu r4,0x1(r3) cmpwi r4,0x4E #Check For "N" bne GetStateInfo_StringSearchLoop lbzu r4,0x1(r3) cmpwi r4,0x5F #Check for Underscore bne GetStateInfo_StringSearchLoop addi r3,r3,0x1 #Start of Move Name in r3 #Copy Move Name To Cut Off "fiagtree" Text subi r4,REG_StateString,0x1 subi r3,r3,0x1 GetStateInfo_StringCopyLoop: lbzu r6,0x1(r3) cmpwi r6,0x5F #Check for Underscore beq GetStateInfo_ExitCopyLoop stbu r6,0x1(r4) b GetStateInfo_StringCopyLoop GetStateInfo_ExitCopyLoop: li r3,0x0 stbu r3,0x1(r4) b GetStateInfo_GetRemainingFrames GetStateInfo_Unknown: bl GetStateInfo_UnkString mflr r4 mr r3,REG_StateString branchl r12,strcpy GetStateInfo_GetRemainingFrames: #Get Remaining Frames lwz r3,0x590(REG_PlayerData) #get anim data lfs f2,0x008(r3) #get anim length (float) GetStateInfo_Exit: mr r3,REG_StateString lfs f1,0x894(REG_PlayerData) restore blr ########################################## GetStateInfo_UnkString: blrl .string "UnkState" .align 2 ########################################## Exit: restore ================================================ FILE: ASM/Additional Codes/QWERTY Keyboard.s ================================================ #To be inserted at 803edc1c .long 0x804D4DD4 .long 0x804D4CAC .long 0x804D4CAC .long 0x804D4D98 .long 0x804D4D9C .long 0x804D4DE8 .long 0x804D4E24 .long 0x804D4CAC .long 0x804D4DA8 .long 0x804D4DAC .long 0x804D4DA0 .long 0x804D4E38 .long 0x804D4CAC .long 0x804D4DB8 .long 0x804D4DBC .long 0x804D4E3C .long 0x804D4D90 .long 0x804D4E10 .long 0x804D4DC8 .long 0x804D4DCC .long 0x804D4DEC .long 0x804D4DB0 .long 0x804D4DFC .long 0x804D4DDC .long 0x804D4DE0 .long 0x804D4D94 .long 0x804D4DC0 .long 0x804D4E20 .long 0x804D4DF0 .long 0x804D4DF4 .long 0x804D4DB4 .long 0x804D4DD0 .long 0x804D4E28 .long 0x804D4E04 .long 0x804D4E08 .long 0x804D4DE4 .long 0x804D4DF8 .long 0x804D4E0C .long 0x804D4E18 .long 0x804D4E1C .long 0x804D4E14 .long 0x804D4DA4 .long 0x804D4E00 .long 0x804D4E2C .long 0x804D4E30 .long 0x804D4DC4 .long 0x804D4E34 .long 0x804D4DD8 .long 0x804D4E40 .long 0x804D4E44 ================================================ FILE: ASM/Additional Codes/Random CSS Music v2/random music modification.asm ================================================ #To be inserted at 8015ecec .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup addi sp,sp,-0x4 mflr r0 stw r0,0(sp) .endm .macro restore lwz r0,0(sp) mtlr r0 addi sp,sp,0x4 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 li r3,0x3 branchl r12,HSD_Randi cmpwi r3,0x0 beq MainMenu1 cmpwi r3,0x1 beq MainMenu2 cmpwi r3,0x2 beq Trophy MainMenu1: li r0,0x34 b done MainMenu2: li r0,0x36 b done Trophy: li r0,0x35 b done done: stb r0, 0x0001 (r31) branch r12, 0x8015ed1c ================================================ FILE: ASM/Additional Codes/Random CSS Music v2/roll on bootup.asm ================================================ #To be inserted at 801a45a8 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup addi sp,sp,-0x4 mflr r0 stw r0,0(sp) .endm .macro restore lwz r0,0(sp) mtlr r0 addi sp,sp,0x4 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 branchl r12,0x8015ecbc original: li r0, 45 ================================================ FILE: ASM/Additional Codes/Random CSS Music v2/roll on match end.asm ================================================ #To be inserted at 8016eba8 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 branchl r12,0x8015ecbc original: lwz r0, 0x001C (sp) ================================================ FILE: ASM/Additional Codes/Randomize Hitboxes Each Stock/Randomize Hitbox Values.s ================================================ #To be inserted at 80071240 .include "../../Globals.s" .set REG_Script,29 .set REG_FighterGObj,28 .set REG_Sum,30 .set REG_Free2,31 # first add up the entire subaction data lwz r3, 0x0008 (REG_Script) li r4,0 li REG_Sum,0 AddLoop: lwz r5,0x0(r3) add REG_Sum,REG_Sum,r5 AddLoopInc: addi r4,r4,1 addi r3,r3,4 cmpwi r4,5 blt AddLoop # get 16 bit int from this (shitty hash) .set REG_Hash,30 sth REG_Sum,0x03C(sp) lhz REG_Hash,0x03C(sp) # get random damage # get random angle # get random KB # exit b Original Original: lwz r4, 0x0008 (REG_Script) ================================================ FILE: ASM/Additional Codes/Rumble Off/Rumble Off.asm ================================================ #To be inserted at 803d4a70 .long 0x00000000 ================================================ FILE: ASM/Additional Codes/Skip Memcard Prompt/Skip Memcard Prompt.asm ================================================ #To be inserted at 801af6f4 .include "../../Globals.s" .set MEMCARD_NONE,0xF .set MEMCARD_NONE2,0xD #Check if no memcard inserted cmpwi r29,MEMCARD_NONE beq NoMemcard cmpwi r29,MEMCARD_NONE2 beq NoMemcard b Original NoMemcard: #Exit memcard think and disable saving branch r12,0x801b01ac Original: cmpwi r29,0 ================================================ FILE: ASM/Additional Codes/Stage Music = 50 50.asm ================================================ #To be inserted at 801C26B0 li r0, 50 ================================================ FILE: ASM/Additional Codes/Toggle Focused Player in Develop Mode Camera/Switch Focused Player in Develop Mode.asm ================================================ #To be inserted at 802276f4 .include "../../Globals.s" .set REG_Inputs,31 .set REG_FocusedPlayer,30 .set REG_CameraStruct,29 .set REG_Additive,28 backup #Get Current Focused Player load REG_CameraStruct,0x80453004 lwz REG_FocusedPlayer,0x4(REG_CameraStruct) #Init REG_Additive li REG_Additive,0 #Check Dpad Left CheckDPadLeft: rlwinm. r0,REG_Inputs,0,25,25 beq CheckDPadRight #Pressing Left li REG_Additive,-1 b GetNextPlayer #Check Dpad Right CheckDPadRight: rlwinm. r0,REG_Inputs,0,26,26 beq GetNextPlayer #Pressing Right li REG_Additive,1 b GetNextPlayer GetNextPlayer: cmpwi REG_Additive,0 beq Exit GetNextPlayerLoop: add REG_FocusedPlayer,REG_FocusedPlayer,REG_Additive #Check if Under 4 cmpwi REG_FocusedPlayer,4 blt GetNextPlayer_Under4 #Loop around back to 0 li REG_FocusedPlayer,0 GetNextPlayer_Under4: #Check if Over 4 cmpwi REG_FocusedPlayer,0 bge GetNextPlayer_CheckIfExists #Loop around back to 3 li REG_FocusedPlayer,3 GetNextPlayer_CheckIfExists: mr r3,REG_FocusedPlayer branchl r12,0x80034110 cmpwi r3,0x0 beq GetNextPlayerLoop #Store New Focused Player stw REG_FocusedPlayer,0x4(REG_CameraStruct) Exit: restore branchl r12,0x80030a50 ================================================ FILE: ASM/Additional Codes/Toggle Focused Player in Develop Mode Camera/WIP/Init CameraMode Struct When Develop is Enabled.s ================================================ #To be inserted at 8016e898 .include "../../Globals.s" lwz r0, -0x6C98 (r13) cmpwi r0,3 blt Original branchl r12,0x8002fc7c Original: lis r3, 0x8047 ================================================ FILE: ASM/Additional Codes/Toggle Rumble From CSS/Toggle Rumble From CSS.asm ================================================ #To be inserted at 802608D8 .include "../../Globals.s" #CREDIT: Dan Salvato loc_0x0: lbz r3, 7(r31) cmpwi r3, 0x0 bne- loc_0x98 lbz r4, 4(r31) mr r23, r4 lwz r0, -30656(r13) add r3, r0, r4 lbz r5, 7360(r3) rlwinm. r0, r28, 0, 28, 28 bne- loc_0x34 rlwinm. r0, r28, 0, 29, 29 bne- loc_0x68 b loc_0xDC loc_0x34: cmplwi r5, 1 beq- loc_0xDC mr r3, r23 li r4, 0x0 li r5, 0xE li r6, 0x0 subi r7, r13, 0x66B0 branchl r12,0x80378430 li r4, 0x1 b loc_0x74 loc_0x68: cmplwi r5, 0 beq- loc_0xDC li r4, 0x0 loc_0x74: mr r3, r23 branchl r12,0x8015ED4C li r4, 0x1 stb r4, 7(r31) lis r4, 0xC040 stw r4, 20(r31) loc_0x98: lfs f1, 20(r31) lfs f2, -29172(r2) lfs f0, 12(r31) fadds f0, f1, f0 stfs f0, 12(r31) fneg f3, f1 fcmpo cr0, f3, f1 bgt- loc_0xBC fmuls f3, f3, f2 loc_0xBC: stfs f3, 20(r31) blt- loc_0xDC lfs f4, -32168(r2) fcmpo cr0, f3, f4 bgt- loc_0xDC li r4, 0x0 stw r4, 20(r31) stb r4, 7(r31) loc_0xDC: lbz r4, 4(r31) ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Characters/Spoof All Characters as Unlocked.asm ================================================ #To be inserted at 80164b14 li r3, 1 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Characters/Spoof Individual Characters as Unlocked.asm ================================================ #To be inserted at 801648f4 li r3, 1 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Rules/Unlock Random Stage Select.asm ================================================ #To be inserted at 8015ee4c li r3, 1 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Rules/Unlock Score Display.asm ================================================ #To be inserted at 8015ee14 li r3, 1 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Special Messages/Special Messages 1.asm ================================================ #To be inserted at 8015d968 .include "../../../Globals.s" li r3,1 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Special Messages/Special Messages 2.asm ================================================ #To be inserted at 8015d9d8 .include "../../../Globals.s" li r3,1 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Special Messages/Spoof No Pending Messages 2.asm ================================================ #To be inserted at 8017229c .include "../../../Globals.s" li r3,0 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Special Messages/Spoof No Pending Messages.asm ================================================ #To be inserted at 801737b0 .include "../../../Globals.s" li r3,0 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Stages/Spoof All Stages Unlocked.asm ================================================ #To be inserted at 80164658 li r3, 1 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Stages/Spoof Individual Stage Unlocked.asm ================================================ #To be inserted at 801644e8 li r3, 1 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Trophies/Fill Save Data.asm ================================================ #To be inserted at 8015f6f8 .include "../../../Globals.s" #Get trophy data lwz r3, -0x77C0 (r13) addi r3, r3, 7376 #Set trophy count li r4,293 sth r4,0x0(r3) #Set individual trophies as unlocked addi r3,r3,4 li r4,99 li r5,0x24f branchl r12,memset Exit: cmpwi r25, 0 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Trophies/Have 99 of Every Trophy.asm ================================================ #To be inserted at 8030490c li r3, 99 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All Trophies/Spoof All Trophies as Unlocked.asm ================================================ #To be inserted at 803044f0 li r3, 1 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock All-Star.asm ================================================ #To be inserted at 8015ee98 li r3, 1 ================================================ FILE: ASM/Additional Codes/Unlock Everything/Unlock Sound Test.asm ================================================ #To be inserted at 8015eddc li r3, 1 ================================================ FILE: ASM/Additional Codes/Unplugging Closes CSS Door.asm ================================================ #To be inserted at 802605fc .include "../Globals.s" li r6,3 ================================================ FILE: ASM/Additional Codes/Use Save Banner #1.asm ================================================ #To be inserted at 8001c838 .include "../Globals.s" .set entity,31 .set player,31 #Check if Memcard lis r3,0x8000 lwz r3,0x0(r3) load r4,0x47544d45 #GTME cmpw r3,r4 beq ISO Memcard: li r0, 2 b Exit ISO: li r0, 1 Exit: ================================================ FILE: ASM/Additional Codes/Winners Names are Gold on CSS/Change Name Color.asm ================================================ #To be inserted at 80265220 .include "../../Globals.s" #Check If Player Won Last Game mr r3,r29 bl CheckIfWonLastGame cmpwi r3,0x0 beq Exit #Change Text Color lwz r3, 0 (r27) li r4,0 load r5,0xFFD70000 stw r5,0x100(sp) addi r5,sp,0x100 branchl r12,0x803a74f0 b Exit ######################################################### CheckIfWonLastGame: .set MatchEndStruct,31 .set MatchEndPlayerStruct,30 .set PlayerSlot,29 backup mr PlayerSlot,r3 load MatchEndStruct,0x80479da4 mulli MatchEndPlayerStruct,PlayerSlot,0xA8 add MatchEndPlayerStruct,MatchEndPlayerStruct,MatchEndStruct #Check if last game data exists lbz r3,0x4(MatchEndStruct) cmpwi r3,0x0 beq CheckIfWonLastGame_DidNotWin #Check if last game was same Mode (Teams/FFA) load r3,0x8046b6a0 lbz r3,0x24D0(r3) lbz r4,0x6(MatchEndStruct) cmpw r3,r4 bne CheckIfWonLastGame_DidNotWin #Check if player partook in last game lbz r3,0x58(MatchEndPlayerStruct) cmpwi r3,3 beq CheckIfWonLastGame_DidNotWin #Check if last game was an LRA Start lbz r3,0x4(MatchEndStruct) cmpwi r3,0x7 bne CheckIfWonLastGame_CheckForTeams #Check if this was a team LRA Start lbz r3,0x6(MatchEndStruct) cmpwi r3,0x1 bne CheckIfWonLastGame_FFA_LRAStart CheckIfWonLastGame_Team_LRAStart: #Check who LRA started lbz r3,0x0(MatchEndStruct) #Get his team ID mulli r3,r3,0xA8 add r3,r3,MatchEndStruct lbz r3,0x5F(r3) #Get current players team ID lbz r4,0x5F(MatchEndPlayerStruct) #Check If Same Team cmpw r3,r4 beq CheckIfWonLastGame_DidNotWin b CheckIfWonLastGame_Won CheckIfWonLastGame_FFA_LRAStart: #Check who LRA started lbz r3,0x0(MatchEndStruct) #If this player did, return 0 cmpw r3,PlayerSlot beq CheckIfWonLastGame_DidNotWin b CheckIfWonLastGame_Won CheckIfWonLastGame_CheckForTeams: #Check if Teams Match lbz r3,0x6(MatchEndStruct) cmpwi r3,0x1 bne CheckIfWonLastGame_FFA #If so find winning team mr r3,MatchEndStruct branchl r12,0x801654a0 #Check this players team lbz r4,0x5F(MatchEndPlayerStruct) #If this player was on winning team, return 1, if not return 0 cmpw r3,r4 beq CheckIfWonLastGame_Won b CheckIfWonLastGame_DidNotWin CheckIfWonLastGame_FFA: #Check If Player Won lbz r3,0x5D(MatchEndPlayerStruct) #if so return 1, if not return 0 cmpwi r3,0 beq CheckIfWonLastGame_Won b CheckIfWonLastGame_DidNotWin CheckIfWonLastGame_DidNotWin: li r3,0 b 0x8 CheckIfWonLastGame_Won: li r3,1 restore blr ######################################################### Exit: lbz r0, -0x49AB (r13) ================================================ FILE: ASM/Additional Codes/Winners Names are Gold on CSS/Remember Who LRA Started.asm ================================================ #To be inserted at 8016ea30 .include "../../Globals.s" #Original Codeline stb r0, 0x0010 (r30) #Check If LRA Start cmpwi r0,0x7 bne Exit #Find Who LRA Started load r4,0x8046b6a0 lbz r4,0x1(r4) stb r4,0xC(r30) Exit: ================================================ FILE: ASM/Additional Codes/XYDisablesStart/Main.asm ================================================ #To be inserted at 803775bc .include "../../Globals.s" #Check if pressing start rlwinm. r3,r0,0,0x1000 beq Injection_Exit #Check if also holding X+Y rlwinm. r3,r0,0,0xC00 beq Injection_Exit #Remove the start input li r3,0 rlwimi r0,r3,12,0x1000 Injection_Exit: #store their instant input stw r0, 0 (r26) ================================================ FILE: ASM/Globals.s ================================================ ##################### ## Melee Variables ## ##################### #Static Memory Locations .set pdLoadCommonData,0x803bcde0 .set InputStructStart,0x804c21cc .set InputStruct_HeldButtons,0x0 .set InputStruct_HeldButtonsPrevFrame,0x4 .set InputStruct_InstantButtons,0x8 .set InputStruct_RapidFireButtons,0xC .set InputStruct_InstantReleasedButtons,0x10 .set InputStruct_RapidFireCounter,0x14 .set InputStruct_LeftAnalogX,0x18 .set InputStruct_LeftAnalogY,0x19 .set InputStruct_RightAnalogX,0x1A .set InputStruct_RightAnalogY,0x1B .set InputStruct_LeftTrigger,0x1C .set InputStruct_RightTrigger,0x1D .set InputStruct_LeftAnalogXFloat,0x20 .set InputStruct_LeftAnalogYFloat,0x24 .set InputStruct_RightAnalogXFloat,0x28 .set InputStruct_RightAnalogYFloat,0x2C .set InputStruct_IsPlugged,0x41 .set InputStruct_Length,68 .set HSD_InputStructStart,0x804c1fac .set PreloadTable,0x80432078 .set Preload_Stage,0x10 .set CSS_CursorPointers,0x804a0bc0 .set HSD_Pad,0x804c1f78 .set CSS_DoorStructs,0x803f0dfc .set CSSDoor_State,0xB #r13 Offsets .set MemcardData,-0x77C0 .set DEBUGLV,-0x6C98 .set CSS_Data,-0x49F0 .set CSS_UnkGObj,-0x49E4 .set CSS_UnkJObj,-0x49E0 .set CSS_PointerToDatNodes,-0x49C8 #these are initialized to at 80266970 .set CSS_MainPlayerPort,-0x49B0 .set CSS_CPUPlayerPort,-0x49AF .set CSS_StartCountdown,-0x49AE .set CSS_Unk,-0x49AC .set CSS_MaxPlayers,-0x49AB .set CSS_Unk,-0x49AA .set CSS_SinglePlayerPortNumber,-0x4DE0 .set HPS_Unk,-0x3F44 .set HPS_CurrentSongEntryNum,-0x3F3C .set HPS_Unk,-0x3F14 .set GObj_CurrentProc,-0x3E68 .set HSDPerf_,0x0 .set Hitbox_DamageLog,-0x5148 #Num of solid hits dealt by the player this check .set Hitbox_TipLog,-0x5144 #Num of phantom hits dealt by the player this check .set StageID_External,-0x6CB8 .set Stage_LedgeInfo,-0x51E8 .set Stage_LineInfo,-0x51EC #ctrl f "stage line counts" in melee notes.txt for detailed info .set Stage_PositionHazardCount,-0x5128 .set Stage_GrabHazardCount,-0x512C .set Stage_DamageHazardCount,-0x5130 .set Audio_NextAreaInSSMHeap,-0x5258 .set Audio_UnkConstant,-0x5250 .set Audio_TotalSSMMemory,-0x5268 .set GObj_Lists,-0x3E74 .set TM_FrozenToggle,-0x4F8C .set TM_GameFrameCounter,-0x49a8 #Scene Struct .set SceneController,0x80479D30 .set Scene.CurrentMajor,0x0 .set Scene.PendingMajor,0x1 .set Scene.PreviousMajor,0x2 .set Scene.CurrentMinor,0x3 .set Scene.PendingMinor,0x4 .set Scene.PreviousMinor,0x5 #Scene ID's .set Scene.TitleScreen,0x00 .set Scene.MainMenu,0x01 .set Scene.VSMode,0x02 .set Scene.ClassicMode,0x03 .set Scene.AdventureMode,0x04 .set Scene.AllStarMode,0x05 .set Scene.MainDebugMenu,0x06 .set Scene.SoundTestDebugMenu,0x07 .set Scene.HanyuTestCSS,0x08 .set Scene.HanyuTestSSS,0x09 .set Scene.CameraModeMemcardPrompt,0x0A .set Scene.TrophyGallery,0x0B .set Scene.TrophyLottery,0x0C .set Scene.TrophyCollection,0x0D .set Scene.DebugDiarantou,0x0E .set Scene.TargetTest,0x0F .set Scene.SuperSuddenDeath,0x10 .set Scene.InvisibleMelee,0x11 .set Scene.SloMoMelee,0x12 .set Scene.LightningMelee,0x13 .set Scene.ChallengerApproaching,0x14 .set Scene.ClassicModeEnding,0x15 .set Scene.AdventureModeEnding,0x16 .set Scene.AllStarModeEnding,0x17 .set Scene.OpeningMovie,0x18 .set Scene.VisualSceneDebug,0x19 .set Scene.1PEndingDebug,0x1A .set Scene.TournamentMode,0x1B .set Scene.TrainingMode,0x1C .set Scene.TinyMelee,0x1D .set Scene.GiantMelee,0x1E .set Scene.StaminaMode,0x1F .set Scene.HomeRunContest,0x20 .set Scene.10ManMelee,0x21 .set Scene.100ManMelee,0x22 .set Scene.3MinuteMelee,0x23 .set Scene.15MinuteMelee,0x24 .set Scene.EndlessMelee,0x25 .set Scene.CruelMelee,0x26 .set Scene.ProgressiveScanPrompt,0x27 .set Scene.BootUp,0x28 .set Scene.MemcardPropmt,0x29 .set Scene.FixedCamera,0x2A .set Scene.EventMode,0x2B .set Scene.SingleButton,0x2C #################### ## Function Names ## #################### .set ActionStateChange,0x800693ac .set OSReport,0x803456a8 .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set AS_Wait,0x8008a2bc .set AS_Fall,0x800cc730 .set AS_Catch,0x800d8c54 .set AS_Guard,0x800939b4 .set HSD_MemAlloc,0x8037f1e4 .set HSD_JObjLoadJoint,0x80370e44 .set memcpy,0x800031f4 .set strcpy,0x80325a50 .set ZeroAreaLength,0x8000c160 .set CreateCameraBox,0x80029020 .set FrameSpeedChange,0x8006f190 .set HUD_KOCounter_UpdateKOs,0x802fa2d0 .set Playerblock_StoreTimesR3KilledR4,0x80034fa8 .set Playerblock_LoadTimesR3KilledR4,0x80034f24 .set SFX_PlaySoundAtFullVolume,0x801c53ec .set SFX_MenuCommonSound,0x80024030 .set AS_Rebirth,0x800d4ff4 .set Stage_GetLeftOfLineCoordinates,0x80053ecc .set Stage_GetRightOfLineCoordinates,0x80053da4 .set AS_RebirthWait,0x800d5600 .set RebirthPlatform_UpdatePosition,0x800d54a4 .set AS_CliffWait,0x8009a804 .set Air_StoreBool_LoseGroundJump_NoECBfor10Frames,0x8007d5d4 .set DataOffset_ECBBottomUpdateEnable,0x8007d5bc .set MovePlayerToLedge,0x80081544 .set ApplyIntangibility,0x8007b760 .set ApplyInvincibility,0x8007b7a4 .set GFX_RemoveAll,0x8007db24 .set PlayerBlock_LoadMainCharDataOffset,0x80034110 .set PlayerBlock_SetDamage,0x80034330 .set PlayerBlock_LoadDamage,0x800342b4 .set StageInfo_CameraLimitLeft_Load,0x80224a54 .set StageInfo_CameraLimitRight_Load,0x80224a68 .set StageInfo_CameraLimitTop_Load,0x80224a80 .set StageInfo_CameraLimitBottom_Load,0x80224a98 .set Stage_map_gobj_Load,0x801c2ba4 .set Stage_map_gobj_LoadJObj,0x801c3fa4 .set Stage_Destroy_map_gobj,0x801c4a08 .set EntityItemSpawn,0x80268b18 .set MatchInfo_LoadSeconds,0x8016aeec .set MatchInfo_LoadSubSeconds,0x8016aefc .set EventMatch_OnWinCondition,0x801bc4f4 .set Events_GetEventSavedScore,0x8015cf5c .set Events_SetEventSavedScore,0x8015cf70 .set Textures_DisplayEffectTextures,0x8005fddc .set AS_GrabOpponent,0x800d9ce8 .set AS_Grabbed,0x800daadc .set AS_CatchWait,0x800da1d8 .set AS_SquatWait,0x800d62c4 .set AS_Sleep,0x800d4f24 .set SetAsGrounded,0x8007d7fc .set FrameSpeedChange,0x8006f190 .set EnvironmentCollision_WaitLanding,0x80084280 .set Air_SetAsGrounded,0x8007d6a4 .set CPU_JoystickXAxis_Convert,0x800a17e4 .set CPU_JoystickYAxis_Convert,0x800a1874 .set Joystick_Angle_Retrieve,0x8007d9d4 .set GFX_UpdatePlayerGFX,0x800c0408 .set cos,0x80326240 .set sin,0x803263d4 .set fmod,0x80364340 .set sqrt,0x8000d5bc .set HSD_Free,0x8037f1b0 .set GObj_Create,0x803901f0 .set GObj_AddUserData,0x80390b68 .set GObj_Destroy,0x80390228 .set GObj_AddProc,0x8038fd54 .set GObj_RemoveProc,0x8038fed4 .set GObj_StorePointerToJObj,0x80390a70 .set GObj_AddGXLink,0x8039069c .set HSD_JObjSetMtxDirtySub,0x803732e8 .set DevelopMode_FrameAdvanceCheck,0x801a45e8 .set MatchInfo_StockModeCheck,0x8016b094 .set PlayerBlock_LoadStocksLeft,0x80033bd8 .set PlayerBlock_LoadSlotType,0x8003241c .set Playerblock_LoadStaticBlock,0x80031724 .set Text_CreateTextStruct,0x803a6754 .set Text_InitializeSubtext,0x803a6b98 .set Text_UpdateSubtextSize,0x803a7548 .set Text_UpdateSubtextPosition,0x803a746c .set Text_UpdateSubtextContents,0x803a70a0 .set Text_ChangeTextColor,0x803a74f0 .set Text_RemoveText,0x803a5cc4 .set strlen,0x80325b04 .set PlayerBlock_LoadExternalCharID,0x80032330 .set PlayerBlock_GotoStaleMoveEntry_0xBC,0x80036244 .set InitializePlayerDataValues,0x80068354 .set Event_GetEventSavedScore,0x8015cf5c .set Events_CheckIfEventWasPlayedYet,0x8015cefc .set Events_SetEventAsPlayed,0x8015ceb4 .set Events_StoreEventScore,0x8015cf70 .set Interrupt_AerialJumpGoTo,0x800cb870 .set PlayerBlock_UpdateXYCoords,0x80032828 .set Raycast_GroundLine,0x8004f008 .set Camera_UpdatePlayerCameraBoxPosition,0x800761c8 .set Camera_CorrectPosition,0x8002f3ac .set ItemCollision_Egg,0x802895a8 .set SFX_StopAllCharacterSFX,0x80088a50 .set SFXManager_StopSFXIfPlaying,0x80321ce8 .set memset,0x80003100 .set Ragdoll_WindDecayThink,0x800115f4 .set Inputs_GetPlayerHeldInputs,0x801a3680 .set Inputs_GetPlayerInstantInputs,0x801a36a0 .set Inputs_GetPlayerRapidInputs,0x801a36c0 .set DevelopText_CreateDataTable,0x80302834 .set DevelopText_Activate,0x80302810 .set DevelopText_AddString,0x80302be4 .set DevelopText_EraseAllText,0x80302bb0 .set DevelopMode_Text_ResetCursorXY,0x80302a3c .set DevelopText_StoreBGColor,0x80302b90 .set DevelopText_HideBG,0x80302ae0 .set DevelopText_ShowBG,0x80302ad0 .set cvt_sll_flt,0x80322da0 .set cvt_fp2unsigned,0x803228c0 .set sprintf,0x80323cf4 .set PlayerBlock_LoadNameTagSlot,0x8003556c .set Nametag_LoadNametagSlotText,0x8023754c .set LoadRulesSettingsPointer1,0x8015cc34 .set CSS_UpdateCSPInfo,0x8025db34 .set Rumble_StoreRumbleFlag,0x8015ed4c #Custom Functions .set TextCreateFunction,0x80005928 .set GetCustomEventPageName,0x8000552c .set SearchStringTable,0x80005530 .set GetNumOfEventsOnCurrentPage,0x80005534 .set GetEventTutorialFileName,0x80005538 .set prim.new,0x804DD84C .set prim.close,0x804DD848 #Character External IDs .set CaptainFalcon.Ext,0x0 .set DK.Ext,0x1 .set Fox.Ext,0x2 .set GaW.Ext,0x3 .set Kirby.Ext,0x4 .set Bowser.Ext,0x5 .set Link.Ext,0x6 .set Luigi.Ext,0x7 .set Mario.Ext,0x8 .set Marth.Ext,0x9 .set Mewtwo.Ext,0xA .set Ness.Ext,0xB .set Peach.Ext,0xC .set Pikachu.Ext,0xD .set IceClimbers.Ext,0xE .set Jigglypuff.Ext,0xF .set Samus.Ext,0x10 .set Yoshi.Ext,0x11 .set Zelda.Ext,0x12 .set Sheik.Ext,0x13 .set Falco.Ext,0x14 .set YLink.Ext,0x15 .set Doc.Ext,0x16 .set Roy.Ext,0x17 .set Pichu.Ext,0x18 .set Ganondorf.Ext,0x19 #Character Internal IDs .set Mario.Int,0x0 .set Fox.Int,0x1 .set CaptainFalcon.Int,0x2 .set DK.Int,0x3 .set Kirby.Int,0x4 .set Bowser.Int,0x5 .set Link.Int,0x6 .set Sheik.Int,0x7 .set Ness.Int,0x8 .set Peach.Int,0x9 .set Popo.Int,0xA .set Nana.Int,0xB .set Pikachu.Int,0xC .set Samus.Int,0xD .set Yoshi.Int,0xE .set Jigglypuff.Int,0xF .set Mewtwo.Int,0x10 .set Luigi.Int,0x11 .set Marth.Int,0x12 .set Zelda.Int,0x13 .set YLink.Int,0x14 .set Doc.Int,0x15 .set Falco.Int,0x16 .set Pichu.Int,0x17 .set GaW.Int,0x18 .set Ganondorf.Int,0x19 .set Roy.Int,0x1A /* #Character CSS ID .set Doc_CSSID,0x0 .set Mario_CSSID,0x1 .set Luigi_CSSID,0x2 .set Bowser_CSSID,0x3 .set Peach_CSSID,0x4 .set Yoshi_CSSID,0x5 .set DK_CSSID,0x6 .set CaptainFalcon_CSSID,0x7 .set Ganondorf_CSSID,0x8 .set Falco_CSSID,0x9 .set Fox_CSSID,0xA .set Ness_CSSID,0xB .set IceClimbers_CSSID,0xC .set Kirby_CSSID,0xD .set Samus_CSSID,0xE .set Zelda_CSSID,0xF .set Link_CSSID,0x10 .set YLink_CSSID,0x11 .set Pichu_CSSID,0x12 .set Pikachu_CSSID,0x13 .set Jigglypuff_CSSID,0x14 .set Mewtwo_CSSID,0x15 .set GaW_CSSID,0x16 .set Marth_CSSID,0x17 .set Roy_CSSID,0x18 */ #Character CSS Bitflag IDs #(used for TM's lookup tables for displaying CSS icons) .set Doc_CSSID,0x1 .set Mario_CSSID,0x2 .set Luigi_CSSID,0x4 .set Bowser_CSSID,0x8 .set Peach_CSSID,0x10 .set Yoshi_CSSID,0x20 .set DK_CSSID,0x40 .set CaptainFalcon_CSSID,0x80 .set Ganondorf_CSSID,0x100 .set Falco_CSSID,0x200 .set Fox_CSSID,0x400 .set Ness_CSSID,0x800 .set IceClimbers_CSSID,0x1000 .set Kirby_CSSID,0x2000 .set Samus_CSSID,0x4000 .set Zelda_CSSID,0x8000 .set Link_CSSID,0x10000 .set YLink_CSSID,0x20000 .set Pichu_CSSID,0x40000 .set Pikachu_CSSID,0x80000 .set Jigglypuff_CSSID,0x100000 .set Mewtwo_CSSID,0x200000 .set GaW_CSSID,0x400000 .set Marth_CSSID,0x800000 .set Roy_CSSID,0x1000000 #Stage External IDs .set FoD,0x2 .set PokemonStadium,0x3 .set PeachsCastle,0x4 .set KongoJungle,0x5 .set Brinstar,0x6 .set Corneria,0x7 .set YoshiStory,0x8 .set Onett,0x9 .set MuteCity,0xA .set RainbowCruise,0xB .set JungleJapes,0xC .set GreatBay,0xD .set HyruleTemple,0xE .set BrinstarDepths,0xF .set YoshiIsland,0x10 .set GreenGreens,0x11 .set Fourside,0x12 .set MushroomKingdomI,0x13 .set MushroomKingdomII,0x14 .set Akaneia,0x15 .set Venom,0x16 .set PokeFloats,0x17 .set BigBlue,0x18 .set IcicleMountain,0x19 .set IceTop,0x1A .set FlatZone,0x1B .set DreamLand,0x1C .set YoshiIsland64,0x1D .set KongoJungle64,0x1E .set Battlefield,0x1F .set FinalDestination,0x20 #Button Definitions .set PAD_BUTTON_LEFT,0x40000 .set PAD_BUTTON_RIGHT,0x80000 .set PAD_BUTTON_DOWN,0x20000 .set PAD_BUTTON_UP,0x10000 .set PAD_BUTTON_DPAD_LEFT,0x0001 .set PAD_BUTTON_DPAD_RIGHT,0x0002 .set PAD_BUTTON_DPAD_DOWN,0x0004 .set PAD_BUTTON_DPAD_UP,0x0008 .set PAD_TRIGGER_Z,0x0010 .set PAD_TRIGGER_R,0x0020 .set PAD_TRIGGER_L,0x0040 .set PAD_BUTTON_A,0x0100 .set PAD_BUTTON_B,0x0200 .set PAD_BUTTON_X,0x0400 .set PAD_BUTTON_Y,0x0800 .set PAD_BUTTON_START,0x1000 #SFX Definitions .set SFX_cs_cancel,0xac .set SFX_cs_decide,0xad .set SFX_cs_mv,0xae .set SFX_cs_beep1,0xaf ######################### ## Playerblock Offsets ## ######################### #Misc .set ControllerPort,0x618 .set CostumeID,0x619 #Input Data .set HeldButtons,0x65C .set InstantButtons,0x668 .set AnalogX,0x620 .set AnalogY,0x624 #Animation Data .set CurrentFrame,0x894 #CPU AI Data .set CPU_HeldButtons,0x1A88 .set CPU_AnalogX,0x1A8C .set CPU_AnalogY,0x1A8D .set CPU_CStickX,0x1A8E .set CPU_CStickY,0x1A8F .set CPU_LAnalog,0x1A90 .set CPU_RAnalog,0x1A91 ############################# ## Player Action State IDs ## ############################# .set ASID_DeadDown, 0x00 .set ASID_DeadLeft, 0x01 .set ASID_DeadRight, 0x02 .set ASID_DeadUp, 0x03 .set ASID_DeadUpStar, 0x04 .set ASID_DeadUpStarIce, 0x05 .set ASID_DeadUpFall, 0x06 .set ASID_DeadUpFallHitCamera, 0x07 .set ASID_DeadUpFallHitCameraFlat, 0x08 .set ASID_DeadUpFallIce, 0x09 .set ASID_DeadUpFallHitCameraIce, 0x0A .set ASID_Sleep, 0x0B .set ASID_Rebirth, 0x0C .set ASID_RebirthWait, 0x0D .set ASID_Wait, 0x0E .set ASID_WalkSlow, 0x0F .set ASID_WalkMiddle, 0x10 .set ASID_WalkFast, 0x11 .set ASID_Turn, 0x12 .set ASID_TurnRun, 0x13 .set ASID_Dash, 0x14 .set ASID_Run, 0x15 .set ASID_RunDirect, 0x16 .set ASID_RunBrake, 0x17 .set ASID_KneeBend, 0x18 .set ASID_JumpF, 0x19 .set ASID_JumpB, 0x1A .set ASID_JumpAerialF, 0x1B .set ASID_JumpAerialB, 0x1C .set ASID_Fall, 0x1D .set ASID_FallF, 0x1E .set ASID_FallB, 0x1F .set ASID_FallAerial, 0x20 .set ASID_FallAerialF, 0x21 .set ASID_FallAerialB, 0x22 .set ASID_FallSpecial, 0x23 .set ASID_FallSpecialF, 0x24 .set ASID_FallSpecialB, 0x25 .set ASID_DamageFall, 0x26 .set ASID_Squat, 0x27 .set ASID_SquatWait, 0x28 .set ASID_SquatRv, 0x29 .set ASID_Landing, 0x2A .set ASID_LandingFallSpecial, 0x2B .set ASID_Attack11, 0x2C .set ASID_Attack12, 0x2D .set ASID_Attack13, 0x2E .set ASID_Attack100Start, 0x2F .set ASID_Attack100Loop, 0x30 .set ASID_Attack100End, 0x31 .set ASID_AttackDash, 0x32 .set ASID_AttackS3Hi, 0x33 .set ASID_AttackS3HiS, 0x34 .set ASID_AttackS3S, 0x35 .set ASID_AttackS3LwS, 0x36 .set ASID_AttackS3Lw, 0x37 .set ASID_AttackHi3, 0x38 .set ASID_AttackLw3, 0x39 .set ASID_AttackS4Hi, 0x3A .set ASID_AttackS4HiS, 0x3B .set ASID_AttackS4S, 0x3C .set ASID_AttackS4LwS, 0x3D .set ASID_AttackS4Lw, 0x3E .set ASID_AttackHi4, 0x3F .set ASID_AttackLw4, 0x40 .set ASID_AttackAirN, 0x41 .set ASID_AttackAirF, 0x42 .set ASID_AttackAirB, 0x43 .set ASID_AttackAirHi, 0x44 .set ASID_AttackAirLw, 0x45 .set ASID_LandingAirN, 0x46 .set ASID_LandingAirF, 0x47 .set ASID_LandingAirB, 0x48 .set ASID_LandingAirHi, 0x49 .set ASID_LandingAirLw, 0x4A .set ASID_DamageHi1, 0x4B .set ASID_DamageHi2, 0x4C .set ASID_DamageHi3, 0x4D .set ASID_DamageN1, 0x4E .set ASID_DamageN2, 0x4F .set ASID_DamageN3, 0x50 .set ASID_DamageLw1, 0x51 .set ASID_DamageLw2, 0x52 .set ASID_DamageLw3, 0x53 .set ASID_DamageAir1, 0x54 .set ASID_DamageAir2, 0x55 .set ASID_DamageAir3, 0x56 .set ASID_DamageFlyHi, 0x57 .set ASID_DamageFlyN, 0x58 .set ASID_DamageFlyLw, 0x59 .set ASID_DamageFlyTop, 0x5A .set ASID_DamageFlyRoll, 0x5B .set ASID_LightGet, 0x5C .set ASID_HeavyGet, 0x5D .set ASID_LightThrowF, 0x5E .set ASID_LightThrowB, 0x5F .set ASID_LightThrowHi, 0x60 .set ASID_LightThrowLw, 0x61 .set ASID_LightThrowDash, 0x62 .set ASID_LightThrowDrop, 0x63 .set ASID_LightThrowAirF, 0x64 .set ASID_LightThrowAirB, 0x65 .set ASID_LightThrowAirHi, 0x66 .set ASID_LightThrowAirLw, 0x67 .set ASID_HeavyThrowF, 0x68 .set ASID_HeavyThrowB, 0x69 .set ASID_HeavyThrowHi, 0x6A .set ASID_HeavyThrowLw, 0x6B .set ASID_LightThrowF4, 0x6C .set ASID_LightThrowB4, 0x6D .set ASID_LightThrowHi4, 0x6E .set ASID_LightThrowLw4, 0x6F .set ASID_LightThrowAirF4, 0x70 .set ASID_LightThrowAirB4, 0x71 .set ASID_LightThrowAirHi4, 0x72 .set ASID_LightThrowAirLw4, 0x73 .set ASID_HeavyThrowF4, 0x74 .set ASID_HeavyThrowB4, 0x75 .set ASID_HeavyThrowHi4, 0x76 .set ASID_HeavyThrowLw4, 0x77 .set ASID_SwordSwing1, 0x78 .set ASID_SwordSwing3, 0x79 .set ASID_SwordSwing4, 0x7A .set ASID_SwordSwingDash, 0x7B .set ASID_BatSwing1, 0x7C .set ASID_BatSwing3, 0x7D .set ASID_BatSwing4, 0x7E .set ASID_BatSwingDash, 0x7F .set ASID_ParasolSwing1, 0x80 .set ASID_ParasolSwing3, 0x81 .set ASID_ParasolSwing4, 0x82 .set ASID_ParasolSwingDash, 0x83 .set ASID_HarisenSwing1, 0x84 .set ASID_HarisenSwing3, 0x85 .set ASID_HarisenSwing4, 0x86 .set ASID_HarisenSwingDash, 0x87 .set ASID_StarRodSwing1, 0x88 .set ASID_StarRodSwing3, 0x89 .set ASID_StarRodSwing4, 0x8A .set ASID_StarRodSwingDash, 0x8B .set ASID_LipStickSwing1, 0x8C .set ASID_LipStickSwing3, 0x8D .set ASID_LipStickSwing4, 0x8E .set ASID_LipStickSwingDash, 0x8F .set ASID_ItemParasolOpen, 0x90 .set ASID_ItemParasolFall, 0x91 .set ASID_ItemParasolFallSpecial, 0x92 .set ASID_ItemParasolDamageFall, 0x93 .set ASID_LGunShoot, 0x94 .set ASID_LGunShootAir, 0x95 .set ASID_LGunShootEmpty, 0x96 .set ASID_LGunShootAirEmpty, 0x97 .set ASID_FireFlowerShoot, 0x98 .set ASID_FireFlowerShootAir, 0x99 .set ASID_ItemScrew, 0x9A .set ASID_ItemScrewAir, 0x9B .set ASID_DamageScrew, 0x9C .set ASID_DamageScrewAir, 0x9D .set ASID_ItemScopeStart, 0x9E .set ASID_ItemScopeRapid, 0x9F .set ASID_ItemScopeFire, 0xA0 .set ASID_ItemScopeEnd, 0xA1 .set ASID_ItemScopeAirStart, 0xA2 .set ASID_ItemScopeAirRapid, 0xA3 .set ASID_ItemScopeAirFire, 0xA4 .set ASID_ItemScopeAirEnd, 0xA5 .set ASID_ItemScopeStartEmpty, 0xA6 .set ASID_ItemScopeRapidEmpty, 0xA7 .set ASID_ItemScopeFireEmpty, 0xA8 .set ASID_ItemScopeEndEmpty, 0xA9 .set ASID_ItemScopeAirStartEmpty, 0xAA .set ASID_ItemScopeAirRapidEmpty, 0xAB .set ASID_ItemScopeAirFireEmpty, 0xAC .set ASID_ItemScopeAirEndEmpty, 0xAD .set ASID_LiftWait, 0xAE .set ASID_LiftWalk1, 0xAF .set ASID_LiftWalk2, 0xB0 .set ASID_LiftTurn, 0xB1 .set ASID_GuardOn, 0xB2 .set ASID_Guard, 0xB3 .set ASID_GuardOff, 0xB4 .set ASID_GuardSetOff, 0xB5 .set ASID_GuardReflect, 0xB6 .set ASID_DownBoundU, 0xB7 .set ASID_DownWaitU, 0xB8 .set ASID_DownDamageU, 0xB9 .set ASID_DownStandU, 0xBA .set ASID_DownAttackU, 0xBB .set ASID_DownFowardU, 0xBC .set ASID_DownBackU, 0xBD .set ASID_DownSpotU, 0xBE .set ASID_DownBoundD, 0xBF .set ASID_DownWaitD, 0xC0 .set ASID_DownDamageD, 0xC1 .set ASID_DownStandD, 0xC2 .set ASID_DownAttackD, 0xC3 .set ASID_DownFowardD, 0xC4 .set ASID_DownBackD, 0xC5 .set ASID_DownSpotD, 0xC6 .set ASID_Passive, 0xC7 .set ASID_PassiveStandF, 0xC8 .set ASID_PassiveStandB, 0xC9 .set ASID_PassiveWall, 0xCA .set ASID_PassiveWallJump, 0xCB .set ASID_PassiveCeil, 0xCC .set ASID_ShieldBreakFly, 0xCD .set ASID_ShieldBreakFall, 0xCE .set ASID_ShieldBreakDownU, 0xCF .set ASID_ShieldBreakDownD, 0xD0 .set ASID_ShieldBreakStandU, 0xD1 .set ASID_ShieldBreakStandD, 0xD2 .set ASID_FuraFura, 0xD3 .set ASID_Catch, 0xD4 .set ASID_CatchPull, 0xD5 .set ASID_CatchDash, 0xD6 .set ASID_CatchDashPull, 0xD7 .set ASID_CatchWait, 0xD8 .set ASID_CatchAttack, 0xD9 .set ASID_CatchCut, 0xDA .set ASID_ThrowF, 0xDB .set ASID_ThrowB, 0xDC .set ASID_ThrowHi, 0xDD .set ASID_ThrowLw, 0xDE .set ASID_CapturePulledHi, 0xDF .set ASID_CaptureWaitHi, 0xE0 .set ASID_CaptureDamageHi, 0xE1 .set ASID_CapturePulledLw, 0xE2 .set ASID_CaptureWaitLw, 0xE3 .set ASID_CaptureDamageLw, 0xE4 .set ASID_CaptureCut, 0xE5 .set ASID_CaptureJump, 0xE6 .set ASID_CaptureNeck, 0xE7 .set ASID_CaptureFoot, 0xE8 .set ASID_EscapeF, 0xE9 .set ASID_EscapeB, 0xEA .set ASID_Escape, 0xEB .set ASID_EscapeAir, 0xEC .set ASID_ReboundStop, 0xED .set ASID_Rebound, 0xEE .set ASID_ThrownF, 0xEF .set ASID_ThrownB, 0xF0 .set ASID_ThrownHi, 0xF1 .set ASID_ThrownLw, 0xF2 .set ASID_ThrownLwWomen, 0xF3 .set ASID_Pass, 0xF4 .set ASID_Ottotto, 0xF5 .set ASID_OttottoWait, 0xF6 .set ASID_FlyReflectWall, 0xF7 .set ASID_FlyReflectCeil, 0xF8 .set ASID_StopWall, 0xF9 .set ASID_StopCeil, 0xFA .set ASID_MissFoot, 0xFB .set ASID_CliffCatch, 0xFC .set ASID_CliffWait, 0xFD .set ASID_CliffClimbSlow, 0xFE .set ASID_CliffClimbQuick, 0xFF .set ASID_CliffAttackSlow, 0x100 .set ASID_CliffAttackQuick, 0x101 .set ASID_CliffEscapeSlow, 0x102 .set ASID_CliffEscapeQuick, 0x103 .set ASID_CliffJumpSlow1, 0x104 .set ASID_CliffJumpSlow2, 0x105 .set ASID_CliffJumpQuick1, 0x106 .set ASID_CliffJumpQuick2, 0x107 .set ASID_AppealR, 0x108 .set ASID_AppealL, 0x109 .set ASID_ShoulderedWait, 0x10A .set ASID_ShoulderedWalkSlow, 0x10B .set ASID_ShoulderedWalkMiddle, 0x10C .set ASID_ShoulderedWalkFast, 0x10D .set ASID_ShoulderedTurn, 0x10E .set ASID_ThrownFF, 0x10F .set ASID_ThrownFB, 0x110 .set ASID_ThrownFHi, 0x111 .set ASID_ThrownFLw, 0x112 .set ASID_CaptureCaptain, 0x113 .set ASID_CaptureYoshi, 0x114 .set ASID_YoshiEgg, 0x115 .set ASID_CaptureKoopa, 0x116 .set ASID_CaptureDamageKoopa, 0x117 .set ASID_CaptureWaitKoopa, 0x118 .set ASID_ThrownKoopaF, 0x119 .set ASID_ThrownKoopaB, 0x11A .set ASID_CaptureKoopaAir, 0x11B .set ASID_CaptureDamageKoopaAir, 0x11C .set ASID_CaptureWaitKoopaAir, 0x11D .set ASID_ThrownKoopaAirF, 0x11E .set ASID_ThrownKoopaAirB, 0x11F .set ASID_CaptureKirby, 0x120 .set ASID_CaptureWaitKirby, 0x121 .set ASID_ThrownKirbyStar, 0x122 .set ASID_ThrownCopyStar, 0x123 .set ASID_ThrownKirby, 0x124 .set ASID_BarrelWait, 0x125 .set ASID_Bury, 0x126 .set ASID_BuryWait, 0x127 .set ASID_BuryJump, 0x128 .set ASID_DamageSong, 0x129 .set ASID_DamageSongWait, 0x12A .set ASID_DamageSongRv, 0x12B .set ASID_DamageBind, 0x12C .set ASID_CaptureMewtwo, 0x12D .set ASID_CaptureMewtwoAir, 0x12E .set ASID_ThrownMewtwo, 0x12F .set ASID_ThrownMewtwoAir, 0x130 .set ASID_WarpStarJump, 0x131 .set ASID_WarpStarFall, 0x132 .set ASID_HammerWait, 0x133 .set ASID_HammerWalk, 0x134 .set ASID_HammerTurn, 0x135 .set ASID_HammerKneeBend, 0x136 .set ASID_HammerFall, 0x137 .set ASID_HammerJump, 0x138 .set ASID_HammerLanding, 0x139 .set ASID_KinokoGiantStart, 0x13A .set ASID_KinokoGiantStartAir, 0x13B .set ASID_KinokoGiantEnd, 0x13C .set ASID_KinokoGiantEndAir, 0x13D .set ASID_KinokoSmallStart, 0x13E .set ASID_KinokoSmallStartAir, 0x13F .set ASID_KinokoSmallEnd, 0x140 .set ASID_KinokoSmallEndAir, 0x141 .set ASID_Entry, 0x142 .set ASID_EntryStart, 0x143 .set ASID_EntryEnd, 0x144 .set ASID_DamageIce, 0x145 .set ASID_DamageIceJump, 0x146 .set ASID_CaptureMasterhand, 0x147 .set ASID_CapturedamageMasterhand, 0x148 .set ASID_CapturewaitMasterhand, 0x149 .set ASID_ThrownMasterhand, 0x14A .set ASID_CaptureKirbyYoshi, 0x14B .set ASID_KirbyYoshiEgg, 0x14C .set ASID_CaptureLeadead, 0x14D .set ASID_CaptureLikelike, 0x14E .set ASID_DownReflect, 0x14F .set ASID_CaptureCrazyhand, 0x150 .set ASID_CapturedamageCrazyhand, 0x151 .set ASID_CapturewaitCrazyhand, 0x152 .set ASID_ThrownCrazyhand, 0x153 .set ASID_BarrelCannonWait, 0x154 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm /* .macro branchl reg, address .long \address ^ 0x80<<24 | 0xC8<<24 .endm */ .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro backupall mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r3,0x8(r1) .endm .macro restoreall lmw r3,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm ================================================ FILE: ASM/m-ex/Custom Playerdata Variables/Adjust Size.asm ================================================ #To be inserted @ 800679bc .include "../../Globals.s" .include "../Header.s" li r4, FighterDataTotalSize ================================================ FILE: ASM/m-ex/Custom Playerdata Variables/Initialize Extended Playerblock Values (Result Screen).asm ================================================ #To be inserted at 800BE830 .include "../../Globals.s" .include "../Header.s" #Backup Data Pointer After Creation addi r30, r3, 0 #Get Player Data Length load r4,0x80458fd0 lwz r4,0x20(r4) #Zero Entire Data Block branchl r12,0x8000c160 exit: mr r3,r30 lis r4, 0x8046 ================================================ FILE: ASM/m-ex/Custom Playerdata Variables/Initialize Extended Playerblock Values.asm ================================================ #To be inserted at 80068eec .include "../../Globals.s" .include "../Header.s" #Backup Data Pointer After Creation addi r30, r3, 0 #Get Player Data Length load r4,0x80458fd0 lwz r4,0x20(r4) #Zero Entire Data Block branchl r12,0x8000c160 exit: mr r3,r30 lis r4, 0x8046 ================================================ FILE: ASM/m-ex/Custom Playerdata Variables/OwnsAnim/Check Animation Owner.s ================================================ #To be inserted @ 8006fe20 .include "../../../Globals.s" .include "../../Header.s" .set REG_PlayerData,3 #Check if anim is coming from opponent lwz r0,MEX_AnimOwner(REG_PlayerData) cmpwi r0,0 ================================================ FILE: ASM/m-ex/Custom Playerdata Variables/OwnsAnim/Store Animation Owner.s ================================================ #To be inserted @ 80069ce0 .include "../../../Globals.s" .include "../../Header.s" .set REG_OpponentGObj,23 .set REG_PlayerData,26 #Check if anim is coming from opponent cmpwi REG_OpponentGObj,0 beq OwnsAnim NoOwnsAnim: li r3,1 stw r3,MEX_AnimOwner(REG_PlayerData) b Exit OwnsAnim: li r3,0 stw r3,MEX_AnimOwner(REG_PlayerData) Exit: cmplwi r23, 0 ================================================ FILE: ASM/m-ex/Header.s ================================================ #Constants .set PersonalEffectStart,5000 # used for stage effects, need to rework this? .set EffMdlStart,5000 .set PtclGenStart,6000 .set CpEffMdlStart,7000 .set CpPtclGenStart,8000 .set MEXEffectEnd,9000 .set CustomItemStart,237 .set RandomIconID,30 .set HUD_Stride,3 #im changing this from 3 because 2 seems to work with hsdraw .set OFST_mexMapData,--0x4A08 .set OFST_mexSelectChr,-0x4A0C #Derived Constants .set SSM_MaxID,100 * 10000 #Custom Functions .set Audio_RequestSSMLoad,0x803d705C .set GetGrFunction,0x803d7068 .set itFunctionInit,0x803d7070 .set Reloc,0x803d7074 .set SFX_PlayStageSFX,0x803d7078 .set GetStockFrame,0x803d7060 .set MenuThink,0x803d7090 #Custom Static Variables .set PersistHeapNum, 5 + 2 #mexSelectChr Offsets .set OFST_mexSelectChr,-0x472C .set OFST_mexSelectChr_IconJoint,-0x4728 #originally SceneLoad_Adventure mode static pointers (8031dea0) .set OFST_stc_icons,-0x4724 # TODO: THIS WILL BREAK STUFF, FIND A BETTER SPOT .set OFST_eblm_matanimjoint,-0x4720 # TODO: THIS WILL BREAK STUFF, FIND A BETTER SPOT .set OFST_mexMenu,-0x4720 .set SlChr_IconModel,0x0 .set SlChr_IconAnimJoint,0x4 .set SlChr_IconMatAnim,0x8 .set SlChr_CSPMatAnim,0xC .set SlChr_CSPStride,0x10 #mexMenu Offsets .set mexMenu_MenuNameFrames,0x0 .set mexMenu_MenuDef,0x4 .set MenuDefStride,0x14 .set MenuDef_PreviewFrames, 0x0 .set MenuDef_Unused, 0x4 .set MenuDef_OptDef, 0x8 .set OptDefStride,8 .set OptDef_Kind, 0x0 # byte .set OptDef_ID, 0x1 # byte .set OptDef_Text,0x2 # byte .set OptDef_NameFrame,0x3 # byte .set OptDef_PreviewFrame,0x4 # byte .set MenuDef_OptNum, 0xC # byte .set MenuDef_PrevMenu, 0xD # byte .set MenuDef_NameFrame, 0xE # byte .set MenuDef_HueIndex, 0xF # byte .set MenuDef_Callback, 0x10 .set mexMenu_DescSis,0x8 .set OptDef_TextSisID, 1 .set mexMenu_MnOptMatAnimJoint,0xC .set mexMenu_MnNameMatAnimJoint,0x10 #Stc_icon Offsets .set StcIcons_ReservedFrames,0x0 .set StcIcons_Stride,0x2 .set StcIcons_MatAnimJoint,0x4 .set StcIcons_EggNum,0x8 .set StcIcons_Eggs,0xC #Eggs .set Eggs_Stride, 0x8 .set Eggs_StockID,0x0 .set Eggs_Input,0x1 .set Eggs_Name,0x4 #BGM in IfAll .set BGMBG_Joint,0x0 .set BMGBG_AnimJoint,0x4 #effBehaviorTable .set effBhv_ptclGenNum,0x8 .set effBhv_ptclGenBhv,0xC .set effMdlBhv_Stride,0x1 .set effBhv_effMdlNum,0x0 .set effBhv_effMdlBhv,0x4 .set effMdlBhv_Stride,0x1 #Scene Data .set MajorStride,0x18 .set MinorTypeStride,0x14 #Archive Offsets .set Arch_Metadata,0x0 .set Arch_Metadata_VersionMajor,0x0 .set Arch_Metadata_VersionMinor,0x1 .set Arch_Metadata_FtIntNum,0x4 .set Arch_Metadata_FtExtNum,0x8 .set Arch_Metadata_CSSIconCount,0xC .set Arch_Metadata_GrIntNum,0x10 .set Arch_Metadata_GrExtNum,0x14 .set Arch_Metadata_SSSIconCount,0x18 .set Arch_Metadata_SSMCount,0x1C .set Arch_Metadata_BGMCount,0x20 .set Arch_Metadata_EffectCount,0x24 .set Arch_Metadata_BootScene,0x28 .set Arch_Metadata_TermMajor,0x2C .set Arch_Metadata_TermMinor,0x30 .set Arch_Menu,0x4 .set Arch_Menu_MenuParam,0x0 .set MenuParam_HandScale,0x0 .set Arch_Menu_CSS,0x4 .set Arch_Menu_SSS,0x8 .set SSS_Stride,0x20 .set Arch_Fighter,0x8 .set Arch_Fighter_NameText,0x0 .set Arch_Fighter_CharFiles,0x4 .set Arch_Fighter_InsigniaIDs,0x8 .set Arch_Fighter_DefineIDs,0xC .set Arch_Fighter_CostumeIDs,0x10 .set Arch_Fighter_CostumeFileSymbols,0x14 .set Arch_Fighter_FtDemo_SymbolNames,0x18 .set Arch_Fighter_AnimFiles,0x1C .set Arch_Fighter_AnimCounts,0x20 .set Arch_Fighter_EffectFileIDs,0x24 .set Arch_Fighter_GmRst_AnimFiles,0x28 .set Arch_Fighter_GmRst_Scale,0x2C .set Arch_Fighter_GmRst_VictoryTheme,0x30 .set Arch_Fighter_AnnouncerCall,0x34 .set Arch_Fighter_SSMFileIDs,0x38 .set Arch_Fighter_RuntimeCostumePointers,0x3C .set Arch_Fighter_ftDataPointers,0x40 .set ftDataPointers_Stride,8 .set Arch_Fighter_onWallJump,0x44 .set Arch_Fighter_GmRstPointers,0x48 .set GmRstPointers_Stride,8 .set Arch_Fighter_MEXItemLookup,0x4C .set MEXItemLookup_Stride,8 .set Arch_Fighter_TargetStage, 0x50 .set Arch_Fighter_BGM, 0x54 .set BGM_Stride, 0x4 .set Arch_Fighter_ViWaitFileNames, 0x58 .set Arch_Fighter_EndClassic, 0x5C .set Arch_Fighter_EndAdventure, 0x60 .set Arch_Fighter_EndAllStar, 0x64 .set Arch_Fighter_EndMovie, 0x68 .set Arch_Fighter_RaceTimes, 0x6C .set RaceTimes_Stride,0x4 .set Arch_FighterFunc,0xC .set Arch_FighterFunc_onLoad,0x0 .set Arch_FighterFunc_onDeath,0x4 .set Arch_FighterFunc_onUnknown,0x8 .set Arch_FighterFunc_MoveLogic,0xC .set Arch_FighterFunc_SpecialN,0x10 .set Arch_FighterFunc_SpecialNAir,0x14 .set Arch_FighterFunc_SpecialS,0x18 .set Arch_FighterFunc_SpecialSAir,0x1C .set Arch_FighterFunc_SpecialHi,0x20 .set Arch_FighterFunc_SpecialHiAir,0x24 .set Arch_FighterFunc_SpecialLw,0x28 .set Arch_FighterFunc_SpecialLwAir,0x2C .set Arch_FighterFunc_onAbsorb,0x30 .set Arch_FighterFunc_OnItemPickup,0x34 .set Arch_FighterFunc_onMakeItemInvisible,0x38 .set Arch_FighterFunc_onMakeItemVisible,0x3C .set Arch_FighterFunc_OnItemRelease,0x40 .set Arch_FighterFunc_OnItemPickup2,0x44 .set Arch_FighterFunc_onUnknownItemRelated,0x48 .set Arch_FighterFunc_onUnknownCharacterModelFlags1,0x4C .set Arch_FighterFunc_onUnknownCharacterModelFlags2,0x50 .set Arch_FighterFunc_onKnockbackEnter,0x54 .set Arch_FighterFunc_onKnockbackExit,0x58 .set Arch_FighterFunc_onFrame,0x5C .set Arch_FighterFunc_onActionStateChange,0x60 .set Arch_FighterFunc_onReapplyAttr,0x64 .set Arch_FighterFunc_onModelRender,0x68 .set Arch_FighterFunc_onShadowRender,0x6C .set Arch_FighterFunc_onUnknownMultijump,0x70 .set Arch_FighterFunc_onActionStateChangeWhileEyeTextureIsChanged,0x74 .set Arch_FighterFunc_onTwoEntryTable,0x78 .set Arch_FighterFunc_onFloat,0x7C .set Arch_FighterFunc_onDoubleJump,0x80 .set Arch_FighterFunc_onZair,0x84 .set Arch_FighterFunc_onLanding,0x88 .set Arch_FighterFunc_onFSmash,0x8C .set Arch_FighterFunc_onUSmash,0x90 .set Arch_FighterFunc_onDSmash,0x94 .set Arch_FighterFunc_onGetExtResultAnim,0x98 .set Arch_FighterFunc_onIndexExtResultAnim,0x9C .set Arch_FighterFunc_MoveLogicDemo,0xA0 .set Arch_FGM,0x10 .set Arch_FGM_Files,0x0 .set Arch_FGM_Flags,0x4 .set Arch_FGM_LookupTable,0x8 .set Arch_FGM_RuntimeStruct,0xC .set Arch_SSMRuntimeStruct_Header,0x0 .set Arch_SSMRuntimeStruct_ToLoadOrig,0x4 .set Arch_SSMRuntimeStruct_ToLoadCopy,0x8 .set Arch_SSMRuntimeStruct_IsLoadedOrig,0xC .set Arch_SSMRuntimeStruct_IsLoadedCopy,0x10 .set Arch_SSMRuntimeStruct_Footer,0x14 .set Arch_BGM,0x14 .set Arch_BGM_Files,0x0 .set Arch_BGM_MenuPlaylist,0x4 .set Arch_BGM_MenuPlaylistNum,0x8 .set Arch_BGM_Labels,0xC .set Arch_Effect,0x18 .set Effect_Files,0x0 .set Effect_RuntimeUnk1,0x4 .set Effect_RuntimeUnk3,0x8 .set Effect_RuntimeTexGrNum,0xC .set Effect_RuntimeTexGrData,0x10 .set Effect_RuntimeUnk4,0x14 .set Effect_RuntimePtclLast,0x18 .set Effect_RuntimePtclData,0x1C .set Effect_effBehaviorTable,0x20 #indexed by fighter ID, points to their effBehaviorTable symbol .set Arch_ItemsAdded,0x1C .set Arch_ItemsAdded_Common,0x0 .set Arch_ItemsAdded_Fighter,0x4 .set Arch_ItemsAdded_Pokemon,0x8 .set Arch_ItemsAdded_Stages,0xC .set Arch_ItemsAdded_Custom,0x10 #.set Arch_ItemsAdded_Unk,0x14 .set Arch_ItemsAdded_RuntimeIndex,0x14 .set Arch_Kirby,0x20 .set Arch_Kirby_AbilityFileNames,0x0 .set Arch_Kirby_AbilityRuntimeStruct,0x4 .set Arch_Kirby_AbilityCostumeFileNames,0x8 .set Arch_Kirby_AbilityCostumeRuntimeStruct,0xC .set Arch_Kirby_EffectIDs,0x10 .set Arch_Kirby_FtCmdRuntime,0x14 .set Arch_KirbyFunction,0x24 .set Arch_KirbyFunction_OnAbilityGain,0x0 .set Arch_KirbyFunction_OnAbilityLose,0x4 .set Arch_Kirby_SpecialN,0x8 .set Arch_Kirby_SpecialNAir,0xC .set Arch_Kirby_OnHit,0x10 .set Arch_Kirby_InitItem,0x14 .set Arch_Kirby_MoveLogicRuntime,0x18 .set Arch_Map,0x28 .set Arch_Map_StageIDs,0x0 .set Arch_Map_Audio,0x4 .set Arch_Map_LineTypeData,0x8 .set Arch_Map_StageItemLookup,0xC .set StageItemLookup_Stride,0x8 .set Arch_Map_StageEffectLookup,0x10 .set Arch_Map_Playlists,0x14 .set Playlists_Stride,0x8 .set Arch_grFunction,0x2C .set Arch_Scene,0x30 .set Scene_Major,0x0 .set Scene_Minor,0x4 #Offsets .set OFST_MnSlChrIconData,0x0 .set OFST_MnSlChrNames,0x4 .set OFST_MnSlChrDefineIDs,0x8 .set OFST_MnSlChrCostumeFileSymbols,0xC .set OFST_MnSlChrCharFileNames,0x10 .set OFST_MnSlChrAnimFileNames,0x14 .set OFST_MnSlChrEffectFileIDs,0x18 .set OFST_MnSlChrEffectFilesSymbols,0x1C .set OFST_MnSlChrSSMFileIDs,0x20 .set OFST_MnSlChrSSMFileNames,0x24 .set OFST_MnSlChrAnimCount,0x28 .set OFST_FighterMoveLogic,0x2C .set OFST_FighterOnLoad,0x30 .set OFST_FighterOnDeath,0x34 .set OFST_FighterSpecialLw,0x38 .set OFST_FighterSpecialLwAir,0x3C .set OFST_FighterSpecialS,0x40 .set OFST_FighterSpecialSAir,0x44 .set OFST_FighterSpecialN,0x48 .set OFST_FighterSpecialNAir,0x4C .set OFST_FighterSpecialHi,0x50 .set OFST_FighterSpecialHiAir,0x54 .set OFST_MnSlChrCostumeIDs,0x58 .set OFST_Char_CostumeRuntimePointers,0x5C .set OFST_SSMStruct,0x60 .set OFST_SSMIDDef,0x64 .set OFST_SSMBankSizes,0x68 .set OFST_GmRstAnimFileNames,0x6C .set OFST_GmRstInsigniaIDs,0x70 .set OFST_GmRstScale,0x74 .set OFST_FtDemoSymbols,0x78 .set OFST_SFXNameDef,0x7C .set OFST_GmRstVictoryTheme,0x80 .set OFST_effBehaviorTable,0x84 .set OFST_ItemsAdded,0x88 .set OFST_ItemIndex,0x8C #unused .set OFST_AudioGroups,0x90 .set OFST_BGMFileNames,0x94 .set OFST_ftDataPointers,0x98 .set OFST_onFloat,0x9C .set OFST_onDoubleJump,0xA0 .set OFST_onZair,0xA4 .set OFST_onLanding,0xA8 .set OFST_onWallJump,0xAC .set OFST_GmRstPointers,0xB0 .set OFST_onFSmash,0xB4 .set OFST_onUSmash,0xB8 .set OFST_onDSmash,0xBC .set OFST_FighterOnItemPickup,0xC0 .set OFST_FighterOnItemPickup2,0xC4 .set OFST_FighterOnItemRelease,0xC8 .set OFST_FighterBGM, OFST_FighterOnItemRelease + 0x4 .set OFST_FighterViWaitFileNames, OFST_FighterBGM + 0x4 .set OFST_MajorScenes, OFST_FighterViWaitFileNames + 0x4 .set OFST_MinorScenes, OFST_MajorScenes + 0x4 .set OFST_PtclRuntime1, OFST_MinorScenes + 0x4 .set OFST_PtclRuntime3, OFST_PtclRuntime1 + 0x4 .set OFST_PtclRuntimeTexGrNum, OFST_PtclRuntime3 + 0x4 .set OFST_PtclRuntimeTexGrData, OFST_PtclRuntimeTexGrNum + 0x4 .set OFST_PtclRuntime4, OFST_PtclRuntimeTexGrData + 0x4 .set OFST_PtclRuntimePtclLast, OFST_PtclRuntime4 + 0x4 .set OFST_PtclRuntimePtclData, OFST_PtclRuntimePtclLast + 0x4 #Chr .set OFST_Menu_Param,OFST_PtclRuntimePtclData+0x4 #Map .set OFST_Menu_SSS,OFST_Menu_Param+0x4 .set OFST_Map_StageIDs,OFST_Menu_SSS+0x4 .set OFST_Map_Audio,OFST_Map_StageIDs+0x4 .set OFST_grFunction,OFST_Map_Audio+0x4 .set OFST_LineTypeData,OFST_grFunction+0x4 #Kirby .set OFST_KirbyHatFileNames,OFST_LineTypeData+0x4 .set OFST_KirbyHatCostumeFileNames,OFST_KirbyHatFileNames+0x4 .set OFST_KirbyHatEffectFileIDs,OFST_KirbyHatCostumeFileNames+0x4 .set OFST_KirbyAbilityCostumeRuntimeStruct,OFST_KirbyHatEffectFileIDs+0x4 .set OFST_KirbyAbilityRuntimeStruct,OFST_KirbyAbilityCostumeRuntimeStruct+0x4 .set OFST_KirbyFtCmdRuntime, OFST_KirbyAbilityRuntimeStruct + 0x4 .set OFST_KirbyOnAbilityGain,OFST_KirbyFtCmdRuntime+0x4 .set OFST_KirbyOnAbilityLose,OFST_KirbyOnAbilityGain+0x4 .set OFST_KirbySpecialN,OFST_KirbyOnAbilityLose+0x4 .set OFST_KirbySpecialNAir,OFST_KirbySpecialN+0x4 .set OFST_KirbyOnHit,OFST_KirbySpecialNAir+0x4 .set OFST_KirbyInitItem,OFST_KirbyOnHit+0x4 .set OFST_KirbyMoveLogicRuntime, OFST_KirbyInitItem + 0x4 #Metadata .set OFST_Metadata_FtIntNum,OFST_KirbyMoveLogicRuntime+0x4 .set OFST_Metadata_FtExtNum,OFST_Metadata_FtIntNum+0x4 .set OFST_Metadata_CSSIconCount,OFST_Metadata_FtExtNum+0x4 .set OFST_Metadata_SSSIconCount,OFST_Metadata_CSSIconCount+0x4 .set OFST_Metadata_SSMCount,OFST_Metadata_SSSIconCount+0x4 .set OFST_Metadata_BGMCount,OFST_Metadata_SSMCount+0x4 .set OFST_Metadata_EffectCount,OFST_Metadata_BGMCount+0x4 .set OFST_MetaData_TermMajor,OFST_Metadata_EffectCount + 0x4 .set OFST_MetaData_TermMinor,OFST_MetaData_TermMajor + 0x4 .set OFST_MetaData_GrIntNum,OFST_MetaData_TermMinor+0x4 .set OFST_MetaData_GrExtNum,OFST_MetaData_GrIntNum+0x4 .set OFST_Metadata,OFST_MetaData_GrExtNum+0x4 .set OFST_mexData,OFST_Metadata+0x4 #Gross bullshit I don't want here .set OFST_EasterEgg,OFST_mexData + 0x4 .set OFST_HeapRuntime,OFST_EasterEgg + 0x8 # Fighter Data Sizes .set FighterDataOrigSize, 0x23ec .set MEX_FighterDataSize, 0xC # mex needs additional 0x4 bytes .set TM_FighterDataSize, 0x34 # TM needs additional 0x34 bytes .set FighterDataTotalSize, FighterDataOrigSize + MEX_FighterDataSize + TM_FighterDataSize # Fighter Data Start .set FighterDataStart, 0x0 .set MEX_FighterDataStart, FighterDataStart + FighterDataOrigSize .set TM_FighterDataStart, MEX_FighterDataStart + MEX_FighterDataSize # Fighter Data Vairables #MEX .set MEX_AnimOwner,MEX_FighterDataStart + 0x0 #4 bytes .set MEX_UCFCurrX, MEX_AnimOwner + 0x4 #1 byte .set MEX_UCFPrevX, MEX_UCFCurrX + 0x1 #1 byte .set MEX_UCF2fX, MEX_UCFPrevX + 0x1 #1 byte .set MEX_align, MEX_UCF2fX + 0x1 #1 byte #TM ## Dedicated ## .set TM_FramesinCurrentAS, TM_FighterDataStart + 0x0 #half .set TM_ShieldFrames, TM_FramesinCurrentAS + 0x2 #half .set TM_PrevASSlots, 6 .set TM_PrevASStart, TM_ShieldFrames + 0x2 #halves .set CurrentAS,0x10 .set TM_OneASAgo,TM_PrevASStart+0x0 .set TM_TwoASAgo,TM_OneASAgo+0x2 .set TM_ThreeASAgo,TM_TwoASAgo+0x2 .set TM_FourASAgo,TM_ThreeASAgo+0x2 .set TM_FiveASAgo,TM_FourASAgo+0x2 .set TM_SixASAgo,TM_FiveASAgo+0x2 .set TM_FramesInPrevASStart,TM_SixASAgo + 0x2 #halves .set TM_FramesinOneASAgo,TM_FramesInPrevASStart+0x0 .set TM_FramesinTwoASAgo,TM_FramesinOneASAgo+0x2 .set TM_FramesinThreeASAgo,TM_FramesinTwoASAgo+0x2 .set TM_FramesinFourASAgo,TM_FramesinThreeASAgo+0x2 .set TM_FramesinFiveASAgo,TM_FramesinFourASAgo+0x2 .set TM_FramesinSixASAgo,TM_FramesinFiveASAgo+0x2 .set TM_PreviousMoveInstanceHitBy,TM_FramesinSixASAgo + 0x2 #half .set TM_TangibleFrameCount, TM_PreviousMoveInstanceHitBy + 0x2 #half .set TM_CanFastfallFrameCount, TM_TangibleFrameCount + 0x2 #half .set TM_align, TM_CanFastfallFrameCount + 0x2 #half .set TM_PostHitstunFrameCount, TM_align + 0x2 #word .set TM_PlayerWhoShieldedAttack, TM_PostHitstunFrameCount + 0x4 #word .set TM_AnimCallback, TM_PlayerWhoShieldedAttack + 0x4 ## Volatile ## .set TM_VolatileStart, TM_AnimCallback + 0x4 #Airdodge .set TM_AirdodgeAngle,TM_VolatileStart + 0x0 #Damage .set TM_SuccessfulSDIInputs,TM_VolatileStart + 0x0 .set TM_TotalSDIInputs,TM_SuccessfulSDIInputs + 0x2 /* #SSM Struct Offsets #Header .set SSM_Header_OFST,0x0 .set SSM_Header_Length,45*4 #Disposable Orig .set SSM_ToLoadOrig_OFST, SSM_Header_OFST + SSM_Header_Length .set SSM_ToLoadOrig_Length, (56 + NumOfAddedChars) * 4 #Disposable Copy .set SSM_ToLoadCopy_OFST, SSM_ToLoadOrig_OFST + SSM_ToLoadOrig_Length .set SSM_ToLoadCopy_Length, (56 + NumOfAddedChars) * 4 #Persist Orig .set SSM_IsLoadedOrig_OFST, SSM_ToLoadCopy_OFST + SSM_ToLoadCopy_Length .set SSM_IsLoadedOrig_Length, (56 + NumOfAddedChars) * 4 #Persist Copy .set SSM_IsLoadedCopy_OFST, SSM_IsLoadedOrig_OFST + SSM_IsLoadedOrig_Length .set SSM_IsLoadedCopy_Length, (56 + NumOfAddedChars) * 4 #Unk .set SSM_Footer_OFST, SSM_IsLoadedCopy_OFST + SSM_IsLoadedCopy_Length .set SSM_Footer_Length, (56 + NumOfAddedChars) * 4 */ ================================================ FILE: ASM/m-ex/Standalone Functions/Audio_RequestFileLoad_Rewrite.asm ================================================ #To be inserted @ 803d705c .include "../../Globals.s" .include "../Header.s" .set REG_SSMID,3 .set REG_ToLoadOrig,12 #Check if null ssm ID cmpwi REG_SSMID,55 beq Exit #Get Disposable Orig lwz REG_ToLoadOrig,OFST_SSMStruct(rtoc) lwz REG_ToLoadOrig,Arch_SSMRuntimeStruct_ToLoadOrig(REG_ToLoadOrig) #Queue up ssm load li r4,1 mulli REG_SSMID,REG_SSMID,4 stwx r4,REG_SSMID,REG_ToLoadOrig Exit: blr ================================================ FILE: ASM/m-ex/Standalone Functions/Get MxDt Data.asm ================================================ #To be inserted @ 803d7094 .include "../../Globals.s" .include "../Header.s" backup # check if over cmpwi r3,8 bge Assert # get jump table bl SkipJumpTable #*****************************# bl FtIntNum bl FtExtNum bl FtIconNum bl MnSlChrIcon bl GrIntNum bl GrExtNum bl GrIconNum bl MnSlMpIcon #*****************************# SkipJumpTable: #Get effect type mflr r4 #Jump Table Start in r4 #Get Event Code Pointer mulli r5,r3,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r4,r4,r5 #Gets ASCII Address in r4 mtctr r4 bctr FtIntNum: lwz r3,OFST_Metadata_FtIntNum(rtoc) b Exit FtExtNum: lwz r3,OFST_Metadata_FtExtNum(rtoc) b Exit FtIconNum: lwz r3,OFST_Metadata_CSSIconCount(rtoc) b Exit MnSlChrIcon: lwz r3,OFST_MnSlChrIconData(rtoc) b Exit GrIntNum: lwz r3,OFST_MetaData_GrIntNum(rtoc) b Exit GrExtNum: lwz r3,OFST_MetaData_GrExtNum(rtoc) b Exit GrIconNum: lwz r3,OFST_Metadata_SSSIconCount(rtoc) b Exit MnSlMpIcon: lwz r3,OFST_Menu_SSS(rtoc) b Exit ############################################# Assert: #OSReport mr r4,r3 bl ErrorString mflr r3 branchl r12,0x803456a8 #Assert bl Assert_Name mflr r3 li r4,0 load r5,0x804d3940 branchl r12,0x80388220 Assert_Name: blrl .string "m-ex" .align 2 ErrorString: blrl .string "error: MEX_GetData() does not have data for id %d\n" .align 2 ############################################### Exit: restore blr ================================================ FILE: ASM/m-ex/Standalone Functions/Get grFunction.asm ================================================ #To be inserted @ 803d7068 .include "../../Globals.s" .include "../Header.s" .set REG_Temp,12 .set REG_Dest,3 load REG_Temp,0x8049e6c8 lwz REG_Temp,0x88(REG_Temp) mulli REG_Temp,REG_Temp,4 lwz REG_Dest,OFST_grFunction(rtoc) lwzx REG_Dest,REG_Dest,REG_Temp lwz REG_Dest,0x4(REG_Dest) blr ================================================ FILE: ASM/m-ex/Standalone Functions/GetFtItemID.asm ================================================ #To be inserted @ 803d7088 .include "../../Globals.s" .include "../Header.s" .set REG_FighterID,31 .set REG_ArticleID,30 .set REG_ID,29 .set REG_MEXItemLookup,28 backup #Backup args mr REG_FighterID,r3 mr REG_ArticleID,r4 # Get table lwz r3,OFST_mexData(rtoc) lwz r3,Arch_Fighter(r3) lwz r3,Arch_Fighter_MEXItemLookup(r3) mulli r4,REG_FighterID,MEXItemLookup_Stride add REG_MEXItemLookup,r3,r4 #Check if exists lwz r3,0x0(REG_MEXItemLookup) cmpw REG_ArticleID,r3 bge DoesNotExist #Get external item ID from internal lwz r3,0x4(REG_MEXItemLookup) mulli r4,REG_ArticleID,2 lhzx r3,r3,r4 b Exit ############################################# DoesNotExist: #OSReport bl ErrorString mflr r3 mr r4,REG_FighterID mr r5,REG_ArticleID branchl r12,0x803456a8 #Assert bl Assert_Name mflr r3 li r4,0 load r5,0x804d3940 branchl r12,0x80388220 Assert_Name: blrl .string "m-ex" .align 2 ErrorString: blrl .string "error: fighter %d does not have item %d\n" .align 2 ############################################### Exit: restore blr ================================================ FILE: ASM/m-ex/Standalone Functions/GetGrItemID.asm ================================================ #To be inserted @ 803d708C .include "../../Globals.s" .include "../Header.s" .set REG_FighterID,31 .set REG_ArticleID,30 .set REG_ID,29 .set REG_MEXItemLookup,28 backup #Backup args mr REG_ArticleID,r3 # Get stage ID load r3,0x8049e6c8 lwz REG_ID,0x88(r3) #Get table from mxdt lwz r3,OFST_mexData(rtoc) lwz r3,Arch_Map(r3) lwz r3,Arch_Map_StageItemLookup(r3) mulli r4,REG_ID,MEXItemLookup_Stride add REG_MEXItemLookup,r3,r4 #Check if exists lwz r3,0x0(REG_MEXItemLookup) cmpw REG_ArticleID,r3 bge DoesNotExist #Get external item ID from internal lwz r3,0x4(REG_MEXItemLookup) mulli r4,REG_ArticleID,2 lhzx r3,r3,r4 b Exit ############################################# DoesNotExist: #OSReport bl ErrorString mflr r3 mr r4,REG_ID mr r5,REG_ArticleID branchl r12,0x803456a8 #Assert bl Assert_Name mflr r3 li r4,0 load r5,0x804d3940 branchl r12,0x80388220 Assert_Name: blrl .string "m-ex" .align 2 ErrorString: blrl .string "error: stage %d does not have item %d\n" .align 2 ############################################### Exit: restore blr ================================================ FILE: ASM/m-ex/Standalone Functions/GetKirbyCpData.asm ================================================ #To be inserted @ 803d7084 .include "../../Globals.s" .include "../Header.s" mulli r3,r3,0x4 lwz r4,OFST_KirbyAbilityRuntimeStruct(rtoc) lwzx r3,r3,r4 blr ================================================ FILE: ASM/m-ex/Standalone Functions/GetMEXItemID.asm ================================================ #To be inserted @ 803d7064 .include "../../Globals.s" .include "../Header.s" .set REG_GObj,31 .set REG_ArticleID,30 .set REG_ID,29 .set REG_MEXItemLookup,28 backup #Backup args mr REG_GObj,r3 mr REG_ArticleID,r4 #Check if player or stage lhz r3,0x0(REG_GObj) cmpwi r3,4 beq isPlayer cmpwi r3,3 beq isStage b Unsupported isPlayer: #Get internal ID lwz r3,0x2C(REG_GObj) lwz REG_ID,0x4(r3) #Get table from mxdt lwz r3,OFST_mexData(rtoc) lwz r3,Arch_Fighter(r3) lwz r3,Arch_Fighter_MEXItemLookup(r3) b Continue isStage: load r3,0x8049e6c8 lwz REG_ID,0x88(r3) #Get table from mxdt lwz r3,OFST_mexData(rtoc) lwz r3,Arch_Map(r3) lwz r3,Arch_Map_StageItemLookup(r3) b Continue Continue: mulli r4,REG_ID,MEXItemLookup_Stride add REG_MEXItemLookup,r3,r4 #Check if exists lwz r3,0x0(REG_MEXItemLookup) cmpw REG_ArticleID,r3 bgt DoesNotExist #Get external item ID from internal lwz r3,0x4(REG_MEXItemLookup) mulli r4,REG_ArticleID,2 lhzx r3,r3,r4 b Exit ############################################# DoesNotExist: #OSReport bl ErrorString mflr r3 mr r4,REG_ID mr r5,REG_ArticleID branchl r12,0x803456a8 #Assert bl Assert_Name mflr r3 li r4,0 load r5,0x804d3940 branchl r12,0x80388220 Assert_Name: blrl .string "m-ex" .align 2 ErrorString: blrl .string "error: fighter %d does not have article ID %d\n" .align 2 ############################################### Unsupported: li r3,-1 Exit: restore blr ================================================ FILE: ASM/m-ex/Standalone Functions/GetMEXPlaylist.asm ================================================ #To be inserted @ 803d707C .include "../../Globals.s" .include "../Header.s" .set REG_StageExtID,11 .set REG_Playlist,10 backup #Check if this stage has a playlist load r3,0x8049e6c8 lwz r3,0x88(r3) lwz r4,OFST_mexData(rtoc) lwz r4,Arch_Map(r4) lwz r4,Arch_Map_Playlists(r4) mulli r3,r3,Playlists_Stride add REG_Playlist,r3,r4 #Start of playlist lwz r3,0x4(REG_Playlist) restore blr ================================================ FILE: ASM/m-ex/Standalone Functions/Index Fighter Item.asm ================================================ #To be inserted @ 803d7058 .include "../../Globals.s" .include "../Header.s" .set REG_FighterID,31 .set REG_ArticleData,30 .set REG_ArticleID,29 .set REG_MEXItemLookup,27 backup #Backup args mr REG_FighterID,r3 mr REG_ArticleData,r4 mr REG_ArticleID,r5 #Get table from mxdt lwz r3,OFST_mexData(rtoc) lwz r3,Arch_Fighter(r3) lwz r3,Arch_Fighter_MEXItemLookup(r3) mulli r4,REG_FighterID,MEXItemLookup_Stride add REG_MEXItemLookup,r3,r4 #Check if MxDt has an entry for this item lwz r3,0x0(REG_MEXItemLookup) cmpw REG_ArticleID,r3 bge DoesNotExist Index: #Get external item ID from internal lwz r3,0x4(REG_MEXItemLookup) mulli r4,REG_ArticleID,2 lhzx r3,r3,r4 #Get runtime index lwz r4,OFST_ItemsAdded(rtoc) lwz r4,Arch_ItemsAdded_RuntimeIndex(r4) #Correctly index item subi r3,r3,CustomItemStart #Store article data mulli r3,r3,4 stwx REG_ArticleData,r3,r4 b Exit ############################################# DoesNotExist: #OSReport bl ErrorString_NoItem mflr r3 mr r4,REG_ArticleID mr r5,REG_FighterID branchl r12,0x803456a8 #Assert bl Assert_Name mflr r3 li r4,0 load r5,0x804d3940 branchl r12,0x80388220 Assert_Name: blrl .string "m-ex" .align 2 ErrorString_NoItem: blrl .string "error: MxDt does not contain item %d for fighter %d\n" .align 2 ############################################### Exit: restore blr ================================================ FILE: ASM/m-ex/Standalone Functions/Init itFunction.asm ================================================ #To be inserted @ 803d7070 .include "../../Globals.s" .include "../Header.s" /* r3 = file header r4 = index r5 = fighter/stage */ .set REG_Index,31 .set REG_Type,30 .set REG_itFunction,29 #ftX struct .set ftX_Code,0x0 .set ftX_InstructionRelocTable,0x4 .set ftX_InstructionRelocTableCount,0x8 .set ftX_FunctionRelocTable,0xC .set FunctionRelocTable_ReplaceThis,0x0 .set FunctionRelocTable_ReplaceWith,0x4 .set ftX_FunctionRelocTableCount,0x10 backup mr REG_Index,r4 mr REG_Type,r5 #Get symbol offset from file bl itFunctionString mflr r4 branchl r12,0x80380358 mr. REG_itFunction,r3 beq itFunction_NoItem #Loop through all items .set REG_ItemCount,20 .set REG_LoopCount,21 lwz REG_ItemCount,0x0(REG_itFunction) li REG_LoopCount,0 cmpwi REG_ItemCount,0 beq itFunction_NoItem itFunction_Init: #Get this item .set REG_ThisItem,22 addi r3,REG_itFunction,0x4 mulli r4,REG_LoopCount,4 lwzx REG_ThisItem,r3,r4 #Ensure it exists cmpwi REG_ThisItem,0 beq itFunction_InitLoop #Reloc lwz r3,ftX_InstructionRelocTableCount(REG_ThisItem) #count lwz r4,ftX_Code(REG_ThisItem) #code lwz r5,ftX_InstructionRelocTable(REG_ThisItem) #reloc table branchl r12,Reloc #Copy function pointers - init .set REG_ThisOffset,12 .set REG_FuncPtrs,11 .set REG_Code,10 .set REG_ItemTable,9 .set REG_Count,8 #Get external item ID from internal mr r3,REG_Index mr r4,REG_Type mr r5,REG_LoopCount bl Item_GetItemTableFromInternal mr REG_ItemTable,r3 #Init lwz REG_FuncPtrs,ftX_FunctionRelocTable(REG_ThisItem) lwz REG_Code,0x0(REG_ThisItem) li REG_Count,0 b itFunction_Overload_CheckLoop itFunction_Overload_Loop: mulli r4,REG_Count,8 add r5,r4,REG_FuncPtrs #Convert to code offset lwz r3,0x4(r5) add r3,r3,REG_Code #get offset lwz r4,0x0(r5) mulli r4,r4,4 #Store to item table stwx r3,r4,REG_ItemTable itFunction_Overload_IncLoop: addi REG_Count,REG_Count,1 itFunction_Overload_CheckLoop: lwz r3,ftX_FunctionRelocTableCount(REG_ThisItem) cmpw REG_Count,r3 blt itFunction_Overload_Loop itFunction_InitLoop: addi REG_LoopCount,REG_LoopCount,1 cmpw REG_LoopCount,REG_ItemCount blt itFunction_Init li r3,1 b Exit itFunction_NoItem: li r3,0 b Exit itFunctionString: blrl .string "itFunction" .align 2 Item_GetItemTableFromInternal: .set REG_ArticleID,12 .set REG_Index,11 .set REG_Type,10 #Init mr REG_Index,r3 mr REG_Type,r4 mr REG_ArticleID,r5 #Get external item ID from internal cmpwi REG_Type,1 beq Item_GetItemTableFromInternal_Stage Item_GetItemTableFromInternal_Fighter: lwz r3,OFST_mexData(rtoc) lwz r3,Arch_Fighter(r3) lwz r3,Arch_Fighter_MEXItemLookup(r3) b Item_GetItemTableFromInternal_GetID Item_GetItemTableFromInternal_Stage: lwz r3,OFST_mexData(rtoc) lwz r3,Arch_Map(r3) lwz r3,Arch_Map_StageItemLookup(r3) b Item_GetItemTableFromInternal_GetID Item_GetItemTableFromInternal_GetID: mulli r4,REG_Index,MEXItemLookup_Stride add r3,r3,r4 lwz r3,0x4(r3) #Ensure item table exists cmpwi r3,0 beq DoesNotExist #Get item ID mulli r4,REG_ArticleID,2 lhzx r3,r3,r4 #Get item's table lwz r4,OFST_ItemsAdded(rtoc) cmpwi r3,43 blt CommonItems cmpwi r3,161 blt FighterItems cmpwi r3,208 blt PokemonItems cmpwi r3,CustomItemStart blt StageItems b CustomItems CommonItems: lwz r4,Arch_ItemsAdded_Common(r4) b GetTable FighterItems: subi r3,r3,43 lwz r4,Arch_ItemsAdded_Fighter(r4) b GetTable PokemonItems: subi r3,r3,161 lwz r4,Arch_ItemsAdded_Pokemon(r4) b GetTable StageItems: subi r3,r3,208 lwz r4,Arch_ItemsAdded_Stages(r4) b GetTable CustomItems: subi r3,r3,CustomItemStart lwz r4,Arch_ItemsAdded_Custom(r4) b GetTable GetTable: mulli r3,r3,0x3C add r3,r3,r4 blr ########################################### DoesNotExist: #Get Object Kind string cmpwi REG_Type, 1 beq DoesNotExist_Stage DoesNotExist_Fighter: bl ErrorString_Fighter mflr r4 b DoesNotExist_OSReport DoesNotExist_Stage: bl ErrorString_Stage mflr r4 b DoesNotExist_OSReport DoesNotExist_OSReport: bl ErrorString mflr r3 mr r5,REG_Index branchl r12,0x803456a8 #Assert bl Assert_Name mflr r3 li r4,0 load r5,0x804d3940 branchl r12,0x80388220 Assert_Name: blrl .string "m-ex" .align 2 ErrorString: blrl .string "error: MxDt does not contain any items for %s %d\n" .align 2 ErrorString_Fighter: blrl .string "fighter" .align 2 ErrorString_Stage: blrl .string "stage" .align 2 ############################################### Exit: restore blr ================================================ FILE: ASM/m-ex/Standalone Functions/KirbyStateChange.asm ================================================ #To be inserted @ 803d7080 .include "../../Globals.s" .include "../Header.s" # void KirbyStateChange(GOBJ *fighter, int state, float startFrame, float animSpeed, float animBlend) .set REG_GObj,31 .set REG_State,30 .set REG_FighterData,29 .set REG_StateMoveLogic,28 .set REG_FtCmd,27 .set REG_AbilityID,26 .set REG_Frame,31 .set REG_Speed,30 .set REG_Blend,29 # Init backup stfs REG_Speed,0x80(sp) stfs REG_Blend,0x84(sp) stfs REG_State,0x88(sp) mr REG_GObj,r3 mr REG_State,r4 fmr REG_Frame,f1 fmr REG_Speed,f2 fmr REG_Blend,f3 lwz REG_FighterData,0x2C(REG_GObj) # Check if Kirby lwz r3,0x4(REG_FighterData) cmpwi r3,4 bne NotKirby # Get current ability ID lwz REG_AbilityID,0x2238(REG_FighterData) # Get this states move logic lwz r3,OFST_KirbyMoveLogicRuntime(rtoc) mulli r4,REG_AbilityID,0x4 lwzx r3,r3,r4 # get this abilities move logic pointer cmpwi r3,0 beq NoMoveLogic mulli r4,REG_State,0x20 # get this states move logic add REG_StateMoveLogic,r3,r4 # Get this states ftcmd lwz r3,OFST_KirbyFtCmdRuntime(rtoc) mulli r4,REG_AbilityID,0x4 lwzx r3,r3,r4 # get this abilities ftcmd pointer cmpwi r3,0 beq NoFtCmd lwz r4,0x0(REG_StateMoveLogic) # get this states animation mulli r4,r4,0x18 # get this states ftcmd add REG_FtCmd,r3,r4 # Enter Dummy State mr r3,REG_GObj li r4,0XEF # dummy state id lis r5,0x2000 # no anim update li r6,0 # no source gobj fmr f1,REG_Frame fmr f2,REG_Speed fmr f3,REG_Blend branchl r12,ActionStateChange # Spoof anim ID as not -1 (so the animation is updated each frame) li r3,0 stw r3,0x14(REG_FighterData) # Spoof state as ItemScopeFire li r3,0xA0 stw r3,0x10(REG_FighterData) # Spoof current anim offset as -1 (will always result in a cache miss for the next anim load) li r3,-1 stw r3,0x5A4(REG_FighterData) # Store pointer to figatree animation symbol lwz r3,0x4(REG_FtCmd) cmpwi r3,0 beq NoAnim stw r3,0x590(REG_FighterData) /* # Load animation data from source mr r3, REG_FighterData # anim dest mr r4, REG_AbilityGObjData # anim source lwz r5,0x0(REG_StateMoveLogic) # anim ID branchl r12,0x80085cd8 */ # Store subaction pointer lwz r3,0xC(REG_FtCmd) # script data stw r3,0x3EC(REG_FighterData) # Enter animation lwz r3,0x590(REG_FighterData) mr r3,REG_GObj fmr f1,REG_Frame fmr f2,REG_Speed fmr f3,REG_Blend branchl r12,0x8006ebe8 # Unk li r3,0 stw r3,0x3E4(REG_FighterData) # Increment state frame info mr r3,REG_GObj branchl r12,0x8006e9b4 # Subaction update stuff lfs f0, -0x778C (rtoc) fcmpo cr0,f0,REG_Frame bne SubactionSkip SubactionStart: mr r3,REG_GObj branchl r12,0x800c0408 # update colanims mr r3,REG_GObj branchl r12,0x80073240 # update subaction unk b SubactionEnd SubactionSkip: mr r3,REG_GObj branchl r12,0x80073354 SubactionEnd: # Copy callbacks from source lwz r3,0xC(REG_StateMoveLogic) # unk callback stw r3,0x21A0(REG_FighterData) lwz r3,0x10(REG_StateMoveLogic) # unk callback stw r3,0x219C(REG_FighterData) lwz r3,0x14(REG_StateMoveLogic) # unk callback stw r3,0x21A4(REG_FighterData) lwz r3,0x18(REG_StateMoveLogic) # unk callback stw r3,0x21A8(REG_FighterData) lwz r3,0x1C(REG_StateMoveLogic) # unk callback stw r3,0x21AC(REG_FighterData) b Exit ############################################# NoMoveLogic: #OSReport bl NoMoveLogicString mflr r3 lwz r4,OFST_KirbyHatFileNames(rtoc) mulli r5,REG_AbilityID,8 lwzx r4,r4,r5 branchl r12,0x803456a8 b Assert NoMoveLogicString: blrl .string "error: kbfunction in %s missing move_logic table\n" .align 2 ############################################### NoFtCmd: #OSReport bl NoFtCmdString mflr r3 lwz r4,OFST_KirbyHatFileNames(rtoc) mulli r5,REG_AbilityID,8 lwzx r4,r4,r5 branchl r12,0x803456a8 b Assert NoFtCmdString: blrl .string "error: %s missing ftcmd symbol\n" .align 2 ############################################### NoAnim: #OSReport bl NoAnimString mflr r3 lwz r4,OFST_KirbyHatFileNames(rtoc) mulli r5,REG_AbilityID,8 lwzx r4,r4,r5 mr r5,REG_State branchl r12,0x803456a8 b Assert NoAnimString: blrl .string "error: ftcmd in %s missing animation for state %d\n" .align 2 ############################################### NotKirby: #OSReport bl NotKirbyString mflr r3 lwz r4,0x4(REG_FighterData) branchl r12,0x803456a8 b Assert NotKirbyString: blrl .string "error: fighter %d is not kirby\n" .align 2 ############################################### Assert: bl Assert_Name mflr r3 li r4,0 load r5,0x804d3940 branchl r12,0x80388220 Assert_Name: blrl .string "m-ex" .align 2 ############################################### Error: b 0x0 Exit: lfs REG_Speed,0x80(sp) lfs REG_Blend,0x84(sp) lfs REG_State,0x88(sp) restore blr ================================================ FILE: ASM/m-ex/Standalone Functions/LoadRELDAT.asm ================================================ #To be inserted @ 803d7080 .include "../../Globals.s" .include "../Header.s" # args are # r3 = file name # r4 = array to store function pointers to # r5 = symbol # returns # r3 = file data .set REG_FileName,31 .set REG_Return,30 .set REG_Symbol,29 .set REG_FileSize,28 .set REG_File,27 .set REG_Header,26 .set REG_mexData,25 backup mr REG_FileName,r3 mr REG_Return,r4 mr REG_Symbol,r5 #Load file mr r3, REG_FileName addi r4, sp, 0x80 mr r5, REG_Symbol li r6,0 branchl r12,0x80016c64 mr REG_Header,r3 #Check if exists lwz REG_mexData,0x80(sp) cmpwi REG_mexData,0 beq mexPatch_Skip #Reloc lwz r3,ftX_InstructionRelocTableCount(REG_mexData) #count lwz r4,ftX_Code(REG_mexData) #code lwz r5,ftX_InstructionRelocTable(REG_mexData) #reloc table branchl r12,Reloc #Overload mr r3,REG_mexData mr r4,REG_Return bl Overload mexPatch_Skip: #Flush instruction cache so code can be run from this file lwz r3,0x20(REG_Header) # file start lwz r4,0x0(REG_Header) # file size branchl r12,0x80328f50 mr r3,REG_Header restore blr ########################################### #ftX struct .set ftX_Code,0x0 .set ftX_InstructionRelocTable,0x4 .set ftX_InstructionRelocTableCount,0x8 .set ftX_FunctionRelocTable,0xC .set FunctionRelocTable_ReplaceThis,0x0 .set FunctionRelocTable_ReplaceWith,0x4 .set ftX_FunctionRelocTableCount,0x10 Overload: # r3 = ftX # r4 = table #Copy function pointers - init .set REG_ftX,12 .set REG_ThisElement,11 .set REG_Code,10 .set REG_OverloadTable,9 .set REG_Count,8 .set REG_RelocTable,7 mr REG_ftX,r3 mr REG_OverloadTable,r4 lwz REG_RelocTable,ftX_FunctionRelocTable(REG_ftX) lwz REG_Code,0x0(REG_ftX) li REG_Count,0 b Overload_CheckLoop Overload_Loop: #Get this element mulli r3,REG_Count,8 add REG_ThisElement,r3,REG_RelocTable Overload_TableIndex: #Get ram offset for this function lwz r3,FunctionRelocTable_ReplaceWith(REG_ThisElement) add r3,r3,REG_Code #Update table lwz r4,FunctionRelocTable_ReplaceThis(REG_ThisElement) mulli r4,r4,4 stwx r3,r4,REG_OverloadTable b Overload_IncLoop Overload_IncLoop: addi REG_Count,REG_Count,1 Overload_CheckLoop: lwz r3,ftX_FunctionRelocTableCount(REG_ftX) cmpw REG_Count,r3 blt Overload_Loop Overload_Exit: blr ############################################ ================================================ FILE: ASM/m-ex/Standalone Functions/MenuThink.asm ================================================ #To be inserted @ 803d7090 .include "../../Globals.s" .include "../Header.s" # slippi hack .set OFST_R13_SWITCH_TO_ONLINE_SUBMENU,-0x49ec # Function used to switch .set REG_GObj,31 .set REG_MenuData,30 .set REG_Inputs,29 .set REG_MenuDef,28 .set REG_OptDef,27 .set REG_ThisOpt,26 .set REG_ThisMenu,25 # init backup mr REG_GObj,r3 load REG_MenuData,0x804a04f0 # Get menu def lwz r3,OFST_mexMenu(r13) lwz r3,mexMenu_MenuDef(r3) lbz r0, 0 (REG_MenuData) mulli r0, r0, MenuDefStride add REG_MenuDef,r3,r0 # Get opt def lwz REG_OptDef,MenuDef_OptDef(REG_MenuDef) # Decrement lockout lhz r3,-0x4AD8(r13) cmpwi r3,0 ble SkipLockoutDec subi r3,r3,1 sth r3,-0x4AD8(r13) b Exit SkipLockoutDec: # Get inputs li r3,4 branchl r12,0x80229624 mr REG_Inputs,r3 stw REG_Inputs, 0x000C (REG_MenuData) li r3,0 stw r3, 0x0008 (REG_MenuData) # Check for A rlwinm. r0,REG_Inputs,0,0x10 beq NoA # SFX li r3, 1 branchl r12,0x80024030 # Store Input Lockout li r3,5 sth r3,-0x4AD8(r13) # Store menu leave animation direction li r3,1 stb r3, 0x0011 (REG_MenuData) # Get this option lhz r3, 0x2 (REG_MenuData) # current cursor mulli r3,r3,OptDefStride add REG_ThisOpt,r3,REG_OptDef # Get option kind lbz r3,OptDef_Kind(REG_ThisOpt) cmpwi r3,0 beq Enter_Menu cmpwi r3,1 beq Enter_Scene b Exit Enter_Menu: # Get this menu lwz r3,OFST_mexMenu(r13) lwz r3,mexMenu_MenuDef(r3) lbz r0, OptDef_ID (REG_ThisOpt) mulli r0, r0, MenuDefStride add REG_ThisMenu,r3,r0 # Check if event mode... lbz r3,OptDef_ID(REG_ThisOpt) cmpwi r3,7 bne Enter_MenuNoEvent # Handle event mode lwz r12,MenuDef_Callback(REG_ThisMenu) cmpwi r12,0 beq Enter_MenuNoCB mtctr r12 li r3,0 li r4,1 bctrl # Delete this menu gobj mr r3,REG_GObj branchl r12,0x80390228 b Exit Enter_MenuNoEvent: # Check if slippi menu... lbz r3,OptDef_ID(REG_ThisOpt) cmpwi r3,8 bne Enter_MenuNoSlippi # Handle slippi menu init lwz r12,OFST_R13_SWITCH_TO_ONLINE_SUBMENU(r13) mtctr r12 bctrl b Exit Enter_MenuNoSlippi: # Check if multiman menu... lbz r3,OptDef_ID(REG_ThisOpt) cmpwi r3,33 bne Enter_MenuNoMultiman # Handle multiman menu init li r3,0 branchl r12,0x8024cd64 # Delete this menu gobj mr r3,REG_GObj branchl r12,0x80390228 b Exit Enter_MenuNoMultiman: Enter_MenuNoSpecial: # check for custom callback lwz r3,MenuDef_Callback(REG_ThisMenu) cmpwi r3,0 beq Enter_MenuNoCB mtctr r3 bctrl # Delete this menu gobj mr r3,REG_GObj branchl r12,0x80390228 b Exit Enter_MenuNoCB: # set prev menu lbz r3, 0x0 (REG_MenuData) stb r3, 0x1 (REG_MenuData) # new curr menu lbz r3,OptDef_ID(REG_ThisOpt) stb r3, 0x0 (REG_MenuData) # determine cursor value for next menu .set REG_Count,20 .set REG_OptNum,11 li REG_Count,0 lwz r3,OFST_mexMenu(r13) lwz r3,mexMenu_MenuDef(r3) lbz r0, 0 (REG_MenuData) mulli r0, r0, MenuDefStride add r3,r3,r0 lbz REG_OptNum,MenuDef_OptNum(r3) SearchNextCursor__Loop: # check if unlocked lbz r3, 0 (REG_MenuData) mr r4,REG_Count # option ID branchl r12,0x80229938 cmpwi r3,0 beq SearchNextCursor__IncLoop # set cursor sth REG_Count, 0x2 (REG_MenuData) # current cursor b SearchNextCursor__Exit SearchNextCursor__IncLoop: addi REG_Count,REG_Count,1 cmpw REG_Count,REG_OptNum blt SearchNextCursor__Loop SearchNextCursor__Exit: # Switch menu li r3,1 # forward branchl r12,0x8022b3a0 # Some proc thing branchl r12,0x80390cd4 # Delete this menu gobj mr r3,REG_GObj branchl r12,0x80390228 # Get next menu lwz r3,OFST_mexMenu(r13) lwz r3,mexMenu_MenuDef(r3) lbz r0, 0x0 (REG_MenuData) mulli r0, r0, MenuDefStride add REG_MenuDef,r3,r0 # Create next menu gobj li r3,0 li r4,1 li r5,128 branchl r12,0x803901f0 # Set this proc load r4,MenuThink li r5,0 branchl r12,0x8038fd54 # Adjust this proc? lwz r4, -0x3E64 (r13) lbz r0, 0x000D (r3) rlwimi r0, r4, 4, 26, 27 stb r0, 0x000D (r3) b Exit Enter_Scene: # Get scene data branchl r12,0x801a4b9c # Store scene ID lbz r0,OptDef_ID(REG_ThisOpt) stb r0,0x0(r3) # Change minor branchl r12,0x801a4b60 b Exit NoA: # Check for B rlwinm. r0,REG_Inputs,0,0x20 beq NoB # SFX li r3, 0 branchl r12,0x80024030 # Check for title screen lbz r3,MenuDef_PrevMenu(REG_MenuDef) extsb r3,r3 cmpwi r3,-1 bne Return_NoTitle # Get scene data branchl r12,0x801a4b9c # Store scene ID li r0,0 stb r0,0x0(r3) # Change minor branchl r12,0x801a4b60 b Exit Return_NoTitle: # Store menu leave animation direction li r3,0 stb r3, 0x0011 (REG_MenuData) # set prev menu lbz r3, 0x0 (REG_MenuData) stb r3, 0x1 (REG_MenuData) # new curr menu lbz r3,MenuDef_PrevMenu(REG_MenuDef) stb r3, 0x0 (REG_MenuData) # determine cursor value for prev menu .set REG_Count,12 .set REG_OptNum,11 .set REG_OptDef,10 .set REG_PrevMenuID,9 li REG_Count,0 lbz REG_PrevMenuID, 0x1 (REG_MenuData) # Get menu def for prev menu lwz r3,OFST_mexMenu(r13) lwz r3,mexMenu_MenuDef(r3) lbz r0, 0 (REG_MenuData) mulli r0, r0, MenuDefStride add r3,r3,r0 lbz REG_OptNum,MenuDef_OptNum(r3) lwz REG_OptDef,MenuDef_OptDef(r3) SearchPrevCursor_Loop: # Get this optdef mulli r0,REG_Count,OptDefStride add r3,REG_OptDef,r0 # check if menu lbz r0,OptDef_Kind(r3) cmpwi r0,0 bne SearchPrevCursor_IncLoop # get menu ID lbz r0,OptDef_ID(r3) cmpw r0,REG_PrevMenuID bne SearchPrevCursor_IncLoop # set cursor sth REG_Count, 0x2 (REG_MenuData) # current cursor b SearchPrevCursor_Exit SearchPrevCursor_IncLoop: addi REG_Count,REG_Count,1 cmpw REG_Count,REG_OptNum blt SearchPrevCursor_Loop SearchPrevCursor_Exit: # Switch menu li r3,3 # backward branchl r12,0x8022b3a0 # Some proc thing branchl r12,0x80390cd4 # Delete this menu gobj mr r3,REG_GObj branchl r12,0x80390228 # Create next menu gobj li r3,0 li r4,1 li r5,128 branchl r12,0x803901f0 # Set this proc load r4,MenuThink li r5,0 branchl r12,0x8038fd54 # Adjust this proc? lwz r4, -0x3E64 (r13) lbz r0, 0x000D (r3) rlwimi r0, r4, 4, 26, 27 stb r0, 0x000D (r3) b Exit NoB: # Check for Up rlwinm. r0,REG_Inputs,0,0x1 beq NoUp # SFX li r3, 2 branchl r12,0x80024030 CursorUpInitLoop: .set REG_TempCursor, 20 lhz REG_TempCursor, 0x2 (REG_MenuData) # current cursor CursorUpLoop: # Move cursor subi REG_TempCursor,REG_TempCursor,1 extsh r0,REG_TempCursor cmpwi r0,-1 bgt CursorUp_NoAdjust # Get last option lbz r3,MenuDef_OptNum(REG_MenuDef) subi REG_TempCursor,r3,1 CursorUp_NoAdjust: # Check if option exists lbz r3, 0x0 (REG_MenuData) mr r4,REG_TempCursor branchl r12,0x80229938 cmpwi r3,0 beq CursorUpLoop CursorUp_Store: sth REG_TempCursor, 0x2 (REG_MenuData) # current cursor b Exit NoUp: # Check for Down rlwinm. r0,REG_Inputs,0,0x2 beq NoDown # SFX li r3, 2 branchl r12,0x80024030 CursorDownInitLoop: .set REG_TempCursor, 20 lhz REG_TempCursor, 0x2 (REG_MenuData) # current cursor CursorDownLoop: # Move cursor addi REG_TempCursor,REG_TempCursor,1 lbz r4,MenuDef_OptNum(REG_MenuDef) cmpw REG_TempCursor,r4 blt CursorDown_NoAdjust # Get first option li REG_TempCursor,0 CursorDown_NoAdjust: # Check if option exists lbz r3, 0x0 (REG_MenuData) mr r4,REG_TempCursor branchl r12,0x80229938 cmpwi r3,0 beq CursorDownLoop CursorDown_Store: sth REG_TempCursor, 0x2 (REG_MenuData) # current cursor b Exit NoDown: Exit: restore blr ================================================ FILE: ASM/m-ex/Standalone Functions/Reloc.asm ================================================ #To be inserted @ 803d7074 .include "../../Globals.s" .include "../Header.s" ########################################### #Intialize pointers .set REG_Count,12 .set REG_Code,11 .set REG_RelocTable,10 mr REG_Count,r3 mr REG_Code,r4 mr REG_RelocTable,r5 Reloc_Loop: .set REG_CodePointer,9 .set REG_FuncPointer,8 .set REG_Flag,7 lwz r3,0x0(REG_RelocTable) rlwinm REG_Flag,r3,8,0x000000FF #get flag rlwinm r3,r3,0,0x00FFFFFF add REG_CodePointer,r3,REG_Code #get code offset #First check if a bl to an dol address lwz r3,0x4(REG_RelocTable) rlwinm r0,r3,8,0x000000F0 cmpwi r0,0x80 beq Reloc_DOLAddr Reloc_CodeAddr: add REG_FuncPointer,r3,REG_Code #get func offset b Reloc_CheckType Reloc_DOLAddr: lwz REG_FuncPointer,0x4(REG_RelocTable) #get func offset Reloc_CheckType: #Check flag type cmpwi REG_Flag,1 beq Reloc_StaticAddress cmpwi REG_Flag,4 beq Reloc_LoadAddress cmpwi REG_Flag,6 beq Reloc_LoadAddress cmpwi REG_Flag,10 beq Reloc_Branch cmpwi REG_Flag,26 beq Reloc_Relative32Bit b Reloc_IncLoop Reloc_StaticAddress: #lwz r3,0x0(REG_FuncPointer) stw REG_FuncPointer,0x0(REG_CodePointer) b Reloc_IncLoop ############################################ Reloc_LoadAddress: #Now check if the low bits are signed rlwinm. r3,REG_FuncPointer,17,0x1 beq Reloc_CheckFlag #Adjust this address to load a negative offset .set REG_NewHigh,6 .set REG_NewLow,5 #High bits rlwinm r3,REG_FuncPointer,16,0x0000FFFF addi r3,r3,1 slwi REG_NewHigh,r3,16 #Low bits sub r3,REG_FuncPointer,REG_NewHigh rlwinm REG_NewLow,r3,0,0x0000FFFF or REG_FuncPointer,REG_NewHigh,REG_NewLow Reloc_CheckFlag: #Check flag type cmpwi REG_Flag,4 beq Reloc_Low16 cmpwi REG_Flag,6 beq Reloc_High16 Reloc_High16: rlwinm r3,REG_FuncPointer,16,0x0000FFFF b Reloc_Store Reloc_Low16: rlwinm r3,REG_FuncPointer,0,0x0000FFFF b Reloc_Store Reloc_Store: sth r3,0x0(REG_CodePointer) b Reloc_IncLoop ############################################ Reloc_Branch: #Store branch to this code sub r3,REG_FuncPointer,REG_CodePointer #Difference relative to branch addr rlwinm r3,r3,0,6,29 #extract bits for offset lwz r4,0x0(REG_CodePointer) #place branch instruction or r3,r3,r4 stw r3,0x0(REG_CodePointer) #place branch instruction b Reloc_IncLoop ############################################ Reloc_Relative32Bit: #Store offset? #Store branch to this code sub r3,REG_FuncPointer,REG_CodePointer #Difference relative to branch addr stw r3,0x0(REG_CodePointer) #place branch instruction b Reloc_IncLoop ############################################ Reloc_IncLoop: addi REG_RelocTable,REG_RelocTable,8 subi REG_Count,REG_Count,1 cmpwi REG_Count,0 bgt Reloc_Loop blr ############################################## ================================================ FILE: ASM/m-ex/Standalone Functions/SFX_PlayStageSFX.asm ================================================ #To be inserted @ 803d7078 .include "../../Globals.s" .include "../Header.s" .set REG_SFXID,31 backup #r3 = stage SFX ID mr REG_SFXID,r3 #Get current stage internal ID load r3,0x8049e6c8 lwz r3,0x88(r3) #Get stage's ssm ID lwz r4,OFST_Map_Audio(rtoc) mulli r3,r3,3 add r3,r3,r4 lbz r3,0x0(r3) #Multiply by 10000 mulli r3,r3,10000 #Add SFX ID add r3,r3,REG_SFXID #Play SFX branchl r12,0x801c53ec Exit: restore blr ================================================ FILE: ASM/m-ex/Standalone Functions/SpawnMEXEffect.s ================================================ #To be inserted @ 803d7060 .include "../../Globals.s" .include "../Header.s" .set REG_EffectID,31 .set REG_PlayerGObj,30 .set REG_Arg1,29 .set REG_Arg2,28 .set REG_Arg3,27 .set REG_Arg4,26 .set REG_Arg5,26 .set REG_PlayerData,21 .set REG_MEXEffectLookup,20 backup #effect id = 5000 + charEffectID addi r3,r3,PersonalEffectStart branchl r12,0x8005fddc Exit: restore blr ================================================ FILE: ASM/m-ex/Standalone Functions/SpawnMEXItem.asm ================================================ #To be inserted @ 80268648 .include "../../Globals.s" .include "../Header.s" .set REG_GObj,31 .set REG_ItemSpawnStruct,30 .set REG_PlayerData,29 .set REG_MEXItemLookup,28 .set REG_ArticleID,27 backup #Check if article >=5000 lwz REG_ArticleID,0x8(REG_ItemSpawnStruct) cmpwi REG_ArticleID,5000 blt Exit #Index subi REG_ArticleID,REG_ArticleID,5000 #Check if player or stage lwz REG_GObj,0x0(REG_ItemSpawnStruct) cmpwi REG_GObj,0 beq IsStageItem lhz r3,0x0(REG_GObj) cmpwi r3,4 beq IsFighterItem cmpwi r3,3 beq IsStageItem b Unsupported IsFighterItem: #Get Fighter MEX Item Lookup lwz r3,OFST_mexData(rtoc) lwz r3,Arch_Fighter(r3) lwz r3,Arch_Fighter_MEXItemLookup(r3) #Get index (fighter internal ID) lwz r4,0x2C(REG_GObj) lwz r4,0x4(r4) b GetMEXItemID IsStageItem: #Get index (stage internal ID) lwz r3,OFST_mexData(rtoc) lwz r3,Arch_Map(r3) lwz r3,Arch_Map_StageItemLookup(r3) #No player gobj passed in, assuming this is a stage item load r4,0x8049e6c8 lwz r4,0x88(r4) GetMEXItemID: #Get table from mxdt mulli r4,r4,MEXItemLookup_Stride add REG_MEXItemLookup,r3,r4 #Check if exists lwz r3,0x0(REG_MEXItemLookup) cmpw REG_ArticleID,r3 bge DoesNotExist SpawnItem: #Get external item ID from internal lwz r3,0x4(REG_MEXItemLookup) mulli r4,REG_ArticleID,2 lhzx r3,r3,r4 stw r3,0x8(REG_ItemSpawnStruct) b Exit ############################################# DoesNotExist: #OSReport bl ErrorString mflr r3 mr r4,REG_ArticleID branchl r12,0x803456a8 #Assert bl Assert_Name mflr r3 li r4,0 load r5,0x804d3940 branchl r12,0x80388220 Assert_Name: blrl .string "m-ex" .align 2 ErrorString: blrl .string "error: MxDt does not have article ID %d\n" .align 2 ############################################### Unsupported: Exit: restore lwz r3, 0x000C (r30) ================================================ FILE: ASM/m-ex/Standalone Functions/Stock Icon Get Frame.asm ================================================ #To be inserted @ 803d7060 .include "../../Globals.s" .include "../Header.s" .set REG_InternalID,31 .set REG_CostumeID,30 .set REG_StcIcons,29 .set REG_InternalIDCount,28 .set masterHand,6 .set crazyHand,5 .set wireMale,4 .set wireFemale,3 .set gigabowser,2 .set sandbag,1 # init backup mr REG_InternalID,r3 mr REG_CostumeID,r4 # Check if custom symbol exists lwz REG_StcIcons,OFST_stc_icons(r13) cmpwi REG_StcIcons,0 beq Exit #Check if a special character lwz REG_InternalIDCount,OFST_Metadata_FtIntNum(rtoc) subi r3,REG_InternalIDCount,masterHand cmpw REG_InternalID,r3 blt NormalCharacter subi r3,REG_InternalIDCount,sandbag cmpw REG_InternalID,r3 bgt NormalCharacter # get special fighter frame subi r3,REG_InternalIDCount,masterHand sub r3,REG_InternalID,r3 bl SpecialCharacterFrames mflr r4 lbzx r3,r3,r4 b CastToFloat # stock frame = reserved + costume * stride + extID NormalCharacter: lhz r3,StcIcons_ReservedFrames(REG_StcIcons) lhz r4,StcIcons_Stride(REG_StcIcons) mullw r4,r4,REG_CostumeID add r3,r3,r4 add r3,r3,REG_InternalID # cast to float CastToFloat: xoris r3,r3,0x8000 lfd f1, -0x35F8 (rtoc) stw r3,0x84(sp) lis r3,0x4330 stw r3,0x80(sp) lfd f2,0x80(sp) fsubs f1,f2,f1 b Exit SpecialCharacterFrames: blrl .byte 3 #master hand .byte 2 #crazy hand .byte 1 #wire male male .byte 1 #wire female .byte 5 #giga bowser .byte 6 #sandbag .align 2 Exit: restore blr ================================================ FILE: ASM/m-ex/Standalone Functions/calloc.asm ================================================ #To be inserted @ 803d706C .include "../../Globals.s" .include "../Header.s" .set REG_Size,31 .set REG_Alloc,30 #init backup mr REG_Size,r3 #alloc branchl r12,HSD_MemAlloc mr REG_Alloc,r3 #clear li r4,0 mr r5,REG_Size branchl r12,0x80003100 #Exit mr r3,REG_Alloc restore blr ================================================ FILE: ASM/m-ex/UCF 0.8/Codes.txt ================================================ C20CA1E8 0000002B #UCF DB.asm D01F002C 7C0802A6 90010004 9421FF00 BE810008 48000121 7FC802A6 C03F0894 C05E0000 FC011040 40820118 808DB0F4 C03F0620 FC200A10 C044003C FC011040 41800100 887F0670 2C030002 408000F4 887F221F 54600739 408200E8 3C60804B 60632FF8 8BA30001 387DFFFE 889F0618 4800008D 7C7C1B78 7FA3EB78 889F0618 4800007D 7C7C1850 7C6319D6 2C0315F9 408100B0 38000001 901F2358 901F2340 809F0004 2C04000A 40A20098 887F000C 38800001 3D808003 618C4780 7D8903A6 4E800421 2C030000 41820078 8083002C 80841ECC C03F002C D0240018 C05E0004 FC011040 4181000C 38600080 48000008 3860007F 98640006 48000048 7C852378 3863FFFF 2C030000 40800008 38630005 3C808045 6084BF10 1C630030 7C841A14 1C65000C 7C841A14 88640002 7C630774 4E800020 4E800021 40000000 00000000 BA810008 80010104 38210100 7C0803A6 60000000 00000000 C20998A4 00000026 #UCF SD.asm 7C0802A6 90010004 9421FF00 BE810008 7C7E1B78 83FE002C 480000DD 7FA802A6 C03F063C 806DAEB4 C0030314 FC010040 408100E4 C03F0620 48000071 D0210090 C03F0624 48000065 C0410090 EC4200B2 EC210072 EC21102A C05D000C FC011040 418000B4 889F0670 2C040003 408100A8 C01D0010 C03F0624 FC000840 40800098 BA810008 80010104 38210100 7C0803A6 8061001C 83E10014 38210018 38630008 7C6803A6 4E800020 FC000A10 C03D0000 EC000072 C03D0004 EC000828 FC00001E D8010080 80610084 38630002 3C004330 C85D0014 6C638000 90010080 90610084 C8210080 EC011028 C03D0000 EC200824 4E800020 4E800021 42A00000 37270000 43300000 3F800000 BF4CCCCD 43300000 80000000 7FC3F378 7FE4FB78 BA810008 80010104 38210100 7C0803A6 00000000 C22669EC 0000001B #UCF Text.asm 7C0802A6 90010004 9421FF00 BE810008 48000089 7FC802A6 38600000 38800000 3DC0803A 61CE6664 7DC903A6 4E800421 7C7F1B78 38800001 989F0049 38800001 989F004A C03E000C D03F0024 D03F0028 7FE3FB78 48000059 7C8802A6 C03E0000 C05E0004 3DC0803A 61CE6B54 7DC903A6 4E800421 7C641B78 7FE3FB78 C03E0008 C05E0008 3D80803A 618C74FC 7D8903A6 4E800421 48000028 4E800021 42180000 C3898000 3EE66666 3DCCCCCD 4E800021 55434620 302E3734 00000000 BA810008 80010104 38210100 7C0803A6 38980000 60000000 00000000 ================================================ FILE: ASM/m-ex/UCF 0.8/UCF DB.asm ================================================ #To be inserted at 800C9A44 .include "../../Globals.s" .include "../Header.s" .set REG_PlayerData,31 .set REG_Floats,30 .set REG_InputIndex,29 .set REG_PrevInput,28 NTSC102: .set Injection,0x800C9A44 .set OFST_PlCo,-0x514C .set InputIndex,0x804c1f78 .set InputArray,0x8046b108 .set PlayerBlock_LoadPlayerGObj,0x8003418c /* NTSC101: .set Injection,0x800C97D0 .set OFST_PlCo,-0x514C .set InputIndex,0x804c1258 .set InputArray,0x8046a428 .set PlayerBlock_LoadPlayerGObj,0x8003418C NTSC100: .set Injection,0x800C968C .set OFST_PlCo,-0x514C .set InputIndex,0x804bfdf8 .set InputArray,0x80469140 .set PlayerBlock_LoadPlayerGObj,0x8003410C PAL100: .set Injection,0x800CA1E8 .set OFST_PlCo,-0x4F0C .set InputIndex,0x804b2ff8 .set InputArray,0x8045bf10 .set PlayerBlock_LoadPlayerGObj,0x80034780 */ #Original codeline stfs f0,0x2C(REG_PlayerData) # Entry point, store new facing direction #Init backup bl Floats mflr REG_Floats CHECK_IF_SLOW_TURN: lfs f1,0x894(REG_PlayerData) # Check if 2nd frame of turn lfs f2,OFST_SlowTurnFrame(REG_Floats) # 2fp fcmpo cr0,f1,f2 bne Injection_Exit CHECK_SMASH_TURN_INPUT_CONDITIONS: lwz r4,OFST_PlCo(r13) lfs f1,0x0620(REG_PlayerData) fabs f1,f1 lfs f2,0x3C(r4) #PlCo constant 0.8 fcmpo cr0,f1,f2 # Load control stick x-inputs and compare to 0.8 blt Injection_Exit #Check that cardinal direction not held 2+ frames lbz r3,0x0670(REG_PlayerData) cmpwi r3,2 bge- Injection_Exit # Skip if no dash input SKIP_IF_NANA: lbz r3,0x221f(REG_PlayerData) # load flags rlwinm. r0,r3,0,28,28 # (08) = secondary character bne Injection_Exit BEGIN_HW_INPUTS: LOAD_2_FRAMES_PAST_INPUTS: lbz REG_PrevInput, MEX_UCF2fX (REG_PlayerData) extsb REG_PrevInput,REG_PrevInput LOAD_CURRENT_FRAME_INPUT: lbz r3, MEX_UCFCurrX (REG_PlayerData) extsb r3,r3 CALCULATE_DIFFERENCE: sub r3,REG_PrevInput,r3 mullw r3, r3, r3 # Take square to get positive value for comparison THRESHOLD_TEST: cmpwi r3, 3600 # compare square of input difference between current frame and 2 frames ago to square of 60 (formerly 75 because different units) ble- Injection_Exit CHANGE_TO_SMASH_TURN: li r0, 1 stw r0, 0x2358(REG_PlayerData) stw r0, 0x2340(REG_PlayerData) # Change smash turn and can dash flags #Check if Popo lwz r4,0x4(REG_PlayerData) # Load character id cmpwi r4,0xA # Check if Popo bne+ Injection_Exit # Skip if not Popo #Get Nana's Block From Popo's in r4 lbz r3,0xC(REG_PlayerData) #P1 Slot li r4,0x1 #Subchar Bool branchl r12,PlayerBlock_LoadPlayerGObj cmpwi r3,0x0 beq Injection_Exit lwz r4,0x2C(r3) #Adjust Nana's inputs lwz r4,0x1ECC(r4) # Load address where popos inputs were last stored lfs f1,0x2C(REG_PlayerData) # get popos facing direction stfs f1,0x18(r4) # Store popos direction for nana #Check which direction popo turned lfs f2,OFST_ZeroFP(REG_Floats) #0fp fcmpo cr0,f1,f2 bgt- POPO_TURNED_RIGHT li r3,0x80 # leftward 1.0 b StoreNanaDirection POPO_TURNED_RIGHT: li r3,0x7f #rightward 1.0 StoreNanaDirection: stb r3,0x6(r4) # Store rightward 1.0 input for Nana b Injection_Exit Floats: .set OFST_SlowTurnFrame,0x0 .set OFST_ZeroFP,0x4 blrl .float 2 .float 0 .align 2 ################### Injection_Exit: restore ================================================ FILE: ASM/m-ex/UCF 0.8/UCF SD.asm ================================================ #To be inserted at 800998A4 .include "../../Globals.s" .include "../Header.s" .set REG_PlayerData,31 .set REG_PlayerGObj,30 .set REG_Floats,29 NTSC102: .set Injection,0x800998A4 .set OFST_PlCo,-0x514C /* NTSC101: .set Injection,0x800996E0 .set OFST_PlCo,-0x514C NTSC100: .set Injection,0x800995F8 .set OFST_PlCo,-0x514C PAL100: .set Injection,0x80099F5C .set OFST_PlCo,-0x4F0C */ backup #Init mr REG_PlayerGObj,r3 lwz REG_PlayerData,0x2C(REG_PlayerGObj) bl Floats mflr REG_Floats #Check if cstick is lfs f1, 0x63C (REG_PlayerData) lwz r3, OFST_PlCo (r13) lfs f0, 0x314 (r3) fcmpo cr0, f1, f0 ble- EnterSpotdodge #Check if left stick X is ? lfs f1, 0x620(REG_PlayerData) bl DoSomething stfs f1,0x90(sp) #Check if left stick Y is ? lfs f1, 0x624(REG_PlayerData) bl DoSomething lfs f2,0x90(sp) #Check if stick was pushed slow enough? fmuls f2, f2, f2 fmuls f1, f1, f1 fadds f1, f1, f2 lfs f2,OFST_1fp(REG_Floats) fcmpo cr0, f1, f2 blt EnterSpotdodge #Check if stick has been pushed horizontally for over 3 frames lbz r4, 0x670(REG_PlayerData) cmpwi r4, 3 ble- EnterSpotdodge #Check if stick Y is below -0.8 lfs f0,OFST_Unk4(REG_Floats) lfs f1, 0x624(REG_PlayerData) fcmpo cr0, f0, f1 bge- EnterSpotdodge #Exit spotdodge function without entering the state # this is very hacky and is how UCF 0.73 functions. # the reason this is used is because the spotdodge function is called # from 2 different places, so instead of making 2 injections, this is done. restore lwz r3, 0x001C (sp) lwz r31, 0x0014 (sp) addi sp, sp, 24 addi r3,r3,0x8 #skip to the end of the function we are coming from mtlr r3 blr ############################# DoSomething: #f1 = input fabs f0, f1 #Multiply by 80 lfs f1,OFST_Unk1(REG_Floats) fmuls f0, f0, f1 #Subtract 0.0001 lfs f1,OFST_Unk2(REG_Floats) fsubs f0, f0, f1 #Floor value fctiwz f0,f0 stfd f0,0x80(sp) lwz r3,0x84(sp) #Add 2 addi r3,r3,2 #Cast back lis r0, 0x4330 lfd f2, OFST_MagicNumber (REG_Floats) xoris r3, r3,0x8000 stw r0,0x80(sp) stw r3,0x84(sp) lfd f1,0x80(sp) fsubs f0,f1,f2 #Convert To Float #Divide by 80 lfs f1,OFST_Unk1(REG_Floats) fdivs f1, f0, f1 #Exit blr ############################# Floats: blrl .set OFST_Unk1,0x0 .set OFST_Unk2,0x4 .set OFST_Unk3,0x8 .set OFST_1fp,0xC .set OFST_Unk4,0x10 .set OFST_MagicNumber,0x14 .float 80 .long 0x37270000 .float 176 .float 1 .float -0.8 .long 0x43300000 .long 0x80000000 EnterSpotdodge: mr r3, REG_PlayerGObj mr r4, REG_PlayerData restore ================================================ FILE: ASM/m-ex/UCF 0.8/UCF Store Inputs CPU.asm ================================================ #To be inserted at 8006adf4 .include "../../Globals.s" .include "../Header.s" # Original Line stfs f1, 0x0624 (r31) # Update array of previous inputs lbz r3, MEX_UCFPrevX(r31) stb r3, MEX_UCF2fX(r31) lbz r3, MEX_UCFCurrX(r31) stb r3, MEX_UCFPrevX(r31) # Store current lbz r3, 0x1A8C (r31) stb r3, MEX_UCFCurrX(r31) ================================================ FILE: ASM/m-ex/UCF 0.8/UCF Store Inputs.asm ================================================ #To be inserted at 8006ae8c .include "../../Globals.s" .include "../Header.s" # Original Line stfs f0, 0x0624 (r31) # Update array of previous inputs lbz r4, MEX_UCFPrevX(r31) stb r4, MEX_UCF2fX(r31) lbz r4, MEX_UCFCurrX(r31) stb r4, MEX_UCFPrevX(r31) # Store current lbz r4,0x18(r3) stb r4, MEX_UCFCurrX(r31) ================================================ FILE: ASM/m-ex/UCF 0.8/UCF Text.asm ================================================ #To be inserted @ 802662D0 .include "../../Globals.s" .include "../Header.s" .set REG_TextGObj,31 .set REG_TextProperties,30 NTSC102: .set Injection,0x802662D0 .set Text_CreateTextGObj,0x803a6754 .set Text_InitializeSubtext,0x803a6b98 .set Text_UpdateSubtextSize,0x803a7548 /* NTSC101: .set Injection,0x80265B34 .set Text_CreateTextGObj,0x803A5A74 .set Text_InitializeSubtext,0x803A5EB8 .set Text_UpdateSubtextSize,0x803A6868 NTSC100: .set Injection,0x80264FB8 .set Text_CreateTextGObj,0x803A4890 .set Text_InitializeSubtext,0x803A4CD4 .set Text_UpdateSubtextSize,0x803A5684 PAL100: .set Injection,0x802669EC .set Text_CreateTextGObj,0x803A6664 .set Text_InitializeSubtext,0x803a6b54 .set Text_UpdateSubtextSize,0x803A74FC */ backup #GET PROPERTIES TABLE bl TEXTPROPERTIES mflr REG_TextProperties ######################## ## Create Text Object ## ######################## #CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3 li r3,0 li r4,0 branchl r14,Text_CreateTextGObj #BACKUP STRUCT POINTER mr REG_TextGObj,r3 #SET TEXT SPACING TO TIGHT li r4,0x1 stb r4,0x49(REG_TextGObj) #SET TEXT TO CENTER AROUND X LOCATION li r4,0x1 stb r4,0x4A(REG_TextGObj) #Scale Canvas Down lfs f1,0xC(REG_TextProperties) stfs f1,0x24(REG_TextGObj) stfs f1,0x28(REG_TextGObj) #################################### ## INITIALIZE PROPERTIES AND TEXT ## #################################### #Initialize Line of Text mr r3,REG_TextGObj #struct pointer bl TEXT mflr r4 #pointer to ASCII lfs f1,0x0(REG_TextProperties) #X offset of REG_TextGObj lfs f2,0x4(REG_TextProperties) #Y offset of REG_TextGObj branchl r14,Text_InitializeSubtext #Set Size/Scaling mr r4,r3 mr r3,REG_TextGObj lfs f1,0x8(REG_TextProperties) #get REG_TextGObj scaling value from table lfs f2,0x8(REG_TextProperties) #get REG_TextGObj scaling value from table branchl r12,Text_UpdateSubtextSize b end #**************************************************# TEXTPROPERTIES: blrl .float 38 #x offset .float -275 #y offset .float 0.45 #REG_TextGObj scaling .float 0.1 #canvas scaling TEXT: blrl .string "UCF 0.8" .align 2 #**************************************************# end: restore addi r4, r24, 0 ================================================ FILE: ASM/m-ex/UCF 0.8/UCF Tumble.asm ================================================ #To be inserted at 800908f4 .include "../../Globals.s" .include "../Header.s" .set REG_PlayerData,31 .set REG_InputIndex,30 .set REG_PrevInput,29 .set REG_HSDPad,28 .set OFST_PlCo,-0x514C .set HSD_Pad,0x804c1f78 #r31 @ 0x80377DC0 backup #Cardinal direction held check: # 0 = successful vanilla wiggle (branch out with cr0 less than bit true) # 1 = continue to check additional conditions # 2+ = wiggle fail due to input held, (branch out with cr0 less than bit false) cmpwi r3, 1 bne- END #Ensure last frame < 0.8 lfs f1,0x628(REG_PlayerData) fabs f1,f1 lwz r3,OFST_PlCo(r13) lfs f2,0x210(r3) fcmpo cr0,f1,f2 bge END BEGIN_HW_INPUTS: LOAD_2_FRAMES_PAST_INPUTS: lbz REG_PrevInput, MEX_UCF2fX (REG_PlayerData) extsb REG_PrevInput,REG_PrevInput LOAD_CURRENT_FRAME_INPUT: lbz r3, MEX_UCFCurrX (REG_PlayerData) extsb r3,r3 CALCULATE_DIFFERENCE: sub r3,REG_PrevInput,r3 mullw r3, r3, r3 # Take square to get positive value for comparison THRESHOLD_TEST: li r4, 3600 # compare square of input difference between current frame and 2 frames ago to square of 60 (formerly 75 because different units) cmpw r4, r3 b END END: restore ================================================ FILE: ASM/training-mode/Custom Events/A+B to Reset Event/Check for Reset on Game End.asm ================================================ #To be inserted at 801bba38 .include "../../Globals.s" .include "../../../m-ex/Header.s" #Get all players inputs li r3,4 branchl r12,0x801a3680 #Check Inputs rlwinm. r0, r4, 0, 23, 23 #check A beq- Original rlwinm. r0, r4, 0, 22, 22 #check B beq- Original Runback: branch r12,0x801bb7a0 Original: li r3, 1 ================================================ FILE: ASM/training-mode/Custom Events/A+B to Reset Event/Check for Reset on LRAStart.asm ================================================ #To be inserted at 801bb844 .include "../../Globals.s" .include "../../../m-ex/Header.s" #Get all players inputs li r3,4 branchl r12,0x801a3680 #Check Inputs rlwinm. r0, r4, 0, 23, 23 #check A beq- Original rlwinm. r0, r4, 0, 22, 22 #check B beq- Original Runback: branch r12,0x801bb7a0 Original: li r3, 1 ================================================ FILE: ASM/training-mode/Custom Events/CSS and SSS/Add SSS To Event Match Scene List.asm ================================================ #To be inserted at 801a44bc .include "../../Globals.s" .include "../../../m-ex/Header.s" ################################################## #Overwrite Event Scene List bl EventSceneList mflr r3 load r4,0x803db010 stw r3,0x0(r4) #Overwrite SSS_SceneDecide bl SSS_SceneDecide mflr r4 stw r4,0x38(r3) #Overwrite MainMenu Scene List bl MainMenuSceneList mflr r3 load r4,0x803dae44 stw r3,0x0(r4) #Overwrite Credits_SceneDecide bl Credits_SceneDecide mflr r4 stw r4,0x20(r3) b exit ############################################### #Event Scene List Pointer @ 0x803db010 EventSceneList: blrl #CSS .long 0x00030000 .long 0x801baa60 .long 0x801baad0 .long 0x08000000 .long 0x80497758 .long 0x80497758 #In-Match .long 0x01030000 .long 0x801bad70 .long 0x801bb758 .long 0x02000000 .long 0x804978a0 .long 0x804979d8 #SSS .long 0x02030000 .long 0x801b1eb8 .long 0x801b1eec .long 0x09000000 .long 0x80497758 .long 0x80497758 .long 0xFF000000 ################################ SSS_SceneDecide: blrl backup #Get Minor Scenes Data Pointer lwz r3, 0x0014 (r3) #Get Method of Leaving SSS lbz r0, 0x0004 (r3) cmpwi r0,0x0 beq SSS_SceneDecide_BackToCSS SSS_SceneDecide_AdvanceToMatch: #Match Minor ID li r3,0x2 b SSS_SceneDecide_Exit SSS_SceneDecide_BackToCSS: li r3,0x1 SSS_SceneDecide_Exit: #Store Next Minor load r4,SceneController stb r3,0x5(r4) restore blr ################################ ################################ MainMenuSceneList: blrl #MainMenu .long 0x00020000 .long 0x801b0ff8 .long 0x801b138c .long 0x01000000 .long 0x804d68b8 .long 0x804d68bc #Credits .long 0x01030000 .long 0x00000000 .long 0xFFFFFFFF .long 0x2B000000 .long 0x00000000 .long 0x00000000 .long 0xFF000000 ################################ Credits_SceneDecide: blrl #Store Next Minor load r4,SceneController li r3,0x0 stb r3,0x5(r4) blr ################################# exit: mr r3, r30 ================================================ FILE: ASM/training-mode/Custom Events/CSS and SSS/Backup HMN And CPU Choices/Backup Event CPU.asm ================================================ #To be inserted at 801bab18 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" #Get Backup Location lwz r9, -0x77C0 (r13) addi r9,r9,3344 #Backup HMN Character Choice lwz r3,CSS_Data(r13) #CSS Match Info addi r4,r9,104 #Character Backup Location li r5,0 #Unk Backup Location addi r6,r9,107 #Costume Backup Location addi r7,r9,114 #Nametag Backup Location li r8,0 #Unk Backup Location branchl r12,0x801b0730 #Also copy to Event's CSS Backup Data for compatibility #Get Backup Location lwz r9, -0x77C0 (r13) addi r9, r9, 1328 #Backup HMN Character Choice lwz r3,CSS_Data(r13) #CSS Match Info addi r4,r9,2 #Character Backup Location li r5,0 #Unk Backup Location addi r6,r9,3 #Costume Backup Location addi r7,r9,4 #Nametag Backup Location li r8,0 #Unk Backup Location branchl r12,0x801b0730 #Get Backup Location lwz r9, -0x77C0 (r13) addi r9,r9,3344 #Backup CPU Character Choice lwz r3,CSS_Data(r13) #CSS Match Info addi r4,r9,140 #Character Backup Location li r5,0 #Unk Backup Location addi r6,r9,143 #Costume Backup Location addi r7,r9,150 #Nametag Backup Location li r8,0 #Unk Backup Location branchl r12,0x801b07e8 ================================================ FILE: ASM/training-mode/Custom Events/CSS and SSS/Backup HMN And CPU Choices/Restore Event CPU.asm ================================================ #To be inserted at 801baa98 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" #Get Backup Location lwz r9, -0x77C0 (r13) addi r9,r9,3344 #Restore HMN Character Choice load r3,0x80497758 #CSS Match Info #mr r4,r4 #CSS Type lbz r5,104(r9) #Character Backup li r6,0 #Unk lbz r7,107(r9) #Costume Backup lbz r8,114(r9) #Nametag Backup Location li r9,0 #Unk Backup Location lbz r10, 0x0006 (r31) #Player who accessed CSS branchl r12,0x801b06b0 #Get Backup Location lwz r9, -0x77C0 (r13) addi r9,r9,3344 #Backup CPU Character Choice load r3,0x80497758 #CSS Match Info lbz r4,140(r9) #Character Backup li r5,1 #Unk lbz r6,143(r9) #Costume Backup lbz r7,150(r9) #Nametag Backup li r8,0 lbz r9, 0x0006 (r31) #Player who accessed CSS branchl r12,0x801b07b4 ================================================ FILE: ASM/training-mode/Custom Events/CSS and SSS/Display Event Name on CSS.asm ================================================ #To be inserted at 80264504 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set text,31 .set textProperties,30 .set EventName,29 #r24 = text struct #r27 = Event ID #Ensure this is event mode load r3,SceneController lbz r3,Scene.CurrentMajor(r3) cmpwi r3,Scene.EventMode bne Original #Check For Custom Event lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) lwz r4, -0x77C0 (r13) lbz r4, 0x0535 (r4) #get event ID rtocbl r12,TM_GetEventName #Save Text mr EventName,r3 #GET PROPERTIES TABLE bl TEXTPROPERTIES mflr textProperties ######################## ## Create Text Object ## ######################## #CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3 li r3,0 li r4,0 branchl r12,0x803a6754 #BACKUP STRUCT POINTER mr text,r3 #SET TEXT SPACING TO TIGHT li r4,0x1 stb r4,0x49(text) #SET TEXT TO CENTER AROUND X LOCATION li r4,0x1 stb r4,0x4A(text) #Scale Canvas Down lfs f1,0xC(textProperties) stfs f1,0x24(text) stfs f1,0x28(text) #################################### ## INITIALIZE PROPERTIES AND TEXT ## #################################### #Initialize Line of Text mr r3,text #struct pointer mr r4,EventName #pointer to ASCII lfs f1,0x0(textProperties) #X offset of text lfs f2,0x4(textProperties) #Y offset of text branchl r12,0x803a6b98 #Set Size/Scaling mr r4,r3 mr r3,text lfs f1,0x8(textProperties) #get text scaling value from table lfs f2,0x8(textProperties) #get text scaling value from table branchl r12,0x803a7548 b Original #**************************************************# TEXTPROPERTIES: blrl .float 38 #x offset .float -245 #y offset .float 0.65 #text scaling .float 0.1 #canvas scaling #**************************************************# VanillaEvent: Original: li r3, 4 ================================================ FILE: ASM/training-mode/Custom Events/CSS and SSS/Load CSS + Preload CPU.asm ================================================ #To be inserted at 801baa80 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set REG_Stage,26 .set REG_CPU,27 .set REG_CSSType,28 .set EventID,29 .set PageID,30 .set REG_SceneData,31 backup #Save scene data mr REG_SceneData,r3 #Get Current Event Number lwz r4, -0x77C0 (r13) lbz EventID, 0x0535 (r4) #Get Current Page in lwz r4,MemcardData(r13) lbz PageID,CurrentEventPage(r4) #Get this events CSS Type mr r3,PageID mr r4,EventID rtocbl r12,TM_GetIsChooseCPU cmpwi r3,0x0 beq EventCSS TrainingCSS: li REG_CSSType,0x17 b CheckToPreloadCPU EventCSS: li REG_CSSType,14 b CheckToPreloadCPU CheckToPreloadCPU: #Check if this event has a pre-determined CPU mr r3,PageID mr r4,EventID rtocbl r12,TM_GetCPUFighter extsb REG_CPU,r3 CheckToPreloadStage: #Check if this event has a pre-determined stage mr r3,PageID mr r4,EventID rtocbl r12,TM_GetStage extsb REG_Stage,r3 UpdatePreloadTable: #Store Preload load r3,PreloadTable cmpwi REG_CPU,-1 beq UpdatePreloadTable_CheckStage stw REG_CPU,0x1C(r3) #p2 character UpdatePreloadTable_CheckStage: cmpwi REG_Stage,-1 beq Exit stw REG_Stage,0x10(r3) #stage b Exit Exit: mr r4,REG_CSSType #Return CSS Choice mr r3,REG_SceneData #Restore scene data restore lbz r5, 0x0002 (r31) #get r5 again since we clobbered it ================================================ FILE: ASM/training-mode/Custom Events/CSS and SSS/Load SSS For Certain Events.asm ================================================ #To be inserted at 801bab28 .include "../../Globals.s" .include "../../../m-ex/Header.s" stb r0, 0x000A (r31) #Get Event ID lwz r3, -0x77C0 (r13) lbz r4, 0x0535 (r3) lbz r3,CurrentEventPage(r3) #Check if this event has a SSS rtocbl r12,TM_GetIsSelectStage cmpwi r3,0 beq original SSS: #Store SSS as Next Scene load r3,SceneController li r4,0x3 stb r4,0x5(r3) original: ================================================ FILE: ASM/training-mode/Custom Events/CSS and SSS/Toggle CSS Icon Vibibility/Toggle CSS Icon Vibibility.asm ================================================ #To be inserted at 80264578 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" backup .set REG_GObj,31 .set REG_Data,30 .set REG_Whitelist,29 #Ensure this is event mode load r3,SceneController lbz r3,Scene.CurrentMajor(r3) cmpwi r3,Scene.EventMode bne Original #Create GObj li r3,4 li r4,5 li r5,0 branchl r12,GObj_Create mr REG_GObj,r3 #Create Data li r3,8 branchl r12,HSD_MemAlloc mr REG_Data,r3 #Attach Data mr r3,REG_GObj li r4,14 load r5,HSD_Free mr r6,REG_Data branchl r12,GObj_AddUserData #Attach Process bl ToggleCSSIcon mflr r4 li r5,2 #Priority (after CSS_BigFunctionMonitorInputsAndMore) branchl r12,GObj_AddProc #Store Whitelist to GObj Data bl GetCharacterList stw r3,0x0(REG_Data) mr REG_Whitelist,r3 #Check if exists cmpwi REG_Whitelist,-1 beq Original #Make P1 Undecided lwz r20,CSS_Data(r13) #CSS Match Info addi r4,r20,0x70 #Get Player Info Start lhz r5,0x0(r20) #Get Player in control of CSS subi r5,r5,1 #Zero index cause Yasuyuki Nagashima is dumb mulli r5,r5,36 add r4,r4,r5 #r4 now contains the players info #Check if 0x21 (N/A) li r3,0x21 stb r3,0x0(r4) # COME BACK TO THIS CODE WHEN I MAKE AN EVENT # THAT HAS A SELECT AMOUNT OF CPU'S AVAILABLE /* CheckCPU: #Ensure CPU is a whitelisted character lwz r20,CSS_Data(r13) #CSS Match Info addi r4,r20,0x78 #Get Player Info Start lhz r5,0x0(r20) #Get Player in control of CSS subic. r5,r5,1 #Zero index cause Yasuyuki Nagashima is dumb bne 0x8 li r5,1 b 0x8 li r5,0 mulli r5,r5,36 add r4,r4,r5 #r4 now contains the players info addi r3,REG_Whitelist,4 #CPU whitelist bl CheckWhitelist */ b Original ####################### ToggleCSSIcon: blrl .set REG_Whitelist,31 backup #Get Whitelist lwz r3,0x2C(r3) lwz REG_Whitelist,0x0(r3) #Check if whitelist exists cmpwi REG_Whitelist,-1 beq ToggleCSSIcon_Exit ToggleCSSIcon_Start: #Get P1's Cursor Data load r3,CSS_CursorPointers #Load CSS Cursor Pointers lwz r5,0x0(r3) #Get P1's Cursor Data #Check if holding a puck lbz r3,0x5(r5) #Check hand state cmpwi r3,0x1 bne ToggleCSSIcon_HoldingP1Puck #Check if holding P1's puck lbz r3,0x6(r5) cmpwi r3,0x0 beq ToggleCSSIcon_HoldingP1Puck #Check if holding CPU's puck cmpwi r3,0x1 beq ToggleCSSIcon_HoldingCPUPuck b ToggleCSSIcon_Exit ToggleCSSIcon_HoldingP1Puck: mr r3,REG_Whitelist bl ToggleCSSIcon_ToggleSelectedIcons b ToggleCSSIcon_Exit ToggleCSSIcon_HoldingCPUPuck: addi r3,REG_Whitelist,0x4 #CPU List is at 0x4 bl ToggleCSSIcon_ToggleSelectedIcons b ToggleCSSIcon_Exit ToggleCSSIcon_Exit: restore blr #******************************# ############################ ## Show Whitelisted Chars ## ############################ ToggleCSSIcon_ToggleSelectedIcons: .set REG_IconDataStart,31 .set REG_Whitelist,30 .set REG_IconData,29 .set REG_VisibilityBool,28 .set REG_LoopCount,27 backup ToggleCSSIcon_ToggleSelectedIconsInit: #Init Stuff lwz REG_Whitelist,0x0(r3) li REG_LoopCount,25 load REG_IconDataStart,0x803f0b24 b ToggleCSSIcon_ToggleSelectedIconsIncLoop ToggleCSSIcon_ToggleSelectedIconsLoop: #Get Icons Data mulli r3,REG_LoopCount,0x1C add REG_IconData,r3,REG_IconDataStart #Check if icon should be visible li r3, 1 slw r0, r3, REG_LoopCount and. r0, r0, REG_Whitelist bne ToggleCSSIcon_ToggleSelectedIcons_Display ToggleCSSIcon_ToggleSelectedIcons_Hide: li REG_VisibilityBool,0 b 0x8 ToggleCSSIcon_ToggleSelectedIcons_Display: li REG_VisibilityBool,1 #Set Invisible #Get JObj lwz r3, -0x49E0 (r13) addi r4,sp,0x80 lbz r5,0x5(REG_IconData) crclr 6 li r6,-1 branchl r12,0x80011e24 #Toggle invisibility flag lwz r3,0x80(sp) li r5,1 cmpwi REG_VisibilityBool,0 beq 0x8 li r5,0 lwz r4,0x14(r3) rlwimi r4,r5,4,27,27 stw r4,0x14(r3) #Set interactable li r3,0 cmpwi REG_VisibilityBool,0 beq 0x8 li r3,2 stb r3,0x2(REG_IconData) ToggleCSSIcon_ToggleSelectedIconsIncLoop: subi REG_LoopCount,REG_LoopCount,1 cmpwi REG_LoopCount,0 bge ToggleCSSIcon_ToggleSelectedIconsLoop ToggleCSSIcon_ToggleSelectedIconsExit: restore blr ####################### GetCharacterList: backup .set EventID,31 .set PageID,30 #Get Hovered Over Event ID in r23 lwz r4, -0x77C0 (r13) lbz EventID, 0x0535 (r4) #Get Current Page lbz PageID,CurrentEventPage(r4) #Get pointer page's string array bl GetCharacterList_SkipJumpTable ##### Page List ####### EventJumpTable ####################### GetCharacterList_SkipJumpTable: mflr r4 #Jump Table Start in r4 mulli r5,PageID,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r6,r4,r5 #Gets Address in r6 #Loop Through Whitelisted Events GetCharacterList_Loop: lbzu r3,0x0(r6) extsb r0,r3 cmpwi r0,-1 beq GetCharacterList_Failed cmpw r3,EventID beq GetCharacterList_Success addi r6,r6,0x9 b GetCharacterList_Loop GetCharacterList_Failed: li r3,-1 b GetCharacterList_Exit GetCharacterList_Success: addi r3,r6,1 GetCharacterList_Exit: restore blr ####################### CheckWhitelist: backup .set REG_PlayerPointer,31 .set REG_Whitelist,30 .set REG_CSSID,29 #Backup registers mr REG_Whitelist,r3 mr REG_PlayerPointer,r4 #Check if no character selected #Get CSS ID From External bl ExternalToCSSID mflr r3 lbz r4,0x0(REG_PlayerPointer) lbzx REG_CSSID,r4,r3 CheckWhitelist_Exit: restore blr ####################### #******************************# EventPlayableCharacters #******************************# ExternalToCSSID: blrl .byte Doc_CSSID, Mario_CSSID, Luigi_CSSID, Bowser_CSSID, Peach_CSSID, Yoshi_CSSID, DK_CSSID, CaptainFalcon_CSSID, Ganondorf_CSSID, Falco_CSSID, Fox_CSSID, Ness_CSSID, IceClimbers_CSSID, Kirby_CSSID, Samus_CSSID, Zelda_CSSID, Link_CSSID, YLink_CSSID, Pichu_CSSID, Pikachu_CSSID, Jigglypuff_CSSID, Mewtwo_CSSID, GaW_CSSID, Marth_CSSID, Roy_CSSID .align 2 #******************************# Original: restore lbz r4, -0x3E57 (r13) ================================================ FILE: ASM/training-mode/Custom Events/Credits Codes/Don't Display Info In TM Credits.asm ================================================ #To be inserted at 801abb1c .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set player,31 .set playerdata,31 load r3,SceneController lbz r3,0x0(r3) cmpwi r3,0x1 bne exit branch r12,0x801abdf4 exit: lwz r3, 0 (r23) ================================================ FILE: ASM/training-mode/Custom Events/Credits Codes/Don't Display Titles In Training Mode Credits.asm ================================================ #To be inserted at 801aae50 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set player,31 .set playerdata,31 .set text,31 load r5,SceneController lbz r5,0x0(r5) cmpwi r5,0x1 #Main Menu beq Skip branchl r12,0x803a6368 Skip: ================================================ FILE: ASM/training-mode/Custom Events/Credits Codes/Swap Out Credit Names in TM Credits.asm ================================================ #To be inserted at 801aac60 #80100000 .include "../../Globals.s" .include "../../../m-ex/Header.s" b FunctionStart Names: blrl .string "Charlotte" .string "Hugh N" .string "HARB" .string "Cyrus R" .string "ravecake" .string "Jeremy" .string "Dominick T" .string "Robert P" .string "Jonathan B" .string "Daniel F" .string "Marshall Z" .string "Thomas B" .string "Rishi" .string "KELLZ" .string "Turkey" .string "Outside" .string "Jesse" .string "BenSW" .string "Setchi " .string "Jimmy M" .string "Micah S" .string "Avi" .string "YungZunga" .string "Randle J" .string "Andreas H" .string "Calszone" .string "Riley D" .string "Anthony C" .string "Kevin T" .string "Zane R" .string "Gage K" .string "Ari" .string "Vitral" .string "CF True" .string "yardsale" .string "James L" .string "Zach N" .string "Sir Lemon" .string "Matt B" .string "Max S" .string "RealDingos " .string "Wasif R" .string "femboy uwu" .string "Spencer G" .string "Ben A" .string "William R" .string "KJH" .string "Reeve" .string "Christian A" .string "Esteban H" .string "Forrest G" .string "Aiden C" .string "Grolex" .string "Manuel P" .string "Methorphan" .string "bofftarget" .string "Mark M" .string "Reece E" .string "Ka Ming AC" .string "BONSAI BOYS" .string "Jean T" .string "Jon" .string "Stuart K" .string "Mike R" .string "James" .string "Miller T" .string "Darren M" .string "ShaggyJ" .string "Bryan K" .string "Collin B" .string "Lucas S" .string "jeremiah K" .string "Will A" .string "Eacab" .string "Maccrea P" .string "Justin H" .string "Zach J" .string "Brandt W" .string "Gene K" .string "Jaycob A" .string "Joseph R" .string "blandeezy" .string "Vim" .string "roob adoob" .string "Sami B" .string "Blake P" .string "Charlon" .string "Aldrin R" .string "Jane L" .string "Martin R" .string "Stephane S" .string "Greg W" .string "Delano W" .string "Kyle S" .string "K OBrien" .string "Albert Z" .string "Lykon" .string "Benjamin E" .string "Dave S" .string "Jordan J" .string "Gear" .string "Fritz" .string "Jeff J" .string "Dalton G" .string "Trevor C" .string "Chad S" .string "Brit B" .string "Austin D" .string "Micah W" .string "Jonathon M" .string "Jason V" .string "Marvin S" .string "Glenn T" .string "Jordan M" .string "Bj C" .string "Lucio" .string "Benno K" .string "Bernando B" .string "Kaveh A" .string "Thomas R" .string "Austin L" .string "Brennan R" .string "Anthony G" .string "Ryan M" .string "Tony K" .string "Shane K" .string "Andrew W" .string "Vincent T" .string "Ali S" .string "Nathan H" .string "Maxime C" .string "Riley B" .string "cagliostro9" .string "Jonathan M" .string "Rafa M" .string "Lucuius M" .string "Julie M" .string "Sergio D" .string "Andre MLO" .string "Juan D" .string "Andrew Y" .string "Fabadam" .string "Tony R" .string "Daniel C" .string "Derex E" .string "Chris C" .string "Samuel CD" .string "Melee Stats" .string "George G" .string "Joey A" .string "Stephan M" .string "Jason S" .string "Kris S" .string "Mikey R" .string "Jake M" .string "Liam M" .string "Andy C" .string "Sunset" .string "Dylan M" .string "Will N" .string "+" .string "Matthew L" .string "Matthew P" .string "Aiden F" .string "Michael O" .string "Drew D" .string "Tyler M" .string "+" .string "masafumsa" .string "Nathan S" .string "Quentin F" .string "Bobby Scar" .string "OuterHalo" .string "Max R" .string "TruckJitsu" .string "Seth M" .string "Jamie C" .string "Eddie A" .string "Cody N" .string "Joel" .string "Kalvar" .string "Armando C" .string "+" .string "+" .string "Special Thanks" .string "Achilles" .string "Dan Salvato" .string "Punkline" .string "DRGN" .string "Fizzi" .string "Minute Melee" .string "Dolphin-Emu" .string "Gecko OS" .string "" .string "" .string "" .string "Thanks to all my patrons who supported this project! www.twitter.com/UnclePunch_ www.patreon.com/UnclePunch" .align 2 FunctionStart: .set FirstNameToReplace,2 .set LastNameToReplace,196 .set text,30 backup #Check For TM Credits load r3,SceneController lbz r3,0x0(r3) cmpwi r3,0x1 bne Exit #Only Display After the First 2 Names CheckWhitelist: lwz r3, -0x4eac (r13) cmpwi r3,FirstNameToReplace blt Exit cmpwi r3,LastNameToReplace bgt Exit #Create Text li r3,0 li r4,0 branchl r12,0x803a6754 mr text,r3 #Init Some Values li r0,1 stb r0,0x4C(text) stb r0,0x4A(text) stb r0,0x49(text) stfs f30, 0x0024 (text) stfs f29, 0x0028 (text) lfs f1, -0x4F10 (rtoc) lfs f2, -0x4F0C (rtoc) lfs f3, -0x4F08 (rtoc) stfs f1,0x00(text) stfs f2,0x04(text) stfs f1,0x08(text) stfs f1,0x0C(text) stfs f3,0x10(text) #Store Pointer lwz r3, -0x4EA8 (r13) stwx text, r3, r31 ConvertToMenuText: #Get Text As Menu Text lwz r3, -0x4EAC (r13) bl Names mflr r4 branchl r12,SearchStringTable mr r4,r3 addi r3,sp,0x40 branchl r12,0x803a67ec mr r20,r3 #Backup text length #Get Text Struct Pointer lwz r3, -0x4EA8 (r13) lwzx text, r3, r31 #Get Allocation Info Pointer lwz r21,0x64(text) #Check To Adjust Allocation lwz r22, 0x0004 (r21) #Get old menu text allocation lwz r0, 0 (r21) lwz r4, 0x0008 (r21) #Get size of allocation sub r3, r0, r22 addi r0, r3, 17 add r0, r20, r0 cmplw r4, r0 bge- NoAdjustAllocation sub r0, r0, r4 rlwinm r3, r0, 25, 7, 31 addi r0, r3, 1 rlwinm r0, r0, 7, 0, 24 add r0, r4, r0 stw r0, 0x0008 (r21) lwz r3, 0x0008 (r21) branchl r12,0x803A5798 addi r5, r22, 0 addi r4, r3, 0 li r7, 0 b ReAllocateLoop_Inc ReAllocateLoop: lbz r0, 0 (r5) addi r7, r7, 1 addi r5, r5, 1 stb r0, 0 (r4) addi r4, r4, 1 ReAllocateLoop_Inc: lwz r6, 0x0004 (r21) lwz r0, 0 (r21) sub r6, r0, r6 addi r0, r6, 1 cmpw r7, r0 blt+ ReAllocateLoop stw r3, 0x0004 (r21) stw r3, 0x005C (text) lwz r0, 0 (r21) sub r0, r0, r22 add r0, r3, r0 stw r0, 0 (r21) mr r3, r22 branchl r12,0x803A594C NoAdjustAllocation: #Copy new text to text struct lwz r3,0x5C(text) addi r4,sp,0x40 mr r5,r20 branchl r12,memcpy #Add Terminator li r3,0x1900 lwz r4,0x5C(text) sthx r3,r20,r4 b CustomExit CustomExit: #Inc Name Count lwz r3, -0x4eac (r13) addi r3,r3,0x1 stw r3, -0x4eac (r13) restore branch r12,0x801aadb8 Exit: lwz r3, -0x4eac (r13) addi r3,r3,0x1 stw r3, -0x4eac (r13) restore lfs f1, -0x4F10 (rtoc) ================================================ FILE: ASM/training-mode/Custom Events/Custom Event Code - Legacy.s ================================================ #To be inserted at 801bb128 .include "../Globals.s" #r25 = event ID #r26 = final match struct #r28 = same as r26 #r29 = event struct index (0x0 of this, then 0x8 of that to get the specifics) #region Event and Menu GObj Data Structs #Event GObj Data Struct .set EventData_DataSize,0x50 .set EventData_MenuDataPointer,(EventData_DataSize-0x4) .set EventData_SaveStateStruct,0x10 #Menu GObj Data Struct .set MenuData_DataSize,0x50 .set MenuData_EventDataPointer,(MenuData_DataSize-0x4) .set MenuData_WindowOptionCountPointer,0x0 .set MenuData_ASCIIStructPointer,0x4 .set MenuData_OptionMenuMemory,0x8 .set MenuData_OptionMenuToggled,0x28 #endregion #region Init Custom Event ################# ## Custom Code ## ################# #all registers free #1 PLAYER, NO ITEMS, TIME COUNTING UP lwz r9,0x0(r29) #get event pointers #ZERO OUT p2-p6 STRUCT li r4,0x0 stw r4,0x18(r9) stw r4,0x1C(r9) stw r4,0x20(r9) stw r4,0x24(r9) stw r4,0x28(r9) #Disable All-Star Flag li r3,0x0 stb r3,0x0(r9) #P1 = Choose Char + Normal Modifiers bl P1Struct mflr r3 stw r3,0x14(r9) #STORE MATCH SETTINGS load r3,0x0BB0027C #HUD and timer behavior stw r3,0x0(r26) load r3,0x90800000 stw r3,0x4(r26) #think functions li r3,0xFF stb r3,0xB(r26) #items to none li r3,0x0 stw r3,0x10(r26) #time amount #STORE UNLIM STOCKS li r3,0xFF stb r3,0x62(r26) #p1 stocks #SET FALL FLAG li r3,0x0 stb r3,0x6C(r26) #SET FFA FLAG li r3,0 stb r3,0x8(r26) #Store SSS Stage load r3,0x80497758 lha r4, 0x001E (r3) sth r4,0xE(r26) #Get Event Code bl SkipPageList ##### Page List ####### EventJumpTable ####################### Minigames: bl Eggs bl Multishine bl Reaction bl LedgeStall .long -1 ####################### GeneralTech: bl LCancel bl Ledgedash bl ComboTraining bl AttackOnShield bl Reversal bl SDITraining bl Powershield bl Ledgetech bl AmsahTech bl ShieldDrop bl WaveshineSDI bl SlideOff bl GrabMashOut .long -1 ####################### SpacieTech: bl LedgetechCounter bl ArmadaShine bl SideBSweetspot bl EscapeSheik .long -1 ####################### SkipPageList: #Get Page Jump Table mflr r4 #Jump Table Start in r4 #Get Current Page lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) mulli r5,r3,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r4,r4,r5 #Gets ASCII Address in r4 #Get Event Code Pointer mulli r5,r25,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction cmpwi r5,-1 beq EventNoExist rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r4,r4,r5 #Gets ASCII Address in r4 mtctr r4 bctr EventNoExist: b exit #endregion ############### ## Minigames ## ############### #region Eggs-ercise ######################### ## Eggs-ercise HIJACK INFO ## ######################### Eggs: #COUNT DOWN TIME li r3,0x6 stb r3,0x0(r26) #1 Minute On the Clock li r3,60 stw r3,0x10(r26) #Store Match Type to READY, GO! li r3,0x80 stb r3,0x1(r26) #SET EVENT TYPE TO KOs load r5,0x8045abf0 #Static Match Struct lbz r3,0xB(r5) #Get Event Score Behavior Byte li r4,0x0 rlwimi r3,r4,1,30,30 #Zero Out Time Bit stb r3,0xB(r5) #Set Event Score Behavior Byte #1 Player lwz r4,0x0(r29) li r3,0x20 stb r3,0x1(r4) #STORE THINK FUNCTION bl EggsLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Eggs-ercise LOAD FUNCT ## ######################## EggsLoad: blrl backup #Schedule Think #r3 = function to run each frame #r4 = priority #r5 = pointer to Window and Option Count #r6 = pointer to ASCII struct bl EggsThink mflr r3 li r4,9 #Priority (After Interrupt) bl EggsWindowInfo mflr r5 bl EggsWindowText mflr r6 bl CreateEventThinkFunction bl InitializeHighScore b EggsLoadExit ######################### ## Eggs-ercise THINK FUNCT ## ######################### #Registers .set EventData,31 .set MenuData,26 .set P1Data,27 .set P1GObj,28 #Offsets .set DamageThreshold,(MenuData_OptionMenuMemory+0x2) +0x0 .set DamageThresholdToggled,(MenuData_OptionMenuToggled) +0x0 EggsThink: blrl backup #Get and Backup Event Data mr r30,r3 #r30 = think entity lwz EventData,0x2c(r3) #backup data pointer in r31 lwz MenuData,EventData_MenuDataPointer(EventData) #Get Player Data bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 #No Staling bl ResetStaleMoves #Check If Free Practice lbz r3,0x5(r31) cmpwi r3,0x0 bne EggsSkipFreePracticeCheck #Check DPad Down lwz r0,0x668(r27) rlwinm. r0,r0,0,29,29 beq EggsSkipFreePracticeCheck #Toggle Free Practice On li r3,0x1 stb r3,0x5(r31) #Timer Now Counts Up load r3,0x8046b6a0 lbz r0,0x24C8(r3) li r4,1 rlwimi r0,r4,0,31,31 stb r0,0x24C8(r3) #Play Sound To Indicate li r3,0x82 branchl r12,SFX_PlaySoundAtFullVolume EggsSkipFreePracticeCheck: #Check If Toggled lbz r3,DamageThresholdToggled(MenuData) cmpwi r3,0x0 beq EggsSkipToggleCheck #Check If Already Free Practice lbz r3,0x5(r31) cmpwi r3,0x0 bne EggsSkipToggleCheck #Make Free Practice li r3,0x1 stb r3,0x5(r31) #Timer Now Counts Up load r3,0x8046b6a0 lbz r0,0x24C8(r3) li r4,1 rlwimi r0,r4,0,31,31 stb r0,0x24C8(r3) #Play Sound To Indicate li r3,0x82 branchl r12,SFX_PlaySoundAtFullVolume EggsSkipToggleCheck: #Check For First Frame lbz r3,0x4(r31) cmpwi r3,0x0 bne EggsNotFirstFrame #Check If Player Can Move li r3,0x0 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block lwz r3,0x2c(r3) #player data in r29 lbz r3,0x221D(r3) rlwinm. r3,r3,0,28,28 bne EggsThinkExit #Set First Frame Over li r3,0x1 stb r3,0x4(r31) EggsNotFirstFrame: #Check If Target is Spawned EggsTargetCheck: #Check If Pointer is Stored lwz r3,0x0(r31) cmpwi r3,0x0 beq EggsThinkSpawn #Check if Item GObj is live lwz r3,0x2C(r3) cmpwi r3,0x0 beq EggsThinkSpawn b EggsThinkSkipSpawn ################ # Spawn Target # ################ .set LeftCameraBound,20 .set RightCameraBound,21 .set TopCameraBound,22 .set BottomCameraBound,23 EggsThinkSpawn: .if debug==1 li r24,0 #Init loop count .endif EggsThinkSpawnLoop: .if debug==1 addi r24,r24,1 #Inc Loop Count .endif #Get OnScreen Boundaries #Left Camera branchl r12,StageInfo_CameraLimitLeft_Load fctiwz f1,f1 stfd f1,0x80(sp) lwz LeftCameraBound,0x84(sp) #Right Camera branchl r12,StageInfo_CameraLimitRight_Load fctiwz f1,f1 stfd f1,0x80(sp) lwz RightCameraBound,0x84(sp) #Top Camera branchl r12,StageInfo_CameraLimitTop_Load fctiwz f1,f1 stfd f1,0x80(sp) lwz TopCameraBound,0x84(sp) #Bottom Camera branchl r12,StageInfo_CameraLimitBottom_Load fctiwz f1,f1 stfd f1,0x80(sp) lwz BottomCameraBound,0x84(sp) #Get Random Velocity branchl r12,HSD_Randf fmr f20,f1 li r3,2 bl IntToFloat fadds f20,f20,f1 #Get Random X Value Between These mr r3,LeftCameraBound mr r4,RightCameraBound bl RandFloat fmr f21,f1 #Get Random Y Value Between These mr r3,BottomCameraBound subi r4,TopCameraBound,70 #Minus 40 so it doesnt fly up offscreen bl RandFloat fmr f22,f1 .set EggSpawnGroundWidth,8 #Check If Egg is Above Ground fmr f1,f21 fmr f2,f22 bl FindGroundUnderCoordinate cmpwi r3,0x0 beq EggsThinkSpawnLoop #Check Left li r3,EggSpawnGroundWidth bl IntToFloat fsubs f1,f21,f1 fmr f2,f22 bl FindGroundUnderCoordinate cmpwi r3,0x0 beq EggsThinkSpawnLoop #Check Right li r3,EggSpawnGroundWidth bl IntToFloat fadds f1,f21,f1 fmr f2,f22 bl FindGroundUnderCoordinate cmpwi r3,0x0 beq EggsThinkSpawnLoop .if debug==1 #OSReport Loop Count load r3,0x803ead3c mr r4,r24 branchl r12,OSReport .endif SpawnEgg: addi r3,sp,0x80 li r4,0x0 stw r4,0x0(r3) #Player Pointer stw r4,0x4(r3) #Player Pointer li r4,0x03 stw r4,0x8(r3) #Item ID lfs f0, -0x2858 (rtoc) stfs f21,0x14(r3) #X Coord stfs f22,0x18(r3) #Y Coord stfs f0,0x1C(r3) #Z Coord stfs f21,0x20(r3) #X Coord stfs f22,0x24(r3) #Y Coord stfs f0,0x28(r3) #Z Coord stfs f0,0x2C(r3) #Unk stfs f0,0x30(r3) #Unk stfs f0,0x34(r3) #X Vel stfs f0,0x38(r3) #Y Vel li r4,0x1 sth r4,0x3C(r3) branchl r12,EntityItemSpawn mr r29,r3 #Backup Entity Pointer stw r29,0x0(r31) #Store Pointer To Target In Event Think #Store Pointer To Event Think In Target lwz r4,0x2C(r29) stw r31,0xDDC(r4) #Store Y Velocity stfs f20,0x44(r4) #Get OnDestroy lwz r4,0x2C(r29) lwz r4,0xB8(r4) #Store OnCollision bl Eggs_OnCollision mflr r3 stw r3,0x1C(r4) #Create Camera Box branchl r12,CreateCameraBox #Attach to Entity lwz r4,0x2c(r29) stw r3, 0x0520 (r4) #Enable Camera Box Bit lbz r0, 0x0DCD (r4) li r5,0x22 rlwimi r0, r5, 5, 24, 25 stb r0, 0x0DCD (r4) #Copy Some Stuff To Camera Box lwz r4, -0x4978 (r13) lfs f0, 0x014C (r4) stfs f0, 0x0040 (r3) lfs f0, 0x0150 (r4) stfs f0, 0x0044 (r3) lfs f0, 0x0154 (r4) stfs f0, 0x0048 (r3) lfs f0, 0x0158 (r4) stfs f0, 0x004C (r3) #Never Timeout lwz r5, 0x002C (r29) lbz r3,0xDD0(r5) li r4,0x1 rlwimi r3,r4,4,27,27 stb r3,0xDD0(r5) #Not Grabbable lbz r3, 0x0DCA (r5) li r4,0x0 rlwimi r3,r4,2,29,29 stb r3, 0x0DCA (r5) #Un-Nudgeable? lbz r3, 0x0DCB (r5) li r4,0x0 rlwimi r3,r4,3,28,28 stb r3, 0x0DCB (r5) EggsThinkSkipSpawn: #Not Grabbable Every Frame lwz r5,0x0(r31) lwz r5,0x2c(r5) lbz r3, 0x0DCA (r5) li r4,0x0 rlwimi r3,r4,2,29,29 stb r3, 0x0DCA (r5) #Update HUD Score li r3,0 li r4,5 branchl r12,Playerblock_LoadTimesR3KilledR4 branchl r12,HUD_KOCounter_UpdateKOs #Check If Free Practice lbz r3,0x5(r31) cmpwi r3,0x0 bne EggsThinkExit #Check For TimeUp branchl r12,MatchInfo_LoadSeconds #Seconds Left cmpwi r3,0x0 bne EggsThinkExit branchl r12,MatchInfo_LoadSubSeconds #Sub-Seconds Left cmpwi r3,59 bne EggsThinkExit #On Event End mr r3,r30 branchl r12,EventMatch_OnWinCondition #EventMatch_OnWinCondition EggsThinkExit: mr r3,MenuData bl ClearToggledOptions restore blr Eggs_OnCollision: blrl #First check if this is an event load r4,SceneController lbz r4,Scene.CurrentMajor(r4) cmpwi r4,Scene.EventMode bne Eggs_OnCollisionOriginalFunction #Now check if its eggs-ercise lwz r4, -0x77C0 (r13) lbz r4, 0x0535 (r4) #get event ID cmpwi r4,Event_Eggs beq Eggs_OnCollisionStart Eggs_OnCollisionOriginalFunction: #Go to the original egg break function branch r12,ItemCollision_Egg Eggs_OnCollisionStart: backup mr r30,r3 lwz r31,0x2C(r3) #Get Data #Check If Any Attack Should Break lwz r3,0xDDC(r31) #Get Event Data lwz r3,EventData_MenuDataPointer(r3) #Get Menu Data lbz r3,DamageThreshold(r3) #Damage Behavior cmpwi r3,0x1 beq Eggs_OnCollisionBreakEgg #Check Damage Dealt Before Exploding lwz r3,0xCA0(r31) cmpwi r3,11 blt Egg_OnCollisionExit Eggs_OnCollisionBreakEgg: #Increment Score li r3,0 li r4,0 li r5,5 branchl r12,Playerblock_StoreTimesR3KilledR4 #Display Effect li r3,1232 mr r4,r30 addi r5, r31, 76 crclr 6 branchl r12,Textures_DisplayEffectTextures #Play Pop Sound mr r3,r31 li r4,244 li r5,127 li r6,64 branchl r12,0x8026ae84 #Explode mr r3,r30 branchl r12,0x80289158 #Spawn New Egg lwz r3,0xDDC(r31) #Get Event Think li r4,0x0 #Get 0 stw r4,0x0(r3) #Zero Pointer Egg_OnCollisionExit: li r3,0x0 Egg_OnCollisionExitSkip: restore blr EggsLoadExit: restore blr #################################################### EggsWindowInfo: blrl #amount of options, amount of options in each window .long 0x0001FFFF #1 window, Smash Attack has 2 options #################################################### EggsWindowText: blrl ###################### ## Damage Threshold ## ###################### #Window Title = Damage Threshold .long 0x44616d61 .long 0x67652054 .long 0x68726573 .long 0x686f6c64 .long 0x #Option 1 = 12+ Damage .long 0x3132817B .long 0x2044616d .long 0x61676500 .long 0x .long 0x #Option 2 = Any Damage .long 0x416e7920 .long 0x44616d61 .long 0x67650000 .long 0x .long 0x ################################################################################ ################################################################################ #endregion #region Multishine ######################### ## Multishine HIJACK INFO ## ######################### Multishine: #COUNT DOWN TIME li r3,0x6 stb r3,0x0(r26) #10 Seconds On the Clock li r3,10 stw r3,0x10(r26) #Store Match Type to READY, GO! li r3,0x80 stb r3,0x1(r26) #SET EVENT TYPE TO KOs load r5,0x8045abf0 #Static Match Struct lbz r3,0xB(r5) #Get Event Score Behavior Byte li r4,0x0 rlwimi r3,r4,1,30,30 #Zero Out Time Bit stb r3,0xB(r5) #Set Event Score Behavior Byte #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,FinalDestination #Use FD load r7,EventOSD_Multishine li r8,0 #Use Sopo Bool bl InitializeMatch #1 Player lwz r4,0x0(r29) li r3,0x20 stb r3,0x1(r9) #STORE THINK FUNCTION bl MultishineLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Multishine LOAD FUNCT ## ######################## MultishineLoad: blrl backup #Schedule Think bl MultishineThink mflr r3 li r4,17 #Priority (After Everything) li r5,0 #No Option Menu li r6,0 bl CreateEventThinkFunction bl InitializeHighScore b MultishineLoadExit ######################### ## Multishine THINK FUNCT ## ######################### MultishineThink: blrl .set EventData,31 .set Event,30 .set P1Data,27 .set P1GObj,28 backup mr Event,r3 lwz EventData,0x2c(Event) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 #First Frame Actions bl CheckIfFirstFrame cmpwi r3,0x0 beq MultishineNotFirstFrame #Init Positions bl PlacePlayersCenterStage MultishineNotFirstFrame: #Check for grounded or aerial shine, frame 1 lwz r3,0x10(P1Data) cmpwi r3,0x168 beq Multishine_IsShining cmpwi r3,0x16D beq Multishine_IsShining b Multishine_SkipShineCheck Multishine_IsShining: #Check for frame 1 lhz r3,FramesinCurrentAS(P1Data) cmpwi r3,0 bne Multishine_SkipShineCheck #Increment Score li r3,0 li r4,0 li r5,5 branchl r12,Playerblock_StoreTimesR3KilledR4 Multishine_SkipShineCheck: #Check For TimeUp branchl r12,MatchInfo_LoadSeconds #Seconds Left cmpwi r3,0x0 bne MultishineThinkExit branchl r12,MatchInfo_LoadSubSeconds #Sub-Seconds Left cmpwi r3,59 bne MultishineThinkExit #On Event End mr r3,Event branchl r12,EventMatch_OnWinCondition #EventMatch_OnWinCondition MultishineThinkExit: #Update HUD Score li r3,0 li r4,5 branchl r12,Playerblock_LoadTimesR3KilledR4 branchl r12,HUD_KOCounter_UpdateKOs MultishineLoadExit: restore blr ################################################################################ ################################################################################ #endregion #region Reaction ######################### ## Reaction HIJACK INFO ## ######################### Reaction: #SET EVENT TYPE TO KOs load r5,0x8045abf0 #Static Match Struct lbz r3,0xB(r5) #Get Event Score Behavior Byte li r4,0x0 rlwimi r3,r4,1,30,30 #Zero Out Time Bit stb r3,0xB(r5) #Set Event Score Behavior Byte #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Fox.Ext #Use chosen CPU li r6,FinalDestination #Use FD load r7,EventOSD_Reaction li r8,0 #Use Sopo Bool bl InitializeMatch #STORE THINK FUNCTION bl ReactionLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Reaction LOAD FUNCT ## ######################## ReactionLoad: blrl backup #Schedule Think bl ReactionThink mflr r3 li r4,3 #Priority (Interrupt) li r5,0 #No Option Menu li r6,0 bl CreateEventThinkFunction b ReactionLoadExit ######################### ## Reaction THINK FUNCT ## ######################### ReactionThink: blrl .set EventData,31 .set Event,30 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 #Constants .set ShineTimerMax,7*60 .set ShineTimerMin,3*60 .set ResetTimer,1*60 #GObj Data Offsets .set OFST_ShineTimer,0x0 .set OFST_ResetTimer,0x2 .set OFST_ReactionTimer,0x4 backup mr Event,r3 lwz EventData,0x2c(Event) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 #First Frame Actions bl CheckIfFirstFrame cmpwi r3,0x0 beq ReactionNotFirstFrame #Init Positions bl PlacePlayersCenterStage #Savestate addi r3,EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Save #Set Initial Timer li r3,ShineTimerMax - ShineTimerMin branchl r12,HSD_Randi addi r3,r3,ShineTimerMin sth r3,OFST_ShineTimer(EventData) #Initialize Reaction Timer li r3,-1 sth r3,OFST_ReactionTimer(EventData) #Stop Music li r3,0 li r4,2 branchl r12,0x80025064 ReactionNotFirstFrame: bl StoreCPUTypeAndZeroInputs #Give Intangibility to both chars mr r3,P1GObj li r4,1 branchl r12,ApplyIntangibility mr r3,P2GObj li r4,1 branchl r12,ApplyIntangibility #Check post countdown timer lhz r3,OFST_ResetTimer(EventData) cmpwi r3,0 ble Reaction_SkipResetTimer #Dec timer, if 0 reset subi r3,r3,1 sth r3,OFST_ResetTimer(EventData) cmpwi r3,0 beq Reaction_Reset b ReactionThinkExit Reaction_SkipResetTimer: #Check shine countdown timer lhz r3,OFST_ShineTimer(EventData) cmpwi r3,0 ble Reaction_SkipShineTimer #Dec timer, if 0 perform move subi r3,r3,1 sth r3,OFST_ShineTimer(EventData) cmpwi r3,0 bgt ReactionThink_CheckIfActedEarly #Perform down b mr r3,P2GObj branchl r12,0x800e8560 #Start reaction timer li r3,0 sth r3,OFST_ReactionTimer(EventData) b ReactionThinkExit ReactionThink_CheckIfActedEarly: #Check if P1 acted early lwz r3,0x10(P1Data) cmpwi r3,ASID_Wait beq ReactionThinkExit #Play Error Noise li r3,0xAF bl PlaySFX #Set Timer li r3,ResetTimer-40 sth r3,OFST_ResetTimer(EventData) b ReactionThinkExit Reaction_SkipShineTimer: #Check reaction timer lhz r3,OFST_ReactionTimer(EventData) extsh r3,r3 cmpwi r3,0 blt Reaction_SkipReactionTimer #Poll Inputs Again #branchl r12,0x80377ce8 #Check if P1 Reacted lbz r3,0x618(P1Data) load r4,InputStructStart mulli r3,r3,68 add r3,r3,r4 lwz r3,0x8(r3) cmpwi r3,0 beq Reaction_SkipReactionTimer #Output reaction time mr r3,P1Data #p1 (no offsetting window) li r4,120 #text timeout li r5,0 #Area to Display (0-2) li r6,OSD.Miscellaneous #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr r20,r3 #backup text pointer #Decide Color lhz r3,OFST_ReactionTimer(EventData) cmpwi r3,15 ble Reaction_Good Reaction_Bad: load r3,0xffa2baff #Red b Reaction_StoreTextColor Reaction_Good: load r3,0x8dff6eff #green Reaction_StoreTextColor: stw r3,0x30(r20) #Create Text 1 mr r3,r20 #text pointer bl Reaction_TopText mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,Text_InitializeSubtext #Create Text 2 mr r3,r20 #text pointer bl Reaction_BottomText mflr r4 lhz r5,OFST_ReactionTimer(EventData) addi r5,r5,1 #0-index is scary lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #default text X/Y branchl r12,Text_InitializeSubtext #Start post countdown timer li r3,ResetTimer sth r3,OFST_ResetTimer(EventData) b ReactionLoadExit Reaction_SkipReactionTimer: #Inc timer lhz r3,OFST_ReactionTimer(EventData) addi r3,r3,1 sth r3,OFST_ReactionTimer(EventData) b ReactionThinkExit Reaction_Reset: #Load State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Reset Variables #Set Initial Timer li r3,ShineTimerMax - ShineTimerMin branchl r12,HSD_Randi addi r3,r3,ShineTimerMin sth r3,OFST_ShineTimer(EventData) #Reset Timer li r3,0 sth r3,OFST_ResetTimer(EventData) #Initialize Reaction Timer li r3,-1 sth r3,OFST_ReactionTimer(EventData) ReactionThinkExit: ReactionLoadExit: restore blr Reaction_TopText: blrl .string "Reaction Time:" .align 2 Reaction_BottomText: blrl .string "%d Frames" .align 2 ################################################################################ ################################################################################ #endregion #region Ledge Stall ########################### ## Ledge Stall HIJACK INFO ## ########################### LedgeStall: #Store Match Type to READY, GO! li r3,0x80 stb r3,0x1(r26) #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 li r6,Brinstar #stage load r7,EventOSD_LedgeStall li r8,1 #Use Sopo bool bl InitializeMatch #1 Player lwz r4,0x0(r29) li r3,0x20 stb r3,0x1(r4) #STORE THINK FUNCTION LedgeStallStoreThink: bl LedgeStallLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## Ledge Stall LOAD FUNCT ## ################################## LedgeStallLoad: blrl backup #Schedule Think bl LedgeStallThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction #Destroy Lava map_gobj proc li r3,8 #lava's map_gobj ID branchl r12,Stage_map_gobj_Load branchl r12,GObj_RemoveProc /* #Make Lava transparent li r3,8 #lava's map_gobj ID branchl r12,Stage_map_gobj_Load li r4,0 branchl r12,Stage_map_gobj_LoadJObj li r5,1 lwz r4,0x14(r3) rlwimi r4,r5,29,2,2 rlwimi r4,r5,28,3,3 rlwimi r4,r5,19,12,12 stw r4,0x14(r3) lwz r3,0x18(r3) lwz r3,0x8(r3) lwz r4,0x4(r3) rlwimi r4,r5,29,2,2 rlwimi r4,r5,30,1,1 stw r4,0x4(r3) lwz r3,0xC(r3) load r4,0x3f000000 stw r4,0xC(r3) */ #Get map_gobj li r3,6 #platform's map_gobj ID branchl r12,Stage_map_gobj_Load #Get platform flesh item pointer lwz r3,0x2C(r3) lwz r3,0xE4(r3) lwz r3,0x2C(r3) #Set Hurtbox as intangible li r4,2 stw r4,0xACC(r3) #Create Camera Box branchl r12,CreateCameraBox mr r20,r3 #Get Stage's Ledge IDs lwz r3,-0x6CB8 (r13) #External Stage ID bl LedgedashCliffIDs mflr r4 mulli r3,r3,0x2 lhzx r3,r3,r4 #Get Ledge Coordinates rlwinm r3,r3,24,24,31 addi r4,sp,0xD0 branchl r12,Stage_GetLeftOfLineCoordinates #Position Base of CameraBox behind the ledge .set CameraBoxXOffset,35 .set CameraBoxYOffset,20 li r3,CameraBoxXOffset bl IntToFloat lfs f2,0xD0(sp) #Ledge X fadds f1,f1,f2 stfs f1,0x10(r20) #Camera X Position li r3,CameraBoxYOffset bl IntToFloat lfs f2,0xD4(sp) #Ledge Y fadds f1,f1,f2 stfs f1,0x14(r20) #Camera Y Position #Make Boundaries around ledge position #Left Bound li r3,-10 bl IntToFloat stfs f1,0x40(r20) #Right Bound li r3,10 bl IntToFloat stfs f1,0x44(r20) #Top Bound li r3,10 bl IntToFloat stfs f1,0x48(r20) #Lower Bound li r3,-10 bl IntToFloat stfs f1,0x4C(r20) #Set Camera To Be Zoomed Out More load r4,0x8049e6c8 load r3,0x3FE66666 stw r3,0x28(r4) b LedgeStallThink_Exit ########################################### LedgeStallThink_Constants: blrl .set LavaRiseRate,0x0 .set LavaMaxY,0x4 .float 0.4 .float 10 ########################################### ################################### ## Ledge Stall THINK FUNCT ## ################################### LedgeStallThink: blrl #Registers .set REG_EventConstants,25 .set REG_MenuData,26 .set REG_EventData,31 .set REG_EventGObj,24 .set REG_P1Data,27 .set REG_P1GObj,28 .set REG_P2Data,29 .set REG_P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_LavaDelay,0x0 .set EventState_LavaRiseThink,0x1 .set EventState_Reset,0x2 .set Timer,0x1 .set LavaTimer,0x2 .set SurvivalTime,0x4 .set LavaPosition,0x8 #Constants .set ResetTimer,30 .set LavaStartY,-100 .set LavaStartTimer,123 .set SuvivalTime_CountInterval,5 backup #INIT FUNCTION VARIABLES mr REG_EventGObj,r3 lwz REG_EventData,0x2c(REG_EventGObj) #backup data pointer in r31 #Get Player Pointers bl GetAllPlayerPointers mr REG_P1GObj,r3 mr REG_P1Data,r4 mr REG_P2GObj,r5 mr REG_P2Data,r6 #Get Menu and Constants Pointers lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData) bl LedgeStallThink_Constants mflr REG_EventConstants #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq LedgeStallThink_Start #Init Positions mr r3,REG_P1GObj mr r4,REG_EventData bl LedgeStall_InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save LedgeStallThink_Start: #Check if player was damaged or died lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_DamageHi1 blt LedgeStallThink_DamageCheckSkip cmpwi r3,ASID_DamageFlyRoll bgt LedgeStallThink_DamageCheckSkip b LedgeStallThink_TookDamage LedgeStallThink_DamageCheckSkip: lbz r3,0x221F(REG_P1Data) rlwinm. r0,r3,0,25,25 beq LedgeStallThink_DeadCheckSkip LedgeStallThink_TookDamage: #Check if took damage already lbz r3,Timer(REG_EventData) cmpwi r3,0 bgt LedgeStallThink_DeadCheckSkip #Set Reset Timer li r3,ResetTimer stb r3,Timer(REG_EventData) #Play Crowd SFX #li r3,0x13D #bl PlaySFX #Advance State li r3,EventState_Reset stb r3,EventState(REG_EventData) LedgeStallThink_DeadCheckSkip: LedgeStallThink_SwitchCase: #Switch Case lbz r3,EventState(REG_EventData) cmpwi r3,EventState_LavaDelay beq LedgeStallThink_LavaDelay cmpwi r3,EventState_LavaRiseThink beq LedgeStallThink_LavaRiseThink cmpwi r3,EventState_Reset beq LedgeStallThink_Reset b LedgeStallThink_CheckTimer #region LedgeStallThink_LavaDelay LedgeStallThink_LavaDelay: #Reset Timer back to 0 li r3,0 load r4,0x8046b6a0 stw r3,0x28(r4) #seconds sth r3,0x2C(r4) #subseconds #Decrement Lava Timer lhz r3,LavaTimer(REG_EventData) subi r3,r3,1 sth r3,LavaTimer(REG_EventData) #Check if up cmpwi r3,0 bgt LedgeStallThink_CheckTimer #Advance State li r3,EventState_LavaRiseThink stb r3,EventState(REG_EventData) b LedgeStallThink_LavaRiseThink #endregion #region LedgeStallThink_LavaRiseThink LedgeStallThink_LavaRiseThink: #Ensure player is in the lava before incrementing survival time lfs f1,LavaPosition(REG_EventData) lfs f2,0xB4(REG_P1Data) fcmpo cr0,f2,f1 bge LedgeStallThink_LavaRiseThink_NotInLava #Increment Score lwz r3,SurvivalTime(REG_EventData) addi r3,r3,1 stw r3,SurvivalTime(REG_EventData) LedgeStallThink_LavaRiseThink_SkipScoreIncrement: #Play HRC SFX every X score li r3,SuvivalTime_CountInterval bl IntToFloat fmr f2,f1 lwz r3,SurvivalTime(REG_EventData) subi r3,r3,1 bl IntToFloat branchl r12,fmod fmr f2,f1 li r3,0 bl IntToFloat fcmpo cr0,f2,f1 bne LedgeStallThink_LavaRiseThink_SkipSFX #Play SFX li r3,0xBB bl PlaySFX li r3,0xBB bl PlaySFX LedgeStallThink_LavaRiseThink_SkipSFX: b LedgeStallThink_LavaRiseThink_NotInLavaSkip LedgeStallThink_LavaRiseThink_NotInLava: #Reset Timer back to 0 li r3,0 load r4,0x8046b6a0 stw r3,0x28(r4) #seconds sth r3,0x2C(r4) #subseconds #Set survival time to 0 stw r3,SurvivalTime(REG_EventData) LedgeStallThink_LavaRiseThink_NotInLavaSkip: #Check if lava is at max height lfs f1,LavaPosition(REG_EventData) lfs f2,LavaMaxY(REG_EventConstants) fcmpo cr0,f1,f2 bge LedgeStallThink_LavaRiseThink_SkipLavaRise #Raise Lava lfs f2,LavaRiseRate(REG_EventConstants) fadds f1,f1,f2 stfs f1,LavaPosition(REG_EventData) bl Ledgestall_UpdateLavaPosition LedgeStallThink_LavaRiseThink_SkipLavaRise: b LedgeStallThink_CheckTimer #endregion #region LedgeStallThink_Reset LedgeStallThink_Reset: #Effectively pause timer load r4,0x8046b6a0 lwz r3,0x28(r4) #seconds cmpwi r3,0 beq LedgeStallThink_NoSecondCarryover lhz r3,0x2C(r4) #subseconds cmpwi r3,0 bne LedgeStallThink_NoSecondCarryover li r3,0x3B sth r3,0x2C(r4) #subseconds lwz r3,0x28(r4) #seconds subi r3,r3,1 stw r3,0x28(r4) #seconds b LedgeStallThink_CheckTimer LedgeStallThink_NoSecondCarryover: lhz r3,0x2C(r4) #subseconds subi r3,r3,1 sth r3,0x2C(r4) #subseconds b LedgeStallThink_CheckTimer #endregion LedgeStallThink_CheckTimer: #Check if timer exists lbz r3,Timer(REG_EventData) cmpwi r3,0 ble LedgeStallThink_Exit #Decrement timer subi r3,r3,1 stb r3,Timer(REG_EventData) cmpwi r3,0 bgt LedgeStallThink_Exit #Pasue game lfs f1, -0x4D68 (rtoc) branchl r12,0x8016b274 #Pause game engine #Check if player had any score when taking damage lwz r3,SurvivalTime(REG_EventData) cmpwi r3,0 ble LedgeStallThink_Failure LedgeStallThink_Success: #Get current high score lwz r3,-0x77C0 (r13) lbz r20,0x535(r3) mr r3,r20 branchl r12,Events_GetEventSavedScore lwz r4,SurvivalTime(REG_EventData) cmpw r4,r3 ble LedgeStallThink_Success_NoHighScore LedgeStallThink_Success_NewHighScore: li r3,2 branchl r12,0x8016b33c #Display Success + SFX load r3,0x9c40 branchl r12,0x8016b350 li r3,325 branchl r12,0x8016b364 #queue crowd cheer after Success branchl r12,0x8016b328 #set game as ended mr r3,r20 #update score lwz r4,SurvivalTime(REG_EventData) branchl r12,Events_SetEventSavedScore mr r3,r20 #set event as played branchl r12,0x8015ceb4 b LedgeStallThink_Success_DestroyGObj LedgeStallThink_Success_NoHighScore: li r3,2 branchl r12,0x8016b33c #Display New Record + SFX li r3,324 branchl r12,0x8016b364 #queue crowd cheer after New Record branchl r12,0x8016b328 #set game as ended b LedgeStallThink_Success_DestroyGObj LedgeStallThink_Failure: li r3,6 branchl r12,0x8016b33c #Display Failure + SFX li r3,328 branchl r12,0x8016b364 #queue crowd sigh after failure li r3,40 branchl r12,0x8016b378 #frames to linger? branchl r12,0x8016b328 #set game as ended b LedgeStallThink_Success_DestroyGObj LedgeStallThink_Success_DestroyGObj: mr r3,REG_EventGObj branchl r12,GObj_Destroy #destroy event gobj b LedgeStallThink_Exit LedgeStallThink_Restore: #Restore State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Load #Init Positions Again mr r3,REG_P1GObj mr r4,REG_EventData bl LedgeStall_InitializePositions #Enable Inputs lbz r3,0x221D(REG_P1Data) li r4,0 rlwimi r3,r4,3,28,28 stb r3,0x221D(REG_P1Data) #Shorten Timer li r3,0 sth r3,LavaTimer(REG_EventData) LedgeStallThink_Exit: restore blr ################################ LedgeStall_InitializePositions: backup .set REG_P1GObj,30 .set REG_P1Data,29 .set REG_EventData,28 .set REG_map_gobj,27 .set REG_map_gobj_JObj,26 #Init Registers mr REG_P1GObj,r3 lwz REG_P1Data,0x2C(REG_P1GObj) mr REG_EventData,r4 #Place on left ledge mr r3,REG_P1GObj li r4,0 bl PlaceOnLedge #Update Camera mr r3,REG_P1GObj bl UpdateCameraBox #Init Lava Y li r3,LavaStartY bl IntToFloat stfs f1,LavaPosition(REG_EventData) bl Ledgestall_UpdateLavaPosition #Reset Variables li r3,EventState_LavaDelay stb r3,EventState(REG_EventData) li r3,0 stb r3,Timer(REG_EventData) stw r3,SurvivalTime(REG_EventData) #Init Lava Start Timer li r3,LavaStartTimer sth r3,LavaTimer(REG_EventData) LedgeStall_InitializePositions_Exit: restore blr ##################################### Ledgestall_UpdateLavaPosition: backup .set REG_LavaY,31 .set REG_map_gobj_JObj,30 #Backup args stfs f1,0x80(sp) #Get Lava map_gobj li r3,8 #lava's map_gobj ID branchl r12,Stage_map_gobj_Load #Get JObj li r4,0 branchl r12,Stage_map_gobj_LoadJObj mr REG_map_gobj_JObj,r3 #Get 55f (jobj doesnt line up with actual position) li r3,55 bl IntToFloat #Update JObj Y position lfs f2,0x80(sp) fadds f1,f1,f2 stfs f1,0x3C(REG_map_gobj_JObj) #DirtySub mr r3,REG_map_gobj_JObj branchl r12,HSD_JObjSetMtxDirtySub #Adjust hitbox position lfs f1,0x80(sp) branchl r12,0x801c438c Ledgestall_UpdateLavaPosition_Exit: restore blr #endregion ################## ## General Tech ## ################## #region L-Cancel Training ######################### ## L Cancel HIJACK INFO ## ######################### LCancel: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,-1 #Use SSS Stage load r7,EventOSD_LCancel li r8,0 #Use Sopo Bool bl InitializeMatch #Make P2 a human lwz r3,0x0(r29) lwz r3,0x18(r3) li r4,0 stb r4,0x1(r3) #STORE THINK FUNCTION bl LCancelLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## L Cancel LOAD FUNCT ## ######################## LCancelLoad: blrl backup #Schedule Think bl LCancelThink mflr r3 li r4,3 #Priority (After Interrupt) li r5,0 #No Option Menu bl CreateEventThinkFunction b LCancelLoadExit ######################### ## L Cancel THINK FUNCT ## ######################### LCancelThink: blrl .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 backup lwz EventData,0x2c(r3) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl CheckIfFirstFrame cmpwi r3,0x0 beq LCancelNotFirstFrame #Init Positions bl PlacePlayersCenterStage #Check if P2-P4 Is Using the Event li r4,0x1 #Make CPU Controlled by P2 lbz r3, -0x5108 (r13) cmpwi r3,0x0 beq LCancelIsP1 li r4,0x0 LCancelIsP1: stb r4,0x618(r29) #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save LCancelNotFirstFrame: #Check For P2 Dpad Down Press lwz r3,0x668(r29) #Inputs rlwinm. r0,r3,0,29,29 beq LCancelThink_CheckForInvinc #Toggle Invinc Bit lbz r3,0x0(r31) nand 3,3,3 stb r3,0x0(r31) LCancelThink_CheckForInvinc: lbz r3,0x0(r31) cmpwi r3,0x0 bne LCancelThink_RemoveInvincibility #Give No Knockback To P2 lbz r3,0x2220(P2Data) li r4,1 rlwimi r3,r4,4,27,27 stb r3,0x2220(P2Data) #Ignore Grabs li r3,0x1FF sth r3,0x1A6A(P2Data) #Ignore Percent li r3,0 bl IntToFloat stfs f1,0x1830(P2Data) lbz r3,0xC(P2Data) li r4,0 li r5,0 branchl r12,0x80034418 #Un-nudgeable li r3,0x1 lbz r0, 0x221D (P2Data) rlwimi r0,r3,2,29,29 stb r0, 0x221D (P2Data) #Apply Overlay mr r3,P2Data li r4,9 li r5,0 branchl r12,0x800bffd0 b LCancelThink_SkipInvincibility LCancelThink_RemoveInvincibility: #Give Invincibility To P2 lbz r3,0x2220(P2Data) li r4,0 rlwimi r3,r4,4,27,27 stb r3,0x2220(P2Data) #Allow Grabs #li r3,0x0 #sth r3,0x1A6A(P2Data) #Allow Percent #li r3,1 #bl IntToFloat #stfs f1,0x182C(P2Data) #Nudgeable li r3,0x0 lbz r0, 0x221D (P2Data) rlwimi r0,r3,2,29,29 stb r0, 0x221D (P2Data) #Remove Overlay mr r3,P2Data li r4,9 branchl r12,0x800c0200 LCancelThink_SkipInvincibility: LCancelThink_CheckForSaveState: #Check For Savestates addi r3,EventData,EventData_SaveStateStruct bl CheckForSaveAndLoad mr r3,P1GObj mr r4,P2GObj addi r5,EventData,EventData_SaveStateStruct bl MoveCPU bl GiveFullShields addi r3,EventData,EventData_SaveStateStruct+(1*0x8) bl DPadCPUPercent bl UpdateAllGFX LCancelLoadExit: restore blr ################################################################################ ################################################################################ #endregion #region Ledgedash Training ########################### ## Ledgedash HIJACK INFO ## ########################### Ledgedash: #SET EVENT TYPE TO KOs load r5,0x8045abf0 #Static Match Struct lbz r3,0xB(r5) #Get Event Score Behavior Byte li r4,0x0 rlwimi r3,r4,1,30,30 #Zero Out Time Bit stb r3,0xB(r5) #Set Event Score Behavior Byte #Make HUD Centered For 1P and No Timer li r3,0x0430 sth r3,0x0(r26) #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,-1 #Use SSS Stage load r7,EventOSD_Ledgedash li r8,1 #Use Sopo Bool bl InitializeMatch #1 Player lwz r4,0x0(r29) li r3,0x20 stb r3,0x1(r9) #STORE THINK FUNCTION LedgedashStoreThink: bl LedgedashLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Ledgedash LOAD FUNCT ## ######################## LedgedashLoad: blrl backup #Schedule Think bl LedgedashThink mflr r3 li r4,9 #Priority (After Interrupt) bl LedgedashWindowInfo mflr r5 bl LedgedashWindowText mflr r6 bl CreateEventThinkFunction bl InitializeHighScore #Remove randall lwz r3,StageID_External(r13) cmpwi r3,YoshiStory bne LedgedashLoad_SkipRemoveRandall #Get randall's map_gobj li r3,2 #randalls map_gobj is 2 branchl r12,Stage_map_gobj_Load branchl r12,Stage_Destroy_map_gobj LedgedashLoad_SkipRemoveRandall: b LedgedashLoadExit ######################### ## Ledgedash THINK FUNCT ## ######################### #Registers .set REG_EventData,31 .set MenuData,27 .set P1GObj,30 .set P1Data,29 #Offsets .set firstFrameFlag,0x0 .set eventState,0x1 .set hitboxFoundFlag,0x2 .set currentLedge,0x3 .set timer,0x4 .set CameraBox,0x8 .set StartingLocation,(MenuData_OptionMenuMemory+0x2+0x0) .set AutoRestore,(MenuData_OptionMenuMemory+0x2+0x1) .set StartingLocationToggled,(MenuData_OptionMenuToggled+0x0) .set AutoRestoreToggled,(MenuData_OptionMenuToggled+0x1) LedgedashThink: blrl backup #INIT FUNCTION VARIABLES lwz REG_EventData,0x2c(r3) #backup data pointer in r31 lwz MenuData,EventData_MenuDataPointer(REG_EventData) bl GetAllPlayerPointers mr P1GObj,r3 #player block in r30 mr P1Data,r4 #player data in r29 #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq LedgedashThinkMain #Create Camera Box branchl r12,CreateCameraBox stw r3,CameraBox(r31) #Place on Ledge mr r3,REG_EventData li r4,0 bl Ledgedash_PlaceOnLedge #Set Camera To Be Zoomed Out More load r4,0x8049e6c8 load r3,0x3FE66666 stw r3,0x28(r4) #Set Tangible Frames High So It Doesn't Constantly Show li r3,100 stw r3,0x2408(r29) #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Set Frame 1 As Over li r3,0x1 stb r3,firstFrameFlag(r31) LedgedashThinkMain: #Update HUD Score lhz r3,-0x4ea8(r13) branchl r12,HUD_KOCounter_UpdateKOs #Check If Toggled Starting Location lbz r3,StartingLocationToggled(MenuData) cmpwi r3,0x0 beq Ledgedash_SkipToggledLoadState b Ledgedash_LoadState Ledgedash_SkipToggledLoadState: #Reset If Anyone Dies bl IsAnyoneDead cmpwi r3,0x0 bne Ledgedash_LoadState #Infinite Time While on Rebirth Platform lwz r3,0x10(P1Data) cmpwi r3,0xD bne LedgedashSkipRebirthTimer li r3,0x2 stw r3,0x2340(P1Data) LedgedashSkipRebirthTimer: #Infinite Time While Holding Ledge lwz r3,0x10(P1Data) cmpwi r3,0xFD bne LedgedashSkipCliffTimer li r3,2 bl IntToFloat stfs f1,0x2344(P1Data) LedgedashSkipCliffTimer: #Make sure nothing else besides Z is held lhz r3,0x662(P1Data) rlwinm. r0,r3,0,27,27 bne 0xC cmpwi r3,0x0 bne GetProgressAndAS #CHECK FOR DPAD TO CHANGE LEDGE lwz r3,0x668(P1Data) #Get DPad rlwinm. r0,r3,0,30,30 beq Ledgedash_CheckLeft #Load Most Recent State addi r3,REG_EventData,EventData_SaveStateStruct bl SaveState_Load #Place on Right Ledge mr r3,REG_EventData li r4,1 bl Ledgedash_PlaceOnLedge #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save b Ledgedash_LoadState Ledgedash_CheckLeft: rlwinm. r0,r3,0,31,31 beq GetProgressAndAS #Load Most Recent State addi r3,REG_EventData,EventData_SaveStateStruct bl SaveState_Load #Place on Left Ledge mr r3,REG_EventData li r4,0 bl Ledgedash_PlaceOnLedge #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save b Ledgedash_LoadState GetProgressAndAS: #Check If AutoRestore is enabled lbz r3,AutoRestore(MenuData) cmpwi r3,0x1 beq LedgedashThinkEnd #Check If Timer Is Set lbz r3,timer(r31) cmpwi r3,0x0 bgt Ledgedash_CheckToReset #Get Progress + AS lbz r3,eventState(r31) #Progress Byte bl LedgedashSkipJumpTable bl LedgedashProg0 bl LedgedashProg1 bl LedgedashProg2 bl LedgedashProg3 bl LedgedashProg4 LedgedashSkipJumpTable: mflr r4 #Jump Table Start in r4 mulli r5,r3,0x4 #Each Pointer is 0x4 Long lwzx r3,r4,r5 #Get bl Instruction rlwinm r3,r3,0,6,29 #Mask Bits 6-29 (the offset) add r3,r4,r3 #Gets Address in r3 add r3,r3,r5 #Offset From Start Of Jump Table #Init Loop subi r3,r3,0x2 lwz r6,0x10(r29) #AS #Check For BlackListed AS ## Terminator = FFFF ## Jump to = 7FXX LedgedashASCheckLoop: lhzu r4,0x2(r3) #Get Next Value extsb r0,r4 cmpwi r0,-1 #Check For Terminator beq Ledgedash_ResetProg rlwinm r0,r4,0,15,23 #Isolate Left Half cmpwi r0,0x7F00 #Check If New "Jump To" bne LedgedashCompareAS rlwinm r5,r4,0,24,31 #Isolate Right Half to r5 b LedgedashASCheckLoop LedgedashCompareAS: cmpw r6,r4 bne LedgedashASCheckLoop stb r5,0x1(r31) #Progress Byte b LedgedashThinkEnd LedgedashThinkEnd: mr r3,MenuData bl ClearToggledOptions restore blr #################### ## Reset Progress ## #################### Ledgedash_ResetProg: #Check If On Ground lwz r3,0xE0(r29) cmpwi r3,0x0 beq Ledgedash_Reset #Check If Dead lbz r3,0x221F(r29) rlwinm. r3,r3,0,25,25 bne Ledgedash_Reset #Check If Frame 9 Of Wrong Move li r3,9 bl IntToFloat lfs f2,0x894(r29) #Frames in State fcmpo cr0,f2,f1 blt LedgedashThinkEnd Ledgedash_Reset: #Play Success or Failure Noise lhz r3,TM_OneASAgo(r29) #Check Prev AS cmpwi r3,ASID_LandingFallSpecial #If Landing, Success beq Ledgedash_PlaySuccess cmpwi r3,ASID_Wait #If Wait, Success (Frame Perfect Action) beq Ledgedash_PlaySuccess lwz r3,CurrentAS(r29) cmpwi r3,ASID_Landing #If Aerial Interrupt, Check If Can IASA Yet beq Ledgedash_AerialInterruptCheck cmpwi r3,ASID_Wait #If No Impact Land, Success beq Ledgedash_PlaySuccess b Ledgedash_PlayFailure Ledgedash_AerialInterruptCheck: #Check If Coming From an Aerial Attack lhz r3,TM_OneASAgo(r29) #Check Prev AS cmpwi r3,ASID_AttackAirN blt Ledgedash_PlayFailure cmpwi r3,ASID_AttackAirLw bgt Ledgedash_PlayFailure #Check If Interruptable Yet lfs f2,0x1F4(r29) #Check Which Frame Landing is Interruptable li r3,1 bl IntToFloat fsubs f1,f2,f1 #Sub 1 Because Order of Operations lfs f2,0x894(r29) #Check Current Frame fcmpo cr0,f2,f1 blt LedgedashThinkEnd Ledgedash_PlaySuccess: #Increment Score lhz r3,-0x4ea8(r13) addi r3,r3,0x1 sth r3,-0x4ea8(r13) #Check To Make New High Score lhz r3,-0x4ea8(r13) lhz r4,-0x4ea6(r13) cmpw r3,r4 ble Ledgedash_PlaySuccess_PlaySound #Copy To High Score sth r3,-0x4ea6(r13) Ledgedash_PlaySuccess_PlaySound: #Play Sound li r3,0xAD bl PlaySFX #Set Timer li r3,30 stb r3,timer(r31) b LedgedashThinkEnd Ledgedash_PlayFailure: #Reset Score li r3,0 sth r3,-0x4ea8(r13) #Play Sound li r3,0xAF Ledgedash_PlaySound: bl PlaySFX #Place on Ledge mr r3,REG_EventData lbz r4,currentLedge(REG_EventData) bl Ledgedash_PlaceOnLedge b Ledgedash_LoadState Ledgedash_CheckToReset: lbz r3,timer(r31) #Check If Timer is Set cmpwi r3,0x0 ble LedgedashThinkEnd Ledgedash_CheckForInvincibleMove: lbz r3,hitboxFoundFlag(r31) #Check If Hitbox Was Already Found cmpwi r3,0x1 beq Ledgedash_DecrementTimer lwz r3,0x1990(r29) #Check If Char is Invincible cmpwi r3,0x0 ble Ledgedash_DecrementTimer mr r3,r30 #Check If a Hitbox is Active bl CheckForActiveHitboxes cmpwi r3,0x0 beq Ledgedash_DecrementTimer li r3,0xAA #Play Sound branchl r12,SFX_PlaySoundAtFullVolume li r3,1 #Mark As Found stb r3,hitboxFoundFlag(r31) Ledgedash_DecrementTimer: lbz r3,timer(r31) subi r3,r3,0x1 #Decrement stb r3,timer(r31) cmpwi r3,0x0 bgt LedgedashThinkEnd #Load State (to cleanup volatile entities) addi r3,REG_EventData,EventData_SaveStateStruct bl SaveState_Load #Place on Ledge mr r3,REG_EventData lbz r4,currentLedge(REG_EventData) bl Ledgedash_PlaceOnLedge #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save Ledgedash_LoadState: #Reset all event variables li r3,0x0 stb r3,eventState(r31) #Progress Byte stb r3,hitboxFoundFlag(r31) #Invincible Move Bool stb r3,timer(r31) #Timer addi r3,REG_EventData,EventData_SaveStateStruct bl SaveState_Load #Create Respawn Platform If Enabled lbz r3,StartingLocation(MenuData) cmpwi r3,0x0 beq Ledgedash_LoadState_SkipRespawnPlatform #Remember Facing Direction (Rebirth changes this) lfs f31,0x2C(r29) #Enter P1 Into Rebirth Again mr r3,r30 branchl r12,AS_Rebirth #Restore Facing Direction stfs f31,0x2C(r29) #Randomize Location #Get Stage's Ledges lwz r3,-0x6CB8 (r13) #External Stage ID bl LedgedashCliffIDs mflr r4 mulli r3,r3,0x2 lhzx r3,r3,r4 #Get Correct Ledge From Facing Direction lfs f1, 0x002C (r29) lfs f0, -0x7660 (rtoc) fcmpo cr0,f1,f0 ble Ledgedash_LoadState_GetRightLedge Ledgedash_LoadState_GetLeftLedge: #Get Ledge X and Y Coordinates rlwinm r3,r3,24,24,31 addi r4,sp,0x80 branchl r12,Stage_GetLeftOfLineCoordinates b Ledgedash_LoadState_RandomizePosition Ledgedash_LoadState_GetRightLedge: #Get Ledge X and Y Coordinates rlwinm r3,r3,0,24,31 addi r4,sp,0x80 branchl r12,Stage_GetRightOfLineCoordinates Ledgedash_LoadState_RandomizePosition: #Get Random Distance from this .set RandomDistanceMinX,30 .set RandomDistanceMaxX,55 .set RandomDistanceMinY,-30 .set RandomDistanceMaxY,30 li r3,RandomDistanceMinX li r4,RandomDistanceMaxX bl RandFloat fmr f31,f1 li r3,RandomDistanceMinY li r4,RandomDistanceMaxY bl RandFloat fmr f30,f1 #Add to Ledge Coordinates lfs f1,0x2C(r29) #Facing Direction fneg f1,f1 fmuls f31,f1,f31 lfs f0,0x80(sp) #Ledge X fadds f31,f0,f31 lfs f1,0x84(sp) #Ledge Y fadds f30,f1,f30 #Store to Player Block stfs f31,0xB0(r29) stfs f30,0xB4(r29) #Enter RebirthWait mr r3,r30 branchl r12,AS_RebirthWait #Store Blr as Physics bl BlrFunctionPointer mflr r3 stw r3,0x21A4(r29) #Store Custom RebirthWait Interrupt bl Custom_InterruptRebirthWait mflr r3 stw r3,0x219C(r29) #Update RebirthPlat Position mr r3,P1GObj branchl r12,RebirthPlatform_UpdatePosition Ledgedash_LoadState_SkipRespawnPlatform: mr r3,r30 bl UpdatePosition #Update Camera Box mr r3,P1GObj bl UpdateCameraBox b LedgedashThinkEnd ##################### ## PlaceAboveLedge ## ##################### Ledgedash_PlaceOnLedge: backup .set REG_EventData,31 .set REG_P1GObj,30 .set REG_P1Data,29 .set REG_LedgeID,28 .set REG_CameraBox,28 #Init mr REG_EventData,r3 mr REG_LedgeID,r4 stb REG_LedgeID,currentLedge(REG_EventData) #Get P1 data li r3,0 branchl r12,PlayerBlock_LoadMainCharDataOffset mr REG_P1GObj,r3 lwz REG_P1Data,0x2C(REG_P1GObj) #Place on ledge mr r3,REG_P1GObj mr r4,REG_LedgeID bl PlaceOnLedge #RESET PROGRESS li r3,0x0 stb r3,eventState(REG_EventData) #Get Stage's Ledge IDs lwz r3,-0x6CB8 (r13) #External Stage ID bl LedgedashCliffIDs mflr r4 mulli r3,r3,0x2 lhzx r3,r3,r4 #Get Requested Ledge cmpwi REG_LedgeID,0x0 beq Ledgedash_PlaceOnLedge_GetLeftLedgeID Ledgedash_PlaceOnLedge_GetRightLedgeID: rlwinm r21,r3,0,24,31 b Ledgedash_PlaceOnLedge_SkipLedgeID Ledgedash_PlaceOnLedge_GetLeftLedgeID: rlwinm r21,r3,24,24,31 Ledgedash_PlaceOnLedge_SkipLedgeID: #Adjust Ledge Camera Box Accordingly #Get Ledge Coordinates mr r3,r21 addi r4,sp,0xD0 lfs f1, 0x002C (REG_P1Data) lfs f0, -0x7660 (rtoc) fcmpo cr0,f1,f0 ble Ledgedash_PlaceOnLedge_CameraBoxRightLedge Ledgedash_PlaceOnLedge_CameraBoxLeftLedge: branchl r12,Stage_GetLeftOfLineCoordinates b Ledgedash_PlaceOnLedge_UpdateCameraBox Ledgedash_PlaceOnLedge_CameraBoxRightLedge: branchl r12,Stage_GetRightOfLineCoordinates Ledgedash_PlaceOnLedge_UpdateCameraBox: #Get CameraBox lwz REG_CameraBox,CameraBox(REG_EventData) #Position Base of CameraBox behind the ledge .set CameraBoxXOffset,35 .set CameraBoxYOffset,20 li r3,CameraBoxXOffset bl IntToFloat lfs f2,0xD0(sp) #Ledge X lfs f3,0x2C(REG_P1Data) fmadds f1,f1,f3,f2 stfs f1,0x10(REG_CameraBox) #Camera X Position li r3,CameraBoxYOffset bl IntToFloat lfs f2,0xD4(sp) #Ledge Y fadds f1,f1,f2 stfs f1,0x14(REG_CameraBox) #Camera Y Position #Make Boundaries around ledge position #Left Bound li r3,-10 bl IntToFloat stfs f1,0x40(REG_CameraBox) #Right Bound li r3,10 bl IntToFloat stfs f1,0x44(REG_CameraBox) #Top Bound li r3,10 bl IntToFloat stfs f1,0x48(REG_CameraBox) #Lower Bound li r3,-10 bl IntToFloat stfs f1,0x4C(REG_CameraBox) #Update Camera Box mr r3,REG_P1GObj bl UpdateCameraBox restore blr #################################### LedgedashCliffIDs: blrl .long 0xFFFFFFFF #Dummy, TEST .long 0x03073336 #FoD, Pokemon Stadium .long 0x030D2945 #Peach's Castle, Kongo Jungle .long 0x0511091A #Brinstar, Corneria .long 0x02061517 #Yoshi's Story, Onett .long 0x0000434C #Mute City, Rainbow Cruise .long 0x00000000 #Jungle Japes, Great Bay .long 0x0E0D0000 #Hyrule Temple, Brinstar Depths .long 0x00051E2E #Yoshi's Island, Green Greens .long 0x0C0E0204 #Fourside, MKI .long 0x03050000 #MKII, Akaneia .long 0x06120000 #Venom, PokeFloats .long 0xD7E20000 #Big Blue, Icicle Mountain .long 0x00000000 #Icetop, Flatzone .long 0x0305030B #Dream Land, Yoshis Island 64 .long 0x06100005 #Kongo Jungle 64, Battlefield .long 0x00020101 #Final Destination #################################### #CliffWait -> Fall LedgedashProg0: #*********************# .hword 0x7F00 .hword ASID_CliffCatch,ASID_CliffWait .hword ASID_RebirthWait #*********************# .hword 0x7F01 .hword ASID_Fall #*********************# .hword 0x7F02 .hword ASID_JumpAerialF,ASID_JumpAerialB #*********************# .hword -1 .align 2 #Fall -> JumpAerial LedgedashProg1: .hword 0x7F00 .hword ASID_CliffCatch,ASID_CliffWait #*********************# .hword 0x7F01 .hword ASID_Fall,ASID_PassiveWallJump #*********************# .hword 0x7F02 .hword ASID_JumpAerialF,ASID_JumpAerialB .hword ASID_FallSpecial,ASID_CliffJumpSlow2 .hword ASID_FallAerial,0x17E .hword 0x166,0x167 .hword 0x170,0x164 .hword 0x155,0x15e .hword 0x15f,0x160 .hword 0x16B,0x171 .hword 0x15C,0x16D .hword 0x165,0x16E .hword 0x168,0x161 .hword 0x176,0x15D .hword 0x169,0x162 #*********************# .hword -1 .align 2 #JumpAerial -> Airdodge LedgedashProg2: #*********************# .hword 0x7F02 .hword ASID_JumpAerialF,ASID_PassiveWallJump .hword ASID_JumpAerialB,ASID_Fall .hword ASID_FallSpecial,ASID_CliffJumpSlow2 .hword ASID_FallAerial,0x17E .hword 0x167,0x170 .hword 0x164,0x162 .hword 0x15e,0x15f .hword 0x160,0x16B .hword 0x171,0x15C .hword 0x16D,0x16E .hword 0x165,0x168 .hword 0x161,0x176 .hword 0x15D,0x155 .hword 0x169,0x166 #*********************# .hword 0x7F03 .hword ASID_EscapeAir,ASID_AttackAirB .hword ASID_AttackAirB,ASID_AttackAirU .hword ASID_AttackAirD,ASID_AttackAirF .hword ASID_AttackAirN,ASID_LandingFallSpecial #*********************# .hword 0x7F00 .hword ASID_CliffCatch #*********************# .hword -1 .align 2 #Airdodge -> Landing LedgedashProg3: #*********************# .hword 0x7F03 .hword 0xAA #i think this is just a placeholder, could prob remove but w/e #*********************# .hword 0x7F04 .hword ASID_LandingFallSpecial,ASID_Landing #*********************# .hword -1 .align 2 #Landing -> Wait LedgedashProg4: #*********************# .hword 0x7F04 .hword ASID_LandingFallSpecial #*********************# .hword 0x7F02 .hword ASID_Fall #*********************# .hword -1 .align 2 #################################### LedgedashWindowInfo: blrl .long 0x010101FF #1 window, Respawn Platform has 2 options, AutoRestore has 2 options LedgedashWindowText: blrl #Option Title = Starting Location .string "Starting Location" .align 2 #Option 1 = Ledge .string "Ledge" .align 2 #Option 2 = Respawn Platform .string "Respawn Platform" .align 2 #Option Title = AutoRestore .string "AutoRestore" .align 2 #Option 1 = On .string "On" .align 2 #Option 2 = Off .string "Off" .align 2 #################################### LedgedashLoadExit: restore blr #endregion #region SDI Training ############################## ## SDI Training HIJACK INFO ## ############################## SDITraining: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Fox.Ext #Use chosen CPU li r6,FinalDestination #Use SSS Stage load r7,EventOSD_SDI li r8,1 #Use Sopo bool bl InitializeMatch #Make default color lwz r3,0x0(r29) lwz r3,0x18(r3) #p2 pointer li r4,0x0 stb r4,0x3(r3) #Default color #STORE THINK FUNCTION SDITrainingStoreThink: bl SDITrainingLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## SDI Training LOAD FUNCT ## ######################## SDITrainingLoad: blrl backup bl InitializeHighScore #Schedule Think bl SDITrainingThink mflr r3 li r4,3 #Priority (After Interrupt) li r5,0 #No Option Menu bl CreateEventThinkFunction b SDITrainingLoadExit ######################### ## SDI Training THINK FUNCT ## ######################### .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 SDITrainingThink: blrl backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 li r3,0xF stw r3,0x1A94(r29) bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq SDITrainingThinkMain bl SDITrainingFloats mflr r3 bl Event_EnterGrab #Store 999 To Breakout lis r3,0x4461 stw r3,0x1A4C(r27) #Give Percent bl SDITrainingStartingPercents mflr r4 lwz r3,0x4(r27) #Get Char ID lbzx r3,r3,r4 #Get Percent load r4,0x80453080 #P1 Static Block sth r3,0x60(r4) #Store Percent Int To Display Value sth r3,0x62(r4) #Store Percent Int To Display Value (Subchar) bl IntToFloat stfs f1,0x1830(r27) #Store to Actual Damage Value #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Random Start Time li r3,60 branchl r12,HSD_Randi li r4,0 sub r3,r4,r3 stw r3,0x4(r31) #Reset Timer SDITrainingThinkMain: #Inc Timer lwz r3,0x4(r31) addi r3,r3,0x1 stw r3,0x4(r31) #Check If SDI'd UpAir (Damage_LightHit + No Hitstun) #Check If Already Incremented lbz r3,0xA(r31) cmpwi r3,0x1 beq SDITraining_SkipSDICheck #Check AS lwz r3,0x10(r27) cmpwi r3,0x55 bne SDITraining_SkipSDICheck #Check For Hitstun lbz r3, 0x221C (r27) rlwinm. r0, r3, 31, 31, 31 bne SDITraining_SkipSDICheck #Set Flag li r3,0x1 stb r3,0xA(r31) #Play Sound li r3,0xAD bl PlaySFX #Increment Score lhz r3,-0x4ea8(r13) addi r3,r3,0x1 sth r3,-0x4ea8(r13) #Check To Make New High Score lhz r3,-0x4ea8(r13) lhz r4,-0x4ea6(r13) cmpw r3,r4 ble SDITraining_SkipSDICheck #Copy To High Score sth r3,-0x4ea6(r13) SDITraining_SkipSDICheck: #Check If Missed SDI (Fox in UpAir + P1 in Damage Heavy State) #Check If Fox Is Up-Airing lwz r3,0x10(r29) cmpwi r3,0x44 bne SDITraining_SkipMissedSDICheck #Check If P1 is in Hitlag lbz r3,0x221A(r27) #Check If in Hitlag rlwinm. r3,r3,0,26,26 beq SDITraining_SkipMissedSDICheck #Check If Fox is Past Frame 11 li r3,11 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f2,f1 blt SDITraining_SkipMissedSDICheck #Reset Score li r3,0 sth r3,-0x4ea8(r13) SDITraining_SkipMissedSDICheck: #Update Score lhz r3,-0x4ea8(r13) branchl r12,HUD_KOCounter_UpdateKOs #Check State lbz r3,0x8(r31) cmpwi r3,0 beq SDITrainingUpThrowThink cmpwi r3,1 beq SDITrainingFollowOpponentThink cmpwi r3,2 beq SDITrainingJumpThink cmpwi r3,3 beq SDITrainingUpAirThink cmpwi r3,4 beq SDITrainingCheckForReset #******************************************************# SDITrainingUpThrowThink: #Check Timer lwz r3,0x4(r31) cmpwi r3,0x0 blt SDITrainingThinkExit #Check If In Wait lwz r3,0x10(r29) cmpwi r3,0xE bne SDITrainingUpThrowThink_InputUpThrow #Advance to Next State li r3,0x1 stb r3,0x8(r31) b SDITrainingFollowOpponentThink SDITrainingUpThrowThink_InputUpThrow: #UpThrow li r3,127 stb r3,0x1A8D(r29) b SDITrainingThinkExit #******************************************************# SDITrainingFollowOpponentThink: SDITrainingFollowOpponentThink_CheckIfAirbourne: lwz r3,0xE0(r29) cmpwi r3,0x1 bne SDITrainingFollowOpponentThink_CheckDistance li r3,0x2 stb r3,0x8(r31) b SDITrainingJumpThink SDITrainingFollowOpponentThink_CheckDistance: #Determine Which Distance Value lwz r3,0x10(r29) cmpwi r3,0x14 bne 0xC li r3,15 b 0x8 li r3,10 bl SDITrainingInputTowardsOpponent #Check If Already Jumping, If So Follow Through lwz r4,0x10(r29) cmpwi r4,0x18 beq SDITrainingFollowOpponentThink_CheckIfJumping cmpwi r3,0x1 #Checks If In Range of Opponent bne SDITrainingThinkExit #Check If Jumping SDITrainingFollowOpponentThink_CheckIfJumping: lwz r3,0x10(r29) cmpwi r3,0x18 bne SDITrainingFollowOpponentThink_InputJump #If Less than 32 Mm Away, Short Hop lfs f1,0xB4(r27) #P1 X Coord lfs f2,0xB4(r29) #P2 X Coord fsubs f3,f2,f1 #Get Difference li r3,32 bl IntToFloat fabs f2,f3 fcmpo cr0,f2,f1 blt SDITrainingThinkExit #Input Jump SDITrainingFollowOpponentThink_InputJump: li r3,0x800 stw r3,0x1A88(r29) b SDITrainingThinkExit #******************************************************# SDITrainingJumpThink: #Follow Opponent li r3,5 bl SDITrainingInputTowardsOpponent #When Less Than 35 Mm Away in the Y Direction, Up Air lfs f1,0xB4(r27) #P1 X Coord lfs f2,0xB4(r29) #P2 X Coord fsubs f3,f2,f1 #Get Difference li r3,35 bl IntToFloat fabs f2,f3 fcmpo cr0,f2,f1 bgt SDITrainingJumpThink_CheckToDJ #Input UpAir li r3,127 stb r3,0x1A8F(r29) #Set Timer To Reset li r3,60 stb r3,0x9(r31) #Advance State li r3,0x3 stb r3,0x8(r31) b SDITrainingUpAirThink SDITrainingJumpThink_CheckToDJ: #If in Frame X Of Jump, DJ lwz r3,0x10(r29) cmpwi r3,0x19 beq SDITrainingJumpThink_CheckToDJ_InJump cmpwi r3,0x1A beq SDITrainingJumpThink_CheckToDJ_InJump b SDITrainingThinkExit SDITrainingJumpThink_CheckToDJ_InJump: li r3,4 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f1,f2 bne SDITrainingThinkExit #Enter DJ li r3,0x800 stw r3,0x1A88(r29) b SDITrainingThinkExit #******************************************************# SDITrainingUpAirThink: #Check If UpAir Hitboxes Are Over li r3,12 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f2,f1 bge SDITrainingCheckForReset #Follow Opponent li r3,5 bl SDITrainingInputTowardsOpponent #Check If Back On Ground lwz r3,0xE0(r29) cmpwi r3,0x0 bne SDITrainingCheckForReset #Advance State li r3,0x4 stb r3,0x8(r31) b SDITrainingCheckForReset #******************************************************# SDITrainingInputTowardsOpponent: #Returns a bool indicating if the character is within range backup mr r31,r3 #Backup Distance Threshold #Get X Distance lfs f1,0xB0(r27) #P1 X Coord lfs f2,0xB0(r29) #P2 X Coord fsubs f3,f2,f1 #Get Difference #If Within 4 Mm, Jump mr r3,r31 bl IntToFloat fabs f2,f3 fcmpo cr0,f2,f1 bgt SDITrainingFollowOpponentThink_InputTowardsOpponent li r3,0x1 b SDITrainingInputTowardsOpponent_Exit SDITrainingFollowOpponentThink_InputTowardsOpponent: #Push Towards Opponent's Direction bl GetDirectionInRelationToP1 mulli r3,r3,-1 #Negate This li r4,127 mullw r3,r3,r4 stb r3,0x1A8C(r29) li r3,0x0 SDITrainingInputTowardsOpponent_Exit: restore blr #******************************************************# SDITrainingCheckForReset: lbz r3,0x9(r31) cmpwi r3,0x0 beq SDITrainingThinkExit subi r3,r3,0x1 stb r3,0x9(r31) cmpwi r3,0x0 bne SDITrainingThinkExit #Load State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Random Timer li r3,60 branchl r12,HSD_Randi mulli r3,r3,-1 stw r3,0x4(r31) #Reset State li r3,0 stb r3,0x8(r31) #Reset SDI'd Flag li r3,0x0 stb r3,0xA(r31) SDITrainingThinkExit: restore blr ############## Event_EnterGrab: backup mr r20,r3 #Move P1 lfs f1,0x0(r20) stfs f1,0xB0(r27) lfs f1,0x4(r20) stfs f1,0xB4(r27) mr r3,r28 bl UpdatePosition mr r3,r28 bl CheckIfPlayerHasAFollower cmpwi r3,0 beq Event_EnterGrab_MoveP2 #Move Subchar lfs f1,0x0(r20) stfs f1,0xB0(r5) lfs f1,0x4(r20) stfs f1,0xB4(r5) bl UpdatePosition Event_EnterGrab_MoveP2: #Move P2 lfs f1,0x8(r20) stfs f1,0xB0(r29) lfs f1,0xC(r20) stfs f1,0xB4(r29) mr r3,r30 bl UpdatePosition mr r3,r30 bl CheckIfPlayerHasAFollower cmpwi r3,0 beq Event_EnterGrab_EnterGrabAS #Move Subchar lfs f1,0x8(r20) stfs f1,0xB0(r5) lfs f1,0xC(r20) stfs f1,0xB4(r5) bl UpdatePosition Event_EnterGrab_EnterGrabAS: #Store P1 into P2 Grab Pointer stw r28,0x1A58(r29) #Enter P2 Into Grab mr r3,r30 #P2 Enters Grab branchl r12,AS_GrabOpponent #Enter P1 Into Grabbed mr r3,r28 #P1 Grabbed mr r4,r30 #P2 = Grabber branchl r12,AS_Grabbed #Enter P2 Into GrabWait mr r3,r30 #P2 Enters GrabWait branchl r12,AS_CatchWait #Enter P2 Into Grounded mr r3,r29 branchl r12,SetAsGrounded #Remove P2's GFX Pointer That Is Crashing the Game li r3,0x0 stw r3,0x60C(r29) restore blr ############## SDITrainingStartingPercents: blrl .long 0x085F8040 # Mario = 8 / Fox = 95 / Falcon = 70 / DK = 25 .long 0x0030190F # Kirby = 0 / Bowser = 25 / Link = 25 / Sheik = 15 .long 0x00000000 # Ness = 0 / Peach = 0 / Popo = 0 / Nana = 0 .long 0x08050F00 # Pikachu = 8 / Samus = 5 / Yoshi = 15 / Jiggs = 0 .long 0x00001400 # Mewtwo = 0 / Luigi = 0 / Marth = 20 / Zelda = 0 .long 0x19085F00 # YLink = 25 / Doc = 8 / Falco = 95 / Pichu = 0 .long 0x002D3A00 # GaW = 0 / Ganon = 45 / Roy = 58 SDITrainingFloats: blrl .long 0xC02CCCCD #P1 X Position .long 0x00000000 #P1 Y Position .long 0x4144CCCD #P2 X Position .long 0x00000000 #P2 Y Position SDITrainingLoadExit: restore blr ################################################################################ ################################################################################ #endregion #region Reversal Training ######################### ## Reversal HIJACK INFO ## ######################### Reversal: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,-1 #Use SSS Stage load r7,EventOSD_Reversal li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION bl ReversalLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Reversal LOAD FUNCT ## ######################## ReversalLoad: blrl backup #Schedule Think bl ReversalThink mflr r3 li r4,3 #Priority (After Interrupt) bl ReversalWindowInfo mflr r5 bl ReversalWindowText mflr r6 bl CreateEventThinkFunction b ReversalLoadExit ######################### ## Reversal THINK FUNCT ## ######################### .set MenuData,26 .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 .set firstFrameFlag,0x0 .set timer,0x4 .set CPUAttack,(MenuData_OptionMenuMemory+0x2)+(0x0) .set P1FacingDirection,(MenuData_OptionMenuMemory+0x2)+(0x1) .set CPUFacingDirection,(MenuData_OptionMenuMemory+0x2)+(0x2) .set CPUAttackToggled,MenuData_OptionMenuToggled+(0x0) .set P1FacingDirectionToggled,MenuData_OptionMenuToggled+(0x1) .set CPUFacingDirectionToggled,MenuData_OptionMenuToggled+(0x2) .set AerialThinkStruct,0x20 ReversalThink: blrl .set EventData,31 backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 lwz MenuData,EventData_MenuDataPointer(EventData) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 li r3,0xF stb r3,0x1A94(r29) bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq ReversalThinkMain #bl Reversal_Floats #mflr r3 #bl InitializePositions #Move PLayers Center Stage bl PlacePlayersCenterStage #Clear Inputs bl RemoveFirstFrameInputs #SaveState addi r3,EventData,0x10 #SaveState start li r4,1 #Override failsafe code bl SaveState_Save #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) #Set Timer to -60 li r3,-60 stw r3,0x4(r31) ReversalThinkMain: bl GiveFullShields #Reset when menu is toggled lbz r3,P1FacingDirectionToggled(MenuData) cmpwi r3,0x0 bne ReversalReset #Only Run When Hovered Over Facing Direction lbz r3,CPUFacingDirectionToggled(MenuData) cmpwi r3,0x0 bne ReversalReset #Only Run When Hovered Over Facing Direction lbz r3,CPUAttackToggled(MenuData) cmpwi r3,0x0 bne ReversalReset ReversalSkipFacingReset: #Move Players Apart With DPad addi r3,EventData,0x10 #SaveState start bl AdjustResetDistance cmpwi r3,-1 bne ReversalReset ReversalThinkSequence: #Increment Timer lwz r20,0x4(r31) #get timer addi r20,r20,0x1 stw r20,0x4(r31) #store timer #Give Invincibility in Wait, Squat Reverse, IASA Flag Flipped lwz r3,0x10(r29) cmpwi r3,0xE beq ReversalGiveInvincibility cmpwi r3,0x29 beq ReversalGiveInvincibility lbz r3, 0x2218 (r29) rlwinm. r3, r3, 25, 31, 31 bne ReversalGiveInvincibility b ReversalCheckToAttack ReversalGiveInvincibility: mr r3,r30 li r4,0x2 bl GiveInvincibility #Check To Attack ReversalCheckToAttack: #Check Timer cmpwi r20,45 blt ReversalThinkExit #Check If Attack is Over lbz r3,AerialThinkStruct(r31) cmpwi r3,0x0 bne ReversalCheckToReset ReversalDecideSmashAttack: lbz r3,CPUAttack(MenuData) cmpwi r3,0x0 beq ReversalRandomSmashAttack cmpwi r3,0x1 beq ReversalFSmash cmpwi r3,0x2 beq ReversalDSmash cmpwi r3,0x3 beq ReversalUSmash cmpwi r3,0x4 beq ReversalRandomAerial cmpwi r3,0x5 beq ReversalNair cmpwi r3,0x6 beq ReversalFair cmpwi r3,0x7 beq ReversalDair cmpwi r3,0x8 beq ReversalFTilt cmpwi r3,0x9 beq ReversalDTilt cmpwi r3,0xA beq ReversalUTilt ReversalRandomSmashAttack: li r3,3 branchl r12,HSD_Randi mr r21,r3 #Check If Move is Blacklisted lwz r4,0x4(r29) #Char ID bl Reversal_Blacklist mflr r5 #Get Frame Data Table mulli r4,r4,0x4 #Get Characters Offset add r4,r4,r5 #Get Characters Table Entry Start lbzx r4,r21,r4 #Get Moves Entry cmpwi r4,0x1 #Is Move BlackListed? beq ReversalRandomSmashAttack #Perform Move cmpwi r21,0x0 beq ReversalFSmash cmpwi r21,0x1 beq ReversalUSmash cmpwi r21,0x2 beq ReversalDSmash ReversalFSmash: #Input Atack li r3,127 #Forward lfs f1,0x2C(r29) #Facing Direction fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) mullw r3,r3,r4 #Forward * facing direction stb r3,0x1A8E(r29) #Set Attack as ended li r3,0x1 stb r3,AerialThinkStruct(r31) b ReversalCheckToReset ReversalUSmash: li r3,127 stb r3,0x1A8F(r29) b ReversalCheckToReset #Set Attack as ended li r3,0x1 stb r3,AerialThinkStruct(r31) ReversalDSmash: li r3,-127 stb r3,0x1A8F(r29) #Set Attack as ended li r3,0x1 stb r3,AerialThinkStruct(r31) b ReversalCheckToReset ReversalRandomAerial: #Perform Aerial mr r3,r30 addi r4,r31,AerialThinkStruct li r5,0 #Random Aerial bl PerformAerialThink b ReversalCheckToReset ReversalNair: ReversalFair: ReversalDair: #Perform Aerial subi r5,r3,0x4 mr r3,r30 addi r4,r31,AerialThinkStruct bl PerformAerialThink b ReversalCheckToReset ReversalFTilt: li r3,45 lfs f1,0x2C(r29) #Facing Direction fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) mullw r3,r3,r4 #Forward * facing direction stb r3,0x1A8C(r29) li r3,0x100 stw r3,0x1A88(r29) #Set Attack as ended li r3,0x1 stb r3,AerialThinkStruct(r31) b ReversalCheckToReset ReversalUTilt: li r3,45 stb r3,0x1A8D(r29) li r3,0x100 stw r3,0x1A88(r29) #Set Attack as ended li r3,0x1 stb r3,AerialThinkStruct(r31) b ReversalCheckToReset ReversalDTilt: li r3,-45 stb r3,0x1A8D(r29) li r3,0x100 stw r3,0x1A88(r29) #Set Attack as ended li r3,0x1 stb r3,AerialThinkStruct(r31) b ReversalCheckToReset ReversalCheckToReset: cmpwi r20,150 #Restore After 120 Frames blt ReversalThinkExit ReversalReset: ReversalSwap: #I fucking hate this code, i need to clean this up at some point. #Get leftmost player pointer in r20, rightmost in r21 addi r5,EventData,0x10 lwz r3,0x0(r5) lfs f1,0xB0(r3) lwz r4,0x8(r5) lfs f2,0xB0(r4) fcmpo cr0,f1,f2 bgt 0x10 mr r20,r3 mr r21,r4 b 0xC mr r20,r4 mr r21,r3 #Get which side to start on li r3,2 #0 = p1 on left, 1 = p1 on right branchl r12,HSD_Randi cmpwi r3,0x0 bne ReversalReset_RightSide ReversalReset_LeftSide: #Swap Position addi r5,EventData,0x10 #Get Leftmost Chars Position li r3,1 bl IntToFloat fmr f2,f1 lfs f3,0xB0(r20) lfs f4,0xB4(r20) #Get Rightmost Chars Position li r3,-1 bl IntToFloat fmr f5,f1 lfs f6,0xB0(r21) lfs f7,0xB4(r21) #Store to P1 Data lwz r3,0x0(r5) stfs f2,0x2C(r3) stfs f3,0xB0(r3) stfs f4,0xB4(r3) #Store to P2 Data lwz r3,0x8(r5) stfs f5,0x2C(r3) stfs f6,0xB0(r3) stfs f7,0xB4(r3) b ReversalReset_SwapEnd ReversalReset_RightSide: addi r5,EventData,0x10 #Get Leftmost Chars Position li r3,1 bl IntToFloat fmr f2,f1 lfs f3,0xB0(r20) lfs f4,0xB4(r20) #Get Rightmost Chars Position li r3,-1 bl IntToFloat fmr f5,f1 lfs f6,0xB0(r21) lfs f7,0xB4(r21) #Store to P2 Data lwz r3,0x8(r5) stfs f2,0x2C(r3) stfs f3,0xB0(r3) stfs f4,0xB4(r3) #Store to P1 Data lwz r3,0x0(r5) stfs f5,0x2C(r3) stfs f6,0xB0(r3) stfs f7,0xB4(r3) ReversalReset_SwapEnd: ReversalAdjustP1Direction: #Adjust P1 Facing Direction Based on Preference addi r5,EventData,0x10 lbz r3,P1FacingDirection(MenuData) cmpwi r3,0x1 bne ReversalAdjustP1Direction_Skip #Invert P1 Facing Direction lwz r3,0x0(r5) lfs f1,0x2C(r3) fneg f1,f1 stfs f1,0x2C(r3) ReversalAdjustP1Direction_Skip: #Adjust CPU Facing Direction Based on Preference ReversalAdjustCPUDirection: lbz r3,CPUFacingDirection(MenuData) cmpwi r3,0x1 bne ReversalAdjustCPUDirection_Skip #Invert P2 Facing Direction lwz r3,0x8(r5) lfs f1,0x2C(r3) fneg f1,f1 stfs f1,0x2C(r3) ReversalAdjustCPUDirection_Skip: #Restore ReversalLoadState: addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Reset Timer li r3,30 branchl r12,HSD_Randi li r4,0 sub r3,r4,r3 stw r3,0x4(r31) #Reset AerialThinkStruct li r3,0x0 stw r3,AerialThinkStruct(r31) ReversalThinkExit: mr r3,MenuData bl ClearToggledOptions bl UpdateAllGFX restore blr ################################# Reversal_Floats: blrl .long 0xC0F9999A #P1 X Position .long 0x40F9999A #P2 X Position .long 0x38d1b717 #FD Floor Y Coord .long 0x38d1b717 #FD Floor Y Coord ################################# Reversal_Blacklist: blrl #Mario .long 0x00000000 #FSmash USmash DSmash #Fox .long 0x01000000 #FSmash USmash DSmash #Cptn Falcon .long 0x00000000 #FSmash USmash DSmash #DK .long 0x00010000 #FSmash USmash DSmash #Kirby .long 0x00000000 #FSmash USmash DSmash #Bowser .long 0x00010000 #FSmash USmash DSmash #link .long 0x00000000 #FSmash USmash DSmash #Sheik .long 0x01000000 #FSmash USmash DSmash #Ness .long 0x00010100 #FSmash USmash DSmash #Peach .long 0x00010000 #FSmash USmash DSmash #Popo .long 0x00000000 #FSmash USmash DSmash #Nana .long 0x00000000 #FSmash USmash DSmash #Pikachu .long 0x00000000 #FSmash USmash DSmash #Samus .long 0x00010000 #FSmash USmash DSmash #Yoshi .long 0x00010000 #FSmash USmash DSmash #Jiggs .long 0x00010000 #FSmash USmash DSmash #mewtwo .long 0x00010000 #FSmash USmash DSmash #Luigi .long 0x00000000 #FSmash USmash DSmash #Marth .long 0x00010000 #FSmash USmash DSmash #Zelda .long 0x00010000 #FSmash USmash DSmash #YLink .long 0x00000000 #FSmash USmash DSmash #Doc .long 0x00000000 #FSmash USmash DSmash #Falco .long 0x01000000 #FSmash USmash DSmash #Pichu .long 0x00000000 #FSmash USmash DSmash #GaW .long 0x00000100 #FSmash USmash DSmash #Ganon .long 0x00000000 #FSmash USmash DSmash #Roy .long 0x00010000 #FSmash USmash DSmash #################################################### ReversalWindowInfo: blrl #amount of options, amount of options in each window .long 0x020A0101 #3 window, Smash Attack has 11 options, Facing Direction Has 2 #################################################### ReversalWindowText: blrl ######## ## DI ## ######## #Window Title = CPU Attack .long 0x43505520 .long 0x41747461 .long 0x636b0000 #Option 1 = Random Smash Attack .long 0x52616e64 .long 0x6f6d2053 .long 0x6d617368 .long 0x20417474 .long 0x61636b00 #Option 2 = Forward Smash .long 0x466f7277 .long 0x61726420 .long 0x536d6173 .long 0x68000000 #Option 3 = Down Smash .long 0x446f776e .long 0x20536d61 .long 0x73680000 #Option 4 = Up Smash .long 0x55702053 .long 0x6d617368 .long 0x #Option 5 = Random Aerial .long 0x52616e64 .long 0x6f6d2041 .long 0x65726961 .long 0x6c000000 #Option 6 = Fair .long 0x46616972 .long 0x #Option 7 = Nair .long 0x4e616972 .long 0x #Option 8 = Dair .long 0x44616972 .long 0x #Option 9 = FTilt .long 0x4654696c .long 0x74000000 #Option 10 = DTilt .long 0x4454696c .long 0x74000000 #Option 11 = UTilt .long 0x5554696c .long 0x74000000 #########$$$############# ## P1 Facing Direction ## ##########$$$############ #Window Title = Facing Direction .long 0x50312046 .long 0x6163696e .long 0x67204469 .long 0x72656374 .long 0x696f6e00 #Option 1 = Towards .long 0x546f7761 .long 0x72647300 .long 0x .long 0x .long 0x #Option 2 = Away .long 0x41776179 .long 0x .long 0x .long 0x .long 0x #########$$$############## ## CPU Facing Direction ## ##########$$$############# #Window Title = CP Facing Direction .long 0x43502046 .long 0x6163696e .long 0x67204469 .long 0x72656374 .long 0x696f6e00 #Option 1 = Towards .long 0x546f7761 .long 0x72647300 .long 0x .long 0x .long 0x #Option 2 = Away .long 0x41776179 .long 0x .long 0x .long 0x .long 0x #################################################### ReversalLoadExit: restore blr ################################################################################ ################################################################################ #endregion #region Powershield Training ######################### ## Powershield HIJACK INFO ## ######################### Powershield: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Falco.Ext #Use chosen CPU li r6,FinalDestination #Use SSS Stage load r7,EventOSD_Powershield li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION bl PowershieldLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Powershield LOAD FUNCT ## ######################## PowershieldLoad: blrl backup #Schedule Think bl PowershieldThink mflr r3 li r4,3 #Priority (After Interrupt) bl PowershieldWindowInfo mflr r5 bl PowershieldWindowText mflr r6 bl CreateEventThinkFunction bl InitializeHighScore b PowershieldLoadExit ######################### ## Powershield THINK FUNCT ## ######################### #Registers .set MenuData,26 .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 #Offsets .set FireSpeed,(MenuData_OptionMenuMemory+0x2)+0x0 PowershieldThink: blrl backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 lwz MenuData,EventData_MenuDataPointer(EventData) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl StoreCPUTypeAndZeroInputs #Make P2 A Follower (No Nudge) #li r3,0x8 #stb r3,0x221F(r29) li r3,0x1 lbz r0, 0x221D (r29) rlwimi r0,r3,2,29,29 stb r0, 0x221D (r29) #Update GFX mr r3,r30 bl UpdateAllGFX #Give Invincibility To P2 mr r3,r30 li r4,0x2 bl GiveInvincibility #Reset All Stale Moves bl ResetStaleMoves #DPad Changes Falco's Side lhz r3,0x662(r27) #Get Held Buttons rlwinm. r0,r3,0,27,27 bne 0xC cmpwi r3,0x0 bne Powershield_SkipPositionChange #CHECK FOR DPAD TO CHANGE Side lwz r3,0x668(r27) #Get DPad rlwinm. r0,r3,0,30,30 beq Powershield_CheckLeft lwz r3,0x10(r31) #P1's Backup lfs f1,0xB0(r3) #X Pos fabs f1,f1 stfs f1,0xB0(r3) #X Pos lfs f1,0x2C(r3) #Facing fabs f1,f1 fneg f1,f1 #Negate Always stfs f1,0x2C(r3) #Facing lwz r3,0x18(r31) #P2's Backup lfs f1,0xB0(r3) #X Pos fabs f1,f1 fneg f1,f1 #Negate Always stfs f1,0xB0(r3) #X Pos lfs f1,0x2C(r3) #Facing fabs f1,f1 #Always Positive stfs f1,0x2C(r3) #Facing b PowershieldRestore Powershield_CheckLeft: rlwinm. r0,r3,0,31,31 beq Powershield_SkipPositionChange lwz r3,0x10(r31) #P1's Backup lfs f1,0xB0(r3) #X Pos fabs f1,f1 fneg f1,f1 #Negate Always stfs f1,0xB0(r3) #X Pos lfs f1,0x2C(r3) #Facing fabs f1,f1 #Always Positive stfs f1,0x2C(r3) #Facing lwz r3,0x18(r31) #P2's Backup lfs f1,0xB0(r3) #X Pos fabs f1,f1 stfs f1,0xB0(r3) #X Pos lfs f1,0x2C(r3) #Facing fabs f1,f1 fneg f1,f1 #Negate Always stfs f1,0x2C(r3) #Facing b PowershieldRestore Powershield_SkipPositionChange: #Act Out Of Laser Hit bl ActOutOfLaserHitDisplay #Check For Powershield Reflect #Check For Shield Action State lwz r3,0x10(r27) cmpwi r3,0xB6 #Shield Start bne Powershield_SkipPowershieldCheck #Check For Powershield Bool lwz r3,0x2368(r27) cmpwi r3,0x0 beq Powershield_SkipPowershieldCheck #Remove Flag li r3,0x0 stw r3,0x2368(r27) #Increment Score lhz r3,-0x4ea8(r13) addi r3,r3,0x1 sth r3,-0x4ea8(r13) #Check To Make New High Score lhz r3,-0x4ea8(r13) lhz r4,-0x4ea6(r13) cmpw r3,r4 ble Powershield_SkipPowershieldCheck #Copy To High Score sth r3,-0x4ea6(r13) Powershield_SkipPowershieldCheck: #Check For Powershield Miss #Check For Shield Stun lwz r3,0x10(r27) cmpwi r3,0xB5 #Shield Stun beq Powershield_ResetScore #Check For Hitstun lbz r3, 0x221C (r27) rlwinm. r0, r3, 31, 31, 31 bne Powershield_ResetScore b Powershield_SkipMissedPowershieldCheck Powershield_ResetScore: #Reset Score li r3,0 sth r3,-0x4ea8(r13) Powershield_SkipMissedPowershieldCheck: #Update HUD Score lhz r3,-0x4ea8(r13) branchl r12,HUD_KOCounter_UpdateKOs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq PowershieldThinkMain #Set Timer to -60 li r3,-60 stw r3,0x4(r31) #Fix Inputs bl CurrentInputsAsLastFramesInputs #SaveState addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save PowershieldThinkMain: bl GiveFullShields PowershieldThinkSequence: #Increment Timer lwz r20,0x4(r31) #get timer addi r20,r20,0x1 stw r20,0x4(r31) #store timer #KneeBend(shorthop) cmpwi r20,0 blt PowershieldThinkExit bne PowershieldSkipJump li r3,0x800 stw r3,0x1A88(r29) b PowershieldThinkExit #Get Random Laser Timing in JumpF PowershieldSkipJump: lwz r3,0x10(r29) cmpwi r3,0x19 bne PowershieldSkipLaser li r3,4 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f1,f2 bne PowershieldThinkExit #Random Laser Timing li r3,2 branchl r12,HSD_Randi addi r3,r3,5 #Start on Frame 5 stw r3,0x8(r31) #Input Laser li r3,0x200 stw r3,0x1A88(r29) b PowershieldThinkExit PowershieldSkipLaser: #Check if in Laser Shoot lwz r3,0x10(r29) cmpwi r3,0x159 bne PowershieldCheckForIASA #Check in on the right frame lwz r3,0x8(r31) bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f1,f2 bne PowershieldCheckForIASA #Input a FF li r3,-127 stb r3,0x1A8D(r29) b PowershieldThinkExit PowershieldCheckForIASA: #Check if in Landing lwz r3,0x10(r29) cmpwi r3,0x2A bne PowershieldThinkExit #Check If Can Interrupt li r3,3 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f2,f1 blt PowershieldThinkExit bne PowershieldRandom li r3,14 branchl r12,HSD_Randi addi r3,r3,15 stb r3,0xF(r31) #Get Interval lbz r3,FireSpeed(MenuData) cmpwi r3,0x0 beq PowershieldRandom cmpwi r3,0x1 beq PowershieldSlow cmpwi r3,0x2 beq PowershieldMedium cmpwi r3,0x3 beq PowershieldFast cmpwi r3,0x4 beq PowershieldVeryFast PowershieldRandom: lbz r3,0xF(r31) bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f2,f1 blt PowershieldThinkExit li r3,-1 stw r3,0x4(r31) b PowershieldThinkExit PowershieldSlow: #Reset Timer li r3,-30 stw r3,0x4(r31) b PowershieldThinkExit PowershieldMedium: #Reset Timer li r3,-15 stw r3,0x4(r31) b PowershieldThinkExit PowershieldFast: #Reset Timer li r3,-8 stw r3,0x4(r31) b PowershieldThinkExit PowershieldVeryFast: #Reset Timer li r3,-1 stw r3,0x4(r31) b PowershieldThinkExit PowershieldThinkExit: mr r3,MenuData bl ClearToggledOptions restore blr PowershieldLoadExit: restore blr ################################## PowershieldRestore: addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load b PowershieldThinkExit ################################## PowershieldWindowInfo: blrl .long 0x00040000 #1 window, 5 options PowershieldWindowText: blrl #Title .long 0x46697265 .long 0x20537065 .long 0x65640000 .long 0x00000000 .long 0x00000000 #Random .long 0x52616e64 .long 0x6f6d0000 .long 0x .long 0x .long 0x #Slow .long 0x536c6f77 .long 0x .long 0x .long 0x .long 0x #Medium .long 0x4d656469 .long 0x756d0000 .long 0x .long 0x .long 0x #Fast .long 0x46617374 .long 0x .long 0x .long 0x .long 0x #Very Fast .long 0x56657279 .long 0x20466173 .long 0x74000000 .long 0x .long 0x ################################## ################################################################################ ################################################################################ #endregion #region Shield Drop Training ######################### ## Shield Drop HIJACK INFO ## ######################### ShieldDrop: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,Battlefield #Use SSS Stage load r7,EventOSD_ShieldDrop li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION bl ShieldDropLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Shield Drop LOAD FUNCT ## ######################## ShieldDropLoad: blrl backup #Schedule Think bl ShieldDropThink mflr r3 li r4,3 #Priority (After Interrupt) bl ShieldDropWindowInfo mflr r5 bl ShieldDropWindowText mflr r6 bl CreateEventThinkFunction b ShieldDropLoadExit ########################## ## Shield Drop THINK FUNCT ## ########################## #Registers .set MenuData,26 .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 #Offsets .set FacingDirection,(MenuData_OptionMenuMemory+0x2)+0x0 .set FacingDirectionToggled,(MenuData_OptionMenuToggled)+0x0 ShieldDropThink: blrl backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 lwz MenuData,EventData_MenuDataPointer(EventData) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq ShieldDropThinkMain #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) bl ShieldDrop_Floats mflr r3 bl InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Store Y Position to Last Known Y Position lfs f1,0xB4(r29) stfs f1,0x834(r29) #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Set Timer to -60 li r3,-60 stw r3,0x4(r31) ShieldDropThinkMain: .set AerialThinkStruct,0x8 bl GiveFullShields lbz r3,FacingDirectionToggled(MenuData) cmpwi r3,0 #Check If Toggled An Option bne ShieldDropReset lbz r3,FacingDirectionToggled(MenuData) cmpwi r3,0 #Check If Toggled An Option bne ShieldDropReset #Move Players Apart With DPad addi r3,EventData,0x10 #SaveState start bl AdjustResetDistance cmpwi r3,-1 bne ShieldDropReset ShieldDropThinkSequence: #Increment Timer lwz r20,0x4(r31) #get timer addi r20,r20,0x1 stw r20,0x4(r31) #store timer #Check if In Wait lwz r3,0x10(r29) cmpwi r3,0xE bne ShieldDropNoIntangibility #Give Intangibility in Wait mr r3,r30 li r4,0x2 bl GiveInvincibility ShieldDropNoIntangibility: #Check To Start Aerial cmpwi r20,40 blt ShieldDropThinkExit #Perform Aerial mr r3,r30 addi r4,r31,AerialThinkStruct li r5,0 #Random Attack bl PerformAerialThink ShieldDropCheckToShield: #Check If CPU is done with Aerial Sequence lbz r3,AerialThinkStruct(r31) cmpwi r3,0x0 beq ShieldDropCheckToReset #Hold Shield li r3,0xC0 #Hit L stw r3,0x1A88(r29) #Hold Shield ShieldDropCheckToReset: cmpwi r20,140 bne ShieldDropThinkExit ShieldDropReset: #Randomize Position li r3,0x1 #Opposing Sides of Stage bl Randomize_LeftorRightSide #Adjust Facing Direction Based on Preference lbz r3,FacingDirection(MenuData) cmpwi r3,0x1 bne ShieldDropLoadState #Invert P1 Facing Direction lwz r3,0x10(r31) lfs f1,0x2C(r3) fneg f1,f1 stfs f1,0x2C(r3) ShieldDropLoadState: #Backup P1 Analog Timers lwz r23,0x620(r27) lwz r24,0x624(r27) #Restore addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Restore P1 Analog Timers lwz r23,0x620(r27) lwz r24,0x624(r27) #Reset Timer li r3,50 branchl r12,HSD_Randi li r4,0 sub r3,r4,r3 stw r3,0x4(r31) #Reset Aerial Move Think Struct li r3,0 stw r3,AerialThinkStruct(r31) ShieldDropThinkExit: mr r3,MenuData bl ClearToggledOptions bl UpdateAllGFX restore blr ################################# ShieldDrop_Floats: blrl .long 0xC0F9999A #P1 X Position .long 0x40F9999A #P2 X Position .long 0x425999b4 #Top Plat Y Position .long 0x425999b4 #Top Plat Y Position .long 0x3E99999A #Y Vel to Attack .long 0x40A00000 #Distance from Ground to L Cancel ################################# ShieldDropWindowInfo: blrl .long 0x0001FFFF #1 Window, Facing Direction Has 2 Options ################################ ShieldDropWindowText: blrl ###################### ## Facing Direction ## ###################### #Window Title = Facing Direction .long 0x46616369 .long 0x6e672044 .long 0x69726563 .long 0x74696f6e .long 0x #Option 1 = Towards .long 0x546f7761 .long 0x72647300 .long 0x .long 0x .long 0x #Option 2 = Away .long 0x41776179 .long 0x .long 0x .long 0x .long 0x ################################# ShieldDropLoadExit: restore blr ################################################################################ #endregion #region Attack on Shield ######################### ## Attack On Shield HIJACK INFO ## ######################### AttackOnShield: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,FinalDestination #Use SSS Stage load r7,EventOSD_AttackOnShield li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION bl AttackOnShieldLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Attack On Shield LOAD FUNCT ## ######################## AttackOnShieldLoad: blrl backup #Schedule Think bl AttackOnShieldThink mflr r3 li r4,3 #Priority (After Interrupt) bl AttackOnShieldWindowInfo mflr r5 bl AttackOnShieldWindowText mflr r6 bl CreateEventThinkFunction b AttackOnShieldLoadExit ######################### ## Attack On Shield THINK FUNCT ## ######################### #Registers .set MenuData,26 .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 .set firstFrameFlag,0x0 .set timer,0x4 .set OoSOption,MenuData_OptionMenuMemory+0x2 + 0x0 .set OoSOptionToggled,MenuData_OptionMenuToggled + 0x0 AttackOnShieldThink: blrl backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 lwz MenuData,EventData_MenuDataPointer(EventData) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq AttackOnShieldThinkMain #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) bl AttackOnShield_Floats mflr r3 bl InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save AttackOnShieldThinkMain: bl GiveFullShields #Reset If Anyone Dies bl IsAnyoneDead cmpwi r3,0x0 bne AttackOnShieldRestoreState AttackOnShieldThinkSequence: lbz r3,OoSOptionToggled(MenuData) cmpwi r3,0 beq AttackOnShieldNoOptionToggled #Clear Last AS So CPU Doesnt Act Immediately li r3,0 sth r3,TM_OneASAgo(r29) AttackOnShieldNoOptionToggled: #Get Floats bl AttackOnShield_Floats mflr r21 #Get Frames as Int lfs f1,0x894(r29) fctiwz f1,f1 stfd f1,0xF0(sp) lwz r22,0xF4(sp) #Check If Perfroming OoS Option lwz r3,0x4(r31) cmpwi r3,0x0 ble AttackOnShieldShieldWait #Branch To OoSThink lbz r3,OoSOption(MenuData) cmpwi r3,0x1 beq AttackOnShieldNairThink cmpwi r3,0x2 beq AttackOnShieldUpBThink cmpwi r3,0x3 beq AttackOnShieldUpSmashThink cmpwi r3,0x4 beq AttackOnShieldShineThink cmpwi r3,0x7 beq AttackOnShieldWavedashThink b AttackOnShieldShieldWait AttackOnShieldNairThink: lwz r3,0x10(r29) cmpwi r3,0x19 bne AttackOnShieldCheckToReset #Input Nair li r3,0x100 stw r3,0x1A88(r29) b AttackOnShieldCheckToReset AttackOnShieldUpBThink: lwz r3,0x10(r29) cmpwi r3,0x18 bne AttackOnShieldCheckToReset li r3,127 stb r3,0x1A8D(r29) #Press Up li r3,0x200 stw r3,0x1A88(r29) #Press B b AttackOnShieldCheckToReset AttackOnShieldUpSmashThink: lwz r3,0x10(r29) cmpwi r3,0x18 bne AttackOnShieldCheckToReset li r3,127 stb r3,0x1A8D(r29) #Press Up li r3,0x100 stw r3,0x1A88(r29) #Press A b AttackOnShieldCheckToReset AttackOnShieldShineThink: lwz r3,0x10(r29) cmpwi r3,0x19 bne AttackOnShieldCheckToReset #Input Shine li r3,-127 stb r3,0x1A8D(r29) li r3,0x200 stw r3,0x1A88(r29) b AttackOnShieldCheckToReset AttackOnShieldWavedashThink: lwz r3,0x10(r29) cmpwi r3,0x19 bne AttackOnShieldCheckToReset #Get Random Airdodge Angle li r3,30 #30 Different Angles branchl r12,HSD_Randi addi r3,r3,310 #Start at 310° bl ComboTrainingDecideStickAngle_ConvertAngle mr r20,r3 #Joystick X = X Component * (OpponentDirection) bl GetDirectionInRelationToP1 mullw r3,r3,r20 stb r3,0x1A8C(r29) #Joystick Y = Y Component stb r4,0x1A8D(r29) #Press L To Wavedash li r3,0xC0 stw r3,0x1A88(r29) b AttackOnShieldCheckToReset AttackOnShieldShieldWait: #Always Hold L li r3,0xC0 #Hit L stw r3,0x1A88(r29) #Held Buttons #Check If Got Shield Poked #Hitlag lbz r3,0x221A(r29) #Check If in Hitlag rlwinm. r3,r3,0,26,26 beq AttackOnShieldCheckForShieldHit #Damage State lwz r3,0x10(r29) cmpwi r3,0x4B blt AttackOnShieldCheckForShieldHit cmpwi r3,0x5B bgt AttackOnShieldCheckForShieldHit #Was Hit, Start Reset Timer li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldCheckForShieldHit: #Check If In ShieldWait (0xb3) lwz r3,0x10(r29) cmpwi r3,0xB3 bne AttackOnShieldCheckToReset #Check If Was Just in ShieldStun lhz r3,TM_OneASAgo(r29) cmpwi r3,0xB5 bne AttackOnShieldCheckToReset #Input OoS Option lbz r3,OoSOption(MenuData) cmpwi r3,0x0 beq AttackOnShieldInputGrab cmpwi r3,0x1 beq AttackOnShieldNair cmpwi r3,0x2 beq AttackOnShieldUpB cmpwi r3,0x3 beq AttackOnShieldUpSmash cmpwi r3,0x4 beq AttackOnShieldShine cmpwi r3,0x5 beq AttackOnShieldSpotdodge cmpwi r3,0x6 beq AttackOnShieldRoll cmpwi r3,0x7 beq AttackOnShieldWavedash cmpwi r3,0x8 beq AttackOnShieldNone AttackOnShieldInputGrab: li r3,0x1C0 stw r3,0x1A88(r29) #Press R+A li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldNair: li r3,0xCC0 stw r3,0x1A88(r29) #Press X/Y li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldUpB: li r3,127 stb r3,0x1A8D(r29) #Press Up li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldUpSmash: li r3,127 stb r3,0x1A8D(r29) #Press Up li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldShine: li r3,0xCC0 stw r3,0x1A88(r29) #Press X/Y li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldSpotdodge: li r3,-127 stb r3,0x1A8D(r29) #Press Down li r3,0xC0 stw r3,0x1A88(r29) #Press R li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldRoll: li r3,0xC0 stw r3,0x1A88(r29) #Press R #Push Towards Opponent's Direction bl GetDirectionInRelationToP1 li r4,127 mullw r3,r3,r4 stb r3,0x1A8C(r29) #Press Away li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldWavedash: li r3,0xCC0 stw r3,0x1A88(r29) #Press X/Y li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldNone: b AttackOnShieldThinkExit #Check To Reset AttackOnShieldCheckToReset: lwz r3,0x4(r31) #get timer #Get Timer cmpwi r3,0x0 #Check if >0 ble AttackOnShieldThinkExit #Dec Timer subi r3,r3,0x1 stw r3,0x4(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne AttackOnShieldThinkExit #Exit If Not #Randomize P1's X Coord #Get Random X Coord lbz r23,0x10(r21) #Starting X Coord lbz r24,0x11(r21) #Furthest X Coord sub r3,r24,r23 #Get Range branchl r12,HSD_Randi #Get Random Number in Between add r3,r3,r23 #Add to Starting Coord #Cast to Float bl IntToFloat lwz r3,0x10(r31) #P1 Backup stfs f1,0xB0(r3) #P1 Backup X Pos li r3,0x1 #Opposing Sides of Stage bl Randomize_LeftorRightSide AttackOnShieldRestoreState: #Restore State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load b AttackOnShieldThinkExit AttackOnShieldThinkExit: mr r3,MenuData bl ClearToggledOptions restore blr ################################# AttackOnShield_Floats: blrl .long 0xC1A00000 #P1 X Position .long 0x41A00000 #P2 X Position .long 0x38d1b717 #FD Floor Y Coord .long 0x38d1b717 #FD Floor Y Coord .long 0x14460000 #P1 X Rand Pos Range ################################# AttackOnShieldWindowInfo: blrl #amount of options, amount of options in each window .long 0x0008FFFF #1 window, OoS Option has 10 options #################################################### AttackOnShieldWindowText: blrl ################ ## OoS Option ## ################ #Window Title = OoS Option .long 0x4f6f5320 .long 0x4f707469 .long 0x6f6e0000 #Option 1 = Grab .long 0x47726162 .long 0x00000000 #Option 2 = Nair .long 0x4e616972 .long 0x00000000 #Option 3 = Up B .long 0x55702042 .long 0x00000000 #Option 5 = Up Smash .long 0x55702d53 .long 0x6d617368 .long 0x #Option 6 = Shine .long 0x5368696e .long 0x65000000 #Option 7 = Spotdodge .long 0x53706f74 .long 0x646f6467 .long 0x65000000 #Option 8 = Roll Away .long 0x526f6c6c .long 0x20417761 .long 0x79000000 #Option 9 = Wavedash Away .long 0x57617665 .long 0x64617368 .long 0x20417761 .long 0x79000000 #Option 10 = None .long 0x4E6F6E65 .long 0x00000000 AttackOnShieldLoadExit: restore blr ################################################################################ #endregion #region Ledgetech Training ######################### ## Ledgetech HIJACK INFO ## ######################### Ledgetech: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Falco.Ext #Use chosen CPU li r6,-1 #Use chosen Stage load r7,EventOSD_LedgeTech li r8,1 #Use Sopo bool bl InitializeMatch #BUFF DEFENSE RATIO lis r3,0x3f00 stw r3,0x14(r20) #STORE THINK FUNCTION LedgetechStoreThink: bl LedgetechLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Ledgetech LOAD FUNCT ## ######################## LedgetechLoad: blrl backup bl InitializeHighScore #Schedule Think bl LedgetechThink mflr r3 li r4,3 #Priority (After Interrupt) li r5,0 #No Option Menu bl CreateEventThinkFunction b LedgetechLoadExit ######################### ## Ledgetech THINK FUNCT ## ######################### LedgetechThink: blrl .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 .set EventData,31 backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq LedgetechThinkMain #Clear Inputs bl RemoveFirstFrameInputs #Random Side of Stage li r3,2 branchl r12,HSD_Randi bl Ledgetech_InitializePositions #Enter SquatWait mr r3,P2GObj branchl r12,AS_SquatWait #P1 Has 90% li r3,90 load r4,0x80453080 #P1 Static Block sth r3,0x60(r4) #Store Percent Int To Display Value lis r3,0x42B4 stw r3,0x1830(r27) #Always Hold Down (Crouch Cancel) li r3,-127 stb r3,0x1A8D(P2Data) #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe bl SaveState_Save LedgetechThinkMain: bl GiveFullShields LedgetechThinkSequence: #Get Floats bl Ledgetech_Floats mflr r21 #Reset if P1 Is In a Dead State lbz r3,0x221F(r27) rlwinm. r3,r3,0,25,25 bne LedgetechRestoreState #D-Pad Left Restores State lwz r3,0x668(r27) rlwinm. r0, r3, 0, 31, 31 bne LedgetechRestoreState #Always Hold Down (Crouch Cancel) li r3,-127 stb r3,0x1A8D(r29) #Start Timer When Leaving Rebirth Plat lbz r3,0x8(r31) #Check If Left Plat Already cmpwi r3,0x0 bne LedgetechSkipTimerStart lwz r3,0x10(r27) cmpwi r3,0xD beq LedgetechIncreaseRespawnPlatTime #Set Flag li r3,0x1 stb r3,0x8(r31) #Remove Invinc li r3,0x0 stw r3,0x198C(r27) stw r3,0x1990(r27) stw r3,0x1994(r27) mr r3,r28 branchl r12,GFX_RemoveAll #Set Timer li r3,180 stw r3,0x4(r31) b LedgetechSkipTimerStart LedgetechIncreaseRespawnPlatTime: li r3,0x2 stw r3,0x2340(r27) LedgetechSkipTimerStart: #Freeze Falco On Frame X lwz r3,0x10(r29) cmpwi r3,0x40 bne LedgetechSkipFalcoFreze li r3,0x6 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f1,f2 bne LedgetechSkipFalcoFreze li r3,0 bl IntToFloat mr r3,r30 branchl r12,FrameSpeedChange LedgetechSkipFalcoFreze: #If Player 1 Ledge Tech's, Set Timer to 2 Seconds #Check Gatekeeper Flag lbz r3,0xA(r31) cmpwi r3,0x1 beq Ledgetech_UpdateLedgetechFlags #Check For Tech lwz r3,0x10(r27) cmpwi r3,0xCA beq LedgetechWallTeched cmpwi r3,0xCB beq LedgetechWallTeched b Ledgetech_UpdateLedgetechFlags LedgetechWallTeched: #Extend Timer li r3,180 stw r3,0x4(r31) #Set Tech Bool li r3,1 stb r3,0x9(r31) #Set Gatekeeper Flag li r3,1 stb r3,0xA(r31) Ledgetech_UpdateLedgetechFlags: #Check If Still Ledgeteching lwz r3,0x10(r27) cmpwi r3,0xCA beq LedgetechUpdateScore cmpwi r3,0xCB beq LedgetechUpdateScore #Not Ledgeteching, Remove Gatekeeper Flag li r3,0 stb r3,0xA(r31) b LedgetechUpdateScoreHUD LedgetechUpdateScore: #Check To Increment Score #Check Ledgetech Bool lbz r3,0x9(r31) cmpwi r3,0x1 bne LedgetechUpdateScoreHUD #Reset LedgeTech Bool li r3,0 stb r3,0x9(r31) #Increment Score lhz r3,-0x4ea8(r13) addi r3,r3,0x1 sth r3,-0x4ea8(r13) #Check To Make New High Score lhz r3,-0x4ea8(r13) lhz r4,-0x4ea6(r13) cmpw r3,r4 ble LedgetechUpdateScoreHUD #Copy To High Score sth r3,-0x4ea6(r13) LedgetechUpdateScoreHUD: #Update HUD Score lhz r3,-0x4ea8(r13) branchl r12,HUD_KOCounter_UpdateKOs #Unfreeze Falco On Hit li r3,0x0 bl IntToFloat lfs f2,0x89C(r29) fcmpo cr0,f1,f2 bne LedgetechSkipFalcoUnfreeze lwz r3,0x988(r29) cmpwi r3,0x0 beq LedgetechSkipFalcoUnfreeze li r3,1 bl IntToFloat mr r3,r30 branchl r12,FrameSpeedChange LedgetechSkipFalcoUnfreeze: LedgetechCheckIfCrouching: #Only Attempt to DSmash in Squat and SquatWait lwz r3,0x10(r29) cmpwi r3,0x27 beq LedgetechCheckDistance cmpwi r3,0x28 beq LedgetechCheckDistance b LedgetechCheckToReset LedgetechCheckDistance: #Distance Formula (Get Distance in f1) addi r3,r29,0xB0 #P2 Positon addi r4,r27,0xB0 #P1 Position bl GetDistance lfs f2,0x0(r21) fcmpo cr0,f1,f2 bgt LedgetechCheckToReset #Enter DSmash li r3,-127 stb r3,0x1A8F(r29) #Initiate Reset Timer lwz r3,0x4(r31) #Get Timer cmpwi r3,0x0 #If Already Set, Skip bne LedgetechCheckToReset li r3,60 stw r3,0x4(r31) #Check To Reset LedgetechCheckToReset: lwz r3,0x4(r31) #get timer #Get Timer cmpwi r3,0x0 #Check if >0 ble LedgetechThinkExit #Dec Timer subi r3,r3,0x1 stw r3,0x4(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne LedgetechThinkExit #Exit If Not LedgetechRestoreState: #Restore State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Random Side of Stage li r3,2 branchl r12,HSD_Randi bl Ledgetech_InitializePositions #Enter SquatWait mr r3,P2GObj branchl r12,AS_SquatWait #Set Timer li r3,0 stw r3,0x4(r31) #Reset Rebirth Plat Fall Flag stb r3,0x8(r31) #Reset Tech and Gatekeeper Flag stb r3,0x9(r31) stb r3,0xA(r31) #Reset Score li r3,0 sth r3,-0x4ea8(r13) b LedgetechThinkExit LedgetechThinkExit: restore blr ################################# Ledgetech_Floats: blrl .float 35.0 #Distance to Initiate DSmash ################################# BlrFunctionPointer: blrl blr ################################# Ledgetech_InitializePositions: backup .set LedgeSide,20 #Backup Ledge Side mr LedgeSide,r3 #Change Facing Directions cmpwi LedgeSide,0x0 beq Ledgetech_InitializePositions_GetLeftLedgeID Ledgetech_InitializePositions_GetRightLedgeID: #Change Facing Direction li r3,-1 bl IntToFloat stfs f1,0x2C(P1Data) li r3,1 bl IntToFloat stfs f1,0x2C(P2Data) b Ledgetech_InitializePositions_DirectionChangeEnd Ledgetech_InitializePositions_GetLeftLedgeID: #Change Facing Direction li r3,1 bl IntToFloat stfs f1,0x2C(P1Data) li r3,-1 bl IntToFloat stfs f1,0x2C(P2Data) Ledgetech_InitializePositions_DirectionChangeEnd: #Get Ledge Coordinates mr r3,LedgeSide addi r4,sp,0x80 bl GetLedgeCoordinates Ledgetech_InitializePositions_StorePosition: #Place P2 a few Mm behind it li r3,10 bl IntToFloat lfs f2,0x2C(P2Data) fmuls f1,f1,f2 lfs f2,0x80(sp) fsubs f1,f2,f1 stfs f1,0xB0(P2Data) lfs f1,0x84(sp) stfs f1,0xB4(P2Data) #Find Ground Below Player mr r3,P2GObj bl FindGroundNearPlayer cmpwi r3,0 #Check if ground was found beq Ledgetech_InitializePositions_SkipGroundCorrection stfs f1,0xB0(P2Data) stfs f2,0xB4(P2Data) stw r4,0x83C(P2Data) Ledgetech_InitializePositions_SkipGroundCorrection: #Enter into Wait mr r3,P2GObj branchl r12,AS_Wait #Update Position mr r3,P2GObj bl UpdatePosition #Update ECB Values for the ground ID mr r3,P2GObj branchl r12,EnvironmentCollision_WaitLanding #Set Grounded mr r3,P2Data branchl r12,Air_SetAsGrounded #Update Camera mr r3,P2GObj bl UpdateCameraBox #Enter Rebirth lwz r26,0x2C(P1Data) mr r3,P1GObj branchl r12,AS_Rebirth stw r26,0x2C(P1Data) #Place P1 a few Mm in front of it li r3,60 bl IntToFloat lfs f2,0x2C(P1Data) fmuls f1,f1,f2 lfs f2,0x80(sp) fsubs f1,f2,f1 stfs f1,0xB0(P1Data) lfs f1,0x84(sp) stfs f1,0xB4(P1Data) #Enter RebirthWait mr r3,P1GObj branchl r12,AS_RebirthWait #Update Position mr r3,P1GObj bl UpdatePosition #Store Blr as Physics bl BlrFunctionPointer mflr r3 stw r3,0x21A4(P1Data) #Store Custom RebirthWait Interrupt bl Custom_InterruptRebirthWait mflr r3 stw r3,0x219C(P1Data) #Update RebirthPlat Position mr r3,P1GObj branchl r12,RebirthPlatform_UpdatePosition #Update Camera mr r3,P1GObj bl UpdateCameraBox restore blr ################################# LedgetechLoadExit: restore blr ################################################### #endregion #region Amsah Tech ######################### ## Amsah Tech HIJACK INFO ## ######################### AmsahTech: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,9 #Use chosen CPU li r6,-1 #Use chosen Stage load r7,EventOSD_AmsahTech li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION bl AmsahTechLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Amsah Tech LOAD FUNCT ## ######################## AmsahTechLoad: blrl backup #Schedule Think bl AmsahTechThink mflr r3 li r4,3 #Priority (After Interrupt) li r5,0 #No Option Menu bl CreateEventThinkFunction b AmsahTechLoadExit ######################### ## Amsah Tech THINK FUNCT ## ######################### .set EventData,31 .set P1Gobj,28 .set P1Data,27 .set P2GObj,30 .set P2Data,29 #Offsets .set Timer,0x8 AmsahTechThink: blrl backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq AmsahTechThinkMain #Move Players bl PlacePlayersCenterStage #P1 Has 120% li r3,120 load r4,0x80453080 #P1 Static Block sth r3,0x60(r4) #Store Percent Int To Display Value bl IntToFloat stfs f1,0x1830(P1Data) #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save AmsahTechThinkMain: #Make P2 A Follower (No Nudge) #li r3,0x8 #stb r3,0x221F(r29) li r3,0x1 lbz r0, 0x221D (r29) rlwimi r0,r3,2,29,29 stb r0, 0x221D (r29) #Give Invincibility To P2 mr r3,r30 li r4,0x2 bl GiveInvincibility #Update GFX mr r3,r30 bl UpdateAllGFX #Reset If Anyone Dies bl IsAnyoneDead cmpwi r3,0x0 bne AmsahTechRestoreState AmsahTechThinkSequence: #Get Floats bl AmsahTech_Floats mflr r21 #Check If Timer Started Already lwz r3,0x4(r31) cmpwi r3,0x0 bne AmsahTechCheckUpBTimer #Check For P1 Taunt lwz r3,0x10(r27) cmpwi r3,0x108 beq AmsahTechIsTaunting cmpwi r3,0x109 beq AmsahTechIsTaunting #Check For Doc Taunt lwz r3,0x4(r27) cmpwi r3,0x15 bne AmsahTechCheckYLink #Check For AS 155 lwz r3,0x10(r27) cmpwi r3,0x155 beq AmsahTechIsTaunting #Check For YLink Taunt AmsahTechCheckYLink: lwz r3,0x4(r27) cmpwi r3,0x14 bne AmsahTechCheckUpBTimer #Check For AS 156 lwz r3,0x10(r27) cmpwi r3,0x156 beq AmsahTechIsTaunting b AmsahTechCheckUpBTimer AmsahTechIsTaunting: #Check for Frame 1 of Taunt lhz r3,0x23EC(P1Data) cmpwi r3,0x1 bne AmsahTechCheckUpBTimer #Check If UpB Timer is Set lwz r3,0x8(r31) cmpwi r3,0x0 #Timer Already Set bne AmsahTechCheckUpBTimer #Check If Marth is In Wait lwz r3,0x10(r29) cmpwi r3,0xE bne AmsahTechCheckUpBTimer #Move Marth X Mm in front of P1, facing him #Get Position li r3,10 bl IntToFloat #Offset from P1 lfs f3,0xB0(P1Data) #P1 X lfs f2,0xB4(P1Data) #P1 Y lfs f4,0x2C(P1Data) #Facing Direction fmuls f1,f1,f4 fadds f1,f1,f3 #Check If P2 Will Be Grounded li r3,0 bl FindGroundNearPlayer cmpwi r3,0 #Check if ground was found beq AmsahTech_NoGroundFound stfs f1,0xB0(P2Data) stfs f2,0xB4(P2Data) stw r4,0x83C(P2Data) lfs f1,0x2C(P1Data) fneg f1,f1 stfs f1,0x2C(P2Data) #Enter Wait mr r3,P2GObj branchl r12,AS_Wait #Update Position mr r3,P2GObj bl UpdatePosition #Update ECB Values for the ground ID mr r3,P2GObj branchl r12,EnvironmentCollision_WaitLanding #Set Grounded mr r3,P2Data branchl r12,Air_SetAsGrounded #Set UpB Timer li r3,30 stw r3,Timer(EventData) #Store To Backups as Well lwz r3,0x18(EventData) #P2 Backup lfs f1,0xB0(P2Data) #Get P2 X stfs f1,0xB0(r3) #Store to P2 Backup lfs f1,0xB4(P2Data) #Get P2 Y stfs f1,0xB4(r3) #Store to P2 Backup lfs f1,0x2C(P2Data) #Get P2 Facing stfs f1,0x2C(r3) #Store to P2 Backup lwz r4,0x83C(P2Data) #Get P2 Ground ID stw r4,0x83C(r3) #Store to P2 Backup lwz r3,0x10(EventData) #P1 Backup lfs f1,0xB0(P1Data) #Get P1 X stfs f1,0xB0(r3) #Store to P1 Backup lfs f1,0xB4(P1Data) #Get P1 X stfs f1,0xB4(r3) #Store to P1 Backup lfs f1,0x2C(P1Data) #Get P1 Facing stfs f1,0x2C(r3) #Store to P1 Backup lwz r4,0x83C(P1Data) #Get P1 Ground ID stw r4,0x83C(r3) #Store to P1 Backup mr r3,P1GObj bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq AmsahTechNoSubchar lwz r3,0x14(EventData) #P1 Subchar Backup lfs f1,0xB0(r4) #Get P1 Subchar X stfs f1,0xB0(r3) #Store to P1 Subchar Backup lfs f1,0x2C(r4) #Get P1 Subchar Facing stfs f1,0x2C(r3) #Store to P1 Subchar Backup AmsahTechNoSubchar: b AmsahTechCheckToReset AmsahTech_NoGroundFound: #Play Error SFX li r3,0xAF bl PlaySFX b AmsahTechCheckToReset AmsahTechCheckUpBTimer: #Check For UpBTimer lwz r3,0x8(r31) cmpwi r3,0x0 #No UpB Timer Set Yet ble AmsahTechCheckToReset #Dec Timer subi r3,r3,0x1 stw r3,0x8(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne AmsahTechCheckToReset #Exit If Not #Move Marth in Front of P1 Again (Fox's lfs f1,0xB0(r27) #Get P1 X lfs f2,0x2C(r27) #Get P1 Facing lfs f3,0x10(r21) #Get Marth Distance fmuls f2,f2,f3 #Distance * Facing Direction fadds f1,f1,f2 #P1.X + (Distance * Facing Direction) stfs f1,0xB0(r29) #Store Position to P2 #Enter UpB li r3,0x200 stw r3,0x1A88(r29) li r3,127 stb r3,0x1A8D(r29) #Initiate Reset Timer li r3,120 stw r3,0x4(r31) #Check To Reset AmsahTechCheckToReset: lwz r3,0x4(r31) #get timer #Get Timer cmpwi r3,0x0 #No Reset Timer Set Yet ble AmsahTechThinkExit #Dec Timer subi r3,r3,0x1 stw r3,0x4(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne AmsahTechThinkExit #Exit If Not AmsahTechRestoreState: #Restore State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Restore Timers Just In Case li r3,0x0 stw r3,0x4(r31) stw r3,0x8(r31) AmsahTechThinkExit: restore blr ################################# AmsahTech_Floats: blrl .long 0x4308ca0c #P1 X Position .long 0x42942371 #P2 X Position .long 0x00000000 #P1 Y Position .long 0x38d1b717 #FD Floor Y Coord .long 0x41800000 #Distance to place Marth from P1 .long 0x428C0000 #FD Stage Boundary X ################################# AmsahTechLoadExit: restore blr ########################################### #endregion #region Combo Training ################################ ## Combo Training HIJACK INFO ## ################################ ComboTraining: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,-1 #Use chosen Stage load r7,EventOSD_ComboTraining li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION bl ComboTrainingLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Combo Training LOAD FUNCT ## ######################## ComboTrainingLoad: blrl backup #Schedule Think bl ComboTrainingThink mflr r3 li r4,3 #Priority (After Interrupt) bl ComboTrainingWindowInfo #r4 = pointer to option info mflr r5 bl ComboTrainingWindowText #r5 = pointer to ASCII struct mflr r6 bl CreateEventThinkFunction bl InitializeHighScore b ComboTrainingLoadExit ######################### ## Combo Training THINK FUNCT ## ######################### #Registers .set MenuData,26 .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 #Offsets .set EventState,0x8 .set DIBehavior,(MenuData_OptionMenuMemory+0x2)+0x0 .set SDIBehavior,(MenuData_OptionMenuMemory+0x2)+0x1 .set TechOption,(MenuData_OptionMenuMemory+0x2)+0x2 .set PostHitstunAction,(MenuData_OptionMenuMemory+0x2)+0x3 .set GrabMashout,(MenuData_OptionMenuMemory+0x2)+0x4 .set DIBehaviorToggled,(MenuData_OptionMenuToggled)+0x0 .set SDIBehaviorToggled,(MenuData_OptionMenuToggled)+0x1 .set TechOptionToggled,(MenuData_OptionMenuToggled)+0x2 .set PostHitstunActionToggled,(MenuData_OptionMenuToggled)+0x3 .set GrabMashoutToggled,(MenuData_OptionMenuToggled)+0x4 #Definitions #DIBehavior .set DI_Random,0x0 .set DI_Survival,0x1 .set DI_ComboDI,0x2 .set DI_SlightDIRandom,0x3 .set DI_SlightDIInwards,0x4 .set DI_DownAndAway,0x5 .set DI_None,0x6 #SDIBehavior .set SDI_33Percent,0x0 .set SDI_66Percent,0x1 .set SDI_Always,0x2 .set SDI_None,0x3 ComboTrainingThink: blrl backup #INIT FUNCTION VARIABLES lwz r31,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 lwz MenuData,EventData_MenuDataPointer(EventData) bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq ComboTrainingThinkMain bl PlacePlayersCenterStage #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Init Score Count lhz r3,-0x4ea8(r13) branchl r12,HUD_KOCounter_UpdateKOs ComboTrainingThinkMain: #Set Combo As Score li r3,0x0 branchl r12,0x8004134c sth r3,-0x4ea8(r13) #Check To Make New High Score lhz r3,-0x4ea8(r13) lhz r4,-0x4ea6(r13) cmpw r3,r4 ble ComboTraining_SkipNewHighscore #Copy To High Score sth r3,-0x4ea6(r13) ComboTraining_SkipNewHighscore: #Update HUD Score lhz r3,-0x4ea8(r13) cmpwi r3,0x1 blt ComboTraining_SkipHUDUpdate branchl r12,HUD_KOCounter_UpdateKOs ComboTraining_SkipHUDUpdate: #DPad Right Makes New Savestate #Check If Trying to SaveState lwz r3,0x668(r27) rlwinm. r0,r3,0,30,30 beq ComboTraining_CheckForSaveAndLoad #Only Allow a Save If Event State is 0 lbz r3,EventState(r31) cmpwi r3,0x0 bne ComboTraining_SkipCheckForSaveAndLoad #Only Allow a Save If P2 is in Wait lwz r3,0x10(r29) cmpwi r3,0xE bne ComboTraining_SkipCheckForSaveAndLoad ComboTraining_CheckForSaveAndLoad: addi r3,EventData,0x10 bl CheckForSaveAndLoad #Check If Loaded Successfully cmpwi r3,0x1 bne ComboTraining_SkipCheckForSaveAndLoad #Restore Event State And Timer li r3,0x0 stb r3,EventState(r31) stw r3,0x4(r31) ComboTraining_SkipCheckForSaveAndLoad: #DPad Down Moves CPU In Front #Only If Event State = 0 lbz r3,EventState(r31) cmpwi r3,0x0 bne ComboTrainingSkipMoveCPU mr r3,P1GObj mr r4,P2GObj addi r5,EventData,0x10 bl MoveCPU ComboTrainingSkipMoveCPU: #L+DPad Controls CPU Percent addi r3,EventData,EventData_SaveStateStruct+(1*0x8) bl DPadCPUPercent bl GiveFullShields #Reset If Anyone Dies bl IsAnyoneDead cmpwi r3,0x0 bne ComboTrainingRestoreState ############################ ## Check If Was Hit Again ## ############################ #Don't Run If Over 6 Frames in Escape Air lwz r3,0x10(r29) cmpwi r3,0xEC bne ComboTrainingCheckIfP2isGrabbed li r3,6 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f1,f2 bge ComboTrainingCheckState #Check If P2 is Grabbed (Any Grab State) ComboTrainingCheckIfP2isGrabbed: lwz r3,0x10(r29) cmpwi r3,0xDF blt ComboTrainingStartCheckIfHit cmpwi r3,0xE8 bgt ComboTrainingStartCheckIfHit b ComboTrainingChangeToRandomDIandTech #Check If P2 is Hit ComboTrainingStartCheckIfHit: lbz r3,0x221A(r29) #Check If in Hitlag rlwinm. r3,r3,0,26,26 bne ComboTrainingCheckIfBeingHit b ComboTrainingCheckState ComboTrainingCheckIfBeingHit: lwz r3,0x10(r29) cmpwi r3,ASID_DamageHi1 blt ComboTrainingCheckState cmpwi r3,ASID_DamageFlyRoll bgt ComboTrainingCheckState ComboTrainingChangeToRandomDIandTech: #Change To DI and Tech li r3,0x1 stb r3,EventState(r31) b ComboTrainingInputDIAndTech #Get Which State ComboTrainingCheckState: lbz r3,EventState(r31) cmpwi r3,0x0 beq ComboTrainingStart cmpwi r3,0x1 beq ComboTrainingInputDIAndTech cmpwi r3,0x2 beq ComboTrainingPostHitstun ComboTrainingStart: b ComboTrainingCheckToReset ComboTrainingInputDIAndTech: bl ComboTrainingCheckExitStates cmpwi r3,0x0 beq ComboTrainingInputDIAndTechNoJiggs b ComboTrainingChangeStateToPostHitstun ComboTrainingInputDIAndTechNoJiggs: lwz r3,0x10(r29) cmpwi r3,0xB8 #Missed Tech, Needs to Input a Roll or Attack beq ComboTrainingMissedTechThink cmpwi r3,0xC0 #Missed Tech, Needs to Input a Roll or Attack beq ComboTrainingMissedTechThink #Check If Still Grabbed cmpwi r3,ASID_ShoulderedWait blt ComboTraining_GrabCheckSkipShoulder cmpwi r3,ASID_ShoulderedTurn ble ComboTrainingMashOutOfGrab ComboTraining_GrabCheckSkipShoulder: cmpwi r3,ASID_CaptureKoopa blt ComboTraining_GrabCheckSkipKoopaLw cmpwi r3,ASID_CaptureWaitKoopa ble ComboTrainingMashOutOfGrab ComboTraining_GrabCheckSkipKoopaLw: cmpwi r3,ASID_CaptureKoopaAir blt ComboTraining_GrabCheckSkipKoopaAir cmpwi r3,ASID_CaptureWaitKoopaAir ble ComboTrainingMashOutOfGrab ComboTraining_GrabCheckSkipKoopaAir: cmpwi r3,ASID_CapturePulledHi #CapturePulledLow blt ComboTraining_GrabCheckSkipGrabbed cmpwi r3,ASID_CaptureFoot #CapturePulledHi ble ComboTrainingMashOutOfGrab ComboTraining_GrabCheckSkipGrabbed: b ComboTrainingDecideInputs #When Grabbed #Check Mash Out Behavior ComboTrainingMashOutOfGrab: lbz r3,GrabMashout(MenuData) cmpwi r3,0x0 beq ComboTrainingInputDIAndTech_RandomMash cmpwi r3,0x1 beq ComboTrainingInputDIAndTech_RandomMash_AnalogInput cmpwi r3,0x2 #No Mash beq ComboTrainingCheckToReset #Random Mash Out ComboTrainingInputDIAndTech_RandomMash: #Only start randomly mashing after a few frames (to simulate human reaction) lwz r3,0x10(r29) cmpwi r3,ASID_CapturePulledHi #CapturePulledLow blt ComboTrainingInputDIAndTech_RandomMashStart cmpwi r3,ASID_CaptureFoot #CapturePulledHi bgt ComboTrainingInputDIAndTech_RandomMashStart #In a normal grab state, should wait a few frames before starting to mash ComboTrainingInputDIAndTech_RandomMashStart: li r3,10 #1- Numbers branchl r12,HSD_Randi cmpwi r3,7 #7 and below are no input ble ComboTrainingCheckToReset cmpwi r3,8 #8 = Button Only, 9 = Both Analog and Button beq ComboTrainingInputDIAndTech_RandomMash_ButtonPress ComboTrainingInputDIAndTech_RandomMash_AnalogInput: li r3,127 stb r3,0x1A8C(r29) #Push Analog Stick Forward li r3,-1 stb r3,0x1A50(r29) #Spoof Analog Stick as First Frame Pushed ComboTrainingInputDIAndTech_RandomMash_ButtonPress: #Input Button Press li r3,0x100 stw r3,0x1A88(r29) #Press A li r3,0 stw r3,0x65C(r29) #Spoof Prev Frame Buttons as Nothing Pushed b ComboTrainingCheckToReset ComboTrainingChangeStateToPostHitstun: #Change State li r3,0x2 stb r3,EventState(r31) b ComboTrainingPostHitstun ComboTrainingDecideInputs: #CHECK TO DI ATTACK ComboTrainingDIThrowsAndHits: #Check If in Hitlag lbz r3,0x221A(r29) rlwinm. r3,r3,0,26,26 beq ComboTrainingCheckIfBeingThrown #Check If In Last Frame of Hitlag lfs f1,-0x7418(rtoc) #1fp lfs f2,0x195C(r29) #hitlag frames left fcmpo cr0,f1,f2 bne ComboTrainingCheckToReset #Check If Attack Was Strong #DI Attack lbz r3,DIBehavior(MenuData) #Get DI Behavior cmpwi r3,DI_SlightDIInwards #Check If Slight In bne 0x8 li r3,0x0 #Override To Never Slight DI In Attacks b 0x8 li r3,0x2 bl ComboTrainingDecideStickAngle #SDI Attack lbz r3,SDIBehavior(MenuData) #Get SDI Behavior cmpwi r3,SDI_None #No SDI beq ComboTrainingNoSDI cmpwi r3,SDI_Always #Always SDI beq ComboTrainingCheckToReset li r3,0x3 branchl r12,HSD_Randi lbz r4,SDIBehavior(MenuData) #Get SDI Behavior cmpwi r4,SDI_33Percent beq ComboTraining33PercentSDI cmpwi r4,SDI_66Percent beq ComboTraining66PercentSDI ComboTraining33PercentSDI: li r4,0 b ComboTrainingCompareSDIChance ComboTraining66PercentSDI: li r4,1 b ComboTrainingCompareSDIChance ComboTrainingCompareSDIChance: cmpw r3,r4 ble ComboTrainingGetChanceToTech #Don't SDI ComboTrainingNoSDI: mr r3,r29 branchl r12,CPU_JoystickXAxis_Convert stfs f1,0x620(r29) mr r3,r29 branchl r12,CPU_JoystickYAxis_Convert stfs f1,0x624(r29) b ComboTrainingGetChanceToTech #CHECK TO DI A THROW ComboTrainingCheckIfBeingThrown: #Check If Being Thrown lwz r3,0x10(r29) cmpwi r3,0xEF blt ComboTrainingCheckToJumpOutOfHitstun cmpwi r3,0xF3 bgt ComboTrainingCheckToJumpOutOfHitstun ComboTrainingInputDI: lbz r3,DIBehavior(MenuData) bl ComboTrainingDecideStickAngle b ComboTrainingCheckToReset #NOT BEING THROWN OR LAST FRAME OF HITLAG #CHECK TO JUMP OUT OF HITSTUN AND BECOME INVINCIBLE ComboTrainingCheckToJumpOutOfHitstun: #Check If in Damage State lwz r3,0x10(r29) cmpwi r3,0x26 #Tumble beq ComboTrainingCheckIfInAir cmpwi r3,0x4B blt ComboTrainingCheckToReset cmpwi r3,0x5B bgt ComboTrainingCheckToReset #IN A DAMAGE STATE #Check If In Air ComboTrainingCheckIfInAir: lwz r3,0xE0(r29) cmpwi r3,0x0 beq ComboTrainingDamageGrounded #IN THE AIR #Check If Still in Hitstun lbz r3,0x221C(r29) rlwinm. r3,r3,0,30,30 bne ComboTrainingGetChanceToTech #NOT IN HITSTUN #Check Post Hitstun Behavior lbz r3,PostHitstunAction(MenuData) cmpwi r3,0x0 beq ComboTrainingAirdodge cmpwi r3,0x1 beq ComboTrainingJumpAndInvincible cmpwi r3,0x2 beq ComboTrainingAerialAttack ComboTrainingJumpAndInvincible: #Always Jump #li r3,0 #stw r3,0x1A8C(r29) #Nuetralize Stick Inputs #i r3,0x400 #stw r3,0x1A88(r29) #X Button b ComboTrainingChangeStateToPostHitstun ComboTrainingAirdodge: #Wiggle Out of Hitstun li r3,127 stb r3,0x1A8C(r29) #Last Frame's Stick Was Centered li r3,0x0 stw r3,0x628(r29) stw r3,0x62C(r29) #Stick Frame Timer Reset li r3,255 stb r3,0x670(r29) #Change State li r3,0x2 stb r3,0x8(r31) b ComboTrainingPostHitstun ComboTrainingAerialAttack: #li r3,0x100 #stw r3,0x1A88(r29) #Nair #Change State li r3,0x2 stb r3,EventState(r31) b ComboTrainingPostHitstun #CHECK TO BECOME INVINCIBLE OUT OF GROUNDED LIGHT DAMAGE STATES ComboTrainingDamageGrounded: #Check For Hitstun (Can Act Out of Certain Light Damage States) lbz r3,0x221C(r29) rlwinm. r3,r3,0,30,30 bne ComboTrainingCheckToReset #Grounded, No Hitstun Left, Become Invincible and Spotdodge #Check Post Hitstun Behavior lbz r3,PostHitstunAction(MenuData) cmpwi r3,0x0 beq ComboTrainingGroundedSpotdodge cmpwi r3,0x1 beq ComboTrainingGroundedInvincibility cmpwi r3,0x2 beq ComboTrainingGroundedAttack ComboTrainingGroundedInvincibility: b ComboTrainingChangeStateToPostHitstun ComboTrainingGroundedSpotdodge: li r3,0xC0 #Hit L stw r3,0x1A88(r29) #Held Buttons li r3,-127 #Hold Down stb r3,0x1A8D(r29) #Stick Y b ComboTrainingChangeStateToPostHitstun ComboTrainingGroundedAttack: #li r3,0x100 #Hit A #stw r3,0x1A88(r29) #Held Buttons b ComboTrainingChangeStateToPostHitstun ComboTrainingGetChanceToTech: #INPUT A TECH WHEN IN AERIAL HITSTUN lbz r3,TechOption(MenuData) #Get Tech Behavior cmpwi r3,0x0 #Random Tech (Original Behavior) beq ComboTrainingRandomTech cmpwi r3,0x1 #Miss Tech beq ComboTrainingMissTech cmpwi r3,0x2 beq ComboTrainingTechInPlace cmpwi r3,0x3 beq ComboTrainingTechTowards cmpwi r3,0x4 beq ComboTrainingTechAway ComboTrainingRandomTech: #Reset Tech Cooldown Window Constantly li r3,0x1 stb r3,0x680(r29) #Frames Since Pressed L/R li r3,0xFF stb r3,0x684(r29) #L/R Lockout Window #Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise) lbz r3,0x221A(r29) rlwinm. r3,r3,0,26,26 bne ComboTrainingCheckToReset #Tech Random Side ComboTrainingRandomTech_GetStickAngle: li r3,4 #Decide between left right and center and none branchl r12,HSD_Randi cmpwi r3,0x0 beq ComboTrainingRandomTech_TechInPlace cmpwi r3,0x1 beq ComboTrainingRandomTech_TechLeft cmpwi r3,0x2 beq ComboTrainingRandomTech_TechRight cmpwi r3,0x3 beq ComboTrainingMissTech ComboTrainingRandomTech_TechInPlace: li r3,0 stb r3,0x1A8C(r29) stb r3,0x1A8D(r29) b ComboTrainingCheckToReset ComboTrainingRandomTech_TechLeft: li r3,-127 stb r3,0x1A8C(r29) b ComboTrainingCheckToReset ComboTrainingRandomTech_TechRight: li r3,127 stb r3,0x1A8C(r29) b ComboTrainingCheckToReset ComboTrainingMissTech: li r3,0x0 stw r3,0x1A88(r29) #Fail Tech Cooldown li r3,0xFF stb r3,0x680(r29) li r3,0x00 stb r3,0x684(r29) b ComboTrainingCheckToReset ComboTrainingTechInPlace: #Hold L li r3,0xC0 stw r3,0x1A88(r29) #Reset Tech Cooldown Window Constantly li r3,0x0 stb r3,0x680(r29) li r3,0xFF stb r3,0x684(r29) #Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise) lbz r3,0x221A(r29) rlwinm. r3,r3,0,26,26 bne ComboTrainingCheckToReset li r3,0x0 stb r3,0x1A8C(r29) b ComboTrainingCheckToReset ComboTrainingTechTowards: #Hold L li r3,0xC0 stw r3,0x1A88(r29) #Reset Tech Cooldown Window Constantly li r3,0x0 stb r3,0x680(r29) li r3,0xFF stb r3,0x684(r29) #Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise) lbz r3,0x221A(r29) rlwinm. r3,r3,0,26,26 bne ComboTrainingCheckToReset #Push Towards Opponent's Direction bl GetDirectionInRelationToP1 mulli r3,r3,-1 #Negate This li r4,127 mullw r3,r3,r4 stb r3,0x1A8C(r29) b ComboTrainingCheckToReset ComboTrainingTechAway: #Hold L li r3,0xC0 stw r3,0x1A88(r29) #Reset Tech Cooldown Window Constantly li r3,0x0 stb r3,0x680(r29) li r3,0xFF stb r3,0x684(r29) #Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise) lbz r3,0x221A(r29) rlwinm. r3,r3,0,26,26 bne ComboTrainingCheckToReset bl GetDirectionInRelationToP1 li r4,127 mullw r3,r3,r4 stb r3,0x1A8C(r29) b ComboTrainingCheckToReset #INPUT AN ATTACK OR DIRECTION WHEN MISSED A TECH ComboTrainingMissedTechThink: li r3,4 #1/4 chance to getup attack branchl r12,HSD_Randi cmpwi r3,0x0 beq ComboTrainingMissedTech_GetupAttack #No Getup Attack, Input Random Direction li r3,0 bl ComboTrainingDecideStickAngle b ComboTrainingCheckToReset #Input Getup Attack ComboTrainingMissedTech_GetupAttack: li r3,0x100 #Press A To Getup Attack stw r3,0x1A88(r29) b ComboTrainingCheckToReset ######################## ## Post Hitstun Think ## ######################## ComboTrainingPostHitstun: #Check Post Hitstun Behavior lbz r3,PostHitstunAction(MenuData) cmpwi r3,0x0 beq ComboTrainingPostHitstun_AirdodgeSpotdodge cmpwi r3,0x1 beq ComboTrainingPostHitstun_GiveInvinc cmpwi r3,0x2 beq ComboTrainingPostHitstun_Attack ComboTrainingPostHitstun_GiveInvinc: #Constantly Press Jump If In The Air lwz r3,0xE0(r29) cmpwi r3,0x0 beq ComboTrainingPostHitstun_GiveInvinc_ApplyInvinc li r3,0x800 stw r3,0x1A88(r29) #Clear Prev Frame Jump Input li r3,0x0 stw r3,0x668(r29) #Apply Invinc ComboTrainingPostHitstun_GiveInvinc_ApplyInvinc: mr r3,r30 li r4,30 branchl r12,ApplyIntangibility #UpdateGFX mr r3,r30 branchl r12,GFX_UpdatePlayerGFX #Set Timer if Not Set lwz r3,0x4(r31) cmpwi r3,0x0 bgt ComboTrainingCheckToReset #Set Timer li r3,30 stw r3,0x4(r31) b ComboTrainingCheckToReset #****************************************************************# ComboTrainingPostHitstun_AirdodgeSpotdodge: #Check If In Airdodge #Check If In Gained Invuln From Air/Spotdodge lwz r3,0x1988(r29) cmpwi r3,0x0 beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge b ComboTrainingPostHitstun_EnteredAirdodgeSpotdodge ComboTrainingPostHitstun_EnteredAirdodgeSpotdodge: #Set Timer if Not Set lwz r3,0x4(r31) cmpwi r3,0x0 bgt ComboTrainingCheckToReset #Set Timer li r3,30 stw r3,0x4(r31) #Give Invince and Exit b ComboTrainingCheckToReset #****************************************************************# ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge: #If in An Exit State, Reset State bl ComboTrainingCheckExitStates cmpwi r3,0x0 beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState #Except Fall lwz r3,0x10(r29) cmpwi r3,0x1D beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState #Except Landing cmpwi r3,0x2A beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState #Except Wait cmpwi r3,0xE beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState #Set Timer if Not Set lwz r3,0x4(r31) cmpwi r3,0x0 bgt ComboTrainingCheckToReset #Set Timer li r3,30 stw r3,0x4(r31) ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState: #Check If in Air lwz r3,0xE0(r29) cmpwi r3,0x0 beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_CheckToSpotdodge #Check If In DamageLightHit With No Hitstun Left (Same interrupts as Fall) lwz r3,0x10(r29) cmpwi r3,0x56 beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_InputAirdodge ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckToWiggleOut: #Check If In Damage States lwz r3,0x10(r29) cmpwi r3,0x4B blt ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckForFall cmpwi r3,0x5B bgt ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckForFall #Wiggle Out to Enter Fall li r3,127 stb r3,0x1A8C(r29) b ComboTrainingCheckToReset #Check If In Fall ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckForFall: lwz r3,0x10(r29) cmpwi r3,0x1D bne ComboTrainingCheckToReset ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_InputAirdodge: #Airdodge li r3,0 stb r3,0x1A8C(r29) li r3,0xC0 stw r3,0x1A88(r29) #Clear Buttons From Last Frame li r3,0x0 stw r3,0x65C(r29) b ComboTrainingCheckToReset ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_CheckToSpotdodge: #Check If Grounded and Actionable lwz r3,0x10(r29) cmpwi r3,0xE #Wait beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_Spotdodge cmpwi r3,0xB6 #Shielding beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_Spotdodge cmpwi r3,0x2A #Land bne ComboTrainingCheckToReset #Check If Can Interrupt Land lfs f1,0x894(r29) lfs f2,0x1F4(r29) fcmpo cr0,f1,f2 blt ComboTrainingCheckToReset ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_Spotdodge: #Clear Buttons From Last Frame li r3,0x0 stw r3,0x65C(r29) #Input Spotdodge li r3,0xC0 stw r3,0x1A88(r29) li r3,-127 stb r3,0x1A8D(r29) b ComboTrainingCheckToReset #****************************************************************# ComboTrainingPostHitstun_Attack: #Clear Buttons From Last Frame li r3,0x0 stw r3,0x65C(r29) #Get Air or Ground lwz r3,0xE0(r29) cmpwi r3,0x0 beq ComboTrainingPostHitstun_AttackGround ComboTrainingPostHitstun_AttackAir: bl ComboTrainingAttackList mflr r5 lwz r4,0x4(r29) lbzx r3,r4,r5 rlwinm r3,r3,0,28,31 #Get Right Bits b ComboTrainingPostHitstun_Attack_BranchToAttack ComboTrainingPostHitstun_AttackGround: bl ComboTrainingAttackList mflr r5 lwz r4,0x4(r29) lbzx r3,r4,r5 rlwinm r3,r3,28,28,31 #Get Left Bits b ComboTrainingPostHitstun_Attack_BranchToAttack ComboTrainingPostHitstun_Attack_BranchToAttack: cmpwi r3,0x0 beq ComboTrainingPostHitstun_Attack_A cmpwi r3,0x1 beq ComboTrainingPostHitstun_Attack_ForwardA cmpwi r3,0x2 beq ComboTrainingPostHitstun_Attack_BackA cmpwi r3,0x3 beq ComboTrainingPostHitstun_Attack_DownA cmpwi r3,0x4 beq ComboTrainingPostHitstun_Attack_UpA cmpwi r3,0x5 beq ComboTrainingPostHitstun_Attack_DownSmash cmpwi r3,0x6 beq ComboTrainingPostHitstun_Attack_UpB cmpwi r3,0x7 beq ComboTrainingPostHitstun_Attack_DownB ComboTrainingPostHitstun_Attack_A: li r3,0x100 #Hit A stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_ForwardA: #Push Towards Opponent's Direction bl GetDirectionInRelationToP1 mulli r3,r3,-1 #Negate This li r4,60 mullw r3,r3,r4 stb r3,0x1A8C(r29) li r3,0x100 #Hit A stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_BackA: #Push Away Opponent's Direction bl GetDirectionInRelationToP1 li r4,60 mullw r3,r3,r4 stb r3,0x1A8C(r29) li r3,0x100 #Hit A stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_DownA: li r3,60 stb r3,0x1A8D(r29) li r3,0x100 #Hit A stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_UpA: li r3,60 stb r3,0x1A8D(r29) li r3,0x100 #Hit A stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_DownSmash: li r3,-127 stb r3,0x1A8F(r29) b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_UpB: li r3,127 stb r3,0x1A8D(r29) li r3,0x200 #Hit B stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_DownB: li r3,-127 stb r3,0x1A8D(r29) li r3,0x200 #Hit B stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox #Search For Active Hitbox ComboTrainingPostHitstun_Attack_CheckForHitbox: mr r3,r30 bl CheckForActiveHitboxes cmpwi r3,0x0 bne ComboTrainingPostHitstun_GiveInvinc_ApplyInvinc #Harcoded Fox Grounded Shine Check =( lwz r3,0x4(r29) cmpwi r3,0x1 beq ComboTrainingPostHitstun_Attack_CheckForGroundShine cmpwi r3,0x16 beq ComboTrainingPostHitstun_Attack_CheckForGroundShine #Hardcoded Puff Rest Check =( cmpwi r3,0xF beq ComboTrainingPostHitstun_Attack_CheckForRest b ComboTrainingCheckToReset ComboTrainingPostHitstun_Attack_CheckForGroundShine: lwz r3,0x10(r29) cmpwi r3,0x168 beq ComboTrainingPostHitstun_GiveInvinc_ApplyInvinc b ComboTrainingCheckToReset ComboTrainingPostHitstun_Attack_CheckForRest: lwz r3,0x10(r29) cmpwi r3,0x171 beq ComboTrainingPostHitstun_GiveInvinc_ApplyInvinc b ComboTrainingCheckToReset #****************************************************************# #Check To Reset ComboTrainingCheckToReset: lwz r3,0x4(r31) #get timer cmpwi r3,0x0 #No Reset Timer Set Yet ble ComboTrainingThinkExit #Dec Timer subi r3,r3,0x1 stw r3,0x4(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne ComboTrainingThinkExit #Exit If Not ComboTrainingRestoreState: #Restore State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Reset State ID li r3,0x0 stb r3,EventState(r31) ComboTrainingThinkExit: mr r3,MenuData bl ClearToggledOptions bl UpdateAllGFX restore blr ################################# ComboTraining_StartingGroundIDs: blrl #Ground IDs to start on .long 0xFFFFFFFF #Dummy, TEST .long 0x00050022 #FoD, Pokemon Stadium .long 0x00050037 #Peach's Castle, Kongo Jungle .long 0x000B0012 #Brinstar, Corneria .long 0x00030019 #Yoshi's Story, Onett .long 0x00000048 #Mute City, Rainbow Cruise .long 0x00000024 #Jungle Japes, Great Bay .long 0x00190007 #Hyrule Temple, Brinstar Depths .long 0x000E0026 #Yoshi's Island, Green Greens .long 0x00040003 #Fourside, MKI .long 0x00040000 #MKII, Akaneia .long 0x00010105 #Venom, PokeFloats .long 0x00D9015B #Big Blue, Icicle Mountain .long 0x00000064 #Icetop, Flatzone .long 0x00040009 #Dream Land, Yoshis Island 64 .long 0x000b0001 #Kongo Jungle 64, Battlefield .long 0x00010000 #Final Destination ################################# ComboTrainingDecideStickAngle: #Decide Stick Angle backup #Clear Stick Inputs Just in Case li r4,0x0 stb r4,0x1A8C(r29) stb r4,0x1A8D(r29) #Check Which Type Of DI To Perform cmpwi r3,DI_Random beq ComboTrainingDecideStickAngle_RandomDI cmpwi r3,DI_Survival beq ComboTrainingDecideStickAngle_SurvivalDI cmpwi r3,DI_ComboDI beq ComboTrainingDecideStickAngle_ComboDI cmpwi r3,DI_SlightDIRandom beq ComboTrainingDecideStickAngle_RandomDI_SlightDI cmpwi r3,DI_SlightDIInwards beq ComboTrainingDecideStickAngle_SlightDIInwards cmpwi r3,DI_DownAndAway beq ComboTrainingDecideStickAngle_DownAwayDI cmpwi r3,DI_None beq ComboTrainingDecideStickAngle_NoDI ############### ## Random DI ## ############### #Roll RNG ComboTrainingDecideStickAngle_RandomDI: li r3,6 branchl r12,HSD_Randi cmpwi r3,0x0 beq ComboTrainingDecideStickAngle_RandomDI_TrulyRandom cmpwi r3,0x1 beq ComboTrainingDecideStickAngle_ComboDI cmpwi r3,0x2 beq ComboTrainingDecideStickAngle_SurvivalDI cmpwi r3,0x3 beq ComboTrainingDecideStickAngle_RandomDI_SlightDI cmpwi r3,0x4 beq ComboTrainingDecideStickAngle_DownAwayDI cmpwi r3,0x5 beq ComboTrainingDecideStickAngle_NoDI ComboTrainingDecideStickAngle_RandomDI_TrulyRandom: .set Combo_RandomAnalogMin, 36 .set Combo_RandomAnalogMax, 127 #Get X magnitude li r3,Combo_RandomAnalogMax - Combo_RandomAnalogMin branchl r12,HSD_Randi addi r3,r3,Combo_RandomAnalogMin stb r3,0x1A8C(r29) #Chance to negate li r3,2 branchl r12,HSD_Randi cmpwi r3,0x0 beq 0x10 lbz r3,0x1A8C(r29) neg r3,r3 stb r3,0x1A8C(r29) #Get Y magnitude li r3,Combo_RandomAnalogMax - Combo_RandomAnalogMin branchl r12,HSD_Randi addi r3,r3,Combo_RandomAnalogMin stb r3,0x1A8D(r29) #Chance to negate li r3,2 branchl r12,HSD_Randi cmpwi r3,0x0 beq 0x10 lbz r3,0x1A8D(r29) neg r3,r3 stb r3,0x1A8D(r29) b ComboTrainingDecideStickAngleExit ComboTrainingDecideStickAngle_RandomDI_SlightDI: .set Combo_SlightAnalogMin, 36 .set Combo_SlightAnalogMax, 66 #Get X magnitude li r3,Combo_SlightAnalogMax - Combo_SlightAnalogMin branchl r12,HSD_Randi addi r3,r3,Combo_RandomAnalogMin stb r3,0x1A8C(r29) #Chance to negate li r3,2 branchl r12,HSD_Randi cmpwi r3,0x0 beq 0x10 lbz r3,0x1A8C(r29) neg r3,r3 stb r3,0x1A8C(r29) #Get Y magnitude li r3,Combo_SlightAnalogMax - Combo_SlightAnalogMin branchl r12,HSD_Randi addi r3,r3,Combo_SlightAnalogMin stb r3,0x1A8D(r29) #Chance to negate li r3,2 branchl r12,HSD_Randi cmpwi r3,0x0 beq 0x10 lbz r3,0x1A8D(r29) neg r3,r3 stb r3,0x1A8D(r29) b ComboTrainingDecideStickAngleExit ####################### ## Slight DI Towards ## ####################### ComboTrainingDecideStickAngle_SlightDIInwards: #Get Random Stick X Input 86-105, 86-95 go in front, 96-105 go behind shiek li r3,19 branchl r12,HSD_Randi addi r3,r3,86 #Start at 86 lfs f1,0x2C(r27) fneg f1,f1 fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) #Facing direction as int mullw r3,r3,r4 stb r3,0x1A8C(r29) b ComboTrainingDecideStickAngleExit ################# ## Survival DI ## ################# ComboTrainingDecideStickAngle_SurvivalDI: #Check If In Throw bl ComboTrainingCheckForThrowAngle cmpwi r3,-1 bne ComboTrainingDecideStickAngle_SurvivalDI_UsingThrowAngle #Get Knockback Angle lwz r3,0x1848(r29) ComboTrainingDecideStickAngle_SurvivalDI_UsingThrowAngle: #Get Perpendicular Angle #Get Damage Direction cmpwi r3,0x169 #Check For Sakurai Angle bne 0xC li r3,0x2D li r4,0x2D cmpwi r3,90 bge ComboTrainingDecideStickAngle_SurvivalDI_Above90 b ComboTrainingDecideStickAngle_SurvivalDI_RightSide ComboTrainingDecideStickAngle_SurvivalDI_Above90: cmpwi r3,269 blt ComboTrainingDecideStickAngle_SurvivalDI_LeftSide ComboTrainingDecideStickAngle_SurvivalDI_RightSide: addi r3,r3,90 cmpwi r3,360 blt 0x8 subi r3,r3,360 b ComboTrainingDecideStickAngle_SurvivalDI_GetXY ComboTrainingDecideStickAngle_SurvivalDI_LeftSide: subi r3,r3,90 cmpwi r3,0 bgt 0x8 addi r3,r3,360 b ComboTrainingDecideStickAngle_SurvivalDI_GetXY ComboTrainingDecideStickAngle_SurvivalDI_GetXY: bl ComboTrainingDecideStickAngle_ConvertAngle stb r3,0x1A8C(r29) stb r4,0x1A8D(r29) bl GetDirectionInRelationToP1 #mulli r3,r3,-1 #Negate This Value lbz r4,0x1A8C(r29) mullw r3,r3,r4 stb r3,0x1A8C(r29) #Point Towards Opponent b ComboTrainingDecideStickAngleExit ############## ## Combo DI ## ############## ComboTrainingDecideStickAngle_ComboDI: #Check If In Throw bl ComboTrainingCheckForThrowAngle cmpwi r3,-1 bne ComboTrainingDecideStickAngle_ComboDI_UsingThrowAngle #Get Knockback Angle lwz r3,0x1848(r29) ComboTrainingDecideStickAngle_ComboDI_UsingThrowAngle: mr r24,r3 #Backup Original Angle We're Using #Get Perpendicular Angle #Get Damage Direction cmpwi r3,0x169 #Check For Sakurai Angle bne 0xC li r3,0x2D li r4,0x2D cmpwi r3,90 bge ComboTrainingDecideStickAngle_ComboDI_Above90 b ComboTrainingDecideStickAngle_ComboDI_RightSide ComboTrainingDecideStickAngle_ComboDI_Above90: cmpwi r3,269 blt ComboTrainingDecideStickAngle_ComboDI_LeftSide ComboTrainingDecideStickAngle_ComboDI_RightSide: subi r3,r3,90 cmpwi r3,0 bgt 0x8 addi r3,r3,360 b ComboTrainingDecideStickAngle_ComboDI_GetXY ComboTrainingDecideStickAngle_ComboDI_LeftSide: addi r3,r3,90 cmpwi r3,360 blt 0x8 subi r3,r3,360 b ComboTrainingDecideStickAngle_ComboDI_GetXY ComboTrainingDecideStickAngle_ComboDI_GetXY: bl ComboTrainingDecideStickAngle_ConvertAngle stb r3,0x1A8C(r29) stb r4,0x1A8D(r29) #If In a Throw, Always DI The Direction Of The Angle lwz r3,0x10(r29) cmpwi r3,0xEF blt ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionNoThrow cmpwi r3,0xF3 bgt ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionNoThrow ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow: cmpwi r24,90 bge ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_Above90 b ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_Above90: cmpwi r3,269 blt ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide: #Always Facing Direction li r3,0x0 bl IntToFloat lfs f2,0x2C(r27) fcmpo cr0,f2,f1 bgt ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_Abs ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_AbsNeg: lbz r3,0x1A8C(r29) extsb r3,r3 bl IntToFloat fabs f1,f1 fneg f1,f1 b ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_StoreX ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_Abs: lbz r3,0x1A8C(r29) extsb r3,r3 bl IntToFloat fabs f1,f1 b ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_StoreX ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_StoreX: fctiwz f1,f1 stfd f1,0xF0(sp) lwz r3,0xF4(sp) stb r3,0x1A8C(r29) b ComboTrainingDecideStickAngleExit ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide: #Always Opposite My Facing Direction li r3,0x0 bl IntToFloat lfs f2,0x2C(r27) fcmpo cr0,f2,f1 bgt ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_AbsNeg ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_Abs: lbz r3,0x1A8C(r29) extsb r3,r3 bl IntToFloat fabs f1,f1 b ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_StoreX ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_AbsNeg: lbz r3,0x1A8C(r29) extsb r3,r3 bl IntToFloat fabs f1,f1 fneg f1,f1 b ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_StoreX ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_StoreX: fctiwz f1,f1 stfd f1,0xF0(sp) lwz r3,0xF4(sp) stb r3,0x1A8C(r29) b ComboTrainingDecideStickAngleExit ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionNoThrow: bl GetDirectionInRelationToP1 #mulli r3,r3,-1 #Negate This Value lbz r4,0x1A8C(r29) mullw r3,r3,r4 stb r3,0x1A8C(r29) #Point Towards Opponent b ComboTrainingDecideStickAngleExit ###################### ## Down And Away DI ## ###################### ComboTrainingDecideStickAngle_DownAwayDI: #Load X Value bl GetDirectionInRelationToP1 #Point Away From P1 li r4,89 mullw r3,r3,r4 stb r3, 0x1A8C (r29) #Load Y Value li r3,-89 stb r3, 0x1A8D (r29) #C-Stick Down li r3,-127 stb r3, 0x1A8F (r29) b ComboTrainingDecideStickAngleExit ########### ## No DI ## ########### ComboTrainingDecideStickAngle_NoDI: ComboTrainingDecideStickAngleExit: restore blr ####################################################### ComboTrainingDecideStickAngle_ConvertAngle: #Convert New Angle To Float backup bl IntToFloat #Get Pi/180 lfs f2,-0x7510(rtoc) #Get Angle As Radian fmuls f31,f1,f2 #Get 127 as Float li r3,127 bl IntToFloat fmr f30,f1 #Convert To X and Y Components fmr f1,f31 branchl r12,cos #load cosine function fmuls f1,f1,f30 #Get X Component As Float fctiwz f1,f1 stfd f1,0xF0(sp) lwz r20,0xF4(sp) fmr f1,f31 branchl r12,sin #load sine function fmuls f1,f1,f30 #Get X Component As Float fctiwz f1,f1 stfd f1,0xF0(sp) lwz r21,0xF4(sp) #Clamp Deadzones ComboTrainingDecideStickAngle_ConvertAngle_ClampX: mr r3,r20 bl IntToFloat fabs f3,f1 li r3,36 bl IntToFloat fcmpo cr0,f3,f1 bge ComboTrainingDecideStickAngle_ConvertAngle_ClampY li r20,0x0 ComboTrainingDecideStickAngle_ConvertAngle_ClampY: mr r3,r21 bl IntToFloat fabs f3,f1 li r3,36 bl IntToFloat fcmpo cr0,f3,f1 bge ComboTrainingDecideStickAngle_ConvertAngle_Exit li r21,0x0 ComboTrainingDecideStickAngle_ConvertAngle_Exit: #Return X Y Stick Values mr r3,r20 mr r4,r21 restore blr ############################################################## ComboTrainingCheckForThrowAngle: #Check If In Throw First (Must Retrieve Angle Manually) lwz r3,0x10(r29) #CPU AS cmpwi r3,0xEF blt ComboTrainingCheckForThrowAngle_NoThrow cmpwi r3,0xF3 bgt ComboTrainingCheckForThrowAngle_NoThrow #Get Throw Angle addi r4,r27,0xdf4 #P1 Throw Hitbox Info? lwz r3,0x20(r4) #Throw Angle b ComboTrainingCheckForThrowAngle_NoThrowExit ComboTrainingCheckForThrowAngle_NoThrow: li r3,-1 ComboTrainingCheckForThrowAngle_NoThrowExit: blr #################################################### ComboTrainingCheckExitStates: #Check For Exit States lwz r3,0x10(r29) cmpwi r3,0xE #Wait beq ComboTrainingCheckExitStates_ExitState cmpwi r3,0x1D #Fall beq ComboTrainingCheckExitStates_ExitState cmpwi r3,0x1B #DJ beq ComboTrainingCheckExitStates_ExitState cmpwi r3,0xFD #CliffWait beq ComboTrainingCheckExitStates_ExitState cmpwi r3,0xF5 #Teeter beq ComboTrainingCheckExitStates_ExitState cmpwi r3,0x1C #JumpB Aerial beq ComboTrainingCheckExitStates_ExitState cmpwi r3,0x2A #Land bne ComboTrainingCheckExitStates_CheckJiggsJump #Check If Can Interrupt Land lfs f1,0x894(r29) lfs f2,0x1F4(r29) fcmpo cr0,f1,f2 bge ComboTrainingCheckExitStates_ExitState ComboTrainingCheckExitStates_CheckJiggsJump: lwz r4,0x4(r29) cmpwi r4,0xF #Check If Jiggs bne ComboTrainingCheckExitStates_NoExitState cmpwi r3,0x155 beq ComboTrainingCheckExitStates_ExitState ComboTrainingCheckExitStates_NoExitState: li r3,0x0 b ComboTrainingCheckExitStates_Exit ComboTrainingCheckExitStates_ExitState: li r3,0x1 b ComboTrainingCheckExitStates_Exit ComboTrainingCheckExitStates_Exit: blr #################################################### ComboTrainingWindowInfo: blrl #amount of options, amount of options in each window .long 0x04060304 #5 windows, DI has 7 options, SDI has 4 Options, Tech Has 5 Options .long 0x02020000 #PostHitstun has 3 options, Mash has 3 options #################################################### ComboTrainingWindowText: blrl ######## ## DI ## ######## #Window Title = DI Behavior .string "DI Behavior" .align 2 #Option 1 = Random DI .string "Random DI" .align 2 #Option 2 = Survival DI .string "Survival DI" .align 2 #Option 3 = Combo DI .string "Combo DI" .align 2 #Option 4 = Slight DI Random .string "Slight DI Random" .align 2 #Option 5 = Slight DI Towards .string "Slight DI Towards" .align 2 #Option 6 = Down and Away DI .string "Down and Away DI" .align 2 #Option 6 = No DI .string "No DI" .align 2 ######### ## SDI ## ######### #SDI Behavior .long 0x53444920 .long 0x42656861 .long 0x76696f72 .long 0x00000000 #Option 1 = 33% Chance to SDI .long 0x33338193 .long 0x20436861 .long 0x6e636520 .long 0x746f2053 .long 0x44490000 #Option 2 = 66% Chance to SDI .long 0x36368193 .long 0x20436861 .long 0x6e636520 .long 0x746f2053 .long 0x44490000 #Option 3 = Always SDI .long 0x416c7761 .long 0x79732053 .long 0x44490000 #Option 4 = No SDI .long 0x4e6f2053 .long 0x44490000 ################# ## Tech Option ## ################# #Tech Option .long 0x54656368 .long 0x204f7074 .long 0x696f6e00 #Option 1 = Random .long 0x52616e64 .long 0x6f6d0000 #Option 2 = Missed Tech .long 0x4d697373 .long 0x65642054 .long 0x65636800 #Option 3 = Tech In Place .long 0x54656368 .long 0x20496e20 .long 0x506c6163 .long 0x65000000 #Option 4 = Tech In .long 0x54656368 .long 0x20496e00 #Option 5 = Tech Away .long 0x54656368 .long 0x20417761 .long 0x79000000 ################# ## Tech Option ## ################# #Post Hitstun Action .long 0x506f7374 .long 0x20486974 .long 0x7374756e .long 0x20416374 .long 0x696f6e00 #Airdodge/Spotdodge .long 0x41697264 .long 0x6f646765 .long 0x815e5370 .long 0x6f74646f .long 0x64676500 #Invincible .long 0x496e7669 .long 0x6e636962 .long 0x6c650000 #Attack .long 0x41747461 .long 0x636b0000 ################### ## Grab Mash-Out ## ################### #Grab Mash-Out .long 0x47726162 .long 0x204d6173 .long 0x682d4f75 .long 0x74000000 .long 0x #Random Mash .long 0x52616e64 .long 0x6f6d204d .long 0x61736800 .long 0x .long 0x #Frame Perfect .long 0x4672616d .long 0x65205065 .long 0x72666563 .long 0x74000000 .long 0x #No Mash-Out .long 0x4e6f204d .long 0x6173682d .long 0x4f757400 .long 0x .long 0x #################################################### ComboTrainingAttackList: blrl .long 0x00700466 .long 0x02660000 .long 0x30000303 .long 0x04660073 .long 0x30000152 .long 0x00007000 .long 0x660400FF #################################################### ComboTrainingLoadExit: restore blr ################################################## #endregion #region Waveshine SDI ######################### ## Waveshine SDI HIJACK INFO ## ######################### WaveshineSDI: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Fox.Ext #Use chosen CPU li r6,FinalDestination #Use chosen Stage load r7,EventOSD_WaveshineSDI li r8,1 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION WaveshineSDIStoreThink: bl WaveshineSDILoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Waveshine SDI LOAD FUNCT ## ######################## WaveshineSDILoad: blrl backup #Schedule Think bl WaveshineSDIThink mflr r3 li r4,3 #Priority (After Interrupt) li r5,0 bl CreateEventThinkFunction /* #Make Long Destination #Get Stage DAT Pointer load r3,0x80432290 lwz r3,0x10(r3) lwz r6,0x4(r3) lis r3, 0x4040 li r5, 0x0 ori r4, r5, 0xF488 stwx r3, r6, r4 ori r4, r5, 0xF4CC stwx r3, r6, r4 ori r4, r5, 0xF4D0 stwx r3, r6, r4 ori r4, r5, 0xF590 stwx r3, r6, r4 lis r4, 0x1 ori r4, r4, 0x88 stwx r3, r6, r4 lis r4, 0x1 ori r4, r4, 0x608 stwx r3, r6, r4 lis r3, 0x4248 ori r4, r5, 0xF4D8 stwx r3, r6, r4 lis r4, 0x5 ori r4, r4, 0x1B90 stwx r5, r6, r4 lis r5, 0x5 lis r3, 0xC3AA ori r3, r3, 0x91EC ori r4, r5, 0x1F20 stwx r3, r6, r4 lis r3, 0x43AA ori r3, r3, 0x91EC ori r4, r5, 0x1F60 stwx r3, r6, r4 lis r3, 0xC3D0 ori r3, r3, 0x91EC ori r4, r5, 0x1FA0 stwx r3, r6, r4 lis r3, 0x43D0 ori r3, r3, 0x91EC ori r4, r5, 0x1FE0 stwx r3, r6, r4 */ b WaveshineSDILoadExit ######################### ## Waveshine SDI THINK FUNCT ## ######################### WaveshineSDIThink: blrl .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq WaveshineSDIThinkMain #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) #Set Facing Directions lis r3,0x3f80 stw r3,0x2C(r29) lis r3,0xBf80 stw r3,0x2C(r27) #Initlize Positions bl WaveshineSDI_Floats mflr r3 bl InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Store Ground As Last Known Position lfs f1, 0x00B4 (r29) stfs f1, 0x0834 (r29) #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Set Timer to -60 li r3,-60 stw r3,0x4(r31) WaveshineSDIThinkMain: WaveshineSDIThinkSequence: #Inc Timer lwz r3,0x4(r31) addi r3,r3,0x1 stw r3,0x4(r31) #Get Floats bl WaveshineSDI_Floats mflr r21 #Check Timer cmpwi r3,0x0 blt WaveshineSDICheckToReset #Check If Edge Of Stage lfs f1,0xB0(r29) #P1 X Coord lfs f2,0x18(r21) #Max X Coord fabs f1,f1 fabs f2,f2 fcmpo cr0,f1,f2 blt WaveshineSDISkipBoundaryCheck #Freeze Fox If So lbz r0,0x2219(r29) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(r29) lwz r3,0xC(r31) cmpwi r3,0x0 #No Reset Timer Set Yet bgt WaveshineSDICheckToReset li r3,60 #Set Timer If Not Set Yet stw r3,0xC(r31) b WaveshineSDICheckToReset WaveshineSDISkipBoundaryCheck: #Check If Fox Grabbed Marth lwz r3,0x10(r29) cmpwi r3,0xD8 bne WaveshineSDICheckDrillOrWaveshine lwz r3,0xC(r31) cmpwi r3,0x0 bgt WaveshineSDICheckDrillOrWaveshine li r3,60 stw r3,0xC(r31) #Check If Drilling or Waveshining WaveshineSDICheckDrillOrWaveshine: lbz r3,0x8(r31) cmpwi r3,0x1 bge WaveshineSDIWaveshineThink #Run Drill Code WaveshineSDIDrillThink: lwz r3,0x10(r29) WaveshineSDIDrillThink_CheckToJump: cmpwi r3,0xE bne WaveshineSDIDrillThink_CheckToDair li r3,0x400 stw r3,0x1A88(r29) b WaveshineSDICheckToReset WaveshineSDIDrillThink_CheckToDair: cmpwi r3,0x19 bne WaveshineSDI_CheckToFF li r3,-127 stb r3,0x1A8F(r29) b WaveshineSDICheckToReset WaveshineSDI_CheckToFF: #Check If Drilling cmpwi r3,0x45 bne WaveshineSDICheckToReset #Joystick X = 36 * Facing Direction (Drift Forward during drill lfs f1,0x2C(r29) fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) li r3,36 #X Stick mullw r3,r3,r4 stb r3,0x1A8C(r29) #Check If Already FF'ing lbz r3,0x221A(r29) rlwinm. r3,r3,0,28,28 bne WaveshineSDICheckToLCancel #Check If Falling lfs f2,0x84(r29) lfs f0, -0x76B0 (rtoc) fcmpo cr0,f2,f0 bge WaveshineSDICheckToReset #Input Down to FF li r3,-127 stb r3,0x1A8D(r29) #Ananlog Y WaveshineSDICheckToLCancel: #Check If Under 5Mm Above Ground lfs f2,0xB4(r29) lfs f0,0x834(r29) #Last Grounded Y Pos fsubs f2,f2,f0 #Distance from Floor lfs f0,0x10(r21) #5 fp fcmpo cr0,f2,f0 #If less than 5 Mm away, Input L Cancel bgt WaveshineSDICheckToReset li r3,0xC0 #Hit L stw r3,0x1A88(r29) #Held Buttons li r3,0x1 #Set Start Waveshine Flag stb r3,0x8(r31) b WaveshineSDICheckToReset #Run Waveshine Code WaveshineSDIWaveshineThink: lwz r3,0x10(r29) #Shine If In Wait cmpwi r3,0xE bne WaveshineSDICheckToJump #Check If First Shine Or FollowUp Shine lbz r4,0x8(r31) cmpwi r4,0x2 beq WaveshineSDIWaveshine_FollowOpponent #Input Shine li r3,-127 stb r3,0x1A8D(r29) li r3,0x200 stw r3,0x1A88(r29) #Set Flag as Mid-Waveshine li r3,0x2 stb r3,0x8(r31) #Get JC Timing li r3,3 branchl r12,HSD_Randi stb r3,0x9(r31) b WaveshineSDICheckToReset #Jump If In Shine Loop WaveshineSDICheckToJump: #Check #Check For Shine Loop cmpwi r3,0x169 bne WaveshineSDICheckToAirdodge #Check For JC Frame lbz r3,0x9(r31) #Get JC Timing bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f1,f2 bne WaveshineSDICheckToReset #Jump li r3,0x400 stw r3,0x1A88(r29) b WaveshineSDICheckToReset #Airdodge If In JumpF WaveshineSDICheckToAirdodge: cmpwi r3,0x19 bne WaveshineSDIWaveshine_CheckIfFollowingOpponent #Get Random Airdodge Angle li r3,30 #30 Different Angles branchl r12,HSD_Randi addi r3,r3,310 #Start at 310° bl ComboTrainingDecideStickAngle_ConvertAngle #Joystick X = X Component * Facing Direction lfs f1,0x2C(r29) fctiwz f1,f1 stfd f1,0xF0(sp) lwz r5,0xF4(sp) mullw r3,r3,r5 stb r3,0x1A8C(r29) #Joystick Y = Y Component stb r4,0x1A8D(r29) #Press L To Wavedash li r3,0xC0 stw r3,0x1A88(r29) b WaveshineSDICheckToReset WaveshineSDIWaveshine_CheckIfFollowingOpponent: cmpwi r3,0xf #Check if Walking blt WaveshineSDICheckIfInTeeter cmpwi r3,0x11 #Check if Walking bgt WaveshineSDICheckIfInTeeter b WaveshineSDIWaveshine_FollowOpponent WaveshineSDICheckIfInTeeter: cmpwi r3,0xf5 bne WaveshineSDICheckToReset b WaveshineSDIRestoreState WaveshineSDIWaveshine_FollowOpponent: #Determine Distance From Opponent lfs f1,0xB0(r27) lfs f2,0xB0(r29) fsubs f1,f1,f2 lfs f2,-0x7414(rtoc) #0f fcmpo cr0,f1,f2 bge WaveshineSDIWaveshine_FollowOpponent_FacingRight WaveshineSDIWaveshine_FollowOpponent_FacingLeft: #Check If Close Enough To Shine lfs f2,0x14(r21) fneg f2,f2 fcmpo cr0,f1,f2 blt WaveshineSDIWaveshine_FollowOpponent_WalkTowards b WaveshineSDIWaveshine_FollowOpponent_EnterShine #b WaveshineSDIWaveshine_FollowOpponent_CheckMarth WaveshineSDIWaveshine_FollowOpponent_FacingRight: lfs f2,0x14(r21) fcmpo cr0,f1,f2 bgt WaveshineSDIWaveshine_FollowOpponent_WalkTowards b WaveshineSDIWaveshine_FollowOpponent_EnterShine #Check Opponent WaveshineSDIWaveshine_FollowOpponent_CheckMarth: lwz r3,0x4(r27) cmpwi r3,0x12 #Marth beq WaveshineSDIWaveshine_FollowOpponent_EnterGrab WaveshineSDIWaveshine_FollowOpponent_EnterShine: #Shine li r3,-127 stb r3,0x1A8D(r29) li r3,0x200 stw r3,0x1A88(r29) #Get JC Timing li r3,3 branchl r12,HSD_Randi stb r3,0x9(r31) b WaveshineSDICheckToReset WaveshineSDIWaveshine_FollowOpponent_EnterGrab: li r3,0x1C0 stw r3,0x1A88(r29) b WaveshineSDICheckToReset WaveshineSDIWaveshine_FollowOpponent_WalkTowards: #Walk Towards Opponent #Stick Forward lfs f1,0x2C(r29) fctiwz f2,f1 stfd f2,0xF0(sp) lwz r4,0xF4(sp) li r3,127 #X Stick mullw r3,r3,r4 stb r3,0x1A8C(r29) #Override Analog Smash Counter So Always Walking (Set Facing As Prev X Input) stfs f1,0x620(r29) b WaveshineSDICheckToReset #Initiate Reset Timer li r3,120 stw r3,0xC(r31) #Check To Reset WaveshineSDICheckToReset: lwz r3,0xC(r31) #get timer #Get Timer cmpwi r3,0x0 #No Reset Timer Set Yet ble WaveshineSDIThinkExit #Dec Timer subi r3,r3,0x1 stw r3,0xC(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne WaveshineSDIThinkExit #Exit If Not WaveshineSDIRestoreState: #Invert Facing Directions lwz r4,0x10(r31) lwz r5,0x18(r31) lfs f1,0x2C(r4) fneg f1,f1 stfs f1,0x2C(r4) lfs f1,0x2C(r5) fneg f1,f1 stfs f1,0x2C(r5) #Invert X Positions lfs f1,0xB0(r4) fneg f1,f1 stfs f1,0xB0(r4) lfs f1,0xB0(r5) fneg f1,f1 stfs f1,0xB0(r5) #Restore State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Reset Timer li r3,60 branchl r12,HSD_Randi li r4,0 sub r3,r4,r3 stw r3,0x4(r31) #Reset Mid-Waveshine Flag li r3,0x0 stb r3,0x8(r31) WaveshineSDIThinkExit: restore blr ################################# WaveshineSDI_Floats: blrl .long 0xC28C0000 #P1 X Position .long 0xc2982e6c #P2 X Position .long 0x38d1b717 #P1 Y Position .long 0x38d1b717 #FD Floor Y Coord .long 0x40A00000 #5fp .long 0x40F00000 #Distance From Opponent to Waveshine .long 0x42A00000 #X Coord To Stop ################################# WaveshineSDILoadExit: restore blr ################################################## #endregion #region Slide Off ########################### ## Slide Off HIJACK INFO ## ########################### SlideOff: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Marth.Ext li r6,PokemonStadium #Use chosen Stage load r7,EventOSD_SlideOff li r8,1 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION SlideOffStoreThink: bl SlideOffLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## Slide Off LOAD FUNCT ## ################################## SlideOffLoad: blrl backup #Schedule Think bl SlideOffThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction b SlideOffThink_Exit ################################### ## Slide Off THINK FUNCT ## ################################### SlideOffThink: blrl #Registers .set REG_EventConstants,25 .set REG_MenuData,26 .set REG_EventData,31 .set REG_P1Data,27 .set REG_P1GObj,28 .set REG_P2Data,29 .set REG_P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_Hitstun,0x0 .set EventState_DetermineAttack,0x1 .set EventState_AttackThink,0x2 .set EventState_Shield,0x3 .set Timer,0x1 .set P1State,0x2 .set P1State_Wait,0x0 .set P1State_Attacking,0x1 .set AttackTimer,0x3 #Constants .set ResetTimer,40 .set AngleLo,83 .set AngleHi,100 .set MagLo,65 .set MagHi,75 .set HitlagFrames,12 .set PercentLo,40 .set PercentHi,40 .set FramesBeforeHitbox,7 backup #INIT FUNCTION VARIABLES lwz REG_EventData,0x2c(r3) #backup data pointer in r31 #Get Player Pointers bl GetAllPlayerPointers mr REG_P1GObj,r3 mr REG_P1Data,r4 mr REG_P2GObj,r5 mr REG_P2Data,r6 #Get Menu and Constants Pointers lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData) bl SlideOffThink_Constants mflr REG_EventConstants bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq SlideOffThink_Start #Init Positions mr r3,REG_P1GObj mr r4,REG_P2GObj bl SlideOff_InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Init State li r3,EventState_Hitstun stb r3,EventState(REG_EventData) SlideOffThink_Start: #Reset if anyone died bl IsAnyoneDead cmpwi r3,0 bne SlideOffThink_Restore SlideOffThink_CheckIfFailed: #Check if failed the slide off (in non-hitlag damage state) #EventState > EventState_Hitstun lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Hitstun ble SlideOffThink_CheckIfFailed_End #Check for hitlag lbz r3,0x221A(REG_P1Data) rlwinm. r3,r3,0,26,26 bne SlideOffThink_CheckIfFailed_End #Check if in hitstun lbz r3,0x221C(REG_P1Data) rlwinm. r3,r3,0,30,30 beq SlideOffThink_CheckIfFailed_End #Check if player has been in this state for over 5 frames lhz r3,FramesinCurrentAS(REG_P1Data) cmpwi r3,5 blt SlideOffThink_CheckIfFailed_End #Check if timer has started lbz r3,Timer(REG_EventData) cmpwi r3,0 bgt SlideOffThink_CheckTimer #Start Timer li r3,10 stb r3,Timer(REG_EventData) SlideOffThink_CheckIfFailed_End: SlideOffThink_CheckIfCPUDamaged: lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_DamageHi1 blt SlideOffThink_CheckIfCPUDamaged_End cmpwi r3,ASID_DamageFlyRoll bgt SlideOffThink_CheckIfCPUDamaged_End #Check if timer has started lbz r3,Timer(REG_EventData) cmpwi r3,0 bgt SlideOffThink_CheckIfCPUDamaged_End #Start Timer li r3,ResetTimer stb r3,Timer(REG_EventData) SlideOffThink_CheckIfCPUDamaged_End: SlideOffThink_SwitchCase: #Switch Case lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Hitstun beq SlideOffThink_Hitstun cmpwi r3,EventState_DetermineAttack beq SlideOffThink_DetermineAttackorShield cmpwi r3,EventState_AttackThink beq SlideOffThink_AttackThink cmpwi r3,EventState_Shield beq SlideOffThink_Shield b SlideOffThink_CheckTimer #region SlideOffThink_Hitstun SlideOffThink_Hitstun: #Check if still in ThrowHi lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_ThrowHi beq SlideOffThink_CheckTimer #Check if P1 is in a tech/mistech state lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_DownBoundU blt SlideOffThink_CheckTimer cmpwi r3,ASID_PassiveStandB bgt SlideOffThink_CheckTimer #Change state to attack li r3,EventState_DetermineAttack stb r3,EventState(EventData) b SlideOffThink_CheckTimer #endregion #region SlideOffThink_DetermineAttackorShield SlideOffThink_DetermineAttackorShield: /* #Ensure facing correct direction #Get Values lfs f1,0xB0(REG_P2Data) #p2 position lfs f2,0x2C(REG_P2Data) #p2 direction lfs f4,TriggerBoxXMin(REG_EventConstants) lfs f5,TriggerBoxXMax(REG_EventConstants) lfs f6,0xB0(REG_P1Data) #Check X fmadds f3,f2,f4,f1 #XMin fmadds f4,f2,f5,f1 #XMax #Make sure player is not behind marths range lfs f1,-0x68E0 (rtoc) #fp 0 fcmpo cr0,f2,f1 bge SlideOffThink_Attck_FacingRight SlideOffThink_Attck_FacingLeft: li r3,1 fcmpo cr0,f6,f3 bge SlideOffThink_Attck_InputTurn b SlideOffThink_Attck_SkipDirectionChange SlideOffThink_Attck_FacingRight: li r3,-1 fcmpo cr0,f6,f3 ble SlideOffThink_Attck_InputTurn b SlideOffThink_Attck_SkipDirectionChange SlideOffThink_Attck_InputTurn: #Check if already turning lwz r4,0x10(REG_P2Data) cmpwi r4,ASID_Turn beq SlideOffThink_Attck_SkipDirectionChange #Input turn mulli r3,r3,36 stb r3,CPU_AnalogX(REG_P2Data) SlideOffThink_Attck_SkipDirectionChange: */ SlideOffThink_DetermineAttackorShield_SkipFailCheck: #Decide to shield or attack lfs f1,0xB4(REG_P2Data) #p2 position lfs f2,TriggerBoxYMin(REG_EventConstants) lfs f3,TriggerBoxYMax(REG_EventConstants) lfs f4,0xB4(REG_P1Data) #p1 position fadds f2,f1,f2 #YMin fadds f3,f1,f3 #YMax #Check if P1 is above YMax fcmpo cr0,f4,f3 bge SlideOffThink_DetermineAttackorShield_AboveTriggerBox #Check if P1 is below YMin fcmpo cr0,f4,f2 bge SlideOffThink_DetermineAttackorShield_CheckToAttack_CanAttack SlideOffThink_DetermineAttackorShield_EnterShield: #Change Event State li r3,EventState_Shield stb r3,EventState(REG_EventData) #Start Timer li r3,ResetTimer stb r3,Timer(REG_EventData) b SlideOffThink_Shield SlideOffThink_DetermineAttackorShield_AboveTriggerBox: #Check if timer has started lbz r3,Timer(REG_EventData) cmpwi r3,0 bgt SlideOffThink_CheckTimer #Start Timer li r3,10 stb r3,Timer(REG_EventData) b SlideOffThink_CheckTimer SlideOffThink_DetermineAttackorShield_CheckToAttack_CanAttack: #Get P1's State lwz r3,0x10(REG_P1Data) #Ensure we have the frame data for this state cmpwi r3,ASID_DownBoundU blt SlideOffThink_DetermineAttackorShield_CheckToAttack_StartAttack cmpwi r3,ASID_PassiveStandB bgt SlideOffThink_DetermineAttackorShield_CheckToAttack_StartAttack #If DownWait or Bound, dont do anything cmpwi r3,ASID_DownWaitD beq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd cmpwi r3,ASID_DownWaitU beq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd cmpwi r3,ASID_DownBoundD beq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd cmpwi r3,ASID_DownBoundU beq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd #Get the frame data to use subi r3,r3,ASID_DownBoundU addi r4,REG_EventConstants,VulnFrameData lbzx r3,r3,r4 #Marth takes 8 frames for his utilt hitbox to appear, so subtract 8 subi r3,r3,FramesBeforeHitbox #Use the custom playerblock offset to check P1's frame count lhz r4,FramesinCurrentAS(REG_P1Data) cmpw r4,r3 blt SlideOffThink_DetermineAttackorShield_CheckToAttackEnd #Time to attack SlideOffThink_DetermineAttackorShield_CheckToAttack_StartAttack: li r3,EventState_AttackThink stb r3,EventState(REG_EventData) b SlideOffThink_DetermineAttackorShield_CheckToAttackEnd SlideOffThink_DetermineAttackorShield_CheckToAttackEnd: b SlideOffThink_CheckTimer #endregion #region SlideOffThink_AttackThink SlideOffThink_AttackThink: #Get Inputs for this frame mr r3,REG_P2Data bl SlideOffThink_AttackInputs mflr r4 lbz r5,AttackTimer(REG_EventData) bl PlaybackInputSequence #Always succeed LCancel li r3,0 stb r3,0x67F(REG_P2Data) #Remove Hitbox ID 1,2 and 3 (problematic for getting slideoff) mr r3,REG_P2GObj li r4,1 branchl r12,0x8007afc8 mr r3,REG_P2GObj li r4,2 branchl r12,0x8007afc8 mr r3,REG_P2GObj li r4,3 branchl r12,0x8007afc8 #Exit AttackThink when returning to Wait lbz r3,AttackTimer(REG_EventData) cmpwi r3,0 ble SlideOffThink_AttackThink_Exit lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_Wait beq SlideOffThink_AttackThink_Reset cmpwi r3,ASID_Landing bne SlideOffThink_AttackThink_Exit #Now check if interruptable lwz r3, 0x2340 (REG_P2Data) cmpwi r3,0 beq SlideOffThink_AttackThink_Exit #Check if this frame is interruptable lfs f1,0x1f4 (REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) lhz r4,FramesinCurrentAS(REG_P2Data) cmpw r4,r3 blt SlideOffThink_AttackThink_Exit SlideOffThink_AttackThink_Reset: li r3,EventState_DetermineAttack #event state stb r3,EventState(REG_EventData) li r3,0 #reset timer stb r3,AttackTimer(REG_EventData) b SlideOffThink_CheckTimer SlideOffThink_AttackThink_Exit: #Check if in Hitlag lbz r3,0x221A(REG_P2Data) rlwinm. r3,r3,0,26,26 bne SlideOffThink_CheckTimer #Increment Attack Timer lbz r3,AttackTimer(REG_EventData) addi r3,r3,1 stb r3,AttackTimer(REG_EventData) b SlideOffThink_CheckTimer #endregion #region SlideOffThink_Shield SlideOffThink_Shield: #Hold Shield li r3,PAD_TRIGGER_R stw r3,CPU_HeldButtons(REG_P2Data) b SlideOffThink_CheckTimer #endregion SlideOffThink_CheckTimer: #Check if timer exists lbz r3,Timer(REG_EventData) cmpwi r3,0 ble SlideOffThink_Exit #Decrement timer subi r3,r3,1 stb r3,Timer(REG_EventData) cmpwi r3,0 bgt SlideOffThink_Exit SlideOffThink_Restore: #Restore State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Load #Init Positions Again mr r3,REG_P1GObj mr r4,REG_P2GObj bl SlideOff_InitializePositions #Reset Variables li r3,0 stb r3,EventState(REG_EventData) stb r3,Timer(REG_EventData) stb r3,P1State(REG_EventData) stb r3,AttackTimer(REG_EventData) SlideOffThink_Exit: restore blr ################################ SlideOffThink_Constants: blrl .set MarthUTiltFrame,8 .set P1X,0x0 .set P1Y,0x4 .set P2X,0x8 .set P2Y,0xC .set UThrowStartFrame,0x10 .set DamageFlyTopStartFrame,0x14 .set MagnitudeScalar,0x18 .set MagnitudeScalar2,0x1C .set MagnitudeScalar3,0x20 .set TriggerBoxXMin,0x24 .set TriggerBoxXMax,0x28 .set TriggerBoxYMin,0x2C .set TriggerBoxYMax,0x30 .set VulnFrameData,0x34 .set Unk,0x48 .float -37.7 #p1 x .float 21.2 #p1 y .float -41.1 #p2 x .float 0 #p2 y .float 13 #marth upthrow starting frame .float 2 #p1 damageflytop starting frame .float 0.1 #baseline for mag scaling .float 1 #mag scaling constant .float 0.4 #mag scaling constant .float -8 #xmin .float 20 #xmax .float 18 #ymin .float 30 #ymax ########################################## .set TechVuln,24-4 .set TechRollVuln,23 .set KnockdownVuln,23 .set GetupVuln,23 .set GetupRollForwardVuln,20-1 .set GetupRollBackwardVuln,30-3 .set GetupAttackVuln,27 .byte KnockdownVuln #DownBoundU .byte 0 #DownWaitU .byte 0 #DownDamageU .byte GetupVuln #DownStandU .byte GetupAttackVuln #DownAttackU .byte GetupRollForwardVuln #DownForwardU .byte GetupRollBackwardVuln #DownBackU .byte -1 #DownSpotU (unused state) .byte KnockdownVuln #DownBoundD .byte 0 #DownWaitD .byte 0 #DownDamageD .byte GetupVuln #DownStandD .byte GetupAttackVuln #DownAttackD .byte GetupRollForwardVuln #DownForwardD .byte GetupRollBackwardVuln #DownBackD .byte -1 #DownSpotD (unused state) .byte TechVuln #Passive .byte TechRollVuln #PassiveStandF .byte TechRollVuln #PassiveStandB .align 2 ########################################### SlideOffThink_AttackInputs: blrl .byte 0 .long PAD_BUTTON_X .byte 0,0,0,0 .byte 4 .long 0 .byte 0,0,0,127 .byte 26 .long PAD_TRIGGER_L .byte 0,-127,0,0 .byte -1 .align 2 ################################# SlideOff_InitializePositions: backup #Change Facing Direction li r3,-1 bl IntToFloat stfs f1,0x2C(REG_P1Data) li r3,1 bl IntToFloat stfs f1,0x2C(REG_P2Data) #Get Starting Coordinates lfs f1,P1X(REG_EventConstants) stfs f1,0xB0(REG_P1Data) lfs f1,P1Y(REG_EventConstants) stfs f1,0xB4(REG_P1Data) mr r3,REG_P1GObj bl UpdatePosition mr r3,REG_P1GObj bl UpdateCameraBox lfs f1,P2X(REG_EventConstants) stfs f1,0xB0(REG_P2Data) lfs f1,P2Y(REG_EventConstants) stfs f1,0xB4(REG_P2Data) mr r3,REG_P2GObj bl PlacePlayerOnGround mr r3,REG_P2GObj bl UpdateCameraBox #P2 enters UpThrow mr r3,REG_P2GObj li r4,ASID_ThrowHi li r5,0 li r6,0 lwz r7,0x10C(REG_P1Data) #determine speed from weight lwz r7,0x0(r7) lfs f1,0x88(r7) lfs f2, -0x68DC (rtoc) lwz r7, -0x514C (r13) lfs f0, 0x037C (r7) fmuls f0,f1,f0 fdivs f2,f2,f0 #anim speed lfs f3, -0x68E0 (rtoc) #frame blend lfs f1,UThrowStartFrame(REG_EventConstants) #starting frame branchl r12,ActionStateChange #P1 enters DamageFlyTop mr r3,REG_P1GObj li r4,ASID_DamageFlyTop li r5,0x40 li r6,0 lfs f1,DamageFlyTopStartFrame (REG_EventConstants) lfs f2, -0x73D0 (rtoc) lfs f3, -0x750C (rtoc) branchl r12,ActionStateChange #Scale KB Magnitude based on characters weight li r3,MagLo bl IntToFloat lfs f2,MagnitudeScalar(REG_EventConstants) lfs f3,0x16C(REG_P1Data) lfs f4,MagnitudeScalar2(REG_EventConstants) lfs f5,MagnitudeScalar3(REG_EventConstants) fdivs f2,f3,f2 fsubs f2,f2,f4 fmuls f2,f2,f5 fmuls f2,f2,f1 fadds f1,f1,f2 fctiwz f1,f1 stfd f1,0x80(sp) lwz r20,0x84(sp) li r3,MagHi bl IntToFloat lfs f2,MagnitudeScalar(REG_EventConstants) lfs f3,0x16C(REG_P1Data) lfs f4,MagnitudeScalar2(REG_EventConstants) lfs f5,MagnitudeScalar3(REG_EventConstants) fdivs f2,f3,f2 fsubs f2,f2,f4 fmuls f2,f2,f5 fmuls f2,f2,f1 fadds f1,f1,f2 fctiwz f1,f1 stfd f1,0x80(sp) lwz r21,0x84(sp) #Enter into knockback mr r3,REG_P1GObj li r4,AngleLo li r5,AngleHi mr r6,r20 mr r7,r21 bl EnterKnockback #Override hitstun amount li r3,50 bl IntToFloat stfs f1,0x2340(REG_P1Data) #Give 7 Frames of Hitlag to Each li r3,HitlagFrames bl IntToFloat stfs f1,0x195C(REG_P1Data) lbz r0,0x221A(REG_P1Data) li r3,1 rlwimi r0,r3,5,26,26 stb r0,0x221A(REG_P1Data) lbz r0,0x2219(REG_P1Data) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(REG_P1Data) li r3,HitlagFrames bl IntToFloat stfs f1,0x195C(REG_P2Data) lbz r0,0x221A(REG_P2Data) li r3,1 rlwimi r0,r3,5,26,26 stb r0,0x221A(REG_P2Data) lbz r0,0x2219(REG_P2Data) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(REG_P2Data) #Random percent between 10-25 li r3,PercentHi-PercentLo branchl r12,HSD_Randi addi r4,r3,PercentLo lbz r3,0xC(REG_P1Data) branchl r12,PlayerBlock_SetDamage SlideOff_InitializePositions_Exit: restore blr #endregion #region Grab Mash Out ########################### ## Grab Mash Out HIJACK INFO ## ########################### GrabMashOut: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Marth.Ext li r6,FinalDestination #Use chosen Stage load r7,EventOSD_GrabMashOut li r8,1 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION GrabMashOutStoreThink: bl GrabMashOutLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## Grab Mash Out LOAD FUNCT ## ################################## GrabMashOutLoad: blrl backup #Schedule Think bl GrabMashOutThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction b GrabMashOutThink_Exit ################################### ## Grab Mash Out THINK FUNCT ## ################################### GrabMashOutThink: blrl #Registers .set REG_EventConstants,25 .set REG_MenuData,26 .set REG_EventData,31 .set REG_P1Data,27 .set REG_P1GObj,28 .set REG_P2Data,29 .set REG_P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_ThrowDelay,0x0 .set EventState_MashOutThink,0x1 .set EventState_Reset,0x2 .set Timer,0x1 .set ThrowTimer,0x2 .set GrabBreakout,0x4 #Constants .set ResetTimer,80 .set PercentLo,0 .set PercentHi,80 .set ThrowTimerLo,40 .set ThrowTimerHi,100 backup #INIT FUNCTION VARIABLES lwz REG_EventData,0x2c(r3) #backup data pointer in r31 #Get Player Pointers bl GetAllPlayerPointers mr REG_P1GObj,r3 mr REG_P1Data,r4 mr REG_P2GObj,r5 mr REG_P2Data,r6 #Get Menu and Constants Pointers lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData) bl GrabMashOutThink_Constants mflr REG_EventConstants bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq GrabMashOutThink_Start #Init Positions mr r3,REG_P1GObj mr r4,REG_P2GObj mr r5,REG_EventData bl GrabMashOut_InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save GrabMashOutThink_Start: #Reset if anyone died bl IsAnyoneDead cmpwi r3,0 bne GrabMashOutThink_Restore GrabMashOutThink_SwitchCase: #Switch Case lbz r3,EventState(REG_EventData) cmpwi r3,EventState_ThrowDelay beq GrabMashOutThink_ThrowDelay cmpwi r3,EventState_MashOutThink beq GrabMashOutThink_MashOutThink cmpwi r3,EventState_Reset beq GrabMashOutThink_Reset b GrabMashOutThink_CheckTimer #region GrabMashOutThink_ThrowDelay GrabMashOutThink_ThrowDelay: #Check to grab lhz r3,ThrowTimer(REG_EventData) subi r3,r3,1 sth r3,ThrowTimer(REG_EventData) cmpwi r3,0 bne GrabMashOutThink_ThrowDelay_TimerSkip #Input grab li r3,PAD_BUTTON_A | PAD_TRIGGER_R stw r3,CPU_HeldButtons(REG_P2Data) GrabMashOutThink_ThrowDelay_TimerSkip: #Check if P1 was grabbed lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_CaptureWaitLw beq GrabMashOutThink_ThrowDelay_Grabbed cmpwi r3,ASID_CaptureWaitHi beq GrabMashOutThink_ThrowDelay_Grabbed #If just grabbed, skip cmpwi r3,ASID_CapturePulledLw beq GrabMashOutThink_CheckTimer cmpwi r3,ASID_CapturePulledHi beq GrabMashOutThink_CheckTimer #Check if P1 acted early cmpwi r3,ASID_Wait bne GrabMashOutThink_ThrowDelay_ActedEarly b GrabMashOutThink_CheckTimer GrabMashOutThink_ThrowDelay_Grabbed: #Get breakout timer lfs f1,0x2354(REG_P1Data) stfs f1,GrabBreakout(REG_EventData) #Change state to attack li r3,EventState_MashOutThink stb r3,EventState(EventData) b GrabMashOutThink_CheckTimer GrabMashOutThink_ThrowDelay_ActedEarly: #Play Error Noise li r3,0xAF bl PlaySFX #Set Timer li r3,ResetTimer-40 stb r3,Timer(REG_EventData) #Change state to reset li r3,EventState_Reset stb r3,EventState(EventData) b GrabMashOutThink_CheckTimer #endregion #region GrabMashOutThink_MashOutThink GrabMashOutThink_MashOutThink: #Wait for P1 to be in CaptureCut lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_CaptureJump beq GrabMashOutThink_BrokeOut cmpwi r3,ASID_CaptureCut beq GrabMashOutThink_BrokeOut b GrabMashOutThink_CheckTimer GrabMashOutThink_BrokeOut: #Set reset timer li r3,ResetTimer stb r3,Timer(REG_EventData) #Advance State li r3,EventState_Reset stb r3,EventState(REG_EventData) b GrabMashOutThink_CheckTimer #endregion #region GrabMashOutThink_Reset GrabMashOutThink_Reset: b GrabMashOutThink_CheckTimer #endregion GrabMashOutThink_CheckTimer: #Check if timer exists lbz r3,Timer(REG_EventData) cmpwi r3,0 ble GrabMashOutThink_Exit #Decrement timer subi r3,r3,1 stb r3,Timer(REG_EventData) cmpwi r3,0 bgt GrabMashOutThink_Exit GrabMashOutThink_Restore: #Restore State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Load #Init Positions Again mr r3,REG_P1GObj mr r4,REG_P2GObj mr r5,REG_EventData bl GrabMashOut_InitializePositions GrabMashOutThink_Exit: restore blr ################################ GrabMashOutThink_Constants: blrl .set P1X,0x0 .set P1Y,0x4 .set P2X,0x8 .set P2Y,0xC .float -8 #p1 x .float 0 #p1 y .float 8 #p2 x .float 0 #p2 y ########################################### GrabMashOut_TopText: blrl .string "Escaped Grab" .align 2 GrabMashOut_BottomText: blrl .string "Frame %d/%d" .align 2 ########################################### GrabMashOut_InitializePositions: backup .set REG_FacingDirection,31 #1 = p1 facing right, -1 = p1 facing left .set REG_P1GObj,30 .set REG_P1Data,29 .set REG_P2GObj,28 .set REG_P2Data,27 .set REG_EventData,26 #Init Registers mr REG_P1GObj,r3 lwz REG_P1Data,0x2C(REG_P1GObj) mr REG_P2GObj,r4 lwz REG_P2Data,0x2C(REG_P2GObj) mr REG_EventData,r5 GrabMashOut_InitializePositions_DetermineFacingDirection: #Determine Facing Direction li REG_FacingDirection,1 li r3,2 branchl r12,HSD_Randi cmpwi r3,0 beq GrabMashOut_InitializePositions_DetermineFacingDirection_End li REG_FacingDirection,-1 GrabMashOut_InitializePositions_DetermineFacingDirection_End: #Apply Facing Directions mr r3,REG_FacingDirection bl IntToFloat stfs f1,0x2C(REG_P1Data) mulli r3,REG_FacingDirection,-1 bl IntToFloat stfs f1,0x2C(REG_P2Data) #Get Starting Coordinates lfs f1,P1X(REG_EventConstants) lfs f2,P1Y(REG_EventConstants) cmpwi REG_FacingDirection,0 blt GrabMashOut_InitializePositions_P1FacingLeft stfs f1,0xB0(REG_P1Data) stfs f2,0xB4(REG_P1Data) b GrabMashOut_InitializePositions_RightPosition GrabMashOut_InitializePositions_P1FacingLeft: stfs f1,0xB0(REG_P2Data) stfs f2,0xB4(REG_P2Data) GrabMashOut_InitializePositions_RightPosition: lfs f1,P2X(REG_EventConstants) lfs f2,P2Y(REG_EventConstants) cmpwi REG_FacingDirection,0 blt GrabMashOut_InitializePositions_P2FacingRight stfs f1,0xB0(REG_P2Data) stfs f2,0xB4(REG_P2Data) b GrabMashOut_InitializePositions_FacingEnd GrabMashOut_InitializePositions_P2FacingRight: stfs f1,0xB0(REG_P1Data) stfs f2,0xB4(REG_P1Data) GrabMashOut_InitializePositions_FacingEnd: #Update Positions mr r3,REG_P1GObj bl PlacePlayerOnGround mr r3,REG_P1GObj bl UpdateCameraBox mr r3,REG_P2GObj bl PlacePlayerOnGround mr r3,REG_P2GObj bl UpdateCameraBox #Enter P1 Into Wait mr r3,REG_P1GObj branchl r12,AS_Wait #Enter P2 Into Wait mr r3,REG_P2GObj branchl r12,AS_Wait #Random percent li r3,PercentHi-PercentLo branchl r12,HSD_Randi addi r4,r3,PercentLo lbz r3,0xC(REG_P1Data) branchl r12,PlayerBlock_SetDamage #Reset Variables li r3,EventState_ThrowDelay stb r3,EventState(REG_EventData) li r3,0 stb r3,Timer(REG_EventData) #Init Throw Timer li r3,ThrowTimerHi-ThrowTimerLo branchl r12,HSD_Randi addi r3,r3,ThrowTimerLo sth r3,ThrowTimer(REG_EventData) GrabMashOut_InitializePositions_Exit: restore blr #endregion #region SDI IC DThrow Dair ######################### ## Event 16 HIJACK INFO ## ######################### Event16: #STORE STAGE li r3,0x20 sth r3,0xE(r26) li r5,0xE #Ice Climbers #STORE CPU bl P2Struct mflr r3 lwz r4,0x0(r29) stw r3,0x18(r4) #p2 pointer stb r5,0x0(r3) #make top tier p2 li r5,0x1 #make CPU controlled stb r5,0x1(r3) #SPAWN 2 PLAYERS li r3,0x40 stb r3,0x1(r4) #STORE THINK FUNCTION bl Event16Load mflr r3 stw r3,0x44(r26) #on match load b exit ######################### ## Event 16 LOAD FUNCT ## ######################### Event16Load: blrl backup #Schedule Think bl Event16Think mflr r3 li r4,3 li r5,0 bl CreateEventThinkFunction b Event16LoadExit ########################## ## Event 16 THINK FUNCT ## ########################## Event16Think: blrl .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 li r3,0xF stw r3,0x1A94(r29) bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq Event16ThinkMain #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) #Set Facing Directions lis r3,0x3f80 stw r3,0x2C(r29) lis r3,0xBf80 stw r3,0x2C(r27) #Initlize Positions bl Event16_Floats mflr r3 bl Event_EnterGrab #Clear Inputs bl RemoveFirstFrameInputs #Store Ground As Last Known Position lfs f1, 0x00B4 (r29) stfs f1, 0x0834 (r29) #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save Event16ThinkMain: Event16ThinkExit: restore blr ################################################# Event16_Floats: blrl .long 0x4144CCCD #P1 X Position .long 0x00000000 #P1 Y Position .long 0xC02CCCCD #P2 X Position .long 0x00000000 #P2 Y Position ################################################# Event16LoadExit: restore blr ################################################## #endregion ############## ## Fox Tech ## ############## #region Ledgetech Counter ################################### ## Ledgetech Counter HIJACK INFO ## ################################### LedgetechCounter: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Marth.Ext #Use marth li r6,-1 #Use chosen Stage load r7,EventOSD_LedgetechCounter li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION LedgetechCounterStoreThink: bl LedgetechCounterLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## Ledgetech Counter LOAD FUNCT ## ################################## LedgetechCounterLoad: blrl backup #Schedule Think bl LedgetechCounterThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction b LedgetechCounterThink_Exit ################################### ## Ledgetech Counter THINK FUNCT ## ################################### LedgetechCounterThink: blrl #Registers .set EventConstants,25 .set MenuData,26 .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_OnRebirthPlat,0x0 .set EventState_Recovering,0x1 .set MarthState,0x1 .set MarthState_Wait,0x0 .set MarthState_Attacked,0x1 .set Timer,0x2 backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 lwz MenuData,EventData_MenuDataPointer(EventData) bl LedgetechCounter_Constants mflr EventConstants bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq LedgetechCounterThink_Start #Random Side of Stage li r3,2 branchl r12,HSD_Randi bl Ledgetech_InitializePositions #Move Marth forward a bit lfs f1,0x2C(P2Data) lfs f2,0x4(EventConstants) fmuls f1,f1,f2 lfs f2,0xB0(P2Data) fadds f1,f1,f2 stfs f1,0xB0(P2Data) #Move Falco down a bit lfs f1,0x8(EventConstants) lfs f2,0xB4(P1Data) fadds f1,f1,f2 stfs f1,0xB4(P1Data) #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Init Score Count lhz r3,-0x4ea8(r13) branchl r12,HUD_KOCounter_UpdateKOs LedgetechCounterThink_Start: #Reset if anyone died bl IsAnyoneDead cmpwi r3,0 bne LedgetechCounterThink_Restore #Switch case for state of event lbz r3,EventState(EventData) cmpwi r3,EventState_OnRebirthPlat beq LedgetechCounterThink_OnRebirthPlat cmpwi r3,EventState_Recovering beq LedgetechCounterThink_Recovering b LedgetechCounterThink_CheckForTimer ########################################### LedgetechCounterThink_OnRebirthPlat: #Check if exited RebirthWait lwz r3,0x10(P1Data) cmpwi r3,ASID_RebirthWait beq LedgetechCounterThink_OnRebirthPlat_ExtendTimer #Change Event State li r3,EventState_Recovering stb r3,EventState(EventData) b LedgetechCounterThink_CheckForTimer LedgetechCounterThink_OnRebirthPlat_ExtendTimer: #Extend RebithWait Timer li r3,2 stw r3,0x2340(P1Data) b LedgetechCounterThink_CheckForTimer ########################################### ########################################### LedgetechCounterThink_Recovering: #Check if marth acted already lbz r3,MarthState(EventData) cmpwi r3,MarthState_Wait bne LedgetechCounterThink_CheckForTimer #Check P1s Distance from Marth addi r3,P1Data,0xB0 addi r4,P2Data,0xB0 bl GetDistance lfs f2,0x0(EventConstants) fcmpo cr0,f1,f2 bgt LedgetechCounterThink_CheckForTimer #P1 is in range, use down B li r3,0x200 stw r3,CPU_HeldButtons(P2Data) li r3,-127 stb r3,CPU_AnalogY(P2Data) #Set as attacking li r3,MarthState_Attacked stb r3,MarthState(EventData) #Start Timer li r3,70 stb r3,Timer(EventData) b LedgetechCounterThink_CheckForTimer ############################################ LedgetechCounterThink_CheckForTimer: #Check Timer lbz r3,Timer(EventData) cmpwi r3,0 beq LedgetechCounterThink_Exit #Decrement subi r3,r3,1 stb r3,Timer(EventData) cmpwi r3,0 bne LedgetechCounterThink_Exit LedgetechCounterThink_Restore: #Load State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Random Side of Stage li r3,2 branchl r12,HSD_Randi bl Ledgetech_InitializePositions #Move Marth forward a bit lfs f1,0x2C(P2Data) lfs f2,0x4(EventConstants) fmuls f1,f1,f2 lfs f2,0xB0(P2Data) fadds f1,f1,f2 stfs f1,0xB0(P2Data) #Move Falco down a bit lfs f1,0x8(EventConstants) lfs f2,0xB4(P1Data) fadds f1,f1,f2 stfs f1,0xB4(P1Data) #Reset Variables li r3,EventState_OnRebirthPlat stb r3,EventState(EventData) li r3,MarthState_Wait stb r3,MarthState(EventData) li r3,0 stb r3,Timer(EventData) LedgetechCounterThink_Exit: restore blr ###### LedgetechCounter_Constants: blrl .float 33 #Mm away from fox to init counter .float 5 #Mm to move marth forward after placing on ledge .float -15 #Mm to move spacies down after placing in the air ###### #endregion #region Armada Shine ################################### ## Armada Shine HIJACK INFO ## ################################### ArmadaShine: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Fox.Ext #Use fox li r6,-1 #Use chosen Stage load r7,EventOSD_ArmadaShine li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION ArmadaShineStoreThink: bl ArmadaShineLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## Armada Shine LOAD FUNCT ## ################################## ArmadaShineLoad: blrl backup #Schedule Think bl ArmadaShineThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction #Remove randall lwz r3,StageID_External(r13) cmpwi r3,YoshiStory bne LedgedashLoad_SkipRemoveRandall #Get randall's map_gobj li r3,2 #randalls map_gobj is 2 branchl r12,Stage_map_gobj_Load branchl r12,Stage_Destroy_map_gobj b ArmadaShineThink_Exit ################################### ## Armada Shine THINK FUNCT ## ################################### ArmadaShineThink: blrl #Registers .set REG_EventConstants,25 .set REG_MenuData,26 .set REG_EventData,31 .set REG_P1Data,27 .set REG_P1GObj,28 .set REG_P2Data,29 .set REG_P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_Hitstun,0x0 .set EventState_Falling,0x1 .set EventState_RecoverStart,0x2 .set EventState_RecoverEnd,0x3 .set EventState_Reset,0x4 .set Timer,0x1 #Constants .set ResetTimer,80 .set QuickResetTimer,30 .set PercentLo,0 .set PercentHi,60 backup #INIT FUNCTION VARIABLES lwz REG_EventData,0x2c(r3) #backup data pointer in r31 #Get Player Pointers bl GetAllPlayerPointers mr REG_P1GObj,r3 mr REG_P1Data,r4 mr REG_P2GObj,r5 mr REG_P2Data,r6 #Get Menu and Constants Pointers lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData) bl ArmadaShineThink_Constants mflr REG_EventConstants bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq ArmadaShineThink_Start #Init Positions mr r3,REG_P1GObj mr r4,REG_P2GObj bl ArmadaShine_InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Init State li r3,EventState_Hitstun stb r3,EventState(REG_EventData) ArmadaShineThink_Start: #Reset if anyone died bl IsAnyoneDead cmpwi r3,0 bne ArmadaShineThink_Restore #DPad left to instant reset lbz r3, 0x0618 (REG_P1Data) bl GetInputStruct lwz r4,InputStruct_InstantButtons(r3) rlwinm. r0,r4,0,31,31 bne ArmadaShineThink_Restore ArmadaShineThink_GroundCheck: #If P2 is grounded, reset quick lwz r3,0xE0(REG_P2Data) cmpwi r3,0 beq ArmadaShineThink_GroundCheck_OnGround #If P2 is grabbing a cliff, reset quick lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_CliffCatch beq ArmadaShineThink_GroundCheck_OnGround b ArmadaShineThink_GroundCheckSkip ArmadaShineThink_GroundCheck_OnGround: #Check if timer was set lbz r3,Timer(REG_EventData) cmpwi r3,QuickResetTimer ble ArmadaShineThink_GroundCheckSkip #Set timer li r3,QuickResetTimer stb r3,Timer(REG_EventData) #Change State li r3,EventState_Reset stb r3,EventState(REG_EventData) ArmadaShineThink_GroundCheckSkip: #Switch Case lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Hitstun beq ArmadaShineThink_Hitstun cmpwi r3,EventState_Falling beq ArmadaShineThink_Falling cmpwi r3,EventState_RecoverStart beq ArmadaShineThink_RecoverStart cmpwi r3,EventState_RecoverEnd beq ArmadaShineThink_RecoverEnd cmpwi r3,EventState_Reset beq ArmadaShineThink_Reset b ArmadaShineThink_Exit #region ArmadaShineThink_Hitstun ArmadaShineThink_Hitstun: #Check if still in hitstun lbz r3,0x221C(REG_P2Data) rlwinm. r3,r3,0,30,30 bne ArmadaShineThink_Hitstun_Exit #Change Event State li r3,EventState_Falling stb r3,EventState(REG_EventData) #Run Next State Code b ArmadaShineThink_Falling ArmadaShineThink_Hitstun_Exit: #Always L-Cancel li r3,0 stb r3,0x67F(REG_P1Data) b ArmadaShineThink_Exit #endregion #region ArmadaShineThink_Falling ArmadaShineThink_Falling: .set FirefoxRadius,80 .set FirefoxChance,8 #Get distance from ledge addi r3,REG_P2Data,0xB0 addi r4,REG_P2Data,0x1ADC bl GetDistance stfs f1,0x80(sp) #Fox travels approx 82 Mm during firefox, so ensure he is at least this far li r3,FirefoxRadius bl IntToFloat lfs f2,0x80(sp) fcmpo cr0,f2,f1 bge ArmadaShineThink_Falling_EnterFirefox #Random chance to firefox li r3,FirefoxChance branchl r12,HSD_Randi cmpwi r3,0 beq ArmadaShineThink_Falling_EnterFirefox b ArmadaShineThink_Exit ArmadaShineThink_Falling_EnterFirefox: #Enter Firefox li r3,127 stb r3,CPU_AnalogY(REG_P2Data) li r3,PAD_BUTTON_B stw r3,CPU_HeldButtons(REG_P2Data) #Change Event State li r3,EventState_RecoverStart stb r3,EventState(REG_EventData) #Exit b ArmadaShineThink_Exit #endregion #region ArmadaShineThink_RecoverStart ArmadaShineThink_RecoverStart: .set RestartTimer,30 .set FirefoxHoldFrames,43 ArmadaShineThink_RecoverStart_CheckIfDone: #Check if no longer in SpecialHiStart lwz r3,0x10(REG_P2Data) cmpwi r3,354 beq ArmadaShineThink_RecoverStart_CheckIfDoneSkip #Start restart timer lwz r3,0x4(REG_P1Data) cmpwi r3,Fox.Int bne ArmadaShineThink_RecoverStart_NotFox li r3,RestartTimer b ArmadaShineThink_RecoverStart_StoreRestartTimer ArmadaShineThink_RecoverStart_NotFox: li r3,RestartTimer+60 ArmadaShineThink_RecoverStart_StoreRestartTimer: stb r3,Timer(REG_EventData) #Change Event State li r3,EventState_RecoverEnd stb r3,EventState(REG_EventData) #Run Next State Code b ArmadaShineThink_RecoverEnd ArmadaShineThink_RecoverStart_CheckIfDoneSkip: /* #Wait until last frame of firefox lhz r3,FramesinCurrentAS(REG_P2Data) cmpwi r3,FirefoxHoldFrames-2 beq ArmadaShineThink_RecoverStart_InputAngle #Input Up li r3,127 stb r3,CPU_AnalogY(REG_P2Data) b ArmadaShineThink_RecoverStart_Exit */ ArmadaShineThink_RecoverStart_InputAngle: #Backup f28-f31 stfs f29,0xB0(sp) stfs f30,0xB4(sp) stfs f31,0xB8(sp) stfs f28,0xBC(sp) stfs f27,0xC0(sp) #Hold towards ledge #Get Angle Between Fox and Ledge addi r3,REG_P2Data,0xB0 addi r4,REG_P2Data,0x1ADC bl GetAngleBetweenPoints #Convert this to an input .set REG_arctan,31 .set REG_XComp,30 .set REG_YComp,31 .set REG_127,29 #Backup arctan fmr REG_arctan,f1 #Get 127 as a float li r3,127 bl IntToFloat fmr REG_127,f1 #Get X Component fmr f1,REG_arctan #angle in radians branchl r12,cos fmr REG_XComp,f1 #Get Y Component fmr f1,REG_arctan #angle in radians branchl r12,sin fmr REG_YComp,f1 #Get X input fmuls f1,REG_XComp,REG_127 fctiwz f1,f1, stfd f1,0x80(sp) lwz r3,0x84(sp) stb r3,0x1A8C(REG_P2Data) #Get Y input fmuls f1,REG_YComp,REG_127 fctiwz f1,f1, stfd f1,0x80(sp) lwz r3,0x84(sp) stb r3,0x1A8D(REG_P2Data) #region ecb test code .set REG_XPerFrame,29 .set REG_YPerFrame,28 .set REG_CurrXPos,27 .set REG_CurrYPos,26 .set REG_ECBStruct,20 .set REG_ECBBoneStruct,21 .set REG_LoopCount,22 .set FirefoxFrames,30 .set RandomAngleRange,20 #Get Per Frame Velocity mr r3,REG_P2Data branchl r12,0x800a17e4 fmr REG_XComp,f1 mr r3,REG_P2Data branchl r12,0x800a1874 fmr REG_YComp,f1 #Get atan2 fmr f1,REG_YComp lfs f2,0x2C(REG_P2Data) fmuls f2,f2,REG_XComp branchl r12,0x80022c30 fmr REG_arctan,f1 #Get XComp fmr f1,REG_arctan branchl r12,0x80326240 fmr REG_XComp,f1 fmr f1,REG_arctan branchl r12,0x803263d4 fmr REG_YComp,f1 #Get Firefox distance per frame lwz r3, 0x02D4 (REG_P2Data) lfs f1, 0x0074 (r3) lfs f0, 0x002C (REG_P2Data) fmuls f1,f1,REG_XComp fmuls REG_XPerFrame,f1,f0 lfs f1, 0x0074 (r3) fmuls REG_YPerFrame,f1,REG_YComp #Create an ECB struct on the stack subi sp,sp,0x1d0 addi REG_ECBBoneStruct,sp,0xC addi REG_ECBStruct,sp,0x24 mr r3,REG_ECBStruct branchl r12,0x80041ee4 #Create ECB Bone struct /* 0x00 = ECB Current Top Y Offset scale * value 0x04 = ECB Current Bottom Y Offset neg(scale * vlaue) 0x08 = ECB Current Left X Offset neg(scale * vlaue) 0x0C = ECB Current Left Y Offset 0 0x10 = ECB Current Right X Offset scale * value 0x14 = ECB Current Right Y Offset 0 */ #Copy Struct mr r3,REG_ECBBoneStruct addi r4,REG_EventConstants,ECB_TopY li r5,0x18 branchl r12,memcpy #Place Current XY into struct lfs REG_CurrXPos,0xB0(REG_P2Data) lfs REG_CurrYPos,0xB4(REG_P2Data) #Subtract 0.4 to account for the frame of animation left in this state lfs f1,FinalAnimYDifference(REG_EventConstants) fsubs REG_CurrYPos,REG_CurrYPos,f1 lfs f1,0xB8(REG_P2Data) stfs f1,0x24(REG_ECBStruct) #Init Loop li REG_LoopCount,0 ArmadaShineThink_RecoverStart_CollisionLoop: #Store current position stfs REG_CurrXPos,0x1C(REG_ECBStruct) stfs REG_CurrYPos,0x20(REG_ECBStruct) #Check if frame X or greater lwz r5, 0x02D4 (REG_P2Data) lfs f1,0x70(r5) fctiwz f1,f1 stfd f1,-0x10(sp) lwz r3,-0x0C(sp) cmpw REG_LoopCount,r3 blt ArmadaShineThink_RecoverStart_CollisionLoop_SkipDecay ArmadaShineThink_RecoverStart_CollisionLoop_Decay: lfs f1,0x78(r5) fmuls f1,f1,REG_XComp lfs f2, 0x002C (REG_P2Data) fmuls f1,f1,f2 fsubs REG_XPerFrame,REG_XPerFrame,f1 lfs f1,0x78(r5) fmuls f1,f1,REG_YComp fsubs REG_YPerFrame,REG_YPerFrame,f1 ArmadaShineThink_RecoverStart_CollisionLoop_SkipDecay: #Store next position fadds f1,REG_CurrXPos,REG_XPerFrame stfs f1,0x4(REG_ECBStruct) fadds f1,REG_CurrYPos,REG_YPerFrame stfs f1,0x8(REG_ECBStruct) lfs f1,0x24(REG_ECBStruct) stfs f1,0xC(REG_ECBStruct) mr r3,REG_ECBStruct mr r4,REG_ECBBoneStruct branchl r12,0x8004730c lfs REG_CurrXPos,0x4(REG_ECBStruct) lfs REG_CurrYPos,0x8(REG_ECBStruct) #Inc Loop addi REG_LoopCount,REG_LoopCount,1 lwz r5, 0x02D4 (REG_P2Data) lfs f1, 0x0068 (r5) fctiwz f1,f1 stfd f1,-0x10(sp) lwz r3,-0x0C(sp) cmpw REG_LoopCount,r3 blt ArmadaShineThink_RecoverStart_CollisionLoop #End Loop addi sp,sp,0x1d0 #endregion #Restore f28-f31 lfs f29,0xB0(sp) lfs f30,0xB4(sp) lfs f31,0xB8(sp) lfs f28,0xBC(sp) lfs f27,0xC0(sp) ArmadaShineThink_RecoverStart_Exit: b ArmadaShineThink_Exit #endregion #region ArmadaShineThink_RecoverEnd ArmadaShineThink_RecoverEnd: #If CPU got hit, recover again lbz r3,0x221C(REG_P2Data) rlwinm. r3,r3,0,30,30 beq ArmadaShineThink_Reset #Enter Hitstun state li r3,EventState_Hitstun stb r3,EventState(REG_EventData) b ArmadaShineThink_Exit #endregion #region ArmadaShineThink_Reset ArmadaShineThink_Reset: #Get timer lbz r3,Timer(REG_EventData) subi r3,r3,1 stb r3,Timer(REG_EventData) cmpwi r3,0 ble ArmadaShineThink_Restore b ArmadaShineThink_Exit #endregion ArmadaShineThink_Restore: #Restore State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Load #Init Positions Again mr r3,REG_P1GObj mr r4,REG_P2GObj bl ArmadaShine_InitializePositions #Reset Variables li r3,0 stb r3,EventState(REG_EventData) stb r3,Timer(REG_EventData) ArmadaShineThink_Exit: restore blr ArmadaShineThink_Constants: blrl .set ECB_TopY,0x0 #scale * value .set ECB_BottomY,0x4 #neg(scale * vlaue) .set ECB_LeftX,0x8 #neg(scale * vlaue) .set ECB_LeftY,0xC #0 .set ECB_RightX,0x10 #scale * value .set ECB_RightY,0x14 #0 .set FinalAnimYDifference,0x18 .float 9 .float 2.5 .float -3.3 .float 5.7 .float 3.3 .float 5.7 .float 0.4 ArmadaShine_InitializePositions: backup .set LedgeSide,20 #Constants .set ArmadaShine_P1X,15 .set ArmadaShine_P1Y,6 .set ArmadaShine_P2X,12 .set ArmadaShine_P2Y,6 .set HitlagFrames,12 #Get random side li r3,2 branchl r12,HSD_Randi #Backup Ledge Side mr LedgeSide,r3 #Change Facing Directions cmpwi LedgeSide,0x0 beq ArmadaShine_InitializePositions_GetLeftLedgeID ArmadaShine_InitializePositions_GetRightLedgeID: #Change Facing Direction li r3,-1 bl IntToFloat stfs f1,0x2C(REG_P1Data) li r3,-1 bl IntToFloat stfs f1,0x2C(REG_P2Data) b ArmadaShine_InitializePositions_DirectionChangeEnd ArmadaShine_InitializePositions_GetLeftLedgeID: #Change Facing Direction li r3,1 bl IntToFloat stfs f1,0x2C(REG_P1Data) li r3,1 bl IntToFloat stfs f1,0x2C(REG_P2Data) ArmadaShine_InitializePositions_DirectionChangeEnd: #Get Ledge Coordinates mr r3,LedgeSide addi r4,sp,0x80 bl GetLedgeCoordinates #Move P1 li r3,ArmadaShine_P1X bl IntToFloat lfs f2,0x80(sp) lfs f3,0x2C(REG_P1Data) fmadds f1,f1,f3,f2 stfs f1,0xB0(REG_P1Data) li r3,ArmadaShine_P1Y bl IntToFloat lfs f2,0x84(sp) fadds f1,f1,f2 stfs f1,0xB4(REG_P1Data) mr r3,REG_P1GObj bl UpdatePosition #Move P2 li r3,ArmadaShine_P2X bl IntToFloat lfs f2,0x80(sp) lfs f3,0x2C(REG_P2Data) fmadds f1,f1,f3,f2 stfs f1,0xB0(REG_P2Data) li r3,ArmadaShine_P2Y bl IntToFloat lfs f2,0x84(sp) fadds f1,f1,f2 stfs f1,0xB4(REG_P2Data) mr r3,REG_P2GObj bl UpdatePosition #P1 enters Bair mr r3,REG_P1GObj li r4,ASID_AttackAirB branchl r12,0x8008cfac #Fastforward to frame 7 li r3,7 bl IntToFloat mr r3,REG_P1GObj lfs f2, -0x67D8 (rtoc) lfs f3, -0x67E4 (rtoc) branchl r12,0x8006ebe8 li r3,7 bl IntToFloat stfs f1,0x894(REG_P1Data) li r3,0 stw r3,0x3E4(REG_P1Data) mr r3,REG_P1GObj branchl r12,0x80073354 #Update Animation mr r3,REG_P1GObj branchl r12,0x8006e9b4 #Remove all hitboxes mr r3,REG_P1GObj branchl r12,0x8007aff8 #Stop subaction script from being updated li r3,0 stw r3,0x3EC(REG_P1Data) #Update Camera mr r3,REG_P1GObj bl UpdateCameraBox #P2 enters DamageFlyN mr r3,REG_P2GObj li r4,ASID_DamageFlyN li r5,0x40 li r6,0 lfs f1, -0x750C (rtoc) lfs f2, -0x7508 (rtoc) lfs f3, -0x750C (rtoc) branchl r12,ActionStateChange #Update Animation mr r3,REG_P2GObj branchl r12,0x8006e9b4 #Remove Jump lwz r3,0x168(REG_P2Data) stb r3,0x1968(REG_P2Data) #Update Camera mr r3,REG_P2GObj bl UpdateCameraBox .set AngleLo,45 .set AngleHi,60 .set MagLo,106 .set MagHi,120 #Enter into knockback mr r3,REG_P2GObj li r4,AngleLo li r5,AngleHi li r6,MagLo li r7,MagHi bl EnterKnockback #Give 7 Frames of Hitlag to Each li r3,HitlagFrames bl IntToFloat stfs f1,0x195C(REG_P1Data) lbz r0,0x221A(REG_P1Data) li r3,1 rlwimi r0,r3,5,26,26 stb r0,0x221A(REG_P1Data) lbz r0,0x2219(REG_P1Data) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(REG_P1Data) li r3,HitlagFrames bl IntToFloat stfs f1,0x195C(REG_P2Data) lbz r0,0x221A(REG_P2Data) li r3,1 rlwimi r0,r3,5,26,26 stb r0,0x221A(REG_P2Data) lbz r0,0x2219(REG_P2Data) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(REG_P2Data) #Random percent li r3,PercentHi-PercentLo branchl r12,HSD_Randi addi r4,r3,PercentLo lbz r3,0xC(REG_P2Data) branchl r12,PlayerBlock_SetDamage ArmadaShine_InitializePositions_Exit: restore blr #endregion #region SideB Sweetspot ########################### ## SideB Sweetspot HIJACK INFO ## ########################### SideBSweetspot: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Marth.Ext li r6,-1 #Use chosen Stage load r7,EventOSD_SideBSweetspot li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION SideBSweetspotStoreThink: bl SideBSweetspotLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## SideB Sweetspot LOAD FUNCT ## ################################## SideBSweetspotLoad: blrl backup #Schedule Think bl SideBSweetspotThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction b SideBSweetspotThink_Exit ################################### ## SideB Sweetspot THINK FUNCT ## ################################### SideBSweetspotThink: blrl #Registers .set REG_EventConstants,25 .set REG_MenuData,26 .set REG_EventData,31 .set REG_P1Data,27 .set REG_P1GObj,28 .set REG_P2Data,29 .set REG_P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_Endlag,0x0 .set EventState_WaitToAttack,0x1 .set EventState_AttackThink,0x2 .set EventState_Reset,0x3 .set Timer,0x1 .set ThrowTimer,0x2 .set JabFrame,0x4 #Constants .set ResetTimer,30 .set AngleLo,45 .set AngleHi,60 .set MagLo,106#106 .set MagHi,135#120 .set PercentHi,100 .set PercentLo,50 backup #INIT FUNCTION VARIABLES lwz REG_EventData,0x2c(r3) #backup data pointer in r31 #Get Player Pointers bl GetAllPlayerPointers mr REG_P1GObj,r3 mr REG_P1Data,r4 mr REG_P2GObj,r5 mr REG_P2Data,r6 #Get Menu and Constants Pointers lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData) bl SideBSweetspotThink_Constants mflr REG_EventConstants bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq SideBSweetspotThink_Start #Init Positions mr r3,REG_P1GObj mr r4,REG_P2GObj mr r5,REG_EventData bl SideBSweetspot_InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save SideBSweetspotThink_Start: #P2 intangible mr r3,P2GObj li r4,1 branchl r12,ApplyIntangibility #Reset if anyone died bl IsAnyoneDead cmpwi r3,0 bne SideBSweetspotThink_Restore SideBSweetspotThink_Crouch: #Always hold crouch when state is higher than EventState_Endlag lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Endlag ble SideBSweetspotThink_CrouchSkip #Input crouch li r3,-127 stb r3,CPU_AnalogY(REG_P2Data) SideBSweetspotThink_CrouchSkip: SideBSweetspotThink_SwitchCase: #Switch Case lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Endlag beq SideBSweetspotThink_Endlag cmpwi r3,EventState_WaitToAttack beq SideBSweetspotThink_WaitToAttack cmpwi r3,EventState_AttackThink beq SideBSweetspotThink_AttackThink cmpwi r3,EventState_Reset beq SideBSweetspotThink_Reset b SideBSweetspotThink_CheckTimer #region SideBSweetspotThink_Endlag SideBSweetspotThink_Endlag: #Check if in Wait lwz r3,0x10(P2Data) cmpwi r3,ASID_Wait bne SideBSweetspotThink_CheckTimer #Input Crouch li r3,-127 stb r3,CPU_AnalogY(REG_P2Data) #Change state to attack li r3,EventState_WaitToAttack stb r3,EventState(EventData) b SideBSweetspotThink_CheckTimer #endregion #region SideBSweetspotThink_WaitToAttack SideBSweetspotThink_WaitToAttack: #Wait for Fox to be in SpecialAirS lwz r3,0x10(REG_P1Data) cmpwi r3,0x15F bne SideBSweetspotThink_WaitToAttackSkip #Input Dtilt li r3,PAD_BUTTON_A stw r3,CPU_HeldButtons(REG_P2Data) li r3,-38 stb r3,CPU_AnalogY(REG_P2Data) #Advance State li r3,EventState_AttackThink stb r3,EventState(REG_EventData) b SideBSweetspotThink_CheckTimer SideBSweetspotThink_WaitToAttackSkip: #Check if fox up-b'd cmpwi r3,0x162 beq SideBSweetspotThink_WaitToAttack_BlacklistMove cmpwi r3,ASID_EscapeAir beq SideBSweetspotThink_WaitToAttack_BlacklistMove b SideBSweetspotThink_WaitToAttack_CheckForBlacklistMovesSkip SideBSweetspotThink_WaitToAttack_BlacklistMove: #PLay Error SFX li r3,0xAF bl PlaySFX #Start Timer li r3,ResetTimer stb r3,Timer(REG_EventData) #Advance State li r3,EventState_Reset stb r3,EventState(REG_EventData) b SideBSweetspotThink_CheckTimer SideBSweetspotThink_WaitToAttack_CheckForBlacklistMovesSkip: #endregion #region SideBSweetspotThink_AttackThink SideBSweetspotThink_AttackThink: #Check if d-tilting lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_AttackLw3 bne SideBSweetspotThink_CheckTimer #Check if frame 7 li r3,7 bl IntToFloat lfs f2,0x894(REG_P2Data) fcmpo cr0,f1,f2 bne SideBSweetspotThink_AttackThink_FreezeSkip #Check if already frozen li r3,0 bl IntToFloat lfs f2,0x89C(REG_P2Data) fcmpo cr0,f1,f2 beq SideBSweetspotThink_AttackThink_FreezeCheckToUnfreeze #Freeze mr r3,REG_P2GObj branchl r12,FrameSpeedChange b SideBSweetspotThink_AttackThink_FreezeSkip SideBSweetspotThink_AttackThink_FreezeCheckToUnfreeze: #Check if player was hit lwz r3,0x2094(REG_P2Data) cmpwi r3,0 beq SideBSweetspotThink_AttackThink_FreezeSkip #Unfreeze li r3,1 bl IntToFloat mr r3,REG_P2GObj branchl r12,FrameSpeedChange #Start Timer li r3,ResetTimer stb r3,Timer(REG_EventData) #Advance State li r3,EventState_Reset stb r3,EventState(REG_EventData) b SideBSweetspotThink_CheckTimer SideBSweetspotThink_AttackThink_FreezeSkip: #Check if P1 grabbed ledge successfully lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_CliffCatch bne SideBSweetspotThink_AttackThink_CliffCatchSkip #Play Success SFX li r3,0xAD bl PlaySFX #Unfreeze P2 li r3,1 bl IntToFloat mr r3,REG_P2GObj branchl r12,FrameSpeedChange #Start Timer li r3,ResetTimer+30 stb r3,Timer(REG_EventData) #Advance State li r3,EventState_Reset stb r3,EventState(REG_EventData) b SideBSweetspotThink_CheckTimer SideBSweetspotThink_AttackThink_CliffCatchSkip: #endregion #region SideBSweetspotThink_Reset SideBSweetspotThink_Reset: b SideBSweetspotThink_CheckTimer #endregion SideBSweetspotThink_CheckTimer: #Check if timer exists lbz r3,Timer(REG_EventData) cmpwi r3,0 ble SideBSweetspotThink_Exit #Decrement timer subi r3,r3,1 stb r3,Timer(REG_EventData) cmpwi r3,0 bgt SideBSweetspotThink_Exit SideBSweetspotThink_Restore: #Restore State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Load #Init Positions Again mr r3,REG_P1GObj mr r4,REG_P2GObj mr r5,REG_EventData bl SideBSweetspot_InitializePositions SideBSweetspotThink_Exit: restore blr ################################ SideBSweetspotThink_Constants: blrl .set P1X,0x0 .set P1Y,0x4 .set P2X,0x8 .set P2Y,0xC .set GrabDistance,0x10 .set HoldShieldVelocity,0x14 .set RunDistance,0x18 .float -8 #p1 x .float 0 #p1 y .float 8 #p2 x .float 0 #p2 y .float 14 #16 .float 1.1 .float 23 ########################################### SideBSweetspot_InitializePositions: backup .set REG_P1GObj,30 .set REG_P1Data,29 .set REG_P2GObj,28 .set REG_P2Data,27 .set REG_EventData,26 .set LedgeSide,20 #Constants .set SideBSweet_P1X,-12 .set SideBSweet_P1Y,6 .set SideBSweet_P2X,15 .set SideBSweet_P2Y,0 .set HitlagFrames,12 #Init Registers mr REG_P1GObj,r3 lwz REG_P1Data,0x2C(REG_P1GObj) mr REG_P2GObj,r4 lwz REG_P2Data,0x2C(REG_P2GObj) mr REG_EventData,r5 #Get random side li r3,2 branchl r12,HSD_Randi #Backup Ledge Side mr LedgeSide,r3 #Change Facing Directions cmpwi LedgeSide,0x0 beq SideBSweet_InitializePositions_GetLeftLedgeID SideBSweet_InitializePositions_GetRightLedgeID: #Change Facing Direction li r3,-1 bl IntToFloat stfs f1,0x2C(REG_P1Data) li r3,1 bl IntToFloat stfs f1,0x2C(REG_P2Data) b SideBSweet_InitializePositions_DirectionChangeEnd SideBSweet_InitializePositions_GetLeftLedgeID: #Change Facing Direction li r3,1 bl IntToFloat stfs f1,0x2C(REG_P1Data) li r3,-1 bl IntToFloat stfs f1,0x2C(REG_P2Data) SideBSweet_InitializePositions_DirectionChangeEnd: #Get Ledge Coordinates mr r3,LedgeSide addi r4,sp,0x80 bl GetLedgeCoordinates #Move P1 li r3,SideBSweet_P1X bl IntToFloat lfs f2,0x80(sp) lfs f3,0x2C(REG_P1Data) fmadds f1,f1,f3,f2 stfs f1,0xB0(REG_P1Data) li r3,SideBSweet_P1Y bl IntToFloat lfs f2,0x84(sp) fadds f1,f1,f2 stfs f1,0xB4(REG_P1Data) mr r3,REG_P1GObj bl UpdatePosition #Move P2 li r3,SideBSweet_P2X bl IntToFloat lfs f2,0x80(sp) lfs f3,0x2C(REG_P2Data) fneg f3,f3 fmadds f1,f1,f3,f2 stfs f1,0xB0(REG_P2Data) li r3,SideBSweet_P2Y bl IntToFloat lfs f2,0x84(sp) fadds f1,f1,f2 stfs f1,0xB4(REG_P2Data) mr r3,REG_P2GObj bl PlacePlayerOnGround #Clear P2's GFX Pointer li r3,0 stw r3,0x60C(REG_P2Data) #P2 enters FSmash li r3,0 bl IntToFloat mr r3,REG_P2GObj branchl r12,0x8008c3e0 #Fastforward to frame 11 li r3,11 bl IntToFloat mr r3,REG_P2GObj lfs f2, -0x67D8 (rtoc) lfs f3, -0x67E4 (rtoc) branchl r12,0x8006ebe8 li r3,7 bl IntToFloat stfs f1,0x894(REG_P2Data) li r3,0 stw r3,0x3E4(REG_P2Data) mr r3,REG_P2GObj branchl r12,0x80073354 #Update Animation mr r3,REG_P2GObj branchl r12,0x8006e9b4 #Remove all hitboxes mr r3,REG_P2GObj branchl r12,0x8007aff8 #Stop subaction script from being updated li r3,0 stw r3,0x3EC(REG_P2Data) #Update Camera mr r3,REG_P2GObj bl UpdateCameraBox #P1 enters DamageFlyN mr r3,REG_P1GObj li r4,ASID_DamageFlyN li r5,0x40 li r6,0 lfs f1, -0x750C (rtoc) lfs f2, -0x7508 (rtoc) lfs f3, -0x750C (rtoc) branchl r12,ActionStateChange #Update Animation mr r3,REG_P1GObj branchl r12,0x8006e9b4 #Remove Jump #lwz r3,0x168(REG_P1Data) #stb r3,0x1968(REG_P1Data) #Update Camera mr r3,REG_P1GObj bl UpdateCameraBox #Enter into knockback mr r3,REG_P1GObj li r4,AngleLo li r5,AngleHi li r6,MagLo li r7,MagHi bl EnterKnockback #Give 7 Frames of Hitlag to Each li r3,HitlagFrames bl IntToFloat stfs f1,0x195C(REG_P1Data) lbz r0,0x221A(REG_P1Data) li r3,1 rlwimi r0,r3,5,26,26 stb r0,0x221A(REG_P1Data) lbz r0,0x2219(REG_P1Data) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(REG_P1Data) li r3,HitlagFrames bl IntToFloat stfs f1,0x195C(REG_P2Data) lbz r0,0x221A(REG_P2Data) li r3,1 rlwimi r0,r3,5,26,26 stb r0,0x221A(REG_P2Data) lbz r0,0x2219(REG_P2Data) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(REG_P2Data) #Random percent li r3,PercentHi-PercentLo branchl r12,HSD_Randi addi r4,r3,PercentLo lbz r3,0xC(REG_P1Data) branchl r12,PlayerBlock_SetDamage #Reset Variables li r3,EventState_ThrowDelay stb r3,EventState(REG_EventData) li r3,0 stb r3,Timer(REG_EventData) SideBSweetspot_InitializePositions_Exit: restore blr #endregion #region Escape Sheik ########################### ## Escape Sheik HIJACK INFO ## ########################### EscapeSheik: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Sheik.Ext li r6,FinalDestination #Use chosen Stage load r7,EventOSD_EscapeSheik li r8,1 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION EscapeSheikStoreThink: bl EscapeSheikLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## Escape Sheik LOAD FUNCT ## ################################## EscapeSheikLoad: blrl backup #Schedule Think bl EscapeSheikThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction b EscapeSheikThink_Exit ################################### ## Escape Sheik THINK FUNCT ## ################################### EscapeSheikThink: blrl #Registers .set REG_EventConstants,25 .set REG_MenuData,26 .set REG_EventData,31 .set REG_P1Data,27 .set REG_P1GObj,28 .set REG_P2Data,29 .set REG_P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_ThrowDelay,0x0 .set EventState_ThrowEndlag,0x1 .set EventState_Chase,0x2 .set EventState_Jab2,0x3 .set EventState_Reset,0x4 .set Timer,0x1 .set ThrowTimer,0x2 .set JabFrame,0x4 .set isJabTwice,0x5 .set Jab2Frame,0x6 .set Jab2Timer,0x7 .set isDisplayedTiming,0x8 #Constants .set ResetTimer,40 .set PercentLo,0 .set PercentHi,40 .set ThrowTimerLo,30 .set ThrowTimerHi,60 .set ReactFrame,12 .set JabFrameLo,15 .set JabFrameHi,20 .set Jab2FrameLo,6 .set Jab2FrameHi,18 backup #INIT FUNCTION VARIABLES lwz REG_EventData,0x2c(r3) #backup data pointer in r31 #Get Player Pointers bl GetAllPlayerPointers mr REG_P1GObj,r3 mr REG_P1Data,r4 mr REG_P2GObj,r5 mr REG_P2Data,r6 #Get Menu and Constants Pointers lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData) bl EscapeSheikThink_Constants mflr REG_EventConstants bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq EscapeSheikThink_Start #Init Positions mr r3,REG_P1GObj mr r4,REG_P2GObj mr r5,REG_EventData bl EscapeSheik_InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save EscapeSheikThink_Start: #Reset if anyone died bl IsAnyoneDead cmpwi r3,0 bne EscapeSheikThink_Restore EscapeSheikThink_CheckIfFailed: #Check if failed the Escape Sheik (grabbed)) #EventState > EventState_Hitstun lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Chase blt EscapeSheikThink_CheckIfFailed_End #Check if grabbed lwz r3,0x10(P1Data) cmpwi r3,ASID_CapturePulledHi blt EscapeSheikThink_CheckIfFailed_End cmpwi r3,ASID_CaptureFoot bgt EscapeSheikThink_CheckIfFailed_End #Check if timer has started lbz r3,Timer(REG_EventData) cmpwi r3,0 bgt EscapeSheikThink_CheckIfFailed_End #Start Timer li r3,ResetTimer stb r3,Timer(REG_EventData) EscapeSheikThink_CheckIfFailed_End: EscapeSheikThink_CheckIfCPUDamaged: lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_DamageHi1 blt EscapeSheikThink_CheckIfCPUDamaged_End cmpwi r3,ASID_DamageFlyRoll bgt EscapeSheikThink_CheckIfCPUDamaged_End #Check if timer has started lbz r3,Timer(REG_EventData) cmpwi r3,0 bgt EscapeSheikThink_CheckIfCPUDamaged_End #Start Timer li r3,ResetTimer stb r3,Timer(REG_EventData) #Play Success Sound? #Maybe increment a high score or something idk EscapeSheikThink_CheckIfCPUDamaged_End: EscapeSheikThink_CheckForMistimedShine: #Check if event state is in chase lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Chase blt EscapeSheikThink_CheckForMistimedShine_End #Check if displayed already lbz r3,isDisplayedTiming(REG_EventData) cmpwi r3,0 bne EscapeSheikThink_CheckForMistimedShine_End #Get this frames inputs lbz r4, 0x0618 (REG_P1Data) bl GetInputStruct mr r5,r3 #Check B Button lwz r3,InputStruct_InstantButtons(r5) rlwinm. r0,r3,0,22,22 beq EscapeSheikThink_CheckForMistimedShine_End #Check if pushing down lbz r3,InputStruct_LeftAnalogY(r5) extsb r3,r3 cmpwi r3,-44 bgt EscapeSheikThink_CheckForMistimedShine_End #Check if in any missed tech state lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_Passive beq EscapeSheikThink_CheckForMistimedShine_Early cmpwi r3,ASID_PassiveStandB beq EscapeSheikThink_CheckForMistimedShine_Early cmpwi r3,ASID_PassiveStandF beq EscapeSheikThink_CheckForMistimedShine_Early #Check if being grabbed cmpwi r3,ASID_CapturePulledLw beq EscapeSheikThink_CheckForMistimedShine_Late cmpwi r3,ASID_CapturePulledHi beq EscapeSheikThink_CheckForMistimedShine_Late cmpwi r3,ASID_CaptureWaitLw beq EscapeSheikThink_CheckForMistimedShine_Late cmpwi r3,ASID_CaptureWaitHi beq EscapeSheikThink_CheckForMistimedShine_Late b EscapeSheikThink_CheckForMistimedShine_End .set REG_String,20 .set REG_Frames,21 EscapeSheikThink_CheckForMistimedShine_Early: #Get early string bl EscapeSheikThink_EarlyText mflr REG_String #Get frames early mr r3,REG_P1Data lwz r4,0x14(REG_P1Data) branchl r12,0x80085e50 lfs f1,0x8(r3) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) lhz r4,FramesinCurrentAS(REG_P1Data) sub REG_Frames,r3,r4 b EscapeSheikThink_CheckForMistimedShine_Display EscapeSheikThink_CheckForMistimedShine_Late: #Get late string bl EscapeSheikThink_LateText mflr REG_String #Get frames late EscapeSheikThink_CheckForMistimedShine_LateSearchInitLoop: .set REG_Count,22 li REG_Count,0 lhz REG_Frames,FramesinCurrentAS(REG_P1Data) EscapeSheikThink_CheckForMistimedShine_LateSearchLoop: #Get previous action state addi r3,REG_P1Data,PrevASStart mulli r4,REG_Count,0x2 add r5,r3,r4 #Check if wait lhz r3,0x0(r5) cmpwi r3,ASID_Wait beq EscapeSheikThink_CheckForMistimedShine_LateSearchFoundWait #Add frames spent in this state lhz r3,0xC(r5) add REG_Frames,REG_Frames,r3 EscapeSheikThink_CheckForMistimedShine_LateSearchIncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,6 blt EscapeSheikThink_CheckForMistimedShine_LateSearchLoop b EscapeSheikThink_CheckForMistimedShine_End EscapeSheikThink_CheckForMistimedShine_LateSearchFoundWait: EscapeSheikThink_CheckForMistimedShine_Display: #Output reaction time mr r3,REG_P1Data #p1 (no offsetting window) li r4,120 #text timeout li r5,0 #Area to Display (0-2) li r6,OSD.Miscellaneous #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr r22,r3 #backup text pointer #Create Text 1 mr r3,r22 #text pointer bl EscapeSheikThink_TopText mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,Text_InitializeSubtext #Create Text 2 mr r3,r22 #text pointer bl EscapeSheikThink_BottomText mflr r4 mr r5,REG_Frames mr r6,REG_String lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #default text X/Y branchl r12,Text_InitializeSubtext #Set as displayed li r3,1 stb r3,isDisplayedTiming(REG_EventData) EscapeSheikThink_CheckForMistimedShine_End: EscapeSheikThink_SwitchCase: #Switch Case lbz r3,EventState(REG_EventData) cmpwi r3,EventState_ThrowDelay beq EscapeSheikThink_ThrowDelay cmpwi r3,EventState_ThrowEndlag beq EscapeSheikThink_ThrowEndlag cmpwi r3,EventState_Chase beq EscapeSheikThink_Chase cmpwi r3,EventState_Reset beq EscapeSheikThink_Reset cmpwi r3,EventState_Jab2 beq EscapeSheikThink_Jab2 b EscapeSheikThink_CheckTimer #region EscapeSheikThink_ThrowDelay EscapeSheikThink_ThrowDelay: #Check to throw lhz r3,ThrowTimer(REG_EventData) subi r3,r3,1 sth r3,ThrowTimer(REG_EventData) cmpwi r3,0 bgt EscapeSheikThink_CheckTimer #Input DThrow li r3,-127 stb r3,CPU_AnalogY(REG_P2Data) #Change state to attack li r3,EventState_ThrowEndlag stb r3,EventState(EventData) b EscapeSheikThink_CheckTimer #endregion #region EscapeSheikThink_ThrowEndlag EscapeSheikThink_ThrowEndlag: #Wait for Sheik to be out of ThrowLw lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_Wait bne EscapeSheikThink_CheckTimer #Wait for P1 to be in their tech option lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_Passive blt EscapeSheikThink_ThrowEndlag_CheckMissTech cmpwi r3,ASID_PassiveStandB ble EscapeSheikThink_ThrowEndlag_End EscapeSheikThink_ThrowEndlag_CheckMissTech: cmpwi r3,ASID_DownBoundD beq EscapeSheikThink_ThrowEndlag_End cmpwi r3,ASID_DownBoundU beq EscapeSheikThink_ThrowEndlag_End b EscapeSheikThink_CheckTimer EscapeSheikThink_ThrowEndlag_End: #Advance State li r3,EventState_Chase stb r3,EventState(REG_EventData) b EscapeSheikThink_Chase #endregion #region EscapeSheikThink_Chase EscapeSheikThink_Chase: .set Distance,0xB0 .set REG_Direction,20 #Get Distance lfs f1,0xB0(REG_P2Data) lfs f2,0xB0(REG_P1Data) fsubs f1,f2,f1 lfs f2,0x2C(REG_P2Data) fmuls f1,f1,f2 stfs f1,Distance(sp) #Get Direction li r3,0 bl IntToFloat lfs f2,Distance(sp) fcmpo cr0,f2,f1 blt 0xC li REG_Direction,1 b 0x8 li REG_Direction,-1 #Determine Tech Option lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_DownBoundD beq EscapeSheikThink_Chase_DownBoundThink cmpwi r3,ASID_DownBoundU beq EscapeSheikThink_Chase_DownBoundThink #Now only run these when over frame 12 lhz r4,FramesinCurrentAS(REG_P1Data) cmpwi r4,ReactFrame blt EscapeSheikThink_CheckTimer cmpwi r3,ASID_Passive beq EscapeSheikThink_Chase_PassiveThink cmpwi r3,ASID_PassiveStandB beq EscapeSheikThink_Chase_PassiveStandThink cmpwi r3,ASID_PassiveStandF beq EscapeSheikThink_Chase_PassiveStandThink b EscapeSheikThink_CheckTimer EscapeSheikThink_Chase_PassiveThink: #Check if facing P1 cmpwi REG_Direction,0 bgt EscapeSheikThink_Chase_PassiveThink_FacingSkip #Input slightly towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,100 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_PassiveThink_FacingSkip: #Check distance (if over 16 units, walk towards) lfs f1,GrabDistance(REG_EventConstants) lfs f2,Distance(sp) fabs f2,f2 fcmpo cr0,f2,f1 ble EscapeSheikThink_Chase_PassiveThink_RunTowardsSkip #If over 24 units, run towards lfs f1,RunDistance(REG_EventConstants) fcmpo cr0,f2,f1 bgt EscapeSheikThink_Chase_PassiveThink_RunTowards EscapeSheikThink_Chase_PassiveThink_WalkTowards: #Walk Towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,100 stb r3,CPU_AnalogX(REG_P2Data) b EscapeSheikThink_Chase_PassiveThink_RunTowardsSkip EscapeSheikThink_Chase_PassiveThink_RunTowards: #Run Towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,127 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_PassiveThink_RunTowardsSkip: #Check distance lfs f1,GrabDistance(REG_EventConstants) lfs f2,Distance(sp) fabs f2,f2 fcmpo cr0,f2,f1 bgt EscapeSheikThink_Chase_PassiveThink_HoldShieldSkip #Check State lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_Dash beq EscapeSheikThink_Chase_PassiveThink_HoldShield cmpwi r3,ASID_Run beq EscapeSheikThink_Chase_PassiveThink_HoldShield b EscapeSheikThink_Chase_PassiveThink_HoldShieldSkip EscapeSheikThink_Chase_PassiveThink_HoldShield: #Enter shield mr r3,REG_P2GObj branchl r12,AS_Guard #And hold li r3,PAD_TRIGGER_R stw r3,CPU_HeldButtons(REG_P2Data) b EscapeSheikThink_Chase_PassiveThink_HoldShieldSkip EscapeSheikThink_Chase_PassiveThink_HoldShieldSkip: #Now grab when P1 is on frame 20 lhz r3,FramesinCurrentAS(REG_P1Data) cmpwi r3,20 blt EscapeSheikThink_CheckTimer #Enter grab mr r3,REG_P2GObj li r4,0xD4 branchl r12,AS_Catch #Advance state li r3,EventState_Reset stb r3,EventState(REG_EventData) #Start timer li r3,ResetTimer stb r3,Timer(REG_EventData) b EscapeSheikThink_CheckTimer EscapeSheikThink_Chase_PassiveStandThink: #Check if facing P1 cmpwi REG_Direction,0 bgt EscapeSheikThink_Chase_PassiveStandThink_FacingSkip #BUT is he coming to me? lfs f2,0xC8(REG_P1Data) li r3,0 bl IntToFloat li r3,1 #Moving Right fcmpo cr0,f2,f1 bgt 0x8 li r3,-1 #Moving Left lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r4,0x84(sp) mullw r4,r4,REG_Direction cmpw r3,r4 bne EscapeSheikThink_Chase_PassiveStandThink_FacingSkip #If under frame 20, run instead li r5,127 lhz r3,FramesinCurrentAS(REG_P1Data) cmpwi r3,20 blt 0x8 li r5,100 #Input slightly towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mullw r3,r3,r5 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_PassiveStandThink_FacingSkip: #Check distance (if over 16 units, run towards) lfs f1,GrabDistance(REG_EventConstants) lfs f2,Distance(sp) fabs f2,f2 fcmpo cr0,f2,f1 ble EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip #Wait until no longer turning lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_Turn bne EscapeSheikThink_Chase_PassiveStandThink_RunTowardCheckMovementDirection #If turning, wait til frame 2 to make a decision lhz r3,FramesinCurrentAS(REG_P2Data) cmpwi r3,2 bge EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip EscapeSheikThink_Chase_PassiveStandThink_RunTowardCheckMovementDirection: #BUT is he coming to me? lfs f2,0xC8(REG_P1Data) li r3,0 bl IntToFloat li r3,1 #Moving Right fcmpo cr0,f2,f1 bgt 0x8 li r3,-1 #Moving Left lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r4,0x84(sp) mullw r4,r4,REG_Direction cmpw r3,r4 bne EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip EscapeSheikThink_Chase_PassiveStandThink_RunTowards: #Run Towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,127 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip: #If and within range and running, hold shield #Check distance lfs f1,GrabDistance(REG_EventConstants) lfs f2,Distance(sp) fabs f2,f2 fcmpo cr0,f2,f1 bgt EscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_Dash beq EscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckFrame cmpwi r3,ASID_Run beq EscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckFrame b EscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip EscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckFrame: lhz r3,FramesinCurrentAS(REG_P1Data) cmpwi r3,28 bge EscapeSheikThink_Chase_PassiveStandThink_HoldShield EscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckVelocity: #Allow to hold shield earlier than usual if the character isnt moving very far lfs f1,0xC8(REG_P1Data) fabs f1,f1, lfs f2,HoldShieldVelocity(REG_EventConstants) fcmpo cr0,f1,f2 bgt EscapeSheikThink_Chase_PassiveStandThink_HoldShieldRunInstead EscapeSheikThink_Chase_PassiveStandThink_HoldShield: #Enter shield mr r3,REG_P2GObj branchl r12,AS_Guard #And hold li r3,PAD_TRIGGER_R stw r3,CPU_HeldButtons(REG_P2Data) b EscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip EscapeSheikThink_Chase_PassiveStandThink_HoldShieldRunInstead: #Run Towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,127 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip: #Now grab when P1 is on frame 34 lhz r3,FramesinCurrentAS(REG_P1Data) cmpwi r3,34 blt EscapeSheikThink_CheckTimer #Enter grab mr r3,REG_P2GObj li r4,0xD4 branchl r12,AS_Catch #Advance state li r3,EventState_Reset stb r3,EventState(REG_EventData) #Start timer li r3,ResetTimer stb r3,Timer(REG_EventData) b EscapeSheikThink_CheckTimer EscapeSheikThink_Chase_DownBoundThink: #Determine jab frame lbz r3,JabFrame(REG_EventData) cmpwi r3,0 bne EscapeSheikThink_Chase_DownBoundThink_JabFrameInitSkip #Init Jab Frame li r3,JabFrameHi-JabFrameLo branchl r12,HSD_Randi addi r3,r3,JabFrameLo stb r3,JabFrame(REG_EventData) #Get chance to jab again li r3,2 branchl r12,HSD_Randi stb r3,isJabTwice(REG_EventData) #Get frame to jab again li r3,Jab2FrameHi-Jab2FrameLo branchl r12,HSD_Randi addi r3,r3,Jab2FrameLo stb r3,Jab2Frame(REG_EventData) #Init Jab 2 Timer li r3,0 stb r3,Jab2Timer(REG_EventData) EscapeSheikThink_Chase_DownBoundThink_JabFrameInitSkip: #Check if facing P1 cmpwi REG_Direction,0 bgt EscapeSheikThink_Chase_DownBoundThink_FacingSkip #Input slightly towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,100 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_DownBoundThink_FacingSkip: #Check distance (if over 16 units, walk towards) lfs f1,GrabDistance(REG_EventConstants) lfs f2,Distance(sp) fabs f2,f2 fcmpo cr0,f2,f1 ble EscapeSheikThink_Chase_DownBoundThink_RunTowardsSkip EscapeSheikThink_Chase_DownBoundThink_WalkTowards: #Walk Towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,100 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_DownBoundThink_RunTowardsSkip: #Check distance lfs f1,GrabDistance(REG_EventConstants) lfs f2,Distance(sp) fabs f2,f2 fcmpo cr0,f2,f1 bgt EscapeSheikThink_Chase_DownBoundThink_HaltSkip #Ensure Facing cmpwi REG_Direction,1 bne EscapeSheikThink_Chase_DownBoundThink_HaltSkip EscapeSheikThink_Chase_DownBoundThink_Halt: #Stop Moving li r3,0 stw r3,CPU_HeldButtons(REG_P2Data) stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_DownBoundThink_HaltSkip: #Now jab when P1 is on the jab frame lhz r3,FramesinCurrentAS(REG_P1Data) lbz r4,JabFrame(REG_EventData) cmpw r3,r4 blt EscapeSheikThink_CheckTimer #Enter jab li r3,PAD_BUTTON_A stw r3,CPU_HeldButtons(REG_P2Data) li r3,0 stb r3,CPU_AnalogX(REG_P2Data) #Check if sheik will double jab lbz r3,isJabTwice(REG_EventData) cmpwi r3,0 beq EscapeSheikThink_Chase_DownBoundThink_SingleJab #Start Double Jab timer lbz r3,Jab2Frame(REG_EventData) stb r3,Jab2Timer(REG_EventData) #Change Event State li r3,EventState_Jab2 stb r3,EventState(REG_EventData) b EscapeSheikThink_CheckTimer EscapeSheikThink_Chase_DownBoundThink_SingleJab: #Advance state li r3,EventState_Reset stb r3,EventState(REG_EventData) #Start timer li r3,ResetTimer+30 stb r3,Timer(REG_EventData) b EscapeSheikThink_CheckTimer #endregion #region EscapeSheikThink_Jab2 EscapeSheikThink_Jab2: #Check if waiting on jab 2 lbz r3,Jab2Timer(REG_EventData) cmpwi r3,0 beq EscapeSheikThink_Chase_DownBoundThink_Jab2Skip #But not during hitlag lbz r3,0x221A(REG_P2Data) rlwinm. r3,r3,0,26,26 bne EscapeSheikThink_Chase_DownBoundThink_Jab2Skip #Decrement timer lbz r3,Jab2Timer(REG_EventData) subi r3,r3,1 stb r3,Jab2Timer(REG_EventData) #Check if up cmpwi r3,0 bgt EscapeSheikThink_CheckTimer #Enter jab li r3,PAD_BUTTON_A stw r3,CPU_HeldButtons(REG_P2Data) li r3,0 stb r3,CPU_AnalogX(REG_P2Data) #Advance state li r3,EventState_Reset stb r3,EventState(REG_EventData) #Start timer li r3,ResetTimer+30 stb r3,Timer(REG_EventData) b EscapeSheikThink_CheckTimer EscapeSheikThink_Chase_DownBoundThink_Jab2Skip: b EscapeSheikThink_CheckTimer #endregion #region EscapeSheikThink_Reset EscapeSheikThink_Reset: #Hold Shield li r3,PAD_TRIGGER_R stw r3,CPU_HeldButtons(REG_P2Data) b EscapeSheikThink_CheckTimer #endregion EscapeSheikThink_CheckTimer: #Check if timer exists lbz r3,Timer(REG_EventData) cmpwi r3,0 ble EscapeSheikThink_Exit #Decrement timer subi r3,r3,1 stb r3,Timer(REG_EventData) cmpwi r3,0 bgt EscapeSheikThink_Exit EscapeSheikThink_Restore: #Restore State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Load #Init Positions Again mr r3,REG_P1GObj mr r4,REG_P2GObj mr r5,REG_EventData bl EscapeSheik_InitializePositions EscapeSheikThink_Exit: restore blr ################################ EscapeSheikThink_Constants: blrl .set P1X,0x0 .set P1Y,0x4 .set P2X,0x8 .set P2Y,0xC .set GrabDistance,0x10 .set HoldShieldVelocity,0x14 .set RunDistance,0x18 .float -8 #p1 x .float 0 #p1 y .float 8 #p2 x .float 0 #p2 y .float 14 #16 .float 1.1 .float 23 ########################################### EscapeSheikThink_TopText: blrl .string "Down B Input" .align 2 EscapeSheikThink_BottomText: blrl .string "%df %s" .align 2 EscapeSheikThink_EarlyText: blrl .string "Early" .align 2 EscapeSheikThink_LateText: blrl .string "Late" .align 2 ########################################### EscapeSheik_InitializePositions: backup .set REG_FacingDirection,31 #1 = p1 facing right, -1 = p1 facing left .set REG_P1GObj,30 .set REG_P1Data,29 .set REG_P2GObj,28 .set REG_P2Data,27 .set REG_EventData,26 #Init Registers mr REG_P1GObj,r3 lwz REG_P1Data,0x2C(REG_P1GObj) mr REG_P2GObj,r4 lwz REG_P2Data,0x2C(REG_P2GObj) mr REG_EventData,r5 EscapeSheik_InitializePositions_DetermineFacingDirection: #Determine Facing Direction li REG_FacingDirection,1 li r3,2 branchl r12,HSD_Randi cmpwi r3,0 beq EscapeSheik_InitializePositions_DetermineFacingDirection_End li REG_FacingDirection,-1 EscapeSheik_InitializePositions_DetermineFacingDirection_End: #Apply Facing Directions mr r3,REG_FacingDirection bl IntToFloat stfs f1,0x2C(REG_P1Data) mulli r3,REG_FacingDirection,-1 bl IntToFloat stfs f1,0x2C(REG_P2Data) #Get Starting Coordinates lfs f1,P1X(REG_EventConstants) lfs f2,P1Y(REG_EventConstants) cmpwi REG_FacingDirection,0 blt EscapeSheik_InitializePositions_P1FacingLeft stfs f1,0xB0(REG_P1Data) stfs f2,0xB4(REG_P1Data) b EscapeSheik_InitializePositions_RightPosition EscapeSheik_InitializePositions_P1FacingLeft: stfs f1,0xB0(REG_P2Data) stfs f2,0xB4(REG_P2Data) EscapeSheik_InitializePositions_RightPosition: lfs f1,P1X(REG_EventConstants) lfs f2,P1Y(REG_EventConstants) cmpwi REG_FacingDirection,0 blt EscapeSheik_InitializePositions_P2FacingRight stfs f1,0xB0(REG_P2Data) stfs f2,0xB4(REG_P2Data) EscapeSheik_InitializePositions_P2FacingRight: stfs f1,0xB0(REG_P1Data) stfs f2,0xB4(REG_P1Data) #Update Positions mr r3,REG_P1GObj bl PlacePlayerOnGround mr r3,REG_P1GObj bl UpdateCameraBox mr r3,REG_P2GObj bl PlacePlayerOnGround mr r3,REG_P2GObj bl UpdateCameraBox #Store P1 into P2 Grab Pointer stw REG_P1GObj,0x1A58(REG_P2Data) stw REG_P1GObj,0x1A5C(REG_P2Data) #Clear P1's Grabbed Player Pointer li r3,0 stw r3,0x1A58(REG_P1Data) stw r3,0x1A5C(REG_P1Data) #Clear P2's GFX Pointer stw r3,0x60C(REG_P2Data) #Enter P2 Into Grab mr r3,REG_P2GObj #P2 Enters Grab branchl r12,AS_GrabOpponent #Enter P1 Into Grabbed mr r3,REG_P1GObj #P1 Grabbed mr r4,REG_P2GObj #P2 = Grabber branchl r12,AS_Grabbed #Enter P2 Into GrabWait mr r3,REG_P2GObj #P2 Enters GrabWait branchl r12,AS_CatchWait #Give a bunch of grabstun li r3,999 bl IntToFloat stfs f1,0x1A4C(REG_P1Data) #Random percent li r3,PercentHi-PercentLo branchl r12,HSD_Randi addi r4,r3,PercentLo lbz r3,0xC(REG_P1Data) branchl r12,PlayerBlock_SetDamage #Reset Variables li r3,EventState_ThrowDelay stb r3,EventState(REG_EventData) li r3,0 stb r3,Timer(REG_EventData) stb r3,JabFrame(REG_EventData) #Init Throw Timer li r3,ThrowTimerHi-ThrowTimerLo branchl r12,HSD_Randi addi r3,r3,ThrowTimerLo sth r3,ThrowTimer(REG_EventData) #Init isDisplayedTiming li r3,0 stb r3,isDisplayedTiming(REG_EventData) EscapeSheik_InitializePositions_Exit: restore blr #endregion #region Scrapped Edgeguard Event /* ######################### ## Event 16 HIJACK INFO ## ######################### Event16: #STORE STAGE li r3,0x20 sth r3,0xE(r26) li r5,0x2 #Ice Climbers li r5,0x14 #STORE CPU lwz r4,0x0(r29) bl P2Struct mflr r3 stw r3,0x18(r4) #p2 pointer stb r5,0x0(r3) #make top tier p2 li r5,0x1 #make CPU controlled stb r5,0x1(r3) #SPAWN 2 PLAYERS li r3,0x40 stb r3,0x1(r4) #STORE THINK FUNCTION bl Event16Load mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Event 16 LOAD FUNCT ## ######################## Event16Load: blrl backup #Schedule Think bl Event16Think mflr r3 li r4,3 #Priority (After Interrupt) bl CreateEventThinkFunction b Event16LoadExit ######################### ## Event 16 THINK FUNCT ## ######################### Event16Think: blrl backup #INIT FUNCTION VARIABLES lwz r31,0x2c(r3) #backup data pointer in r31 #Get P2 li r3,0x1 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block mr r30,r3 #player block in r30 lwz r29,0x2c(r30) #player data in r29 #Get P1 li r3,0x0 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block mr r28,r3 #player block in r28 lwz r27,0x2c(r28) #player data in r27 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME lbz r3,0x0(r31) cmpwi r3,0x0 bne Event16ThinkMain lbz r3,0x221D(r29) rlwinm. r3,r3,0,28,28 bne Event16ThinkExit #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) #Initlize Positions bl Event16_Floats mflr r3 #bl InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State mr r3,r31 bl SaveState_Save #Set Timer to -60 li r3,-60 stw r3,0x4(r31) Event16ThinkMain: Event16ThinkSequence: #Inc Timer lwz r3,0x4(r31) addi r3,r3,0x1 stw r3,0x4(r31) #Get Floats bl Event16_Floats mflr r21 #L+DPad Controls CPU Percent bl DPadCPUPercent #Check If Already in A Recovery Mode lbz r3,0x8(r31) cmpwi r3,0x1 beq Event16CheckRecoveryFlag #Check If CPU Is Offstage mr r3,r29 branchl r12,0x800a2c80 cmpwi r3,0x0 beq Event16CheckRecoveryFlag #Check If Still in Hitstun lbz r3,0x221C(r29) rlwinm. r3,r3,0,30,30 bne Event16CheckRecoveryFlag #Check If Below Ledge #Hold Towards Ledge #Get Random Recovery Option Event16GetRandomRecovery: li r3,3 #Number of Recovery Options (Side B Immediately,Jump Then Side B, ShineStall-Jump-SideB) branchl r12,HSD_Randi cmpwi r3,0x0 bne Event16StoreRecoveryType #Check If Can Side B Only #Check If Above Ledge lfs f1,0xB4(r29) #Get Y Coord #lfs f2,0x10(r21) #fcmpo cr0,f1,f2 #bgt Event16GetRandomRecovery #lfs f2,0x10(r21) #Check If Below Ledge lfs f2,0x14(r21) fcmpo cr0,f1,f2 blt Event16GetRandomRecovery Event16StoreRecoveryType: stb r3,0x9(r31) #Init Recovery Flag li r3,0x1 stb r3,0x8(r31) Event16CheckRecoveryFlag: #Check Recovery Flag lbz r3,0x8(r31) cmpwi r3,0x0 beq Event16CheckToReset #******************************************************************# #IsRecovering #If Timer Is Set, Dont Run Any of This lwz r3,0xC(r31) #get timer #Get Timer cmpwi r3,0x0 #No Reset Timer Set Yet bgt Event16GetRecoveryID #Hold Towards Stage li r3,127 lfs f0,0x00B0 (r29) #X Pos lfs f1,0x1ADC (r29) #Last Grounded X Pos fcmpo cr0,f1,f0 bgt Event16HoldTowardsRight neg r3,r3 Event16HoldTowardsRight: stb r3,0x1A8C(r29) #Check If Died lbz r3,0x221F(r29) rlwinm. r3,r3,0,25,25 bne Event16SideBThink_Reset #Check If In Hitlag #Recover again lbz r3,0x221A(r29) rlwinm. r3,r3,0,26,26 bne Event16RecoverAgain #Check If Made It Back #Check Ground Flag lwz r3,0xE0(r29) cmpwi r3,0x0 beq Event16SideBThink_Reset #Check CliffCatch lwz r3,0x10(r29) cmpwi r3,0xFC beq Event16SideBThink_Reset b Event16GetRecoveryID Event16RecoverAgain: #Recover Again li r3,0x0 stb r3,0x8(r31) stb r3,0x9(r31) b Event16CheckToReset Event16SideBThink_Reset: #Set Timer lwz r3,0xC(r31) #get timer #Get Timer cmpwi r3,0x0 #No Reset Timer Set Yet bgt Event16CheckToReset #Reset Timer Set li r3,30 stw r3,0xC(r31) #Store Reset Timer b Event16CheckToReset #Run Recovery Think #Get Which Recovery To Perform Event16GetRecoveryID: lbz r3,0x9(r31) cmpwi r3,0x0 beq Event16SideBOnly cmpwi r3,0x1 beq Event16JumpSideB cmpwi r3,0x2 beq Event16SSJumpSideB cmpwi r3,0x3 beq Event16SideBThink #*************************************************# Event16SideBOnly: #Be in ledge Y range, Check if next frame will be out of Y range bl Event16CheckIfLineUpWithLedge cmpwi r3,-1 #Not In Range Yet beq Event16CheckToReset cmpwi r3,0x0 beq Event16ChanceToInputSideB #If OoRange Next Frame + Descending, Side B Immediately lfs f0, -0x7208 (rtoc) lfs f1,0xCC(r29) fcmpo cr0,f1,f0 blt Event16InputSideB Event16ChanceToInputSideB: li r3,5 branchl r12,HSD_Randi cmpwi r3,0x0 beq Event16InputSideB b Event16CheckToReset Event16InputSideB: #Joystick X = 120 * Facing Direction lfs f1,0x2C(r29) fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) li r3,120 #X Stick mullw r3,r3,r4 stb r3,0x1A8C(r29) li r3,0x200 stw r3,0x1A88(r29) #li r3,0x0 #stb r3,0x8(r31) #Change State to Mid-Side B li r3,3 stb r3,0x9(r31) b Event16CheckToReset #*************************************************# Event16JumpSideB: #Be above bottom most coord, Check if next frame will be out of Y range #Be in ledge Y range, Check if next frame will be out of Y range #Check If Above Bottom-most lfs f1,0xB4(r29) #Get Next Frames Y Coord lfs f2,0x84(r29) fadds f1,f1,f2 lfs f2,0x18(r21) #Get Bottom Y Coord fcmpo cr0,f1,f2 blt Event16JumpSideB_Jump Event16JumpSideB_ChanceToJump: li r3,20 #1 in 4 Chance branchl r12,HSD_Randi cmpwi r3,0x0 beq Event16JumpSideB_Jump b Event16CheckToReset Event16JumpSideB_Jump: li r3,0x800 stw r3,0x1A88(r29) #Advance to Next State li r3,0x0 stb r3,0x9(r31) b Event16CheckToReset #*************************************************# Event16SSJumpSideB: #Hold Down B #Be above bottom most coord, Check if next frame will be out of Y range #Be in ledge Y range, Check if next frame will be out of Y range #Always Hold Down B li r3,-127 stb r3,0x1A8D(r29) li r3,0x200 stw r3,0x1A88(r29) #Wait Until in Shine Loop lwz r3,0x10(r29) cmpwi r3,0x16E bne Event16CheckToReset #Check If Above Bottom-most lfs f1,0xB4(r29) #Get Next Frames Y Coord lfs f2,0x84(r29) fadds f1,f1,f2 lfs f2,0x18(r21) #Get Bottom Y Coord fcmpo cr0,f1,f2 blt Event16SSJumpSideB_Jump Event16SSJumpSideB_ChanceToJump: li r3,15 #1 in 6 Chance branchl r12,HSD_Randi cmpwi r3,0x0 beq Event16SSJumpSideB_Jump b Event16CheckToReset Event16SSJumpSideB_Jump: li r3,0x800 stw r3,0x1A88(r29) #Advance to Next State li r3,0x0 stb r3,0x9(r31) b Event16CheckToReset #*************************************************# Event16SideBThink: b Event16CheckToReset #*************************************************# #Check To Reset Event16CheckToReset: lwz r3,0xC(r31) #Get Timer cmpwi r3,0x0 #No Reset Timer Set Yet ble Event16ThinkExit #Dec Timer subi r3,r3,0x1 stw r3,0xC(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne Event16ThinkExit #Exit If Not Event16RestoreState: #Restore State mr r3,r31 bl SaveState_Load #Reset Timer li r3,60 branchl r12,HSD_Randi li r4,0 sub r3,r4,r3 stw r3,0x4(r31) li r3,0x0 stb r3,0x8(r31) Event16ThinkExit: restore blr ################################# Event16_Floats: blrl .long 0xC28C0000 #P1 X Position .long 0xc2982e6c #P2 X Position .long 0x38d1b717 #P1 Y Position .long 0x38d1b717 #FD Floor Y Coord .long 0x40A00000 #Top Most Y Value = -5 .long 0xC1700000 #Bottom-most Y Value = -15 .long 0xC25C0000 #Shine Stall Bottom Most Coord ################################# Event16CheckIfLineUpWithLedge: #-1 = Not In Any Range Yet #0 = In Range This And Next Frame #1 = In Range This but NOT Next Frame #Check If In Range This Frame lfs f1,0xB4(r29) #Get Y Coord lfs f2,0x10(r21) fcmpo cr0,f1,f2 bgt Event16CheckIfLineUpWithLedge_NotInRange lfs f2,0x14(r21) fcmpo cr0,f1,f2 blt Event16CheckIfLineUpWithLedge_NotInRange Event16CheckIfLineUpWithLedge_CheckNextFrame: #Check If Out Of Range Next Range lfs f1,0xB4(r29) #Get Y Coord lfs f2,0x84(r29) #Get Y Vel fadds f1,f1,f2 #Get Next Frames Position #Check If Will Be Above Ledge Next Frame lfs f2,0x10(r21) fcmpo cr0,f1,f2 bgt Event16CheckIfLineUpWithLedge_OutOfRangeNextFrame lfs f2,0x10(r21) #Check If Will Be Below Ledge Next Frame lfs f2,0x14(r21) fcmpo cr0,f1,f2 blt Event16CheckIfLineUpWithLedge_OutOfRangeNextFrame b Event16CheckIfLineUpWithLedge_InRangeThisAndNextFrame Event16CheckIfLineUpWithLedge_NotInRange: li r3,-1 b Event16CheckIfLineUpWithLedge_Exit Event16CheckIfLineUpWithLedge_InRangeThisAndNextFrame: li r3,0x0 b Event16CheckIfLineUpWithLedge_Exit Event16CheckIfLineUpWithLedge_OutOfRangeNextFrame: li r3,0x1 Event16CheckIfLineUpWithLedge_Exit: blr ################################# Event16LoadExit: restore blr */ #endregion #region Scrapped Dash Dance Code /* ######################### ## Shield Drop HIJACK INFO ## ######################### ShieldDrop: #STORE STAGE li r3,0x20 sth r3,0xE(r26) #STORE CPU lwz r4,0x0(r29) bl P2Struct mflr r3 stw r3,0x18(r4) #p2 pointer li r5,0x2 #fox ext ID stb r5,0x0(r3) #make fox p2 li r5,0x1 #make CPU controlled stb r5,0x1(r3) #SPAWN 2 PLAYERS li r3,0x40 stb r3,0x1(r4) #STORE THINK FUNCTION bl ShieldDropLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Shield Drop LOAD FUNCT ## ######################## ShieldDropLoad: blrl backup #Schedule Think bl ShieldDropThink mflr r3 li r4,3 #Priority (After Interrupt) bl CreateEventThinkFunction b ShieldDropLoadExit ######################### ## Shield Drop THINK FUNCT ## ######################### ShieldDropThink: blrl backup #INIT FUNCTION VARIABLES lwz r31,0x2c(r3) #backup data pointer in r31 #Get P2 li r3,0x1 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block mr r30,r3 #player block in r30 lwz r29,0x2c(r30) #player data in r29 #Get P1 li r3,0x0 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block mr r28,r3 #player block in r28 lwz r27,0x2c(r28) #player data in r27 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME lbz r3,0x0(r31) cmpwi r3,0x0 bne ShieldDropThinkMain lbz r3,0x221D(r29) rlwinm. r3,r3,0,28,28 bne ShieldDropThinkExit #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) bl ShieldDrop_InitializePositions mr r3,r31 bl SaveState_Save ShieldDropThinkMain: bl GiveFullShields ShieldDropThinkSequence: #Get Floats and Frame Info bl ShieldDropFloats mflr r21 #Get Floats lwz r20,0x4(r31) #Get State lfs f1,0x894(r29) fctiwz f1,f1 stfd f1,0xF0(sp) lwz r24,0xF4(sp) #Frame Number in r24 #Get Distance and Direction #f1 = distance #r22= towards direction #r23= away direction lfs f1,0xB0(r27) lfs f2,0xB0(r29) fsubs f1,f1,f2 lfs f0, -0x6768 (rtoc) fcmpo cr0,f1,f0 bgt ShieldDropRight ShieldDropLeft: li r22,-127 li r23,127 b ShieldDropCheckState ShieldDropRight: li r22,127 li r23,-127 ShieldDropCheckState: #When DDing, Move In Facing Direction cmpwi r20,0x1 bne ShieldDrop_SkipHoldForward lfs f2,0x2C(r29) fctiwz f2,f2 stfd f2,0xF0(sp) lwz r3,0xF4(sp) #Facing direction as int mulli r3,r3,127 stb r3,0x1A8C(r29) #Move Towards ShieldDrop_SkipHoldForward: fabs f1,f1 #abs distance cmpwi r20,0x0 beq ShieldDropDashDanceStart cmpwi r20,0x1 beq ShieldDropDashDanceThink cmpwi r20,0x2 beq ShieldDropJumpThink cmpwi r20,0x3 beq ShieldDropLCancelThink cmpwi r20,0x4 beq ShieldDropInvincibleThink ShieldDropDashDanceStart: stb r23,0x1A8C(r29) #Move Away li r3,0x1 #Enter DDThink stw r3,0x4(r31) b ShieldDropThinkExit ShieldDropDashDanceThink: #Check If Too Close ShieldDropDashDanceThink_CheckIfTooClose: lfs f2,0x0(r21) fcmpo cr0,f1,f2 bgt ShieldDropDashDanceThink_CheckIfTooFar stb r23,0x1A8C(r29) #Move Away b ShieldDropThinkExit ShieldDropDashDanceThink_CheckIfTooFar: lfs f2,0x4(r21) fcmpo cr0,f1,f2 blt ShieldDropDashDanceThink_CheckToAttack stb r22,0x1A8C(r29) #Move Towards b ShieldDropThinkExit ShieldDropDashDanceThink_CheckToAttack: lfs f2,0x8(r21) fcmpo cr0,f1,f2 bgt ShieldDropDashDanceThink_CheckToChangeDirection ShieldDropDashDanceThink_CheckIfFacingOpponent: lfs f2,0x2C(r29) fctiwz f2,f2 stfd f2,0xF0(sp) lwz r3,0xF4(sp) #Facing direction as int cmpwi r3,0x0 blt ShieldDropDashDanceThink_FacingLeft ShieldDropDashDanceThink_FacingRight: cmpwi r22,0x0 bgt ShieldDropDashDanceThink_FacingOpponent b ShieldDropDashDanceThink_NotFacingOpponent ShieldDropDashDanceThink_FacingLeft: cmpwi r22,0x0 blt ShieldDropDashDanceThink_FacingOpponent b ShieldDropDashDanceThink_NotFacingOpponent ShieldDropDashDanceThink_FacingOpponent: li r3,0x1 b 0x8 ShieldDropDashDanceThink_NotFacingOpponent: li r3,0x0 cmpwi r3,0x0 beq ShieldDropDashDanceThink_CheckToChangeDirection #RNG Chance To Attack li r3,20 branchl r12,HSD_Randi cmpwi r3,0x0 bne ShieldDropDashDanceThink_CheckToChangeDirection li r3,0x400 #X Button stw r3,0x1A88(r29) #Held Buttons li r3,0x2 #JumpThink stw r3,0x4(r31) b ShieldDropThinkExit ShieldDropDashDanceThink_CheckToChangeDirection: #Move if in Wait lwz r3,0x10(r29) cmpwi r3,0xE beq ShieldDropDashDanceThink_ChangeDirection #At least frame 3 of dash cmpwi r24,6 blt ShieldDropThinkExit cmpwi r24,11 bge ShieldDropDashDanceThink_ChangeDirection #RNG Chance To ChangeDirection li r3,7 branchl r12,HSD_Randi cmpwi r3,0x0 bne ShieldDropThinkExit ShieldDropDashDanceThink_ChangeDirection: lfs f2,0x2C(r29) fctiwz f2,f2 stfd f2,0xF0(sp) lwz r3,0xF4(sp) #Facing direction as int mulli r3,r3,127 mulli r3,r3,-1 stb r3,0x1A8C(r29) #Move Away b ShieldDropThinkExit ShieldDropJumpThink: lwz r3,0xE0(r29) cmpwi r3,0x0 beq ShieldDropThinkExit li r3,0x100 #A Button stw r3,0x1A88(r29) #Held Buttons li r3,0x3 #LCancelThink stw r3,0x4(r31) b ShieldDropThinkExit ShieldDropLCancelThink: ShieldDropLCancelInputFF: lfs f2,0x84(r29) lfs f0, -0x76B0 (rtoc) fcmpo cr0,f2,f0 bge ShieldDropThinkExit #Input Down to FF li r3,-127 stb r3,0x1A8D(r29) #Ananlog Y #Check If Under 5Mm Above Ground lfs f2,0xB4(r29) lfs f0,0xC(r21) fcmpo cr0,f2,f0 bgt ShieldDropThinkExit li r3,0xC0 #Hit L stw r3,0x1A88(r29) #Held Buttons #Enter InvincibleThink + Init Counter li r3,0x4 #State stw r3,0x4(r31) li r3,60 stw r3,0x8(r31) #Counter b ShieldDropThinkExit ShieldDropInvincibleThink: #Dec Counter And Check To Restore lwz r3,0x8(r31) subi r3,r3,0x1 stw r3,0x8(r31) cmpwi r3,0x0 bgt ShieldDrop_CheckToMakeInvincible #Reset State ID li r3,0x0 stw r3,0x4(r31) #Restore Savestate mr r3,r31 bl SaveState_Load b ShieldDropThinkExit ShieldDrop_CheckToMakeInvincible: lwz r3,0x10(r29) cmpwi r3,0xE #bne ShieldDropThinkExit #Make Invincible #mr r3,r30 #li r4,0x2 #branchl r12,ApplyInvincibility #b ShieldDropThinkExit #Multishine mr r3,r29 bl CPUActions_MultiShine b ShieldDropThinkExit ShieldDropThinkExit: restore blr ########################## ShieldDropFloats: blrl .long 0x41A00000 #no closer than this .long 0x42180000 #no further than this .long 0x41C80000 #at least this close to jump .long 0x40000000 #below this Y coord to L Cancel .long 0xC02CCCCD #P1 X Position .long 0x4144CCCD #P2 X Position ################################# ShieldDrop_InitializePositions: backup #P1 @ -2.7 #P2 @ 12.3 #Get Floats bl ShieldDropFloats mflr r20 #Move P1 mr r3,r28 branchl r12,0x8008a2bc #Enter Wait lfs f1,0x10(r20) stfs f1,0xB0(r27) mr r3,r28 bl UpdatePosition #Move P2 mr r3,r30 branchl r12,0x8008a2bc #Enter Wait lfs f1,0x14(r20) stfs f1,0xB0(r29) mr r3,r30 bl UpdatePosition restore blr ################################### ShieldDropLoadExit: restore blr */ #endregion #region Event Template /* ######################### ## Eggs-ercise HIJACK INFO ## ######################### Eggs: #STORE THINK FUNCTION bl EggsLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Eggs-ercise LOAD FUNCT ## ######################## EggsLoad: blrl backup #Schedule Think bl EggsThink mflr r3 bl CreateEventThinkFunction b EggsLoadExit ######################### ## Eggs-ercise THINK FUNCT ## ######################### EggsThink: blrl backup EggsThinkExit: restore blr EggsLoadExit: restore blr */ #################################################### #endregion ############### ## P1 STRUCT ## ############### P1Struct: blrl .long 0x01000200 #external char, player type, stocks, costume .long 0xff000400 #spawn point, subcolor,team,voice pitch .long 0x00040700 #player flag .long 0x00000000 #level and starting % .long 0x3f800000 #attk ratio .long 0x3f800000 #def ratio .long 0x3f800000 #model scale ############### ## P2 STRUCT ## ############### P2Struct: blrl .long 0x01010200 #external char, player type, stocks, costume .long 0xff000400 #spawn point, subcolor,team,voice pitch .long 0x00040700 #player flag .long 0x00000000 #level and starting % .long 0x3f800000 #attk ratio .long 0x3f800000 #def ratio .long 0x3f800000 #model scale ########################### ## Create Think Function ## ########################### CreateEventThinkFunction: #Registers .set WindowOptionCount,31 .set ASCIIStruct,30 .set EventGObj,29 .set EventData,28 .set MenuGObj,27 .set MenuData,26 .set Priority,25 .set Function,24 backup mr Function,r3 mr Priority,r4 mr WindowOptionCount,r5 mr ASCIIStruct,r6 ######################## ## Create Event Think ## ######################## #Create GObj li r3,6 #GObj Type li r4,7 #On-Pause Function li r5,80 branchl r12,GObj_Create #Backup Allocation mr EventGObj,r3 #Schedule Task mr r4,Function mr r5,Priority branchl r12,GObj_AddProc #Give Task Some Data Space li r3,EventData_DataSize #50 bytes of space branchl r12,HSD_MemAlloc #HSD_MemAlloc mr EventData,r3 #Initalize GObj mr r6,r3 mr r3,EventGObj #task space li r4,0x0 #typedef load r5,HSD_Free #destructor (HSD_Free) branchl r12,GObj_AddUserData #Create Data Block #Zero Dataspace mr r3,EventData li r4,EventData_DataSize branchl r12,ZeroAreaLength #zero length ############################## ## Create Option Menu Think ## ############################## #Check if Option Menu is enabled for this event cmpwi WindowOptionCount,0 beq CreateEventThinkFunction_NoOptionMenu #Create GObj li r3,6 #GObj Type li r4,0 #On-Pause Function li r5,80 branchl r12,GObj_Create #Backup Allocation mr MenuGObj,r3 #Schedule Task bl OptionMenuThink mflr r4 li r5,22 #Last Function to Run branchl r12,GObj_AddProc #Give Task Some Data Space li r3,MenuData_DataSize #50 bytes of space branchl r12,HSD_MemAlloc #HSD_MemAlloc mr MenuData,r3 #Initalize GObj mr r6,MenuData mr r3,MenuGObj #task space li r4,0x0 #typedef load r5,HSD_Free #destructor (HSD_Free) branchl r12,GObj_AddUserData #Create Data Block #Zero Dataspace mr r3,MenuData li r4,MenuData_DataSize branchl r12,ZeroAreaLength #zero length #Store Option Menu info to Dataspace stw WindowOptionCount,MenuData_WindowOptionCountPointer(MenuData) stw ASCIIStruct,MenuData_ASCIIStructPointer(MenuData) #Store Pointers to Each Other stw MenuData,EventData_MenuDataPointer(EventData) stw EventData,MenuData_EventDataPointer(MenuData) CreateEventThinkFunction_NoOptionMenu: #Disable Hazards bl DisableHazards CreateEventThinkFunction_Exit: restore blr #################################### ## Create Option Menu When Paused ## #################################### OptionMenuThink: blrl .set MenuData,31 backup #Load Data Pointer lwz MenuData,0x2C(r3) #Check If Paused li r3,1 branchl r12,DevelopMode_FrameAdvanceCheck cmpwi r3,0x2 bne OptionMenuThink_Exit #Run OptionThink Code OptionMenuThink_CheckInputs: addi r3,MenuData,MenuData_OptionMenuMemory lwz r4,MenuData_WindowOptionCountPointer(MenuData) lwz r5,MenuData_ASCIIStructPointer(MenuData) bl OptionWindow #Store Modified Option Bool cmpwi r3,0 beq OptionMenuThink_Exit addi r5,MenuData,MenuData_OptionMenuToggled stbx r3,r4,r5 OptionMenuThink_Exit: restore blr ########################## ## Clear Option Toggled ## ########################## ClearToggledOptions: #in #r3 = Menu Data #Get Amount of Options lwz r4,MenuData_WindowOptionCountPointer(r3) lbz r4,0x0(r4) #Loop Through All Data addi r3,r3,MenuData_OptionMenuToggled li r5,0 ClearToggledOptions_Loop: stbx r5,r3,r4 #Zero Byte subi r4,r4,1 cmpwi r4,0 bge ClearToggledOptions_Loop ClearToggledOptions_Exit: blr ###################### ## Save States Main ## ###################### #0x0 -> 0x23EC = player block #0x23EC -> 0x24EC = Static Block #0x24EC = Camera Flag ################################ ## Save State Quick Functions ## ################################ SaveState_Save: .set REG_SaveStruct,31 .set REG_PlayerTotal,30 .set REG_LoopCount,29 .set REG_isSubchar,23 .set REG_Backup,28 .set REG_SpawnedOrder,22 .set REG_PlayerGObj,25 .set REG_PlayerData,26 .set REG_PlayerDataSize,24 .set REG_PlayerData_Backup,27 backup #Backup Task Data mr REG_SaveStruct,r3 #Backup "skip failsafe" bool mr r20,r4 #Count Players in Match branchl r3,0x8016b558 #Move Player Number to REG_PlayerTotal mr REG_PlayerTotal,r3 #Check to run failsafe code cmpwi r20,0x0 bne SaveState_SaveLoopInit SaveState_OnDeathCheck: #Mini loop to make sure no players have on-death functions li REG_LoopCount,0x0 #player ID li REG_isSubchar,0x0 #main/sub char bool SaveState_OnDeathCheckLoop: #Get Proper Player Data mr r3,REG_LoopCount mr r4,REG_isSubchar bl SaveState_GetPlayerDataPointer #returns player slot,player pointer and player data cmpwi r3,0xFF #check if player didnt exist beq SaveState_OnDeathCheckInc #move on with loop #Check for on-death function lwz r3,0x21E0(r5) cmpwi r3,0x0 bne SaveState_OnDeathCheckExit lwz r3,0x21E4(r5) cmpwi r3,0x0 bne SaveState_OnDeathCheckExit lwz r3,0x21E8(r5) cmpwi r3,0x0 bne SaveState_OnDeathCheckExit #Check if holding an item lwz r3,0x1974(r5) cmpwi r3,0x0 bne SaveState_OnDeathCheckExit lwz r3,0x1978(r5) cmpwi r3,0x0 bne SaveState_OnDeathCheckExit #Check for fighter accessory lwz r3,0x20A0(r5) cmpwi r3,0x0 bne SaveState_OnDeathCheckExit b SaveState_OnDeathCheckInc SaveState_OnDeathCheckExit: #PLay Error SFX li r3,0xAF bl PlaySFX li r3,0xAF bl PlaySFX b SaveState_SaveExit SaveState_OnDeathCheckInc: #Check For Subchar Before Looping cmpwi REG_isSubchar,0x1 beq SaveState_OnDeathCheck_ToggleSubCharOff li REG_isSubchar,0x1 b SaveState_OnDeathCheckLoop SaveState_OnDeathCheck_ToggleSubCharOff: li REG_isSubchar,0x0 addi REG_LoopCount,REG_LoopCount,0x1 cmpw REG_LoopCount,REG_PlayerTotal blt SaveState_OnDeathCheckLoop SaveState_SaveLoopInit: #Init Save Loop li REG_LoopCount,0x0 #player ID li REG_isSubchar,0x0 #main/sub char bool SaveState_SaveLoop: #Get This Player's Backup Pointer in REG_Backup mulli r4,REG_LoopCount,0x8 #8 bytes per player pointer add REG_Backup,r4,REG_SaveStruct #REG_Backup contains this players block backup #Check If Backup Exists cmpwi REG_isSubchar,0x0 beq SaveState_Save_MainChar SaveState_Save_SubChar: lwz r3,0x4(REG_Backup) #get pointer to backup if it exists b SaveState_Save_CheckIfExists SaveState_Save_MainChar: lwz r3,0x0(REG_Backup) #get pointer to backup if it exists SaveState_Save_CheckIfExists: cmpwi r3,0x0 beq SaveState_SaveStart #Remove Old Backup (HSD_Free) branchl r12,HSD_Free SaveState_SaveStart: #Get Proper Player Data mr r3,REG_LoopCount mr r4,REG_isSubchar bl SaveState_GetPlayerDataPointer #returns player slot,player pointer and player data cmpwi r3,0xFF #check if player didnt exist beq SaveState_SaveLoopInc #move on with loop mr REG_SpawnedOrder,r3 #REG_SpawnedOrder contains actual player slot mr REG_PlayerData,r5 #REG_PlayerData contains real player block #Get Player Data Length SaveState_Save_GetPlayerBlockLength: load r3,0x80458fd0 lwz REG_PlayerDataSize,0x20(r3) #get player block length in REG_PlayerDataSize addi r3,REG_PlayerDataSize,0x100 #add static block length addi r3,r3,0x10 #add additional storage branchl r12,HSD_MemAlloc #HSD_MemAlloc #Store Pointer To Task Struct cmpwi REG_isSubchar,0x0 bne Savestate_Save_StoreBackupSubChar stw r3,0x0(REG_Backup) b Savestate_Save_StoreBackupEnd Savestate_Save_StoreBackupSubChar: stw r3,0x4(REG_Backup) Savestate_Save_StoreBackupEnd: mr REG_PlayerData_Backup,r3 #REG_PlayerData_Backup contains playerblock backup #Copy Player Block to Backup mr r3,REG_PlayerData_Backup #r3 = destination to copy to mr r4,REG_PlayerData #r4 = source mr r5,REG_PlayerDataSize #r5 = playerblock length branchl r12,memcpy #mempcy #Copy Static Block to Backup cmpwi REG_isSubchar,0x0 #unless this is a subcharacter bne Savestate_Save_SkipStaticBlockBackup add r3,REG_PlayerDataSize,REG_PlayerData_Backup #get end of playerblock in r4 load r4,0x80453080 #get static block in r4 li r5,0xE90 mullw r5,r5,REG_SpawnedOrder add r4,r4,r5 li r5,0x100 #only copying the first 100 bytes branchl r12,memcpy #mempcy Savestate_Save_SkipStaticBlockBackup: #Save Camera Flag lwz r3,0x890(REG_PlayerData) lwz r3,0x8(r3) add r4,REG_PlayerDataSize,REG_PlayerData_Backup #get end of player block in r4 addi r4,r4,0x100 #get end of static block stw r3,0x0(r4) #store to end of block SaveState_SaveLoopInc: #Check For Subchar Before Looping cmpwi REG_isSubchar,0x1 beq SaveState_SaveLoopInc_ToggleSubCharOff li REG_isSubchar,0x1 b SaveState_SaveLoop SaveState_SaveLoopInc_ToggleSubCharOff: li REG_isSubchar,0x0 addi REG_LoopCount,REG_LoopCount,0x1 cmpw REG_LoopCount,REG_PlayerTotal blt SaveState_SaveLoop SaveState_SaveExit: restore blr SaveState_Load: .set REG_SaveStruct,31 .set REG_PlayerTotal,30 .set REG_LoopCount,29 .set REG_isSubchar,23 .set REG_Backup,28 .set REG_SpawnedOrder,22 .set REG_PlayerGObj,25 .set REG_PlayerData,26 .set REG_PlayerDataSize,24 .set REG_PlayerData_Backup,27 backup mr REG_SaveStruct,r3 #Count Players in Match branchl r3,0x8016b558 #Move Player Number to REG_PlayerTotal mr REG_PlayerTotal,r3 #Restore Camera Info Here #Init Load Loop li REG_LoopCount,0x0 #player count li REG_isSubchar,0x0 #main/subchar bool SaveState_LoadLoop: #Get This Player's Backup Pointer in REG_Backup mulli r4,REG_LoopCount,0x8 #8 bytes per player pointer add REG_Backup,r4,REG_SaveStruct #REG_Backup contains this players block backup #Check If Backup Exists cmpwi REG_isSubchar,0x0 beq SaveState_Load_MainChar SaveState_Load_SubChar: lwz r3,0x4(REG_Backup) #get pointer to backup if it exists b SaveState_Load_CheckIfExists SaveState_Load_MainChar: lwz r3,0x0(REG_Backup) #get pointer to backup if it exists SaveState_Load_CheckIfExists: cmpwi r3,0x0 beq SaveState_LoadLoopInc SaveState_LoadStart: #Get Proper Player Data mr r3,REG_LoopCount mr r4,REG_isSubchar bl SaveState_GetPlayerDataPointer #returns player slot,player pointer and player data cmpwi r3,0xFF #check if player didnt exist beq SaveState_LoadLoopInc #move on with loop mr REG_SpawnedOrder,r3 #REG_SpawnedOrder contains actual player slot mr REG_PlayerGObj,r4 #REG_PlayerGObj contains external player mr REG_PlayerData,r5 #REG_PlayerData contains real player block #Get Player Block Length in REG_PlayerDataSize SaveState_Load_GetPlayerBlockLength: load REG_PlayerDataSize,0x80458fd0 lwz REG_PlayerDataSize,0x20(REG_PlayerDataSize) #REG_PlayerDataSize = length #Get Pointer From Task Struct cmpwi REG_isSubchar,0x0 #check if subcharacter beq Savestate_Load_GetBackupMainChar Savestate_Load_GetBackupSubChar: lwz REG_PlayerData_Backup,0x4(REG_Backup) #REG_PlayerData_Backup contains playerblock backup b Savestate_Load_RestoreFacingDirection Savestate_Load_GetBackupMainChar: lwz REG_PlayerData_Backup,0x0(REG_Backup) #REG_PlayerData_Backup contains playerblock backup #Restore Facing Direction Savestate_Load_RestoreFacingDirection: lwz r3,0x2C(REG_PlayerData_Backup) #backed up Facing Direction stw r3,0x2C(REG_PlayerData) #Enter Into Sleep mr r3,REG_PlayerGObj li r4,0x0 branchl r12,AS_Sleep #Remove On Death Function Pointer li r3,0x0 stw r3,0x21E4(REG_PlayerData) stw r3,0x21E8(REG_PlayerData) #Enter Into Backed Up State mr r3,REG_PlayerGObj lwz r4,0x10(REG_PlayerData_Backup) #backed up AS li r5,0x0 li r6,0x0 lfs f1,0x894(REG_PlayerData_Backup) #backed up Frame Number lfs f2,0x89C(REG_PlayerData_Backup) #backed up Frame Speed lfs f3,-0x7548 (rtoc) #lfs f3,0x8A4(REG_PlayerData_Backup) #backup up Blend Amount branchl r12,ActionStateChange #ASC #Keep Previous Frame Buttons From Current Block lwz r3,0x620(REG_PlayerData) stw r3,0xD0(sp) lwz r3,0x624(REG_PlayerData) stw r3,0xD4(sp) lwz r3,0x65C(REG_PlayerData) stw r3,0xD8(sp) #Keep Collision Bubble Toggles lwz r3,0x21FC(REG_PlayerData) stw r3,0xDC(sp) #Copy PlayerBlock Backup to Current mr r3,REG_PlayerData mr r4,REG_PlayerData_Backup mr r5,REG_PlayerDataSize branchl r12,memcpy #mempcy #Zero Blend #lfs f1,-0x7548 (rtoc) #stfs f1,0x8A4(REG_PlayerData) #Copy Static Block Backup to Current cmpwi REG_isSubchar,0 #but not if subcharacter bne Savestate_Load_SkipStaticBlockRestore load r3,0x80453080 #get static block in r3 li r4,0xE90 mullw r4,r4,REG_SpawnedOrder add r3,r3,r4 add r4,REG_PlayerDataSize,REG_PlayerData_Backup #get end of block in r4 li r5,0x100 #length is 0x100 branchl r12,memcpy #mempcy Savestate_Load_SkipStaticBlockRestore: #Restore Previous Frame Buttons From Current Block lwz r3,0xD0(sp) stw r3,0x620(REG_PlayerData) stw r3,0x628(REG_PlayerData) lwz r3,0xD4(sp) stw r3,0x624(REG_PlayerData) stw r3,0x62C(REG_PlayerData) lwz r3,0xD8(sp) stw r3,0x65C(REG_PlayerData) stw r3,0x660(REG_PlayerData) stw r3,0x664(REG_PlayerData) #Restore Collision Bubble Toggles lwz r3,0xDC(sp) stw r3,0x21FC(REG_PlayerData) #Remove Cached Animation Pointer (This fixes the Fall Animation Bug) li r3,0x0 stw r3,0x5A8(REG_PlayerData) #Remove Respawn Platform JObj Pointer and Think Function stw r3,0x20A0(REG_PlayerData) stw r3,0x21B0(REG_PlayerData) #Remove Held Item Pointer stw r3,0x1974(REG_PlayerData) #Update ECB Position mr r3,REG_PlayerGObj bl UpdatePosition #Stop Player's SFX mr r3,REG_PlayerData branchl r12,SFX_StopAllCharacterSFX #Stop Crowd SFX branchl r12,SFXManager_StopSFXIfPlaying #Remove GFX mr r3,REG_PlayerGObj branchl r12,GFX_RemoveAll /* #Removing this, causes ground issues when restoring. instead im removing the OSReport call for the error #If Grounded, Change Ground Variable Back lwz r3,0xE0(REG_PlayerData) cmpwi r3,0x0 bne Savestate_RestoreCameraFlag li r3,0x1 stw r3,0x83C(REG_PlayerData) */ #Restore Camera Flag Savestate_RestoreCameraFlag: add r3,REG_PlayerDataSize,REG_PlayerData_Backup #get end of block in r4 addi r3,r3,0x100 #static block length = 0x100 lwz r3,0x0(r3) #get flag lwz r4,0x890(REG_PlayerData) stw r3,0x8(r4) #Update Camera Box Position mr r3,REG_PlayerGObj bl UpdateCameraBox #Remake HUD For Dead Players (Taken from Achilles' GitHub) cmpwi REG_isSubchar,0x1 #dont run this on subcharacters beq SaveState_HUD_End load r3,0x804a10c8 #get base HUD info mulli r4,REG_SpawnedOrder,100 #get offset add r20,r4,r3 #get to this player's HUD info branchl r12,0x8016b094 #MatchInfo_StockModeCheck cmpwi r3,0 #if not stock mode beq- SaveState_RELOAD_PERCENT_HUDS_NOT_STOCK SaveState_RELOAD_PERCENT_HUDS_STOCK: mr r3,REG_SpawnedOrder #get player number branchl r12,0x80033bd8 #get stocks left cmpwi r3,0 bne- SaveState_RELOAD_PERCENT_HUDS_NOT_STOCK li r5,0x80 #remove percent stb r5,0x10(r20) b SaveState_HUD_End SaveState_RELOAD_PERCENT_HUDS_NOT_STOCK: lbz r5,0x10(r20) rlwinm. r5,r5,0,24,24 # (00000080), is player HUD percent gone? beq- SaveState_HUD_End SaveState_REMAKE_PERCENT: .set HUD_PlayerCreate_Prefunction, 0x802f6e1c mr r3,REG_SpawnedOrder branchl r4, HUD_PlayerCreate_Prefunction SaveState_HUD_End: SaveState_LoadLoopInc: #Check For Subchar Before Looping cmpwi REG_isSubchar,0x1 beq SaveState_LoadLoopInc_ToggleSubCharOff li REG_isSubchar,0x1 b SaveState_LoadLoop SaveState_LoadLoopInc_ToggleSubCharOff: li REG_isSubchar,0x0 addi REG_LoopCount,REG_LoopCount,0x1 cmpw REG_LoopCount,REG_PlayerTotal blt SaveState_LoadLoop SaveState_LoadEnd: /* SaveState_Load_RemoveAllGFX: #Get First GFX lwz r3,-0x3E74 (r13) lwz r20,0x30(r3) #Check if exists SaveState_Load_CheckIfGFXExists: cmpwi r20,0 beq SaveState_Load_RemoveAllGFXEnd #Check if this is a particle GObj? lbz r3,0x4(r20) cmpwi r3,1 beq SaveState_Load_GetNextGFX #Remove this GFX mr r3,r20 branchl r12,0x80390228 #Get next GFX SaveState_Load_GetNextGFX: lwz r20,0x8(r20) b SaveState_Load_CheckIfGFXExists SaveState_Load_RemoveAllGFXEnd: */ SaveState_LoadExit: restore blr ######################################################################### ############################ ## Get PlayerData Pointer ## ############################ SaveState_GetPlayerDataPointer: #r3 = player number (regardless of port) #r4 = 0x0 for main char // 0x1 for subchar #returns: #r3 = player slot #r4 = external player #r5 = internal player subi sp,sp,0x8 mr r11,r3 #move desired player into r11 mr r10,r4 #move subchar status into r4 mr r9,sp #move bytefield into r10 li r3,-0x1 #zero out new space stw r3,0x0(r9) stw r3,0x4(r9) #Make Bytefield For Player Order li r7,0x0 #init loop li r6,0x0 #init player ID load r5,0x80453080 #first playerblock SaveState_GetPlayerDataPointer_LoopStart: lwz r3,0x0(r5) #an inactive player block will store "0" at offset 0x0 cmpwi r3,0x0 beq SaveState_GetPlayerDataPointer_Empty SaveState_GetPlayerDataPointer_PlayerPresent: stbx r7,r6,r9 #store loop count to player ID offset addi r6,r6,0x1 #next player ID SaveState_GetPlayerDataPointer_Empty: addi r5,r5,0xe90 #next playerblock addi r7,r7,0x1 #inc loop cmpwi r7,6 blt SaveState_GetPlayerDataPointer_LoopStart #Now r9 contains player bytefield lbzx r3,r11,r9 #get the correct player slot for the X player cmpwi r3,0xFF #check if player exists beq SaveState_GetPlayerDataPointer_Exit #if not exit with -1 return load r5,0x80453080 #first playerblock mulli r4,r3,0xe90 #get offset add r4,r4,r5 #get static block in r4 cmpwi r10,0x0 beq SaveState_GetPlayerDataPointer_MainChar SaveState_GetPlayerDataPointer_SubChar: lwz r4,0xB4(r4) b SaveState_GetPlayerDataPointer_LoadInternal SaveState_GetPlayerDataPointer_MainChar: lwz r4,0xB0(r4) SaveState_GetPlayerDataPointer_LoadInternal: #Check If Player Exists cmpwi r4,0x0 bne SaveState_GetPlayerDataPointer_LoadInternalContinue li r3,0xFF b SaveState_GetPlayerDataPointer_Exit SaveState_GetPlayerDataPointer_LoadInternalContinue: lwz r5,0x2c(r4) SaveState_GetPlayerDataPointer_Exit: addi sp,sp,0x8 blr ####################################################### CheckForSaveAndLoad: .set LoopCount,31 backup mr r29,r3 #Task Data #Init Loop li LoopCount,0 #Loop CheckForSaveAndLoad_Loop: mr r3,LoopCount branchl r12,PlayerBlock_LoadMainCharDataOffset cmpwi r3,0x0 beq CheckForSaveAndLoad_Inc CheckForSaveAndLoad_CheckInputs: load r3,0x804c21cc #load r3,0x804c1fac mulli r0,LoopCount,68 add r4,r3,r0 #Make Sure Nothing Else Is Held lhz r3,0x2(r4) rlwinm. r0,r3,0,0,26 bne CheckForSaveAndLoad_Inc lwz r3,0x8(r4) rlwinm. r0,r3,0,30,30 beq CheckForSaveAndLoad_NoSave mr r3,r29 li r4,0 #run failsafe code bl SaveState_Save li r3,0x0 b CheckForSaveAndLoad_Exit CheckForSaveAndLoad_NoSave: rlwinm. r0,r3,0,31,31 beq CheckForSaveAndLoad_Inc mr r3,r29 bl SaveState_Load mr r3,r29 bl SaveState_Load li r3,0x1 b CheckForSaveAndLoad_Exit CheckForSaveAndLoad_Inc: addi LoopCount,LoopCount,1 cmpwi LoopCount,4 blt CheckForSaveAndLoad_Loop CheckForSaveAndLoad_Exit: restore blr ############################################ GiveFullShields: backup GiveFullShields_GetFirstPlayer: lwz r3, -0x3E74 (r13) lwz r20, 0x0020 (r3) b GiveFullShields_CheckIfPlayerExists GiveFullShields_GetNextPlayer: lwz r20,0x8(r20) GiveFullShields_CheckIfPlayerExists: cmpwi r20,0x0 beq GiveFullShields_Exit lwz r21,0x2C(r20) #Give Full Shield lwz r3, -0x514C (r13) lfs f0, 0x0260 (r3) stfs f0,0x1998(r21) b GiveFullShields_GetNextPlayer GiveFullShields_Exit: restore blr ############################################ UpdateAllGFX: backup mr r3,30 branchl r12,GFX_UpdatePlayerGFX #Check For Follower mr r3,r30 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq UpdateAllGFX_Exit #Apply To Follower Char branchl r12,GFX_UpdatePlayerGFX UpdateAllGFX_Exit: restore blr ############################################ GiveInvincibility: #r3 = ext pointer #r4 = frames backup #Give To Main Char mr r31,r3 mr r30,r4 branchl r12,ApplyInvincibility #Check For Follower mr r3,r31 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq GiveInvincibility_Exit #Apply To Follower Char mr r4,r30 branchl r12,ApplyInvincibility GiveInvincibility_Exit: restore blr ############################################ StoreCPUTypeAndZeroInputs: #Set P2 AI Type to None #li r3,0xF #stw r3,0x1A94(r29) #Clear Inputs For P2 CPU li r3,0x0 stw r3,0x1A88(r29) stw r3,0x1A8C(r29) sth r3,0x1A90(r29) blr ########################################### ClearNanaInputs: backup #Clear Inputs if P1 is Ice Climbers mr r3,28 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq ClearNanaInputs_P2 li r3,0x0 stw r3,0x1A88(r4) stw r3,0x1A8C(r4) #Clear Inputs if P2 is Ice Climbers ClearNanaInputs_P2: mr r3,30 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq ClearNanaInputs_Exit li r3,0x0 stw r3,0x1A88(r4) stw r3,0x1A8C(r4) ClearNanaInputs_Exit: restore blr ########################################### CheckIfFirstFrame: lwz r3,TM_GameFrameCounter(r13) cmpwi r3,0x1 bne CheckIfFirstFrame_False li r3,0x1 b CheckIfFirstFrame_Exit CheckIfFirstFrame_False: li r3,0x0 CheckIfFirstFrame_Exit: blr ############################################# CurrentInputsAsLastFramesInputs: load r3,0x804c21cc lwz r3,0x0(r3) stw r3,0x65C(r27) stw r3,0x664(r27) #Check For Z Press rlwinm. r0, r3, 0, 27, 27 beq CurrentInputsAsLastFramesInputs_Exit oris r0, r3, 0x8000 ori r0, r0, 0x0100 stw r0,0x65C(r27) stw r0,0x664(r27) CurrentInputsAsLastFramesInputs_Exit: blr ############################################# /* CPUActions_MultiShine: backup mr r29,r3 #Get AS and Frame Number lwz r4,0x10(r3) #Get Current AS #Start - Check to Grounded Shine cmpwi r4,0xE #Wait beq Multishine_StartShine cmpwi r4,0x169 #Shine Loop Ground beq Multishine_JumpCancelShine cmpwi r4,0x19 #JumpF beq Multishine_StartShine b CPUActions_MultiShine_Exit Multishine_StartShine: li r3,-127 #Down stb r3,0x1A8D(r29) #Analog Y li r3,0x200 #B stw r3,0x1A88(r29) #Inputs b CPUActions_MultiShine_Exit Multishine_JumpCancelShine: li r3,0x800 #X stw r3,0x1A88(r29) #Inputs b CPUActions_MultiShine_Exit Multishine_ShineAir: b CPUActions_MultiShine_Exit CPUActions_MultiShine_Exit: restore blr */ ################################### RAndDPadChangesEventOption: OptionWindow: #in #r3 = pointer to option byte in memory #r4 = pointer to Window and Option Count #r5 = pointer to ASCII struct #out #r3 = .set TextCreateFunction,0x80005928 .set OptionWindowMemory,20 .set OptionTextInfo,21 .set OptionASCII,22 .set text,23 .set toggledBool,28 .set toggledOption,29 backup #Backup Parameters mr OptionWindowMemory,r3 #pointer to option byte in memory mr OptionTextInfo,r4 #pointer to Window and Option Count mr OptionASCII,r5 #pointer to ASCII struct #Initialize Toggled Bools li toggledBool,0 li toggledOption,-1 #Get Number Of Options Onscreen At Once (1,2,or 3) lbz r24,0x0(OptionTextInfo) #Get Number of Different Windows cmpwi r24,2 #Check If Over 3 ble 0x8 li r24,2 #Make 3 #Get Pausing Player's Inputs load r3,0x8046b6a0 lbz r3,0x1(r3) load r4,0x804c1fac mulli r3,r3,68 add r3,r3,r4 lwz r3,0x8(r3) #Check For DPad Up And Down cmpwi r3,0x04 beq RAndDPadChangesEventOption_CursorDown cmpwi r3,0x08 beq RAndDPadChangesEventOption_CursorUp b RAndDPadChangesEventOption_CheckDPadLeftAndRight RAndDPadChangesEventOption_CursorUp: #Update Cursor Position lbz r3,0x0(OptionWindowMemory) #Get Current Cursor Position Byte subi r3,r3,0x1 #Subtract by 1 stb r3,0x0(OptionWindowMemory) cmpwi r3,0x0 bge RAndDPadChangesEventOption_PlayScrollSFX #Cursor Stays at the top of the screen li r3,0 stb r3,0x0(OptionWindowMemory) #Check To Scroll Down #Get Current Window ID (cursor + scroll) lbz r3,0x0(OptionWindowMemory) lbz r4,0x1(OptionWindowMemory) add r3,r3,r4 #Check If This is the Beginning cmpwi r3,0 ble RAndDPadChangesEventOption_DisplayWindow #Scroll Down lbz r4,0x1(OptionWindowMemory) subi r4,r4,1 stb r4,0x1(OptionWindowMemory) b RAndDPadChangesEventOption_PlayScrollSFX b RAndDPadChangesEventOption_DisplayWindow RAndDPadChangesEventOption_CursorDown: #Update Cursor Position lbz r3,0x0(OptionWindowMemory) #Get Current Option Byte addi r3,r3,0x1 #Add 1 stb r3,0x0(OptionWindowMemory) cmpw r3,r24 ble RAndDPadChangesEventOption_PlayScrollSFX #Cursor Stays at the Bottom of the Screen stb r24,0x0(OptionWindowMemory) #Check To Scroll Down #Get Current Window ID (cursor + scroll) lbz r3,0x0(OptionWindowMemory) lbz r4,0x1(OptionWindowMemory) add r3,r3,r4 #Get Max Number Of Windows lbz r4,0x0(OptionTextInfo) #Get Number of Different Windows #Check If This is the End cmpw r3,r4 bge RAndDPadChangesEventOption_DisplayWindow #Scroll Down lbz r4,0x1(OptionWindowMemory) addi r4,r4,1 stb r4,0x1(OptionWindowMemory) b RAndDPadChangesEventOption_PlayScrollSFX #Check For DPad Left And Right RAndDPadChangesEventOption_CheckDPadLeftAndRight: cmpwi r3,0x02 beq RAndDPadChangesEventOption_Increment cmpwi r3,0x01 beq RAndDPadChangesEventOption_Decrement b RAndDPadChangesEventOption_DisplayWindow RAndDPadChangesEventOption_Increment: #Get Current Window ID (cursor + scroll) lbz r3,0x0(OptionWindowMemory) lbz r4,0x1(OptionWindowMemory) add r3,r3,r4 #Set as Toggled li toggledBool,1 mr toggledOption,r3 addi r5,r3,2 lbzx r3,r5,OptionWindowMemory #Get Current Option Byte addi r3,r3,0x1 stbx r3,r5,OptionWindowMemory #Store New Option Byte Value subi r5,r5,1 lbzx r4,r5,OptionTextInfo #Get Window's Option Byte Max Value cmpw r3,r4 ble RAndDPadChangesEventOption_PlayScrollSFX li r3,0x0 addi r5,r5,1 stbx r3,r5,OptionWindowMemory #Get New Option Byte Value b RAndDPadChangesEventOption_PlayScrollSFX RAndDPadChangesEventOption_Decrement: #Get Current Window ID (cursor + scroll) lbz r3,0x0(OptionWindowMemory) lbz r4,0x1(OptionWindowMemory) add r3,r3,r4 #Set as Toggled li toggledBool,1 mr toggledOption,r3 addi r5,r3,0x2 lbzx r3,r5,OptionWindowMemory #Get Current Option Byte subi r3,r3,0x1 stbx r3,r5,OptionWindowMemory #Store New Option Byte Value cmpwi r3,0x0 bge RAndDPadChangesEventOption_PlayScrollSFX subi r5,r5,1 lbzx r3,r5,OptionTextInfo #Get Window's Option Byte Max Value addi r5,r5,1 stbx r3,r5,OptionWindowMemory #Store New Option Byte Value b RAndDPadChangesEventOption_PlayScrollSFX RAndDPadChangesEventOption_PlayScrollSFX: li r3,0x2 branchl r12,SFX_MenuCommonSound RAndDPadChangesEventOption_DisplayWindow: #Display Text For The New Option Value mr r3,r27 #p1 (no offsetting window) li r4,1 #text timeout li r5,0x2 #window instance #3 li r6,0 #window ID #3 branchl r12,TextCreateFunction #create text custom function mr text,r3 #backup text pointer ######################### ## Display Option Menu ## ######################### #Check How Many Options In The Menu cmpwi r24,0 beq RAndDPadChangesEventOption_DisplayWindow_LoopInit #Change Background Size bl RAndDPadChangesEventOption_Floats mflr r5 lfs f1,0x0(r5) #12.5 addi r5,r5,0x4 #Skip Window X subi r6,r24,1 #Zero Index mulli r6,r6,0x4 #Get Y Offset lfsx f2,r6,r5 li r4,0 branchl r12,Text_UpdateSubtextSize #Move Window bl RAndDPadChangesEventOption_Floats mflr r5 lfs f1, -0x37B4 (rtoc) addi r5,r5,0xC #Skip Window X and Window Y's subi r6,r24,1 #Zero Index mulli r6,r6,0x4 #Get Y Offset lfsx f2,r6,r5 mr r3,text li r4,0 branchl r12,Text_UpdateSubtextPosition ############################ ## Display Up/Down Arrows ## ############################ #Check if at the top of the screen lbz r3,0x1(r20) cmpwi r3,0x0 beq RAndDPadChangesEventOption_DisplayDownArrow #Create Title Text li r3,-20 #Y bl IntToFloat fmr f2,f1 li r3,-210 #X bl IntToFloat mr r3,text #text pointer bl RAndDPadChangesEventOption_UpArrowText mflr r4 branchl r12,Text_InitializeSubtext RAndDPadChangesEventOption_DisplayDownArrow: #Check if at the bottom of the screen lbz r3,0x0(r21) cmpwi r3,2 blt RAndDPadChangesEventOption_DisplayArrowExit lbz r4,0x1(r20) sub r3,r3,r4 cmpwi r3,2 ble RAndDPadChangesEventOption_DisplayArrowExit #Create Title Text li r3,320 #Y value bl IntToFloat fmr f2,f1 li r3,-210 #X Value bl IntToFloat mr r3,text #text pointer bl RAndDPadChangesEventOption_DownArrowText mflr r4 branchl r12,Text_InitializeSubtext RAndDPadChangesEventOption_DisplayArrowExit: ############################ ## Print Each Option Loop ## ############################ RAndDPadChangesEventOption_DisplayWindow_LoopInit: li r27,0 #Init Loop RAndDPadChangesEventOption_DisplayWindow_Loop: #Get Window Title And Option mr r3,OptionASCII #Option ASCII Start lbz r4,0x1(OptionWindowMemory) #Get Scroll Position add r4,r4,r27 #Get Loop Count's Window addi r5,OptionWindowMemory,0x2 #Selection ID's lbzx r5,r4,r5 #Get Current Option This Window is On bl RAndDPadChangesEventOption_GetOptionASCII mr r25,r3 mr r26,r4 #Create Title Text lfs f2, -0x37B4 (rtoc) #default text Y li r3,120 mullw r3,r3,r27 bl IntToFloat fadds f2,f1,f2 lfs f1, -0x37B4 (rtoc) #default text X mr r3,text #text pointer mr r4,r25 #Title Text Pointer branchl r12,Text_InitializeSubtext #Make Text Grey load r4,0xdfdfdf00 stw r4,0xF0(sp) addi r5,sp,0xF0 mr r4,r3 mr r3,text branchl r12,Text_ChangeTextColor #Create Selection Text lfs f2, -0x37B0 (rtoc) #shift down on Y axis li r3,120 mullw r3,r3,r27 bl IntToFloat fadds f2,f1,f2 lfs f1, -0x37B4 (rtoc) #default text X/Y mr r3,text #text pointer mr r4,r26 #Selection Text branchl r12,Text_InitializeSubtext #Check To Outline in Yellow lbz r4,0x0(OptionWindowMemory) #Get Cursor Position cmpw r4,r27 #Compare With Loop Counter bne RAndDPadChangesEventOption_DisplayWindow_SkipColor load r4,0xf7ff2700 stw r4,0xF0(sp) addi r5,sp,0xF0 mr r4,r3 mr r3,text branchl r12,Text_ChangeTextColor RAndDPadChangesEventOption_DisplayWindow_SkipColor: cmpw r27,r24 addi r27,r27,1 blt RAndDPadChangesEventOption_DisplayWindow_Loop b RAndDPadChangesEventOption_Exit ######################################### RAndDPadChangesEventOption_GetOptionASCII: backup mr r31,r3 #Option ASCII Start mr r30,r4 #Option ID We're Looking For mr r29,r5 #Option Selection We're Looking For #Init Loop li r27,0 RAndDPadChangesEventOption_GetOptionASCII_OptionIDLoop: cmpw r27,r30 #Check If This is the Window We're Looking For beq RAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection ######################## ## Skip Entire Option ## ######################## RAndDPadChangesEventOption_GetOptionASCII_GetNextOptionID: #Skip Past Window Title mr r3,r31 bl RAndDPadChangesEventOption_GetNextString mr r31,r3 #Backup New Pointer #Loop Through All The Window's Selections li r26,0 #Loop Count RAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections: #Get This Options (r27) Total Number of Selections (Pointer in OptionTextInfo) addi r3,OptionTextInfo,0x1 #Get to Option Selection Counts lbzx r3,r3,r27 #Get This Windows Total Number of Selections addi r3,r3,0x1 #Add 1 To Ensure We Are at the Start of the Next Window Title cmpw r3,r26 #Check If This is the Last Selection bne RAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections_NextSelection #End of Loop, Done With This Option #Increment Loop Count addi r27,r27,1 #Increment Option Count b RAndDPadChangesEventOption_GetOptionASCII_OptionIDLoop RAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections_NextSelection: #Get Next Selection mr r3,r31 bl RAndDPadChangesEventOption_GetNextString mr r31,r3 #Backup New Pointer #Increment Loop Count addi r26,r26,1 b RAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections ########################### ## Find Option Selection ## ########################### RAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection: #Init Loop Count + Backup Window Title li r26,0 #Init Loop Count mr r25,r31 #r25 = Window Title #Skip Window Title mr r3,r31 bl RAndDPadChangesEventOption_GetNextString mr r31,r3 #Backup New Pointer RAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Loop: #Check If This is the Selection We're Looking For cmpw r26,r29 beq RAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Done #Get Next Selection #Strlen the entry mr r3,r31 bl RAndDPadChangesEventOption_GetNextString mr r31,r3 #Backup New Pointer #Increment Loop Count addi r26,r26,1 b RAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Loop RAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Done: mr r3,r25 #Return Window Name mr r4,r31 #Return Selection String RAndDPadChangesEventOption_GetOptionASCII_Exit: restore blr ######################################### RAndDPadChangesEventOption_GetNextString: backup mr r31,r3 #Backup String Pointer branchl r12,strlen #Get Length add r3,r3,r31 #Get End of String #From here, mini loop to find the next non-zero value. RAndDPadChangesEventOption_GetNextString_Loop: lbzu r4,0x1(r3) cmpwi r4,0x0 beq RAndDPadChangesEventOption_GetNextString_Loop restore blr ######################################### RAndDPadChangesEventOption_Floats: blrl .float 16 #12.5, X position .long 0x427c0000 #63, 2 Window Y Scale .long 0x42bc0000 #94, 3 Window Y Scale .long 0xc4610000 #-900, 2 Window Y position .long 0xc4a8c000 #-1350, 3 Window Y position ######################################### RAndDPadChangesEventOption_UpArrowText: blrl .string "^" .align 2 RAndDPadChangesEventOption_DownArrowText: blrl .string "v" .align 2 ######################################### RAndDPadChangesEventOption_Exit: mr r3,toggledBool mr r4,toggledOption restore blr ################################## DPadCPUPercent: backup .set REG_SaveStruct,31 .set REG_PercentInt,30 .set REG_isSubcharBool,29 #Backup savestate struct mr REG_SaveStruct,r3 #Get P1 Block li r3,0x0 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block lwz r3,0x2C(r3) #Get P2 Percent load r6,0x80453F10 lhz REG_PercentInt,0x60(r6) #Get Subchar Bool lbz REG_isSubcharBool,0xC(r6) #Get inputs load r4,0x804c21cc lbz r3,0x618(r3) mulli r0,r3,68 add r5,r4,r0 #Make Sure L Is Held lwz r3,0x0(r5) #get held inputs rlwinm. r0,r3,0,25,25 beq DPadCPUPercent_Exit #Check DPad lwz r3,0xC(r5) #get rapid inputs rlwinm. r0,r3,0,30,30 bne DPadCPUPercent_IncByOne rlwinm. r0,r3,0,31,31 bne DPadCPUPercent_DecByOne rlwinm. r0,r3,0,28,28 bne DPadCPUPercent_IncByTen rlwinm. r0,r3,0,29,29 bne DPadCPUPercent_DecByTen b DPadCPUPercent_Exit DPadCPUPercent_IncByOne: cmpwi REG_PercentInt,999 blt DPadCPUPercent_IncByOneReal li REG_PercentInt,999 b DPadCPUPercent_StorePercent DPadCPUPercent_IncByOneReal: addi REG_PercentInt,REG_PercentInt,0x1 b DPadCPUPercent_StorePercent DPadCPUPercent_DecByOne: cmpwi REG_PercentInt,0 bgt DPadCPUPercent_DecByOneReal li REG_PercentInt,0 b DPadCPUPercent_StorePercent DPadCPUPercent_DecByOneReal: subi REG_PercentInt,REG_PercentInt,0x1 b DPadCPUPercent_StorePercent DPadCPUPercent_IncByTen: cmpwi REG_PercentInt,989 blt DPadCPUPercent_IncByTenReal li REG_PercentInt,999 b DPadCPUPercent_StorePercent DPadCPUPercent_IncByTenReal: addi REG_PercentInt,REG_PercentInt,10 b DPadCPUPercent_StorePercent DPadCPUPercent_DecByTen: cmpwi REG_PercentInt,9 bgt DPadCPUPercent_DecByTenReal li REG_PercentInt,0 b DPadCPUPercent_StorePercent DPadCPUPercent_DecByTenReal: subi REG_PercentInt,REG_PercentInt,10 b DPadCPUPercent_StorePercent DPadCPUPercent_StorePercent: #Store to Active Static Playerblock sth REG_PercentInt,0x60(r6) #Convert to Float mr r3,REG_PercentInt bl IntToFloat #Active PlayerData li r3,0x1 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block lwz r3,0x2C(r3) stfs f1,0x1830(r3) #Backed Up PlayerData mulli r4,REG_isSubcharBool,0x4 lwzx r3,r4,REG_SaveStruct stfs f1,0x1830(r3) #Backed Up Static Playerblock load r4,0x80458fd0 #get player block length lwz r4,0x20(r4) #get player block length lwz r3,0x0(REG_SaveStruct) #only the main character has a static block backup add r3,r3,r4 #static block start sth REG_PercentInt,0x60(r3) sth REG_PercentInt,0x62(r3) DPadCPUPercent_Exit: restore blr ################################## InitializePositions: backup #Move Float Pointer mr r20,r3 #P1 Static Block load r22,0x80453080 #P2 Static Block addi r23,r22,0xE90 #Move P1 mr r3,r28 branchl r12,0x8008a2bc #Enter Wait lfs f1,0x0(r20) stfs f1,0xB0(r27) lfs f1,0x8(r20) stfs f1,0xB4(r27) mr r3,r28 bl UpdatePosition mr r3,r28 bl UpdateCameraBox mr r3,r28 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq InitializePositions_MoveP2 #Move This Char Too mr r24,r3 mr r25,r4 mr r3,r24 branchl r12,0x8008a2bc #Enter Wait lfs f1,0x0(r20) stfs f1,0xB0(r25) lfs f1,0x8(r20) stfs f1,0xB4(r25) mr r3,r24 bl UpdatePosition mr r3,r24 bl UpdateCameraBox #Move P2 InitializePositions_MoveP2: mr r3,r30 branchl r12,0x8008a2bc #Enter Wait lfs f1,0x4(r20) stfs f1,0xB0(r29) lfs f1,0xC(r20) stfs f1,0xB4(r29) mr r3,r30 bl UpdatePosition mr r3,r30 bl UpdateCameraBox mr r3,r30 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq InitializePositions_Exit #Move This Char Too mr r24,r3 mr r25,r4 mr r3,r24 branchl r12,0x8008a2bc #Enter Wait lfs f1,0x4(r20) stfs f1,0xB0(r25) lfs f1,0xC(r20) stfs f1,0xB4(r25) mr r3,r24 bl UpdatePosition mr r3,r24 bl UpdateCameraBox InitializePositions_Exit: bl ClearNanaInputs bl CurrentInputsAsLastFramesInputs restore blr ######################################################### CheckIfPlayerHasAFollower: #Returns #r3 = 0 for no follower // External Pointer #r4 = 0 for no follower // Internal Pointer backup #Get Players Data lwz r31,0x2C(r3) #Get Player Slot lbz r3,0xC(r31) li r4,0x1 bl SaveState_GetPlayerDataPointer #returns r3=Slot/-1 if subchar doesnt exist, r4= external, r5=internal cmpwi r3,0xFF beq CheckIfPlayerHasAFollower_NoFollower #Check If Follower mr r24,r4 mr r25,r5 lbz r3,0xC(r25) #get slot branchl r12,0x80032330 #get external character ID load r4,pdLoadCommonData #pdLoadCommonData table mulli r0, r3, 3 #struct length add r3,r4,r0 #get characters entry lbz r0, 0x2 (r3) #get subchar functionality cmpwi r0,0x0 #if not a follower, exit bne CheckIfPlayerHasAFollower_NoFollower #Return Follower Pointers mr r3,r24 #External mr r4,r25 #Internal b CheckIfPlayerHasAFollower_Exit CheckIfPlayerHasAFollower_NoFollower: li r3,0x0 li r4,0x0 CheckIfPlayerHasAFollower_Exit: restore blr ######################################################### Randomize_LeftorRightSide: #r3 = 0 = Same Side of Stage // 1 = Opposing Sides of Stage backup mr r20,r3 #Backup Stage Side Bool #Get Left or Right Side li r3,2 branchl r12,HSD_Randi #Check To Negate cmpwi r3,0x0 #0 = Left, 1 = Right bne Randomize_RightSide Randomize_LeftSide: #P1 X Position lwz r3,0x10(r31) #P1 Backup Start lwz r4,0x18(r31) #P2 Backup Start lfs f1,0xB0(r3) #P1 Backup X Pos cmpwi r20,0x0 beq 0xC bl Randomize_AlwaysNegative b 0x8 bl Randomize_AlwaysNegative stfs f1,0xB0(r3) #P1 Backup X Pos #P2 X Position lfs f1,0xB0(r4) #P2 Backup X Pos cmpwi r20,0x0 beq 0xC bl Randomize_AlwaysPositive b 0x8 bl Randomize_AlwaysNegative stfs f1,0xB0(r4) #P2 Backup X Pos #Facing Directions lis r5,0x3f80 #P1 Face Right lis r6,0xbf80 #P2 Face Left stw r5,0x2C(r3) #P1 Backup Facing stw r6,0x2C(r4) #P2 Facing b Randomize_LeftorRightSide_CheckForFollowers Randomize_RightSide: #P1 X Position lwz r3,0x10(r31) #P1 Backup Start lwz r4,0x18(r31) #P2 Backup Start lfs f1,0xB0(r3) #P1 Backup X Pos cmpwi r20,0x0 beq 0xC bl Randomize_AlwaysPositive b 0x8 bl Randomize_AlwaysPositive stfs f1,0xB0(r3) #P1 Backup X Pos #P2 X Position lfs f1,0xB0(r4) #P2 Backup X Pos cmpwi r20,0x0 beq 0xC bl Randomize_AlwaysNegative b 0x8 bl Randomize_AlwaysPositive stfs f1,0xB0(r4) #P2 Backup X Pos #Facing Directions lis r5,0xbf80 #P1 Face Left lis r6,0x3f80 #P2 Face Right stw r5,0x2C(r3) #P1 Backup Facing stw r6,0x2C(r4) #P2 Facing Randomize_LeftorRightSide_CheckForFollowers: Randomize_LeftorRightSide_GetFirstPlayer: lwz r3, -0x3E74 (r13) lwz r20, 0x0020 (r3) b Randomize_LeftorRightSide_CheckIfPlayerExists Randomize_LeftorRightSide_GetNextPlayer: lwz r20,0x8(r20) Randomize_LeftorRightSide_CheckIfPlayerExists: cmpwi r20,0x0 beq Randomize_LeftorRightSide_Exit lwz r21,0x2C(r20) #Check If This Fighter is a Main Char lbz r3,0x221F(r21) rlwinm. r0, r3, 29, 31, 31 bne Randomize_LeftorRightSide_GetNextPlayer #Check For Follower, r20 = External. r21 = Internal mr r3,r20 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 #No Follower, Go To Next Player beq Randomize_LeftorRightSide_GetNextPlayer #Transfer Info #Get Backups addi r3,r31,0x10 #Get Backup Start lbz r4,0xC(r21) #Get Subchars Slot mulli r4,r4,0x8 #Each Slot has 2 backups, so get to this slots backup add r3,r3,r4 #Each Slot has 2 backups, so get to this slots backup #Copy Main Char's Info Into Subchars lwz r4,0x0(r3) #Main Char Backup lwz r5,0x4(r3) #Follower Backup lwz r3,0xB0(r4) #Main Char X stw r3,0xB0(r5) #Into Subchar X lwz r3,0x2C(r4) #Main Char Facing stw r3,0x2C(r5) #Into Subchar Facing b Randomize_LeftorRightSide_GetNextPlayer Randomize_LeftorRightSide_Exit: restore blr #********************************************# Randomize_AlwaysPositive: fabs f1,f1 #Always Positive blr Randomize_AlwaysNegative: fabs f1,f1 fneg f1,f1 #Always Negative blr #********************************************# ############################################ IntToFloat: mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) stfs f2,0x38(r1) lis r0, 0x4330 lfd f2, -0x6758 (rtoc) xoris r3, r3,0x8000 stw r0,0xF0(sp) stw r3,0xF4(sp) lfd f1,0xF0(sp) fsubs f1,f1,f2 #Convert To Float lfs f2,0x38(r1) lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 blr ############################################ GetDirectionInRelationToP1: #Get P1 Direction lfs f1,0xB0(r27) lfs f2,0xB0(r29) fsubs f1,f1,f2 lfs f2, -0x6768 (rtoc) fcmpo cr0,f2,f1 blt 0xC li r3,1 b 0x8 li r3,-1 blr ############################################ IsAnyoneDead: backup IsAnyoneDead_GetFirstPlayer: lwz r3, -0x3E74 (r13) lwz r20, 0x0020 (r3) b IsAnyoneDead_CheckIfPlayerExists IsAnyoneDead_GetNextPlayer: lwz r20,0x8(r20) IsAnyoneDead_CheckIfPlayerExists: cmpwi r20,0x0 bne IsAnyoneDead_GetPlayerData #Exit If No Other Players li r3,0x0 b IsAnyoneDead_Exit IsAnyoneDead_GetPlayerData: lwz r21,0x2C(r20) #Check If Follower lbz r3,0x221F(r21) rlwinm. r0,r3,0,28,28 bne IsAnyoneDead_GetNextPlayer #Check If Dead lbz r3,0x221F(r21) rlwinm. r0,r3,0,25,25 beq IsAnyoneDead_GetNextPlayer li r3,0x1 b IsAnyoneDead_Exit IsAnyoneDead_Exit: restore blr ############################################ ResetStaleMoves: backup ResetStaleMoves_GetFirstPlayer: lwz r3, -0x3E74 (r13) lwz r20, 0x0020 (r3) b ResetStaleMoves_CheckIfPlayerExists ResetStaleMoves_GetNextPlayer: lwz r20,0x8(r20) ResetStaleMoves_CheckIfPlayerExists: cmpwi r20,0x0 bne ResetStaleMoves_GetPlayerData #Exit If No Other Players li r3,0x0 b ResetStaleMoves_Exit ResetStaleMoves_GetPlayerData: lwz r21,0x2C(r20) #Reset Stale Moves #Get Stale Move Table lbz r3,0xC(r21) #Get Slot branchl r12,0x80036244 #Get This Players Stale Table #Fill With 0's li r4,0x2C branchl r12,ZeroAreaLength b ResetStaleMoves_GetNextPlayer ResetStaleMoves_Exit: restore blr ############################################ ActOutOfLaserHitDisplay: backup #Check If In Run lwz r3,0x10(r27) cmpwi r3,0x14 bne ActOutOfLaserHitDisplayExit #Check If Frame 2 li r3,2 bl IntToFloat lfs f2,0x894(r27) fcmpo cr0,f2,f1 bne ActOutOfLaserHitDisplayExit #Search Prev AS For Laser Hit, returns r3=AS's Since Laser Hit or -1 for didnt happen li r3,0x0 #Number of AS's ago addi r4,r27,0x23F0 #First Prev AS subi r4,r4,0x2 ActOutOfLaserHitDisplay_SearchLoop: addi r3,r3,0x1 lhzu r5,0x2(r4) cmpwi r5,0x4E #Laser Hit beq ActOutOfLaserHitDisplay_ExitLoop cmpwi r5,0x4B #Laser Hit beq ActOutOfLaserHitDisplay_ExitLoop cmpwi r3,0x3 beq ActOutOfLaserHitDisplay_NoLaserHit b ActOutOfLaserHitDisplay_SearchLoop ActOutOfLaserHitDisplay_NoLaserHit: li r3,-1 ActOutOfLaserHitDisplay_ExitLoop: cmpwi r3,-1 beq ActOutOfLaserHitDisplayExit ActOutOfLaserHitDisplay_CountFrameInit: #Get Amount Of Frames Since Laser Hit Ended li r5,0x23FC #As's Frame Count offset li r20,0 #Frames Since Laser Hit ActOutOfLaserHitDisplay_CountFrameLoop: cmpwi r3,0 #Check If Done Counting beq ActOutOfLaserHitDisplay_CountFrameLoopFinish mulli r4,r3,2 #Frame Count Offset subi r4,r4,0x2 #1 AS Before add r4,r4,r5 #Get Offset in Playerblock lhzx r6,r4,r27 #Get Frame Count Value subi r4,r4,0xC #Get AS Associated With It lhzx r4,r4,r27 #Get AS ID #Check If This AS is Turn cmpwi r4,0x12 beq 0x8 add r20,r20,r6 #Add To Toal cmpwi r4,0x4E beq ActOutOfLaserHitDisplay_SubtractHitstun cmpwi r4,0x4B beq ActOutOfLaserHitDisplay_SubtractHitstun b ActOutOfLaserHitDisplay_SkipSubtractHitstun ActOutOfLaserHitDisplay_SubtractHitstun: subi r20,r20,0x8 ActOutOfLaserHitDisplay_SkipSubtractHitstun: subi r3,r3,1 b ActOutOfLaserHitDisplay_CountFrameLoop ActOutOfLaserHitDisplay_CountFrameLoopFinish: ActOutOfLaserHitDisplay_DisplayOSD: mr r3,r27 #p1 (no offsetting window) li r4,120 #text timeout li r5,0 #Area to Display (0-2) li r6,OSD.Miscellaneous #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr text,r3 #backup text pointer cmpwi r20,0x1 beq ActOutOfLaserHitDisplay_Perfect ActOutOfLaserHitDisplay_Late: load r3,0xffa2baff #Red b ActOutOfLaserHitDisplay_StoreTextColor ActOutOfLaserHitDisplay_Perfect: load r3,0x8dff6eff #green ActOutOfLaserHitDisplay_StoreTextColor: stw r3,0x30(text) #Create Text 1 mr r3,text #text pointer bl ActOutOfLaserHitDisplay_TopText mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,Text_InitializeSubtext #Create Text 2 mr r3,text #text pointer bl ActOutOfLaserHitDisplay_BottomText mflr r4 mr r5,r20 #Frame Count lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #default text X/Y branchl r12,Text_InitializeSubtext ActOutOfLaserHitDisplayExit: restore blr ##################### ## Text Properties ## ##################### ActOutOfLaserHitDisplay_TextProperties: blrl .long 0xC1A80000 #Whether to Use HUD Location, 0 = no .long 0x41100000 #Y Value .long 0x41600000 #X Difference Between Players .long 0x3D23D70A #Text Size .long 0xC3CD0000 #background Y position .long 0x4129999A #background X stretch .long 0x41E00000 #background Y stretch ############## ## Top Text ## ############## ActOutOfLaserHitDisplay_TopText: blrl .long 0x44617368 .long 0x204f6f4c .long 0x61736572 .long 0x48697400 ################# ## Bottom Text ## ################# ActOutOfLaserHitDisplay_BottomText: blrl .long 0x4672616d .long 0x65202564 .long 0x ############################################ MoveCPU: #in #r3 = P1 GObj #r4 = P2 GObj #r5 = SaveState Struct .set P1GObj,31 .set P1Data,30 .set P2GObj,29 .set P2Data,28 .set SaveStateStruct,27 .set P2Subchar,26 .set P2SubcharData,25 backup #Get Variables mr P1GObj,r3 lwz P1Data,0x2C(P1GObj) mr P2GObj,r4 lwz P2Data,0x2C(P2GObj) mr SaveStateStruct,r5 #Get Input lbz r4, 0x0618 (P1Data) load r3,InputStructStart mulli r0, r4, 68 add r5, r0, r3 #Check DPad Down lwz r3,0xC(r5) rlwinm. r0,r3,0,29,29 beq MoveCPUExit #Make Sure Nothing Is Held lwz r3,0x0(r5) li r4,0 rlwimi r3,r4,0,29,29 #except dpad down rlwimi r3,r4,0,27,27 #except Z (cause frame advance) cmpwi r3,0 bne MoveCPUExit #Make Sure Player is Grounded lwz r3,0xE0(P1Data) cmpwi r3,0x0 bne MoveCPU_NoGroundFound #Get Position li r3,10 bl IntToFloat #Offset from P1 lfs f3,0xB0(P1Data) #P1 X lfs f2,0xB4(P1Data) #P1 Y lfs f4,0x2C(P1Data) #Facing Direction fmuls f1,f1,f4 fadds f1,f1,f3 #Check If P2 Will Be Grounded li r3,0 bl FindGroundNearPlayer cmpwi r3,0 #Check if ground was found beq MoveCPU_NoGroundFound stfs f1,0xB0(P2Data) stfs f2,0xB4(P2Data) stw r4,0x83C(P2Data) lfs f1,0x2C(P1Data) fneg f1,f1 stfs f1,0x2C(P2Data) #Enter Wait mr r3,P2GObj branchl r12,AS_Wait #Update Position mr r3,P2GObj bl UpdatePosition #Update ECB Values for the ground ID mr r3,P2GObj branchl r12,EnvironmentCollision_WaitLanding #Set Grounded mr r3,P2Data branchl r12,Air_SetAsGrounded #Check For Follower mr r3,P2GObj bl CheckIfPlayerHasAFollower cmpwi r3,0 beq MoveCPU_NoFollower mr P2Subchar,r3 mr P2SubcharData,r4 #Init Player Data Values (So CPU Init is called and nana knows where popp is) mr r3,P2Subchar branchl r12,0x80068354 #Copy Positions lfs f1,0xB0(P2Data) stfs f1,0xB0(P2SubcharData) lfs f1,0xB4(P2Data) stfs f1,0xB4(P2SubcharData) lwz r3,0x83C(P2Data) stw r3,0x83C(P2SubcharData) lfs f1,0x2C(P2Data) stfs f1,0x2C(P2SubcharData) #Enter Wait mr r3,P2Subchar branchl r12,AS_Wait #Update Position mr r3,P2Subchar bl UpdatePosition #Update ECB Values for the ground ID mr r3,P2Subchar branchl r12,EnvironmentCollision_WaitLanding #Set Grounded mr r3,P2SubcharData branchl r12,Air_SetAsGrounded MoveCPU_NoFollower: #Savestate mr r3,SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Play SFX li r3,0xDD bl PlaySFX b MoveCPUExit MoveCPU_NoGroundFound: #PLay Error SFX li r3,0xAF bl PlaySFX MoveCPUNoSubchar: MoveCPUExit: restore blr ############################################ AdjustResetDistance: .set SaveStateStruct,25 .set P2Direction,3 .set PlayerX,2 .set P1X,31 .set P2X,30 backup mr SaveStateStruct,r3 #Make Sure Nothing is Held lhz r3,0x662(r27) rlwinm. r0,r3,0,27,27 bne 0xC cmpwi r3,0x0 bne AdjustResetDistance_NoPress #Check For DPad Right AdjustResetDistance_CheckRightDPad: lwz r3,0x668(r27) #Get DPad rlwinm. r0,r3,0,30,30 beq AdjustResetDistance_CheckLeftDPad #Move Apart #Determine if P2 is to the left or right of P1 + Get X Pos Multiplier bl GetDirectionInRelationToP1 bl IntToFloat fmr P2Direction,f1 #Load P1 Backup X Location lwz r20,0x0(SaveStateStruct) lfs PlayerX,0xB0(r20) #Add One in the correct direction li r3,1 bl IntToFloat fneg P2Direction,P2Direction fmuls f1,f1,P2Direction fadds P1X,f1,PlayerX #New P1 X #Load P2 Backup X Location lwz r21,0x8(SaveStateStruct) lfs PlayerX,0xB0(r21) #Add One in the correct direction li r3,1 bl IntToFloat fneg P2Direction,P2Direction fmuls f1,f1,P2Direction fadds P2X,f1,PlayerX #New P2 X #Check if already 30 Mm apart fsubs f2,P1X,P2X fabs f2,f2 #get abs distance from each other in f2 li r3,30 bl IntToFloat fcmpo cr0,f2,f1 bge AdjustResetDistance_NoPress #Store Back To PlayerBlock stfs P1X,0xB0(r20) stfs P2X,0xB0(r21) b AdjustResetDistance_WasPressed #Check For DPad Left AdjustResetDistance_CheckLeftDPad: rlwinm. r0,r3,0,31,31 beq AdjustResetDistance_NoPress #Move Together #Determine if P2 is to the left or right of P1 + Get X Pos Multiplier bl GetDirectionInRelationToP1 bl IntToFloat fmr P2Direction,f1 #Load P1 Backup X Location lwz r20,0x0(SaveStateStruct) lfs PlayerX,0xB0(r20) #Add One in the correct direction li r3,1 bl IntToFloat #fneg P2Direction,P2Direction fmuls f1,f1,P2Direction fadds P1X,f1,PlayerX #New P1 X #Load P2 Backup X Location lwz r21,0x8(SaveStateStruct) lfs PlayerX,0xB0(r21) #Add One in the correct direction li r3,1 bl IntToFloat fneg P2Direction,P2Direction fmuls f1,f1,P2Direction fadds P2X,f1,PlayerX #New P2 X #Check if already 10 Mm apart fsubs f2,P1X,P2X fabs f2,f2 #get abs distance from each other in f2 li r3,10 bl IntToFloat fcmpo cr0,f2,f1 ble AdjustResetDistance_NoPress #Store Back To PlayerBlock stfs P1X,0xB0(r20) stfs P2X,0xB0(r21) b AdjustResetDistance_WasPressed AdjustResetDistance_NoPress: li r3,-1 b AdjustResetDistance_Exit AdjustResetDistance_WasPressed: li r3,1 AdjustResetDistance_Exit: restore blr ############################################ CheckForActiveHitboxes: backup lwz r31,0x2C(r3) CheckForActiveHitboxes_InitLoop: li r29,0x0 CheckForActiveHitboxes_LoopStart: lwz r0, 0x0914 (r31) #Check Hitbox Active Bool cmpwi r0,0x0 beq CheckForActiveHitboxes_NextHitbox li r3,0x1 b CheckForActiveHitboxes_Exit CheckForActiveHitboxes_NextHitbox: addi r29,r29,1 addi r31,r31,312 #Next Hitbox Struct cmpwi r29,4 blt CheckForActiveHitboxes_LoopStart CheckForActiveHitboxes_NoHitboxesActive: li r3,0x0 CheckForActiveHitboxes_Exit: restore blr ############################################# Event_ExitFunction: blrl backup #Ensure No Contest/Retry lwz r3, -0x77C0 (r13) lbz r3, 0x053B (r3) rlwinm. r0, r3, 0, 25, 25 bne Event_ExitFunction_Exit #Update Event Score load r20,0x8045abf0 #Current Event Info #Get High Score lbz r3,0x5(r20) #Event ID branchl r12,0x8015cf5c mr r21,r3 #Backup High Score #Check If Event Was Played Yet lbz r3,0x5(r20) #Event ID branchl r12,0x8015cefc cmpwi r3,0x0 beq Event_ExitFunction_SaveScore #Check If Greater lhz r3,-0x4ea6(r13) #Current Score cmpw r3,r21 ble Event_ExitFunction_Exit #Store As New High Score Event_ExitFunction_SaveScore: lbz r3,0x5(r20) #Event ID lhz r4,-0x4ea6(r13) branchl r12,0x8015cf70 #Set Event As Played lbz r3,0x5(r20) #Event ID branchl r12,0x8015ceb4 Event_ExitFunction_Exit: restore blr ############################################# InitializeHighScore: backup #Create HUD KO Counter li r3,0x0 branchl r12,0x802fa5bc #Init Score Count li r3,0x0 stw r3,-0x4ea8(r13) #Store Exit Function bl Event_ExitFunction mflr r3 load r4,0x8046b6a0 stw r3,0x2518(r4) restore blr ############################################# PerformAerialThink: #in # r3 CPU Player Pointer # r4 Pointer to dedicated memory to use # r5 Attack to Perform (0 = Random, 1 = Fair, 2 = Nair, 3 = Dair) .set player,31 .set playerdata,30 .set variables,29 .set frame,28 .set aerialToPerform,27 .set performAerial,0x00 .set aerialAttack,0x01 .set attackFrame,0x02 backup #Get player pointers and frame count mr player,r3 #Get Player lwz playerdata,0x2C(player) #Get Playerdata mr variables,r4 #Get Variable Memory lfs f1,0x894(playerdata) #Get Frames as Int fctiwz f1,f1 stfd f1,0xF0(sp) lwz frame,0xF4(sp) mr aerialToPerform,r5 #Aerial to perform #Check To Aerial lbz r3,performAerial(variables) cmpwi r3,0x0 bne PerformAerialThink_Exit #Check Which Action to Perform lwz r3,0x10(playerdata) #Get Action State #Branch To Think Functions #During Wait cmpwi r3,0xE beq PerformAerialThink_DuringWait #During Jump cmpwi r3,0x19 beq PerformAerialThink_DuringJump cmpwi r3,0x1A beq PerformAerialThink_DuringJump #During Attack cmpwi r3,0x41 blt 0x10 cmpwi r3,0x45 bgt 0x8 b PerformAerialThink_DuringAttack #During Landing cmpwi r3,0x2A beq PerformAerialThink_DuringLanding cmpwi r3,0x46 blt 0x10 cmpwi r3,0x4A bgt 0x8 b PerformAerialThink_DuringLanding #None of The Above b PerformAerialThink_Exit PerformAerialThink_DuringWait: #Input Jump li r3,0x800 stw r3,0x1A88(playerdata) #Determine Which Aerial Attack To Do #Check To Randomize cmpwi aerialToPerform,0x0 beq PerformAerialThink_GetRandomAttack #Store Attack Chosen subi r3,aerialToPerform,0x1 stb r3,aerialAttack(variables) b PerformAerialThink_CheckForValidAttack PerformAerialThink_GetRandomAttack: li r3,3 branchl r12,HSD_Randi stb r3,aerialAttack(variables) #Determine Frame to Attack on PerformAerialThink_CheckForValidAttack: lwz r4,0x4(playerdata) #get char ID bl PerformAerial_FrameData mflr r5 mulli r4,r4,0xC #Get Characters Offset add r4,r4,r5 #Get Characters Table Entry Start mulli r3,r3,0x2 #Move Frame Data is 0x2 Long add r27,r3,r4 #Get Moves Frame Data lbz r4,0x0(r27) #First Possible Frame lbz r5,0x1(r27) #Last Possible Frame cmpwi r4,0x0 bne PerformAerialThink_GetRandomFrame cmpwi r5,0x0 bne PerformAerialThink_GetRandomFrame #Move Disabled For Char, Get a New One b PerformAerialThink_GetRandomAttack PerformAerialThink_GetRandomFrame: sub r3,r5,r4 #Get Amount of Possibilities branchl r12,HSD_Randi #Get Random Frame lbz r4,0x0(r27) #First Possible Frame add r3,r3,r4 #Adjust for First Possible Frame stb r3,attackFrame(variables) #Store Frame to Attack on b PerformAerialThink_Exit PerformAerialThink_DuringJump: #Check To Attack lbz r3,attackFrame(variables) cmpw r3,frame bne PerformAerialThink_InputFastfallAndLCancel #Perform Attack lbz r3,aerialAttack(variables) #Get Attack ID cmpwi r3,0x0 beq PerformAerialThink_Fair cmpwi r3,0x1 beq PerformAerialThink_Nair cmpwi r3,0x2 beq PerformAerialThink_Dair PerformAerialThink_Fair: li r3,127 #Forward lfs f1,0x2C(playerdata) #Facing Direction fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) mullw r3,r3,r4 #Forward * facing direction stb r3,0x1A8E(playerdata) b PerformAerialThink_InputFastfallAndLCancel PerformAerialThink_Nair: li r3,0x100 stw r3,0x1A88(playerdata) b PerformAerialThink_InputFastfallAndLCancel PerformAerialThink_Dair: li r3,-127 stb r3,0x1A8F(playerdata) b PerformAerialThink_InputFastfallAndLCancel b PerformAerialThink_InputFastfallAndLCancel PerformAerialThink_DuringAttack: b PerformAerialThink_InputFastfallAndLCancel PerformAerialThink_DuringLanding: #Set Sequence as Over li r3,1 stb r3,performAerial(variables) b PerformAerialThink_Exit PerformAerialThink_InputFastfallAndLCancel: #Input Fastfall #Check If Already FastFalling lbz r3,0x221A(playerdata) rlwinm. r3,r3,0,28,28 bne PerformAerialThink_InputLCancel #Check If Falling lfs f2,0x84(playerdata) lfs f0, -0x76B0 (rtoc) fcmpo cr0,f2,f0 bge PerformAerialThink_InputLCancel #Check If Inputting A Nair lwz r3,0x1A88(playerdata) cmpwi r3,0x100 beq PerformAerialThink_InputLCancel #Input Down to FF li r3,-127 stb r3,0x1A8D(playerdata) #Analog Y PerformAerialThink_InputLCancel: #Spoof Mash L li r3,0x1 stb r3,0x67F(playerdata) b PerformAerialThink_Exit ################################# PerformAerial_FrameData: blrl #Mario .long 0x00040012 #Fair and Nair .long 0x00100005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Fox .long 0x0009000A #Fair and Nair .long 0x00080005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Cptn Falcon .long 0x0006000E #Fair and Nair .long 0x00040005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #DK .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Kirby .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Bowser .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #link .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Sheik .long 0x10140018 #Fair and Nair .long 0x00000005 #Dar (was 0-A) and UAir .long 0x0005FFFF #Bair and Nothing #Ness .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Peach .long 0x000D001A #Fair and Nair .long 0x000E0005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Popo .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Nana .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Pikachu .long 0x000C000F #Fair and Nair .long 0x00080005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Samus .long 0x00200020 #Fair and Nair .long 0x080D0005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Yoshi .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Jiggs .long 0x00100010 #Fair and Nair .long 0x00100005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #mewtwo .long 0x00050019 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Luigi .long 0x0017001B #Fair and Nair .long 0x00110005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Marth .long 0x00160013 #Fair and Nair .long 0x00120005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Zelda .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #YLink .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Doc .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Falco .long 0x070B000D #Fair and Nair .long 0x000C0005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Pichu .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #GaW .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Ganon .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Roy .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #################################### PerformAerialThink_Exit: restore blr ##################################### RandFloat: #in #r3 = Rand Float Lower Bound #r4 = Rand Float Upper Bound backup stfs f31,0x80(sp) mr r31,r3 #Get Random Upper Bound sub r3,r4,r31 branchl r12,HSD_Randi #Add Lower Bound add r3,r3,r31 #Convert to Float bl IntToFloat fmr f31,f1 #Get Random Float branchl r12,HSD_Randf fadds f1,f1,f31 lfs f31,0x80(sp) restore blr ##################################### Custom_InterruptRebirthWait: blrl .set player,31 .set playdata,30 backup #Get Pointers mr player,r3 lwz playerdata,0x2C(player) #Check For Aerial Jump mr r3,player branchl r12,0x800cb870 cmpwi r3,0x0 bne Custom_InterruptRebirthWait_Exit #Ensure Stick Was Just Moved lbz r3, 0x0670 (playerdata) cmpwi r3,2 bge Custom_InterruptRebirthWait_CheckJoystickDown #Check For Any X Joystick Push lwz r3, -0x514C (r13) lfs f0, 0x0024 (r3) lfs f1, 0x0620 (playerdata) fabs f1,f1 fcmpo cr0,f1,f0 cror 2, 1, 2 beq Custom_InterruptRebirthWait_EnterFall Custom_InterruptRebirthWait_CheckJoystickDown: #Ensure Stick Was Just Moved lbz r3, 0x0671 (playerdata) cmpwi r3,4 bge Custom_InterruptRebirthWait_Exit #Check For Down Joystick Push lwz r3, -0x514C (r13) lfs f0, 0x0090 (r3) fneg f0,f0 lfs f1, 0x0624 (playerdata) fcmpo cr0,f1,f0 blt Custom_InterruptRebirthWait_EnterFall b Custom_InterruptRebirthWait_Exit Custom_InterruptRebirthWait_EnterFall: #Enter Fall mr r3,player branchl r12,AS_Fall Custom_InterruptRebirthWait_Exit: restore blr ##################################### UpdatePosition: .set PlayerGObj,31 .set PlayerData,30 backup #Backup Pointer mr PlayerGObj,r3 lwz PlayerData,0x2C(PlayerGObj) #Update Position (Copy Physics XYZ into all ECB XYZ) #X lwz r3, 0x00B0 (PlayerData) stw r3, 0x06F4 (PlayerData) stw r3, 0x0700 (PlayerData) stw r3, 0x070C (PlayerData) stw r3, 0x0718 (PlayerData) #Y lwz r3, 0x00B4 (PlayerData) stw r3, 0x06F8 (PlayerData) stw r3, 0x0704 (PlayerData) stw r3, 0x0710 (PlayerData) stw r3, 0x071C (PlayerData) #Z lwz r3, 0x00B8 (PlayerData) stw r3, 0x06FC (PlayerData) stw r3, 0x0708 (PlayerData) stw r3, 0x0714 (PlayerData) stw r3, 0x0720 (PlayerData) #Update Collision Frame ID lwz r3, -0x51F4 (r13) stw r3, 0x728(PlayerData) #branchl r12,0x80081b38 #Stopped using this because it deletes way too much ECB info #branchl r12,0x80082a68 #Better than the above function, but all i need is to copy current position into the ECB previous values #Adjust JObj position (code copied from 8006c324) lwz r3,0x28(PlayerGObj) #get character model JObj lwz r4,0xB0(PlayerData) #get X stw r4,0x38(r3) #store X lwz r4,0xB4(PlayerData) #get Y stw r4,0x3C(r3) #store Y lwz r4,0xB8(PlayerData) #get Z stw r4,0x40(r3) #store Z #Dirty Sub #branchl r12,0x803732e8 #Update Static Player Block Coords lbz r3,0xC(PlayerData) lbz r4, 0x221F (PlayerData) rlwinm r4, r4, 29, 31, 31 addi r5,PlayerData,176 branchl r12,0x80032828 restore blr ##################################### GetGroundCenter: #in #r3 = Ground ID #Get Corner IDs from Ground ID mulli r0,r3,8 lwz r5, -0x51E4 (r13) lwzx r5,r5,r0 lhz r3,0x0(r5) lhz r4,0x2(r5) #Get Coordinates lwz r5, -0x51E8 (r13) mulli r3,r3,24 addi r3,r3,8 add r3,r3,r5 lfs f1,0x0(r3) #Left X lfs f2,0x4(r3) #Left Y mulli r4,r4,24 addi r4,r4,8 add r4,r4,r5 lfs f3,0x0(r4) #Right X lfs f4,0x4(r4) #Right Y #Get Center Value lfs f5,-0x4df0(rtoc) #2f fadds f1,f1,f3 fdivs f1,f1,f5 #Center X fadds f2,f2,f4 fdivs f2,f2,f5 #Center Y blr #################################### PlacePlayersCenterStage: #in #none backup #Loop through players 1 and 2 .set count,27 .set player,26 .set playerdata,25 .set subchar,24 .set subchardata,23 li count,0 PlacePlayersCenterStage_Loop: #Get Player GObj mr r3,r27 branchl r12,PlayerBlock_LoadMainCharDataOffset #Check if exists cmpwi r3,0x0 beq PlacePlayersCenterStage_IncLoop mr player,r3 lwz playerdata,0x2C(player) #Get Subchar Bool bl CheckIfPlayerHasAFollower mr subchar,r3 mr subchardata,r4 #Call function to do heavy lifting mr r3,player bl PlacePlayersCenterStage_DoStuff #Check if subchar exits cmpwi subchar,0 beq PlacePlayersCenterStage_IncLoop #Call function for this character mr r3,subchar bl PlacePlayersCenterStage_DoStuff #Next Player PlacePlayersCenterStage_IncLoop: addi count,count,1 cmpwi count,6 blt PlacePlayersCenterStage_Loop b PlacePlayersCenterStage_Exit #*****************************# PlacePlayersCenterStage_DoStuff: #in #r3 = player .set player,31 .set playerdata,30 .set constants,29 backup #Get Pointers mr player,r3 lwz playerdata,0x2C(r3) #Get Constants bl PlacePlayersCenterStage_Constants mflr constants lbz r3,0xC(playerdata) mulli r3,r3,0x2 add constants,constants,r3 #Initialize Player Data (Mainly for ICs so Nana knows where Popo is) mr r3,player branchl r12,0x80068354 #Get Stage's Ground ID lwz r3,-0x6CB8 (r13) #External Stage ID bl ComboTraining_StartingGroundIDs mflr r4 mulli r3,r3,0x2 lhzx r3,r3,r4 bl GetGroundCenter fmr f30,f1 fmr f31,f2 #Facing Directions lbz r3,0x0(constants) #This players facing direction extsb r3,r3 bl IntToFloat stfs f1,0x2C(playerdata) #Move Players lbz r3,0x1(constants) #This players X offset extsb r3,r3 bl IntToFloat fadds f2,f1,f30 #Player X = X+6 stfs f2,0xB0(playerdata) stfs f31,0xB4(playerdata) #Enter into Wait mr r3,player branchl r12,AS_Wait #Find Ground Below Player mr r3,player bl FindGroundNearPlayer cmpwi r3,0 #Check if ground was found beq PlacePlayersCenterStage_DoStuff_SkipGroundCorrection stfs f1,0xB0(playerdata) stfs f2,0xB4(playerdata) stw r4,0x83C(playerdata) PlacePlayersCenterStage_DoStuff_SkipGroundCorrection: #Update Position mr r3,player bl UpdatePosition #Update ECB Values for the ground ID mr r3,player branchl r12,EnvironmentCollision_WaitLanding #Set Grounded mr r3,playerdata branchl r12,Air_SetAsGrounded #Update Camera mr r3,player bl UpdateCameraBox PlacePlayersCenterStage_DoStuff_Exit: restore blr #*********# PlacePlayersCenterStage_Constants: blrl .byte 1,-6,-1,6 .align 2 #*********# PlacePlayersCenterStage_Exit: restore blr ##################################### FindGroundNearPlayer: #in #r3 = player GObj (optional) #f1 = X value #f2 = Y Value .set player,31 .set playerdata,30 backup stfs f30,0x38(sp) stfs f31,0x3C(sp) #Check If Given Player GObj cmpwi r3,0x0 bne FindGroundNearPlayer_GObjPassedIn FindGroundNearPlayer_CoordinatesPassedIn: #Backup Coords fmr f30,f1 fmr f31,f2 #Get 10f li r3,10 bl IntToFloat #Get Bottom Coord fmr f3,f30 #Bottom X is same as Top X fsubs f4,f31,f1 #Bottom Y is Top Y - 1000 #Move Top Coords Back fmr f1,f30 fmr f2,f31 lfs f0, -0x7188 (rtoc) fadds f2,f2,f0 b FindGroundNearPlayer_Continue FindGroundNearPlayer_GObjPassedIn: #Init Variables mr player,r3 lwz playerdata,0x2C(player) #Get Players X and Y+10 lfs f1,0xB0(playerdata) lfs f2,0xB4(playerdata) lfs f0, -0x7188 (rtoc) fadds f2,f2,f0 #Get Bottom Coord (X and Y-1000) lfs f3,0xB0(playerdata) lfs f4,0xB0(playerdata) lfs f0,-0x71A8 (rtoc) fsubs f4,f4,f0 FindGroundNearPlayer_Continue: #Get Unk f5 argument lfs f5, -0x7208 (rtoc) #Setup stack for return values addi r3,sp,0x54 #(Returns Ground Coordinates addi r4,sp,0x44 #(Returns Ground ID) addi r5,sp,0x40 #(Returns Ground Type) addi r6,sp,0x48 #(Returns Unk) #Unk arguments li r7,-1 li r8,-1 li r9,-1 #Additional function pointer li r10,0 #Call function branchl r12,Raycast_GroundLine #Check if ground exists cmpwi r3,0 beq FindGroundNearPlayer_Exit #Return Coordinates of ground below player lfs f1,0x54(sp) lfs f2,0x58(sp) lwz r4,0x44(sp) FindGroundNearPlayer_Exit: lfs f30,0x38(sp) lfs f31,0x3C(sp) restore blr ##################################### FindGroundUnderCoordinate: #in #f1 = X value #f2 = Y Value backup stfs f30,0x38(sp) stfs f31,0x3C(sp) FindGroundUnderCoordinate_CoordinatesPassedIn: #Backup Coords fmr f30,f1 fmr f31,f2 #Get 1000f li r3,1000 bl IntToFloat #Get Bottom Coord fmr f3,f30 #Bottom X is same as Top X fsubs f4,f31,f1 #Bottom Y is Top Y - 1000 #Move Top Coords Back fmr f1,f30 fmr f2,f31 FindGroundUnderCoordinate_Continue: #Get Unk f5 argument lfs f5, -0x7208 (rtoc) #Setup stack for return values addi r3,sp,0x54 #(Returns Ground Coordinates addi r4,sp,0x44 #(Returns Ground ID) addi r5,sp,0x40 #(Returns Ground Type) addi r6,sp,0x48 #(Returns Unk) #Unk arguments li r7,-1 li r8,-1 li r9,-1 li r10,0 #Call function branchl r12,Raycast_GroundLine #Check if ground exists cmpwi r3,0 beq FindGroundUnderCoordinate_Exit #Return Coordinates of ground below player lfs f1,0x54(sp) lfs f2,0x58(sp) lwz r4,0x44(sp) FindGroundUnderCoordinate_Exit: lfs f30,0x38(sp) lfs f31,0x3C(sp) restore blr ##################################### PlacePlayerOnGround: backup .set REG_GObj,31 .set REG_GObjData,30 #Get Pointers mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) #Find Ground Below Player mr r3,REG_GObj bl FindGroundNearPlayer cmpwi r3,0 #Check if ground was found beq PlacePlayerOnGround_SkipGroundCorrection stfs f1,0xB0(REG_GObjData) stfs f2,0xB4(REG_GObjData) stw r4,0x83C(REG_GObjData) PlacePlayerOnGround_SkipGroundCorrection: #Update Position mr r3,REG_GObj bl UpdatePosition #Update ECB Values for the ground ID mr r3,REG_GObj branchl r12,EnvironmentCollision_WaitLanding #Set Grounded mr r3,REG_GObjData branchl r12,Air_SetAsGrounded PlacePlayerOnGround_Exit: restore blr ##################################### PlaySFX: backup branchl r12,SFX_PlaySoundAtFullVolume restore blr ##################################### UpdateCameraBox: #in #r3 = player .set player,31 .set playerdata,30 backup #Get Pointer mr player,r3 lwz playerdata,0x2C(player) #Update Camera Box Position mr r3,player branchl r12,Camera_UpdatePlayerCameraBoxPosition #Update Camera Box Direction Tween # lwz r3,0x2C(player) # branchl r12,0x80076064 #Update Camera Box Direction Tween lwz r3,0x890(playerdata) lfs f1,0x40(r3) #Leftmost Bound stfs f1,0x2C(r3) #Current Left Box Bound lfs f1,0x44(r3) #Rightmost Bound stfs f1,0x30(r3) #Current Right Box Bound #Correct Camera Position branchl r12,Camera_CorrectPosition restore blr ##################################### GetAllPlayerPointers: #in #nothing #out #r3 = P1GObj #r4 = P1Data #r5 = P2GObj #r6 = P2Data #r7 = P3GObj #r8 = P3Data #r9 = P4GObj #r10 = P4Data backup #Get Space to Store all Pointer to addi r21,sp,0x40 #Init Loop Count li r20,0 GetAllPlayerPointers_Loop: #Get GObj mr r3,r20 branchl r12,PlayerBlock_LoadMainCharDataOffset #Check If Exists cmpwi r3,0x0 li r4,0 #Zero Data pointer just in case it doesnt exist beq GetAllPlayerPointers_StoreToStack #Get Data lwz r4,0x2C(r3) #Store Both to Stack GetAllPlayerPointers_StoreToStack: mulli r5,r20,8 add r5,r5,r21 stw r3,0x0(r5) stw r4,0x4(r5) GetAllPlayerPointers_IncLoop: addi r20,r20,1 cmpwi r20,4 blt GetAllPlayerPointers_Loop GetAllPlayerPointers_LoadPointers: lwz r3,0x00(r21) lwz r4,0x04(r21) lwz r5,0x08(r21) lwz r6,0x0C(r21) lwz r7,0x10(r21) lwz r8,0x14(r21) lwz r9,0x18(r21) lwz r10,0x1C(r21) GetAllPlayerPointers_Exit: restore blr ##################################### RemoveFirstFrameInputs: RemoveFirstFrameInputs_GetFirstPlayer: lwz r3, -0x3E74 (r13) lwz r12, 0x0020 (r3) b RemoveFirstFrameInputs_CheckIfPlayerExists RemoveFirstFrameInputs_GetNextPlayer: lwz r12,0x8(r12) RemoveFirstFrameInputs_CheckIfPlayerExists: cmpwi r12,0x0 beq RemoveFirstFrameInputs_Exit lwz r5,0x2C(r12) #Remove Input Flag lbz r0, 0x221D (r5) li r3,0x1 rlwimi r0,r3,4,27,27 stb r0,0x221D (r5) #Store Current Input lbz r4, 0x0618 (r5) load r3,InputStructStart mulli r0, r4, 68 add r3, r0, r3 lwz r0, 0 (r3) stw r0, 0x065C (r5) b RemoveFirstFrameInputs_GetNextPlayer RemoveFirstFrameInputs_Exit: blr ##################################### InitializeMatch: .set REG_EventStruct,31 .set REG_MatchStruct,30 .set REG_CPUChoice,29 .set REG_StageChoice,28 .set REG_EventOSDs,27 .set REG_PlayerStruct,26 .set REG_UseSopo,25 #Init backup mr REG_EventStruct,r3 mr REG_MatchStruct,r4 mr REG_CPUChoice,r5 mr REG_StageChoice,r6 mr REG_EventOSDs,r7 mr REG_UseSopo,r8 #Check to override OSD Toggles lwz r4,-0x77C0(r13) lbz r3,0x1f2A(r4) cmpwi r3,1 beq InitializeMatch_SkipOSDOverride #Store Events FDD Toggles lwz r3,0x1F24(r4) or r3,r3,REG_EventOSDs stw r3,0x1F24(r4) InitializeMatch_SkipOSDOverride: #SPAWN 2 PLAYERS li r3,0x40 stb r3,0x1(REG_EventStruct) #Make Copy of Struct li r3,32 branchl r12,HSD_MemAlloc mr REG_PlayerStruct,r3 bl P2Struct mflr r4 li r5,0x1C branchl r12,memcpy #Store to P2 pointer in event struct stw REG_PlayerStruct,0x18(REG_EventStruct) #Store CPU cmpwi REG_CPUChoice,-1 beq InitializeMatch_StoreCSSCPU #Store this CPU stb REG_CPUChoice,0x0(REG_PlayerStruct) b InitializeMatch_StoreStage InitializeMatch_StoreCSSCPU: load r3,0x8043207c #get preload table lwz r4,0x18(r3) #get p2 character ID cmpwi r4,0x12 #check if zelda bne 0x8 li r4,0x13 #make zelda sheik stb r4,0x0(REG_PlayerStruct) #store chosen char lbz r6,0x1C(r3) #get p2 costume ID stb r6,0x3(REG_PlayerStruct) #store p2 costume ID li r5,0x1 #make CPU controlled stb r5,0x1(REG_PlayerStruct) InitializeMatch_StoreStage: #Store Stage cmpwi REG_StageChoice,-1 beq InitializeMatch_StoreSSSStage #Store this Stage sth REG_StageChoice,0xE(REG_MatchStruct) b InitializeMatch_StoreStage_End InitializeMatch_StoreSSSStage: load r3,0x8043207c #get preload table lwz r3, 0x00C (r3) sth r3,0xE(REG_MatchStruct) #store chosen stage InitializeMatch_StoreStage_End: InitializeMatch_SwapInSopo: cmpwi REG_UseSopo,0 beq InitializeMatch_SwapInSopo_End #Swap P1 Character to Sopo lwz r4, -0x77C0 (r13) addi r4, r4, 1328 #event mode match backup struct? lbz r3,0x2(r4) #P1 External ID cmpwi r3,0xE bne InitializeMatch_SwapInSopo_End li r3,0x20 stb r3,0x2(r4) #Make SoPo InitializeMatch_SwapInSopo_End: InitializeMatch_Exit: restore blr ##################################### GetDistance: lfs f3,0x0(r3) #X lfs f4,0x4(r3) #Y lfs f5,0x0(r4) #X lfs f6,0x4(r4) #Y fsubs f1,f5,f3 fsubs f2,f4,f6 fmuls f1,f1,f1 fmuls f2,f2,f2 fadds f2,f1,f2 frsqrte f1,f2 fmuls f1,f1,f2 blr ##################################### GetLedgeCoordinates: .set LedgeSide,20 .set LedgeID,21 .set Return,22 backup #Backup Ledge Choice (0 = Left, 1 = Right) mr LedgeSide,r3 mr Return,r4 #Get Stage's Ledge IDs lwz r3,-0x6CB8 (r13) #External Stage ID bl LedgedashCliffIDs mflr r4 mulli r3,r3,0x2 lhzx r3,r3,r4 #Get Requested Ledge cmpwi LedgeSide,0x0 beq GetLedgeCoordinates_GetLeftLedgeID GetLedgeCoordinates_GetRightLedgeID: rlwinm LedgeID,r3,0,24,31 #Get Ledge Coords (0x80 = X, 0x84 = Y) mr r3,LedgeID mr r4,Return branchl r12,Stage_GetRightOfLineCoordinates b GetLedgeCoordinates_Exit GetLedgeCoordinates_GetLeftLedgeID: rlwinm LedgeID,r3,24,24,31 #Get Ledge Coords (0x80 = X, 0x84 = Y) mr r3,LedgeID mr r4,Return branchl r12,Stage_GetLeftOfLineCoordinates b GetLedgeCoordinates_Exit GetLedgeCoordinates_Exit: restore blr ########################################## GetAngleBetweenPoints: .set REG_arctan,2 .set REG_Constants,31 backup #Get Constants bl GetAngleBetweenPoints_Constants mflr REG_Constants #Get Values lfs f1,0x0(r3) lfs f2,0x4(r3) lfs f3,0x0(r4) lfs f4,0x4(r4) #Get slope ydelta / xdelta fsubs f5,f4,f2 fsubs f6,f3,f1 fdivs f1,f5,f6 #atan branchl r12,0x80022e68 fmr REG_arctan,f1 #Ensure above 0 and below 6.28319 GetAngleBetweenPoints_CheckIfOver0: lfs f1,0x0(REG_Constants) fcmpo cr0,REG_arctan,f1 bge GetAngleBetweenPoints_CheckIfUnder360 #Add 180 lfs f1,0x8(REG_Constants) fadds REG_arctan,REG_arctan,f1 b GetAngleBetweenPoints_CheckIfOver0 GetAngleBetweenPoints_CheckIfUnder360: lfs f1,0x4(REG_Constants) fcmpo cr0,REG_arctan,f1 ble GetAngleBetweenPoints_Under360 #Add 180 lfs f1,0x8(REG_Constants) fsubs REG_arctan,REG_arctan,f1 b GetAngleBetweenPoints_CheckIfUnder360 GetAngleBetweenPoints_Under360: fmr f1,REG_arctan GetAngleBetweenPoints_Exit: restore blr GetAngleBetweenPoints_Constants: blrl .float 0 .float 6.28319 .float 3.14159 ########################################## EnterKnockback: backup .set REG_GObj,31 .set REG_GObjData,30 .set REG_AngleLo,29 .set REG_AngleHi,28 .set REG_MagLo,27 .set REG_MagHi,26 .set REG_Angle,29 .set REG_Magnitude,28 #Backup Data mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) mr REG_AngleLo,r4 mr REG_AngleHi,r5 mr REG_MagLo,r6 mr REG_MagHi,r7 #Random angle between sub r3,REG_AngleHi,REG_AngleLo branchl r12,HSD_Randi add REG_Angle,r3,REG_AngleLo #Cast to float mr r3,REG_Angle bl IntToFloat #Now in radians lfs f2, -0x7510 (rtoc) fmuls f1,f1,f2 stfs f1,0x80(sp) #Random magnitude between X and Y mr r3,REG_MagLo mr r4,REG_MagHi bl RandFloat stfs f1,0x7C(sp) #will be used later for lwz r3, -0x514C (r13) lfs f0, 0x0100 (r3) fmuls f1,f1,f0 stfs f1,0x84(sp) #Get X Component lfs f1,0x80(sp) #KB angle in radians branchl r12,cos lfs f2,0x84(sp) #KB magnitude fmuls f1,f1,f2 lfs f2,0x2C(REG_GObjData) fneg f2,f2 fmuls f1,f1,f2 stfs f1,0x8C(REG_GObjData) #Get Y Component lfs f1,0x80(sp) #KB angle in radians branchl r12,sin lfs f2,0x84(sp) #KB magnitude fmuls f1,f1,f2 stfs f1,0x90(REG_GObjData) #Calculate Hitstun lwz r3, -0x514C (r13) lfs f0, 0x0154 (r3) lfs f1,0x7C(sp) fmuls f1,f1,f0 #hitstun frames is 0.4 * magnitude fctiwz f1,f1 #Round down stfd f1,0x88(sp) lwz r3,0x8C(sp) bl IntToFloat stfs f1,0x2340(REG_GObjData) #Enable Hitstun Bit lbz r0,0x221C(REG_GObjData) li r3,1 rlwimi r0,r3,1,30,30 stb r0,0x221C(REG_GObjData) #Enable ECB Update mr r3,REG_GObjData branchl r12,0x8007d5bc EnterKnockback_Exit: restore blr ########################################## DisableHazards: #Get list start bl DisableHazards_SkipList ######################## bl DisableHazards_Dummy bl DisableHazards_TEST bl DisableHazards_Izumi bl DisableHazards_Pstadium bl DisableHazards_Castle bl DisableHazards_Kongo bl DisableHazards_Zebes bl DisableHazards_Corneria bl DisableHazards_Story bl DisableHazards_Onett bl DisableHazards_MuteCity bl DisableHazards_RCruise bl DisableHazards_Garden bl DisableHazards_GreatBay bl DisableHazards_Shrine bl DisableHazards_Kraid bl DisableHazards_Yoster bl DisableHazards_Greens bl DisableHazards_Fourside bl DisableHazards_MK1 bl DisableHazards_MK2 bl DisableHazards_Akaneia bl DisableHazards_Venom bl DisableHazards_Pura bl DisableHazards_BigBlue bl DisableHazards_Icemt bl DisableHazards_Icetop bl DisableHazards_FlatZone bl DisableHazards_OldDL bl DisableHazards_OldYS bl DisableHazards_OldKongo bl DisableHazards_Battlefield bl DisableHazards_FinalDestination ######################## DisableHazards_SkipList: mflr r3 lwz r4,StageID_External(r13) mulli r4,r4,4 add r4,r3,r4 lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) cmpwi r5,0 #If pointer is null, exit beq DisableHazards_SkipList_Exit add r4,r4,r5 #Pointer to code now in r4 mtctr r4 bctr ######################## DisableHazards_Story: /* #Get randall's line ID mr r3,REG_map_gobj branchl r12,0x801c6330 lwz r3,0x4(r3) #get map_head lwz r3,0x8(r3) #get map_gobj info mulli r4,REG_map_gobj,52 #get randall's info add r3,r3,r4 lwz r3,0x20(r3) #pointer to the collision data lhz r3,0x0(r3) #i believe this is randalls line ID #Get randalls corner IDs mulli r3,r3,8 #0x8 in length lwz r4, -0x51E4 (r13) #line to corner ID table lwzx r5,r3,r4 #now have the corner ID struct lhz r3,0x0(r5) #left corner id lhz r4,0x2(r5) #right corner id #Get corner IDs info lwz r5, -0x51E8 (r13) mulli r3,r3,24 mulli r4,r4,24 add r3,r3,r5 add r4,r4,r5 #Zero current X and Y positions, effectively removing these lines li r5,0 stw r5,0x8(r3) stw r5,0xC(r3) stw r5,0x8(r4) stw r5,0xC(r4) */ /* #Get randall's map_gobj li r3,2 #randalls map_gobj is 2 branchl r12,Stage_map_gobj_Load branchl r12,Stage_Destroy_map_gobj */ #Get shyguy's map_gobj li r3,3 #shyguys map_gobj is branchl r12,Stage_map_gobj_Load #Remove Proc branchl r12,GObj_RemoveProc #Fix ragdoll issue bl DisableHazards_RagdollFix b DisableHazards_SkipList_Exit ######################## DisableHazards_Pstadium: #Get transformation's map_gobj li r3,2 #transformation's map_gobj ID branchl r12,Stage_map_gobj_Load #Remove Proc branchl r12,GObj_RemoveProc #Fix ragdoll issue bl DisableHazards_RagdollFix b DisableHazards_SkipList_Exit ######################## DisableHazards_OldDL: #Destroy whispy's map_gobj li r3,7 #transformation's map_gobj ID branchl r12,Stage_map_gobj_Load branchl r12,Stage_Destroy_map_gobj #Destroy whispy's blink map_gobj proc li r3,6 #transformation's map_gobj ID branchl r12,Stage_map_gobj_Load branchl r12,GObj_RemoveProc #set wind hazard count to 0 li r3,0 stw r3,Stage_PositionHazardCount(r13) b DisableHazards_SkipList_Exit ######################## DisableHazards_OldYS: #Destroy cloud's map_gobj li r3,2 #map_gobj ID branchl r12,Stage_map_gobj_Load branchl r12,Stage_Destroy_map_gobj b DisableHazards_SkipList_Exit ######################## DisableHazards_OldKongo: #Destroy barrel's map_gobj li r3,1 #map_gobj ID branchl r12,Stage_map_gobj_Load branchl r12,Stage_Destroy_map_gobj b DisableHazards_SkipList_Exit ######################## DisableHazards_RagdollFix: #Certain stages have an essential ragdoll function #in their map_gobj think function. If the think function is removed, #the ragdoll function must be re-scheduled to function properly. backup #Create GObj li r3,3 #GObj Type li r4,5 #On-Pause Function li r5,0 branchl r12,GObj_Create #Schedule Task bl DisableHazards_RagdollFix_Think mflr r4 li r5,4 #Priority branchl r12,GObj_AddProc b DisableHazards_RagdollFix_Exit #********************************# DisableHazards_RagdollFix_Think: blrl backup branchl r12,Ragdoll_WindDecayThink restore blr #********************************# DisableHazards_RagdollFix_Exit: restore blr ######################### DisableHazards_SkipList_Exit: restore blr ########################################### PlaybackInputSequence: .set REG_PlayerData,31 .set REG_InputSequence,30 .set REG_AttackTimer,29 #Input Sequence Struct .set InputSequence_Length,0x9 .set InputSequence_Frame,0x0 .set InputSequence_Buttons,0x1 .set InputSequence_AnalogX,0x5 .set InputSequence_AnalogY,0x6 .set InputSequence_CStickX,0x7 .set InputSequence_CStickY,0x8 backup #Backup args mr REG_PlayerData,r3 mr REG_InputSequence,r4 mr REG_AttackTimer,r5 PlaybackInputSequence_Loop: #Search for this frames input in the sequence lbz r3,InputSequence_Frame(REG_InputSequence) #Check if end of sequence extsb r0,r3 cmpwi r0,-1 beq PlaybackInputSequenceExit #Check if this frame's input cmpw r5,r3 beq PlaybackInputSequence_PlayInput blt PlaybackInputSequenceExit #Check if the current frame is less than the parsed frame #If greater, continue parsing addi REG_InputSequence,REG_InputSequence,InputSequence_Length b PlaybackInputSequence_Loop #If greater, continue parsing PlaybackInputSequence_PlayInput: lwz r3,InputSequence_Buttons(REG_InputSequence) stw r3,CPU_HeldButtons(REG_PlayerData) lbz r3,InputSequence_AnalogX(REG_InputSequence) stb r3,CPU_AnalogX(REG_PlayerData) lbz r3,InputSequence_AnalogY(REG_InputSequence) stb r3,CPU_AnalogY(REG_PlayerData) lbz r3,InputSequence_CStickX(REG_InputSequence) stb r3,CPU_CStickX(REG_PlayerData) lbz r3,InputSequence_CStickY(REG_InputSequence) stb r3,CPU_CStickY(REG_PlayerData) PlaybackInputSequenceExit: restore blr ########################################### PlaceOnLedge: backup .set REG_LedgeID,31 .set REG_P1GObj,30 .set REG_P1Data,29 #Backup pointers mr REG_P1GObj,r3 lwz REG_P1Data,0x2C(REG_P1GObj) mr REG_LedgeID,r4 #Get Stage's Ledge IDs lwz r3,-0x6CB8 (r13) #External Stage ID bl LedgedashCliffIDs mflr r4 mulli r3,r3,0x2 lhzx r3,r3,r4 #Get Requested Ledge cmpwi REG_LedgeID,0x0 beq PlaceOnLedge_GetLeftLedgeID PlaceOnLedge_GetRightLedgeID: rlwinm r20,r3,0,24,31 #Change Facing Direction li r3,-1 bl IntToFloat stfs f1,0x2C(REG_P1Data) b PlaceOnLedge_StoreLedgeIDAndPosition PlaceOnLedge_GetLeftLedgeID: rlwinm r20,r3,24,24,31 #Change Facing Direction li r3,1 bl IntToFloat stfs f1,0x2C(REG_P1Data) b PlaceOnLedge_StoreLedgeIDAndPosition PlaceOnLedge_StoreLedgeIDAndPosition: #Store Ledge to Player Block stw r20,0x2340(REG_P1Data) #Enter CliffWait mr r3,REG_P1GObj branchl r12,AS_CliffWait #Init state variable (would be 1 at the start of the next frame if it ocurred naturally) li r3,1 stw r3,0x2348(REG_P1Data) #Spoof in state for 1 frame li r3,1 sth r3,FramesinCurrentAS(REG_P1Data) #Get Jump Back mr r3,REG_P1Data branchl r12,Air_StoreBool_LoseGroundJump_NoECBfor10Frames #Set ECB Update Flag mr r3,REG_P1Data branchl r12,DataOffset_ECBBottomUpdateEnable #Update ECB Corner Positions addi r3,REG_P1Data,0x6F0 branchl r12,0x80048160 #Move Player To Ledge mr r3,REG_P1GObj branchl r12,MovePlayerToLedge #Update Position mr r3,REG_P1GObj bl UpdatePosition #Kill Velocity li r3,0x0 stw r3,0x80(REG_P1Data) #X Velocity stw r3,0x84(REG_P1Data) #Y Velocity #Give Intangibility (30) mr r3,REG_P1GObj lwz r4, -0x514C (r13) lwz r4, 0x049C (r4) branchl r12,ApplyIntangibility restore blr ########################################### GetInputStruct: load r4,InputStructStart mulli r0, r3, 68 add r3, r0, r4 blr ########################################### exit: li r0, 3 ================================================ FILE: ASM/training-mode/Custom Events/Custom Event Code - Rewrite.asm ================================================ #To be inserted at 801bb128 .include "../Globals.s" .include "../../m-ex/Header.s" # Check if event is legacy (no file) lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) mr r4,r25 #event mr r5,r26 #match struct rtocbl r12,TM_GetEventFile cmpwi r3,0 beq LegacyEvent #Branch to C function to initialize the event lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) mr r4,r25 #event mr r5,r26 #match struct rtocbl r12,TM_EventInit branch r12,0x801bb738 LegacyEvent: #r25 = event ID #r26 = final match struct #r28 = same as r26 #r29 = event struct index (0x0 of this, then 0x8 of that to get the specifics) #region Event and Menu GObj Data Structs #Event GObj Data Struct .set EventData_DataSize,0x50 .set EventData_MenuDataPointer,(EventData_DataSize-0x4) .set EventData_SaveStateStruct,0x10 #Menu GObj Data Struct .set MenuData_DataSize,0x50 .set MenuData_EventDataPointer,(MenuData_DataSize-0x4) .set MenuData_WindowOptionCountPointer,0x0 .set MenuData_ASCIIStructPointer,0x4 .set MenuData_OptionMenuMemory,0x8 .set MenuData_OptionMenuToggled,0x28 #endregion #region Init Custom Event ################# ## Custom Code ## ################# #all registers free #1 PLAYER, NO ITEMS, TIME COUNTING UP lwz r9,0x0(r29) #get event pointers #ZERO OUT p2-p6 STRUCT li r4,0x0 stw r4,0x18(r9) stw r4,0x1C(r9) stw r4,0x20(r9) stw r4,0x24(r9) stw r4,0x28(r9) #Disable All-Star Flag li r3,0x0 stb r3,0x0(r9) #P1 = Choose Char + Normal Modifiers bl P1Struct mflr r3 stw r3,0x14(r9) #STORE MATCH SETTINGS load r3,0x0BB0027C #HUD and timer behavior stw r3,0x0(r26) load r3,0x90800000 stw r3,0x4(r26) #think functions li r3,0xFF stb r3,0xB(r26) #items to none li r3,0x0 stw r3,0x10(r26) #time amount #STORE UNLIM STOCKS li r3,0xFF stb r3,0x62(r26) #p1 stocks #SET FALL FLAG li r3,0x0 stb r3,0x6C(r26) #SET FFA FLAG li r3,0 stb r3,0x8(r26) #Store SSS Stage load r3,0x80497758 lha r4, 0x001E (r3) sth r4,0xE(r26) #Get Event Code bl SkipPageList ##### Page List ####### EventJumpTable ####################### Minigames: bl Eggs bl Multishine bl Reaction bl LedgeStall .long -1 ####################### GeneralTech: bl TrainingLab bl LCancel bl Ledgedash bl 0x0 # wavedash bl ComboTraining bl AttackOnShield bl Reversal bl SDITraining bl Powershield bl Ledgetech bl AmsahTech bl ShieldDrop bl WaveshineSDI bl SlideOff bl GrabMashOut .long -1 ####################### SpacieTech: bl LedgetechCounter bl ArmadaShine bl SideBSweetspot bl EscapeSheik .long -1 ####################### SkipPageList: #Get Page Jump Table mflr r4 #Jump Table Start in r4 #Get Current Page lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) mulli r5,r3,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r4,r4,r5 #Gets ASCII Address in r4 #Get Event Code Pointer mulli r5,r25,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction cmpwi r5,-1 beq EventNoExist rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r4,r4,r5 #Gets ASCII Address in r4 mtctr r4 bctr EventNoExist: b exit #endregion ############### ## Minigames ## ############### #region Eggs-ercise ######################### ## Eggs-ercise HIJACK INFO ## ######################### Eggs: #COUNT DOWN TIME li r3,0x6 stb r3,0x0(r26) #1 Minute On the Clock li r3,60 stw r3,0x10(r26) #Store Match Type to READY, GO! li r3,0x80 stb r3,0x1(r26) #SET EVENT TYPE TO KOs load r5,0x8045abf0 #Static Match Struct lbz r3,0xB(r5) #Get Event Score Behavior Byte li r4,0x0 rlwimi r3,r4,1,30,30 #Zero Out Time Bit stb r3,0xB(r5) #Set Event Score Behavior Byte #1 Player lwz r4,0x0(r29) li r3,0x20 stb r3,0x1(r4) #STORE THINK FUNCTION bl EggsLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Eggs-ercise LOAD FUNCT ## ######################## EggsLoad: blrl backup #Schedule Think #r3 = function to run each frame #r4 = priority #r5 = pointer to Window and Option Count #r6 = pointer to ASCII struct bl EggsThink mflr r3 li r4,9 #Priority (After Interrupt) bl EggsWindowInfo mflr r5 bl EggsWindowText mflr r6 bl CreateEventThinkFunction bl InitializeHighScore b EggsLoadExit ######################### ## Eggs-ercise THINK FUNCT ## ######################### #Registers .set EventData,31 .set MenuData,26 .set P1Data,27 .set P1GObj,28 #Offsets .set DamageThreshold,(MenuData_OptionMenuMemory+0x2) +0x0 .set DamageThresholdToggled,(MenuData_OptionMenuToggled) +0x0 EggsThink: blrl backup #Get and Backup Event Data mr r30,r3 #r30 = think entity lwz EventData,0x2c(r3) #backup data pointer in r31 lwz MenuData,EventData_MenuDataPointer(EventData) #Get Player Data bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 #No Staling bl ResetStaleMoves #Check If Free Practice lbz r3,0x5(r31) cmpwi r3,0x0 bne EggsSkipFreePracticeCheck #Check DPad Down lwz r0,0x668(r27) rlwinm. r0,r0,0,29,29 beq EggsSkipFreePracticeCheck #Toggle Free Practice On li r3,0x1 stb r3,0x5(r31) #Timer Now Counts Up load r3,0x8046b6a0 lbz r0,0x24C8(r3) li r4,1 rlwimi r0,r4,0,31,31 stb r0,0x24C8(r3) #Play Sound To Indicate li r3,0x82 branchl r12,SFX_PlaySoundAtFullVolume EggsSkipFreePracticeCheck: #Check If Toggled lbz r3,DamageThresholdToggled(MenuData) cmpwi r3,0x0 beq EggsSkipToggleCheck #Check If Already Free Practice lbz r3,0x5(r31) cmpwi r3,0x0 bne EggsSkipToggleCheck #Make Free Practice li r3,0x1 stb r3,0x5(r31) #Timer Now Counts Up load r3,0x8046b6a0 lbz r0,0x24C8(r3) li r4,1 rlwimi r0,r4,0,31,31 stb r0,0x24C8(r3) #Play Sound To Indicate li r3,0x82 branchl r12,SFX_PlaySoundAtFullVolume EggsSkipToggleCheck: #Check For First Frame lbz r3,0x4(r31) cmpwi r3,0x0 bne EggsNotFirstFrame #Check If Player Can Move li r3,0x0 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block lwz r3,0x2c(r3) #player data in r29 lbz r3,0x221D(r3) rlwinm. r3,r3,0,28,28 bne EggsThinkExit #Set First Frame Over li r3,0x1 stb r3,0x4(r31) EggsNotFirstFrame: #Check If Target is Spawned EggsTargetCheck: #Check If Pointer is Stored lwz r3,0x0(r31) cmpwi r3,0x0 beq EggsThinkSpawn #Check if Item GObj is live lwz r3,0x2C(r3) cmpwi r3,0x0 beq EggsThinkSpawn b EggsThinkSkipSpawn ################ # Spawn Target # ################ .set LeftCameraBound,20 .set RightCameraBound,21 .set TopCameraBound,22 .set BottomCameraBound,23 EggsThinkSpawn: .if debug==1 li r24,0 #Init loop count .endif EggsThinkSpawnLoop: .if debug==1 addi r24,r24,1 #Inc Loop Count .endif #Get OnScreen Boundaries #Left Camera branchl r12,StageInfo_CameraLimitLeft_Load fctiwz f1,f1 stfd f1,0x80(sp) lwz LeftCameraBound,0x84(sp) #Right Camera branchl r12,StageInfo_CameraLimitRight_Load fctiwz f1,f1 stfd f1,0x80(sp) lwz RightCameraBound,0x84(sp) #Top Camera branchl r12,StageInfo_CameraLimitTop_Load fctiwz f1,f1 stfd f1,0x80(sp) lwz TopCameraBound,0x84(sp) #Bottom Camera branchl r12,StageInfo_CameraLimitBottom_Load fctiwz f1,f1 stfd f1,0x80(sp) lwz BottomCameraBound,0x84(sp) #Get Random Velocity branchl r12,HSD_Randf fmr f20,f1 li r3,2 bl IntToFloat fadds f20,f20,f1 #Get Random X Value Between These mr r3,LeftCameraBound mr r4,RightCameraBound bl RandFloat fmr f21,f1 #Get Random Y Value Between These mr r3,BottomCameraBound subi r4,TopCameraBound,70 #Minus 40 so it doesnt fly up offscreen bl RandFloat fmr f22,f1 .set EggSpawnGroundWidth,8 #Check If Egg is Above Ground fmr f1,f21 fmr f2,f22 bl FindGroundUnderCoordinate cmpwi r3,0x0 beq EggsThinkSpawnLoop #Check Left li r3,EggSpawnGroundWidth bl IntToFloat fsubs f1,f21,f1 fmr f2,f22 bl FindGroundUnderCoordinate cmpwi r3,0x0 beq EggsThinkSpawnLoop #Check Right li r3,EggSpawnGroundWidth bl IntToFloat fadds f1,f21,f1 fmr f2,f22 bl FindGroundUnderCoordinate cmpwi r3,0x0 beq EggsThinkSpawnLoop .if debug==1 #OSReport Loop Count load r3,0x803ead3c mr r4,r24 branchl r12,OSReport .endif SpawnEgg: addi r3,sp,0x80 li r4,0x0 stw r4,0x0(r3) #Player Pointer stw r4,0x4(r3) #Player Pointer li r4,0x03 stw r4,0x8(r3) #Item ID lfs f0, -0x2858 (rtoc) stfs f21,0x14(r3) #X Coord stfs f22,0x18(r3) #Y Coord stfs f0,0x1C(r3) #Z Coord stfs f21,0x20(r3) #X Coord stfs f22,0x24(r3) #Y Coord stfs f0,0x28(r3) #Z Coord stfs f0,0x2C(r3) #Unk stfs f0,0x30(r3) #Unk stfs f0,0x34(r3) #X Vel stfs f0,0x38(r3) #Y Vel li r4,0x1 sth r4,0x3C(r3) branchl r12,EntityItemSpawn mr r29,r3 #Backup Entity Pointer stw r29,0x0(r31) #Store Pointer To Target In Event Think #Store Pointer To Event Think In Target lwz r4,0x2C(r29) stw r31,0xDDC(r4) #Store Y Velocity stfs f20,0x44(r4) #Get OnDestroy lwz r4,0x2C(r29) lwz r4,0xB8(r4) #Store OnCollision bl Eggs_OnCollision mflr r3 stw r3,0x1C(r4) #Create Camera Box branchl r12,CreateCameraBox #Attach to Entity lwz r4,0x2c(r29) stw r3, 0x0520 (r4) #Enable Camera Box Bit lbz r0, 0x0DCD (r4) li r5,0x22 rlwimi r0, r5, 5, 24, 25 stb r0, 0x0DCD (r4) #Copy Some Stuff To Camera Box lwz r4, -0x4978 (r13) lfs f0, 0x014C (r4) stfs f0, 0x0040 (r3) lfs f0, 0x0150 (r4) stfs f0, 0x0044 (r3) lfs f0, 0x0154 (r4) stfs f0, 0x0048 (r3) lfs f0, 0x0158 (r4) stfs f0, 0x004C (r3) #Never Timeout lwz r5, 0x002C (r29) lbz r3,0xDD0(r5) li r4,0x1 rlwimi r3,r4,4,27,27 stb r3,0xDD0(r5) #Not Grabbable lbz r3, 0x0DCA (r5) li r4,0x0 rlwimi r3,r4,2,29,29 stb r3, 0x0DCA (r5) #Un-Nudgeable? lbz r3, 0x0DCB (r5) li r4,0x0 rlwimi r3,r4,3,28,28 stb r3, 0x0DCB (r5) EggsThinkSkipSpawn: #Not Grabbable Every Frame lwz r5,0x0(r31) lwz r5,0x2c(r5) lbz r3, 0x0DCA (r5) li r4,0x0 rlwimi r3,r4,2,29,29 stb r3, 0x0DCA (r5) #Update HUD Score li r3,0 li r4,5 branchl r12,Playerblock_LoadTimesR3KilledR4 branchl r12,HUD_KOCounter_UpdateKOs #Check If Free Practice lbz r3,0x5(r31) cmpwi r3,0x0 bne EggsThinkExit #Check For TimeUp branchl r12,MatchInfo_LoadSeconds #Seconds Left cmpwi r3,0x0 bne EggsThinkExit branchl r12,MatchInfo_LoadSubSeconds #Sub-Seconds Left cmpwi r3,59 bne EggsThinkExit #On Event End mr r3,r30 branchl r12,EventMatch_OnWinCondition #EventMatch_OnWinCondition EggsThinkExit: mr r3,MenuData bl ClearToggledOptions restore blr Eggs_OnCollision: blrl #First check if this is an event load r4,SceneController lbz r4,Scene.CurrentMajor(r4) cmpwi r4,Scene.EventMode bne Eggs_OnCollisionOriginalFunction #Now check if its eggs-ercise lwz r4, -0x77C0 (r13) lbz r4, 0x0535 (r4) #get event ID cmpwi r4,Event_Eggs beq Eggs_OnCollisionStart Eggs_OnCollisionOriginalFunction: #Go to the original egg break function branch r12,ItemCollision_Egg Eggs_OnCollisionStart: backup mr r30,r3 lwz r31,0x2C(r3) #Get Data #Check If Any Attack Should Break lwz r3,0xDDC(r31) #Get Event Data lwz r3,EventData_MenuDataPointer(r3) #Get Menu Data lbz r3,DamageThreshold(r3) #Damage Behavior cmpwi r3,0x1 beq Eggs_OnCollisionBreakEgg #Check Damage Dealt Before Exploding lwz r3,0xCA0(r31) cmpwi r3,11 blt Egg_OnCollisionExit Eggs_OnCollisionBreakEgg: #Increment Score li r3,0 li r4,0 li r5,5 branchl r12,Playerblock_StoreTimesR3KilledR4 #Display Effect li r3,1232 mr r4,r30 addi r5, r31, 76 crclr 6 branchl r12,Textures_DisplayEffectTextures #Play Pop Sound mr r3,r31 li r4,244 li r5,127 li r6,64 branchl r12,0x8026ae84 #Explode mr r3,r30 branchl r12,0x80289158 #Spawn New Egg lwz r3,0xDDC(r31) #Get Event Think li r4,0x0 #Get 0 stw r4,0x0(r3) #Zero Pointer Egg_OnCollisionExit: li r3,0x0 Egg_OnCollisionExitSkip: restore blr EggsLoadExit: restore blr #################################################### EggsWindowInfo: blrl #amount of options, amount of options in each window .long 0x0001FFFF #1 window, Smash Attack has 2 options #################################################### EggsWindowText: blrl ###################### ## Damage Threshold ## ###################### #Window Title = Damage Threshold .long 0x44616d61 .long 0x67652054 .long 0x68726573 .long 0x686f6c64 .long 0x #Option 1 = 12+ Damage .long 0x3132817B .long 0x2044616d .long 0x61676500 .long 0x .long 0x #Option 2 = Any Damage .long 0x416e7920 .long 0x44616d61 .long 0x67650000 .long 0x .long 0x ################################################################################ ################################################################################ #endregion #region Multishine ######################### ## Multishine HIJACK INFO ## ######################### Multishine: #COUNT DOWN TIME li r3,0x6 stb r3,0x0(r26) #10 Seconds On the Clock li r3,10 stw r3,0x10(r26) #Store Match Type to READY, GO! li r3,0x80 stb r3,0x1(r26) #SET EVENT TYPE TO KOs load r5,0x8045abf0 #Static Match Struct lbz r3,0xB(r5) #Get Event Score Behavior Byte li r4,0x0 rlwimi r3,r4,1,30,30 #Zero Out Time Bit stb r3,0xB(r5) #Set Event Score Behavior Byte #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,FinalDestination #Use FD load r7,EventOSD_Multishine li r8,0 #Use Sopo Bool bl InitializeMatch #1 Player lwz r4,0x0(r29) li r3,0x20 stb r3,0x1(r9) #STORE THINK FUNCTION bl MultishineLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Multishine LOAD FUNCT ## ######################## MultishineLoad: blrl backup #Schedule Think bl MultishineThink mflr r3 li r4,17 #Priority (After Everything) li r5,0 #No Option Menu li r6,0 bl CreateEventThinkFunction bl InitializeHighScore b MultishineLoadExit ######################### ## Multishine THINK FUNCT ## ######################### MultishineThink: blrl .set EventData,31 .set Event,30 .set P1Data,27 .set P1GObj,28 backup mr Event,r3 lwz EventData,0x2c(Event) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 #First Frame Actions bl CheckIfFirstFrame cmpwi r3,0x0 beq MultishineNotFirstFrame #Init Positions bl PlacePlayersCenterStage MultishineNotFirstFrame: #Check for grounded or aerial shine, frame 1 lwz r3,0x10(P1Data) cmpwi r3,0x168 beq Multishine_IsShining cmpwi r3,0x16D beq Multishine_IsShining b Multishine_SkipShineCheck Multishine_IsShining: #Check for frame 1 lhz r3,TM_FramesinCurrentAS(P1Data) cmpwi r3,0 bne Multishine_SkipShineCheck #Increment Score li r3,0 li r4,0 li r5,5 branchl r12,Playerblock_StoreTimesR3KilledR4 Multishine_SkipShineCheck: #Check For TimeUp branchl r12,MatchInfo_LoadSeconds #Seconds Left cmpwi r3,0x0 bne MultishineThinkExit branchl r12,MatchInfo_LoadSubSeconds #Sub-Seconds Left cmpwi r3,59 bne MultishineThinkExit #On Event End mr r3,Event branchl r12,EventMatch_OnWinCondition #EventMatch_OnWinCondition MultishineThinkExit: #Update HUD Score li r3,0 li r4,5 branchl r12,Playerblock_LoadTimesR3KilledR4 branchl r12,HUD_KOCounter_UpdateKOs MultishineLoadExit: restore blr ################################################################################ ################################################################################ #endregion #region Reaction ######################### ## Reaction HIJACK INFO ## ######################### Reaction: #SET EVENT TYPE TO KOs load r5,0x8045abf0 #Static Match Struct lbz r3,0xB(r5) #Get Event Score Behavior Byte li r4,0x0 rlwimi r3,r4,1,30,30 #Zero Out Time Bit stb r3,0xB(r5) #Set Event Score Behavior Byte #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Fox.Ext #Use chosen CPU li r6,FinalDestination #Use FD load r7,EventOSD_Reaction li r8,0 #Use Sopo Bool bl InitializeMatch #STORE THINK FUNCTION bl ReactionLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Reaction LOAD FUNCT ## ######################## ReactionLoad: blrl backup #Schedule Think bl ReactionThink mflr r3 li r4,3 #Priority (Interrupt) li r5,0 #No Option Menu li r6,0 bl CreateEventThinkFunction b ReactionLoadExit ######################### ## Reaction THINK FUNCT ## ######################### ReactionThink: blrl .set EventData,31 .set Event,30 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 #Constants .set ShineTimerMax,7*60 .set ShineTimerMin,3*60 .set ResetTimer,1*60 #GObj Data Offsets .set OFST_ShineTimer,0x0 .set OFST_ResetTimer,0x2 .set OFST_ReactionTimer,0x4 backup mr Event,r3 lwz EventData,0x2c(Event) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 #First Frame Actions bl CheckIfFirstFrame cmpwi r3,0x0 beq ReactionNotFirstFrame #Init Positions bl PlacePlayersCenterStage #Savestate addi r3,EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Save #Set Initial Timer li r3,ShineTimerMax - ShineTimerMin branchl r12,HSD_Randi addi r3,r3,ShineTimerMin sth r3,OFST_ShineTimer(EventData) #Initialize Reaction Timer li r3,-1 sth r3,OFST_ReactionTimer(EventData) #Stop Music li r3,0 li r4,2 branchl r12,0x80025064 ReactionNotFirstFrame: bl StoreCPUTypeAndZeroInputs #Give Intangibility to both chars mr r3,P1GObj li r4,1 branchl r12,ApplyIntangibility mr r3,P2GObj li r4,1 branchl r12,ApplyIntangibility #Check post countdown timer lhz r3,OFST_ResetTimer(EventData) cmpwi r3,0 ble Reaction_SkipResetTimer #Dec timer, if 0 reset subi r3,r3,1 sth r3,OFST_ResetTimer(EventData) cmpwi r3,0 beq Reaction_Reset b ReactionThinkExit Reaction_SkipResetTimer: #Check shine countdown timer lhz r3,OFST_ShineTimer(EventData) cmpwi r3,0 ble Reaction_SkipShineTimer #Dec timer, if 0 perform move subi r3,r3,1 sth r3,OFST_ShineTimer(EventData) cmpwi r3,0 bgt ReactionThink_CheckIfActedEarly #Perform down b mr r3,P2GObj branchl r12,0x800e8560 #Start reaction timer li r3,0 sth r3,OFST_ReactionTimer(EventData) b ReactionThinkExit ReactionThink_CheckIfActedEarly: #Check if P1 acted early lwz r3,0x10(P1Data) cmpwi r3,ASID_Wait beq ReactionThinkExit #Play Error Noise li r3,0xAF bl PlaySFX #Set Timer li r3,ResetTimer-40 sth r3,OFST_ResetTimer(EventData) b ReactionThinkExit Reaction_SkipShineTimer: #Check reaction timer lhz r3,OFST_ReactionTimer(EventData) extsh r3,r3 cmpwi r3,0 blt Reaction_SkipReactionTimer #Poll Inputs Again #branchl r12,0x80377ce8 #Check if P1 Reacted lbz r3,0x618(P1Data) load r4,InputStructStart mulli r3,r3,68 add r3,r3,r4 lwz r3,0x8(r3) cmpwi r3,0 beq Reaction_SkipReactionTimer #Output reaction time mr r3,P1Data #p1 (no offsetting window) li r4,120 #text timeout li r5,0 #Area to Display (0-2) li r6,OSD.Miscellaneous #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr r20,r3 #backup text pointer #Decide Color lhz r3,OFST_ReactionTimer(EventData) cmpwi r3,15 ble Reaction_Good Reaction_Bad: load r3,0xffa2baff #Red b Reaction_StoreTextColor Reaction_Good: load r3,0x8dff6eff #green Reaction_StoreTextColor: stw r3,0x30(r20) #Create Text 1 mr r3,r20 #text pointer bl Reaction_TopText mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,Text_InitializeSubtext #Create Text 2 mr r3,r20 #text pointer bl Reaction_BottomText mflr r4 lhz r5,OFST_ReactionTimer(EventData) addi r5,r5,1 #0-index is scary lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #default text X/Y branchl r12,Text_InitializeSubtext #Start post countdown timer li r3,ResetTimer sth r3,OFST_ResetTimer(EventData) b ReactionLoadExit Reaction_SkipReactionTimer: #Inc timer lhz r3,OFST_ReactionTimer(EventData) addi r3,r3,1 sth r3,OFST_ReactionTimer(EventData) b ReactionThinkExit Reaction_Reset: #Load State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Reset Variables #Set Initial Timer li r3,ShineTimerMax - ShineTimerMin branchl r12,HSD_Randi addi r3,r3,ShineTimerMin sth r3,OFST_ShineTimer(EventData) #Reset Timer li r3,0 sth r3,OFST_ResetTimer(EventData) #Initialize Reaction Timer li r3,-1 sth r3,OFST_ReactionTimer(EventData) ReactionThinkExit: ReactionLoadExit: restore blr Reaction_TopText: blrl .string "Reaction Time:" .align 2 Reaction_BottomText: blrl .string "%d Frames" .align 2 ################################################################################ ################################################################################ #endregion #region Ledge Stall ########################### ## Ledge Stall HIJACK INFO ## ########################### LedgeStall: #Store Match Type to READY, GO! li r3,0x80 stb r3,0x1(r26) #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 li r6,Brinstar #stage load r7,EventOSD_LedgeStall li r8,1 #Use Sopo bool bl InitializeMatch #1 Player lwz r4,0x0(r29) li r3,0x20 stb r3,0x1(r4) #STORE THINK FUNCTION LedgeStallStoreThink: bl LedgeStallLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## Ledge Stall LOAD FUNCT ## ################################## LedgeStallLoad: blrl backup #Schedule Think bl LedgeStallThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction #Destroy Lava map_gobj proc li r3,8 #lava's map_gobj ID branchl r12,Stage_map_gobj_Load branchl r12,GObj_RemoveProc /* #Make Lava transparent li r3,8 #lava's map_gobj ID branchl r12,Stage_map_gobj_Load li r4,0 branchl r12,Stage_map_gobj_LoadJObj li r5,1 lwz r4,0x14(r3) rlwimi r4,r5,29,2,2 rlwimi r4,r5,28,3,3 rlwimi r4,r5,19,12,12 stw r4,0x14(r3) lwz r3,0x18(r3) lwz r3,0x8(r3) lwz r4,0x4(r3) rlwimi r4,r5,29,2,2 rlwimi r4,r5,30,1,1 stw r4,0x4(r3) lwz r3,0xC(r3) load r4,0x3f000000 stw r4,0xC(r3) */ #Get map_gobj li r3,6 #platform's map_gobj ID branchl r12,Stage_map_gobj_Load #Get platform flesh item pointer lwz r3,0x2C(r3) lwz r3,0xE4(r3) lwz r3,0x2C(r3) #Set Hurtbox as intangible li r4,2 stw r4,0xACC(r3) #Create Camera Box branchl r12,CreateCameraBox mr r20,r3 #Get Stage's Ledge IDs lwz r3,-0x6CB8 (r13) #External Stage ID bl LedgedashCliffIDs mflr r4 mulli r3,r3,0x2 lhzx r3,r3,r4 #Get Ledge Coordinates rlwinm r3,r3,24,24,31 addi r4,sp,0xD0 branchl r12,Stage_GetLeftOfLineCoordinates #Position Base of CameraBox behind the ledge .set CameraBoxXOffset,35 .set CameraBoxYOffset,20 li r3,CameraBoxXOffset bl IntToFloat lfs f2,0xD0(sp) #Ledge X fadds f1,f1,f2 stfs f1,0x10(r20) #Camera X Position li r3,CameraBoxYOffset bl IntToFloat lfs f2,0xD4(sp) #Ledge Y fadds f1,f1,f2 stfs f1,0x14(r20) #Camera Y Position #Make Boundaries around ledge position #Left Bound li r3,-10 bl IntToFloat stfs f1,0x40(r20) #Right Bound li r3,10 bl IntToFloat stfs f1,0x44(r20) #Top Bound li r3,10 bl IntToFloat stfs f1,0x48(r20) #Lower Bound li r3,-10 bl IntToFloat stfs f1,0x4C(r20) #Set Camera To Be Zoomed Out More load r4,0x8049e6c8 load r3,0x3FE66666 stw r3,0x28(r4) b LedgeStallThink_Exit ########################################### LedgeStallThink_Constants: blrl .set LavaRiseRate,0x0 .set LavaMaxY,0x4 .float 0.4 .float 10 ########################################### ################################### ## Ledge Stall THINK FUNCT ## ################################### LedgeStallThink: blrl #Registers .set REG_EventConstants,25 .set REG_MenuData,26 .set REG_EventData,31 .set REG_EventGObj,24 .set REG_P1Data,27 .set REG_P1GObj,28 .set REG_P2Data,29 .set REG_P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_LavaDelay,0x0 .set EventState_LavaRiseThink,0x1 .set EventState_Reset,0x2 .set Timer,0x1 .set LavaTimer,0x2 .set SurvivalTime,0x4 .set LavaPosition,0x8 #Constants .set ResetTimer,30 .set LavaStartY,-100 .set LavaStartTimer,123 .set SuvivalTime_CountInterval,5 backup #INIT FUNCTION VARIABLES mr REG_EventGObj,r3 lwz REG_EventData,0x2c(REG_EventGObj) #backup data pointer in r31 #Get Player Pointers bl GetAllPlayerPointers mr REG_P1GObj,r3 mr REG_P1Data,r4 mr REG_P2GObj,r5 mr REG_P2Data,r6 #Get Menu and Constants Pointers lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData) bl LedgeStallThink_Constants mflr REG_EventConstants #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq LedgeStallThink_Start #Init Positions mr r3,REG_P1GObj mr r4,REG_EventData bl LedgeStall_InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save LedgeStallThink_Start: #Check if player was damaged or died lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_DamageHi1 blt LedgeStallThink_DamageCheckSkip cmpwi r3,ASID_DamageFlyRoll bgt LedgeStallThink_DamageCheckSkip b LedgeStallThink_TookDamage LedgeStallThink_DamageCheckSkip: lbz r3,0x221F(REG_P1Data) rlwinm. r0,r3,0,25,25 beq LedgeStallThink_DeadCheckSkip LedgeStallThink_TookDamage: #Check if took damage already lbz r3,Timer(REG_EventData) cmpwi r3,0 bgt LedgeStallThink_DeadCheckSkip #Set Reset Timer li r3,ResetTimer stb r3,Timer(REG_EventData) #Play Crowd SFX #li r3,0x13D #bl PlaySFX #Advance State li r3,EventState_Reset stb r3,EventState(REG_EventData) LedgeStallThink_DeadCheckSkip: LedgeStallThink_SwitchCase: #Switch Case lbz r3,EventState(REG_EventData) cmpwi r3,EventState_LavaDelay beq LedgeStallThink_LavaDelay cmpwi r3,EventState_LavaRiseThink beq LedgeStallThink_LavaRiseThink cmpwi r3,EventState_Reset beq LedgeStallThink_Reset b LedgeStallThink_CheckTimer #region LedgeStallThink_LavaDelay LedgeStallThink_LavaDelay: #Reset Timer back to 0 li r3,0 load r4,0x8046b6a0 stw r3,0x28(r4) #seconds sth r3,0x2C(r4) #subseconds #Decrement Lava Timer lhz r3,LavaTimer(REG_EventData) subi r3,r3,1 sth r3,LavaTimer(REG_EventData) #Check if up cmpwi r3,0 bgt LedgeStallThink_CheckTimer #Advance State li r3,EventState_LavaRiseThink stb r3,EventState(REG_EventData) b LedgeStallThink_LavaRiseThink #endregion #region LedgeStallThink_LavaRiseThink LedgeStallThink_LavaRiseThink: #Ensure player is in the lava before incrementing survival time lfs f1,LavaPosition(REG_EventData) lfs f2,0xB4(REG_P1Data) fcmpo cr0,f2,f1 bge LedgeStallThink_LavaRiseThink_NotInLava #Increment Score lwz r3,SurvivalTime(REG_EventData) addi r3,r3,1 stw r3,SurvivalTime(REG_EventData) LedgeStallThink_LavaRiseThink_SkipScoreIncrement: #Play HRC SFX every X score li r3,SuvivalTime_CountInterval bl IntToFloat fmr f2,f1 lwz r3,SurvivalTime(REG_EventData) subi r3,r3,1 bl IntToFloat branchl r12,fmod fmr f2,f1 li r3,0 bl IntToFloat fcmpo cr0,f2,f1 bne LedgeStallThink_LavaRiseThink_SkipSFX #Play SFX li r3,0xBB bl PlaySFX li r3,0xBB bl PlaySFX LedgeStallThink_LavaRiseThink_SkipSFX: b LedgeStallThink_LavaRiseThink_NotInLavaSkip LedgeStallThink_LavaRiseThink_NotInLava: #Reset Timer back to 0 li r3,0 load r4,0x8046b6a0 stw r3,0x28(r4) #seconds sth r3,0x2C(r4) #subseconds #Set survival time to 0 stw r3,SurvivalTime(REG_EventData) LedgeStallThink_LavaRiseThink_NotInLavaSkip: #Check if lava is at max height lfs f1,LavaPosition(REG_EventData) lfs f2,LavaMaxY(REG_EventConstants) fcmpo cr0,f1,f2 bge LedgeStallThink_LavaRiseThink_SkipLavaRise #Raise Lava lfs f2,LavaRiseRate(REG_EventConstants) fadds f1,f1,f2 stfs f1,LavaPosition(REG_EventData) bl Ledgestall_UpdateLavaPosition LedgeStallThink_LavaRiseThink_SkipLavaRise: b LedgeStallThink_CheckTimer #endregion #region LedgeStallThink_Reset LedgeStallThink_Reset: #Effectively pause timer load r4,0x8046b6a0 lwz r3,0x28(r4) #seconds cmpwi r3,0 beq LedgeStallThink_NoSecondCarryover lhz r3,0x2C(r4) #subseconds cmpwi r3,0 bne LedgeStallThink_NoSecondCarryover li r3,0x3B sth r3,0x2C(r4) #subseconds lwz r3,0x28(r4) #seconds subi r3,r3,1 stw r3,0x28(r4) #seconds b LedgeStallThink_CheckTimer LedgeStallThink_NoSecondCarryover: lhz r3,0x2C(r4) #subseconds subi r3,r3,1 sth r3,0x2C(r4) #subseconds b LedgeStallThink_CheckTimer #endregion LedgeStallThink_CheckTimer: #Check if timer exists lbz r3,Timer(REG_EventData) cmpwi r3,0 ble LedgeStallThink_Exit #Decrement timer subi r3,r3,1 stb r3,Timer(REG_EventData) cmpwi r3,0 bgt LedgeStallThink_Exit #Pasue game lfs f1, -0x4D68 (rtoc) branchl r12,0x8016b274 #Pause game engine #Check if player had any score when taking damage lwz r3,SurvivalTime(REG_EventData) cmpwi r3,0 ble LedgeStallThink_Failure LedgeStallThink_Success: #Get current high score lwz r3,-0x77C0 (r13) lbz r20,0x535(r3) mr r3,r20 branchl r12,Events_GetEventSavedScore lwz r4,SurvivalTime(REG_EventData) cmpw r4,r3 ble LedgeStallThink_Success_NoHighScore LedgeStallThink_Success_NewHighScore: li r3,2 branchl r12,0x8016b33c #Display Success + SFX load r3,0x9c40 branchl r12,0x8016b350 li r3,325 branchl r12,0x8016b364 #queue crowd cheer after Success branchl r12,0x8016b328 #set game as ended mr r3,r20 #update score lwz r4,SurvivalTime(REG_EventData) branchl r12,Events_SetEventSavedScore mr r3,r20 #set event as played branchl r12,0x8015ceb4 b LedgeStallThink_Success_DestroyGObj LedgeStallThink_Success_NoHighScore: li r3,2 branchl r12,0x8016b33c #Display New Record + SFX li r3,324 branchl r12,0x8016b364 #queue crowd cheer after New Record branchl r12,0x8016b328 #set game as ended b LedgeStallThink_Success_DestroyGObj LedgeStallThink_Failure: li r3,6 branchl r12,0x8016b33c #Display Failure + SFX li r3,328 branchl r12,0x8016b364 #queue crowd sigh after failure li r3,40 branchl r12,0x8016b378 #frames to linger? branchl r12,0x8016b328 #set game as ended b LedgeStallThink_Success_DestroyGObj LedgeStallThink_Success_DestroyGObj: mr r3,REG_EventGObj branchl r12,GObj_Destroy #destroy event gobj b LedgeStallThink_Exit LedgeStallThink_Restore: #Restore State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Load #Init Positions Again mr r3,REG_P1GObj mr r4,REG_EventData bl LedgeStall_InitializePositions #Enable Inputs lbz r3,0x221D(REG_P1Data) li r4,0 rlwimi r3,r4,3,28,28 stb r3,0x221D(REG_P1Data) #Shorten Timer li r3,0 sth r3,LavaTimer(REG_EventData) LedgeStallThink_Exit: restore blr ################################ LedgeStall_InitializePositions: backup .set REG_P1GObj,30 .set REG_P1Data,29 .set REG_EventData,28 .set REG_map_gobj,27 .set REG_map_gobj_JObj,26 #Init Registers mr REG_P1GObj,r3 lwz REG_P1Data,0x2C(REG_P1GObj) mr REG_EventData,r4 #Place on left ledge mr r3,REG_P1GObj li r4,0 bl PlaceOnLedge #Update Camera mr r3,REG_P1GObj bl UpdateCameraBox #Init Lava Y li r3,LavaStartY bl IntToFloat stfs f1,LavaPosition(REG_EventData) bl Ledgestall_UpdateLavaPosition #Reset Variables li r3,EventState_LavaDelay stb r3,EventState(REG_EventData) li r3,0 stb r3,Timer(REG_EventData) stw r3,SurvivalTime(REG_EventData) #Init Lava Start Timer li r3,LavaStartTimer sth r3,LavaTimer(REG_EventData) LedgeStall_InitializePositions_Exit: restore blr ##################################### Ledgestall_UpdateLavaPosition: backup .set REG_LavaY,31 .set REG_map_gobj_JObj,30 #Backup args stfs f1,0x80(sp) #Get Lava map_gobj li r3,8 #lava's map_gobj ID branchl r12,Stage_map_gobj_Load #Get JObj li r4,0 branchl r12,Stage_map_gobj_LoadJObj mr REG_map_gobj_JObj,r3 #Get 55f (jobj doesnt line up with actual position) li r3,55 bl IntToFloat #Update JObj Y position lfs f2,0x80(sp) fadds f1,f1,f2 stfs f1,0x3C(REG_map_gobj_JObj) #DirtySub mr r3,REG_map_gobj_JObj branchl r12,HSD_JObjSetMtxDirtySub #Adjust hitbox position lfs f1,0x80(sp) branchl r12,0x801c438c Ledgestall_UpdateLavaPosition_Exit: restore blr #endregion ################## ## General Tech ## ################## #region L-Cancel Training ######################### ## L Cancel HIJACK INFO ## ######################### LCancel: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,-1 #Use SSS Stage load r7,EventOSD_LCancel li r8,0 #Use Sopo Bool bl InitializeMatch #Make P2 a human lwz r3,0x0(r29) lwz r3,0x18(r3) li r4,0 stb r4,0x1(r3) #STORE THINK FUNCTION bl LCancelLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## L Cancel LOAD FUNCT ## ######################## LCancelLoad: blrl backup #Schedule Think bl LCancelThink mflr r3 li r4,3 #Priority (After Interrupt) li r5,0 #No Option Menu bl CreateEventThinkFunction b LCancelLoadExit ######################### ## L Cancel THINK FUNCT ## ######################### LCancelThink: blrl .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 backup lwz EventData,0x2c(r3) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl CheckIfFirstFrame cmpwi r3,0x0 beq LCancelNotFirstFrame #Init Positions bl PlacePlayersCenterStage #Check if P2-P4 Is Using the Event li r4,0x1 #Make CPU Controlled by P2 lbz r3, -0x5108 (r13) cmpwi r3,0x0 beq LCancelIsP1 li r4,0x0 LCancelIsP1: stb r4,0x618(r29) #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save LCancelNotFirstFrame: #Check For P2 Dpad Down Press lwz r3,0x668(r29) #Inputs rlwinm. r0,r3,0,29,29 beq LCancelThink_CheckForInvinc #Toggle Invinc Bit lbz r3,0x0(r31) nand 3,3,3 stb r3,0x0(r31) LCancelThink_CheckForInvinc: lbz r3,0x0(r31) cmpwi r3,0x0 bne LCancelThink_RemoveInvincibility #Give No Knockback To P2 lbz r3,0x2220(P2Data) li r4,1 rlwimi r3,r4,4,27,27 stb r3,0x2220(P2Data) #Ignore Grabs li r3,0x1FF sth r3,0x1A6A(P2Data) #Ignore Percent li r3,0 bl IntToFloat stfs f1,0x1830(P2Data) lbz r3,0xC(P2Data) li r4,0 li r5,0 branchl r12,0x80034418 #Un-nudgeable li r3,0x1 lbz r0, 0x221D (P2Data) rlwimi r0,r3,2,29,29 stb r0, 0x221D (P2Data) #Apply Overlay mr r3,P2Data li r4,9 li r5,0 branchl r12,0x800bffd0 b LCancelThink_SkipInvincibility LCancelThink_RemoveInvincibility: #Give Invincibility To P2 lbz r3,0x2220(P2Data) li r4,0 rlwimi r3,r4,4,27,27 stb r3,0x2220(P2Data) #Allow Grabs #li r3,0x0 #sth r3,0x1A6A(P2Data) #Allow Percent #li r3,1 #bl IntToFloat #stfs f1,0x182C(P2Data) #Nudgeable li r3,0x0 lbz r0, 0x221D (P2Data) rlwimi r0,r3,2,29,29 stb r0, 0x221D (P2Data) #Remove Overlay mr r3,P2Data li r4,9 branchl r12,0x800c0200 LCancelThink_SkipInvincibility: LCancelThink_CheckForSaveState: #Check For Savestates addi r3,EventData,EventData_SaveStateStruct bl CheckForSaveAndLoad mr r3,P1GObj mr r4,P2GObj addi r5,EventData,EventData_SaveStateStruct bl MoveCPU bl GiveFullShields addi r3,EventData,EventData_SaveStateStruct+(1*0x8) bl DPadCPUPercent bl UpdateAllGFX LCancelLoadExit: restore blr ################################################################################ ################################################################################ #endregion #region Ledgedash Training ########################### ## Ledgedash HIJACK INFO ## ########################### Ledgedash: #SET EVENT TYPE TO KOs load r5,0x8045abf0 #Static Match Struct lbz r3,0xB(r5) #Get Event Score Behavior Byte li r4,0x0 rlwimi r3,r4,1,30,30 #Zero Out Time Bit stb r3,0xB(r5) #Set Event Score Behavior Byte #Make HUD Centered For 1P and No Timer li r3,0x0430 sth r3,0x0(r26) #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,-1 #Use SSS Stage load r7,EventOSD_Ledgedash li r8,1 #Use Sopo Bool bl InitializeMatch #1 Player lwz r4,0x0(r29) li r3,0x20 stb r3,0x1(r9) #STORE THINK FUNCTION LedgedashStoreThink: bl LedgedashLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Ledgedash LOAD FUNCT ## ######################## LedgedashLoad: blrl backup #Schedule Think bl LedgedashThink mflr r3 li r4,9 #Priority (After Interrupt) bl LedgedashWindowInfo mflr r5 bl LedgedashWindowText mflr r6 bl CreateEventThinkFunction bl InitializeHighScore #Remove randall lwz r3,StageID_External(r13) cmpwi r3,YoshiStory bne LedgedashLoad_SkipRemoveRandall #Get randall's map_gobj li r3,2 #randalls map_gobj is 2 branchl r12,Stage_map_gobj_Load branchl r12,Stage_Destroy_map_gobj LedgedashLoad_SkipRemoveRandall: b LedgedashLoadExit ######################### ## Ledgedash THINK FUNCT ## ######################### #Registers .set REG_EventData,31 .set MenuData,27 .set P1GObj,30 .set P1Data,29 #Offsets .set firstFrameFlag,0x0 .set eventState,0x1 .set hitboxFoundFlag,0x2 .set currentLedge,0x3 .set timer,0x4 .set CameraBox,0x8 .set StartingLocation,(MenuData_OptionMenuMemory+0x2+0x0) .set AutoRestore,(MenuData_OptionMenuMemory+0x2+0x1) .set StartingLocationToggled,(MenuData_OptionMenuToggled+0x0) .set AutoRestoreToggled,(MenuData_OptionMenuToggled+0x1) LedgedashThink: blrl backup #INIT FUNCTION VARIABLES lwz REG_EventData,0x2c(r3) #backup data pointer in r31 lwz MenuData,EventData_MenuDataPointer(REG_EventData) bl GetAllPlayerPointers mr P1GObj,r3 #player block in r30 mr P1Data,r4 #player data in r29 #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq LedgedashThinkMain #Create Camera Box branchl r12,CreateCameraBox stw r3,CameraBox(r31) #Place on Ledge mr r3,REG_EventData li r4,0 bl Ledgedash_PlaceOnLedge #Set Camera To Be Zoomed Out More load r4,0x8049e6c8 load r3,0x3FE66666 stw r3,0x28(r4) #Set Tangible Frames High So It Doesn't Constantly Show li r3,100 stw r3,0x2408(r29) #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Set Frame 1 As Over li r3,0x1 stb r3,firstFrameFlag(r31) LedgedashThinkMain: #Update HUD Score lhz r3,-0x4ea8(r13) branchl r12,HUD_KOCounter_UpdateKOs #Check If Toggled Starting Location lbz r3,StartingLocationToggled(MenuData) cmpwi r3,0x0 beq Ledgedash_SkipToggledLoadState b Ledgedash_LoadState Ledgedash_SkipToggledLoadState: #Reset If Anyone Dies bl IsAnyoneDead cmpwi r3,0x0 bne Ledgedash_LoadState #Infinite Time While on Rebirth Platform lwz r3,0x10(P1Data) cmpwi r3,0xD bne LedgedashSkipRebirthTimer li r3,0x2 stw r3,0x2340(P1Data) LedgedashSkipRebirthTimer: #Infinite Time While Holding Ledge lwz r3,0x10(P1Data) cmpwi r3,0xFD bne LedgedashSkipCliffTimer li r3,2 bl IntToFloat stfs f1,0x2344(P1Data) LedgedashSkipCliffTimer: #Make sure nothing else besides Z is held lhz r3,0x662(P1Data) rlwinm. r0,r3,0,27,27 bne 0xC cmpwi r3,0x0 bne GetProgressAndAS #CHECK FOR DPAD TO CHANGE LEDGE lwz r3,0x668(P1Data) #Get DPad rlwinm. r0,r3,0,30,30 beq Ledgedash_CheckLeft #Load Most Recent State addi r3,REG_EventData,EventData_SaveStateStruct bl SaveState_Load #Place on Right Ledge mr r3,REG_EventData li r4,1 bl Ledgedash_PlaceOnLedge #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save b Ledgedash_LoadState Ledgedash_CheckLeft: rlwinm. r0,r3,0,31,31 beq GetProgressAndAS #Load Most Recent State addi r3,REG_EventData,EventData_SaveStateStruct bl SaveState_Load #Place on Left Ledge mr r3,REG_EventData li r4,0 bl Ledgedash_PlaceOnLedge #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save b Ledgedash_LoadState GetProgressAndAS: #Check If AutoRestore is enabled lbz r3,AutoRestore(MenuData) cmpwi r3,0x1 beq LedgedashThinkEnd #Check If Timer Is Set lbz r3,timer(r31) cmpwi r3,0x0 bgt Ledgedash_CheckToReset #Get Progress + AS lbz r3,eventState(r31) #Progress Byte bl LedgedashSkipJumpTable bl LedgedashProg0 bl LedgedashProg1 bl LedgedashProg2 bl LedgedashProg3 bl LedgedashProg4 LedgedashSkipJumpTable: mflr r4 #Jump Table Start in r4 mulli r5,r3,0x4 #Each Pointer is 0x4 Long lwzx r3,r4,r5 #Get bl Instruction rlwinm r3,r3,0,6,29 #Mask Bits 6-29 (the offset) add r3,r4,r3 #Gets Address in r3 add r3,r3,r5 #Offset From Start Of Jump Table #Init Loop subi r3,r3,0x2 lwz r6,0x10(r29) #AS #Check For BlackListed AS ## Terminator = FFFF ## Jump to = 7FXX LedgedashASCheckLoop: lhzu r4,0x2(r3) #Get Next Value extsb r0,r4 cmpwi r0,-1 #Check For Terminator beq Ledgedash_ResetProg rlwinm r0,r4,0,15,23 #Isolate Left Half cmpwi r0,0x7F00 #Check If New "Jump To" bne LedgedashCompareAS rlwinm r5,r4,0,24,31 #Isolate Right Half to r5 b LedgedashASCheckLoop LedgedashCompareAS: cmpw r6,r4 bne LedgedashASCheckLoop stb r5,0x1(r31) #Progress Byte b LedgedashThinkEnd LedgedashThinkEnd: mr r3,MenuData bl ClearToggledOptions restore blr #################### ## Reset Progress ## #################### Ledgedash_ResetProg: #Check If On Ground lwz r3,0xE0(r29) cmpwi r3,0x0 beq Ledgedash_Reset #Check If Dead lbz r3,0x221F(r29) rlwinm. r3,r3,0,25,25 bne Ledgedash_Reset #Check If Frame 9 Of Wrong Move li r3,9 bl IntToFloat lfs f2,0x894(r29) #Frames in State fcmpo cr0,f2,f1 blt LedgedashThinkEnd Ledgedash_Reset: #Play Success or Failure Noise lhz r3,TM_OneASAgo(r29) #Check Prev AS cmpwi r3,ASID_LandingFallSpecial #If Landing, Success beq Ledgedash_PlaySuccess cmpwi r3,ASID_Wait #If Wait, Success (Frame Perfect Action) beq Ledgedash_PlaySuccess lwz r3,CurrentAS(r29) cmpwi r3,ASID_Landing #If Aerial Interrupt, Check If Can IASA Yet beq Ledgedash_AerialInterruptCheck cmpwi r3,ASID_Wait #If No Impact Land, Success beq Ledgedash_PlaySuccess b Ledgedash_PlayFailure Ledgedash_AerialInterruptCheck: #Check If Coming From an Aerial Attack lhz r3,TM_OneASAgo(r29) #Check Prev AS cmpwi r3,ASID_AttackAirN blt Ledgedash_PlayFailure cmpwi r3,ASID_AttackAirLw bgt Ledgedash_PlayFailure #Check If Interruptable Yet lfs f2,0x1F4(r29) #Check Which Frame Landing is Interruptable li r3,1 bl IntToFloat fsubs f1,f2,f1 #Sub 1 Because Order of Operations lfs f2,0x894(r29) #Check Current Frame fcmpo cr0,f2,f1 blt LedgedashThinkEnd Ledgedash_PlaySuccess: #Increment Score lhz r3,-0x4ea8(r13) addi r3,r3,0x1 sth r3,-0x4ea8(r13) #Check To Make New High Score lhz r3,-0x4ea8(r13) lhz r4,-0x4ea6(r13) cmpw r3,r4 ble Ledgedash_PlaySuccess_PlaySound #Copy To High Score sth r3,-0x4ea6(r13) Ledgedash_PlaySuccess_PlaySound: #Play Sound li r3,0xAD bl PlaySFX #Set Timer li r3,30 stb r3,timer(r31) b LedgedashThinkEnd Ledgedash_PlayFailure: #Reset Score li r3,0 sth r3,-0x4ea8(r13) #Play Sound li r3,0xAF Ledgedash_PlaySound: bl PlaySFX #Place on Ledge mr r3,REG_EventData lbz r4,currentLedge(REG_EventData) bl Ledgedash_PlaceOnLedge b Ledgedash_LoadState Ledgedash_CheckToReset: lbz r3,timer(r31) #Check If Timer is Set cmpwi r3,0x0 ble LedgedashThinkEnd Ledgedash_CheckForInvincibleMove: lbz r3,hitboxFoundFlag(r31) #Check If Hitbox Was Already Found cmpwi r3,0x1 beq Ledgedash_DecrementTimer lwz r3,0x1990(r29) #Check If Char is Invincible cmpwi r3,0x0 ble Ledgedash_DecrementTimer mr r3,r30 #Check If a Hitbox is Active bl CheckForActiveHitboxes cmpwi r3,0x0 beq Ledgedash_DecrementTimer li r3,0xAA #Play Sound branchl r12,SFX_PlaySoundAtFullVolume li r3,1 #Mark As Found stb r3,hitboxFoundFlag(r31) Ledgedash_DecrementTimer: lbz r3,timer(r31) subi r3,r3,0x1 #Decrement stb r3,timer(r31) cmpwi r3,0x0 bgt LedgedashThinkEnd #Load State (to cleanup volatile entities) addi r3,REG_EventData,EventData_SaveStateStruct bl SaveState_Load #Place on Ledge mr r3,REG_EventData lbz r4,currentLedge(REG_EventData) bl Ledgedash_PlaceOnLedge #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save Ledgedash_LoadState: #Reset all event variables li r3,0x0 stb r3,eventState(r31) #Progress Byte stb r3,hitboxFoundFlag(r31) #Invincible Move Bool stb r3,timer(r31) #Timer addi r3,REG_EventData,EventData_SaveStateStruct bl SaveState_Load #Create Respawn Platform If Enabled lbz r3,StartingLocation(MenuData) cmpwi r3,0x0 beq Ledgedash_LoadState_SkipRespawnPlatform #Remember Facing Direction (Rebirth changes this) lfs f31,0x2C(r29) #Enter P1 Into Rebirth Again mr r3,r30 branchl r12,AS_Rebirth #Restore Facing Direction stfs f31,0x2C(r29) #Randomize Location #Get Stage's Ledges lwz r3,-0x6CB8 (r13) #External Stage ID bl LedgedashCliffIDs mflr r4 mulli r3,r3,0x2 lhzx r3,r3,r4 #Get Correct Ledge From Facing Direction lfs f1, 0x002C (r29) lfs f0, -0x7660 (rtoc) fcmpo cr0,f1,f0 ble Ledgedash_LoadState_GetRightLedge Ledgedash_LoadState_GetLeftLedge: #Get Ledge X and Y Coordinates rlwinm r3,r3,24,24,31 addi r4,sp,0x80 branchl r12,Stage_GetLeftOfLineCoordinates b Ledgedash_LoadState_RandomizePosition Ledgedash_LoadState_GetRightLedge: #Get Ledge X and Y Coordinates rlwinm r3,r3,0,24,31 addi r4,sp,0x80 branchl r12,Stage_GetRightOfLineCoordinates Ledgedash_LoadState_RandomizePosition: #Get Random Distance from this .set RandomDistanceMinX,30 .set RandomDistanceMaxX,55 .set RandomDistanceMinY,-30 .set RandomDistanceMaxY,30 li r3,RandomDistanceMinX li r4,RandomDistanceMaxX bl RandFloat fmr f31,f1 li r3,RandomDistanceMinY li r4,RandomDistanceMaxY bl RandFloat fmr f30,f1 #Add to Ledge Coordinates lfs f1,0x2C(r29) #Facing Direction fneg f1,f1 fmuls f31,f1,f31 lfs f0,0x80(sp) #Ledge X fadds f31,f0,f31 lfs f1,0x84(sp) #Ledge Y fadds f30,f1,f30 #Store to Player Block stfs f31,0xB0(r29) stfs f30,0xB4(r29) #Enter RebirthWait mr r3,r30 branchl r12,AS_RebirthWait #Store Blr as Physics bl BlrFunctionPointer mflr r3 stw r3,0x21A4(r29) #Store Custom RebirthWait Interrupt bl Custom_InterruptRebirthWait mflr r3 stw r3,0x219C(r29) #Update RebirthPlat Position mr r3,P1GObj branchl r12,RebirthPlatform_UpdatePosition Ledgedash_LoadState_SkipRespawnPlatform: mr r3,r30 bl UpdatePosition #Update Camera Box mr r3,P1GObj bl UpdateCameraBox b LedgedashThinkEnd ##################### ## PlaceAboveLedge ## ##################### Ledgedash_PlaceOnLedge: backup .set REG_EventData,31 .set REG_P1GObj,30 .set REG_P1Data,29 .set REG_LedgeID,28 .set REG_CameraBox,28 #Init mr REG_EventData,r3 mr REG_LedgeID,r4 stb REG_LedgeID,currentLedge(REG_EventData) #Get P1 data li r3,0 branchl r12,PlayerBlock_LoadMainCharDataOffset mr REG_P1GObj,r3 lwz REG_P1Data,0x2C(REG_P1GObj) #Place on ledge mr r3,REG_P1GObj mr r4,REG_LedgeID bl PlaceOnLedge #RESET PROGRESS li r3,0x0 stb r3,eventState(REG_EventData) #Get Stage's Ledge IDs lwz r3,-0x6CB8 (r13) #External Stage ID bl LedgedashCliffIDs mflr r4 mulli r3,r3,0x2 lhzx r3,r3,r4 #Get Requested Ledge cmpwi REG_LedgeID,0x0 beq Ledgedash_PlaceOnLedge_GetLeftLedgeID Ledgedash_PlaceOnLedge_GetRightLedgeID: rlwinm r21,r3,0,24,31 b Ledgedash_PlaceOnLedge_SkipLedgeID Ledgedash_PlaceOnLedge_GetLeftLedgeID: rlwinm r21,r3,24,24,31 Ledgedash_PlaceOnLedge_SkipLedgeID: #Adjust Ledge Camera Box Accordingly #Get Ledge Coordinates mr r3,r21 addi r4,sp,0xD0 lfs f1, 0x002C (REG_P1Data) lfs f0, -0x7660 (rtoc) fcmpo cr0,f1,f0 ble Ledgedash_PlaceOnLedge_CameraBoxRightLedge Ledgedash_PlaceOnLedge_CameraBoxLeftLedge: branchl r12,Stage_GetLeftOfLineCoordinates b Ledgedash_PlaceOnLedge_UpdateCameraBox Ledgedash_PlaceOnLedge_CameraBoxRightLedge: branchl r12,Stage_GetRightOfLineCoordinates Ledgedash_PlaceOnLedge_UpdateCameraBox: #Get CameraBox lwz REG_CameraBox,CameraBox(REG_EventData) #Position Base of CameraBox behind the ledge .set CameraBoxXOffset,35 .set CameraBoxYOffset,20 li r3,CameraBoxXOffset bl IntToFloat lfs f2,0xD0(sp) #Ledge X lfs f3,0x2C(REG_P1Data) fmadds f1,f1,f3,f2 stfs f1,0x10(REG_CameraBox) #Camera X Position li r3,CameraBoxYOffset bl IntToFloat lfs f2,0xD4(sp) #Ledge Y fadds f1,f1,f2 stfs f1,0x14(REG_CameraBox) #Camera Y Position #Make Boundaries around ledge position #Left Bound li r3,-10 bl IntToFloat stfs f1,0x40(REG_CameraBox) #Right Bound li r3,10 bl IntToFloat stfs f1,0x44(REG_CameraBox) #Top Bound li r3,10 bl IntToFloat stfs f1,0x48(REG_CameraBox) #Lower Bound li r3,-10 bl IntToFloat stfs f1,0x4C(REG_CameraBox) #Update Camera Box mr r3,REG_P1GObj bl UpdateCameraBox restore blr #################################### LedgedashCliffIDs: blrl .long 0xFFFFFFFF #Dummy, TEST .long 0x03073336 #FoD, Pokemon Stadium .long 0x030D2945 #Peach's Castle, Kongo Jungle .long 0x0511091A #Brinstar, Corneria .long 0x02061517 #Yoshi's Story, Onett .long 0x0000434C #Mute City, Rainbow Cruise .long 0x00000000 #Jungle Japes, Great Bay .long 0x0E0D0000 #Hyrule Temple, Brinstar Depths .long 0x00051E2E #Yoshi's Island, Green Greens .long 0x0C0E0204 #Fourside, MKI .long 0x03050000 #MKII, Akaneia .long 0x06120000 #Venom, PokeFloats .long 0xD7E20000 #Big Blue, Icicle Mountain .long 0x00000000 #Icetop, Flatzone .long 0x0305030B #Dream Land, Yoshis Island 64 .long 0x06100005 #Kongo Jungle 64, Battlefield .long 0x00020101 #Final Destination #################################### #CliffWait -> Fall LedgedashProg0: #*********************# .hword 0x7F00 .hword ASID_CliffCatch,ASID_CliffWait .hword ASID_RebirthWait #*********************# .hword 0x7F01 .hword ASID_Fall #*********************# .hword 0x7F02 .hword ASID_JumpAerialF,ASID_JumpAerialB #*********************# .hword -1 .align 2 #Fall -> JumpAerial LedgedashProg1: .hword 0x7F00 .hword ASID_CliffCatch,ASID_CliffWait #*********************# .hword 0x7F01 .hword ASID_Fall,ASID_PassiveWallJump #*********************# .hword 0x7F02 .hword ASID_JumpAerialF,ASID_JumpAerialB .hword ASID_FallSpecial,ASID_CliffJumpSlow2 .hword ASID_FallAerial,0x17E .hword 0x166,0x167 .hword 0x170,0x164 .hword 0x155,0x15e .hword 0x15f,0x160 .hword 0x16B,0x171 .hword 0x15C,0x16D .hword 0x165,0x16E .hword 0x168,0x161 .hword 0x176,0x15D .hword 0x169,0x162 #*********************# .hword -1 .align 2 #JumpAerial -> Airdodge LedgedashProg2: #*********************# .hword 0x7F02 .hword ASID_JumpAerialF,ASID_PassiveWallJump .hword ASID_JumpAerialB,ASID_Fall .hword ASID_FallSpecial,ASID_CliffJumpSlow2 .hword ASID_FallAerial,0x17E .hword 0x167,0x170 .hword 0x164,0x162 .hword 0x15e,0x15f .hword 0x160,0x16B .hword 0x171,0x15C .hword 0x16D,0x16E .hword 0x165,0x168 .hword 0x161,0x176 .hword 0x15D,0x155 .hword 0x169,0x166 #*********************# .hword 0x7F03 .hword ASID_EscapeAir,ASID_AttackAirB .hword ASID_AttackAirB,ASID_AttackAirU .hword ASID_AttackAirD,ASID_AttackAirF .hword ASID_AttackAirN,ASID_LandingFallSpecial #*********************# .hword 0x7F00 .hword ASID_CliffCatch #*********************# .hword -1 .align 2 #Airdodge -> Landing LedgedashProg3: #*********************# .hword 0x7F03 .hword 0xAA #i think this is just a placeholder, could prob remove but w/e #*********************# .hword 0x7F04 .hword ASID_LandingFallSpecial,ASID_Landing #*********************# .hword -1 .align 2 #Landing -> Wait LedgedashProg4: #*********************# .hword 0x7F04 .hword ASID_LandingFallSpecial #*********************# .hword 0x7F02 .hword ASID_Fall #*********************# .hword -1 .align 2 #################################### LedgedashWindowInfo: blrl .long 0x010101FF #1 window, Respawn Platform has 2 options, AutoRestore has 2 options LedgedashWindowText: blrl #Option Title = Starting Location .string "Starting Location" .align 2 #Option 1 = Ledge .string "Ledge" .align 2 #Option 2 = Respawn Platform .string "Respawn Platform" .align 2 #Option Title = AutoRestore .string "AutoRestore" .align 2 #Option 1 = On .string "On" .align 2 #Option 2 = Off .string "Off" .align 2 #################################### LedgedashLoadExit: restore blr #endregion #region SDI Training ############################## ## SDI Training HIJACK INFO ## ############################## SDITraining: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Fox.Ext #Use chosen CPU li r6,FinalDestination #Use SSS Stage load r7,EventOSD_SDI li r8,1 #Use Sopo bool bl InitializeMatch #Make default color lwz r3,0x0(r29) lwz r3,0x18(r3) #p2 pointer li r4,0x0 stb r4,0x3(r3) #Default color #STORE THINK FUNCTION SDITrainingStoreThink: bl SDITrainingLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## SDI Training LOAD FUNCT ## ######################## SDITrainingLoad: blrl backup bl InitializeHighScore #Schedule Think bl SDITrainingThink mflr r3 li r4,3 #Priority (After Interrupt) li r5,0 #No Option Menu bl CreateEventThinkFunction b SDITrainingLoadExit ######################### ## SDI Training THINK FUNCT ## ######################### .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 SDITrainingThink: blrl backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 li r3,0xF stw r3,0x1A94(r29) bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq SDITrainingThinkMain bl SDITrainingFloats mflr r3 bl Event_EnterGrab #Store 999 To Breakout lis r3,0x4461 stw r3,0x1A4C(r27) #Give Percent bl SDITrainingStartingPercents mflr r4 lwz r3,0x4(r27) #Get Char ID lbzx r3,r3,r4 #Get Percent load r4,0x80453080 #P1 Static Block sth r3,0x60(r4) #Store Percent Int To Display Value sth r3,0x62(r4) #Store Percent Int To Display Value (Subchar) bl IntToFloat stfs f1,0x1830(r27) #Store to Actual Damage Value #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Random Start Time li r3,60 branchl r12,HSD_Randi li r4,0 sub r3,r4,r3 stw r3,0x4(r31) #Reset Timer SDITrainingThinkMain: #Inc Timer lwz r3,0x4(r31) addi r3,r3,0x1 stw r3,0x4(r31) #Check If SDI'd UpAir (Damage_LightHit + No Hitstun) #Check If Already Incremented lbz r3,0xA(r31) cmpwi r3,0x1 beq SDITraining_SkipSDICheck #Check AS lwz r3,0x10(r27) cmpwi r3,0x55 bne SDITraining_SkipSDICheck #Check For Hitstun lbz r3, 0x221C (r27) rlwinm. r0, r3, 31, 31, 31 bne SDITraining_SkipSDICheck #Set Flag li r3,0x1 stb r3,0xA(r31) #Play Sound li r3,0xAD bl PlaySFX #Increment Score lhz r3,-0x4ea8(r13) addi r3,r3,0x1 sth r3,-0x4ea8(r13) #Check To Make New High Score lhz r3,-0x4ea8(r13) lhz r4,-0x4ea6(r13) cmpw r3,r4 ble SDITraining_SkipSDICheck #Copy To High Score sth r3,-0x4ea6(r13) SDITraining_SkipSDICheck: #Check If Missed SDI (Fox in UpAir + P1 in Damage Heavy State) #Check If Fox Is Up-Airing lwz r3,0x10(r29) cmpwi r3,0x44 bne SDITraining_SkipMissedSDICheck #Check If P1 is in Hitlag lbz r3,0x221A(r27) #Check If in Hitlag rlwinm. r3,r3,0,26,26 beq SDITraining_SkipMissedSDICheck #Check If Fox is Past Frame 11 li r3,11 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f2,f1 blt SDITraining_SkipMissedSDICheck #Reset Score li r3,0 sth r3,-0x4ea8(r13) SDITraining_SkipMissedSDICheck: #Update Score lhz r3,-0x4ea8(r13) branchl r12,HUD_KOCounter_UpdateKOs #Check State lbz r3,0x8(r31) cmpwi r3,0 beq SDITrainingUpThrowThink cmpwi r3,1 beq SDITrainingFollowOpponentThink cmpwi r3,2 beq SDITrainingJumpThink cmpwi r3,3 beq SDITrainingUpAirThink cmpwi r3,4 beq SDITrainingCheckForReset #******************************************************# SDITrainingUpThrowThink: #Check Timer lwz r3,0x4(r31) cmpwi r3,0x0 blt SDITrainingThinkExit #Check If In Wait lwz r3,0x10(r29) cmpwi r3,0xE bne SDITrainingUpThrowThink_InputUpThrow #Advance to Next State li r3,0x1 stb r3,0x8(r31) b SDITrainingFollowOpponentThink SDITrainingUpThrowThink_InputUpThrow: #UpThrow li r3,127 stb r3,0x1A8D(r29) b SDITrainingThinkExit #******************************************************# SDITrainingFollowOpponentThink: SDITrainingFollowOpponentThink_CheckIfAirbourne: lwz r3,0xE0(r29) cmpwi r3,0x1 bne SDITrainingFollowOpponentThink_CheckDistance li r3,0x2 stb r3,0x8(r31) b SDITrainingJumpThink SDITrainingFollowOpponentThink_CheckDistance: #Determine Which Distance Value lwz r3,0x10(r29) cmpwi r3,0x14 bne 0xC li r3,15 b 0x8 li r3,10 bl SDITrainingInputTowardsOpponent #Check If Already Jumping, If So Follow Through lwz r4,0x10(r29) cmpwi r4,0x18 beq SDITrainingFollowOpponentThink_CheckIfJumping cmpwi r3,0x1 #Checks If In Range of Opponent bne SDITrainingThinkExit #Check If Jumping SDITrainingFollowOpponentThink_CheckIfJumping: lwz r3,0x10(r29) cmpwi r3,0x18 bne SDITrainingFollowOpponentThink_InputJump #If Less than 32 Mm Away, Short Hop lfs f1,0xB4(r27) #P1 X Coord lfs f2,0xB4(r29) #P2 X Coord fsubs f3,f2,f1 #Get Difference li r3,32 bl IntToFloat fabs f2,f3 fcmpo cr0,f2,f1 blt SDITrainingThinkExit #Input Jump SDITrainingFollowOpponentThink_InputJump: li r3,0x800 stw r3,0x1A88(r29) b SDITrainingThinkExit #******************************************************# SDITrainingJumpThink: #Follow Opponent li r3,5 bl SDITrainingInputTowardsOpponent #When Less Than 35 Mm Away in the Y Direction, Up Air lfs f1,0xB4(r27) #P1 X Coord lfs f2,0xB4(r29) #P2 X Coord fsubs f3,f2,f1 #Get Difference li r3,35 bl IntToFloat fabs f2,f3 fcmpo cr0,f2,f1 bgt SDITrainingJumpThink_CheckToDJ #Input UpAir li r3,127 stb r3,0x1A8F(r29) #Set Timer To Reset li r3,60 stb r3,0x9(r31) #Advance State li r3,0x3 stb r3,0x8(r31) b SDITrainingUpAirThink SDITrainingJumpThink_CheckToDJ: #If in Frame X Of Jump, DJ lwz r3,0x10(r29) cmpwi r3,0x19 beq SDITrainingJumpThink_CheckToDJ_InJump cmpwi r3,0x1A beq SDITrainingJumpThink_CheckToDJ_InJump b SDITrainingThinkExit SDITrainingJumpThink_CheckToDJ_InJump: li r3,4 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f1,f2 bne SDITrainingThinkExit #Enter DJ li r3,0x800 stw r3,0x1A88(r29) b SDITrainingThinkExit #******************************************************# SDITrainingUpAirThink: #Check If UpAir Hitboxes Are Over li r3,12 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f2,f1 bge SDITrainingCheckForReset #Follow Opponent li r3,5 bl SDITrainingInputTowardsOpponent #Check If Back On Ground lwz r3,0xE0(r29) cmpwi r3,0x0 bne SDITrainingCheckForReset #Advance State li r3,0x4 stb r3,0x8(r31) b SDITrainingCheckForReset #******************************************************# SDITrainingInputTowardsOpponent: #Returns a bool indicating if the character is within range backup mr r31,r3 #Backup Distance Threshold #Get X Distance lfs f1,0xB0(r27) #P1 X Coord lfs f2,0xB0(r29) #P2 X Coord fsubs f3,f2,f1 #Get Difference #If Within 4 Mm, Jump mr r3,r31 bl IntToFloat fabs f2,f3 fcmpo cr0,f2,f1 bgt SDITrainingFollowOpponentThink_InputTowardsOpponent li r3,0x1 b SDITrainingInputTowardsOpponent_Exit SDITrainingFollowOpponentThink_InputTowardsOpponent: #Push Towards Opponent's Direction bl GetDirectionInRelationToP1 mulli r3,r3,-1 #Negate This li r4,127 mullw r3,r3,r4 stb r3,0x1A8C(r29) li r3,0x0 SDITrainingInputTowardsOpponent_Exit: restore blr #******************************************************# SDITrainingCheckForReset: lbz r3,0x9(r31) cmpwi r3,0x0 beq SDITrainingThinkExit subi r3,r3,0x1 stb r3,0x9(r31) cmpwi r3,0x0 bne SDITrainingThinkExit #Load State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Random Timer li r3,60 branchl r12,HSD_Randi mulli r3,r3,-1 stw r3,0x4(r31) #Reset State li r3,0 stb r3,0x8(r31) #Reset SDI'd Flag li r3,0x0 stb r3,0xA(r31) SDITrainingThinkExit: restore blr ############## Event_EnterGrab: backup mr r20,r3 #Move P1 lfs f1,0x0(r20) stfs f1,0xB0(r27) lfs f1,0x4(r20) stfs f1,0xB4(r27) mr r3,r28 bl UpdatePosition mr r3,r28 bl CheckIfPlayerHasAFollower cmpwi r3,0 beq Event_EnterGrab_MoveP2 #Move Subchar lfs f1,0x0(r20) stfs f1,0xB0(r5) lfs f1,0x4(r20) stfs f1,0xB4(r5) bl UpdatePosition Event_EnterGrab_MoveP2: #Move P2 lfs f1,0x8(r20) stfs f1,0xB0(r29) lfs f1,0xC(r20) stfs f1,0xB4(r29) mr r3,r30 bl UpdatePosition mr r3,r30 bl CheckIfPlayerHasAFollower cmpwi r3,0 beq Event_EnterGrab_EnterGrabAS #Move Subchar lfs f1,0x8(r20) stfs f1,0xB0(r5) lfs f1,0xC(r20) stfs f1,0xB4(r5) bl UpdatePosition Event_EnterGrab_EnterGrabAS: #Store P1 into P2 Grab Pointer stw r28,0x1A58(r29) #Enter P2 Into Grab mr r3,r30 #P2 Enters Grab branchl r12,AS_GrabOpponent #Enter P1 Into Grabbed mr r3,r28 #P1 Grabbed mr r4,r30 #P2 = Grabber branchl r12,AS_Grabbed #Enter P2 Into GrabWait mr r3,r30 #P2 Enters GrabWait branchl r12,AS_CatchWait #Enter P2 Into Grounded mr r3,r29 branchl r12,SetAsGrounded #Remove P2's GFX Pointer That Is Crashing the Game li r3,0x0 stw r3,0x60C(r29) restore blr ############## SDITrainingStartingPercents: blrl .long 0x085F8040 # Mario = 8 / Fox = 95 / Falcon = 70 / DK = 25 .long 0x0030190F # Kirby = 0 / Bowser = 25 / Link = 25 / Sheik = 15 .long 0x00000000 # Ness = 0 / Peach = 0 / Popo = 0 / Nana = 0 .long 0x08050F00 # Pikachu = 8 / Samus = 5 / Yoshi = 15 / Jiggs = 0 .long 0x00001400 # Mewtwo = 0 / Luigi = 0 / Marth = 20 / Zelda = 0 .long 0x19085F00 # YLink = 25 / Doc = 8 / Falco = 95 / Pichu = 0 .long 0x002D3A00 # GaW = 0 / Ganon = 45 / Roy = 58 SDITrainingFloats: blrl .long 0xC02CCCCD #P1 X Position .long 0x00000000 #P1 Y Position .long 0x4144CCCD #P2 X Position .long 0x00000000 #P2 Y Position SDITrainingLoadExit: restore blr ################################################################################ ################################################################################ #endregion #region Reversal Training ######################### ## Reversal HIJACK INFO ## ######################### Reversal: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,-1 #Use SSS Stage load r7,EventOSD_Reversal li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION bl ReversalLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Reversal LOAD FUNCT ## ######################## ReversalLoad: blrl backup #Schedule Think bl ReversalThink mflr r3 li r4,3 #Priority (After Interrupt) bl ReversalWindowInfo mflr r5 bl ReversalWindowText mflr r6 bl CreateEventThinkFunction b ReversalLoadExit ######################### ## Reversal THINK FUNCT ## ######################### .set MenuData,26 .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 .set firstFrameFlag,0x0 .set timer,0x4 .set CPUAttack,(MenuData_OptionMenuMemory+0x2)+(0x0) .set P1FacingDirection,(MenuData_OptionMenuMemory+0x2)+(0x1) .set CPUFacingDirection,(MenuData_OptionMenuMemory+0x2)+(0x2) .set CPUAttackToggled,MenuData_OptionMenuToggled+(0x0) .set P1FacingDirectionToggled,MenuData_OptionMenuToggled+(0x1) .set CPUFacingDirectionToggled,MenuData_OptionMenuToggled+(0x2) .set AerialThinkStruct,0x20 ReversalThink: blrl .set EventData,31 backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 lwz MenuData,EventData_MenuDataPointer(EventData) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 li r3,0xF stb r3,0x1A94(r29) bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq ReversalThinkMain #bl Reversal_Floats #mflr r3 #bl InitializePositions #Move PLayers Center Stage bl PlacePlayersCenterStage #Clear Inputs bl RemoveFirstFrameInputs #SaveState addi r3,EventData,0x10 #SaveState start li r4,1 #Override failsafe code bl SaveState_Save #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) #Set Timer to -60 li r3,-60 stw r3,0x4(r31) ReversalThinkMain: bl GiveFullShields #Reset when menu is toggled lbz r3,P1FacingDirectionToggled(MenuData) cmpwi r3,0x0 bne ReversalReset #Only Run When Hovered Over Facing Direction lbz r3,CPUFacingDirectionToggled(MenuData) cmpwi r3,0x0 bne ReversalReset #Only Run When Hovered Over Facing Direction lbz r3,CPUAttackToggled(MenuData) cmpwi r3,0x0 bne ReversalReset ReversalSkipFacingReset: #Move Players Apart With DPad addi r3,EventData,0x10 #SaveState start bl AdjustResetDistance cmpwi r3,-1 bne ReversalReset ReversalThinkSequence: #Increment Timer lwz r20,0x4(r31) #get timer addi r20,r20,0x1 stw r20,0x4(r31) #store timer #Give Invincibility in Wait, Squat Reverse, IASA Flag Flipped lwz r3,0x10(r29) cmpwi r3,0xE beq ReversalGiveInvincibility cmpwi r3,0x29 beq ReversalGiveInvincibility lbz r3, 0x2218 (r29) rlwinm. r3, r3, 25, 31, 31 bne ReversalGiveInvincibility b ReversalCheckToAttack ReversalGiveInvincibility: mr r3,r30 li r4,0x2 bl GiveInvincibility #Check To Attack ReversalCheckToAttack: #Check Timer cmpwi r20,45 blt ReversalThinkExit #Check If Attack is Over lbz r3,AerialThinkStruct(r31) cmpwi r3,0x0 bne ReversalCheckToReset ReversalDecideSmashAttack: lbz r3,CPUAttack(MenuData) cmpwi r3,0x0 beq ReversalRandomSmashAttack cmpwi r3,0x1 beq ReversalFSmash cmpwi r3,0x2 beq ReversalDSmash cmpwi r3,0x3 beq ReversalUSmash cmpwi r3,0x4 beq ReversalRandomAerial cmpwi r3,0x5 beq ReversalNair cmpwi r3,0x6 beq ReversalFair cmpwi r3,0x7 beq ReversalDair cmpwi r3,0x8 beq ReversalFTilt cmpwi r3,0x9 beq ReversalDTilt cmpwi r3,0xA beq ReversalUTilt ReversalRandomSmashAttack: li r3,3 branchl r12,HSD_Randi mr r21,r3 #Check If Move is Blacklisted lwz r4,0x4(r29) #Char ID bl Reversal_Blacklist mflr r5 #Get Frame Data Table mulli r4,r4,0x4 #Get Characters Offset add r4,r4,r5 #Get Characters Table Entry Start lbzx r4,r21,r4 #Get Moves Entry cmpwi r4,0x1 #Is Move BlackListed? beq ReversalRandomSmashAttack #Perform Move cmpwi r21,0x0 beq ReversalFSmash cmpwi r21,0x1 beq ReversalUSmash cmpwi r21,0x2 beq ReversalDSmash ReversalFSmash: #Input Atack li r3,127 #Forward lfs f1,0x2C(r29) #Facing Direction fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) mullw r3,r3,r4 #Forward * facing direction stb r3,0x1A8E(r29) #Set Attack as ended li r3,0x1 stb r3,AerialThinkStruct(r31) b ReversalCheckToReset ReversalUSmash: li r3,127 stb r3,0x1A8F(r29) b ReversalCheckToReset #Set Attack as ended li r3,0x1 stb r3,AerialThinkStruct(r31) ReversalDSmash: li r3,-127 stb r3,0x1A8F(r29) #Set Attack as ended li r3,0x1 stb r3,AerialThinkStruct(r31) b ReversalCheckToReset ReversalRandomAerial: #Perform Aerial mr r3,r30 addi r4,r31,AerialThinkStruct li r5,0 #Random Aerial bl PerformAerialThink b ReversalCheckToReset ReversalNair: ReversalFair: ReversalDair: #Perform Aerial subi r5,r3,0x4 mr r3,r30 addi r4,r31,AerialThinkStruct bl PerformAerialThink b ReversalCheckToReset ReversalFTilt: li r3,45 lfs f1,0x2C(r29) #Facing Direction fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) mullw r3,r3,r4 #Forward * facing direction stb r3,0x1A8C(r29) li r3,0x100 stw r3,0x1A88(r29) #Set Attack as ended li r3,0x1 stb r3,AerialThinkStruct(r31) b ReversalCheckToReset ReversalUTilt: li r3,45 stb r3,0x1A8D(r29) li r3,0x100 stw r3,0x1A88(r29) #Set Attack as ended li r3,0x1 stb r3,AerialThinkStruct(r31) b ReversalCheckToReset ReversalDTilt: li r3,-45 stb r3,0x1A8D(r29) li r3,0x100 stw r3,0x1A88(r29) #Set Attack as ended li r3,0x1 stb r3,AerialThinkStruct(r31) b ReversalCheckToReset ReversalCheckToReset: cmpwi r20,150 #Restore After 120 Frames blt ReversalThinkExit ReversalReset: ReversalSwap: #I fucking hate this code, i need to clean this up at some point. #Get leftmost player pointer in r20, rightmost in r21 addi r5,EventData,0x10 lwz r3,0x0(r5) lfs f1,0xB0(r3) lwz r4,0x8(r5) lfs f2,0xB0(r4) fcmpo cr0,f1,f2 bgt 0x10 mr r20,r3 mr r21,r4 b 0xC mr r20,r4 mr r21,r3 #Get which side to start on li r3,2 #0 = p1 on left, 1 = p1 on right branchl r12,HSD_Randi cmpwi r3,0x0 bne ReversalReset_RightSide ReversalReset_LeftSide: #Swap Position addi r5,EventData,0x10 #Get Leftmost Chars Position li r3,1 bl IntToFloat fmr f2,f1 lfs f3,0xB0(r20) lfs f4,0xB4(r20) #Get Rightmost Chars Position li r3,-1 bl IntToFloat fmr f5,f1 lfs f6,0xB0(r21) lfs f7,0xB4(r21) #Store to P1 Data lwz r3,0x0(r5) stfs f2,0x2C(r3) stfs f3,0xB0(r3) stfs f4,0xB4(r3) #Store to P2 Data lwz r3,0x8(r5) stfs f5,0x2C(r3) stfs f6,0xB0(r3) stfs f7,0xB4(r3) b ReversalReset_SwapEnd ReversalReset_RightSide: addi r5,EventData,0x10 #Get Leftmost Chars Position li r3,1 bl IntToFloat fmr f2,f1 lfs f3,0xB0(r20) lfs f4,0xB4(r20) #Get Rightmost Chars Position li r3,-1 bl IntToFloat fmr f5,f1 lfs f6,0xB0(r21) lfs f7,0xB4(r21) #Store to P2 Data lwz r3,0x8(r5) stfs f2,0x2C(r3) stfs f3,0xB0(r3) stfs f4,0xB4(r3) #Store to P1 Data lwz r3,0x0(r5) stfs f5,0x2C(r3) stfs f6,0xB0(r3) stfs f7,0xB4(r3) ReversalReset_SwapEnd: ReversalAdjustP1Direction: #Adjust P1 Facing Direction Based on Preference addi r5,EventData,0x10 lbz r3,P1FacingDirection(MenuData) cmpwi r3,0x1 bne ReversalAdjustP1Direction_Skip #Invert P1 Facing Direction lwz r3,0x0(r5) lfs f1,0x2C(r3) fneg f1,f1 stfs f1,0x2C(r3) ReversalAdjustP1Direction_Skip: #Adjust CPU Facing Direction Based on Preference ReversalAdjustCPUDirection: lbz r3,CPUFacingDirection(MenuData) cmpwi r3,0x1 bne ReversalAdjustCPUDirection_Skip #Invert P2 Facing Direction lwz r3,0x8(r5) lfs f1,0x2C(r3) fneg f1,f1 stfs f1,0x2C(r3) ReversalAdjustCPUDirection_Skip: #Restore ReversalLoadState: addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Reset Timer li r3,30 branchl r12,HSD_Randi li r4,0 sub r3,r4,r3 stw r3,0x4(r31) #Reset AerialThinkStruct li r3,0x0 stw r3,AerialThinkStruct(r31) ReversalThinkExit: mr r3,MenuData bl ClearToggledOptions bl UpdateAllGFX restore blr ################################# Reversal_Floats: blrl .long 0xC0F9999A #P1 X Position .long 0x40F9999A #P2 X Position .long 0x38d1b717 #FD Floor Y Coord .long 0x38d1b717 #FD Floor Y Coord ################################# Reversal_Blacklist: blrl #Mario .long 0x00000000 #FSmash USmash DSmash #Fox .long 0x01000000 #FSmash USmash DSmash #Cptn Falcon .long 0x00000000 #FSmash USmash DSmash #DK .long 0x00010000 #FSmash USmash DSmash #Kirby .long 0x00000000 #FSmash USmash DSmash #Bowser .long 0x00010000 #FSmash USmash DSmash #link .long 0x00000000 #FSmash USmash DSmash #Sheik .long 0x01000000 #FSmash USmash DSmash #Ness .long 0x00010100 #FSmash USmash DSmash #Peach .long 0x00010000 #FSmash USmash DSmash #Popo .long 0x00000000 #FSmash USmash DSmash #Nana .long 0x00000000 #FSmash USmash DSmash #Pikachu .long 0x00000000 #FSmash USmash DSmash #Samus .long 0x00010000 #FSmash USmash DSmash #Yoshi .long 0x00010000 #FSmash USmash DSmash #Jiggs .long 0x00010000 #FSmash USmash DSmash #mewtwo .long 0x00010000 #FSmash USmash DSmash #Luigi .long 0x00000000 #FSmash USmash DSmash #Marth .long 0x00010000 #FSmash USmash DSmash #Zelda .long 0x00010000 #FSmash USmash DSmash #YLink .long 0x00000000 #FSmash USmash DSmash #Doc .long 0x00000000 #FSmash USmash DSmash #Falco .long 0x01000000 #FSmash USmash DSmash #Pichu .long 0x00000000 #FSmash USmash DSmash #GaW .long 0x00000100 #FSmash USmash DSmash #Ganon .long 0x00000000 #FSmash USmash DSmash #Roy .long 0x00010000 #FSmash USmash DSmash #################################################### ReversalWindowInfo: blrl #amount of options, amount of options in each window .long 0x020A0101 #3 window, Smash Attack has 11 options, Facing Direction Has 2 #################################################### ReversalWindowText: blrl ######## ## DI ## ######## #Window Title = CPU Attack .long 0x43505520 .long 0x41747461 .long 0x636b0000 #Option 1 = Random Smash Attack .long 0x52616e64 .long 0x6f6d2053 .long 0x6d617368 .long 0x20417474 .long 0x61636b00 #Option 2 = Forward Smash .long 0x466f7277 .long 0x61726420 .long 0x536d6173 .long 0x68000000 #Option 3 = Down Smash .long 0x446f776e .long 0x20536d61 .long 0x73680000 #Option 4 = Up Smash .long 0x55702053 .long 0x6d617368 .long 0x #Option 5 = Random Aerial .long 0x52616e64 .long 0x6f6d2041 .long 0x65726961 .long 0x6c000000 #Option 6 = Fair .long 0x46616972 .long 0x #Option 7 = Nair .long 0x4e616972 .long 0x #Option 8 = Dair .long 0x44616972 .long 0x #Option 9 = FTilt .long 0x4654696c .long 0x74000000 #Option 10 = DTilt .long 0x4454696c .long 0x74000000 #Option 11 = UTilt .long 0x5554696c .long 0x74000000 #########$$$############# ## P1 Facing Direction ## ##########$$$############ #Window Title = Facing Direction .long 0x50312046 .long 0x6163696e .long 0x67204469 .long 0x72656374 .long 0x696f6e00 #Option 1 = Towards .long 0x546f7761 .long 0x72647300 .long 0x .long 0x .long 0x #Option 2 = Away .long 0x41776179 .long 0x .long 0x .long 0x .long 0x #########$$$############## ## CPU Facing Direction ## ##########$$$############# #Window Title = CP Facing Direction .long 0x43502046 .long 0x6163696e .long 0x67204469 .long 0x72656374 .long 0x696f6e00 #Option 1 = Towards .long 0x546f7761 .long 0x72647300 .long 0x .long 0x .long 0x #Option 2 = Away .long 0x41776179 .long 0x .long 0x .long 0x .long 0x #################################################### ReversalLoadExit: restore blr ################################################################################ ################################################################################ #endregion #region Powershield Training ######################### ## Powershield HIJACK INFO ## ######################### Powershield: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Falco.Ext #Use chosen CPU li r6,FinalDestination #Use SSS Stage load r7,EventOSD_Powershield li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION bl PowershieldLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Powershield LOAD FUNCT ## ######################## PowershieldLoad: blrl backup #Schedule Think bl PowershieldThink mflr r3 li r4,3 #Priority (After Interrupt) bl PowershieldWindowInfo mflr r5 bl PowershieldWindowText mflr r6 bl CreateEventThinkFunction bl InitializeHighScore b PowershieldLoadExit ######################### ## Powershield THINK FUNCT ## ######################### #Registers .set MenuData,26 .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 #Offsets .set FireSpeed,(MenuData_OptionMenuMemory+0x2)+0x0 PowershieldThink: blrl backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 lwz MenuData,EventData_MenuDataPointer(EventData) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl StoreCPUTypeAndZeroInputs #Make P2 A Follower (No Nudge) #li r3,0x8 #stb r3,0x221F(r29) li r3,0x1 lbz r0, 0x221D (r29) rlwimi r0,r3,2,29,29 stb r0, 0x221D (r29) #Update GFX mr r3,r30 bl UpdateAllGFX #Give Invincibility To P2 mr r3,r30 li r4,0x2 bl GiveInvincibility #Reset All Stale Moves bl ResetStaleMoves #DPad Changes Falco's Side lhz r3,0x662(r27) #Get Held Buttons rlwinm. r0,r3,0,27,27 bne 0xC cmpwi r3,0x0 bne Powershield_SkipPositionChange #CHECK FOR DPAD TO CHANGE Side lwz r3,0x668(r27) #Get DPad rlwinm. r0,r3,0,30,30 beq Powershield_CheckLeft lwz r3,0x10(r31) #P1's Backup lfs f1,0xB0(r3) #X Pos fabs f1,f1 stfs f1,0xB0(r3) #X Pos lfs f1,0x2C(r3) #Facing fabs f1,f1 fneg f1,f1 #Negate Always stfs f1,0x2C(r3) #Facing lwz r3,0x18(r31) #P2's Backup lfs f1,0xB0(r3) #X Pos fabs f1,f1 fneg f1,f1 #Negate Always stfs f1,0xB0(r3) #X Pos lfs f1,0x2C(r3) #Facing fabs f1,f1 #Always Positive stfs f1,0x2C(r3) #Facing b PowershieldRestore Powershield_CheckLeft: rlwinm. r0,r3,0,31,31 beq Powershield_SkipPositionChange lwz r3,0x10(r31) #P1's Backup lfs f1,0xB0(r3) #X Pos fabs f1,f1 fneg f1,f1 #Negate Always stfs f1,0xB0(r3) #X Pos lfs f1,0x2C(r3) #Facing fabs f1,f1 #Always Positive stfs f1,0x2C(r3) #Facing lwz r3,0x18(r31) #P2's Backup lfs f1,0xB0(r3) #X Pos fabs f1,f1 stfs f1,0xB0(r3) #X Pos lfs f1,0x2C(r3) #Facing fabs f1,f1 fneg f1,f1 #Negate Always stfs f1,0x2C(r3) #Facing b PowershieldRestore Powershield_SkipPositionChange: #Act Out Of Laser Hit bl ActOutOfLaserHitDisplay #Check For Powershield Reflect #Check For Shield Action State lwz r3,0x10(r27) cmpwi r3,0xB6 #Shield Start bne Powershield_SkipPowershieldCheck #Check For Powershield Bool lwz r3,0x2368(r27) cmpwi r3,0x0 beq Powershield_SkipPowershieldCheck #Remove Flag li r3,0x0 stw r3,0x2368(r27) #Increment Score lhz r3,-0x4ea8(r13) addi r3,r3,0x1 sth r3,-0x4ea8(r13) #Check To Make New High Score lhz r3,-0x4ea8(r13) lhz r4,-0x4ea6(r13) cmpw r3,r4 ble Powershield_SkipPowershieldCheck #Copy To High Score sth r3,-0x4ea6(r13) Powershield_SkipPowershieldCheck: #Check For Powershield Miss #Check For Shield Stun lwz r3,0x10(r27) cmpwi r3,0xB5 #Shield Stun beq Powershield_ResetScore #Check For Hitstun lbz r3, 0x221C (r27) rlwinm. r0, r3, 31, 31, 31 bne Powershield_ResetScore b Powershield_SkipMissedPowershieldCheck Powershield_ResetScore: #Reset Score li r3,0 sth r3,-0x4ea8(r13) Powershield_SkipMissedPowershieldCheck: #Update HUD Score lhz r3,-0x4ea8(r13) branchl r12,HUD_KOCounter_UpdateKOs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq PowershieldThinkMain #Set Timer to -60 li r3,-60 stw r3,0x4(r31) #Fix Inputs bl CurrentInputsAsLastFramesInputs #SaveState addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save PowershieldThinkMain: bl GiveFullShields PowershieldThinkSequence: #Increment Timer lwz r20,0x4(r31) #get timer addi r20,r20,0x1 stw r20,0x4(r31) #store timer #KneeBend(shorthop) cmpwi r20,0 blt PowershieldThinkExit bne PowershieldSkipJump li r3,0x800 stw r3,0x1A88(r29) b PowershieldThinkExit #Get Random Laser Timing in JumpF PowershieldSkipJump: lwz r3,0x10(r29) cmpwi r3,0x19 bne PowershieldSkipLaser li r3,4 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f1,f2 bne PowershieldThinkExit #Random Laser Timing li r3,2 branchl r12,HSD_Randi addi r3,r3,5 #Start on Frame 5 stw r3,0x8(r31) #Input Laser li r3,0x200 stw r3,0x1A88(r29) b PowershieldThinkExit PowershieldSkipLaser: #Check if in Laser Shoot lwz r3,0x10(r29) cmpwi r3,0x159 bne PowershieldCheckForIASA #Check in on the right frame lwz r3,0x8(r31) bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f1,f2 bne PowershieldCheckForIASA #Input a FF li r3,-127 stb r3,0x1A8D(r29) b PowershieldThinkExit PowershieldCheckForIASA: #Check if in Landing lwz r3,0x10(r29) cmpwi r3,0x2A bne PowershieldThinkExit #Check If Can Interrupt li r3,3 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f2,f1 blt PowershieldThinkExit bne PowershieldRandom li r3,14 branchl r12,HSD_Randi addi r3,r3,15 stb r3,0xF(r31) #Get Interval lbz r3,FireSpeed(MenuData) cmpwi r3,0x0 beq PowershieldRandom cmpwi r3,0x1 beq PowershieldSlow cmpwi r3,0x2 beq PowershieldMedium cmpwi r3,0x3 beq PowershieldFast cmpwi r3,0x4 beq PowershieldVeryFast PowershieldRandom: lbz r3,0xF(r31) bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f2,f1 blt PowershieldThinkExit li r3,-1 stw r3,0x4(r31) b PowershieldThinkExit PowershieldSlow: #Reset Timer li r3,-30 stw r3,0x4(r31) b PowershieldThinkExit PowershieldMedium: #Reset Timer li r3,-15 stw r3,0x4(r31) b PowershieldThinkExit PowershieldFast: #Reset Timer li r3,-8 stw r3,0x4(r31) b PowershieldThinkExit PowershieldVeryFast: #Reset Timer li r3,-1 stw r3,0x4(r31) b PowershieldThinkExit PowershieldThinkExit: mr r3,MenuData bl ClearToggledOptions restore blr PowershieldLoadExit: restore blr ################################## PowershieldRestore: addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load b PowershieldThinkExit ################################## PowershieldWindowInfo: blrl .long 0x00040000 #1 window, 5 options PowershieldWindowText: blrl #Title .long 0x46697265 .long 0x20537065 .long 0x65640000 .long 0x00000000 .long 0x00000000 #Random .long 0x52616e64 .long 0x6f6d0000 .long 0x .long 0x .long 0x #Slow .long 0x536c6f77 .long 0x .long 0x .long 0x .long 0x #Medium .long 0x4d656469 .long 0x756d0000 .long 0x .long 0x .long 0x #Fast .long 0x46617374 .long 0x .long 0x .long 0x .long 0x #Very Fast .long 0x56657279 .long 0x20466173 .long 0x74000000 .long 0x .long 0x ################################## ################################################################################ ################################################################################ #endregion #region Shield Drop Training ######################### ## Shield Drop HIJACK INFO ## ######################### ShieldDrop: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,Battlefield #Use SSS Stage load r7,EventOSD_ShieldDrop li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION bl ShieldDropLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Shield Drop LOAD FUNCT ## ######################## ShieldDropLoad: blrl backup #Schedule Think bl ShieldDropThink mflr r3 li r4,3 #Priority (After Interrupt) bl ShieldDropWindowInfo mflr r5 bl ShieldDropWindowText mflr r6 bl CreateEventThinkFunction b ShieldDropLoadExit ########################## ## Shield Drop THINK FUNCT ## ########################## #Registers .set MenuData,26 .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 #Offsets .set FacingDirection,(MenuData_OptionMenuMemory+0x2)+0x0 .set FacingDirectionToggled,(MenuData_OptionMenuToggled)+0x0 ShieldDropThink: blrl backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 lwz MenuData,EventData_MenuDataPointer(EventData) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq ShieldDropThinkMain #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) bl ShieldDrop_Floats mflr r3 bl InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Store Y Position to Last Known Y Position lfs f1,0xB4(r29) stfs f1,0x834(r29) #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Set Timer to -60 li r3,-60 stw r3,0x4(r31) ShieldDropThinkMain: .set AerialThinkStruct,0x8 bl GiveFullShields lbz r3,FacingDirectionToggled(MenuData) cmpwi r3,0 #Check If Toggled An Option bne ShieldDropReset lbz r3,FacingDirectionToggled(MenuData) cmpwi r3,0 #Check If Toggled An Option bne ShieldDropReset #Move Players Apart With DPad addi r3,EventData,0x10 #SaveState start bl AdjustResetDistance cmpwi r3,-1 bne ShieldDropReset ShieldDropThinkSequence: #Increment Timer lwz r20,0x4(r31) #get timer addi r20,r20,0x1 stw r20,0x4(r31) #store timer #Check if In Wait lwz r3,0x10(r29) cmpwi r3,0xE bne ShieldDropNoIntangibility #Give Intangibility in Wait mr r3,r30 li r4,0x2 bl GiveInvincibility ShieldDropNoIntangibility: #Check To Start Aerial cmpwi r20,40 blt ShieldDropThinkExit #Perform Aerial mr r3,r30 addi r4,r31,AerialThinkStruct li r5,0 #Random Attack bl PerformAerialThink ShieldDropCheckToShield: #Check If CPU is done with Aerial Sequence lbz r3,AerialThinkStruct(r31) cmpwi r3,0x0 beq ShieldDropCheckToReset #Hold Shield li r3,0xC0 #Hit L stw r3,0x1A88(r29) #Hold Shield ShieldDropCheckToReset: cmpwi r20,140 bne ShieldDropThinkExit ShieldDropReset: #Randomize Position li r3,0x1 #Opposing Sides of Stage bl Randomize_LeftorRightSide #Adjust Facing Direction Based on Preference lbz r3,FacingDirection(MenuData) cmpwi r3,0x1 bne ShieldDropLoadState #Invert P1 Facing Direction lwz r3,0x10(r31) lfs f1,0x2C(r3) fneg f1,f1 stfs f1,0x2C(r3) ShieldDropLoadState: #Backup P1 Analog Timers lwz r23,0x620(r27) lwz r24,0x624(r27) #Restore addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Restore P1 Analog Timers lwz r23,0x620(r27) lwz r24,0x624(r27) #Reset Timer li r3,50 branchl r12,HSD_Randi li r4,0 sub r3,r4,r3 stw r3,0x4(r31) #Reset Aerial Move Think Struct li r3,0 stw r3,AerialThinkStruct(r31) ShieldDropThinkExit: mr r3,MenuData bl ClearToggledOptions bl UpdateAllGFX restore blr ################################# ShieldDrop_Floats: blrl .long 0xC0F9999A #P1 X Position .long 0x40F9999A #P2 X Position .long 0x425999b4 #Top Plat Y Position .long 0x425999b4 #Top Plat Y Position .long 0x3E99999A #Y Vel to Attack .long 0x40A00000 #Distance from Ground to L Cancel ################################# ShieldDropWindowInfo: blrl .long 0x0001FFFF #1 Window, Facing Direction Has 2 Options ################################ ShieldDropWindowText: blrl ###################### ## Facing Direction ## ###################### #Window Title = Facing Direction .long 0x46616369 .long 0x6e672044 .long 0x69726563 .long 0x74696f6e .long 0x #Option 1 = Towards .long 0x546f7761 .long 0x72647300 .long 0x .long 0x .long 0x #Option 2 = Away .long 0x41776179 .long 0x .long 0x .long 0x .long 0x ################################# ShieldDropLoadExit: restore blr ################################################################################ #endregion #region Attack on Shield ######################### ## Attack On Shield HIJACK INFO ## ######################### AttackOnShield: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,FinalDestination #Use SSS Stage load r7,EventOSD_AttackOnShield li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION bl AttackOnShieldLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Attack On Shield LOAD FUNCT ## ######################## AttackOnShieldLoad: blrl backup #Schedule Think bl AttackOnShieldThink mflr r3 li r4,3 #Priority (After Interrupt) bl AttackOnShieldWindowInfo mflr r5 bl AttackOnShieldWindowText mflr r6 bl CreateEventThinkFunction b AttackOnShieldLoadExit ######################### ## Attack On Shield THINK FUNCT ## ######################### #Registers .set MenuData,26 .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 .set firstFrameFlag,0x0 .set timer,0x4 .set OoSOption,MenuData_OptionMenuMemory+0x2 + 0x0 .set OoSOptionToggled,MenuData_OptionMenuToggled + 0x0 AttackOnShieldThink: blrl backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 lwz MenuData,EventData_MenuDataPointer(EventData) bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq AttackOnShieldThinkMain #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) bl AttackOnShield_Floats mflr r3 bl InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save AttackOnShieldThinkMain: bl GiveFullShields #Reset If Anyone Dies bl IsAnyoneDead cmpwi r3,0x0 bne AttackOnShieldRestoreState AttackOnShieldThinkSequence: lbz r3,OoSOptionToggled(MenuData) cmpwi r3,0 beq AttackOnShieldNoOptionToggled #Clear Last AS So CPU Doesnt Act Immediately li r3,0 sth r3,TM_OneASAgo(r29) AttackOnShieldNoOptionToggled: #Get Floats bl AttackOnShield_Floats mflr r21 #Get Frames as Int lfs f1,0x894(r29) fctiwz f1,f1 stfd f1,0xF0(sp) lwz r22,0xF4(sp) #Check If Perfroming OoS Option lwz r3,0x4(r31) cmpwi r3,0x0 ble AttackOnShieldShieldWait #Branch To OoSThink lbz r3,OoSOption(MenuData) cmpwi r3,0x1 beq AttackOnShieldNairThink cmpwi r3,0x2 beq AttackOnShieldUpBThink cmpwi r3,0x3 beq AttackOnShieldUpSmashThink cmpwi r3,0x4 beq AttackOnShieldShineThink cmpwi r3,0x7 beq AttackOnShieldWavedashThink b AttackOnShieldShieldWait AttackOnShieldNairThink: lwz r3,0x10(r29) cmpwi r3,0x19 bne AttackOnShieldCheckToReset #Input Nair li r3,0x100 stw r3,0x1A88(r29) b AttackOnShieldCheckToReset AttackOnShieldUpBThink: lwz r3,0x10(r29) cmpwi r3,0x18 bne AttackOnShieldCheckToReset li r3,127 stb r3,0x1A8D(r29) #Press Up li r3,0x200 stw r3,0x1A88(r29) #Press B b AttackOnShieldCheckToReset AttackOnShieldUpSmashThink: lwz r3,0x10(r29) cmpwi r3,0x18 bne AttackOnShieldCheckToReset li r3,127 stb r3,0x1A8D(r29) #Press Up li r3,0x100 stw r3,0x1A88(r29) #Press A b AttackOnShieldCheckToReset AttackOnShieldShineThink: lwz r3,0x10(r29) cmpwi r3,0x19 bne AttackOnShieldCheckToReset #Input Shine li r3,-127 stb r3,0x1A8D(r29) li r3,0x200 stw r3,0x1A88(r29) b AttackOnShieldCheckToReset AttackOnShieldWavedashThink: lwz r3,0x10(r29) cmpwi r3,0x19 bne AttackOnShieldCheckToReset #Get Random Airdodge Angle li r3,30 #30 Different Angles branchl r12,HSD_Randi addi r3,r3,310 #Start at 310° bl ComboTrainingDecideStickAngle_ConvertAngle mr r20,r3 #Joystick X = X Component * (OpponentDirection) bl GetDirectionInRelationToP1 mullw r3,r3,r20 stb r3,0x1A8C(r29) #Joystick Y = Y Component stb r4,0x1A8D(r29) #Press L To Wavedash li r3,0xC0 stw r3,0x1A88(r29) b AttackOnShieldCheckToReset AttackOnShieldShieldWait: #Always Hold L li r3,0xC0 #Hit L stw r3,0x1A88(r29) #Held Buttons #Check If Got Shield Poked #Hitlag lbz r3,0x221A(r29) #Check If in Hitlag rlwinm. r3,r3,0,26,26 beq AttackOnShieldCheckForShieldHit #Damage State lwz r3,0x10(r29) cmpwi r3,0x4B blt AttackOnShieldCheckForShieldHit cmpwi r3,0x5B bgt AttackOnShieldCheckForShieldHit #Was Hit, Start Reset Timer li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldCheckForShieldHit: #Check If In ShieldWait (0xb3) lwz r3,0x10(r29) cmpwi r3,0xB3 bne AttackOnShieldCheckToReset #Check If Was Just in ShieldStun lhz r3,TM_OneASAgo(r29) cmpwi r3,0xB5 bne AttackOnShieldCheckToReset #Input OoS Option lbz r3,OoSOption(MenuData) cmpwi r3,0x0 beq AttackOnShieldInputGrab cmpwi r3,0x1 beq AttackOnShieldNair cmpwi r3,0x2 beq AttackOnShieldUpB cmpwi r3,0x3 beq AttackOnShieldUpSmash cmpwi r3,0x4 beq AttackOnShieldShine cmpwi r3,0x5 beq AttackOnShieldSpotdodge cmpwi r3,0x6 beq AttackOnShieldRoll cmpwi r3,0x7 beq AttackOnShieldWavedash cmpwi r3,0x8 beq AttackOnShieldNone AttackOnShieldInputGrab: li r3,0x1C0 stw r3,0x1A88(r29) #Press R+A li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldNair: li r3,0xCC0 stw r3,0x1A88(r29) #Press X/Y li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldUpB: li r3,127 stb r3,0x1A8D(r29) #Press Up li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldUpSmash: li r3,127 stb r3,0x1A8D(r29) #Press Up li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldShine: li r3,0xCC0 stw r3,0x1A88(r29) #Press X/Y li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldSpotdodge: li r3,-127 stb r3,0x1A8D(r29) #Press Down li r3,0xC0 stw r3,0x1A88(r29) #Press R li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldRoll: li r3,0xC0 stw r3,0x1A88(r29) #Press R #Push Towards Opponent's Direction bl GetDirectionInRelationToP1 li r4,127 mullw r3,r3,r4 stb r3,0x1A8C(r29) #Press Away li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldWavedash: li r3,0xCC0 stw r3,0x1A88(r29) #Press X/Y li r3,48 #Init Timer stw r3,0x4(r31) b AttackOnShieldThinkExit AttackOnShieldNone: b AttackOnShieldThinkExit #Check To Reset AttackOnShieldCheckToReset: lwz r3,0x4(r31) #get timer #Get Timer cmpwi r3,0x0 #Check if >0 ble AttackOnShieldThinkExit #Dec Timer subi r3,r3,0x1 stw r3,0x4(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne AttackOnShieldThinkExit #Exit If Not #Randomize P1's X Coord #Get Random X Coord lbz r23,0x10(r21) #Starting X Coord lbz r24,0x11(r21) #Furthest X Coord sub r3,r24,r23 #Get Range branchl r12,HSD_Randi #Get Random Number in Between add r3,r3,r23 #Add to Starting Coord #Cast to Float bl IntToFloat lwz r3,0x10(r31) #P1 Backup stfs f1,0xB0(r3) #P1 Backup X Pos li r3,0x1 #Opposing Sides of Stage bl Randomize_LeftorRightSide AttackOnShieldRestoreState: #Restore State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load b AttackOnShieldThinkExit AttackOnShieldThinkExit: mr r3,MenuData bl ClearToggledOptions restore blr ################################# AttackOnShield_Floats: blrl .long 0xC1A00000 #P1 X Position .long 0x41A00000 #P2 X Position .long 0x38d1b717 #FD Floor Y Coord .long 0x38d1b717 #FD Floor Y Coord .long 0x14460000 #P1 X Rand Pos Range ################################# AttackOnShieldWindowInfo: blrl #amount of options, amount of options in each window .long 0x0008FFFF #1 window, OoS Option has 10 options #################################################### AttackOnShieldWindowText: blrl ################ ## OoS Option ## ################ #Window Title = OoS Option .long 0x4f6f5320 .long 0x4f707469 .long 0x6f6e0000 #Option 1 = Grab .long 0x47726162 .long 0x00000000 #Option 2 = Nair .long 0x4e616972 .long 0x00000000 #Option 3 = Up B .long 0x55702042 .long 0x00000000 #Option 5 = Up Smash .long 0x55702d53 .long 0x6d617368 .long 0x #Option 6 = Shine .long 0x5368696e .long 0x65000000 #Option 7 = Spotdodge .long 0x53706f74 .long 0x646f6467 .long 0x65000000 #Option 8 = Roll Away .long 0x526f6c6c .long 0x20417761 .long 0x79000000 #Option 9 = Wavedash Away .long 0x57617665 .long 0x64617368 .long 0x20417761 .long 0x79000000 #Option 10 = None .long 0x4E6F6E65 .long 0x00000000 AttackOnShieldLoadExit: restore blr ################################################################################ #endregion #region Ledgetech Training ######################### ## Ledgetech HIJACK INFO ## ######################### Ledgetech: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Falco.Ext #Use chosen CPU li r6,-1 #Use chosen Stage load r7,EventOSD_LedgeTech li r8,1 #Use Sopo bool bl InitializeMatch #BUFF DEFENSE RATIO lis r3,0x3f00 stw r3,0x14(r20) #STORE THINK FUNCTION LedgetechStoreThink: bl LedgetechLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Ledgetech LOAD FUNCT ## ######################## LedgetechLoad: blrl backup bl InitializeHighScore #Schedule Think bl LedgetechThink mflr r3 li r4,3 #Priority (After Interrupt) li r5,0 #No Option Menu bl CreateEventThinkFunction b LedgetechLoadExit ######################### ## Ledgetech THINK FUNCT ## ######################### LedgetechThink: blrl .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 .set EventData,31 backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq LedgetechThinkMain #Clear Inputs bl RemoveFirstFrameInputs #Random Side of Stage li r3,2 branchl r12,HSD_Randi bl Ledgetech_InitializePositions #Enter SquatWait mr r3,P2GObj branchl r12,AS_SquatWait #P1 Has 90% li r3,90 load r4,0x80453080 #P1 Static Block sth r3,0x60(r4) #Store Percent Int To Display Value lis r3,0x42B4 stw r3,0x1830(r27) #Always Hold Down (Crouch Cancel) li r3,-127 stb r3,0x1A8D(P2Data) #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe bl SaveState_Save LedgetechThinkMain: bl GiveFullShields LedgetechThinkSequence: #Get Floats bl Ledgetech_Floats mflr r21 #Reset if P1 Is In a Dead State lbz r3,0x221F(r27) rlwinm. r3,r3,0,25,25 bne LedgetechRestoreState #D-Pad Left Restores State lwz r3,0x668(r27) rlwinm. r0, r3, 0, 31, 31 bne LedgetechRestoreState #Always Hold Down (Crouch Cancel) li r3,-127 stb r3,0x1A8D(r29) #Start Timer When Leaving Rebirth Plat lbz r3,0x8(r31) #Check If Left Plat Already cmpwi r3,0x0 bne LedgetechSkipTimerStart lwz r3,0x10(r27) cmpwi r3,0xD beq LedgetechIncreaseRespawnPlatTime #Set Flag li r3,0x1 stb r3,0x8(r31) #Remove Invinc li r3,0x0 stw r3,0x198C(r27) stw r3,0x1990(r27) stw r3,0x1994(r27) mr r3,r28 branchl r12,GFX_RemoveAll #Set Timer li r3,180 stw r3,0x4(r31) b LedgetechSkipTimerStart LedgetechIncreaseRespawnPlatTime: li r3,0x2 stw r3,0x2340(r27) LedgetechSkipTimerStart: #Freeze Falco On Frame X lwz r3,0x10(r29) cmpwi r3,0x40 bne LedgetechSkipFalcoFreze li r3,0x6 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f1,f2 bne LedgetechSkipFalcoFreze li r3,0 bl IntToFloat mr r3,r30 branchl r12,FrameSpeedChange LedgetechSkipFalcoFreze: #If Player 1 Ledge Tech's, Set Timer to 2 Seconds #Check Gatekeeper Flag lbz r3,0xA(r31) cmpwi r3,0x1 beq Ledgetech_UpdateLedgetechFlags #Check For Tech lwz r3,0x10(r27) cmpwi r3,0xCA beq LedgetechWallTeched cmpwi r3,0xCB beq LedgetechWallTeched b Ledgetech_UpdateLedgetechFlags LedgetechWallTeched: #Extend Timer li r3,180 stw r3,0x4(r31) #Set Tech Bool li r3,1 stb r3,0x9(r31) #Set Gatekeeper Flag li r3,1 stb r3,0xA(r31) Ledgetech_UpdateLedgetechFlags: #Check If Still Ledgeteching lwz r3,0x10(r27) cmpwi r3,0xCA beq LedgetechUpdateScore cmpwi r3,0xCB beq LedgetechUpdateScore #Not Ledgeteching, Remove Gatekeeper Flag li r3,0 stb r3,0xA(r31) b LedgetechUpdateScoreHUD LedgetechUpdateScore: #Check To Increment Score #Check Ledgetech Bool lbz r3,0x9(r31) cmpwi r3,0x1 bne LedgetechUpdateScoreHUD #Reset LedgeTech Bool li r3,0 stb r3,0x9(r31) #Increment Score lhz r3,-0x4ea8(r13) addi r3,r3,0x1 sth r3,-0x4ea8(r13) #Check To Make New High Score lhz r3,-0x4ea8(r13) lhz r4,-0x4ea6(r13) cmpw r3,r4 ble LedgetechUpdateScoreHUD #Copy To High Score sth r3,-0x4ea6(r13) LedgetechUpdateScoreHUD: #Update HUD Score lhz r3,-0x4ea8(r13) branchl r12,HUD_KOCounter_UpdateKOs #Unfreeze Falco On Hit li r3,0x0 bl IntToFloat lfs f2,0x89C(r29) fcmpo cr0,f1,f2 bne LedgetechSkipFalcoUnfreeze lwz r3,0x988(r29) cmpwi r3,0x0 beq LedgetechSkipFalcoUnfreeze li r3,1 bl IntToFloat mr r3,r30 branchl r12,FrameSpeedChange LedgetechSkipFalcoUnfreeze: LedgetechCheckIfCrouching: #Only Attempt to DSmash in Squat and SquatWait lwz r3,0x10(r29) cmpwi r3,0x27 beq LedgetechCheckDistance cmpwi r3,0x28 beq LedgetechCheckDistance b LedgetechCheckToReset LedgetechCheckDistance: #Distance Formula (Get Distance in f1) addi r3,r29,0xB0 #P2 Positon addi r4,r27,0xB0 #P1 Position bl GetDistance lfs f2,0x0(r21) fcmpo cr0,f1,f2 bgt LedgetechCheckToReset #Enter DSmash li r3,-127 stb r3,0x1A8F(r29) #Initiate Reset Timer lwz r3,0x4(r31) #Get Timer cmpwi r3,0x0 #If Already Set, Skip bne LedgetechCheckToReset li r3,60 stw r3,0x4(r31) #Check To Reset LedgetechCheckToReset: lwz r3,0x4(r31) #get timer #Get Timer cmpwi r3,0x0 #Check if >0 ble LedgetechThinkExit #Dec Timer subi r3,r3,0x1 stw r3,0x4(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne LedgetechThinkExit #Exit If Not LedgetechRestoreState: #Restore State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Random Side of Stage li r3,2 branchl r12,HSD_Randi bl Ledgetech_InitializePositions #Enter SquatWait mr r3,P2GObj branchl r12,AS_SquatWait #Set Timer li r3,0 stw r3,0x4(r31) #Reset Rebirth Plat Fall Flag stb r3,0x8(r31) #Reset Tech and Gatekeeper Flag stb r3,0x9(r31) stb r3,0xA(r31) #Reset Score li r3,0 sth r3,-0x4ea8(r13) b LedgetechThinkExit LedgetechThinkExit: restore blr ################################# Ledgetech_Floats: blrl .float 35.0 #Distance to Initiate DSmash ################################# BlrFunctionPointer: blrl blr ################################# Ledgetech_InitializePositions: backup .set LedgeSide,20 #Backup Ledge Side mr LedgeSide,r3 #Change Facing Directions cmpwi LedgeSide,0x0 beq Ledgetech_InitializePositions_GetLeftLedgeID Ledgetech_InitializePositions_GetRightLedgeID: #Change Facing Direction li r3,-1 bl IntToFloat stfs f1,0x2C(P1Data) li r3,1 bl IntToFloat stfs f1,0x2C(P2Data) b Ledgetech_InitializePositions_DirectionChangeEnd Ledgetech_InitializePositions_GetLeftLedgeID: #Change Facing Direction li r3,1 bl IntToFloat stfs f1,0x2C(P1Data) li r3,-1 bl IntToFloat stfs f1,0x2C(P2Data) Ledgetech_InitializePositions_DirectionChangeEnd: #Get Ledge Coordinates mr r3,LedgeSide addi r4,sp,0x80 bl GetLedgeCoordinates Ledgetech_InitializePositions_StorePosition: #Place P2 a few Mm behind it li r3,10 bl IntToFloat lfs f2,0x2C(P2Data) fmuls f1,f1,f2 lfs f2,0x80(sp) fsubs f1,f2,f1 stfs f1,0xB0(P2Data) lfs f1,0x84(sp) stfs f1,0xB4(P2Data) #Find Ground Below Player mr r3,P2GObj bl FindGroundNearPlayer cmpwi r3,0 #Check if ground was found beq Ledgetech_InitializePositions_SkipGroundCorrection stfs f1,0xB0(P2Data) stfs f2,0xB4(P2Data) stw r4,0x83C(P2Data) Ledgetech_InitializePositions_SkipGroundCorrection: #Enter into Wait mr r3,P2GObj branchl r12,AS_Wait #Update Position mr r3,P2GObj bl UpdatePosition #Update ECB Values for the ground ID mr r3,P2GObj branchl r12,EnvironmentCollision_WaitLanding #Set Grounded mr r3,P2Data branchl r12,Air_SetAsGrounded #Update Camera mr r3,P2GObj bl UpdateCameraBox #Enter Rebirth lwz r26,0x2C(P1Data) mr r3,P1GObj branchl r12,AS_Rebirth stw r26,0x2C(P1Data) #Place P1 a few Mm in front of it li r3,60 bl IntToFloat lfs f2,0x2C(P1Data) fmuls f1,f1,f2 lfs f2,0x80(sp) fsubs f1,f2,f1 stfs f1,0xB0(P1Data) lfs f1,0x84(sp) stfs f1,0xB4(P1Data) #Enter RebirthWait mr r3,P1GObj branchl r12,AS_RebirthWait #Update Position mr r3,P1GObj bl UpdatePosition #Store Blr as Physics bl BlrFunctionPointer mflr r3 stw r3,0x21A4(P1Data) #Store Custom RebirthWait Interrupt bl Custom_InterruptRebirthWait mflr r3 stw r3,0x219C(P1Data) #Update RebirthPlat Position mr r3,P1GObj branchl r12,RebirthPlatform_UpdatePosition #Update Camera mr r3,P1GObj bl UpdateCameraBox restore blr ################################# LedgetechLoadExit: restore blr ################################################### #endregion #region Amsah Tech ######################### ## Amsah Tech HIJACK INFO ## ######################### AmsahTech: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,9 #Use chosen CPU li r6,-1 #Use chosen Stage load r7,EventOSD_AmsahTech li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION bl AmsahTechLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Amsah Tech LOAD FUNCT ## ######################## AmsahTechLoad: blrl backup #Schedule Think bl AmsahTechThink mflr r3 li r4,3 #Priority (After Interrupt) li r5,0 #No Option Menu bl CreateEventThinkFunction b AmsahTechLoadExit ######################### ## Amsah Tech THINK FUNCT ## ######################### .set EventData,31 .set P1Gobj,28 .set P1Data,27 .set P2GObj,30 .set P2Data,29 #Offsets .set Timer,0x8 AmsahTechThink: blrl backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq AmsahTechThinkMain #Move Players bl PlacePlayersCenterStage #P1 Has 120% li r3,120 load r4,0x80453080 #P1 Static Block sth r3,0x60(r4) #Store Percent Int To Display Value bl IntToFloat stfs f1,0x1830(P1Data) #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save AmsahTechThinkMain: #Make P2 A Follower (No Nudge) #li r3,0x8 #stb r3,0x221F(r29) li r3,0x1 lbz r0, 0x221D (r29) rlwimi r0,r3,2,29,29 stb r0, 0x221D (r29) #Give Invincibility To P2 mr r3,r30 li r4,0x2 bl GiveInvincibility #Update GFX mr r3,r30 bl UpdateAllGFX #Reset If Anyone Dies bl IsAnyoneDead cmpwi r3,0x0 bne AmsahTechRestoreState AmsahTechThinkSequence: #Get Floats bl AmsahTech_Floats mflr r21 #Check If Timer Started Already lwz r3,0x4(r31) cmpwi r3,0x0 bne AmsahTechCheckUpBTimer #Check For P1 Taunt lwz r3,0x10(r27) cmpwi r3,0x108 beq AmsahTechIsTaunting cmpwi r3,0x109 beq AmsahTechIsTaunting #Check For Doc Taunt lwz r3,0x4(r27) cmpwi r3,0x15 bne AmsahTechCheckYLink #Check For AS 155 lwz r3,0x10(r27) cmpwi r3,0x155 beq AmsahTechIsTaunting #Check For YLink Taunt AmsahTechCheckYLink: lwz r3,0x4(r27) cmpwi r3,0x14 bne AmsahTechCheckUpBTimer #Check For AS 156 lwz r3,0x10(r27) cmpwi r3,0x156 beq AmsahTechIsTaunting b AmsahTechCheckUpBTimer AmsahTechIsTaunting: #Check for Frame 1 of Taunt lhz r3,TM_FramesinCurrentAS(P1Data) cmpwi r3,0x1 bne AmsahTechCheckUpBTimer #Check If UpB Timer is Set lwz r3,0x8(r31) cmpwi r3,0x0 #Timer Already Set bne AmsahTechCheckUpBTimer #Check If Marth is In Wait lwz r3,0x10(r29) cmpwi r3,0xE bne AmsahTechCheckUpBTimer #Move Marth X Mm in front of P1, facing him #Get Position li r3,10 bl IntToFloat #Offset from P1 lfs f3,0xB0(P1Data) #P1 X lfs f2,0xB4(P1Data) #P1 Y lfs f4,0x2C(P1Data) #Facing Direction fmuls f1,f1,f4 fadds f1,f1,f3 #Check If P2 Will Be Grounded li r3,0 bl FindGroundNearPlayer cmpwi r3,0 #Check if ground was found beq AmsahTech_NoGroundFound stfs f1,0xB0(P2Data) stfs f2,0xB4(P2Data) stw r4,0x83C(P2Data) lfs f1,0x2C(P1Data) fneg f1,f1 stfs f1,0x2C(P2Data) #Enter Wait mr r3,P2GObj branchl r12,AS_Wait #Update Position mr r3,P2GObj bl UpdatePosition #Update ECB Values for the ground ID mr r3,P2GObj branchl r12,EnvironmentCollision_WaitLanding #Set Grounded mr r3,P2Data branchl r12,Air_SetAsGrounded #Set UpB Timer li r3,30 stw r3,Timer(EventData) #Store To Backups as Well lwz r3,0x18(EventData) #P2 Backup lfs f1,0xB0(P2Data) #Get P2 X stfs f1,0xB0(r3) #Store to P2 Backup lfs f1,0xB4(P2Data) #Get P2 Y stfs f1,0xB4(r3) #Store to P2 Backup lfs f1,0x2C(P2Data) #Get P2 Facing stfs f1,0x2C(r3) #Store to P2 Backup lwz r4,0x83C(P2Data) #Get P2 Ground ID stw r4,0x83C(r3) #Store to P2 Backup lwz r3,0x10(EventData) #P1 Backup lfs f1,0xB0(P1Data) #Get P1 X stfs f1,0xB0(r3) #Store to P1 Backup lfs f1,0xB4(P1Data) #Get P1 X stfs f1,0xB4(r3) #Store to P1 Backup lfs f1,0x2C(P1Data) #Get P1 Facing stfs f1,0x2C(r3) #Store to P1 Backup lwz r4,0x83C(P1Data) #Get P1 Ground ID stw r4,0x83C(r3) #Store to P1 Backup mr r3,P1GObj bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq AmsahTechNoSubchar lwz r3,0x14(EventData) #P1 Subchar Backup lfs f1,0xB0(r4) #Get P1 Subchar X stfs f1,0xB0(r3) #Store to P1 Subchar Backup lfs f1,0x2C(r4) #Get P1 Subchar Facing stfs f1,0x2C(r3) #Store to P1 Subchar Backup AmsahTechNoSubchar: b AmsahTechCheckToReset AmsahTech_NoGroundFound: #Play Error SFX li r3,0xAF bl PlaySFX b AmsahTechCheckToReset AmsahTechCheckUpBTimer: #Check For UpBTimer lwz r3,0x8(r31) cmpwi r3,0x0 #No UpB Timer Set Yet ble AmsahTechCheckToReset #Dec Timer subi r3,r3,0x1 stw r3,0x8(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne AmsahTechCheckToReset #Exit If Not #Move Marth in Front of P1 Again (Fox's lfs f1,0xB0(r27) #Get P1 X lfs f2,0x2C(r27) #Get P1 Facing lfs f3,0x10(r21) #Get Marth Distance fmuls f2,f2,f3 #Distance * Facing Direction fadds f1,f1,f2 #P1.X + (Distance * Facing Direction) stfs f1,0xB0(r29) #Store Position to P2 #Enter UpB li r3,0x200 stw r3,0x1A88(r29) li r3,127 stb r3,0x1A8D(r29) #Initiate Reset Timer li r3,120 stw r3,0x4(r31) #Check To Reset AmsahTechCheckToReset: lwz r3,0x4(r31) #get timer #Get Timer cmpwi r3,0x0 #No Reset Timer Set Yet ble AmsahTechThinkExit #Dec Timer subi r3,r3,0x1 stw r3,0x4(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne AmsahTechThinkExit #Exit If Not AmsahTechRestoreState: #Restore State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Restore Timers Just In Case li r3,0x0 stw r3,0x4(r31) stw r3,0x8(r31) AmsahTechThinkExit: restore blr ################################# AmsahTech_Floats: blrl .long 0x4308ca0c #P1 X Position .long 0x42942371 #P2 X Position .long 0x00000000 #P1 Y Position .long 0x38d1b717 #FD Floor Y Coord .long 0x41800000 #Distance to place Marth from P1 .long 0x428C0000 #FD Stage Boundary X ################################# AmsahTechLoadExit: restore blr ########################################### #endregion #region Combo Training ################################ ## Combo Training HIJACK INFO ## ################################ ComboTraining: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,-1 #Use chosen CPU li r6,-1 #Use chosen Stage load r7,EventOSD_ComboTraining li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION bl ComboTrainingLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Combo Training LOAD FUNCT ## ######################## ComboTrainingLoad: blrl backup #Schedule Think bl ComboTrainingThink mflr r3 li r4,3 #Priority (After Interrupt) bl ComboTrainingWindowInfo #r4 = pointer to option info mflr r5 bl ComboTrainingWindowText #r5 = pointer to ASCII struct mflr r6 bl CreateEventThinkFunction bl InitializeHighScore b ComboTrainingLoadExit ######################### ## Combo Training THINK FUNCT ## ######################### #Registers .set MenuData,26 .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 #Offsets .set EventState,0x8 .set DIBehavior,(MenuData_OptionMenuMemory+0x2)+0x0 .set SDIBehavior,(MenuData_OptionMenuMemory+0x2)+0x1 .set TechOption,(MenuData_OptionMenuMemory+0x2)+0x2 .set PostHitstunAction,(MenuData_OptionMenuMemory+0x2)+0x3 .set GrabMashout,(MenuData_OptionMenuMemory+0x2)+0x4 .set DIBehaviorToggled,(MenuData_OptionMenuToggled)+0x0 .set SDIBehaviorToggled,(MenuData_OptionMenuToggled)+0x1 .set TechOptionToggled,(MenuData_OptionMenuToggled)+0x2 .set PostHitstunActionToggled,(MenuData_OptionMenuToggled)+0x3 .set GrabMashoutToggled,(MenuData_OptionMenuToggled)+0x4 #Definitions #DIBehavior .set DI_Random,0x0 .set DI_Survival,0x1 .set DI_ComboDI,0x2 .set DI_SlightDIRandom,0x3 .set DI_SlightDIInwards,0x4 .set DI_DownAndAway,0x5 .set DI_None,0x6 #SDIBehavior .set SDI_33Percent,0x0 .set SDI_66Percent,0x1 .set SDI_Always,0x2 .set SDI_None,0x3 ComboTrainingThink: blrl backup #INIT FUNCTION VARIABLES lwz r31,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 lwz MenuData,EventData_MenuDataPointer(EventData) bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq ComboTrainingThinkMain bl PlacePlayersCenterStage #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Init Score Count lhz r3,-0x4ea8(r13) branchl r12,HUD_KOCounter_UpdateKOs ComboTrainingThinkMain: #Set Combo As Score li r3,0x0 branchl r12,0x8004134c sth r3,-0x4ea8(r13) #Check To Make New High Score lhz r3,-0x4ea8(r13) lhz r4,-0x4ea6(r13) cmpw r3,r4 ble ComboTraining_SkipNewHighscore #Copy To High Score sth r3,-0x4ea6(r13) ComboTraining_SkipNewHighscore: #Update HUD Score lhz r3,-0x4ea8(r13) cmpwi r3,0x1 blt ComboTraining_SkipHUDUpdate branchl r12,HUD_KOCounter_UpdateKOs ComboTraining_SkipHUDUpdate: #DPad Right Makes New Savestate #Check If Trying to SaveState lwz r3,0x668(r27) rlwinm. r0,r3,0,30,30 beq ComboTraining_CheckForSaveAndLoad #Only Allow a Save If Event State is 0 lbz r3,EventState(r31) cmpwi r3,0x0 bne ComboTraining_SkipCheckForSaveAndLoad #Only Allow a Save If P2 is in Wait lwz r3,0x10(r29) cmpwi r3,0xE bne ComboTraining_SkipCheckForSaveAndLoad ComboTraining_CheckForSaveAndLoad: addi r3,EventData,0x10 bl CheckForSaveAndLoad #Check If Loaded Successfully cmpwi r3,0x1 bne ComboTraining_SkipCheckForSaveAndLoad #Restore Event State And Timer li r3,0x0 stb r3,EventState(r31) stw r3,0x4(r31) ComboTraining_SkipCheckForSaveAndLoad: #DPad Down Moves CPU In Front #Only If Event State = 0 lbz r3,EventState(r31) cmpwi r3,0x0 bne ComboTrainingSkipMoveCPU mr r3,P1GObj mr r4,P2GObj addi r5,EventData,0x10 bl MoveCPU ComboTrainingSkipMoveCPU: #L+DPad Controls CPU Percent addi r3,EventData,EventData_SaveStateStruct+(1*0x8) bl DPadCPUPercent bl GiveFullShields #Reset If Anyone Dies bl IsAnyoneDead cmpwi r3,0x0 bne ComboTrainingRestoreState ############################ ## Check If Was Hit Again ## ############################ #Don't Run If Over 6 Frames in Escape Air lwz r3,0x10(r29) cmpwi r3,0xEC bne ComboTrainingCheckIfP2isGrabbed li r3,6 bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f1,f2 bge ComboTrainingCheckState #Check If P2 is Grabbed (Any Grab State) ComboTrainingCheckIfP2isGrabbed: lwz r3,0x10(r29) cmpwi r3,0xDF blt ComboTrainingStartCheckIfHit cmpwi r3,0xE8 bgt ComboTrainingStartCheckIfHit b ComboTrainingChangeToRandomDIandTech #Check If P2 is Hit ComboTrainingStartCheckIfHit: lbz r3,0x221A(r29) #Check If in Hitlag rlwinm. r3,r3,0,26,26 bne ComboTrainingCheckIfBeingHit b ComboTrainingCheckState ComboTrainingCheckIfBeingHit: lwz r3,0x10(r29) cmpwi r3,ASID_DamageHi1 blt ComboTrainingCheckState cmpwi r3,ASID_DamageFlyRoll bgt ComboTrainingCheckState ComboTrainingChangeToRandomDIandTech: #Change To DI and Tech li r3,0x1 stb r3,EventState(r31) b ComboTrainingInputDIAndTech #Get Which State ComboTrainingCheckState: lbz r3,EventState(r31) cmpwi r3,0x0 beq ComboTrainingStart cmpwi r3,0x1 beq ComboTrainingInputDIAndTech cmpwi r3,0x2 beq ComboTrainingPostHitstun ComboTrainingStart: b ComboTrainingCheckToReset ComboTrainingInputDIAndTech: bl ComboTrainingCheckExitStates cmpwi r3,0x0 beq ComboTrainingInputDIAndTechNoJiggs b ComboTrainingChangeStateToPostHitstun ComboTrainingInputDIAndTechNoJiggs: lwz r3,0x10(r29) cmpwi r3,0xB8 #Missed Tech, Needs to Input a Roll or Attack beq ComboTrainingMissedTechThink cmpwi r3,0xC0 #Missed Tech, Needs to Input a Roll or Attack beq ComboTrainingMissedTechThink #Check If Still Grabbed cmpwi r3,ASID_ShoulderedWait blt ComboTraining_GrabCheckSkipShoulder cmpwi r3,ASID_ShoulderedTurn ble ComboTrainingMashOutOfGrab ComboTraining_GrabCheckSkipShoulder: cmpwi r3,ASID_CaptureKoopa blt ComboTraining_GrabCheckSkipKoopaLw cmpwi r3,ASID_CaptureWaitKoopa ble ComboTrainingMashOutOfGrab ComboTraining_GrabCheckSkipKoopaLw: cmpwi r3,ASID_CaptureKoopaAir blt ComboTraining_GrabCheckSkipKoopaAir cmpwi r3,ASID_CaptureWaitKoopaAir ble ComboTrainingMashOutOfGrab ComboTraining_GrabCheckSkipKoopaAir: cmpwi r3,ASID_CapturePulledHi #CapturePulledLow blt ComboTraining_GrabCheckSkipGrabbed cmpwi r3,ASID_CaptureFoot #CapturePulledHi ble ComboTrainingMashOutOfGrab ComboTraining_GrabCheckSkipGrabbed: b ComboTrainingDecideInputs #When Grabbed #Check Mash Out Behavior ComboTrainingMashOutOfGrab: lbz r3,GrabMashout(MenuData) cmpwi r3,0x0 beq ComboTrainingInputDIAndTech_RandomMash cmpwi r3,0x1 beq ComboTrainingInputDIAndTech_RandomMash_AnalogInput cmpwi r3,0x2 #No Mash beq ComboTrainingCheckToReset #Random Mash Out ComboTrainingInputDIAndTech_RandomMash: #Only start randomly mashing after a few frames (to simulate human reaction) lwz r3,0x10(r29) cmpwi r3,ASID_CapturePulledHi #CapturePulledLow blt ComboTrainingInputDIAndTech_RandomMashStart cmpwi r3,ASID_CaptureFoot #CapturePulledHi bgt ComboTrainingInputDIAndTech_RandomMashStart #In a normal grab state, should wait a few frames before starting to mash ComboTrainingInputDIAndTech_RandomMashStart: li r3,10 #1- Numbers branchl r12,HSD_Randi cmpwi r3,7 #7 and below are no input ble ComboTrainingCheckToReset cmpwi r3,8 #8 = Button Only, 9 = Both Analog and Button beq ComboTrainingInputDIAndTech_RandomMash_ButtonPress ComboTrainingInputDIAndTech_RandomMash_AnalogInput: li r3,127 stb r3,0x1A8C(r29) #Push Analog Stick Forward li r3,-1 stb r3,0x1A50(r29) #Spoof Analog Stick as First Frame Pushed ComboTrainingInputDIAndTech_RandomMash_ButtonPress: #Input Button Press li r3,0x100 stw r3,0x1A88(r29) #Press A li r3,0 stw r3,0x65C(r29) #Spoof Prev Frame Buttons as Nothing Pushed b ComboTrainingCheckToReset ComboTrainingChangeStateToPostHitstun: #Change State li r3,0x2 stb r3,EventState(r31) b ComboTrainingPostHitstun ComboTrainingDecideInputs: #CHECK TO DI ATTACK ComboTrainingDIThrowsAndHits: #Check If in Hitlag lbz r3,0x221A(r29) rlwinm. r3,r3,0,26,26 beq ComboTrainingCheckIfBeingThrown #Check If In Last Frame of Hitlag lfs f1,-0x7418(rtoc) #1fp lfs f2,0x195C(r29) #hitlag frames left fcmpo cr0,f1,f2 bne ComboTrainingCheckToReset #Check If Attack Was Strong #DI Attack lbz r3,DIBehavior(MenuData) #Get DI Behavior cmpwi r3,DI_SlightDIInwards #Check If Slight In bne 0x8 li r3,0x0 #Override To Never Slight DI In Attacks b 0x8 li r3,0x2 bl ComboTrainingDecideStickAngle #SDI Attack lbz r3,SDIBehavior(MenuData) #Get SDI Behavior cmpwi r3,SDI_None #No SDI beq ComboTrainingNoSDI cmpwi r3,SDI_Always #Always SDI beq ComboTrainingCheckToReset li r3,0x3 branchl r12,HSD_Randi lbz r4,SDIBehavior(MenuData) #Get SDI Behavior cmpwi r4,SDI_33Percent beq ComboTraining33PercentSDI cmpwi r4,SDI_66Percent beq ComboTraining66PercentSDI ComboTraining33PercentSDI: li r4,0 b ComboTrainingCompareSDIChance ComboTraining66PercentSDI: li r4,1 b ComboTrainingCompareSDIChance ComboTrainingCompareSDIChance: cmpw r3,r4 ble ComboTrainingGetChanceToTech #Don't SDI ComboTrainingNoSDI: mr r3,r29 branchl r12,CPU_JoystickXAxis_Convert stfs f1,0x620(r29) mr r3,r29 branchl r12,CPU_JoystickYAxis_Convert stfs f1,0x624(r29) b ComboTrainingGetChanceToTech #CHECK TO DI A THROW ComboTrainingCheckIfBeingThrown: #Check If Being Thrown lwz r3,0x10(r29) cmpwi r3,0xEF blt ComboTrainingCheckToJumpOutOfHitstun cmpwi r3,0xF3 bgt ComboTrainingCheckToJumpOutOfHitstun ComboTrainingInputDI: lbz r3,DIBehavior(MenuData) bl ComboTrainingDecideStickAngle b ComboTrainingCheckToReset #NOT BEING THROWN OR LAST FRAME OF HITLAG #CHECK TO JUMP OUT OF HITSTUN AND BECOME INVINCIBLE ComboTrainingCheckToJumpOutOfHitstun: #Check If in Damage State lwz r3,0x10(r29) cmpwi r3,0x26 #Tumble beq ComboTrainingCheckIfInAir cmpwi r3,0x4B blt ComboTrainingCheckToReset cmpwi r3,0x5B bgt ComboTrainingCheckToReset #IN A DAMAGE STATE #Check If In Air ComboTrainingCheckIfInAir: lwz r3,0xE0(r29) cmpwi r3,0x0 beq ComboTrainingDamageGrounded #IN THE AIR #Check If Still in Hitstun lbz r3,0x221C(r29) rlwinm. r3,r3,0,30,30 bne ComboTrainingGetChanceToTech #NOT IN HITSTUN #Check Post Hitstun Behavior lbz r3,PostHitstunAction(MenuData) cmpwi r3,0x0 beq ComboTrainingAirdodge cmpwi r3,0x1 beq ComboTrainingJumpAndInvincible cmpwi r3,0x2 beq ComboTrainingAerialAttack ComboTrainingJumpAndInvincible: #Always Jump #li r3,0 #stw r3,0x1A8C(r29) #Nuetralize Stick Inputs #i r3,0x400 #stw r3,0x1A88(r29) #X Button b ComboTrainingChangeStateToPostHitstun ComboTrainingAirdodge: #Wiggle Out of Hitstun li r3,127 stb r3,0x1A8C(r29) #Last Frame's Stick Was Centered li r3,0x0 stw r3,0x628(r29) stw r3,0x62C(r29) #Stick Frame Timer Reset li r3,255 stb r3,0x670(r29) #Change State li r3,0x2 stb r3,0x8(r31) b ComboTrainingPostHitstun ComboTrainingAerialAttack: #li r3,0x100 #stw r3,0x1A88(r29) #Nair #Change State li r3,0x2 stb r3,EventState(r31) b ComboTrainingPostHitstun #CHECK TO BECOME INVINCIBLE OUT OF GROUNDED LIGHT DAMAGE STATES ComboTrainingDamageGrounded: #Check For Hitstun (Can Act Out of Certain Light Damage States) lbz r3,0x221C(r29) rlwinm. r3,r3,0,30,30 bne ComboTrainingCheckToReset #Grounded, No Hitstun Left, Become Invincible and Spotdodge #Check Post Hitstun Behavior lbz r3,PostHitstunAction(MenuData) cmpwi r3,0x0 beq ComboTrainingGroundedSpotdodge cmpwi r3,0x1 beq ComboTrainingGroundedInvincibility cmpwi r3,0x2 beq ComboTrainingGroundedAttack ComboTrainingGroundedInvincibility: b ComboTrainingChangeStateToPostHitstun ComboTrainingGroundedSpotdodge: li r3,0xC0 #Hit L stw r3,0x1A88(r29) #Held Buttons li r3,-127 #Hold Down stb r3,0x1A8D(r29) #Stick Y b ComboTrainingChangeStateToPostHitstun ComboTrainingGroundedAttack: #li r3,0x100 #Hit A #stw r3,0x1A88(r29) #Held Buttons b ComboTrainingChangeStateToPostHitstun ComboTrainingGetChanceToTech: #INPUT A TECH WHEN IN AERIAL HITSTUN lbz r3,TechOption(MenuData) #Get Tech Behavior cmpwi r3,0x0 #Random Tech (Original Behavior) beq ComboTrainingRandomTech cmpwi r3,0x1 #Miss Tech beq ComboTrainingMissTech cmpwi r3,0x2 beq ComboTrainingTechInPlace cmpwi r3,0x3 beq ComboTrainingTechTowards cmpwi r3,0x4 beq ComboTrainingTechAway ComboTrainingRandomTech: #Reset Tech Cooldown Window Constantly li r3,0x1 stb r3,0x680(r29) #Frames Since Pressed L/R li r3,0xFF stb r3,0x684(r29) #L/R Lockout Window #Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise) lbz r3,0x221A(r29) rlwinm. r3,r3,0,26,26 bne ComboTrainingCheckToReset #Tech Random Side ComboTrainingRandomTech_GetStickAngle: li r3,4 #Decide between left right and center and none branchl r12,HSD_Randi cmpwi r3,0x0 beq ComboTrainingRandomTech_TechInPlace cmpwi r3,0x1 beq ComboTrainingRandomTech_TechLeft cmpwi r3,0x2 beq ComboTrainingRandomTech_TechRight cmpwi r3,0x3 beq ComboTrainingMissTech ComboTrainingRandomTech_TechInPlace: li r3,0 stb r3,0x1A8C(r29) stb r3,0x1A8D(r29) b ComboTrainingCheckToReset ComboTrainingRandomTech_TechLeft: li r3,-127 stb r3,0x1A8C(r29) b ComboTrainingCheckToReset ComboTrainingRandomTech_TechRight: li r3,127 stb r3,0x1A8C(r29) b ComboTrainingCheckToReset ComboTrainingMissTech: li r3,0x0 stw r3,0x1A88(r29) #Fail Tech Cooldown li r3,0xFF stb r3,0x680(r29) li r3,0x00 stb r3,0x684(r29) b ComboTrainingCheckToReset ComboTrainingTechInPlace: #Hold L li r3,0xC0 stw r3,0x1A88(r29) #Reset Tech Cooldown Window Constantly li r3,0x0 stb r3,0x680(r29) li r3,0xFF stb r3,0x684(r29) #Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise) lbz r3,0x221A(r29) rlwinm. r3,r3,0,26,26 bne ComboTrainingCheckToReset li r3,0x0 stb r3,0x1A8C(r29) b ComboTrainingCheckToReset ComboTrainingTechTowards: #Hold L li r3,0xC0 stw r3,0x1A88(r29) #Reset Tech Cooldown Window Constantly li r3,0x0 stb r3,0x680(r29) li r3,0xFF stb r3,0x684(r29) #Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise) lbz r3,0x221A(r29) rlwinm. r3,r3,0,26,26 bne ComboTrainingCheckToReset #Push Towards Opponent's Direction bl GetDirectionInRelationToP1 mulli r3,r3,-1 #Negate This li r4,127 mullw r3,r3,r4 stb r3,0x1A8C(r29) b ComboTrainingCheckToReset ComboTrainingTechAway: #Hold L li r3,0xC0 stw r3,0x1A88(r29) #Reset Tech Cooldown Window Constantly li r3,0x0 stb r3,0x680(r29) li r3,0xFF stb r3,0x684(r29) #Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise) lbz r3,0x221A(r29) rlwinm. r3,r3,0,26,26 bne ComboTrainingCheckToReset bl GetDirectionInRelationToP1 li r4,127 mullw r3,r3,r4 stb r3,0x1A8C(r29) b ComboTrainingCheckToReset #INPUT AN ATTACK OR DIRECTION WHEN MISSED A TECH ComboTrainingMissedTechThink: li r3,4 #1/4 chance to getup attack branchl r12,HSD_Randi cmpwi r3,0x0 beq ComboTrainingMissedTech_GetupAttack #No Getup Attack, Input Random Direction li r3,0 bl ComboTrainingDecideStickAngle b ComboTrainingCheckToReset #Input Getup Attack ComboTrainingMissedTech_GetupAttack: li r3,0x100 #Press A To Getup Attack stw r3,0x1A88(r29) b ComboTrainingCheckToReset ######################## ## Post Hitstun Think ## ######################## ComboTrainingPostHitstun: #Check Post Hitstun Behavior lbz r3,PostHitstunAction(MenuData) cmpwi r3,0x0 beq ComboTrainingPostHitstun_AirdodgeSpotdodge cmpwi r3,0x1 beq ComboTrainingPostHitstun_GiveInvinc cmpwi r3,0x2 beq ComboTrainingPostHitstun_Attack ComboTrainingPostHitstun_GiveInvinc: #Constantly Press Jump If In The Air lwz r3,0xE0(r29) cmpwi r3,0x0 beq ComboTrainingPostHitstun_GiveInvinc_ApplyInvinc li r3,0x800 stw r3,0x1A88(r29) #Clear Prev Frame Jump Input li r3,0x0 stw r3,0x668(r29) #Apply Invinc ComboTrainingPostHitstun_GiveInvinc_ApplyInvinc: mr r3,r30 li r4,30 branchl r12,ApplyIntangibility #UpdateGFX mr r3,r30 branchl r12,GFX_UpdatePlayerGFX #Set Timer if Not Set lwz r3,0x4(r31) cmpwi r3,0x0 bgt ComboTrainingCheckToReset #Set Timer li r3,30 stw r3,0x4(r31) b ComboTrainingCheckToReset #****************************************************************# ComboTrainingPostHitstun_AirdodgeSpotdodge: #Check If In Airdodge #Check If In Gained Invuln From Air/Spotdodge lwz r3,0x1988(r29) cmpwi r3,0x0 beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge b ComboTrainingPostHitstun_EnteredAirdodgeSpotdodge ComboTrainingPostHitstun_EnteredAirdodgeSpotdodge: #Set Timer if Not Set lwz r3,0x4(r31) cmpwi r3,0x0 bgt ComboTrainingCheckToReset #Set Timer li r3,30 stw r3,0x4(r31) #Give Invince and Exit b ComboTrainingCheckToReset #****************************************************************# ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge: #If in An Exit State, Reset State bl ComboTrainingCheckExitStates cmpwi r3,0x0 beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState #Except Fall lwz r3,0x10(r29) cmpwi r3,0x1D beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState #Except Landing cmpwi r3,0x2A beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState #Except Wait cmpwi r3,0xE beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState #Set Timer if Not Set lwz r3,0x4(r31) cmpwi r3,0x0 bgt ComboTrainingCheckToReset #Set Timer li r3,30 stw r3,0x4(r31) ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState: #Check If in Air lwz r3,0xE0(r29) cmpwi r3,0x0 beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_CheckToSpotdodge #Check If In DamageLightHit With No Hitstun Left (Same interrupts as Fall) lwz r3,0x10(r29) cmpwi r3,0x56 beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_InputAirdodge ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckToWiggleOut: #Check If In Damage States lwz r3,0x10(r29) cmpwi r3,0x4B blt ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckForFall cmpwi r3,0x5B bgt ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckForFall #Wiggle Out to Enter Fall li r3,127 stb r3,0x1A8C(r29) b ComboTrainingCheckToReset #Check If In Fall ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckForFall: lwz r3,0x10(r29) cmpwi r3,0x1D bne ComboTrainingCheckToReset ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_InputAirdodge: #Airdodge li r3,0 stb r3,0x1A8C(r29) li r3,0xC0 stw r3,0x1A88(r29) #Clear Buttons From Last Frame li r3,0x0 stw r3,0x65C(r29) b ComboTrainingCheckToReset ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_CheckToSpotdodge: #Check If Grounded and Actionable lwz r3,0x10(r29) cmpwi r3,0xE #Wait beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_Spotdodge cmpwi r3,0xB6 #Shielding beq ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_Spotdodge cmpwi r3,0x2A #Land bne ComboTrainingCheckToReset #Check If Can Interrupt Land lfs f1,0x894(r29) lfs f2,0x1F4(r29) fcmpo cr0,f1,f2 blt ComboTrainingCheckToReset ComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_Spotdodge: #Clear Buttons From Last Frame li r3,0x0 stw r3,0x65C(r29) #Input Spotdodge li r3,0xC0 stw r3,0x1A88(r29) li r3,-127 stb r3,0x1A8D(r29) b ComboTrainingCheckToReset #****************************************************************# ComboTrainingPostHitstun_Attack: #Clear Buttons From Last Frame li r3,0x0 stw r3,0x65C(r29) #Get Air or Ground lwz r3,0xE0(r29) cmpwi r3,0x0 beq ComboTrainingPostHitstun_AttackGround ComboTrainingPostHitstun_AttackAir: bl ComboTrainingAttackList mflr r5 lwz r4,0x4(r29) lbzx r3,r4,r5 rlwinm r3,r3,0,28,31 #Get Right Bits b ComboTrainingPostHitstun_Attack_BranchToAttack ComboTrainingPostHitstun_AttackGround: bl ComboTrainingAttackList mflr r5 lwz r4,0x4(r29) lbzx r3,r4,r5 rlwinm r3,r3,28,28,31 #Get Left Bits b ComboTrainingPostHitstun_Attack_BranchToAttack ComboTrainingPostHitstun_Attack_BranchToAttack: cmpwi r3,0x0 beq ComboTrainingPostHitstun_Attack_A cmpwi r3,0x1 beq ComboTrainingPostHitstun_Attack_ForwardA cmpwi r3,0x2 beq ComboTrainingPostHitstun_Attack_BackA cmpwi r3,0x3 beq ComboTrainingPostHitstun_Attack_DownA cmpwi r3,0x4 beq ComboTrainingPostHitstun_Attack_UpA cmpwi r3,0x5 beq ComboTrainingPostHitstun_Attack_DownSmash cmpwi r3,0x6 beq ComboTrainingPostHitstun_Attack_UpB cmpwi r3,0x7 beq ComboTrainingPostHitstun_Attack_DownB ComboTrainingPostHitstun_Attack_A: li r3,0x100 #Hit A stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_ForwardA: #Push Towards Opponent's Direction bl GetDirectionInRelationToP1 mulli r3,r3,-1 #Negate This li r4,60 mullw r3,r3,r4 stb r3,0x1A8C(r29) li r3,0x100 #Hit A stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_BackA: #Push Away Opponent's Direction bl GetDirectionInRelationToP1 li r4,60 mullw r3,r3,r4 stb r3,0x1A8C(r29) li r3,0x100 #Hit A stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_DownA: li r3,60 stb r3,0x1A8D(r29) li r3,0x100 #Hit A stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_UpA: li r3,60 stb r3,0x1A8D(r29) li r3,0x100 #Hit A stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_DownSmash: li r3,-127 stb r3,0x1A8F(r29) b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_UpB: li r3,127 stb r3,0x1A8D(r29) li r3,0x200 #Hit B stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox ComboTrainingPostHitstun_Attack_DownB: li r3,-127 stb r3,0x1A8D(r29) li r3,0x200 #Hit B stw r3,0x1A88(r29) #Held Buttons b ComboTrainingPostHitstun_Attack_CheckForHitbox #Search For Active Hitbox ComboTrainingPostHitstun_Attack_CheckForHitbox: mr r3,r30 bl CheckForActiveHitboxes cmpwi r3,0x0 bne ComboTrainingPostHitstun_GiveInvinc_ApplyInvinc #Harcoded Fox Grounded Shine Check =( lwz r3,0x4(r29) cmpwi r3,0x1 beq ComboTrainingPostHitstun_Attack_CheckForGroundShine cmpwi r3,0x16 beq ComboTrainingPostHitstun_Attack_CheckForGroundShine #Hardcoded Puff Rest Check =( cmpwi r3,0xF beq ComboTrainingPostHitstun_Attack_CheckForRest b ComboTrainingCheckToReset ComboTrainingPostHitstun_Attack_CheckForGroundShine: lwz r3,0x10(r29) cmpwi r3,0x168 beq ComboTrainingPostHitstun_GiveInvinc_ApplyInvinc b ComboTrainingCheckToReset ComboTrainingPostHitstun_Attack_CheckForRest: lwz r3,0x10(r29) cmpwi r3,0x171 beq ComboTrainingPostHitstun_GiveInvinc_ApplyInvinc b ComboTrainingCheckToReset #****************************************************************# #Check To Reset ComboTrainingCheckToReset: lwz r3,0x4(r31) #get timer cmpwi r3,0x0 #No Reset Timer Set Yet ble ComboTrainingThinkExit #Dec Timer subi r3,r3,0x1 stw r3,0x4(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne ComboTrainingThinkExit #Exit If Not ComboTrainingRestoreState: #Restore State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Reset State ID li r3,0x0 stb r3,EventState(r31) ComboTrainingThinkExit: mr r3,MenuData bl ClearToggledOptions bl UpdateAllGFX restore blr ################################# ComboTraining_StartingGroundIDs: blrl #Ground IDs to start on .long 0xFFFFFFFF #Dummy, TEST .long 0x00050022 #FoD, Pokemon Stadium .long 0x00050037 #Peach's Castle, Kongo Jungle .long 0x000B0012 #Brinstar, Corneria .long 0x00030019 #Yoshi's Story, Onett .long 0x00000048 #Mute City, Rainbow Cruise .long 0x00000024 #Jungle Japes, Great Bay .long 0x00190007 #Hyrule Temple, Brinstar Depths .long 0x000E0026 #Yoshi's Island, Green Greens .long 0x00040003 #Fourside, MKI .long 0x00040000 #MKII, Akaneia .long 0x00010105 #Venom, PokeFloats .long 0x00D9015B #Big Blue, Icicle Mountain .long 0x00000064 #Icetop, Flatzone .long 0x00040009 #Dream Land, Yoshis Island 64 .long 0x000b0001 #Kongo Jungle 64, Battlefield .long 0x00010000 #Final Destination ################################# ComboTrainingDecideStickAngle: #Decide Stick Angle backup #Clear Stick Inputs Just in Case li r4,0x0 stb r4,0x1A8C(r29) stb r4,0x1A8D(r29) #Check Which Type Of DI To Perform cmpwi r3,DI_Random beq ComboTrainingDecideStickAngle_RandomDI cmpwi r3,DI_Survival beq ComboTrainingDecideStickAngle_SurvivalDI cmpwi r3,DI_ComboDI beq ComboTrainingDecideStickAngle_ComboDI cmpwi r3,DI_SlightDIRandom beq ComboTrainingDecideStickAngle_RandomDI_SlightDI cmpwi r3,DI_SlightDIInwards beq ComboTrainingDecideStickAngle_SlightDIInwards cmpwi r3,DI_DownAndAway beq ComboTrainingDecideStickAngle_DownAwayDI cmpwi r3,DI_None beq ComboTrainingDecideStickAngle_NoDI ############### ## Random DI ## ############### #Roll RNG ComboTrainingDecideStickAngle_RandomDI: li r3,6 branchl r12,HSD_Randi cmpwi r3,0x0 beq ComboTrainingDecideStickAngle_RandomDI_TrulyRandom cmpwi r3,0x1 beq ComboTrainingDecideStickAngle_ComboDI cmpwi r3,0x2 beq ComboTrainingDecideStickAngle_SurvivalDI cmpwi r3,0x3 beq ComboTrainingDecideStickAngle_RandomDI_SlightDI cmpwi r3,0x4 beq ComboTrainingDecideStickAngle_DownAwayDI cmpwi r3,0x5 beq ComboTrainingDecideStickAngle_NoDI ComboTrainingDecideStickAngle_RandomDI_TrulyRandom: .set Combo_RandomAnalogMin, 36 .set Combo_RandomAnalogMax, 127 #Get X magnitude li r3,Combo_RandomAnalogMax - Combo_RandomAnalogMin branchl r12,HSD_Randi addi r3,r3,Combo_RandomAnalogMin stb r3,0x1A8C(r29) #Chance to negate li r3,2 branchl r12,HSD_Randi cmpwi r3,0x0 beq 0x10 lbz r3,0x1A8C(r29) neg r3,r3 stb r3,0x1A8C(r29) #Get Y magnitude li r3,Combo_RandomAnalogMax - Combo_RandomAnalogMin branchl r12,HSD_Randi addi r3,r3,Combo_RandomAnalogMin stb r3,0x1A8D(r29) #Chance to negate li r3,2 branchl r12,HSD_Randi cmpwi r3,0x0 beq 0x10 lbz r3,0x1A8D(r29) neg r3,r3 stb r3,0x1A8D(r29) b ComboTrainingDecideStickAngleExit ComboTrainingDecideStickAngle_RandomDI_SlightDI: .set Combo_SlightAnalogMin, 36 .set Combo_SlightAnalogMax, 66 #Get X magnitude li r3,Combo_SlightAnalogMax - Combo_SlightAnalogMin branchl r12,HSD_Randi addi r3,r3,Combo_RandomAnalogMin stb r3,0x1A8C(r29) #Chance to negate li r3,2 branchl r12,HSD_Randi cmpwi r3,0x0 beq 0x10 lbz r3,0x1A8C(r29) neg r3,r3 stb r3,0x1A8C(r29) #Get Y magnitude li r3,Combo_SlightAnalogMax - Combo_SlightAnalogMin branchl r12,HSD_Randi addi r3,r3,Combo_SlightAnalogMin stb r3,0x1A8D(r29) #Chance to negate li r3,2 branchl r12,HSD_Randi cmpwi r3,0x0 beq 0x10 lbz r3,0x1A8D(r29) neg r3,r3 stb r3,0x1A8D(r29) b ComboTrainingDecideStickAngleExit ####################### ## Slight DI Towards ## ####################### ComboTrainingDecideStickAngle_SlightDIInwards: #Get Random Stick X Input 86-105, 86-95 go in front, 96-105 go behind shiek li r3,19 branchl r12,HSD_Randi addi r3,r3,86 #Start at 86 lfs f1,0x2C(r27) fneg f1,f1 fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) #Facing direction as int mullw r3,r3,r4 stb r3,0x1A8C(r29) b ComboTrainingDecideStickAngleExit ################# ## Survival DI ## ################# ComboTrainingDecideStickAngle_SurvivalDI: #Check If In Throw bl ComboTrainingCheckForThrowAngle cmpwi r3,-1 bne ComboTrainingDecideStickAngle_SurvivalDI_UsingThrowAngle #Get Knockback Angle lwz r3,0x1848(r29) ComboTrainingDecideStickAngle_SurvivalDI_UsingThrowAngle: #Get Perpendicular Angle #Get Damage Direction cmpwi r3,0x169 #Check For Sakurai Angle bne 0xC li r3,0x2D li r4,0x2D cmpwi r3,90 bge ComboTrainingDecideStickAngle_SurvivalDI_Above90 b ComboTrainingDecideStickAngle_SurvivalDI_RightSide ComboTrainingDecideStickAngle_SurvivalDI_Above90: cmpwi r3,269 blt ComboTrainingDecideStickAngle_SurvivalDI_LeftSide ComboTrainingDecideStickAngle_SurvivalDI_RightSide: addi r3,r3,90 cmpwi r3,360 blt 0x8 subi r3,r3,360 b ComboTrainingDecideStickAngle_SurvivalDI_GetXY ComboTrainingDecideStickAngle_SurvivalDI_LeftSide: subi r3,r3,90 cmpwi r3,0 bgt 0x8 addi r3,r3,360 b ComboTrainingDecideStickAngle_SurvivalDI_GetXY ComboTrainingDecideStickAngle_SurvivalDI_GetXY: bl ComboTrainingDecideStickAngle_ConvertAngle stb r3,0x1A8C(r29) stb r4,0x1A8D(r29) bl GetDirectionInRelationToP1 #mulli r3,r3,-1 #Negate This Value lbz r4,0x1A8C(r29) mullw r3,r3,r4 stb r3,0x1A8C(r29) #Point Towards Opponent b ComboTrainingDecideStickAngleExit ############## ## Combo DI ## ############## ComboTrainingDecideStickAngle_ComboDI: #Check If In Throw bl ComboTrainingCheckForThrowAngle cmpwi r3,-1 bne ComboTrainingDecideStickAngle_ComboDI_UsingThrowAngle #Get Knockback Angle lwz r3,0x1848(r29) ComboTrainingDecideStickAngle_ComboDI_UsingThrowAngle: mr r24,r3 #Backup Original Angle We're Using #Get Perpendicular Angle #Get Damage Direction cmpwi r3,0x169 #Check For Sakurai Angle bne 0xC li r3,0x2D li r4,0x2D cmpwi r3,90 bge ComboTrainingDecideStickAngle_ComboDI_Above90 b ComboTrainingDecideStickAngle_ComboDI_RightSide ComboTrainingDecideStickAngle_ComboDI_Above90: cmpwi r3,269 blt ComboTrainingDecideStickAngle_ComboDI_LeftSide ComboTrainingDecideStickAngle_ComboDI_RightSide: subi r3,r3,90 cmpwi r3,0 bgt 0x8 addi r3,r3,360 b ComboTrainingDecideStickAngle_ComboDI_GetXY ComboTrainingDecideStickAngle_ComboDI_LeftSide: addi r3,r3,90 cmpwi r3,360 blt 0x8 subi r3,r3,360 b ComboTrainingDecideStickAngle_ComboDI_GetXY ComboTrainingDecideStickAngle_ComboDI_GetXY: bl ComboTrainingDecideStickAngle_ConvertAngle stb r3,0x1A8C(r29) stb r4,0x1A8D(r29) #If In a Throw, Always DI The Direction Of The Angle lwz r3,0x10(r29) cmpwi r3,0xEF blt ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionNoThrow cmpwi r3,0xF3 bgt ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionNoThrow ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow: cmpwi r24,90 bge ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_Above90 b ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_Above90: cmpwi r3,269 blt ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide: #Always Facing Direction li r3,0x0 bl IntToFloat lfs f2,0x2C(r27) fcmpo cr0,f2,f1 bgt ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_Abs ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_AbsNeg: lbz r3,0x1A8C(r29) extsb r3,r3 bl IntToFloat fabs f1,f1 fneg f1,f1 b ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_StoreX ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_Abs: lbz r3,0x1A8C(r29) extsb r3,r3 bl IntToFloat fabs f1,f1 b ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_StoreX ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_StoreX: fctiwz f1,f1 stfd f1,0xF0(sp) lwz r3,0xF4(sp) stb r3,0x1A8C(r29) b ComboTrainingDecideStickAngleExit ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide: #Always Opposite My Facing Direction li r3,0x0 bl IntToFloat lfs f2,0x2C(r27) fcmpo cr0,f2,f1 bgt ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_AbsNeg ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_Abs: lbz r3,0x1A8C(r29) extsb r3,r3 bl IntToFloat fabs f1,f1 b ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_StoreX ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_AbsNeg: lbz r3,0x1A8C(r29) extsb r3,r3 bl IntToFloat fabs f1,f1 fneg f1,f1 b ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_StoreX ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_StoreX: fctiwz f1,f1 stfd f1,0xF0(sp) lwz r3,0xF4(sp) stb r3,0x1A8C(r29) b ComboTrainingDecideStickAngleExit ComboTrainingDecideStickAngle_ComboDI_AdjustDirectionNoThrow: bl GetDirectionInRelationToP1 #mulli r3,r3,-1 #Negate This Value lbz r4,0x1A8C(r29) mullw r3,r3,r4 stb r3,0x1A8C(r29) #Point Towards Opponent b ComboTrainingDecideStickAngleExit ###################### ## Down And Away DI ## ###################### ComboTrainingDecideStickAngle_DownAwayDI: #Load X Value bl GetDirectionInRelationToP1 #Point Away From P1 li r4,89 mullw r3,r3,r4 stb r3, 0x1A8C (r29) #Load Y Value li r3,-89 stb r3, 0x1A8D (r29) #C-Stick Down li r3,-127 stb r3, 0x1A8F (r29) b ComboTrainingDecideStickAngleExit ########### ## No DI ## ########### ComboTrainingDecideStickAngle_NoDI: ComboTrainingDecideStickAngleExit: restore blr ####################################################### ComboTrainingDecideStickAngle_ConvertAngle: #Convert New Angle To Float backup bl IntToFloat #Get Pi/180 lfs f2,-0x7510(rtoc) #Get Angle As Radian fmuls f31,f1,f2 #Get 127 as Float li r3,127 bl IntToFloat fmr f30,f1 #Convert To X and Y Components fmr f1,f31 branchl r12,cos #load cosine function fmuls f1,f1,f30 #Get X Component As Float fctiwz f1,f1 stfd f1,0xF0(sp) lwz r20,0xF4(sp) fmr f1,f31 branchl r12,sin #load sine function fmuls f1,f1,f30 #Get X Component As Float fctiwz f1,f1 stfd f1,0xF0(sp) lwz r21,0xF4(sp) #Clamp Deadzones ComboTrainingDecideStickAngle_ConvertAngle_ClampX: mr r3,r20 bl IntToFloat fabs f3,f1 li r3,36 bl IntToFloat fcmpo cr0,f3,f1 bge ComboTrainingDecideStickAngle_ConvertAngle_ClampY li r20,0x0 ComboTrainingDecideStickAngle_ConvertAngle_ClampY: mr r3,r21 bl IntToFloat fabs f3,f1 li r3,36 bl IntToFloat fcmpo cr0,f3,f1 bge ComboTrainingDecideStickAngle_ConvertAngle_Exit li r21,0x0 ComboTrainingDecideStickAngle_ConvertAngle_Exit: #Return X Y Stick Values mr r3,r20 mr r4,r21 restore blr ############################################################## ComboTrainingCheckForThrowAngle: #Check If In Throw First (Must Retrieve Angle Manually) lwz r3,0x10(r29) #CPU AS cmpwi r3,0xEF blt ComboTrainingCheckForThrowAngle_NoThrow cmpwi r3,0xF3 bgt ComboTrainingCheckForThrowAngle_NoThrow #Get Throw Angle addi r4,r27,0xdf4 #P1 Throw Hitbox Info? lwz r3,0x20(r4) #Throw Angle b ComboTrainingCheckForThrowAngle_NoThrowExit ComboTrainingCheckForThrowAngle_NoThrow: li r3,-1 ComboTrainingCheckForThrowAngle_NoThrowExit: blr #################################################### ComboTrainingCheckExitStates: #Check For Exit States lwz r3,0x10(r29) cmpwi r3,0xE #Wait beq ComboTrainingCheckExitStates_ExitState cmpwi r3,0x1D #Fall beq ComboTrainingCheckExitStates_ExitState cmpwi r3,0x1B #DJ beq ComboTrainingCheckExitStates_ExitState cmpwi r3,0xFD #CliffWait beq ComboTrainingCheckExitStates_ExitState cmpwi r3,0xF5 #Teeter beq ComboTrainingCheckExitStates_ExitState cmpwi r3,0x1C #JumpB Aerial beq ComboTrainingCheckExitStates_ExitState cmpwi r3,0x2A #Land bne ComboTrainingCheckExitStates_CheckJiggsJump #Check If Can Interrupt Land lfs f1,0x894(r29) lfs f2,0x1F4(r29) fcmpo cr0,f1,f2 bge ComboTrainingCheckExitStates_ExitState ComboTrainingCheckExitStates_CheckJiggsJump: lwz r4,0x4(r29) cmpwi r4,0xF #Check If Jiggs bne ComboTrainingCheckExitStates_NoExitState cmpwi r3,0x155 beq ComboTrainingCheckExitStates_ExitState ComboTrainingCheckExitStates_NoExitState: li r3,0x0 b ComboTrainingCheckExitStates_Exit ComboTrainingCheckExitStates_ExitState: li r3,0x1 b ComboTrainingCheckExitStates_Exit ComboTrainingCheckExitStates_Exit: blr #################################################### ComboTrainingWindowInfo: blrl #amount of options, amount of options in each window .long 0x04060304 #5 windows, DI has 7 options, SDI has 4 Options, Tech Has 5 Options .long 0x02020000 #PostHitstun has 3 options, Mash has 3 options #################################################### ComboTrainingWindowText: blrl ######## ## DI ## ######## #Window Title = DI Behavior .string "DI Behavior" .align 2 #Option 1 = Random DI .string "Random DI" .align 2 #Option 2 = Survival DI .string "Survival DI" .align 2 #Option 3 = Combo DI .string "Combo DI" .align 2 #Option 4 = Slight DI Random .string "Slight DI Random" .align 2 #Option 5 = Slight DI Towards .string "Slight DI Towards" .align 2 #Option 6 = Down and Away DI .string "Down and Away DI" .align 2 #Option 6 = No DI .string "No DI" .align 2 ######### ## SDI ## ######### #SDI Behavior .long 0x53444920 .long 0x42656861 .long 0x76696f72 .long 0x00000000 #Option 1 = 33% Chance to SDI .long 0x33338193 .long 0x20436861 .long 0x6e636520 .long 0x746f2053 .long 0x44490000 #Option 2 = 66% Chance to SDI .long 0x36368193 .long 0x20436861 .long 0x6e636520 .long 0x746f2053 .long 0x44490000 #Option 3 = Always SDI .long 0x416c7761 .long 0x79732053 .long 0x44490000 #Option 4 = No SDI .long 0x4e6f2053 .long 0x44490000 ################# ## Tech Option ## ################# #Tech Option .long 0x54656368 .long 0x204f7074 .long 0x696f6e00 #Option 1 = Random .long 0x52616e64 .long 0x6f6d0000 #Option 2 = Missed Tech .long 0x4d697373 .long 0x65642054 .long 0x65636800 #Option 3 = Tech In Place .long 0x54656368 .long 0x20496e20 .long 0x506c6163 .long 0x65000000 #Option 4 = Tech In .long 0x54656368 .long 0x20496e00 #Option 5 = Tech Away .long 0x54656368 .long 0x20417761 .long 0x79000000 ################# ## Tech Option ## ################# #Post Hitstun Action .long 0x506f7374 .long 0x20486974 .long 0x7374756e .long 0x20416374 .long 0x696f6e00 #Airdodge/Spotdodge .long 0x41697264 .long 0x6f646765 .long 0x815e5370 .long 0x6f74646f .long 0x64676500 #Invincible .long 0x496e7669 .long 0x6e636962 .long 0x6c650000 #Attack .long 0x41747461 .long 0x636b0000 ################### ## Grab Mash-Out ## ################### #Grab Mash-Out .long 0x47726162 .long 0x204d6173 .long 0x682d4f75 .long 0x74000000 .long 0x #Random Mash .long 0x52616e64 .long 0x6f6d204d .long 0x61736800 .long 0x .long 0x #Frame Perfect .long 0x4672616d .long 0x65205065 .long 0x72666563 .long 0x74000000 .long 0x #No Mash-Out .long 0x4e6f204d .long 0x6173682d .long 0x4f757400 .long 0x .long 0x #################################################### ComboTrainingAttackList: blrl .long 0x00700466 .long 0x02660000 .long 0x30000303 .long 0x04660073 .long 0x30000152 .long 0x00007000 .long 0x660400FF #################################################### ComboTrainingLoadExit: restore blr ################################################## #endregion #region Waveshine SDI ######################### ## Waveshine SDI HIJACK INFO ## ######################### WaveshineSDI: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Fox.Ext #Use chosen CPU li r6,FinalDestination #Use chosen Stage load r7,EventOSD_WaveshineSDI li r8,1 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION WaveshineSDIStoreThink: bl WaveshineSDILoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Waveshine SDI LOAD FUNCT ## ######################## WaveshineSDILoad: blrl backup #Schedule Think bl WaveshineSDIThink mflr r3 li r4,3 #Priority (After Interrupt) li r5,0 bl CreateEventThinkFunction /* #Make Long Destination #Get Stage DAT Pointer load r3,0x80432290 lwz r3,0x10(r3) lwz r6,0x4(r3) lis r3, 0x4040 li r5, 0x0 ori r4, r5, 0xF488 stwx r3, r6, r4 ori r4, r5, 0xF4CC stwx r3, r6, r4 ori r4, r5, 0xF4D0 stwx r3, r6, r4 ori r4, r5, 0xF590 stwx r3, r6, r4 lis r4, 0x1 ori r4, r4, 0x88 stwx r3, r6, r4 lis r4, 0x1 ori r4, r4, 0x608 stwx r3, r6, r4 lis r3, 0x4248 ori r4, r5, 0xF4D8 stwx r3, r6, r4 lis r4, 0x5 ori r4, r4, 0x1B90 stwx r5, r6, r4 lis r5, 0x5 lis r3, 0xC3AA ori r3, r3, 0x91EC ori r4, r5, 0x1F20 stwx r3, r6, r4 lis r3, 0x43AA ori r3, r3, 0x91EC ori r4, r5, 0x1F60 stwx r3, r6, r4 lis r3, 0xC3D0 ori r3, r3, 0x91EC ori r4, r5, 0x1FA0 stwx r3, r6, r4 lis r3, 0x43D0 ori r3, r3, 0x91EC ori r4, r5, 0x1FE0 stwx r3, r6, r4 */ b WaveshineSDILoadExit ######################### ## Waveshine SDI THINK FUNCT ## ######################### WaveshineSDIThink: blrl .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq WaveshineSDIThinkMain #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) #Set Facing Directions lis r3,0x3f80 stw r3,0x2C(r29) lis r3,0xBf80 stw r3,0x2C(r27) #Initlize Positions bl WaveshineSDI_Floats mflr r3 bl InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Store Ground As Last Known Position lfs f1, 0x00B4 (r29) stfs f1, 0x0834 (r29) #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Set Timer to -60 li r3,-60 stw r3,0x4(r31) WaveshineSDIThinkMain: WaveshineSDIThinkSequence: #Inc Timer lwz r3,0x4(r31) addi r3,r3,0x1 stw r3,0x4(r31) #Get Floats bl WaveshineSDI_Floats mflr r21 #Check Timer cmpwi r3,0x0 blt WaveshineSDICheckToReset #Check If Edge Of Stage lfs f1,0xB0(r29) #P1 X Coord lfs f2,0x18(r21) #Max X Coord fabs f1,f1 fabs f2,f2 fcmpo cr0,f1,f2 blt WaveshineSDISkipBoundaryCheck #Freeze Fox If So lbz r0,0x2219(r29) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(r29) lwz r3,0xC(r31) cmpwi r3,0x0 #No Reset Timer Set Yet bgt WaveshineSDICheckToReset li r3,60 #Set Timer If Not Set Yet stw r3,0xC(r31) b WaveshineSDICheckToReset WaveshineSDISkipBoundaryCheck: #Check If Fox Grabbed Marth lwz r3,0x10(r29) cmpwi r3,0xD8 bne WaveshineSDICheckDrillOrWaveshine lwz r3,0xC(r31) cmpwi r3,0x0 bgt WaveshineSDICheckDrillOrWaveshine li r3,60 stw r3,0xC(r31) #Check If Drilling or Waveshining WaveshineSDICheckDrillOrWaveshine: lbz r3,0x8(r31) cmpwi r3,0x1 bge WaveshineSDIWaveshineThink #Run Drill Code WaveshineSDIDrillThink: lwz r3,0x10(r29) WaveshineSDIDrillThink_CheckToJump: cmpwi r3,0xE bne WaveshineSDIDrillThink_CheckToDair li r3,0x400 stw r3,0x1A88(r29) b WaveshineSDICheckToReset WaveshineSDIDrillThink_CheckToDair: cmpwi r3,0x19 bne WaveshineSDI_CheckToFF li r3,-127 stb r3,0x1A8F(r29) b WaveshineSDICheckToReset WaveshineSDI_CheckToFF: #Check If Drilling cmpwi r3,0x45 bne WaveshineSDICheckToReset #Joystick X = 36 * Facing Direction (Drift Forward during drill lfs f1,0x2C(r29) fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) li r3,36 #X Stick mullw r3,r3,r4 stb r3,0x1A8C(r29) #Check If Already FF'ing lbz r3,0x221A(r29) rlwinm. r3,r3,0,28,28 bne WaveshineSDICheckToLCancel #Check If Falling lfs f2,0x84(r29) lfs f0, -0x76B0 (rtoc) fcmpo cr0,f2,f0 bge WaveshineSDICheckToReset #Input Down to FF li r3,-127 stb r3,0x1A8D(r29) #Ananlog Y WaveshineSDICheckToLCancel: #Check If Under 5Mm Above Ground lfs f2,0xB4(r29) lfs f0,0x834(r29) #Last Grounded Y Pos fsubs f2,f2,f0 #Distance from Floor lfs f0,0x10(r21) #5 fp fcmpo cr0,f2,f0 #If less than 5 Mm away, Input L Cancel bgt WaveshineSDICheckToReset li r3,0xC0 #Hit L stw r3,0x1A88(r29) #Held Buttons li r3,0x1 #Set Start Waveshine Flag stb r3,0x8(r31) b WaveshineSDICheckToReset #Run Waveshine Code WaveshineSDIWaveshineThink: lwz r3,0x10(r29) #Shine If In Wait cmpwi r3,0xE bne WaveshineSDICheckToJump #Check If First Shine Or FollowUp Shine lbz r4,0x8(r31) cmpwi r4,0x2 beq WaveshineSDIWaveshine_FollowOpponent #Input Shine li r3,-127 stb r3,0x1A8D(r29) li r3,0x200 stw r3,0x1A88(r29) #Set Flag as Mid-Waveshine li r3,0x2 stb r3,0x8(r31) #Get JC Timing li r3,3 branchl r12,HSD_Randi stb r3,0x9(r31) b WaveshineSDICheckToReset #Jump If In Shine Loop WaveshineSDICheckToJump: #Check #Check For Shine Loop cmpwi r3,0x169 bne WaveshineSDICheckToAirdodge #Check For JC Frame lbz r3,0x9(r31) #Get JC Timing bl IntToFloat lfs f2,0x894(r29) fcmpo cr0,f1,f2 bne WaveshineSDICheckToReset #Jump li r3,0x400 stw r3,0x1A88(r29) b WaveshineSDICheckToReset #Airdodge If In JumpF WaveshineSDICheckToAirdodge: cmpwi r3,0x19 bne WaveshineSDIWaveshine_CheckIfFollowingOpponent #Get Random Airdodge Angle li r3,30 #30 Different Angles branchl r12,HSD_Randi addi r3,r3,310 #Start at 310° bl ComboTrainingDecideStickAngle_ConvertAngle #Joystick X = X Component * Facing Direction lfs f1,0x2C(r29) fctiwz f1,f1 stfd f1,0xF0(sp) lwz r5,0xF4(sp) mullw r3,r3,r5 stb r3,0x1A8C(r29) #Joystick Y = Y Component stb r4,0x1A8D(r29) #Press L To Wavedash li r3,0xC0 stw r3,0x1A88(r29) b WaveshineSDICheckToReset WaveshineSDIWaveshine_CheckIfFollowingOpponent: cmpwi r3,0xf #Check if Walking blt WaveshineSDICheckIfInTeeter cmpwi r3,0x11 #Check if Walking bgt WaveshineSDICheckIfInTeeter b WaveshineSDIWaveshine_FollowOpponent WaveshineSDICheckIfInTeeter: cmpwi r3,0xf5 bne WaveshineSDICheckToReset b WaveshineSDIRestoreState WaveshineSDIWaveshine_FollowOpponent: #Determine Distance From Opponent lfs f1,0xB0(r27) lfs f2,0xB0(r29) fsubs f1,f1,f2 lfs f2,-0x7414(rtoc) #0f fcmpo cr0,f1,f2 bge WaveshineSDIWaveshine_FollowOpponent_FacingRight WaveshineSDIWaveshine_FollowOpponent_FacingLeft: #Check If Close Enough To Shine lfs f2,0x14(r21) fneg f2,f2 fcmpo cr0,f1,f2 blt WaveshineSDIWaveshine_FollowOpponent_WalkTowards b WaveshineSDIWaveshine_FollowOpponent_EnterShine #b WaveshineSDIWaveshine_FollowOpponent_CheckMarth WaveshineSDIWaveshine_FollowOpponent_FacingRight: lfs f2,0x14(r21) fcmpo cr0,f1,f2 bgt WaveshineSDIWaveshine_FollowOpponent_WalkTowards b WaveshineSDIWaveshine_FollowOpponent_EnterShine #Check Opponent WaveshineSDIWaveshine_FollowOpponent_CheckMarth: lwz r3,0x4(r27) cmpwi r3,0x12 #Marth beq WaveshineSDIWaveshine_FollowOpponent_EnterGrab WaveshineSDIWaveshine_FollowOpponent_EnterShine: #Shine li r3,-127 stb r3,0x1A8D(r29) li r3,0x200 stw r3,0x1A88(r29) #Get JC Timing li r3,3 branchl r12,HSD_Randi stb r3,0x9(r31) b WaveshineSDICheckToReset WaveshineSDIWaveshine_FollowOpponent_EnterGrab: li r3,0x1C0 stw r3,0x1A88(r29) b WaveshineSDICheckToReset WaveshineSDIWaveshine_FollowOpponent_WalkTowards: #Walk Towards Opponent #Stick Forward lfs f1,0x2C(r29) fctiwz f2,f1 stfd f2,0xF0(sp) lwz r4,0xF4(sp) li r3,127 #X Stick mullw r3,r3,r4 stb r3,0x1A8C(r29) #Override Analog Smash Counter So Always Walking (Set Facing As Prev X Input) stfs f1,0x620(r29) b WaveshineSDICheckToReset #Initiate Reset Timer li r3,120 stw r3,0xC(r31) #Check To Reset WaveshineSDICheckToReset: lwz r3,0xC(r31) #get timer #Get Timer cmpwi r3,0x0 #No Reset Timer Set Yet ble WaveshineSDIThinkExit #Dec Timer subi r3,r3,0x1 stw r3,0xC(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne WaveshineSDIThinkExit #Exit If Not WaveshineSDIRestoreState: #Invert Facing Directions lwz r4,0x10(r31) lwz r5,0x18(r31) lfs f1,0x2C(r4) fneg f1,f1 stfs f1,0x2C(r4) lfs f1,0x2C(r5) fneg f1,f1 stfs f1,0x2C(r5) #Invert X Positions lfs f1,0xB0(r4) fneg f1,f1 stfs f1,0xB0(r4) lfs f1,0xB0(r5) fneg f1,f1 stfs f1,0xB0(r5) #Restore State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Reset Timer li r3,60 branchl r12,HSD_Randi li r4,0 sub r3,r4,r3 stw r3,0x4(r31) #Reset Mid-Waveshine Flag li r3,0x0 stb r3,0x8(r31) WaveshineSDIThinkExit: restore blr ################################# WaveshineSDI_Floats: blrl .long 0xC28C0000 #P1 X Position .long 0xc2982e6c #P2 X Position .long 0x38d1b717 #P1 Y Position .long 0x38d1b717 #FD Floor Y Coord .long 0x40A00000 #5fp .long 0x40F00000 #Distance From Opponent to Waveshine .long 0x42A00000 #X Coord To Stop ################################# WaveshineSDILoadExit: restore blr ################################################## #endregion #region Slide Off ########################### ## Slide Off HIJACK INFO ## ########################### SlideOff: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Marth.Ext li r6,PokemonStadium #Use chosen Stage load r7,EventOSD_SlideOff li r8,1 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION SlideOffStoreThink: bl SlideOffLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## Slide Off LOAD FUNCT ## ################################## SlideOffLoad: blrl backup #Schedule Think bl SlideOffThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction b SlideOffThink_Exit ################################### ## Slide Off THINK FUNCT ## ################################### SlideOffThink: blrl #Registers .set REG_EventConstants,25 .set REG_MenuData,26 .set REG_EventData,31 .set REG_P1Data,27 .set REG_P1GObj,28 .set REG_P2Data,29 .set REG_P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_Hitstun,0x0 .set EventState_DetermineAttack,0x1 .set EventState_AttackThink,0x2 .set EventState_Shield,0x3 .set Timer,0x1 .set P1State,0x2 .set P1State_Wait,0x0 .set P1State_Attacking,0x1 .set AttackTimer,0x3 #Constants .set ResetTimer,40 .set AngleLo,83 .set AngleHi,100 .set MagLo,65 .set MagHi,75 .set HitlagFrames,12 .set PercentLo,40 .set PercentHi,40 .set FramesBeforeHitbox,7 backup #INIT FUNCTION VARIABLES lwz REG_EventData,0x2c(r3) #backup data pointer in r31 #Get Player Pointers bl GetAllPlayerPointers mr REG_P1GObj,r3 mr REG_P1Data,r4 mr REG_P2GObj,r5 mr REG_P2Data,r6 #Get Menu and Constants Pointers lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData) bl SlideOffThink_Constants mflr REG_EventConstants bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq SlideOffThink_Start #Init Positions mr r3,REG_P1GObj mr r4,REG_P2GObj bl SlideOff_InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Init State li r3,EventState_Hitstun stb r3,EventState(REG_EventData) SlideOffThink_Start: #Reset if anyone died bl IsAnyoneDead cmpwi r3,0 bne SlideOffThink_Restore SlideOffThink_CheckIfFailed: #Check if failed the slide off (in non-hitlag damage state) #EventState > EventState_Hitstun lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Hitstun ble SlideOffThink_CheckIfFailed_End #Check for hitlag lbz r3,0x221A(REG_P1Data) rlwinm. r3,r3,0,26,26 bne SlideOffThink_CheckIfFailed_End #Check if in hitstun lbz r3,0x221C(REG_P1Data) rlwinm. r3,r3,0,30,30 beq SlideOffThink_CheckIfFailed_End #Check if player has been in this state for over 5 frames lhz r3,TM_FramesinCurrentAS(REG_P1Data) cmpwi r3,5 blt SlideOffThink_CheckIfFailed_End #Check if timer has started lbz r3,Timer(REG_EventData) cmpwi r3,0 bgt SlideOffThink_CheckTimer #Start Timer li r3,10 stb r3,Timer(REG_EventData) SlideOffThink_CheckIfFailed_End: SlideOffThink_CheckIfCPUDamaged: lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_DamageHi1 blt SlideOffThink_CheckIfCPUDamaged_End cmpwi r3,ASID_DamageFlyRoll bgt SlideOffThink_CheckIfCPUDamaged_End #Check if timer has started lbz r3,Timer(REG_EventData) cmpwi r3,0 bgt SlideOffThink_CheckIfCPUDamaged_End #Start Timer li r3,ResetTimer stb r3,Timer(REG_EventData) SlideOffThink_CheckIfCPUDamaged_End: SlideOffThink_SwitchCase: #Switch Case lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Hitstun beq SlideOffThink_Hitstun cmpwi r3,EventState_DetermineAttack beq SlideOffThink_DetermineAttackorShield cmpwi r3,EventState_AttackThink beq SlideOffThink_AttackThink cmpwi r3,EventState_Shield beq SlideOffThink_Shield b SlideOffThink_CheckTimer #region SlideOffThink_Hitstun SlideOffThink_Hitstun: #Check if still in ThrowHi lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_ThrowHi beq SlideOffThink_CheckTimer #Check if P1 is in a tech/mistech state lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_DownBoundU blt SlideOffThink_CheckTimer cmpwi r3,ASID_PassiveStandB bgt SlideOffThink_CheckTimer #Change state to attack li r3,EventState_DetermineAttack stb r3,EventState(EventData) b SlideOffThink_CheckTimer #endregion #region SlideOffThink_DetermineAttackorShield SlideOffThink_DetermineAttackorShield: /* #Ensure facing correct direction #Get Values lfs f1,0xB0(REG_P2Data) #p2 position lfs f2,0x2C(REG_P2Data) #p2 direction lfs f4,TriggerBoxXMin(REG_EventConstants) lfs f5,TriggerBoxXMax(REG_EventConstants) lfs f6,0xB0(REG_P1Data) #Check X fmadds f3,f2,f4,f1 #XMin fmadds f4,f2,f5,f1 #XMax #Make sure player is not behind marths range lfs f1,-0x68E0 (rtoc) #fp 0 fcmpo cr0,f2,f1 bge SlideOffThink_Attck_FacingRight SlideOffThink_Attck_FacingLeft: li r3,1 fcmpo cr0,f6,f3 bge SlideOffThink_Attck_InputTurn b SlideOffThink_Attck_SkipDirectionChange SlideOffThink_Attck_FacingRight: li r3,-1 fcmpo cr0,f6,f3 ble SlideOffThink_Attck_InputTurn b SlideOffThink_Attck_SkipDirectionChange SlideOffThink_Attck_InputTurn: #Check if already turning lwz r4,0x10(REG_P2Data) cmpwi r4,ASID_Turn beq SlideOffThink_Attck_SkipDirectionChange #Input turn mulli r3,r3,36 stb r3,CPU_AnalogX(REG_P2Data) SlideOffThink_Attck_SkipDirectionChange: */ SlideOffThink_DetermineAttackorShield_SkipFailCheck: #Decide to shield or attack lfs f1,0xB4(REG_P2Data) #p2 position lfs f2,TriggerBoxYMin(REG_EventConstants) lfs f3,TriggerBoxYMax(REG_EventConstants) lfs f4,0xB4(REG_P1Data) #p1 position fadds f2,f1,f2 #YMin fadds f3,f1,f3 #YMax #Check if P1 is above YMax fcmpo cr0,f4,f3 bge SlideOffThink_DetermineAttackorShield_AboveTriggerBox #Check if P1 is below YMin fcmpo cr0,f4,f2 bge SlideOffThink_DetermineAttackorShield_CheckToAttack_CanAttack SlideOffThink_DetermineAttackorShield_EnterShield: #Change Event State li r3,EventState_Shield stb r3,EventState(REG_EventData) #Start Timer li r3,ResetTimer stb r3,Timer(REG_EventData) b SlideOffThink_Shield SlideOffThink_DetermineAttackorShield_AboveTriggerBox: #Check if timer has started lbz r3,Timer(REG_EventData) cmpwi r3,0 bgt SlideOffThink_CheckTimer #Start Timer li r3,10 stb r3,Timer(REG_EventData) b SlideOffThink_CheckTimer SlideOffThink_DetermineAttackorShield_CheckToAttack_CanAttack: #Get P1's State lwz r3,0x10(REG_P1Data) #Ensure we have the frame data for this state cmpwi r3,ASID_DownBoundU blt SlideOffThink_DetermineAttackorShield_CheckToAttack_StartAttack cmpwi r3,ASID_PassiveStandB bgt SlideOffThink_DetermineAttackorShield_CheckToAttack_StartAttack #If DownWait or Bound, dont do anything cmpwi r3,ASID_DownWaitD beq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd cmpwi r3,ASID_DownWaitU beq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd cmpwi r3,ASID_DownBoundD beq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd cmpwi r3,ASID_DownBoundU beq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd #Get the frame data to use subi r3,r3,ASID_DownBoundU addi r4,REG_EventConstants,VulnFrameData lbzx r3,r3,r4 #Marth takes 8 frames for his utilt hitbox to appear, so subtract 8 subi r3,r3,FramesBeforeHitbox #Use the custom playerblock offset to check P1's frame count lhz r4,TM_FramesinCurrentAS(REG_P1Data) cmpw r4,r3 blt SlideOffThink_DetermineAttackorShield_CheckToAttackEnd #Time to attack SlideOffThink_DetermineAttackorShield_CheckToAttack_StartAttack: li r3,EventState_AttackThink stb r3,EventState(REG_EventData) b SlideOffThink_DetermineAttackorShield_CheckToAttackEnd SlideOffThink_DetermineAttackorShield_CheckToAttackEnd: b SlideOffThink_CheckTimer #endregion #region SlideOffThink_AttackThink SlideOffThink_AttackThink: #Get Inputs for this frame mr r3,REG_P2Data bl SlideOffThink_AttackInputs mflr r4 lbz r5,AttackTimer(REG_EventData) bl PlaybackInputSequence #Always succeed LCancel li r3,0 stb r3,0x67F(REG_P2Data) #Remove Hitbox ID 1,2 and 3 (problematic for getting slideoff) mr r3,REG_P2GObj li r4,1 branchl r12,0x8007afc8 mr r3,REG_P2GObj li r4,2 branchl r12,0x8007afc8 mr r3,REG_P2GObj li r4,3 branchl r12,0x8007afc8 #Exit AttackThink when returning to Wait lbz r3,AttackTimer(REG_EventData) cmpwi r3,0 ble SlideOffThink_AttackThink_Exit lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_Wait beq SlideOffThink_AttackThink_Reset cmpwi r3,ASID_Landing bne SlideOffThink_AttackThink_Exit #Now check if interruptable lwz r3, 0x2340 (REG_P2Data) cmpwi r3,0 beq SlideOffThink_AttackThink_Exit #Check if this frame is interruptable lfs f1,0x1f4 (REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) lhz r4,TM_FramesinCurrentAS(REG_P2Data) cmpw r4,r3 blt SlideOffThink_AttackThink_Exit SlideOffThink_AttackThink_Reset: li r3,EventState_DetermineAttack #event state stb r3,EventState(REG_EventData) li r3,0 #reset timer stb r3,AttackTimer(REG_EventData) b SlideOffThink_CheckTimer SlideOffThink_AttackThink_Exit: #Check if in Hitlag lbz r3,0x221A(REG_P2Data) rlwinm. r3,r3,0,26,26 bne SlideOffThink_CheckTimer #Increment Attack Timer lbz r3,AttackTimer(REG_EventData) addi r3,r3,1 stb r3,AttackTimer(REG_EventData) b SlideOffThink_CheckTimer #endregion #region SlideOffThink_Shield SlideOffThink_Shield: #Hold Shield li r3,PAD_TRIGGER_R stw r3,CPU_HeldButtons(REG_P2Data) b SlideOffThink_CheckTimer #endregion SlideOffThink_CheckTimer: #Check if timer exists lbz r3,Timer(REG_EventData) cmpwi r3,0 ble SlideOffThink_Exit #Decrement timer subi r3,r3,1 stb r3,Timer(REG_EventData) cmpwi r3,0 bgt SlideOffThink_Exit SlideOffThink_Restore: #Restore State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Load #Init Positions Again mr r3,REG_P1GObj mr r4,REG_P2GObj bl SlideOff_InitializePositions #Reset Variables li r3,0 stb r3,EventState(REG_EventData) stb r3,Timer(REG_EventData) stb r3,P1State(REG_EventData) stb r3,AttackTimer(REG_EventData) SlideOffThink_Exit: restore blr ################################ SlideOffThink_Constants: blrl .set MarthUTiltFrame,8 .set P1X,0x0 .set P1Y,0x4 .set P2X,0x8 .set P2Y,0xC .set UThrowStartFrame,0x10 .set DamageFlyTopStartFrame,0x14 .set MagnitudeScalar,0x18 .set MagnitudeScalar2,0x1C .set MagnitudeScalar3,0x20 .set TriggerBoxXMin,0x24 .set TriggerBoxXMax,0x28 .set TriggerBoxYMin,0x2C .set TriggerBoxYMax,0x30 .set VulnFrameData,0x34 .set Unk,0x48 .float -37.7 #p1 x .float 21.2 #p1 y .float -41.1 #p2 x .float 0 #p2 y .float 13 #marth upthrow starting frame .float 2 #p1 damageflytop starting frame .float 0.1 #baseline for mag scaling .float 1 #mag scaling constant .float 0.4 #mag scaling constant .float -8 #xmin .float 20 #xmax .float 18 #ymin .float 30 #ymax ########################################## .set TechVuln,24-4 .set TechRollVuln,23 .set KnockdownVuln,23 .set GetupVuln,23 .set GetupRollForwardVuln,20-1 .set GetupRollBackwardVuln,30-3 .set GetupAttackVuln,27 .byte KnockdownVuln #DownBoundU .byte 0 #DownWaitU .byte 0 #DownDamageU .byte GetupVuln #DownStandU .byte GetupAttackVuln #DownAttackU .byte GetupRollForwardVuln #DownForwardU .byte GetupRollBackwardVuln #DownBackU .byte -1 #DownSpotU (unused state) .byte KnockdownVuln #DownBoundD .byte 0 #DownWaitD .byte 0 #DownDamageD .byte GetupVuln #DownStandD .byte GetupAttackVuln #DownAttackD .byte GetupRollForwardVuln #DownForwardD .byte GetupRollBackwardVuln #DownBackD .byte -1 #DownSpotD (unused state) .byte TechVuln #Passive .byte TechRollVuln #PassiveStandF .byte TechRollVuln #PassiveStandB .align 2 ########################################### SlideOffThink_AttackInputs: blrl .byte 0 .long PAD_BUTTON_X .byte 0,0,0,0 .byte 4 .long 0 .byte 0,0,0,127 .byte 26 .long PAD_TRIGGER_L .byte 0,-127,0,0 .byte -1 .align 2 ################################# SlideOff_InitializePositions: backup #Change Facing Direction li r3,-1 bl IntToFloat stfs f1,0x2C(REG_P1Data) li r3,1 bl IntToFloat stfs f1,0x2C(REG_P2Data) #Get Starting Coordinates lfs f1,P1X(REG_EventConstants) stfs f1,0xB0(REG_P1Data) lfs f1,P1Y(REG_EventConstants) stfs f1,0xB4(REG_P1Data) mr r3,REG_P1GObj bl UpdatePosition mr r3,REG_P1GObj bl UpdateCameraBox lfs f1,P2X(REG_EventConstants) stfs f1,0xB0(REG_P2Data) lfs f1,P2Y(REG_EventConstants) stfs f1,0xB4(REG_P2Data) mr r3,REG_P2GObj bl PlacePlayerOnGround mr r3,REG_P2GObj bl UpdateCameraBox #P2 enters UpThrow mr r3,REG_P2GObj li r4,ASID_ThrowHi li r5,0 li r6,0 lwz r7,0x10C(REG_P1Data) #determine speed from weight lwz r7,0x0(r7) lfs f1,0x88(r7) lfs f2, -0x68DC (rtoc) lwz r7, -0x514C (r13) lfs f0, 0x037C (r7) fmuls f0,f1,f0 fdivs f2,f2,f0 #anim speed lfs f3, -0x68E0 (rtoc) #frame blend lfs f1,UThrowStartFrame(REG_EventConstants) #starting frame branchl r12,ActionStateChange #P1 enters DamageFlyTop mr r3,REG_P1GObj li r4,ASID_DamageFlyTop li r5,0x40 li r6,0 lfs f1,DamageFlyTopStartFrame (REG_EventConstants) lfs f2, -0x73D0 (rtoc) lfs f3, -0x750C (rtoc) branchl r12,ActionStateChange #Scale KB Magnitude based on characters weight li r3,MagLo bl IntToFloat lfs f2,MagnitudeScalar(REG_EventConstants) lfs f3,0x16C(REG_P1Data) lfs f4,MagnitudeScalar2(REG_EventConstants) lfs f5,MagnitudeScalar3(REG_EventConstants) fdivs f2,f3,f2 fsubs f2,f2,f4 fmuls f2,f2,f5 fmuls f2,f2,f1 fadds f1,f1,f2 fctiwz f1,f1 stfd f1,0x80(sp) lwz r20,0x84(sp) li r3,MagHi bl IntToFloat lfs f2,MagnitudeScalar(REG_EventConstants) lfs f3,0x16C(REG_P1Data) lfs f4,MagnitudeScalar2(REG_EventConstants) lfs f5,MagnitudeScalar3(REG_EventConstants) fdivs f2,f3,f2 fsubs f2,f2,f4 fmuls f2,f2,f5 fmuls f2,f2,f1 fadds f1,f1,f2 fctiwz f1,f1 stfd f1,0x80(sp) lwz r21,0x84(sp) #Enter into knockback mr r3,REG_P1GObj li r4,AngleLo li r5,AngleHi mr r6,r20 mr r7,r21 bl EnterKnockback #Override hitstun amount li r3,50 bl IntToFloat stfs f1,0x2340(REG_P1Data) #Give 7 Frames of Hitlag to Each li r3,HitlagFrames bl IntToFloat stfs f1,0x195C(REG_P1Data) lbz r0,0x221A(REG_P1Data) li r3,1 rlwimi r0,r3,5,26,26 stb r0,0x221A(REG_P1Data) lbz r0,0x2219(REG_P1Data) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(REG_P1Data) li r3,HitlagFrames bl IntToFloat stfs f1,0x195C(REG_P2Data) lbz r0,0x221A(REG_P2Data) li r3,1 rlwimi r0,r3,5,26,26 stb r0,0x221A(REG_P2Data) lbz r0,0x2219(REG_P2Data) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(REG_P2Data) #Random percent between 10-25 li r3,PercentHi-PercentLo branchl r12,HSD_Randi addi r4,r3,PercentLo lbz r3,0xC(REG_P1Data) branchl r12,PlayerBlock_SetDamage SlideOff_InitializePositions_Exit: restore blr #endregion #region Grab Mash Out ########################### ## Grab Mash Out HIJACK INFO ## ########################### GrabMashOut: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Marth.Ext li r6,FinalDestination #Use chosen Stage load r7,EventOSD_GrabMashOut li r8,1 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION GrabMashOutStoreThink: bl GrabMashOutLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## Grab Mash Out LOAD FUNCT ## ################################## GrabMashOutLoad: blrl backup #Schedule Think bl GrabMashOutThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction b GrabMashOutThink_Exit ################################### ## Grab Mash Out THINK FUNCT ## ################################### GrabMashOutThink: blrl #Registers .set REG_EventConstants,25 .set REG_MenuData,26 .set REG_EventData,31 .set REG_P1Data,27 .set REG_P1GObj,28 .set REG_P2Data,29 .set REG_P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_ThrowDelay,0x0 .set EventState_MashOutThink,0x1 .set EventState_Reset,0x2 .set Timer,0x1 .set ThrowTimer,0x2 .set GrabBreakout,0x4 #Constants .set ResetTimer,80 .set PercentLo,0 .set PercentHi,80 .set ThrowTimerLo,40 .set ThrowTimerHi,100 backup #INIT FUNCTION VARIABLES lwz REG_EventData,0x2c(r3) #backup data pointer in r31 #Get Player Pointers bl GetAllPlayerPointers mr REG_P1GObj,r3 mr REG_P1Data,r4 mr REG_P2GObj,r5 mr REG_P2Data,r6 #Get Menu and Constants Pointers lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData) bl GrabMashOutThink_Constants mflr REG_EventConstants bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq GrabMashOutThink_Start #Init Positions mr r3,REG_P1GObj mr r4,REG_P2GObj mr r5,REG_EventData bl GrabMashOut_InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save GrabMashOutThink_Start: #Reset if anyone died bl IsAnyoneDead cmpwi r3,0 bne GrabMashOutThink_Restore GrabMashOutThink_SwitchCase: #Switch Case lbz r3,EventState(REG_EventData) cmpwi r3,EventState_ThrowDelay beq GrabMashOutThink_ThrowDelay cmpwi r3,EventState_MashOutThink beq GrabMashOutThink_MashOutThink cmpwi r3,EventState_Reset beq GrabMashOutThink_Reset b GrabMashOutThink_CheckTimer #region GrabMashOutThink_ThrowDelay GrabMashOutThink_ThrowDelay: #Check to grab lhz r3,ThrowTimer(REG_EventData) subi r3,r3,1 sth r3,ThrowTimer(REG_EventData) cmpwi r3,0 bne GrabMashOutThink_ThrowDelay_TimerSkip #Input grab li r3,PAD_BUTTON_A | PAD_TRIGGER_R stw r3,CPU_HeldButtons(REG_P2Data) GrabMashOutThink_ThrowDelay_TimerSkip: #Check if P1 was grabbed lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_CaptureWaitLw beq GrabMashOutThink_ThrowDelay_Grabbed cmpwi r3,ASID_CaptureWaitHi beq GrabMashOutThink_ThrowDelay_Grabbed #If just grabbed, skip cmpwi r3,ASID_CapturePulledLw beq GrabMashOutThink_CheckTimer cmpwi r3,ASID_CapturePulledHi beq GrabMashOutThink_CheckTimer #Check if P1 acted early cmpwi r3,ASID_Wait bne GrabMashOutThink_ThrowDelay_ActedEarly b GrabMashOutThink_CheckTimer GrabMashOutThink_ThrowDelay_Grabbed: #Get breakout timer lfs f1,0x2354(REG_P1Data) stfs f1,GrabBreakout(REG_EventData) #Change state to attack li r3,EventState_MashOutThink stb r3,EventState(EventData) b GrabMashOutThink_CheckTimer GrabMashOutThink_ThrowDelay_ActedEarly: #Play Error Noise li r3,0xAF bl PlaySFX #Set Timer li r3,ResetTimer-40 stb r3,Timer(REG_EventData) #Change state to reset li r3,EventState_Reset stb r3,EventState(EventData) b GrabMashOutThink_CheckTimer #endregion #region GrabMashOutThink_MashOutThink GrabMashOutThink_MashOutThink: #Wait for P1 to be in CaptureCut lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_CaptureJump beq GrabMashOutThink_BrokeOut cmpwi r3,ASID_CaptureCut beq GrabMashOutThink_BrokeOut b GrabMashOutThink_CheckTimer GrabMashOutThink_BrokeOut: #Set reset timer li r3,ResetTimer stb r3,Timer(REG_EventData) #Advance State li r3,EventState_Reset stb r3,EventState(REG_EventData) b GrabMashOutThink_CheckTimer #endregion #region GrabMashOutThink_Reset GrabMashOutThink_Reset: b GrabMashOutThink_CheckTimer #endregion GrabMashOutThink_CheckTimer: #Check if timer exists lbz r3,Timer(REG_EventData) cmpwi r3,0 ble GrabMashOutThink_Exit #Decrement timer subi r3,r3,1 stb r3,Timer(REG_EventData) cmpwi r3,0 bgt GrabMashOutThink_Exit GrabMashOutThink_Restore: #Restore State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Load #Init Positions Again mr r3,REG_P1GObj mr r4,REG_P2GObj mr r5,REG_EventData bl GrabMashOut_InitializePositions GrabMashOutThink_Exit: restore blr ################################ GrabMashOutThink_Constants: blrl .set P1X,0x0 .set P1Y,0x4 .set P2X,0x8 .set P2Y,0xC .float -8 #p1 x .float 0 #p1 y .float 8 #p2 x .float 0 #p2 y ########################################### GrabMashOut_TopText: blrl .string "Escaped Grab" .align 2 GrabMashOut_BottomText: blrl .string "Frame %d/%d" .align 2 ########################################### GrabMashOut_InitializePositions: backup .set REG_FacingDirection,31 #1 = p1 facing right, -1 = p1 facing left .set REG_P1GObj,30 .set REG_P1Data,29 .set REG_P2GObj,28 .set REG_P2Data,27 .set REG_EventData,26 #Init Registers mr REG_P1GObj,r3 lwz REG_P1Data,0x2C(REG_P1GObj) mr REG_P2GObj,r4 lwz REG_P2Data,0x2C(REG_P2GObj) mr REG_EventData,r5 GrabMashOut_InitializePositions_DetermineFacingDirection: #Determine Facing Direction li REG_FacingDirection,1 li r3,2 branchl r12,HSD_Randi cmpwi r3,0 beq GrabMashOut_InitializePositions_DetermineFacingDirection_End li REG_FacingDirection,-1 GrabMashOut_InitializePositions_DetermineFacingDirection_End: #Apply Facing Directions mr r3,REG_FacingDirection bl IntToFloat stfs f1,0x2C(REG_P1Data) mulli r3,REG_FacingDirection,-1 bl IntToFloat stfs f1,0x2C(REG_P2Data) #Get Starting Coordinates lfs f1,P1X(REG_EventConstants) lfs f2,P1Y(REG_EventConstants) cmpwi REG_FacingDirection,0 blt GrabMashOut_InitializePositions_P1FacingLeft stfs f1,0xB0(REG_P1Data) stfs f2,0xB4(REG_P1Data) b GrabMashOut_InitializePositions_RightPosition GrabMashOut_InitializePositions_P1FacingLeft: stfs f1,0xB0(REG_P2Data) stfs f2,0xB4(REG_P2Data) GrabMashOut_InitializePositions_RightPosition: lfs f1,P2X(REG_EventConstants) lfs f2,P2Y(REG_EventConstants) cmpwi REG_FacingDirection,0 blt GrabMashOut_InitializePositions_P2FacingRight stfs f1,0xB0(REG_P2Data) stfs f2,0xB4(REG_P2Data) b GrabMashOut_InitializePositions_FacingEnd GrabMashOut_InitializePositions_P2FacingRight: stfs f1,0xB0(REG_P1Data) stfs f2,0xB4(REG_P1Data) GrabMashOut_InitializePositions_FacingEnd: #Update Positions mr r3,REG_P1GObj bl PlacePlayerOnGround mr r3,REG_P1GObj bl UpdateCameraBox mr r3,REG_P2GObj bl PlacePlayerOnGround mr r3,REG_P2GObj bl UpdateCameraBox #Enter P1 Into Wait mr r3,REG_P1GObj branchl r12,AS_Wait #Enter P2 Into Wait mr r3,REG_P2GObj branchl r12,AS_Wait #Random percent li r3,PercentHi-PercentLo branchl r12,HSD_Randi addi r4,r3,PercentLo lbz r3,0xC(REG_P1Data) branchl r12,PlayerBlock_SetDamage #Reset Variables li r3,EventState_ThrowDelay stb r3,EventState(REG_EventData) li r3,0 stb r3,Timer(REG_EventData) #Init Throw Timer li r3,ThrowTimerHi-ThrowTimerLo branchl r12,HSD_Randi addi r3,r3,ThrowTimerLo sth r3,ThrowTimer(REG_EventData) GrabMashOut_InitializePositions_Exit: restore blr #endregion #region SDI IC DThrow Dair ######################### ## Event 16 HIJACK INFO ## ######################### Event16: #STORE STAGE li r3,0x20 sth r3,0xE(r26) li r5,0xE #Ice Climbers #STORE CPU bl P2Struct mflr r3 lwz r4,0x0(r29) stw r3,0x18(r4) #p2 pointer stb r5,0x0(r3) #make top tier p2 li r5,0x1 #make CPU controlled stb r5,0x1(r3) #SPAWN 2 PLAYERS li r3,0x40 stb r3,0x1(r4) #STORE THINK FUNCTION bl Event16Load mflr r3 stw r3,0x44(r26) #on match load b exit ######################### ## Event 16 LOAD FUNCT ## ######################### Event16Load: blrl backup #Schedule Think bl Event16Think mflr r3 li r4,3 li r5,0 bl CreateEventThinkFunction b Event16LoadExit ########################## ## Event 16 THINK FUNCT ## ########################## Event16Think: blrl .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 li r3,0xF stw r3,0x1A94(r29) bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq Event16ThinkMain #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) #Set Facing Directions lis r3,0x3f80 stw r3,0x2C(r29) lis r3,0xBf80 stw r3,0x2C(r27) #Initlize Positions bl Event16_Floats mflr r3 bl Event_EnterGrab #Clear Inputs bl RemoveFirstFrameInputs #Store Ground As Last Known Position lfs f1, 0x00B4 (r29) stfs f1, 0x0834 (r29) #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save Event16ThinkMain: Event16ThinkExit: restore blr ################################################# Event16_Floats: blrl .long 0x4144CCCD #P1 X Position .long 0x00000000 #P1 Y Position .long 0xC02CCCCD #P2 X Position .long 0x00000000 #P2 Y Position ################################################# Event16LoadExit: restore blr ################################################## #endregion ############## ## Fox Tech ## ############## #region Ledgetech Counter ################################### ## Ledgetech Counter HIJACK INFO ## ################################### LedgetechCounter: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Marth.Ext #Use marth li r6,-1 #Use chosen Stage load r7,EventOSD_LedgetechCounter li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION LedgetechCounterStoreThink: bl LedgetechCounterLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## Ledgetech Counter LOAD FUNCT ## ################################## LedgetechCounterLoad: blrl backup #Schedule Think bl LedgetechCounterThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction b LedgetechCounterThink_Exit ################################### ## Ledgetech Counter THINK FUNCT ## ################################### LedgetechCounterThink: blrl #Registers .set EventConstants,25 .set MenuData,26 .set EventData,31 .set P1Data,27 .set P1GObj,28 .set P2Data,29 .set P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_OnRebirthPlat,0x0 .set EventState_Recovering,0x1 .set MarthState,0x1 .set MarthState_Wait,0x0 .set MarthState_Attacked,0x1 .set Timer,0x2 backup #INIT FUNCTION VARIABLES lwz EventData,0x2c(r3) #backup data pointer in r31 bl GetAllPlayerPointers mr P1GObj,r3 mr P1Data,r4 mr P2GObj,r5 mr P2Data,r6 lwz MenuData,EventData_MenuDataPointer(EventData) bl LedgetechCounter_Constants mflr EventConstants bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq LedgetechCounterThink_Start #Random Side of Stage li r3,2 branchl r12,HSD_Randi bl Ledgetech_InitializePositions #Move Marth forward a bit lfs f1,0x2C(P2Data) lfs f2,0x4(EventConstants) fmuls f1,f1,f2 lfs f2,0xB0(P2Data) fadds f1,f1,f2 stfs f1,0xB0(P2Data) #Move Falco down a bit lfs f1,0x8(EventConstants) lfs f2,0xB4(P1Data) fadds f1,f1,f2 stfs f1,0xB4(P1Data) #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Init Score Count lhz r3,-0x4ea8(r13) branchl r12,HUD_KOCounter_UpdateKOs LedgetechCounterThink_Start: #Reset if anyone died bl IsAnyoneDead cmpwi r3,0 bne LedgetechCounterThink_Restore #Switch case for state of event lbz r3,EventState(EventData) cmpwi r3,EventState_OnRebirthPlat beq LedgetechCounterThink_OnRebirthPlat cmpwi r3,EventState_Recovering beq LedgetechCounterThink_Recovering b LedgetechCounterThink_CheckForTimer ########################################### LedgetechCounterThink_OnRebirthPlat: #Check if exited RebirthWait lwz r3,0x10(P1Data) cmpwi r3,ASID_RebirthWait beq LedgetechCounterThink_OnRebirthPlat_ExtendTimer #Change Event State li r3,EventState_Recovering stb r3,EventState(EventData) b LedgetechCounterThink_CheckForTimer LedgetechCounterThink_OnRebirthPlat_ExtendTimer: #Extend RebithWait Timer li r3,2 stw r3,0x2340(P1Data) b LedgetechCounterThink_CheckForTimer ########################################### ########################################### LedgetechCounterThink_Recovering: #Check if marth acted already lbz r3,MarthState(EventData) cmpwi r3,MarthState_Wait bne LedgetechCounterThink_CheckForTimer #Check P1s Distance from Marth addi r3,P1Data,0xB0 addi r4,P2Data,0xB0 bl GetDistance lfs f2,0x0(EventConstants) fcmpo cr0,f1,f2 bgt LedgetechCounterThink_CheckForTimer #P1 is in range, use down B li r3,0x200 stw r3,CPU_HeldButtons(P2Data) li r3,-127 stb r3,CPU_AnalogY(P2Data) #Set as attacking li r3,MarthState_Attacked stb r3,MarthState(EventData) #Start Timer li r3,70 stb r3,Timer(EventData) b LedgetechCounterThink_CheckForTimer ############################################ LedgetechCounterThink_CheckForTimer: #Check Timer lbz r3,Timer(EventData) cmpwi r3,0 beq LedgetechCounterThink_Exit #Decrement subi r3,r3,1 stb r3,Timer(EventData) cmpwi r3,0 bne LedgetechCounterThink_Exit LedgetechCounterThink_Restore: #Load State addi r3,EventData,EventData_SaveStateStruct bl SaveState_Load #Random Side of Stage li r3,2 branchl r12,HSD_Randi bl Ledgetech_InitializePositions #Move Marth forward a bit lfs f1,0x2C(P2Data) lfs f2,0x4(EventConstants) fmuls f1,f1,f2 lfs f2,0xB0(P2Data) fadds f1,f1,f2 stfs f1,0xB0(P2Data) #Move Falco down a bit lfs f1,0x8(EventConstants) lfs f2,0xB4(P1Data) fadds f1,f1,f2 stfs f1,0xB4(P1Data) #Reset Variables li r3,EventState_OnRebirthPlat stb r3,EventState(EventData) li r3,MarthState_Wait stb r3,MarthState(EventData) li r3,0 stb r3,Timer(EventData) LedgetechCounterThink_Exit: restore blr ###### LedgetechCounter_Constants: blrl .float 33 #Mm away from fox to init counter .float 5 #Mm to move marth forward after placing on ledge .float -15 #Mm to move spacies down after placing in the air ###### #endregion #region Armada Shine ################################### ## Armada Shine HIJACK INFO ## ################################### ArmadaShine: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Fox.Ext #Use fox li r6,-1 #Use chosen Stage load r7,EventOSD_ArmadaShine li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION ArmadaShineStoreThink: bl ArmadaShineLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## Armada Shine LOAD FUNCT ## ################################## ArmadaShineLoad: blrl backup #Schedule Think bl ArmadaShineThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction #Remove randall lwz r3,StageID_External(r13) cmpwi r3,YoshiStory bne LedgedashLoad_SkipRemoveRandall #Get randall's map_gobj li r3,2 #randalls map_gobj is 2 branchl r12,Stage_map_gobj_Load branchl r12,Stage_Destroy_map_gobj b ArmadaShineThink_Exit ################################### ## Armada Shine THINK FUNCT ## ################################### ArmadaShineThink: blrl #Registers .set REG_EventConstants,25 .set REG_MenuData,26 .set REG_EventData,31 .set REG_P1Data,27 .set REG_P1GObj,28 .set REG_P2Data,29 .set REG_P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_Hitstun,0x0 .set EventState_Falling,0x1 .set EventState_RecoverStart,0x2 .set EventState_RecoverEnd,0x3 .set EventState_Reset,0x4 .set Timer,0x1 #Constants .set ResetTimer,80 .set QuickResetTimer,30 .set PercentLo,0 .set PercentHi,60 backup #INIT FUNCTION VARIABLES lwz REG_EventData,0x2c(r3) #backup data pointer in r31 #Get Player Pointers bl GetAllPlayerPointers mr REG_P1GObj,r3 mr REG_P1Data,r4 mr REG_P2GObj,r5 mr REG_P2Data,r6 #Get Menu and Constants Pointers lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData) bl ArmadaShineThink_Constants mflr REG_EventConstants bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq ArmadaShineThink_Start #Init Positions mr r3,REG_P1GObj mr r4,REG_P2GObj bl ArmadaShine_InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Init State li r3,EventState_Hitstun stb r3,EventState(REG_EventData) ArmadaShineThink_Start: #Reset if anyone died bl IsAnyoneDead cmpwi r3,0 bne ArmadaShineThink_Restore #DPad left to instant reset lbz r3, 0x0618 (REG_P1Data) bl GetInputStruct lwz r4,InputStruct_InstantButtons(r3) rlwinm. r0,r4,0,31,31 bne ArmadaShineThink_Restore ArmadaShineThink_GroundCheck: #If P2 is grounded, reset quick lwz r3,0xE0(REG_P2Data) cmpwi r3,0 beq ArmadaShineThink_GroundCheck_OnGround #If P2 is grabbing a cliff, reset quick lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_CliffCatch beq ArmadaShineThink_GroundCheck_OnGround b ArmadaShineThink_GroundCheckSkip ArmadaShineThink_GroundCheck_OnGround: #Check if timer was set lbz r3,Timer(REG_EventData) cmpwi r3,QuickResetTimer ble ArmadaShineThink_GroundCheckSkip #Set timer li r3,QuickResetTimer stb r3,Timer(REG_EventData) #Change State li r3,EventState_Reset stb r3,EventState(REG_EventData) ArmadaShineThink_GroundCheckSkip: #Switch Case lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Hitstun beq ArmadaShineThink_Hitstun cmpwi r3,EventState_Falling beq ArmadaShineThink_Falling cmpwi r3,EventState_RecoverStart beq ArmadaShineThink_RecoverStart cmpwi r3,EventState_RecoverEnd beq ArmadaShineThink_RecoverEnd cmpwi r3,EventState_Reset beq ArmadaShineThink_Reset b ArmadaShineThink_Exit #region ArmadaShineThink_Hitstun ArmadaShineThink_Hitstun: #Check if still in hitstun lbz r3,0x221C(REG_P2Data) rlwinm. r3,r3,0,30,30 bne ArmadaShineThink_Hitstun_Exit #Change Event State li r3,EventState_Falling stb r3,EventState(REG_EventData) #Run Next State Code b ArmadaShineThink_Falling ArmadaShineThink_Hitstun_Exit: #Always L-Cancel li r3,0 stb r3,0x67F(REG_P1Data) b ArmadaShineThink_Exit #endregion #region ArmadaShineThink_Falling ArmadaShineThink_Falling: .set FirefoxRadius,80 .set FirefoxChance,8 #Get distance from ledge addi r3,REG_P2Data,0xB0 addi r4,REG_P2Data,0x1ADC bl GetDistance stfs f1,0x80(sp) #Fox travels approx 82 Mm during firefox, so ensure he is at least this far li r3,FirefoxRadius bl IntToFloat lfs f2,0x80(sp) fcmpo cr0,f2,f1 bge ArmadaShineThink_Falling_EnterFirefox #Random chance to firefox li r3,FirefoxChance branchl r12,HSD_Randi cmpwi r3,0 beq ArmadaShineThink_Falling_EnterFirefox b ArmadaShineThink_Exit ArmadaShineThink_Falling_EnterFirefox: #Enter Firefox li r3,127 stb r3,CPU_AnalogY(REG_P2Data) li r3,PAD_BUTTON_B stw r3,CPU_HeldButtons(REG_P2Data) #Change Event State li r3,EventState_RecoverStart stb r3,EventState(REG_EventData) #Exit b ArmadaShineThink_Exit #endregion #region ArmadaShineThink_RecoverStart ArmadaShineThink_RecoverStart: .set RestartTimer,30 .set FirefoxHoldFrames,43 ArmadaShineThink_RecoverStart_CheckIfDone: #Check if no longer in SpecialHiStart lwz r3,0x10(REG_P2Data) cmpwi r3,354 beq ArmadaShineThink_RecoverStart_CheckIfDoneSkip #Start restart timer lwz r3,0x4(REG_P1Data) cmpwi r3,Fox.Int bne ArmadaShineThink_RecoverStart_NotFox li r3,RestartTimer b ArmadaShineThink_RecoverStart_StoreRestartTimer ArmadaShineThink_RecoverStart_NotFox: li r3,RestartTimer+60 ArmadaShineThink_RecoverStart_StoreRestartTimer: stb r3,Timer(REG_EventData) #Change Event State li r3,EventState_RecoverEnd stb r3,EventState(REG_EventData) #Run Next State Code b ArmadaShineThink_RecoverEnd ArmadaShineThink_RecoverStart_CheckIfDoneSkip: /* #Wait until last frame of firefox lhz r3,TM_FramesinCurrentAS(REG_P2Data) cmpwi r3,FirefoxHoldFrames-2 beq ArmadaShineThink_RecoverStart_InputAngle #Input Up li r3,127 stb r3,CPU_AnalogY(REG_P2Data) b ArmadaShineThink_RecoverStart_Exit */ ArmadaShineThink_RecoverStart_InputAngle: #Backup f28-f31 stfs f29,0xB0(sp) stfs f30,0xB4(sp) stfs f31,0xB8(sp) stfs f28,0xBC(sp) stfs f27,0xC0(sp) #Hold towards ledge #Get Angle Between Fox and Ledge addi r3,REG_P2Data,0xB0 addi r4,REG_P2Data,0x1ADC bl GetAngleBetweenPoints #Convert this to an input .set REG_arctan,31 .set REG_XComp,30 .set REG_YComp,31 .set REG_127,29 #Backup arctan fmr REG_arctan,f1 #Get 127 as a float li r3,127 bl IntToFloat fmr REG_127,f1 #Get X Component fmr f1,REG_arctan #angle in radians branchl r12,cos fmr REG_XComp,f1 #Get Y Component fmr f1,REG_arctan #angle in radians branchl r12,sin fmr REG_YComp,f1 #Get X input fmuls f1,REG_XComp,REG_127 fctiwz f1,f1, stfd f1,0x80(sp) lwz r3,0x84(sp) stb r3,0x1A8C(REG_P2Data) #Get Y input fmuls f1,REG_YComp,REG_127 fctiwz f1,f1, stfd f1,0x80(sp) lwz r3,0x84(sp) stb r3,0x1A8D(REG_P2Data) #region ecb test code .set REG_XPerFrame,29 .set REG_YPerFrame,28 .set REG_CurrXPos,27 .set REG_CurrYPos,26 .set REG_ECBStruct,20 .set REG_ECBBoneStruct,21 .set REG_LoopCount,22 .set FirefoxFrames,30 .set RandomAngleRange,20 #Get Per Frame Velocity mr r3,REG_P2Data branchl r12,0x800a17e4 fmr REG_XComp,f1 mr r3,REG_P2Data branchl r12,0x800a1874 fmr REG_YComp,f1 #Get atan2 fmr f1,REG_YComp lfs f2,0x2C(REG_P2Data) fmuls f2,f2,REG_XComp branchl r12,0x80022c30 fmr REG_arctan,f1 #Get XComp fmr f1,REG_arctan branchl r12,0x80326240 fmr REG_XComp,f1 fmr f1,REG_arctan branchl r12,0x803263d4 fmr REG_YComp,f1 #Get Firefox distance per frame lwz r3, 0x02D4 (REG_P2Data) lfs f1, 0x0074 (r3) lfs f0, 0x002C (REG_P2Data) fmuls f1,f1,REG_XComp fmuls REG_XPerFrame,f1,f0 lfs f1, 0x0074 (r3) fmuls REG_YPerFrame,f1,REG_YComp #Create an ECB struct on the stack subi sp,sp,0x1d0 addi REG_ECBBoneStruct,sp,0xC addi REG_ECBStruct,sp,0x24 mr r3,REG_ECBStruct branchl r12,0x80041ee4 #Create ECB Bone struct /* 0x00 = ECB Current Top Y Offset scale * value 0x04 = ECB Current Bottom Y Offset neg(scale * vlaue) 0x08 = ECB Current Left X Offset neg(scale * vlaue) 0x0C = ECB Current Left Y Offset 0 0x10 = ECB Current Right X Offset scale * value 0x14 = ECB Current Right Y Offset 0 */ #Copy Struct mr r3,REG_ECBBoneStruct addi r4,REG_EventConstants,ECB_TopY li r5,0x18 branchl r12,memcpy #Place Current XY into struct lfs REG_CurrXPos,0xB0(REG_P2Data) lfs REG_CurrYPos,0xB4(REG_P2Data) #Subtract 0.4 to account for the frame of animation left in this state lfs f1,FinalAnimYDifference(REG_EventConstants) fsubs REG_CurrYPos,REG_CurrYPos,f1 lfs f1,0xB8(REG_P2Data) stfs f1,0x24(REG_ECBStruct) #Init Loop li REG_LoopCount,0 ArmadaShineThink_RecoverStart_CollisionLoop: #Store current position stfs REG_CurrXPos,0x1C(REG_ECBStruct) stfs REG_CurrYPos,0x20(REG_ECBStruct) #Check if frame X or greater lwz r5, 0x02D4 (REG_P2Data) lfs f1,0x70(r5) fctiwz f1,f1 stfd f1,-0x10(sp) lwz r3,-0x0C(sp) cmpw REG_LoopCount,r3 blt ArmadaShineThink_RecoverStart_CollisionLoop_SkipDecay ArmadaShineThink_RecoverStart_CollisionLoop_Decay: lfs f1,0x78(r5) fmuls f1,f1,REG_XComp lfs f2, 0x002C (REG_P2Data) fmuls f1,f1,f2 fsubs REG_XPerFrame,REG_XPerFrame,f1 lfs f1,0x78(r5) fmuls f1,f1,REG_YComp fsubs REG_YPerFrame,REG_YPerFrame,f1 ArmadaShineThink_RecoverStart_CollisionLoop_SkipDecay: #Store next position fadds f1,REG_CurrXPos,REG_XPerFrame stfs f1,0x4(REG_ECBStruct) fadds f1,REG_CurrYPos,REG_YPerFrame stfs f1,0x8(REG_ECBStruct) lfs f1,0x24(REG_ECBStruct) stfs f1,0xC(REG_ECBStruct) mr r3,REG_ECBStruct mr r4,REG_ECBBoneStruct branchl r12,0x8004730c lfs REG_CurrXPos,0x4(REG_ECBStruct) lfs REG_CurrYPos,0x8(REG_ECBStruct) #Inc Loop addi REG_LoopCount,REG_LoopCount,1 lwz r5, 0x02D4 (REG_P2Data) lfs f1, 0x0068 (r5) fctiwz f1,f1 stfd f1,-0x10(sp) lwz r3,-0x0C(sp) cmpw REG_LoopCount,r3 blt ArmadaShineThink_RecoverStart_CollisionLoop #End Loop addi sp,sp,0x1d0 #endregion #Restore f28-f31 lfs f29,0xB0(sp) lfs f30,0xB4(sp) lfs f31,0xB8(sp) lfs f28,0xBC(sp) lfs f27,0xC0(sp) ArmadaShineThink_RecoverStart_Exit: b ArmadaShineThink_Exit #endregion #region ArmadaShineThink_RecoverEnd ArmadaShineThink_RecoverEnd: #If CPU got hit, recover again lbz r3,0x221C(REG_P2Data) rlwinm. r3,r3,0,30,30 beq ArmadaShineThink_Reset #Enter Hitstun state li r3,EventState_Hitstun stb r3,EventState(REG_EventData) b ArmadaShineThink_Exit #endregion #region ArmadaShineThink_Reset ArmadaShineThink_Reset: #Get timer lbz r3,Timer(REG_EventData) subi r3,r3,1 stb r3,Timer(REG_EventData) cmpwi r3,0 ble ArmadaShineThink_Restore b ArmadaShineThink_Exit #endregion ArmadaShineThink_Restore: #Restore State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Load #Init Positions Again mr r3,REG_P1GObj mr r4,REG_P2GObj bl ArmadaShine_InitializePositions #Reset Variables li r3,0 stb r3,EventState(REG_EventData) stb r3,Timer(REG_EventData) ArmadaShineThink_Exit: restore blr ArmadaShineThink_Constants: blrl .set ECB_TopY,0x0 #scale * value .set ECB_BottomY,0x4 #neg(scale * vlaue) .set ECB_LeftX,0x8 #neg(scale * vlaue) .set ECB_LeftY,0xC #0 .set ECB_RightX,0x10 #scale * value .set ECB_RightY,0x14 #0 .set FinalAnimYDifference,0x18 .float 9 .float 2.5 .float -3.3 .float 5.7 .float 3.3 .float 5.7 .float 0.4 ArmadaShine_InitializePositions: backup .set LedgeSide,20 #Constants .set ArmadaShine_P1X,15 .set ArmadaShine_P1Y,6 .set ArmadaShine_P2X,12 .set ArmadaShine_P2Y,6 .set HitlagFrames,12 #Get random side li r3,2 branchl r12,HSD_Randi #Backup Ledge Side mr LedgeSide,r3 #Change Facing Directions cmpwi LedgeSide,0x0 beq ArmadaShine_InitializePositions_GetLeftLedgeID ArmadaShine_InitializePositions_GetRightLedgeID: #Change Facing Direction li r3,-1 bl IntToFloat stfs f1,0x2C(REG_P1Data) li r3,-1 bl IntToFloat stfs f1,0x2C(REG_P2Data) b ArmadaShine_InitializePositions_DirectionChangeEnd ArmadaShine_InitializePositions_GetLeftLedgeID: #Change Facing Direction li r3,1 bl IntToFloat stfs f1,0x2C(REG_P1Data) li r3,1 bl IntToFloat stfs f1,0x2C(REG_P2Data) ArmadaShine_InitializePositions_DirectionChangeEnd: #Get Ledge Coordinates mr r3,LedgeSide addi r4,sp,0x80 bl GetLedgeCoordinates #Move P1 li r3,ArmadaShine_P1X bl IntToFloat lfs f2,0x80(sp) lfs f3,0x2C(REG_P1Data) fmadds f1,f1,f3,f2 stfs f1,0xB0(REG_P1Data) li r3,ArmadaShine_P1Y bl IntToFloat lfs f2,0x84(sp) fadds f1,f1,f2 stfs f1,0xB4(REG_P1Data) mr r3,REG_P1GObj bl UpdatePosition #Move P2 li r3,ArmadaShine_P2X bl IntToFloat lfs f2,0x80(sp) lfs f3,0x2C(REG_P2Data) fmadds f1,f1,f3,f2 stfs f1,0xB0(REG_P2Data) li r3,ArmadaShine_P2Y bl IntToFloat lfs f2,0x84(sp) fadds f1,f1,f2 stfs f1,0xB4(REG_P2Data) mr r3,REG_P2GObj bl UpdatePosition #P1 enters Bair mr r3,REG_P1GObj li r4,ASID_AttackAirB branchl r12,0x8008cfac #Fastforward to frame 7 li r3,7 bl IntToFloat mr r3,REG_P1GObj lfs f2, -0x67D8 (rtoc) lfs f3, -0x67E4 (rtoc) branchl r12,0x8006ebe8 li r3,7 bl IntToFloat stfs f1,0x894(REG_P1Data) li r3,0 stw r3,0x3E4(REG_P1Data) mr r3,REG_P1GObj branchl r12,0x80073354 #Update Animation mr r3,REG_P1GObj branchl r12,0x8006e9b4 #Remove all hitboxes mr r3,REG_P1GObj branchl r12,0x8007aff8 #Stop subaction script from being updated li r3,0 stw r3,0x3EC(REG_P1Data) #Update Camera mr r3,REG_P1GObj bl UpdateCameraBox #P2 enters DamageFlyN mr r3,REG_P2GObj li r4,ASID_DamageFlyN li r5,0x40 li r6,0 lfs f1, -0x750C (rtoc) lfs f2, -0x7508 (rtoc) lfs f3, -0x750C (rtoc) branchl r12,ActionStateChange #Update Animation mr r3,REG_P2GObj branchl r12,0x8006e9b4 #Remove Jump lwz r3,0x168(REG_P2Data) stb r3,0x1968(REG_P2Data) #Update Camera mr r3,REG_P2GObj bl UpdateCameraBox .set AngleLo,45 .set AngleHi,60 .set MagLo,106 .set MagHi,120 #Enter into knockback mr r3,REG_P2GObj li r4,AngleLo li r5,AngleHi li r6,MagLo li r7,MagHi bl EnterKnockback #Give 7 Frames of Hitlag to Each li r3,HitlagFrames bl IntToFloat stfs f1,0x195C(REG_P1Data) lbz r0,0x221A(REG_P1Data) li r3,1 rlwimi r0,r3,5,26,26 stb r0,0x221A(REG_P1Data) lbz r0,0x2219(REG_P1Data) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(REG_P1Data) li r3,HitlagFrames bl IntToFloat stfs f1,0x195C(REG_P2Data) lbz r0,0x221A(REG_P2Data) li r3,1 rlwimi r0,r3,5,26,26 stb r0,0x221A(REG_P2Data) lbz r0,0x2219(REG_P2Data) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(REG_P2Data) #Random percent li r3,PercentHi-PercentLo branchl r12,HSD_Randi addi r4,r3,PercentLo lbz r3,0xC(REG_P2Data) branchl r12,PlayerBlock_SetDamage ArmadaShine_InitializePositions_Exit: restore blr #endregion #region SideB Sweetspot ########################### ## SideB Sweetspot HIJACK INFO ## ########################### SideBSweetspot: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Marth.Ext li r6,-1 #Use chosen Stage load r7,EventOSD_SideBSweetspot li r8,0 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION SideBSweetspotStoreThink: bl SideBSweetspotLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## SideB Sweetspot LOAD FUNCT ## ################################## SideBSweetspotLoad: blrl backup #Schedule Think bl SideBSweetspotThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction b SideBSweetspotThink_Exit ################################### ## SideB Sweetspot THINK FUNCT ## ################################### SideBSweetspotThink: blrl #Registers .set REG_EventConstants,25 .set REG_MenuData,26 .set REG_EventData,31 .set REG_P1Data,27 .set REG_P1GObj,28 .set REG_P2Data,29 .set REG_P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_Endlag,0x0 .set EventState_WaitToAttack,0x1 .set EventState_AttackThink,0x2 .set EventState_Reset,0x3 .set Timer,0x1 .set ThrowTimer,0x2 .set JabFrame,0x4 #Constants .set ResetTimer,30 .set AngleLo,45 .set AngleHi,60 .set MagLo,106#106 .set MagHi,135#120 .set PercentHi,100 .set PercentLo,50 backup #INIT FUNCTION VARIABLES lwz REG_EventData,0x2c(r3) #backup data pointer in r31 #Get Player Pointers bl GetAllPlayerPointers mr REG_P1GObj,r3 mr REG_P1Data,r4 mr REG_P2GObj,r5 mr REG_P2Data,r6 #Get Menu and Constants Pointers lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData) bl SideBSweetspotThink_Constants mflr REG_EventConstants bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq SideBSweetspotThink_Start #Init Positions mr r3,REG_P1GObj mr r4,REG_P2GObj mr r5,REG_EventData bl SideBSweetspot_InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save SideBSweetspotThink_Start: #P2 intangible mr r3,P2GObj li r4,1 branchl r12,ApplyIntangibility #Reset if anyone died bl IsAnyoneDead cmpwi r3,0 bne SideBSweetspotThink_Restore SideBSweetspotThink_Crouch: #Always hold crouch when state is higher than EventState_Endlag lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Endlag ble SideBSweetspotThink_CrouchSkip #Input crouch li r3,-127 stb r3,CPU_AnalogY(REG_P2Data) SideBSweetspotThink_CrouchSkip: SideBSweetspotThink_SwitchCase: #Switch Case lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Endlag beq SideBSweetspotThink_Endlag cmpwi r3,EventState_WaitToAttack beq SideBSweetspotThink_WaitToAttack cmpwi r3,EventState_AttackThink beq SideBSweetspotThink_AttackThink cmpwi r3,EventState_Reset beq SideBSweetspotThink_Reset b SideBSweetspotThink_CheckTimer #region SideBSweetspotThink_Endlag SideBSweetspotThink_Endlag: #Check if in Wait lwz r3,0x10(P2Data) cmpwi r3,ASID_Wait bne SideBSweetspotThink_CheckTimer #Input Crouch li r3,-127 stb r3,CPU_AnalogY(REG_P2Data) #Change state to attack li r3,EventState_WaitToAttack stb r3,EventState(EventData) b SideBSweetspotThink_CheckTimer #endregion #region SideBSweetspotThink_WaitToAttack SideBSweetspotThink_WaitToAttack: #Wait for Fox to be in SpecialAirS lwz r3,0x10(REG_P1Data) cmpwi r3,0x15F bne SideBSweetspotThink_WaitToAttackSkip #Input Dtilt li r3,PAD_BUTTON_A stw r3,CPU_HeldButtons(REG_P2Data) li r3,-38 stb r3,CPU_AnalogY(REG_P2Data) #Advance State li r3,EventState_AttackThink stb r3,EventState(REG_EventData) b SideBSweetspotThink_CheckTimer SideBSweetspotThink_WaitToAttackSkip: #Check if fox up-b'd cmpwi r3,0x162 beq SideBSweetspotThink_WaitToAttack_BlacklistMove cmpwi r3,ASID_EscapeAir beq SideBSweetspotThink_WaitToAttack_BlacklistMove b SideBSweetspotThink_WaitToAttack_CheckForBlacklistMovesSkip SideBSweetspotThink_WaitToAttack_BlacklistMove: #PLay Error SFX li r3,0xAF bl PlaySFX #Start Timer li r3,ResetTimer stb r3,Timer(REG_EventData) #Advance State li r3,EventState_Reset stb r3,EventState(REG_EventData) b SideBSweetspotThink_CheckTimer SideBSweetspotThink_WaitToAttack_CheckForBlacklistMovesSkip: #endregion #region SideBSweetspotThink_AttackThink SideBSweetspotThink_AttackThink: #Check if d-tilting lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_AttackLw3 bne SideBSweetspotThink_CheckTimer #Check if frame 7 li r3,7 bl IntToFloat lfs f2,0x894(REG_P2Data) fcmpo cr0,f1,f2 bne SideBSweetspotThink_AttackThink_FreezeSkip #Check if already frozen li r3,0 bl IntToFloat lfs f2,0x89C(REG_P2Data) fcmpo cr0,f1,f2 beq SideBSweetspotThink_AttackThink_FreezeCheckToUnfreeze #Freeze mr r3,REG_P2GObj branchl r12,FrameSpeedChange b SideBSweetspotThink_AttackThink_FreezeSkip SideBSweetspotThink_AttackThink_FreezeCheckToUnfreeze: #Check if player was hit lwz r3,0x2094(REG_P2Data) cmpwi r3,0 beq SideBSweetspotThink_AttackThink_FreezeSkip #Unfreeze li r3,1 bl IntToFloat mr r3,REG_P2GObj branchl r12,FrameSpeedChange #Start Timer li r3,ResetTimer stb r3,Timer(REG_EventData) #Advance State li r3,EventState_Reset stb r3,EventState(REG_EventData) b SideBSweetspotThink_CheckTimer SideBSweetspotThink_AttackThink_FreezeSkip: #Check if P1 grabbed ledge successfully lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_CliffCatch bne SideBSweetspotThink_AttackThink_CliffCatchSkip #Play Success SFX li r3,0xAD bl PlaySFX #Unfreeze P2 li r3,1 bl IntToFloat mr r3,REG_P2GObj branchl r12,FrameSpeedChange #Start Timer li r3,ResetTimer+30 stb r3,Timer(REG_EventData) #Advance State li r3,EventState_Reset stb r3,EventState(REG_EventData) b SideBSweetspotThink_CheckTimer SideBSweetspotThink_AttackThink_CliffCatchSkip: #endregion #region SideBSweetspotThink_Reset SideBSweetspotThink_Reset: b SideBSweetspotThink_CheckTimer #endregion SideBSweetspotThink_CheckTimer: #Check if timer exists lbz r3,Timer(REG_EventData) cmpwi r3,0 ble SideBSweetspotThink_Exit #Decrement timer subi r3,r3,1 stb r3,Timer(REG_EventData) cmpwi r3,0 bgt SideBSweetspotThink_Exit SideBSweetspotThink_Restore: #Restore State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Load #Init Positions Again mr r3,REG_P1GObj mr r4,REG_P2GObj mr r5,REG_EventData bl SideBSweetspot_InitializePositions SideBSweetspotThink_Exit: restore blr ################################ SideBSweetspotThink_Constants: blrl .set P1X,0x0 .set P1Y,0x4 .set P2X,0x8 .set P2Y,0xC .set GrabDistance,0x10 .set HoldShieldVelocity,0x14 .set RunDistance,0x18 .float -8 #p1 x .float 0 #p1 y .float 8 #p2 x .float 0 #p2 y .float 14 #16 .float 1.1 .float 23 ########################################### SideBSweetspot_InitializePositions: backup .set REG_P1GObj,30 .set REG_P1Data,29 .set REG_P2GObj,28 .set REG_P2Data,27 .set REG_EventData,26 .set LedgeSide,20 #Constants .set SideBSweet_P1X,-12 .set SideBSweet_P1Y,6 .set SideBSweet_P2X,15 .set SideBSweet_P2Y,0 .set HitlagFrames,12 #Init Registers mr REG_P1GObj,r3 lwz REG_P1Data,0x2C(REG_P1GObj) mr REG_P2GObj,r4 lwz REG_P2Data,0x2C(REG_P2GObj) mr REG_EventData,r5 #Get random side li r3,2 branchl r12,HSD_Randi #Backup Ledge Side mr LedgeSide,r3 #Change Facing Directions cmpwi LedgeSide,0x0 beq SideBSweet_InitializePositions_GetLeftLedgeID SideBSweet_InitializePositions_GetRightLedgeID: #Change Facing Direction li r3,-1 bl IntToFloat stfs f1,0x2C(REG_P1Data) li r3,1 bl IntToFloat stfs f1,0x2C(REG_P2Data) b SideBSweet_InitializePositions_DirectionChangeEnd SideBSweet_InitializePositions_GetLeftLedgeID: #Change Facing Direction li r3,1 bl IntToFloat stfs f1,0x2C(REG_P1Data) li r3,-1 bl IntToFloat stfs f1,0x2C(REG_P2Data) SideBSweet_InitializePositions_DirectionChangeEnd: #Get Ledge Coordinates mr r3,LedgeSide addi r4,sp,0x80 bl GetLedgeCoordinates #Move P1 li r3,SideBSweet_P1X bl IntToFloat lfs f2,0x80(sp) lfs f3,0x2C(REG_P1Data) fmadds f1,f1,f3,f2 stfs f1,0xB0(REG_P1Data) li r3,SideBSweet_P1Y bl IntToFloat lfs f2,0x84(sp) fadds f1,f1,f2 stfs f1,0xB4(REG_P1Data) mr r3,REG_P1GObj bl UpdatePosition #Move P2 li r3,SideBSweet_P2X bl IntToFloat lfs f2,0x80(sp) lfs f3,0x2C(REG_P2Data) fneg f3,f3 fmadds f1,f1,f3,f2 stfs f1,0xB0(REG_P2Data) li r3,SideBSweet_P2Y bl IntToFloat lfs f2,0x84(sp) fadds f1,f1,f2 stfs f1,0xB4(REG_P2Data) mr r3,REG_P2GObj bl PlacePlayerOnGround #Clear P2's GFX Pointer li r3,0 stw r3,0x60C(REG_P2Data) #P2 enters FSmash li r3,0 bl IntToFloat mr r3,REG_P2GObj branchl r12,0x8008c3e0 #Fastforward to frame 11 li r3,11 bl IntToFloat mr r3,REG_P2GObj lfs f2, -0x67D8 (rtoc) lfs f3, -0x67E4 (rtoc) branchl r12,0x8006ebe8 li r3,7 bl IntToFloat stfs f1,0x894(REG_P2Data) li r3,0 stw r3,0x3E4(REG_P2Data) mr r3,REG_P2GObj branchl r12,0x80073354 #Update Animation mr r3,REG_P2GObj branchl r12,0x8006e9b4 #Remove all hitboxes mr r3,REG_P2GObj branchl r12,0x8007aff8 #Stop subaction script from being updated li r3,0 stw r3,0x3EC(REG_P2Data) #Update Camera mr r3,REG_P2GObj bl UpdateCameraBox #P1 enters DamageFlyN mr r3,REG_P1GObj li r4,ASID_DamageFlyN li r5,0x40 li r6,0 lfs f1, -0x750C (rtoc) lfs f2, -0x7508 (rtoc) lfs f3, -0x750C (rtoc) branchl r12,ActionStateChange #Update Animation mr r3,REG_P1GObj branchl r12,0x8006e9b4 #Remove Jump #lwz r3,0x168(REG_P1Data) #stb r3,0x1968(REG_P1Data) #Update Camera mr r3,REG_P1GObj bl UpdateCameraBox #Enter into knockback mr r3,REG_P1GObj li r4,AngleLo li r5,AngleHi li r6,MagLo li r7,MagHi bl EnterKnockback #Give 7 Frames of Hitlag to Each li r3,HitlagFrames bl IntToFloat stfs f1,0x195C(REG_P1Data) lbz r0,0x221A(REG_P1Data) li r3,1 rlwimi r0,r3,5,26,26 stb r0,0x221A(REG_P1Data) lbz r0,0x2219(REG_P1Data) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(REG_P1Data) li r3,HitlagFrames bl IntToFloat stfs f1,0x195C(REG_P2Data) lbz r0,0x221A(REG_P2Data) li r3,1 rlwimi r0,r3,5,26,26 stb r0,0x221A(REG_P2Data) lbz r0,0x2219(REG_P2Data) li r3,1 rlwimi r0,r3,2,29,29 stb r0,0x2219(REG_P2Data) #Random percent li r3,PercentHi-PercentLo branchl r12,HSD_Randi addi r4,r3,PercentLo lbz r3,0xC(REG_P1Data) branchl r12,PlayerBlock_SetDamage #Reset Variables li r3,EventState_ThrowDelay stb r3,EventState(REG_EventData) li r3,0 stb r3,Timer(REG_EventData) SideBSweetspot_InitializePositions_Exit: restore blr #endregion #region Escape Sheik ########################### ## Escape Sheik HIJACK INFO ## ########################### EscapeSheik: #Store Stage, CPU, and FDD Toggles lwz r3,0x0(r29) #Send event struct mr r4,r26 #Send match struct li r5,Sheik.Ext li r6,FinalDestination #Use chosen Stage load r7,EventOSD_EscapeSheik li r8,1 #Use Sopo bool bl InitializeMatch #STORE THINK FUNCTION EscapeSheikStoreThink: bl EscapeSheikLoad mflr r3 stw r3,0x44(r26) #on match load b exit ################################## ## Escape Sheik LOAD FUNCT ## ################################## EscapeSheikLoad: blrl backup #Schedule Think bl EscapeSheikThink mflr r3 li r4,3 #Priority (After EnvCOllision) li r5,0 bl CreateEventThinkFunction b EscapeSheikThink_Exit ################################### ## Escape Sheik THINK FUNCT ## ################################### EscapeSheikThink: blrl #Registers .set REG_EventConstants,25 .set REG_MenuData,26 .set REG_EventData,31 .set REG_P1Data,27 .set REG_P1GObj,28 .set REG_P2Data,29 .set REG_P2GObj,30 #Event Data Offsets .set EventState,0x0 .set EventState_ThrowDelay,0x0 .set EventState_ThrowEndlag,0x1 .set EventState_Chase,0x2 .set EventState_Jab2,0x3 .set EventState_Reset,0x4 .set Timer,0x1 .set ThrowTimer,0x2 .set JabFrame,0x4 .set isJabTwice,0x5 .set Jab2Frame,0x6 .set Jab2Timer,0x7 .set isDisplayedTiming,0x8 #Constants .set ResetTimer,40 .set PercentLo,0 .set PercentHi,40 .set ThrowTimerLo,30 .set ThrowTimerHi,60 .set ReactFrame,12 .set JabFrameLo,15 .set JabFrameHi,20 .set Jab2FrameLo,6 .set Jab2FrameHi,18 backup #INIT FUNCTION VARIABLES lwz REG_EventData,0x2c(r3) #backup data pointer in r31 #Get Player Pointers bl GetAllPlayerPointers mr REG_P1GObj,r3 mr REG_P1Data,r4 mr REG_P2GObj,r5 mr REG_P2Data,r6 #Get Menu and Constants Pointers lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData) bl EscapeSheikThink_Constants mflr REG_EventConstants bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME bl CheckIfFirstFrame cmpwi r3,0x0 beq EscapeSheikThink_Start #Init Positions mr r3,REG_P1GObj mr r4,REG_P2GObj mr r5,REG_EventData bl EscapeSheik_InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save EscapeSheikThink_Start: #Reset if anyone died bl IsAnyoneDead cmpwi r3,0 bne EscapeSheikThink_Restore EscapeSheikThink_CheckIfFailed: #Check if failed the Escape Sheik (grabbed)) #EventState > EventState_Hitstun lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Chase blt EscapeSheikThink_CheckIfFailed_End #Check if grabbed lwz r3,0x10(P1Data) cmpwi r3,ASID_CapturePulledHi blt EscapeSheikThink_CheckIfFailed_End cmpwi r3,ASID_CaptureFoot bgt EscapeSheikThink_CheckIfFailed_End #Check if timer has started lbz r3,Timer(REG_EventData) cmpwi r3,0 bgt EscapeSheikThink_CheckIfFailed_End #Start Timer li r3,ResetTimer stb r3,Timer(REG_EventData) EscapeSheikThink_CheckIfFailed_End: EscapeSheikThink_CheckIfCPUDamaged: lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_DamageHi1 blt EscapeSheikThink_CheckIfCPUDamaged_End cmpwi r3,ASID_DamageFlyRoll bgt EscapeSheikThink_CheckIfCPUDamaged_End #Check if timer has started lbz r3,Timer(REG_EventData) cmpwi r3,0 bgt EscapeSheikThink_CheckIfCPUDamaged_End #Start Timer li r3,ResetTimer stb r3,Timer(REG_EventData) #Play Success Sound? #Maybe increment a high score or something idk EscapeSheikThink_CheckIfCPUDamaged_End: EscapeSheikThink_CheckForMistimedShine: #Check if event state is in chase lbz r3,EventState(REG_EventData) cmpwi r3,EventState_Chase blt EscapeSheikThink_CheckForMistimedShine_End #Check if displayed already lbz r3,isDisplayedTiming(REG_EventData) cmpwi r3,0 bne EscapeSheikThink_CheckForMistimedShine_End #Get this frames inputs lbz r4, 0x0618 (REG_P1Data) bl GetInputStruct mr r5,r3 #Check B Button lwz r3,InputStruct_InstantButtons(r5) rlwinm. r0,r3,0,22,22 beq EscapeSheikThink_CheckForMistimedShine_End #Check if pushing down lbz r3,InputStruct_LeftAnalogY(r5) extsb r3,r3 cmpwi r3,-44 bgt EscapeSheikThink_CheckForMistimedShine_End #Check if in any missed tech state lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_Passive beq EscapeSheikThink_CheckForMistimedShine_Early cmpwi r3,ASID_PassiveStandB beq EscapeSheikThink_CheckForMistimedShine_Early cmpwi r3,ASID_PassiveStandF beq EscapeSheikThink_CheckForMistimedShine_Early #Check if being grabbed cmpwi r3,ASID_CapturePulledLw beq EscapeSheikThink_CheckForMistimedShine_Late cmpwi r3,ASID_CapturePulledHi beq EscapeSheikThink_CheckForMistimedShine_Late cmpwi r3,ASID_CaptureWaitLw beq EscapeSheikThink_CheckForMistimedShine_Late cmpwi r3,ASID_CaptureWaitHi beq EscapeSheikThink_CheckForMistimedShine_Late b EscapeSheikThink_CheckForMistimedShine_End .set REG_String,20 .set REG_Frames,21 EscapeSheikThink_CheckForMistimedShine_Early: #Get early string bl EscapeSheikThink_EarlyText mflr REG_String #Get frames early mr r3,REG_P1Data lwz r4,0x14(REG_P1Data) branchl r12,0x80085e50 lfs f1,0x8(r3) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) lhz r4,TM_FramesinCurrentAS(REG_P1Data) sub REG_Frames,r3,r4 b EscapeSheikThink_CheckForMistimedShine_Display EscapeSheikThink_CheckForMistimedShine_Late: #Get late string bl EscapeSheikThink_LateText mflr REG_String #Get frames late EscapeSheikThink_CheckForMistimedShine_LateSearchInitLoop: .set REG_Count,22 li REG_Count,0 lhz REG_Frames,TM_FramesinCurrentAS(REG_P1Data) EscapeSheikThink_CheckForMistimedShine_LateSearchLoop: #Get previous action state addi r3,REG_P1Data,TM_PrevASStart mulli r4,REG_Count,0x2 add r5,r3,r4 #Check if wait lhz r3,0x0(r5) cmpwi r3,ASID_Wait beq EscapeSheikThink_CheckForMistimedShine_LateSearchFoundWait #Add frames spent in this state lhz r3,0xC(r5) add REG_Frames,REG_Frames,r3 EscapeSheikThink_CheckForMistimedShine_LateSearchIncLoop: addi REG_Count,REG_Count,1 cmpwi REG_Count,6 blt EscapeSheikThink_CheckForMistimedShine_LateSearchLoop b EscapeSheikThink_CheckForMistimedShine_End EscapeSheikThink_CheckForMistimedShine_LateSearchFoundWait: EscapeSheikThink_CheckForMistimedShine_Display: #Output reaction time mr r3,REG_P1Data #p1 (no offsetting window) li r4,120 #text timeout li r5,0 #Area to Display (0-2) li r6,OSD.Miscellaneous #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr r22,r3 #backup text pointer #Create Text 1 mr r3,r22 #text pointer bl EscapeSheikThink_TopText mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,Text_InitializeSubtext #Create Text 2 mr r3,r22 #text pointer bl EscapeSheikThink_BottomText mflr r4 mr r5,REG_Frames mr r6,REG_String lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #default text X/Y branchl r12,Text_InitializeSubtext #Set as displayed li r3,1 stb r3,isDisplayedTiming(REG_EventData) EscapeSheikThink_CheckForMistimedShine_End: EscapeSheikThink_SwitchCase: #Switch Case lbz r3,EventState(REG_EventData) cmpwi r3,EventState_ThrowDelay beq EscapeSheikThink_ThrowDelay cmpwi r3,EventState_ThrowEndlag beq EscapeSheikThink_ThrowEndlag cmpwi r3,EventState_Chase beq EscapeSheikThink_Chase cmpwi r3,EventState_Reset beq EscapeSheikThink_Reset cmpwi r3,EventState_Jab2 beq EscapeSheikThink_Jab2 b EscapeSheikThink_CheckTimer #region EscapeSheikThink_ThrowDelay EscapeSheikThink_ThrowDelay: #Check to throw lhz r3,ThrowTimer(REG_EventData) subi r3,r3,1 sth r3,ThrowTimer(REG_EventData) cmpwi r3,0 bgt EscapeSheikThink_CheckTimer #Input DThrow li r3,-127 stb r3,CPU_AnalogY(REG_P2Data) #Change state to attack li r3,EventState_ThrowEndlag stb r3,EventState(EventData) b EscapeSheikThink_CheckTimer #endregion #region EscapeSheikThink_ThrowEndlag EscapeSheikThink_ThrowEndlag: #Wait for Sheik to be out of ThrowLw lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_Wait bne EscapeSheikThink_CheckTimer #Wait for P1 to be in their tech option lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_Passive blt EscapeSheikThink_ThrowEndlag_CheckMissTech cmpwi r3,ASID_PassiveStandB ble EscapeSheikThink_ThrowEndlag_End EscapeSheikThink_ThrowEndlag_CheckMissTech: cmpwi r3,ASID_DownBoundD beq EscapeSheikThink_ThrowEndlag_End cmpwi r3,ASID_DownBoundU beq EscapeSheikThink_ThrowEndlag_End b EscapeSheikThink_CheckTimer EscapeSheikThink_ThrowEndlag_End: #Advance State li r3,EventState_Chase stb r3,EventState(REG_EventData) b EscapeSheikThink_Chase #endregion #region EscapeSheikThink_Chase EscapeSheikThink_Chase: .set Distance,0xB0 .set REG_Direction,20 #Get Distance lfs f1,0xB0(REG_P2Data) lfs f2,0xB0(REG_P1Data) fsubs f1,f2,f1 lfs f2,0x2C(REG_P2Data) fmuls f1,f1,f2 stfs f1,Distance(sp) #Get Direction li r3,0 bl IntToFloat lfs f2,Distance(sp) fcmpo cr0,f2,f1 blt 0xC li REG_Direction,1 b 0x8 li REG_Direction,-1 #Determine Tech Option lwz r3,0x10(REG_P1Data) cmpwi r3,ASID_DownBoundD beq EscapeSheikThink_Chase_DownBoundThink cmpwi r3,ASID_DownBoundU beq EscapeSheikThink_Chase_DownBoundThink #Now only run these when over frame 12 lhz r4,TM_FramesinCurrentAS(REG_P1Data) cmpwi r4,ReactFrame blt EscapeSheikThink_CheckTimer cmpwi r3,ASID_Passive beq EscapeSheikThink_Chase_PassiveThink cmpwi r3,ASID_PassiveStandB beq EscapeSheikThink_Chase_PassiveStandThink cmpwi r3,ASID_PassiveStandF beq EscapeSheikThink_Chase_PassiveStandThink b EscapeSheikThink_CheckTimer EscapeSheikThink_Chase_PassiveThink: #Check if facing P1 cmpwi REG_Direction,0 bgt EscapeSheikThink_Chase_PassiveThink_FacingSkip #Input slightly towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,100 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_PassiveThink_FacingSkip: #Check distance (if over 16 units, walk towards) lfs f1,GrabDistance(REG_EventConstants) lfs f2,Distance(sp) fabs f2,f2 fcmpo cr0,f2,f1 ble EscapeSheikThink_Chase_PassiveThink_RunTowardsSkip #If over 24 units, run towards lfs f1,RunDistance(REG_EventConstants) fcmpo cr0,f2,f1 bgt EscapeSheikThink_Chase_PassiveThink_RunTowards EscapeSheikThink_Chase_PassiveThink_WalkTowards: #Walk Towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,100 stb r3,CPU_AnalogX(REG_P2Data) b EscapeSheikThink_Chase_PassiveThink_RunTowardsSkip EscapeSheikThink_Chase_PassiveThink_RunTowards: #Run Towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,127 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_PassiveThink_RunTowardsSkip: #Check distance lfs f1,GrabDistance(REG_EventConstants) lfs f2,Distance(sp) fabs f2,f2 fcmpo cr0,f2,f1 bgt EscapeSheikThink_Chase_PassiveThink_HoldShieldSkip #Check State lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_Dash beq EscapeSheikThink_Chase_PassiveThink_HoldShield cmpwi r3,ASID_Run beq EscapeSheikThink_Chase_PassiveThink_HoldShield b EscapeSheikThink_Chase_PassiveThink_HoldShieldSkip EscapeSheikThink_Chase_PassiveThink_HoldShield: #Enter shield mr r3,REG_P2GObj branchl r12,AS_Guard #And hold li r3,PAD_TRIGGER_R stw r3,CPU_HeldButtons(REG_P2Data) b EscapeSheikThink_Chase_PassiveThink_HoldShieldSkip EscapeSheikThink_Chase_PassiveThink_HoldShieldSkip: #Now grab when P1 is on frame 20 lhz r3,TM_FramesinCurrentAS(REG_P1Data) cmpwi r3,20 blt EscapeSheikThink_CheckTimer #Enter grab mr r3,REG_P2GObj li r4,0xD4 branchl r12,AS_Catch #Advance state li r3,EventState_Reset stb r3,EventState(REG_EventData) #Start timer li r3,ResetTimer stb r3,Timer(REG_EventData) b EscapeSheikThink_CheckTimer EscapeSheikThink_Chase_PassiveStandThink: #Check if facing P1 cmpwi REG_Direction,0 bgt EscapeSheikThink_Chase_PassiveStandThink_FacingSkip #BUT is he coming to me? lfs f2,0xC8(REG_P1Data) li r3,0 bl IntToFloat li r3,1 #Moving Right fcmpo cr0,f2,f1 bgt 0x8 li r3,-1 #Moving Left lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r4,0x84(sp) mullw r4,r4,REG_Direction cmpw r3,r4 bne EscapeSheikThink_Chase_PassiveStandThink_FacingSkip #If under frame 20, run instead li r5,127 lhz r3,TM_FramesinCurrentAS(REG_P1Data) cmpwi r3,20 blt 0x8 li r5,100 #Input slightly towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mullw r3,r3,r5 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_PassiveStandThink_FacingSkip: #Check distance (if over 16 units, run towards) lfs f1,GrabDistance(REG_EventConstants) lfs f2,Distance(sp) fabs f2,f2 fcmpo cr0,f2,f1 ble EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip #Wait until no longer turning lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_Turn bne EscapeSheikThink_Chase_PassiveStandThink_RunTowardCheckMovementDirection #If turning, wait til frame 2 to make a decision lhz r3,TM_FramesinCurrentAS(REG_P2Data) cmpwi r3,2 bge EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip EscapeSheikThink_Chase_PassiveStandThink_RunTowardCheckMovementDirection: #BUT is he coming to me? lfs f2,0xC8(REG_P1Data) li r3,0 bl IntToFloat li r3,1 #Moving Right fcmpo cr0,f2,f1 bgt 0x8 li r3,-1 #Moving Left lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r4,0x84(sp) mullw r4,r4,REG_Direction cmpw r3,r4 bne EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip EscapeSheikThink_Chase_PassiveStandThink_RunTowards: #Run Towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,127 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip: #If and within range and running, hold shield #Check distance lfs f1,GrabDistance(REG_EventConstants) lfs f2,Distance(sp) fabs f2,f2 fcmpo cr0,f2,f1 bgt EscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip lwz r3,0x10(REG_P2Data) cmpwi r3,ASID_Dash beq EscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckFrame cmpwi r3,ASID_Run beq EscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckFrame b EscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip EscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckFrame: lhz r3,TM_FramesinCurrentAS(REG_P1Data) cmpwi r3,28 bge EscapeSheikThink_Chase_PassiveStandThink_HoldShield EscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckVelocity: #Allow to hold shield earlier than usual if the character isnt moving very far lfs f1,0xC8(REG_P1Data) fabs f1,f1, lfs f2,HoldShieldVelocity(REG_EventConstants) fcmpo cr0,f1,f2 bgt EscapeSheikThink_Chase_PassiveStandThink_HoldShieldRunInstead EscapeSheikThink_Chase_PassiveStandThink_HoldShield: #Enter shield mr r3,REG_P2GObj branchl r12,AS_Guard #And hold li r3,PAD_TRIGGER_R stw r3,CPU_HeldButtons(REG_P2Data) b EscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip EscapeSheikThink_Chase_PassiveStandThink_HoldShieldRunInstead: #Run Towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,127 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip: #Now grab when P1 is on frame 34 lhz r3,TM_FramesinCurrentAS(REG_P1Data) cmpwi r3,34 blt EscapeSheikThink_CheckTimer #Enter grab mr r3,REG_P2GObj li r4,0xD4 branchl r12,AS_Catch #Advance state li r3,EventState_Reset stb r3,EventState(REG_EventData) #Start timer li r3,ResetTimer stb r3,Timer(REG_EventData) b EscapeSheikThink_CheckTimer EscapeSheikThink_Chase_DownBoundThink: #Determine jab frame lbz r3,JabFrame(REG_EventData) cmpwi r3,0 bne EscapeSheikThink_Chase_DownBoundThink_JabFrameInitSkip #Init Jab Frame li r3,JabFrameHi-JabFrameLo branchl r12,HSD_Randi addi r3,r3,JabFrameLo stb r3,JabFrame(REG_EventData) #Get chance to jab again li r3,2 branchl r12,HSD_Randi stb r3,isJabTwice(REG_EventData) #Get frame to jab again li r3,Jab2FrameHi-Jab2FrameLo branchl r12,HSD_Randi addi r3,r3,Jab2FrameLo stb r3,Jab2Frame(REG_EventData) #Init Jab 2 Timer li r3,0 stb r3,Jab2Timer(REG_EventData) EscapeSheikThink_Chase_DownBoundThink_JabFrameInitSkip: #Check if facing P1 cmpwi REG_Direction,0 bgt EscapeSheikThink_Chase_DownBoundThink_FacingSkip #Input slightly towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,100 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_DownBoundThink_FacingSkip: #Check distance (if over 16 units, walk towards) lfs f1,GrabDistance(REG_EventConstants) lfs f2,Distance(sp) fabs f2,f2 fcmpo cr0,f2,f1 ble EscapeSheikThink_Chase_DownBoundThink_RunTowardsSkip EscapeSheikThink_Chase_DownBoundThink_WalkTowards: #Walk Towards lfs f1,0x2C(REG_P2Data) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) mullw r3,r3,REG_Direction mulli r3,r3,100 stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_DownBoundThink_RunTowardsSkip: #Check distance lfs f1,GrabDistance(REG_EventConstants) lfs f2,Distance(sp) fabs f2,f2 fcmpo cr0,f2,f1 bgt EscapeSheikThink_Chase_DownBoundThink_HaltSkip #Ensure Facing cmpwi REG_Direction,1 bne EscapeSheikThink_Chase_DownBoundThink_HaltSkip EscapeSheikThink_Chase_DownBoundThink_Halt: #Stop Moving li r3,0 stw r3,CPU_HeldButtons(REG_P2Data) stb r3,CPU_AnalogX(REG_P2Data) EscapeSheikThink_Chase_DownBoundThink_HaltSkip: #Now jab when P1 is on the jab frame lhz r3,TM_FramesinCurrentAS(REG_P1Data) lbz r4,JabFrame(REG_EventData) cmpw r3,r4 blt EscapeSheikThink_CheckTimer #Enter jab li r3,PAD_BUTTON_A stw r3,CPU_HeldButtons(REG_P2Data) li r3,0 stb r3,CPU_AnalogX(REG_P2Data) #Check if sheik will double jab lbz r3,isJabTwice(REG_EventData) cmpwi r3,0 beq EscapeSheikThink_Chase_DownBoundThink_SingleJab #Start Double Jab timer lbz r3,Jab2Frame(REG_EventData) stb r3,Jab2Timer(REG_EventData) #Change Event State li r3,EventState_Jab2 stb r3,EventState(REG_EventData) b EscapeSheikThink_CheckTimer EscapeSheikThink_Chase_DownBoundThink_SingleJab: #Advance state li r3,EventState_Reset stb r3,EventState(REG_EventData) #Start timer li r3,ResetTimer+30 stb r3,Timer(REG_EventData) b EscapeSheikThink_CheckTimer #endregion #region EscapeSheikThink_Jab2 EscapeSheikThink_Jab2: #Check if waiting on jab 2 lbz r3,Jab2Timer(REG_EventData) cmpwi r3,0 beq EscapeSheikThink_Chase_DownBoundThink_Jab2Skip #But not during hitlag lbz r3,0x221A(REG_P2Data) rlwinm. r3,r3,0,26,26 bne EscapeSheikThink_Chase_DownBoundThink_Jab2Skip #Decrement timer lbz r3,Jab2Timer(REG_EventData) subi r3,r3,1 stb r3,Jab2Timer(REG_EventData) #Check if up cmpwi r3,0 bgt EscapeSheikThink_CheckTimer #Enter jab li r3,PAD_BUTTON_A stw r3,CPU_HeldButtons(REG_P2Data) li r3,0 stb r3,CPU_AnalogX(REG_P2Data) #Advance state li r3,EventState_Reset stb r3,EventState(REG_EventData) #Start timer li r3,ResetTimer+30 stb r3,Timer(REG_EventData) b EscapeSheikThink_CheckTimer EscapeSheikThink_Chase_DownBoundThink_Jab2Skip: b EscapeSheikThink_CheckTimer #endregion #region EscapeSheikThink_Reset EscapeSheikThink_Reset: #Hold Shield li r3,PAD_TRIGGER_R stw r3,CPU_HeldButtons(REG_P2Data) b EscapeSheikThink_CheckTimer #endregion EscapeSheikThink_CheckTimer: #Check if timer exists lbz r3,Timer(REG_EventData) cmpwi r3,0 ble EscapeSheikThink_Exit #Decrement timer subi r3,r3,1 stb r3,Timer(REG_EventData) cmpwi r3,0 bgt EscapeSheikThink_Exit EscapeSheikThink_Restore: #Restore State addi r3,REG_EventData,EventData_SaveStateStruct li r4,1 bl SaveState_Load #Init Positions Again mr r3,REG_P1GObj mr r4,REG_P2GObj mr r5,REG_EventData bl EscapeSheik_InitializePositions EscapeSheikThink_Exit: restore blr ################################ EscapeSheikThink_Constants: blrl .set P1X,0x0 .set P1Y,0x4 .set P2X,0x8 .set P2Y,0xC .set GrabDistance,0x10 .set HoldShieldVelocity,0x14 .set RunDistance,0x18 .float -8 #p1 x .float 0 #p1 y .float 8 #p2 x .float 0 #p2 y .float 14 #16 .float 1.1 .float 23 ########################################### EscapeSheikThink_TopText: blrl .string "Down B Input" .align 2 EscapeSheikThink_BottomText: blrl .string "%df %s" .align 2 EscapeSheikThink_EarlyText: blrl .string "Early" .align 2 EscapeSheikThink_LateText: blrl .string "Late" .align 2 ########################################### EscapeSheik_InitializePositions: backup .set REG_FacingDirection,31 #1 = p1 facing right, -1 = p1 facing left .set REG_P1GObj,30 .set REG_P1Data,29 .set REG_P2GObj,28 .set REG_P2Data,27 .set REG_EventData,26 #Init Registers mr REG_P1GObj,r3 lwz REG_P1Data,0x2C(REG_P1GObj) mr REG_P2GObj,r4 lwz REG_P2Data,0x2C(REG_P2GObj) mr REG_EventData,r5 EscapeSheik_InitializePositions_DetermineFacingDirection: #Determine Facing Direction li REG_FacingDirection,1 li r3,2 branchl r12,HSD_Randi cmpwi r3,0 beq EscapeSheik_InitializePositions_DetermineFacingDirection_End li REG_FacingDirection,-1 EscapeSheik_InitializePositions_DetermineFacingDirection_End: #Apply Facing Directions mr r3,REG_FacingDirection bl IntToFloat stfs f1,0x2C(REG_P1Data) mulli r3,REG_FacingDirection,-1 bl IntToFloat stfs f1,0x2C(REG_P2Data) #Get Starting Coordinates lfs f1,P1X(REG_EventConstants) lfs f2,P1Y(REG_EventConstants) cmpwi REG_FacingDirection,0 blt EscapeSheik_InitializePositions_P1FacingLeft stfs f1,0xB0(REG_P1Data) stfs f2,0xB4(REG_P1Data) b EscapeSheik_InitializePositions_RightPosition EscapeSheik_InitializePositions_P1FacingLeft: stfs f1,0xB0(REG_P2Data) stfs f2,0xB4(REG_P2Data) EscapeSheik_InitializePositions_RightPosition: lfs f1,P1X(REG_EventConstants) lfs f2,P1Y(REG_EventConstants) cmpwi REG_FacingDirection,0 blt EscapeSheik_InitializePositions_P2FacingRight stfs f1,0xB0(REG_P2Data) stfs f2,0xB4(REG_P2Data) EscapeSheik_InitializePositions_P2FacingRight: stfs f1,0xB0(REG_P1Data) stfs f2,0xB4(REG_P1Data) #Update Positions mr r3,REG_P1GObj bl PlacePlayerOnGround mr r3,REG_P1GObj bl UpdateCameraBox mr r3,REG_P2GObj bl PlacePlayerOnGround mr r3,REG_P2GObj bl UpdateCameraBox #Store P1 into P2 Grab Pointer stw REG_P1GObj,0x1A58(REG_P2Data) stw REG_P1GObj,0x1A5C(REG_P2Data) #Clear P1's Grabbed Player Pointer li r3,0 stw r3,0x1A58(REG_P1Data) stw r3,0x1A5C(REG_P1Data) #Clear P2's GFX Pointer stw r3,0x60C(REG_P2Data) #Enter P2 Into Grab mr r3,REG_P2GObj #P2 Enters Grab branchl r12,AS_GrabOpponent #Enter P1 Into Grabbed mr r3,REG_P1GObj #P1 Grabbed mr r4,REG_P2GObj #P2 = Grabber branchl r12,AS_Grabbed #Enter P2 Into GrabWait mr r3,REG_P2GObj #P2 Enters GrabWait branchl r12,AS_CatchWait #Give a bunch of grabstun li r3,999 bl IntToFloat stfs f1,0x1A4C(REG_P1Data) #Random percent li r3,PercentHi-PercentLo branchl r12,HSD_Randi addi r4,r3,PercentLo lbz r3,0xC(REG_P1Data) branchl r12,PlayerBlock_SetDamage #Reset Variables li r3,EventState_ThrowDelay stb r3,EventState(REG_EventData) li r3,0 stb r3,Timer(REG_EventData) stb r3,JabFrame(REG_EventData) #Init Throw Timer li r3,ThrowTimerHi-ThrowTimerLo branchl r12,HSD_Randi addi r3,r3,ThrowTimerLo sth r3,ThrowTimer(REG_EventData) #Init isDisplayedTiming li r3,0 stb r3,isDisplayedTiming(REG_EventData) EscapeSheik_InitializePositions_Exit: restore blr #endregion #region Scrapped Edgeguard Event /* ######################### ## Event 16 HIJACK INFO ## ######################### Event16: #STORE STAGE li r3,0x20 sth r3,0xE(r26) li r5,0x2 #Ice Climbers li r5,0x14 #STORE CPU lwz r4,0x0(r29) bl P2Struct mflr r3 stw r3,0x18(r4) #p2 pointer stb r5,0x0(r3) #make top tier p2 li r5,0x1 #make CPU controlled stb r5,0x1(r3) #SPAWN 2 PLAYERS li r3,0x40 stb r3,0x1(r4) #STORE THINK FUNCTION bl Event16Load mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Event 16 LOAD FUNCT ## ######################## Event16Load: blrl backup #Schedule Think bl Event16Think mflr r3 li r4,3 #Priority (After Interrupt) bl CreateEventThinkFunction b Event16LoadExit ######################### ## Event 16 THINK FUNCT ## ######################### Event16Think: blrl backup #INIT FUNCTION VARIABLES lwz r31,0x2c(r3) #backup data pointer in r31 #Get P2 li r3,0x1 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block mr r30,r3 #player block in r30 lwz r29,0x2c(r30) #player data in r29 #Get P1 li r3,0x0 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block mr r28,r3 #player block in r28 lwz r27,0x2c(r28) #player data in r27 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME lbz r3,0x0(r31) cmpwi r3,0x0 bne Event16ThinkMain lbz r3,0x221D(r29) rlwinm. r3,r3,0,28,28 bne Event16ThinkExit #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) #Initlize Positions bl Event16_Floats mflr r3 #bl InitializePositions #Clear Inputs bl RemoveFirstFrameInputs #Save State mr r3,r31 bl SaveState_Save #Set Timer to -60 li r3,-60 stw r3,0x4(r31) Event16ThinkMain: Event16ThinkSequence: #Inc Timer lwz r3,0x4(r31) addi r3,r3,0x1 stw r3,0x4(r31) #Get Floats bl Event16_Floats mflr r21 #L+DPad Controls CPU Percent bl DPadCPUPercent #Check If Already in A Recovery Mode lbz r3,0x8(r31) cmpwi r3,0x1 beq Event16CheckRecoveryFlag #Check If CPU Is Offstage mr r3,r29 branchl r12,0x800a2c80 cmpwi r3,0x0 beq Event16CheckRecoveryFlag #Check If Still in Hitstun lbz r3,0x221C(r29) rlwinm. r3,r3,0,30,30 bne Event16CheckRecoveryFlag #Check If Below Ledge #Hold Towards Ledge #Get Random Recovery Option Event16GetRandomRecovery: li r3,3 #Number of Recovery Options (Side B Immediately,Jump Then Side B, ShineStall-Jump-SideB) branchl r12,HSD_Randi cmpwi r3,0x0 bne Event16StoreRecoveryType #Check If Can Side B Only #Check If Above Ledge lfs f1,0xB4(r29) #Get Y Coord #lfs f2,0x10(r21) #fcmpo cr0,f1,f2 #bgt Event16GetRandomRecovery #lfs f2,0x10(r21) #Check If Below Ledge lfs f2,0x14(r21) fcmpo cr0,f1,f2 blt Event16GetRandomRecovery Event16StoreRecoveryType: stb r3,0x9(r31) #Init Recovery Flag li r3,0x1 stb r3,0x8(r31) Event16CheckRecoveryFlag: #Check Recovery Flag lbz r3,0x8(r31) cmpwi r3,0x0 beq Event16CheckToReset #******************************************************************# #IsRecovering #If Timer Is Set, Dont Run Any of This lwz r3,0xC(r31) #get timer #Get Timer cmpwi r3,0x0 #No Reset Timer Set Yet bgt Event16GetRecoveryID #Hold Towards Stage li r3,127 lfs f0,0x00B0 (r29) #X Pos lfs f1,0x1ADC (r29) #Last Grounded X Pos fcmpo cr0,f1,f0 bgt Event16HoldTowardsRight neg r3,r3 Event16HoldTowardsRight: stb r3,0x1A8C(r29) #Check If Died lbz r3,0x221F(r29) rlwinm. r3,r3,0,25,25 bne Event16SideBThink_Reset #Check If In Hitlag #Recover again lbz r3,0x221A(r29) rlwinm. r3,r3,0,26,26 bne Event16RecoverAgain #Check If Made It Back #Check Ground Flag lwz r3,0xE0(r29) cmpwi r3,0x0 beq Event16SideBThink_Reset #Check CliffCatch lwz r3,0x10(r29) cmpwi r3,0xFC beq Event16SideBThink_Reset b Event16GetRecoveryID Event16RecoverAgain: #Recover Again li r3,0x0 stb r3,0x8(r31) stb r3,0x9(r31) b Event16CheckToReset Event16SideBThink_Reset: #Set Timer lwz r3,0xC(r31) #get timer #Get Timer cmpwi r3,0x0 #No Reset Timer Set Yet bgt Event16CheckToReset #Reset Timer Set li r3,30 stw r3,0xC(r31) #Store Reset Timer b Event16CheckToReset #Run Recovery Think #Get Which Recovery To Perform Event16GetRecoveryID: lbz r3,0x9(r31) cmpwi r3,0x0 beq Event16SideBOnly cmpwi r3,0x1 beq Event16JumpSideB cmpwi r3,0x2 beq Event16SSJumpSideB cmpwi r3,0x3 beq Event16SideBThink #*************************************************# Event16SideBOnly: #Be in ledge Y range, Check if next frame will be out of Y range bl Event16CheckIfLineUpWithLedge cmpwi r3,-1 #Not In Range Yet beq Event16CheckToReset cmpwi r3,0x0 beq Event16ChanceToInputSideB #If OoRange Next Frame + Descending, Side B Immediately lfs f0, -0x7208 (rtoc) lfs f1,0xCC(r29) fcmpo cr0,f1,f0 blt Event16InputSideB Event16ChanceToInputSideB: li r3,5 branchl r12,HSD_Randi cmpwi r3,0x0 beq Event16InputSideB b Event16CheckToReset Event16InputSideB: #Joystick X = 120 * Facing Direction lfs f1,0x2C(r29) fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) li r3,120 #X Stick mullw r3,r3,r4 stb r3,0x1A8C(r29) li r3,0x200 stw r3,0x1A88(r29) #li r3,0x0 #stb r3,0x8(r31) #Change State to Mid-Side B li r3,3 stb r3,0x9(r31) b Event16CheckToReset #*************************************************# Event16JumpSideB: #Be above bottom most coord, Check if next frame will be out of Y range #Be in ledge Y range, Check if next frame will be out of Y range #Check If Above Bottom-most lfs f1,0xB4(r29) #Get Next Frames Y Coord lfs f2,0x84(r29) fadds f1,f1,f2 lfs f2,0x18(r21) #Get Bottom Y Coord fcmpo cr0,f1,f2 blt Event16JumpSideB_Jump Event16JumpSideB_ChanceToJump: li r3,20 #1 in 4 Chance branchl r12,HSD_Randi cmpwi r3,0x0 beq Event16JumpSideB_Jump b Event16CheckToReset Event16JumpSideB_Jump: li r3,0x800 stw r3,0x1A88(r29) #Advance to Next State li r3,0x0 stb r3,0x9(r31) b Event16CheckToReset #*************************************************# Event16SSJumpSideB: #Hold Down B #Be above bottom most coord, Check if next frame will be out of Y range #Be in ledge Y range, Check if next frame will be out of Y range #Always Hold Down B li r3,-127 stb r3,0x1A8D(r29) li r3,0x200 stw r3,0x1A88(r29) #Wait Until in Shine Loop lwz r3,0x10(r29) cmpwi r3,0x16E bne Event16CheckToReset #Check If Above Bottom-most lfs f1,0xB4(r29) #Get Next Frames Y Coord lfs f2,0x84(r29) fadds f1,f1,f2 lfs f2,0x18(r21) #Get Bottom Y Coord fcmpo cr0,f1,f2 blt Event16SSJumpSideB_Jump Event16SSJumpSideB_ChanceToJump: li r3,15 #1 in 6 Chance branchl r12,HSD_Randi cmpwi r3,0x0 beq Event16SSJumpSideB_Jump b Event16CheckToReset Event16SSJumpSideB_Jump: li r3,0x800 stw r3,0x1A88(r29) #Advance to Next State li r3,0x0 stb r3,0x9(r31) b Event16CheckToReset #*************************************************# Event16SideBThink: b Event16CheckToReset #*************************************************# #Check To Reset Event16CheckToReset: lwz r3,0xC(r31) #Get Timer cmpwi r3,0x0 #No Reset Timer Set Yet ble Event16ThinkExit #Dec Timer subi r3,r3,0x1 stw r3,0xC(r31) #store timer cmpwi r3,0x0 #Check if 0 now bne Event16ThinkExit #Exit If Not Event16RestoreState: #Restore State mr r3,r31 bl SaveState_Load #Reset Timer li r3,60 branchl r12,HSD_Randi li r4,0 sub r3,r4,r3 stw r3,0x4(r31) li r3,0x0 stb r3,0x8(r31) Event16ThinkExit: restore blr ################################# Event16_Floats: blrl .long 0xC28C0000 #P1 X Position .long 0xc2982e6c #P2 X Position .long 0x38d1b717 #P1 Y Position .long 0x38d1b717 #FD Floor Y Coord .long 0x40A00000 #Top Most Y Value = -5 .long 0xC1700000 #Bottom-most Y Value = -15 .long 0xC25C0000 #Shine Stall Bottom Most Coord ################################# Event16CheckIfLineUpWithLedge: #-1 = Not In Any Range Yet #0 = In Range This And Next Frame #1 = In Range This but NOT Next Frame #Check If In Range This Frame lfs f1,0xB4(r29) #Get Y Coord lfs f2,0x10(r21) fcmpo cr0,f1,f2 bgt Event16CheckIfLineUpWithLedge_NotInRange lfs f2,0x14(r21) fcmpo cr0,f1,f2 blt Event16CheckIfLineUpWithLedge_NotInRange Event16CheckIfLineUpWithLedge_CheckNextFrame: #Check If Out Of Range Next Range lfs f1,0xB4(r29) #Get Y Coord lfs f2,0x84(r29) #Get Y Vel fadds f1,f1,f2 #Get Next Frames Position #Check If Will Be Above Ledge Next Frame lfs f2,0x10(r21) fcmpo cr0,f1,f2 bgt Event16CheckIfLineUpWithLedge_OutOfRangeNextFrame lfs f2,0x10(r21) #Check If Will Be Below Ledge Next Frame lfs f2,0x14(r21) fcmpo cr0,f1,f2 blt Event16CheckIfLineUpWithLedge_OutOfRangeNextFrame b Event16CheckIfLineUpWithLedge_InRangeThisAndNextFrame Event16CheckIfLineUpWithLedge_NotInRange: li r3,-1 b Event16CheckIfLineUpWithLedge_Exit Event16CheckIfLineUpWithLedge_InRangeThisAndNextFrame: li r3,0x0 b Event16CheckIfLineUpWithLedge_Exit Event16CheckIfLineUpWithLedge_OutOfRangeNextFrame: li r3,0x1 Event16CheckIfLineUpWithLedge_Exit: blr ################################# Event16LoadExit: restore blr */ #endregion #region Scrapped Dash Dance Code /* ######################### ## Shield Drop HIJACK INFO ## ######################### ShieldDrop: #STORE STAGE li r3,0x20 sth r3,0xE(r26) #STORE CPU lwz r4,0x0(r29) bl P2Struct mflr r3 stw r3,0x18(r4) #p2 pointer li r5,0x2 #fox ext ID stb r5,0x0(r3) #make fox p2 li r5,0x1 #make CPU controlled stb r5,0x1(r3) #SPAWN 2 PLAYERS li r3,0x40 stb r3,0x1(r4) #STORE THINK FUNCTION bl ShieldDropLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Shield Drop LOAD FUNCT ## ######################## ShieldDropLoad: blrl backup #Schedule Think bl ShieldDropThink mflr r3 li r4,3 #Priority (After Interrupt) bl CreateEventThinkFunction b ShieldDropLoadExit ######################### ## Shield Drop THINK FUNCT ## ######################### ShieldDropThink: blrl backup #INIT FUNCTION VARIABLES lwz r31,0x2c(r3) #backup data pointer in r31 #Get P2 li r3,0x1 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block mr r30,r3 #player block in r30 lwz r29,0x2c(r30) #player data in r29 #Get P1 li r3,0x0 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block mr r28,r3 #player block in r28 lwz r27,0x2c(r28) #player data in r27 bl StoreCPUTypeAndZeroInputs #ON FIRST FRAME lbz r3,0x0(r31) cmpwi r3,0x0 bne ShieldDropThinkMain lbz r3,0x221D(r29) rlwinm. r3,r3,0,28,28 bne ShieldDropThinkExit #Set Frame 1 As Over li r3,0x1 stb r3,0x0(r31) bl ShieldDrop_InitializePositions mr r3,r31 bl SaveState_Save ShieldDropThinkMain: bl GiveFullShields ShieldDropThinkSequence: #Get Floats and Frame Info bl ShieldDropFloats mflr r21 #Get Floats lwz r20,0x4(r31) #Get State lfs f1,0x894(r29) fctiwz f1,f1 stfd f1,0xF0(sp) lwz r24,0xF4(sp) #Frame Number in r24 #Get Distance and Direction #f1 = distance #r22= towards direction #r23= away direction lfs f1,0xB0(r27) lfs f2,0xB0(r29) fsubs f1,f1,f2 lfs f0, -0x6768 (rtoc) fcmpo cr0,f1,f0 bgt ShieldDropRight ShieldDropLeft: li r22,-127 li r23,127 b ShieldDropCheckState ShieldDropRight: li r22,127 li r23,-127 ShieldDropCheckState: #When DDing, Move In Facing Direction cmpwi r20,0x1 bne ShieldDrop_SkipHoldForward lfs f2,0x2C(r29) fctiwz f2,f2 stfd f2,0xF0(sp) lwz r3,0xF4(sp) #Facing direction as int mulli r3,r3,127 stb r3,0x1A8C(r29) #Move Towards ShieldDrop_SkipHoldForward: fabs f1,f1 #abs distance cmpwi r20,0x0 beq ShieldDropDashDanceStart cmpwi r20,0x1 beq ShieldDropDashDanceThink cmpwi r20,0x2 beq ShieldDropJumpThink cmpwi r20,0x3 beq ShieldDropLCancelThink cmpwi r20,0x4 beq ShieldDropInvincibleThink ShieldDropDashDanceStart: stb r23,0x1A8C(r29) #Move Away li r3,0x1 #Enter DDThink stw r3,0x4(r31) b ShieldDropThinkExit ShieldDropDashDanceThink: #Check If Too Close ShieldDropDashDanceThink_CheckIfTooClose: lfs f2,0x0(r21) fcmpo cr0,f1,f2 bgt ShieldDropDashDanceThink_CheckIfTooFar stb r23,0x1A8C(r29) #Move Away b ShieldDropThinkExit ShieldDropDashDanceThink_CheckIfTooFar: lfs f2,0x4(r21) fcmpo cr0,f1,f2 blt ShieldDropDashDanceThink_CheckToAttack stb r22,0x1A8C(r29) #Move Towards b ShieldDropThinkExit ShieldDropDashDanceThink_CheckToAttack: lfs f2,0x8(r21) fcmpo cr0,f1,f2 bgt ShieldDropDashDanceThink_CheckToChangeDirection ShieldDropDashDanceThink_CheckIfFacingOpponent: lfs f2,0x2C(r29) fctiwz f2,f2 stfd f2,0xF0(sp) lwz r3,0xF4(sp) #Facing direction as int cmpwi r3,0x0 blt ShieldDropDashDanceThink_FacingLeft ShieldDropDashDanceThink_FacingRight: cmpwi r22,0x0 bgt ShieldDropDashDanceThink_FacingOpponent b ShieldDropDashDanceThink_NotFacingOpponent ShieldDropDashDanceThink_FacingLeft: cmpwi r22,0x0 blt ShieldDropDashDanceThink_FacingOpponent b ShieldDropDashDanceThink_NotFacingOpponent ShieldDropDashDanceThink_FacingOpponent: li r3,0x1 b 0x8 ShieldDropDashDanceThink_NotFacingOpponent: li r3,0x0 cmpwi r3,0x0 beq ShieldDropDashDanceThink_CheckToChangeDirection #RNG Chance To Attack li r3,20 branchl r12,HSD_Randi cmpwi r3,0x0 bne ShieldDropDashDanceThink_CheckToChangeDirection li r3,0x400 #X Button stw r3,0x1A88(r29) #Held Buttons li r3,0x2 #JumpThink stw r3,0x4(r31) b ShieldDropThinkExit ShieldDropDashDanceThink_CheckToChangeDirection: #Move if in Wait lwz r3,0x10(r29) cmpwi r3,0xE beq ShieldDropDashDanceThink_ChangeDirection #At least frame 3 of dash cmpwi r24,6 blt ShieldDropThinkExit cmpwi r24,11 bge ShieldDropDashDanceThink_ChangeDirection #RNG Chance To ChangeDirection li r3,7 branchl r12,HSD_Randi cmpwi r3,0x0 bne ShieldDropThinkExit ShieldDropDashDanceThink_ChangeDirection: lfs f2,0x2C(r29) fctiwz f2,f2 stfd f2,0xF0(sp) lwz r3,0xF4(sp) #Facing direction as int mulli r3,r3,127 mulli r3,r3,-1 stb r3,0x1A8C(r29) #Move Away b ShieldDropThinkExit ShieldDropJumpThink: lwz r3,0xE0(r29) cmpwi r3,0x0 beq ShieldDropThinkExit li r3,0x100 #A Button stw r3,0x1A88(r29) #Held Buttons li r3,0x3 #LCancelThink stw r3,0x4(r31) b ShieldDropThinkExit ShieldDropLCancelThink: ShieldDropLCancelInputFF: lfs f2,0x84(r29) lfs f0, -0x76B0 (rtoc) fcmpo cr0,f2,f0 bge ShieldDropThinkExit #Input Down to FF li r3,-127 stb r3,0x1A8D(r29) #Ananlog Y #Check If Under 5Mm Above Ground lfs f2,0xB4(r29) lfs f0,0xC(r21) fcmpo cr0,f2,f0 bgt ShieldDropThinkExit li r3,0xC0 #Hit L stw r3,0x1A88(r29) #Held Buttons #Enter InvincibleThink + Init Counter li r3,0x4 #State stw r3,0x4(r31) li r3,60 stw r3,0x8(r31) #Counter b ShieldDropThinkExit ShieldDropInvincibleThink: #Dec Counter And Check To Restore lwz r3,0x8(r31) subi r3,r3,0x1 stw r3,0x8(r31) cmpwi r3,0x0 bgt ShieldDrop_CheckToMakeInvincible #Reset State ID li r3,0x0 stw r3,0x4(r31) #Restore Savestate mr r3,r31 bl SaveState_Load b ShieldDropThinkExit ShieldDrop_CheckToMakeInvincible: lwz r3,0x10(r29) cmpwi r3,0xE #bne ShieldDropThinkExit #Make Invincible #mr r3,r30 #li r4,0x2 #branchl r12,ApplyInvincibility #b ShieldDropThinkExit #Multishine mr r3,r29 bl CPUActions_MultiShine b ShieldDropThinkExit ShieldDropThinkExit: restore blr ########################## ShieldDropFloats: blrl .long 0x41A00000 #no closer than this .long 0x42180000 #no further than this .long 0x41C80000 #at least this close to jump .long 0x40000000 #below this Y coord to L Cancel .long 0xC02CCCCD #P1 X Position .long 0x4144CCCD #P2 X Position ################################# ShieldDrop_InitializePositions: backup #P1 @ -2.7 #P2 @ 12.3 #Get Floats bl ShieldDropFloats mflr r20 #Move P1 mr r3,r28 branchl r12,0x8008a2bc #Enter Wait lfs f1,0x10(r20) stfs f1,0xB0(r27) mr r3,r28 bl UpdatePosition #Move P2 mr r3,r30 branchl r12,0x8008a2bc #Enter Wait lfs f1,0x14(r20) stfs f1,0xB0(r29) mr r3,r30 bl UpdatePosition restore blr ################################### ShieldDropLoadExit: restore blr */ #endregion #region Event Template /* ######################### ## Eggs-ercise HIJACK INFO ## ######################### Eggs: #STORE THINK FUNCTION bl EggsLoad mflr r3 stw r3,0x44(r26) #on match load b exit ######################## ## Eggs-ercise LOAD FUNCT ## ######################## EggsLoad: blrl backup #Schedule Think bl EggsThink mflr r3 bl CreateEventThinkFunction b EggsLoadExit ######################### ## Eggs-ercise THINK FUNCT ## ######################### EggsThink: blrl backup EggsThinkExit: restore blr EggsLoadExit: restore blr */ #################################################### #endregion ############### ## P1 STRUCT ## ############### P1Struct: blrl .long 0x01000200 #external char, player type, stocks, costume .long 0xff000400 #spawn point, subcolor,team,voice pitch .long 0x00040700 #player flag .long 0x00000000 #level and starting % .long 0x3f800000 #attk ratio .long 0x3f800000 #def ratio .long 0x3f800000 #model scale ############### ## P2 STRUCT ## ############### P2Struct: blrl .long 0x01010200 #external char, player type, stocks, costume .long 0xff000400 #spawn point, subcolor,team,voice pitch .long 0x00040700 #player flag .long 0x00000000 #level and starting % .long 0x3f800000 #attk ratio .long 0x3f800000 #def ratio .long 0x3f800000 #model scale ########################### ## Create Think Function ## ########################### CreateEventThinkFunction: #Registers .set WindowOptionCount,31 .set ASCIIStruct,30 .set EventGObj,29 .set EventData,28 .set MenuGObj,27 .set MenuData,26 .set Priority,25 .set Function,24 backup mr Function,r3 mr Priority,r4 mr WindowOptionCount,r5 mr ASCIIStruct,r6 ######################## ## Create Event Think ## ######################## #Create GObj li r3,6 #GObj Type li r4,7 #On-Pause Function li r5,80 branchl r12,GObj_Create #Backup Allocation mr EventGObj,r3 #Schedule Task mr r4,Function mr r5,Priority branchl r12,GObj_AddProc #Give Task Some Data Space li r3,EventData_DataSize #50 bytes of space branchl r12,HSD_MemAlloc #HSD_MemAlloc mr EventData,r3 #Initalize GObj mr r6,r3 mr r3,EventGObj #task space li r4,0x0 #typedef load r5,HSD_Free #destructor (HSD_Free) branchl r12,GObj_AddUserData #Create Data Block #Zero Dataspace mr r3,EventData li r4,EventData_DataSize branchl r12,ZeroAreaLength #zero length ############################## ## Create Option Menu Think ## ############################## #Check if Option Menu is enabled for this event cmpwi WindowOptionCount,0 beq CreateEventThinkFunction_NoOptionMenu #Create GObj li r3,6 #GObj Type li r4,0 #On-Pause Function li r5,80 branchl r12,GObj_Create #Backup Allocation mr MenuGObj,r3 #Schedule Task bl OptionMenuThink mflr r4 li r5,22 #Last Function to Run branchl r12,GObj_AddProc #Give Task Some Data Space li r3,MenuData_DataSize #50 bytes of space branchl r12,HSD_MemAlloc #HSD_MemAlloc mr MenuData,r3 #Initalize GObj mr r6,MenuData mr r3,MenuGObj #task space li r4,0x0 #typedef load r5,HSD_Free #destructor (HSD_Free) branchl r12,GObj_AddUserData #Create Data Block #Zero Dataspace mr r3,MenuData li r4,MenuData_DataSize branchl r12,ZeroAreaLength #zero length #Store Option Menu info to Dataspace stw WindowOptionCount,MenuData_WindowOptionCountPointer(MenuData) stw ASCIIStruct,MenuData_ASCIIStructPointer(MenuData) #Store Pointers to Each Other stw MenuData,EventData_MenuDataPointer(EventData) stw EventData,MenuData_EventDataPointer(MenuData) CreateEventThinkFunction_NoOptionMenu: #Disable Hazards bl DisableHazards CreateEventThinkFunction_Exit: restore blr #################################### ## Create Option Menu When Paused ## #################################### OptionMenuThink: blrl .set MenuData,31 backup #Load Data Pointer lwz MenuData,0x2C(r3) #Check If Paused li r3,1 branchl r12,DevelopMode_FrameAdvanceCheck cmpwi r3,0x2 bne OptionMenuThink_Exit #Run OptionThink Code OptionMenuThink_CheckInputs: addi r3,MenuData,MenuData_OptionMenuMemory lwz r4,MenuData_WindowOptionCountPointer(MenuData) lwz r5,MenuData_ASCIIStructPointer(MenuData) bl OptionWindow #Store Modified Option Bool cmpwi r3,0 beq OptionMenuThink_Exit addi r5,MenuData,MenuData_OptionMenuToggled stbx r3,r4,r5 OptionMenuThink_Exit: restore blr ########################## ## Clear Option Toggled ## ########################## ClearToggledOptions: #in #r3 = Menu Data #Get Amount of Options lwz r4,MenuData_WindowOptionCountPointer(r3) lbz r4,0x0(r4) #Loop Through All Data addi r3,r3,MenuData_OptionMenuToggled li r5,0 ClearToggledOptions_Loop: stbx r5,r3,r4 #Zero Byte subi r4,r4,1 cmpwi r4,0 bge ClearToggledOptions_Loop ClearToggledOptions_Exit: blr ###################### ## Save States Main ## ###################### #0x0 -> 0x23EC = player block #0x23EC -> 0x24EC = Static Block #0x24EC = Camera Flag ################################ ## Save State Quick Functions ## ################################ SaveState_Save: .set REG_SaveStruct,31 .set REG_PlayerTotal,30 .set REG_LoopCount,29 .set REG_isSubchar,23 .set REG_Backup,28 .set REG_SpawnedOrder,22 .set REG_PlayerGObj,25 .set REG_PlayerData,26 .set REG_PlayerDataSize,24 .set REG_PlayerData_Backup,27 backup #Backup Task Data mr REG_SaveStruct,r3 #Backup "skip failsafe" bool mr r20,r4 #Count Players in Match branchl r3,0x8016b558 #Move Player Number to REG_PlayerTotal mr REG_PlayerTotal,r3 #Check to run failsafe code cmpwi r20,0x0 bne SaveState_SaveLoopInit SaveState_OnDeathCheck: #Mini loop to make sure no players have on-death functions li REG_LoopCount,0x0 #player ID li REG_isSubchar,0x0 #main/sub char bool SaveState_OnDeathCheckLoop: #Get Proper Player Data mr r3,REG_LoopCount mr r4,REG_isSubchar bl SaveState_GetPlayerDataPointer #returns player slot,player pointer and player data cmpwi r3,0xFF #check if player didnt exist beq SaveState_OnDeathCheckInc #move on with loop #Check for on-death function lwz r3,0x21E0(r5) cmpwi r3,0x0 bne SaveState_OnDeathCheckExit lwz r3,0x21E4(r5) cmpwi r3,0x0 bne SaveState_OnDeathCheckExit lwz r3,0x21E8(r5) cmpwi r3,0x0 bne SaveState_OnDeathCheckExit #Check if holding an item lwz r3,0x1974(r5) cmpwi r3,0x0 bne SaveState_OnDeathCheckExit lwz r3,0x1978(r5) cmpwi r3,0x0 bne SaveState_OnDeathCheckExit #Check for fighter accessory lwz r3,0x20A0(r5) cmpwi r3,0x0 bne SaveState_OnDeathCheckExit b SaveState_OnDeathCheckInc SaveState_OnDeathCheckExit: #PLay Error SFX li r3,0xAF bl PlaySFX li r3,0xAF bl PlaySFX b SaveState_SaveExit SaveState_OnDeathCheckInc: #Check For Subchar Before Looping cmpwi REG_isSubchar,0x1 beq SaveState_OnDeathCheck_ToggleSubCharOff li REG_isSubchar,0x1 b SaveState_OnDeathCheckLoop SaveState_OnDeathCheck_ToggleSubCharOff: li REG_isSubchar,0x0 addi REG_LoopCount,REG_LoopCount,0x1 cmpw REG_LoopCount,REG_PlayerTotal blt SaveState_OnDeathCheckLoop SaveState_SaveLoopInit: #Init Save Loop li REG_LoopCount,0x0 #player ID li REG_isSubchar,0x0 #main/sub char bool SaveState_SaveLoop: #Get This Player's Backup Pointer in REG_Backup mulli r4,REG_LoopCount,0x8 #8 bytes per player pointer add REG_Backup,r4,REG_SaveStruct #REG_Backup contains this players block backup #Check If Backup Exists cmpwi REG_isSubchar,0x0 beq SaveState_Save_MainChar SaveState_Save_SubChar: lwz r3,0x4(REG_Backup) #get pointer to backup if it exists b SaveState_Save_CheckIfExists SaveState_Save_MainChar: lwz r3,0x0(REG_Backup) #get pointer to backup if it exists SaveState_Save_CheckIfExists: cmpwi r3,0x0 beq SaveState_SaveStart #Remove Old Backup (HSD_Free) branchl r12,HSD_Free SaveState_SaveStart: #Get Proper Player Data mr r3,REG_LoopCount mr r4,REG_isSubchar bl SaveState_GetPlayerDataPointer #returns player slot,player pointer and player data cmpwi r3,0xFF #check if player didnt exist beq SaveState_SaveLoopInc #move on with loop mr REG_SpawnedOrder,r3 #REG_SpawnedOrder contains actual player slot mr REG_PlayerData,r5 #REG_PlayerData contains real player block #Get Player Data Length SaveState_Save_GetPlayerBlockLength: load r3,0x80458fd0 lwz REG_PlayerDataSize,0x20(r3) #get player block length in REG_PlayerDataSize addi r3,REG_PlayerDataSize,0x100 #add static block length addi r3,r3,0x10 #add additional storage branchl r12,HSD_MemAlloc #HSD_MemAlloc #Store Pointer To Task Struct cmpwi REG_isSubchar,0x0 bne Savestate_Save_StoreBackupSubChar stw r3,0x0(REG_Backup) b Savestate_Save_StoreBackupEnd Savestate_Save_StoreBackupSubChar: stw r3,0x4(REG_Backup) Savestate_Save_StoreBackupEnd: mr REG_PlayerData_Backup,r3 #REG_PlayerData_Backup contains playerblock backup #Copy Player Block to Backup mr r3,REG_PlayerData_Backup #r3 = destination to copy to mr r4,REG_PlayerData #r4 = source mr r5,REG_PlayerDataSize #r5 = playerblock length branchl r12,memcpy #mempcy #Copy Static Block to Backup cmpwi REG_isSubchar,0x0 #unless this is a subcharacter bne Savestate_Save_SkipStaticBlockBackup add r3,REG_PlayerDataSize,REG_PlayerData_Backup #get end of playerblock in r4 load r4,0x80453080 #get static block in r4 li r5,0xE90 mullw r5,r5,REG_SpawnedOrder add r4,r4,r5 li r5,0x100 #only copying the first 100 bytes branchl r12,memcpy #mempcy Savestate_Save_SkipStaticBlockBackup: #Save Camera Flag lwz r3,0x890(REG_PlayerData) lwz r3,0x8(r3) add r4,REG_PlayerDataSize,REG_PlayerData_Backup #get end of player block in r4 addi r4,r4,0x100 #get end of static block stw r3,0x0(r4) #store to end of block SaveState_SaveLoopInc: #Check For Subchar Before Looping cmpwi REG_isSubchar,0x1 beq SaveState_SaveLoopInc_ToggleSubCharOff li REG_isSubchar,0x1 b SaveState_SaveLoop SaveState_SaveLoopInc_ToggleSubCharOff: li REG_isSubchar,0x0 addi REG_LoopCount,REG_LoopCount,0x1 cmpw REG_LoopCount,REG_PlayerTotal blt SaveState_SaveLoop SaveState_SaveExit: restore blr SaveState_Load: .set REG_SaveStruct,31 .set REG_PlayerTotal,30 .set REG_LoopCount,29 .set REG_isSubchar,23 .set REG_Backup,28 .set REG_SpawnedOrder,22 .set REG_PlayerGObj,25 .set REG_PlayerData,26 .set REG_PlayerDataSize,24 .set REG_PlayerData_Backup,27 backup mr REG_SaveStruct,r3 #Count Players in Match branchl r3,0x8016b558 #Move Player Number to REG_PlayerTotal mr REG_PlayerTotal,r3 #Restore Camera Info Here #Init Load Loop li REG_LoopCount,0x0 #player count li REG_isSubchar,0x0 #main/subchar bool SaveState_LoadLoop: #Get This Player's Backup Pointer in REG_Backup mulli r4,REG_LoopCount,0x8 #8 bytes per player pointer add REG_Backup,r4,REG_SaveStruct #REG_Backup contains this players block backup #Check If Backup Exists cmpwi REG_isSubchar,0x0 beq SaveState_Load_MainChar SaveState_Load_SubChar: lwz r3,0x4(REG_Backup) #get pointer to backup if it exists b SaveState_Load_CheckIfExists SaveState_Load_MainChar: lwz r3,0x0(REG_Backup) #get pointer to backup if it exists SaveState_Load_CheckIfExists: cmpwi r3,0x0 beq SaveState_LoadLoopInc SaveState_LoadStart: #Get Proper Player Data mr r3,REG_LoopCount mr r4,REG_isSubchar bl SaveState_GetPlayerDataPointer #returns player slot,player pointer and player data cmpwi r3,0xFF #check if player didnt exist beq SaveState_LoadLoopInc #move on with loop mr REG_SpawnedOrder,r3 #REG_SpawnedOrder contains actual player slot mr REG_PlayerGObj,r4 #REG_PlayerGObj contains external player mr REG_PlayerData,r5 #REG_PlayerData contains real player block #Get Player Block Length in REG_PlayerDataSize SaveState_Load_GetPlayerBlockLength: load REG_PlayerDataSize,0x80458fd0 lwz REG_PlayerDataSize,0x20(REG_PlayerDataSize) #REG_PlayerDataSize = length #Get Pointer From Task Struct cmpwi REG_isSubchar,0x0 #check if subcharacter beq Savestate_Load_GetBackupMainChar Savestate_Load_GetBackupSubChar: lwz REG_PlayerData_Backup,0x4(REG_Backup) #REG_PlayerData_Backup contains playerblock backup b Savestate_Load_RestoreFacingDirection Savestate_Load_GetBackupMainChar: lwz REG_PlayerData_Backup,0x0(REG_Backup) #REG_PlayerData_Backup contains playerblock backup #Restore Facing Direction Savestate_Load_RestoreFacingDirection: lwz r3,0x2C(REG_PlayerData_Backup) #backed up Facing Direction stw r3,0x2C(REG_PlayerData) #Enter Into Sleep mr r3,REG_PlayerGObj li r4,0x0 branchl r12,AS_Sleep #Remove On Death Function Pointer li r3,0x0 stw r3,0x21E4(REG_PlayerData) stw r3,0x21E8(REG_PlayerData) #Enter Into Backed Up State mr r3,REG_PlayerGObj lwz r4,0x10(REG_PlayerData_Backup) #backed up AS li r5,0x0 li r6,0x0 lfs f1,0x894(REG_PlayerData_Backup) #backed up Frame Number lfs f2,0x89C(REG_PlayerData_Backup) #backed up Frame Speed lfs f3,-0x7548 (rtoc) #lfs f3,0x8A4(REG_PlayerData_Backup) #backup up Blend Amount branchl r12,ActionStateChange #ASC #Keep Previous Frame Buttons From Current Block lwz r3,0x620(REG_PlayerData) stw r3,0xD0(sp) lwz r3,0x624(REG_PlayerData) stw r3,0xD4(sp) lwz r3,0x65C(REG_PlayerData) stw r3,0xD8(sp) #Keep Collision Bubble Toggles lwz r3,0x21FC(REG_PlayerData) stw r3,0xDC(sp) #Copy PlayerBlock Backup to Current mr r3,REG_PlayerData mr r4,REG_PlayerData_Backup mr r5,REG_PlayerDataSize branchl r12,memcpy #mempcy #Zero Blend #lfs f1,-0x7548 (rtoc) #stfs f1,0x8A4(REG_PlayerData) #Copy Static Block Backup to Current cmpwi REG_isSubchar,0 #but not if subcharacter bne Savestate_Load_SkipStaticBlockRestore load r3,0x80453080 #get static block in r3 li r4,0xE90 mullw r4,r4,REG_SpawnedOrder add r3,r3,r4 add r4,REG_PlayerDataSize,REG_PlayerData_Backup #get end of block in r4 li r5,0x100 #length is 0x100 branchl r12,memcpy #mempcy Savestate_Load_SkipStaticBlockRestore: #Restore Previous Frame Buttons From Current Block lwz r3,0xD0(sp) stw r3,0x620(REG_PlayerData) stw r3,0x628(REG_PlayerData) lwz r3,0xD4(sp) stw r3,0x624(REG_PlayerData) stw r3,0x62C(REG_PlayerData) lwz r3,0xD8(sp) stw r3,0x65C(REG_PlayerData) stw r3,0x660(REG_PlayerData) stw r3,0x664(REG_PlayerData) #Restore Collision Bubble Toggles lwz r3,0xDC(sp) stw r3,0x21FC(REG_PlayerData) #Remove Cached Animation Pointer (This fixes the Fall Animation Bug) li r3,0x0 stw r3,0x5A8(REG_PlayerData) #Remove Respawn Platform JObj Pointer and Think Function stw r3,0x20A0(REG_PlayerData) stw r3,0x21B0(REG_PlayerData) #Remove Held Item Pointer stw r3,0x1974(REG_PlayerData) #Update ECB Position mr r3,REG_PlayerGObj bl UpdatePosition #Stop Player's SFX mr r3,REG_PlayerData branchl r12,SFX_StopAllCharacterSFX #Stop Crowd SFX branchl r12,SFXManager_StopSFXIfPlaying #Remove GFX mr r3,REG_PlayerGObj branchl r12,GFX_RemoveAll /* #Removing this, causes ground issues when restoring. instead im removing the OSReport call for the error #If Grounded, Change Ground Variable Back lwz r3,0xE0(REG_PlayerData) cmpwi r3,0x0 bne Savestate_RestoreCameraFlag li r3,0x1 stw r3,0x83C(REG_PlayerData) */ #Restore Camera Flag Savestate_RestoreCameraFlag: add r3,REG_PlayerDataSize,REG_PlayerData_Backup #get end of block in r4 addi r3,r3,0x100 #static block length = 0x100 lwz r3,0x0(r3) #get flag lwz r4,0x890(REG_PlayerData) stw r3,0x8(r4) #Update Camera Box Position mr r3,REG_PlayerGObj bl UpdateCameraBox #Remake HUD For Dead Players (Taken from Achilles' GitHub) cmpwi REG_isSubchar,0x1 #dont run this on subcharacters beq SaveState_HUD_End load r3,0x804a10c8 #get base HUD info mulli r4,REG_SpawnedOrder,100 #get offset add r20,r4,r3 #get to this player's HUD info branchl r12,0x8016b094 #MatchInfo_StockModeCheck cmpwi r3,0 #if not stock mode beq- SaveState_RELOAD_PERCENT_HUDS_NOT_STOCK SaveState_RELOAD_PERCENT_HUDS_STOCK: mr r3,REG_SpawnedOrder #get player number branchl r12,0x80033bd8 #get stocks left cmpwi r3,0 bne- SaveState_RELOAD_PERCENT_HUDS_NOT_STOCK li r5,0x80 #remove percent stb r5,0x10(r20) b SaveState_HUD_End SaveState_RELOAD_PERCENT_HUDS_NOT_STOCK: lbz r5,0x10(r20) rlwinm. r5,r5,0,24,24 # (00000080), is player HUD percent gone? beq- SaveState_HUD_End SaveState_REMAKE_PERCENT: .set HUD_PlayerCreate_Prefunction, 0x802f6e1c mr r3,REG_SpawnedOrder branchl r4, HUD_PlayerCreate_Prefunction SaveState_HUD_End: SaveState_LoadLoopInc: #Check For Subchar Before Looping cmpwi REG_isSubchar,0x1 beq SaveState_LoadLoopInc_ToggleSubCharOff li REG_isSubchar,0x1 b SaveState_LoadLoop SaveState_LoadLoopInc_ToggleSubCharOff: li REG_isSubchar,0x0 addi REG_LoopCount,REG_LoopCount,0x1 cmpw REG_LoopCount,REG_PlayerTotal blt SaveState_LoadLoop SaveState_LoadEnd: /* SaveState_Load_RemoveAllGFX: #Get First GFX lwz r3,-0x3E74 (r13) lwz r20,0x30(r3) #Check if exists SaveState_Load_CheckIfGFXExists: cmpwi r20,0 beq SaveState_Load_RemoveAllGFXEnd #Check if this is a particle GObj? lbz r3,0x4(r20) cmpwi r3,1 beq SaveState_Load_GetNextGFX #Remove this GFX mr r3,r20 branchl r12,0x80390228 #Get next GFX SaveState_Load_GetNextGFX: lwz r20,0x8(r20) b SaveState_Load_CheckIfGFXExists SaveState_Load_RemoveAllGFXEnd: */ SaveState_LoadExit: restore blr ######################################################################### ############################ ## Get PlayerData Pointer ## ############################ SaveState_GetPlayerDataPointer: #r3 = player number (regardless of port) #r4 = 0x0 for main char // 0x1 for subchar #returns: #r3 = player slot #r4 = external player #r5 = internal player subi sp,sp,0x8 mr r11,r3 #move desired player into r11 mr r10,r4 #move subchar status into r4 mr r9,sp #move bytefield into r10 li r3,-0x1 #zero out new space stw r3,0x0(r9) stw r3,0x4(r9) #Make Bytefield For Player Order li r7,0x0 #init loop li r6,0x0 #init player ID load r5,0x80453080 #first playerblock SaveState_GetPlayerDataPointer_LoopStart: lwz r3,0x0(r5) #an inactive player block will store "0" at offset 0x0 cmpwi r3,0x0 beq SaveState_GetPlayerDataPointer_Empty SaveState_GetPlayerDataPointer_PlayerPresent: stbx r7,r6,r9 #store loop count to player ID offset addi r6,r6,0x1 #next player ID SaveState_GetPlayerDataPointer_Empty: addi r5,r5,0xe90 #next playerblock addi r7,r7,0x1 #inc loop cmpwi r7,6 blt SaveState_GetPlayerDataPointer_LoopStart #Now r9 contains player bytefield lbzx r3,r11,r9 #get the correct player slot for the X player cmpwi r3,0xFF #check if player exists beq SaveState_GetPlayerDataPointer_Exit #if not exit with -1 return load r5,0x80453080 #first playerblock mulli r4,r3,0xe90 #get offset add r4,r4,r5 #get static block in r4 cmpwi r10,0x0 beq SaveState_GetPlayerDataPointer_MainChar SaveState_GetPlayerDataPointer_SubChar: lwz r4,0xB4(r4) b SaveState_GetPlayerDataPointer_LoadInternal SaveState_GetPlayerDataPointer_MainChar: lwz r4,0xB0(r4) SaveState_GetPlayerDataPointer_LoadInternal: #Check If Player Exists cmpwi r4,0x0 bne SaveState_GetPlayerDataPointer_LoadInternalContinue li r3,0xFF b SaveState_GetPlayerDataPointer_Exit SaveState_GetPlayerDataPointer_LoadInternalContinue: lwz r5,0x2c(r4) SaveState_GetPlayerDataPointer_Exit: addi sp,sp,0x8 blr ####################################################### CheckForSaveAndLoad: .set LoopCount,31 backup mr r29,r3 #Task Data #Init Loop li LoopCount,0 #Loop CheckForSaveAndLoad_Loop: mr r3,LoopCount branchl r12,PlayerBlock_LoadMainCharDataOffset cmpwi r3,0x0 beq CheckForSaveAndLoad_Inc CheckForSaveAndLoad_CheckInputs: load r3,0x804c21cc #load r3,0x804c1fac mulli r0,LoopCount,68 add r4,r3,r0 #Make Sure Nothing Else Is Held lhz r3,0x2(r4) rlwinm. r0,r3,0,0,26 bne CheckForSaveAndLoad_Inc lwz r3,0x8(r4) rlwinm. r0,r3,0,30,30 beq CheckForSaveAndLoad_NoSave mr r3,r29 li r4,0 #run failsafe code bl SaveState_Save li r3,0x0 b CheckForSaveAndLoad_Exit CheckForSaveAndLoad_NoSave: rlwinm. r0,r3,0,31,31 beq CheckForSaveAndLoad_Inc mr r3,r29 bl SaveState_Load mr r3,r29 bl SaveState_Load li r3,0x1 b CheckForSaveAndLoad_Exit CheckForSaveAndLoad_Inc: addi LoopCount,LoopCount,1 cmpwi LoopCount,4 blt CheckForSaveAndLoad_Loop CheckForSaveAndLoad_Exit: restore blr ############################################ GiveFullShields: backup GiveFullShields_GetFirstPlayer: lwz r3, -0x3E74 (r13) lwz r20, 0x0020 (r3) b GiveFullShields_CheckIfPlayerExists GiveFullShields_GetNextPlayer: lwz r20,0x8(r20) GiveFullShields_CheckIfPlayerExists: cmpwi r20,0x0 beq GiveFullShields_Exit lwz r21,0x2C(r20) #Give Full Shield lwz r3, -0x514C (r13) lfs f0, 0x0260 (r3) stfs f0,0x1998(r21) b GiveFullShields_GetNextPlayer GiveFullShields_Exit: restore blr ############################################ UpdateAllGFX: backup mr r3,30 branchl r12,GFX_UpdatePlayerGFX #Check For Follower mr r3,r30 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq UpdateAllGFX_Exit #Apply To Follower Char branchl r12,GFX_UpdatePlayerGFX UpdateAllGFX_Exit: restore blr ############################################ GiveInvincibility: #r3 = ext pointer #r4 = frames backup #Give To Main Char mr r31,r3 mr r30,r4 branchl r12,ApplyInvincibility #Check For Follower mr r3,r31 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq GiveInvincibility_Exit #Apply To Follower Char mr r4,r30 branchl r12,ApplyInvincibility GiveInvincibility_Exit: restore blr ############################################ StoreCPUTypeAndZeroInputs: #Set P2 AI Type to None #li r3,0xF #stw r3,0x1A94(r29) #Clear Inputs For P2 CPU li r3,0x0 stw r3,0x1A88(r29) stw r3,0x1A8C(r29) sth r3,0x1A90(r29) blr ########################################### ClearNanaInputs: backup #Clear Inputs if P1 is Ice Climbers mr r3,28 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq ClearNanaInputs_P2 li r3,0x0 stw r3,0x1A88(r4) stw r3,0x1A8C(r4) #Clear Inputs if P2 is Ice Climbers ClearNanaInputs_P2: mr r3,30 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq ClearNanaInputs_Exit li r3,0x0 stw r3,0x1A88(r4) stw r3,0x1A8C(r4) ClearNanaInputs_Exit: restore blr ########################################### CheckIfFirstFrame: lwz r3,TM_GameFrameCounter(r13) cmpwi r3,0x1 bne CheckIfFirstFrame_False li r3,0x1 b CheckIfFirstFrame_Exit CheckIfFirstFrame_False: li r3,0x0 CheckIfFirstFrame_Exit: blr ############################################# CurrentInputsAsLastFramesInputs: load r3,0x804c21cc lwz r3,0x0(r3) stw r3,0x65C(r27) stw r3,0x664(r27) #Check For Z Press rlwinm. r0, r3, 0, 27, 27 beq CurrentInputsAsLastFramesInputs_Exit oris r0, r3, 0x8000 ori r0, r0, 0x0100 stw r0,0x65C(r27) stw r0,0x664(r27) CurrentInputsAsLastFramesInputs_Exit: blr ############################################# /* CPUActions_MultiShine: backup mr r29,r3 #Get AS and Frame Number lwz r4,0x10(r3) #Get Current AS #Start - Check to Grounded Shine cmpwi r4,0xE #Wait beq Multishine_StartShine cmpwi r4,0x169 #Shine Loop Ground beq Multishine_JumpCancelShine cmpwi r4,0x19 #JumpF beq Multishine_StartShine b CPUActions_MultiShine_Exit Multishine_StartShine: li r3,-127 #Down stb r3,0x1A8D(r29) #Analog Y li r3,0x200 #B stw r3,0x1A88(r29) #Inputs b CPUActions_MultiShine_Exit Multishine_JumpCancelShine: li r3,0x800 #X stw r3,0x1A88(r29) #Inputs b CPUActions_MultiShine_Exit Multishine_ShineAir: b CPUActions_MultiShine_Exit CPUActions_MultiShine_Exit: restore blr */ ################################### RAndDPadChangesEventOption: OptionWindow: #in #r3 = pointer to option byte in memory #r4 = pointer to Window and Option Count #r5 = pointer to ASCII struct #out #r3 = .set TextCreateFunction,0x80005928 .set OptionWindowMemory,20 .set OptionTextInfo,21 .set OptionASCII,22 .set text,23 .set toggledBool,28 .set toggledOption,29 backup #Backup Parameters mr OptionWindowMemory,r3 #pointer to option byte in memory mr OptionTextInfo,r4 #pointer to Window and Option Count mr OptionASCII,r5 #pointer to ASCII struct #Initialize Toggled Bools li toggledBool,0 li toggledOption,-1 #Get Number Of Options Onscreen At Once (1,2,or 3) lbz r24,0x0(OptionTextInfo) #Get Number of Different Windows cmpwi r24,2 #Check If Over 3 ble 0x8 li r24,2 #Make 3 #Get Pausing Player's Inputs load r3,0x8046b6a0 lbz r3,0x1(r3) load r4,0x804c1fac mulli r3,r3,68 add r3,r3,r4 lwz r3,0x8(r3) #Check For DPad Up And Down cmpwi r3,0x04 beq RAndDPadChangesEventOption_CursorDown cmpwi r3,0x08 beq RAndDPadChangesEventOption_CursorUp b RAndDPadChangesEventOption_CheckDPadLeftAndRight RAndDPadChangesEventOption_CursorUp: #Update Cursor Position lbz r3,0x0(OptionWindowMemory) #Get Current Cursor Position Byte subi r3,r3,0x1 #Subtract by 1 stb r3,0x0(OptionWindowMemory) cmpwi r3,0x0 bge RAndDPadChangesEventOption_PlayScrollSFX #Cursor Stays at the top of the screen li r3,0 stb r3,0x0(OptionWindowMemory) #Check To Scroll Down #Get Current Window ID (cursor + scroll) lbz r3,0x0(OptionWindowMemory) lbz r4,0x1(OptionWindowMemory) add r3,r3,r4 #Check If This is the Beginning cmpwi r3,0 ble RAndDPadChangesEventOption_DisplayWindow #Scroll Down lbz r4,0x1(OptionWindowMemory) subi r4,r4,1 stb r4,0x1(OptionWindowMemory) b RAndDPadChangesEventOption_PlayScrollSFX b RAndDPadChangesEventOption_DisplayWindow RAndDPadChangesEventOption_CursorDown: #Update Cursor Position lbz r3,0x0(OptionWindowMemory) #Get Current Option Byte addi r3,r3,0x1 #Add 1 stb r3,0x0(OptionWindowMemory) cmpw r3,r24 ble RAndDPadChangesEventOption_PlayScrollSFX #Cursor Stays at the Bottom of the Screen stb r24,0x0(OptionWindowMemory) #Check To Scroll Down #Get Current Window ID (cursor + scroll) lbz r3,0x0(OptionWindowMemory) lbz r4,0x1(OptionWindowMemory) add r3,r3,r4 #Get Max Number Of Windows lbz r4,0x0(OptionTextInfo) #Get Number of Different Windows #Check If This is the End cmpw r3,r4 bge RAndDPadChangesEventOption_DisplayWindow #Scroll Down lbz r4,0x1(OptionWindowMemory) addi r4,r4,1 stb r4,0x1(OptionWindowMemory) b RAndDPadChangesEventOption_PlayScrollSFX #Check For DPad Left And Right RAndDPadChangesEventOption_CheckDPadLeftAndRight: cmpwi r3,0x02 beq RAndDPadChangesEventOption_Increment cmpwi r3,0x01 beq RAndDPadChangesEventOption_Decrement b RAndDPadChangesEventOption_DisplayWindow RAndDPadChangesEventOption_Increment: #Get Current Window ID (cursor + scroll) lbz r3,0x0(OptionWindowMemory) lbz r4,0x1(OptionWindowMemory) add r3,r3,r4 #Set as Toggled li toggledBool,1 mr toggledOption,r3 addi r5,r3,2 lbzx r3,r5,OptionWindowMemory #Get Current Option Byte addi r3,r3,0x1 stbx r3,r5,OptionWindowMemory #Store New Option Byte Value subi r5,r5,1 lbzx r4,r5,OptionTextInfo #Get Window's Option Byte Max Value cmpw r3,r4 ble RAndDPadChangesEventOption_PlayScrollSFX li r3,0x0 addi r5,r5,1 stbx r3,r5,OptionWindowMemory #Get New Option Byte Value b RAndDPadChangesEventOption_PlayScrollSFX RAndDPadChangesEventOption_Decrement: #Get Current Window ID (cursor + scroll) lbz r3,0x0(OptionWindowMemory) lbz r4,0x1(OptionWindowMemory) add r3,r3,r4 #Set as Toggled li toggledBool,1 mr toggledOption,r3 addi r5,r3,0x2 lbzx r3,r5,OptionWindowMemory #Get Current Option Byte subi r3,r3,0x1 stbx r3,r5,OptionWindowMemory #Store New Option Byte Value cmpwi r3,0x0 bge RAndDPadChangesEventOption_PlayScrollSFX subi r5,r5,1 lbzx r3,r5,OptionTextInfo #Get Window's Option Byte Max Value addi r5,r5,1 stbx r3,r5,OptionWindowMemory #Store New Option Byte Value b RAndDPadChangesEventOption_PlayScrollSFX RAndDPadChangesEventOption_PlayScrollSFX: li r3,0x2 branchl r12,SFX_MenuCommonSound RAndDPadChangesEventOption_DisplayWindow: #Display Text For The New Option Value mr r3,r27 #p1 (no offsetting window) li r4,1 #text timeout li r5,0x2 #window instance #3 li r6,0 #window ID #3 branchl r12,TextCreateFunction #create text custom function mr text,r3 #backup text pointer ######################### ## Display Option Menu ## ######################### #Check How Many Options In The Menu cmpwi r24,0 beq RAndDPadChangesEventOption_DisplayWindow_LoopInit #Change Background Size bl RAndDPadChangesEventOption_Floats mflr r5 lfs f1,0x0(r5) #12.5 addi r5,r5,0x4 #Skip Window X subi r6,r24,1 #Zero Index mulli r6,r6,0x4 #Get Y Offset lfsx f2,r6,r5 li r4,0 branchl r12,Text_UpdateSubtextSize #Move Window bl RAndDPadChangesEventOption_Floats mflr r5 lfs f1, -0x37B4 (rtoc) addi r5,r5,0xC #Skip Window X and Window Y's subi r6,r24,1 #Zero Index mulli r6,r6,0x4 #Get Y Offset lfsx f2,r6,r5 mr r3,text li r4,0 branchl r12,Text_UpdateSubtextPosition ############################ ## Display Up/Down Arrows ## ############################ #Check if at the top of the screen lbz r3,0x1(r20) cmpwi r3,0x0 beq RAndDPadChangesEventOption_DisplayDownArrow #Create Title Text li r3,-20 #Y bl IntToFloat fmr f2,f1 li r3,-210 #X bl IntToFloat mr r3,text #text pointer bl RAndDPadChangesEventOption_UpArrowText mflr r4 branchl r12,Text_InitializeSubtext RAndDPadChangesEventOption_DisplayDownArrow: #Check if at the bottom of the screen lbz r3,0x0(r21) cmpwi r3,2 blt RAndDPadChangesEventOption_DisplayArrowExit lbz r4,0x1(r20) sub r3,r3,r4 cmpwi r3,2 ble RAndDPadChangesEventOption_DisplayArrowExit #Create Title Text li r3,320 #Y value bl IntToFloat fmr f2,f1 li r3,-210 #X Value bl IntToFloat mr r3,text #text pointer bl RAndDPadChangesEventOption_DownArrowText mflr r4 branchl r12,Text_InitializeSubtext RAndDPadChangesEventOption_DisplayArrowExit: ############################ ## Print Each Option Loop ## ############################ RAndDPadChangesEventOption_DisplayWindow_LoopInit: li r27,0 #Init Loop RAndDPadChangesEventOption_DisplayWindow_Loop: #Get Window Title And Option mr r3,OptionASCII #Option ASCII Start lbz r4,0x1(OptionWindowMemory) #Get Scroll Position add r4,r4,r27 #Get Loop Count's Window addi r5,OptionWindowMemory,0x2 #Selection ID's lbzx r5,r4,r5 #Get Current Option This Window is On bl RAndDPadChangesEventOption_GetOptionASCII mr r25,r3 mr r26,r4 #Create Title Text lfs f2, -0x37B4 (rtoc) #default text Y li r3,120 mullw r3,r3,r27 bl IntToFloat fadds f2,f1,f2 lfs f1, -0x37B4 (rtoc) #default text X mr r3,text #text pointer mr r4,r25 #Title Text Pointer branchl r12,Text_InitializeSubtext #Make Text Grey load r4,0xdfdfdf00 stw r4,0xF0(sp) addi r5,sp,0xF0 mr r4,r3 mr r3,text branchl r12,Text_ChangeTextColor #Create Selection Text lfs f2, -0x37B0 (rtoc) #shift down on Y axis li r3,120 mullw r3,r3,r27 bl IntToFloat fadds f2,f1,f2 lfs f1, -0x37B4 (rtoc) #default text X/Y mr r3,text #text pointer mr r4,r26 #Selection Text branchl r12,Text_InitializeSubtext #Check To Outline in Yellow lbz r4,0x0(OptionWindowMemory) #Get Cursor Position cmpw r4,r27 #Compare With Loop Counter bne RAndDPadChangesEventOption_DisplayWindow_SkipColor load r4,0xf7ff2700 stw r4,0xF0(sp) addi r5,sp,0xF0 mr r4,r3 mr r3,text branchl r12,Text_ChangeTextColor RAndDPadChangesEventOption_DisplayWindow_SkipColor: cmpw r27,r24 addi r27,r27,1 blt RAndDPadChangesEventOption_DisplayWindow_Loop b RAndDPadChangesEventOption_Exit ######################################### RAndDPadChangesEventOption_GetOptionASCII: backup mr r31,r3 #Option ASCII Start mr r30,r4 #Option ID We're Looking For mr r29,r5 #Option Selection We're Looking For #Init Loop li r27,0 RAndDPadChangesEventOption_GetOptionASCII_OptionIDLoop: cmpw r27,r30 #Check If This is the Window We're Looking For beq RAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection ######################## ## Skip Entire Option ## ######################## RAndDPadChangesEventOption_GetOptionASCII_GetNextOptionID: #Skip Past Window Title mr r3,r31 bl RAndDPadChangesEventOption_GetNextString mr r31,r3 #Backup New Pointer #Loop Through All The Window's Selections li r26,0 #Loop Count RAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections: #Get This Options (r27) Total Number of Selections (Pointer in OptionTextInfo) addi r3,OptionTextInfo,0x1 #Get to Option Selection Counts lbzx r3,r3,r27 #Get This Windows Total Number of Selections addi r3,r3,0x1 #Add 1 To Ensure We Are at the Start of the Next Window Title cmpw r3,r26 #Check If This is the Last Selection bne RAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections_NextSelection #End of Loop, Done With This Option #Increment Loop Count addi r27,r27,1 #Increment Option Count b RAndDPadChangesEventOption_GetOptionASCII_OptionIDLoop RAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections_NextSelection: #Get Next Selection mr r3,r31 bl RAndDPadChangesEventOption_GetNextString mr r31,r3 #Backup New Pointer #Increment Loop Count addi r26,r26,1 b RAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections ########################### ## Find Option Selection ## ########################### RAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection: #Init Loop Count + Backup Window Title li r26,0 #Init Loop Count mr r25,r31 #r25 = Window Title #Skip Window Title mr r3,r31 bl RAndDPadChangesEventOption_GetNextString mr r31,r3 #Backup New Pointer RAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Loop: #Check If This is the Selection We're Looking For cmpw r26,r29 beq RAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Done #Get Next Selection #Strlen the entry mr r3,r31 bl RAndDPadChangesEventOption_GetNextString mr r31,r3 #Backup New Pointer #Increment Loop Count addi r26,r26,1 b RAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Loop RAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Done: mr r3,r25 #Return Window Name mr r4,r31 #Return Selection String RAndDPadChangesEventOption_GetOptionASCII_Exit: restore blr ######################################### RAndDPadChangesEventOption_GetNextString: backup mr r31,r3 #Backup String Pointer branchl r12,strlen #Get Length add r3,r3,r31 #Get End of String #From here, mini loop to find the next non-zero value. RAndDPadChangesEventOption_GetNextString_Loop: lbzu r4,0x1(r3) cmpwi r4,0x0 beq RAndDPadChangesEventOption_GetNextString_Loop restore blr ######################################### RAndDPadChangesEventOption_Floats: blrl .float 16 #12.5, X position .long 0x427c0000 #63, 2 Window Y Scale .long 0x42bc0000 #94, 3 Window Y Scale .long 0xc4610000 #-900, 2 Window Y position .long 0xc4a8c000 #-1350, 3 Window Y position ######################################### RAndDPadChangesEventOption_UpArrowText: blrl .string "^" .align 2 RAndDPadChangesEventOption_DownArrowText: blrl .string "v" .align 2 ######################################### RAndDPadChangesEventOption_Exit: mr r3,toggledBool mr r4,toggledOption restore blr ################################## DPadCPUPercent: backup .set REG_SaveStruct,31 .set REG_PercentInt,30 .set REG_isSubcharBool,29 #Backup savestate struct mr REG_SaveStruct,r3 #Get P1 Block li r3,0x0 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block lwz r3,0x2C(r3) #Get P2 Percent load r6,0x80453F10 lhz REG_PercentInt,0x60(r6) #Get Subchar Bool lbz REG_isSubcharBool,0xC(r6) #Get inputs load r4,0x804c21cc lbz r3,0x618(r3) mulli r0,r3,68 add r5,r4,r0 #Make Sure L Is Held lwz r3,0x0(r5) #get held inputs rlwinm. r0,r3,0,25,25 beq DPadCPUPercent_Exit #Check DPad lwz r3,0xC(r5) #get rapid inputs rlwinm. r0,r3,0,30,30 bne DPadCPUPercent_IncByOne rlwinm. r0,r3,0,31,31 bne DPadCPUPercent_DecByOne rlwinm. r0,r3,0,28,28 bne DPadCPUPercent_IncByTen rlwinm. r0,r3,0,29,29 bne DPadCPUPercent_DecByTen b DPadCPUPercent_Exit DPadCPUPercent_IncByOne: cmpwi REG_PercentInt,999 blt DPadCPUPercent_IncByOneReal li REG_PercentInt,999 b DPadCPUPercent_StorePercent DPadCPUPercent_IncByOneReal: addi REG_PercentInt,REG_PercentInt,0x1 b DPadCPUPercent_StorePercent DPadCPUPercent_DecByOne: cmpwi REG_PercentInt,0 bgt DPadCPUPercent_DecByOneReal li REG_PercentInt,0 b DPadCPUPercent_StorePercent DPadCPUPercent_DecByOneReal: subi REG_PercentInt,REG_PercentInt,0x1 b DPadCPUPercent_StorePercent DPadCPUPercent_IncByTen: cmpwi REG_PercentInt,989 blt DPadCPUPercent_IncByTenReal li REG_PercentInt,999 b DPadCPUPercent_StorePercent DPadCPUPercent_IncByTenReal: addi REG_PercentInt,REG_PercentInt,10 b DPadCPUPercent_StorePercent DPadCPUPercent_DecByTen: cmpwi REG_PercentInt,9 bgt DPadCPUPercent_DecByTenReal li REG_PercentInt,0 b DPadCPUPercent_StorePercent DPadCPUPercent_DecByTenReal: subi REG_PercentInt,REG_PercentInt,10 b DPadCPUPercent_StorePercent DPadCPUPercent_StorePercent: #Store to Active Static Playerblock sth REG_PercentInt,0x60(r6) #Convert to Float mr r3,REG_PercentInt bl IntToFloat #Active PlayerData li r3,0x1 branchl r12,PlayerBlock_LoadMainCharDataOffset #get player block lwz r3,0x2C(r3) stfs f1,0x1830(r3) #Backed Up PlayerData mulli r4,REG_isSubcharBool,0x4 lwzx r3,r4,REG_SaveStruct stfs f1,0x1830(r3) #Backed Up Static Playerblock load r4,0x80458fd0 #get player block length lwz r4,0x20(r4) #get player block length lwz r3,0x0(REG_SaveStruct) #only the main character has a static block backup add r3,r3,r4 #static block start sth REG_PercentInt,0x60(r3) sth REG_PercentInt,0x62(r3) DPadCPUPercent_Exit: restore blr ################################## InitializePositions: backup #Move Float Pointer mr r20,r3 #P1 Static Block load r22,0x80453080 #P2 Static Block addi r23,r22,0xE90 #Move P1 mr r3,r28 branchl r12,0x8008a2bc #Enter Wait lfs f1,0x0(r20) stfs f1,0xB0(r27) lfs f1,0x8(r20) stfs f1,0xB4(r27) mr r3,r28 bl UpdatePosition mr r3,r28 bl UpdateCameraBox mr r3,r28 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq InitializePositions_MoveP2 #Move This Char Too mr r24,r3 mr r25,r4 mr r3,r24 branchl r12,0x8008a2bc #Enter Wait lfs f1,0x0(r20) stfs f1,0xB0(r25) lfs f1,0x8(r20) stfs f1,0xB4(r25) mr r3,r24 bl UpdatePosition mr r3,r24 bl UpdateCameraBox #Move P2 InitializePositions_MoveP2: mr r3,r30 branchl r12,0x8008a2bc #Enter Wait lfs f1,0x4(r20) stfs f1,0xB0(r29) lfs f1,0xC(r20) stfs f1,0xB4(r29) mr r3,r30 bl UpdatePosition mr r3,r30 bl UpdateCameraBox mr r3,r30 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 beq InitializePositions_Exit #Move This Char Too mr r24,r3 mr r25,r4 mr r3,r24 branchl r12,0x8008a2bc #Enter Wait lfs f1,0x4(r20) stfs f1,0xB0(r25) lfs f1,0xC(r20) stfs f1,0xB4(r25) mr r3,r24 bl UpdatePosition mr r3,r24 bl UpdateCameraBox InitializePositions_Exit: bl ClearNanaInputs bl CurrentInputsAsLastFramesInputs restore blr ######################################################### CheckIfPlayerHasAFollower: #Returns #r3 = 0 for no follower // External Pointer #r4 = 0 for no follower // Internal Pointer backup #Get Players Data lwz r31,0x2C(r3) #Get Player Slot lbz r3,0xC(r31) li r4,0x1 bl SaveState_GetPlayerDataPointer #returns r3=Slot/-1 if subchar doesnt exist, r4= external, r5=internal cmpwi r3,0xFF beq CheckIfPlayerHasAFollower_NoFollower #Check If Follower mr r24,r4 mr r25,r5 lbz r3,0xC(r25) #get slot branchl r12,0x80032330 #get external character ID load r4,pdLoadCommonData #pdLoadCommonData table mulli r0, r3, 3 #struct length add r3,r4,r0 #get characters entry lbz r0, 0x2 (r3) #get subchar functionality cmpwi r0,0x0 #if not a follower, exit bne CheckIfPlayerHasAFollower_NoFollower #Return Follower Pointers mr r3,r24 #External mr r4,r25 #Internal b CheckIfPlayerHasAFollower_Exit CheckIfPlayerHasAFollower_NoFollower: li r3,0x0 li r4,0x0 CheckIfPlayerHasAFollower_Exit: restore blr ######################################################### Randomize_LeftorRightSide: #r3 = 0 = Same Side of Stage // 1 = Opposing Sides of Stage backup mr r20,r3 #Backup Stage Side Bool #Get Left or Right Side li r3,2 branchl r12,HSD_Randi #Check To Negate cmpwi r3,0x0 #0 = Left, 1 = Right bne Randomize_RightSide Randomize_LeftSide: #P1 X Position lwz r3,0x10(r31) #P1 Backup Start lwz r4,0x18(r31) #P2 Backup Start lfs f1,0xB0(r3) #P1 Backup X Pos cmpwi r20,0x0 beq 0xC bl Randomize_AlwaysNegative b 0x8 bl Randomize_AlwaysNegative stfs f1,0xB0(r3) #P1 Backup X Pos #P2 X Position lfs f1,0xB0(r4) #P2 Backup X Pos cmpwi r20,0x0 beq 0xC bl Randomize_AlwaysPositive b 0x8 bl Randomize_AlwaysNegative stfs f1,0xB0(r4) #P2 Backup X Pos #Facing Directions lis r5,0x3f80 #P1 Face Right lis r6,0xbf80 #P2 Face Left stw r5,0x2C(r3) #P1 Backup Facing stw r6,0x2C(r4) #P2 Facing b Randomize_LeftorRightSide_CheckForFollowers Randomize_RightSide: #P1 X Position lwz r3,0x10(r31) #P1 Backup Start lwz r4,0x18(r31) #P2 Backup Start lfs f1,0xB0(r3) #P1 Backup X Pos cmpwi r20,0x0 beq 0xC bl Randomize_AlwaysPositive b 0x8 bl Randomize_AlwaysPositive stfs f1,0xB0(r3) #P1 Backup X Pos #P2 X Position lfs f1,0xB0(r4) #P2 Backup X Pos cmpwi r20,0x0 beq 0xC bl Randomize_AlwaysNegative b 0x8 bl Randomize_AlwaysPositive stfs f1,0xB0(r4) #P2 Backup X Pos #Facing Directions lis r5,0xbf80 #P1 Face Left lis r6,0x3f80 #P2 Face Right stw r5,0x2C(r3) #P1 Backup Facing stw r6,0x2C(r4) #P2 Facing Randomize_LeftorRightSide_CheckForFollowers: Randomize_LeftorRightSide_GetFirstPlayer: lwz r3, -0x3E74 (r13) lwz r20, 0x0020 (r3) b Randomize_LeftorRightSide_CheckIfPlayerExists Randomize_LeftorRightSide_GetNextPlayer: lwz r20,0x8(r20) Randomize_LeftorRightSide_CheckIfPlayerExists: cmpwi r20,0x0 beq Randomize_LeftorRightSide_Exit lwz r21,0x2C(r20) #Check If This Fighter is a Main Char lbz r3,0x221F(r21) rlwinm. r0, r3, 29, 31, 31 bne Randomize_LeftorRightSide_GetNextPlayer #Check For Follower, r20 = External. r21 = Internal mr r3,r20 bl CheckIfPlayerHasAFollower cmpwi r3,0x0 #No Follower, Go To Next Player beq Randomize_LeftorRightSide_GetNextPlayer #Transfer Info #Get Backups addi r3,r31,0x10 #Get Backup Start lbz r4,0xC(r21) #Get Subchars Slot mulli r4,r4,0x8 #Each Slot has 2 backups, so get to this slots backup add r3,r3,r4 #Each Slot has 2 backups, so get to this slots backup #Copy Main Char's Info Into Subchars lwz r4,0x0(r3) #Main Char Backup lwz r5,0x4(r3) #Follower Backup lwz r3,0xB0(r4) #Main Char X stw r3,0xB0(r5) #Into Subchar X lwz r3,0x2C(r4) #Main Char Facing stw r3,0x2C(r5) #Into Subchar Facing b Randomize_LeftorRightSide_GetNextPlayer Randomize_LeftorRightSide_Exit: restore blr #********************************************# Randomize_AlwaysPositive: fabs f1,f1 #Always Positive blr Randomize_AlwaysNegative: fabs f1,f1 fneg f1,f1 #Always Negative blr #********************************************# ############################################ IntToFloat: mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) stfs f2,0x38(r1) lis r0, 0x4330 lfd f2, -0x6758 (rtoc) xoris r3, r3,0x8000 stw r0,0xF0(sp) stw r3,0xF4(sp) lfd f1,0xF0(sp) fsubs f1,f1,f2 #Convert To Float lfs f2,0x38(r1) lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 blr ############################################ GetDirectionInRelationToP1: #Get P1 Direction lfs f1,0xB0(r27) lfs f2,0xB0(r29) fsubs f1,f1,f2 lfs f2, -0x6768 (rtoc) fcmpo cr0,f2,f1 blt 0xC li r3,1 b 0x8 li r3,-1 blr ############################################ IsAnyoneDead: backup IsAnyoneDead_GetFirstPlayer: lwz r3, -0x3E74 (r13) lwz r20, 0x0020 (r3) b IsAnyoneDead_CheckIfPlayerExists IsAnyoneDead_GetNextPlayer: lwz r20,0x8(r20) IsAnyoneDead_CheckIfPlayerExists: cmpwi r20,0x0 bne IsAnyoneDead_GetPlayerData #Exit If No Other Players li r3,0x0 b IsAnyoneDead_Exit IsAnyoneDead_GetPlayerData: lwz r21,0x2C(r20) #Check If Follower lbz r3,0x221F(r21) rlwinm. r0,r3,0,28,28 bne IsAnyoneDead_GetNextPlayer #Check If Dead lbz r3,0x221F(r21) rlwinm. r0,r3,0,25,25 beq IsAnyoneDead_GetNextPlayer li r3,0x1 b IsAnyoneDead_Exit IsAnyoneDead_Exit: restore blr ############################################ ResetStaleMoves: backup ResetStaleMoves_GetFirstPlayer: lwz r3, -0x3E74 (r13) lwz r20, 0x0020 (r3) b ResetStaleMoves_CheckIfPlayerExists ResetStaleMoves_GetNextPlayer: lwz r20,0x8(r20) ResetStaleMoves_CheckIfPlayerExists: cmpwi r20,0x0 bne ResetStaleMoves_GetPlayerData #Exit If No Other Players li r3,0x0 b ResetStaleMoves_Exit ResetStaleMoves_GetPlayerData: lwz r21,0x2C(r20) #Reset Stale Moves #Get Stale Move Table lbz r3,0xC(r21) #Get Slot branchl r12,0x80036244 #Get This Players Stale Table #Fill With 0's li r4,0x2C branchl r12,ZeroAreaLength b ResetStaleMoves_GetNextPlayer ResetStaleMoves_Exit: restore blr ############################################ ActOutOfLaserHitDisplay: backup #Check If In Run lwz r3,0x10(r27) cmpwi r3,0x14 bne ActOutOfLaserHitDisplayExit #Check If Frame 2 li r3,2 bl IntToFloat lfs f2,0x894(r27) fcmpo cr0,f2,f1 bne ActOutOfLaserHitDisplayExit #Search Prev AS For Laser Hit, returns r3=AS's Since Laser Hit or -1 for didnt happen li r3,0x0 #Number of AS's ago addi r4,r27,0x23F0 #First Prev AS subi r4,r4,0x2 ActOutOfLaserHitDisplay_SearchLoop: addi r3,r3,0x1 lhzu r5,0x2(r4) cmpwi r5,0x4E #Laser Hit beq ActOutOfLaserHitDisplay_ExitLoop cmpwi r5,0x4B #Laser Hit beq ActOutOfLaserHitDisplay_ExitLoop cmpwi r3,0x3 beq ActOutOfLaserHitDisplay_NoLaserHit b ActOutOfLaserHitDisplay_SearchLoop ActOutOfLaserHitDisplay_NoLaserHit: li r3,-1 ActOutOfLaserHitDisplay_ExitLoop: cmpwi r3,-1 beq ActOutOfLaserHitDisplayExit ActOutOfLaserHitDisplay_CountFrameInit: #Get Amount Of Frames Since Laser Hit Ended li r5,0x23FC #As's Frame Count offset li r20,0 #Frames Since Laser Hit ActOutOfLaserHitDisplay_CountFrameLoop: cmpwi r3,0 #Check If Done Counting beq ActOutOfLaserHitDisplay_CountFrameLoopFinish mulli r4,r3,2 #Frame Count Offset subi r4,r4,0x2 #1 AS Before add r4,r4,r5 #Get Offset in Playerblock lhzx r6,r4,r27 #Get Frame Count Value subi r4,r4,0xC #Get AS Associated With It lhzx r4,r4,r27 #Get AS ID #Check If This AS is Turn cmpwi r4,0x12 beq 0x8 add r20,r20,r6 #Add To Toal cmpwi r4,0x4E beq ActOutOfLaserHitDisplay_SubtractHitstun cmpwi r4,0x4B beq ActOutOfLaserHitDisplay_SubtractHitstun b ActOutOfLaserHitDisplay_SkipSubtractHitstun ActOutOfLaserHitDisplay_SubtractHitstun: subi r20,r20,0x8 ActOutOfLaserHitDisplay_SkipSubtractHitstun: subi r3,r3,1 b ActOutOfLaserHitDisplay_CountFrameLoop ActOutOfLaserHitDisplay_CountFrameLoopFinish: ActOutOfLaserHitDisplay_DisplayOSD: mr r3,r27 #p1 (no offsetting window) li r4,120 #text timeout li r5,0 #Area to Display (0-2) li r6,OSD.Miscellaneous #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr text,r3 #backup text pointer cmpwi r20,0x1 beq ActOutOfLaserHitDisplay_Perfect ActOutOfLaserHitDisplay_Late: load r3,0xffa2baff #Red b ActOutOfLaserHitDisplay_StoreTextColor ActOutOfLaserHitDisplay_Perfect: load r3,0x8dff6eff #green ActOutOfLaserHitDisplay_StoreTextColor: stw r3,0x30(text) #Create Text 1 mr r3,text #text pointer bl ActOutOfLaserHitDisplay_TopText mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,Text_InitializeSubtext #Create Text 2 mr r3,text #text pointer bl ActOutOfLaserHitDisplay_BottomText mflr r4 mr r5,r20 #Frame Count lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #default text X/Y branchl r12,Text_InitializeSubtext ActOutOfLaserHitDisplayExit: restore blr ##################### ## Text Properties ## ##################### ActOutOfLaserHitDisplay_TextProperties: blrl .long 0xC1A80000 #Whether to Use HUD Location, 0 = no .long 0x41100000 #Y Value .long 0x41600000 #X Difference Between Players .long 0x3D23D70A #Text Size .long 0xC3CD0000 #background Y position .long 0x4129999A #background X stretch .long 0x41E00000 #background Y stretch ############## ## Top Text ## ############## ActOutOfLaserHitDisplay_TopText: blrl .long 0x44617368 .long 0x204f6f4c .long 0x61736572 .long 0x48697400 ################# ## Bottom Text ## ################# ActOutOfLaserHitDisplay_BottomText: blrl .long 0x4672616d .long 0x65202564 .long 0x ############################################ MoveCPU: #in #r3 = P1 GObj #r4 = P2 GObj #r5 = SaveState Struct .set P1GObj,31 .set P1Data,30 .set P2GObj,29 .set P2Data,28 .set SaveStateStruct,27 .set P2Subchar,26 .set P2SubcharData,25 backup #Get Variables mr P1GObj,r3 lwz P1Data,0x2C(P1GObj) mr P2GObj,r4 lwz P2Data,0x2C(P2GObj) mr SaveStateStruct,r5 #Get Input lbz r4, 0x0618 (P1Data) load r3,InputStructStart mulli r0, r4, 68 add r5, r0, r3 #Check DPad Down lwz r3,0xC(r5) rlwinm. r0,r3,0,29,29 beq MoveCPUExit #Make Sure Nothing Is Held lwz r3,0x0(r5) li r4,0 rlwimi r3,r4,0,29,29 #except dpad down rlwimi r3,r4,0,27,27 #except Z (cause frame advance) cmpwi r3,0 bne MoveCPUExit #Make Sure Player is Grounded lwz r3,0xE0(P1Data) cmpwi r3,0x0 bne MoveCPU_NoGroundFound #Get Position li r3,10 bl IntToFloat #Offset from P1 lfs f3,0xB0(P1Data) #P1 X lfs f2,0xB4(P1Data) #P1 Y lfs f4,0x2C(P1Data) #Facing Direction fmuls f1,f1,f4 fadds f1,f1,f3 #Check If P2 Will Be Grounded li r3,0 bl FindGroundNearPlayer cmpwi r3,0 #Check if ground was found beq MoveCPU_NoGroundFound stfs f1,0xB0(P2Data) stfs f2,0xB4(P2Data) stw r4,0x83C(P2Data) lfs f1,0x2C(P1Data) fneg f1,f1 stfs f1,0x2C(P2Data) #Enter Wait mr r3,P2GObj branchl r12,AS_Wait #Update Position mr r3,P2GObj bl UpdatePosition #Update ECB Values for the ground ID mr r3,P2GObj branchl r12,EnvironmentCollision_WaitLanding #Set Grounded mr r3,P2Data branchl r12,Air_SetAsGrounded #Check For Follower mr r3,P2GObj bl CheckIfPlayerHasAFollower cmpwi r3,0 beq MoveCPU_NoFollower mr P2Subchar,r3 mr P2SubcharData,r4 #Init Player Data Values (So CPU Init is called and nana knows where popp is) mr r3,P2Subchar branchl r12,0x80068354 #Copy Positions lfs f1,0xB0(P2Data) stfs f1,0xB0(P2SubcharData) lfs f1,0xB4(P2Data) stfs f1,0xB4(P2SubcharData) lwz r3,0x83C(P2Data) stw r3,0x83C(P2SubcharData) lfs f1,0x2C(P2Data) stfs f1,0x2C(P2SubcharData) #Enter Wait mr r3,P2Subchar branchl r12,AS_Wait #Update Position mr r3,P2Subchar bl UpdatePosition #Update ECB Values for the ground ID mr r3,P2Subchar branchl r12,EnvironmentCollision_WaitLanding #Set Grounded mr r3,P2SubcharData branchl r12,Air_SetAsGrounded MoveCPU_NoFollower: #Savestate mr r3,SaveStateStruct li r4,1 #Override failsafe code bl SaveState_Save #Play SFX li r3,0xDD bl PlaySFX b MoveCPUExit MoveCPU_NoGroundFound: #PLay Error SFX li r3,0xAF bl PlaySFX MoveCPUNoSubchar: MoveCPUExit: restore blr ############################################ AdjustResetDistance: .set SaveStateStruct,25 .set P2Direction,3 .set PlayerX,2 .set P1X,31 .set P2X,30 backup mr SaveStateStruct,r3 #Make Sure Nothing is Held lhz r3,0x662(r27) rlwinm. r0,r3,0,27,27 bne 0xC cmpwi r3,0x0 bne AdjustResetDistance_NoPress #Check For DPad Right AdjustResetDistance_CheckRightDPad: lwz r3,0x668(r27) #Get DPad rlwinm. r0,r3,0,30,30 beq AdjustResetDistance_CheckLeftDPad #Move Apart #Determine if P2 is to the left or right of P1 + Get X Pos Multiplier bl GetDirectionInRelationToP1 bl IntToFloat fmr P2Direction,f1 #Load P1 Backup X Location lwz r20,0x0(SaveStateStruct) lfs PlayerX,0xB0(r20) #Add One in the correct direction li r3,1 bl IntToFloat fneg P2Direction,P2Direction fmuls f1,f1,P2Direction fadds P1X,f1,PlayerX #New P1 X #Load P2 Backup X Location lwz r21,0x8(SaveStateStruct) lfs PlayerX,0xB0(r21) #Add One in the correct direction li r3,1 bl IntToFloat fneg P2Direction,P2Direction fmuls f1,f1,P2Direction fadds P2X,f1,PlayerX #New P2 X #Check if already 30 Mm apart fsubs f2,P1X,P2X fabs f2,f2 #get abs distance from each other in f2 li r3,30 bl IntToFloat fcmpo cr0,f2,f1 bge AdjustResetDistance_NoPress #Store Back To PlayerBlock stfs P1X,0xB0(r20) stfs P2X,0xB0(r21) b AdjustResetDistance_WasPressed #Check For DPad Left AdjustResetDistance_CheckLeftDPad: rlwinm. r0,r3,0,31,31 beq AdjustResetDistance_NoPress #Move Together #Determine if P2 is to the left or right of P1 + Get X Pos Multiplier bl GetDirectionInRelationToP1 bl IntToFloat fmr P2Direction,f1 #Load P1 Backup X Location lwz r20,0x0(SaveStateStruct) lfs PlayerX,0xB0(r20) #Add One in the correct direction li r3,1 bl IntToFloat #fneg P2Direction,P2Direction fmuls f1,f1,P2Direction fadds P1X,f1,PlayerX #New P1 X #Load P2 Backup X Location lwz r21,0x8(SaveStateStruct) lfs PlayerX,0xB0(r21) #Add One in the correct direction li r3,1 bl IntToFloat fneg P2Direction,P2Direction fmuls f1,f1,P2Direction fadds P2X,f1,PlayerX #New P2 X #Check if already 10 Mm apart fsubs f2,P1X,P2X fabs f2,f2 #get abs distance from each other in f2 li r3,10 bl IntToFloat fcmpo cr0,f2,f1 ble AdjustResetDistance_NoPress #Store Back To PlayerBlock stfs P1X,0xB0(r20) stfs P2X,0xB0(r21) b AdjustResetDistance_WasPressed AdjustResetDistance_NoPress: li r3,-1 b AdjustResetDistance_Exit AdjustResetDistance_WasPressed: li r3,1 AdjustResetDistance_Exit: restore blr ############################################ CheckForActiveHitboxes: backup lwz r31,0x2C(r3) CheckForActiveHitboxes_InitLoop: li r29,0x0 CheckForActiveHitboxes_LoopStart: lwz r0, 0x0914 (r31) #Check Hitbox Active Bool cmpwi r0,0x0 beq CheckForActiveHitboxes_NextHitbox li r3,0x1 b CheckForActiveHitboxes_Exit CheckForActiveHitboxes_NextHitbox: addi r29,r29,1 addi r31,r31,312 #Next Hitbox Struct cmpwi r29,4 blt CheckForActiveHitboxes_LoopStart CheckForActiveHitboxes_NoHitboxesActive: li r3,0x0 CheckForActiveHitboxes_Exit: restore blr ############################################# Event_ExitFunction: blrl backup #Ensure No Contest/Retry lwz r3, -0x77C0 (r13) lbz r3, 0x053B (r3) rlwinm. r0, r3, 0, 25, 25 bne Event_ExitFunction_Exit #Update Event Score load r20,0x8045abf0 #Current Event Info #Get High Score lbz r3,0x5(r20) #Event ID branchl r12,0x8015cf5c mr r21,r3 #Backup High Score #Check If Event Was Played Yet lbz r3,0x5(r20) #Event ID branchl r12,0x8015cefc cmpwi r3,0x0 beq Event_ExitFunction_SaveScore #Check If Greater lhz r3,-0x4ea6(r13) #Current Score cmpw r3,r21 ble Event_ExitFunction_Exit #Store As New High Score Event_ExitFunction_SaveScore: lbz r3,0x5(r20) #Event ID lhz r4,-0x4ea6(r13) branchl r12,0x8015cf70 #Set Event As Played lbz r3,0x5(r20) #Event ID branchl r12,0x8015ceb4 Event_ExitFunction_Exit: restore blr ############################################# InitializeHighScore: backup #Create HUD KO Counter li r3,0x0 branchl r12,0x802fa5bc #Init Score Count li r3,0x0 stw r3,-0x4ea8(r13) #Store Exit Function bl Event_ExitFunction mflr r3 load r4,0x8046b6a0 stw r3,0x2518(r4) restore blr ############################################# PerformAerialThink: #in # r3 CPU Player Pointer # r4 Pointer to dedicated memory to use # r5 Attack to Perform (0 = Random, 1 = Fair, 2 = Nair, 3 = Dair) .set player,31 .set playerdata,30 .set variables,29 .set frame,28 .set aerialToPerform,27 .set performAerial,0x00 .set aerialAttack,0x01 .set attackFrame,0x02 backup #Get player pointers and frame count mr player,r3 #Get Player lwz playerdata,0x2C(player) #Get Playerdata mr variables,r4 #Get Variable Memory lfs f1,0x894(playerdata) #Get Frames as Int fctiwz f1,f1 stfd f1,0xF0(sp) lwz frame,0xF4(sp) mr aerialToPerform,r5 #Aerial to perform #Check To Aerial lbz r3,performAerial(variables) cmpwi r3,0x0 bne PerformAerialThink_Exit #Check Which Action to Perform lwz r3,0x10(playerdata) #Get Action State #Branch To Think Functions #During Wait cmpwi r3,0xE beq PerformAerialThink_DuringWait #During Jump cmpwi r3,0x19 beq PerformAerialThink_DuringJump cmpwi r3,0x1A beq PerformAerialThink_DuringJump #During Attack cmpwi r3,0x41 blt 0x10 cmpwi r3,0x45 bgt 0x8 b PerformAerialThink_DuringAttack #During Landing cmpwi r3,0x2A beq PerformAerialThink_DuringLanding cmpwi r3,0x46 blt 0x10 cmpwi r3,0x4A bgt 0x8 b PerformAerialThink_DuringLanding #None of The Above b PerformAerialThink_Exit PerformAerialThink_DuringWait: #Input Jump li r3,0x800 stw r3,0x1A88(playerdata) #Determine Which Aerial Attack To Do #Check To Randomize cmpwi aerialToPerform,0x0 beq PerformAerialThink_GetRandomAttack #Store Attack Chosen subi r3,aerialToPerform,0x1 stb r3,aerialAttack(variables) b PerformAerialThink_CheckForValidAttack PerformAerialThink_GetRandomAttack: li r3,3 branchl r12,HSD_Randi stb r3,aerialAttack(variables) #Determine Frame to Attack on PerformAerialThink_CheckForValidAttack: lwz r4,0x4(playerdata) #get char ID bl PerformAerial_FrameData mflr r5 mulli r4,r4,0xC #Get Characters Offset add r4,r4,r5 #Get Characters Table Entry Start mulli r3,r3,0x2 #Move Frame Data is 0x2 Long add r27,r3,r4 #Get Moves Frame Data lbz r4,0x0(r27) #First Possible Frame lbz r5,0x1(r27) #Last Possible Frame cmpwi r4,0x0 bne PerformAerialThink_GetRandomFrame cmpwi r5,0x0 bne PerformAerialThink_GetRandomFrame #Move Disabled For Char, Get a New One b PerformAerialThink_GetRandomAttack PerformAerialThink_GetRandomFrame: sub r3,r5,r4 #Get Amount of Possibilities branchl r12,HSD_Randi #Get Random Frame lbz r4,0x0(r27) #First Possible Frame add r3,r3,r4 #Adjust for First Possible Frame stb r3,attackFrame(variables) #Store Frame to Attack on b PerformAerialThink_Exit PerformAerialThink_DuringJump: #Check To Attack lbz r3,attackFrame(variables) cmpw r3,frame bne PerformAerialThink_InputFastfallAndLCancel #Perform Attack lbz r3,aerialAttack(variables) #Get Attack ID cmpwi r3,0x0 beq PerformAerialThink_Fair cmpwi r3,0x1 beq PerformAerialThink_Nair cmpwi r3,0x2 beq PerformAerialThink_Dair PerformAerialThink_Fair: li r3,127 #Forward lfs f1,0x2C(playerdata) #Facing Direction fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) mullw r3,r3,r4 #Forward * facing direction stb r3,0x1A8E(playerdata) b PerformAerialThink_InputFastfallAndLCancel PerformAerialThink_Nair: li r3,0x100 stw r3,0x1A88(playerdata) b PerformAerialThink_InputFastfallAndLCancel PerformAerialThink_Dair: li r3,-127 stb r3,0x1A8F(playerdata) b PerformAerialThink_InputFastfallAndLCancel b PerformAerialThink_InputFastfallAndLCancel PerformAerialThink_DuringAttack: b PerformAerialThink_InputFastfallAndLCancel PerformAerialThink_DuringLanding: #Set Sequence as Over li r3,1 stb r3,performAerial(variables) b PerformAerialThink_Exit PerformAerialThink_InputFastfallAndLCancel: #Input Fastfall #Check If Already FastFalling lbz r3,0x221A(playerdata) rlwinm. r3,r3,0,28,28 bne PerformAerialThink_InputLCancel #Check If Falling lfs f2,0x84(playerdata) lfs f0, -0x76B0 (rtoc) fcmpo cr0,f2,f0 bge PerformAerialThink_InputLCancel #Check If Inputting A Nair lwz r3,0x1A88(playerdata) cmpwi r3,0x100 beq PerformAerialThink_InputLCancel #Input Down to FF li r3,-127 stb r3,0x1A8D(playerdata) #Analog Y PerformAerialThink_InputLCancel: #Spoof Mash L li r3,0x1 stb r3,0x67F(playerdata) b PerformAerialThink_Exit ################################# PerformAerial_FrameData: blrl #Mario .long 0x00040012 #Fair and Nair .long 0x00100005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Fox .long 0x0009000A #Fair and Nair .long 0x00080005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Cptn Falcon .long 0x0006000E #Fair and Nair .long 0x00040005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #DK .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Kirby .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Bowser .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #link .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Sheik .long 0x10140018 #Fair and Nair .long 0x00000005 #Dar (was 0-A) and UAir .long 0x0005FFFF #Bair and Nothing #Ness .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Peach .long 0x000D001A #Fair and Nair .long 0x000E0005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Popo .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Nana .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Pikachu .long 0x000C000F #Fair and Nair .long 0x00080005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Samus .long 0x00200020 #Fair and Nair .long 0x080D0005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Yoshi .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Jiggs .long 0x00100010 #Fair and Nair .long 0x00100005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #mewtwo .long 0x00050019 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Luigi .long 0x0017001B #Fair and Nair .long 0x00110005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Marth .long 0x00160013 #Fair and Nair .long 0x00120005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Zelda .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #YLink .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Doc .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Falco .long 0x070B000D #Fair and Nair .long 0x000C0005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Pichu .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #GaW .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Ganon .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #Roy .long 0x00050005 #Fair and Nair .long 0x00050005 #Dar and UAir .long 0x0005FFFF #Bair and Nothing #################################### PerformAerialThink_Exit: restore blr ##################################### RandFloat: #in #r3 = Rand Float Lower Bound #r4 = Rand Float Upper Bound backup stfs f31,0x80(sp) mr r31,r3 #Get Random Upper Bound sub r3,r4,r31 branchl r12,HSD_Randi #Add Lower Bound add r3,r3,r31 #Convert to Float bl IntToFloat fmr f31,f1 #Get Random Float branchl r12,HSD_Randf fadds f1,f1,f31 lfs f31,0x80(sp) restore blr ##################################### Custom_InterruptRebirthWait: blrl .set player,31 .set playdata,30 backup #Get Pointers mr player,r3 lwz playerdata,0x2C(player) #Check For Aerial Jump mr r3,player branchl r12,0x800cb870 cmpwi r3,0x0 bne Custom_InterruptRebirthWait_Exit #Ensure Stick Was Just Moved lbz r3, 0x0670 (playerdata) cmpwi r3,2 bge Custom_InterruptRebirthWait_CheckJoystickDown #Check For Any X Joystick Push lwz r3, -0x514C (r13) lfs f0, 0x0024 (r3) lfs f1, 0x0620 (playerdata) fabs f1,f1 fcmpo cr0,f1,f0 cror 2, 1, 2 beq Custom_InterruptRebirthWait_EnterFall Custom_InterruptRebirthWait_CheckJoystickDown: #Ensure Stick Was Just Moved lbz r3, 0x0671 (playerdata) cmpwi r3,4 bge Custom_InterruptRebirthWait_Exit #Check For Down Joystick Push lwz r3, -0x514C (r13) lfs f0, 0x0090 (r3) fneg f0,f0 lfs f1, 0x0624 (playerdata) fcmpo cr0,f1,f0 blt Custom_InterruptRebirthWait_EnterFall b Custom_InterruptRebirthWait_Exit Custom_InterruptRebirthWait_EnterFall: #Enter Fall mr r3,player branchl r12,AS_Fall Custom_InterruptRebirthWait_Exit: restore blr ##################################### UpdatePosition: .set PlayerGObj,31 .set PlayerData,30 backup #Backup Pointer mr PlayerGObj,r3 lwz PlayerData,0x2C(PlayerGObj) #Update Position (Copy Physics XYZ into all ECB XYZ) #X lwz r3, 0x00B0 (PlayerData) stw r3, 0x06F4 (PlayerData) stw r3, 0x0700 (PlayerData) stw r3, 0x070C (PlayerData) stw r3, 0x0718 (PlayerData) #Y lwz r3, 0x00B4 (PlayerData) stw r3, 0x06F8 (PlayerData) stw r3, 0x0704 (PlayerData) stw r3, 0x0710 (PlayerData) stw r3, 0x071C (PlayerData) #Z lwz r3, 0x00B8 (PlayerData) stw r3, 0x06FC (PlayerData) stw r3, 0x0708 (PlayerData) stw r3, 0x0714 (PlayerData) stw r3, 0x0720 (PlayerData) #Update Collision Frame ID lwz r3, -0x51F4 (r13) stw r3, 0x728(PlayerData) #branchl r12,0x80081b38 #Stopped using this because it deletes way too much ECB info #branchl r12,0x80082a68 #Better than the above function, but all i need is to copy current position into the ECB previous values #Adjust JObj position (code copied from 8006c324) lwz r3,0x28(PlayerGObj) #get character model JObj lwz r4,0xB0(PlayerData) #get X stw r4,0x38(r3) #store X lwz r4,0xB4(PlayerData) #get Y stw r4,0x3C(r3) #store Y lwz r4,0xB8(PlayerData) #get Z stw r4,0x40(r3) #store Z #Dirty Sub #branchl r12,0x803732e8 #Update Static Player Block Coords lbz r3,0xC(PlayerData) lbz r4, 0x221F (PlayerData) rlwinm r4, r4, 29, 31, 31 addi r5,PlayerData,176 branchl r12,0x80032828 restore blr ##################################### GetGroundCenter: #in #r3 = Ground ID #Get Corner IDs from Ground ID mulli r0,r3,8 lwz r5, -0x51E4 (r13) lwzx r5,r5,r0 lhz r3,0x0(r5) lhz r4,0x2(r5) #Get Coordinates lwz r5, -0x51E8 (r13) mulli r3,r3,24 addi r3,r3,8 add r3,r3,r5 lfs f1,0x0(r3) #Left X lfs f2,0x4(r3) #Left Y mulli r4,r4,24 addi r4,r4,8 add r4,r4,r5 lfs f3,0x0(r4) #Right X lfs f4,0x4(r4) #Right Y #Get Center Value lfs f5,-0x4df0(rtoc) #2f fadds f1,f1,f3 fdivs f1,f1,f5 #Center X fadds f2,f2,f4 fdivs f2,f2,f5 #Center Y blr #################################### PlacePlayersCenterStage: #in #none backup #Loop through players 1 and 2 .set count,27 .set player,26 .set playerdata,25 .set subchar,24 .set subchardata,23 li count,0 PlacePlayersCenterStage_Loop: #Get Player GObj mr r3,r27 branchl r12,PlayerBlock_LoadMainCharDataOffset #Check if exists cmpwi r3,0x0 beq PlacePlayersCenterStage_IncLoop mr player,r3 lwz playerdata,0x2C(player) #Get Subchar Bool bl CheckIfPlayerHasAFollower mr subchar,r3 mr subchardata,r4 #Call function to do heavy lifting mr r3,player bl PlacePlayersCenterStage_DoStuff #Check if subchar exits cmpwi subchar,0 beq PlacePlayersCenterStage_IncLoop #Call function for this character mr r3,subchar bl PlacePlayersCenterStage_DoStuff #Next Player PlacePlayersCenterStage_IncLoop: addi count,count,1 cmpwi count,6 blt PlacePlayersCenterStage_Loop b PlacePlayersCenterStage_Exit #*****************************# PlacePlayersCenterStage_DoStuff: #in #r3 = player .set player,31 .set playerdata,30 .set constants,29 backup #Get Pointers mr player,r3 lwz playerdata,0x2C(r3) #Get Constants bl PlacePlayersCenterStage_Constants mflr constants lbz r3,0xC(playerdata) mulli r3,r3,0x2 add constants,constants,r3 #Initialize Player Data (Mainly for ICs so Nana knows where Popo is) mr r3,player branchl r12,0x80068354 #Get Stage's Ground ID lwz r3,-0x6CB8 (r13) #External Stage ID bl ComboTraining_StartingGroundIDs mflr r4 mulli r3,r3,0x2 lhzx r3,r3,r4 bl GetGroundCenter fmr f30,f1 fmr f31,f2 #Facing Directions lbz r3,0x0(constants) #This players facing direction extsb r3,r3 bl IntToFloat stfs f1,0x2C(playerdata) #Move Players lbz r3,0x1(constants) #This players X offset extsb r3,r3 bl IntToFloat fadds f2,f1,f30 #Player X = X+6 stfs f2,0xB0(playerdata) stfs f31,0xB4(playerdata) #Enter into Wait mr r3,player branchl r12,AS_Wait #Find Ground Below Player mr r3,player bl FindGroundNearPlayer cmpwi r3,0 #Check if ground was found beq PlacePlayersCenterStage_DoStuff_SkipGroundCorrection stfs f1,0xB0(playerdata) stfs f2,0xB4(playerdata) stw r4,0x83C(playerdata) PlacePlayersCenterStage_DoStuff_SkipGroundCorrection: #Update Position mr r3,player bl UpdatePosition #Update ECB Values for the ground ID mr r3,player branchl r12,EnvironmentCollision_WaitLanding #Set Grounded mr r3,playerdata branchl r12,Air_SetAsGrounded #Update Camera mr r3,player bl UpdateCameraBox PlacePlayersCenterStage_DoStuff_Exit: restore blr #*********# PlacePlayersCenterStage_Constants: blrl .byte 1,-6,-1,6 .align 2 #*********# PlacePlayersCenterStage_Exit: restore blr ##################################### FindGroundNearPlayer: #in #r3 = player GObj (optional) #f1 = X value #f2 = Y Value .set player,31 .set playerdata,30 backup stfs f30,0x38(sp) stfs f31,0x3C(sp) #Check If Given Player GObj cmpwi r3,0x0 bne FindGroundNearPlayer_GObjPassedIn FindGroundNearPlayer_CoordinatesPassedIn: #Backup Coords fmr f30,f1 fmr f31,f2 #Get 10f li r3,10 bl IntToFloat #Get Bottom Coord fmr f3,f30 #Bottom X is same as Top X fsubs f4,f31,f1 #Bottom Y is Top Y - 1000 #Move Top Coords Back fmr f1,f30 fmr f2,f31 lfs f0, -0x7188 (rtoc) fadds f2,f2,f0 b FindGroundNearPlayer_Continue FindGroundNearPlayer_GObjPassedIn: #Init Variables mr player,r3 lwz playerdata,0x2C(player) #Get Players X and Y+10 lfs f1,0xB0(playerdata) lfs f2,0xB4(playerdata) lfs f0, -0x7188 (rtoc) fadds f2,f2,f0 #Get Bottom Coord (X and Y-1000) lfs f3,0xB0(playerdata) lfs f4,0xB0(playerdata) lfs f0,-0x71A8 (rtoc) fsubs f4,f4,f0 FindGroundNearPlayer_Continue: #Get Unk f5 argument lfs f5, -0x7208 (rtoc) #Setup stack for return values addi r3,sp,0x54 #(Returns Ground Coordinates addi r4,sp,0x44 #(Returns Ground ID) addi r5,sp,0x40 #(Returns Ground Type) addi r6,sp,0x48 #(Returns Unk) #Unk arguments li r7,-1 li r8,-1 li r9,-1 #Additional function pointer li r10,0 #Call function branchl r12,Raycast_GroundLine #Check if ground exists cmpwi r3,0 beq FindGroundNearPlayer_Exit #Return Coordinates of ground below player lfs f1,0x54(sp) lfs f2,0x58(sp) lwz r4,0x44(sp) FindGroundNearPlayer_Exit: lfs f30,0x38(sp) lfs f31,0x3C(sp) restore blr ##################################### FindGroundUnderCoordinate: #in #f1 = X value #f2 = Y Value backup stfs f30,0x38(sp) stfs f31,0x3C(sp) FindGroundUnderCoordinate_CoordinatesPassedIn: #Backup Coords fmr f30,f1 fmr f31,f2 #Get 1000f li r3,1000 bl IntToFloat #Get Bottom Coord fmr f3,f30 #Bottom X is same as Top X fsubs f4,f31,f1 #Bottom Y is Top Y - 1000 #Move Top Coords Back fmr f1,f30 fmr f2,f31 FindGroundUnderCoordinate_Continue: #Get Unk f5 argument lfs f5, -0x7208 (rtoc) #Setup stack for return values addi r3,sp,0x54 #(Returns Ground Coordinates addi r4,sp,0x44 #(Returns Ground ID) addi r5,sp,0x40 #(Returns Ground Type) addi r6,sp,0x48 #(Returns Unk) #Unk arguments li r7,-1 li r8,-1 li r9,-1 li r10,0 #Call function branchl r12,Raycast_GroundLine #Check if ground exists cmpwi r3,0 beq FindGroundUnderCoordinate_Exit #Return Coordinates of ground below player lfs f1,0x54(sp) lfs f2,0x58(sp) lwz r4,0x44(sp) FindGroundUnderCoordinate_Exit: lfs f30,0x38(sp) lfs f31,0x3C(sp) restore blr ##################################### PlacePlayerOnGround: backup .set REG_GObj,31 .set REG_GObjData,30 #Get Pointers mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) #Find Ground Below Player mr r3,REG_GObj bl FindGroundNearPlayer cmpwi r3,0 #Check if ground was found beq PlacePlayerOnGround_SkipGroundCorrection stfs f1,0xB0(REG_GObjData) stfs f2,0xB4(REG_GObjData) stw r4,0x83C(REG_GObjData) PlacePlayerOnGround_SkipGroundCorrection: #Update Position mr r3,REG_GObj bl UpdatePosition #Update ECB Values for the ground ID mr r3,REG_GObj branchl r12,EnvironmentCollision_WaitLanding #Set Grounded mr r3,REG_GObjData branchl r12,Air_SetAsGrounded PlacePlayerOnGround_Exit: restore blr ##################################### PlaySFX: backup branchl r12,SFX_PlaySoundAtFullVolume restore blr ##################################### UpdateCameraBox: #in #r3 = player .set player,31 .set playerdata,30 backup #Get Pointer mr player,r3 lwz playerdata,0x2C(player) #Update Camera Box Position mr r3,player branchl r12,Camera_UpdatePlayerCameraBoxPosition #Update Camera Box Direction Tween # lwz r3,0x2C(player) # branchl r12,0x80076064 #Update Camera Box Direction Tween lwz r3,0x890(playerdata) lfs f1,0x40(r3) #Leftmost Bound stfs f1,0x2C(r3) #Current Left Box Bound lfs f1,0x44(r3) #Rightmost Bound stfs f1,0x30(r3) #Current Right Box Bound #Correct Camera Position branchl r12,Camera_CorrectPosition restore blr ##################################### GetAllPlayerPointers: #in #nothing #out #r3 = P1GObj #r4 = P1Data #r5 = P2GObj #r6 = P2Data #r7 = P3GObj #r8 = P3Data #r9 = P4GObj #r10 = P4Data backup #Get Space to Store all Pointer to addi r21,sp,0x40 #Init Loop Count li r20,0 GetAllPlayerPointers_Loop: #Get GObj mr r3,r20 branchl r12,PlayerBlock_LoadMainCharDataOffset #Check If Exists cmpwi r3,0x0 li r4,0 #Zero Data pointer just in case it doesnt exist beq GetAllPlayerPointers_StoreToStack #Get Data lwz r4,0x2C(r3) #Store Both to Stack GetAllPlayerPointers_StoreToStack: mulli r5,r20,8 add r5,r5,r21 stw r3,0x0(r5) stw r4,0x4(r5) GetAllPlayerPointers_IncLoop: addi r20,r20,1 cmpwi r20,4 blt GetAllPlayerPointers_Loop GetAllPlayerPointers_LoadPointers: lwz r3,0x00(r21) lwz r4,0x04(r21) lwz r5,0x08(r21) lwz r6,0x0C(r21) lwz r7,0x10(r21) lwz r8,0x14(r21) lwz r9,0x18(r21) lwz r10,0x1C(r21) GetAllPlayerPointers_Exit: restore blr ##################################### RemoveFirstFrameInputs: RemoveFirstFrameInputs_GetFirstPlayer: lwz r3, -0x3E74 (r13) lwz r12, 0x0020 (r3) b RemoveFirstFrameInputs_CheckIfPlayerExists RemoveFirstFrameInputs_GetNextPlayer: lwz r12,0x8(r12) RemoveFirstFrameInputs_CheckIfPlayerExists: cmpwi r12,0x0 beq RemoveFirstFrameInputs_Exit lwz r5,0x2C(r12) #Remove Input Flag lbz r0, 0x221D (r5) li r3,0x1 rlwimi r0,r3,4,27,27 stb r0,0x221D (r5) #Store Current Input lbz r4, 0x0618 (r5) load r3,InputStructStart mulli r0, r4, 68 add r3, r0, r3 lwz r0, 0 (r3) stw r0, 0x065C (r5) b RemoveFirstFrameInputs_GetNextPlayer RemoveFirstFrameInputs_Exit: blr ##################################### InitializeMatch: .set REG_EventStruct,31 .set REG_MatchStruct,30 .set REG_CPUChoice,29 .set REG_StageChoice,28 .set REG_EventOSDs,27 .set REG_PlayerStruct,26 .set REG_UseSopo,25 #Init backup mr REG_EventStruct,r3 mr REG_MatchStruct,r4 mr REG_CPUChoice,r5 mr REG_StageChoice,r6 mr REG_EventOSDs,r7 mr REG_UseSopo,r8 #Check to override OSD Toggles lwz r4,-0x77C0(r13) lbz r3,0x1f2A(r4) cmpwi r3,1 beq InitializeMatch_SkipOSDOverride #Store Events FDD Toggles lwz r3,0x1F24(r4) or r3,r3,REG_EventOSDs stw r3,0x1F24(r4) InitializeMatch_SkipOSDOverride: #SPAWN 2 PLAYERS li r3,0x40 stb r3,0x1(REG_EventStruct) #Make Copy of Struct li r3,32 branchl r12,HSD_MemAlloc mr REG_PlayerStruct,r3 bl P2Struct mflr r4 li r5,0x1C branchl r12,memcpy #Store to P2 pointer in event struct stw REG_PlayerStruct,0x18(REG_EventStruct) #Store CPU cmpwi REG_CPUChoice,-1 beq InitializeMatch_StoreCSSCPU #Store this CPU stb REG_CPUChoice,0x0(REG_PlayerStruct) b InitializeMatch_StoreStage InitializeMatch_StoreCSSCPU: load r3,0x8043207c #get preload table lwz r4,0x18(r3) #get p2 character ID cmpwi r4,0x12 #check if zelda bne 0x8 li r4,0x13 #make zelda sheik stb r4,0x0(REG_PlayerStruct) #store chosen char lbz r6,0x1C(r3) #get p2 costume ID stb r6,0x3(REG_PlayerStruct) #store p2 costume ID li r5,0x1 #make CPU controlled stb r5,0x1(REG_PlayerStruct) InitializeMatch_StoreStage: #Store Stage cmpwi REG_StageChoice,-1 beq InitializeMatch_StoreSSSStage #Store this Stage sth REG_StageChoice,0xE(REG_MatchStruct) b InitializeMatch_StoreStage_End InitializeMatch_StoreSSSStage: load r3,0x8043207c #get preload table lwz r3, 0x00C (r3) sth r3,0xE(REG_MatchStruct) #store chosen stage InitializeMatch_StoreStage_End: InitializeMatch_SwapInSopo: cmpwi REG_UseSopo,0 beq InitializeMatch_SwapInSopo_End #Swap P1 Character to Sopo lwz r4, -0x77C0 (r13) addi r4, r4, 1328 #event mode match backup struct? lbz r3,0x2(r4) #P1 External ID cmpwi r3,0xE bne InitializeMatch_SwapInSopo_End li r3,0x20 stb r3,0x2(r4) #Make SoPo InitializeMatch_SwapInSopo_End: InitializeMatch_Exit: restore blr ##################################### GetDistance: lfs f3,0x0(r3) #X lfs f4,0x4(r3) #Y lfs f5,0x0(r4) #X lfs f6,0x4(r4) #Y fsubs f1,f5,f3 fsubs f2,f4,f6 fmuls f1,f1,f1 fmuls f2,f2,f2 fadds f2,f1,f2 frsqrte f1,f2 fmuls f1,f1,f2 blr ##################################### GetLedgeCoordinates: .set LedgeSide,20 .set LedgeID,21 .set Return,22 backup #Backup Ledge Choice (0 = Left, 1 = Right) mr LedgeSide,r3 mr Return,r4 #Get Stage's Ledge IDs lwz r3,-0x6CB8 (r13) #External Stage ID bl LedgedashCliffIDs mflr r4 mulli r3,r3,0x2 lhzx r3,r3,r4 #Get Requested Ledge cmpwi LedgeSide,0x0 beq GetLedgeCoordinates_GetLeftLedgeID GetLedgeCoordinates_GetRightLedgeID: rlwinm LedgeID,r3,0,24,31 #Get Ledge Coords (0x80 = X, 0x84 = Y) mr r3,LedgeID mr r4,Return branchl r12,Stage_GetRightOfLineCoordinates b GetLedgeCoordinates_Exit GetLedgeCoordinates_GetLeftLedgeID: rlwinm LedgeID,r3,24,24,31 #Get Ledge Coords (0x80 = X, 0x84 = Y) mr r3,LedgeID mr r4,Return branchl r12,Stage_GetLeftOfLineCoordinates b GetLedgeCoordinates_Exit GetLedgeCoordinates_Exit: restore blr ########################################## GetAngleBetweenPoints: .set REG_arctan,2 .set REG_Constants,31 backup #Get Constants bl GetAngleBetweenPoints_Constants mflr REG_Constants #Get Values lfs f1,0x0(r3) lfs f2,0x4(r3) lfs f3,0x0(r4) lfs f4,0x4(r4) #Get slope ydelta / xdelta fsubs f5,f4,f2 fsubs f6,f3,f1 fdivs f1,f5,f6 #atan branchl r12,0x80022e68 fmr REG_arctan,f1 #Ensure above 0 and below 6.28319 GetAngleBetweenPoints_CheckIfOver0: lfs f1,0x0(REG_Constants) fcmpo cr0,REG_arctan,f1 bge GetAngleBetweenPoints_CheckIfUnder360 #Add 180 lfs f1,0x8(REG_Constants) fadds REG_arctan,REG_arctan,f1 b GetAngleBetweenPoints_CheckIfOver0 GetAngleBetweenPoints_CheckIfUnder360: lfs f1,0x4(REG_Constants) fcmpo cr0,REG_arctan,f1 ble GetAngleBetweenPoints_Under360 #Add 180 lfs f1,0x8(REG_Constants) fsubs REG_arctan,REG_arctan,f1 b GetAngleBetweenPoints_CheckIfUnder360 GetAngleBetweenPoints_Under360: fmr f1,REG_arctan GetAngleBetweenPoints_Exit: restore blr GetAngleBetweenPoints_Constants: blrl .float 0 .float 6.28319 .float 3.14159 ########################################## EnterKnockback: backup .set REG_GObj,31 .set REG_GObjData,30 .set REG_AngleLo,29 .set REG_AngleHi,28 .set REG_MagLo,27 .set REG_MagHi,26 .set REG_Angle,29 .set REG_Magnitude,28 #Backup Data mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) mr REG_AngleLo,r4 mr REG_AngleHi,r5 mr REG_MagLo,r6 mr REG_MagHi,r7 #Random angle between sub r3,REG_AngleHi,REG_AngleLo branchl r12,HSD_Randi add REG_Angle,r3,REG_AngleLo #Cast to float mr r3,REG_Angle bl IntToFloat #Now in radians lfs f2, -0x7510 (rtoc) fmuls f1,f1,f2 stfs f1,0x80(sp) #Random magnitude between X and Y mr r3,REG_MagLo mr r4,REG_MagHi bl RandFloat stfs f1,0x7C(sp) #will be used later for lwz r3, -0x514C (r13) lfs f0, 0x0100 (r3) fmuls f1,f1,f0 stfs f1,0x84(sp) #Get X Component lfs f1,0x80(sp) #KB angle in radians branchl r12,cos lfs f2,0x84(sp) #KB magnitude fmuls f1,f1,f2 lfs f2,0x2C(REG_GObjData) fneg f2,f2 fmuls f1,f1,f2 stfs f1,0x8C(REG_GObjData) #Get Y Component lfs f1,0x80(sp) #KB angle in radians branchl r12,sin lfs f2,0x84(sp) #KB magnitude fmuls f1,f1,f2 stfs f1,0x90(REG_GObjData) #Calculate Hitstun lwz r3, -0x514C (r13) lfs f0, 0x0154 (r3) lfs f1,0x7C(sp) fmuls f1,f1,f0 #hitstun frames is 0.4 * magnitude fctiwz f1,f1 #Round down stfd f1,0x88(sp) lwz r3,0x8C(sp) bl IntToFloat stfs f1,0x2340(REG_GObjData) #Enable Hitstun Bit lbz r0,0x221C(REG_GObjData) li r3,1 rlwimi r0,r3,1,30,30 stb r0,0x221C(REG_GObjData) #Enable ECB Update mr r3,REG_GObjData branchl r12,0x8007d5bc EnterKnockback_Exit: restore blr ########################################## DisableHazards: #Get list start bl DisableHazards_SkipList ######################## bl DisableHazards_Dummy bl DisableHazards_TEST bl DisableHazards_Izumi bl DisableHazards_Pstadium bl DisableHazards_Castle bl DisableHazards_Kongo bl DisableHazards_Zebes bl DisableHazards_Corneria bl DisableHazards_Story bl DisableHazards_Onett bl DisableHazards_MuteCity bl DisableHazards_RCruise bl DisableHazards_Garden bl DisableHazards_GreatBay bl DisableHazards_Shrine bl DisableHazards_Kraid bl DisableHazards_Yoster bl DisableHazards_Greens bl DisableHazards_Fourside bl DisableHazards_MK1 bl DisableHazards_MK2 bl DisableHazards_Akaneia bl DisableHazards_Venom bl DisableHazards_Pura bl DisableHazards_BigBlue bl DisableHazards_Icemt bl DisableHazards_Icetop bl DisableHazards_FlatZone bl DisableHazards_OldDL bl DisableHazards_OldYS bl DisableHazards_OldKongo bl DisableHazards_Battlefield bl DisableHazards_FinalDestination ######################## DisableHazards_SkipList: mflr r3 lwz r4,StageID_External(r13) mulli r4,r4,4 add r4,r3,r4 lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) cmpwi r5,0 #If pointer is null, exit beq DisableHazards_SkipList_Exit add r4,r4,r5 #Pointer to code now in r4 mtctr r4 bctr ######################## DisableHazards_Story: /* #Get randall's line ID mr r3,REG_map_gobj branchl r12,0x801c6330 lwz r3,0x4(r3) #get map_head lwz r3,0x8(r3) #get map_gobj info mulli r4,REG_map_gobj,52 #get randall's info add r3,r3,r4 lwz r3,0x20(r3) #pointer to the collision data lhz r3,0x0(r3) #i believe this is randalls line ID #Get randalls corner IDs mulli r3,r3,8 #0x8 in length lwz r4, -0x51E4 (r13) #line to corner ID table lwzx r5,r3,r4 #now have the corner ID struct lhz r3,0x0(r5) #left corner id lhz r4,0x2(r5) #right corner id #Get corner IDs info lwz r5, -0x51E8 (r13) mulli r3,r3,24 mulli r4,r4,24 add r3,r3,r5 add r4,r4,r5 #Zero current X and Y positions, effectively removing these lines li r5,0 stw r5,0x8(r3) stw r5,0xC(r3) stw r5,0x8(r4) stw r5,0xC(r4) */ /* #Get randall's map_gobj li r3,2 #randalls map_gobj is 2 branchl r12,Stage_map_gobj_Load branchl r12,Stage_Destroy_map_gobj */ #Get shyguy's map_gobj li r3,3 #shyguys map_gobj is branchl r12,Stage_map_gobj_Load #Remove Proc branchl r12,GObj_RemoveProc #Fix ragdoll issue bl DisableHazards_RagdollFix b DisableHazards_SkipList_Exit ######################## DisableHazards_Pstadium: #Get transformation's map_gobj li r3,2 #transformation's map_gobj ID branchl r12,Stage_map_gobj_Load #Remove Proc branchl r12,GObj_RemoveProc #Fix ragdoll issue bl DisableHazards_RagdollFix b DisableHazards_SkipList_Exit ######################## DisableHazards_OldDL: #Destroy whispy's map_gobj li r3,7 #transformation's map_gobj ID branchl r12,Stage_map_gobj_Load branchl r12,Stage_Destroy_map_gobj #Destroy whispy's blink map_gobj proc li r3,6 #transformation's map_gobj ID branchl r12,Stage_map_gobj_Load branchl r12,GObj_RemoveProc #set wind hazard count to 0 li r3,0 stw r3,Stage_PositionHazardCount(r13) b DisableHazards_SkipList_Exit ######################## DisableHazards_OldYS: #Destroy cloud's map_gobj li r3,2 #map_gobj ID branchl r12,Stage_map_gobj_Load branchl r12,Stage_Destroy_map_gobj b DisableHazards_SkipList_Exit ######################## DisableHazards_OldKongo: #Destroy barrel's map_gobj li r3,1 #map_gobj ID branchl r12,Stage_map_gobj_Load branchl r12,Stage_Destroy_map_gobj b DisableHazards_SkipList_Exit ######################## DisableHazards_RagdollFix: #Certain stages have an essential ragdoll function #in their map_gobj think function. If the think function is removed, #the ragdoll function must be re-scheduled to function properly. backup #Create GObj li r3,3 #GObj Type li r4,5 #On-Pause Function li r5,0 branchl r12,GObj_Create #Schedule Task bl DisableHazards_RagdollFix_Think mflr r4 li r5,4 #Priority branchl r12,GObj_AddProc b DisableHazards_RagdollFix_Exit #********************************# DisableHazards_RagdollFix_Think: blrl backup branchl r12,Ragdoll_WindDecayThink restore blr #********************************# DisableHazards_RagdollFix_Exit: restore blr ######################### DisableHazards_SkipList_Exit: restore blr ########################################### PlaybackInputSequence: .set REG_PlayerData,31 .set REG_InputSequence,30 .set REG_AttackTimer,29 #Input Sequence Struct .set InputSequence_Length,0x9 .set InputSequence_Frame,0x0 .set InputSequence_Buttons,0x1 .set InputSequence_AnalogX,0x5 .set InputSequence_AnalogY,0x6 .set InputSequence_CStickX,0x7 .set InputSequence_CStickY,0x8 backup #Backup args mr REG_PlayerData,r3 mr REG_InputSequence,r4 mr REG_AttackTimer,r5 PlaybackInputSequence_Loop: #Search for this frames input in the sequence lbz r3,InputSequence_Frame(REG_InputSequence) #Check if end of sequence extsb r0,r3 cmpwi r0,-1 beq PlaybackInputSequenceExit #Check if this frame's input cmpw r5,r3 beq PlaybackInputSequence_PlayInput blt PlaybackInputSequenceExit #Check if the current frame is less than the parsed frame #If greater, continue parsing addi REG_InputSequence,REG_InputSequence,InputSequence_Length b PlaybackInputSequence_Loop #If greater, continue parsing PlaybackInputSequence_PlayInput: lwz r3,InputSequence_Buttons(REG_InputSequence) stw r3,CPU_HeldButtons(REG_PlayerData) lbz r3,InputSequence_AnalogX(REG_InputSequence) stb r3,CPU_AnalogX(REG_PlayerData) lbz r3,InputSequence_AnalogY(REG_InputSequence) stb r3,CPU_AnalogY(REG_PlayerData) lbz r3,InputSequence_CStickX(REG_InputSequence) stb r3,CPU_CStickX(REG_PlayerData) lbz r3,InputSequence_CStickY(REG_InputSequence) stb r3,CPU_CStickY(REG_PlayerData) PlaybackInputSequenceExit: restore blr ########################################### PlaceOnLedge: backup .set REG_LedgeID,31 .set REG_P1GObj,30 .set REG_P1Data,29 #Backup pointers mr REG_P1GObj,r3 lwz REG_P1Data,0x2C(REG_P1GObj) mr REG_LedgeID,r4 #Get Stage's Ledge IDs lwz r3,-0x6CB8 (r13) #External Stage ID bl LedgedashCliffIDs mflr r4 mulli r3,r3,0x2 lhzx r3,r3,r4 #Get Requested Ledge cmpwi REG_LedgeID,0x0 beq PlaceOnLedge_GetLeftLedgeID PlaceOnLedge_GetRightLedgeID: rlwinm r20,r3,0,24,31 #Change Facing Direction li r3,-1 bl IntToFloat stfs f1,0x2C(REG_P1Data) b PlaceOnLedge_StoreLedgeIDAndPosition PlaceOnLedge_GetLeftLedgeID: rlwinm r20,r3,24,24,31 #Change Facing Direction li r3,1 bl IntToFloat stfs f1,0x2C(REG_P1Data) b PlaceOnLedge_StoreLedgeIDAndPosition PlaceOnLedge_StoreLedgeIDAndPosition: #Store Ledge to Player Block stw r20,0x2340(REG_P1Data) #Enter CliffWait mr r3,REG_P1GObj branchl r12,AS_CliffWait #Init state variable (would be 1 at the start of the next frame if it ocurred naturally) li r3,1 stw r3,0x2348(REG_P1Data) #Spoof in state for 1 frame li r3,1 sth r3,TM_FramesinCurrentAS(REG_P1Data) #Get Jump Back mr r3,REG_P1Data branchl r12,Air_StoreBool_LoseGroundJump_NoECBfor10Frames #Set ECB Update Flag mr r3,REG_P1Data branchl r12,DataOffset_ECBBottomUpdateEnable #Update ECB Corner Positions addi r3,REG_P1Data,0x6F0 branchl r12,0x80048160 #Move Player To Ledge mr r3,REG_P1GObj branchl r12,MovePlayerToLedge #Update Position mr r3,REG_P1GObj bl UpdatePosition #Kill Velocity li r3,0x0 stw r3,0x80(REG_P1Data) #X Velocity stw r3,0x84(REG_P1Data) #Y Velocity #Give Intangibility (30) mr r3,REG_P1GObj lwz r4, -0x514C (r13) lwz r4, 0x049C (r4) branchl r12,ApplyIntangibility restore blr ########################################### GetInputStruct: load r4,InputStructStart mulli r0, r3, 68 add r3, r0, r4 blr ########################################### exit: li r0, 3 ================================================ FILE: ASM/training-mode/Custom Events/Custom Event Preload Behavior/Disable Event Preload - CSS Enter.asm ================================================ #To be inserted at 801baaa8 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 .set playerdata,31 CustomEvent: branch r12,0x801baabc ================================================ FILE: ASM/training-mode/Custom Events/Custom Event Preload Behavior/Disable Event Preload - Match Enter.asm ================================================ #To be inserted at 801bb648 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 .set playerdata,31 li r0,-1 #Load -1, which doesnt attempt to hijack any preload table values ================================================ FILE: ASM/training-mode/Custom Events/Custom Event Preload Behavior/Disable Event Preload.asm ================================================ #To be inserted at 803db000 .long 0x012b0000 ================================================ FILE: ASM/training-mode/Custom Events/Custom Event Preload Behavior/Dont Adjust CPU Color in Event Mode When Its Already in Use.asm ================================================ #To be inserted at 801bb294 .include "../../Globals.s" .include "../../../m-ex/Header.s" b 0x30 ================================================ FILE: ASM/training-mode/Custom Events/Custom Event Preload Behavior/Load Character ssm Files.asm ================================================ #To be inserted at 801bab04 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 .set playerdata,31 backup mr r31,r3 #Loop through selected characters and load .ssm files mr r27,r31 li r28,0 mulli r0,r28,36 li r29,0 li r30,0 Loop: lbz r3,0x70(r27) extsb r3,r3 branchl r12,0x80026e84 addi r28,r28,1 cmpwi r28,6 or r29,r29,r4 or r30,r30,r3 addi r27,r27,36 blt Loop #Clear Audio Cache? li r3,20 branchl r12,0x80026f2c #Request All ssm Files li r3,4 mr r5,r30 mr r6,r29 branchl r12,0x8002702c #Load Preload Cache branchl r12,0x80027168 exit: mr r3,r31 restore addi r4, r31, 2 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Backup FDD Backup on Event Choose.asm ================================================ #To be inserted at 8024d95c .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 .set playerdata,31 #Backup lwz r6,-0x77C0(r13) lwz r5,0x1F24(r6) stw r5,-0xDA8(rtoc) Exit: lwz r3, 0x0004 (r28) ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Better X and Y Event Jump/Jump Down - Update Cursor.asm ================================================ #To be inserted at 8024da98 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" #Update cursor position #Get Texture Data lwz r3, -0x4A40 (r13) lwz r3, 0x0028 (r3) addi r4,sp,0x40 li r5,11 li r6,-1 crclr 6 branchl r12,0x80011e24 #Get New Y Offset lis r0,0x4330 stw r0,0xA8(sp) lwz r3, -0x4A40 (r13) lwz r3, 0x002C (r3) lbz r3,0x0(r3) #event selection ID stw r3,0xAC(sp) lfd f1,0xA8(sp) lfd f2, -0x3888 (rtoc) fsubs f1,f1,f2 bl Float mflr r3 lfs f2,0x0(r3) fmuls f1,f1,f2 #Change Y offset lwz r3,0x40(sp) stfs f1,0x3C(r3) #DirtySub lwz r3,0x40(sp) branchl r12,0x803732e8 b Original Float: blrl .float -1.32 Original: mr r3,r28 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Better X and Y Event Jump/Jump Down.asm ================================================ #To be inserted at 8024d998 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set EventID,31 .set PageID,30 .set NumOfEvents,30 backup #Get Current Event lbz r3,0x0(r28) lwz r4,0x4(r28) add EventID,r3,r4 #Get Current Page lwz r3,MemcardData(r13) lbz PageID,CurrentEventPage(r3) #Get pointer page's string array bl SkipJumpTable ##### Page List ####### EventJumpTable ####################### SkipJumpTable: #Get number of events on this page mflr r4 #Jump Table Start in r4 mulli r5,PageID,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r5,r4,r5 #Gets Address in r4 lwz NumOfEvents,0x0(r5) #Check if already on last event cmpw EventID,NumOfEvents bge exit #Jump 9 events addi r3,EventID,9 #Check if exceeded NumOfEvents cmpw r3,NumOfEvents bge LastEvent JumpEvent: #add 9 to event ID lbz r3,0x0(r28) addi r3,r3,9 stb r3,0x0(r28) b UpdateText LastEvent: #if NumOfEvents >= 9, event ID = 9, scroll ID = NumOfEvents-8 cmpwi NumOfEvents,9 blt LessThan9Events GreaterThan9Events: li r3,8 stb r3,0x0(r28) subi r3,NumOfEvents,8 stw r3,0x4(r28) b UpdateText LessThan9Events: #if NumOfEvents < 9, event ID = NumOfEvents, scroll ID = 0 stb NumOfEvents,0x0(r28) li r3,0 stw r3,0x4(r28) b UpdateText ############################# EventAmountPerPage ############################## UpdateText: #overflow event ID to scroll ID lbz r3,0x0(r28) cmpwi r3,8 ble 0x1C #get overflow and add to scroll subi r3,r3,8 lwz r4,0x4(r28) add r3,r3,r4 stw r3,0x4(r28) #add to scroll li r3,8 stb r3,0x0(r28) #now Correct Scroll lwz r3,0x4(r28) subi r4,NumOfEvents,8 cmpw r3,r4 ble UpdateText1 #Highlight last entry cmpwi NumOfEvents,8 bgt 0x10 mr r3,NumOfEvents li r4,0 b 0x8 li r3,8 #highlight last entry stb r3,0x0(r28) stw r4,0x4(r28) #last scroll UpdateText1: #Play SFX and Update Text li r3,2 branchl r12,0x80024030 restore branch r12,0x8024d9dc exit: restore branch r12,0x8024e198 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Better X and Y Event Jump/Jump Up - Update Cursor.asm ================================================ #To be inserted at 8024dbb4 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" #Update cursor position #Get Texture Data lwz r3, -0x4A40 (r13) lwz r3, 0x0028 (r3) addi r4,sp,0x40 li r5,11 li r6,-1 crclr 6 branchl r12,0x80011e24 #Get New Y Offset lis r0,0x4330 stw r0,0xA8(sp) lwz r3, -0x4A40 (r13) lwz r3, 0x002C (r3) lbz r3,0x0(r3) #event selection ID stw r3,0xAC(sp) lfd f1,0xA8(sp) lfd f2, -0x3888 (rtoc) fsubs f1,f1,f2 bl Float mflr r3 lfs f2,0x0(r3) fmuls f1,f1,f2 #Change Y offset lwz r3,0x40(sp) stfs f1,0x3C(r3) #DirtySub lwz r3,0x40(sp) branchl r12,0x803732e8 b Original Float: blrl .float -1.32 Original: mr r3,r28 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Better X and Y Event Jump/Jump Up.asm ================================================ #To be inserted at 8024dabc .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set EventID,31 .set PageID,30 .set NumOfEvents,30 backup #Get Current Event lbz r3,0x0(r28) lwz r4,0x4(r28) add EventID,r3,r4 #Check if already on first event cmpwi EventID,0 ble exit #Jump 9 events subi r3,EventID,9 #Check if exceeded 0 cmpwi r3,0 ble FirstEvent JumpEvent: #sub 9 from event ID lbz r3,0x0(r28) subi r3,r3,9 stb r3,0x0(r28) b UpdateText FirstEvent: li r3,0 stb r3,0x0(r28) stw r3,0x4(r28) b UpdateText UpdateText: #overflow event ID to scroll ID lbz r3,0x0(r28) extsb r3,r3 cmpwi r3,0 bge UpdateText1 #get overflow and add to scroll lwz r4,0x4(r28) add r3,r3,r4 stw r3,0x4(r28) #add to scroll li r3,0 stb r3,0x0(r28) UpdateText1: #Play SFX and Update Text li r3,2 branchl r12,0x80024030 restore branch r12,0x8024daf8 exit: restore branch r12,0x8024e198 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Change ESS Proc To Pri 1.asm ================================================ #To be inserted at 8024e910 .include "../../Globals.s" .include "../../../m-ex/Header.s" li r5,1 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Choose Any Character for Events/Always Copy CSS Character Info.asm ================================================ #To be inserted at 801bb1b0 nop ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Choose Any Character for Events/Always Show Select Character Texture.asm ================================================ #To be inserted at 8024d0e8 nop ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Choose Any Character for Events/Always Spoof AnyCharacter.asm ================================================ #To be inserted at 801bbfb0 li r0, 33 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Custom ESS Button Actions.asm ================================================ #To be inserted at 8024d92c .include "../../Globals.s" .include "../../../m-ex/Header.s" backup #Check For L li r3,4 branchl r12,Inputs_GetPlayerInstantInputs rlwinm. r0, r4, 0, 25, 25 #CHECK FOR L bne OpenFDD /* rlwinm. r0, r4, 0, 27, 27 #CHECK FOR Z bne OpenOptions #Check for Tutotial (R) #Check For Training Mode ISO Game ID First lis r5,0x8000 lwz r5,0x0(r5) load r6,0x47544d45 #GTME cmpw r5,r6 bne CheckToSwitchPage #Check for R rlwinm. r0, r4, 0, 26, 26 #CHECK FOR R bne PlayMovie */ CheckToSwitchPage: li r3,4 branchl r12,Inputs_GetPlayerRapidInputs #Check For Left li r5,-1 rlwinm. r0,r3,0,25,25 bne SwitchPage #Check For Right li r5,1 rlwinm. r0,r3,0,24,24 bne SwitchPage b exit OpenFDD: #PLAY SFX li r3, 1 branchl r4,0x80024030 #SET FLAG IN RULES STRUCT li r0,3 #3 = frame data from event toggle load r3,0x804a04f0 stb r0, 0x0011 (r3) #SET SOMETHING li r0, 5 sth r0, -0x4AD8 (r13) #BACKUP CURRENT EVENT ID lwz r3, -0x4A40 (r13) lwz r5, 0x002C (r3) lbz r3,0x0(r5) lwz r4,0x4(r5) add r3,r3,r4 lwz r4, -0x77C0 (r13) stb r3, 0x0535 (r4) #LOAD RSS branchl r3,0x80237410 #REMOVE EVENT THINK FUNCTION lwz r3, -0x3E84 (r13) branchl r12,0x80390228 b exit /* OpenOptions: #Create Background + GObj bl OptionMenu_CreateBackground #Display Menus Text bl MenuData_MainMenuBlrl mflr r4 bl OptionMenu_CreateText #Play SFX li r3,1 branchl r12,0x80024030 b exit #region OptionMenu_CreateBackground BG_Constants: blrl .set BG_Transparency,0x0 .set BG_ScaleX,0x4 .set BG_ScaleY,0x8 .set BG_TransformX,0xC .set BG_TransformY,0x10 .set BG_TransformZ,0x14 .set BG_Color,0x18 .float 0.85 #transparency .float 0.1 #scale X .float 0.15 #scale Y .float 8 #X Position .float 3 #Y position .float 20 #Z Position .byte 13, 13, 46, 255 #Color OptionMenu_CreateBackground: .set REG_GObj,20 .set REG_GObjData,21 backup #Create Background GObj li r3,6 li r4,7 li r5,0x80 branchl r12,GObj_Create mr REG_GObj,r3 #Allocate Space li r3,64 branchl r12,HSD_MemAlloc mr REG_GObjData,r3 #Zero li r4,64 branchl r12,ZeroAreaLength #Initialize mr r6,REG_GObjData mr r3,REG_GObj li r4,4 load r5,0x8037f1b0 branchl r12,GObj_AddUserData #Add Process mr r3,REG_GObj bl OptionMenu_Think mflr r4 li r5,0 branchl r12,GObj_AddProc #Get JObj from archive lwz r3, -0x4AE8 (r13) load r4,0x803efa0c branchl r12,0x80380358 #Load JObj branchl r12,HSD_JObjLoadJoint #Get child JObj (the black background) mr r22,r3 lwz r3,0x10(r3) #Remove parent and child (the message box) li r4,0 stw r4,0x0c(r3) stw r4,0x10(r3) #Adjust transparency lwz r4,0x18(r3) lwz r4,0x8(r4) lwz r4,0xC(r4) bl BG_Constants mflr r5 lfs f1,BG_Transparency(r5) stfs f1,0xC(r4) #Adjust color lwz r6,BG_Color(r5) stw r6,0x4(r4) #Adjust Scale lfs f1,BG_ScaleX(r5) stfs f1,0x2C(r3) lfs f1,BG_ScaleY(r5) stfs f1,0x30(r3) #Adjust Position lfs f1,BG_TransformX(r5) stfs f1,0x38(r3) lfs f1,BG_TransformY(r5) stfs f1,0x3C(r3) lfs f1,BG_TransformZ(r5) stfs f1,0x40(r3) #Store JObj to GObj mr r5,r22 mr r3,REG_GObj lbz r4, -0x3E57 (r13) branchl r12,GObj_StorePointerToJObj #Add GX Link mr r3,REG_GObj load r4,0x80391070 li r5,7 #layer id? higher = drawn later li r6,127 #priority, higher = drawn later branchl r12,GObj_AddGXLink #Return the GObj mr r3,REG_GObj #Exit restore blr #endregion #region OptionMenu_Think OptionMenu_Think: blrl .set REG_GObj,31 backup #Backup mr REG_GObj,r3 lwz REG_GObjData,0x2C(REG_GObj) #Disable Event Menu li r3,1 sth r3, -0x4AD8 (r13) #Check for Z and close menu li r3,4 branchl r12,Inputs_GetPlayerInstantInputs rlwinm. r0, r4, 0, 27, 27 #CHECK FOR Z bne OptionMenu_ThinkDestroy rlwinm. r0, r3, 0, 26, 26 #CHECK FOR Down bne OptionMenu_ThinkDown rlwinm. r0, r3, 0, 27, 27 #CHECK FOR Up bne OptionMenu_ThinkUp rlwinm. r0, r3, 0, 31, 31 #CHECK FOR A bne OptionMenu_ThinkSelect rlwinm. r0, r3, 0, 30, 30 #CHECK FOR B bne OptionMenu_ThinkBack b OptionMenu_ThinkExit OptionMenu_ThinkDown: #Down one cursor position lwz r3,Cursor(REG_GObjData) addi r4,r3,1 #Highlight current cursor mr r3,REG_GObjData bl OptionMenu_AdjustCursor #Play SFX li r3,2 branchl r12,0x80024030 b OptionMenu_ThinkExit OptionMenu_ThinkUp: #Up one cursor position lwz r3,Cursor(REG_GObjData) subi r4,r3,1 #Highlight current cursor mr r3,REG_GObjData bl OptionMenu_AdjustCursor #Play SFX li r3,2 branchl r12,0x80024030 b OptionMenu_ThinkExit OptionMenu_ThinkSelect: #Loop through current menu .set REG_Count,20 .set REG_OptionData,22 .set REG_OptionCount,23 .set REG_MenuData,24 .set REG_Cursor,25 #Init li REG_Count,0 #loop count li REG_OptionCount,0 #Only incremented when an option is found lwz REG_MenuData,MenuData(REG_GObjData) lwz REG_Cursor,Cursor(REG_GObjData) OptionMenu_ThinkSelect_SearchOptionsLoop: #Get this option's text addi r3,REG_MenuData,MenuData_OptionsStart mulli r4,REG_Count,MenuData_OptionDataLength add REG_OptionData,r3,r4 #Get OnSelectType lwz r3,MenuData_OnSelectType(REG_OptionData) cmpwi r3,OnSelect_None beq OptionMenu_ThinkSelect_SearchOptionsIncLoop #Check if this is the desired option cmpw REG_OptionCount,REG_Cursor beq OptionMenu_ThinkSelect_SelectOption #Increment Option Count addi REG_OptionCount,REG_OptionCount,1 b OptionMenu_ThinkSelect_SearchOptionsIncLoop OptionMenu_ThinkSelect_SelectOption: #Play SFX li r3,1 branchl r12,0x80024030 #Decide Selection Type lwz r3,MenuData_OnSelectType(REG_OptionData) cmpwi r3,OnSelect_Menu beq OptionMenu_ThinkSelect_GetNextMenu cmpwi r3,OnSelect_Function beq OptionMenu_ThinkSelect_GetFunction b OptionMenu_ThinkSelect_SearchOptionsEnd OptionMenu_ThinkSelect_GetNextMenu: #Convert bl instruction to mem address addi r4,REG_OptionData,MenuData_OnSelectData lwz r5,0x0(r4) rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) extsh r5,r5 add r4,r4,r5 #Gets Address in r3 #Create Text mr r3,REG_GObj bl OptionMenu_CreateText b OptionMenu_ThinkSelect_SearchOptionsEnd OptionMenu_ThinkSelect_GetFunction: #Convert bl instruction to mem address addi r4,REG_OptionData,MenuData_OnSelectData lwz r5,0x0(r4) rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) extsh r5,r5 cmpwi r5,0 beq OptionMenu_ThinkSelect_NoFunction add r4,r4,r5 #Gets Address in r3 mtctr r4 mr r3,REG_GObj bctrl b OptionMenu_ThinkSelect_SearchOptionsEnd OptionMenu_ThinkSelect_NoFunction: #Play Error Sound li r3, 3 branchl r12,0x80024030 li r3, 3 branchl r12,0x80024030 b OptionMenu_ThinkSelect_SearchOptionsEnd OptionMenu_ThinkSelect_SearchOptionsIncLoop: addi REG_Count,REG_Count,1 b OptionMenu_ThinkSelect_SearchOptionsLoop OptionMenu_ThinkSelect_SearchOptionsEnd: b OptionMenu_ThinkExit OptionMenu_ThinkBack: .set REG_MenuData,24 lwz r4,MenuData(REG_GObjData) #Convert bl instruction to mem address addi r4,r4,MenuData_ReturnMenu lwz r5,0x0(r4) rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) extsh r5,r5 cmpwi r5,0 beq OptionMenu_ThinkDestroy add r4,r4,r5 #Gets Address in r4 #Load Prev Menu mr r3,REG_GObj bl OptionMenu_CreateText #Play SFX li r3,0 branchl r12,0x80024030 b OptionMenu_ThinkExit OptionMenu_ThinkDestroy: #Remove text lwz r3,0x2C(REG_GObj) lwz r3,TextGObj(r3) branchl r12,Text_RemoveText #Remove GObj mr r3,REG_GObj branchl r12,GObj_Destroy #Play SFX li r3,0 branchl r12,0x80024030 OptionMenu_ThinkExit: restore blr #endregion #region OptionMenu_CreateText TextProperties: blrl .set VersionX,0x0 .set VersionY,0x4 .set ZOffset,0x8 .set CanvasScaling,0xC .set Scale,0x10 .set YOffset,0x14 .set YOffsetAddAfterTitle,0x18 .set HighlightColor,0x1C .set NonHighlightColor,0x20 .float 120 #REG_TextGObj X pos .float -250 #REG_TextGObj Y pos .float 21.9 #Z offset .float 0.035 #Canvas Scaling .float 0.65 #Text scale .float 30 #Y offset difference .float 20 #Y Offset to Add After Title .byte 251,199,57,255 #highlighted color .byte 170,170,170,255 #nonhighlighted color OptionMenu_CreateText: .set REG_MenuData,28 .set REG_GObjData,29 .set REG_TextProp,30 .set REG_TextGObj,31 #GObj Data Struct .set Cursor,0x0 .set TextGObj,0x4 .set MenuData,0x8 backup #Backup GObj and MenuData lwz REG_GObjData,0x2C(r3) mr REG_MenuData,r4 #Check if a text gobj already lwz r3,TextGObj(REG_GObjData) cmpwi r3,0 beq OptionMenu_CreateText_SkipDestroyOldText #Destroy branchl r12,Text_RemoveText li r3,0 stw r3,TextGObj(REG_GObjData) OptionMenu_CreateText_SkipDestroyOldText: #Store new menudata stw REG_MenuData,MenuData(REG_GObjData) #GET PROPERTIES TABLE bl TextProperties mflr REG_TextProp ######################## ## Create Text Object ## ######################## #CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3 li r3,0 li r4,1 branchl r12,Text_CreateTextStruct stw r3,TextGObj(REG_GObjData) #BACKUP STRUCT POINTER mr REG_TextGObj,r3 #SET TEXT SPACING TO TIGHT li r4,0x1 stb r4,0x49(REG_TextGObj) #SET TEXT TO CENTER AROUND X LOCATION li r4,0x0 stb r4,0x4A(REG_TextGObj) #Store Base Z Offset lfs f1,ZOffset(REG_TextProp) #Z offset stfs f1,0x8(REG_TextGObj) #Scale Canvas Down lfs f1,CanvasScaling(REG_TextProp) stfs f1,0x24(REG_TextGObj) stfs f1,0x28(REG_TextGObj) OptionMenu_CreateText_PrintOptions: .set REG_Count,20 .set REG_ASCII,21 .set REG_OptionData,22 .set OFST_LastYPos,0x80 #Init li REG_Count,0 #loop count lfs f1,VersionY(REG_TextProp) #Last text's Y position stfs f1,OFST_LastYPos(sp) OptionMenu_CreateText_PrintOptionsLoop: #Get this option's text addi r3,REG_MenuData,MenuData_OptionsStart mulli r4,REG_Count,MenuData_OptionDataLength add REG_OptionData,r3,r4 #Convert bl instruction to mem address lwz r4,0x0(REG_OptionData) #Get bl Instruction extsb r5,r4 #Check if none left cmpwi r5,-1 beq OptionMenu_CreateText_PrintOptionsEnd rlwinm r4,r4,0,6,29 #Mask Bits 6-29 (the offset) extsh r4,r4 add REG_ASCII,REG_OptionData,r4 #Gets ASCII Address in r3 #Get Y offset lfs f2,OFST_LastYPos(sp) #Y base offset of REG_TextGObj lfs f3,YOffset(REG_TextProp) #Y offset difference fadds f2,f2,f3 #Check if this is the first option cmpwi REG_Count,0 beq OptionMenu_CreateText_PrintOptions_SkipTitleAdjust #Check if last option was a title lwz r3,-MenuData_OptionDataLength + MenuData_OnSelectType(REG_OptionData) cmpwi r3,OnSelect_None bne OptionMenu_CreateText_PrintOptions_SkipTitleAdjust #Move down further lfs f1,YOffsetAddAfterTitle(REG_TextProp) fadds f2,f1,f2 OptionMenu_CreateText_PrintOptions_SkipTitleAdjust: #Store as last Y position stfs f2,OFST_LastYPos(sp) #Initialize Subtext mr r3,REG_TextGObj #struct pointer mr r4,REG_ASCII #text lfs f1,VersionX(REG_TextProp) #X offset of REG_TextGObj branchl r12,0x803a6b98 #Change Text Scale mr r3,REG_TextGObj #struct pointer mr r4,REG_Count lfs f1,Scale(REG_TextProp) #X offset of REG_TextGObj lfs f2,Scale(REG_TextProp) #Y offset of REG_TextGObj branchl r12,Text_UpdateSubtextSize OptionMenu_CreateText_PrintOptionsIncLoop: addi REG_Count,REG_Count,1 b OptionMenu_CreateText_PrintOptionsLoop OptionMenu_CreateText_PrintOptionsEnd: #Reset cursor position li r3,0 #Highlight current cursor mr r4,r3 mr r3,REG_GObjData bl OptionMenu_AdjustCursor #Exit restore blr #endregion #region OptionMenu_AdjustCursor OptionMenu_AdjustCursor: .set REG_GObjData,31 .set REG_TextGObj,30 .set REG_Cursor,29 .set REG_TextProp,28 backup #Backup mr REG_GObjData,r3 lwz REG_TextGObj,TextGObj(REG_GObjData) mr REG_Cursor,r4 bl TextProperties mflr REG_TextProp #Change all options to white OptionMenu_AdjustCursor_ResetColors: .set REG_Count,20 #Init li REG_Count,0 #loop count OptionMenu_AdjustCursor_ResetColorsLoop: #Adjust Subtext mr r3,REG_TextGObj #struct pointer mr r4,REG_Count #subtext text addi r5,REG_TextProp,NonHighlightColor branchl r12,Text_ChangeTextColor OptionMenu_AdjustCursor_ResetColorsIncLoop: addi REG_Count,REG_Count,1 #Get number of subtexts lwz r3,0x64(REG_TextGObj) lwz r3,0xC(r3) cmpw REG_Count,r3 blt OptionMenu_AdjustCursor_ResetColorsLoop #Ensure this isnt below 0 cmpwi REG_Cursor,0 bge OptionMenu_AdjustCursor_SearchOptions #Adjust to be 0 li REG_Cursor,0 #Loop through current menu OptionMenu_AdjustCursor_SearchOptions: .set REG_Count,20 .set REG_ASCII,21 .set REG_OptionData,22 .set REG_OptionCount,23 .set REG_MenuData,24 #Init li REG_Count,0 #loop count li REG_OptionCount,0 #Only incremented when an option is found lwz REG_MenuData,MenuData(REG_GObjData) OptionMenu_AdjustCursor_SearchOptionsLoop: #Get this option's text addi r3,REG_MenuData,MenuData_OptionsStart mulli r4,REG_Count,MenuData_OptionDataLength add REG_OptionData,r3,r4 #Convert bl instruction to mem address lwz r4,0x0(REG_OptionData) #Get bl Instruction extsb r5,r4 #Check if none left cmpwi r5,-1 bne OptionMenu_AdjustCursor_SearchOptionsNotLast subi REG_OptionCount,REG_OptionCount,1 OptionMenu_AdjustCursor_SearchOptionsGetLastValidOption: subi REG_Count,REG_Count,1 addi r3,REG_MenuData,MenuData_OptionsStart mulli r4,REG_Count,MenuData_OptionDataLength add REG_OptionData,r3,r4 lwz r3,MenuData_OnSelectType(REG_OptionData) cmpwi r3,OnSelect_None beq OptionMenu_AdjustCursor_SearchOptionsGetLastValidOption b OptionMenu_AdjustCursor_SearchOptionsChangeColor #Get OnSelectType OptionMenu_AdjustCursor_SearchOptionsNotLast: lwz r3,MenuData_OnSelectType(REG_OptionData) cmpwi r3,OnSelect_None beq OptionMenu_AdjustCursor_SearchOptionsIncLoop #Check if this is the desired option cmpw REG_OptionCount,REG_Cursor beq OptionMenu_AdjustCursor_SearchOptionsChangeColor #Increment Option Count addi REG_OptionCount,REG_OptionCount,1 b OptionMenu_AdjustCursor_SearchOptionsIncLoop OptionMenu_AdjustCursor_SearchOptionsChangeColor: #Adjust Subtext mr r3,REG_TextGObj #struct pointer mr r4,REG_Count #subtext text addi r5,REG_TextProp,HighlightColor branchl r12,Text_ChangeTextColor #Update Cursor Position stw REG_OptionCount,Cursor(REG_GObjData) b OptionMenu_AdjustCursor_SearchOptionsEnd OptionMenu_AdjustCursor_SearchOptionsIncLoop: addi REG_Count,REG_Count,1 b OptionMenu_AdjustCursor_SearchOptionsLoop OptionMenu_AdjustCursor_SearchOptionsEnd: #Exit restore blr #endregion #region MenuData #MenuData Structure .set MenuData_ReturnMenu,0x0 .set MenuData_OptionsStart,0x4 .set MenuData_OptionName,0x0 .set MenuData_OnSelectType,0x4 .set MenuData_OnSelectData,0x8 .set MenuData_OptionDataLength,0xC #OnSelect Definitions .set OnSelect_None,0 .set OnSelect_Menu,1 .set OnSelect_Function,2 #region Options MenuData_MainMenuBlrl: blrl MenuData_MainMenu: #Return menu .long 0 #Options bl MenuData_MainMenu_OptionsTitleName .long OnSelect_None .long 0 #Create Save File bl MenuData_MainMenu_CreateSaveName .long OnSelect_Menu bl MenuData_CreateSave #Play bl MenuData_MainMenu_PlayCreditsName .long OnSelect_Function bl LoadCredits .long -1 .align 2 MenuData_MainMenu_OptionsTitleName: .string "" .align 2 MenuData_MainMenu_PlayCreditsName: .string "Show Credits" .align 2 MenuData_MainMenu_CreateSaveName: .string "Create Save" .align 2 #endregion #region Create Save MenuData_CreateSave: #Return menu bl MenuData_MainMenu #Create Save bl MenuData_MainMenu_CreateSaveTitleName .long OnSelect_None .long 0 #Play bl MenuData_CreateSave_SlotA .long OnSelect_Function .long 0#bl CreateSave_SlotA #Create Save File bl MenuData_CreateSave_SlotB .long OnSelect_Function .long 0#bl CreateSave_SlotB #Space bl MenuData_CreateSave_Empty .long OnSelect_None .long 0 #Disabled bl MenuData_MainMenu_Disabled .long OnSelect_None .long 0 .long -1 .align 2 MenuData_MainMenu_CreateSaveTitleName: .string "" .align 2 MenuData_CreateSave_SlotA: .string "Save to Slot A" .align 2 MenuData_CreateSave_SlotB: .string "Save to Slot B" .align 2 MenuData_CreateSave_Empty: .string "" .align 2 MenuData_MainMenu_Disabled: .string "(Temp Disabled)" .align 2 CreateSave_SlotA: li r3,0 b CreateSave CreateSave_SlotB: li r3,1 b CreateSave #endregion #endregion #region CreateSave CreateSave: .set MemcardFileList,0x804333c8 .set REG_MemcardSlot,20 backup #Backup slot mr REG_MemcardSlot,r3 #Backup current Game ID addi r3,sp,0xB0 lis r4,0x8000 branchl r12,strcpy #Change Game ID to Melee's lis r3,0x8000 bl MeleeGameID mflr r4 branchl r12,strcpy #Get memcard pointer .set REG_Memcard,30 lwz REG_Memcard, -0x77C0 (r13) ########################### ## Create Main Save File ## ########################### #Check if save file already exists mr r3,REG_MemcardSlot load r6,0x803bab60 addi r4, r6, 252 addi r5, r6, 20 load r7,0x8043331C branchl r12,0x8001b7e0 cmpwi r3,0x1 bne CreateMainSave DeleteMainSave: mr r3,REG_MemcardSlot load r4,0x803bac5c load r5,0x8043331c branchl r12,0x8001ba44 cmpwi r3,0 bne SaveError CreateMainSave: .set REG_OldSaveBackup,31 #Allocate mem to backup current save data to load r3,68144 branchl r12,HSD_MemAlloc mr REG_OldSaveBackup,r3 #Copy old data here mr r4, REG_Memcard load r5,68144 branchl r12,memcpy #Start building exploit addi r3,REG_Memcard,0x3190 #destination load r4,0xdd064bdd #data to write li r5,0xD4 #length to write subi r3,r3,4 ExploitFillLoop: stwu r4,0x4(r3) subi r5,r5,0x4 cmpwi r5,0 bgt ExploitFillLoop #Place LR hijacks mr r3, REG_Memcard load r4,0x804eeac8 stw r4,0x3230(r3) load r4,0x8045d930 stw r4,0x3234(r3) load r4,0x804ee8f8 stw r4,0x3264(r3) load r4,0x8045d930 stw r4,0x3268(r3) #Place exploit code for 1.02 addi r3,REG_Memcard,0x3270 #exploit code destination bl ExploitCode102 mflr r4 li r5,0xD30 #length of code branchl r12,memcpy #Place exploit code for 1.00 addi r3,REG_Memcard,0x5238 #exploit code destination bl ExploitCode100 mflr r4 li r5,0x80 #length of code branchl r12,memcpy #Place exploit code for 1.01 addi r3,REG_Memcard,0x3f50 #exploit code destination bl ExploitCode101 mflr r4 li r5,0x80 #length of code branchl r12,memcpy #Run onSaveCreate functions (enable UCF and unlock trophies) OnSaveCreate #Unlock All Messages addi r3,REG_Memcard,0x1B4C li r4,0xFF li r5,0x34 branchl r12,0x80003100 #Only Mewtwo Unlocked li r3,0x8 stb r3,6249(REG_Memcard) #Wipe High Scores addi r3,REG_Memcard,0x1A70 li r4,0 li r5,0xCC branchl r12,0x80003100 #Set as unplayed li r3,0 stw r3,0x1A68(REG_Memcard) stw r3,0x1A6C(REG_Memcard) #Create Save mr r3,REG_MemcardSlot load r6,0x803bab60 addi r5,r6,20 addi r4,r6,252 bl MainSaveName mflr r7 load r10,0x80433318 lwz r9,0x5C(r10) lwz r8,0x8(r9) #banner data with flames lwz r9,0xC(r9) #icon data addi r10,r10,4 branchl r12,0x8001bc18 cmpwi r3,0 bne SaveError #Copy original save data back mr r3, REG_Memcard mr r4,REG_OldSaveBackup load r5,68144 branchl r12,memcpy #Free allocation mr r3,REG_OldSaveBackup branchl r12,HSD_Free ########################## ## Create Snapshot File ## ########################## #Update list of present memcard snapshots mr r3,REG_MemcardSlot branchl r12,0x80253e90 .set REG_Count,31 .set REG_Index,30 .set REG_SnapshotStruct,29 .set REG_SnapshotID,28 #Check if file exists on card load r3,MemcardFileList #go to pointer location lwz REG_SnapshotStruct,0x0(r3) #access pointer to snapshot file list mulli r3,REG_MemcardSlot,1032 add REG_SnapshotStruct,REG_SnapshotStruct,r3 lwz REG_Index,0x4(REG_SnapshotStruct) #get number of snapshots present addi REG_SnapshotStruct,REG_SnapshotStruct,0x10 #get to snapshot info bl SnapshotID #get ID we are looking for mflr r3 lwz REG_SnapshotID,0x0(r3) li REG_Count,0 #init count SnapshotSearchLoop: cmpw REG_Count,REG_Index bge SnapshotSearchLoop_NotFound #Get the next snapshots ID mulli r3,REG_Count,0x8 #each snapshots data is 0x8 long add r3,r3,REG_SnapshotStruct lwz r4,0x0(r3) #get the snaps ID cmpw r4,REG_SnapshotID bne SnapshotSearchLoop_IncLoop b SnapshotSearchLoop_Found SnapshotSearchLoop_IncLoop: addi REG_Count,REG_Count,1 b SnapshotSearchLoop SnapshotSearchLoop_NotFound: b CreateSnapshot SnapshotSearchLoop_Found: #Delete Snapshot mr r3,REG_MemcardSlot mr r4,REG_Count branchl r12,0x8001d5fc WaitToDeleteLoop: branchl r12,0x8001b6f8 cmpwi r3,0xB beq WaitToDeleteLoop #If Exists cmpwi r3,0x0 beq CreateSnapshot cmpwi r3,0x9 bne SaveError CreateSnapshot: .set REG_Codeset,31 #Get codeset pointer and length lwz REG_Codeset,CodesetPointer(rtoc) bl SnapshotSaveStruct mflr r4 stw REG_Codeset,0x8(r4) #Store file size lwz r3,0x0(REG_Codeset) stw r3,0x0(r4) #Load banner and image #Convert ID to string addi r3,sp,0x80 bl SnapshotString mflr r4 bl SnapshotID mflr r5 lwz r5,0x0(r5) branchl r12,0x80323cf4 #Create File mr r3,REG_MemcardSlot addi r4,sp,0x80 #Snapshot ID bl SnapshotSaveStruct mflr r5 load r6,0x803bacc8 bl SnapshotSaveName mflr r7 bl SnapshotBanner mflr r8 bl SnapshotIcon mflr r9 li r10,0 branchl r12,0x8001bb48 WaitToLoadLoop: branchl r12,0x8001b6f8 cmpwi r3,0xB beq WaitToLoadLoop #If Exists cmpwi r3,0x0 beq Success cmpwi r3,0x9 beq Success b Failure Success: li r3,0xAA branchl r12,0x801c53ec b CreateSnapshot_End Failure: #Play Error Sound li r3, 3 branchl r12,0x80024030 li r3, 3 branchl r12,0x80024030 b CreateSnapshot_End CreateSnapshot_End: #Change Game ID back lis r3,0x8000 addi r4,sp,0xB0 branchl r12,strcpy b ExitInjection SaveError: #Play Error Sound li r3, 3 branchl r12,0x80024030 li r3, 3 branchl r12,0x80024030 #Change Game ID back lis r3,0x8000 addi r4,sp,0xB0 branchl r12,strcpy b ExitInjection ################### MainSaveName: blrl .ascii "Super Smash Bros. Melee " .ascii "Mod Launcher (1 of 2) " ################### SnapshotID: blrl .long 0x00D0C0DE .align 2 ################### SnapshotString: blrl .string "%u" .align 2 ################### SnapshotSaveStruct: blrl .long 0 #File size, will dynamically change based on gct size .long 3 #Unknown .long 0 #Pointer to snapshot data, will be stored to during runtime .long -1 #end of structure .align 2 ################### SnapshotSaveName: blrl .ascii "Training Mode v2.0 " .ascii "Mod Data (2 of 2) " ################### CodeFileName: blrl .string "codes.gct" .align 2 ################### TMGameID: blrl .string "GTME01" .align 2 ################### MeleeGameID: blrl .string "GALE01" .align 2 ################### #region ExploitCode102 ExploitCode102: blrl .set InjectionPoint,0x80375510 #0x803754e4 .set InjectionReturn,0x803754dc #0x803754e8 ################################## ## PLACE AT 0xb6f3d0 IN state FILE ## ################################## #*** Possibly inject into 801a4000, memcard stuff has already been reset, this might be the #neatest place to do this. destroy the heap, make a new one, load the snapshot and rerun this #function ################## ## Change Major ## ################## #request to change screen branchl r3,0x801A4B60 #Set Next Scene Byte (Main Menu) for sceneDecide_Menu #Check For X Button Held li r3,4 branchl r12,0x801a3680 rlwinm. r4,r4,0,21,21 beq ExploitCode102_GoToEventSS ExploitCode102_GoToCSS: li r3,2 b ExploitCode102_StoreNewScene #Spoof current (soon to be previous) screen ExploitCode102_GoToEventSS: li r3,0x2b load r4,0x80479d30 stb r3,0x0(r4) li r3,0x1 ExploitCode102_StoreNewScene: lis r4,0x804d stb r3,0x68bC(r4) ################################ ## Disable memory card saving ## ################################ #lis r5,0x8043 #v1.0=80431360 #li r6,4 #stw r6,0x3320(r5) # store 4 to disable memory card saving henceforth ######################### ## Tournament Settings ## ######################### lwz r4, -0x77C0 (r13) load r3,0x00340102 stw r3,0x1850(r4) #store stock mode load r3,0x04000A00 stw r3,0x1854(r4) #store 4 stocks load r3,0x08010100 stw r3,0x1858(r4) #store 8 minutes load r3,0xFF000000 stw r3,0x1CB0(r4) #store items off load r3,0xE70000B0 stw r3,0x1CC8(r4) #store stages ################################# ## Place Branch To Heap Hijack ## ################################# #Get Function To Branch To bl ExploitCode102_HeapHijack mflr r3 #Get Where to Place Branch load r4,InjectionPoint #Make a Branch Instruction out of This (FunctionAddress - BranchPoint) sub r3,r3,r4 #r3 contains difference between rlwinm r3,r3,0,6,29 #Mask Out bits 6 through 29 oris r3,r3,0x4800 #Place 0x48 at the start (opcode) stw r3,0x0(r4) ##################### ## TRK_flush_cache ## ##################### load r3,InjectionPoint lis r4,0x4 branchl r12,0x80328F50 ########## ## Exit ## ########## lis r12,0x8023 ori r12,r12,0x9e9c mtctr r12 bctr ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ###################### ## Heap Hijack Code ## ###################### ExploitCode102_HeapHijack: blrl backup ################### ## Load Snapshot ## ################### #Update list of present memcard snapshots li r3,0 branchl r12,0x80253e90 .set MemcardFileList,0x804333c8 .set REG_Count,31 .set REG_Index,30 .set REG_SnapshotStruct,29 .set REG_SnapshotID,28 #Check if file exists on card load r3,MemcardFileList #go to pointer location lwz REG_SnapshotStruct,0x0(r3) #access pointer to snapshot file list lwz REG_Index,0x4(REG_SnapshotStruct) #get number of snapshots present addi REG_SnapshotStruct,REG_SnapshotStruct,0x10 #get to snapshot info bl ExploitCode102_HeapHijack_SnapshotIDInt #get ID we are looking for mflr r3 lwz REG_SnapshotID,0x0(r3) li REG_Count,0 #init count ExploitCode102_HeapHijack_SnapshotSearchLoop: cmpw REG_Count,REG_Index bge ExploitCode102_HeapHijack_SnapshotSearchLoop_NotFound #Get the next snapshots ID mulli r3,REG_Count,0x8 #each snapshots data is 0x8 long add r3,r3,REG_SnapshotStruct lwz r4,0x0(r3) #get the snaps ID cmpw r4,REG_SnapshotID bne ExploitCode102_HeapHijack_SnapshotSearchLoop_IncLoop b ExploitCode102_HeapHijack_SnapshotSearchLoop_Found ExploitCode102_HeapHijack_SnapshotSearchLoop_IncLoop: addi REG_Count,REG_Count,1 b ExploitCode102_HeapHijack_SnapshotSearchLoop ExploitCode102_HeapHijack_SnapshotSearchLoop_NotFound: #Play Error Sound li r3, 3 branchl r12,0x80024030 li r3, 3 branchl r12,0x80024030 #Disable Saving lis r4,0x8043 li r3,4 stw r3,0x3320(r4) # store 4 to disable memory card saving b ExploitCode102_HeapHijack_CleanUpHijack ExploitCode102_HeapHijack_SnapshotSearchLoop_Found: .set REG_CodesetSize,31 .set REG_CodesetPointer,30 #Convert blocks to bytes lhz r3,0x6(r3) mulli REG_CodesetSize,r3,0x2000 #Alloc Space For Snapshot File mr r3,REG_CodesetSize branchl r12,0x8037f1e4 #HSD_Alloc mr REG_CodesetPointer,r3 load r5,0x803bacdc #Snapshot Data Struct stw REG_CodesetPointer,0x8(r5) #Store Pointer to this area #Remove Pointer To Current Memcard Stuff branchl r12,0x8001c5a4 #Alloc Space For Memcard Stuff branchl r12,0x8001c550 #Load File li r3,0x0 #Slot A? bl ExploitCode102_HeapHijack_SnapshotID mflr r4 load r5,0x803bacdc #Snapshot Data Struct load r6,0x80433384 #String Space? load r9,0x80433380 lwz r9,0x44(r9) lwz r7,0x0(r9) #Weird Char Pointer, Maybe Icon Image lwz r8,0x4(r9) #Banner Image li r9,0 #Unk branchl r12,0x8001bf04 #Store Result load r4,0x804A0B6C stw r3,0x0(r4) ExploitCode102_HeapHijack_WaitToLoadLoop: branchl r12,0x8001b6f8 cmpwi r3,0xB beq ExploitCode102_HeapHijack_WaitToLoadLoop #If Exists cmpwi r3,0x0 beq ExploitCode102_HeapHijack_Success cmpwi r3,0x9 beq ExploitCode102_HeapHijack_Success b ExploitCode102_HeapHijack_Failure ExploitCode102_HeapHijack_SnapshotIDInt: blrl .long 0x00D0C0DE .align 2 ExploitCode102_HeapHijack_SnapshotID: blrl .string "13680862" .align 2 ############# ## Failure ## ############# ExploitCode102_HeapHijack_Failure: #Play Error Sound li r3, 3 branchl r12,0x80024030 li r3, 3 branchl r12,0x80024030 #Disable Saving lis r4,0x8043 li r3,4 stw r3,0x3320(r4) # store 4 to disable memory card saving b ExploitCode102_Exit ############# ## Success ## ############# ExploitCode102_HeapHijack_Success: #Store codeset pointer and length stw REG_CodesetPointer,CodesetPointer(rtoc) #Play SFX li r3,0xAA branchl r12,0x801c53ec #Boot up tasks OnBootup ##################### ## Run Codehandler ## ##################### ExploitCode102_HeapHijack_RunCodehandler: addi r4,REG_CodesetPointer,32 bl GeckoCodehandler ################################### ## Change Start Of Original Heap ## ################################### load r3,0x8043200c #Heap Start mr r4,REG_CodesetSize #Space to Add lwz r5,0x4(r3) #Get Heap Start add r4,r4,r5 #Add stw r4,0x4(r3) #Store New Heap Start ################## ## Destroy Heap ## ################## lwz r3, -0x58A0 (r13) branchl r12,0x80344154 ##################### ## Exit HeapHijack ## ##################### #Adjust Heap Start lwz r3, -0x3FE8 (r13) mr r4,REG_CodesetSize add r3,r3,r4 stw r3,-0x3FE8 (r13) ExploitCode102_HeapHijack_CleanUpHijack: ################################ ## Remove Branch To This Code ## ################################ load r3,0x806da760 load r4,InjectionPoint stw r3,0x0(r4) ############################# ## Flush Instruction Cache ## ############################# ExploitCode102_Exit: #Now flush the instruction cache lis r3,0x8000 load r4,0x3b722c #might be overkill but flush the entire dol file branchl r12,0x80328f50 ################################### ## Zero fill entire nametag area ## ################################### restore load r3,InjectionReturn mtlr r3 lis r3,0x8045 ori r3,r3,0xd850 #v1.0 = 8045b888 li r4,0 li r5,0 ori r5,r5,0xc344 lis r12,0x8000 ori r12,r12,0x3130 #v1.0 = 8045b888 mtctr r12 bctr ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ######################################################### ####################### ## Gecko Codehandler ## ####################### .text .set r0,0; .set r1,1; .set r2,2; .set r3,3; .set r4,4 .set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 .set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 .set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 .set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 .set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 .set r30,30; .set r31,31; .set f0,0; .set f2,2; .set f3,3 .globl _start cheatdata: .long frozenvalue .space 39*4 GeckoCodehandler: _start: stwu r1,-168(r1) # stores sp stw r0,8(r1) # stores r0 mflr r0 stw r0,172(r1) # stores lr mfcr r0 stw r0,12(r1) # stores cr mfctr r0 stw r0,16(r1) # stores ctr mfxer r0 stw r0,20(r1) # stores xer stmw r3,24(r1) # saves r3-r31 mfmsr r20 ori r26,r20,0x2000 #enable floating point ? andi. r26,r26,0xF9FF mtmsr r26 stfd f2,152(r1) # stores f2 stfd f3,160(r1) # stores f3 lis r31,0x8000 lis r3, 0xCC00 lhz r28, 0x4010(r3) ori r21, r28, 0xFF sth r21, 0x4010(r3) # disable MP3 memory protection mflr r29 mr r15,r4 ori r7, r31, cheatdata@l # set pointer for storing data (before the codelist) lis r6,0x8000 # default base address = 0x80000000 (code handler) mr r16,r6 # default pointer =0x80000000 (code handler) li r8,0 # code execution status set to true (code handler) lis r3,0x00D0 ori r3,r3,0xC0DE lwz r4,0(r15) cmpw r3,r4 bne- _exitcodehandler lwz r4,4(r15) cmpw r3,r4 bne- _exitcodehandler # lf no code list skip code handler addi r15,r15,8 b _readcodes _exitcodehandler: mtlr r29 resumegame: lis r3, 0xCC00 sth r28,0x4010(r3) # restore memory protection value lfd f2,152(r1) # loads f2 lfd f3,160(r1) # loads f3 mtmsr r20 # restore msr lwz r0,172(r1) mtlr r0 # restores lr lwz r0,12(r1) mtcr r0 # restores cr lwz r0,16(r1) mtctr r0 # restores ctr lwz r0,20(r1) mtxer r0 # restores xer lmw r3,24(r1) # restores r3-r31 lwz r0,8(r1) # loads r0 addi r1,r1,168 isync blr # return back to game _readcodes: lwz r3,0(r15) #load code address lwz r4,4(r15) #load code value addi r15,r15,8 #r15 points to next code andi. r9,r8,1 cmpwi cr7,r9,0 #check code execution status in cr7. eq = true, ne = false li r9,0 #Clears r9 rlwinm r10,r3,3,29,31 #r10 = extract code type, 3 bits rlwinm r5,r3,7,29,31 #r5 = extract sub code type 3 bits andis. r11,r3,0x1000 #test pointer rlwinm r3,r3,0,7,31 #r3 = extract address in r3 (code type 0/1/2) #0x01FFFFFF bne +12 #jump lf the pointer is used rlwinm r12,r6,0,0,6 #lf pointer is not used, address = base address b +8 mr r12,r16 #lf pointer is used, address = pointer cmpwi cr4,r5,0 #compares sub code type with 0 in cr4 cmpwi r10,1 blt+ _write #code type 0 : write beq+ _conditional #code type 1 : conditional cmpwi r10,3 blt+ _ba_pointer #Code type 2 : base address operation beq- _repeat_goto #Code type 3 : Repeat & goto cmpwi r10,5 blt- _operation_rN #Code type 4 : rN Operation beq+ _compare16_NM_counter #Code type 5 : compare [rN] with [rM] cmpwi r10,7 blt+ _hook_execute #Code type 6 : hook, execute code b _terminator_onoff_ #code type 7 : End of code list #CT0============================================================================= #write 8bits (0): 00XXXXXX YYYY00ZZ #write 16bits (1): 02XXXXXX YYYYZZZZ #write 32bits (2): 04XXXXXX ZZZZZZZZ #string code (3): 06XXXXXX YYYYYYYY, d1d1d1d1 d2d2d2d2, d3d3d3d3 .... #Serial Code (4): 08XXXXXX YYYYYYYY TNNNZZZZ VVVVVVVV _write: add r12,r12,r3 #address = (ba/po)+(XXXXXX) cmpwi r5,3 beq- _write_string #r5 == 3, goto string code bgt- _write_serial #r5 >= 4, goto serial code bne- cr7,_readcodes #lf code execution set to false skip code cmpwi cr4,r5,1 #compares sub code type and 1 in cr4 bgt- cr4,_write32 #lf sub code type == 2, goto write32 #lf sub code type = 0 or 1 (8/16bits) rlwinm r10,r4,16,16,31 #r10 = extract number of times to write (16bits value) _write816: beq cr4,+16 #lf r5 = 1 then 16 bits write stbx r4,r9,r12 #write byte addi r9,r9,1 b +12 sthx r4,r9,r12 #write halfword addi r9,r9,2 subic. r10,r10,1 #number of times to write -1 bge- _write816 b _readcodes _write32: rlwinm r12,r12,0,0,29 #32bits align adress stw r4,0(r12) #write word to address b _readcodes _write_string: #endianess ? mr r9,r4 bne- cr7,_skip_and_align #lf code execution is false, skip string code data _stb: subic. r9,r9,1 #r9 -= 1 (and compares r9 with 0) blt- _skip_and_align #lf r9 < 0 then ExploitCode102_Exit lbzx r5,r9,r15 stbx r5,r9,r12 #loop until all the data has been written b _stb _write_serial: addi r15,r15,8 #r15 points to the code after the serial code bne- cr7,_readcodes #lf code execution is false, skip serial code lwz r5,-8(r15) #load TNNNZZZZ lwz r11,-4(r15) #r11 = load VVVVVVVV rlwinm r17,r5,0,16,31 #r17 = ZZZZ rlwinm r10,r5,16,20,31 #r10 = NNN (# of times to write -1) rlwinm r5,r5,4,28,31 #r5 = T (0:8bits/1:16bits/2:32bits) _loop_serial: cmpwi cr5,r5,1 beq- cr5,+16 #lf 16bits bgt+ cr5,+20 #lf 32bits stbx r4,r9,r12 #write serial byte (CT04,T=0) b +16 sthx r4,r9,r12 #write serial halfword (CT04,T=1) b +8 stwx r4,r9,r12 #write serial word (CT04,T>=2) add r4,r4,r11 #value +=VVVVVVVV add r9,r9,r17 #address +=ZZZZ subic. r10,r10,1 bge+ _loop_serial #loop until all the data has been written b _readcodes #CT1============================================================================= #32bits conditional (0,1,2,3): 20XXXXXX YYYYYYYY #16bits conditional (4,5,6,7): 28XXXXXX ZZZZYYYY #PS : 31 bit of address = endlf. _conditional: rlwinm. r9,r3,0,31,31 #r10 = (bit31 & 1) (endlf enabled?) beq +16 #jump lf endlf is not enabled rlwinm r8,r8,31,1,31 #Endlf (r8>>1) andi. r9,r8,1 #r9=code execution status cmpwi cr7,r9,0 #check code execution status in cr7 cmpwi cr5,r5,4 #compares sub code type and 4 in cr5 cmpwi cr3,r10,5 #compares code type and 5 in cr3 rlwimi r8,r8,1,0,30 #r8<<1 and current execution status = old execution status bne- cr7,_true_end #lf code execution is set to false -> ExploitCode102_Exit bgt cr3,_addresscheck2 #lf code type==6 -> address check add r12,r12,r3 #address = (ba/po)+(XXXXXX) blt cr3,+12 #jump lf code type <5 (==1) blt cr5,_condition_sub #compare [rN][rM] b _conditional16_2 #counter compare bge cr5,_conditional16 #lf sub code type>=4 -> 16 bits conditional _conditional32: rlwinm r12,r12,0,0,29 #32bits align lwz r11,0(r12) b _condition_sub _conditional16: rlwinm r12,r12,0,0,30 #16bits align lhz r11,0(r12) _conditional16_2: nor r9,r4,r4 rlwinm r9,r9,16,16,31 #r9 = extract mask and r11,r11,r9 #r11 &= r9 rlwinm r4,r4,0,16,31 #r4 = extract data to check against _condition_sub: cmpl cr6,r11,r4 #Unsigned compare. r11=data at address, r4=YYYYYYYY andi. r9,r5,3 beq _skip_NE #lf sub code (type & 3) == 0 cmpwi r9,2 beq _skip_LE #lf sub code (type & 3) == 2 bgt _skip_GE #lf sub code (type & 3) == 3 _skip_EQ:#1 bne- cr6,_true_end #CT21, CT25, CT29 or CT2D (lf !=) b _skip _skip_NE:#0 beq- cr6,_true_end #CT20, CT24, CT28 or CT2C (lf==) b _skip _skip_LE:#2 bgt- cr6,_true_end #CT22, CT26, CT2A or CT2E (lf r4>[]) b _skip _skip_GE:#3 blt- cr6,_true_end #CT23, CT27, CT2B or CT2F (lf r4 5 blt cr5,_readcodes lwz r11,-8(r15) #load counter bne cr7,_clearcounter #lf previous code execution false clear counter andi. r12,r3,0x8 #else lf clear counter bit not set increase counter beq _increase_counter andi. r12,r8,0x1 #else lf.. code result true clear counter beq _clearcounter _increase_counter: addi r12,r11,0x10 #else increase the counter rlwimi r11,r12,0,12,27 #update counter b _savecounter _clearcounter: rlwinm r11,r11,0,28,11 #clear the counter _savecounter: stw r11,-8(r15) #save counter b _readcodes #CT2============================================================================ #load base adress (0): 40TYZ00N XXXXXXXX = (load/add:T) ba from [(ba/po:Y)+XXXXXXXX(+rN:Z)] #set base address (1): 42TYZ00N XXXXXXXX = (set/add:T) ba to (ba/po:Y)+XXXXXXXX(+rN:Z) #store base address (2): 440Y0000 XXXXXXXX = store base address to [(ba/po)+XXXXXXXX] #set base address to (3): 4600XXXX 00000000 = set base address to code address+XXXXXXXX #load pointer (4): 48TYZ00N XXXXXXXX = (load/add:T) po from [(ba/po:Y)+XXXXXXXX(+rN:Z)] #set pointer (5): 4ATYZ00N XXXXXXXX = (set/add:T) po to (ba/po:Y)+XXXXXXXX(+rN:Y) #store pointer (6): 4C0Y0000 XXXXXXXX = store pointer to [(ba/po)+XXXXXXXX] #set pointer to (7): 4E00XXXX 00000000 = set pointer to code address+XXXXXXXX _ba_pointer: bne- cr7,_readcodes rlwinm r9,r3,2,26,29 #r9 = extract N, makes N*4 rlwinm r14,r3,16,31,31 #r3 = add ba/po flag bit (Y) cmpwi cr3,r14,0 cmpwi cr4,r5,4 #cr4 = compare sub code type with 4 (ba/po) andi. r14,r5,3 #r14 = sub code type and 3 cmpwi cr5,r14,2 #compares sub code type and 2 blt- cr5,_p01 beq- cr5,_p2 #sub code type 2 _p3: extsh r4,r3 add r4,r4,r15 #r4=XXXXXXXX+r15 (code location in memory) b _pend _p01: rlwinm. r5,r3,20,31,31 #r3 = rN use bit (Z) beq +12 #flag is not set(=0), address = XXXXXXXX lwzx r9,r7,r9 #r9 = load register N add r4,r4,r9 #flag is set (=1), address = XXXXXXXX+rN beq cr3,+8 #(Y) flag is not set(=0), address = XXXXXXXX (+rN) add r4,r12,r4 #address = XXXXXXXX (+rN) + (ba/po) cmpwi cr5,r14,1 beq cr5,+8 #address = (ba/po)+XXXXXXXX(+rN) lwz r4,0(r4) #address = [(ba/po)+XXXXXXXX(+rN)] rlwinm. r3,r3,12,31,31 #r5 = add/replace flag (T) beq _pend #flag is not set (=0), (ba/po)= XXXXXXXX (+rN) + (ba/po) bge cr4,+12 add r4,r4,r6 #ba += XXXXXXXX (+rN) + (ba/po) b _pend add r4,r4,r16 #po += XXXXXXXX (+rN) + (ba/po) b _pend _p2: rlwinm. r5,r3,20,31,31 #r3 = rN use bit (Z) beq +12 #flag is not set(=0), address = XXXXXXXX lwzx r9,r7,r9 #r9 = load register N add r4,r4,r9 #flag is set (=1), address = XXXXXXXX+rN bge cr4,+12 stwx r6,r12,r4 #[(ba/po)+XXXXXXXX] = base address b _readcodes stwx r16,r12,r4 #[(ba/po)+XXXXXXXX] = pointer b _readcodes _pend: bge cr4,+12 mr r6,r4 #store result to base address b _readcodes mr r16,r4 #store result to pointer b _readcodes #CT3============================================================================ #set repeat (0): 6000ZZZZ 0000000P = set repeat #execute repeat (1): 62000000 0000000P = execute repeat #return (2): 64S00000 0000000P = return (lf true/false/always) #goto (3): 66S0XXXX 00000000 = goto (lf true/false/always) #gosub (4): 68S0XXXX 0000000P = gosub (lf true/false/always) _repeat_goto: rlwinm r9,r4,3,25,28 #r9 = extract P, makes P*8 addi r9,r9,0x40 #offset that points to block P's cmpwi r5,2 #compares sub code type with 2 blt- _repeat rlwinm. r11,r3,10,0,1 #extract (S&3) beq +20 #S=0, skip lf true, don't skip lf false bgt +8 b _b_bl_blr_nocheck #S=2/3, always skip (code exec status turned to true) beq- cr7,_readcodes #S=1, skip lf false, don't skip lf true b _b_bl_blr_nocheck _b_bl_blr: bne- cr7,_readcodes #lf code execution set to false skip code _b_bl_blr_nocheck: cmpwi r5,3 bgt- _bl #sub code type >=4, bl beq+ _b #sub code type ==3, b _blr: lwzx r15,r7,r9 #loads the next code address b _readcodes _bl: stwx r15,r7,r9 #stores the next code address in block P's address _b: extsh r4,r3 #XXXX becomes signed rlwinm r4,r4,3,9,28 add r15,r15,r4 #next code address +/-=line XXXX b _readcodes _repeat: bne- cr7,_readcodes #lf code execution set to false skip code add r5,r7,r9 #r5 points to P address bne- cr4,_execute_repeat #branch lf sub code type == 1 _set_repeat: rlwinm r4,r3,0,16,31 #r4 = extract NNNNN stw r15,0(r5) #store current code address to [bP's address] stw r4,4(r5) #store NNNN to [bP's address+4] b _readcodes _execute_repeat: lwz r9,4(r5) #load NNNN from [M+4] cmpwi r9,0 beq- _readcodes subi r9,r9,1 stw r9,4(r5) #saves (NNNN-1) to [bP's address+4] lwz r15,0(r5) #load next code address from [bP's address] b _readcodes #CT4============================================================================ #set/add to rN(0) : 80SY000N XXXXXXXX = rN = (ba/po) + XXXXXXXX #load rN (1) : 82UY000N XXXXXXXX = rN = [XXXXXXXX] (offset support) (U:8/16/32) #store rN (2) : 84UYZZZN XXXXXXXX = store rN in [XXXXXXXX] (offset support) (8/16/32) #operation 1 (3) : 86TY000N XXXXXXXX = operation rN?XXXXXXXX ([rN]?XXXXXXXX) #operation 2 (4) : 88TY000N 0000000M = operation rN?rM ([rN]?rM, rN?[rM], [rN]?[rM]) #copy1 (5) : 8AYYYYNM XXXXXXXX = copy YYYY bytes from [rN] to ([rM]+)XXXXXXXX #copy2 (6) : 8CYYYYNM XXXXXXXX = copy YYYY bytes from ([rN]+)XXXXXX to [rM] #for copy1/copy2, lf register == 0xF, base address is used. #of course, sub codes types 0/1, 2/3 and 4/5 can be put together lf we need more subtypes. _operation_rN: bne- cr7,_readcodes rlwinm r11,r3,2,26,29 #r11 = extract N, makes N*4 add r26,r7,r11 #1st value address = rN's address lwz r9,0(r26) #r9 = rN rlwinm r14,r3,12,30,31 #extracts S, U, T (3bits) beq- cr4,_op0 #lf sub code type = 0 cmpwi cr4,r5,5 bge- cr4,_op56 #lf sub code type = 5/6 cmpwi cr4,r5,3 bge- cr4,_op34 #lf sub code type = 3/4 cmpwi cr4,r5,1 _op12: #load/store rlwinm. r5,r3,16,31,31 #+(ba/po) flag : Y beq +8 #address = XXXXXXXX add r4,r12,r4 cmpwi cr6,r14,1 bne- cr4,_store _load: bgt+ cr6,+24 beq- cr6,+12 lbz r4,0(r4) #load byte at address b _store_reg lhz r4,0(r4) #load halfword at address b _store_reg lwz r4,0(r4) #load word at address b _store_reg _store: rlwinm r19,r3,28,20,31 #r9=r3 ror 12 (N84UYZZZ) _storeloop: bgt+ cr6,+32 beq- cr6,+16 stb r9,0(r4) #store byte at address addi r4,r4,1 b _storeloopend sth r9,0(r4) #store byte at address addi r4,r4,2 b _storeloopend stw r9,0(r4) #store byte at address addi r4,r4,4 _storeloopend: subic. r19,r19,1 bge _storeloop b _readcodes _op0: rlwinm. r5,r3,16,31,31 #+(ba/po) flag : Y beq +8 #value = XXXXXXXX add r4,r4,r12 #value = XXXXXXXX+(ba/po) andi. r5,r14,1 #add flag : S beq _store_reg #add flag not set (=0), rN=value add r4,r4,r9 #add flag set (=1), rN=rN+value b _store_reg _op34: #operation 1 & 2 rlwinm r10,r3,16,30,31 #extracts Y rlwinm r14,r4,2,26,29 #r14 = extract M (in r4), makes M*=4 add r19,r7,r14 #2nd value address = rM's address bne cr4,+8 subi r19,r15,4 #lf CT3, 2nd value address = XXXXXXXX's address lwz r4,0(r26) #1st value = rN lwz r9,0(r19) #2nd value = rM/XXXXXXXX andi. r11,r10,1 #lf [] for 1st value beq +8 mr r26,r4 andi. r11,r10,2 #lf [] for 2nd value beq +16 mr r19,r9 bne+ cr4,+8 add r19,r12,r19 #lf CT3, 2nd value address = XXXXXXXX+(ba/op) rlwinm. r5,r3,12,28,31 #operation # flag : T cmpwi r5,9 bge _op_float _operation_bl: bl _operation_bl_return _op450: add r4,r9,r4 #N + M b _store_reg _op451: mullw r4,r9,r4 #N * M b _store_reg _op452: or r4,r9,r4 #N | M b _store_reg _op453: and r4,r9,r4 #N & M b _store_reg _op454: xor r4,r9,r4 #N ^ M b _store_reg _op455: slw r4,r9,r4 #N << M b _store_reg _op456: srw r4,r9,r4 #N >> M b _store_reg _op457: rlwnm r4,r9,r4,0,31 #N rol M b _store_reg _op458: sraw r4,r9,r4 #N asr M _store_reg: stw r4,0(r26) #Store result in rN/[rN] b _readcodes _op_float: cmpwi r5,0xA bgt _readcodes lfs f2,0(r26) #f2 = load 1st value lfs f3,0(r19) #f3 = load 2nd value beq- _op45A _op459: fadds f2,f3,f2 #N = N + M (float) b _store_float _op45A: fmuls f2,f3,f2 #N = N * M (float) _store_float: stfs f2,0(r26) #Store result in rN/[rN] b _readcodes _operation_bl_return: mflr r10 rlwinm r5,r5,3,25,28 #r5 = T*8 add r10,r10,r5 #jumps to _op5: + r5 lwz r4,0(r26) #load [rN] lwz r9,0(r19) #2nd value address = rM/XXXXXXXX mtlr r10 blr #copy1 (5) : 8AYYYYNM XXXXXXXX = copy YYYY bytes from [rN] to ([rM]+)XXXXXXXX #copy2 (6) : 8CYYYYNM XXXXXXXX = copy YYYY bytes from ([rN]+)XXXXXX to [rM] _op56: bne- cr7,_readcodes #lf code execution set to false skip code rlwinm r9,r3,24,0,31 #r9=r3 ror 8 (NM8AYYYY, NM8CYYYY) mr r14,r12 #r14=(ba/po) bl _load_NM beq- cr4,+12 add r17,r17,r4 #lf sub code type==0 then source+=XXXXXXXX b +8 add r9,r9,r4 #lf sub code type==1 then destination+=XXXXXXXX rlwinm. r4,r3,24,16,31 #Extracts YYYY, compares it with 0 li r5,0 _copy_loop: beq _readcodes #Loop until all bytes have been copied. lbzx r10,r5,r17 stbx r10,r5,r9 addi r5,r5,1 cmpw r5,r4 b _copy_loop #=============================================================================== #This is a routine called by _memory_copy and _compare_NM_16 _load_NM: cmpwi cr5,r10,4 #compare code type and 4(rn Operations) in cr5 rlwinm r17,r9,6,26,29 #Extracts N*4 cmpwi r17,0x3C lwzx r17,r7,r17 #Loads rN value in r17 bne +8 mr r17,r14 #lf N==0xF then source address=(ba/po)(+XXXXXXXX, CT5) beq cr5,+8 lhz r17,0(r17) #...and lf CT5 then N = 16 bits at [XXXXXX+base address] rlwinm r9,r9,10,26,29 #Extracts M*4 cmpwi r9,0x3C lwzx r9,r7,r9 #Loads rM value in r9 bne +8 mr r9,r14 #lf M==0xF then dest address=(ba/po)(+XXXXXXXX, CT5) beq cr5,+8 lhz r9,0(r9) #...and lf CT5 then M = 16 bits at [XXXXXX+base address] blr #CT5============================================================================ #16bits conditional (0,1,2,3): A0XXXXXX NM00YYYY (unknown values) #16bits conditional (4,5,6,7): A8XXXXXX ZZZZYYYY (counter) #sub codes types 0,1,2,3 compare [rN] with [rM] (both 16bits values) #lf register == 0xF, the value at [base address+XXXXXXXX] is used. _compare16_NM_counter: cmpwi r5,4 bge _compare16_counter _compare16_NM: mr r9,r4 #r9=NM00YYYY add r14,r3,r12 #r14 = XXXXXXXX+(ba/po) rlwinm r14,r14,0,0,30 #16bits align (base address+XXXXXXXX) bl _load_NM #r17 = N's value, r9 = M's value nor r4,r4,r4 #r4=!r4 rlwinm r4,r4,0,16,31 #Extracts !YYYY and r11,r9,r4 #r3 = (M AND !YYYY) and r4,r17,r4 #r4 = (N AND !YYYY) b _conditional _compare16_counter: rlwinm r11,r3,28,16,31 #extract counter value from r3 in r11 b _conditional #=============================================================================== #execute (0) : C0000000 NNNNNNNN = execute #hook1 (2) : C4XXXXXX NNNNNNNN = insert instructions at XXXXXX #hook2 (3) : C6XXXXXX YYYYYYYY = branch from XXXXXX to YYYYYY #on/off (6) : CC000000 00000000 = on/off switch #range check (7) : CE000000 XXXXYYYY = is ba/po in XXXX0000-YYYY0000 _hook_execute: mr r26,r4 #r18 = 0YYYYYYY rlwinm r4,r4,3,0,28 #r4 = NNNNNNNN*8 = number of lines (and not number of bytes) bne- cr4,_hook_addresscheck #lf sub code type != 0 bne- cr7,_skip_and_align _execute: mtlr r15 blrl _skip_and_align: add r15,r4,r15 addi r15,r15,7 rlwinm r15,r15,0,0,28 #align 64-bit b _readcodes _hook_addresscheck: cmpwi cr4,r5,3 bgt- cr4,_addresscheck1 #lf sub code type ==6 or 7 lis r5,0x4800 add r12,r3,r12 rlwinm r12,r12,0,0,29 #align address bne- cr4,_hook1 #lf sub code type ==2 _hook2: bne- cr7,_readcodes rlwinm r4,r26,0,0,29 #address &=0x01FFFFFC sub r4,r4,r12 #r4 = to-from rlwimi r5,r4,0,6,29 #r5 = (r4 AND 0x03FFFFFC) OR 0x48000000 rlwimi r5,r3,0,31,31 #restore lr bit stw r5,0(r12) #store opcode b _readcodes _hook1: bne- cr7,_skip_and_align sub r9,r15,r12 #r9 = to-from rlwimi r5,r9,0,6,29 #r5 = (r9 AND 0x03FFFFFC) OR 0x48000000 stw r5,0(r12) #stores b at the hook place (over original instruction) addi r12,r12,4 add r11,r15,r4 subi r11,r11,4 #r11 = address of the last work of the hook1 code sub r9,r12,r11 rlwimi r5,r9,0,6,29 #r5 = (r9 AND 0x03FFFFFC) OR 0x48000000 stw r5,0(r11) #stores b at the last word of the hook1 code b _skip_and_align _addresscheck1: cmpwi cr4,r5,6 beq cr4,_onoff b _conditional _addresscheck2: rlwinm r12,r12,16,16,31 rlwinm r4,r26,16,16,31 rlwinm r26,r26,0,16,31 cmpw r12,r4 blt _skip cmpw r12,r26 bge _skip b _readcodes _onoff: rlwinm r5,r26,31,31,31 #extracts old exec status (x b a) xori r5,r5,1 andi. r3,r8,1 #extracts current exec status cmpw r5,r3 beq _onoff_end rlwimi r26,r8,1,30,30 xori r26,r26,2 rlwinm. r5,r26,31,31,31 #extracts b beq +8 xori r26,r26,1 stw r26,-4(r15) #updates the code value in the code list _onoff_end: rlwimi r8,r26,0,31,31 #current execution status = a b _readcodes #=============================================================================== #Full terminator (0) = E0000000 XXXXXXXX = full terminator #Endlfs/Else (1) = E2T000VV XXXXXXXX = endlfs (+else) #End code handler = F0000000 00000000 _terminator_onoff_: cmpwi r11,0 #lf code type = 0xF beq _notTerminator cmpwi r5,1 beq _asmTypeba cmpwi r5,2 beq _asmTypepo cmpwi r5,3 beq _patchType b _exitcodehandler _asmTypeba: rlwinm r12,r6,0,0,6 # use base address _asmTypepo: rlwinm r23,r4,8,24,31 # extract number of half words to XOR rlwinm r24,r4,24,16,31 # extract XOR checksum rlwinm r4,r4,0,24,31 # set code value to number of ASM lines only bne cr7,_goBackToHandler #skip code if code execution is set to false rlwinm. r25,r23,0,24,24 # check for negative number of half words mr r26,r12 # copy ba/po address add r26,r3,r26 # add code offset to ba/po code address rlwinm r26,r26,0,0,29 # clear last two bits to align address to 32-bit beq _positiveOffset # if number of half words is negative, extra setup needs to be done extsb r23,r23 neg r23,r23 mulli r25,r23,2 addi r25,r25,4 subf r26,r25,r26 _positiveOffset: cmpwi r23,0 beq _endXORLoop li r25,0 mtctr r23 _XORLoop: lhz r27,4(r26) xor r25,r27,r25 addi r26,r26,2 bdnz _XORLoop _endXORLoop: cmpw r24,r25 bne _goBackToHandler b _hook_execute _patchType: rlwimi r8,r8,1,0,30 #r8<<1 and current execution status = old execution status bne cr7,_exitpatch #lf code execution is set to false -> ExploitCode102_Exit rlwinm. r23,r3,22,0,1 bgt _patchfail blt _copytopo _runpatch: rlwinm r30,r3,0,24,31 mulli r30,r30,2 rlwinm r23,r4,0,0,15 xoris r24,r23,0x8000 cmpwi r24,0 bne- _notincodehandler ori r23,r23,0x3000 _notincodehandler: rlwinm r24,r4,16,0,15 mulli r25,r30,4 subf r24,r25,r24 _patchloop: li r25,0 _patchloopnext: mulli r26,r25,4 lwzx r27,r15,r26 lwzx r26,r23,r26 addi r25,r25,1 cmplw r23,r24 bgt _failpatchloop cmpw r25,r30 bgt _foundaddress cmpw r26,r27 beq _patchloopnext addi r23,r23,4 b _patchloop _foundaddress: lwz r3,-8(r15) ori r3,r3,0x300 stw r3,-8(r15) stw r23,-4(r15) mr r16,r23 b _exitpatch _failpatchloop: lwz r3,-8(r15) ori r3,r3,0x100 stw r3,-8(r15) _patchfail: ori r8,r8,1 #r8|=1 (execution status set to false) b _exitpatch _copytopo: mr r16,r4 _exitpatch: rlwinm r4,r3,0,24,31 # set code to number of lines only _goBackToHandler: mulli r4,r4,8 add r15,r4,r15 # skip the lines of the code b _readcodes _notTerminator: _terminator: bne cr4,+12 #check lf sub code type == 0 li r8,0 #clear whole code execution status lf T=0 b +20 rlwinm. r9,r3,0,27,31 #extract VV # bne +8 #lf VV!=0 # bne- cr7,+16 rlwinm r5,r3,12,31,31 #extract "else" bit srw r8,r8,r9 #r8>>VV, meaning endlf VV lfs rlwinm. r23,r8,31,31,31 bne +8 # execution is false if code execution >>, so don't invert code status xor r8,r8,r5 #lf 'else' is set then invert current code status _load_baseaddress: rlwinm. r5,r4,0,0,15 beq +8 mr r6,r5 #base address = r4 rlwinm. r5,r4,16,0,15 beq +8 mr r16,r5 #pointer = r4 b _readcodes #=============================================================================== frozenvalue: #frozen value, then LR .long 0,0 dwordbuffer: .long 0,0 rem: .long 0 bpbuffer: .long 0 #int address to bp on .long 0 #data address to bp on .long 0 #alignement check .long 0 #counter for alignement regbuffer: #.space 72*4 #.align 3 #codelist: #.space 2*4 #.end #endregion #region ExploitCode101 ExploitCode101: blrl #Scene Change branchl r12,0x801a4518 #Start Menu li r3, 0 lis r4, 0x804D stb r3, 0x5B9C (r4) #Disable Saving lis r5,0x8043 li r6, 4 stw r6, 0x2640 (r5) #Error SFX li r3,3 branchl r12,0x80024030 #Error SFX li r3,3 branchl r12,0x80024030 #Zero Nametag and exit load r3,0x80239700 mtlr r3 load r3,0x8045cb70 li r4,0 load r5,0xC344 branch r12,0x80003130 #endregion #region ExploitCode100 ExploitCode100: blrl #Scene Change branchl r12,0x801a3e18 #Start Menu li r3, 0 lis r4, 0x804D stb r3, 0x473c (r4) #Disable Saving lis r5,0x8043 li r6,4 stw r6,0x1360 (r5) #Error SFX li r3,3 branchl r12,0x80023fb0 #Error SFX li r3,3 branchl r12,0x80023fb0 #Zero Nametag and exit load r3,0x80238b90 mtlr r3 load r3,0x8045b888 li r4,0 load r5,0xC344 branch r12,0x80003130 #endregion ExitInjection: #Exit restore blr #region SnapshotBanner: SnapshotBanner: blrl .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x26,0x98,0xa6 .byte 0x84,0x25,0x84,0x46,0x88,0x46,0xc5,0xc6,0x84,0x25,0x84,0x25,0x9c,0xc6,0xb1,0x26 .byte 0x88,0x45,0xa0,0xe6,0xa5,0x06,0xa4,0xe6,0xc5,0xa6,0xb1,0x46,0xad,0x26,0xad,0x26 .byte 0x9c,0xc6,0x9c,0xc6,0x9c,0xc6,0x9c,0xc6,0xad,0x26,0xff,0x67,0xff,0x47,0xff,0x27 .byte 0xa4,0xe6,0xa9,0x06,0xa9,0x06,0xa9,0x06,0xad,0x26,0xad,0x26,0xad,0x26,0xad,0x26 .byte 0x9c,0xc6,0x9c,0xc6,0x9c,0xc6,0x90,0x85,0xff,0x27,0xff,0x47,0xff,0x67,0xd6,0x26 .byte 0xa5,0x06,0xa9,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xb1,0x46 .byte 0x80,0x05,0x80,0x06,0x80,0x05,0x80,0x05,0x80,0x05,0x88,0x46,0x84,0x25,0x80,0x25 .byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xad,0x26,0xad,0x26,0xad,0x26 .byte 0x84,0x25,0x9c,0xc6,0x9c,0xc6,0x9c,0xc6,0x94,0x85,0xff,0x07,0xff,0x47,0xff,0x47 .byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xad,0x26,0xad,0x26,0xb1,0x26,0xb1,0x46 .byte 0x9c,0xc6,0x9c,0xc6,0x88,0x45,0x80,0x05,0xff,0x47,0xff,0x47,0xf6,0xe7,0xa9,0x06 .byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46 .byte 0x80,0x05,0x80,0x26,0x80,0x05,0x80,0x05,0x80,0x05,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46 .byte 0x80,0x05,0x80,0x26,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x26,0x8c,0x66 .byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xad,0x26,0xad,0x26,0xb1,0x26,0xb1,0x46 .byte 0x94,0x85,0xa0,0xe6,0x8c,0x45,0x80,0x05,0xf2,0xc7,0xff,0x67,0xd6,0x06,0x80,0x05 .byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46 .byte 0x80,0x05,0x80,0x26,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x88,0x46,0x88,0x46 .byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xad,0x26 .byte 0x80,0x05,0x80,0x06,0x88,0x45,0x9c,0xc6,0x84,0x25,0x80,0x26,0xb1,0x46,0xff,0x87 .byte 0xa4,0xe6,0xa5,0x06,0xa5,0x06,0xa4,0xe6,0xb1,0x26,0xb5,0x46,0xb1,0x46,0xb1,0x46 .byte 0x8c,0x65,0x80,0x06,0x80,0x05,0x80,0x05,0xbd,0x86,0x80,0x06,0x88,0x46,0x88,0x46 .byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xb5,0x46,0xad,0x26,0xad,0x26 .byte 0x80,0x05,0x80,0x06,0x98,0xa6,0x9c,0xc6,0x84,0x26,0x88,0x46,0xea,0x87,0xff,0x67 .byte 0xa4,0xe6,0xa5,0x06,0xa5,0x06,0xa4,0xe6,0xb1,0x46,0xb5,0x46,0xb5,0x46,0xb1,0x26 .byte 0x84,0x25,0x80,0x05,0x80,0x05,0x8c,0x65,0xc1,0xa6,0x80,0x06,0x80,0x06,0xc1,0xa6 .byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xad,0x26,0xb1,0x46,0xb5,0x46,0xb1,0x46 .byte 0x9c,0xc6,0x88,0x46,0x80,0x05,0x80,0x05,0xff,0x67,0xa4,0xe6,0x84,0x26,0x88,0x46 .byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xad,0x26 .byte 0x80,0x05,0x80,0x05,0x80,0x26,0x98,0xa6,0x84,0x26,0x84,0x26,0x8c,0x66,0xf6,0xe7 .byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xad,0x26,0xb1,0x46,0xb5,0x46,0xb1,0x46 .byte 0x98,0xa6,0x80,0x05,0x80,0x06,0x80,0x05,0xee,0xc6,0x88,0x46,0x88,0x46,0x84,0x26 .byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xad,0x26 .byte 0x80,0x05,0x80,0x05,0x8c,0x66,0x9c,0xc6,0x84,0x25,0x80,0x05,0xbd,0x86,0xff,0x67 .byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xad,0x26,0xb1,0x46,0xb5,0x46,0xb1,0x46 .byte 0x90,0x65,0x80,0x05,0x80,0x06,0x84,0x25,0xee,0xa7,0x88,0x45,0x80,0x26,0x94,0x85 .byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xad,0x26,0xad,0x26,0xb5,0x46,0xb1,0x46 .byte 0x9c,0xc6,0x90,0x85,0x80,0x06,0x80,0x05,0xff,0x47,0xd2,0x06,0x80,0x06,0x84,0x25 .byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xb1,0x46 .byte 0x80,0x05,0x80,0x05,0x80,0x26,0x80,0x05,0x84,0x25,0x84,0x25,0x88,0x46,0x80,0x05 .byte 0xa4,0xe6,0xa4,0xe6,0xa9,0x06,0xa9,0x06,0xb1,0x46,0xad,0x26,0xad,0x26,0xa9,0x06 .byte 0x80,0x05,0x8c,0x65,0xb1,0x46,0xbd,0x86,0xb1,0x46,0xfb,0x07,0xff,0x47,0xfb,0x07 .byte 0xa9,0x06,0xa9,0x06,0xa5,0x06,0x90,0x66,0xad,0x26,0xb1,0x26,0xb5,0x46,0xc5,0xc6 .byte 0xad,0x26,0x88,0x45,0x80,0x05,0x84,0x25,0xff,0x47,0xf2,0xe7,0xa0,0xe6,0x80,0x05 .byte 0x80,0x05,0x84,0x26,0x88,0x46,0x84,0x25,0xa4,0xe6,0x80,0x26,0x88,0x46,0x88,0x46 .byte 0xc5,0xc6,0x94,0x86,0x84,0x25,0x84,0x25,0xa4,0xe6,0xb1,0x46,0x80,0x05,0x84,0x25 .byte 0x84,0x25,0x84,0x26,0xa0,0xe6,0xb1,0x26,0x84,0x25,0x84,0x26,0xa0,0xc6,0xb1,0x46 .byte 0x84,0x25,0x84,0x26,0xa0,0xe6,0xb1,0x46,0x84,0x25,0x84,0x26,0xa0,0xe6,0xb1,0x46 .byte 0x88,0x45,0xa0,0xe6,0xa0,0xc6,0xea,0x86,0x80,0x05,0x80,0x26,0x80,0x05,0xe2,0x66 .byte 0x80,0x05,0x88,0x46,0x84,0x26,0xe2,0x66,0x80,0x05,0x84,0x26,0x80,0x25,0xe2,0x66 .byte 0xff,0x07,0xa9,0x06,0xa0,0xc6,0x98,0xa6,0xff,0x07,0x90,0x66,0x80,0x06,0x84,0x26 .byte 0xff,0x07,0x90,0x86,0x84,0x25,0x84,0x25,0xff,0x07,0x90,0x86,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46,0x88,0x46,0x84,0x26 .byte 0x84,0x25,0x84,0x26,0x84,0x25,0x80,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x80,0x25 .byte 0x94,0x86,0xff,0x27,0xe6,0x87,0x9c,0xc6,0x94,0x86,0xff,0x27,0xda,0x26,0x80,0x05 .byte 0x94,0x85,0xff,0x27,0xea,0xa6,0xb1,0x46,0x94,0x85,0xfb,0x07,0xff,0x27,0xff,0x27 .byte 0x9c,0xc6,0xb5,0x66,0xff,0x27,0xee,0xc7,0x80,0x05,0x80,0x05,0xee,0xa7,0xfb,0x07 .byte 0xb1,0x46,0xc5,0xc6,0xfb,0x27,0xcd,0xe6,0xff,0x27,0xff,0x47,0xf7,0x07,0x9c,0xc6 .byte 0x88,0x46,0x88,0x46,0x88,0x46,0x88,0x46,0x8c,0x65,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0x80,0x05,0x84,0x26,0x84,0x25,0x84,0x25,0x80,0x05,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x88,0x46,0x80,0x06,0xad,0x26,0x84,0x25,0x84,0x26,0x80,0x05,0xda,0x26 .byte 0x84,0x25,0x84,0x26,0x90,0x65,0xfb,0x07,0x84,0x25,0x80,0x06,0xb5,0x46,0xff,0x67 .byte 0xff,0x47,0xff,0x27,0xf6,0xe7,0x90,0x66,0xf6,0xe7,0xcd,0xe6,0xff,0x47,0xb1,0x26 .byte 0xda,0x26,0x94,0x86,0xff,0x27,0xda,0x46,0xb5,0x66,0x84,0x26,0xea,0x86,0xfb,0x07 .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x80,0x05,0x84,0x26,0x84,0x25,0x84,0x25 .byte 0x80,0x05,0x84,0x26,0x84,0x25,0x84,0x25,0x94,0x85,0x84,0x26,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x80,0x05,0xb1,0x26,0xff,0x67,0x84,0x25,0x80,0x05,0xad,0x26,0xff,0x67 .byte 0x84,0x25,0x80,0x06,0xb1,0x26,0xff,0x67,0x84,0x25,0x80,0x06,0xb1,0x26,0xff,0x67 .byte 0xbd,0x86,0x80,0x05,0x84,0x25,0x84,0x25,0xbd,0x86,0x80,0x05,0x84,0x25,0x84,0x25 .byte 0xbd,0x86,0x80,0x06,0x84,0x25,0x84,0x25,0xbd,0x86,0x80,0x06,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0xe6,0x86,0xff,0x47,0x84,0x25,0x84,0x25,0xe6,0x87,0xf6,0xe7 .byte 0x84,0x25,0x84,0x26,0xea,0x87,0xea,0xa6,0x84,0x25,0x84,0x26,0xea,0x87,0xee,0xc7 .byte 0xfb,0x07,0x94,0x86,0x80,0x05,0xbd,0x86,0xfb,0x07,0xd6,0x26,0x80,0x05,0xbd,0x86 .byte 0xbd,0x86,0xff,0x47,0x9c,0xa6,0xb9,0x66,0x88,0x45,0xea,0xa6,0xe2,0x66,0xbd,0x86 .byte 0xff,0x47,0xa0,0xe6,0x80,0x05,0x84,0x25,0xff,0x47,0xa0,0xe6,0x80,0x05,0x84,0x25 .byte 0xff,0x47,0xa0,0xe6,0x80,0x25,0x84,0x25,0xff,0x47,0xa0,0xe6,0x80,0x26,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x8c,0x66,0xf6,0xe7,0x84,0x25,0x84,0x25,0x8c,0x46,0xf2,0xc7 .byte 0x84,0x25,0x84,0x25,0x8c,0x46,0xf2,0xc7,0x84,0x25,0x84,0x25,0x8c,0x66,0xf2,0xc7 .byte 0xee,0xa6,0x88,0x46,0x84,0x26,0x84,0x26,0xea,0xa6,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0xea,0xa6,0x84,0x25,0x84,0x26,0x84,0x25,0xea,0xa6,0x88,0x25,0x84,0x26,0x84,0x25 .byte 0x84,0x26,0x80,0x05,0xb9,0x66,0xff,0x47,0x84,0x25,0x80,0x05,0xb9,0x66,0xff,0x27 .byte 0x84,0x25,0x80,0x05,0xb9,0x66,0xff,0x47,0x84,0x25,0x80,0x05,0xb9,0x66,0xff,0x67 .byte 0xff,0x47,0xc1,0xa6,0x80,0x06,0x94,0x86,0xee,0xc7,0xfb,0x07,0x90,0x66,0x90,0x65 .byte 0xb5,0x46,0xf6,0xe7,0xd2,0x06,0x8c,0x65,0xa0,0xe6,0xb5,0x46,0xff,0x47,0xb1,0x26 .byte 0xff,0x27,0xd2,0x06,0x80,0x26,0x88,0x46,0xff,0x27,0xd2,0x06,0x80,0x05,0x84,0x25 .byte 0xff,0x27,0xd2,0x06,0x80,0x05,0x84,0x25,0xfb,0x07,0xd2,0x06,0x80,0x06,0x84,0x25 .byte 0x88,0x46,0x84,0x26,0x84,0x26,0x9c,0xc6,0x84,0x25,0x84,0x25,0x80,0x06,0xcd,0xe6 .byte 0x84,0x25,0x84,0x25,0x84,0x25,0xe6,0x66,0x84,0x25,0x84,0x25,0x84,0x26,0xe6,0x86 .byte 0xff,0x27,0xee,0xc7,0xa0,0xc6,0x88,0x45,0xff,0x67,0xad,0x06,0x80,0x06,0x84,0x26 .byte 0xff,0x07,0x90,0x85,0x80,0x25,0x8c,0x65,0xfb,0x07,0x90,0x65,0x80,0x05,0xb5,0x66 .byte 0xa9,0x06,0xff,0x27,0xf6,0xe7,0x88,0x45,0x80,0x05,0xa4,0xe6,0xb9,0x66,0x8c,0x46 .byte 0x98,0xa6,0x94,0x86,0x94,0x86,0x84,0x26,0xff,0x67,0xff,0x27,0xff,0x27,0x9c,0xa6 .byte 0x9c,0xc6,0xb1,0x46,0x80,0x26,0x84,0x25,0xa0,0xc6,0xb1,0x46,0x80,0x26,0x84,0x25 .byte 0xa0,0xc6,0xb1,0x46,0x84,0x26,0x88,0x46,0x9c,0xa6,0xb1,0x46,0x80,0x05,0x84,0x25 .byte 0x84,0x25,0x80,0x25,0xa0,0xc6,0xb1,0x46,0x84,0x25,0x84,0x26,0xa0,0xc6,0xb1,0x46 .byte 0x84,0x25,0x84,0x26,0xa0,0xc6,0xb1,0x46,0x84,0x25,0x84,0x26,0xa0,0xe6,0xb1,0x46 .byte 0x80,0x05,0x84,0x26,0x84,0x25,0xe2,0x66,0x80,0x05,0x88,0x46,0x84,0x25,0xe2,0x66 .byte 0x80,0x05,0x88,0x46,0x84,0x26,0xea,0x86,0x80,0x05,0x84,0x26,0x84,0x26,0xad,0x26 .byte 0xff,0x07,0x90,0x86,0x84,0x25,0x84,0x25,0xff,0x07,0x90,0x86,0x84,0x25,0x84,0x25 .byte 0xff,0x47,0x94,0x86,0x84,0x26,0x84,0x26,0xb9,0x66,0x8c,0x66,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x25 .byte 0x84,0x26,0x88,0x46,0x88,0x46,0x84,0x26,0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25 .byte 0x94,0x85,0xff,0x27,0xde,0x66,0x8c,0x65,0x94,0x85,0xff,0x27,0xda,0x46,0x80,0x05 .byte 0x94,0x86,0xff,0x47,0xe2,0x66,0x80,0x26,0x8c,0x45,0xb9,0x86,0xa9,0x06,0x80,0x05 .byte 0x8c,0x65,0xb9,0x66,0xff,0x47,0xd6,0x26,0x80,0x05,0x94,0xa6,0xff,0x27,0xe2,0x66 .byte 0x80,0x25,0x94,0xa6,0xff,0x47,0xee,0xa7,0x80,0x05,0x84,0x26,0xb5,0x46,0xb9,0x66 .byte 0x80,0x05,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x26 .byte 0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25,0x8c,0x45,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x84,0x26,0xde,0x46,0xff,0x47,0x80,0x25,0x98,0xa6,0xfb,0x27,0xea,0xa7 .byte 0x80,0x05,0xc5,0xa6,0xff,0xa7,0xb5,0x66,0x84,0x25,0xa9,0x06,0xb9,0x86,0x8c,0x65 .byte 0xfb,0x07,0xf6,0xe7,0xff,0x27,0xff,0x47,0xc1,0xa6,0xc5,0xc6,0xcd,0xe6,0xff,0x27 .byte 0x80,0x05,0x80,0x05,0x80,0x05,0xee,0xc7,0x80,0x25,0x84,0x26,0x80,0x25,0xa4,0xe6 .byte 0xb5,0x66,0x80,0x06,0x84,0x25,0x84,0x25,0xe2,0x66,0x84,0x26,0x88,0x46,0x88,0x46 .byte 0xff,0x47,0x9c,0xc6,0x80,0x05,0x84,0x25,0xb9,0x86,0x98,0xa6,0x80,0x25,0x84,0x25 .byte 0x84,0x25,0x80,0x06,0xb1,0x26,0xff,0x67,0x84,0x26,0x80,0x26,0xb1,0x46,0xff,0x67 .byte 0x84,0x25,0x80,0x05,0xb1,0x46,0xff,0x87,0x84,0x25,0x80,0x25,0x94,0x86,0xb9,0x86 .byte 0xbd,0x86,0x80,0x06,0x84,0x25,0x84,0x25,0xbd,0x86,0x80,0x06,0x88,0x46,0x88,0x46 .byte 0xc1,0x86,0x80,0x05,0x84,0x25,0x84,0x25,0x9c,0xc6,0x80,0x25,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x84,0x26,0xea,0x87,0xf2,0xc7,0x84,0x25,0x88,0x46,0xea,0xa7,0xf2,0xc7 .byte 0x84,0x25,0x84,0x25,0xee,0xc7,0xf6,0xe7,0x84,0x25,0x84,0x25,0xa9,0x06,0xb1,0x26 .byte 0x80,0x25,0xa5,0x06,0xff,0x27,0xea,0xa6,0x88,0x46,0x80,0x06,0xda,0x26,0xff,0x47 .byte 0x88,0x45,0x80,0x05,0x98,0xa6,0xff,0x27,0x84,0x25,0x84,0x25,0x80,0x05,0xa9,0x06 .byte 0xff,0x27,0xa0,0xe6,0x80,0x26,0x84,0x25,0xff,0x27,0xa0,0xe6,0x84,0x26,0x88,0x46 .byte 0xff,0x67,0xa0,0xe6,0x80,0x05,0x84,0x25,0xb9,0x66,0x90,0x66,0x80,0x25,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x8c,0x66,0xf2,0xc7,0x84,0x26,0x84,0x26,0x8c,0x66,0xf6,0xe7 .byte 0x84,0x25,0x84,0x25,0x8c,0x66,0xfb,0x07,0x84,0x25,0x80,0x25,0x84,0x25,0xb1,0x46 .byte 0xea,0xa6,0x88,0x25,0x84,0x26,0x84,0x25,0xea,0xa6,0x88,0x46,0x88,0x46,0x88,0x46 .byte 0xf2,0xc7,0x84,0x25,0x84,0x25,0x84,0x25,0xad,0x26,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x80,0x05,0xb9,0x66,0xff,0x67,0x88,0x46,0x80,0x06,0xb9,0x86,0xff,0x67 .byte 0x84,0x25,0x80,0x05,0xbd,0x86,0xff,0x87,0x84,0x25,0x80,0x05,0x98,0xa6,0xb9,0x86 .byte 0xa9,0x06,0x80,0x05,0xee,0xa7,0xf2,0xc7,0xad,0x26,0x80,0x05,0xad,0x26,0xff,0x47 .byte 0xad,0x26,0x80,0x05,0x80,0x26,0xda,0x46,0x90,0x85,0x80,0x05,0x80,0x05,0x90,0x85 .byte 0xff,0x27,0xcd,0xe6,0x80,0x06,0x84,0x25,0xff,0x47,0xcd,0xe6,0x80,0x06,0x84,0x26 .byte 0xff,0x87,0xd2,0x06,0x80,0x06,0x88,0x46,0xb9,0x86,0xa0,0xe6,0x80,0x05,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x80,0x26,0xda,0x26,0x84,0x25,0x84,0x25,0x80,0x26,0xad,0x26 .byte 0x84,0x26,0x84,0x25,0x88,0x46,0x84,0x26,0x84,0x25,0x84,0x25,0x84,0x26,0x80,0x05 .byte 0xff,0x47,0x9c,0xc6,0x80,0x06,0x94,0x85,0xff,0x67,0xde,0x46,0x8c,0x66,0x80,0x05 .byte 0xcd,0xe6,0xff,0x67,0xfb,0x07,0xe6,0x86,0x80,0x05,0xa9,0x06,0xd2,0x06,0xda,0x26 .byte 0xa4,0xe6,0xd6,0x06,0xff,0x47,0x9c,0xa6,0x90,0x65,0xee,0xa7,0xff,0x27,0x98,0xa6 .byte 0xff,0x07,0xe6,0x87,0xff,0x27,0x98,0xa6,0xb5,0x46,0x88,0x45,0xb1,0x46,0xb1,0x46 .byte 0x98,0xa6,0xb1,0x46,0x80,0x05,0x84,0x25,0x9c,0xc6,0xb1,0x46,0x80,0x26,0x84,0x25 .byte 0xb5,0x46,0xa0,0xe6,0x84,0x26,0x84,0x25,0xc1,0xa6,0x84,0x25,0x88,0x46,0x88,0x46 .byte 0x84,0x25,0x80,0x25,0xa0,0xc6,0xb1,0x46,0x84,0x25,0x80,0x25,0xa0,0xc6,0xad,0x26 .byte 0x84,0x25,0x84,0x26,0xa0,0xc6,0xad,0x26,0x84,0x25,0x84,0x26,0xa0,0xc6,0xad,0x26 .byte 0x80,0x05,0x88,0x46,0x84,0x25,0x80,0x05,0xc1,0x86,0xee,0xc7,0xea,0x86,0x94,0x85 .byte 0xcd,0xe6,0xff,0x47,0xff,0x47,0xa9,0x06,0xcd,0xe6,0xfb,0x07,0xf2,0xc7,0xc9,0xc6 .byte 0x80,0x05,0x84,0x26,0x84,0x25,0x88,0x45,0x80,0x05,0x8c,0x66,0xe2,0x66,0xee,0xe7 .byte 0x80,0x05,0xa0,0xe6,0xff,0x27,0xff,0x47,0x80,0x05,0xbd,0x86,0xf6,0xe7,0xf6,0xe7 .byte 0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25,0xcd,0xe6,0x84,0x26,0x84,0x25,0x84,0x25 .byte 0xda,0x46,0x84,0x26,0x84,0x25,0x84,0x25,0xda,0x46,0x84,0x26,0x84,0x26,0x80,0x05 .byte 0x84,0x25,0x80,0x05,0x80,0x05,0x90,0x85,0x80,0x05,0x94,0x86,0xda,0x46,0xff,0x27 .byte 0x8c,0x45,0xea,0xa6,0xff,0x47,0xc9,0xc6,0xb5,0x66,0xff,0x67,0xc9,0xc6,0x80,0x05 .byte 0x98,0xa6,0x90,0x86,0x80,0x05,0x80,0x05,0xff,0x47,0xff,0x27,0xd6,0x26,0x8c,0x65 .byte 0xa9,0x06,0xd2,0x06,0xff,0x67,0xe2,0x66,0x80,0x05,0x80,0x06,0xd6,0x06,0xff,0x67 .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x80,0x25,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25,0xad,0x06,0x80,0x26,0x88,0x46,0x88,0x46 .byte 0x84,0x25,0x84,0x26,0x80,0x05,0x84,0x25,0x80,0x05,0xc9,0xc6,0xee,0xc7,0xf2,0xc7 .byte 0x80,0x05,0xda,0x26,0xff,0x47,0xd6,0x06,0x80,0x05,0xd6,0x26,0xff,0x27,0x90,0x86 .byte 0x88,0x45,0x88,0x46,0x80,0x05,0x80,0x05,0xf6,0xe7,0xf2,0xc7,0xd6,0x26,0x94,0x86 .byte 0xc9,0xc6,0xda,0x26,0xff,0x47,0xee,0xa6,0x80,0x05,0x80,0x06,0xc5,0xa6,0xff,0x67 .byte 0x80,0x05,0x84,0x26,0x84,0x25,0x84,0x25,0x80,0x05,0x88,0x46,0x84,0x25,0x80,0x05 .byte 0x8c,0x45,0x84,0x26,0x84,0x25,0x80,0x05,0xb9,0x66,0x80,0x06,0x88,0x46,0x80,0x06 .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x05,0xa5,0x06,0xee,0xc7,0xf2,0xc7,0xf6,0xe7 .byte 0xad,0x26,0xff,0x67,0xe6,0x86,0xc9,0xc6,0xad,0x26,0xff,0x67,0xb5,0x46,0x80,0x05 .byte 0x84,0x25,0x88,0x46,0x88,0x45,0x84,0x25,0xf2,0xc7,0xf6,0xe7,0xea,0xa6,0x8c,0x65 .byte 0xcd,0xe6,0xcd,0xe6,0xc9,0xc6,0x88,0x45,0x80,0x05,0x80,0x06,0x80,0x06,0x80,0x26 .byte 0x84,0x25,0x88,0x46,0xad,0x26,0xb9,0x66,0x84,0x25,0xc1,0xa6,0xa9,0x06,0x8c,0x65 .byte 0x9c,0xa6,0xb9,0x86,0x80,0x06,0x84,0x25,0xa0,0xe6,0xb5,0x46,0x80,0x26,0x88,0x46 .byte 0xbd,0x86,0xc1,0x86,0xc1,0x86,0xb9,0x66,0x8c,0x65,0x8c,0x66,0x8c,0x66,0x8c,0x65 .byte 0x84,0x25,0x84,0x26,0x84,0x26,0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46,0x88,0x46 .byte 0xb9,0x66,0xbd,0x86,0xc1,0xa6,0xbd,0x86,0x8c,0x65,0x8c,0x66,0x8c,0x66,0x8c,0x65 .byte 0x84,0x25,0x84,0x25,0x84,0x46,0x84,0x25,0x88,0x46,0x88,0x46,0x88,0x46,0x88,0x46 .byte 0xbd,0x86,0xc1,0x86,0xc1,0x86,0xb9,0x66,0x8c,0x65,0x8c,0x66,0x8c,0x66,0x8c,0x65 .byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x8c,0x67,0x88,0x46,0x88,0x46,0x88,0x46 .byte 0xb9,0x66,0xbd,0x86,0xc1,0x86,0xbd,0x86,0x8c,0x65,0x8c,0x66,0x8c,0x66,0x8c,0x65 .byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x88,0x46,0x88,0x46,0x88,0x46,0x88,0x46 .byte 0xbd,0x86,0xc1,0x86,0xbd,0x86,0xb9,0x66,0x8c,0x65,0x8c,0x66,0x90,0x66,0x8c,0x65 .byte 0x84,0x25,0x84,0x25,0x84,0x46,0x84,0x25,0x88,0x46,0x84,0x26,0x88,0x46,0x8c,0x66 .byte 0xbd,0x86,0xc1,0x86,0xc1,0xa6,0xbd,0x86,0x8c,0x65,0x8c,0x65,0x90,0x66,0x8c,0x65 .byte 0x84,0x25,0x84,0x25,0x84,0x46,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x88,0x46 .byte 0xb9,0x66,0xb9,0x66,0xc1,0xa6,0xbd,0x86,0x8c,0x65,0x8c,0x65,0x90,0x66,0x8c,0x65 .byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x88,0x46 .byte 0xbd,0x86,0xbd,0x86,0xc1,0x86,0xbd,0x86,0x8c,0x65,0x8c,0x65,0x90,0x66,0x8c,0x65 .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x8c,0x67,0x8c,0x67 .byte 0xbd,0x86,0xb9,0x66,0xb9,0x66,0xb9,0x66,0x8c,0x65,0x8c,0x65,0x8c,0x66,0x8c,0x65 .byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x8c,0x67,0x88,0x46,0x88,0x46,0x88,0x46 .byte 0xb9,0x66,0xbd,0x86,0xb9,0x86,0xbd,0x86,0x8c,0x65,0x8c,0x65,0x8c,0x66,0x80,0x05 .byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x26,0x84,0x25,0x88,0x46,0x88,0x46 .byte 0x88,0x45,0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x26,0x88,0x46,0x84,0x25 .byte 0x84,0x26,0x84,0x26,0xa0,0xe6,0xad,0x26,0x84,0x25,0x84,0x25,0xa0,0xc6,0xad,0x26 .byte 0x84,0x25,0x84,0x26,0xa0,0xc6,0xad,0x26,0x84,0x25,0x84,0x26,0xa0,0xc6,0xa9,0x06 .byte 0xcd,0xe6,0xf6,0xe7,0xd6,0x26,0xe6,0x86,0xcd,0xe6,0xf6,0xe7,0xb9,0x66,0xf6,0xe7 .byte 0xcd,0xe6,0xfb,0x07,0xa0,0xe6,0xf6,0xe7,0xcd,0xe6,0xfb,0x07,0x90,0x65,0xe6,0x86 .byte 0x80,0x05,0xda,0x26,0xda,0x46,0xee,0xc7,0x90,0x65,0xee,0xa6,0xbd,0x86,0xee,0xc7 .byte 0xb9,0x66,0xf6,0xe7,0xa0,0xe6,0xf2,0xc7,0xee,0xc7,0xea,0xa6,0x90,0x65,0xf6,0xe7 .byte 0xda,0x46,0x80,0x26,0x84,0x25,0x80,0x05,0xda,0x46,0x80,0x25,0x84,0x25,0x80,0x05 .byte 0xda,0x46,0x80,0x26,0x84,0x25,0x80,0x05,0xda,0x46,0x84,0x26,0x84,0x25,0x80,0x05 .byte 0xd2,0x06,0xff,0x47,0x9c,0xc6,0x80,0x05,0xda,0x26,0xff,0x27,0x94,0x86,0x80,0x05 .byte 0xd2,0x06,0xff,0x47,0xa0,0xc6,0x80,0x05,0xb1,0x26,0xff,0x67,0xcd,0xe6,0x80,0x05 .byte 0x84,0x25,0x80,0x05,0xa9,0x06,0xff,0x67,0x84,0x25,0x80,0x05,0xa0,0xe6,0xff,0x47 .byte 0x84,0x25,0x80,0x06,0xad,0x26,0xff,0x67,0x80,0x05,0x80,0x26,0xda,0x46,0xff,0x67 .byte 0xc5,0xc6,0x80,0x05,0x84,0x25,0x84,0x25,0xcd,0xe6,0x80,0x05,0x84,0x25,0x84,0x25 .byte 0xc5,0xa6,0x80,0x06,0x84,0x25,0x84,0x25,0xa4,0xe6,0x80,0x26,0x84,0x25,0x84,0x25 .byte 0x80,0x05,0xd6,0x26,0xff,0x27,0x98,0xa6,0x80,0x05,0xd6,0x26,0xff,0x27,0x98,0xa6 .byte 0x80,0x05,0xd6,0x26,0xff,0x27,0x98,0xa6,0x80,0x05,0xd6,0x26,0xff,0x27,0x90,0x86 .byte 0x80,0x05,0x80,0x05,0xa0,0xc6,0xff,0x47,0x80,0x05,0x80,0x25,0x9c,0xc6,0xff,0x47 .byte 0x80,0x05,0x80,0x06,0xa9,0x06,0xff,0x67,0x80,0x05,0x84,0x26,0xda,0x46,0xff,0x67 .byte 0xd2,0x06,0x80,0x05,0x84,0x25,0x80,0x05,0xd6,0x26,0x80,0x05,0x84,0x25,0x80,0x05 .byte 0xc9,0xc6,0x80,0x06,0x84,0x25,0x80,0x05,0xa5,0x06,0x80,0x26,0x84,0x25,0x80,0x05 .byte 0xad,0x26,0xff,0x47,0xe2,0x66,0xc5,0xa6,0xad,0x26,0xff,0x47,0xfb,0x07,0xf6,0xe7 .byte 0xad,0x26,0xff,0x67,0xbd,0x86,0x84,0x25,0xad,0x26,0xff,0x67,0xb9,0x66,0x80,0x05 .byte 0xc5,0xc6,0xc9,0xe6,0xb1,0x26,0x80,0x05,0xf6,0xe7,0xfb,0x07,0xcd,0xe6,0x80,0x05 .byte 0x88,0x45,0x88,0x46,0x88,0x45,0x80,0x05,0x80,0x05,0x80,0x05,0x80,0x05,0x80,0x05 .byte 0xa0,0xc6,0xb5,0x46,0x80,0x05,0x84,0x25,0xa0,0xc6,0xb5,0x46,0x80,0x05,0x84,0x25 .byte 0xa0,0xc6,0xb5,0x46,0x80,0x05,0x84,0x25,0xa0,0xc6,0xb5,0x66,0x80,0x05,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x90,0x88,0x84,0x25,0x84,0x25,0x80,0x05,0x9c,0xea .byte 0x84,0x25,0x84,0x26,0x84,0x25,0xa9,0x4d,0x84,0x25,0x84,0x25,0x84,0x25,0xb5,0xaf .byte 0xc2,0x11,0xa9,0x4d,0x80,0x04,0xa1,0x0b,0xc2,0x11,0xad,0x6d,0x88,0x46,0xb5,0xaf .byte 0xb5,0xae,0xa9,0x4c,0x9c,0xea,0xb1,0x8e,0xa5,0x2c,0xad,0x6d,0xad,0x6d,0xa9,0x4c .byte 0xc2,0x11,0x98,0xc9,0x84,0x25,0x80,0x05,0xbd,0xf1,0x90,0x87,0x84,0x25,0x98,0xc9 .byte 0xb5,0xaf,0x84,0x25,0x94,0xa8,0xb1,0x8e,0xb1,0x8e,0x80,0x05,0x98,0xc9,0xa9,0x4c .byte 0x80,0x05,0x84,0x25,0x84,0x25,0x84,0x25,0xad,0x6d,0x9c,0xea,0x88,0x46,0x80,0x05 .byte 0xa9,0x4c,0xc2,0x11,0x90,0x87,0x90,0x88,0xa9,0x4c,0xbd,0xf0,0x88,0x46,0xb1,0x8e .byte 0x84,0x25,0x80,0x04,0x8c,0x67,0xb9,0xcf,0x94,0xa8,0xa9,0x4c,0xa5,0x2b,0xb9,0xcf .byte 0xc2,0x11,0xb1,0x8e,0xc2,0x11,0xad,0x6d,0xa5,0x2c,0x80,0x03,0xb1,0x8e,0xa1,0x0a .byte 0x8c,0x67,0x84,0x25,0x84,0x25,0x80,0x05,0x84,0x25,0x88,0x46,0xa5,0x2b,0xa9,0x4c .byte 0x80,0x05,0xb1,0x8e,0xb1,0x8e,0xb5,0xaf,0x90,0x88,0xbd,0xf0,0x9c,0xea,0x9c,0xea .byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x90,0x87,0x84,0x25,0x84,0x26,0x84,0x25 .byte 0xb5,0xaf,0x84,0x25,0x88,0x46,0x84,0x25,0xa1,0x0b,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0x84,0x25,0x88,0x46,0xb9,0xcf,0xc2,0x11,0x84,0x25,0x94,0xa8,0xbd,0xf0,0x90,0x88 .byte 0x80,0x05,0x9c,0xea,0xc2,0x11,0xa9,0x4c,0x80,0x05,0xad,0x6d,0xb9,0xcf,0xa5,0x2c .byte 0xc2,0x11,0xb9,0xcf,0x90,0x88,0x84,0x25,0x90,0x88,0xc2,0x11,0x98,0xc9,0x8c,0x66 .byte 0xad,0x6d,0xb5,0xae,0x88,0x46,0x90,0x87,0xb5,0xae,0xb9,0xcf,0x88,0x46,0x88,0x46 .byte 0x80,0x05,0x84,0x25,0x84,0x25,0x84,0x25,0xa5,0x2b,0x84,0x25,0x94,0xa8,0xa1,0x0b .byte 0xc2,0x11,0x8c,0x66,0xb5,0xae,0xa1,0x0b,0xb9,0xcf,0xa1,0x0b,0xb5,0xae,0x84,0x25 .byte 0x88,0x46,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25 .byte 0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0x84,0x25,0x84,0x26,0xa0,0xc6,0xad,0x26,0x84,0x25,0x84,0x26,0x8c,0x66,0xc1,0xa6 .byte 0x84,0x25,0x84,0x26,0x80,0x05,0xa4,0xe6,0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x05 .byte 0xcd,0xe6,0xff,0x27,0x8c,0x66,0xd2,0x06,0xc1,0xa6,0xda,0x46,0x84,0x25,0xa9,0x06 .byte 0xc5,0xa6,0xa0,0xe6,0xa0,0xc6,0x9c,0xc6,0x94,0x86,0xb1,0x26,0xb5,0x46,0xb1,0x46 .byte 0xff,0x87,0xda,0x26,0x88,0x46,0xfb,0x07,0xde,0x86,0xad,0x26,0x80,0x25,0xda,0x26 .byte 0x9c,0xc6,0x9c,0xc6,0xa0,0xc6,0x9c,0xc6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xb1,0x46 .byte 0xde,0x66,0x84,0x26,0x84,0x26,0x84,0x25,0xc1,0xa6,0x80,0x06,0x80,0x25,0x80,0x25 .byte 0x9c,0xc6,0xa0,0xe6,0xa0,0xc6,0xa0,0xe6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46 .byte 0x88,0x25,0xe2,0x67,0xff,0x67,0xd6,0x26,0x80,0x05,0x8c,0x46,0xc9,0xe6,0xf2,0xc7 .byte 0xa0,0xe6,0xa0,0xc6,0x9c,0xa6,0xa5,0x06,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46 .byte 0xb9,0x66,0xde,0x46,0xff,0x67,0xda,0x26,0xfb,0x07,0xf2,0xc7,0xc5,0xa6,0x84,0x25 .byte 0xa9,0x26,0xa5,0x06,0x9c,0xa6,0xa0,0xc6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xb1,0x46 .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x80,0x05,0x84,0x26,0x84,0x26,0x80,0x25 .byte 0xa0,0xe6,0xa0,0xe6,0xa0,0xc6,0xa0,0xc6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46 .byte 0x80,0x05,0xda,0x26,0xff,0x67,0xe2,0x66,0x80,0x05,0xbd,0x86,0xde,0x66,0xe2,0x66 .byte 0xa0,0xe6,0xa0,0xc6,0x9c,0xc6,0x9c,0xc6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46 .byte 0xda,0x26,0xea,0xa7,0xff,0x67,0xda,0x26,0xe6,0x86,0xe2,0x66,0xbd,0x86,0x84,0x26 .byte 0x9c,0xc6,0x9c,0xc6,0x98,0xa5,0xa0,0xc6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xb1,0x46 .byte 0x84,0x25,0x88,0x46,0x84,0x26,0x80,0x05,0x80,0x05,0x84,0x26,0x84,0x26,0x80,0x05 .byte 0xa0,0xe6,0xa0,0xe6,0xa0,0xc6,0xa0,0xe6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46 .byte 0xad,0x26,0xff,0x67,0xee,0xa7,0xda,0x26,0xa0,0xc6,0xde,0x66,0xe2,0x66,0xe6,0x86 .byte 0xa0,0xc6,0x9c,0xc6,0x9c,0xc6,0x9c,0xc6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46 .byte 0xda,0x46,0xde,0x46,0xde,0x46,0x94,0x86,0xe6,0x66,0xe6,0x86,0xe6,0x86,0x94,0xa6 .byte 0x9c,0xc6,0x9c,0xc6,0x9c,0xc6,0xbd,0x86,0xb1,0x46,0xb5,0x46,0xb1,0x46,0x9c,0xc6 .byte 0x9c,0xc6,0xb5,0x46,0x80,0x06,0x84,0x25,0xbd,0x86,0xa0,0xc6,0x84,0x26,0x88,0x46 .byte 0xb5,0x66,0x80,0x25,0x84,0x25,0x84,0x25,0x80,0x05,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x8c,0x67,0xbd,0xf0,0x84,0x26,0x84,0x25,0x94,0xa8,0xad,0x6d .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0x98,0xc9,0xc2,0x11,0xa5,0x2c,0xad,0x6d,0x8c,0x67,0xb1,0x8e,0x90,0x88,0xa9,0x4c .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0xa5,0x2c,0x84,0x25,0xbd,0xf0,0x9c,0xea,0x94,0xa8,0x84,0x25,0xa9,0x4c,0xa9,0x4c .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0xa9,0x4c,0xb5,0xaf,0x84,0x25,0xb5,0xaf,0xa9,0x4c,0xa5,0x2c,0x84,0x25,0x98,0xc9 .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0xa9,0x4d,0x98,0xc9,0xc2,0x11,0x90,0x88,0xb5,0xaf,0xa9,0x4c,0xad,0x6d,0x88,0x46 .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25 .byte 0x98,0xc9,0xbd,0xf0,0x94,0xa9,0x9c,0xea,0x88,0x46,0xa9,0x4c,0xb5,0xaf,0xa5,0x2c .byte 0x84,0x25,0x80,0x05,0x84,0x25,0x80,0x05,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25 .byte 0x8c,0x67,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0x84,0x25,0xb9,0xd0,0xb1,0x8e,0x98,0xc9,0x88,0x46,0xb1,0x8e,0xb5,0xaf,0xb9,0xcf .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25 .byte 0xb1,0x8e,0xb9,0xcf,0x88,0x46,0x88,0x46,0xad,0x6d,0x8c,0x67,0x84,0x25,0x80,0x05 .byte 0x80,0x05,0x84,0x25,0x84,0x25,0x9c,0xea,0x84,0x25,0x84,0x25,0x88,0x46,0xa1,0x0a .byte 0xb5,0xaf,0xc2,0x11,0x98,0xc9,0x84,0x25,0xb1,0x8e,0xb1,0x8e,0x84,0x25,0x84,0x25 .byte 0xb9,0xcf,0x90,0x87,0x84,0x25,0x84,0x25,0x94,0xa8,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0x84,0x26,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x26 .byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x26,0x88,0x46,0x88,0x46,0x84,0x25 .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x80,0x04 .byte 0x80,0x05,0xb5,0xaf,0xa9,0x6e,0x80,0x04,0x88,0x46,0xd2,0x95,0xad,0x6d,0x80,0x04 .byte 0x98,0xc9,0xd6,0xb5,0x98,0xc9,0x80,0x04,0xa9,0x4c,0xd2,0x94,0x88,0x46,0x80,0x04 .byte 0x80,0x05,0xb9,0xd1,0xa1,0x2c,0x80,0x05,0x90,0x87,0xda,0xd6,0xa1,0x0b,0x80,0x05 .byte 0xa1,0x0b,0xd6,0xb5,0x90,0x88,0x84,0x25,0xb1,0x8e,0xce,0x73,0x84,0x25,0x84,0x25 .byte 0x80,0x05,0x80,0x26,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x8c,0x67 .byte 0x88,0x46,0x88,0x46,0x84,0x25,0xbd,0xf0,0x84,0x25,0x84,0x25,0x88,0x46,0xce,0x74 .byte 0x80,0x05,0x80,0x05,0x80,0x05,0x80,0x05,0x8c,0x67,0x90,0x88,0x90,0x88,0x84,0x25 .byte 0xce,0x73,0xc2,0x11,0xd6,0xb5,0xa5,0x2c,0xb1,0x8e,0x84,0x25,0xce,0x74,0xb1,0x8e .byte 0x80,0x05,0x80,0x26,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x25,0x80,0x04,0x84,0x26,0x84,0x25,0x84,0x25 .byte 0x80,0x05,0x80,0x06,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x90,0x88,0x8c,0x67 .byte 0x90,0x87,0xc6,0x32,0xd6,0xb5,0xd6,0xb5,0xc2,0x11,0xc6,0x31,0x8c,0x67,0xb5,0xaf .byte 0x80,0x05,0x80,0x26,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0xa5,0x2b,0x84,0x25,0x88,0x46,0x88,0x46,0xad,0x6d,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0x80,0x05,0x80,0x05,0xb5,0xb0,0xa1,0x0c,0x84,0x25,0x8c,0x67,0xd6,0xb5,0xa1,0x0a .byte 0x84,0x25,0x98,0xca,0xd2,0x95,0x90,0x87,0x80,0x04,0xa9,0x4c,0xca,0x53,0x84,0x26 .byte 0x80,0x04,0x80,0x26,0x80,0x05,0x80,0x05,0x80,0x04,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x98,0xca .byte 0x80,0x05,0x80,0x05,0x80,0x05,0x80,0x05,0x80,0x05,0x8c,0x67,0x94,0xa8,0x84,0x26 .byte 0xa9,0x4c,0xce,0x73,0xd2,0x94,0xc2,0x11,0xda,0xd6,0xb1,0x8e,0xb1,0x8e,0xde,0xf6 .byte 0x80,0x05,0x80,0x05,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0x88,0x46,0x84,0x26,0x88,0x46,0x84,0x25,0x94,0xa9,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0x80,0x05,0x98,0xc9,0xca,0x53,0xca,0x53,0x80,0x04,0xb1,0x8e,0xd2,0x94,0xa5,0x2b .byte 0x84,0x25,0xc6,0x32,0xb9,0xcf,0x80,0x03,0x88,0x46,0xce,0x74,0xce,0x74,0xc2,0x11 .byte 0xca,0x53,0xb9,0xcf,0x8c,0x67,0x84,0x25,0xad,0x6d,0xda,0xd6,0xa5,0x2c,0x80,0x04 .byte 0x8c,0x67,0xd6,0xb5,0xa1,0x0b,0x84,0x25,0xd2,0x94,0xc6,0x32,0x88,0x46,0x84,0x25 .byte 0x84,0x25,0x84,0x26,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x8c,0x67 .byte 0x84,0x25,0x84,0x26,0x88,0x46,0xca,0x53,0x84,0x25,0x84,0x25,0x90,0x87,0xd2,0x95 .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x8c,0x67,0x84,0x25,0x90,0x87,0x90,0x87 .byte 0xad,0x6d,0x80,0x04,0xc6,0x32,0xb5,0xaf,0x98,0xc9,0x88,0x46,0xd2,0x94,0xa5,0x2b .byte 0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0x80,0x05,0x88,0x46,0x88,0x46,0x84,0x25,0x80,0x05,0x84,0x25,0x88,0x46,0x80,0x04 .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x26,0x90,0x88,0x8c,0x67,0x94,0xa8 .byte 0x94,0xa9,0xd6,0xb5,0xbd,0xf1,0xce,0x73,0xa9,0x4c,0xd2,0x94,0x8c,0x67,0xa1,0x0b .byte 0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0xca,0x52,0x88,0x46,0x88,0x46,0x88,0x46,0xd6,0xb5,0x8c,0x67,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x8c,0x67 .byte 0x84,0x26,0x84,0x25,0xa9,0x4d,0xd2,0x94,0x80,0x05,0x98,0xc9,0xd6,0xb5,0xa1,0x0b .byte 0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x94,0xa8,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0xd6,0xb5,0xc6,0x32,0x8c,0x67,0x84,0x26,0x98,0xc9,0xc2,0x11,0x90,0x88,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x98,0xc9,0x84,0x25,0x84,0x25,0x84,0x25,0xb1,0x8e .byte 0x88,0x46,0x84,0x25,0x84,0x25,0xbd,0xf1,0x84,0x25,0x84,0x25,0x88,0x46,0xce,0x74 .byte 0xc2,0x11,0x88,0x46,0x84,0x25,0x84,0x25,0xca,0x52,0x8c,0x67,0x90,0x88,0x84,0x25 .byte 0xce,0x74,0xca,0x53,0xd6,0xb5,0xa5,0x2b,0xb9,0xd0,0x90,0x87,0xd2,0x94,0xad,0x6d .byte 0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46 .byte 0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x26,0x80,0x04,0x84,0x25,0x84,0x26,0x84,0x25 .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x04,0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x04 .byte 0x84,0x26,0x88,0x46,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25 .byte 0xb9,0xd0,0xca,0x52,0x80,0x04,0x80,0x05,0xb5,0xae,0xda,0xd6,0xb5,0xaf,0xc2,0x11 .byte 0x8c,0x67,0xb1,0x8e,0xc2,0x11,0xb9,0xcf,0x84,0x25,0x80,0x05,0x80,0x05,0x80,0x05 .byte 0xca,0x53,0xb9,0xd0,0x80,0x04,0x84,0x25,0xd6,0xb5,0x94,0xa9,0x80,0x05,0x84,0x25 .byte 0x94,0xa8,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x26 .byte 0x84,0x25,0x84,0x25,0x94,0xa8,0xd6,0xb5,0x84,0x25,0x80,0x05,0xa5,0x2c,0xd2,0x94 .byte 0x84,0x25,0x84,0x25,0xa5,0x2b,0xb1,0x8d,0x88,0x46,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0x90,0x88,0x8c,0x66,0xd2,0x94,0x9c,0xea,0x84,0x25,0xa1,0x0a,0xd6,0xb5,0x8c,0x67 .byte 0x80,0x04,0xa1,0x0b,0xb5,0xae,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0x80,0x05,0x84,0x26,0x84,0x25,0x90,0x87,0x84,0x25,0x88,0x46,0x84,0x25,0x8c,0x67 .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x25 .byte 0xd6,0xb5,0x98,0xc9,0x80,0x04,0x98,0xc9,0xd6,0xb5,0xc2,0x11,0xc2,0x11,0xca,0x53 .byte 0xa1,0x0b,0xc2,0x11,0xb5,0xaf,0x8c,0x67,0x80,0x05,0x84,0x25,0x80,0x04,0x84,0x25 .byte 0x8c,0x66,0x84,0x25,0x84,0x25,0x84,0x25,0x8c,0x66,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0x80,0x04,0xbd,0xf0,0xbd,0xf0,0x80,0x04,0x84,0x26,0xce,0x74,0xa9,0x4d,0x80,0x04 .byte 0x8c,0x66,0xb9,0xd0,0x94,0xa8,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x80,0x04,0xb5,0xaf,0x84,0x25,0x88,0x46,0x80,0x05,0xb1,0x8e .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0xce,0x73,0xa5,0x2c,0xad,0x6d,0xad,0x6d,0xd6,0xb5,0xb1,0x8e,0xbd,0xf0,0xa1,0x0b .byte 0xb1,0x8e,0xc2,0x11,0xa9,0x4d,0x88,0x46,0x80,0x04,0x84,0x25,0x80,0x05,0x84,0x25 .byte 0x88,0x46,0x84,0x25,0x84,0x25,0x80,0x05,0x80,0x05,0x84,0x26,0x84,0x25,0x80,0x04 .byte 0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25 .byte 0x94,0xa8,0xd6,0xb5,0xb9,0xcf,0xb1,0x8e,0xa9,0x4c,0xd6,0xb5,0x88,0x46,0x80,0x04 .byte 0xa5,0x2c,0xb5,0xae,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25 .byte 0xa9,0x4c,0x88,0x46,0x84,0x25,0x84,0x25,0x80,0x04,0x84,0x25,0x84,0x26,0x84,0x25 .byte 0x84,0x25,0x84,0x26,0x84,0x26,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x26,0x84,0x25 .byte 0x84,0x25,0x80,0x05,0x9c,0xea,0xd2,0x94,0x84,0x25,0x80,0x05,0xa9,0x4c,0xda,0xd6 .byte 0x84,0x25,0x84,0x25,0x90,0x87,0xb9,0xcf,0x84,0x25,0x84,0x26,0x84,0x25,0x80,0x04 .byte 0x84,0x25,0x98,0xc9,0xd6,0xb5,0x90,0x88,0xb5,0xaf,0xce,0x73,0xce,0x74,0x88,0x46 .byte 0xb5,0xaf,0xad,0x6d,0xad,0x6d,0x84,0x25,0x80,0x04,0x80,0x05,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x80,0x04,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0xb9,0xd0,0xbd,0xf0,0x80,0x03,0xb1,0x8e,0xce,0x74,0xad,0x6d,0x80,0x04,0xca,0x52 .byte 0xb9,0xcf,0x94,0xa8,0x88,0x46,0xb5,0xaf,0x80,0x05,0x84,0x25,0x88,0x46,0x80,0x05 .byte 0xca,0x52,0x84,0x25,0x84,0x25,0x84,0x25,0xb9,0xcf,0x80,0x04,0x88,0x46,0x84,0x25 .byte 0x9c,0xea,0x80,0x05,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0x80,0x04,0xb5,0xaf,0xca,0x52,0x80,0x03,0x80,0x04,0xb1,0x8e,0xd6,0xb5,0xb5,0xaf .byte 0x84,0x25,0x8c,0x67,0xb5,0xaf,0xc2,0x11,0x84,0x25,0x84,0x25,0x84,0x25,0x80,0x05 .byte 0x8c,0x67,0x94,0xa9,0x84,0x25,0x84,0x25,0xd2,0x94,0xad,0x6d,0x84,0x25,0x84,0x25 .byte 0xa1,0x0b,0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x05,0x84,0x25,0x88,0x46,0x88,0x46 .byte 0x84,0x25,0x84,0x25,0x94,0xa8,0xd6,0xb5,0x84,0x25,0x80,0x04,0xa9,0x4c,0xd2,0x94 .byte 0x84,0x25,0x80,0x05,0xa5,0x2b,0xb1,0x8e,0x88,0x46,0x84,0x26,0x84,0x26,0x84,0x25 .byte 0x90,0x88,0x84,0x26,0xd2,0x94,0x9c,0xea,0x84,0x25,0x9c,0xea,0xd6,0xb5,0x8c,0x67 .byte 0x80,0x04,0x9c,0xea,0xb5,0xaf,0x84,0x26,0x88,0x46,0x84,0x25,0x84,0x25,0x88,0x46 .byte 0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25 .byte 0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x26,0x84,0x25,0x88,0x46,0x84,0x25 #endregion #region SnapshotIcon SnapshotIcon: blrl .byte 0x00,0x00,0x0c,0x1c,0x13,0x17,0x06,0x06,0x00,0x06,0x54,0xbe,0x52,0x54,0x0f,0x0f .byte 0x00,0x0e,0x4c,0x53,0xc4,0x1a,0x4a,0x35,0x00,0x17,0x49,0xc1,0x09,0x09,0x6a,0xc5 .byte 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0e,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x49 .byte 0x4a,0x1a,0x1a,0x1a,0x35,0x35,0x1a,0x4e,0x6a,0x09,0x09,0x09,0x1a,0x4e,0x09,0x09 .byte 0x1c,0x25,0x0c,0x00,0x00,0x00,0x00,0x00,0x6e,0x30,0x06,0x00,0x00,0x00,0x00,0x00 .byte 0xc9,0x52,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x4f,0x38,0x0c,0x00,0x00,0x00,0x00 .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .byte 0x00,0x17,0xbc,0xc3,0x09,0xc2,0x30,0x67,0x00,0x06,0x30,0x7a,0x4e,0x32,0x1e,0x44 .byte 0x00,0x12,0x1b,0x47,0x6b,0x13,0x17,0x23,0x00,0x00,0xa5,0x45,0x19,0x05,0x06,0x23 .byte 0x4a,0x09,0x09,0x6c,0x80,0x88,0x6b,0x6c,0x73,0x09,0x27,0x4d,0x32,0x1e,0x0f,0x82 .byte 0x63,0x27,0x1f,0x4d,0x1b,0x14,0x05,0x68,0x63,0x1f,0x4b,0x47,0x1b,0x06,0x12,0x1c .byte 0x09,0x4f,0x1c,0x01,0x00,0x00,0x00,0x00,0x27,0x78,0x7f,0x12,0x00,0x00,0x00,0x00 .byte 0xb3,0xad,0x34,0x14,0x00,0x00,0x00,0x00,0xa5,0x71,0x44,0x06,0x00,0x00,0x00,0x00 .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .byte 0x0c,0x12,0x32,0x48,0x1c,0x12,0x06,0x23,0x00,0x00,0x12,0x38,0x0c,0x00,0x06,0x23 .byte 0x00,0x00,0x0c,0x01,0x00,0x00,0x06,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x43 .byte 0x45,0x4b,0x76,0x47,0x1b,0x06,0x00,0x17,0x45,0x39,0x39,0xab,0x1b,0x06,0x00,0x0c .byte 0xa6,0x3a,0x3a,0xae,0x1b,0x1e,0x17,0x17,0xa9,0x3b,0x3b,0x81,0x6e,0x51,0x69,0x19 .byte 0x30,0x48,0xa2,0x14,0x00,0x00,0x00,0x00,0x25,0x25,0x12,0x00,0x00,0x00,0x00,0x00 .byte 0x05,0x05,0x05,0x14,0x13,0x00,0x00,0x0e,0x19,0x4c,0x49,0x34,0x14,0x0c,0x13,0x51 .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 .byte 0x17,0x17,0x17,0x17,0x17,0x0e,0x00,0x00,0xbb,0x4c,0x19,0x19,0x69,0xa3,0x00,0x00 .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x43 .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0xb1,0x00,0x00,0x00,0x00,0x0c,0x14,0x1e,0x68 .byte 0xac,0x65,0x65,0xc8,0xcd,0x84,0x73,0x53,0xb0,0x55,0x55,0xce,0x56,0x34,0xd7,0xdb .byte 0x5b,0x9a,0x70,0xd4,0x56,0x1d,0x51,0x58,0xc0,0xcc,0xd1,0x8c,0x87,0x28,0x72,0xdc .byte 0x75,0x53,0xc6,0x67,0x05,0x0c,0x25,0xca,0x09,0x09,0x50,0x19,0x17,0x0c,0x25,0x4f .byte 0x7d,0x09,0x4d,0x32,0x0e,0xd3,0x34,0x58,0x48,0x09,0x1f,0x58,0x38,0xd8,0xe2,0x79 .byte 0x7d,0x50,0x75,0x50,0x79,0xa7,0x13,0x04,0x09,0x09,0x09,0x35,0xbd,0x1c,0x0a,0x00 .byte 0x1a,0x09,0x09,0xcf,0x0b,0x2f,0x42,0x10,0x84,0x27,0x27,0x7e,0x5a,0x0d,0x0d,0x2d .byte 0x00,0x00,0x00,0x00,0x00,0x83,0xb7,0xb9,0x00,0x00,0x00,0x17,0x19,0xb5,0xb8,0xb6 .byte 0x00,0x00,0x00,0x0e,0x72,0xb4,0x29,0x36,0x00,0x00,0x00,0x13,0x14,0x28,0x28,0x28 .byte 0xbf,0x74,0x74,0xd6,0xda,0x52,0x7b,0x5d,0x37,0x37,0x37,0x37,0xd9,0xde,0x8f,0x78 .byte 0x86,0xba,0x3c,0x89,0x3c,0x36,0x6d,0x95,0x85,0x6f,0xc7,0x6f,0xdd,0x28,0x7c,0x5f .byte 0xe0,0x7a,0x27,0x71,0xe1,0xe3,0x5e,0x82,0x80,0xe6,0x1f,0xe7,0x96,0x8b,0x5d,0x3f .byte 0x88,0x95,0x39,0x98,0x5e,0xa0,0xf6,0x9f,0xef,0x3f,0x9c,0x3a,0x5f,0x94,0x86,0x97 .byte 0x94,0x1f,0x1f,0x7e,0xd2,0x02,0x0b,0x22,0x3f,0x76,0x4b,0x56,0x8b,0x02,0x0b,0xa8 .byte 0x9b,0x98,0x39,0x8d,0x59,0x26,0x2e,0x15,0x5e,0x9c,0x3a,0x8d,0x59,0x0d,0x16,0x61 .byte 0x00,0x00,0x00,0x00,0x00,0x0c,0x2d,0x2b,0x00,0x00,0x00,0x00,0x04,0x21,0x31,0x24 .byte 0x00,0x00,0x0c,0x01,0x0c,0x0c,0x04,0x10,0x00,0x0c,0x0c,0x33,0x2b,0x2f,0x16,0x01 .byte 0x41,0x0b,0x24,0x15,0x0a,0x38,0x5f,0x60,0x24,0x42,0x10,0x01,0x10,0x7f,0x60,0x60 .byte 0x0a,0x10,0x04,0x10,0x1e,0x8e,0x5b,0x91,0x00,0x00,0x0a,0x64,0x33,0x3f,0xe9,0xec .byte 0x57,0x9f,0xfb,0x3b,0xfc,0xfe,0xf5,0x5a,0xa1,0xa1,0x99,0x9e,0x55,0xf9,0x9b,0x33 .byte 0x83,0x1e,0xfd,0xfa,0x9a,0x5b,0x54,0x1d,0xee,0x85,0xf8,0x90,0x93,0x9d,0x31,0xf2 .byte 0xf0,0x81,0x3b,0x29,0x57,0x22,0x2a,0x11,0xf4,0xf1,0x9e,0x99,0xe4,0x46,0x03,0x11 .byte 0x5d,0xeb,0x9a,0x91,0x8e,0x1e,0x03,0x03,0x9d,0x8c,0x93,0x90,0x52,0xb2,0x46,0x03 .byte 0x00,0x01,0x33,0x41,0x2c,0x16,0x04,0x00,0x0a,0x42,0x41,0x3e,0x21,0x0a,0x00,0x01 .byte 0x21,0x2b,0x22,0x01,0x01,0x00,0x0a,0x15,0x2d,0x2d,0x0a,0x04,0x00,0x0a,0x64,0x2b .byte 0x04,0x0a,0xaf,0xcb,0xd0,0x77,0x92,0x92,0x01,0x31,0x26,0x57,0x5c,0x8a,0x3c,0x3c .byte 0x3e,0x0b,0x02,0x02,0x20,0x20,0x20,0x20,0x0b,0x02,0x02,0x02,0x02,0x02,0x02,0x02 .byte 0xed,0x5c,0xf3,0xf7,0x3d,0x96,0xa0,0xea,0x8a,0x5c,0x59,0x89,0x8f,0x97,0xe5,0x87 .byte 0x20,0x20,0x26,0x5a,0xdf,0x16,0xd5,0x18,0x0b,0x0d,0x2f,0x16,0x03,0x66,0x07,0x07 .byte 0xe8,0x3d,0x3d,0x3d,0x77,0xaa,0xa4,0x1e,0x29,0x36,0x36,0x36,0x29,0x6d,0xa4,0x1e .byte 0x18,0x18,0x18,0x18,0x18,0x18,0x46,0x08,0x07,0x07,0x07,0x07,0x07,0x07,0x08,0x08 .byte 0x04,0x01,0x00,0x04,0x0a,0x42,0x02,0x0b,0x00,0x00,0x04,0x13,0x31,0x0b,0x0d,0x0d .byte 0x00,0x00,0x04,0x22,0x2c,0x2c,0x2e,0x2e,0x00,0x00,0x00,0x13,0x15,0x21,0x21,0x15 .byte 0x02,0x02,0x02,0x02,0x0d,0x0b,0x0b,0x2c,0x0d,0x0b,0x0b,0x0d,0x2e,0x3e,0x42,0x15 .byte 0x2f,0x24,0x22,0x62,0x15,0x2a,0x40,0x08,0x01,0x11,0x61,0x2a,0x03,0x11,0x11,0x03 .byte 0x24,0x62,0x03,0x40,0x07,0x08,0x07,0x07,0x40,0x40,0x07,0x08,0x08,0x07,0x07,0x07 .byte 0x03,0x08,0x08,0x08,0x07,0x07,0x07,0x07,0x08,0x08,0x08,0x08,0x07,0x07,0x07,0x07 .byte 0x07,0x07,0x07,0x07,0x07,0x08,0x08,0x08,0x07,0x07,0x07,0x07,0x08,0x08,0x08,0x03 .byte 0x07,0x07,0x07,0x07,0x08,0x08,0x03,0x11,0x07,0x08,0x08,0x08,0x03,0x03,0x11,0x11 .byte 0x84,0x25,0x84,0x25,0xa8,0x0f,0x84,0x24,0x84,0x25,0x80,0x04,0x80,0x05,0x84,0x24 .byte 0x84,0x24,0x80,0x00,0x84,0x24,0xa8,0x30,0x84,0x25,0xa8,0x10,0x80,0x04,0x98,0xca .byte 0x84,0x25,0x84,0x24,0x84,0x25,0x84,0x25,0x80,0x05,0x88,0x26,0x90,0x28,0x80,0x04 .byte 0x80,0x04,0xad,0x6e,0xb1,0x8c,0xbd,0xd0,0x8c,0x67,0x80,0x03,0x80,0x03,0x84,0x00 .byte 0xa4,0x10,0x88,0x26,0x94,0x2a,0xa1,0x0c,0x9c,0x2c,0x88,0x46,0xa8,0x10,0x80,0x00 .byte 0x80,0x05,0xcd,0xcf,0x84,0x24,0xa0,0x2e,0xa4,0x2f,0x8c,0x28,0xa4,0x2e,0xa0,0x0d .byte 0xb9,0xd0,0x98,0x2b,0xb9,0xd0,0x98,0x0c,0x98,0xc9,0xa9,0x4a,0xd1,0xd0,0xf4,0x41 .byte 0x88,0x46,0x90,0x00,0x98,0x00,0xa4,0x00,0xd9,0xd4,0xec,0x21,0x9c,0x2c,0xc9,0xf3 .byte 0x80,0x24,0xac,0x11,0x90,0x29,0xa1,0x0c,0xa1,0x0b,0xb9,0x6a,0x80,0x04,0x98,0x63 .byte 0xd2,0x74,0xb1,0x8e,0xad,0x6b,0x88,0x00,0xad,0x6e,0x90,0x63,0xa5,0x29,0xbd,0xf0 .byte 0x9c,0xe7,0xa5,0x4c,0xbd,0xf1,0x9c,0xe7,0x9c,0xea,0xb4,0x00,0xc5,0xf1,0xb4,0x92 .byte 0xc1,0xf0,0xb0,0x72,0xac,0x31,0xd9,0x4a,0xe2,0x36,0xc5,0xf0,0xc9,0xd3,0xc5,0xae .byte 0xcd,0x8d,0x80,0x24,0x8c,0x27,0xb1,0x4a,0x8c,0x27,0xac,0x00,0x80,0x23,0xb5,0xaf .byte 0xb1,0x8f,0xa9,0x4d,0x94,0x84,0xc6,0x31,0x8c,0x42,0xda,0x32,0xca,0x53,0xa0,0x0e .byte 0xc4,0x00,0xb5,0x8c,0xa5,0x2c,0xad,0x6a,0xe0,0x00,0xa1,0x07,0x90,0x00,0xf5,0x4a .byte 0xb9,0xce,0xc2,0x0f,0x8c,0x41,0xbd,0xf1,0xbd,0xcf,0xa1,0x08,0xc5,0xf2,0x90,0x88 .byte 0xc6,0x33,0xac,0x41,0xc6,0x11,0x8c,0xa8,0xd6,0xb5,0x8c,0x09,0xcd,0xef,0xd6,0x11 .byte 0xa9,0x4d,0xdd,0xf5,0xdd,0xd2,0xac,0x51,0xd4,0x00,0xc9,0xd0,0x98,0xea,0xf2,0x53 .byte 0xe0,0xc6,0xd5,0x8c,0xe8,0x20,0xd4,0x00,0xd6,0x76,0xc1,0xad,0xcd,0xb5,0xb8,0xd3 .byte 0x98,0x20,0xd1,0xae,0xc0,0x00,0xc5,0xb3,0xa4,0x21,0xdd,0xf1,0xb0,0x00,0xc5,0x75 .byte 0xc1,0x35,0xa8,0xaf,0x94,0xa9,0xa5,0x2c,0x9d,0x0a,0xbd,0xf0,0xbd,0x4a,0xd2,0x95 .byte 0x94,0x29,0xc5,0x4a,0xea,0x73,0xa0,0x62,0xc9,0x4a,0xb1,0x6c,0xa8,0x63,0x90,0x08 .byte 0xd1,0x4a,0xa1,0x2c,0x80,0x25,0xa5,0x07,0xd6,0x11,0xfa,0x72,0xf8,0x42,0xad,0x8f .byte 0xfd,0x6a,0xe1,0xf0,0xd1,0xf1,0xad,0x6e,0xb5,0xaf,0xb9,0xb1,0xca,0x53,0xe0,0x00 .byte 0xdc,0xe7,0x9c,0xc6,0xb1,0x8c,0x94,0xa4,0x94,0xa5,0xb5,0xad,0xbd,0xee,0xa4,0x10 .byte 0xb4,0x21,0x84,0x21,0xce,0x74,0xb0,0xb1,0xd0,0x00,0xe2,0xf7,0xc0,0x42,0xc5,0xf2 .byte 0xea,0x77,0xd0,0x00,0xac,0x51,0x80,0x04,0xcc,0x42,0x84,0x04,0xdc,0x00,0xc2,0x11 .byte 0x84,0x06,0xf4,0x20,0xe9,0x29,0x88,0x42,0xce,0x52,0x88,0x08,0xfc,0xe7,0xa4,0x70 .byte 0xda,0xd7,0xa8,0xee,0xbd,0x52,0xa0,0x0e,0xa0,0xad,0xb9,0x31,0xad,0x08,0xa4,0xc5 .byte 0xf0,0xa5,0xdc,0x83,0xf6,0x74,0xc8,0x21,0xe1,0x28,0xf5,0xce,0xb5,0x92,0x9c,0xcc .byte 0xd1,0xd4,0xbc,0x21,0x98,0xad,0xb9,0x35,0xcd,0xd3,0xd1,0xd2,0xca,0x0f,0xed,0x8c .byte 0xc1,0x92,0xc9,0x07,0xc8,0x21,0xc1,0x07,0xbd,0x08,0xce,0x10,0xe2,0xb4,0xcd,0xae #endregion #endregion #region LoadCredits LoadCredits: backup #Load Minor Scene 0x1 load r4,SceneController li r3,0x1 stb r3,0x4(r4) #Change Screen li r3,0x1 stw r3,0x34(r4) #Make Previous Major Event CSS So It Returns to Event SS load r4,SceneController li r3,0x2B stb r3,0x2(r4) #BACKUP CURRENT EVENT ID lwz r3, -0x4A40 (r13) lwz r5, 0x002C (r3) lbz r3,0x0(r5) lwz r4,0x4(r5) add r3,r3,r4 lwz r4, -0x77C0 (r13) stb r3, 0x0535 (r4) #Return To Event SS #load r4,0x804d68b8 #li r3,0x7 #stb r3,0x0(r4) #li r3,0x2B #stb r3,0x4(r4) #Overwrite SceneDecide Function So It Doesn't Change Majors bl TempSceneDecide mflr r3 load r4,0x803dae44 #Main Menu's Minor Table Pointer lwz r4,0x0(r4) stw r3,0x8(r4) #Overwrite MainMenu's SceneDecide Temporarily #Init Name Count Variable li r3,0x0 stw r3, -0x4eac (r13) #Exit restore blr #endregion #region PlayMovie PlayMovie: #Get Events Tutorial lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) lwz r4, -0x77C0 (r13) lbz r4, 0x0535 (r4) rtocbl r12,TM_GetEventTut mr r20,r3 #Get Event's Tutorial File Name in r20 #Get Extension Pointer in r21 bl FileSuffixes mflr r21 ############################## ## Play Movie's Audio Track ## ############################## #Copy To Temp Audio String Space load r22,0x803bb380 #Temp Audio String Space addi r3,r22,0x7 #After the /audio/ mr r4,r20 #Movie FileName branchl r12,0x80325a50 #strcpy #Get Length of This String Now mr r3,r22 branchl r12,0x80325b04 #Copy .hps to the end of it add r3,r3,r22 #Dest mr r4,r21 #.hps string branchl r12,0x80325a50 #Check If File Exists mr r3,r22 branchl r12,0x8033796c cmpwi r3,-1 beq FileNotFound #Load Song File LoadSongFile: mr r3,r22 #Full Song File Name li r4,127 #Volume? li r5,1 #Unk branchl r12,0x80023ed4 ##################### ## Load Movie File ## ##################### StartLoadMovieFile: #Copy File Name To Temp Space load r22,0x80432058 #Temp File Name Space mr r3,r22 #Destination mr r4,r20 #Movie FileName branchl r12,0x80325a50 #strcpy #Get Length of This String Now mr r3,r22 #Destination branchl r12,0x80325b04 #Copy .mth Suffix add r3,r3,r22 #Dest addi r4,r21,0x8 #.mth string branchl r12,0x80325a50 #Check If File Exists mr r3,r22 branchl r12,0x8033796c cmpwi r3,-1 beq FileNotFound #PLAY SFX li r3, 1 branchl r4,0x80024030 #Unk Set li r3,0x1 branchl r12,0x80024e50 #Load Movie File mr r3,r22 #File Name bl FramerateDefinition mflr r4 #0x803dbfb4 = opening movie fps define li r5,0 #lwz r5, -0x4A14 (r13) load r6,0x00271000 #li r6,0 #Frame Buffer Heap Size? li r7,0 branchl r12,0x8001f410 #Set Framerate load r3,0x804333e0 lwz r3,0x18(r3) #get framerate from mth header li r4,60 divw r3,r4,r3 #decide how many in game frames per movie frame bl FramerateDefinition mflr r4 stw r3,0x4(r4) #update fps #Unk Unset li r3,0x0 branchl r12,0x80024e50 #Create And Schedule Custom Movie Think Functions #Create Camera Think Entity li r3, 13 li r4,14 li r5,0 branchl r12,0x803901f0 #Attach Camera Think mr r31,r3 li r4,640 li r5,480 li r6,8 li r7,0 branchl r12,0x801a9dd0 li r0,0x800 stw r0,0x24(r31) li r0,0x0 stw r0,0x20(r31) #Create Movie Display Entity li r3, 14 li r4,15 li r5,0 branchl r12,0x803901f0 mr r30,r3 stw r3, -0x4E48 (r13) lbz r4, -0x3D40 (r13) li r5, 0 branchl r12,0x80390a70 #Attach Display Process mr r3,r30 load r4,0x8001f67c li r5,11 li r6,0 branchl r12,0x8039069c #Change Screen Size to Fullscreen mr r3,r30 li r4,640 li r5,480 branchl r12,0x8001f624 lfs f0, -0x3680 (rtoc) stfs f0, 0x0010 (r3) stfs f0, 0x0014 (r3) #Create Movie Think Entity li r3, 6 li r4,7 li r5,128 branchl r12,0x803901f0 mr r29,r3 #Alloc 10 Bytes li r3,10 branchl r12,0x8037f1e4 #Initliaze Entity mr r6,r3 mr r3,r29 li r4,0x0 load r5,0x8037f1b0 branchl r12,0x80390b68 #Schedule Think mr r3,r29 bl MovieThink mflr r4 li r5,0x0 branchl r12,0x8038fd54 #Store Display Entity and Camera Entity to the Think Entity lwz r3,0x2C(r29) #Think's Data stw r31,0x0(r3) #Camera Entity stw r30,0x4(r3) #Display Entity #REMOVE EVENT THINK FUNCTION lwz r3, -0x3E84 (r13) branchl r12,0x80390228 b exit #endregion ####################################### FramerateDefinition: blrl #This structure is passed through via r4 to the MTH play function #It contains variable framerate information #Structure is # 0x0 = number of frames to use the following fps for # 0x4 = in game frames per movie frame .long 1048576 .long 2 ####################################### FileNotFound: #PLAY SFX li r3, 3 branchl r4,0x80024030 b exit ####################################### TempSceneDecide: blrl #Store Back load r3,0x801b138c #Function Address load r4,0x803dae44 #Main Menu's Minor Table Pointer lwz r4,0x0(r4) stw r3,0x8(r4) #Overwrite MainMenu's SceneDecide blr ####################################### MovieThink: blrl backup #Backup Entity Pointer mr r31,r3 lwz r30,0x2C(r3) #Advance Frame branchl r12,0x8001f578 #Check If Movie Is Over branchl r12,0x8001f604 cmpwi r3,0x0 bne EndMovie #Check For Button Press li r3, 4 branchl r12,0x801a36a0 #All Players Inputs andi. r4,r4,0x1100 beq Exit #PLAY SFX li r3, 1 branchl r4,0x80024030 b EndMovie restore blr EndMovie: #Stop Music branchl r12,0x800236dc #Remove Camera Think Function lwz r3,0x0(r30) #Camera Entity branchl r12,0x80390228 #Remove Display Process Function lwz r3,0x4(r30) #Display Entity branchl r12,0x80390228 #Remove This Think Function mr r3,r31 branchl r12,0x80390228 #Unload Movie branchl r12,0x8001f800 #Play Menu Music lwz r3, -0x77C0 (r13) lbz r3, 0x1851 (r3) branchl r12,0x80023f28 #Reload Event Match Think li r3, 0 li r4, 1 li r5, 128 branchl r12,0x803901f0 load r4,0x8024d864 li r5,0 branchl r12,0x8038fd54 Exit: restore blr FileSuffixes: blrl #.hps .string ".hps" .align 2 #.mth .string ".mth" .align 2 ####################################### */ SwitchPage: #Get number of pages rtocbl r12,TM_GetPageNum mr r6,r3 #Change page lwz r4,MemcardData(r13) lbz r3,CurrentEventPage(r4) add r3,r3,r5 stb r3,CurrentEventPage(r4) #Check if within page bounds SwitchPage_CheckHigh: cmpw r3,r6 ble SwitchPage_CheckLow #Stay on current page subi r3,r3,1 stb r3,CurrentEventPage(r4) b exit SwitchPage_CheckLow: cmpwi r3,0 bge SwitchPage_ChangePage #Stay on current page li r3,0 stb r3,CurrentEventPage(r4) b exit SwitchPage_ChangePage: #Get Page Name string lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) rtocbl r12,TM_GetPageName #Update Page Name mr r5,r3 lwz r3,-0x4EB4(r13) li r4,0 branchl r12,Text_UpdateSubtextContents #Reset cursor to 0,0 lwz r5, -0x4A40 (r13) lwz r5, 0x002C (r5) li r3,0 stw r3, 0x0004 (r5) #Selection Number stb r3, 0 (r5) #Page Number #Redraw Event Text SwitchPage_DrawEventTextInit: li r29,0 #loop count lwz r3, 0x0004 (r5) #Selection Number lbz r4, 0 (r5) #Page Number add r28,r3,r4 SwitchPage_DrawEventTextLoop: mr r3,r29 add r4,r29,r28 branchl r12,0x8024d15c addi r29,r29,1 cmpwi r29,9 blt SwitchPage_DrawEventTextLoop #Redraw Event Description lwz r3, -0x4A40 (r13) mr r4,r28 branchl r12,0x8024d7e0 #Update High Score lwz r3, -0x4A40 (r13) li r4,0 branchl r12,0x8024d5b0 #Update cursor position #Get Texture Data lwz r3, -0x4A40 (r13) lwz r3, 0x0028 (r3) addi r4,sp,0x40 li r5,11 li r6,-1 crclr 6 branchl r12,0x80011e24 lwz r3,0x40(sp) #Change Y offset? li r0,0 stw r0,0x3C(r3) #DirtySub branchl r12,0x803732e8 #Play SFX li r3,2 branchl r12,SFX_MenuCommonSound ####################################### exit: restore li r0, 16 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event High Scores/Load Event High Scores.asm ================================================ #To be inserted at 8015cf60 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" #r3 = event #r4 = event score pointer .set REG_EventID,3 .set REG_EventScorePointer,4 .set REG_PageID,5 .set REG_HighScoreTable,6 backup #Get page ID lbz REG_PageID,CurrentEventPage(REG_EventScorePointer) #Get event's score offset using table bl EventHighScores mflr REG_HighScoreTable lbzx REG_PageID,REG_PageID,REG_HighScoreTable #Multiply and add to score pointer mulli REG_PageID,REG_PageID,4 add REG_EventScorePointer,REG_PageID,REG_EventScorePointer #Now this events offset mulli REG_EventID,REG_EventID,4 add REG_EventScorePointer,REG_EventID,REG_EventScorePointer #Load score lwz r3, 0x1A70 (REG_EventScorePointer) b Exit EventHighScores Exit: restore blr ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event High Scores/Save Event High Scores.asm ================================================ #To be inserted at 8015cf74 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" #r3 = event #r4 = score #r5 = event score pointer .set REG_EventID,3 .set REG_EventScore,4 .set REG_EventScorePointer,5 .set REG_PageID,6 .set REG_HighScoreTable,7 backup #Get page ID lbz REG_PageID,CurrentEventPage(REG_EventScorePointer) #Get event's score offset using table bl EventHighScores mflr REG_HighScoreTable lbzx REG_PageID,REG_PageID,REG_HighScoreTable #Multiply and add to score pointer mulli REG_PageID,REG_PageID,4 add REG_EventScorePointer,REG_PageID,REG_EventScorePointer #Now this events offset mulli REG_EventID,REG_EventID,4 add REG_EventScorePointer,REG_EventID,REG_EventScorePointer #Save score stw REG_EventScore, 0x1A70 (REG_EventScorePointer) b Exit EventHighScores Exit: restore blr ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/CannotScrollPastEventsOnPage.asm ================================================ #To be inserted at 8024dec8 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set PageID,31 #Get number of events on this page lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) rtocbl r12,TM_GetPageEventNum #Get current event lbz r4, 0 (r28) #If on the last event, dont scroll down cmpw r4,r3 blt Exit #Exit EventThink branch r12,0x8024e198 Exit: lbz r0, 0 (r28) cmplwi r0, 8 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/Custom Event Highscore Types.asm ================================================ #To be inserted at 801beb8c .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set EventID,31 .set PageID,30 .set KO,0x0 .set Time,0x1 backup #Backup Requested Event mr EventID,r3 #Get Current Page lwz r3,MemcardData(r13) lbz PageID,CurrentEventPage(r3) bl SkipPageList ##### Page List ####### EventJumpTable ####################### Minigames: .byte KO .byte KO .byte KO .byte Time .align 2 GeneralTech: .byte KO .byte KO .byte KO .byte KO .byte KO .byte KO .byte KO .byte KO .byte KO .byte KO .byte KO .byte KO .byte KO .align 2 SpacieTech: .byte KO .byte KO .byte KO .byte KO .align 2 ########################## SkipPageList: mflr r4 #Jump Table Start in r4 mulli r5,PageID,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r4,r4,r5 #Gets ASCII Address in r4 #Get Byte lbzx r3,EventID,r4 exit: restore blr ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/Display Custom Event Descriptions.asm ================================================ #To be inserted at 8024d80c .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set HeaderLength,0xB .set EventID,30 #Get Event ID lbz r3,0x0(r31) lwz r4,0x4(r31) add r4,r3,r4 #Get page number lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) #Get Event Description ASCII rtocbl r12,TM_GetEventDesc CustomEvent: .set text,24 .set ascii,23 mflr r0 stw r0, 0x4(r1) stwu r1,-0x200(r1) # make space for 12 registers stmw r20,0x8(r1) #Backup ASCII mr ascii,r3 #Create Text li r3,0 li r4,0 branchl r12,0x803a6754 mr text,r3 #Store pointer to text so it can be removed by the game stw text,0x78(r31) #Set Text Values lfs f1, -0x384C (rtoc) lfs f2, -0x3848 (rtoc) lfs f3, -0x3874 (rtoc) lfs f4, -0x386C (rtoc) lfs f5, -0x3868 (rtoc) stfs f1,0x00(text) stfs f2,0x04(text) stfs f3,0x08(text) stfs f4,0x0C(text) stfs f5,0x10(text) lfs f0, -0x3844 (rtoc) stfs f0, 0x0024 (text) stfs f0, 0x0028 (text) #Convert To Menu Text mr r4,ascii #ASCII To Store addi r3,sp,0x40 branchl r12,0x803a67ec #Backup Length mr r20,r3 #Get Allocation Info Pointer lwz r21,0x64(text) #Check To Adjust Allocation lwz r22, 0x0004 (r21) #Get old menu text allocation lwz r0, 0 (r21) lwz r4, 0x0008 (r21) #Get size of allocation sub r3, r0, r22 addi r0, r3, 17 add r0, r20, r0 cmplw r4, r0 bge- NoAdjustAllocation sub r0, r0, r4 rlwinm r3, r0, 25, 7, 31 addi r0, r3, 1 rlwinm r0, r0, 7, 0, 24 add r0, r4, r0 stw r0, 0x0008 (r21) lwz r3, 0x0008 (r21) branchl r12,0x803A5798 addi r5, r22, 0 addi r4, r3, 0 li r7, 0 b ReAllocateLoop_Inc ReAllocateLoop: lbz r0, 0 (r5) addi r7, r7, 1 addi r5, r5, 1 stb r0, 0 (r4) addi r4, r4, 1 ReAllocateLoop_Inc: lwz r6, 0x0004 (r21) lwz r0, 0 (r21) sub r6, r0, r6 addi r0, r6, 1 cmpw r7, r0 blt+ ReAllocateLoop stw r3, 0x0004 (r21) stw r3, 0x005C (text) lwz r0, 0 (r21) sub r0, r0, r22 add r0, r3, r0 stw r0, 0 (r21) mr r3, r22 branchl r12,0x803A594C NoAdjustAllocation: #Copy Header to Text Allocation lwz r3,0x5C(text) #Get Pointer to Next Available Menu Text Location bl DescriptionHeader mflr r4 li r5,HeaderLength branchl r12,0x800031f4 #Copy Text to Text Allocation mr r5,r20 #Length lwz r3,0x5C(text) #Get Pointer to Next Available Menu Text Location addi r3,r3,HeaderLength #Skip Past Header addi r4,sp,0x40 branchl r12,0x800031f4 #Add Terminator li r3,0x1900 lwz r4,0x5C(text) addi r4,r4,HeaderLength #Skip Header Length add r4,r4,r20 #Skip Text Length sth r3,0x0(r4) Exit: lmw r20,0x8(r1) lwz r0, 0x204(r1) addi r1,r1,0x200 # release the space mtlr r0 branch r12,0x8024d84c DescriptionHeader: blrl .long 0x160caaaa .long 0xaa0e00b3 .long 0x00b31800 VanillaEvent: rlwinm r3, r30, 1, 0, 30 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/Display Custom Event Names on ESS.asm ================================================ #To be inserted at 8024d470 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" #r24 = text struct #r27 = Event ID CustomEvent: .set text,24 #Create Text li r3,0 li r4,0 branchl r12,0x803a6754 mr text,r3 #Store pointer to text so it can be removed by the game stw text,0x0(r23) #Set Text Values lfs f1, 0x0030 (r31) lfs f4, 0x007C (sp) fadds f1,f4,f1 lfs f0, 0x0034 (r31) fadds f2,f31,f0 lfs f3, -0x3874 (rtoc) lfs f4, -0x386C (rtoc) lfs f5, -0x3868 (rtoc) stfs f1,0x00(text) stfs f2,0x04(text) stfs f3,0x08(text) stfs f4,0x0C(text) stfs f5,0x10(text) lfs f0, -0x3878 (rtoc) stfs f0, 0x0024 (text) stfs f0, 0x0028 (text) li r3,1 stb r3,0x48(text) li r3,1 stb r3,0x49(text) backup #Get Event Name lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) mr r4,r27 rtocbl r12,TM_GetEventName # Add subtext mr r4,r3 mr r3,text lfs f1, -0x3870 (rtoc) lfs f2, -0x3870 (rtoc) branchl r12,0x803a6b98 # Get event file lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) mr r4,r27 rtocbl r12,TM_GetEventFile cmpwi r3,0 bne HasFile NoFile: # Change color mr r3,text li r4,0 bl Color mflr r5 branchl r12,0x803a74f0 HasFile: #Exit restore branch r12,0x8024d4c8 Color: blrl .byte 180, 180, 180, 255 VanillaEvent: Original: lfs f0, 0x0034 (r31) ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/Get Custom Event Description.asm ================================================ #To be inserted at 80005528 .include "../../../Globals.s" .set EventID,31 .set PageID,30 backup #Backup Requested Event mr EventID,r3 #Get Current Page lwz r3,MemcardData(r13) lbz PageID,CurrentEventPage(r3) bl SkipPageList ##### Page List ####### EventJumpTable ####################### EventDescriptionStrings ####################### SkipPageList: mflr r4 #Jump Table Start in r4 mulli r5,PageID,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) #Get String mr r3,EventID add r4,r4,r5 #Gets ASCII Address in r4 branchl r12,SearchStringTable Exit: restore blr ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/Get Custom Event Description.s ================================================ #To be inserted at 80005528 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set EventID,31 .set PageID,30 backup #Backup Requested Event mr EventID,r3 #Get Current Page lwz r3,MemcardData(r13) lbz PageID,CurrentEventPage(r3) bl SkipPageList ##### Page List ####### EventJumpTable ####################### EventDescriptionStrings ####################### SkipPageList: mflr r4 #Jump Table Start in r4 mulli r5,PageID,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) #Get String mr r3,EventID add r4,r4,r5 #Gets ASCII Address in r4 branchl r12,SearchStringTable Exit: restore blr ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/Get Custom Event Name.asm ================================================ #To be inserted at 80005524 .include "../../../Globals.s" .set EventID,31 .set PageID,30 backup #Backup Requested Event mr EventID,r3 #Get Current Page lwz r3,MemcardData(r13) lbz PageID,CurrentEventPage(r3) bl SkipPageList ##### Page List ####### EventJumpTable ####################### EventNameStrings ####################### SkipPageList: mflr r4 #Jump Table Start in r4 mulli r5,PageID,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) #Get String mr r3,EventID add r4,r4,r5 #Gets ASCII Address in r4 branchl r12,SearchStringTable ####################### Exit: restore blr ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/Get Custom Event Name.s ================================================ #To be inserted at 80005524 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set EventID,31 .set PageID,30 backup #Backup Requested Event mr EventID,r3 #Get Current Page lwz r3,MemcardData(r13) lbz PageID,CurrentEventPage(r3) bl SkipPageList ##### Page List ####### EventJumpTable ####################### EventNameStrings ####################### SkipPageList: mflr r4 #Jump Table Start in r4 mulli r5,PageID,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) #Get String mr r3,EventID add r4,r4,r5 #Gets ASCII Address in r4 branchl r12,SearchStringTable ####################### Exit: restore blr ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/Get Custom Event Page Name.asm ================================================ #To be inserted at 8000552c .include "../../../Globals.s" .set PageID,31 backup mr PageID,r3 #Get Events Text bl SkipJumpTable ##### Page List ####### EventJumpTable ####################### SkipJumpTable: mflr r4 #Jump Table Start in r4 mulli r5,PageID,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r3,r4,r5 #Gets ASCII Address in r4 b Exit Minigames: .string "Minigames" .align 2 GeneralTech: .string "Universal Tech" .align 2 SpacieTech: .string "Spacie Tech" .align 2 Exit: restore blr ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/Get Custom Event Page Name.s ================================================ #To be inserted at 8000552c .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set PageID,31 backup mr PageID,r3 #Get Events Text bl SkipJumpTable ##### Page List ####### EventJumpTable ####################### SkipJumpTable: mflr r4 #Jump Table Start in r4 mulli r5,PageID,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r3,r4,r5 #Gets ASCII Address in r4 b Exit Minigames: .string "Minigames" .align 2 GeneralTech: .string "Universal Tech" .align 2 SpacieTech: .string "Spacie Tech" .align 2 Exit: restore blr ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/GetNumOfEventsOnCurrentPage.asm ================================================ #To be inserted at 80005534 .include "../../../Globals.s" .set EventID,31 .set PageID,30 backup #Backup Requested Event mr EventID,r3 #Get Current Page lwz r3,MemcardData(r13) lbz PageID,CurrentEventPage(r3) #Get pointer page's string array bl SkipJumpTable ##### Page List ####### EventJumpTable ####################### SkipJumpTable: mflr r4 #Jump Table Start in r4 mulli r5,PageID,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r5,r4,r5 #Gets Address in r4 lwz r3,0x0(r5) b exit Minigames: .long Minigames.NumOfEvents .align 2 GeneralTech: .long GeneralTech.NumOfEvents .align 2 SpacieTech: .long SpacieTech.NumOfEvents .align 2 exit: restore blr ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/GetNumOfEventsOnCurrentPage.s ================================================ #To be inserted at 80005534 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set EventID,31 .set PageID,30 backup #Backup Requested Event mr EventID,r3 #Get Current Page lwz r3,MemcardData(r13) lbz PageID,CurrentEventPage(r3) #Get pointer page's string array bl SkipJumpTable ##### Page List ####### EventJumpTable ####################### SkipJumpTable: mflr r4 #Jump Table Start in r4 mulli r5,PageID,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r5,r4,r5 #Gets Address in r4 lwz r3,0x0(r5) b exit Minigames: .long Minigames.NumOfEvents .align 2 GeneralTech: .long GeneralTech.NumOfEvents .align 2 SpacieTech: .long SpacieTech.NumOfEvents .align 2 exit: restore blr ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/Never Scroll If Less than 9 Events on Page.asm ================================================ #To be inserted at 8024e438 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" #Original Codeline addi r30, r3, 0 #First check if page has 9 events lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) rtocbl r12,TM_GetPageEventNum cmpwi r3,9 bge Original #Set no scroll li r0,0 stw r0,0x4(r30) #Set selection stb r31,0x0(r30) #Exit branch r12,0x8024e464 Original: addi r3, r30, 0 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/OnlyDisplayEventsOnPage.asm ================================================ #To be inserted at 8024cffc .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set PageID,31 #Get number of events on this page lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) rtocbl r12,TM_GetPageEventNum cmpwi r3,8 blt Exit subi r3,r3,8 Exit: lwz r0, 0x001C (sp) ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Event Text/SkipDisplayingEventNames.asm ================================================ #To be inserted at 8024d3e8 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set PageID,31 #Get number of events on this page lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) rtocbl r12,TM_GetPageEventNum #Check if event exists on this page cmpw r27,r3 ble Exit #Zero out Lv X text li r3,0 stw r3, 0 (r23) #Remove Text lwz r3,0x24(r23) branchl r12,Text_RemoveText li r3,0 stw r3,0x24(r23) #Skip displaying this event branch r12,0x8024d4c8 Exit: li r3, 0 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/GetEventTutorialFileName.asm ================================================ #To be inserted at 80005538 .include "../../Globals.s" .include "../../../m-ex/Header.s" backup ################################################ ## Get Movie's FileName and Extension Pointer ## ################################################ .set EventID,23 .set PageID,24 .set ReturnString,25 #Backup return string mr ReturnString,r3 #Get Hovered Over Event ID in r23 lwz r5, -0x4A40 (r13) lwz r5, 0x002C (r5) lwz r3, 0x0004 (r5) #Selection Number lbz r0, 0 (r5) #Page Number add EventID,r3,r0 #Get Current Page in lwz r3,MemcardData(r13) lbz PageID,CurrentEventPage(r3) #Get pointer page's string array bl SkipJumpTable ##### Page List ####### EventJumpTable ####################### SkipJumpTable: mflr r4 #Jump Table Start in r4 mulli r5,PageID,0x4 #Each Pointer is 0x4 Long add r4,r4,r5 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) #Get Movie File String mr r3,EventID add r4,r4,r5 #Gets ASCII Address in r4 branchl r12,SearchStringTable restore blr ####################################### EventTutorials ####################################### ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Restore FDD Backup on Main Menu Load.asm ================================================ #To be inserted at 8022e630 .include "../../Globals.s" .include "../../../m-ex/Header.s" #Check If First Boot CheckIfFirstBoot: lbz r5,FirstBootFlag(rtoc) cmpwi r5,0x0 beq RestoreBackup #On First Boot #Backup Instead of Restoring lwz r6,-0x77C0(r13) lwz r5,0x1F24(r6) stw r5,-0xDA8(rtoc) #Remove Boot Flag li r5,0x0 stb r5,FirstBootFlag(rtoc) b Exit RestoreBackup: lwz r5,-0xDA8(rtoc) lwz r6,-0x77C0(r13) stw r5,0x1F24(r6) Exit: #Original Line li r3, 3 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Spoof All Events as Not Played.asm ================================================ #To be inserted at 8024d288 li r3,0 ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Version Indicator/Event Code Version Indicator.asm ================================================ #To be inserted at 8024e568 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set text,31 .set textproperties,30 .set VersionString,0x8040a58c .set MainTextOffset,-0x4EB4 .set LeftArrowTextOffset,-0x4EB0 .set RightArrowTextOffset,-0x4EAC .set TutTextOffset,-0x4EA8 .set MenuBackgroundPointer,-0x4EA4 .set MenuTextPointer,-0x4EA0 backup #GET PROPERTIES TABLE bl TEXTPROPERTIES mflr textproperties #Init background pointer li r3,0 stw r3,MenuBackgroundPointer(r13) ######################## ## Create Text Object ## ######################## #CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3 li r3,0 li r4,0 branchl r12,0x803a6754 #BACKUP STRUCT POINTER mr text,r3 #STORE POINTER stw text,MainTextOffset(r13) #SET TEXT SPACING TO TIGHT li r4,0x1 stb r4,0x49(text) #SET TEXT TO CENTER AROUND X LOCATION li r4,0x1 stb r4,0x4A(text) #Store Base Z Offset lfs f1,ZOffset(textproperties) #Z offset stfs f1,0x8(text) #Scale Canvas Down lfs f1,CanvasScaling(textproperties) stfs f1,0x24(text) stfs f1,0x28(text) ############### ## Page Name ## ############### #Get Current Page lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) rtocbl r12,TM_GetPageName #Initialize Subtext mr r4,r3 lfs f1,PageX(textproperties) #X offset of text lfs f2,PageY(textproperties) #Y offset of text mr r3,text #struct pointer branchl r12,0x803a6b98 ############# ## L = OSD ## ############# #Initialize Subtext lfs f1,LX(textproperties) #X offset of text lfs f2,LY(textproperties) #Y offset of text mr r3,text #struct pointer bl LText mflr r4 #pointer to ASCII branchl r12,0x803a6b98 #Change scale mr r4,r3 mr r3,text lfs f1,RScale(textproperties) lfs f2,RScale(textproperties) branchl r12,Text_UpdateSubtextSize ################## ## Version Text ## ################## #Get version string rtocbl r12,TM_GetTMVersLong mr r4,r3 #Initialize Subtext lfs f1,VersionX(textproperties) #X offset of text lfs f2,VersionY(textproperties) #Y offset of text mr r3,text #struct pointer branchl r12,0x803a6b98 #Temp remember subtext ID mr r20,r3 #Change scale mr r4,r20 mr r3,text lfs f1,VersionScale(textproperties) lfs f2,VersionScale(textproperties) branchl r12,Text_UpdateSubtextSize #Change Color mr r4,r20 #subtext id mr r3,text #text pointer load r5,0x8dff6eff stw r5,0xF0(sp) addi r5,sp,0xF0 branchl r12,Text_ChangeTextColor /* ################# ## Z = Options ## ################# #Initialize Subtext lfs f1,OptionsX(textproperties) #X offset of text lfs f2,OptionsY(textproperties) #Y offset of text mr r3,text #struct pointer bl OptionsText mflr r4 #pointer to ASCII branchl r12,0x803a6b98 #Change scale mr r4,r3 mr r3,text lfs f1,OptionsScale(textproperties) lfs f2,OptionsScale(textproperties) branchl r12,Text_UpdateSubtextSize */ ############################### ## Left Page Arrow Indicator ## ############################### #CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3 li r3,0 li r4,0 branchl r12,0x803a6754 #BACKUP STRUCT POINTER mr text,r3 #STORE POINTER stw text,LeftArrowTextOffset(r13) #SET TEXT SPACING TO TIGHT li r4,0x1 stb r4,0x49(text) #SET TEXT TO CENTER AROUND X LOCATION li r4,0x1 stb r4,0x4A(text) #Store Base Z Offset lfs f1,ZOffset(textproperties) #Z offset stfs f1,0x8(text) #Scale Canvas Down lfs f1,CanvasScaling(textproperties) stfs f1,0x24(text) stfs f1,0x28(text) #Initialize Subtext lfs f1,LeftArrowX(textproperties) #X offset of text lfs f2,ArrowY(textproperties) #Y offset of text mr r3,text #struct pointer bl PageArrowLeft mflr r4 branchl r12,0x803a6b98 #Change scale mr r4,r3 mr r3,text lfs f1,ArrowScale(textproperties) lfs f2,ArrowScale(textproperties) branchl r12,Text_UpdateSubtextSize ############################### ## Right Page Arrow Indicator ## ############################### #CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3 li r3,0 li r4,0 branchl r12,0x803a6754 #BACKUP STRUCT POINTER mr text,r3 #STORE POINTER stw text,RightArrowTextOffset(r13) #SET TEXT SPACING TO TIGHT li r4,0x1 stb r4,0x49(text) #SET TEXT TO CENTER AROUND X LOCATION li r4,0x1 stb r4,0x4A(text) #Store Base Z Offset lfs f1,ZOffset(textproperties) #Z offset stfs f1,0x8(text) #Scale Canvas Down lfs f1,CanvasScaling(textproperties) stfs f1,0x24(text) stfs f1,0x28(text) #Initialize Subtext lfs f1,RightArrowX(textproperties) #X offset of text lfs f2,ArrowY(textproperties) #Y offset of text mr r3,text #struct pointer bl PageArrowRight mflr r4 branchl r12,0x803a6b98 #Change scale mr r4,r3 mr r3,text lfs f1,ArrowScale(textproperties) lfs f2,ArrowScale(textproperties) branchl r12,Text_UpdateSubtextSize ################## ## R = Tutorial ## ################## #Check For Training Mode ISO Game ID lis r5,0x8000 lwz r5,0x0(r5) load r6,0x47544d45 #GTME cmpw r5,r6 bne IsMemcard #CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3 li r3,0 li r4,0 branchl r12,0x803a6754 #BACKUP STRUCT POINTER mr text,r3 #STORE POINTER stw text,TutTextOffset(r13) #SET TEXT SPACING TO TIGHT li r4,0x1 stb r4,0x49(text) #SET TEXT TO CENTER AROUND X LOCATION li r4,0x1 stb r4,0x4A(text) #Store Base Z Offset lfs f1,ZOffset(textproperties) #Z offset stfs f1,0x8(text) #Scale Canvas Down lfs f1,CanvasScaling(textproperties) stfs f1,0x24(text) stfs f1,0x28(text) #Initialize Subtext lfs f1,RX(textproperties) #X offset of text lfs f2,RY(textproperties) #Y offset of text mr r3,text #struct pointer bl RText mflr r4 #pointer to ASCII branchl r12,0x803a6b98 #Change scale mr r4,r3 mr r3,text lfs f1,RScale(textproperties) lfs f2,RScale(textproperties) branchl r12,Text_UpdateSubtextSize b TutorialSkip IsMemcard: li r3,0 stw r3,TutTextOffset(r13) TutorialSkip: b end #**************************************************# TEXTPROPERTIES: blrl .set PageX,0x0 .set PageY,0x4 .set ZOffset,0x8 .set RX,0xC .set RY,0x10 .set RScale,0x14 .set LX,0x18 .set LY,0x1C .set VersionX,0x20 .set VersionY,0x24 .set VersionScale,0x28 .set CanvasScaling,0x2C .set ArrowY,0x30 .set LeftArrowX,0x34 .set RightArrowX,0x38 .set ArrowScale,0x3C .set OptionsX,0x40 .set OptionsY,0x44 .set OptionsScale,0x48 #Page .float 0 #text X pos .float -240 #text Y pos .float 17 #Z offset #Press R .float 310 #text X pos .float -230 #text Y pos .float 0.8 #scale #Press L .float -310 #text X pos .float -230 #text Y pos #Version .float 0 #text X pos .float -212 #text Y pos .float 0.6 #text scale .float 0.035 #Canvas Scaling #Arrows .float -215 #Y coordinate .float -210 #left X .float 210 #Right X .float 0.7 #Scale #Options .float 299 #text X pos .float -282 #text Y pos .float 0.8 #text scale NullString: blrl .string "Null" .align 2 PageArrowLeft: blrl .string "<" .align 2 PageArrowRight: blrl .string ">" .align 2 RText: blrl .string "R = Tut" .align 2 LText: blrl .string "L = OSD" .align 2 VersionText: blrl .string "Training Mode %s" .align 2 OptionsText: blrl .string "Z = Options" .align 2 #**************************************************# end: restore lwz r3, 0 (r30) ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Version Indicator/Remove Event Texture.asm ================================================ #To be inserted at 8022e5e4 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 #Original Codeline stw r3, -0x4AE8 (r13) #GET START OF DAT lwz r5,0x0(r3) #get dat length subi r3,r3,0x31 #get to the end of the dat in memory sub r5,r3,r5 #get start of dat #Zero li r3,0 #Make Background Texture Transparent load r4,0x1e754 add r4,r4,r5 stw r3,0xC(r4) #Make Subject Table Texture Transparent load r4,0x1ec88 add r4,r4,r5 stw r3,0xC(r4) exit: ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Version Indicator/Remove Version Indicator 1.asm ================================================ #To be inserted at 8024e304 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set MainTextOffset,-0x4EB4 .set LeftArrowTextOffset,-0x4EB0 .set RightArrowTextOffset,-0x4EAC .set TutTextOffset,-0x4EA8 #Remove All Text lwz r3, MainTextOffset (r13) branchl r12,0x803a5cc4 lwz r3, LeftArrowTextOffset (r13) branchl r12,0x803a5cc4 lwz r3, RightArrowTextOffset (r13) branchl r12,0x803a5cc4 lwz r3, TutTextOffset (r13) cmpwi r3,0 beq SkipTutorial branchl r12,0x803a5cc4 SkipTutorial: #Original Line lwz r3, 0x0074 (r31) ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Version Indicator/Remove Version Indicator 2.asm ================================================ #To be inserted at 8024e3b0 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set MainTextOffset,-0x4EB4 .set LeftArrowTextOffset,-0x4EB0 .set RightArrowTextOffset,-0x4EAC .set TutTextOffset,-0x4EA8 #Remove All Text lwz r3, MainTextOffset (r13) branchl r12,0x803a5cc4 lwz r3, LeftArrowTextOffset (r13) branchl r12,0x803a5cc4 lwz r3, RightArrowTextOffset (r13) branchl r12,0x803a5cc4 lwz r3, TutTextOffset (r13) cmpwi r3,0 beq SkipTutorial branchl r12,0x803a5cc4 SkipTutorial: #Original Line lwz r3, 0x0074 (r31) ================================================ FILE: ASM/training-mode/Custom Events/Event Select Screen/Version Indicator/Toggle Tutorial Text.asm ================================================ #To be inserted at 8024d84c .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set MainTextOffset,-0x4EB4 .set LeftArrowTextOffset,-0x4EB0 .set RightArrowTextOffset,-0x4EAC .set TutTextOffset,-0x4EA8 backup .set REG_PageNum,22 .set EventID,23 .set PageID,24 #Get number of pages rtocbl r12,TM_GetPageNum mr REG_PageNum,r3 #Get Event ID lbz r3,0x0(r31) lwz r4,0x4(r31) add EventID,r3,r4 #Check if first page lwz r3,MemcardData(r13) lbz PageID,CurrentEventPage(r3) cmpwi PageID,0 bne ShowFirstPage #Hide left arrow li r4,1 b FirstPageVisibility ShowFirstPage: #Show left arrow li r4,0 b FirstPageVisibility FirstPageVisibility: lwz r3, LeftArrowTextOffset (r13) stb r4,0x4D(r3) #Check if last page cmpw PageID,REG_PageNum bne ShowLastPage #Hide right arrow li r4,1 b LastPageVisibility ShowLastPage: #Show right arrow li r4,0 b LastPageVisibility LastPageVisibility: lwz r3, RightArrowTextOffset (r13) stb r4,0x4D(r3) #Check For Training Mode ISO Game ID lis r5,0x8000 lwz r5,0x0(r5) load r6,0x47544d45 #GTME cmpw r5,r6 bne end #Get Events Tutorial lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) mr r4,EventID rtocbl r12,TM_GetEventTut mr r20,r3 #Copy File Name To Temp Space addi r21,sp,0x80 mr r3,r21 #Destination mr r4,r20 #Movie FileName branchl r12,0x80325a50 #strcpy #Get Length of This String Now mr r3,r21 #Destination branchl r12,0x80325b04 #Copy .mth Suffix add r3,r3,r21 #Dest bl FileSuffix mflr r4 branchl r12,0x80325a50 #Check if exists mr r3,r21 #Destination branchl r12,0x8033796c cmpwi r3,-1 beq HideTutorial ShowTutorial: li r4,0 b DisplayTutorial HideTutorial: li r4,1 DisplayTutorial: lwz r3, TutTextOffset (r13) stb r4,0x4D(r3) b end FileSuffix: blrl .string ".mth" .align 2 end: restore lwz r0, 0x0024 (sp) ================================================ FILE: ASM/training-mode/Custom Events/Unlock All Events/Unlock Event 1.asm ================================================ #To be inserted at 8024CEC4 b 0x58 ================================================ FILE: ASM/training-mode/Custom Events/Unlock All Events/Unlock Event 2.asm ================================================ #To be inserted at 80162EE8 beq- 0xC ================================================ FILE: ASM/training-mode/Globals.s ================================================ #Debug Flag .set debug,0 #PAL Flag, compiles with PAL codes when enabled .set PAL,0 ####################### ## Codeset Variables ## ####################### #Number of Pages .set NumOfPages,3 -1 #Score Types .set KO,0x0 .set Time,0x1 ################################## #region Minigame Page Data #Number of Events .set Minigames.NumOfEvents,4 -1 #region Eggs-ercise .set Event_Eggs,0 #Event Name .macro Event_Eggs_Name .string "Eggs-ercise" .endm .macro Event_Eggs_Description .string "Break the eggs! Only strong hits will break them. DPad down = free practice." .endm .macro Event_Eggs_Tutorial .string "TvEgg" .endm .macro Event_Eggs_ChooseCPU .endm .macro Event_Eggs_PreloadData .endm .macro Event_Eggs_LoadSSS .byte Event_Eggs .endm .macro Event_Eggs_PlayableCharacters .endm .macro Event_Eggs_AvailableCPUs .endm .macro Event_Eggs_ScoreType .byte KO .endm #endregion #region Multishine .set Event_Multishine,1 #Event Name .macro Event_Multishine_Name .string "Shined Blind" .endm .macro Event_Multishine_Description .string "How many shines can you perform in 10 seconds?" .endm .macro Event_Multishine_Tutorial .string "TvMulShine" .endm .macro Event_Multishine_ChooseCPU .endm .macro Event_Multishine_PreloadData .byte Event_Multishine, -1, FinalDestination .endm .macro Event_Multishine_LoadSSS .endm .macro Event_Multishine_PlayableCharacters .byte Event_Multishine .long Falco_CSSID | Fox_CSSID .long -1 .endm .macro Event_Multishine_AvailableCPUs .endm .macro Event_Multishine_ScoreType .byte KO .endm #endregion #region Reaction .set Event_Reaction,2 #Event Name .macro Event_Reaction_Name .string "Reaction Test" .endm .macro Event_Reaction_Description .string "Test your reaction time by pressing any button when you see/hear Fox shine!" .endm .macro Event_Reaction_Tutorial .string "TvReaction" .endm .macro Event_Reaction_ChooseCPU .endm .macro Event_Reaction_PreloadData .byte Event_Reaction, Fox.Ext, FinalDestination .endm .macro Event_Reaction_LoadSSS .endm .macro Event_Reaction_PlayableCharacters .endm .macro Event_Reaction_AvailableCPUs .endm .macro Event_Reaction_ScoreType .byte KO .endm #endregion #region Ledgestall .set Event_Ledgestall,3 #Event Name .macro Event_Ledgestall_Name .string "Under Fire" .endm .macro Event_Ledgestall_Description .string "Use ledgestalling to remain invincible while the lava rises!" .endm .macro Event_Ledgestall_Tutorial .string "TvMulShine" .endm .macro Event_Ledgestall_ChooseCPU .endm .macro Event_Ledgestall_PreloadData .byte Event_Ledgestall, -1, Brinstar .endm .macro Event_Ledgestall_LoadSSS .endm .macro Event_Ledgestall_PlayableCharacters .byte #Event_Ledgestall .long #Falco_CSSID | Fox_CSSID | Zelda_CSSID | Mewtwo_CSSID | Pikachu_CSSID | CaptainFalcon_CSSID | Ganondorf_CSSID | Link_CSSID | Roy_CSSID | Bowser_CSSID | Marth_CSSID | Yoshi_CSSID .long #-1 .endm .macro Event_Ledgestall_AvailableCPUs .endm .macro Event_Ledgestall_ScoreType .byte Time .endm .set EventOSD_LedgeStall,0x00000000 #endregion #endregion #region Universal Tech Page Data #Number of Events .set GeneralTech.NumOfEvents, 13 -1 #Event List #region LCancel .set Event_LCancel,0 #Event Name .macro Event_LCancel_Name .string "L-Cancel Training" .endm .macro Event_LCancel_Description .string "Practice L-Cancelling on a stationary CPU." .endm .macro Event_LCancel_Tutorial .string "TvLC" .endm .macro Event_LCancel_ChooseCPU .byte Event_LCancel .endm .macro Event_LCancel_PreloadData .endm .macro Event_LCancel_LoadSSS .byte Event_LCancel .endm .macro Event_LCancel_PlayableCharacters .endm .macro Event_LCancel_ScoreType .byte KO .endm #endregion #region Ledgedash .set Event_Ledgedash,1 #Event Name .macro Event_Ledgedash_Name .string "Ledgedash Training" .endm .macro Event_Ledgedash_Description .string "Practice Ledgedashes! Use D-Pad to change ledge." .endm .macro Event_Ledgedash_Tutorial .string "TvLedDa" .endm .macro Event_Ledgedash_ChooseCPU .endm .macro Event_Ledgedash_PreloadData .endm .macro Event_Ledgedash_LoadSSS .byte Event_Ledgedash .endm .macro Event_Ledgedash_PlayableCharacters .endm .macro Event_Ledgedash_ScoreType .byte KO .endm #endregion #region Combo .set Event_Combo,2 #Event Name .macro Event_Combo_Name .string "Combo Training" .endm .macro Event_Combo_Description .string "L+DPad adjusts percent | DPadDown moves CPU DPad right/left saves and loads positions." .endm .macro Event_Combo_Tutorial .string "TvCombo" .endm .macro Event_Combo_ChooseCPU .byte Event_Combo .endm .macro Event_Combo_PreloadData .endm .macro Event_Combo_LoadSSS .byte Event_Combo .endm .macro Event_Combo_PlayableCharacters .endm .macro Event_Combo_ScoreType .byte KO .endm #endregion #region AttackOnShield .set Event_AttackOnShield,3 #Event Name .macro Event_AttackOnShield_Name .string "Attack On Shield" .endm .macro Event_AttackOnShield_Description .string "Practice attacks on a shielding opponent! Pause to change their OoS option." .endm .macro Event_AttackOnShield_Tutorial .string "TvAttOnSh" .endm .macro Event_AttackOnShield_ChooseCPU .byte Event_AttackOnShield .endm .macro Event_AttackOnShield_PreloadData .byte Event_AttackOnShield,-1,FinalDestination .endm .macro Event_AttackOnShield_LoadSSS .endm .macro Event_AttackOnShield_PlayableCharacters .endm .macro Event_AttackOnShield_ScoreType .byte KO .endm #endregion #region Reversal .set Event_Reversal,4 #Event Name .macro Event_Reversal_Name .string "Reversal Training" .endm .macro Event_Reversal_Description .string "Practice OoS punishes! DPad left/right moves characters closer and further apart." .endm .macro Event_Reversal_Tutorial .string "TvRvrsl" .endm .macro Event_Reversal_ChooseCPU .byte Event_Reversal .endm .macro Event_Reversal_PreloadData .endm .macro Event_Reversal_LoadSSS .byte Event_Reversal .endm .macro Event_Reversal_PlayableCharacters .endm .macro Event_Reversal_ScoreType .byte KO .endm #endregion #region SDI .set Event_SDI,5 #Event Name .macro Event_SDI_Name .string "SDI Training" .endm .macro Event_SDI_Description .string "Practice Smash DI'ing Fox's up-air!" .endm .macro Event_SDI_Tutorial .string "TvSDI" .endm .macro Event_SDI_ChooseCPU .endm .macro Event_SDI_PreloadData .byte Event_SDI, Fox.Ext, FinalDestination .endm .macro Event_SDI_LoadSSS .endm .macro Event_SDI_PlayableCharacters .endm .macro Event_SDI_ScoreType .byte KO .endm #endregion #region Powershield .set Event_Powershield,6 #Event Name .macro Event_Powershield_Name .string "Powershield Training" .endm .macro Event_Powershield_Description .string "Powershield Falco's laser! Pause to change fire-rate." .endm .macro Event_Powershield_Tutorial .string "TvPowSh" .endm .macro Event_Powershield_ChooseCPU .endm .macro Event_Powershield_PreloadData .byte Event_Powershield, Falco.Ext, FinalDestination .endm .macro Event_Powershield_LoadSSS .endm .macro Event_Powershield_PlayableCharacters .endm .macro Event_Powershield_ScoreType .byte KO .endm #endregion #region LedgeTech .set Event_LedgeTech,7 #Event Name .macro Event_LedgeTech_Name .string "Ledge-Tech Training" .endm .macro Event_LedgeTech_Description #Ledge-Tech Training .string "Practice ledge-teching Falco's down-smash!" .endm .macro Event_LedgeTech_Tutorial .string "TvLedTc" .endm .macro Event_LedgeTech_ChooseCPU .endm .macro Event_LedgeTech_PreloadData .byte Event_LedgeTech, Falco.Ext, -1 .endm .macro Event_LedgeTech_LoadSSS .byte Event_LedgeTech .endm .macro Event_LedgeTech_PlayableCharacters .endm .macro Event_LedgeTech_ScoreType .byte KO .endm #endregion #region AmsahTech .set Event_AmsahTech,8 #Event Name .macro Event_AmsahTech_Name .string "Amsah-Tech Training" .endm .macro Event_AmsahTech_Description .string "Taunt to have Marth Up-B, then ASDI down and tech!" .endm .macro Event_AmsahTech_Tutorial .string "TvAmsTc" .endm .macro Event_AmsahTech_ChooseCPU .endm .macro Event_AmsahTech_PreloadData .byte Event_AmsahTech, Marth.Ext, -1 .endm .macro Event_AmsahTech_LoadSSS .byte Event_AmsahTech .endm .macro Event_AmsahTech_PlayableCharacters .endm .macro Event_AmsahTech_ScoreType .byte KO .endm #endregion #region ShieldDrop .set Event_ShieldDrop,9 #Event Name .macro Event_ShieldDrop_Name .string "Shield Drop Training" .endm .macro Event_ShieldDrop_Description .string "Counter with a shield-drop aerial! DPad left/right moves players apart." .endm .macro Event_ShieldDrop_Tutorial .string "TvShDrp" .endm .macro Event_ShieldDrop_ChooseCPU .byte Event_ShieldDrop .endm .macro Event_ShieldDrop_PreloadData .byte Event_ShieldDrop, -1, Battlefield .endm .macro Event_ShieldDrop_LoadSSS .endm .macro Event_ShieldDrop_PlayableCharacters .endm .macro Event_ShieldDrop_ScoreType .byte KO .endm #endregion #region WaveshineSDI .set Event_WaveshineSDI,10 #Event Name .macro Event_WaveshineSDI_Name .string "Waveshine SDI" .endm .macro Event_WaveshineSDI_Description .string "Use Smash DI to get out of Fox's waveshine!" .endm .macro Event_WaveshineSDI_Tutorial .string "TvWvSDI" .endm .macro Event_WaveshineSDI_ChooseCPU .endm .macro Event_WaveshineSDI_PreloadData .byte Event_WaveshineSDI, Fox.Ext, FinalDestination .endm .macro Event_WaveshineSDI_LoadSSS .endm .macro Event_WaveshineSDI_PlayableCharacters .byte Event_WaveshineSDI .if PAL==0 .long Doc_CSSID | Mario_CSSID | Bowser_CSSID | Peach_CSSID | Yoshi_CSSID | DK_CSSID | CaptainFalcon_CSSID | Ganondorf_CSSID | Ness_CSSID | Samus_CSSID | Zelda_CSSID | Link_CSSID | Marth_CSSID .endif .if PAL==1 .long Doc_CSSID | Mario_CSSID | Bowser_CSSID | Peach_CSSID | Yoshi_CSSID | DK_CSSID | CaptainFalcon_CSSID | Ganondorf_CSSID | Ness_CSSID | Samus_CSSID | Zelda_CSSID | Link_CSSID .endif .long -1 .endm .macro Event_WaveshineSDI_ScoreType .byte KO .endm #endregion #region SlideOff .set Event_SlideOff,11 #Event Name .macro Event_SlideOff_Name .string "Slide-Off Training" .endm .macro Event_SlideOff_Description .string "Use Slide-Off DI to slide off the platform and counter attack!" .endm .macro Event_SlideOff_Tutorial .string "TvSlOff" .endm .macro Event_SlideOff_ChooseCPU .endm .macro Event_SlideOff_PreloadData .byte Event_SlideOff, Marth.Ext, PokemonStadium .endm .macro Event_SlideOff_LoadSSS .endm .macro Event_SlideOff_PlayableCharacters .endm .macro Event_SlideOff_ScoreType .endm .set EventOSD_SlideOff,0x00000000 #endregion #region GrabMashOut .set Event_GrabMashOut,12 #Event Name .macro Event_GrabMashOut_Name .string "Grab Mash Training" .endm .macro Event_GrabMashOut_Description .string "Mash buttons to escape the grab as quickly as possible!" .endm .macro Event_GrabMashOut_Tutorial .string "TvGrabMash" .endm .macro Event_GrabMashOut_ChooseCPU .endm .macro Event_GrabMashOut_PreloadData .byte Event_GrabMashOut, Marth.Ext, FinalDestination .endm .macro Event_GrabMashOut_LoadSSS .endm .macro Event_GrabMashOut_PlayableCharacters .endm .macro Event_GrabMashOut_ScoreType .byte KO .endm .set EventOSD_GrabMashOut,0x01000000 #endregion #endregion #region Spacie Tech Page Data #Number of Events .set SpacieTech.NumOfEvents,4 -1 #Event List #region LedgetechCounter .set Event_LedgetechCounter,0 #Event Name .macro Event_LedgetechCounter_Name .string "Ledgetech Marth Counter" .endm .macro Event_LedgetechCounter_Description .string "Practice ledge-teching Marth's counter!" .endm .macro Event_LedgetechCounter_Tutorial .string "TvLdTcCntr" .endm .macro Event_LedgetechCounter_ChooseCPU .endm .macro Event_LedgetechCounter_PreloadData .byte Event_LedgetechCounter, Marth.Ext, -1 .endm .macro Event_LedgetechCounter_LoadSSS .byte Event_LedgetechCounter .endm .macro Event_LedgetechCounter_PlayableCharacters .byte Event_LedgetechCounter .long Fox_CSSID | Falco_CSSID #Player Characters .long -1 .endm .macro Event_LedgetechCounter_ScoreType .byte KO .endm #endregion #region ArmadaShine .set Event_ArmadaShine,1 #Event Name .macro Event_ArmadaShine_Name .string "Armada-Shine Training" .endm .macro Event_ArmadaShine_Description .string "Finish off the enemy Fox with an Armada-Shine!" .endm .macro Event_ArmadaShine_Tutorial .string "TvArmShine" .endm .macro Event_ArmadaShine_ChooseCPU .endm .macro Event_ArmadaShine_PreloadData .byte Event_ArmadaShine, Fox.Ext, -1 .endm .macro Event_ArmadaShine_LoadSSS .byte Event_ArmadaShine .endm .macro Event_ArmadaShine_PlayableCharacters .byte Event_ArmadaShine .long -1 #Fox_CSSID #Player Characters .long -1 .endm .macro Event_ArmadaShine_ScoreType .byte KO .endm .set EventOSD_ArmadaShine,0x00000000 #endregion #region SideBSweetspot .set Event_SideBSweetspot,2 #Event Name .macro Event_SideBSweetspot_Name .string "Side-B Sweetspot" .endm .macro Event_SideBSweetspot_Description .string "Use a sweetspot side-B to avoid Marth's down-tilt and grab the ledge!" .endm .macro Event_SideBSweetspot_Tutorial .string "TvSideBSweet" .endm .macro Event_SideBSweetspot_ChooseCPU .endm .macro Event_SideBSweetspot_PreloadData .byte Event_SideBSweetspot, Marth.Ext, -1 .endm .macro Event_SideBSweetspot_LoadSSS .byte Event_SideBSweetspot .endm .macro Event_SideBSweetspot_PlayableCharacters .byte Event_SideBSweetspot .long Fox_CSSID | Falco_CSSID #Player Characters .long -1 .endm .macro Event_SideBSweetspot_ScoreType .byte KO .endm #endregion #region EscapeSheik .set Event_EscapeSheik,3 #Event Name .macro Event_EscapeSheik_Name .string "Escape Sheik Techchase" .endm .macro Event_EscapeSheik_Description .string "Practice escaping the techchase with a frame perfect shine or jab SDI!" .endm .macro Event_EscapeSheik_Tutorial .string "TvEscSheik" .endm .macro Event_EscapeSheik_ChooseCPU .endm .macro Event_EscapeSheik_PreloadData .byte Event_EscapeSheik, Sheik.Ext, FinalDestination .endm .macro Event_EscapeSheik_LoadSSS .endm .macro Event_EscapeSheik_PlayableCharacters .byte Event_EscapeSheik .long Fox_CSSID | Falco_CSSID | CaptainFalcon_CSSID #Player Characters .long -1 .endm .macro Event_EscapeSheik_ScoreType .byte KO .endm #endregion #endregion ################################## #region Event Table Macros #region Event Page Order #This macro will change the order of the pages #Only thing this macro doesn't affect is Load CSS + Preload CPU + high scores. Must change this manually. .macro EventJumpTable bl Minigames bl GeneralTech bl SpacieTech .endm #endregion #region EventAmountPerPage .macro EventAmountPerPage Minigames: .long Minigames.NumOfEvents .align 2 GeneralTech: .long GeneralTech.NumOfEvents .align 2 SpacieTech: .long SpacieTech.NumOfEvents .align 2 .endm #endregion #region EventNameStrings .macro EventNameStrings Minigames: Event_Eggs_Name Event_Multishine_Name Event_Reaction_Name Event_Ledgestall_Name .align 2 GeneralTech: Event_LCancel_Name Event_Ledgedash_Name Event_Combo_Name Event_AttackOnShield_Name Event_Reversal_Name Event_SDI_Name Event_Powershield_Name Event_LedgeTech_Name Event_AmsahTech_Name Event_ShieldDrop_Name Event_WaveshineSDI_Name Event_SlideOff_Name Event_GrabMashOut_Name .align 2 ####################### SpacieTech: #Ledgetech Marth Counter Event_LedgetechCounter_Name #Armada-Shine Practice Event_ArmadaShine_Name Event_SideBSweetspot_Name Event_EscapeSheik_Name .align 2 .endm #endregion #region EventDescriptionStrings .macro EventDescriptionStrings ################ Minigames: Event_Eggs_Description Event_Multishine_Description Event_Reaction_Description Event_Ledgestall_Description .align 2 ################ GeneralTech: Event_LCancel_Description Event_Ledgedash_Description Event_Combo_Description Event_AttackOnShield_Description Event_Reversal_Description Event_SDI_Description Event_Powershield_Description Event_LedgeTech_Description Event_AmsahTech_Description Event_ShieldDrop_Description Event_WaveshineSDI_Description Event_SlideOff_Description Event_GrabMashOut_Description .align 2 ####################### SpacieTech: #Ledgetech Marths Counter Event_LedgetechCounter_Description #Armada-Shine Practice Event_ArmadaShine_Description Event_SideBSweetspot_Description Event_EscapeSheik_Description .align 2 ######################## .endm #endregion #region EventChooseCPU .macro EventChooseCPU ############################ ChooseCPU_Minigames: Event_Eggs_ChooseCPU Event_Multishine_ChooseCPU Event_Reaction_ChooseCPU Event_Ledgestall_ChooseCPU .byte -1 .align 2 ############################ ChooseCPU_GeneralTech: Event_LCancel_ChooseCPU Event_Ledgedash_ChooseCPU Event_SDI_ChooseCPU Event_Reversal_ChooseCPU Event_Powershield_ChooseCPU Event_ShieldDrop_ChooseCPU Event_AttackOnShield_ChooseCPU Event_LedgeTech_ChooseCPU Event_AmsahTech_ChooseCPU Event_Combo_ChooseCPU Event_WaveshineSDI_ChooseCPU Event_SlideOff_ChooseCPU Event_GrabMashOut_ChooseCPU .byte -1 .align 2 ############################ ChooseCPU_SpacieTech: Event_LedgetechCounter_ChooseCPU Event_ArmadaShine_ChooseCPU Event_SideBSweetspot_ChooseCPU Event_EscapeSheik_ChooseCPU .byte -1 .align 2 ############################ .endm #endregion #region EventPreloadData .macro EventPreloadData ############################ PreloadEvents_Minigames: Event_Eggs_PreloadData Event_Multishine_PreloadData Event_Reaction_PreloadData Event_Ledgestall_PreloadData .byte -1 .align 2 ############################ PreloadEvents_GeneralTech: Event_LCancel_PreloadData Event_Ledgedash_PreloadData Event_SDI_PreloadData Event_Reversal_PreloadData Event_Powershield_PreloadData Event_ShieldDrop_PreloadData Event_AttackOnShield_PreloadData Event_LedgeTech_PreloadData Event_AmsahTech_PreloadData Event_Combo_PreloadData Event_WaveshineSDI_PreloadData Event_SlideOff_PreloadData Event_GrabMashOut_PreloadData .byte -1 .align 2 ############################ PreloadEvents_SpacieTech: Event_LedgetechCounter_PreloadData Event_ArmadaShine_PreloadData Event_SideBSweetspot_PreloadData Event_EscapeSheik_PreloadData .byte -1 .align 2 ############################ .endm #endregion #region EventLoadSSS .macro EventLoadSSS ############################ Minigames: Event_Eggs_LoadSSS Event_Multishine_LoadSSS Event_Reaction_LoadSSS Event_Ledgestall_LoadSSS .byte -1 .align 2 ############################ GeneralTech: Event_LCancel_LoadSSS Event_Ledgedash_LoadSSS Event_SDI_LoadSSS Event_Reversal_LoadSSS Event_Powershield_LoadSSS Event_ShieldDrop_LoadSSS Event_AttackOnShield_LoadSSS Event_LedgeTech_LoadSSS Event_AmsahTech_LoadSSS Event_Combo_LoadSSS Event_WaveshineSDI_LoadSSS Event_SlideOff_LoadSSS Event_GrabMashOut_LoadSSS .byte -1 .align 2 ############################ SpacieTech: Event_LedgetechCounter_LoadSSS Event_ArmadaShine_LoadSSS Event_SideBSweetspot_LoadSSS Event_EscapeSheik_LoadSSS .byte -1 .align 2 ############################ .endm #endregion #region EventPlayableCharacters .macro EventPlayableCharacters ############################ Minigames: Event_Eggs_PlayableCharacters Event_Multishine_PlayableCharacters Event_Reaction_PlayableCharacters Event_Ledgestall_PlayableCharacters .byte -1 .align 2 ############################ GeneralTech: Event_LCancel_PlayableCharacters Event_Ledgedash_PlayableCharacters Event_SDI_PlayableCharacters Event_Reversal_PlayableCharacters Event_Powershield_PlayableCharacters Event_ShieldDrop_PlayableCharacters Event_AttackOnShield_PlayableCharacters Event_LedgeTech_PlayableCharacters Event_AmsahTech_PlayableCharacters Event_Combo_PlayableCharacters Event_WaveshineSDI_PlayableCharacters Event_SlideOff_PlayableCharacters Event_GrabMashOut_PlayableCharacters .byte -1 .align 2 ############################ SpacieTech: Event_LedgetechCounter_PlayableCharacters Event_ArmadaShine_PlayableCharacters Event_SideBSweetspot_PlayableCharacters Event_EscapeSheik_PlayableCharacters .byte -1 .align 2 ############################ .endm #endregion #region EventHighScores .macro EventHighScores EventHighScores: blrl .byte 0 .byte Minigames.NumOfEvents +1 .byte Minigames.NumOfEvents + GeneralTech.NumOfEvents +1 .align 2 .endm #endregion #region EventTutorials .macro EventTutorials Minigames: Event_Eggs_Tutorial Event_Multishine_Tutorial Event_Reaction_Tutorial Event_Ledgestall_Tutorial .align 2 GeneralTech: Event_LCancel_Tutorial Event_Ledgedash_Tutorial Event_Combo_Tutorial Event_AttackOnShield_Tutorial Event_Reversal_Tutorial Event_SDI_Tutorial Event_Powershield_Tutorial Event_LedgeTech_Tutorial Event_AmsahTech_Tutorial Event_ShieldDrop_Tutorial Event_WaveshineSDI_Tutorial Event_SlideOff_Tutorial Event_GrabMashOut_Tutorial .align 2 SpacieTech: Event_LedgetechCounter_Tutorial Event_ArmadaShine_Tutorial Event_SideBSweetspot_Tutorial Event_EscapeSheik_Tutorial .align 2 .endm #endregion #endregion #region OnSaveCreate .macro OnSaveCreate #Get trophy data lwz r3, -0x77C0 (r13) addi r3, r3, 7376 #Set trophy count li r4,293 sth r4,0x0(r3) #Set individual trophies as unlocked addi r3,r3,4 li r4,99 li r5,0x24f branchl r12,memset InitSettings: #Set Max OSD on No Memcard li r3,1 lwz r4, -0x77C0 (r13) stb r3,0x1F28(r4) #Set Initial Page Number li r3,0x1 stb r3,CurrentEventPage(r4) #Enable Recommended OSDs li r3,0 stb r3,OSDRecommended(r4) #Enable UCF by default load r3,0x08000000 stw r3,OSDBitfield(r4) .endm #endregion #region OnBootup .macro OnBootup #Set First Boot Flag (used for OSD backup/restore) li r3,0x1 stb r3,FirstBootFlag(rtoc) #Set CPU Info li r3,0x21 stb r3,EventCPUBackup_CharID(rtoc) #Set CPU Character ID .endm #endregion #Custom Memcard Data Bitfield .set OSDBitfield,0x1F24 .set OSDMaxWindows,0x1F28 .set CurrentEventPage,0x1F29 .set OSDRecommended,0x1F2A #Custom rtoc offsets .set EventCPUBackup_CharID,-0xDA5 #byte .set FirstBootFlag,-0xDA4 #byte .set CodesetPointer,-0xDA0 #word .set CodesetLength,-0xD9C #word #OSD IDs .set OSD.Wavedash,0 .set OSD.LCancel,1 .set OSD.MissedTech,2 .set OSD.ActOoS,3 .set OSD.MeteorCancel,4 .set OSD.Dashback,5 .set OSD.ShieldDrop,6 .set OSD.APM,7 .set OSD.SpacieTech,8 .set OSD.SDI,10 .set OSD.Powershield,9 .set OSD.ShieldPoke,11 .set OSD.HitstunLeft,12 .set OSD.ShieldStun,13 .set OSD.ASFramesLeft,14 .set OSD.Miscellaneous,15 .set OSD.ActOoWait,16 .set OSD.CrouchCancel,17 .set OSD.ActOoJump,18 .set OSD.ActOoJumpSquat,19 .set OSD.Fastfall,20 .set OSD.FrameAdvantage,21 .set OSD.ComboCounter,22 .set OSD_23,23 .set OSD.GrabBreakout,24 .set OSD_25,25 .set OSD.Ledge,26 .set OSD.UCF,27 .set OSD.ActOoHitstun,28 .set OSD.DIDraw,0x800000 #Event OSDs .set EventOSD_Eggs,0x00000000 .set EventOSD_Multishine,0x00000000 .set EventOSD_Reaction,0x00000000 .set EventOSD_LCancel,0x00000003 .set EventOSD_Ledgedash,0x04000000 .set EventOSD_Eggs,0x00000000 .set EventOSD_SDI,0x10000400 .set EventOSD_Reversal,0x002C0009 .set EventOSD_Powershield,0x00000200 .set EventOSD_ShieldDrop,0x00200048 .set EventOSD_AttackOnShield,0x00210000 .set EventOSD_LedgeTech,0x00000404 .set EventOSD_AmsahTech,0x00000004 .set EventOSD_ComboTraining,0x01010020 .set EventOSD_WaveshineSDI,0x10000400 .set EventOSD_LedgetechCounter,0x00000604 .set EventOSD_EscapeSheik,0x00000400 ##################### ## Melee Variables ## ##################### #Static Memory Locations .set pdLoadCommonData,0x803bcde0 .set InputStructStart,0x804c21cc .set InputStruct_HeldButtons,0x0 .set InputStruct_HeldButtonsPrevFrame,0x4 .set InputStruct_InstantButtons,0x8 .set InputStruct_RapidFireButtons,0xC .set InputStruct_InstantReleasedButtons,0x10 .set InputStruct_RapidFireCounter,0x14 .set InputStruct_LeftAnalogX,0x18 .set InputStruct_LeftAnalogY,0x19 .set InputStruct_RightAnalogX,0x1A .set InputStruct_RightAnalogY,0x1B .set InputStruct_LeftTrigger,0x1C .set InputStruct_RightTrigger,0x1D .set InputStruct_LeftAnalogXFloat,0x20 .set InputStruct_LeftAnalogYFloat,0x24 .set InputStruct_RightAnalogXFloat,0x28 .set InputStruct_RightAnalogYFloat,0x2C .set InputStruct_IsPlugged,0x41 .set InputStruct_Length,68 .set HSD_InputStructStart,0x804c1fac .set PreloadTable,0x80432078 .set Preload_Stage,0x10 .set CSS_CursorPointers,0x804a0bc0 .set HSD_Pad,0x804c1f78 .set CSS_DoorStructs,0x803f0dfc .set CSSDoor_State,0xB #r13 Offsets .set MemcardData,-0x77C0 .set DEBUGLV,-0x6C98 .set CSS_Data,-0x49F0 .set CSS_UnkGObj,-0x49E4 .set CSS_UnkJObj,-0x49E0 .set CSS_PointerToDatNodes,-0x49C8 #these are initialized to at 80266970 .set CSS_MainPlayerPort,-0x49B0 .set CSS_CPUPlayerPort,-0x49AF .set CSS_StartCountdown,-0x49AE .set CSS_Unk,-0x49AC .set CSS_MaxPlayers,-0x49AB .set CSS_Unk,-0x49AA .set CSS_SinglePlayerPortNumber,-0x4DE0 .set HPS_Unk,-0x3F44 .set HPS_CurrentSongEntryNum,-0x3F3C .set HPS_Unk,-0x3F14 .set GObj_CurrentProc,-0x3E68 .set HSDPerf_,0x0 .set Hitbox_DamageLog,-0x5148 #Num of solid hits dealt by the player this check .set Hitbox_TipLog,-0x5144 #Num of phantom hits dealt by the player this check .set StageID_External,-0x6CB8 .set Stage_LedgeInfo,-0x51E8 .set Stage_LineInfo,-0x51EC #ctrl f "stage line counts" in melee notes.txt for detailed info .set Stage_PositionHazardCount,-0x5128 .set Stage_GrabHazardCount,-0x512C .set Stage_DamageHazardCount,-0x5130 .set Audio_NextAreaInSSMHeap,-0x5258 .set Audio_UnkConstant,-0x5250 .set Audio_TotalSSMMemory,-0x5268 .set GObj_Lists,-0x3E74 .set TM_FrozenToggle,-0x4F8C .set TM_GameFrameCounter,-0x49a8 #TM Function .set TM_tmFunction,-(50*4) #offset of rtoc where function pointers are kept, probably temp solution .set TM_EventPages, TM_tmFunction + 0x0 .set TM_GetEventName, TM_EventPages + 0x4 .set TM_GetEventDesc, TM_GetEventName + 0x4 .set TM_GetEventTut, TM_GetEventDesc + 0x4 .set TM_GetPageName, TM_GetEventTut + 0x4 .set TM_GetPageEventNum, TM_GetPageName + 0x4 .set TM_GetTMVersShort, TM_GetPageEventNum + 0x4 .set TM_GetTMVersLong, TM_GetTMVersShort + 0x4 .set TM_GetTMCompile, TM_GetTMVersLong + 0x4 .set TM_GetPageNum, TM_GetTMCompile + 0x4 .set TM_GetIsChooseCPU, TM_GetPageNum + 0x4 .set TM_GetIsSelectStage, TM_GetIsChooseCPU + 0x4 .set TM_GetFighter, TM_GetIsSelectStage + 0x4 .set TM_GetCPUFighter, TM_GetFighter + 0x4 .set TM_GetStage, TM_GetCPUFighter + 0x4 .set TM_GetEventFile, TM_GetStage + 0x4 .set TM_GetCSSFile, TM_GetEventFile + 0x4 .set TM_EventInit, TM_GetCSSFile + 0x4 .set TM_OnSceneChange, TM_EventInit + 0x4 .set TM_OnBoot, TM_OnSceneChange + 0x4 .set TM_OnStartMelee, TM_OnBoot + 0x4 .set TM_OnFileLoad, TM_OnStartMelee + 0x4 .set TM_MessageDisplay, TM_OnFileLoad + 0x4 #TmDt Data Pointers .set TM_Data,TM_tmFunction - 0x4 #Scene Struct .set SceneController,0x80479D30 .set Scene.CurrentMajor,0x0 .set Scene.PendingMajor,0x1 .set Scene.PreviousMajor,0x2 .set Scene.CurrentMinor,0x3 .set Scene.PendingMinor,0x4 .set Scene.PreviousMinor,0x5 #Scene ID's .set Scene.TitleScreen,0x00 .set Scene.MainMenu,0x01 .set Scene.VSMode,0x02 .set Scene.ClassicMode,0x03 .set Scene.AdventureMode,0x04 .set Scene.AllStarMode,0x05 .set Scene.MainDebugMenu,0x06 .set Scene.SoundTestDebugMenu,0x07 .set Scene.HanyuTestCSS,0x08 .set Scene.HanyuTestSSS,0x09 .set Scene.CameraModeMemcardPrompt,0x0A .set Scene.TrophyGallery,0x0B .set Scene.TrophyLottery,0x0C .set Scene.TrophyCollection,0x0D .set Scene.DebugDiarantou,0x0E .set Scene.TargetTest,0x0F .set Scene.SuperSuddenDeath,0x10 .set Scene.InvisibleMelee,0x11 .set Scene.SloMoMelee,0x12 .set Scene.LightningMelee,0x13 .set Scene.ChallengerApproaching,0x14 .set Scene.ClassicModeEnding,0x15 .set Scene.AdventureModeEnding,0x16 .set Scene.AllStarModeEnding,0x17 .set Scene.OpeningMovie,0x18 .set Scene.VisualSceneDebug,0x19 .set Scene.1PEndingDebug,0x1A .set Scene.TournamentMode,0x1B .set Scene.TrainingMode,0x1C .set Scene.TinyMelee,0x1D .set Scene.GiantMelee,0x1E .set Scene.StaminaMode,0x1F .set Scene.HomeRunContest,0x20 .set Scene.10ManMelee,0x21 .set Scene.100ManMelee,0x22 .set Scene.3MinuteMelee,0x23 .set Scene.15MinuteMelee,0x24 .set Scene.EndlessMelee,0x25 .set Scene.CruelMelee,0x26 .set Scene.ProgressiveScanPrompt,0x27 .set Scene.BootUp,0x28 .set Scene.MemcardPropmt,0x29 .set Scene.FixedCamera,0x2A .set Scene.EventMode,0x2B .set Scene.SingleButton,0x2C #################### ## Function Names ## #################### .set ActionStateChange,0x800693ac .set OSReport,0x803456a8 .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set AS_Wait,0x8008a2bc .set AS_Fall,0x800cc730 .set AS_Catch,0x800d8c54 .set AS_Guard,0x800939b4 .set HSD_MemAlloc,0x8037f1e4 .set HSD_JObjLoadJoint,0x80370e44 .set memcpy,0x800031f4 .set strcpy,0x80325a50 .set ZeroAreaLength,0x8000c160 .set CreateCameraBox,0x80029020 .set FrameSpeedChange,0x8006f190 .set HUD_KOCounter_UpdateKOs,0x802fa2d0 .set Playerblock_StoreTimesR3KilledR4,0x80034fa8 .set Playerblock_LoadTimesR3KilledR4,0x80034f24 .set SFX_PlaySoundAtFullVolume,0x801c53ec .set SFX_MenuCommonSound,0x80024030 .set AS_Rebirth,0x800d4ff4 .set Stage_GetLeftOfLineCoordinates,0x80053ecc .set Stage_GetRightOfLineCoordinates,0x80053da4 .set AS_RebirthWait,0x800d5600 .set RebirthPlatform_UpdatePosition,0x800d54a4 .set AS_CliffWait,0x8009a804 .set Air_StoreBool_LoseGroundJump_NoECBfor10Frames,0x8007d5d4 .set DataOffset_ECBBottomUpdateEnable,0x8007d5bc .set MovePlayerToLedge,0x80081544 .set ApplyIntangibility,0x8007b760 .set ApplyInvincibility,0x8007b7a4 .set GFX_RemoveAll,0x8007db24 .set PlayerBlock_LoadMainCharDataOffset,0x80034110 .set PlayerBlock_SetDamage,0x80034330 .set PlayerBlock_LoadDamage,0x800342b4 .set StageInfo_CameraLimitLeft_Load,0x80224a54 .set StageInfo_CameraLimitRight_Load,0x80224a68 .set StageInfo_CameraLimitTop_Load,0x80224a80 .set StageInfo_CameraLimitBottom_Load,0x80224a98 .set Stage_map_gobj_Load,0x801c2ba4 .set Stage_map_gobj_LoadJObj,0x801c3fa4 .set Stage_Destroy_map_gobj,0x801c4a08 .set EntityItemSpawn,0x80268b18 .set MatchInfo_LoadSeconds,0x8016aeec .set MatchInfo_LoadSubSeconds,0x8016aefc .set EventMatch_OnWinCondition,0x801bc4f4 .set Events_GetEventSavedScore,0x8015cf5c .set Events_SetEventSavedScore,0x8015cf70 .set Textures_DisplayEffectTextures,0x8005fddc .set AS_GrabOpponent,0x800d9ce8 .set AS_Grabbed,0x800daadc .set AS_CatchWait,0x800da1d8 .set AS_SquatWait,0x800d62c4 .set AS_Sleep,0x800d4f24 .set SetAsGrounded,0x8007d7fc .set FrameSpeedChange,0x8006f190 .set EnvironmentCollision_WaitLanding,0x80084280 .set Air_SetAsGrounded,0x8007d6a4 .set CPU_JoystickXAxis_Convert,0x800a17e4 .set CPU_JoystickYAxis_Convert,0x800a1874 .set Joystick_Angle_Retrieve,0x8007d9d4 .set GFX_UpdatePlayerGFX,0x800c0408 .set cos,0x80326240 .set sin,0x803263d4 .set fmod,0x80364340 .set sqrt,0x8000d5bc .set HSD_Free,0x8037f1b0 .set GObj_Create,0x803901f0 .set GObj_AddUserData,0x80390b68 .set GObj_Destroy,0x80390228 .set GObj_AddProc,0x8038fd54 .set GObj_RemoveProc,0x8038fed4 .set GObj_StorePointerToJObj,0x80390a70 .set GObj_AddGXLink,0x8039069c .set HSD_JObjSetMtxDirtySub,0x803732e8 .set DevelopMode_FrameAdvanceCheck,0x801a45e8 .set MatchInfo_StockModeCheck,0x8016b094 .set PlayerBlock_LoadStocksLeft,0x80033bd8 .set PlayerBlock_LoadSlotType,0x8003241c .set Playerblock_LoadStaticBlock,0x80031724 .set Text_CreateTextStruct,0x803a6754 .set Text_InitializeSubtext,0x803a6b98 .set Text_UpdateSubtextSize,0x803a7548 .set Text_UpdateSubtextPosition,0x803a746c .set Text_UpdateSubtextContents,0x803a70a0 .set Text_ChangeTextColor,0x803a74f0 .set Text_RemoveText,0x803a5cc4 .set strlen,0x80325b04 .set PlayerBlock_LoadExternalCharID,0x80032330 .set PlayerBlock_GotoStaleMoveEntry_0xBC,0x80036244 .set InitializePlayerDataValues,0x80068354 .set Event_GetEventSavedScore,0x8015cf5c .set Events_CheckIfEventWasPlayedYet,0x8015cefc .set Events_SetEventAsPlayed,0x8015ceb4 .set Events_StoreEventScore,0x8015cf70 .set Interrupt_AerialJumpGoTo,0x800cb870 .set PlayerBlock_UpdateXYCoords,0x80032828 .set Raycast_GroundLine,0x8004f008 .set Camera_UpdatePlayerCameraBoxPosition,0x800761c8 .set Camera_CorrectPosition,0x8002f3ac .set ItemCollision_Egg,0x802895a8 .set SFX_StopAllCharacterSFX,0x80088a50 .set SFXManager_StopSFXIfPlaying,0x80321ce8 .set memset,0x80003100 .set Ragdoll_WindDecayThink,0x800115f4 .set Inputs_GetPlayerHeldInputs,0x801a3680 .set Inputs_GetPlayerInstantInputs,0x801a36a0 .set Inputs_GetPlayerRapidInputs,0x801a36c0 .set DevelopText_CreateDataTable,0x80302834 .set DevelopText_Activate,0x80302810 .set DevelopText_AddString,0x80302be4 .set DevelopText_EraseAllText,0x80302bb0 .set DevelopMode_Text_ResetCursorXY,0x80302a3c .set DevelopText_StoreBGColor,0x80302b90 .set DevelopText_HideBG,0x80302ae0 .set DevelopText_ShowBG,0x80302ad0 .set cvt_sll_flt,0x80322da0 .set cvt_fp2unsigned,0x803228c0 .set sprintf,0x80323cf4 .set PlayerBlock_LoadNameTagSlot,0x8003556c .set Nametag_LoadNametagSlotText,0x8023754c .set LoadRulesSettingsPointer1,0x8015cc34 .set CSS_UpdateCSPInfo,0x8025db34 .set Rumble_StoreRumbleFlag,0x8015ed4c #Custom Functions .set TextCreateFunction,0x80005928 .set GetCustomEventPageName,0x8000552c .set SearchStringTable,0x80005530 .set GetNumOfEventsOnCurrentPage,0x80005534 .set GetEventTutorialFileName,0x80005538 .set prim.new,0x804DD84C .set prim.close,0x804DD848 #Character External IDs .set CaptainFalcon.Ext,0x0 .set DK.Ext,0x1 .set Fox.Ext,0x2 .set GaW.Ext,0x3 .set Kirby.Ext,0x4 .set Bowser.Ext,0x5 .set Link.Ext,0x6 .set Luigi.Ext,0x7 .set Mario.Ext,0x8 .set Marth.Ext,0x9 .set Mewtwo.Ext,0xA .set Ness.Ext,0xB .set Peach.Ext,0xC .set Pikachu.Ext,0xD .set IceClimbers.Ext,0xE .set Jigglypuff.Ext,0xF .set Samus.Ext,0x10 .set Yoshi.Ext,0x11 .set Zelda.Ext,0x12 .set Sheik.Ext,0x13 .set Falco.Ext,0x14 .set YLink.Ext,0x15 .set Doc.Ext,0x16 .set Roy.Ext,0x17 .set Pichu.Ext,0x18 .set Ganondorf.Ext,0x19 #Character Internal IDs .set Mario.Int,0x0 .set Fox.Int,0x1 .set CaptainFalcon.Int,0x2 .set DK.Int,0x3 .set Kirby.Int,0x4 .set Bowser.Int,0x5 .set Link.Int,0x6 .set Sheik.Int,0x7 .set Ness.Int,0x8 .set Peach.Int,0x9 .set Popo.Int,0xA .set Nana.Int,0xB .set Pikachu.Int,0xC .set Samus.Int,0xD .set Yoshi.Int,0xE .set Jigglypuff.Int,0xF .set Mewtwo.Int,0x10 .set Luigi.Int,0x11 .set Marth.Int,0x12 .set Zelda.Int,0x13 .set YLink.Int,0x14 .set Doc.Int,0x15 .set Falco.Int,0x16 .set Pichu.Int,0x17 .set GaW.Int,0x18 .set Ganondorf.Int,0x19 .set Roy.Int,0x1A /* #Character CSS ID .set Doc_CSSID,0x0 .set Mario_CSSID,0x1 .set Luigi_CSSID,0x2 .set Bowser_CSSID,0x3 .set Peach_CSSID,0x4 .set Yoshi_CSSID,0x5 .set DK_CSSID,0x6 .set CaptainFalcon_CSSID,0x7 .set Ganondorf_CSSID,0x8 .set Falco_CSSID,0x9 .set Fox_CSSID,0xA .set Ness_CSSID,0xB .set IceClimbers_CSSID,0xC .set Kirby_CSSID,0xD .set Samus_CSSID,0xE .set Zelda_CSSID,0xF .set Link_CSSID,0x10 .set YLink_CSSID,0x11 .set Pichu_CSSID,0x12 .set Pikachu_CSSID,0x13 .set Jigglypuff_CSSID,0x14 .set Mewtwo_CSSID,0x15 .set GaW_CSSID,0x16 .set Marth_CSSID,0x17 .set Roy_CSSID,0x18 */ #Character CSS Bitflag IDs #(used for TM's lookup tables for displaying CSS icons) .set Doc_CSSID,0x1 .set Mario_CSSID,0x2 .set Luigi_CSSID,0x4 .set Bowser_CSSID,0x8 .set Peach_CSSID,0x10 .set Yoshi_CSSID,0x20 .set DK_CSSID,0x40 .set CaptainFalcon_CSSID,0x80 .set Ganondorf_CSSID,0x100 .set Falco_CSSID,0x200 .set Fox_CSSID,0x400 .set Ness_CSSID,0x800 .set IceClimbers_CSSID,0x1000 .set Kirby_CSSID,0x2000 .set Samus_CSSID,0x4000 .set Zelda_CSSID,0x8000 .set Link_CSSID,0x10000 .set YLink_CSSID,0x20000 .set Pichu_CSSID,0x40000 .set Pikachu_CSSID,0x80000 .set Jigglypuff_CSSID,0x100000 .set Mewtwo_CSSID,0x200000 .set GaW_CSSID,0x400000 .set Marth_CSSID,0x800000 .set Roy_CSSID,0x1000000 #Stage External IDs .set FoD,0x2 .set PokemonStadium,0x3 .set PeachsCastle,0x4 .set KongoJungle,0x5 .set Brinstar,0x6 .set Corneria,0x7 .set YoshiStory,0x8 .set Onett,0x9 .set MuteCity,0xA .set RainbowCruise,0xB .set JungleJapes,0xC .set GreatBay,0xD .set HyruleTemple,0xE .set BrinstarDepths,0xF .set YoshiIsland,0x10 .set GreenGreens,0x11 .set Fourside,0x12 .set MushroomKingdomI,0x13 .set MushroomKingdomII,0x14 .set Akaneia,0x15 .set Venom,0x16 .set PokeFloats,0x17 .set BigBlue,0x18 .set IcicleMountain,0x19 .set IceTop,0x1A .set FlatZone,0x1B .set DreamLand,0x1C .set YoshiIsland64,0x1D .set KongoJungle64,0x1E .set Battlefield,0x1F .set FinalDestination,0x20 #Button Definitions .set PAD_BUTTON_LEFT,0x40000 .set PAD_BUTTON_RIGHT,0x80000 .set PAD_BUTTON_DOWN,0x20000 .set PAD_BUTTON_UP,0x10000 .set PAD_BUTTON_DPAD_LEFT,0x0001 .set PAD_BUTTON_DPAD_RIGHT,0x0002 .set PAD_BUTTON_DPAD_DOWN,0x0004 .set PAD_BUTTON_DPAD_UP,0x0008 .set PAD_TRIGGER_Z,0x0010 .set PAD_TRIGGER_R,0x0020 .set PAD_TRIGGER_L,0x0040 .set PAD_BUTTON_A,0x0100 .set PAD_BUTTON_B,0x0200 .set PAD_BUTTON_X,0x0400 .set PAD_BUTTON_Y,0x0800 .set PAD_BUTTON_START,0x1000 #SFX Definitions .set SFX_cs_cancel,0xac .set SFX_cs_decide,0xad .set SFX_cs_mv,0xae .set SFX_cs_beep1,0xaf ######################### ## Playerblock Offsets ## ######################### #Misc .set ControllerPort,0x618 .set CostumeID,0x619 #Input Data .set HeldButtons,0x65C .set InstantButtons,0x668 .set AnalogX,0x620 .set AnalogY,0x624 #Animation Data .set CurrentFrame,0x894 #CPU AI Data .set CPU_HeldButtons,0x1A88 .set CPU_AnalogX,0x1A8C .set CPU_AnalogY,0x1A8D .set CPU_CStickX,0x1A8E .set CPU_CStickY,0x1A8F .set CPU_LAnalog,0x1A90 .set CPU_RAnalog,0x1A91 ############################# ## Player Action State IDs ## ############################# .set ASID_DeadDown, 0x00 .set ASID_DeadLeft, 0x01 .set ASID_DeadRight, 0x02 .set ASID_DeadUp, 0x03 .set ASID_DeadUpStar, 0x04 .set ASID_DeadUpStarIce, 0x05 .set ASID_DeadUpFall, 0x06 .set ASID_DeadUpFallHitCamera, 0x07 .set ASID_DeadUpFallHitCameraFlat, 0x08 .set ASID_DeadUpFallIce, 0x09 .set ASID_DeadUpFallHitCameraIce, 0x0A .set ASID_Sleep, 0x0B .set ASID_Rebirth, 0x0C .set ASID_RebirthWait, 0x0D .set ASID_Wait, 0x0E .set ASID_WalkSlow, 0x0F .set ASID_WalkMiddle, 0x10 .set ASID_WalkFast, 0x11 .set ASID_Turn, 0x12 .set ASID_TurnRun, 0x13 .set ASID_Dash, 0x14 .set ASID_Run, 0x15 .set ASID_RunDirect, 0x16 .set ASID_RunBrake, 0x17 .set ASID_KneeBend, 0x18 .set ASID_JumpF, 0x19 .set ASID_JumpB, 0x1A .set ASID_JumpAerialF, 0x1B .set ASID_JumpAerialB, 0x1C .set ASID_Fall, 0x1D .set ASID_FallF, 0x1E .set ASID_FallB, 0x1F .set ASID_FallAerial, 0x20 .set ASID_FallAerialF, 0x21 .set ASID_FallAerialB, 0x22 .set ASID_FallSpecial, 0x23 .set ASID_FallSpecialF, 0x24 .set ASID_FallSpecialB, 0x25 .set ASID_DamageFall, 0x26 .set ASID_Squat, 0x27 .set ASID_SquatWait, 0x28 .set ASID_SquatRv, 0x29 .set ASID_Landing, 0x2A .set ASID_LandingFallSpecial, 0x2B .set ASID_Attack11, 0x2C .set ASID_Attack12, 0x2D .set ASID_Attack13, 0x2E .set ASID_Attack100Start, 0x2F .set ASID_Attack100Loop, 0x30 .set ASID_Attack100End, 0x31 .set ASID_AttackDash, 0x32 .set ASID_AttackS3Hi, 0x33 .set ASID_AttackS3HiS, 0x34 .set ASID_AttackS3S, 0x35 .set ASID_AttackS3LwS, 0x36 .set ASID_AttackS3Lw, 0x37 .set ASID_AttackHi3, 0x38 .set ASID_AttackLw3, 0x39 .set ASID_AttackS4Hi, 0x3A .set ASID_AttackS4HiS, 0x3B .set ASID_AttackS4S, 0x3C .set ASID_AttackS4LwS, 0x3D .set ASID_AttackS4Lw, 0x3E .set ASID_AttackHi4, 0x3F .set ASID_AttackLw4, 0x40 .set ASID_AttackAirN, 0x41 .set ASID_AttackAirF, 0x42 .set ASID_AttackAirB, 0x43 .set ASID_AttackAirHi, 0x44 .set ASID_AttackAirLw, 0x45 .set ASID_LandingAirN, 0x46 .set ASID_LandingAirF, 0x47 .set ASID_LandingAirB, 0x48 .set ASID_LandingAirHi, 0x49 .set ASID_LandingAirLw, 0x4A .set ASID_DamageHi1, 0x4B .set ASID_DamageHi2, 0x4C .set ASID_DamageHi3, 0x4D .set ASID_DamageN1, 0x4E .set ASID_DamageN2, 0x4F .set ASID_DamageN3, 0x50 .set ASID_DamageLw1, 0x51 .set ASID_DamageLw2, 0x52 .set ASID_DamageLw3, 0x53 .set ASID_DamageAir1, 0x54 .set ASID_DamageAir2, 0x55 .set ASID_DamageAir3, 0x56 .set ASID_DamageFlyHi, 0x57 .set ASID_DamageFlyN, 0x58 .set ASID_DamageFlyLw, 0x59 .set ASID_DamageFlyTop, 0x5A .set ASID_DamageFlyRoll, 0x5B .set ASID_LightGet, 0x5C .set ASID_HeavyGet, 0x5D .set ASID_LightThrowF, 0x5E .set ASID_LightThrowB, 0x5F .set ASID_LightThrowHi, 0x60 .set ASID_LightThrowLw, 0x61 .set ASID_LightThrowDash, 0x62 .set ASID_LightThrowDrop, 0x63 .set ASID_LightThrowAirF, 0x64 .set ASID_LightThrowAirB, 0x65 .set ASID_LightThrowAirHi, 0x66 .set ASID_LightThrowAirLw, 0x67 .set ASID_HeavyThrowF, 0x68 .set ASID_HeavyThrowB, 0x69 .set ASID_HeavyThrowHi, 0x6A .set ASID_HeavyThrowLw, 0x6B .set ASID_LightThrowF4, 0x6C .set ASID_LightThrowB4, 0x6D .set ASID_LightThrowHi4, 0x6E .set ASID_LightThrowLw4, 0x6F .set ASID_LightThrowAirF4, 0x70 .set ASID_LightThrowAirB4, 0x71 .set ASID_LightThrowAirHi4, 0x72 .set ASID_LightThrowAirLw4, 0x73 .set ASID_HeavyThrowF4, 0x74 .set ASID_HeavyThrowB4, 0x75 .set ASID_HeavyThrowHi4, 0x76 .set ASID_HeavyThrowLw4, 0x77 .set ASID_SwordSwing1, 0x78 .set ASID_SwordSwing3, 0x79 .set ASID_SwordSwing4, 0x7A .set ASID_SwordSwingDash, 0x7B .set ASID_BatSwing1, 0x7C .set ASID_BatSwing3, 0x7D .set ASID_BatSwing4, 0x7E .set ASID_BatSwingDash, 0x7F .set ASID_ParasolSwing1, 0x80 .set ASID_ParasolSwing3, 0x81 .set ASID_ParasolSwing4, 0x82 .set ASID_ParasolSwingDash, 0x83 .set ASID_HarisenSwing1, 0x84 .set ASID_HarisenSwing3, 0x85 .set ASID_HarisenSwing4, 0x86 .set ASID_HarisenSwingDash, 0x87 .set ASID_StarRodSwing1, 0x88 .set ASID_StarRodSwing3, 0x89 .set ASID_StarRodSwing4, 0x8A .set ASID_StarRodSwingDash, 0x8B .set ASID_LipStickSwing1, 0x8C .set ASID_LipStickSwing3, 0x8D .set ASID_LipStickSwing4, 0x8E .set ASID_LipStickSwingDash, 0x8F .set ASID_ItemParasolOpen, 0x90 .set ASID_ItemParasolFall, 0x91 .set ASID_ItemParasolFallSpecial, 0x92 .set ASID_ItemParasolDamageFall, 0x93 .set ASID_LGunShoot, 0x94 .set ASID_LGunShootAir, 0x95 .set ASID_LGunShootEmpty, 0x96 .set ASID_LGunShootAirEmpty, 0x97 .set ASID_FireFlowerShoot, 0x98 .set ASID_FireFlowerShootAir, 0x99 .set ASID_ItemScrew, 0x9A .set ASID_ItemScrewAir, 0x9B .set ASID_DamageScrew, 0x9C .set ASID_DamageScrewAir, 0x9D .set ASID_ItemScopeStart, 0x9E .set ASID_ItemScopeRapid, 0x9F .set ASID_ItemScopeFire, 0xA0 .set ASID_ItemScopeEnd, 0xA1 .set ASID_ItemScopeAirStart, 0xA2 .set ASID_ItemScopeAirRapid, 0xA3 .set ASID_ItemScopeAirFire, 0xA4 .set ASID_ItemScopeAirEnd, 0xA5 .set ASID_ItemScopeStartEmpty, 0xA6 .set ASID_ItemScopeRapidEmpty, 0xA7 .set ASID_ItemScopeFireEmpty, 0xA8 .set ASID_ItemScopeEndEmpty, 0xA9 .set ASID_ItemScopeAirStartEmpty, 0xAA .set ASID_ItemScopeAirRapidEmpty, 0xAB .set ASID_ItemScopeAirFireEmpty, 0xAC .set ASID_ItemScopeAirEndEmpty, 0xAD .set ASID_LiftWait, 0xAE .set ASID_LiftWalk1, 0xAF .set ASID_LiftWalk2, 0xB0 .set ASID_LiftTurn, 0xB1 .set ASID_GuardOn, 0xB2 .set ASID_Guard, 0xB3 .set ASID_GuardOff, 0xB4 .set ASID_GuardSetOff, 0xB5 .set ASID_GuardReflect, 0xB6 .set ASID_DownBoundU, 0xB7 .set ASID_DownWaitU, 0xB8 .set ASID_DownDamageU, 0xB9 .set ASID_DownStandU, 0xBA .set ASID_DownAttackU, 0xBB .set ASID_DownFowardU, 0xBC .set ASID_DownBackU, 0xBD .set ASID_DownSpotU, 0xBE .set ASID_DownBoundD, 0xBF .set ASID_DownWaitD, 0xC0 .set ASID_DownDamageD, 0xC1 .set ASID_DownStandD, 0xC2 .set ASID_DownAttackD, 0xC3 .set ASID_DownFowardD, 0xC4 .set ASID_DownBackD, 0xC5 .set ASID_DownSpotD, 0xC6 .set ASID_Passive, 0xC7 .set ASID_PassiveStandF, 0xC8 .set ASID_PassiveStandB, 0xC9 .set ASID_PassiveWall, 0xCA .set ASID_PassiveWallJump, 0xCB .set ASID_PassiveCeil, 0xCC .set ASID_ShieldBreakFly, 0xCD .set ASID_ShieldBreakFall, 0xCE .set ASID_ShieldBreakDownU, 0xCF .set ASID_ShieldBreakDownD, 0xD0 .set ASID_ShieldBreakStandU, 0xD1 .set ASID_ShieldBreakStandD, 0xD2 .set ASID_FuraFura, 0xD3 .set ASID_Catch, 0xD4 .set ASID_CatchPull, 0xD5 .set ASID_CatchDash, 0xD6 .set ASID_CatchDashPull, 0xD7 .set ASID_CatchWait, 0xD8 .set ASID_CatchAttack, 0xD9 .set ASID_CatchCut, 0xDA .set ASID_ThrowF, 0xDB .set ASID_ThrowB, 0xDC .set ASID_ThrowHi, 0xDD .set ASID_ThrowLw, 0xDE .set ASID_CapturePulledHi, 0xDF .set ASID_CaptureWaitHi, 0xE0 .set ASID_CaptureDamageHi, 0xE1 .set ASID_CapturePulledLw, 0xE2 .set ASID_CaptureWaitLw, 0xE3 .set ASID_CaptureDamageLw, 0xE4 .set ASID_CaptureCut, 0xE5 .set ASID_CaptureJump, 0xE6 .set ASID_CaptureNeck, 0xE7 .set ASID_CaptureFoot, 0xE8 .set ASID_EscapeF, 0xE9 .set ASID_EscapeB, 0xEA .set ASID_Escape, 0xEB .set ASID_EscapeAir, 0xEC .set ASID_ReboundStop, 0xED .set ASID_Rebound, 0xEE .set ASID_ThrownF, 0xEF .set ASID_ThrownB, 0xF0 .set ASID_ThrownHi, 0xF1 .set ASID_ThrownLw, 0xF2 .set ASID_ThrownLwWomen, 0xF3 .set ASID_Pass, 0xF4 .set ASID_Ottotto, 0xF5 .set ASID_OttottoWait, 0xF6 .set ASID_FlyReflectWall, 0xF7 .set ASID_FlyReflectCeil, 0xF8 .set ASID_StopWall, 0xF9 .set ASID_StopCeil, 0xFA .set ASID_MissFoot, 0xFB .set ASID_CliffCatch, 0xFC .set ASID_CliffWait, 0xFD .set ASID_CliffClimbSlow, 0xFE .set ASID_CliffClimbQuick, 0xFF .set ASID_CliffAttackSlow, 0x100 .set ASID_CliffAttackQuick, 0x101 .set ASID_CliffEscapeSlow, 0x102 .set ASID_CliffEscapeQuick, 0x103 .set ASID_CliffJumpSlow1, 0x104 .set ASID_CliffJumpSlow2, 0x105 .set ASID_CliffJumpQuick1, 0x106 .set ASID_CliffJumpQuick2, 0x107 .set ASID_AppealR, 0x108 .set ASID_AppealL, 0x109 .set ASID_ShoulderedWait, 0x10A .set ASID_ShoulderedWalkSlow, 0x10B .set ASID_ShoulderedWalkMiddle, 0x10C .set ASID_ShoulderedWalkFast, 0x10D .set ASID_ShoulderedTurn, 0x10E .set ASID_ThrownFF, 0x10F .set ASID_ThrownFB, 0x110 .set ASID_ThrownFHi, 0x111 .set ASID_ThrownFLw, 0x112 .set ASID_CaptureCaptain, 0x113 .set ASID_CaptureYoshi, 0x114 .set ASID_YoshiEgg, 0x115 .set ASID_CaptureKoopa, 0x116 .set ASID_CaptureDamageKoopa, 0x117 .set ASID_CaptureWaitKoopa, 0x118 .set ASID_ThrownKoopaF, 0x119 .set ASID_ThrownKoopaB, 0x11A .set ASID_CaptureKoopaAir, 0x11B .set ASID_CaptureDamageKoopaAir, 0x11C .set ASID_CaptureWaitKoopaAir, 0x11D .set ASID_ThrownKoopaAirF, 0x11E .set ASID_ThrownKoopaAirB, 0x11F .set ASID_CaptureKirby, 0x120 .set ASID_CaptureWaitKirby, 0x121 .set ASID_ThrownKirbyStar, 0x122 .set ASID_ThrownCopyStar, 0x123 .set ASID_ThrownKirby, 0x124 .set ASID_BarrelWait, 0x125 .set ASID_Bury, 0x126 .set ASID_BuryWait, 0x127 .set ASID_BuryJump, 0x128 .set ASID_DamageSong, 0x129 .set ASID_DamageSongWait, 0x12A .set ASID_DamageSongRv, 0x12B .set ASID_DamageBind, 0x12C .set ASID_CaptureMewtwo, 0x12D .set ASID_CaptureMewtwoAir, 0x12E .set ASID_ThrownMewtwo, 0x12F .set ASID_ThrownMewtwoAir, 0x130 .set ASID_WarpStarJump, 0x131 .set ASID_WarpStarFall, 0x132 .set ASID_HammerWait, 0x133 .set ASID_HammerWalk, 0x134 .set ASID_HammerTurn, 0x135 .set ASID_HammerKneeBend, 0x136 .set ASID_HammerFall, 0x137 .set ASID_HammerJump, 0x138 .set ASID_HammerLanding, 0x139 .set ASID_KinokoGiantStart, 0x13A .set ASID_KinokoGiantStartAir, 0x13B .set ASID_KinokoGiantEnd, 0x13C .set ASID_KinokoGiantEndAir, 0x13D .set ASID_KinokoSmallStart, 0x13E .set ASID_KinokoSmallStartAir, 0x13F .set ASID_KinokoSmallEnd, 0x140 .set ASID_KinokoSmallEndAir, 0x141 .set ASID_Entry, 0x142 .set ASID_EntryStart, 0x143 .set ASID_EntryEnd, 0x144 .set ASID_DamageIce, 0x145 .set ASID_DamageIceJump, 0x146 .set ASID_CaptureMasterhand, 0x147 .set ASID_CapturedamageMasterhand, 0x148 .set ASID_CapturewaitMasterhand, 0x149 .set ASID_ThrownMasterhand, 0x14A .set ASID_CaptureKirbyYoshi, 0x14B .set ASID_KirbyYoshiEgg, 0x14C .set ASID_CaptureLeadead, 0x14D .set ASID_CaptureLikelike, 0x14E .set ASID_DownReflect, 0x14F .set ASID_CaptureCrazyhand, 0x150 .set ASID_CapturedamageCrazyhand, 0x151 .set ASID_CapturewaitCrazyhand, 0x152 .set ASID_ThrownCrazyhand, 0x153 .set ASID_BarrelCannonWait, 0x154 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro rtocbl reg, offset lwz \reg,\offset(rtoc) mtctr \reg bctrl .endm /* .macro branchl reg, address .long \address ^ 0x80<<24 | 0xC8<<24 .endm */ .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro backupall mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r3,0x8(r1) .endm .macro restoreall lmw r3,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .set R13_EventVars, -0x4A0C .set EventVars_MessageDisplay, (8 * 4) #Message Display .macro Message_Display crset 6 rtocbl r12,TM_MessageDisplay .endm .set MsgData_Text,0x0 .set MSGCOLOR_WHITE, 0 .set MSGCOLOR_GREEN, 1 .set MSGCOLOR_RED, 2 .set MSGCOLOR_YELLOW, 3 ================================================ FILE: ASM/training-mode/Hooks/OnBoot.asm ================================================ #To be inserted at 801bfa28 .include "../Globals.s" .include "../../m-ex/Header.s" #Call function in TmDt rtocbl r12,TM_OnBoot #Original Line lwz r0, 0x001C (sp) ================================================ FILE: ASM/training-mode/Hooks/OnCSSLoad.asm ================================================ #To be inserted at 80266810 .include "../Globals.s" .include "../../m-ex/Header.s" backup # Check if event scene load r3,SceneController lbz r3,Scene.CurrentMajor(r3) cmpwi r3,Scene.EventMode bne Exit # Init pointer as 0 li r3,0 stw r3,0x80(sp) # Get file string lwz r3,MemcardData(r13) lbz r3,CurrentEventPage(r3) lwz r4, -0x77C0 (r13) lbz r4, 0x0535 (r4) rtocbl r12,TM_GetCSSFile cmpwi r3,0 beq Exit # Load this file addi r4,sp,0x80 bl SymbolName mflr r5 branchl r12,0x803d7080 # Execute the function lwz r12,0x80(sp) cmpwi r12,0 beq Exit mtctr r12 bctrl b Exit SymbolName: blrl .string "cssFunction" .align 2 Exit: # Original Line restore lwz r3, -0x49F0 (r13) ================================================ FILE: ASM/training-mode/Hooks/OnSceneChange.asm ================================================ #To be inserted at 801a4c94 .include "../Globals.s" .include "../../m-ex/Header.s" #Original Line stw r3, -0x4F74 (r13) #Call function in TmDt rtocbl r12,TM_OnSceneChange ================================================ FILE: ASM/training-mode/Hooks/OnStartMelee.asm ================================================ #To be inserted at 8016e8c8 .include "../Globals.s" .include "../../m-ex/Header.s" #Call function in TmDt rtocbl r12,TM_OnStartMelee #Original Line lwz r12, 0x0044 (r31) ================================================ FILE: ASM/training-mode/Misc/Adjust Pad Params/Adjust Menu Navigation Deadzone Boot.asm ================================================ #To be inserted at 80406dc0 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set Deadzone,40 .byte 00 .byte Deadzone .byte 00 .byte 00 ================================================ FILE: ASM/training-mode/Misc/Adjust Pad Params/Adjust Menu Navigation Deadzone.asm ================================================ #To be inserted at 804c1f8c .include "../../Globals.s" .include "../../../m-ex/Header.s" .set Deadzone,40 .byte 00 .byte Deadzone .byte 00 .byte 00 ================================================ FILE: ASM/training-mode/Misc/Adjust Pad Params/Increase Rapid Fire Timer.s ================================================ #To be inserted at 8037797c .include "../../Globals.s" .include "../../../m-ex/Header.s" .set AltTimer,3 # Check if R is held lwz r0,0x0(r26) rlwinm. r0,r0,0,0x20 beq Original # Use new timer li r0,AltTimer b Exit Original: # Original timer lwz r0, 0x0010 (r30) Exit: ================================================ FILE: ASM/training-mode/Misc/Better VS Mode Frame Counter/Inc Counter.asm ================================================ #To be inserted at 8016d310 .include "../../Globals.s" .include "../../../m-ex/Header.s" lwz r3,TM_GameFrameCounter(r13) addi r3,r3,1 stw r3,TM_GameFrameCounter(r13) Exit: lwz r31, 0x0034 (sp) ================================================ FILE: ASM/training-mode/Misc/Better VS Mode Frame Counter/Init Counter.asm ================================================ #To be inserted at 8016e744 .include "../../Globals.s" .include "../../../m-ex/Header.s" li r3,0 stw r3,TM_GameFrameCounter(r13) Exit: stw r30, 0x0018 (sp) ================================================ FILE: ASM/training-mode/Misc/Boot Up Tasks.asm ================================================ #To be inserted at 801b02ec .include "../Globals.s" .include "../../m-ex/Header.s" .set entity,31 .set player,31 .set playerdata,31 OnBootup Original: lwz r0, 0x001C (sp) ================================================ FILE: ASM/training-mode/Misc/CSS - Increase SIS Text Heap.asm ================================================ #To be inserted at 801a3f9c .include "../Globals.s" .include "../../m-ex/Header.s" li r3, 18432 ================================================ FILE: ASM/training-mode/Misc/Corneria - Move Ship on Stage Init.asm ================================================ #To be inserted at 801dd980 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm /* I honestly cant believe this code is needed. Melee spawns the players at Y coordinate 300, but the stage starts at Y coordinate 0. Because of this, when i get the coordinate of the ground ID i want to spawn the players over, corneria is technically IN THE BLASTZONE. Therefore, i spawn the players in the blastzone and it loads state on death, so it infinitely kills the players and eventually crashes. This code changes corneria's initialization code to move the ship, instead of waiting for the per frame think function to do it. This way the stage is in the right position when i request the coordinates. */ #Move Corneria mr r3,r30 branchl r12,0x801c2fe0 #Original Codeline lwz r0, 0x0034 (sp) ================================================ FILE: ASM/training-mode/Misc/Count NonExistant Player Kills.asm ================================================ #To be inserted at 801bc59c nop ================================================ FILE: ASM/training-mode/Misc/Disable Calls to ScoreDisplay_Remove.asm ================================================ #To be inserted at 802ff4fc blr ================================================ FILE: ASM/training-mode/Misc/Disable USB Screenshot.asm ================================================ #To be inserted at 801a5070 .include "../Globals.s" .include "../../m-ex/Header.s" nop ================================================ FILE: ASM/training-mode/Misc/Display Stick Info When Paused/Create Text on Pause.asm ================================================ #To be inserted at 801a10e8 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set text,31 .set textproperties,30 .set staticTextData,29 .set inputStruct,28 .set GObj,31 backup #Only in Event Mode load r3,SceneController lbz r3,Scene.CurrentMajor(r3) cmpwi r3,Scene.EventMode bne Exit load staticTextData,0x804a1f58 #CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3 li r3,2 lwz r4,0x0(staticTextData) branchl r12,0x803a6754 mr text,r3 #Store pointer to text stw r3,0x8(staticTextData) #Get Properties bl Text_Properties mflr textproperties #Check Who Paused load r3,0x8046b69c lbz r3,0x5(r3) #Get Inputs mulli r3,r3,68 load r4,0x804c21cc add inputStruct,r3,r4 #SET TEXT SPACING TO TIGHT li r4,0x0 stb r4,0x49(text) #SET TEXT TO NOT CENTER AROUND X LOCATION li r4,0x0 stb r4,0x4A(text) #Change Background Text Color li r3,0x0 stw r3,0x30(text) #Init Background Text mr r3,text #struct pointer lfs f1,0x10(textproperties) #X offset of text lfs f2,0x14(textproperties) #Y offset of text bl TextBackground mflr r4 branchl r12,0x803a6b98 #set size/scaling mr r4,r3 mr r3,text lfs f1,0x18(textproperties) #get text scaling value from table lfs f2,0x1C(textproperties) #get text scaling value from table branchl r12,0x803a7548 #SET TEXT SPACING TO TIGHT li r4,0x1 stb r4,0x49(text) #Init Textline X mr r3,text #struct pointer lfs f1,0x0(textproperties) #X offset of text lfs f2,0x4(textproperties) #Y offset of text bl TextX mflr r4 lbz r5,0x18(inputStruct) lfs f3,0x20(inputStruct) crset 6 branchl r12,0x803a6b98 #set size/scaling mr r4,r3 mr r3,text lfs f1,0x8(textproperties) #get text scaling value from table lfs f2,0x8(textproperties) #get text scaling value from table branchl r12,0x803a7548 #Init Textline Y mr r3,text #struct pointer lfs f1,0x0(textproperties) #X offset of text lfs f2,0xC(textproperties) #Y offset of text bl TextY mflr r4 lbz r5,0x19(inputStruct) lfs f3,0x24(inputStruct) crset 6 branchl r12,0x803a6b98 #set size/scaling mr r4,r3 mr r3,text lfs f1,0x8(textproperties) #get text scaling value from table lfs f2,0x8(textproperties) #get text scaling value from table branchl r12,0x803a7548 ############################### ## Schedule Updater Function ## ############################### #Create GObj li r3, 6 li r4, 0 li r5, 128 branchl r12,0x803901f0 mr GObj,r3 #Store Pointer stw GObj,0xC(staticTextData) #Attach Per Frame Process mr r3,GObj bl TextUpdateFunction mflr r4 li r5,10 branchl r12,0x8038fd54 b Exit #**************************************************# TextBackground: blrl .long 0x815B0000 TextX: blrl .long 0x583a2025 .long 0x342e3466 .long 0x20815e20 .long 0x25640000 TextY: blrl .long 0x593a2025 .long 0x342e3466 .long 0x20815e20 .long 0x25640000 #**************************************************# Text_Properties: blrl .long 0xC1D80000 #X VALUE x offset (-27) .long 0xC1B80000 #X VALUE y offset (-23) .long 0x3D4CCCCD #XANDY text scaling .long 0xC1A80000 #Y VALUE y offset (-21) .long 0xC1E80000 #background x offset (-29) .long 0xC1000000 #background y offset (-8) .float 0.50 #background X text scaling #0.56 .float 1.08 #background Y text scaling #1.08 #***************************************************# TextUpdateFunction: blrl backup #Get Text Info load staticTextData,0x804a1f58 lwz text,0x8(staticTextData) #Check Who Paused load r3,0x8046b69c lbz r3,0x5(r3) #Get Inputs mulli r3,r3,68 load r4,0x804c21cc add inputStruct,r3,r4 #Update X Color lbz r6,0x18(inputStruct) extsb r6,r6 cmpwi r6,0x0 blt XNeg XPos: load r3,0x8dff6eff b XUpdateColor XNeg: load r3,0xffa2baff b XUpdateColor XUpdateColor: stw r3,0xF8(sp) mr r3,text li r4,1 addi r5,sp,0xF8 branchl r12,0x803a74f0 #Update Textline X mr r3,text #struct pointer li r4,1 bl TextX mflr r5 lbz r6,0x18(inputStruct) extsb r6,r6 cmpwi r6,0 bge 0x8 neg r6,r6 lfs f1,0x20(inputStruct) fabs f1,f1 crset 6 branchl r12,0x803a70a0 #Update Y Color lbz r6,0x19(inputStruct) extsb r6,r6 cmpwi r6,0x0 blt YNeg YPos: load r3,0x8dff6eff b YUpdateColor YNeg: load r3,0xffa2baff b YUpdateColor YUpdateColor: stw r3,0xF8(sp) mr r3,text li r4,2 addi r5,sp,0xF8 branchl r12,0x803a74f0 #Update Textline Y mr r3,text #struct pointer li r4,2 bl TextY mflr r5 lbz r6,0x19(inputStruct) extsb r6,r6 cmpwi r6,0 bge 0x8 neg r6,r6 lfs f1,0x24(inputStruct) fabs f1,f1 crset 6 branchl r12,0x803a70a0 restore blr #***************************************************# Exit: restore lmw r26, 0x0018 (sp) ================================================ FILE: ASM/training-mode/Misc/Display Stick Info When Paused/Remove Text on UnPause.asm ================================================ #To be inserted at 801a1124 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set FFVar,0x240C #Only in Event Mode load r3,SceneController lbz r3,Scene.CurrentMajor(r3) cmpwi r3,Scene.EventMode bne Exit #Get Text Struct load r3,0x804a1f58 lwz r3,0x8(r3) #Remove Text Struct branchl r12,0x803a5cc4 #Get GObj load r5,0x804a1f58 lwz r3,0xC(r5) #Zero Out Data li r4,0 stw r4,0x8(r5) stw r4,0xC(r5) #Remove GObj branchl r12,0x80390228 Exit: #Original Codeline lwz r0, 0x000C (sp) ================================================ FILE: ASM/training-mode/Misc/Display Tweet Message And Version Number.asm ================================================ #To be inserted at 80394a6c .include "../Globals.s" .set VersionString,0x8040a58c # Remove all previous OSReports #load r3,0x804cf7e8 #li r4,0 #stw r4,0xC(r3) # Play SFX? li r3, 317 #188 = warning #317 = gasp branchl r12,0x801c53ec ############################# ## OS Report Tweet Message ## ############################# load r20,0x803456a8 #OSReport #OSReport Blank Line bl NewLine mflr r3 mtctr r20 bctrl #OSReport # Line bl PoundLine mflr r3 mtctr r20 bctrl #OSReport Error Message bl ResetCombo #StackDumpMessage1 mflr r3 mtctr r20 bctrl #OSReport # Line bl PoundLine mflr r3 mtctr r20 bctrl #OSReport Blank Line bl NewLine mflr r3 mtctr r20 bctrl #OSReport Mod Version rtocbl r12,TM_GetTMVersLong mr r4,r3 bl Version mflr r3 mtctr r20 bctrl #OSReport Compile Date rtocbl r12,TM_GetTMCompile mtctr r20 bctrl #OSReport Blank Line bl NewLine mflr r3 mtctr r20 bctrl b Exit ######################################################### PoundLine: blrl .long 0x23232323 .long 0x23232323 .long 0x23232323 .long 0x23232323 .long 0x23232323 .long 0x23232323 .long 0x23232323 .long 0x23232323 .long 0x23232323 .long 0x23232323 .long 0x23232323 .long 0x23232323 .long 0x23232323 .long 0x230A0000 NewLine: blrl .long 0x0A000000 Version: blrl .string "%s\n" .align 2 ResetCombo: blrl .string "## TWEET A PICTURE OF THIS MESSAGE TO @UnclePunch_ ##\n## After submitting, PRESS LRA-START to reboot ##\n" .align 2 ######################################################### Exit: addi r3, r30, 2252 ================================================ FILE: ASM/training-mode/Misc/Do Not Save Nametag Region to Memcard for GALE01.asm ================================================ #To be inserted at 8001ae8c .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup stwu r1,-0x100(r1) # make space for 12 registers stmw r3,8(r1) # push r20-r31 onto the stack mflr r0 stw r0,0xFC(sp) .endm .macro restore lwz r0,0xFC(sp) mtlr r0 lmw r3,8(r1) # pop r20-r31 off the stack addi r1,r1,0x100 # release the space .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set TextCreateFunction,0x80005928 .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 #Check If Save Chunk #2 and #3 cmpwi r25,0x2 beq SkipSave cmpwi r25,0x3 beq SkipSave b original #Check For Game ID GALE01 (Memcard Only) SkipSave: lis r3,0x8000 lwz r3,0x0(r3) load r4,0x47414c45 #GALE cmpw r3,r4 bne original li r0,0 b exit original: lwz r0, 0x00F4 (r31) exit: ================================================ FILE: ASM/training-mode/Misc/Edit Carrot Texture.s ================================================ #To be inserted at 8042a760 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00144444 .long 0x008FFFFF .long 0x008FFFFF .long 0x00EFFFFD .long 0x02FFFFF8 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x44441000 .long 0xFFFF8000 .long 0xFFFF8000 .long 0xFFFFE000 .long 0xFFFFF200 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000002 .long 0x00000008 .long 0x08FFFFD1 .long 0x0BFFFFB0 .long 0x1EFFFF80 .long 0x4FFFFF40 .long 0x8FFFFF10 .long 0xDFFFFD00 .long 0xFFFFF800 .long 0xFFFFF800 .long 0xDFFFF800 .long 0xBFFFFB00 .long 0x8FFFFE10 .long 0x4FFFFF40 .long 0x1FFFFF80 .long 0x0DFFFFD0 .long 0x08FFFFF2 .long 0x08FFFFF8 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000008 .long 0x0000000D .long 0x0000002F .long 0x0000008F .long 0x000000BF .long 0x00000088 .long 0x00000000 .long 0x00000000 .long 0xFFFFF200 .long 0xFFFFD000 .long 0xFFFFB000 .long 0xFFFF8000 .long 0xFFFF4000 .long 0x88880000 .long 0x00000000 .long 0x00000000 .long 0x02FFFFF8 .long 0x00DFFFFD .long 0x00BFFFFF .long 0x008FFFFF .long 0x004FFFFF .long 0x00088888 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x20000000 .long 0x80000000 ================================================ FILE: ASM/training-mode/Misc/Edit Hyphen Texture.s ================================================ #To be inserted at 8042ABD8 .long 0x00888888 .long 0x00888888 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x88888888 .long 0x88888888 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x88888888 .long 0x88888888 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x88888880 .long 0x88888880 .long 0x00888888 .long 0x00888888 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x88888888 .long 0x88888888 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x88888888 .long 0x88888888 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x88888880 .long 0x88888880 ================================================ FILE: ASM/training-mode/Misc/Frame Advance Rewrite.asm ================================================ #To be inserted at 8016bbb4 .include "../Globals.s" .include "../../m-ex/Header.s" .set REG_Timer, 10 .set REG_Inputs, 11 .set REG_Count, 12 backup bl Timer mflr REG_Timer load REG_Inputs,0x804c1fac li REG_Count,0 Loop: .set REG_ThisInputs, 9 mulli r3,REG_Count,68 add REG_ThisInputs,r3,REG_Inputs # Check for Z lwz r0,0x0(REG_ThisInputs) rlwinm. r0,r0,0,0x10 beq LoopInc # increment timer lwz r3,0x0(REG_Timer) addi r3,r3,1 stw r3,0x0(REG_Timer) # Check if held for 30 frames lwz r3,0x0(REG_Timer) cmpwi r3,1 beq Success cmpwi r3,30 bge Success b Failure Success: # Inputted, now remove input li r4,0 lwz r0,0x0(REG_ThisInputs) rlwimi r0,r4,4,0x10 stw r0,0x0(REG_ThisInputs) lwz r0,0x8(REG_ThisInputs) rlwimi r0,r4,4,0x10 stw r0,0x8(REG_ThisInputs) # Exit with success li r3,1 b Exit LoopInc: addi REG_Count,REG_Count,1 cmpwi REG_Count,4 blt Loop # Reset timer li r3,0 stw r3,0x0(REG_Timer) # Set advance to 0 load r3,0x80479d48 li r4,0 lbz r0,0x22(r3) rlwimi r0,r4,31,0x1 stb r0,0x22(r3) Failure: li r3,0 b Exit Timer: blrl .long 0 Exit: restore blr ================================================ FILE: ASM/training-mode/Misc/GObj_Destory Exits When Input = 0.asm ================================================ #To be inserted at 80390240 b 0xD8 ================================================ FILE: ASM/training-mode/Misc/HSD_Update Tweak/Allow Z in VS While Paused.asm ================================================ #To be inserted at 8006b0b4 .include "../../Globals.s" .include "../../../m-ex/Header.s" nop ================================================ FILE: ASM/training-mode/Misc/HSD_Update Tweak/Always Run Debug Update.asm ================================================ #To be inserted at 801a4df4 .include "../../Globals.s" .include "../../../m-ex/Header.s" nop ================================================ FILE: ASM/training-mode/Misc/HSD_Update Tweak/Check for DBLevel.asm ================================================ #To be inserted at 801a49a8 .include "../../Globals.s" .include "../../../m-ex/Header.s" lwz r0, -0x6C98 (r13) cmpwi r0,3 bge isDebug NoDebug: #Run just HSDUpdate branch r12,0x801a4a78 isDebug: #Run as normal ================================================ FILE: ASM/training-mode/Misc/HSD_Update Tweak/Clear HSDUpdate for no Debug Melee.asm ================================================ #To be inserted at 801a4b14 .include "../../Globals.s" .include "../../../m-ex/Header.s" # Finish storing function stw r4, 0x0018 (r5) # Check if DBLevel lwz r0, -0x6C98 (r13) cmpwi r0,3 bge isDebug NoDebug: # Clear these functions li r0,0 stw r0, 0x0014 (r5) stw r0, 0x0018 (r5) isDebug: #Run as normal ================================================ FILE: ASM/training-mode/Misc/HSD_Update Tweak/Clear HSDUpdate for no Debug.asm ================================================ #To be inserted at 801a4c08 .include "../../Globals.s" .include "../../../m-ex/Header.s" # Finish storing function stw r0, 0x0028 (r31) # Check if DBLevel lwz r0, -0x6C98 (r13) cmpwi r0,3 bge isDebug NoDebug: # Clear these functions li r0,0 stw r0,0x24(r31) stw r0,0x28(r31) isDebug: #Run as normal ================================================ FILE: ASM/training-mode/Misc/Load .gct on Boot.s ================================================ #To be inserted at 80375384 .include "../Globals.s" .set GeckoCodehandler,0x8040a5e4 .set HeaderSize,32 ######################### ## LOAD FILE FROM DISC ## ######################### backup #Backup ArenaLo to r25 mr r25,r31 #Get File Name bl fileName mflr r3 #Get File Length For Heap Creation mr r29, r3 branchl r12,0x800163D8 #Check If File Exists cmpwi r3,-1 bne CreateHeapBoundaries mr r3,r25 b exit #Create Heap Boundaries .set REG_FileSize,28 CreateHeapBoundaries: addi r3,r3,HeaderSize #add some extra space for the header addi r0, r3, 31 #allign to something rlwinm REG_FileSize, r0, 0, 0, 26 #allign to something mr r3,r25 #r3 = start of heap add r25,r3,REG_FileSize #ArenaHi = ArenaLo+ .gct size addi r25,r25,0x500 #ArenaHi = ArenaHi+ 0x500 (misc space for file loading) mr r4,r25 #r4= end of heap branchl r12,0x803440e8 #Create Heap stw r3, -0x5688 (r13) #Store Active Heap #Allocate persistent file space .set REG_Codeset,27 li r3, 0 mr r4,REG_FileSize branchl r12,0x80015BD0 #Load File addi REG_Codeset, r3, 0 addi r3, r29, 0 addi r4, REG_Codeset, HeaderSize addi r5, sp, 12 branchl r12,0x8001668C #Store codeset pointer and length stw REG_Codeset,CodesetPointer(rtoc) stw REG_FileSize,0x0(REG_Codeset) #Run Codehandler addi r4,REG_Codeset,HeaderSize branchl r12,GeckoCodehandler #Now flush the instruction cache lis r3,0x8000 load r4,0x3b722c #might be overkill but flush the entire dol file branchl r12,0x80328f50 #Return End of Heap mr r3,r25 b exit fileName: blrl .string "codes.gct" .align 2 #EXIT exit: restore mr r31,r3 #r31 = start of next heap addi r3, r31, 31 #original codeline ================================================ FILE: ASM/training-mode/Misc/Load TmDt.asm ================================================ #To be inserted at 803753b0 .include "../Globals.s" .include "../../m-ex/Header.s" .include "../../m-ex/Header.s" #ftX struct .set ftX_Code,0x0 .set ftX_InstructionRelocTable,0x4 .set ftX_InstructionRelocTableCount,0x8 .set ftX_FunctionRelocTable,0xC .set FunctionRelocTable_ReplaceThis,0x0 .set FunctionRelocTable_ReplaceWith,0x4 .set ftX_FunctionRelocTableCount,0x10 .set REG_HeapLo,31 .set REG_FileSize,28 .set REG_File,27 .set REG_HeapID,26 .set REG_Header,25 .set REG_mexData,24 stw r31, -0x3FE8 (r13) backup #Check if file exists bl FileName mflr r3 branchl r12,0x8033796c cmpwi r3,-1 beq Exit #Get size of TmDt.dat bl FileName mflr r3 branchl r12,0x800163d8 addi REG_FileSize,r3,0 #ALlign addi REG_FileSize,REG_FileSize,31 rlwinm REG_FileSize, REG_FileSize, 0, 0, 26 #Create heap of this size add r4,REG_HeapLo,REG_FileSize #heap hi = start + filesize addi r4,r4,32*5 #plus 96 for header mr r3,REG_HeapLo #heap lo = start mr REG_HeapLo,r4 #new start = heap hi branchl r12,0x803440e8 mr REG_HeapID,r3 #Alloc header li r4,68 branchl r12,0x80343ef0 mr REG_Header,r3 #Alloc from this heap mr r3,REG_HeapID mr r4,REG_FileSize branchl r12,0x80343ef0 mr REG_File,r3 #Load file here bl FileName mflr r3 mr r4, REG_File addi r5, sp, 0x80 branchl r12,0x8001668C #Init Archive lwz r5,0x80(sp) mr r3,REG_Header #store header mr r4,REG_File #file branchl r12,0x80016a54 #Get symbol offset mr r3,REG_Header bl SymbolName mflr r4 branchl r12,0x80380358 mr. REG_mexData,r3 beq mexPatch_Skip #Reloc lwz r3,ftX_InstructionRelocTableCount(REG_mexData) #count lwz r4,ftX_Code(REG_mexData) #code lwz r5,ftX_InstructionRelocTable(REG_mexData) #reloc table branchl r12,Reloc #Overload mr r3,REG_mexData addi r4,rtoc,TM_tmFunction bl Overload mexPatch_Skip: #Flush instruction cache so code can be run from this file mr r3,REG_File mr r4,REG_FileSize branchl r12,0x80328f50 #Run TM_OnFileLoad lwz r12,TM_OnFileLoad(rtoc) cmpwi r12,0 beq Skip_OnFileLoad mr r3,REG_Header mtctr r12 bctrl Skip_OnFileLoad: b Exit ########################################### Overload: # r3 = ftX # r4 = table #Copy function pointers - init .set REG_ftX,12 .set REG_ThisElement,11 .set REG_Code,10 .set REG_OverloadTable,9 .set REG_Count,8 .set REG_RelocTable,7 mr REG_ftX,r3 mr REG_OverloadTable,r4 lwz REG_RelocTable,ftX_FunctionRelocTable(REG_ftX) lwz REG_Code,0x0(REG_ftX) li REG_Count,0 b Overload_CheckLoop Overload_Loop: #Get this element mulli r3,REG_Count,8 add REG_ThisElement,r3,REG_RelocTable Overload_TableIndex: #Get ram offset for this function lwz r3,FunctionRelocTable_ReplaceWith(REG_ThisElement) add r3,r3,REG_Code #Update table mulli r4,REG_Count,4 stwx r3,r4,REG_OverloadTable b Overload_IncLoop Overload_IncLoop: addi REG_Count,REG_Count,1 Overload_CheckLoop: lwz r3,ftX_FunctionRelocTableCount(REG_ftX) cmpw REG_Count,r3 blt Overload_Loop Overload_Exit: blr ############################################ FileName: blrl .string "TM/TmDt.dat" .align 2 SymbolName: blrl .string "tmFunction" .align 2 Exit: mr r3,REG_HeapLo restore mr r31,r3 stw r31, -0x3FE8 (r13) mr r3, r31 mr r4, r29 ================================================ FILE: ASM/training-mode/Misc/Never Play Movies in Archives.asm ================================================ #To be inserted at 80259090 b 0x18 ================================================ FILE: ASM/training-mode/Misc/OSReport Match Load Time/Output Time Since Last Tick.asm ================================================ #To be inserted at 8016e91c .include "../../Globals.s" .include "../../../m-ex/Header.s" #************************************************* .if debug==1 #Get Prev Tick lwz r3,-0x49b4(r13) #Get Current Tick mftbl r4 #Find Difference sub r3,r4,r3 #Convert to ms #Get Clock Bus load r4,0x800000f8 lwz r4,0x0(r4) #Clock Bus / 4 li r5,4 divw r4,r4,r5 #Divided by 1000 li r5,1000 divw r4,r4,r5 #divided by ticks divw r4,r3,r4 #OSReport Difference bl OSReportString mflr r3 branchl r12,0x803456a8 b Exit OSReportString: blrl .string "Match loaded in: %dms " .align 2 .endif #************************************************* Exit: lwz r0, 0x0024 (sp) ================================================ FILE: ASM/training-mode/Misc/OSReport Match Load Time/Store Starting Tick.asm ================================================ #To be inserted at 8016e740 .include "../../Globals.s" .include "../../../m-ex/Header.s" mr r31, r3 .if debug==1 #Store Current tick mftbl r3 stw r3,-0x49b4(r13) .endif ================================================ FILE: ASM/training-mode/Misc/On No Save.asm ================================================ #To be inserted at 801af6f4 .include "../Globals.s" .set MEMCARD_HASSAVE,0x0 .set MEMCARD_NOSAVE,0x4 .set MEMCARD_NONE,0xF .set MEMCARD_NONE2,0xD #Check if no memcard inserted cmpwi r29,MEMCARD_HASSAVE beq Original cmpwi r29,MEMCARD_NOSAVE beq NoSave cmpwi r29,MEMCARD_NONE beq NoMemcard cmpwi r29,MEMCARD_NONE2 beq NoMemcard b NoSave NoSave: bl InitSave b Original NoMemcard: bl InitSave #Exit memcard think and disable saving branch r12,0x801b01ac InitSave: backup OnSaveCreate restore blr Original: cmpwi r29,0 ================================================ FILE: ASM/training-mode/Misc/Overwrite Compile Date.s ================================================ #To be inserted at 803ea6c8 .string "DATE 08.22.2019 TIME 10.47 PM" .align 2 ================================================ FILE: ASM/training-mode/Misc/PAL Changes/Character DAT Patcher.asm ================================================ #To be inserted at 80068f30 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set player,31 .if PAL==1 backup lwz r31,0x10C(r30) lwz r31,0x8(r31) subi r31,r31,0x20 lwz r3,0x0(r29) #get character internal ID cmpwi r3,0x1b #check if master hand, crazy hand, wireframes, giga or sandbag bge exit #exit if so bl SkipTable bl diffMario bl diffFox bl diffCaptain bl diffDK bl diffKirby bl diffBowser bl diffLink bl diffSheik bl diffNess bl diffPeach bl diffPopo bl diffNana bl diffPikachu bl diffSamus bl diffYoshi bl diffJigglypuff bl diffMewtwo bl diffLuigi bl diffMarth bl diffZelda bl diffYLink bl diffDoc bl diffFalco bl diffPichu bl diffGaW bl diffGanon bl diffRoy SkipTable: mflr r4 #Jump Table Start in r4 mulli r3,r3,0x4 #Each Pointer is 0x4 Long add r4,r4,r3 #Get Event's Pointer Address lwz r5,0x0(r4) #Get bl Instruction rlwinm r5,r5,0,6,29 #Mask Bits 6-29 (the offset) add r5,r4,r5 #Gets Address in r4 ################ ## Patch Loop ## ################ continue: patchLoop: lwz r3,0x0(r5) lwz r4,0x4(r5) cmpwi r3,0xFF beq endPatchLoop add r3,r3,r31 stw r4,0x0(r3) addi r5,r5,0x8 b patchLoop endPatchLoop: b exit ################# ## DIFF TABLES ## ################# diffMario: .long 0x00003344 .long 0x3f547ae1 .long 0x00003360 .long 0x42c40000 .long 0x000000FF diffFox: .long 0x0000379c .long 0x42920000 .long 0x00003908 .long 0x40000000 .long 0x0000390c .long 0x40866666 .long 0x00003910 .long 0x3dea0ea1 .long 0x00003928 .long 0x41a00000 .long 0x00003c04 .long 0x2c01480c .long 0x00004720 .long 0x1b968013 .long 0x00004734 .long 0x1b968013 .long 0x0000473C .long 0x04000009 .long 0x00004A40 .long 0x2C006811 .long 0x00004A4C .long 0x281B0013 .long 0x00004A50 .long 0x0D00010B .long 0x00004A54 .long 0x2C806811 .long 0x00004A60 .long 0x281B0013 .long 0x00004A64 .long 0x0D00010B .long 0x00004B24 .long 0x2C00680D .long 0x00004B30 .long 0x0F104013 .long 0x00004B38 .long 0x2C80380D .long 0x00004B44 .long 0x0F104013 .long 0x000000FF diffCaptain: .long 0x0000380c .long 0x00000007 .long 0x00004ef8 .long 0x2c003803 .long 0x00004f08 .long 0x0f80000b .long 0x00004f0c .long 0x2c802003 .long 0x00004f1C .long 0x0f80000b .long 0x000000FF diffDK: .long 0x000000FF diffKirby: .long 0x00004d10 .long 0x3fc00000 .long 0x00004d70 .long 0x42940000 .long 0x00004dd4 .long 0x41900000 .long 0x00004de0 .long 0x41900000 .long 0x000083ac .long 0x2c000009 .long 0x000083b8 .long 0x348c8011 .long 0x00008400 .long 0x348C8011 .long 0x00008430 .long 0x0500008b .long 0x00008438 .long 0x041a0500 .long 0x00008444 .long 0x0500008b .long 0x000084dc .long 0x05780578 .long 0x000085b8 .long 0x1000010b .long 0x000085c0 .long 0x03e801f4 .long 0x000085cc .long 0x1000010b .long 0x000085d4 .long 0x038403e8 .long 0x000085e0 .long 0x1000010b .long 0x00008818 .long 0x0b00010b .long 0x0000882c .long 0x0b00010b .long 0x000088f8 .long 0x041a0bb8 .long 0x0000893c .long 0x041a0bb8 .long 0x00008980 .long 0x041a0bb8 .long 0x000089E0 .long 0x04fef704 .long 0x000000FF diffBowser: .long 0x000036cc .long 0x42EC0000 .long 0x000037c4 .long 0x0C000000 .long 0x000000FF diffLink: .long 0x00003468 .long 0x3f666666 .long 0x000039d8 .long 0x440C0000 .long 0x00003a44 .long 0xb4990011 .long 0x00003a48 .long 0x1b8c008f .long 0x00003a58 .long 0xb4990011 .long 0x00003a5c .long 0x1b8c008f .long 0x00003a6c .long 0xb4990011 .long 0x00003a70 .long 0x1b8c008f .long 0x00003b30 .long 0x440C0000 .long 0x000000FF diffSheik: .long 0x000045c8 .long 0x2c015010 .long 0x000045d4 .long 0x2d198013 .long 0x000045dc .long 0x2c80b010 .long 0x000045e8 .long 0x2d198013 .long 0x000049c4 .long 0x2c00680a .long 0x000049d0 .long 0x281b8013 .long 0x000049d8 .long 0x2c80780a .long 0x000049e4 .long 0x281b8013 .long 0x000049f0 .long 0x2c006808 .long 0x000049fc .long 0x231b8013 .long 0x00004a04 .long 0x2c807808 .long 0x00004a10 .long 0x231b8013 .long 0x00005c98 .long 0x1e0c8080 .long 0x00005cf4 .long 0xb4800c90 .long 0x00005d08 .long 0xb4800c90 .long 0x000000FF diffNess: .long 0x00003a1c .long 0xb4940013 .long 0x00003a64 .long 0x2c000015 .long 0x00003a70 .long 0xb4928013 .long 0x000000FF diffPeach: .long 0x000000FF diffPopo: .long 0x000000FF diffNana: .long 0x000000FF diffPikachu: .long 0x0000647C .long 0xb49a4017 .long 0x00006480 .long 0x64001097 .long 0x000000FF diffSamus: .long 0x000000FF diffYoshi: .long 0x000033e4 .long 0x42de0000 .long 0x00004528 .long 0x2c013011 .long 0x00004534 .long 0xb4988013 .long 0x0000453c .long 0x2c813011 .long 0x00004548 .long 0xb4988013 .long 0x00004550 .long 0x2d002011 .long 0x0000455c .long 0xb4988013 .long 0x000045f8 .long 0x2c01300f .long 0x00004608 .long 0x0f00010b .long 0x0000460c .long 0x2c81280f .long 0x0000461c .long 0x0f00010b .long 0x00004aec .long 0x2c007003 .long 0x00004b00 .long 0x2c803803 .long 0x000000FF diffJigglypuff: .long 0x000000FF diffMewtwo: .long 0x0000485c .long 0x2c00000f .long 0x000000FF diffLuigi: .long 0x000000FF diffMarth: .long 0x000037b0 .long 0x3f59999a .long 0x000037cc .long 0x42aa0000 .long 0x00005520 .long 0x87118013 .long 0x000000FF diffZelda: .long 0x000000FF diffYLink: .long 0x00003b8c .long 0x440c0000 .long 0x00003d0c .long 0x440c0000 .long 0x000000FF diffDoc: .long 0x000000FF diffFalco: .long 0x000050e4 .long 0xb4990013 .long 0x000050f8 .long 0xb4990013 .long 0x000000FF diffPichu: .long 0x000000FF diffGaW: .long 0x000000FF diffGanon: .long 0x00004eb0 .long 0x02bcff38 .long 0x00004ebc .long 0x14000123 .long 0x00004ec4 .long 0x038401f4 .long 0x00004ed0 .long 0x14000123 .long 0x00004ed8 .long 0x044c04b0 .long 0x00004ee4 .long 0x14000123 .long 0x0000505c .long 0x2c006815 .long 0x0000506c .long 0x14080123 .long 0x00005070 .long 0x2c806015 .long 0x00005080 .long 0x14080123 .long 0x00005084 .long 0x2d002015 .long 0x00005094 .long 0x14080123 .long 0x000000FF diffRoy: .long 0x000000FF exit: restore .endif lis r3, 0x803C ================================================ FILE: ASM/training-mode/Misc/PAL Changes/DK - Keep Up B Charge After Getting Hit out of Up B/Keep Charge Aerial Up B.asm ================================================ #To be inserted at 8010fc48 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .if PAL==1 nop .endif .if PAL==0 stw r0, 0x21DC (r5) .endif ================================================ FILE: ASM/training-mode/Misc/PAL Changes/DK - Keep Up B Charge After Getting Hit out of Up B/Keep Charge Grounded Up B.asm ================================================ #To be inserted at 8010fb68 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .if PAL==1 nop .endif .if PAL==0 stw r0, 0x21DC (r5) .endif ================================================ FILE: ASM/training-mode/Misc/PAL Changes/Detection Hitboxes Does Not Skip Hurtbox Collision Check.asm ================================================ #To be inserted at 800796e0 .include "../../Globals.s" .include "../../../m-ex/Header.s" .if PAL==1 nop .endif .if PAL==0 li r18, 1 .endif ================================================ FILE: ASM/training-mode/Misc/PAL Changes/Fix Freeze Glitch.asm ================================================ #To be inserted at 801239a8 .include "../../Globals.s" .include "../../../m-ex/Header.s" .if PAL==1 nop .endif .if PAL==0 stw r0, 0x1A5C (r31) .endif ================================================ FILE: ASM/training-mode/Misc/PAL Changes/PAL CSS Indicator.asm ================================================ #To be inserted at 80266978 .include "../../Globals.s" .include "../../../m-ex/Header.s" .if PAL==1 loc_0x0: mflr r14 bl loc_0x34 mflr r4 mtlr r14 lis r14, 0x35 ori r14, r14, 0x6A60 sub r3, r3, r14 li r5, 0x238 lis r14, 0x8000 ori r14, r14, 0x31F4 mtctr r14 bctrl b loc_0x274 loc_0x34: blrl .long 0x00000000 .long 0x00006fff .long 0x00007ff1 .long 0x00007ff0 .long 0x00007ff0 .long 0x00007ff0 .long 0x00007fff .long 0x00007ff1 .long 0x00000000 .long 0xffc40002 .long 0x17ff3006 .long 0x00ef800b .long 0x00ef801f .long 0x04ff404f .long 0xfff7009f .long 0x110000ef .long 0x00000000 .long 0xfff8000d .long 0xfefd000f .long 0xfbff300f .long 0xF6DF700F .long 0xF3BFC00F .long 0xE07FF10F .long 0xB14FF60F .long 0x00000000 .long 0xF6000000 .long 0xF7000000 .long 0xF7000000 .long 0xF7000000 .long 0xF7000000 .long 0xF7000000 .long 0xF7000000 .long 0x04ff9888 .long 0x00cfb888 .long 0x009fc888 .long 0x006fd888 .long 0x004fe888 .long 0x002ff888 .long 0x000ff888 .long 0x002ff888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x8888888E .long 0x888888DF .long 0x88888CFF .long 0x8888AFF7 .long 0x8889FFA0 .long 0x888FFC00 .long 0x8DFFB100 .long 0xeff60000 .long 0xff400000 .long 0xF3000000 .long 0x40000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x88888888 .long 0x8888EF40 .long 0x8888DF60 .long 0x8888CF90 .long 0x8888BFC0 .long 0x88889FF4 .long 0x88888DF9 .long 0x88888BFE .long 0x888888EF .long 0x00007ff0 .long 0x00007ff0 .long 0x00006fd0 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x30000000 .long 0x90000000 .long 0x000003ff .long 0x000008ff .long 0x00000bfb .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0xeffffb0f .long 0x200AFF1F .long 0x0004ff4d .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0xF7000000 .long 0xF7111100 .long 0xfffffb00 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x00000000 .long 0x004fe888 .long 0x006fd888 .long 0x009fc888 .long 0x00cfb888 .long 0x04ff9888 .long 0x09fd8888 .long 0x3EFB8888 .endif loc_0x274: addi r3, r31, 0x718 ================================================ FILE: ASM/training-mode/Misc/PAL Changes/PAL Stock Icons.asm ================================================ #To be inserted at 802f9a3c .include "../../Globals.s" .include "../../../m-ex/Header.s" .if PAL==1 #Get Flaots bl Floats mflr r4 #Store X Scale lwz r3,0x0(r4) stw r3,0x2c(r29) #Store Y Scale stw r3,0x30(r29) #Load Y Offset lwz r3,0x4(r4) stw r3,0x3C(r29) b original ###################################### Floats: blrl .float 0.85 #x and y scale .float -21 #y offset ###################################### original: lwz r0, 0x0014 (r29) .endif .if PAL==0 lwz r0, 0x0014 (r29) .endif ================================================ FILE: ASM/training-mode/Misc/PAL Changes/Samus - Disable Extender/Disable Initial Extender Polling.asm ================================================ #To be inserted at 802b7e54 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .if PAL==1 b 0x88 .endif .if PAL==0 lbz r3, 0x2240 (r31) .endif ================================================ FILE: ASM/training-mode/Misc/PAL Changes/Samus - Disable Extender/Disable Secondary Extender Polling.asm ================================================ #To be inserted at 802b808c .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .if PAL==1 b 0x84 .endif .if PAL==0 cmpwi r3, 2 .endif ================================================ FILE: ASM/training-mode/Misc/PAL Changes/Samus Cant Bomb Jump Out of Grapple.asm ================================================ #To be inserted at 803ce4d4 .include "../../Globals.s" .include "../../../m-ex/Header.s" .if PAL==1 .long 0x00240464 .endif .if PAL==0 .long 0x00200000 .endif ================================================ FILE: ASM/training-mode/Misc/Save File Renaming.asm ================================================ #To be inserted at 8001c800 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set TextCreateFunction,0x80005928 .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 #Check For Game ID GTME (ISO) lis r11,0x8000 lwz r11,0x0(r11) load r12,0x47544d45 #GTME cmpw r11,r12 beq ISO b Memcard ISO: bl ISOSaveName mflr r5 b exit Memcard: bl MemcardSaveName mflr r5 bl MemcardStringFormat mflr r4 b exit ISOSaveName: blrl .long 0x54726169 .long 0x6e696e67 .long 0x204d6f64 .long 0x65206279 .long 0x20556e63 .long 0x6c655075 .long 0x6e636820 .long 0x20202020 ISOSaveDesc: #blrl .long 0x47616D65 .long 0x20446174 .long 0x61000000 MemcardSaveName: blrl .long 0x53757065 .long 0x7220536D .long 0x61736820 .long 0x42726F73 .long 0x2E204D65 .long 0x6C656520 .long 0x20202020 .long 0x20202020 MemcardSaveDesc: #blrl .long 0x4d6f6420 .long 0x4c61756e .long 0x63686572 .long 0x20283120 .long 0x6f662032 .long 0x29000000 MemcardStringFormat: blrl .long 0x25730000 exit: branchl r12,0x80323cf4 ================================================ FILE: ASM/training-mode/Misc/ScoreDisplay - Change GXLink Pri.asm ================================================ #To be inserted at 802ff4d8 li r9,1 ================================================ FILE: ASM/training-mode/Misc/SearchStringTable.asm ================================================ #To be inserted at 0x80005530 .include "../Globals.s" .include "../../m-ex/Header.s" ############################################# .set ID,31 .set LoopCount,30 .set Name,29 backup #Get ID mr ID,r3 #Get Names mr Name,r4 #Init Loop Count li LoopCount,0 SearchStringTable_Loop: #Check if we are up to the correct name cmpw ID,LoopCount beq SearchStringTable_Exit #Get string length mr r3,Name branchl r12,0x80325b04 #Add to current name pointer add Name,Name,r3 addi Name,Name,1 #Inc Loop Count addi LoopCount,LoopCount,1 b SearchStringTable_Loop SearchStringTable_Exit: mr r3,Name restore blr ################################### ================================================ FILE: ASM/training-mode/Misc/Skip Assert for Respawn Platform.asm ================================================ #To be inserted at 800d5524 b 0x7C ================================================ FILE: ASM/training-mode/Misc/Skip Assert for no_reaction_always.asm ================================================ #To be inserted at 8006d494 b 0x20C ================================================ FILE: ASM/training-mode/Misc/Skip SetGroundStateAssert For Restore States.asm ================================================ #To be inserted at 8007d8e8 b 0x30 ================================================ FILE: ASM/training-mode/Misc/Store Version Number.s ================================================ #To be inserted at 8040a58c .string "v2.0 Beta 3" .align 2 ================================================ FILE: ASM/training-mode/Misc/Text - Increment Max Size.asm.asm ================================================ #To be inserted at 803a6b7c b -0x360 ================================================ FILE: ASM/training-mode/Misc/Text Modifications/Add Symbols to ASCII-Menu Text Lookup Table.asm ================================================ #To be inserted at 803a684c .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set TextCreateFunction,0x80005928 .set LoopCount,31 .set Dictionary,30 .set CurrentDictOffset,12 #Runs When the ASCII Value is 0x85 or Greater #Katagana Starts at Dictionary Offset 0xB0 backup #Search custom symbol table bl CustomSymbolDictionary mflr Dictionary li LoopCount,0 Loop: mulli CurrentDictOffset,LoopCount,0x3 add CurrentDictOffset,CurrentDictOffset,Dictionary lbz r11,0x0(CurrentDictOffset) cmpwi r11,0xFF beq Exit cmpw r10,r11 beq CharacterFound IncLoop: addi LoopCount,LoopCount,1 b Loop CharacterFound: #If overriding 0xA lbz r10,0x0(CurrentDictOffset) #Check Matched Character cmpwi r10,0x0A bne CharacterFound_Resume #Store 0x3 to the menu text string li r10,0x03 stbx r10,r3,r9 #increment r9 by 1 to get next offset in menu text string addi r9,r9,1 #branch to 803a6b70, will increment r5 and r6 by 1 to get next offset in ASCII string and loop restore branch r12,0x803a6b70 CharacterFound_Resume: lbz r10,0x1(CurrentDictOffset) #Load Override Character lbz r12,0x2(CurrentDictOffset) #Load Override Character restore mr r31,r12 load r0,0x8040c8c0 branch r12,0x803a6b08 CustomSymbolDictionary: blrl .byte 0x21,0x81,0x49 #Exclamation Point .byte 0x2f,0x81,0x5E #Slash .byte 0x2e,0x81,0x44 #Period .byte 0x3d,0x81,0x81 #Equals Sign .byte 0x2b,0x81,0x7B #Plus Sign .byte 0x25,0x81,0x93 #Percent Sign .byte 0x0A,0x03,0x00 #New Line .byte 0x27,0x81,0x66 #Apostrophe .byte 0x3e,0x81,0x84 #Greater than .byte 0x3c,0x81,0x83 #Less than .byte 0x5F,0x81,0x51 #Underscore .byte 0x5E,0x81,0x4F #Carrot .byte 0x3F,0x81,0x48 #Question mark .byte 0x7c,0x81,0x62 # | symbol .byte 0x28,0x81,0x69 #Open Parenthesis .byte 0x29,0x81,0x6A #Close Parenthesis .byte 0xFF .align 2 Exit: restore load r0,0x8040c8c0 cmplwi r10, 32 /* #Katagana code cmpwi r10,0x85 blt original addi r31,r10,0x2b branch r12,0x803a6b38 original: lbzu r31, 0x0001 (r6) */ ================================================ FILE: ASM/training-mode/Misc/Text Modifications/Make Spaces Not Store 00s.asm ================================================ #To be inserted at 803a6868 b 0x34 ================================================ FILE: ASM/training-mode/Misc/Text Modifications/Make Spaces Store 0x1A.asm ================================================ #To be inserted at 803a6860 li r8, 26 ================================================ FILE: ASM/training-mode/Misc/Text Modifications/Parse Numbers Correctly.asm ================================================ #To be inserted at 803a69c0 b 0x3C ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOS Frame Display/Count During GuardOff.asm ================================================ #To be inserted at 80092ce8 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,4 .set player,30 .set text,29 .set textprop,28 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## lwz playerdata, 0x002C (r31) lhz r5,TM_ShieldFrames(playerdata) cmpwi r5,0xFF beq skipInc addi r5,r5,0x1 sth r5,TM_ShieldFrames(playerdata) skipInc: lwz r0, 0x0024 (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOS Frame Display/Count During ShieldWait.asm ================================================ #To be inserted at 80092a38 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,4 .set player,30 .set text,29 .set textprop,28 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## lwz r4, 0x002C (r3) lhz r5,TM_ShieldFrames(playerdata) cmpwi r5,0xFF beq skipInc addi r5,r5,0x1 sth r5,TM_ShieldFrames(playerdata) skipInc: ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOS Frame Display/Display OOS Frame Count Standalone.asm ================================================ #To be inserted at 80005508 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set REG_FighterData,31 .set player,30 .set REG_TextColor, 29 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall mr player,r4 lwz REG_FighterData,0x2C(player) ##################### ## CHECK IF IASA'd ## ##################### #CHECK IF ENABLED li r0,OSD.ActOoS #wavedash ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r5, 1 slw r0, r5, r0 and. r0, r0, r4 beq Moonwalk_Exit CheckForIASA: cmpwi r3,0x1 bne Moonwalk_Exit CheckForFollower: mr r3,REG_FighterData branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit CheckForGuardOff: lwz r3,0x10(REG_FighterData) cmpwi r3,0xB4 beq Moonwalk_Exit ShieldWaitCheck: #CHECK IF 3RD MOST RECENT AS WAS SHIELD STUN lhz r3,TM_TwoASAgo(REG_FighterData) cmpwi r3,0xB5 beq CreateText GuardOffCheck: #CHECK IF 4TH MOST RECENT AS WAS SHIELD STUN lhz r3,TM_ThreeASAgo(REG_FighterData) cmpwi r3,0xB5 beq CreateText b Moonwalk_Exit CreateText: #Change color to Green if frame perfect act oos lhz r3,TM_ShieldFrames(REG_FighterData) #get shield stun frames left cmpwi r3,0x0 bgt WhiteText li REG_TextColor,MSGCOLOR_GREEN b PrintMessage WhiteText: li REG_TextColor,MSGCOLOR_WHITE b PrintMessage PrintMessage: li r3,3 #Message Kind lbz r4,0xC(REG_FighterData) #Message Queue mr r5,REG_TextColor bl OoS_String mflr r6 lhz r7,TM_ShieldFrames(REG_FighterData) #get shield stun frames left addi r7,r7,1 Message_Display b Moonwalk_Exit /* mr r3,REG_FighterData #backup REG_FighterData pointer li r4,60 #display for 60 frames li r5,0 #Area to Display (0-2) li r6,3 #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr text,r3 #backup text pointer #CHECK IF FRAME PERFECT lhz r3,0x23EE(REG_FighterData) #get shield stun frames left cmpwi r3,0x0 bgt NotFramePerfect #SET TEXT COLOR TO GREEN load r3,0x8dff6eff stw r3, 0x0030 (text) NotFramePerfect: #INITALIZE TEXT 1 mr r3,r29 #text pointer bl DuringSSASCII mflr r4 #get ASCII to print lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,0x803a6b98 #INITALIZE TEXT 2 mr r3,r29 #text pointer bl DuringSSASCII2 mflr r4 #get ASCII to print lhz r5,0x23EE(REG_FighterData) #get shield stun frames left addi r5,r5,0x1 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis branchl r12,0x803a6b98 b Moonwalk_Exit */ ################### ## TEXT CONTENTS ## ################### OoS_String: blrl .string "Act OoShield\nFrame %d" .align 2 ############################## Moonwalk_Exit: restoreall blr ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOS Frame Display/GuardOff - Display OOS Frame Count.asm ================================================ #To be inserted at 80092dfc .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set TextCreateFunction,0x80005928 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## mr r4,r30 branchl r12,0x80005508 lwz r0, 0x0024 (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOS Frame Display/GuardWait - Display OOS Frame Count.asm ================================================ #To be inserted at 80092b58 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set TextCreateFunction,0x80005928 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## mr r4,r30 branchl r12,0x80005508 lwz r0, 0x001C (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOS Frame Display/Init Frame Count.asm ================================================ #To be inserted at 80093388 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## #init count li r0,0 sth r0,TM_ShieldFrames(r29) lwz r0, 0x234C (r29) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/DamageFall - Check For Interrupt.asm ================================================ #To be inserted at 80090924 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 #Check If Entered Fall lwz r4,0x10(r31) cmpwi r4,0x1D bne CheckToDisplay li r3,1 CheckToDisplay: #Branch to Interrupt Check With Interrupt Bool in r3 and player in r4 mr r4,r30 branchl r12,0x80005504 lwz r0, 0x001C (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/DamageFlyTop - CheckForInterrupt.asm ================================================ #To be inserted at 8008ff14 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 #Branch to Interrupt Check With Interrupt Bool in r3 and player in r4 mr r4,r31 branchl r12,0x80005504 branch r12,0x8008ff1c ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/DamageLightHit - Check For Animation Interrupt.asm ================================================ #To be inserted at 8008f914 .include "../../Globals.s" .include "../../../m-ex/Header.s" #Branch to Interrupt Check With Interrupt Bool in r3 and player in r4 mr r4,r31 branchl r12,0x80005504 branch r12,0x8008f920 ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/DamageLightHit - Check For Interrupt - Aerial Jump.asm ================================================ #To be inserted at 8008f8fc .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 #Branch to Interrupt Check With Interrupt Bool in r3 and player in r4 mr r4,r31 branchl r12,0x80005504 branch r12,0x8008f904 ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/DamageLightHit - Check ForInterrupt.asm ================================================ #To be inserted at 8008fae4 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 #Branch to Interrupt Check With Interrupt Bool in r3 and player in r4 mr r4,r30 branchl r12,0x80005504 branch r12,0x8008fb00 ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/Increment Post Hitstun Count.asm ================================================ #To be inserted at 8006ab60 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set player,31 .set Text,30 .set TextProp,29 ################################### ## Increment Post-Hitstun Frames ## ################################### #Check If In Hitstun lbz r3, 0x221C (r31) rlwinm. r0, r3, 31, 31, 31 beq NoHitstun InHitstun: li r3,0 sth r3,TM_PostHitstunFrameCount(r31) b Hitstun_End NoHitstun: lhz r3,TM_PostHitstunFrameCount(r31) addi r3,r3,1 sth r3,TM_PostHitstunFrameCount(r31) b Hitstun_End Hitstun_End: exit: lwz r12, 0x21A0 (r31) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageFall - Increment Counter.asm ================================================ #To be inserted at 80090824 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,4 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 lwz playerdata,0x2c(r3) #Increment PostHitstun Counter lhz r3,TM_PostHitstunFrameCount(playerdata) addi r3,r3,0x1 sth r3,TM_PostHitstunFrameCount(playerdata) Exit: blr ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageFlyRoll - Increment Counter.asm ================================================ #To be inserted at 8009029c .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,29 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 #Check If Not In Hitstun lbz r3, 0x221C (r29) rlwinm. r0, r3, 31, 31, 31 bne Exit #Increment PostHitstun Counter lhz r3,TM_PostHitstunFrameCount(playerdata) addi r3,r3,0x1 sth r3,TM_PostHitstunFrameCount(playerdata) Exit: lbz r3, 0x221C (r29) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageFlyRoll - Init DamageFallCounter.asm ================================================ #To be inserted at 800902c4 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,29 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 stb r3, 0x221C (r29) #Initialize Counter at 0x2354 sth r0,TM_PostHitstunFrameCount(playerdata) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageFlyTop - Increment Counter.asm ================================================ #To be inserted at 8008fe64 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,29 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 #Check If Not In Hitstun lbz r3, 0x221C (r29) rlwinm. r0, r3, 31, 31, 31 bne Exit #Increment PostHitstun Counter lhz r3,TM_PostHitstunFrameCount(playerdata) addi r3,r3,0x1 sth r3,TM_PostHitstunFrameCount(playerdata) Exit: lbz r3, 0x221C (r29) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageFlyTop - Init DamageFallCounter.asm ================================================ #To be inserted at 8008fe8c .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,29 .set player,30 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## stb r3, 0x221C (r29) #Initialize Counter at 0x2354 sth r0, TM_PostHitstunFrameCount(playerdata) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageLightHit - Increment Counter.asm ================================================ #To be inserted at 8008f828 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set playerdata,30 .set player,30 #Check If Not In Hitstun lbz r3, 0x221C (playerdata) rlwinm. r0, r3, 31, 31, 31 bne Exit #Increment PostHitstun Counter lhz r3,TM_PostHitstunFrameCount(playerdata) addi r3,r3,0x1 sth r3,TM_PostHitstunFrameCount(playerdata) Exit: lbz r3, 0x221C (playerdata) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageLightHit - Init DamageFallCounter.asm ================================================ #To be inserted at 8008f850 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,30 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## stb r3, 0x221C (r30) #Initialize Counter at 0x2340 sth r0,TM_PostHitstunFrameCount(playerdata) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/MissFoot - Init Counter.asm ================================================ #To be inserted at 8009f3ec .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## #Initialize Counter at 0x2354 li r0,0 sth r0,TM_PostHitstunFrameCount(playerdata) lwz r0, 0x001C (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OOTumble/Static Function - Display Frames Spent Post Hitstun.asm ================================================ #To be inserted at 80005504 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set REG_FighterData,31 .set player,30 .set REG_TextColor,29 .set REG_Text,28 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backup mr player,r4 lwz REG_FighterData,0x2c(player) #Check For Interrupt cmpwi r3,0x1 bne Moonwalk_Exit #CHECK IF ENABLED li r0,OSD.ActOoHitstun #PowerShield ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit CheckForFollower: mr r3,REG_FighterData branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit #Check if frame 1 lhz r3,TM_PostHitstunFrameCount(REG_FighterData) cmpwi r3,0 bgt WhiteText GreenText: li REG_TextColor,MSGCOLOR_GREEN b PrintMessage WhiteText: li REG_TextColor,MSGCOLOR_WHITE b PrintMessage PrintMessage: li r3,5 #Message Kind lbz r4,0xC(REG_FighterData) #Message Queue mr r5,REG_TextColor bl ActOoHitstun_String mflr r6 lhz r7,TM_PostHitstunFrameCount(REG_FighterData) addi r7,r7,1 Message_Display b Moonwalk_Exit /* bl CreateText #Change Text Color lhz r3,TM_PostHitstunFrameCount(REG_FighterData) cmpwi r3,0x0 bne RedText GreenText: load r3,0x8dff6eff #green b StoreTextColor RedText: load r3,0xffa2baff StoreTextColor: stw r3,0x30(text) #Create Text bl TopText mr r3,r29 #text pointer mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,0x803a6b98 #Create Text2 bl BottomText mr r3,r29 #text pointer mflr r4 lhz r5,TM_PostHitstunFrameCount(REG_FighterData) addi r5,r5,1 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis branchl r12,0x803a6b98 CreateText: mflr r0 stw r0, 0x0004 (sp) stwu sp, -0x0008 (sp) mr r3,REG_FighterData #backup REG_FighterData pointer li r4,60 #display for 60 frames li r5,0 #Area to Display (0-2) li r6,15 #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr text,r3 #backup text pointer lwz r0, 0x000C (sp) addi sp, sp, 8 mtlr r0 blr */ ################### ## TEXT CONTENTS ## ################### ActOoHitstun_String: blrl .string "Act OoHitstun\nFrame %d" .align 2 ############################## Moonwalk_Exit: restore blr ================================================ FILE: ASM/training-mode/Onscreen Display/Act OoWait/Act OOWait- Standalone.asm ================================================ #To be inserted at 8000551c .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set FramesSince,28 .set ASBeforeWait,27 .set REG_Color,26 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall #Get Player Pointers mr player,r3 lwz playerdata,0x2c(player) #CHECK IF ENABLED li r0,OSD.ActOoWait #PowerShield ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit CheckForFollower: mr r3,playerdata branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit #Calculate Frames Since Wait and Get AS Before Wait li r5,0 #Loop Count li r4,TM_PrevASStart WaitSearchLoop: mulli r3,r5,0x2 add r3,r3,r4 lhzx r3,r3,playerdata cmpwi r3,0xE beq WaitSearchExit addi r5,r5,1 cmpwi r5,6 bge Moonwalk_Exit b WaitSearchLoop WaitSearchExit: #Get AS Before Wait addi r3,r5,1 mulli r3,r3,0x2 add r3,r3,r4 lhzx ASBeforeWait,r3,playerdata #Get Frames In Wait li r4,TM_FramesInPrevASStart #Frame Count Start li FramesSince,0 #Init Frame Count FrameCountLoop: cmpwi r5,0 beq FrameCountLoopFinish mulli r3,r5,0x2 add r3,r3,r4 lhzx r3,r3,playerdata add FramesSince,r3,FramesSince subi r5,r5,1 b FrameCountLoop FrameCountLoopFinish: lhz r3,TM_FramesInPrevASStart(playerdata) #Frames spent in Wait add FramesSince,r3,FramesSince #Get Total Frames Since #Check If Under 13 Frames cmpwi FramesSince,13 bgt Moonwalk_Exit #Only Coming from Throws, Aerial Landing, and Teching/Getups #Aerial Landing cmpwi ASBeforeWait,0x46 blt NotThrow cmpwi ASBeforeWait,0x4A bgt NotThrow b ComingFromWhitelist NotThrow: #Throws cmpwi ASBeforeWait,0xDB blt NotAerialLanding cmpwi ASBeforeWait,0xDE bgt NotAerialLanding b ComingFromWhitelist NotAerialLanding: #Teching/Getups #Aerial Landing cmpwi ASBeforeWait,0xB7 blt NotTeching cmpwi ASBeforeWait,0xC9 bgt NotTeching b ComingFromWhitelist NotTeching: #Wavedash cmpwi ASBeforeWait,ASID_LandingFallSpecial bne NotWavedash b ComingFromWhitelist NotWavedash: b Moonwalk_Exit ComingFromWhitelist: SpawnText: #Change Text Color cmpwi FramesSince,0x1 bne RedText GreenText: load r3,0x8dff6eff #green b StoreTextColor RedText: load r3,0xffa2baff StoreTextColor: stw r3,0x80(sp) #Create Text li r3,5 #Message Kind lbz r4,0xC(playerdata) #Message Queue li r5,MSGCOLOR_WHITE bl TechText mflr r6 mr r7,FramesSince Message_Display ChangeColor: lwz r3,0x2C(r3) lwz r3,MsgData_Text(r3) li r4,1 addi r5,sp,0x80 branchl r12,Text_ChangeTextColor b Moonwalk_Exit ################### ## TEXT CONTENTS ## ################### TechText: blrl .string "Act OoWait\nFrame: %d" .align 2 ############################## Moonwalk_Exit: restoreall blr ================================================ FILE: ASM/training-mode/Onscreen Display/Act OoWait/Act OoWait - From Crouch.asm ================================================ #To be inserted at 800d6228 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,30 .set player,31 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall #Get Playerdata lwz playerdata,0x2C(player) #Check If Interrupted lwz r3,0x10(playerdata) cmpwi r3,0x27 beq Moonwalk_Exit #Make Sure Player Didn't Buffer Shield lwz r3,0x10(playerdata) cmpwi r3,0xB2 beq Moonwalk_Exit #Ensure I'm Actually Coming from Wait lhz r3,TM_TwoASAgo(playerdata) cmpwi r3,0xE bne Moonwalk_Exit #Check To Display OSD mr r3,r31 branchl r12,0x8000551c Moonwalk_Exit: restoreall lwz r0, 0x0024 (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OoWait/Act OoWait - From Landing.asm ================================================ #To be inserted at 800d5efc .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,30 .set player,29 .set text,29 .set FramesSince,28 .set ASBeforeLanding,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall #Check if Interrupted cmpwi r3,0x1 bne Moonwalk_Exit #CHECK IF ENABLED li r0,0x10 #PowerShield ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit CheckForFollower: mr r3,playerdata branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit #Ensure I'm Actually Coming from Landing (Wait interrupt is used for certain IASA) lhz r3,TM_OneASAgo(playerdata) cmpwi r3,ASID_Landing bne Moonwalk_Exit #Make Sure Player Didn't Buffer Crouch, Shield, or Walk lwz r3,0x10(playerdata) cmpwi r3,0xF beq Moonwalk_Exit cmpwi r3,0x10 beq Moonwalk_Exit cmpwi r3,0x11 beq Moonwalk_Exit cmpwi r3,0x27 beq Moonwalk_Exit cmpwi r3,0xB2 beq Moonwalk_Exit cmpwi r3,ASID_SquatWait beq Moonwalk_Exit #Ensure player came from aerial attack landing or special move CheckForAerial: lhz r3,TM_TwoASAgo(playerdata) cmpwi r3,ASID_AttackAirN blt CheckForSpecialMove cmpwi r3,ASID_AttackAirLw bgt CheckForSpecialMove b LandingSearch CheckForSpecialMove: cmpwi r3,ASID_BarrelCannonWait ble Moonwalk_Exit LandingSearch: #Calculate Frames Since Wait and Get AS Before Wait li r5,0 #Loop Count li r4,TM_PrevASStart LandingSearchLoop: mulli r3,r5,0x2 add r3,r3,r4 lhzx r3,r3,playerdata cmpwi r3,ASID_Landing beq LandingSearchExit addi r5,r5,1 cmpwi r5,6 bge Moonwalk_Exit b LandingSearchLoop LandingSearchExit: #Get AS Before Wait addi r3,r5,1 mulli r3,r3,0x2 add r3,r3,r4 lhzx ASBeforeLanding,r3,playerdata #Get Frames In Wait li r4,TM_FramesInPrevASStart #Frame Count Start li FramesSince,0 #Init Frame Count FrameCountLoop: cmpwi r5,0 beq FrameCountLoopFinish mulli r3,r5,0x2 add r3,r3,r4 lhzx r3,r3,playerdata add FramesSince,r3,FramesSince subi r5,r5,1 b FrameCountLoop FrameCountLoopFinish: lhz r3,TM_FramesInPrevASStart(playerdata) #Frames spent in Wait add FramesSince,r3,FramesSince #Get Total Frames Since #Minus in-actionable frames lfs f1, 0x01F4 (playerdata) fctiwz f1,f1 stfd f1,0xB0(sp) lwz r3,0xB4(sp) sub FramesSince,FramesSince,r3 #Change Text Color cmpwi FramesSince,0x0 bne RedText GreenText: load r3,0x8dff6eff #green b StoreTextColor RedText: load r3,0xffa2baff StoreTextColor: stw r3,0x80(sp) #Create Text li r3,5 #Message Kind lbz r4,0xC(playerdata) #Message Queue li r5,MSGCOLOR_WHITE bl Text mflr r6 addi r7,FramesSince,1 Message_Display ChangeColor: lwz r3,0x2C(r3) lwz r3,MsgData_Text(r3) li r4,1 addi r5,sp,0x80 branchl r12,Text_ChangeTextColor b Moonwalk_Exit ################### ## TEXT CONTENTS ## ################### Text: blrl .string "Act OoAutoCancel\nFrame: %d" .align 2 ############################## Moonwalk_Exit: restoreall lwz r0, 0x002C (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Act OoWait/Act OoWait - From Wait.asm ================================================ #To be inserted at 8008A630 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,30 .set player,31 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall #Check If Interrupted cmpwi r3,0x0 beq Moonwalk_Exit #Get Playerdata lwz playerdata,0x2C(player) #Ensure I'm Actually Coming from Wait (Wait interrupt is used for certain IASA) lhz r3,TM_OneASAgo(playerdata) cmpwi r3,0xE bne Moonwalk_Exit #Make Sure Player Didn't Buffer Crouch, Shield, or Walk lwz r3,0x10(playerdata) cmpwi r3,0xF beq Moonwalk_Exit cmpwi r3,0x10 beq Moonwalk_Exit cmpwi r3,0x11 beq Moonwalk_Exit cmpwi r3,0x27 beq Moonwalk_Exit cmpwi r3,0xB2 beq Moonwalk_Exit cmpwi r3,ASID_SquatWait beq Moonwalk_Exit #Check To Display OSD mr r3,r31 branchl r12,0x8000551c Moonwalk_Exit: restoreall lwz r0, 0x001C (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Additional Playerblock Variables/Fastfall Timer/Display FF Timing.asm ================================================ #To be inserted at 8007d57c .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set REG_FighterData,31 .set player,30 .set REG_TextColor,29 .set REG_Text,28 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall mr REG_FighterData,r3 #CHECK IF ENABLED li r0,OSD.Fastfall #PowerShield ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit CheckForFollower: mr r3,REG_FighterData branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit #Check If Falling Off Ledge and Respawn Platform lhz r3,TM_OneASAgo(REG_FighterData) # cmpwi r3,0xFD #CliffWait # beq Moonwalk_Exit cmpwi r3,0xD #RebirthWait beq Moonwalk_Exit PrintMessage: li r3,7 #Message Kind lbz r4,0xC(REG_FighterData) #Message Queue li r5,MSGCOLOR_WHITE bl Fastfall_String mflr r6 lhz r7,TM_CanFastfallFrameCount(REG_FighterData) Message_Display lwz r3,0x2C(r3) lwz REG_Text,MsgData_Text(r3) #Check if frame 1 lhz r3,TM_CanFastfallFrameCount(REG_FighterData) cmpwi r3,1 bne Moonwalk_Exit mr r3,REG_Text li r4,1 bl Colors mflr r5 branchl r12,Text_ChangeTextColor b Moonwalk_Exit ################### ## TEXT CONTENTS ## ################### Fastfall_String: blrl .string "Fastfall\nFrame %d" .align 2 Colors: blrl .long 0x8dff6eff #green ############################## Moonwalk_Exit: restoreall li r0, 1 ================================================ FILE: ASM/training-mode/Onscreen Display/Additional Playerblock Variables/Fastfall Timer/Increment Fastfall Variable.asm ================================================ #To be inserted at 8007d550 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set player,31 .set Text,30 .set TextProp,29 #Increment FastFall Variable lhz r6,TM_CanFastfallFrameCount(r3) addi r6,r6,0x1 sth r6,TM_CanFastfallFrameCount(r3) #Original Codeline lwz r6, -0x514C (r13) ================================================ FILE: ASM/training-mode/Onscreen Display/Additional Playerblock Variables/Fastfall Timer/Initialize Fastfall Variable.asm ================================================ #To be inserted at 800698c8 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set player,31 .set Text,30 .set TextProp,29 #Store IsFastFalling Bit (Original Line) stb r0, 0x221A (r26) #Initialize FastFall Variable li r0,0 sth r0,TM_CanFastfallFrameCount(r26) ================================================ FILE: ASM/training-mode/Onscreen Display/Additional Playerblock Variables/Frame Advantage/Initialize Frame Advantage Think.asm ================================================ #To be inserted at 80092e68 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set REG_FighterData,30 .set player,31 .set text,29 .set actionableFlag,28 .set hitbool,27 .set REG_FrameAdvantage,26 .set REG_TextColor,25 ############################## ## Init FrameAdvantageThink ## ############################## #CHECK IF ENABLED li r0,OSD.FrameAdvantage #PowerShield ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4, 0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq InjectionExit #Check If Entity That Hit Shield Was a Player lwz r3, 0x002C (r30) lwz r3, 0x19A8 (r3) branchl r12,0x80086960 cmpwi r3,0x0 beq InjectionExit #Store Pointer to Frame Advantage Think bl FrameAdvantageThink mflr r3 lwz r4, 0x002C (r30) lwz r4, 0x19A8 (r4) lwz r4, 0x002C (r4) stw r3, TM_AnimCallback (r4) b InjectionExit ########################### ## Frame Advantage Think ## ########################### FrameAdvantageThink: blrl .set REG_VictimData, 20 backup mr player,r3 lwz REG_FighterData,0x2c(player) #Get Entity Who Shielded Attack lwz REG_VictimData,TM_PlayerWhoShieldedAttack(REG_FighterData) #Self Destruct If Player was Hit or Grabbed #Check Hitstun lbz r3, 0x221C (REG_FighterData) rlwinm. r0, r3, 31, 31, 31 bne SelfDestruct #Check Grabbed AS's lwz r3,0x10(REG_FighterData) cmpwi r3,0xDF blt SkipGrabCheck cmpwi r3,0xE8 bgt SkipGrabCheck b SelfDestruct SkipGrabCheck: #Check If ShieldStun Ended #lwz r3,0x10(REG_VictimData) #cmpwi r3,0xB5 #beq Moonwalk_Exit ######################### ## Check If Actionable ## ######################### #Am I in Non-IASA Landing? lwz r3,0x10 (REG_FighterData) cmpwi r3,0x2A bne SkipIASALandingCheck lfs f1, 0x0894 (REG_FighterData) lfs f0, 0x01F4 (REG_FighterData) fcmpo cr0,f1,f0 bge Actionable SkipIASALandingCheck: #Check For Any Form of Jumping/Falling cmpwi r3,0x19 blt SkipJumpFallCheck cmpwi r3,0x22 bgt SkipJumpFallCheck b Actionable SkipJumpFallCheck: #Check For AS Wait cmpwi r3,0xE beq Actionable #Check For AS CrouchWait cmpwi r3,0x28 beq Actionable #Check For Peach Float lwz r4,0x4(REG_FighterData) cmpwi r4,0x9 bne SkipPeachFloat cmpwi r3,0x155 beq Actionable SkipPeachFloat: ########################### ## Check For IASA States ## ########################### #Check Jabs Tilts Aerials Smash Attacks cmpwi r3,0x2C blt SkipAttackCheck cmpwi r3,0x45 bgt SkipAttackCheck b CheckIASA SkipAttackCheck: #Check Throws cmpwi r3,0xDB blt SkipThrowCheck cmpwi r3,0xDE bgt SkipThrowCheck b CheckIASA SkipThrowCheck: b Moonwalk_Exit ######################### ## Check for IASA Flag ## ######################### CheckIASA: lbz r3,0x2218(REG_FighterData) rlwinm. r3,r3,0,24,24 beq Moonwalk_Exit ########################## ## Get Frame Advantages ## ########################## Actionable: #Check If Still in ShieldStun lwz r3,0x10(REG_VictimData) cmpwi r3,0xB5 bne CheckFramesPassed #################################### ## Get Frames of Shield Stun Left ## #################################### #Check Frames Left of Shield Stun lwz r3,0x590(REG_VictimData) #get anim data lfs f1,0x008(r3) #get anim length (float) lfs f2,0x89C(REG_VictimData) #get anim speed lfs f3,0x894(REG_VictimData) #get current AS fdivs f4,f1,f2 #get calculated AS length in f4 fdivs f1,f3,f1 #yields percentage of animation finished fmuls f1,f4,f1 #(DEFINED_LENGTH)*(PERCENTAGE) fsubs f3,f4,f1 #SUBTRACT FROM DEFINED ConvertASFrameToInt: #ROUND APPROX FRAMES LEFT UP #GET FRAME NUMBER IN F1 WITHOUT DECIMAL POINT fctiwz f1,f3 stfd f1,0xF0(sp) lwz r3,0xF4(sp) xoris r4,r3,0x8000 lis r5,0x4330 stw r5,0xF0(sp) stw r4,0xF4(sp) lfd f1,0xF0(sp) lfd f2,-0x7470(rtoc) #load magic number fsubs f1,f1,f2 #SUBTRACT ROUNDED DOWN NUMBER FROM ORIGINAL TO GET DECIMAL POINT fsubs f1,f3,f1 lfs f2, -0x6B00 (rtoc) #get 0 float #CHECK IF GREATER THAN 0.0 fcmpo cr0,f1,f2 beq RoundDown RoundUp: addi r5,r3,0x1 b SubFrameCount RoundDown: mr r5,r3 SubFrameCount: subi REG_FrameAdvantage,r5,0x1 #backup frame number b CreateTextGObj ######################################## ## Get Frames Since Shield Stun Ended ## ######################################## CheckFramesPassed: #Check How Long Since Opponent's Shield Stun Ended #Search For Shield Stun In Opponent's Previous Actions li r5,0 #loop count init addi r4,REG_VictimData,TM_PrevASStart #Beginning of Prev Actions subi r4,r4,0x2 #Adjust for lhzu instruction ShieldStunSearchLoop: lhzu r3,0x2(r4) #Get AS cmpwi r3,0xB5 #Is this shield stun? beq ShieldStunFound addi r5,r5,1 cmpwi r5,6 #6 Total Prev Actions bgt SelfDestruct #Self Destruct if not Found b ShieldStunSearchLoop ShieldStunFound: li REG_FrameAdvantage,0 #total frame count init addi r4,REG_VictimData,TM_FramesInPrevASStart #Beginning of Prev AS Frames subi r4,r4,0x2 #Adjust for lhzu instruction ShieldStunFrameCountLoop: cmpwi r5,0 #Check If Done ble ShieldStunAddCurrentAS lhzu r3,0x2(r4) #Get Frame Count sub REG_FrameAdvantage,REG_FrameAdvantage,r3 #Add to Total subi r5,r5,1 b ShieldStunFrameCountLoop ShieldStunAddCurrentAS: lhz r3,TM_FramesinCurrentAS(REG_VictimData) #Add Current AS's Frame Count as Well sub REG_FrameAdvantage,REG_FrameAdvantage,r3 CreateTextGObj: #Check if frame 1 cmpwi REG_FrameAdvantage,-6 blt WhiteText GreenText: li REG_TextColor,MSGCOLOR_GREEN b PrintMessage WhiteText: li REG_TextColor,MSGCOLOR_WHITE b PrintMessage PrintMessage: li r3,6 #Message Kind lbz r4,0xC(REG_FighterData) #Message Queue mr r5,REG_TextColor bl FrameAdvantage_String mflr r6 mr r7,REG_FrameAdvantage Message_Display #Self Destruct SelfDestruct: li r3,0 stw r3,TM_AnimCallback(REG_FighterData) #Exit b Moonwalk_Exit ################### ## TEXT CONTENTS ## ################### FrameAdvantage_String: blrl .string "Frame Advantage\n%d Frames" .align 2 ############################## Moonwalk_Exit: restore blr ############################################################################ InjectionExit: lwz r3, 0x002C (r30) ================================================ FILE: ASM/training-mode/Onscreen Display/Additional Playerblock Variables/Frame Advantage/Save Pointer to Shield Owner On Hit.asm ================================================ #To be inserted at 80076eac .include "../../../Globals.s" .include "../../../../m-ex/Header.s" ################################# ## On Hitbox->Shield Collision ## ################################# #Store Pointer to Player Whose Shield Was Hit stw r31,TM_PlayerWhoShieldedAttack(r29) InjectionExit: lfs f1, 0x19B4 (r31) ================================================ FILE: ASM/training-mode/Onscreen Display/Additional Playerblock Variables/Previous Move Instance Hit By/Backup Previous Move Instance Player was Hit By.asm ================================================ #To be inserted at 8003820c .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 #Backup Previous Move Instance ID lhz r3,0x18EC(r25) sth r3,0x2418(r25) #Original Line rlwinm. r3, r27, 0, 16, 31 ================================================ FILE: ASM/training-mode/Onscreen Display/Additional Playerblock Variables/StatesAndTimers/IncFrameCounts.asm ================================================ #To be inserted at 8006ab78 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" # Inc Frame Count + Frames Tangible + Hitstun #Don't Run During Hitlag lbz r0, 0x2219 (r31) rlwinm. r0, r0, 30, 31, 31 bne exit ######################## ## Increment AS Frame ## ######################## lhz r3,TM_FramesinCurrentAS(r31) addi r3,r3,0x1 sth r3,TM_FramesinCurrentAS(r31) ################################## ## Increment Tangibility Frames ## ################################## #Check Timer Intangible Count lwz r3,0x1990(r31) cmpwi r3,0x0 bgt IsIntangible #Ensure Player Had Ledge Intang FIRST lhz r3,TM_TangibleFrameCount(r31) cmpwi r3,0x0 bne IncTangibleFrames #Check For Subaction Intang lwz r3,0x1988(r31) cmpwi r3,0x2 bne IncTangibleFrames #Set Tangible Frames to 0 When Player Has Intangibility IsIntangible: li r3,0x0 sth r3,TM_TangibleFrameCount(r31) #Store Tangible Frame Count b Tangible_End IncTangibleFrames: lhz r3,TM_TangibleFrameCount(r31) addi r3,r3,0x1 sth r3,TM_TangibleFrameCount(r31) Tangible_End: exit: mr r3, r30 ================================================ FILE: ASM/training-mode/Onscreen Display/Additional Playerblock Variables/StatesAndTimers/ShiftStates.asm ================================================ #To be inserted at 800693ec .include "../../../Globals.s" .include "../../../../m-ex/Header.s" # Store Previous AS + Reset AS Frame Count Timer ################### ## Shift AS ID's ## ################### #SHIFT AS ID's li r12,TM_PrevASSlots-2 #Loop Count ASLoop: addi r3,r26,TM_PrevASStart #Get Start of AS List mulli r4,r12,2 #Current AS ID * Length add r4,r3,r4 #Get AS Offset in Playerblock lhz r3,0x0(r4) #Load Previous AS sth r3,0x2(r4) #Push Back ASIncLoop: subi r12,r12,1 cmpwi r12,0x0 bge ASLoop #Move Current AS To Last AS lwz r3,0x10(r26) #get action state that we just left sth r3,TM_PrevASStart(r26) #store as last action state ######################### ## SHIFT FRAME NUMBERS ## ######################### #SHIFT AS Frame #'s li r12,TM_PrevASSlots-2 #Loop Count FrameCountLoop: addi r3,r26,TM_FramesInPrevASStart #Get to the Start of the Frame Counts mulli r4,r12,2 #Current AS ID * Length add r4,r3,r4 #Get AS Offset in Playerblock lhz r3,0x0(r4) #Load Previous AS sth r3,0x2(r4) #Push up FrameCountIncLoop: subi r12,r12,1 cmpwi r12,0x0 bge FrameCountLoop #Move Current AS Frame To Last AS Frame addi r3,r26,TM_FramesInPrevASStart #Get to the Start of the Frame Counts lhz r4,TM_FramesinCurrentAS(r26) #Get AS Frame Number we Just Left sth r4,0x0(r3) ########################################### ## Init Current AS Frame To Int Variable ## ########################################### #lfs f1,0x894(r26) #fctiwz f1,f1 #stfd f1,0x8(sp) #lwz r3,0xC(sp) li r3,0x0 sth r3,TM_FramesinCurrentAS(r26) exit: cmplwi r27, 0 ================================================ FILE: ASM/training-mode/Onscreen Display/Check For IC's Static Function.asm ================================================ #To be inserted at 80005510 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set TextCreateFunction,0x80005928 .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 backup mr r31,r3 #Get Byte lbz r3, 0x221F (playerdata) #Check If Subchar rlwinm. r0, r3, 29, 31, 31 beq NoFollower #Check If Follower lbz r3,0xC(playerdata) #get slot branchl r12,0x80032330 #get external character ID load r4,0x803bcde0 #pdLoadCommonData table mulli r0, r3, 3 #struct length add r3,r4,r0 #get characters entry lbz r0, 0x2 (r3) #get subchar functionality cmpwi r0,0x0 #if not a follower, exit bne NoFollower Follower: li r3,0x1 b 0x8 NoFollower: li r3,0x0 Moonwalk_Exit: restore blr ================================================ FILE: ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Custom Function Blrl + Keep Combo Counter Going For Missed Techs+Getups.asm ================================================ #To be inserted at 8006ab88 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set actionableFlag,28 .set hitbool,27 #Check For Function Pointer lwz r12,TM_AnimCallback(r31) cmpwi r12,0x0 beq SkipFunctionBlrl mtlr r12 addi r3, r30, 0 blrl SkipFunctionBlrl: ################################# ## Check To End Combo Progress ## ################################# #Check Hitstun lbz r0, 0x221C (r31) rlwinm. r0, r0, 31, 31, 31 bne InjectionExit #Am I in Missfoot? lwz r3,0x10(playerdata) cmpwi r3,0xFB beq InjectionExit #Am I in Non-IASA Landing? cmpwi r3,0x2A bne SkipIASALandingCheck lfs f1, 0x0894 (playerdata) lfs f0, 0x01F4 (playerdata) fcmpo cr0,f1,f0 blt InjectionExit SkipIASALandingCheck: #Am I in Missed Tech, Tech Roll, Slow Getup, Or Getup Attack lwz r0,0x10(playerdata) cmpwi r0,0xB7 blt EndCombo cmpwi r0,0xC9 bgt CheckGrab b InjectionExit CheckGrab: cmpwi r0,0xDF blt EndCombo cmpwi r0,0xE8 bgt CheckThrow b InjectionExit CheckThrow: cmpwi r0,0xEF blt EndCombo cmpwi r0,0xF3 bgt CheckSpecialThrows b InjectionExit CheckSpecialThrows: cmpwi r0,0x10A blt EndCombo cmpwi r0,0x130 bgt EndCombo b InjectionExit EndCombo: lbz r3, 0x000C (r31) lbz r4, 0x221F (r31) rlwinm r4, r4, 29, 31, 31 branchl r12,0x800411c4 InjectionExit: lwz r0, 0x0034 (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Disregard Projectile Hitboxes w Same Move ID.asm ================================================ #To be inserted at 800789e0 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" #r31 = Projectile Data #r30 = Victim GObj #Check If Same Move ID as Last Hit lwz r3,0x2C(r30) lhz r3,0x18EC(r3) #Last Move Instance Victim Was Hit By lhz r4,0xDA8(r31) #Attacking Player's Current Move Instance cmpw r3,r4 beq SkipComboIncrement b Exit SkipComboIncrement: branch r12,0x80078a10 Exit: lwz r3, 0x0518 (r31) ================================================ FILE: ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Disregard Throw Hitboxes.asm.bak ================================================ #To be inserted at 80078950 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" #Original Line lwz r7, 0x002C (r30) #Check if this is a Pummel lwz r3,0x10(r7) cmpwi r3,0xD9 beq Exit #Allow for Cliff Attacks cmpwi r3,0x100 beq Exit cmpwi r3,0x101 beq Exit #Check If Attacker Is Grabbable (Attacker is Set Grabbable When the Throw Releases the Victim) lhz r3,0x1A6A(r7) #Grabbable Flag cmpwi r3,0x0 bne SkipComboIncrement #Check If Attacker Is Throwing, Allow Combo Inc lwz r3,0x10(r7) cmpwi r3,0xDB blt SkipThrowCheck cmpwi r3,0xDE bgt SkipThrowCheck b Exit SkipThrowCheck: #Check If Same Move ID as Last Hit #lwz r3,0x2C(r31) #lhz r3,0x18EC(r3) #Last Move Instance Victim Was Hit By #lhz r4,0x2088(r7) #Attacking Player's Current Move Instance #cmpw r3,r4 #beq SkipComboIncrement b Exit SkipComboIncrement: branch r12,0x8007897c Exit: ================================================ FILE: ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Interrupting Move with Same Move Gives a Unique ID.asm ================================================ #To be inserted at 80089610 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" #Check If Move Was Interrupted With the Same Move lwz r3,0x10(r26) #New Move lhz r4,TM_OneASAgo(r26) #Previous Moe cmpw r3,r4 bne Original #Interrupted move with same move, assign unique move ID branch r12,0x8008961c Original: lbz r0, 0x2073 (r31) ================================================ FILE: ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Keep Combo Counter Going For Missed Techs+Getups.asm ================================================ #To be inserted at 8006ab48 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set player,31 .set playerdata,31 #Am I in Hitstun? (Ran prior to the injection) #Am I in Missfoot? lwz r3,0x10(playerdata) cmpwi r3,0xFB beq ContinueCombo #Am I in Non-IASA Landing? cmpwi r3,0x2A bne SkipIASALandingCheck lfs f1, 0x0894 (playerdata) lfs f0, 0x01F4 (playerdata) fcmpo cr0,f1,f0 blt ContinueCombo SkipIASALandingCheck: #Am I in Missed Tech, Tech Roll, Slow Getup, Or Getup Attack lwz r0,0x10(playerdata) cmpwi r0,0xB7 blt EndCombo cmpwi r0,0xC9 bgt CheckGrab b ContinueCombo CheckGrab: cmpwi r0,0xDF blt EndCombo cmpwi r0,0xE8 bgt CheckThrow b ContinueCombo CheckThrow: cmpwi r0,0xEF blt EndCombo cmpwi r0,0xF3 bgt CheckSpecialThrows b ContinueCombo CheckSpecialThrows: cmpwi r0,0x10A blt EndCombo cmpwi r0,0x130 bgt EndCombo b ContinueCombo ContinueCombo: branch r12,0x8006ab58 EndCombo: lbz r4, 0x221F (r31) ================================================ FILE: ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Pummels and Multi-Hits Increment Total Damage But Not Combo Counter.asm ================================================ #To be inserted at 80040f04 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set player,31 .set playerdata,31 #r27 = Attacker Slot #r28 = Victim Slot #r5 = Attacker #r6 = Victim #This injection makes the Pummel Move ID skip the combo count increment. Originally only 5 moves perform this behavior, pummel not being one of them. #Get Attacker Pointer mr r3,r27 branchl r12,0x80034110 lwz r5,0x2C(r3) #Get Victim Pointer mr r3,r28 branchl r12,0x80034110 lwz r6,0x2C(r3) ###################### ## Check For Pummel ## ###################### cmpwi r30,0x34 beq NoComboInc ################################# ## Check For Same Move as Last ## ################################# SameMoveCheck: lhz r3,0x18EC(r6) #Last Move Instance Victim Was Hit By lhz r4,0x2088(r5) #Attacking Player's Current Move Instance cmpw r3,r4 bne SkipSameMoveCheck #Check If Its a Throw cmpwi r30,0x35 blt NoComboInc cmpwi r30,0x38 bgt NoComboInc #Check If Attacker Is Grabbable (Attacker is Set Grabbable When the Throw Releases the Victim) lhz r3,0x1A6A(r5) #Grabbable Flag cmpwi r3,0x0 bne NoComboInc b Original SkipSameMoveCheck: ################################ ## Check For MidGrab Hitboxes ## ################################ #Allow Cliff Attacks cmpwi r30,0x3F beq Original cmpwi r30,0x3E beq Original #Check If Attacker Is Grabbable (Attacker is Set Grabbable When the Throw Releases the Victim) lhz r3,0x1A6A(r5) #Grabbable Flag cmpwi r3,0x0 bne NoComboInc b Original NoComboInc: #Spoof Pummel as Some Other Move that Triggers the Check li r30,76 Original: addi r3, r28, 0 ================================================ FILE: ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Skip Original Combo End Check.asm ================================================ #To be inserted at 8006ab44 b 0x14 ================================================ FILE: ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Throw Hitboxes Update (Last Damage Source) Variable in Playerblock.asm ================================================ #To be inserted at 800dde68 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set player,31 .set playerdata,31 #Store/Update Last Damage Source For Victim stw r24,0x1868(r30) Exit: #Original Line lwz r0, 0x1988 (r30) ================================================ FILE: ASM/training-mode/Onscreen Display/Combo Counter/Combo Counter - On Combo Increment.asm ================================================ #To be inserted at 80040fa4 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set ComboCount,28 .set hitbool,27 .set MessageAreaLength,0x100 .set PerPlayerMessageStructLength,0x28 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backup #Backup Combo Count lhz ComboCount,0x14(r3) #CHECK IF ENABLED li r0,OSD.ComboCounter #PowerShield ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit #Get Playerdata mr r3,r27 branchl r12,0x80034110 mr player,r3 lwz playerdata,0x2C(player) CheckForFollower: mr r3,playerdata branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit #Check If Combo Count is 2 Hits or Higher cmpwi ComboCount,2 blt Moonwalk_Exit bl CreateText #Create Text bl TopText mr r3,r29 #text pointer mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,0x803a6b98 #Get Damage as Int lbz r3,0xC(playerdata) branchl r12,0x80041300 mr r6,r3 #Create Text2 bl BottomText mr r3,r29 #text pointer mflr r4 mr r5,ComboCount lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis branchl r12,0x803a6b98 #Store Per Frame Function to Monitor When Hitstun Runs Out lwz r3,0x2094(playerdata) #Check If Valid Player GObj branchl r12,0x80086960 cmpwi r3,0 beq Moonwalk_Exit #Store Function bl HitstunMonitor mflr r3 lwz r4,0x2094(playerdata) lwz r4,0x2C(r4) stw r3,TM_AnimCallback(r4) b Moonwalk_Exit CreateText: mflr r0 stw r0, 0x0004 (sp) stwu sp, -0x0008 (sp) mr r3,playerdata #backup playerdata pointer li r4,120 #display until terminated li r5,0 #Area to Display (0-2) li r6,13 #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr text,r3 #backup text pointer lwz r0, 0x000C (sp) addi sp, sp, 8 mtlr r0 blr ################### ## TEXT CONTENTS ## ################### TopText: blrl .string "Combo Count" .align 2 BottomText: blrl .string "%d Hits / %d%" .align 2 /* .long 0x25642048 .long 0x69747320 .long 0x815e2025 .long 0x64819300 */ ############################## HitstunMonitor: blrl backup #Get Pointers mr player,r3 lwz playerdata,0x2C(player) #Get Damage Source (Person Combo'ing Me) lwz r3,0x1868(playerdata) #Ensure It's a Player branchl r12,0x80086960 cmpwi r3,0x0 beq HitstunMonitor_SelfDestruct lwz r28,0x1868(playerdata) lwz r28,0x2C(r28) #Save For Later #Check If Combo Has Ended #Am I in Hitstun? lbz r0, 0x221C (playerdata) rlwinm. r0, r0, 31, 31, 31 bne HitstunMonitor_ContinueCombo #Am I in Missfoot? lwz r3,0x10(playerdata) cmpwi r3,0xFB beq HitstunMonitor_ContinueCombo #Am I in Non-IASA Landing? cmpwi r3,0x2A bne HitstunMonitor_SkipIASALandingCheck lfs f1, 0x0894 (playerdata) lfs f0, 0x01F4 (playerdata) fcmpo cr0,f1,f0 blt HitstunMonitor_ContinueCombo HitstunMonitor_SkipIASALandingCheck: #Am I in Missed Tech, Tech Roll, Slow Getup, Or Getup Attack lwz r0,0x10(playerdata) cmpwi r0,0xB7 blt HitstunMonitor_EndCombo cmpwi r0,0xC9 bgt HitstunMonitor_CheckGrab b HitstunMonitor_ContinueCombo HitstunMonitor_CheckGrab: cmpwi r0,0xDF blt HitstunMonitor_EndCombo cmpwi r0,0xE8 bgt HitstunMonitor_CheckThrow b HitstunMonitor_ContinueCombo HitstunMonitor_CheckThrow: cmpwi r0,0xEF blt HitstunMonitor_EndCombo cmpwi r0,0xF3 bgt HitstunMonitor_CheckSpecialThrows b HitstunMonitor_ContinueCombo HitstunMonitor_CheckSpecialThrows: cmpwi r0,0x10A blt HitstunMonitor_EndCombo cmpwi r0,0x130 bgt HitstunMonitor_EndCombo b HitstunMonitor_ContinueCombo HitstunMonitor_EndCombo: #Find MessageBox Pointer #Get Player's Message Struct in r29 load r3,0x804a1f58 lwz r29,0x4(r3) lbz r3,0xC(r28) mulli r4,r3,PerPlayerMessageStructLength add r29,r29,r4 #Init Search Loop li r27,0 HitstunMonitor_SearchLoop: mulli r3,r27,8 add r3,r3,r29 lhz r4,0x6(r3) #Get OSD ID cmpwi r4,13 beq HitstunMonitor_EditOSD addi r27,r27,1 cmpwi r27,4 ble HitstunMonitor_SearchLoop #OSD Not Found, Self Destruct b HitstunMonitor_SelfDestruct HitstunMonitor_EditOSD: mr r26,r3 #Backup OSD Info #Set Time To Expire li r3,60 sth r3,0x4(r26) #Get Green On Stack load r3,0x8dff6eff stw r3,0xF0(sp) #Change Subtext's Colors lwz r3,0x0(r26) li r4,1 addi r5,sp,0xF0 branchl r12,0x803a74f0 lwz r3,0x0(r26) li r4,2 addi r5,sp,0xF0 branchl r12,0x803a74f0 HitstunMonitor_SelfDestruct: li r3,0 stw r3,TM_AnimCallback(playerdata) HitstunMonitor_ContinueCombo: HitstunMonitor_Exit: restore blr ############################## Moonwalk_Exit: restore lmw r27, 0x0024 (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Dashback/Dashback Display - Static Function.asm ================================================ #To be inserted at 80005518 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set REG_FighterData,31 .set player,30 .set REG_DBBool, 29 .set REG_String, 28 .set REG_DBRate,27 .set REG_TextColor,26 .set REG_Text,25 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall mr player,r3 lwz REG_FighterData,0x2C(player) mr REG_DBBool,r4 #Dashback Bool #CHECK IF ENABLED li r0,OSD.Dashback #wavedash ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit CheckForFollower: mr r3,REG_FighterData branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit #Change color to Green if frame perfect act oos cmpwi REG_DBBool,0x0 beq FailedDB #Check If UCF DB or Vanilla DB lwz r3,0x2350(REG_FighterData) #get turn flag cmpwi r3,0x0 #if 0, was a smash turn bne UCFDB VanillaDB: mr r3,REG_FighterData bl IncDBRate mr REG_DBRate,r3 bl DBVanilla_String mflr REG_String li REG_TextColor,MSGCOLOR_GREEN b PrintMessage UCFDB: mr r3,REG_FighterData bl IncDBRate mr REG_DBRate,r3 bl DBUCF_String mflr REG_String li REG_TextColor,MSGCOLOR_YELLOW b PrintMessage FailedDB: mr r3,REG_FighterData bl DecDBRate mr REG_DBRate,r3 bl DBFailed_String mflr REG_String li REG_TextColor,MSGCOLOR_RED b PrintMessage PrintMessage: li r3,4 #Message Kind lbz r4,0xC(REG_FighterData) #Message Queue li r5,MSGCOLOR_WHITE mr r6,REG_String mr r7,REG_DBRate Message_Display lwz r3,0x2C(r3) lwz REG_Text,MsgData_Text(r3) # adjust top line color bl Colors mflr r3 cmpwi REG_TextColor,MSGCOLOR_GREEN beq GreenText cmpwi REG_TextColor,MSGCOLOR_RED beq RedText YellowText: addi r5,r3,0x4 b ChangeColor GreenText: addi r5,r3,0x0 b ChangeColor RedText: addi r5,r3,0x8 b ChangeColor ChangeColor: mr r3,REG_Text li r4,0 branchl r12,Text_ChangeTextColor b Moonwalk_Exit ######################### ### DB Rate Functions ### ######################### IncDBRate: stwu r1,-0x100(r1) # make space for 12 registers mflr r0 stw r0,0xFC(sp) lbz r3,0xC(r3) #get player slot load r4,0x804a1fc8 #get DB rate mem location mulli r3,r3,0x4 #length of players DB info add r8,r3,r4 #players DB info in r8 lhz r3,0x0(r8) #successful DBs addi r3,r3,0x1 sth r3,0x0(r8) #successful DBs lhz r3,0x2(r8) #total DBs addi r3,r3,0x1 sth r3,0x2(r8) #total DBs mr r3,r8 bl GetDBRate lwz r0,0xFC(sp) mtlr r0 addi r1,r1,0x100 # release the space blr DecDBRate: stwu r1,-0x100(r1) # make space for 12 registers mflr r0 stw r0,0xFC(sp) lbz r3,0xC(r3) #get player slot load r4,0x804a1fc8 #get DB rate mem location mulli r3,r3,0x4 #length of players DB info add r8,r3,r4 #players DB info in r8 lhz r3,0x2(r8) #total DBs addi r3,r3,0x1 sth r3,0x2(r8) #total DBs mr r3,r8 bl GetDBRate lwz r0,0xFC(sp) mtlr r0 addi r1,r1,0x100 # release the space blr GetDBRate: #Get Values lhz r4,0x0(r3) #successful DBs lhz r5,0x2(r3) #total DBs #Get as Floats (f1 = successful, f2 = total lis r0, 0x4330 lfd f5, -0x6758 (rtoc) xoris r6, r4, 0x8000 xoris r7, r5, 0x8000 stw r0,0xF0(sp) #Successful DB stw r6,0xF4(sp) lfd f1,0xF0(sp) fsubs f1,f1,f5 #Total DB stw r7,0xF4(sp) lfd f2,0xF0(sp) fsubs f2,f2,f5 #100f li r4,100 xoris r4,r4,0x8000 stw r4,0xF4(sp) lfd f3,0xF0(sp) fsubs f3,f3,f5 fdivs f1,f1,f2 #successful DB / total DB fmuls f1,f1,f3 #times 100 #Back to Int fctiwz f1,f1 stfd f1,0xF0(sp) lwz r3,0xF4(sp) blr ################### ## TEXT CONTENTS ## ################### DBVanilla_String: blrl .string "Vanilla Dashback\nSuccession: %d%" .align 2 DBUCF_String: blrl .string "UCF Dashback\nSuccession: %d%" .align 2 DBFailed_String: blrl .string "Failed Dashback\nSuccession: %d%" .align 2 Colors: blrl .long 0x8dff6eff #green .long 0xfff000ff #yellow .byte 255, 162, 186, 255 #red ############################## Moonwalk_Exit: restoreall blr ================================================ FILE: ASM/training-mode/Onscreen Display/Dashback/Grab Out of Tilt Turn.asm.bak ================================================ #To be inserted at 800c9b38 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall #Check If Jumped cmpwi r3,0x0 beq Moonwalk_Exit #Check If Dashed Back (Flag at 0x2340) mr r3,player mr r4,r20 branchl r12,0x80005518 Moonwalk_Exit: restoreall cmpwi r3,0x0 cmpwi r20, 0 ================================================ FILE: ASM/training-mode/Onscreen Display/Dashback/Run Out of Tilt Turn.asm ================================================ #To be inserted at 800c9b88 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall #Ensure NOT Coming From Dash or Crouch lhz r3,TM_OneASAgo(playerdata) #load last AS cmpwi r3,0x14 beq Moonwalk_Exit cmpwi r3,0x28 beq Moonwalk_Exit #Check If Dashed Back (Flag at 0x2340) mr r3,player lhz r4,0x894(playerdata) cmpwi r4,0x4000 beq 0xC li r4,0x0 b 0x8 li r4,0x1 branchl r12,0x80005518 Moonwalk_Exit: restoreall mr r3,r30 li r4,0x0 ================================================ FILE: ASM/training-mode/Onscreen Display/Fox Training Codes/Side B Shorten Display.asm ================================================ #To be inserted at 8006b7f4 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall #General AS's #Check If Fox or Falco lwz r3,0x4(playerdata) cmpwi r3,0x1 beq FoxFalco cmpwi r3,0x16 beq FoxFalco #Check If Anyone Else b Moonwalk_Exit #///////////////////////////////////////////////////////////////////////////// FoxFalco: #CHECK IF ENABLED li r0,OSD.SpacieTech #Fox Training Codes ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit #Branch to AS Functions lwz r3,0x10(playerdata) cmpwi r3,0x15B #Ground Side B Start beq Fox_SideBStart cmpwi r3,0x15E #Air Side B Start beq Fox_SideBStart cmpwi r3,0x15C #Ground Side B beq Fox_SideB cmpwi r3,0x15F #Air Side B beq Fox_SideB cmpwi r3,0x15D #Ground Side B End beq Fox_SideBEnd cmpwi r3,0x160 #Air Side B End beq Fox_SideBEnd cmpwi r3,0x169 beq Fox_ShineGroundLoop cmpwi r3,0x16E beq Fox_ShineAirLoop b Moonwalk_Exit #///////////////////////////////////////////////////////////////////////////// Fox_SideBStart: #Check If Pressed B lwz r3,0x668(playerdata) rlwinm. r3,r3,0,22,22 beq Fox_SideBStart_NoPress #Create Text bl CreateText mr text,r3 #backup text pointer #Change Text Color load r3,0xffa2baff stw r3,0x30(text) #Create Top Line bl ShortenPress #Create Bottom Line #Get Current Frame #lfs f1,0x894(playerdata) #fctiwz f1,f1 #stfd f1,0xF0(sp) #lwz r3,0xF4(sp) lhz r3,0x23EC(playerdata) #Get Frames Early lwz r5,0x590(playerdata) #get anim data lfs f1,0x008(r5) #get anim length (float) fctiwz f1,f1 stfd f1,0xF0(sp) lwz r4,0xF4(sp) sub r5,r4,r3 subi r5,r5,0x1 bl EarlyPressText mflr r4 mr r3,text lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis branchl r12,0x803a6b98 Fox_SideBStart_NoPress: b Moonwalk_Exit #///////////////////////////////////////////////////////////////////////////// Fox_SideB: #Check If Pressed B lwz r3,0x668(playerdata) rlwinm. r3,r3,0,22,22 beq Fox_SideB_NoPress #Create Text bl CreateText mr text,r3 #backup text pointer #Change Text Color load r3,0x8dff6eff stw r3,0x30(text) #Create Top Line bl ShortenPress #Create Bottom Line #Get Current Frame lfs f1,0x894(playerdata) fctiwz f1,f1 stfd f1,0xF0(sp) lwz r3,0xF4(sp) #Get Frames Early addi r5,r3,0x1 bl ShortenTypeText mflr r4 mr r3,text lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis branchl r12,0x803a6b98 Fox_SideB_NoPress: b Moonwalk_Exit #///////////////////////////////////////////////////////////////////////////// Fox_SideBEnd: #Check If Pressed B lwz r3,0x668(playerdata) rlwinm. r3,r3,0,22,22 beq Fox_SideBEnd_NoPress #Create Text bl CreateText mr text,r3 #backup text pointer #Change Text Color load r3,0xffa2baff stw r3,0x30(text) #Create Top Line bl ShortenPress #Create Bottom Line #Get Current Frame #lfs f1,0x894(playerdata) #fctiwz f1,f1 #stfd f1,0xF0(sp) #lwz r3,0xF4(sp) lhz r5,0x23EC(playerdata) #addi r5,r3,0x1 bl LatePressText mflr r4 mr r3,text lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis branchl r12,0x803a6b98 Fox_SideBEnd_NoPress: b Moonwalk_Exit #///////////////////////////////////////////////////////////////////////////// Fox_ShineGroundLoop: #Check For JC bl CheckForJumpCancel cmpwi r3,0x0 beq Moonwalk_Exit Fox_ShineGroundLoop_Interrupted: #Create Text bl CreateText mr text,r3 #backup text pointer #Check If Frame Perfect #Get Current Frame #lfs f1,0x894(playerdata) #fctiwz f1,f1 #stfd f1,0xF0(sp) #lwz r3,0xF4(sp) lhz r3,0x23EC(playerdata) cmpwi r3,0x1 bne Fox_ShineGroundLoop_RedText #Frame Perfect load r3,0x8dff6eff #green b Fox_ShineGroundLoop_StoreColor Fox_ShineGroundLoop_RedText: load r3,0xffa2baff Fox_ShineGroundLoop_StoreColor: stw r3,0x30(text) Fox_ShineGroundLoop_TopLine: #Create Text bl ActOOShineTop mr r3,r29 #text pointer mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,0x803a6b98 Fox_ShineGroundLoop_BottomLine: #Create Text2 bl ActOOShineBottom mr r3,r29 #text pointer mflr r4 #Get Current Frame #lfs f1,0x894(playerdata) #fctiwz f1,f1 #stfd f1,0xF0(sp) #lwz r3,0xF4(sp) lhz r5,0x23EC(playerdata) lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis branchl r12,0x803a6b98 b Moonwalk_Exit #///////////////////////////////////////////////////////////////////////////// Fox_ShineAirLoop: #Check For Remaining Jump lbz r3, 0x1968 (playerdata) #Jumps Used lwz r0, 0x0168 (playerdata) #Total Jumps cmpw r3,r0 bge Moonwalk_Exit #Check For JC bl CheckForJumpCancel cmpwi r3,0x0 beq Moonwalk_Exit Fox_ShineAirLoop_Interrupted: #Create Text bl CreateText mr text,r3 #backup text pointer #Check If Frame Perfect #Get Current Frame #lfs f1,0x894(playerdata) #fctiwz f1,f1 #stfd f1,0xF0(sp) #lwz r3,0xF4(sp) lhz r3,0x23EC(playerdata) cmpwi r3,0x1 bne Fox_ShineAirLoop_RedText #Frame Perfect load r3,0x8dff6eff #green b Fox_ShineAirLoop_StoreColor Fox_ShineAirLoop_RedText: load r3,0xffa2baff Fox_ShineAirLoop_StoreColor: stw r3,0x30(text) Fox_ShineAirLoop_TopLine: #Create Text bl ActOOShineTop mr r3,r29 #text pointer mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,0x803a6b98 Fox_ShineAirLoop_BottomLine: #Create Text2 bl ActOOShineBottom mr r3,r29 #text pointer mflr r4 #Get Current Frame #lfs f1,0x894(playerdata) #fctiwz f1,f1 #stfd f1,0xF0(sp) #lwz r3,0xF4(sp) lhz r5,0x23EC(playerdata) lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis branchl r12,0x803a6b98 b Moonwalk_Exit #///////////////////////////////////////////////////////////////////////////// CheckForJumpCancel: mflr r0 stw r0, 0x0004 (sp) stwu sp, -0x0038 (sp) #Check For JC lwz r5, -0x514C (r13) lfs f0, 0x0070 (r5) lfs f1, 0x0624 (playerdata) fcmpo cr0,f1,f0 blt CheckForJumpCancel_CheckButtons lbz r3, 0x0671 (playerdata) lwz r0, 0x0074 (r5) cmpw r3,r0 bge CheckForJumpCancel_CheckButtons li r3,0x1 b CheckForJumpCancel_Exit CheckForJumpCancel_CheckButtons: lwz r0, 0x0668 (playerdata) rlwinm. r0, r0, 0, 20, 21 beq CheckForJumpCancel_NoButtons li r3,0x1 b CheckForJumpCancel_Exit CheckForJumpCancel_NoButtons: li r3,0x0 CheckForJumpCancel_Exit: lwz r0, 0x003C (sp) addi sp, sp, 56 mtlr r0 blr ShortenPress: mflr r0 stw r0, 0x0004 (sp) stwu sp, -0x0038 (sp) bl ShortenPressText mr r3,r29 #text pointer mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,0x803a6b98 lwz r0, 0x003C (sp) addi sp, sp, 56 mtlr r0 blr CreateText: mflr r0 stw r0, 0x0004 (sp) stwu sp, -0x0008 (sp) mr r3,playerdata #backup playerdata pointer li r4,60 #display for 60 frames li r5,0 #Area to Display (0-2) li r6,8 #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function lwz r0, 0x000C (sp) addi sp, sp, 8 mtlr r0 blr ################### ## TEXT CONTENTS ## ################### ShortenPressText: blrl .string "Shorten Press" .align 2 EarlyPressText: blrl .string "%df Early" .align 2 ShortenTypeText: blrl .string "Frame %d/4" .align 2 LatePressText: blrl .string "%df Late" .align 2 ActOOShineTop: blrl .string "Act OOShine" .align 2 ActOOShineBottom: blrl .string "Frame %d" .align 2 ############################## Moonwalk_Exit: restoreall lwz r12, 0x219C (r31) ================================================ FILE: ASM/training-mode/Onscreen Display/L Cancel Display NEW.asm ================================================ #To be inserted at 8008d770 .include "../Globals.s" .include "../../m-ex/Header.s" .set entity,31 .set REG_FighterData,31 .set player,30 .set text,29 .set textprop,28 .set REG_TextColor,27 .set REG_String,26 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall lwz REG_FighterData,0x2c(player) #CHECK IF ENABLED li r0,OSD.LCancel #wavedash ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit CheckForFollower: mr r3,REG_FighterData branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit # Check if succeeded lbz r5,0x67F(REG_FighterData) #get decimal to print cmpwi r5,0x7 blt SuccessLCancel FailedLCancel: li REG_TextColor,MSGCOLOR_RED mr r3,REG_FighterData bl DecLCRate b DetermineString SuccessLCancel: li REG_TextColor,MSGCOLOR_GREEN mr r3,REG_FighterData bl IncLCRate b DetermineString DetermineString: # If under 40 frames, qualify as an attempt lbz r8,0x67F(REG_FighterData) #get decimal to print cmpwi r8,40 bgt DetermineString_NoPress bl LCancel_Press mflr REG_String b PrintMessage DetermineString_NoPress: bl LCancel_NoPress mflr REG_String b PrintMessage PrintMessage: mr r7,r3 #LCancel Percent li r3,1 #Message Kind lbz r4,0xC(REG_FighterData) #Message Queue mr r5,REG_TextColor mr r6,REG_String lbz r8,0x67F(REG_FighterData) #get decimal to print addi r8,r8,1 Message_Display # Make Top Line White lwz r3,0x2C(r3) lwz r3,MsgData_Text(r3) li r4,0 bl Color_White mflr r5 branchl r12,Text_ChangeTextColor b Moonwalk_Exit ######################### ### LC Rate Functions ### ######################### IncLCRate: stwu r1,-0x100(r1) # make space for 12 registers mflr r0 stw r0,0xFC(sp) lbz r3,0xC(r3) #get player slot load r4,0x804a1fa8 #get LC rate mem location mulli r3,r3,0x4 #length of players DB info add r8,r3,r4 #players LC info in r8 lhz r3,0x0(r8) #successful LCs addi r3,r3,0x1 sth r3,0x0(r8) #successful LCs lhz r3,0x2(r8) #total LCs addi r3,r3,0x1 sth r3,0x2(r8) #total LCs mr r3,r8 bl GetLCRate lwz r0,0xFC(sp) mtlr r0 addi r1,r1,0x100 # release the space blr DecLCRate: stwu r1,-0x100(r1) # make space for 12 registers mflr r0 stw r0,0xFC(sp) lbz r3,0xC(r3) #get player slot load r4,0x804a1fa8 #get DB rate mem location mulli r3,r3,0x4 #length of players DB info add r8,r3,r4 #players DB info in r8 lhz r3,0x2(r8) #total DBs addi r3,r3,0x1 sth r3,0x2(r8) #total DBs mr r3,r8 bl GetLCRate lwz r0,0xFC(sp) mtlr r0 addi r1,r1,0x100 # release the space blr GetLCRate: #Get Values lhz r4,0x0(r3) #successful LCs lhz r5,0x2(r3) #total LCs #Get as Floats (f1 = successful, f2 = total lis r0, 0x4330 lfd f5, -0x6758 (rtoc) xoris r6, r4, 0x8000 xoris r7, r5, 0x8000 stw r0,0xF0(sp) #Successful DB stw r6,0xF4(sp) lfd f1,0xF0(sp) fsubs f1,f1,f5 #Total DB stw r7,0xF4(sp) lfd f2,0xF0(sp) fsubs f2,f2,f5 #100f li r4,100 xoris r4,r4,0x8000 stw r4,0xF4(sp) lfd f3,0xF0(sp) fsubs f3,f3,f5 fdivs f1,f1,f2 #successful LC / total LC fmuls f1,f1,f3 #times 100 #Back to Int fctiwz f1,f1 stfd f1,0xF0(sp) lwz r3,0xF4(sp) blr LCancel_Press: blrl .string "L-Cancel %d%%\nFrame %d/7" .align 2 LCancel_NoPress: blrl .string "L-Cancel %d%%\nNo Press" .align 2 Color_White: blrl .long 0xFFFFFFFF ############################## Moonwalk_Exit: restoreall lwz r0, 0x0034 (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Ledge Codes/Frames Spent in CliffWait.asm ================================================ #To be inserted at 8009ab78 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## stw r0, 0x2064 (r6) backupall mr playerdata,r6 #CHECK IF ENABLED li r0,OSD.Ledge #PowerShield ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit CheckForFollower: mr r3,playerdata branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit #Check if Over 20 Frames lhz r3,0x23EC(playerdata) cmpwi r3,20 bgt Moonwalk_Exit bl CreateText #Change Text Color lhz r3,0x23EC(playerdata) subi r3,r3,1 cmpwi r3,0x1 bne RedText GreenText: load r3,0x8dff6eff #green b StoreTextColor RedText: load r3,0xffa2baff StoreTextColor: stw r3,0x30(text) #Create Text bl TopText mr r3,r29 #text pointer mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,0x803a6b98 #Create Text2 bl BottomText mr r3,r29 #text pointer mflr r4 lhz r5,0x23EC(playerdata) subi r5,r5,1 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis branchl r12,0x803a6b98 b Moonwalk_Exit CreateText: mflr r0 stw r0, 0x0004 (sp) stwu sp, -0x0008 (sp) mr r3,playerdata #backup playerdata pointer li r4,60 #display for 60 frames #Display Up Top For Event load r5,SceneController lbz r5,0x0(r5) cmpwi r5,0x2B bne 0xC li r5,1 b 0x8 li r5,0 #Area to Display (0-2) li r6,13 #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr text,r3 #backup text pointer lwz r0, 0x000C (sp) addi sp, sp, 8 mtlr r0 blr ################### ## TEXT CONTENTS ## ################### TopText: blrl .string "Frames in" .align 2 BottomText: blrl .string "Cliffwait: %d" .align 2 ############################## Moonwalk_Exit: restoreall ================================================ FILE: ASM/training-mode/Onscreen Display/Ledge Codes/GALINT/GALINT Aerail Interrupt.asm ================================================ #To be inserted at 8008d6f4 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall #Check For CliffWait lhz r4, TM_ThreeASAgo (r5) cmpwi r4,0xFD bne Moonwalk_Exit li r4,1 branchl r12,0x80005514 Moonwalk_Exit: restoreall branchl r12,0x800d5bf8 ================================================ FILE: ASM/training-mode/Onscreen Display/Ledge Codes/GALINT/GALINT Laser Land.asm ================================================ #To be inserted at 80082c40 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall #Search last 5 AS's for CliffWait li r5,0x0 lwz r6,0x2C(28) CliffWaitSearch: mulli r3,r5,0x2 addi r3,r3,TM_PrevASStart lhzx r3,r3,r6 cmpwi r3,0xFD beq DisplayGALINT addi r5,r5,1 cmpwi r5,5 ble CliffWaitSearch b Moonwalk_Exit #Display GALINT DisplayGALINT: mr r3,r28 li r4,0 branchl r12,0x80005514 Moonwalk_Exit: restoreall mr r3, r28 ================================================ FILE: ASM/training-mode/Onscreen Display/Ledge Codes/GALINT/GALINT Ledgedash.asm ================================================ #To be inserted at 800d5d5c .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall lwz r5,0x2C(r31) #Check If Coming From Airdodge lhz r3, TM_OneASAgo (r5) cmpwi r3,0xEC bne Moonwalk_Exit #Check For CliffWait lhz r3, TM_FourASAgo (r5) cmpwi r3,0xFD bne Moonwalk_Exit mr r3,r31 li r4,0 branchl r12,0x80005514 Moonwalk_Exit: restoreall mr r3, r31 ================================================ FILE: ASM/training-mode/Onscreen Display/Ledge Codes/GALINT/GALINT No Impact Land.asm ================================================ #To be inserted at 80082b4c .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall lwz r5,0x2C(r30) #Check For CliffWait lhz r3, TM_TwoASAgo (r5) cmpwi r3,0xFD bne Moonwalk_Exit mr r3,r30 li r4,0 branchl r12,0x80005514 Moonwalk_Exit: restoreall mr r3, r30 ================================================ FILE: ASM/training-mode/Onscreen Display/Ledge Codes/GALINT/Standalaone - GALINT Display.asm ================================================ #To be inserted at 80005514 .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set REG_isAerialInterrupt,28 .set REG_GALINT,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall mr player,r3 lwz playerdata,0x2c(player) mr REG_isAerialInterrupt,r4 #CHECK IF ENABLED li r0,OSD.Ledge #PowerShield ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit CheckForFollower: mr r3,playerdata branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit #Check if Over 20 Frames past GALINT lhz r3,TM_TangibleFrameCount(playerdata) cmpwi r3,20 bgt Moonwalk_Exit #Get GALINT Frames (Ledge Intang - Landing Lag) lwz REG_GALINT,0x1990 (playerdata) cmpwi REG_isAerialInterrupt,0 beq SkipAI lfs f1,0x1F4 (playerdata) fctiwz f1,f1 stfd f1,0x80(sp) lwz r3,0x84(sp) sub REG_GALINT,REG_GALINT,r3 SkipAI: bl CreateText #Change Text Color cmpwi REG_GALINT,0x0 ble RedText GreenText: load r3,0x8dff6eff #green b StoreTextColor RedText: load r3,0xffa2baff StoreTextColor: stw r3,0x30(text) #Create Text bl TopText mr r3,r29 #text pointer mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,0x803a6b98 #Create Text2 bl BottomText mr r3,r29 #text pointer mflr r4 mr r5,REG_GALINT cmpwi r5,0x0 bgt SkipShowingTangibleFrames #Show Tangible Frames lwz r5,0x2408(playerdata) addi r5,r5,0x1 neg r5,r5 SkipShowingTangibleFrames: lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis branchl r12,0x803a6b98 b Moonwalk_Exit CreateText: mflr r0 stw r0, 0x0004 (sp) stwu sp, -0x0008 (sp) mr r3,playerdata #backup playerdata pointer li r4,60 #display for 60 frames li r5,0 #Area to Display (0-2) li r6,14 #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr text,r3 #backup text pointer lwz r0, 0x000C (sp) addi sp, sp, 8 mtlr r0 blr ################### ## TEXT CONTENTS ## ################### TopText: blrl .string "Ledgedash GALINT" .align 2 BottomText: blrl .string "Frames: %d" .align 2 ############################## Moonwalk_Exit: restoreall blr ================================================ FILE: ASM/training-mode/Onscreen Display/Ledge Codes/Ledgestall/Ledgestall Display.asm ================================================ #To be inserted at 800814ec .include "../../../Globals.s" .include "../../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall lwz playerdata,0x2c(player) #CHECK IF ENABLED li r0,OSD.Ledge #Ledge Codes ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit CheckForFollower: mr r3,playerdata branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit #Check If Under 15 Frames lwz r3, 0x2408 (playerdata) subi r3,r3,1 cmpwi r3,15 bgt Moonwalk_Exit bl CreateText #Change Text Color lwz r3, 0x2408 (playerdata) subi r3,r3,1 cmpwi r3,0 bgt RedText GreenText: load r3,0x8dff6eff #green b StoreTextColor RedText: load r3,0xffa2baff StoreTextColor: stw r3,0x30(text) #Create Text bl TopText mr r3,r29 #text pointer mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,0x803a6b98 #Create Text2 bl BottomText_FramesLate mr r3,r29 #text pointer mflr r4 lwz r5, 0x2408 (playerdata) subi r5,r5,1 cmpwi r5,0x0 neg r5,r5 bgt LateLedgestall #Show Perfect Ledgestall Text bl BottomText_PerfectStall mflr r4 LateLedgestall: lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis branchl r12,0x803a6b98 b Moonwalk_Exit CreateText: mflr r0 stw r0, 0x0004 (sp) stwu sp, -0x0008 (sp) mr r3,playerdata #backup playerdata pointer li r4,60 #display for 60 frames li r5,0 #Area to Display (0-2) li r6,14 #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr text,r3 #backup text pointer lwz r0, 0x000C (sp) addi sp, sp, 8 mtlr r0 blr ################### ## TEXT CONTENTS ## ################### TopText: blrl .string "Ledgestall" .align 2 BottomText_FramesLate: blrl .string "Frames Late: %d" .align 2 BottomText_PerfectStall: blrl .string "Perfect" .align 2 ############################## Moonwalk_Exit: restoreall lwz r0, 0x0034 (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Message Display System/Create Message Struct.asm ================================================ #To be inserted at 802ff4e8 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set MessageStructTotalSize,0x300 .set MessageAreaLength,0x100 .set PerPlayerMessageStructLength,0x28 ######################################################## ## Allocate 0x300 Bytes and Store Pointer at 804a1f5c ## ######################################################## li r3,MessageStructTotalSize branchl r12,0x8037f1e4 stw r3,0x4(r31) #Zero Space li r4,MessageStructTotalSize branchl r12,0x8000c160 ############################################## ## Create Message Management Think Function ## ############################################## #Create GObj li r3,0xE li r4,0x7 li r5,0x0 branchl r12,0x803901f0 #Attach Think Function bl MessageThink mflr r4 #Get Function Address li r5,0x0 branchl r12,0x8038fd54 b exit ################################################################# ################ ## MessageThink ## ################ MessageThink: blrl backup ############################################### ## Update Message Area 1 (Above Player HUDs) ## ############################################### #Init Loop li r31,0x0 #Loop Count MessageThink_UpdateArea1Loop: li r3,0x0 #Area 1 mr r4,r31 #Player bl MessageThink_Updater MessageThink_UpdateArea1IncLoop: addi r31,r31,0x1 cmpwi r31,0x4 blt MessageThink_UpdateArea1Loop ########################################### ## Update Message Area 2 (Top of Screen) ## ########################################### #Init Loop li r31,0x0 #Loop Count MessageThink_UpdateArea2Loop: li r3,1 #Area 2 mr r4,r31 #Player bl MessageThink_Updater MessageThink_UpdateArea2IncLoop: addi r31,r31,0x1 cmpwi r31,0x4 blt MessageThink_UpdateArea2Loop ################################################# ## Update Message Area 3 (Right Side of Screen ## ################################################# li r3,2 #Area 3 bl MessageThink_Updater MessageThink_Exit: restore blr ################################################################## ########################## ## MessageThink_Updater ## ########################## MessageThink_Updater: backup mr r31,r3 #Area ID mr r30,r4 #Player ID #Get Area's Message Struct in r29 load r3,0x804a1f58 lwz r3,0x4(r3) mulli r4,r31,MessageAreaLength add r29,r3,r4 #Check For Area 3, No Player Dependent Stuff If So cmpwi r31,0x2 bge MessageThink_Updater_NonPlayerArea ###################################################################################### MessageThink_Updater_PlayerAreaLoopInit: mulli r4,r30,PerPlayerMessageStructLength add r29,r29,r4 li r28,0x0 #Offset In Player's Area MessageThink_Updater_PlayerAreaLoop: add r27,r28,r29 lwz r3,0x0(r27) #Get Text Pointer cmpwi r3,0 #If There's No Text Here, Skip beq MessageThink_Updater_PlayerAreaIncLoop #Check If No Timer (-1) lhz r3,0x4(r27) #Get Timer cmpwi r3,-1 beq MessageThink_Updater_PlayerAreaIncLoop #Decrement Timer #lhz r3,0x4(r27) #Get Timer subi r3,r3,0x1 sth r3,0x4(r27) #Check If Expired cmpwi r3,0x0 bgt MessageThink_Updater_PlayerAreaIncLoop #Remove Text lwz r3,0x0(r27) #Get Text Pointer branchl r12,0x803a5cc4 #Zero Out Entry li r3,0x0 stw r3,0x0(r27) stw r3,0x4(r27) #Check To Shift Upwards addi r26,r28,0x8 #Next Offset cmpwi r26,PerPlayerMessageStructLength #Check If There's Nothing Left to Shift bge MessageThink_Updater_PlayerAreaIncLoop #Skip Shift Code #Shift Everything Below it Upwards MessageThink_Updater_PlayerAreaShiftMessagesLoop: add r5,r26,r29 #Get Next Individual Message Struct lwz r3,0x0(r5) #Get Messages Text Pointer lwz r4,0x4(r5) #Get Messages Timer and ID stw r3,-0x8(r5) #Push Up stw r4,-0x4(r5) #Push Up #Check If This Entry Is Live cmpwi r3,0x0 beq MessageThink_Updater_PlayerAreaShiftMessagesIncLoop #Move Message Downwards/Upwards Depending On The Area bl MessageThink_Floats mflr r4 mulli r5,r31,0x4 #Area ID into offset lfsx f1,r4,r5 lfs f2,0x4(r3) #Get Text's Y Value fadds f1,f1,f2 stfs f1,0x4(r3) #Store Text's Y Value #Go To Next Message's Offset MessageThink_Updater_PlayerAreaShiftMessagesIncLoop: addi r26,r26,0x8 #Next Offset cmpwi r26,PerPlayerMessageStructLength #Check If There's Nothing Left to Shift blt MessageThink_Updater_PlayerAreaShiftMessagesLoop #Run Code if There Is MessageThink_Updater_PlayerAreaIncLoop: addi r28,r28,0x8 #Length of Each Message Data cmpwi r28,PerPlayerMessageStructLength blt MessageThink_Updater_PlayerAreaLoop b MessageThink_Updater_Exit ###################################################################################### MessageThink_Updater_NonPlayerArea: lwz r3,0x0(r29) #Get Text Pointer cmpwi r3,0 #If There's No Text Here, Skip beq MessageThink_Updater_Exit #Check If No Timer (-1) lhz r3,0x4(r29) #Get Timer cmpwi r3,-1 beq MessageThink_Updater_Exit #Decrement Timer #lhz r3,0x4(r29) #Get Timer subi r3,r3,0x1 sth r3,0x4(r29) #Check If Expired cmpwi r3,0x0 bgt MessageThink_Updater_Exit #Remove Text lwz r3,0x0(r29) #Get Text Pointer branchl r12,0x803a5cc4 #Zero Out Entry li r3,0x0 stw r3,0x0(r29) stw r3,0x4(r29) b MessageThink_Updater_Exit ###################################################################################### #******************# MessageThink_Floats: blrl .long 0x40900000 #Area 1 .long 0xC0900000 #Area 2 #******************# MessageThink_Updater_Exit: restore blr ################################################################# exit: lwz r0, 0x001C (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Message Display System/Disable Hiding Score on Pause.asm ================================================ #To be inserted at 802f33b8 nop ================================================ FILE: ASM/training-mode/Onscreen Display/Message Display System/Disable Showing Score on Unpause.asm ================================================ #To be inserted at 802f33f0 nop ================================================ FILE: ASM/training-mode/Onscreen Display/Message Display System/Display Message 2.0.asm ================================================ #To be inserted at 80005928 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set playerdata,31 .set messageStruct,30 .set text,29 .set textprop,28 .set texttimer,27 .set AreaID,26 .set overlayID,25 .set MaxWindows,24 .set messageAreaStructLength,0x100 .set messageStructLength,0x28 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## #Message Area Struct Layout ##0x00 = P1 Area ##0x28 = P2 Area ##0x50 = P3 Area ##0x78 = P4 Area #PX Area #0x0 = 32-bit int, number of active windows in this area #0x4 = Start Individual Message Struct #0x0 = Text Pointer #0x4 = Countdown Until Expiration #0x6 = Unique Message ID (which text prompt this is) backup mr playerdata,r3 mr texttimer,r4 mr AreaID,r5 #custom window struct in the stock text match struct mr overlayID,r6 mr textprop,r7 #Load Max Number of Windows Variable From OSD Menu lwz r3,-0x77C0(r13) #Get Memcard Data lbz MaxWindows,0x1f28(r3) #Get Window's Area in the Message Struct in r3 load r3,0x804a1f58 lwz r3,0x4(r3) mulli r4,AreaID,messageAreaStructLength add r3,r3,r4 #Check If Area 3 (No Shift or anything Special) cmpwi AreaID,0x2 blt GetPlayersArea mr messageStruct,r3 #Remove Old Area 3 Window lwz r3,0x0(messageStruct) branchl r12,0x803a5cc4 b CreateText GetPlayersArea: #Get to the player's area lbz r4,0xC(playerdata) mulli r4,r4,messageStructLength add messageStruct,r3,r4 #Search Queue For This Text ID (Loop) mr r3,overlayID mr r4,MaxWindows mr r5,messageStruct bl CheckForDuplicates #Shift Queue To Make Room For New Message CallShiftFunction: mr r3,MaxWindows bl ShiftQueue CreateText: #CREATE TEXT ABOVE PLAYERS HUD ELEMENT li r3,0x2 load r4,0x804a1f58 #get text objects ID? lwz r4,0x0(r4) branchl r12,0x803a6754 #STORE PLAYERS TEXT POINTER mr r29,r3 #backup text pointer stw r3,0x0(messageStruct) #STORE PLAYERS TEXT TIMEOUT sth texttimer,0x4(messageStruct) #STORE OVERLAY ID sth overlayID,0x6(messageStruct) #SET TEXT TO CENTER AROUND X LOCATION AND BE CLOSE li r3,0x1 stb r3,0x4A(r29) stb r3,0x49(r29) #SET X AND Y VALUES #Get Area's Text Properties bl TextProperties mflr textprop mulli r3,AreaID,0x1C add textprop,textprop,r3 #Check To Override HUD Location lwz r3,0x0(textprop) #base X value cmpwi r3,0x0 bne GetHUDLocation lfs f1,0x8(textprop) #base X value b GetYLocation #Get HUD Location GetHUDLocation: lbz r3,0xC(playerdata) load r4,0x804a0ff0 mulli r3,r3,0xC #HUD Info is 0xC Long Per Player lfsx f1,r3,r4 #Get This Players HUD Info GetYLocation: lfs f2,0x4(textprop) #players Y value stfs f1,0x0(text) #store X value to struct stfs f2,0x4(text) #store Y value to struct #SET TEXT SIZE lfs f1,0xC(textprop) stfs f1,0x24(text) #X stretch stfs f1,0x28(text) #Y stretch #INIT BACKGROUND (HYPHEN) mr r3,r29 #text pointer bl TextASCII3 mflr r4 #get ASCII to print lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, 0x10 (textprop) #background Y branchl r12,0x803a6b98 #CHANGE TEXT COLOR TO BLACK mr r3,text li r4,0x0 li r5,0x0 stw r5,0xF0(sp) addi r5,sp,0xF0 branchl r12,0x803a74f0 #CHANGE TEXT SIZE mr r3,text li r4,0x0 lfs f1, 0x14 (textprop) #stretch X (12) lfs f2, 0x18 (textprop) #stretch Y (30) branchl r12,0x803a7548 b Moonwalk_Exit ####################################################################### #################### ## Shift Messages ## #################### ShiftQueue: backup mr r31,r3 #Max Windows #Remove Last Message if Exists mulli r3,r31,0x8 lwzx r3,r3,messageStruct cmpwi r3,0x0 beq ShiftQueue_CheckForOneWindowOnly #Remove Message branchl r12,0x803a5cc4 #Zero Out Entry mulli r4,r31,0x8 add r4,r4,messageStruct li r3,0 stw r3,0x0(r4) stw r3,0x4(r4) ShiftQueue_CheckForOneWindowOnly: #Check If Only 1 Message cmpwi r31,0 beq ShiftQueue_Exit ShiftQueue_Loop: #Shift This Message Upwards in the Queue mulli r3,r31,0x8 add r3,r3,messageStruct #Get to the nth Message lwz r4,0x0(r3) #Load Text Pointer into r4 lwz r5,0x4(r3) #Load Timer and ID into r5 stw r4,0x8(r3) #Push up stw r5,0xC(r3) #Push up li r4,0x0 stw r4,0x0(r3) #Zero Out stw r4,0x4(r3) #Zero Out #Move This Message Upwards Onscreen lwz r4,0x8(r3) #Text Pointer cmpwi r4,0x0 beq ShiftQueue_IncLoop #Move Message Downwards/Upwards Depending On The Area bl ShiftQueue_Floats mflr r3 mulli r5,AreaID,0x4 #Area ID into offset lfsx f1,r3,r5 lfs f2,0x4(r4) #Get Text's Y Value fadds f1,f1,f2 stfs f1,0x4(r4) #Store Text's Y Value #Next Message ShiftQueue_IncLoop: subi r31,r31,0x1 cmpwi r31,0x0 bge ShiftQueue_Loop ShiftQueue_Exit: restore blr ################################################ ##################### ## Check For Dupes ## ##################### #Inputs: #r3 = OverlayID #r4 = Max Window Count #r5 = Message Queue Start CheckForDuplicates: backup mr r31,r3 mr r30,r4 mr r29,r5 #Search Loop For Matching Window #Init Loop li r28,0x0 #Matching Window Loop Count CheckForDuplicates_MatchingWindowLoop: mulli r5,r28,0x8 #Get Message's Offset add r4,r5,r29 #Get Message's Location in Memory lwz r3,0x0(r4) #Get Text Pointer cmpwi r3,0x0 #Check If This Entry Exists beq CheckForDuplicates_MatchingWindowIncLoop lhz r3,0x6(r4) #Get Window ID cmpw r3,r31 #Check If They Match bne CheckForDuplicates_MatchingWindowIncLoop #Upon Finding a Match #Remove This Window lwz r3,0x0(r4) branchl r12,0x803a5cc4 #Zero Out Entry mulli r5,r28,0x8 #Get Message's Offset add r4,r5,r29 #Get Message's Location in Memory li r3,0x0 stw r3,0x0(r4) stw r3,0x4(r4) #Init Shift Loop Count addi r27,r28,0x1 #Window After Matching Window ID = Shift Loop Count Starting Value #Loop - Move All Windows After This Down CheckForDuplicates_MatchingWindowShiftLoop: mulli r5,r27,0x8 #Get Message's Offset add r4,r5,r29 #Get Message's Location in Memory lwz r5,0x0(r4) #Load Text Pointer lwz r6,0x4(r4) #Load Text Timer and ID stw r5,-0x8(r4) #Store Text Pointer stw r6,-0x4(r4) #Store Text Timer and ID li r3,0x0 stw r3,0x0(r4) #Zero Out stw r3,0x4(r4) #Zero Out #Move Message Downwards/Upwards Depending On The Area lwz r3,-0x8(r4) #Get Text Pointer cmpwi r3,0x0 #Check If This Entry Is Active beq CheckForDuplicates_MatchingWindowShiftIncLoop bl CheckForDuplicates_Floats mflr r4 mulli r5,AreaID,0x4 #Area ID into offset lfsx f1,r4,r5 lfs f2,0x4(r3) #Get Text's Y Value fadds f1,f1,f2 stfs f1,0x4(r3) #Store Text's Y Value CheckForDuplicates_MatchingWindowShiftIncLoop: addi r27,r27,0x1 cmpw r27,r30 blt CheckForDuplicates_MatchingWindowShiftLoop b CheckForDuplicates_Exit CheckForDuplicates_MatchingWindowIncLoop: addi r28,r28,0x1 cmpw r28,r30 blt CheckForDuplicates_MatchingWindowLoop CheckForDuplicates_Exit: restore blr ############################## TextProperties: blrl #Area 1 (Above HUD) .long 0xC1A80000 #X Base .long 0x41300000 #Y Value .long 0x41600000 #X Difference Between Players .long 0x3D23D70A #Text Size .long 0xC3CD0000 #background Y position .long 0x41400000 #background X stretch .long 0x41E00000 #background Y stretch #Area 2 (top of screen) .long 0xC1A80000 #X Base .long 0xC1A00000 #Y Value .long 0x41600000 #X Difference Between Players .long 0x3D23D70A #Text Size .long 0xC3CD0000 #background Y position .long 0x41180000 #background X stretch .long 0x41E00000 #background Y stretch #Area 3 (Event Popup) .long 0x00000000 #Whether to Use HUD Location, 0 = no .float -15 #Y Value .float 19 #X Value .float 0.04 #Canvas Size .float -410 #background Y position .float 13.5 #background X stretch .float 28 #background Y stretch ############################## #******************# ShiftQueue_Floats: blrl .long 0xC0900000 #Area 1 .long 0x40900000 #Area 2 #******************# #******************# CheckForDuplicates_Floats: blrl .long 0x40900000 #Area 1 .long 0xC0900000 #Area 2 #******************# TextASCII3: blrl .long 0x815B0000 Moonwalk_Exit: mr r3,text #return text pointer restore blr ================================================ FILE: ASM/training-mode/Onscreen Display/SDI Display/Initialize Total SDI Inputs Variable.asm ================================================ #To be inserted at 8008f71c .include "../../Globals.s" .include "../../../m-ex/Header.s" .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## #Get Victims Data lwz r6,0x2C(r31) #Get Attacker GObj lwz r5,0x1868(r6) #If Pointer doesn't exist, its most likely environmental damage (break the targets walls) cmpwi r5,0x0 beq ResetSDICount #Check if Player lhz r0,0(r5) #Entity Type lwz r5,0x2C(r5) #Get Attacker Data cmpwi r0,4 #Player beq LastPlayerMove cmpwi r0,6 #Item beq LastItemMove b exit #If neither, exit LastPlayerMove: #Get current Move Instance from attacker lhz r4,0x2088(r5) b GetLastMoveVictimHitBy LastItemMove: #Get current Move Instance from attacker lhz r4,0xDA8(r5) GetLastMoveVictimHitBy: #Get last Move Instance Victim was hit by lhz r3,TM_PreviousMoveInstanceHitBy(r6) #If the move instance is 0, was most likely a stage element (corneria lasers) cmpwi r4,0 beq ResetSDICount #Check If New Hit cmpw r3,r4 beq exit #Reset SDI Counter ResetSDICount: li r0, 0x0 sth r0, TM_SuccessfulSDIInputs (r6) sth r0, TM_TotalSDIInputs (r6) exit: cmpwi r30, 0 ================================================ FILE: ASM/training-mode/Onscreen Display/SDI Display/SDI Display Main.asm ================================================ #To be inserted at 8008e52c .include "../../Globals.s" .include "../../../m-ex/Header.s" .set REG_FighterData,31 .set player,30 .set REG_TextColor,29 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## backupall stfs f0,0x80(sp) stfs f1,0x84(sp) stfs f2,0x8C(sp) stfs f3,0x88(sp) mr REG_FighterData,r3 #CHECK IF ENABLED li r0,OSD.SDI #PowerShield ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit CheckForFollower: mr r3,REG_FighterData branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit SDICheck: #Check For SDI fcmpo cr0,f1,f0 cror 2, 1, 2 bne NoSDI #Check For SDI Cont. lbz r0, 0x0670 (REG_FighterData) lwz r4, -0x514C (r13) lwz r5, 0x04B4 (r4) cmpw r0, r5 blt SuccessfulSDI #Check For SDI Cont.. lbz r0, 0x0671 (REG_FighterData) cmpw r0, r5 bge NoSDI SuccessfulSDI: #Increment Successful SDI lhz r3,TM_SuccessfulSDIInputs(REG_FighterData) addi r3,r3,0x1 sth r3,TM_SuccessfulSDIInputs(REG_FighterData) NoSDI: #Increment Total SDI lhz r3,TM_TotalSDIInputs(REG_FighterData) addi r3,r3,0x1 sth r3,TM_TotalSDIInputs(REG_FighterData) #Change color to Green if SDI'd once lhz r3,TM_SuccessfulSDIInputs(REG_FighterData) cmpwi r3,0x0 beq RedText li REG_TextColor,MSGCOLOR_GREEN b PrintMessage RedText: li REG_TextColor,MSGCOLOR_RED b PrintMessage PrintMessage: li r3,2 #Message Kind lbz r4,0xC(REG_FighterData) #Message Queue mr r5,REG_TextColor bl SDI_String mflr r6 lhz r7,TM_SuccessfulSDIInputs(REG_FighterData) lhz r8,TM_TotalSDIInputs(REG_FighterData) Message_Display b Moonwalk_Exit ################### ## TEXT CONTENTS ## ################### SDI_String: blrl .string "SDI Inputs\n%d/%d" .align 2 ############ ## Floats ## ############ Floats: blrl .long 0x41300000 ############################## Moonwalk_Exit: lfs f0,0x80(sp) lfs f1,0x84(sp) lfs f2,0x8C(sp) lfs f3,0x88(sp) restoreall fcmpo cr0,f1,f0 ================================================ FILE: ASM/training-mode/Onscreen Display/Template.s ================================================ #To be inserted at 804df470 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set TextCreateFunction,0x80005928 .set entity,31 .set playerdata,31 .set player,30 .set text,29 .set textprop,28 .set hitbool,27 ########################################################## ## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ## ## Is 0x80 long and is zero'd at the start ## ## of every VS Match ## ## Store Text Info here ## ########################################################## /* backup mr playerdata,r3 #CHECK IF ENABLED li r0,0x14 #PowerShield ID #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Moonwalk_Exit CheckForFollower: mr r3,playerdata branchl r12,0x80005510 cmpwi r3,0x1 beq Moonwalk_Exit bl CreateText #Change Text Color cmpwi r3,0x1 bgt RedText GreenText: load r3,0x8dff6eff #green b StoreTextColor RedText: load r3,0xffa2baff StoreTextColor: stw r3,0x30(text) #Create Text bl TopText mr r3,r29 #text pointer mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y branchl r12,0x803a6b98 #Create Text2 bl BottomText mr r3,r29 #text pointer mflr r4 lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis branchl r12,0x803a6b98 b Moonwalk_Exit CreateText: stwu r1,-0x100(r1) # make space for 12 registers mflr r0 stw r0,0xFC(sp) mr r3,playerdata #backup playerdata pointer li r4,60 #display for 60 frames li r5,0 #Area to Display (0-2) li r6,13 #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr text,r3 #backup text pointer lwz r0,0xFC(sp) mtlr r0 addi r1,r1,0x100 # release the space blr ################### ## TEXT CONTENTS ## ################### TopText: blrl .long 0x46617374 .long 0x66616c6c .long 0x BottomText: blrl .long 0x4672616d .long 0x65202564 .long 0x ############################## Moonwalk_Exit: restore li r0, 1 */ blr ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/Can Disable All Toggles in Custom RSS.asm ================================================ #To be inserted at 80236064 .include "../../Globals.s" .include "../../../m-ex/Header.s" #CHECK FLAG IN RULES STRUCT load r3,0x804a04f0 lbz r0, 0x0011 (r3) cmpwi r0,0x2 blt original #REMOVE CUSTOM TEXT li r0, 0 b exit original: li r0, 1 exit: ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/Disable Save to Bitfield Every Change.asm ================================================ #To be inserted at 802360e0 nop ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/Load Alt Text When Loaded With L.asm ================================================ #To be inserted at 80236b40 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set Text,30 .set TextProp,28 #CHECK FLAG IN RULES STRUCT load r4,0x804a04f0 lbz r0, 0x0011 (r4) cmpwi r0,0x2 blt original backup #SPAWN TEXT bl TextProperties mflr TextProp ########################## ## Write Left Side Text ## ########################## CreateText: #CREATE TEXT ABOVE PLAYERS HUD ELEMENT li r3,0x0 lbz r4, -0x4AEB (r13) branchl r12,0x803a6754 #BACKUP TEXT POINTER mr r30,r3 stw r3,0x40(r31) #INITALIZE TEXT ATTRIBUTES lfs f1,0x0(TextProp) lfs f2,0x4(TextProp) #Y Base lfs f3, -0x3B30 (rtoc) stfs f1,0x0(Text) stfs f2,0x4(Text) stfs f3,0x8(Text) li r3,0x2 li r4,0x1 stb r3,0x4A(r30) stb r4,0x48(r30) stb r4,0x49(Text) lfs f2,0x8(TextProp) stfs f2,0x24(Text) stfs f2,0x28(Text) #Write Text to the Left Side of the Screen InitLoopLeft: li r29,0 LoopStartLeft: mr r3,Text #text struct to write to bl TextASCIILeft mflr r4 #text ascii mr r5,r29 #text ID lfs f1, -0x35FC (rtoc) #X offset bl WriteText IncLoopLeft: addi r29,r29,0x1 cmpwi r29,16 blt LoopStartLeft ##################### ## Write FDD Title ## ##################### #Create Text mr r3,r30 bl FDDTitleText mflr r4 lfs f1,0x14(TextProp) lfs f2,0x18(TextProp) branchl r12,0x803a6b98 #Change Color mr r4,r3 mr r3,r30 addi r5,sp,0xF0 load r6,0xff7575FF stw r6,0x0(r5) branchl r12,0x803a74f0 ##################### ## Recommended OSD ## ##################### #Get Options String lwz r3,-0x77C0(r13) #Get Memcard Data lbz r3,OSDRecommended(r3) bl FDDRecommendedOptions mflr r4 branchl r12,SearchStringTable #Create Text mr r5,r3 mr r3,r30 bl FDDRecommended mflr r4 lfs f1,RecommendedX(TextProp) lfs f2,RecommendedY(TextProp) branchl r12,Text_InitializeSubtext stb r3,0x49(r31) #Store Subtext ID #Change Color mr r4,r3 mr r3,r30 addi r5,TextProp,RecommendedColor branchl r12,Text_ChangeTextColor #Create Z Text mr r3,r30 bl FDDRecommendedZ mflr r4 lfs f1,RecommendedZX(TextProp) lfs f2,0x28(TextProp) branchl r12,Text_InitializeSubtext #Change Color mr r4,r3 mr r3,r30 addi r5,TextProp,RecommendedColor branchl r12,Text_ChangeTextColor ######################### ## Write Max OSD Count ## ######################### #Create Text mr r3,r30 bl MaxOSDText mflr r4 lwz r5, -0x77C0 (r13) lbz r5, 0x1F28 (r5) addi r5,r5,1 lfs f1,0x1C(TextProp) lfs f2,0x20(TextProp) branchl r12,0x803a6b98 stb r3,0x48(r31) #Change Color mr r4,r3 mr r3,r30 addi r5,sp,0xF0 load r6,0x8dff6eff stw r6,0x0(r5) branchl r12,0x803a74f0 #Create XY Text mr r3,r30 bl XYText mflr r4 lfs f1,0x24(TextProp) lfs f2,0x28(TextProp) branchl r12,0x803a6b98 #Change Color mr r4,r3 mr r3,r30 addi r5,sp,0xF0 branchl r12,0x803a74f0 ########################### ## Write Right Side Text ## ########################### #CREATE TEXT ABOVE PLAYERS HUD ELEMENT li r3,0x0 lbz r4, -0x4AEB (r13) branchl r12,0x803a6754 #BACKUP TEXT POINTER mr r30,r3 stw r3,0x44(r31) #INITALIZE TEXT ATTRIBUTES lfs f1,0x0(TextProp) lfs f2,0x4(TextProp) #Y Base lfs f3, -0x3B30 (rtoc) stfs f1,0x0(Text) stfs f2,0x4(Text) stfs f3,0x8(Text) li r3,0x2 li r4,0x1 stb r3,0x4A(r30) stb r4,0x48(r30) stb r4,0x49(Text) lfs f2,0x8(TextProp) stfs f2,0x24(Text) stfs f2,0x28(Text) #Write Text to the Right Side of the Screen InitLoopRight: li r29,0 LoopStartRight: mr r3,Text #text struct to write to bl TextASCIIRight mflr r4 #text ascii mr r5,r29 #text ID lfs f1,0x10(TextProp) bl WriteText IncLoopRight: addi r29,r29,0x1 cmpwi r29,15 blt LoopStartRight restore b exit ############### ## WriteText ## ############### #r3= TextStruct #r4= TextASCIIPointer #r5= Text ID #f1= X Offset WriteText: .set REG_TextGObj,31 .set REG_StringArray,30 .set REG_StringID,29 .set TextProp,28 #Backup args backup mr REG_TextGObj,r3 mr REG_StringArray,r4 mr REG_StringID,r5 bl TextProperties mflr TextProp stfs f1,0xB0(sp) mr r3,REG_StringID mr r4,REG_StringArray branchl r12,SearchStringTable #GET Y VALUE xoris r0, REG_StringID, 0x8000 stw r0, 0xF4 (sp) lis r0, 0x4330 stw r0, 0xF0 (sp) lfd f0, 0xF0 (sp) lfd f3, -0x3B20 (rtoc) fsubs f0,f3,f0 lfs f2,0x4(TextProp) #Y Base lfs f3,0xC(TextProp) #Y DIff fmuls f0,f0,f3 fsubs f2,f2,f0 mr r4,r3 mr r3,REG_TextGObj lfs f1,0xB0(sp) branchl r12,Text_InitializeSubtext restore blr TextProperties: blrl .set RecommendedX,0x2C .set RecommendedY,0x30 .set RecommendedColor,0x34 .set RecommendedZX,0x38 .long 0xC0900000 #Text X Location .long 0xC0E80000 #Text Y Base .long 0x3CB43958 #Text Scaling .long 0x42480000 #Text Y Difference .long 0x4423C000 #Right Text X Offset .long 0x43960000 #Center Title X .long 0xC22C0000 #Center Title Y .long 0xC3200000 #Max Windows X .long 0xC22C0000 #Max Windows Y .long 0xC3700000 #XYText X .long 0xC0E80000 #XYText Y .float 800 .float -43.0 .long 0x8dff6eff .float 630 FDDRecommended: blrl .string "Suggested OSDs: %s" .align 2 FDDRecommendedOptions: blrl .string "On" .string "Off" .align 2 FDDRecommendedZ: blrl .string "(Z)" .align 2 TextASCIILeft: blrl .string "" .string "Wavedash Info" .string "L-Cancel" .string "Missed Tech" .string "Act OoS Frame" .string "Meteor Cancel" .string "Dashback" .string "Shield Drop" .string "Inputs Per Minute" .string "Spacie Tech" .string "Powershield Frame" .string "Shield Poke + ADT" .string "SDI Inputs" .string "Grab Breakout" .string "Ledgedash Info" .string "Act OoHitstun" .align 2 TextASCIIRight: blrl .string "" .string "Hitstun/Hitlag" .string "Shield Stun" .string "State Frames Left" .string "" .string "Act OoLag" .string "Crouch Cancel" .string "Act OoJump" .string "Act OoJumpSquat" .string "Fastfall Timing" .string "Frame Advantage" .string "Combo Counter" .string "DI Draw" .string "" .string "UniversalControllerFix" .align 2 FDDTitleText: blrl .long 0x4f534420 .long 0x4d656e75 .long 0x00000000 MaxOSDText: blrl .long 0x4d617820 .long 0x4f534427 .long 0x733a2025 .long 0x64000000 XYText: blrl .long 0x81695881 .long 0x5e59816A .long 0x00000000 original: branchl r4,0x802359c8 exit: ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/Load Random Stage Select On L Press.asm ================================================ #To be inserted at 8022f578 .include "../../Globals.s" .include "../../../m-ex/Header.s" rlwinm. r0, r3, 0, 25, 25 #CHECK FOR L beq exit #PLAY SFX li r3, 1 branchl r4,0x80024030 #SET FLAG IN RULES STRUCT li r0,2 #2 = frame data toggle load r3,0x804a04f0 stb r0, 0x0011 (r3) #SET SOMETHING li r0, 5 sth r0, -0x4AD8 (r13) #LOAD RSS branchl r3,0x80237410 #REMOVE CURRENT THINK FUNCTION mr r3,r29 branchl r4,0x80390228 branch r3,0x8022fb68 #branch r3,0x8022f5f4 exit: rlwinm. r0, r3, 0, 22, 22 ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/Load Toggles When Loaded With L .asm ================================================ #To be inserted at 80236e00 .include "../../Globals.s" .include "../../../m-ex/Header.s" #CHECK FLAG IN RULES STRUCT load r4,0x804a04f0 lbz r0, 0x0011 (r4) cmpwi r0,0x2 blt original #CUSTOM CODE rlwinm r0, r3, 0, 16, 31 #lwz r4,-0xdbc(rtoc) #get frame data toggle bits lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Off On: li r3,0x1 b exit Off: li r3,0x0 b exit original: branchl r4,0x80164250 exit: ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/Press L for OSD Indicator.asm ================================================ #To be inserted at 80231618 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set text,31 .set textproperties,30 .set originalRegister,29 .set VersionString,0x8040a58c backup ######################## ## Create Text Object ## ######################## #Backup r3 mr originalRegister,r3 #CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3 li r3,0 li r4,1 branchl r12,0x803a6754 #BACKUP STRUCT POINTER mr text,r3 #STORE POINTER stw text,-0x4EB4(r13) #SET TEXT SPACING TO TIGHT li r4,0x1 stb r4,0x49(text) #SET TEXT TO CENTER AROUND X LOCATION li r4,0x1 stb r4,0x4A(text) #GET PROPERTIES TABLE bl TEXTPROPERTIES mflr textproperties #Store Base Z Offset lfs f1,ZPos(textproperties) #Z offset stfs f1,0x8(text) #Scale Canvas Down lfs f1,CanvasScaling(textproperties) stfs f1,0x24(text) stfs f1,0x28(text) ####################### ## Version Indicator ## ####################### #Initialize Subtext lfs f1,XPos(textproperties) #X offset of text lfs f2,YPos(textproperties) #Y offset of text mr r3,text #struct pointer bl Text mflr r4 branchl r12,0x803a6b98 #Change scale mr r4,r3 mr r3,text lfs f1,TextScale(textproperties) lfs f2,TextScale(textproperties) branchl r12,Text_UpdateSubtextSize b end #**************************************************# TEXTPROPERTIES: blrl .set XPos,0x0 .set YPos,0x4 .set ZPos,0x8 .set TextScale,0xC .set CanvasScaling,0x10 #Version .float -250 #text X pos .float -241 #text Y pos .float 17 #Z offset .float 0.8 #text scale .float 0.035 #Canvas Scaling Text: blrl .string "L = OSD" .align 2 #**************************************************# end: mr r3,originalRegister restore lmw r14, 0x00E0 (sp) ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/Remove Press L for OSD Indicator.asm ================================================ #To be inserted at 80230974 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set text,31 .set textproperties,30 Original: stw r0, 0x0130 (r31) #Get Pointer lwz r3,-0x4EB4(r13) cmpwi r3,0 beq Exit #Remove Text branchl r12,Text_RemoveText Exit: ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/Remove Text When Leaving Custom RSS.asm ================================================ #To be inserted at 80236bbc .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 #CHECK FLAG IN RULES STRUCT load r3,0x804a04f0 lbz r0, 0x0011 (r3) cmpwi r0,0x2 blt original #REMOVE CUSTOM TEXT lwz r3,0x40(r31) #GET TEXT POINTER branchl r12,0x803a5cc4 #REMOVE TEXT lwz r3,0x44(r31) #GET TEXT POINTER branchl r12,0x803a5cc4 #REMOVE TEXT branch r12,0x80236be0 #EXIT original: li r25, 0 exit: ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/Return to Event Screen When Pressing Start.asm ================================================ #To be inserted at 80236128 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 #CHECK FLAG IN RULES STRUCT lbz r3, 0x0011 (r31) cmpwi r3,0x3 bne original LoadEvents: mr r3, r27 branchl r12,0x80390228 lwz r3, -0x77C0 (r13) lbz r3, 0x0535 (r3) #Get Last Event Match li r4,1 #No Delay On Text Loading branchl r12,0x8024e838 branch r12,0x80236164 original: li r3, 2 ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/Return to First Page When Loaded With L.asm ================================================ #To be inserted at 80235fe4 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 #CHECK FLAG IN RULES STRUCT load r3,0x804a04f0 lbz r0, 0x0011 (r3) cmpwi r0,0x2 blt original #DETERMINE WHERE TO RETURN cmpwi r0,0x2 beq LoadRulesFirstPage cmpwi r0,0x3 beq LoadEvents LoadRulesFirstPage: branchl r12,0x8023164c b exit LoadEvents: lwz r3, -0x77C0 (r13) lbz r3, 0x0535 (r3) #Get Last Event Match li r4,1 #No Delay On Text Loading branchl r12,0x8024e838 b exit original: branchl r12,0x802339fc exit: ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/Save Toggles When Loaded With L.asm ================================================ #To be inserted at 80235994 .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 #CHECK FLAG IN RULES STRUCT load r5,0x804a04f0 lbz r0, 0x0011 (r5) cmpwi r0,0x2 blt original #CUSTOM CODE rlwinm r0, r3, 0, 24, 31 #put menu selection in r0 #lwz r5,-0xdbc(rtoc) #get frame data toggle bits lwz r6,-0x77C0(r13) lwz r5,0x1F24(r6) rlwinm. r4, r4, 0, 24, 31 #check if turning on or off beq turnOff turnOn: li r4, 1 slw r0, r4, r0 or r0, r5, r0 stw r0,0x1F24(r6) #stw r0,-0xdbc(rtoc) #store frame data toggle bits b exit turnOff: li r4, 1 slw r0, r4, r0 andc r0, r5, r0 stw r0,0x1F24(r6) #stw r0,-0xdbc(rtoc) #store frame data toggle bits b exit original: branchl r5,0x801641e4 exit: ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/Set Flag on Leaving Custom RSS.asm ================================================ #To be inserted at 80235fcc .macro branchl reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctrl .endm .macro branch reg, address lis \reg, \address @h ori \reg,\reg,\address @l mtctr \reg bctr .endm .macro load reg, address lis \reg, \address @h ori \reg, \reg, \address @l .endm .macro loadf regf,reg,address lis \reg, \address @h ori \reg, \reg, \address @l stw \reg,-0x4(sp) lfs \regf,-0x4(sp) .endm .macro backup mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) .endm .macro restore lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 .endm .macro intToFloat reg,reg2 xoris \reg,\reg,0x8000 lis r18,0x4330 lfd f16,-0x7470(rtoc) # load magic number stw r18,0(r2) stw \reg,4(r2) lfd \reg2,0(r2) fsubs \reg2,\reg2,f16 .endm .set ActionStateChange,0x800693ac .set HSD_Randi,0x80380580 .set HSD_Randf,0x80380528 .set Wait,0x8008a348 .set Fall,0x800cc730 .set entity,31 .set player,31 #CHECK FLAG IN RULES STRUCT lbz r0, 0x0011 (r31) cmpwi r0,0x2 bge exit original: stb r30, 0x0011 (r31) exit: ================================================ FILE: ASM/training-mode/Onscreen Display/Toggle UI/XY To Adjust Max OSD.asm ================================================ #To be inserted at 802360f8 .include "../../Globals.s" .include "../../../m-ex/Header.s" .set Text,30 .set TextProp,28 .set MaxWindows,4-1 #Injected into CursorMovement Check backup #CHECK FLAG IN RULES STRUCT load r4,0x804a04f0 lbz r0, 0x0011 (r4) cmpwi r0,0x2 blt exit li r3,4 branchl r12,Inputs_GetPlayerInstantInputs lwz r20,-0x77C0(r13) #Get Memcard Data ############################################# CheckY: rlwinm. r0, r4, 0, 20, 20 #Check For Y beq CheckX #Increase Number lbz r3,0x1f28(r20) addi r3,r3,0x1 #Check If Over Max cmpwi r3,MaxWindows ble CheckY_Store #Loop Back to 0 li r3,0x0 CheckY_Store: stb r3,0x1f28(r20) b UpdateText ############################################# CheckX: rlwinm. r0, r4, 0, 21, 21 #Check For X beq CheckZ #Decrease Number lbz r3,0x1f28(r20) subi r3,r3,0x1 #Check If Over Max cmpwi r3,0 bge CheckX_Store #Loop Back to MaxWindows li r3,MaxWindows CheckX_Store: stb r3,0x1f28(r20) b UpdateText ############################################# CheckZ: rlwinm. r0, r4, 0, 27, 27 #Check For Z beq exit #Toggle option lbz r3,OSDRecommended(r20) xori r3,r3,1 stb r3,OSDRecommended(r20) #Get Options String bl FDDRecommendedOptions mflr r4 branchl r12,SearchStringTable #Update Text mr r6,r3 lwz r3,0x40(r29) #Get Text Structure lbz r4,0x49(r29) #Get Subtext ID bl FDDRecommended mflr r5 crclr 6 branchl r12,Text_UpdateSubtextContents b PlaySFX ############################################# UpdateText: lwz r3,0x40(r29) #Get Text Structure lbz r4,0x48(r29) #Get Subtext ID bl UpdateText_Text mflr r5 lbz r6,0x1f28(r20) addi r6,r6,0x1 branchl r12,0x803a70a0 b PlaySFX ############################################# UpdateText_Text: blrl .string "Max OSD's: %d" .align 2 FDDRecommended: blrl .string "Suggested OSDs: %s" .align 2 FDDRecommendedOptions: blrl .string "On" .string "Off" .align 2 ######################################## PlaySFX: li r3,2 branchl r12,0x80024030 exit: restore rlwinm. r0, r28, 0, 23, 23 ================================================ FILE: ASM/training-mode/Onscreen Display/Wavedash Display/Save Airdodge Y Angle.asm ================================================ #To be inserted at 80099b74 .include "../../Globals.s" .include "../../../m-ex/Header.s" #Get Airdodge Angle mr r3,r31 branchl r12,Joystick_Angle_Retrieve #Save angle stfs f1,TM_AirdodgeAngle(r31) Exit: addi r3, r29, 0 ================================================ FILE: ASM/training-mode/Onscreen Display/Wavedash Display/Wavedash Timing Display.asm ================================================ #To be inserted at 80099d7c .include "../../Globals.s" .include "../../../m-ex/Header.s" .set REG_FighterData,29 .set REG_FighterGObj,27 .set text,28 .set REG_Text,30 backup #Get Pointers mr REG_FighterGObj,r3 lwz REG_FighterData,0x2C(REG_FighterGObj) #CHECK IF OSD IS ENABLED li r0,OSD.Wavedash #wavedash ID lwz r4,-0x77C0(r13) lwz r4,0x1F24(r4) li r3, 1 slw r0, r3, r0 and. r0, r0, r4 beq Injection_Exit #Check if fighter is a subcharacter mr r3,REG_FighterData branchl r12,0x80005510 cmpwi r3,0x1 beq Injection_Exit #CHECK IF IT WAS A WAVEDASH (landed within 20 frames) lhz r3,TM_FramesinCurrentAS(REG_FighterData) cmpwi r3,20 bgt Injection_Exit #Get wavedash angle lfs f1,TM_AirdodgeAngle(REG_FighterData) bl GetWavedashAngle stfs f1,0x80(sp) PrintMessage: li r3,0 #Message Kind lbz r4,0xC(REG_FighterData) #Message Queue li r5,MSGCOLOR_WHITE bl Wavedash_String mflr r6 lhz r7,TM_FramesinCurrentAS(REG_FighterData) addi r7,r7,1 #1-index number Message_Display lwz r3,0x2C(r3) lwz REG_Text,MsgData_Text(r3) # Adjust Timing color lhz r3,TM_FramesinCurrentAS(REG_FighterData) cmpwi r3,0 bne AdjustAngleColor bl Floats mflr r4 addi r5,r4,0xC #Change Color mr r3,REG_Text #text pointer li r4,0 branchl r12,Text_ChangeTextColor AdjustAngleColor: # Adjust Angle color #Get Angle and Float Pointer bl Floats mflr r4 lfs f1, 0x80(sp) #Check For Perfect Angle lfs f2,0x0(r4) fcmpo cr0,f1,f2 blt Injection_Exit lfs f2,0x4(r4) fcmpo cr0,f1,f2 blt PerfectAngle lfs f2,0x8(r4) fcmpo cr0,f1,f2 bgt Injection_Exit OKAngle: addi r5,r4,0x10 b ChangeAngleColor PerfectAngle: addi r5,r4,0xC b ChangeAngleColor ChangeAngleColor: #Change Color mr r3,REG_Text #text pointer li r4,1 branchl r12,Text_ChangeTextColor b Injection_Exit /* #Create OSD Popup mr r3,REG_FighterData #backup REG_FighterData pointer li r4,60 #display for 60 frames li r5,0 #Area to Display (0-2) li r6,0 #Window ID (Unique to This Display) branchl r12,TextCreateFunction #create text custom function mr text,r3 #backup text pointer ########################### ## Print Wavedash Timing ## ########################### #Write out top line mr r3,text #text pointer bl TextASCII mflr r4 #get ASCII to print lhz r5,TM_FramesinCurrentAS(REG_FighterData) addi r5,r5,1 #1-index number lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B4 (rtoc) #default text X/Y crset 6 branchl r12,0x803a6b98 #Check if frame perfect lbz r4,0x680(REG_FighterData) cmpwi r4,0x0 bne DisplayWavedashAngle #Change Color mr r4,r3 #subtext id mr r3,text #text pointer load r5,0x8dff6eff stw r5,0xF0(sp) addi r5,sp,0xF0 branchl r12,0x803a74f0 */ ######################### ## Get Wavedash Angle ## ######################### GetWavedashAngle: backup #Convert angle to degrees lfs f2, -0x3D10 (rtoc) #0.017453 fdivs f2,f1,f2 #Multiply by 10 to preserve 1 decimal point li r3,10 bl IntToFloat fmuls f2,f1,f2 #Cast to int to floor fctiwz f1,f2 stfd f1,-0x4(sp) lwz r3,0x0(sp) #Cast back to float bl IntToFloat #Divide by 10 to get decimal point back fmr f2,f1 li r3,10 bl IntToFloat fdivs f2,f2,f1 #Normalize to 0-90, definitely could have handled this better but its w/e li r3,0 bl IntToFloat fcmpo cr0,f2,f1 bge TopQuadrant BottomQuadrant: li r3,-90 bl IntToFloat fcmpo cr0,f2,f1 bgt Quadrant4 Quadrant3: li r3,180 bl IntToFloat fadds f2,f1,f2 b SaveAngle Quadrant4: fneg f2,f2 b SaveAngle TopQuadrant: li r3,90 bl IntToFloat fcmpo cr0,f2,f1 bgt Quadrant2 Quadrant1: b SaveAngle Quadrant2: fneg f2,f2 li r3,180 bl IntToFloat fadds f2,f1,f2 b SaveAngle SaveAngle: fmr f1,f2 restore blr /* #Display Wavedash Angle mr r3,text #text pointer bl TextASCII2 mflr r4 #get ASCII to print lfs f1, -0x37B4 (rtoc) #default text X/Y lfs f2, -0x37B0 (rtoc) #shift down on Y axis lfs f3, 0x80(sp) crset 6 branchl r12,0x803a6b98 #Get Angle and Float Pointer bl Floats mflr r4 lfs f1, 0x80(sp) #Check For Perfect Angle lfs f2,0x0(r4) fcmpo cr0,f1,f2 blt Injection_Exit lfs f2,0x4(r4) fcmpo cr0,f1,f2 blt PerfectAngle lfs f2,0x8(r4) fcmpo cr0,f1,f2 bgt Injection_Exit OKAngle: load r5,0xfff000ff stw r5,0xF0(sp) b ChangeAngleColor PerfectAngle: load r5,0x8dff6eff stw r5,0xF0(sp) b ChangeAngleColor ChangeAngleColor: #Change Color mr r4,r3 #subtext id mr r3,text #text pointer addi r5,sp,0xF0 branchl r12,0x803a74f0 */ ######################### Wavedash_String: blrl .string "Wavedash Frame: %d\nAngle: %2.1f" .align 2 TextASCII: blrl .string "Wavedash Frame: %d" .align 2 TextASCII2: blrl .string "Angle: %2.1f" .align 2 Floats: blrl .float 16.8 #Great Angle Min .float 23.7 #Great Angle Max .float 30.5 #Good Angle Max .long 0x8dff6eff #Perfect Angle .long 0xfff000ff #Great Angle ############################## IntToFloat: mflr r0 stw r0, 0x4(r1) stwu r1,-0x100(r1) # make space for 12 registers stmw r20,0x8(r1) stfs f2,0x38(r1) lis r0, 0x4330 lfd f2, -0x6758 (rtoc) xoris r3, r3,0x8000 stw r0,0xF0(sp) stw r3,0xF4(sp) lfd f1,0xF0(sp) fsubs f1,f1,f2 #Convert To Float lfs f2,0x38(r1) lmw r20,0x8(r1) lwz r0, 0x104(r1) addi r1,r1,0x100 # release the space mtlr r0 blr ############################## Injection_Exit: mr r3,REG_FighterGObj restore lwz r4, -0x514C (r13) ================================================ FILE: Additional ISO Files/TvAmsTc.mth ================================================ [File too large to display: 37.2 MB] ================================================ FILE: Additional ISO Files/TvLC.mth ================================================ [File too large to display: 35.8 MB] ================================================ FILE: Additional ISO Files/TvLedDa.mth ================================================ [File too large to display: 51.7 MB] ================================================ FILE: Additional ISO Files/TvLedTc.mth ================================================ [File too large to display: 30.5 MB] ================================================ FILE: Additional ISO Files/TvPowSh.mth ================================================ [File too large to display: 28.0 MB] ================================================ FILE: Additional ISO Files/TvRvrsl.mth ================================================ [File too large to display: 20.4 MB] ================================================ FILE: Additional ISO Files/TvSDI.mth ================================================ [File too large to display: 18.8 MB] ================================================ FILE: Additional ISO Files/TvShDrp.mth ================================================ [File too large to display: 18.7 MB] ================================================ FILE: Build TM Codeset/Build Training Mode Codeset.bat ================================================ gecko build pause ================================================ FILE: Build TM Codeset/codes.json ================================================ { "settings": { "areIncludesRelativeFromFile": true }, "outputFiles": [ { "file": "..\\Additional ISO Files\\codes.gct" } ], "codes": [ { "name": "Training Mode Codset", "authors": [ "UnclePunch" ], "description": [ "Complete TM Codeset" ], "build": [ { "type": "injectFolder", "sourceFolder": "..\\ASM", "isRecursive": true }, { "type": "replaceCodeBlock", "address": "8042ABD8", "sourceFile": "..\\ASM\\training-mode\\Misc\\Edit Hyphen Texture.s", "annotation": "Edit Hyphen Texture" }, { "type": "replaceCodeBlock", "address": "8042a760", "sourceFile": "..\\ASM\\training-mode\\Misc\\Edit Carrot Texture.s", "annotation": "Edit Carrot Texture" }, { "type": "replaceCodeBlock", "address": "8040a58c", "sourceFile": "..\\ASM\\training-mode\\Misc\\Store Version Number.s", "annotation": "Version Number" }, { "type": "replaceCodeBlock", "address": "803ea6c8", "sourceFile": "..\\ASM\\training-mode\\Misc\\Overwrite Compile Date.s", "annotation": "Overwrite Compile Date" }, { "type": "replaceCodeBlock", "address": "803edc1c", "sourceFile": "..\\ASM\\Additional Codes\\QWERTY Keyboard.s", "annotation": "QWERTY Keyboard" } ] } ] } ================================================ FILE: Build TM Codeset/mac/codes.json ================================================ { "settings": { "areIncludesRelativeFromFile": true }, "outputFiles": [ { "file": "../../Additional ISO Files//codes.gct" } ], "codes": [ { "name": "Training Mode Codset", "authors": [ "UnclePunch" ], "description": [ "Complete TM Codeset" ], "build": [ { "type": "injectFolder", "sourceFolder": "../../ASM", "isRecursive": true }, { "type": "replaceCodeBlock", "address": "8042ABD8", "sourceFile": "../../ASM/Misc/Edit Hyphen Texture.s", "annotation": "Edit Hyphen Texture" }, { "type": "replaceCodeBlock", "address": "8040a58c", "sourceFile": "../../ASM/Misc/Store Version Number.s", "annotation": "Version Number" }, { "type": "replaceCodeBlock", "address": "803ea6c8", "sourceFile": "../../ASM/Misc/Overwrite Compile Date.s", "annotation": "Overwrite Compile Date" }, { "type": "replaceCodeBlock", "address": "803edc1c", "sourceFile": "../../ASM/Additional Codes/QWERTY Keyboard.s", "annotation": "QWERTY Keyboard" } ] } ] } ================================================ FILE: Build TM Codeset/mac/modifyStartDol.sh ================================================ output_dir=../../Additional\ ISO\ Files/Start.dol xdelta_patch_path=../../Build\ TM\ Start.dol/StartDolTMPatch.xdelta echo Creating Training Mode Start.dol... echo Mofifying Start.dol located at $1 xdelta3 -d -f -s $1 "${xdelta_patch_path}" "${output_dir}" echo Done! echo The file is located at ../../Additional ISO Files/Start.dol ================================================ FILE: Build TM Start.dol/Drag Melee v1.02 Start.dol Here.bat ================================================ @echo off echo ##################################### echo ## ## echo ## ## echo ## Training Mode Start.dol Creator ## echo ## ## echo ## ## echo ##################################### echo. echo Creating Training Mode Start.dol... echo. cd /d %~dp0 xdelta.exe -d -f -s %1 "patch.xdelta" "..\Additional ISO Files\Start.dol" echo. echo Done! echo The file is located in the "Additional ISO Files" folder! pause ================================================ FILE: MexTK/MexTK.exe.config ================================================ ================================================ FILE: MexTK/cssFunction.txt ================================================ OnCSSLoad ================================================ FILE: MexTK/evFunction.txt ================================================ Event_Init Event_Update Event_Think Event_Menu ================================================ FILE: MexTK/ftFunction.txt ================================================ onload ondeath onunknown move_logic specialn specialairn specials specialairs specialhi specialairhi speciallw specialairlw onabsorb onitempickup onmakeiteminvisible onmakeitemvisible onitemdrop onitemcatch onunknownitemrelated onunknowncharactermodelflags1 onunknowncharactermodelflags2 onhit onunknowneyetexturerelated onframe onactionstatechange onrespawn onmodelrender onshadowrender onunknownmultijump onactionstatechangewhileeyetextureischanged ontwoentrytable enterfloat enterdoublejump entertether onlanding onsmashf onsmashhi onsmashlw ================================================ FILE: MexTK/grFunction.txt ================================================ null_1 map_gobjs null_2 oninit onunk1 onload ongo onunk2 onTouchLine onunk4 ================================================ FILE: MexTK/include/archive.h ================================================ #ifndef MEX_H_ARCHIVE #define MEX_H_ARCHIVE #include "structs.h" #include "datatypes.h" struct ArchiveInfo { int file_size; // size of file int *reloc_offset; // pointer to relocation table offset? int reloc_num; // number of entries on the rleoc table int symbol_num; // total number of symbols int refsymbol_num; // number of reference symbols int archive_vers; // idk for sure sometimes 001B int unk1; // int unk2; // int *general_points; //0x20 = pointer to the "general points" int *reloc_table; //pointer to relocation table in memory int *symbols1; //pointer to symbol pointers and name offsets int *refsymmbols; //pointer to reference symbol info in memory int *symbols2; //pointer to symbol list in memory int *file_start; //pointer to the header of the dat }; ArchiveInfo *File_Load(char *filename); void File_LoadInitReturnSymbol(char *filename, void *ptr, ...); // input each symbol name pointer sequentially and terminate with 0; void *File_GetSymbol(void *archive, char *symbol); #endif ================================================ FILE: MexTK/include/audio.h ================================================ #ifndef MEX_H_AUDIO #define MEX_H_AUDIO #include "structs.h" #include "datatypes.h" char *Nametag_GetText(int tag_index); void Audio_ResetCache(int group_index); void Audio_QueueFileLoad(int group_index, u64 ssm_index); void Audio_UpdateCache(); void Audio_SyncLoadAll(); int BGM_GetMenuBGM(); void BGM_Play(int hpsID); #endif ================================================ FILE: MexTK/include/boneset.h ================================================ #ifndef MEX_H_BONESET #define MEX_H_BONESET #include "structs.h" /*** Structs ***/ #endif ================================================ FILE: MexTK/include/collision.h ================================================ #ifndef MEX_H_COLLISION #define MEX_H_COLLISION #include "structs.h" #include "datatypes.h" #include "obj.h" // ECB Flags #define ECB_GROUND 0x8000 #define ECB_CEIL 0x4000 #define ECB_WALLLEFT 0x800 #define ECB_WALLRIGHT 0x20 // Line Directions #define LINE_GROUND 1 #define LINE_CEIL 2 #define LINE_WALLRIGHT 4 #define LINE_WALLLEFT 8 /*** Structs ***/ struct ECBBones { float topY; float botY; Vec2 left; Vec2 right; }; struct DmgHazard { int x0; int dmg; int angle; int kb_growth; int x10; int kb_base; int element; int x1c; int sfx; }; struct CollData { GOBJ *gobj; // 0x0 Vec3 topN_Curr; // 0x4 Vec3 topN_CurrCorrect; // 0x10 Vec3 topN_Prev; // 0x1c Vec3 topN_Proj; // 0x28 int flags1; // 0x34 int coll_test; // 0x38, is the ID of the most recent collision test for this object int ignore_line; // 0x3c, ignores this line ID during collision int ledge_left; // 0x40, ledge ID in contact with int ledge_right; // 0x44, ledge ID in contact with int ignore_group; // 0x48 ignores this line group during collision int check_group; // 0x4c checks only this line group during collision int x50; // 0x50 int x54; // 0x54 int x58; // 0x58 int x5c; // 0x5c int x60; // 0x60 int x64; // 0x64 int x68; // 0x68 int x6c; // 0x6c int x70; // 0x70 int x74; // 0x74 int x78; // 0x78 int x7c; // 0x7c int x80; // 0x80 Vec2 ecbCurr_top; // 0x84 Vec2 ecbCurr_bot; // 0x8C Vec2 ecbCurr_right; // 0x94 Vec2 ecbCurr_left; // 0x9C Vec2 ecbCurrCorrect_top; // 0xA4 Vec2 ecbCurrCorrect_bot; // 0xAC Vec2 ecbCurrCorrect_right; // 0xB4 Vec2 ecbCurrCorrect_left; // 0xBC Vec2 ecbPrev_top; // 0xC4 Vec2 ecbPrev_bot; // 0xCC Vec2 ecbPrev_right; // 0xD4 Vec2 ecbPrev_left; // 0xDC Vec2 ecbProj_top; // 0xE4 Vec2 ecbProj_bot; // 0xEC Vec2 ecbProj_right; // 0xF4 Vec2 ecbProj_left; // 0xFC int x104; // 0x104 JOBJ *joint_1; // 0x108 JOBJ *joint_2; // 0x10c JOBJ *joint_3; // 0x110 JOBJ *joint_4; // 0x114 JOBJ *joint_5; // 0x118 JOBJ *joint_6; // 0x11c JOBJ *joint_7; // 0x120 int x124; // 0x124 int x128; // 0x128 int x12c; // 0x12c int flags; // 0x130 int envFlags; // 0x134 int envFlags_prev; // 0x138 int x13c; // 0x13c int x140; // 0x140 int x144; // 0x144 int x148; // 0x148 int ground_index; // 0x14c, ground u8 ground_info; // 0x150 u8 ground_unk; // 0x151 u8 ground_type; // 0x152, platform/ledgegrab u8 ground_mat; // 0x153, grass/ice etc Vec3 ground_slope; // 0x154 int rightwall_index; // 0x160 u8 rightwall_info; // 0x164 u8 rightwall_unk; // 0x165 u8 rightwall_type; // 0x166, platform/ledgegrab u8 rightwall_mat; // 0x167, grass/ice etc Vec3 rightwall_slope; // 0x168 int leftwall_index; // 0x174 u8 leftwall_info; // 0x178 u8 leftwall_unk; // 0x179 u8 leftwall_type; // 0x17A, platform/ledgegrab u8 leftwall_mat; // 0x17B, grass/ice etc Vec3 leftwall_slope; // 0x17C int ceil_index; // 0x188 u8 ceil_info; // 0x18C u8 ceil_unk; // 0x18D u8 ceil_type; // 0x18E, platform/ledgegrab u8 ceil_mat; // 0x18F, grass/ice etc Vec3 ceil_slope; // 0x190 int ecb_lock; // 0x19c }; struct CollGroupDesc // exists in stage file { u16 floor_start; u16 floor_num; u16 ceil_start; u16 ceil_num; u16 rwall_start; u16 rwall_num; u16 lwall_start; u16 lwall_num; u16 dyn_start; u16 dyn_num; Vec2 area_min; // 0x10 Vec2 area_max; // 0x18 u16 vert_start; u16 vert_num; }; struct CollGroup // exists in heap { CollGroup *next; CollGroupDesc *desc; int x8; // flags u16 ray_id; // id of the last raycast u16 xe; // flags Vec2 area_min; // 0x10 Vec2 area_max; // 0x18 JOBJ *jobj; // 0x20 void *cb_floor; // 0x24 void *map_data_floor; // 0x28 void *cb_ceil; // 0x2C void *map_data_ceil; // 0x30 int x34; // 0x34 }; struct CollLineInfo { s16 vert_prev; // 0x0 s16 vert_next; // 0x2 s16 line_prev; // 0x4 s16 line_next; // 0x6 s16 line_prev_altgroup; // 0x8 s16 line_next_altgroup; // 0xA u8 xc; u8 xd_1 : 1; // 0xD, 0x8000 u8 xd_2 : 1; // 0xD, 0x8000 u8 xd_3 : 1; // 0xD, 0x8000 u8 disabled : 1; // 0xD, 0x8000 u8 is_left : 1; // 0xD, 0x8000 u8 is_right : 1; // 0xD, 0x8000 u8 is_ceil : 1; // 0xD, 0x0200 u8 is_floor : 1; // 0xD, 0x8000 u8 xe_1 : 1; // 0xE, 0x8000 u8 xe_2 : 1; // 0xE, 0x8000 u8 xe_3 : 1; // 0xE, 0x8000 u8 xe_4 : 1; // 0xE, 0x8000 u8 xe_5 : 1; // 0xE, 0x8000 u8 is_drop : 1; // 0xE, 0x8000 u8 is_ledge : 1; // 0xE, 0x0200 u8 is_unk : 1; // 0xE, 0x8000 u8 material; }; struct CollLine { CollLineInfo *info; u8 x4; // 0x4 u8 x5_1 : 1; // 0x5 u8 x5_2 : 1; // 0x5 u8 x5_3 : 1; // 0x5 u8 x5_4 : 1; // 0x5 u8 x5_5 : 1; // 0x5 u8 x5_6 : 1; // 0x5 u8 x5_7 : 1; // 0x5 u8 is_enabled : 1; // 0x5 u8 x6; // 0x6 u8 x7 : 4; // 0x7 u8 is_rwall : 1; // 0x7, 0x8 u8 is_lwall : 1; // 0x7, 0x4 u8 is_ceil : 1; // 0x7, 0x2 u8 is_floor : 1; // 0x7, 0x1 }; struct CollVert { Vec2 pos_orig; Vec2 pos_curr; Vec2 pos_prev; }; struct CollDataStage { void *verts; int vert_num; void *lines; int line_num; u16 floor_start; u16 floor_num; u16 ceil_start; u16 ceil_num; u16 rwall_start; u16 rwall_num; u16 lwall_start; u16 lwall_num; u16 dyn_start; u16 dyn_num; void *groups; int group_num; }; /*** Functions ***/ void Coll_ECBCurrToPrev(CollData *coll_data); void Coll_InitECB(CollData *coll_data); int ECB_CollGround_PassLedge(CollData *ecb, ECBBones *bones); // returns is touching ground bool void ECB_CollAir(CollData *ecb, ECBBones *bones); void GrColl_GetLedgeLeft(int floor_index, Vec3 *pos); // this functon will crawl along the entire line sequence and find the end of the ledge void GrColl_GetLedgeRight(int floor_index, Vec3 *pos); // this functon will crawl along the entire line sequence and find the end of the ledge void GrColl_GetLedgeLeft2(int floor_index, Vec3 *pos); // this functon will crawl along the entire line sequence and find the end of the ledge void GrColl_GetLedgeRight2(int floor_index, Vec3 *pos); // this functon will crawl along the entire line sequence and find the end of the ledge int GrColl_RaycastGround(Vec3 *coll_pos, int *line_index, int *line_kind, Vec3 *unk1, Vec3 *unk2, Vec3 *unk3, Vec3 *unk4, void *cb, float fromX, float fromY, float toX, float toY, float unk5); // make unk5 int GrColl_CrawlGround(int line_index, Vec3 *pos, int *return_line, Vec3 *return_pos, int *return_flags, Vec3 *return_slope, float x_offset, float y_offset); // returns bool for if position on line series exists int GrColl_GetPosDifference(int line_index, Vec3 *pos, Vec3 *return_pos); int GrColl_GetLineInfo(int line_index, Vec3 *r4, void *r5, int *flags, Vec3 *return_slope); void GrColl_GetLineSlope(int line_index, Vec3 *return_slope); int GrColl_CheckIfLineEnabled(int line_index); static int *stc_colltest = R13 + (COLL_TEST); static CollGroup **stc_firstcollgroup = R13 + (-0x51DC); static CollGroup **stc_collgroup = R13 + (-0x51E0); static CollLine **stc_collline = R13 + (-0x51E4); static CollVert **stc_collvert = R13 + (-0x51E8); static CollDataStage **stc_colldata = R13 + (-0x51EC); #endif ================================================ FILE: MexTK/include/color.h ================================================ #ifndef MEX_H_COLOR #define MEX_H_COLOR #include "structs.h" #include "datatypes.h" /*** Structs ***/ struct GXColor { u8 r; u8 g; u8 b; u8 a; }; struct ColorOverlay { int timer; // 0x0 int pri; // 0x4 this colanims priority, lower = will persist int *ptr1; // 0x8 int loop; // 0xc int *ptr2; // 0x10 int x14; // 0x14 int *alloc; // 0x18 int x1c; // 0x1c int x20; // 0x20 int x24; // 0x24 int colanim; // 0x28, id for the color animation in effect GXColor hex; // 0x2C float color_red; // 0x30 float color_green; // 0x34 float color_blue; // 0x38 float color_alpha; // 0x3C float colorblend_red; // 0x40 float colorblend_green; // 0x44 float colorblend_blue; // 0x48 float colorblend_alpha; // 0x4C GXColor light_color; //0x50 float light_red; // 0x54 float light_green; // 0x58 float light_blue; // 0x5C float light_alpha; // 0x60 float lightblend_red; // 0x64 float lightblend_green; // 0x68 float lightblend_blue; // 0x6c float lightblend_alpha; // 0x70 float light_angle; // 0x74 float light_unk; // 0x78 unsigned char color_enable : 1; // 0x7c unsigned char flag2 : 1; // 0x7c unsigned char light_enable : 1; // 0x7c unsigned char flag4 : 1; // 0x7c unsigned char flag5 : 1; // 0x7c unsigned char flag6 : 1; // 0x7c unsigned char flag7 : 1; // 0x7c unsigned char flag8 : 1; // 0x7c }; #endif ================================================ FILE: MexTK/include/css.h ================================================ #ifndef MEX_H_CSS #define MEX_H_CSS #include "structs.h" #include "datatypes.h" #include "fighter.h" #include "scene.h" /*** Structs ***/ struct CSSBackup { u8 fighter_prev; //0x0 u8 x1; //0x1 u8 fighter; //0x2 u8 costume; //0x3 u8 nametag; //0x4 u8 event; //0x5 u8 port; //0x6 u8 x7; //0x7 u8 x8; //0x8 u8 x9; //0x9 u8 xA; //0xA }; struct MnSelectChrDataTable { COBJDesc *cobj; void *lobj1; void *lobj2; void *fog; JOBJAnimSet bg; JOBJAnimSet cursor; JOBJAnimSet puck; JOBJAnimSet vsmenu; JOBJAnimSet start; JOBJAnimSet camdoor; JOBJAnimSet solomenu; JOBJAnimSet solooption; JOBJAnimSet cpudoor; }; enum CSSCursorState { SLCHRCUR_POINT, SLCHRCUR_HOLD, SLCHRCUR_OPEN, SLCHRCUR_HIDDEN, }; struct CSSCursor { GOBJ *gobj; u8 port; u8 state; // 0x5, 0x0 = Pointing / 0x1 = Holding Puck / 0x2 = Open Hand / 0x3 = Hidden/Unplugged u8 puck; // 0x6, puck index being held u8 x7; // 0x7, u16 x8; u16 exit_timer; // 0xa, frames held B Vec2 pos; // 0xc-0x10 }; struct CSSPuck { GOBJ *gobj; // 0x0, u8 port; // 0x4, port this puck belongs to u8 state; // 0x5, 0x0 = Pointing / 0x1 = Holding Puck / 0x2 = Open Hand / 0x3 = Hidden/Unplugged u8 held; // 0x6, port that this puck is being held by u8 anim_timer; // 0x7, Animation Timer. resets animation when this hits 39, checked for @ 80262790 Vec2 pos_proj; // 0x8, where the puck should be Vec2 pos_correct; // 0x10, where the puck is corrected to }; struct MnSlChrIcon { u8 ft_hudindex; // used for getting combo count @ 8025c0c4 u8 ft_kind; // icons external ID u8 state; // Dictates whether icon can be chosen. 0x0 = Not Unlocked, 0x1 = Unlocked (temp value), 0x2 = Unlocked and Displayed u8 anim_timer; // is made to be 0xC when the character is chosen. u8 joint_id; // icon background jobj ID u8 joint2_id; // used to icons JObj pointer int sfx; // 0x8, float bound_l; // 0xC float bound_r; // 0x10 float bound_u; // 0x14 float bound_d; // 0x18 }; enum DoorState { DOOR_HMN, DOOR_CPU, DOOR_UNK, DOOR_CLOSED, }; struct MnSlChrDoor { u8 x0; u8 csp_joint; u8 x2; u8 joint_id; // 0x3 u8 x4; u8 x5; // nametag window joint id u8 x6; u8 cpuslider_joint; // 0x7 u8 slider2_joint; //0x8 u8 x9; u8 dooranim_timer; // 0xa u8 state; // 0x0 = HMN, 0x1 = CPU, 0x3 = Closed u8 xc; u8 costume; // 0xd u8 sel_icon; // 0xe, icon this player has selected u8 xf; u8 x10; u8 slideranim_timer; u8 x12; u8 x13; float button_l; // HMN button bound float button_t; // HMN button bound float button_u; // HMN button bound float button_d; // HMN button bound }; struct MnSlChrTagData { Text *name; Text *namelist; // 0x4, used when opening the tag window float x8; // 0x8 float scroll_amt; // xC, Text Y Offset to scroll up each frame float scroll_force; //x10 int timer; // x14, state timer u8 next_tag; // 0x18, index of next empty tag u8 port; u8 state; // 0x1a, is nametag window open bool u8 use_tag; // 0x1b, is using a nametag bool }; struct MnSlChrTag { MnSlChrTagData *tag_data; u8 x4; u8 list_joint; u8 name_joint; u8 x7; u8 kostartext_joint; u8 x9; u8 xa; u8 xb; }; struct MnSlChrKOStar { Text *text; float x4; u8 joint; int xc; int x10; int x14; int x18; int x1c; }; struct MnSlChrData { u8 GaWName[0x1C]; // 0x0 u8 x1C[0xC0]; // 0x1c MnSlChrIcon icons[25 + 1]; // 0xDC MnSlChrDoor doors[4]; // 0x3b4 MnSlChrTag tags[4]; // 0x444 u8 x474; // 0x474 u8 x475; // 0x475 u8 x476; // 0x476 u8 x477; // 0x477 u8 x478; // 0x478 u8 x479; // 0x479 u8 x47a; // 0x47a u8 x47b; // 0x47b u8 x47c; // 0x47c u8 x47d; // 0x47d u8 x47e; // 0x47e u8 x47f; // 0x47f u8 x480; // 0x480 u8 x481; // 0x481 u8 x482; // 0x482 u8 x483; // 0x483 u8 x484[0x40]; // 0x484 MnSlChrKOStar ko_stars[4]; // 0x4c4 }; struct VSMinorData { u16 x0; u8 css_kind; // 0 = VS u8 exit_kind; // 1 = advance, 2 = leave void *ko_data; // used for displaying KO stars on CSS ScDataVS vs_data; }; /*** Variables ***/ static MnSlChrData *stc_css_data = 0x803f0a48; static VSMinorData **stc_css_minorscene = R13 + (-0x49F0); static u8 *stc_css_regtagnum = R13 + (-0x49A8); // number of registered tags static u8 *stc_css_49b0 = R13 + (-0x49B0); static u8 *stc_css_49a7 = R13 + (-0x49A7); static u8 *stc_css_49a8 = R13 + (-0x49A8); static ArchiveInfo **stc_css_archive = R13 + (-0x49D0); static ArchiveInfo **stc_css_menuarchive = R13 + (-0x49CC); static u8 *stc_css_49ac = R13 + (-0x49AC); static GOBJ **stc_css_menugobj = R13 + (-0x49E4); static JOBJ **stc_css_menumodel = R13 + (-0x49E0); static CSSCursor **stc_css_cursors = 0x804a0bc0; static CSSPuck **stc_css_pucks = 0x804a0bd0; static u8 *stc_css_hmnport = R13 + (-0x49B0); static u8 *stc_css_cpuport = R13 + (-0x49AF); static u8 *stc_css_delay = R13 + (-0x49AE); static u8 *stc_css_maxply = R13 + (-0x49AB); static u8 *stc_css_singeplyport = R13 + (-0x4DE0); static u8 *stc_css_49f0 = R13 + (-0x49f0); static int *stc_css_49c0 = R13 + (-0x49c0); static int *stc_css_49c4 = R13 + (-0x49c4); static int *stc_css_49b8 = R13 + (-0x49b8); static int *stc_css_49bc = R13 + (-0x49bc); static int *stc_css_bgtimer = R13 + (-0x49b4); static u8 *stc_css_hasreleasedb = R13 + (-0x49ad); static u8 *stc_css_exitkind = R13 + (-0x49aa); static u8 *stc_css_49a9 = R13 + (-0x49a9); static MnSelectChrDataTable **stc_css_datatable = R13 + (-0x49EC); static COBJDesc **stc_css_cobjdesc = R13 + (-0x4ADC); static GOBJ **stc_css_camgobj = R13 + (-0x49E8); static HSD_Pad *stc_css_pad = 0x804c20bc; static u8 *stc_css_unkarr = 0x804d50c8; /*** Functions ***/ void MainMenu_CamRotateThink(GOBJ *gobj); int CSS_GetNametagRumble(int player, u8 tag); void CSS_InitPlayerData(PlayerData *player); void CSS_CameraRotateThink(GOBJ *gobj); void CSS_MenuModelThink(GOBJ *gobj); void CSS_CursorThink(GOBJ *gobj); void CSS_PuckThink(GOBJ *gobj); void CSS_TagThink(GOBJ *gobj); void CSS_UpdateRulesText(); void CSS_UpdateKOStars(int ply, int unk); void CSS_StartThink(GOBJ *gobj); int CSS_GetHandicapValue(int ply, int nametag_id); void CSS_SetModeTexture(int css_kind); int CSS_ReturnPuck(int ply); int CSS_SetRandomFighter(int ply, int unk); void CSS_UpdateCSP(int ply); int CSS_GetCostumeNum(int ext_id); void CSS_PlayFighterName(int ext_id); void CSS_CostumeChange(int port, int button_down); void CSS_UpdateCSPTexture(int port, int costume, int is_none); #endif ================================================ FILE: MexTK/include/datatypes.h ================================================ #ifndef MEX_H_DATATYPES #define MEX_H_DATATYPES #include "structs.h" #include "offsets.h" // Data types typedef signed char s8; typedef signed short s16; typedef signed int s32; typedef signed long long s64; typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; typedef float f32; typedef double f64; // PadGet Types #define PADGET_MASTER 0 #define PADGET_ENGINE 1 // Matrix definition typedef float Mtx[3][4]; typedef float (*MtxPtr)[4]; // Ghidrish #define undefined8 long #define undefined4 int #define byte char #define uint unsigned int // bool lingo #define true 1 #define false 0 // Other Macros #define RTOC_PTR(offset) *(void **)(0x804df9e0 + offset) #define R13_PTR(offset) *(void **)(R13 + offset) #define R13_INT(offset) *(int *)(R13 + offset) #define R13_U8(offset) *(u8 *)(R13 + offset) #define R13_FLOAT(offset) *(float *)(R13 + offset) #define AS_FLOAT(num) *(float *)&num #define AS_INT(num) *(int *)&num #define ACCESS_INT(addr) *(int *)(addr) #define ACCESS_U8(addr) *(u8 *)(addr) #define ACCESS_PTR(addr) *(void **)(addr) /*** Structs ***/ struct Vec2 { float X; float Y; }; struct Vec3 { float X; float Y; float Z; }; struct Vec4 { float X; float Y; float Z; float W; }; #endif ================================================ FILE: MexTK/include/devtext.h ================================================ #ifndef MEX_H_DEVTEXT #define MEX_H_DEVTEXT #include "structs.h" #include "color.h" /*** Structs ***/ struct DevText { int x0; // 0x0 int x4; // 0x4 int x8; // 0x8 int xc; // 0xc GXColor bg_color; // 0x10 int x14; // 0x14 int x18; // 0x18 int x1c; // 0x1c int x20; // 0x20 char x24; // 0x24 char x25; // 0x25 char show_text : 1; // 0x26 char show_background : 1; // 0x26 char show_cursor : 1; // 0x26 char x27; // 0x27 int x28; // 0x28 int x2c; // 0x2c DevText *next; // 0x30 int x34; // 0x34 int x38; // 0x38 int x3c; // 0x3c int x40; // 0x40 int x44; // 0x44 int x48; // 0x48 int x4c; // 0x4c int x50; // 0x50 int x54; // 0x54 int x58; // 0x58 int x5c; // 0x5c }; /*** Functions ***/ DevText *DevelopText_CreateDataTable(int unk1, int x, int y, int width, int height, void *alloc); void DevelopText_Activate(void *unk, DevText *text); void DevelopText_AddString(DevText *text, ...); void DevelopText_EraseAllText(DevText *text); void DevelopText_StoreBGColor(DevText *text, u8 *RGBA); void DevelopText_HideText(DevText *text); void DevelopText_HideBG(DevText *text); void DevelopText_StoreTextScale(DevText *text, float x, float y); void Develop_DrawSphere(float size, Vec3 *pos1, Vec2 *pos2, GXColor *diffuse, GXColor *ambient); int *stc_dblevel = R13 + (-0x6C98); #endif ================================================ FILE: MexTK/include/effects.h ================================================ #ifndef MEX_H_EFFECTS #define MEX_H_EFFECTS #include "structs.h" #include "datatypes.h" #include "obj.h" #define PTCL_LINKMAX 16 /*** Structs ***/ struct Effect { GOBJ *child; GOBJ *gobj; int x8; int xc; void *callback; int x14; int x18; int x1c; float x20; short lifetime; char x26; char x27; char x28; char x29; }; struct Particle { int x0; int x4; int x8; int xc; int x10; int x14; int x18; int x1c; int x20; int x24; int x28; int x2c; int x30; int x34; int x38; int x3c; int x40; int x44; int x48; int x4c; int x50; GeneratorAppSRT *param; }; struct ptclGen // allocated at 8039d9c8 { struct ptclGen *next; // 0x0 int kind; // x4 float random; // x8 float xc; // xc JOBJ *joint; // x10 u16 genlife; // x14 u16 type; // x16 u8 ef_file; // x18 u8 link_no; // x19, r3 for 8039f05c u8 tex_group; // x1a u8 x1b; // x1b u16 instance; // x1c u16 life; // x1e void *track; // x20, pointer to track data Vec3 pos; // x24 Vec3 vel; // x30 float gravity; // x3c float friction; // x40 float size; // x44 float radius; // x48 float angle; // x4c int timer; // x50 void *mtx; // x54, points to an SRT mtx used for transforming the generator while attached to a joint }; struct GeneratorAppSRT // allocated at 803a42b0 { int x0; //x0 int x4; //x4 int x8; //x8 int xc; //xc int x10; //x10 int x14; //x14 int x18; //x18 int x1c; //x1c int x20; //x20 Vec3 scale; //x24 int x30; //x30 int x34; //x34 int x38; //x38 int x3c; //x3c int x40; //x40 int x44; //x44 int x48; //x48 int x4c; //x4c int x50; //x50 int x54; //x54 int x58; //x58 int x5c; //x5c int x60; //x60 int x64; //x64 int x68; //x68 int x6c; //x6c int x70; //x70 int x74; //x74 int x78; //x78 int x7c; //x7c int x80; //x80 int x84; //x84 int x88; //x88 int x8c; //x8c int x90; //x90 int x94; //x94 int x98; //x98 int x9c; //x9c int xa0; //xa0 u16 xa2; }; struct Particle2 // created at 80398c90. dont feel like labelling this, offsets are @ 80398de4 { struct Particle2 *next; // 0x0 u32 kind; // 0x4 u8 bank; // 0x8 u8 texGroup; // 0x9 u8 poseNum; // 0xa u8 palNum; // 0xb u16 sizeCount; // 0xc u16 primColCount; // 0xe u16 envColCount; // 0x10 u8 primCol[4]; // 0x12 u8 envCol[4]; // 0x16 u16 cmdWait; // 0x1a u8 loopCount; // 0x1c u8 linkNo; // 0x1d u16 idnum; // 0x1e void *cmdList; // 0x20 u16 cmdPtr; // 0x24 u16 cmdMarkPtr; // 0x26 u16 cmdLoopPtr; // 0x28 u16 life; // 0x2a Vec3 v; // 0x2C float grav; // 0x38 float fric; // 0x3C Vec3 pos; // 0x40 float size; // 0x4C float rotate; // 0x50 u16 aCmpCount; // 0x54 u8 aCmpMode; // 0x56 u8 aCmpParam1; // 0x57 u8 aCmpParam2; // 0x58 void *x5c; void *x60; void *x64; void *x68; void *x6c; void *x70; void *x74; void *x78; void *x7c; void *x80; void *x84; void *x88; void *gen; void *x90; // theres more but i got bored, rest are here courtesy of psilupan: https://pastebin.com/raw/yQdjypW0 }; /*** Functions ***/ Effect *Effect_SpawnSync(int gfx_id, ...); void Effect_SpawnAsync(GOBJ *fighter, Effect *ptr, int type, int gfx_id, ...); void Effect_SpawnFtEffectLookup(GOBJ *gobj, int gfx_id, int bone, int unk, int destroy_on_leave, ...); void Effect_SpawnItEffectLookup(GOBJ *gobj, int gfx_id, int bone, Vec3 *offset, Vec3 *scatter, int unk3); void Effect_SpawnItEffect(GOBJ *gobj, int gfx_id); void Effect_DestroyAll(GOBJ *fighter); void Particle_DestroyAll(JOBJ *jobj); void Effect_PauseAll(GOBJ *fighter); void Effect_ResumeAll(GOBJ *fighter); int psRemoveParticleAppSRT(Particle2 *ptcl); void psDeletePntJObjwithParticle(Particle2 *ptcl); ptclGen *psKillGenerator(ptclGen *gen, ptclGen *unk); u16 *stc_ptclnum = R13 + (-0x3DBE); // number of pctls alive Particle2 **stc_ptcl = 0x804d0908; // last created ptcl ptclGen **stc_ptclgen = R13 + (-0x3DA4); // last created gen ptclGen **stc_ptclgencurr = R13 + (-0x3DA8); u16 *stc_ptclgennum = R13 + (-0x3DC0); #endif ================================================ FILE: MexTK/include/fighter.h ================================================ #ifndef MEX_H_FIGHTER #define MEX_H_FIGHTER #include "structs.h" #include "datatypes.h" #include "obj.h" #include "color.h" #include "effects.h" #include "match.h" #include "collision.h" // action state flags #define ASC_PRESERVE_FASTFALL 0x1 #define ASC_PRESERVE_GFX 0x2 #define ASC_PRESERVE_EYE 0x80 #define ASC_1000 0x1000 #define ASC_SKIP_SCRIPT 0x4000 #define ASC_PRESERVE_VISIBILITY 0x40000 #define ASC_80000 0x80000 #define ASC_400000 0x400000 #define ASC_4000000 0x4000000 #define ASC_8000000 0x8000000 #define ASC_NOANIM 0x20000000 enum FtCommonBone { TopN, TransN, XRotN, YRotN, HipN, WaistN, LLegJA, LLegJ, LKneeJ, LFootJA, LFootJ, RLegJA, RLegJ, RKneeJ, RFootJA, RFootJ, WaistN2, BustN, LShoulderN, LShoulderJA, LShoulderJ, LArmJ, LHandN, L1stNa, L1stNb, L2ndNa, L2ndNb, L3rdNa, L3rdNb, L4thNa, L4thNb, LHaveN, LThumbNa, LThumbNb, NeckN, HeadN, RShoulderN, RShoulderJA, RShoulderJ, RArmJ, RHandN, R1stNa, R1stNb, R2ndNa, R2ndNb, R3rdNa, R3rdNb, R4thNa, R4thNb, RHaveN, RThumbNa, RThumbNb, ThrowN, Extra }; // Fighter States *to-do, make this an enum #define ASID_DEADDOWN 0X00 #define ASID_DEADLEFT 0X01 #define ASID_DEADRIGHT 0X02 #define ASID_DEADUP 0X03 #define ASID_DEADUPSTAR 0X04 #define ASID_DEADUPSTARICE 0X05 #define ASID_DEADUPFALL 0X06 #define ASID_DEADUPFALLHITCAMERA 0X07 #define ASID_DEADUPFALLHITCAMERAFLAT 0X08 #define ASID_DEADUPFALLICE 0X09 #define ASID_DEADUPFALLHITCAMERAICE 0X0A #define ASID_SLEEP 0X0B #define ASID_REBIRTH 0X0C #define ASID_REBIRTHWAIT 0X0D #define ASID_WAIT 0X0E #define ASID_WALKSLOW 0X0F #define ASID_WALKMIDDLE 0X10 #define ASID_WALKFAST 0X11 #define ASID_TURN 0X12 #define ASID_TURNRUN 0X13 #define ASID_DASH 0X14 #define ASID_RUN 0X15 #define ASID_RUNDIRECT 0X16 #define ASID_RUNBRAKE 0X17 #define ASID_KNEEBEND 0X18 #define ASID_JUMPF 0X19 #define ASID_JUMPB 0X1A #define ASID_JUMPAERIALF 0X1B #define ASID_JUMPAERIALB 0X1C #define ASID_FALL 0X1D #define ASID_FALLF 0X1E #define ASID_FALLB 0X1F #define ASID_FALLAERIAL 0X20 #define ASID_FALLAERIALF 0X21 #define ASID_FALLAERIALB 0X22 #define ASID_FALLSPECIAL 0X23 #define ASID_FALLSPECIALF 0X24 #define ASID_FALLSPECIALB 0X25 #define ASID_DAMAGEFALL 0X26 #define ASID_SQUAT 0X27 #define ASID_SQUATWAIT 0X28 #define ASID_SQUATRV 0X29 #define ASID_LANDING 0X2A #define ASID_LANDINGFALLSPECIAL 0X2B #define ASID_ATTACK11 0X2C #define ASID_ATTACK12 0X2D #define ASID_ATTACK13 0X2E #define ASID_ATTACK100START 0X2F #define ASID_ATTACK100LOOP 0X30 #define ASID_ATTACK100END 0X31 #define ASID_ATTACKDASH 0X32 #define ASID_ATTACKS3HI 0X33 #define ASID_ATTACKS3HIS 0X34 #define ASID_ATTACKS3S 0X35 #define ASID_ATTACKS3LWS 0X36 #define ASID_ATTACKS3LW 0X37 #define ASID_ATTACKHI3 0X38 #define ASID_ATTACKLW3 0X39 #define ASID_ATTACKS4HI 0X3A #define ASID_ATTACKS4HIS 0X3B #define ASID_ATTACKS4S 0X3C #define ASID_ATTACKS4LWS 0X3D #define ASID_ATTACKS4LW 0X3E #define ASID_ATTACKHI4 0X3F #define ASID_ATTACKLW4 0X40 #define ASID_ATTACKAIRN 0X41 #define ASID_ATTACKAIRF 0X42 #define ASID_ATTACKAIRB 0X43 #define ASID_ATTACKAIRHI 0X44 #define ASID_ATTACKAIRLW 0X45 #define ASID_LANDINGAIRN 0X46 #define ASID_LANDINGAIRF 0X47 #define ASID_LANDINGAIRB 0X48 #define ASID_LANDINGAIRHI 0X49 #define ASID_LANDINGAIRLW 0X4A #define ASID_DAMAGEHI1 0X4B #define ASID_DAMAGEHI2 0X4C #define ASID_DAMAGEHI3 0X4D #define ASID_DAMAGEN1 0X4E #define ASID_DAMAGEN2 0X4F #define ASID_DAMAGEN3 0X50 #define ASID_DAMAGELW1 0X51 #define ASID_DAMAGELW2 0X52 #define ASID_DAMAGELW3 0X53 #define ASID_DAMAGEAIR1 0X54 #define ASID_DAMAGEAIR2 0X55 #define ASID_DAMAGEAIR3 0X56 #define ASID_DAMAGEFLYHI 0X57 #define ASID_DAMAGEFLYN 0X58 #define ASID_DAMAGEFLYLW 0X59 #define ASID_DAMAGEFLYTOP 0X5A #define ASID_DAMAGEFLYROLL 0X5B #define ASID_LIGHTGET 0X5C #define ASID_HEAVYGET 0X5D #define ASID_LIGHTTHROWF 0X5E #define ASID_LIGHTTHROWB 0X5F #define ASID_LIGHTTHROWHI 0X60 #define ASID_LIGHTTHROWLW 0X61 #define ASID_LIGHTTHROWDASH 0X62 #define ASID_LIGHTTHROWDROP 0X63 #define ASID_LIGHTTHROWAIRF 0X64 #define ASID_LIGHTTHROWAIRB 0X65 #define ASID_LIGHTTHROWAIRHI 0X66 #define ASID_LIGHTTHROWAIRLW 0X67 #define ASID_HEAVYTHROWF 0X68 #define ASID_HEAVYTHROWB 0X69 #define ASID_HEAVYTHROWHI 0X6A #define ASID_HEAVYTHROWLW 0X6B #define ASID_LIGHTTHROWF4 0X6C #define ASID_LIGHTTHROWB4 0X6D #define ASID_LIGHTTHROWHI4 0X6E #define ASID_LIGHTTHROWLW4 0X6F #define ASID_LIGHTTHROWAIRF4 0X70 #define ASID_LIGHTTHROWAIRB4 0X71 #define ASID_LIGHTTHROWAIRHI4 0X72 #define ASID_LIGHTTHROWAIRLW4 0X73 #define ASID_HEAVYTHROWF4 0X74 #define ASID_HEAVYTHROWB4 0X75 #define ASID_HEAVYTHROWHI4 0X76 #define ASID_HEAVYTHROWLW4 0X77 #define ASID_SWORDSWING1 0X78 #define ASID_SWORDSWING3 0X79 #define ASID_SWORDSWING4 0X7A #define ASID_SWORDSWINGDASH 0X7B #define ASID_BATSWING1 0X7C #define ASID_BATSWING3 0X7D #define ASID_BATSWING4 0X7E #define ASID_BATSWINGDASH 0X7F #define ASID_PARASOLSWING1 0X80 #define ASID_PARASOLSWING3 0X81 #define ASID_PARASOLSWING4 0X82 #define ASID_PARASOLSWINGDASH 0X83 #define ASID_HARISENSWING1 0X84 #define ASID_HARISENSWING3 0X85 #define ASID_HARISENSWING4 0X86 #define ASID_HARISENSWINGDASH 0X87 #define ASID_STARRODSWING1 0X88 #define ASID_STARRODSWING3 0X89 #define ASID_STARRODSWING4 0X8A #define ASID_STARRODSWINGDASH 0X8B #define ASID_LIPSTICKSWING1 0X8C #define ASID_LIPSTICKSWING3 0X8D #define ASID_LIPSTICKSWING4 0X8E #define ASID_LIPSTICKSWINGDASH 0X8F #define ASID_ITEMPARASOLOPEN 0X90 #define ASID_ITEMPARASOLFALL 0X91 #define ASID_ITEMPARASOLFALLSPECIAL 0X92 #define ASID_ITEMPARASOLDAMAGEFALL 0X93 #define ASID_LGUNSHOOT 0X94 #define ASID_LGUNSHOOTAIR 0X95 #define ASID_LGUNSHOOTEMPTY 0X96 #define ASID_LGUNSHOOTAIREMPTY 0X97 #define ASID_FIREFLOWERSHOOT 0X98 #define ASID_FIREFLOWERSHOOTAIR 0X99 #define ASID_ITEMSCREW 0X9A #define ASID_ITEMSCREWAIR 0X9B #define ASID_DAMAGESCREW 0X9C #define ASID_DAMAGESCREWAIR 0X9D #define ASID_ITEMSCOPESTART 0X9E #define ASID_ITEMSCOPERAPID 0X9F #define ASID_ITEMSCOPEFIRE 0XA0 #define ASID_ITEMSCOPEEND 0XA1 #define ASID_ITEMSCOPEAIRSTART 0XA2 #define ASID_ITEMSCOPEAIRRAPID 0XA3 #define ASID_ITEMSCOPEAIRFIRE 0XA4 #define ASID_ITEMSCOPEAIREND 0XA5 #define ASID_ITEMSCOPESTARTEMPTY 0XA6 #define ASID_ITEMSCOPERAPIDEMPTY 0XA7 #define ASID_ITEMSCOPEFIREEMPTY 0XA8 #define ASID_ITEMSCOPEENDEMPTY 0XA9 #define ASID_ITEMSCOPEAIRSTARTEMPTY 0XAA #define ASID_ITEMSCOPEAIRRAPIDEMPTY 0XAB #define ASID_ITEMSCOPEAIRFIREEMPTY 0XAC #define ASID_ITEMSCOPEAIRENDEMPTY 0XAD #define ASID_LIFTWAIT 0XAE #define ASID_LIFTWALK1 0XAF #define ASID_LIFTWALK2 0XB0 #define ASID_LIFTTURN 0XB1 #define ASID_GUARDON 0XB2 #define ASID_GUARD 0XB3 #define ASID_GUARDOFF 0XB4 #define ASID_GUARDSETOFF 0XB5 #define ASID_GUARDREFLECT 0XB6 #define ASID_DOWNBOUNDU 0XB7 #define ASID_DOWNWAITU 0XB8 #define ASID_DOWNDAMAGEU 0XB9 #define ASID_DOWNSTANDU 0XBA #define ASID_DOWNATTACKU 0XBB #define ASID_DOWNFOWARDU 0XBC #define ASID_DOWNBACKU 0XBD #define ASID_DOWNSPOTU 0XBE #define ASID_DOWNBOUNDD 0XBF #define ASID_DOWNWAITD 0XC0 #define ASID_DOWNDAMAGED 0XC1 #define ASID_DOWNSTANDD 0XC2 #define ASID_DOWNATTACKD 0XC3 #define ASID_DOWNFOWARDD 0XC4 #define ASID_DOWNBACKD 0XC5 #define ASID_DOWNSPOTD 0XC6 #define ASID_PASSIVE 0XC7 #define ASID_PASSIVESTANDF 0XC8 #define ASID_PASSIVESTANDB 0XC9 #define ASID_PASSIVEWALL 0XCA #define ASID_PASSIVEWALLJUMP 0XCB #define ASID_PASSIVECEIL 0XCC #define ASID_SHIELDBREAKFLY 0XCD #define ASID_SHIELDBREAKFALL 0XCE #define ASID_SHIELDBREAKDOWNU 0XCF #define ASID_SHIELDBREAKDOWND 0XD0 #define ASID_SHIELDBREAKSTANDU 0XD1 #define ASID_SHIELDBREAKSTANDD 0XD2 #define ASID_FURAFURA 0XD3 #define ASID_CATCH 0XD4 #define ASID_CATCHPULL 0XD5 #define ASID_CATCHDASH 0XD6 #define ASID_CATCHDASHPULL 0XD7 #define ASID_CATCHWAIT 0XD8 #define ASID_CATCHATTACK 0XD9 #define ASID_CATCHCUT 0XDA #define ASID_THROWF 0XDB #define ASID_THROWB 0XDC #define ASID_THROWHI 0XDD #define ASID_THROWLW 0XDE #define ASID_CAPTUREPULLEDHI 0XDF #define ASID_CAPTUREWAITHI 0XE0 #define ASID_CAPTUREDAMAGEHI 0XE1 #define ASID_CAPTUREPULLEDLW 0XE2 #define ASID_CAPTUREWAITLW 0XE3 #define ASID_CAPTUREDAMAGELW 0XE4 #define ASID_CAPTURECUT 0XE5 #define ASID_CAPTUREJUMP 0XE6 #define ASID_CAPTURENECK 0XE7 #define ASID_CAPTUREFOOT 0XE8 #define ASID_ESCAPEF 0XE9 #define ASID_ESCAPEB 0XEA #define ASID_ESCAPE 0XEB #define ASID_ESCAPEAIR 0XEC #define ASID_REBOUNDSTOP 0XED #define ASID_REBOUND 0XEE #define ASID_THROWNF 0XEF #define ASID_THROWNB 0XF0 #define ASID_THROWNHI 0XF1 #define ASID_THROWNLW 0XF2 #define ASID_THROWNLWWOMEN 0XF3 #define ASID_PASS 0XF4 #define ASID_OTTOTTO 0XF5 #define ASID_OTTOTTOWAIT 0XF6 #define ASID_FLYREFLECTWALL 0XF7 #define ASID_FLYREFLECTCEIL 0XF8 #define ASID_STOPWALL 0XF9 #define ASID_STOPCEIL 0XFA #define ASID_MISSFOOT 0XFB #define ASID_CLIFFCATCH 0XFC #define ASID_CLIFFWAIT 0XFD #define ASID_CLIFFCLIMBSLOW 0XFE #define ASID_CLIFFCLIMBQUICK 0XFF #define ASID_CLIFFATTACKSLOW 0X100 #define ASID_CLIFFATTACKQUICK 0X101 #define ASID_CLIFFESCAPESLOW 0X102 #define ASID_CLIFFESCAPEQUICK 0X103 #define ASID_CLIFFJUMPSLOW1 0X104 #define ASID_CLIFFJUMPSLOW2 0X105 #define ASID_CLIFFJUMPQUICK1 0X106 #define ASID_CLIFFJUMPQUICK2 0X107 #define ASID_APPEALR 0X108 #define ASID_APPEALL 0X109 #define ASID_SHOULDEREDWAIT 0X10A #define ASID_SHOULDEREDWALKSLOW 0X10B #define ASID_SHOULDEREDWALKMIDDLE 0X10C #define ASID_SHOULDEREDWALKFAST 0X10D #define ASID_SHOULDEREDTURN 0X10E #define ASID_THROWNFF 0X10F #define ASID_THROWNFB 0X110 #define ASID_THROWNFHI 0X111 #define ASID_THROWNFLW 0X112 #define ASID_CAPTURECAPTAIN 0X113 #define ASID_CAPTUREYOSHI 0X114 #define ASID_YOSHIEGG 0X115 #define ASID_CAPTUREKOOPA 0X116 #define ASID_CAPTUREDAMAGEKOOPA 0X117 #define ASID_CAPTUREWAITKOOPA 0X118 #define ASID_THROWNKOOPAF 0X119 #define ASID_THROWNKOOPAB 0X11A #define ASID_CAPTUREKOOPAAIR 0X11B #define ASID_CAPTUREDAMAGEKOOPAAIR 0X11C #define ASID_CAPTUREWAITKOOPAAIR 0X11D #define ASID_THROWNKOOPAAIRF 0X11E #define ASID_THROWNKOOPAAIRB 0X11F #define ASID_CAPTUREKIRBY 0X120 #define ASID_CAPTUREWAITKIRBY 0X121 #define ASID_THROWNKIRBYSTAR 0X122 #define ASID_THROWNCOPYSTAR 0X123 #define ASID_THROWNKIRBY 0X124 #define ASID_BARRELWAIT 0X125 #define ASID_BURY 0X126 #define ASID_BURYWAIT 0X127 #define ASID_BURYJUMP 0X128 #define ASID_DAMAGESONG 0X129 #define ASID_DAMAGESONGWAIT 0X12A #define ASID_DAMAGESONGRV 0X12B #define ASID_DAMAGEBIND 0X12C #define ASID_CAPTUREMEWTWO 0X12D #define ASID_CAPTUREMEWTWOAIR 0X12E #define ASID_THROWNMEWTWO 0X12F #define ASID_THROWNMEWTWOAIR 0X130 #define ASID_WARPSTARJUMP 0X131 #define ASID_WARPSTARFALL 0X132 #define ASID_HAMMERWAIT 0X133 #define ASID_HAMMERWALK 0X134 #define ASID_HAMMERTURN 0X135 #define ASID_HAMMERKNEEBEND 0X136 #define ASID_HAMMERFALL 0X137 #define ASID_HAMMERJUMP 0X138 #define ASID_HAMMERLANDING 0X139 #define ASID_KINOKOGIANTSTART 0X13A #define ASID_KINOKOGIANTSTARTAIR 0X13B #define ASID_KINOKOGIANTEND 0X13C #define ASID_KINOKOGIANTENDAIR 0X13D #define ASID_KINOKOSMALLSTART 0X13E #define ASID_KINOKOSMALLSTARTAIR 0X13F #define ASID_KINOKOSMALLEND 0X140 #define ASID_KINOKOSMALLENDAIR 0X141 #define ASID_ENTRY 0X142 #define ASID_ENTRYSTART 0X143 #define ASID_ENTRYEND 0X144 #define ASID_DAMAGEICE 0X145 #define ASID_DAMAGEICEJUMP 0X146 #define ASID_CAPTUREMASTERHAND 0X147 #define ASID_CAPTUREDAMAGEMASTERHAND 0X148 #define ASID_CAPTUREWAITMASTERHAND 0X149 #define ASID_THROWNMASTERHAND 0X14A #define ASID_CAPTUREKIRBYYOSHI 0X14B #define ASID_KIRBYYOSHIEGG 0X14C #define ASID_CAPTURELEADEAD 0X14D #define ASID_CAPTURELIKELIKE 0X14E #define ASID_DOWNREFLECT 0X14F #define ASID_CAPTURECRAZYHAND 0X150 #define ASID_CAPTUREDAMAGECRAZYHAND 0X151 #define ASID_CAPTUREWAITCRAZYHAND 0X152 #define ASID_THROWNCRAZYHAND 0X153 #define ASID_BARRELCANNONWAIT 0X154 #define ASID_ACTIONABLE 1000 #define ASID_ACTIONABLEGROUND 1001 #define ASID_ACTIONABLEAIR 1002 #define ASID_DAMAGEAIR 1003 #define ASID_JUMPS 1004 #define ASID_FALLS 1005 enum Ft_AttackKind { ATKKIND_0, ATKKIND_NONE, ATKKIND_JAB1, ATKKIND_JAB2, ATKKIND_JAB3, ATKKIND_JAB4, ATKKIND_DASH, ATKKIND_FTILT, ATKKIND_UTILT, ATKKIND_DTILT, ATKKIND_FSMASH, ATKKIND_USMASH, ATKKIND_DSMASH, ATKKIND_NAIR, ATKKIND_FAIR, ATKKIND_BAIR, ATKKIND_UAIR, ATKKIND_DAIR, ATKKIND_SPECIALN, ATKKIND_SPECIALS, ATKKIND_SPECIALHI, ATKKIND_SPECIALLW, }; /*** Structs ***/ struct Playerblock { int state; // 0x00 = not present, 0x02 = HMN, 0x03 = CPU int ft_kind; // external ID int type; // (0x00 is HMN, 0x01 is CPU, 0x02 is Demo, 0x03 n/a) u8 isTransformed[2]; // 0xC, 1 indicates the fighter that is active Vec3 tagPos; // 0x10 Vec3 spawnPos; // 0x1C Vec3 respawnPos; // 0x28 int x34; int x38; int x3C; float initialFacing; // 0x40 u8 costume; // 0x44 u8 x45; // 0x45 u8 tint; // 0x46 u8 team; // 0x47 u8 controller; // 0x48 u8 cpuLv; u8 cpuKind; u8 handicap; float x50; float attack; float defense; float scale; u16 damage; u16 initialDamage; u16 stamina; int falls[2]; int ko[6]; int x88; u16 selfDestructs; u8 stocks; int coins_curr; int coins_total; int x98; int x9c; int stickSmashes[2]; int tag; u8 flags2; u8 flags3; GOBJ *fighterData; GOBJ *fighterDataSub; }; struct PlayerData { // byte 0x0 u8 kind; u8 status; u8 stocks; u8 costume; // 0x4 u8 portNumberOverride; u8 spawnPointOverride; u8 facingDirection; u8 subcolor; // 0x8 u8 handicap; u8 team; u8 nametag; u8 xb; // 0xC unsigned char isRumble : 1; unsigned char isEntry : 1; unsigned char unk2 : 6; unsigned char unk3 : 8; u8 cpuKind; u8 cpuLevel; // 0xf // 0x10 u16 damageStart; u16 damageSpawn; u16 staminaStart; // 0x14 float attack; // 0x18 float defense; // 0x1C float scale; // 0x20 }; struct FighterBone { JOBJ *joint; JOBJ *joint2; // used for interpolation int flags; int flags2; }; struct DynamicsDesc { int root_bone; // bone index; void *params; // dynamics params; int num; // number of children bones to make dynamic float xc; float x10; float x14; }; struct DynamicsHitDesc { int bone; // bone index int x4; // unk Vec3 x8; // unk }; struct DynamicsBehave { int num; // number of dynamic bones to animate in the boneset }; struct ftDynamics { int dynamics_num; // number of dynamic bonesets for this fighter DynamicsDesc *dynamics_desc; // boneset data array (one for each boneset) int dynamics_hit_num; // (no collide bubbles), max is 11 DynamicsHitDesc *dynamics_hit_desc; // dynamic hit data array (one for each dynamic hit) DynamicsBehave **dynamics_behave; // pointer to an array of dynamics behavior pointers. }; struct ftData { char footBoneL; char footBoneR; int *charAttributes; // 0x4 u8 *modelLookup; // 0x8 int animFlags; // 0xC int animDynamics; // 0x10 int x14; int x18; int x1C; int x20; int x24; int x28; ftDynamics *dynamics; // 0x2C int hurtbox; int *center_bubble; int x38; int x3C; int x40; int coll; void *items; int *x4C; int x50; int x54; int *boneLookup; }; struct ftChkDevice // 80459a68 { int x0; int x4; int x8; int xc; int x10; int x14; int x18; int x1c; int x20; GOBJ *gobj; int hazard_kind; void *check; }; struct SubactionHeader { char *symbol; int animOffset; int animSize; int *subactionData; int flags; }; struct MoveLogic { int animation_id; int flags; char move_id; char bitflags1; void *animation_callback; void *iasa_callback; void *physics_callback; void *collision_callback; void *camera_callback; }; struct ReflectDesc { int bone; int max_damage; Vec3 pos; float radius; float damage_mult; float velocity_mult; int flags; }; struct ShieldDesc { int bone; int max_damage; Vec3 pos; float radius; float damage_mult; float velocity_mult; int flags; }; struct AbsorbDesc { int bone; int max_damage; Vec3 pos; float radius; float damage_mult; float velocity_mult; int flags; }; struct HitVictim { void *victim_data; // the gobj that was hit int unk; // not sure, is set to 0 when hitting them }; struct ftHit { int active; // 0x0 int x4; // 0x4 int dmg; // 0x8 float dmg_f; // 0xc Vec3 offset; // 0x10 float size; // 0x1c int angle; // 0x20 int kb_growth; // 0x24 int wdsk; // 0x28 int kb; // 0x2c int attribute; // 0x30 int shield_dmg; // 0x34 int hitsound_severity; // 0x38. hurtbox interaction. 0 = none, 1 = grounded, 2 = aerial, 3 = both int hitsound_kind; // 0x3c char x40; // 0x40 char x41; // 0x41 unsigned char x421 : 1; // 0x42 0x80 unsigned char x422 : 1; // 0x42 0x40 unsigned char x423 : 1; // 0x42 0x20 unsigned char x424 : 1; // 0x42 0x10 unsigned char no_hurt : 1; // 0x42 0x08 ignore hurtbox unsigned char no_reflect : 1; // 0x42 0x04 ignore reflect? unsigned char x427 : 1; // 0x42 0x02 unsigned char x428 : 1; // 0x42 0x01 unsigned char x431 : 1; // 0x43 0x80 unsigned char x432 : 1; // 0x43 0x40 unsigned char hit_all : 1; // 0x43 0x20 unsigned char x434 : 1; // 0x43 0x10 unsigned char x435 : 1; // 0x43 0x08 unsigned char x436 : 1; // 0x43 0x04 unsigned char x437 : 1; // 0x43 0x02 unsigned char x438 : 1; // 0x43 0x01 int x44; // 0x44 JOBJ *bone; // 0x48 Vec3 pos; // 0x4c Vec3 pos_prev; // 0x58 Vec3 pos_coll; // 0x64 position of hurt collision float coll_distance; // 0x70 Distance From Collding FtHurt (Used for phantom hit collision calculation) HitVictim victims[24]; // 0x74 int x134; // 0x134, flags of some sort }; struct FtHurt { int x0; // 0x0 Vec3 hurt1_offset; // 0x4 Vec3 hurt2_offset; // 0x10 float scale; // 0x1c JOBJ *jobj; // 0x20 unsigned char is_updated : 1; // 0x24, if enabled, wont update position unsigned char x24_2 : 1; // 0x24 0x40 unsigned char x24_3 : 1; // 0x24 0x20 unsigned char x24_4 : 1; // 0x24 0x10 unsigned char x24_5 : 1; // 0x24 0x08 unsigned char x24_6 : 1; // 0x24 0x04 unsigned char x24_7 : 1; // 0x24 0x02 unsigned char x24_8 : 1; // 0x24 0x01 Vec3 hurt1_pos; // 0x28 Vec3 hurt2_pos; // 0x34 int bone_index; // 0x40 int hurt_kind; // 0x44. 0 = low, 1 = mid, 2 = high int is_grabbable; // 0x48 }; struct FtDynamicBoneset { int apply_phys_num; // if this is 256, dyanmics are not processed void *unk_ptr; // is stored @ 8000fdd4, comes from a nonstandard heap @ -0x52fc(r13) int bone_num; // number of bones in this boneset float xc; // stored @ 80011718, 0x8 of dynamicdesc float x10; // stored @ 80011720, 0xC of dynamicdesc float x14; // stored @ 80011728, 0x10 of dynamicdesc }; struct FtDynamicRoot { JOBJ *jobj; // 0x0 Vec4 rot; // 0x4 quaternion Vec3 trans; // 0x14 Vec3 scale; // 0x20 Vec3 rot_global; // 0x2C, copied from 0x50, 0x60, 0x70 of jobj float x38; // 0x38, initialized to 1 @ 8000ff30 float x3c; // 0x3c, initialized to 0 @ 8000ff34 float x40; // 0x40, initialized to 0 @ 8000ff38 float x44; // 0x44, initialized to 0 @ 8000ff3c float x48; // x48, initialized to 0 @ 8000ff44 float x4c; // x4c, THIS IS THE START OF A STRUCTURE, bunch of floats from the dynamicdesc. stored @ 80011744 float x50; // 0x3c float x54; // 0x40 float x58; // 0x44 float x5c; // x048 float x60; // 0x38 float x64; // 0x3c float x68; // 0x40 float x6c; // 0x44 float x70; // x048 float x74; // 0x38 float x78; // 0x3c float x7c; // 0x40 float x80; // 0x44 float x84; // x048 float x88; // 0x38 float x8c; // 0x3c FtDynamicRoot *next; // 0x90 float x94; // 0x44 }; struct FtDynamicHit { int x0; // 0x1670 Vec3 x4; // 0x1674 JOBJ *bone; // 0x1680 int x14; // 0x1684 Vec3 pos; // 0x1688 int bone_index; // 0x1694 }; struct FtAfterImageKey { Vec3 pos; Vec3 rot; } FtAfterImageKey; struct CPU { int held; // 0x0 s8 lstickX; // 0x4 s8 lstickY; // 0x5 s8 cstickX; // 0x6 s8 cstickY; // 0x7 int x8; // 0x8 int ai; // 0xc int level; // 0x10 int x14; // 0x14 int x18; // 0x18 int x1c; // 0x1c int x20; // 0x20 int x24; // 0x24 int x28; // 0x28 int x2c; // 0x2c int x30; // 0x30 int x34; // 0x34 int x38; // 0x38 int x3c; // 0x3c int x40; // 0x40 int x44; // 0x44 int x48; // 0x48 int x4c; // 0x4c int x50; // 0x50 int x54; // 0x54 int x58; // 0x58 int x5c; // 0x5c int x60; // 0x60 int x64; // 0x64 int x68; // 0x68 int x6c; // 0x6c int x70; // 0x70 int x74; // 0x74 int x78; // 0x78 int x7c; // 0x7c int x80; // 0x80 int x84; // 0x84 int x88; // 0x88 int x8c; // 0x8c int x90; // 0x90 int x94; // 0x94 int x98; // 0x98 int x9c; // 0x9c int xa0; // 0xa0 int xa4; // 0xa4 int xa8; // 0xa8 int xac; // 0xac int xb0; // 0xb0 int xb4; // 0xb4 int xb8; // 0xb8 int xbc; // 0xbc int xc0; // 0xc0 int xc4; // 0xc4 int xc8; // 0xc8 int xcc; // 0xcc int xd0; // 0xd0 int xd4; // 0xd4 int xd8; // 0xd8 int xdc; // 0xdc int xe0; // 0xe0 int xe4; // 0xe4 int xe8; // 0xe8 int xec; // 0xec int xf0; // 0xf0 int xf4; // 0xf4 int xf8; // 0xf8 int xfc; // 0xfc int x100; // 0x100 int x104; // 0x104 int x108; // 0x108 int x10c; // 0x10c int x110; // 0x110 int x114; // 0x114 int x118; // 0x118 int x11c; // 0x11c int x120; // 0x120 int x124; // 0x124 int x128; // 0x128 int x12c; // 0x12c int x130; // 0x130 int x134; // 0x134 int x138; // 0x138 int x13c; // 0x13c int x140; // 0x140 int x144; // 0x144 int x148; // 0x148 int x14c; // 0x14c int x150; // 0x150 int x154; // 0x154 int x158; // 0x158 int x15c; // 0x15c int x160; // 0x160 int x164; // 0x164 int x168; // 0x168 int x16c; // 0x16c int x170; // 0x170 int x174; // 0x174 int x178; // 0x178 int x17c; // 0x17c int x180; // 0x180 int x184; // 0x184 int x188; // 0x188 int x18c; // 0x18c int x190; // 0x190 int x194; // 0x194 int x198; // 0x198 int x19c; // 0x19c int x1a0; // 0x1a0 int x1a4; // 0x1a4 int x1a8; // 0x1a8 int x1ac; // 0x1ac int x1b0; // 0x1b0 int x1b4; // 0x1b4 int x1b8; // 0x1b8 int x1bc; // 0x1bc int x1c0; // 0x1c0 int x1c4; // 0x1c4 int x1c8; // 0x1c8 int x1cc; // 0x1cc int x1d0; // 0x1d0 int x1d4; // 0x1d4 int x1d8; // 0x1d8 int x1dc; // 0x1dc int x1e0; // 0x1e0 int x1e4; // 0x1e4 int x1e8; // 0x1e8 int x1ec; // 0x1ec int x1f0; // 0x1f0 int x1f4; // 0x1f4 int x1f8; // 0x1f8 int x1fc; // 0x1fc int x200; // 0x200 int x204; // 0x204 int x208; // 0x208 int x20c; // 0x20c int x210; // 0x210 int x214; // 0x214 int x218; // 0x218 int x21c; // 0x21c int x220; // 0x220 int x224; // 0x224 int x228; // 0x228 int x22c; // 0x22c int x230; // 0x230 int x234; // 0x234 int x238; // 0x238 int x23c; // 0x23c int x240; // 0x240 int x244; // 0x244 int x248; // 0x248 int x24c; // 0x24c int x250; // 0x250 int x254; // 0x254 int x258; // 0x258 int x25c; // 0x25c int x260; // 0x260 int x264; // 0x264 int x268; // 0x268 int x26c; // 0x26c int x270; // 0x270 int x274; // 0x274 int x278; // 0x278 int x27c; // 0x27c int x280; // 0x280 int x284; // 0x284 int x288; // 0x288 int x28c; // 0x28c int x290; // 0x290 int x294; // 0x294 int x298; // 0x298 int x29c; // 0x29c int x2a0; // 0x2a0 int x2a4; // 0x2a4 int x2a8; // 0x2a8 int x2ac; // 0x2ac int x2b0; // 0x2b0 int x2b4; // 0x2b4 int x2b8; // 0x2b8 int x2bc; // 0x2bc int x2c0; // 0x2c0 int x2c4; // 0x2c4 int x2c8; // 0x2c8 int x2cc; // 0x2cc int x2d0; // 0x2d0 int x2d4; // 0x2d4 int x2d8; // 0x2d8 int x2dc; // 0x2dc int x2e0; // 0x2e0 int x2e4; // 0x2e4 int x2e8; // 0x2e8 int x2ec; // 0x2ec int x2f0; // 0x2f0 int x2f4; // 0x2f4 int x2f8; // 0x2f8 int x2fc; // 0x2fc int x300; // 0x300 int x304; // 0x304 int x308; // 0x308 int x30c; // 0x30c int x310; // 0x310 int x314; // 0x314 int x318; // 0x318 int x31c; // 0x31c int x320; // 0x320 int x324; // 0x324 int x328; // 0x328 int x32c; // 0x32c int x330; // 0x330 int x334; // 0x334 int x338; // 0x338 int x33c; // 0x33c int x340; // 0x340 int x344; // 0x344 int x348; // 0x348 int x34c; // 0x34c int x350; // 0x350 int x354; // 0x354 int x358; // 0x358 int x35c; // 0x35c int x360; // 0x360 int x364; // 0x364 int x368; // 0x368 int x36c; // 0x36c int x370; // 0x370 int x374; // 0x374 int x378; // 0x378 int x37c; // 0x37c int x380; // 0x380 int x384; // 0x384 int x388; // 0x388 int x38c; // 0x38c int x390; // 0x390 int x394; // 0x394 int x398; // 0x398 int x39c; // 0x39c int x3a0; // 0x3a0 int x3a4; // 0x3a4 int x3a8; // 0x3a8 int x3ac; // 0x3ac int x3b0; // 0x3b0 int x3b4; // 0x3b4 int x3b8; // 0x3b8 int x3bc; // 0x3bc int x3c0; // 0x3c0 int x3c4; // 0x3c4 int x3c8; // 0x3c8 int x3cc; // 0x3cc int x3d0; // 0x3d0 int x3d4; // 0x3d4 int x3d8; // 0x3d8 int x3dc; // 0x3dc int x3e0; // 0x3e0 int x3e4; // 0x3e4 int x3e8; // 0x3e8 int x3ec; // 0x3ec int x3f0; // 0x3f0 int x3f4; // 0x3f4 int x3f8; // 0x3f8 int x3fc; // 0x3fc int x400; // 0x400 int x404; // 0x404 int x408; // 0x408 int x40c; // 0x40c int x410; // 0x410 int x414; // 0x414 int x418; // 0x418 int x41c; // 0x41c int x420; // 0x420 int x424; // 0x424 int x428; // 0x428 int x42c; // 0x42c int x430; // 0x430 int x434; // 0x434 int x438; // 0x438 int x43c; // 0x43c int x440; // 0x440 int *curr_unk; // 0x444 int *curr_unk2; // 0x448 int x44c; // 0x44c int x450; // 0x450 int x454; // 0x454 int x458; // 0x458 int x45c; // 0x45c int x460; // 0x460 int x464; // 0x464 int x468; // 0x468 int x46c; // 0x46c int x470; // 0x470 int x474; // 0x474 int x478; // 0x478 int x47c; // 0x47c int x480; // 0x480 int x484; // 0x484 int x488; // 0x488 int x48c; // 0x48c int x490; // 0x490 int x494; // 0x494 int x498; // 0x498 int x49c; // 0x49c int x4a0; // 0x4a0 int x4a4; // 0x4a4 int x4a8; // 0x4a8 int x4ac; // 0x4ac int x4b0; // 0x4b0 int x4b4; // 0x4b4 int x4b8; // 0x4b8 int x4bc; // 0x4bc int x4c0; // 0x4c0 int x4c4; // 0x4c4 int x4c8; // 0x4c8 int x4cc; // 0x4cc int x4d0; // 0x4d0 int x4d4; // 0x4d4 int x4d8; // 0x4d8 int x4dc; // 0x4dc int x4e0; // 0x4e0 int x4e4; // 0x4e4 int x4e8; // 0x4e8 int x4ec; // 0x4ec int x4f0; // 0x4f0 int x4f4; // 0x4f4 int x4f8; // 0x4f8 int x4fc; // 0x4fc int x500; // 0x500 int x504; // 0x504 int x508; // 0x508 int x50c; // 0x50c int x510; // 0x510 int x514; // 0x514 int x518; // 0x518 int x51c; // 0x51c int x520; // 0x520 int x524; // 0x524 int x528; // 0x528 int x52c; // 0x52c int x530; // 0x530 int x534; // 0x534 int x538; // 0x538 int x53c; // 0x53c int x540; // 0x540 int x544; // 0x544 int x548; // 0x548 int x54c; // 0x54c int x550; // 0x550 int x554; // 0x554 }; struct ftCommonData { float x0; // 0x0 float x4; // 0x4 float x8; // 0x8 float xc; // 0xc float x10; // 0x10 float x14; // 0x14 float x18; // 0x18 float x1c; // 0x1c float lstick_tilt; // 0x20 float x24; // 0x24 float x28; // 0x28 float x2c; // 0x2c float x30; // 0x30 float x34; // 0x34 float x38; // 0x38 float x3c; // 0x3c float x40; // 0x40 float x44; // 0x44 float x48; // 0x48 float x4c; // 0x4c float x50; // 0x50 float x54; // 0x54 float x58; // 0x58 float x5c; // 0x5c float x60; // 0x60 float x64; // 0x64 float x68; // 0x68 float friction_mult; // 0x6c float jumpaerial_lsticky; // 0x70 float jumpaerial_lsticktimer; // 0x74 float x78; // 0x78 float x7c; // 0x7c float x80; // 0x80 float x84; // 0x84 float x88; // 0x88 float x8c; // 0x8c float lstick_rebirthfall; // 0x90 float x94; // 0x94 float x98; // 0x98 float x9c; // 0x9c float xa0; // 0xa0 float xa4; // 0xa4 float xa8; // 0xa8 float xac; // 0xac float xb0; // 0xb0 float xb4; // 0xb4 float xb8; // 0xb8 float xbc; // 0xbc float xc0; // 0xc0 float xc4; // 0xc4 float xc8; // 0xc8 float xcc; // 0xcc float xd0; // 0xd0 float xd4; // 0xd4 float xd8; // 0xd8 float xdc; // 0xdc float xe0; // 0xe0 float xe4; // 0xe4 float xe8; // 0xe8 float xec; // 0xec float xf0; // 0xf0 float xf4; // 0xf4 float xf8; // 0xf8 float xfc; // 0xfc float kb_mult; // 0x100 float x104; // 0x104 float x108; // 0x108 float x10c; // 0x10c float x110; // 0x110 float x114; // 0x114 float x118; // 0x118 float x11c; // 0x11c float x120; // 0x120 float x124; // 0x124 float x128; // 0x128 float x12c; // 0x12c float x130; // 0x130 float x134; // 0x134 float x138; // 0x138 float x13c; // 0x13c float x140; // 0x140 float x144; // 0x144 float x148; // 0x148 float x14c; // 0x14c float x150; // 0x150 float x154; // 0x154 float x158; // 0x158 float x15c; // 0x15c float x160; // 0x160 float x164; // 0x164 float x168; // 0x168 float kb_maxVelX; // 0x16c float x170; // 0x170 float x174; // 0x174 float x178; // 0x178 float x17c; // 0x17c float x180; // 0x180 float x184; // 0x184 float x188; // 0x188 float x18c; // 0x18c float x190; // 0x190 float x194; // 0x194 float x198; // 0x198 float x19c; // 0x19c float x1a0; // 0x1a0 float x1a4; // 0x1a4 float tdi_maxAngle; // 0x1a8 float x1ac; // 0x1ac float x1b0; // 0x1b0 float x1b4; // 0x1b4 float x1b8; // 0x1b8 float kb_bounceDecay; // 0x1bc float x1c0; // 0x1c0 float x1c4; // 0x1c4 float x1c8; // 0x1c8 float x1cc; // 0x1cc float x1d0; // 0x1d0 float x1d4; // 0x1d4 float x1d8; // 0x1d8 float x1dc; // 0x1dc float x1e0; // 0x1e0 float x1e4; // 0x1e4 float x1e8; // 0x1e8 float x1ec; // 0x1ec float x1f0; // 0x1f0 float x1f4; // 0x1f4 float x1f8; // 0x1f8 float x1fc; // 0x1fc float x200; // 0x200 float kb_frameDecay; // 0x204 float x208; // 0x208 float x20c; // 0x20c float x210; // 0x210 float x214; // 0x214 float x218; // 0x218 float x21c; // 0x21c float x220; // 0x220 float x224; // 0x224 float x228; // 0x228 float x22c; // 0x22c float x230; // 0x230 float x234; // 0x234 float x238; // 0x238 float x23c; // 0x23c float x240; // 0x240 float x244; // 0x244 float x248; // 0x248 float x24c; // 0x24c float x250; // 0x250 float x254; // 0x254 float x258; // 0x258 float x25c; // 0x25c float x260; // 0x260 float x264; // 0x264 float x268; // 0x268 float x26c; // 0x26c float x270; // 0x270 float x274; // 0x274 float x278; // 0x278 float x27c; // 0x27c float x280; // 0x280 float x284; // 0x284 float x288; // 0x288 float x28c; // 0x28c float x290; // 0x290 float x294; // 0x294 float x298; // 0x298 float x29c; // 0x29c float x2a0; // 0x2a0 float x2a4; // 0x2a4 float x2a8; // 0x2a8 float x2ac; // 0x2ac float x2b0; // 0x2b0 float x2b4; // 0x2b4 float x2b8; // 0x2b8 float x2bc; // 0x2bc float x2c0; // 0x2c0 float x2c4; // 0x2c4 float x2c8; // 0x2c8 float x2cc; // 0x2cc float x2d0; // 0x2d0 float x2d4; // 0x2d4 float x2d8; // 0x2d8 float x2dc; // 0x2dc float x2e0; // 0x2e0 float x2e4; // 0x2e4 float x2e8; // 0x2e8 float x2ec; // 0x2ec float x2f0; // 0x2f0 float x2f4; // 0x2f4 float x2f8; // 0x2f8 float x2fc; // 0x2fc float x300; // 0x300 float x304; // 0x304 float x308; // 0x308 float x30c; // 0x30c float x310; // 0x310 float x314; // 0x314 float x318; // 0x318 float x31c; // 0x31c float x320; // 0x320 float x324; // 0x324 float x328; // 0x328 float x32c; // 0x32c float x330; // 0x330 float x334; // 0x334 float escapeair_vel; // 0x338 float escapeair_veldecaymult; // 0x33c float x340; // 0x340 float x344; // 0x344 float x348; // 0x348 float x34c; // 0x34c float x350; // 0x350 float x354; // 0x354 float x358; // 0x358 float x35c; // 0x35c float x360; // 0x360 float x364; // 0x364 float x368; // 0x368 float x36c; // 0x36c float x370; // 0x370 float x374; // 0x374 float x378; // 0x378 float x37c; // 0x37c float x380; // 0x380 float x384; // 0x384 float x388; // 0x388 float x38c; // 0x38c float x390; // 0x390 float x394; // 0x394 float x398; // 0x398 float x39c; // 0x39c float x3a0; // 0x3a0 float x3a4; // 0x3a4 float x3a8; // 0x3a8 float x3ac; // 0x3ac float x3b0; // 0x3b0 float x3b4; // 0x3b4 float x3b8; // 0x3b8 float x3bc; // 0x3bc float x3c0; // 0x3c0 float x3c4; // 0x3c4 float x3c8; // 0x3c8 float x3cc; // 0x3cc float x3d0; // 0x3d0 float x3d4; // 0x3d4 float x3d8; // 0x3d8 float x3dc; // 0x3dc float x3e0; // 0x3e0 float x3e4; // 0x3e4 float x3e8; // 0x3e8 float x3ec; // 0x3ec float x3f0; // 0x3f0 float x3f4; // 0x3f4 float x3f8; // 0x3f8 float x3fc; // 0x3fc float x400; // 0x400 float x404; // 0x404 float x408; // 0x408 float x40c; // 0x40c float x410; // 0x410 float x414; // 0x414 float x418; // 0x418 float x41c; // 0x41c float x420; // 0x420 float x424; // 0x424 float x428; // 0x428 float x42c; // 0x42c float x430; // 0x430 float x434; // 0x434 float x438; // 0x438 float x43c; // 0x43c float x440; // 0x440 float x444; // 0x444 float x448; // 0x448 float x44c; // 0x44c float x450; // 0x450 float zjostle_frame; // 0x45c float zjostle_max; // 0x460 float ms_zjostle_frame; // 0x45c float ms_zjostle_max; // 0x460 float x464; // 0x464 float x468; // 0x468 float x46c; // 0x46c float x470; // 0x470 float x474; // 0x474 float x478; // 0x478 float x47c; // 0x47c float x480; // 0x480 float x484; // 0x484 float x488; // 0x488 float x48c; // 0x48c float x490; // 0x490 float x494; // 0x494 float x498; // 0x498 int cliff_invuln_time; // 0x49c float x4a0; // 0x4a0 float x4a4; // 0x4a4 float x4a8; // 0x4a8 float x4ac; // 0x4ac float asdi_mag; // 0x4b0 float x4b4; // 0x4b4 float x4b8; // 0x4b8 float asdi_units; // 0x4bc float x4c0; // 0x4c0 float x4c4; // 0x4c4 float x4c8; // 0x4c8 float x4cc; // 0x4cc float x4d0; // 0x4d0 float x4d4; // 0x4d4 float x4d8; // 0x4d8 float x4dc; // 0x4dc float x4e0; // 0x4e0 float x4e4; // 0x4e4 float x4e8; // 0x4e8 float x4ec; // 0x4ec float x4f0; // 0x4f0 float x4f4; // 0x4f4 float x4f8; // 0x4f8 float x4fc; // 0x4fc float x500; // 0x500 float x504; // 0x504 float x508; // 0x508 float x50c; // 0x50c float x510; // 0x510 float x514; // 0x514 float x518; // 0x518 float x51c; // 0x51c float x520; // 0x520 float x524; // 0x524 float x528; // 0x528 float x52c; // 0x52c float x530; // 0x530 float x534; // 0x534 float x538; // 0x538 float x53c; // 0x53c float x540; // 0x540 float x544; // 0x544 float x548; // 0x548 float x54c; // 0x54c float x550; // 0x550 float x554; // 0x554 float x558; // 0x558 float x55c; // 0x55c float x560; // 0x560 float x564; // 0x564 float x568; // 0x568 float x56c; // 0x56c float x570; // 0x570 float x574; // 0x574 float x578; // 0x578 float x57c; // 0x57c float x580; // 0x580 float x584; // 0x584 float x588; // 0x588 float x58c; // 0x58c float x590; // 0x590 float x594; // 0x594 float x598; // 0x598 float x59c; // 0x59c float x5a0; // 0x5a0 float x5a4; // 0x5a4 float x5a8; // 0x5a8 float x5ac; // 0x5ac float x5b0; // 0x5b0 float x5b4; // 0x5b4 float x5b8; // 0x5b8 float x5bc; // 0x5bc float x5c0; // 0x5c0 float x5c4; // 0x5c4 float x5c8; // 0x5c8 float x5cc; // 0x5cc float x5d0; // 0x5d0 float x5d4; // 0x5d4 float x5d8; // 0x5d8 float x5dc; // 0x5dc float x5e0; // 0x5e0 float x5e4; // 0x5e4 float x5e8; // 0x5e8 float x5ec; // 0x5ec float x5f0; // 0x5f0 float x5f4; // 0x5f4 float x5f8; // 0x5f8 float x5fc; // 0x5fc float x600; // 0x600 float x604; // 0x604 float x608; // 0x608 float x60c; // 0x60c float x610; // 0x610 float x614; // 0x614 float x618; // 0x618 float x61c; // 0x61c float x620; // 0x620 float x624; // 0x624 float x628; // 0x628 float x62c; // 0x62c float x630; // 0x630 float x634; // 0x634 float x638; // 0x638 float x63c; // 0x63c float x640; // 0x640 float x644; // 0x644 float x648; // 0x648 float x64c; // 0x64c float x650; // 0x650 float x654; // 0x654 float x658; // 0x658 float x65c; // 0x65c float x660; // 0x660 float x664; // 0x664 float x668; // 0x668 float x66c; // 0x66c float x670; // 0x670 float x674; // 0x674 float x678; // 0x678 float x67c; // 0x67c float x680; // 0x680 float x684; // 0x684 float x688; // 0x688 float x68c; // 0x68c float x690; // 0x690 float x694; // 0x694 float x698; // 0x698 float x69c; // 0x69c float x6a0; // 0x6a0 float x6a4; // 0x6a4 float x6a8; // 0x6a8 float x6ac; // 0x6ac float x6b0; // 0x6b0 float x6b4; // 0x6b4 float x6b8; // 0x6b8 float x6bc; // 0x6bc float x6c0; // 0x6c0 float x6c4; // 0x6c4 float x6c8; // 0x6c8 float x6cc; // 0x6cc float x6d0; // 0x6d0 float x6d4; // 0x6d4 float x6d8; // 0x6d8 float x6dc; // 0x6dc float x6e0; // 0x6e0 float x6e4; // 0x6e4 float x6e8; // 0x6e8 float x6ec; // 0x6ec float x6f0; // 0x6f0 float x6f4; // 0x6f4 float x6f8; // 0x6f8 float x6fc; // 0x6fc float x700; // 0x700 float x704; // 0x704 float x708; // 0x708 float x70c; // 0x70c float x710; // 0x710 float x714; // 0x714 float x718; // 0x718 float x71c; // 0x71c float x720; // 0x720 float x724; // 0x724 float x728; // 0x728 float x72c; // 0x72c float x730; // 0x730 float x734; // 0x734 float x738; // 0x738 float x73c; // 0x73c float x740; // 0x740 float x744; // 0x744 float x748; // 0x748 float x74c; // 0x74c float x750; // 0x750 float x754; // 0x754 float x758; // 0x758 float x75c; // 0x75c float x760; // 0x760 float x764; // 0x764 float x768; // 0x768 float x76c; // 0x76c float x770; // 0x770 float x774; // 0x774 float x778; // 0x778 float x77c; // 0x77c float x780; // 0x780 float x784; // 0x784 float x788; // 0x788 float x78c; // 0x78c float x790; // 0x790 float x794; // 0x794 float x798; // 0x798 float x79c; // 0x79c float x7a0; // 0x7a0 float x7a4; // 0x7a4 float x7a8; // 0x7a8 float x7ac; // 0x7ac float x7b0; // 0x7b0 float x7b4; // 0x7b4 float x7b8; // 0x7b8 float x7bc; // 0x7bc float x7c0; // 0x7c0 float x7c4; // 0x7c4 float x7c8; // 0x7c8 float x7cc; // 0x7cc float x7d0; // 0x7d0 float x7d4; // 0x7d4 float x7d8; // 0x7d8 float x7dc; // 0x7dc float x7e0; // 0x7e0 float x7e4; // 0x7e4 float x7e8; // 0x7e8 float x7ec; // 0x7ec float x7f0; // 0x7f0 float x7f4; // 0x7f4 float x7f8; // 0x7f8 float x7fc; // 0x7fc float x800; // 0x800 float x804; // 0x804 float x808; // 0x808 float x80c; // 0x80c float x810; // 0x810 }; struct FighterData { GOBJ *fighter; // 0x0 int kind; // 0x4 int spawn_num; // 0x8 char ply; // 0xC char unknown; // 0xD char unknownE; // 0xE char unknownF; // 0xF int state; // 0x10 int anim_id; // 0x14 int state_num; // 0x18 MoveLogic *common_states; // 0x1C MoveLogic *special_states; // 0x20 int *anim_flags; // 0x24 u16 *dynamics_data; // 0x28 float facing_direction; // 0x2C float facing_direction_repeated; // 0x30 float scale1; // 0x34 float scale2; // 0x38 float scale3; // 0x3C int pointer_to_next_linked_list; // 0x40 int pointer_to_0x40__pointer_to_prev_linked_list; // 0x44 int length_of_linked_list; // 0x48 int unknown4C; // 0x4C int unknown50; // 0x50 int unknown54; // 0x54 int unknown58; // 0x58 int unknown5C; // 0x5C int unknown60; // 0x60 int unknown64; // 0x64 int unknown68; // 0x68 int unknown6C; // 0x6C int unknown70; // 0x70 struct phys // 0x74 { // Vec3 anim_vel; // 0x74 Vec3 self_vel; // 0x80 Vec3 kb_vel; // 0x8C int x98; // 0x98 int x9c; // 0x9C int xa0; // 0xA0 int xa4; // 0xA4 int xa8; // 0xA8 int xac; // 0xAC Vec3 pos; // 0xb0 Vec3 pos_prev; // 0xBC Vec3 pos_delta; // 0xC8 Vec3 unknownD4; // 0xD4 int air_state; // 0xE0 float horzitonal_velocity_queue_will_be_added_to_0xec; // 0xE4 float vertical_velocity_queue_will_be_added_to_0xec; // 0xE8 Vec3 selfVelGround; // 0xEC int unknownF8; // 0xF8 int unknownFC; // 0xFC int unknown100; // 0x100 } phys; // int *costume_JObjDesc; // 0x104 int *costume_archive; // 0x108 ftData *ftData; // 0x10C struct attr // 0x110 { // float walk_initial_velocity; // 0x110 float walk_acceleration; // 0x114 float walk_maximum_velocity; // 0x118 float slow_walk_max; // 0x11C float mid_walk_point; // 0x120 float fast_walk_min; // 0x124 float ground_friction; // 0x128 float dash_initial_velocity; // 0x12C float dashrun_acceleration_a; // 0x130 float dashrun_acceleration_b; // 0x134 float dashrun_terminal_velocity; // 0x138 float run_animation_scaling; // 0x13C float max_runbrake_frames; // 0x140 float grounded_max_horizontal_velocity; // 0x144 float jump_startup_time; // 0x148 float jump_h_initial_velocity; // 0x14C float jump_v_initial_velocity; // 0x150 float ground_to_air_jump_momentum_multiplier; // 0x154 float jump_h_max_velocity; // 0x158 float hop_v_initial_velocity; // 0x15C float air_jump_v_multiplier; // 0x160 float air_jump_h_multiplier; // 0x164 int max_jumps; // 0x168 float gravity; // 0x16C float terminal_velocity; // 0x170 float aerialDriftStickMult; // 0x174 float aerialDriftBase; // 0x178 float aerialDriftMax; // 0x17C float aerialFriction; // 0x180 float fastfall_velocity; // 0x184 float horizontal_air_mobility_constant; // 0x188 int jab_2_input_window; // 0x18C int jab_3_input_window; // 0x190 int frames_to_change_direction_on_standing_turn; // 0x194 float weight; // 0x198 float model_scaling; // 0x19C float initial_shield_size; // 0x1A0 float shield_break_initial_velocity; // 0x1A4 int rapid_jab_window; // 0x1A8 int unknown1AC; // 0x1AC int unknown1B0; // 0x1B0 int unknown1B4; // 0x1B4 float ledge_jump_horizontal_velocity; // 0x1B8 float ledge_jump_vertical_velocity; // 0x1BC float item_throw_velocity_multiplier; // 0x1C0 int unknown1C4; // 0x1C4 int unknown1C8; // 0x1C8 int unknown1CC; // 0x1CC int unknown1D0; // 0x1D0 int unknown1D4; // 0x1D4 int unknown1D8; // 0x1D8 int unknown1DC; // 0x1DC int unknown1E0; // 0x1E0 int unknown1E4; // 0x1E4 int unknown1E8; // 0x1E8 int unknown1EC; // 0x1EC float kirby_b_star_damage; // 0x1F0 float normal_landing_lag; // 0x1F4 float n_air_landing_lag; // 0x1F8 float f_air_landing_lag; // 0x1FC float b_air_landing_lag; // 0x200 float u_air_landing_lag; // 0x204 float d_air_landing_lag; // 0x208 float nametag_height; // 0x20C int unknown210; // 0x210 float wall_jump_horizontal_velocity; // 0x214 float wall_jump_vertical_velocity; // 0x218 int unknown21C; // 0x21C float trophy_scale; // 0x220 int unknown224; // 0x224 int unknown228; // 0x228 int unknown22C; // 0x22C int unknown230; // 0x230 int unknown234; // 0x234 int unknown238; // 0x238 int unknown23C; // 0x23C int unknown240; // 0x240 int unknown244; // 0x244 int unknown248; // 0x248 int unknown24C; // 0x24C int unknown250; // 0x250 int unknown254; // 0x254 int unknown258; // 0x258 float bubble_ratio; // 0x25C int unknown260; // 0x260 int unknown264; // 0x264 int unknown268; // 0x268 int unknown26C; // 0x26C float respawn_platform_scale; // 0x270 int unknown274; // 0x274 int unknown278; // 0x278 int camera_zoom_target_bone; // 0x27C int unknown280; // 0x280 int unknown284; // 0x284 int unknown288; // 0x288 int special_jump_action___1; // 0x28C int weight_dependent_throw_speed_flags; // 0x290 } attr; // int unknown294; // 0x294 int unknown298; // 0x298 int unknown29C; // 0x29C int unknown2A0; // 0x2A0 int unknown2A4; // 0x2A4 int unknown2A8; // 0x2A8 int unknown2AC; // 0x2AC int unknown2B0; // 0x2B0 int unknown2B4; // 0x2B4 int unknown2B8; // 0x2B8 int unknown2BC; // 0x2BC int unknown2C0; // 0x2C0 int unknown2C4; // 0x2C4 int unknown2C8; // 0x2C8 int unknown2CC; // 0x2CC int unknown2D0; // 0x2D0 int *special_attributes; // 0x2D4 int *special_attributes2; // 0x2D8 int unknown2DC; // 0x2DC int unknown2E0; // 0x2E0 int unknown2E4; // 0x2E4 int unknown2E8; // 0x2E8 int unknown2EC; // 0x2EC FtDynamicBoneset dynamics_boneset[10]; // 0x2f0 int dynamics_num; // 0x3E0 struct script // 0x3E4 { // float script_event_timer; // 0x3E4 float script_frame_timer; // 0x3E8 int *script_current; // 0x3EC int script_loop_num; // 0x3F0 int *script_return; // 0x3F4 } script; // int unk; // 0x3F8 int unk3FC; // 0x3FC int pointer_to_0x460; // 0x400 int pointer_to_0x3c0; // 0x404 ColorOverlay color[3]; // 0x408 int *LObj; // 0x588 int anim_num; // 0x58C int *anim_curr_flags_ptr; // 0x590 int anim_curr_flags; // 0x594 int *anim_requested; // 0x598 int *anim_cache_curr; // 0x59C int *anim_cache_persist; // 0x5A0 int *anim_curr_ARAM; // 0x5A4 int *anim_persist_ARAM; // 0x5A8 int dobj_toggle_num; // 0x5AC int unknown5B0; // 0x5B0 int unknown5B4; // 0x5B4 int unknown5B8; // 0x5B8 int unknown5BC; // 0x5BC int unknown5C0; // 0x5C0 int unknown5C4; // 0x5C4 int unknown5C8; // 0x5C8 int unknown5CC; // 0x5CC int unknown5D0; // 0x5D0 int unknown5D4; // 0x5D4 int unknown5D8; // 0x5D8 int unknown5DC; // 0x5DC int unknown5E0; // 0x5E0 int unknown5E4; // 0x5E4 FighterBone *bones; // 0x5E8 int bone_num; // 0x5EC int bone_arr; // 0x5F0 u16 dobj_toggle[12]; // 0x5f4 Effect *gfx; // 0x60C int unknown610; // 0x610 int unknown614; // 0x614 char player_controller_number; // 0x618 char costume_id; // 0x619 char color_overlay_id; // 0x61A u8 team; // 0x61B char unknown61E; // 0x61E char unknown61F; // 0x61F struct input // input data { // float lstick_x; // 0x620 float lstick_y; // 0x624 float lstick_prev_x; // 0x628 float lstick_prev_y; // 0x62C int unknown630; // 0x630 int unknown634; // 0x634 float cstick_x; // 0x638 float cstick_y; // 0x63C int x640; // 0x640 int unknown644; // 0x644 int unknown648; // 0x648 int unknown64C; // 0x64C float trigger; // 0x650 int unknown654; // 0x654 int unknown658; // 0x658 int held; // 0x65C int held_prev; // 0x660 int unknown664; // 0x664 int down; // 0x668 int unknown66C; // 0x66C char timer_lstick_tilt_x; // 0x670 char timer_lstick_tilt_y; // 0x671 char timer_trigger_analog; // 0x672 char timer_lstick_smash_x; // 0x673 char timer_lstick_smash_y; // 0x674 char timer_trigger_digital; // 0x675 char timer_lstick_any_x; // 0x676 char timer_lstick_any_y; // 0x677 char timer_trigger_any; // 0x678 char x679; // 0x679 char x67A; // 0x67A char x67B; // 0x67B char timer_a; // 0x67C char timer_b; // 0x67D char timer_xy; // 0x67E char timer_trigger_any_ignore_hitlag; // 0x67F char timer_LR; // 0x680 char timer_padup; // 0x681 char timer_paddown; // 0x682 char timer_item_release; // 0x683 char sinceRapidLR; // 0x684 char timer_unk2; // 0x685 char timer_unk3; // 0x686 char timer_unk4; // 0x687 char timer_sideb; // 0x688 char timer_neutralb; // 0x689 char timer_unk5; // 0x68A char timer_unk6; // 0x68B } input; // Vec3 transN_pos; // x68c Vec3 transN_pos_prev; // 0x698 Vec3 transN_offset; // 0x6A4 Vec3 transN_offset_prev; // 0x6B0 float input_stickangle; // 0x6BC int unknown6C0; // 0x6C0 int unknown6C4; // 0x6C4 int unknown6C8; // 0x6C8 int unknown6CC; // 0x6CC int unknown6D0; // 0x6D0 int unknown6D4; // 0x6D4 int unknown6D8; // 0x6D8 int unknown6DC; // 0x6DC int unknown6E0; // 0x6E0 int unknown6E4; // 0x6E4 int unknown6E8; // 0x6E8 int unknown6EC; // 0x6EC CollData coll_data; // 0x6F0 -> 0x88C CameraBox *cameraBox; // 0x890 float stateFrame; // 0x894 int unknown898; // 0x898 float stateSpeed; // 0x89C int x8a0; // 0x8a0 float stateBlend; // 0x8a4 int x8a8; // 0x8a8 JOBJ *animSkeleton; // 0x8ac int x8b0; // 0x8b0 int x8b4; // 0x8b4 int x8b8; // 0x8b8 int x8bc; // 0x8bc int x8c0; // 0x8c0 int x8c4; // 0x8c4 int x8c8; // 0x8c8 int x8cc; // 0x8cc int x8d0; // 0x8d0 int x8d4; // 0x8d4 int x8d8; // 0x8d8 int x8dc; // 0x8dc int x8e0; // 0x8e0 int x8e4; // 0x8e4 int x8e8; // 0x8e8 int x8ec; // 0x8ec int x8f0; // 0x8f0 int x8f4; // 0x8f4 int x8f8; // 0x8f8 int x8fc; // 0x8fc int x900; // 0x900 int x904; // 0x904 int x908; // 0x908 int x90c; // 0x90c int x910; // 0x910 ftHit hitbox[4]; // 0x914 ftHit throw_hitbox[2]; // 0xdf4 ftHit unk_hitbox; // 0x1064 u8 teamID; // 0x119c, friendly fire related u8 grabbersID; // 0x119D, slot ID of the person grabbing this fighter u8 hurtboxNum; // 0x119E, number of hurtboxesz FtHurt hurtbox[15]; // 0x11A0 int x1614; // 0x1614 int x1618; // 0x1618 int x161c; // 0x161c int x1620; // 0x1620 int x1624; // 0x1624 int x1628; // 0x1628 int x162c; // 0x162c int x1630; // 0x1630 int x1634; // 0x1634 int x1638; // 0x1638 int x163c; // 0x163c int x1640; // 0x1640 int x1644; // 0x1644 int x1648; // 0x1648 int x164c; // 0x164c int x1650; // 0x1650 int x1654; // 0x1654 int x1658; // 0x1658 int x165c; // 0x165c int x1660; // 0x1660 int x1664; // 0x1664 int x1668; // 0x1668 int dynamics_hit_num; // 0x166c FtDynamicHit dynamics_hit[11]; // 0x1670 int x1828; // 0x1828 struct dmg // 0x182c { // int behavior; // 0x182c float percent; // 0x1830 int x1834; // 0x1834 float percent_temp; // 0x1838 float applied; // 0x183c int x1840; // 0x1840 float direction; // 0x1844 int kb_angle; // 0x1848 int damaged_hurtbox; // 0x184c float force_applied; // 0x1850 Vec3 collpos; // 0x1854 int dealt; // 0x1860 int x1864; // 0x1864 GOBJ *source; // 0x1868 int x186c; // 0x186c int x1870; // 0x1870 int x1874; // 0x1874 int x1878; // 0x1878 int x187c; // 0x187c int x1880; // 0x1880 int x1884; // 0x1884 int x1888; // 0x1888 int x188c; // 0x188c int x1890; // 0x1890 int x1894; // 0x1894 int x1898; // 0x1898 int x189c; // 0x189c int x18a0; // 0x18a0 float kb_mag; // 0x18a4 kb magnitude int x18a8; // 0x18a8 int time_since_hit; // 0x18ac in frames int x18b0; // 0x18b0 float armor; // 0x18b4 int x18b8; // 0x18b8 int x18bc; // 0x18bc int x18c0; // 0x18c0 int source_ply; // 0x18c4 damage source ply number int x18c8; // 0x18c8 int x18cc; // 0x18cc int x18d0; // 0x18d0 int x18d4; // 0x18d4 int x18d8; // 0x18d8 int x18dc; // 0x18dc int x18e0; // 0x18e0 int x18e4; // 0x18e4 int x18e8; // 0x18e8 u16 instancehitby; // 0x18ec. Last Move Instance This Player Was Hit by int x18f0; // 0x18f0 int x18f4; // 0x18f4 u8 x18f8; // 0x18f8 u8 x18f9; // 0x18f8 u16 model_shift_frames; // 0x18f8 u8 x18fc; // 0x18fc u8 x18fd; // 0x18fd int x1900; // 0x1900 int x1904; // 0x1904 int x1908; // 0x1908 int x190c; // 0x190c int x1910; // 0x1910 int x1914; // 0x1914 int x1918; // 0x1918 int x191c; // 0x191c int x1920; // 0x1920 int x1924; // 0x1924 int x1928; // 0x1928 int x192c; // 0x192c int x1930; // 0x1930 int x1934; // 0x1934 int x1938; // 0x1938 int x193c; // 0x193c int x1940; // 0x1940 int x1944; // 0x1944 int x1948; // 0x1948 int x194c; // 0x194c int x1950; // 0x1950 int x1954; // 0x1954 int x1958; // 0x1958 float hitlag_frames; // 0x195c } dmg; // int x1960; // 0x1960 float x1964; // 0x1964 struct jump // 0x1968 { // char jumps_used; // 0x1968 char walljumps_used; // 0x1969 } jump; // int x196c; // 0x196c int x1970; // 0x1970 GOBJ *heldItem; // 0x1974 GOBJ *x1978; // 0x1978 int x197c; // 0x197c GOBJ *headItem; // 0x1980 GOBJ *heldItemSpecial; // 0x1984 struct hurtstatus // 0x1988 { // int script; // 0x1988 int game; // 0x198c int ledge_intang_left; // 0x1990 int respawn_intang_left; // 0x1994 } hurtstatus; // struct shield { float health; // 0x1998 float lightshield_amt; // 0x199c int dmg_taken; // 0x19a0, seems to be all damage taken during the frame, is reset at the end of the frame int dmg_taken2; // 0x19a4, idk there so many of these GOBJ *dmg_source; // 0x19a8, points to the entity that hit the shield float hit_direction; // 0x19ac int hit_attr; // 0x19b0, attribute of the hitbox that collided float x19b4; // 0x19b4 float x19b8; // 0x19b8 int dmg_taken3; // 0x19bc, seems to be the most recent amount of damage taken } shield; struct shield_update // 0x19c0 { JOBJ *bone; // 0x19c0 unsigned char is_checked : 1; // 0x19d0 0x80. is checked for collision when 0 Vec3 pos; // 19d4 Vec3 offset; // 0x19d4 float size_mult; // 0x19e0 } shield_bubble; struct reflect_update // 0x19e4 { JOBJ *bone; // 0x19e4 unsigned char is_checked : 1; // 0x19d0 0x80. is checked for collision when 0 Vec3 pos; // 0x19d4 Vec3 offset; // 0x19f8 float size_mult; // 0x1a04 } reflect_bubble; struct absorb_update // 0x1a08 { JOBJ *bone; // 0x1a08 unsigned char is_checked : 1; // 0x1a0c 0x80. is checked for collision when 0 Vec3 pos; // 0x1a10 Vec3 offset; // 0x1a1c float size_mult; // 0x1a28 } absorb_bubble; struct reflect_hit // 0x1a2c { // float hit_direction; // 0x1a2c int max_dmg; // 0x1a30 float dmg_mult; // 0x1a34 int is_break; // 0x1a38 } reflect_hit; // struct absorb_hit // 0x1a40 { // int x1a3c; // 0x1a3c float hit_direction; // 0x1a40 int dmg_taken; // 0x1a44 int hits_taken; // 0x1a48 } absorb_hit; // struct grab // 0x1a4c { // float grab_timer; // 0x1a4c int x1a50; // 0x1a50 int x1a54; // 0x1a54 GOBJ *grab_attacker; // 0x1a58 GOBJ *grab_victim; // 0x1a5c int x1a60; // 0x1a60 int x1a64; // 0x1a64 u16 x1a68; // 0x1a68 u16 vuln; // 0x1a6a int x1a6c; // 0x1a6c int x1a70; // 0x1a70 int x1a74; // 0x1a74 int x1a78; // 0x1a78 int x1a7c; // 0x1a7c int x1a80; // 0x1a80 int x1a84; // 0x1a84 } grab; // CPU cpu; // 0x1a88 int x1fe0; // 0x1fe0 int x1fe4; // 0x1fe4 int x1fe8; // 0x1fe8 int x1fec; // 0x1fec int x1ff0; // 0x1ff0 int x1ff4; // 0x1ff4 int x1ff8; // 0x1ff8 int x1ffc; // 0x1ffc int x2000; // 0x2000 int x2004; // 0x2004 int x2008; // 0x2008 int x200c; // 0x200c int x2010; // 0x2010 int x2014; // 0x2014 int x2018; // 0x2018 int x201c; // 0x201c int x2020; // 0x2020 int x2024; // 0x2024 int x2028; // 0x2028 int x202c; // 0x202c int x2030; // 0x2030 int x2034; // 0x2034 int x2038; // 0x2038 int x203c; // 0x203c int x2040; // 0x2040 int x2044; // 0x2044 int x2048; // 0x2048 int x204c; // 0x204c int x2050; // 0x2050 int x2054; // 0x2054 int x2058; // 0x2058 int x205c; // 0x205c int x2060; // 0x2060 int ledge_cooldown; // 0x2064 int attack_kind; // 0x2068, non attacks have id 1 int x206c; // 0x206c u8 x2070; // 0x2070 u8 x2071; // 0x2071 u8 x2072; // 0x2072 u8 x2073; // 0x2073 int x2074; // 0x2074 int x2078; // 0x2078 int x207c; // 0x207c int x2080; // 0x2080 int x2084; // 0x2084 u16 moveID; // 0x2088 int x208c; // 0x208c int x2090; // 0x2090 int x2094; // 0x2094 int x2098; // 0x2098 int x209c; // 0x209c JOBJ *accessory; // 0x20a0 int x20a4; // 0x20a4 void *shadow; // 0x20a8, ASSERTS @ 8037f7b8, describes multiple struct members int x20ac; // 0x20ac struct afterimage // { // struct FtAfterImageKey afterimage[3]; // 0x20b0 float afterimage_bottom; // 0x20f8 float afterimage_top; // 0x20fc u8 afterimage_state; // 0x2100 unsigned char afterimage_num : 7; // 0x2101 } afterimage; // int x2104; // 0x2104 int x2108; // 0x2108 int x210c; // 0x210c int x2110; // 0x2110 struct smash // 0x2114 { // int state; // 0x2114 0 = none, 1 = pre-charge, 2 = charging, 3 = release int frame; // 0x2118 number of frames fighter has charged for float hold_frame; // 0x211c frame that charge begins/ends float dmg_mult; // 0x2120 damage multiplier float speed_mult; // 0x2124 speed multiplier? int x2128; // 0x2128 int x212c; // 0x212c int is_sfx_played; // 0x2130 bool for smash sfx? u8 vibrate_frame; // 0x2134 u8 x22135; // 0x2135 float since_hitbox; // 0x2138 } smash; // int x213c; // 0x213c int x2140; // 0x2140 int x2144; // 0x2144 int x2148; // 0x2148 int x214c; // 0x214c int x2150; // 0x2150 int x2154; // 0x2154 int x2158; // 0x2158 int x215c; // 0x215c int x2160; // 0x2160 int x2164; // 0x2164 int x2168; // 0x2168 int x216c; // 0x216c int x2170; // 0x2170 int x2174; // 0x2174 int x2178; // 0x2178 int x217c; // 0x217c int x2180; // 0x2180 int x2184; // 0x2184 int x2188; // 0x2188 int x218c; // 0x218c struct cb { void (*OnGrabFighter_Self)(GOBJ *fighter); // 0x2190 void (*x2194)(GOBJ *fighter); // 0x2194 void (*OnGrabFighter_Victim)(GOBJ *fighter); // 0x2198 void (*IASA)(GOBJ *fighter); // 0x219C void (*Anim)(GOBJ *fighter); // 0x21A0 void (*Phys)(GOBJ *fighter); // 0x21a4 void (*Coll)(GOBJ *fighter); // 0x21a8 void (*Cam)(GOBJ *fighter); // 0x21ac void (*Accessory1)(GOBJ *fighter); // 0x21b0 void (*Accessory2)(GOBJ *fighter); // 0x21b4 void (*Accessory3)(GOBJ *fighter); // 0x21b8 void (*Accessory4)(GOBJ *fighter); // 0x21bc void (*OnGiveDamage)(GOBJ *fighter); // 0x21c0 void (*OnShieldHit)(GOBJ *fighter); // 0x21c4 void (*OnReflectHit)(GOBJ *fighter); // 0x21c8 void (*x21cc)(GOBJ *fighter); // 0x21cc void (*EveryHitlag)(GOBJ *fighter); // 0x21d0 void (*EnterHitlag)(GOBJ *fighter); // 0x21d4 void (*ExitHitlag)(GOBJ *fighter); // 0x21d8 void (*OnTakeDamage)(GOBJ *fighter); // 0x21dc void (*OnDeath)(GOBJ *fighter); // 0x21e0 void (*OnDeath2)(GOBJ *fighter); // 0x21e4, internally Dead_Proc as evidenced by 800f5430 void (*OnDeath3)(GOBJ *fighter); // 0x21e8 void (*OnActionStateChange)(GOBJ *fighter); // 0x21ec void (*OnTakeDamage2)(GOBJ *fighter); // 0x21f0 void (*OnHurtboxDetect)(GOBJ *fighter); // 0x21f4 void (*OnSpin)(GOBJ *fighter); // 0x21f8 } cb; unsigned char x21fc_1 : 1; // 0x80 - x21fc_ unsigned char show_center_sphere : 1; // 0x40 - x21fc_ unsigned char show_item_pickup : 1; // 0x20 - x21fc_ unsigned char show_cpu_ai : 1; // 0x10 - x21fc_ unsigned char show_footstool : 1; // 0x8 - x21fc_ unsigned char show_dynamics : 1; // 0x4 - x21fc_ unsigned char show_hit : 1; // 0x2 - x21fc_ unsigned char show_model : 1; // 0x1 - x21fc_ struct ftcmd_var // 0x2200 { // int subactionFlag0; // 0x2200 int subactionFlag1; // 0x2204 int subactionFlag2; // 0x2208 int subactionFlag3; // 0x220C } ftcmd_var; // struct flags // 0x2210 { // unsigned char throw_1 : 1; // 0x80 - x2210 unsigned char throw_2 : 1; // 0x40 - x2210 unsigned char throw_3 : 1; // 0x20 - x2210 unsigned char throw_release : 1; // 0x10 - x2210. also used to change users direction during aerial attacks unsigned char throw_turn : 1; // 0x8 - x2210 unsigned char throw_6 : 1; // 0x4 - x2210 unsigned char throw_7 : 1; // 0x2 - x2210 unsigned char throw_8 : 1; // 0x1 - x2210 float throw_timerval; // equal to script_event_timer of the attacker unsigned char x2218_1 : 1; // 0x80 - x2218 unsigned char x2218_2 : 1; // 0x40 - x2218 unsigned char x2218_3 : 1; // 0x20 - x2218 unsigned char reflect_enable : 1; // 0x10 - x2218 unsigned char reflect_nochangeowner : 1; // 0x8 - x2218 unsigned char x2218_6 : 1; // 0x4 - x2218 unsigned char absorb_enable : 1; // 0x2 - x2218 unsigned char absorb_unk : 1; // 0x1 - x2218 unsigned char persistent_gfx : 1; // is shielding bool. 0x80 - 0x2219 unsigned char immune : 1; // 0x40 - 0x2219 unsigned char x2219_3 : 1; // 0x20 - 0x2219 unsigned char hitbox_active : 1; // 0x10 - 0x2219 unsigned char x2219_5 : 1; // 0x8 - 0x2219 unsigned char freeze : 1; // 0x4 - 0x2219 unsigned char hitlag_unk : 1; // 0x2 - 0x2219 unsigned char hitlag_unk2 : 1; // 0x1 - 0x2219 unsigned char x221a_1 : 1; // 0x80 - 0x221a unsigned char x221a_2 : 1; // 0x40 - 0x221a unsigned char hitlag : 1; // 0x20 - 0x221a unsigned char x221a_4 : 1; // 0x10 - 0x221a unsigned char is_fastfall : 1; // 0x8 - 0x221a unsigned char no_hurt_script : 1; // 0x4 - 0x221a unsigned char x221a_7 : 1; // 0x2 - 0x221a unsigned char gfx_persist : 1; // 0x1 - 0x221a unsigned char shield_enable : 1; // 0x80 - 0x221b unsigned char shield_x40 : 1; // 0x40 - 0x221b unsigned char shield_x20 : 1; // 0x20 - 0x221b unsigned char shield_x10 : 1; // 0x10 - 0x221b unsigned char shield_x8 : 1; // 0x8 - 0x221b unsigned char x221b_6 : 1; // 0x4 - 0x221b unsigned char x221b_7 : 1; // 0x2 - 0x221b unsigned char x221b_8 : 1; // 0x1 - 0x221b unsigned char x221c_1 : 1; // 0x80 - 0x221c unsigned char x221c_2 : 1; // 0x40 - 0x221c unsigned char x221c_3 : 1; // 0x20 - 0x221c unsigned char x221c_4 : 1; // 0x10 - 0x221c unsigned char x221c_5 : 1; // 0x8 - 0x221c unsigned char x221c_6 : 1; // 0x4 - 0x221c unsigned char hitstun : 1; // 0x2 - 0x221c unsigned char x221c_8 : 1; // 0x1 = 0x221c unsigned char x221d_1 : 1; // 0x80 - 0x221d unsigned char x221d_2 : 1; // 0x40 - 0x221d unsigned char x221d_3 : 1; // 0x20 - 0x221d unsigned char input_enable : 1; // 0x10 - 0x221d unsigned char x221d_5 : 1; // 0x8 - 0x221d unsigned char nudge_disable : 1; // 0x4 - 0x221d unsigned char ground_ignore : 1; // 0x2 - 0x221d unsigned char x221d_8 : 1; // 0x1 - 0x221d unsigned char invisible : 1; // 0x80 - 0x221e unsigned char x221e_2 : 1; // 0x40 - 0x221e unsigned char x221e_3 : 1; // 0x20 - 0x221e unsigned char isItemVisible : 1; // 0x10 - 0x221e unsigned char x221e_5 : 1; // 0x8 - 0x221e unsigned char x221e_6 : 1; // 0x4 - 0x221e unsigned char x221e_7 : 1; // 0x2 - 0x221e unsigned char x221e_8 : 1; // 0x1 - 0x221e unsigned char is_offscreen : 1; // 0x80 - 0x221f unsigned char dead : 1; // 0x40 - 0x221f unsigned char x221f_3 : 1; // 0x20 - 0x221f unsigned char sleep : 1; // 0x10 unsigned char ms : 1; // ms = master/slave. is 1 when the player is a slave unsigned char x221f_6 : 1; unsigned char x221f_7 : 1; unsigned char x221f_8 : 1; char flags_2220; // 0x2220 char flags_2221; // 0x2221 unsigned char x2222_1 : 1; // 0x80 - 0x2222 unsigned char is_multijump : 1; // 0x40 - 0x2222 unsigned char x2222_3 : 1; // 0x20 - 0x2222 unsigned char ceilko_nokb : 1; // 0x10 - 0x2222, allow death off top without any Y KB unsigned char x2222_5 : 1; // 0x08 - 0x2222 unsigned char has_follower : 1; // 0x04 - 0x2222, this makes the subcharacter enter sleep when the main char dies unsigned char x2222_7 : 1; // 0x02 - 0x2222 unsigned char x2222_8 : 1; // 0x01 - 0x2222 char flags_2223; // 0x2223 unsigned char x2224_1 : 1; // 0x80 - 0x2224 unsigned char x2224_2 : 1; // 0x40 - 0x2224 unsigned char stamina_dead : 1; // 0x20 - 0x2224 unsigned char x2224_4 : 1; // 0x10 - 0x2224 unsigned char x2224_5 : 1; // 0x8 - 0x2224 unsigned char x2224_6 : 1; // 0x4 - 0x2224 unsigned char x2224_7 : 1; // 0x2 - 0x2224 unsigned char x2224_8 : 1; // 0x1 - 0x2224 unsigned char x2225_1 : 1; // 0x80 - 0x2225 unsigned char x2225_2 : 1; // 0x40 - 0x2225 unsigned char has_model_addition : 1; // 0x20 - 0x2225 bool for if fighter has a model addition, like kirby copy ability and puff hat unsigned char x2225_4 : 1; // 0x10 - 0x2225 unsigned char x2225_5 : 1; // 0x8 - 0x2225 unsigned char x2225_6 : 1; // 0x4 - 0x2225 unsigned char x2225_7 : 1; // 0x2 - 0x2225 unsigned char x2225_8 : 1; // 0x1 - 0x2225 unsigned char x2226_1 : 1; // 0x80 - 0x2226 unsigned char x2226_2 : 1; // 0x40 - 0x2226 unsigned char is_thrown : 1; // 0x20 - 0x2226, might actually be for skipping grab collision unsigned char x2226_4 : 1; // 0x10 - 0x2226 unsigned char x2226_5 : 1; // 0x8 - 0x2226 unsigned char x2226_6 : 1; // 0x4 - 0x2226 unsigned char x2226_7 : 1; // 0x2 - 0x2226 unsigned char x2226_8 : 1; // 0x1 - 0x2226 char flags_2227; // 0x2227 char x2228_1 : 1; // 0x80 - 0x2228 char x2228_2 : 1; // 0x40 - 0x2228 char x2228_3 : 1; // 0x20 - 0x2228 char x2228_4 : 1; // 0x10 - 0x2228 char x2228_5 : 1; // 0x08 - 0x2228 char x2228_6 : 1; // 0x04 - 0x2228 char used_tether : 1; // 0x02 - 0x2228 char x2228_8 : 1; // 0x01 - 0x2228 unsigned char x2229_1 : 1; // 0x80 - 0x2229 unsigned char x2229_2 : 1; // 0x40 - 0x2229 unsigned char x2229_3 : 1; // 0x20 - 0x2229 unsigned char x2229_4 : 1; // 0x10 - 0x2229 unsigned char x2229_5 : 1; // 0x8 - 0x2229 unsigned char x2229_6 : 1; // 0x4 - 0x2229 unsigned char x2229_7 : 1; // 0x2 - 0x2229 unsigned char no_reaction_always : 1; // 0x1 - 0x2229 char flags_222A; // 0x222A char flags_222B; // 0x222B } flags; // struct fighter_var // 0x222c { // int charVar1; // 0x222c int charVar2; // 0x2230 int charVar3; // 0x2234 int charVar4; // 0x2238 int charVar5; // 0x223c int charVar6; // 0x2240 int charVar7; // 0x2244 int charVar8; // 0x2248 int charVar9; // 0x224c int charVar10; // 0x2250 int charVar11; // 0x2254 int charVar12; // 0x2258 int charVar13; // 0x225c int charVar14; // 0x2260 int charVar15; // 0x2264 int charVar16; // 0x2268 int charVar17; // 0x226c int charVar18; // 0x2270 int charVar19; // 0x2274 int charVar20; // 0x2278 int charVar21; // 0x227c int charVar22; // 0x2280 int charVar23; // 0x2284 int charVar24; // 0x2288 int charVar25; // 0x228c int charVar26; // 0x2290 int charVar27; // 0x2294 int charVar28; // 0x2298 int charVar29; // 0x229c int charVar30; // 0x22a0 int charVar31; // 0x22a4 int charVar32; // 0x22a8 int charVar33; // 0x22ac int charVar34; // 0x22b0 int charVar35; // 0x22b4 int charVar36; // 0x22b8 int charVar37; // 0x22bc int charVar38; // 0x22c0 int charVar39; // 0x22c4 int charVar40; // 0x22c8 int charVar41; // 0x22cc int charVar42; // 0x22d0 int charVar43; // 0x22d4 int charVar44; // 0x22d8 int charVar45; // 0x22dc int charVar46; // 0x22e0 int charVar47; // 0x22e4 int charVar48; // 0x22e8 int charVar49; // 0x22ec int charVar50; // 0x22f0 int charVar51; // 0x22f4 int charVar52; // 0x22f8 } fighter_var; int x22fc; // 0x22fc int x2300; // 0x2300 int x2304; // 0x2304 int x2308; // 0x2308 int x230c; // 0x230c int x2310; // 0x2310 int x2314; // 0x2314 int x2318; // 0x2318 int x231c; // 0x231c int x2320; // 0x2320 int stage_internal; // 0x2324 so stupid, used for decrementing hazard immunity int x2328; // 0x2328 int x232c; // 0x232c int x2330; // 0x2330 int x2334; // 0x2334 int x2338; // 0x2338 int x233c; // 0x233c struct state_var // 0x2340 { // int stateVar1; // 0x2340 int stateVar2; // 0x2344 int stateVar3; // 0x2348 int stateVar4; // 0x234c int stateVar5; // 0x2350 int stateVar6; // 0x2354 int stateVar7; // 0x2358 int stateVar8; // 0x235c int stateVar9; // 0x2360 int stateVar10; // 0x2364 int stateVar11; // 0x2368 int stateVar12; // 0x236c int stateVar13; // 0x2370 int stateVar14; // 0x2374 int stateVar15; // 0x2378 int stateVar16; // 0x237c int stateVar17; // 0x2380 int stateVar18; // 0x2384 } state_var; // int x2388; // 0x2388 int x238c; // 0x238c int x2390; // 0x2390 int x2394; // 0x2394 int x2398; // 0x2398 int x239c; // 0x239c int x23a0; // 0x23a0 int x23a4; // 0x23a4 int x23a8; // 0x23a8 int x23ac; // 0x23ac int x23b0; // 0x23b0 int x23b4; // 0x23b4 int x23b8; // 0x23b8 int x23bc; // 0x23bc int x23c0; // 0x23c0 int x23c4; // 0x23c4 int x23c8; // 0x23c8 int x23cc; // 0x23cc int x23d0; // 0x23d0 int x23d4; // 0x23d4 int x23d8; // 0x23d8 int x23dc; // 0x23dc int x23e0; // 0x23e0 int x23e4; // 0x23e4 int x23e8; // 0x23e8 struct MEX { int anim_owner; GOBJ *kb_abilitysource; u8 ucf_stickX[3]; } MEX; struct TM { s16 state_frame; // how many frames the player has been in this state s16 shield_frame; // how many frames the player has been shielding u16 state_prev[6]; u16 state_prev_frames[6]; u16 last_move_hurt; // Previous Move Instance Hit By u16 vuln_frames; // how many frames the fighter has been vulnerable u16 can_fastfall_frames; // how many frames the fighter has been able to fast fall int post_hitstun_frames; // frames fighter has been out of hitstun GOBJ *fighter_hurt_shield; // pointer to the fighter who's shield this fighter hit void *cb_anim; // additional animation callback } TM; }; struct FtParts // is in the fighter data { int num; // 0x2240 DOBJ **dobj; // 0x2244 array of dobjs for the ftpar void *x8; // 0x2248 void *xc; // 0x224C }; struct FtPartsDesc { int model_num; // 0x2250 FtPartsLookup *lookups; }; struct FtDOBJUnk3 { int num; FtDOBJUnk2 *x4; // pointer to u8 array }; struct FtDOBJUnk2 { int num; u8 *id; // pointer to u8 array }; struct FtPartsLookup { FtDOBJUnk3 *x0; void *x4; void *x8; void *xc; void *x10; }; struct FtDOBJUnk // is in the fighter data { int num; // 0x2250 u8 x4[5]; // array of bools? FtDOBJUnk3 *xc; void *x10; void *x14; void *x18; void *x1c; }; /** State Structs **/ struct FtCliffCatch { int ledge_index; float fall_timer; int timer; }; /** Static Variables **/ static ftCommonData **stc_ftcommon = (R13 + -0x514C); static GXColor **stc_shieldcolors = (R13 + -0x5194); /*** Functions ***/ void ActionStateChange(float startFrame, float animSpeed, float animBlend, GOBJ *fighter, int stateID, int flags1, int flags2); void Subaction_Update(GOBJ *fighter); void Fighter_UpdateBonePos(FighterData *fighter_data, int unk); void *Animation_GetAddress(FighterData *fighter, int animID); SubactionHeader *Fighter_GetSubactionHeader(FighterData *fighter, int animID); float Animation_GetLength(int animAddress); void Fighter_EnterLightThrow(GOBJ *fighter, int stateID); void Fighter_EnterDamageFall(GOBJ *fighter); void Fighter_EnterWait(GOBJ *fighter); void Fighter_EnterFall(GOBJ *fighter); void Fighter_EnterSpecialFall(GOBJ *fighter, int can_fastfall, int can_not_noimpactland, int can_not_interrupt, float aerialDriftMultipler, float landing_frames); void Fighter_EnterLanding(GOBJ *fighter); void Fighter_EnterSpecialLanding(GOBJ *fighter, int unk, float state_length); void Fighter_EnterSleep(GOBJ *fighter, int ms); void Fighter_EnterCliffWait(GOBJ *fighter); void Fighter_EnterRebirth(GOBJ *fighter); void Fighter_EnterRebirthWait(GOBJ *fighter); void Fighter_UpdateRebirthPlatformPos(GOBJ *fighter); void Fighter_MoveToCliff(GOBJ *fighter); GOBJ *Fighter_GetGObj(int ply); GOBJ *Fighter_GetSubcharGObj(int ply, int ms); Playerblock *Fighter_GetPlayerblock(int ply); void Fighter_SetSlotType(int ply, int slot); int Fighter_GetControllerPort(int ply); int *Fighter_GetStaleMoveTable(int ply); void Fighter_SetPosition(int ply, int ms, Vec3 *pos); void Fighter_ApplyIntang(GOBJ *fighter, int duration); int Fighter_GetSlotType(int index); // returns 0x0 for HMN, 0x1 for CPU, 0x2 for Demo, 0x3 for not present int Fighter_GetStocks(int ply); void Fighter_SetFallNum(int index, int ms, int falls); void Fighter_EnableECBBottomUpdate(FighterData *fighter); void Fighter_EnterDamageState(GOBJ *fighter, int stateID, float frame); int Fighter_BoneLookup(FighterData *fighter, int boneID); void Fighter_GiveDamage(FighterData *fighter, float damage); void Fighter_GiveHeal(FighterData *fighter, int heal); void Fighter_SetHUDDamage(int player, u16 damage); void Fighter_RunOnHitCallbacks(GOBJ *fighter); void Fighter_SetStocks(int ply, int stocks); int FrameTimerCheck(GOBJ *fighter); void Fighter_EnterMiscPassState(float start_frame, GOBJ *fighter, int state, int flags); int Fighter_CollGround_PassLedge(GOBJ *fighter); void Fighter_CollGround_StopLedge(GOBJ *fighter); int Fighter_CollAir_GrabLedgeWalljump(GOBJ *fighter, void *perFrame, void *onLand); int Fighter_CollAir_GrabLedge(GOBJ *fighter, int grab_direction); void Fighter_CollAir_IgnoreLedge(GOBJ *fighter, void *callback); int Fighter_CollAir_IgnoreLedge_NoCB(GOBJ *fighter); int Fighter_IASACheck_CliffCatch(GOBJ *fighter); int Fighter_IASACheck_JumpAerial(GOBJ *fighter); int Fighter_IASACheck_JumpF(GOBJ *fighter); int Fighter_IASACheck_PassConditions(GOBJ *fighter); int Fighter_IASACheck_Turn(GOBJ *fighter); void Fighter_PhysGround_ApplyFriction(GOBJ *fighter); void Fighter_PhysAir_ApplyGravity(FighterData *fighter, float gravity, float limit); void Fighter_PhysAir_LimitVelocity(FighterData *fighter); void Fighter_Phys_UseAnimPos(FighterData *fighter); void Fighter_Phys_UseAnimPosAndStick(FighterData *fighter); void Fighter_SetGrounded(FighterData *fighter); void Fighter_SetGrounded2(FighterData *fighter); void Fighter_SetAirborne(FighterData *fighter); void Fighter_LoseGroundJump(FighterData *fighter_data); void Fighter_EnableCollUpdate(FighterData *fighter_data); void Fighter_KillAllVelocity(GOBJ *fighter); void Fighter_AdvanceScript(GOBJ *fighter); void Fighter_GFXRemoveAll(GOBJ *fighter); void Fighter_EnableReflectUpdate(GOBJ *fighter); void Fighter_CreateReflect(GOBJ *fighter, ReflectDesc *reflect, void *cb_OnReflectHit); float Fighter_GetBoneRotation(FighterData *fighter, int bone); float Fighter_RotateBone_Pitch(FighterData *fighter, int bone, float angle); float Fighter_RotateBone_Yaw(FighterData *fighter, int bone, float angle); float Fighter_RotateBone_Roll(FighterData *fighter, int bone, float angle); void Fighter_PlayVoiceSFX(FighterData *fighter, int sfxID, int volume, int balance); void Fighter_ApplyOverlay(FighterData *fighter_data, int overlay, int unk); void Fighter_UpdateOverlay(GOBJ *fighter); void Fighter_DisableBlend(GOBJ *fighter, int animd_id); void Fighter_UpdateDynamics(GOBJ *fighter, u16 *dynamic_struct); void Fighter_ZeroCPUInputs(FighterData *fighter_data); void Fighter_CreateShieldGFX(GOBJ *fighter); void Fighter_UpdateShieldGFX(GOBJ *fighter, float size); int Fighter_GetShieldColorIndex(int ply); int Fighter_GetExternalID(int ply); int Fighter_GetCostumeID(int ply); float Fighter_GetBaseScale(FighterData *fighter); void Fighter_SetScale(GOBJ *fighter, float scale); void Fighter_InitDynamics(FighterData *fighter_data); void Fighter_ProcDynamics(GOBJ *fighter); float Fighter_GetKnockbackAngle(FighterData *fighter_data); void Fighter_UpdateCameraBox(GOBJ *fighter); void Fighter_SetAllHurtboxesNotUpdated(GOBJ *fighter); void Fighter_UpdateHurtboxes(FighterData *fighter_data); void Fighter_UpdateIK(GOBJ *fighter); void Fighter_ColorRemove(FighterData *fighter_data, int color_kind); void Fighter_CPUInitialize(FighterData *fighter_data, int cpu_kind, int cpu_level, int unk); int Fighter_GetCPUKind(int ply); int Fighter_GetCPULevel(int ply); char *Fighter_GetName(int external_id); void Fighter_InitPObj(); void Fighter_InitPObj2(); void Fighter_IndexFtPartsDObjs(GOBJ *fighter, JOBJ *copy_model, FtParts *ftparts); // inits the dobj array in ftpartsmodel void Fighter_InitFtPartsModel(FtPartsDesc *ftpartsdesc, FtDOBJUnk *unk, int index, FtParts *ftparts, FtParts *ftparts2); int Fighter_CheckUnlocked(int ext_id); void Fighter_UpdateOnscreenBool(GOBJ *fighter); #endif ================================================ FILE: MexTK/include/hsd.h ================================================ #ifndef MEX_H_HSD #define MEX_H_HSD #include "structs.h" #include "datatypes.h" #include "obj.h" #include "color.h" // button bits #define PAD_BUTTON_DPAD_LEFT 0x1 #define PAD_BUTTON_DPAD_RIGHT 0x2 #define PAD_BUTTON_DPAD_DOWN 0x4 #define PAD_BUTTON_DPAD_UP 0x8 #define PAD_TRIGGER_Z 0x10 #define PAD_TRIGGER_R 0x20 #define PAD_TRIGGER_L 0x40 #define PAD_BUTTON_A 0x100 #define PAD_BUTTON_B 0x200 #define PAD_BUTTON_X 0x400 #define PAD_BUTTON_Y 0x800 #define PAD_BUTTON_START 0x1000 #define PAD_BUTTON_UP 0x10000 #define PAD_BUTTON_DOWN 0x20000 #define PAD_BUTTON_LEFT 0x40000 #define PAD_BUTTON_RIGHT 0x80000 #define HSD_BUTTON_DPAD_LEFT 0x0001 #define HSD_BUTTON_DPAD_RIGHT 0x0002 #define HSD_BUTTON_DPAD_DOWN 0x0004 #define HSD_BUTTON_DPAD_UP 0x0008 #define HSD_TRIGGER_Z 0x0010 #define HSD_TRIGGER_R 0x0020 #define HSD_TRIGGER_L 0x0040 #define HSD_BUTTON_A 0x0100 #define HSD_BUTTON_B 0x0200 #define HSD_BUTTON_X 0x0400 #define HSD_BUTTON_Y 0x0800 #define HSD_BUTTON_START 0x1000 #define HSD_BUTTON_UP 0x10000 #define HSD_BUTTON_DOWN 0x20000 #define HSD_BUTTON_LEFT 0x40000 #define HSD_BUTTON_RIGHT 0x80000 /*** Structs ***/ struct HSD_ObjAllocData { u32 flags; //0x00 - Technically 2 diff flags void *freehead; //0x04 u32 used; //0x08 u32 free; //0x0C u32 peak; //0x10 u32 num_limit; //0x14 u32 heap_limit_size; //0x18 u32 heap_limit_num; //0x1C u32 size; //0x20 u32 align; //0x24 struct HSD_ObjAllocData *next; //0x28 }; struct HSD_Material { GXColor ambient; GXColor diffuse; GXColor specular; float alpha; float shininess; }; struct HSD_Pad { int held; // 0x0 int heldPrev; // 0x4 int down; // 0x8 int rapidFire; // 0xc int up; // 0x10 int rapidTimer; // 0x14 s8 stickX; // 0x18 s8 stickY; // 0x19 s8 substickX; // 0x1a s8 substickY; // 0x1b u8 triggerLeft; // 0x1c u8 triggerRight; // 0x1d float fstickX; // 0x20 float fstickY; // 0x24 float fsubstickX; // 0x28 float fsubstickY; // 0x2c float ftriggerLeft; // 0x30 float ftriggerRight; // 0x34 float x38; // 0x38 float x3c; // 0x3c u8 x40; // 0x40 u8 status; // 0x41 0 = plugged, -1 = unplugged }; struct HSD_Pads { HSD_Pad pad[4]; }; struct HSD_Update { // 0x80479d58 u32 sys_frames_pre; //0x0 u32 sys_frames_post; //0x4 u32 engine_frames; //0x8 u32 change_scene; //0xC unsigned char flag1 : 1; //0x10 - 0x80 unsigned char flag2 : 1; //0x10 - 0x40 unsigned char flag3 : 1; //0x10 - 0x20 unsigned char flag4 : 1; //0x10 - 0x10 unsigned char flag5 : 1; //0x10 - 0x08 unsigned char flag6 : 1; //0x10 - 0x04 unsigned char pause_game : 1; //0x10 - 0x02 unsigned char pause_develop : 1; //0x10 - 0x01 unsigned char flag9 : 1; //0x11 - 0x80 unsigned char flag10 : 1; //0x11 - 0x40 unsigned char flag11 : 1; //0x11 - 0x20 unsigned char flag12 : 1; //0x11 - 0x10 unsigned char flag13 : 1; //0x11 - 0x08 unsigned char flag14 : 1; //0x11 - 0x04 unsigned char pause_game_prev : 1; //0x11 - 0x02 unsigned char pause_develop_prev : 1; //0x11 - 0x01 unsigned char flag17 : 1; //0x12 - 0x80 unsigned char flag18 : 1; //0x12 - 0x40 unsigned char flag19 : 1; //0x12 - 0x20 unsigned char flag20 : 1; //0x12 - 0x10 unsigned char flag21 : 1; //0x12 - 0x08 unsigned char flag22 : 1; //0x12 - 0x04 unsigned char flag23 : 1; //0x12 - 0x02 unsigned char advance : 1; //0x12 - 0x01 unsigned char flag24 : 1; //0x12 - 0x80 unsigned char flag25 : 1; //0x12 - 0x40 unsigned char flag26 : 1; //0x12 - 0x20 unsigned char flag27 : 1; //0x12 - 0x10 unsigned char flag28 : 1; //0x12 - 0x08 unsigned char flag29 : 1; //0x12 - 0x04 unsigned char flag30 : 1; //0x12 - 0x02 unsigned char advance_prev : 1; //0x12 - 0x01 int (*checkPause)(); //0x14 returns 1 when toggling pause int (*checkAdvance)(); //0x18 returns 1 when advancing frame u32 x1c; //0x1C u32 x20; u32 x24; u32 x28; u32 x2c; void (*onFrame)(); //0x30 }; struct HSD_VI { int x0; int x4; int is_prog; }; /*** Static Variables ***/ static HSD_VI *stc_HSD_VI = 0x8046b0f0; /*** Functions ***/ int HSD_Randi(int max); float HSD_Randf(); void *HSD_MemAlloc(int size); void HSD_Free(void *ptr); void *HSD_ObjAlloc(HSD_ObjAllocData *obj_def); void HSD_ObjFree(HSD_ObjAllocData *obj_def, void *obj); void HSD_ImageDescCopyFromEFB(_HSD_ImageDesc *image_desc, int left, int top, int z_flag); // must be called from a cobj callback! void GX_AllocImageData(_HSD_ImageDesc *image_desc, int width, int height, int fmt, int size); // image data buffer is stored to the image_desc void GXTexModeSync(); void GXPixModeSync(); void GXInvalidateTexAll(); u64 Pad_GetRapidHeld(int pad); #endif ================================================ FILE: MexTK/include/inline.h ================================================ #ifndef MEX_H_INLINE #define MEX_H_INLINE #include "structs.h" #include "fighter.h" #include "obj.h" #include "mex.h" #include "datatypes.h" #include "hsd.h" #include "math.h" #include "useful.h" /*** Functions ***/ static float fabs(float x) { if (x < 0) { return -x; } return x; } static int abs(int x) { if (x < 0) { return -x; } return x; } static void enterKnockback(GOBJ *fighter, int angle, float mag) { FighterData *fighter_data = ((FighterData *)fighter->userdata); // store damage variables fighter_data->dmg.force_applied = mag; fighter_data->dmg.kb_angle = angle; fighter_data->dmg.direction = fighter_data->facing_direction; fighter_data->dmg.damaged_hurtbox = 0; fighter_data->dmg.dealt = 0; fighter_data->dmg.collpos.X = fighter_data->phys.pos.X; fighter_data->dmg.collpos.Y = fighter_data->phys.pos.Y; fighter_data->dmg.collpos.Z = fighter_data->phys.pos.Z; Fighter_EnterDamageState(fighter, -1, 0); return; } static void null() { return; } static void __attribute__((optimize("O0"))) PRIM_DRAW(PRIM *gx, float x, float y, float z, int color) { AS_FLOAT(gx->data) = x; AS_FLOAT(gx->data) = y; AS_FLOAT(gx->data) = z; gx->data = color; return; } static void C_QUATMtx(Vec4 *r, Mtx m) { /*---------------------------------------------------------------------------* Name: QUATMtx Description: Converts a matrix to a unit quaternion. Arguments: r - result quaternion m - the matrix Returns: NONE *---------------------------------------------------------------------------*/ float tr, s; int i, j, k; int nxt[3] = {1, 2, 0}; float q[3]; tr = m[0][0] + m[1][1] + m[2][2]; if (tr > 0.0f) { s = (float)sqrtf(tr + 1.0f); r->W = s * 0.5f; s = 0.5f / s; r->X = (m[1][2] - m[2][1]) * s; r->Y = (m[2][0] - m[0][2]) * s; r->Z = (m[0][1] - m[1][0]) * s; } else { i = 0; if (m[1][1] > m[0][0]) i = 1; if (m[2][2] > m[i][i]) i = 2; j = nxt[i]; k = nxt[j]; s = (float)sqrtf((m[i][i] - (m[j][j] + m[k][k])) + 1.0f); q[i] = s * 0.5f; if (s != 0.0f) s = 0.5f / s; r->W = (m[j][k] - m[k][j]) * s; q[j] = (m[i][j] + m[j][i]) * s; q[k] = (m[i][k] + m[k][i]) * s; r->X = q[0]; r->Y = q[1]; r->Z = q[2]; } } static HSD_Pad *PadGet(int playerIndex, int padType) { HSD_Pads *pads; // get the correct pad if (padType == PADGET_MASTER) pads = 0x804c1fac; else if (padType == PADGET_ENGINE) pads = 0x804c21cc; return (&pads->pad[playerIndex]); } static float lerp(Translation *anim, float currFrame) { float prevFrame, prevPos, nextFrame, nextPos, amt; // get previous threshold int i = 0; prevFrame = anim[i].frame; prevPos = anim[i].value; nextFrame = anim[i + 1].frame; nextPos = anim[i + 1].value; while ((currFrame < prevFrame) | (currFrame > nextFrame)) { i++; prevFrame = anim[i].frame; prevPos = anim[i].value; nextFrame = anim[i + 1].frame; nextPos = anim[i + 1].value; } // get amt amt = (currFrame - prevFrame) / (nextFrame - prevFrame); return amt * (nextPos - prevPos) + prevPos; } static float JOBJ_GetAnimFrame(JOBJ *joint) { // check for AOBJ in jobj JOBJ *jobj; jobj = joint; while (jobj != 0) { if (jobj->aobj != 0) { return jobj->aobj->curr_frame; } // check for AOBJ in dobj DOBJ *dobj; dobj = jobj->dobj; while (dobj != 0) { if (dobj->aobj != 0) { return dobj->aobj->curr_frame; } // check for AOBJ in mobj MOBJ *mobj; mobj = dobj->mobj; if (mobj->aobj != 0) { return mobj->aobj->curr_frame; } // check for AOBJ in tobj TOBJ *tobj; tobj = mobj->tobj; while (tobj != 0) { if (tobj->aobj != 0) { return tobj->aobj->curr_frame; } tobj = tobj->next; } dobj = dobj->next; } jobj = jobj->child; } // no aobj found, return -1 return -1; } static AOBJ *JOBJ_GetFirstAOBJ(JOBJ *jobj) { // check for AOBJ in this jobj if (jobj->aobj != 0) { return jobj->aobj; } // check for AOBJ in dobj DOBJ *dobj; dobj = jobj->dobj; while (dobj != 0) { if (dobj->aobj != 0) { return dobj->aobj; } // check for AOBJ in mobj MOBJ *mobj; mobj = dobj->mobj; if (mobj->aobj != 0) { return mobj->aobj; } // check for AOBJ in tobj TOBJ *tobj; tobj = mobj->tobj; while (tobj != 0) { if (tobj->aobj != 0) { return tobj->aobj; } tobj = tobj->next; } dobj = dobj->next; } // this jobj doesnt have an aobj, check the child if (jobj->child != 0) { AOBJ *aobj = JOBJ_GetFirstAOBJ(jobj->child); if (aobj != 0) return aobj; } // child did not have an aobj, check the sibling if (jobj->sibling != 0) { AOBJ *aobj = JOBJ_GetFirstAOBJ(jobj->sibling); if (aobj != 0) return aobj; } // no aobj found, return 0 return 0; } static AOBJ *JOBJ_GetJointAOBJ(JOBJ *jobj) { // check for AOBJ in this jobj if (jobj->aobj != 0) { return jobj->aobj; } // this jobj doesnt have an aobj, check the child if (jobj->child != 0) { AOBJ *aobj = JOBJ_GetJointAOBJ(jobj->child); if (aobj != 0) return aobj; } // child did not have an aobj, check the sibling if (jobj->sibling != 0) { AOBJ *aobj = JOBJ_GetJointAOBJ(jobj->sibling); if (aobj != 0) return aobj; } // no aobj found, return 0 return 0; } static DOBJ *JOBJ_GetDObjChild(JOBJ *joint, int dobj_index) { int count = 0; DOBJ *dobj = joint->dobj; while (count < dobj_index) { if (dobj->next == 0) assert("dobj not found!"); else dobj = dobj->next; count++; } return dobj; } static float Math_Vec2Angle(Vec2 *a, Vec2 *b) { // get angle // float angle = atan((b->Y - a->Y) / (b->X - a->X)); float angle = atan2((b->Y - a->Y), (b->X - a->X)); /* //Ensure above 0 and below 6.28319 while (angle < 0) { angle += M_PI; } while (angle > M_PI * 2) { angle -= M_PI; } */ return angle; } static float Math_Vec2Distance(Vec2 *a, Vec2 *b) { return sqrtf(pow((a->X - b->X), 2) + pow((a->Y - b->Y), 2)); } static float Math_Vec3Distance(Vec3 *a, Vec3 *b) { return sqrtf(pow((a->X - b->X), 2) + pow((a->Y - b->Y), 2)); } #endif ================================================ FILE: MexTK/include/item.h ================================================ #ifndef MEX_H_ITEM #define MEX_H_ITEM #include "structs.h" #include "datatypes.h" #include "obj.h" #include "color.h" // Item IDs #define ITEM_CAPSULE 0 #define ITEM_BOX 1 #define ITEM_BARREL 2 #define ITEM_EGG 3 #define ITEM_PARTYBALL 4 #define ITEM_BARRELCANNON 5 #define ITEM_BOBOMB 6 #define ITEM_MRSATURN 7 #define ITEM_HEARTCONTAINER 8 #define ITEM_MAXIMTOMATO 9 #define ITEM_STARMAN 10 #define ITEM_HOMERUNBAT 11 #define ITEM_BEAMSWORD 12 #define ITEM_PARASOL 13 #define ITEM_GREENSHELL 14 #define ITEM_REDSHELL 15 #define ITEM_RAYGUN 16 #define ITEM_FREEZIE 17 #define ITEM_FOOD 18 #define ITEM_MOTIONSENSORBOMB 19 #define ITEM_FLIPPER 20 #define ITEM_SUPERSCOPE 21 #define ITEM_STARROD 22 #define ITEM_LIPSSTICK 23 #define ITEM_FAN 24 #define ITEM_FIREFLOWER 25 #define ITEM_SUPERMUSHROOM 26 #define ITEM_POISONMUSHROOM 27 #define ITEM_HAMMER 28 #define ITEM_WARPSTAR 29 #define ITEM_SCREWATTACK 30 #define ITEM_BUNNYHOOD 31 #define ITEM_METALBOX 32 #define ITEM_CLOAKINGDEVICE 33 #define ITEM_POKEBALL 34 #define ITEM_RAYGUNUNK 35 #define ITEM_STARRODSTAR 36 #define ITEM_LIPSSTICKDUST 37 #define ITEM_SUPERSCOPEBEAM 38 #define ITEM_RAYGUNBEAM 39 #define ITEM_HAMMERHEAD 40 #define ITEM_FLOWER 41 #define ITEM_YOSHISEGG 42 #define ITEM_GOOMBA 43 #define ITEM_REDEAD 44 #define ITEM_OCTAROK 45 #define ITEM_OTTOSEA 46 #define ITEM_STONE 47 #define ITEM_MARIOFIRE 48 #define ITEM_DRMARIOPILL 49 #define ITEM_KIRBYCUTTER 50 #define ITEM_KIRBYHAMMER 51 #define ITEM_KIRBYABILITYSTAR 52 /* #define ITEM_ 53 #define ITEM_ 54 #define ITEM_ 55 #define ITEM_ 56 #define ITEM_ 57 #define ITEM_ 58 #define ITEM_ 59 #define ITEM_ 60 #define ITEM_ 61 #define ITEM_ 62 #define ITEM_ 63 #define ITEM_ 64 #define ITEM_ 65 #define ITEM_ 66 #define ITEM_ 67 #define ITEM_ 68 #define ITEM_ 69 #define ITEM_ 70 #define ITEM_ 71 #define ITEM_ 72 #define ITEM_ 73 #define ITEM_ 74 #define ITEM_ 75 #define ITEM_ 76 #define ITEM_ 77 #define ITEM_ 78 #define ITEM_ 79 #define ITEM_ 80 #define ITEM_ 81 #define ITEM_ 82 #define ITEM_ 83 #define ITEM_ 84 #define ITEM_ 85 #define ITEM_ 86 #define ITEM_ 87 #define ITEM_ 88 #define ITEM_ 89 #define ITEM_ 90 #define ITEM_ 91 #define ITEM_ 92 #define ITEM_ 93 #define ITEM_ 94 #define ITEM_ 95 #define ITEM_ 96 #define ITEM_ 97 #define ITEM_ 98 #define ITEM_ 99 #define ITEM_ 100 #define ITEM_ 101 #define ITEM_ 102 #define ITEM_ 103 #define ITEM_ 104 #define ITEM_ 105 #define ITEM_ 106 #define ITEM_ 107 #define ITEM_ 108 #define ITEM_ 109 #define ITEM_ 110 #define ITEM_ 111 #define ITEM_ 112 #define ITEM_ 113 #define ITEM_ 114 #define ITEM_ 115 #define ITEM_ 116 #define ITEM_ 117 #define ITEM_ 118 #define ITEM_ 119 #define ITEM_ 120 #define ITEM_ 121 #define ITEM_ 122 #define ITEM_ 123 #define ITEM_ 124 #define ITEM_ 125 #define ITEM_ 126 #define ITEM_ 127 #define ITEM_ 128 #define ITEM_ 129 #define ITEM_ 130 #define ITEM_ 131 #define ITEM_ 132 #define ITEM_ 133 #define ITEM_ 134 #define ITEM_ 135 #define ITEM_ 136 #define ITEM_ 137 #define ITEM_ 138 #define ITEM_ 139 #define ITEM_ 140 #define ITEM_ 141 #define ITEM_ 142 #define ITEM_ 143 #define ITEM_ 144 #define ITEM_ 145 #define ITEM_ 146 #define ITEM_ 147 #define ITEM_ 148 #define ITEM_ 149 #define ITEM_ 150 #define ITEM_ 151 #define ITEM_ 152 #define ITEM_ 153 #define ITEM_ 154 #define ITEM_ 155 #define ITEM_ 156 #define ITEM_ 157 #define ITEM_ 158 #define ITEM_ 159 */ #define ITEM_POKERANDOM 160 #define ITEM_GOLDEEN 161 #define ITEM_CHICORITA 162 #define ITEM_SNORLAX 163 #define ITEM_BLASTOISE 164 #define ITEM_WEEZING 165 #define ITEM_CHARIZARD 166 #define ITEM_MOLTRES 167 #define ITEM_ZAPDOS 168 #define ITEM_ARCTICUNO 169 #define ITEM_WOBBUFFET 170 #define ITEM_SCIZOR 171 #define ITEM_UNOWN 172 #define ITEM_ENTEI 173 #define ITEM_RAIKOU 174 #define ITEM_SUICUNE 175 #define ITEM_BELLOSSOM 176 #define ITEM_ELECTRODE 177 #define ITEM_LUGIA 178 #define ITEM_HOOH 179 #define ITEM_DITTO 180 #define ITEM_CLEFAIRY 181 #define ITEM_TOGEPI 182 #define ITEM_MEW 183 #define ITEM_CELEBI 184 #define ITEM_STARYU 185 #define ITEM_CHANSEY 186 #define ITEM_PORYGON2 187 #define ITEM_CYNDAQUIL 188 #define ITEM_MARILL 189 #define ITEM_VENUSAUR 190 /* #define ITEM_ 191 #define ITEM_ 192 #define ITEM_ 193 #define ITEM_ 194 #define ITEM_ 195 #define ITEM_ 196 #define ITEM_ 197 #define ITEM_ 198 #define ITEM_ 199 #define ITEM_ 200 #define ITEM_ 201 #define ITEM_ 202 #define ITEM_ 203 #define ITEM_ 204 #define ITEM_ 205 #define ITEM_ 206 #define ITEM_ 207 #define ITEM_ 208 */ #define ITEM_TARGET 209 /* #define ITEM_ 210 #define ITEM_ 211 #define ITEM_ 212 #define ITEM_ 213 #define ITEM_ 214 #define ITEM_ 215 #define ITEM_ 216 #define ITEM_ 217 #define ITEM_ 218 #define ITEM_ 219 #define ITEM_ 220 #define ITEM_ 221 #define ITEM_ 222 #define ITEM_ 223 #define ITEM_ 224 #define ITEM_ 225 #define ITEM_ 226 #define ITEM_ 227 #define ITEM_ 228 #define ITEM_ 229 #define ITEM_ 230 #define ITEM_ 231 #define ITEM_ 232 #define ITEM_ 233 #define ITEM_ 234 #define ITEM_ 235 */ // ItemStateChange Flags #define ITEMSTATE_UPDATEANIM 0x2 #define ITEMSTATE_GRAB 0x4 #define ITEMSTATE_KEEPHIT 0x10 // dont remove hitboxes on state change // Item hold_kind definitions #define ITHOLD_HAND 0 // held item, like a capsule #define ITHOLD_HEAVY 1 // overhead item, like a crate #define ITHOLD_NONE 8 // unable to be held /*** Structs ***/ struct itData { int x0; float *param_ext; void *archive; void *animFlags; void *animDynamics; int x14; int x18; int x1C; int x20; int x24; int x28; int dynamics; int hurtbox; int x34; int x38; int x3C; int x40; int coll; int *items; int x4C; int x50; int x54; int boneLookup; }; struct itCommonAttr { char flags1; //0x0, bit 0x80 = is heavy item (crate) unsigned char x1_1 : 1; // 0x1 0x80 unsigned char x1_2 : 1; // 0x1 0x40 unsigned char x1_3 : 1; // 0x1 0x20 unsigned char x1_4 : 1; // 0x1 0x10 unsigned char x1_5 : 1; // 0x1 0x08 unsigned char cam_kind : 2; // 0x1 0x06, is stored to 0xdcd unsigned char x1_8 : 1; // 0x1 0x01 char flags3; //0x2 char flags4; //0x3 int x4; int x8; float spinVelocity; float fallSpeed; float maxFallSpeed; float x18; float x1C; //collision related int x20; // 0x20 int x24; // 0x24 int x28; // 0x28 int x2c; // 0x2c int x30; // 0x30 int x34; // 0x34 int x38; // 0x38 int x3c; // 0x3c float ecb_top; // 0x40 float ecb_bot; // 0x44 float ecb_right; // 0x48 float ecb_left; // 0x4c int x50; // 0x50 int x54; // 0x54 int x58; // 0x58 int x5c; // 0x5c int x60; // 0x60 int x64; // 0x64 int x68; // 0x68 int x6c; // 0x6c int x70; // 0x70 int x74; // 0x74 int x78; // 0x78 int x7c; // 0x7c int x80; // 0x80 int x84; // 0x84 int x88; // 0x88 int x8c; // 0x8c int x90; // 0x90 int x94; // 0x94 int x98; // 0x98 int x9c; // 0x9c }; struct ItemState { int state; void *animCallback; void *physCallback; void *collCallback; }; struct SpawnItem { GOBJ *parent_gobj; // 0x0 GOBJ *parent_gobj2; // 0x4 int it_kind; // 0x8, id of the item to spawn int hold_kind; // 0xC, defines the behavior of the item, such as thrown and pickup. 0 = capsule int unk2; // 0x10 Vec3 pos; // 0x14 Vec3 pos2; // 0x20 Vec3 vel; // 0x2C float facing_direction; // 0x38 short damage; // 0x3C short unk5; // 0x3E int unk6; // 0x40, 1 = correct initial position char unk7; // 0x44, 0x80 = perform initial collision check int is_spin; // 0x48, enables item spinning }; struct itHit { int active; // 0x0 int x4; // 0x4, depends on int dmg; // 0x8 float dmg_f; // 0xc Vec3 offset; // 0x10 float size; // 0x1c int angle; // 0x20 int kb_growth; // 0x24 int wdsk; // 0x28 int kb; // 0x2c int attribute; // 0x30 int shield_dmg; // 0x34 int hitsound_severity; // 0x38. hurtbox interaction. 0 = none, 1 = grounded, 2 = aerial, 3 = both int hitsound_kind; // 0x3c unsigned char x401 : 1; // 0x40 0x80 unsigned char x402 : 1; // 0x40 0x40 unsigned char hit_air : 1; // 0x40 0x20. bool to check against aerial fighters unsigned char hit_ground : 1; // 0x40 0x10. bool to check against grounded fighters unsigned char x405 : 1; // 0x40 0x08 unsigned char x406 : 1; // 0x40 0x04 unsigned char x407 : 1; // 0x40 0x02 unsigned char x408 : 1; // 0x40 0x01 char x41; // 0x41 unsigned char x421 : 1; // 0x42 0x80 unsigned char x422 : 1; // 0x42 0x40 unsigned char hit_facing : 1; // 0x42 0x20. bool to only hit fighters facing the item unsigned char x424 : 1; // 0x42 0x10 unsigned char no_hurt : 1; // 0x42 0x08 ignore hurtbox unsigned char no_reflect : 1; // 0x42 0x04 ignore reflect? unsigned char x427 : 1; // 0x42 0x02 unsigned char x428 : 1; // 0x42 0x01 unsigned char x431 : 1; // 0x43 0x80 unsigned char x432 : 1; // 0x43 0x40 unsigned char hit_all : 1; // 0x43 0x20 unsigned char x434 : 1; // 0x43 0x10 unsigned char x435 : 1; // 0x43 0x08 unsigned char x436 : 1; // 0x43 0x04 unsigned char x437 : 1; // 0x43 0x02 unsigned char x438 : 1; // 0x43 0x01 int x44; // 0x44 JOBJ *bone; // 0x48 Vec3 pos; // 0x4c Vec3 pos_prev; // 0x58 Vec3 pos_coll; // 0x64 position of hurt collision float coll_distance; // 0x70 Distance From Collding Hurtbox (Used for phantom hit collision calculation) GOBJ *victim; // 0x74 int x78; // 0x78 int x7c; // 0x7c int x80; // 0x80 int x84; // 0x84 int x88; // 0x88 int x8c; // 0x8c int x90; // 0x90 int x94; // 0x94 int x98; // 0x98 int x9c; // 0x9c int xa0; // 0xa0 int xa4; // 0xa4 int xa8; // 0xa8 int xac; // 0xac int xb0; // 0xb0 int xb4; // 0xb4 int xb8; // 0xb8 int xbc; // 0xbc int xc0; // 0xc0 int xc4; // 0xc4 int xc8; // 0xc8 int xcc; // 0xcc int xd0; // 0xd0 int xd4; // 0xd4 int xd8; // 0xd8 int xdc; // 0xdc int xe0; // 0xe0 int xe4; // 0xe4 int xe8; // 0xe8 int xec; // 0xec int xf0; // 0xf0 int xf4; // 0xf4 int xf8; // 0xf8 int xfc; // 0xfc int x100; // 0x100 int x104; // 0x104 int x108; // 0x108 int x10c; // 0x10c int x110; // 0x110 int x114; // 0x114 int x118; // 0x118 int x11c; // 0x11c int x120; // 0x120 int x124; // 0x124 int x128; // 0x128 int x12c; // 0x12c int x130; // 0x130 int x134; // 0x134 int x138; // 0x138 }; struct ItemData { int x0; // 0x0 GOBJ *item; // 0x0 int x8; // 0x8 int spawnType; // 0xC int itemID; // 0x10 int x14; // 0x14 int x18; // 0x18 int x1c; // 0x1c int x20; // 0x20 int stateID; // 0x24 int x28; // 0x28 float facing_direction; // 0x2c int x30; // 0x30 float spinUnk; // 0x34 float scale; // 0x38 int x3c; // 0x3c Vec3 self_vel; // 0x40 Vec3 pos; // 0x4C Vec3 unkVel; // 0x58-0x64 int x64; // 0x64 int x68; // 0x68 int x6c; // 0x6c Vec3 nudgeVel; // 0x70 - 0x7C int x7c; // 0x7c int x80; // 0x80 int x84; // 0x84 int x88; // 0x88 int x8c; // 0x8c int x90; // 0x90 int x94; // 0x94 int x98; // 0x98 int x9c; // 0x9c int xa0; // 0xa0 int xa4; // 0xa4 int xa8; // 0xa8 int xac; // 0xac int xb0; // 0xb0 int xb4; // 0xb4 void *it_cb; // 0xb8, global item callbacks ItemState *itemStates; // 0xbc int isRotate; // 0xc0 itData *itData; // 0xc4 JOBJ *joint; // 0xc8 itCommonAttr *itemAttributes; // 0xcc int xd0; // 0xd0 int xd4; // 0xd4 int xd8; // 0xd8 int xdc; // 0xdc int xe0; // 0xe0 int xe4; // 0xe4 int xe8; // 0xe8 int xec; // 0xec int xf0; // 0xf0 int xf4; // 0xf4 int xf8; // 0xf8 int xfc; // 0xfc int x100; // 0x100 int x104; // 0x104 int x108; // 0x108 int x10c; // 0x10c int x110; // 0x110 int x114; // 0x114 int x118; // 0x118 int x11c; // 0x11c int x120; // 0x120 int x124; // 0x124 int x128; // 0x128 int x12c; // 0x12c int x130; // 0x130 int x134; // 0x134 int x138; // 0x138 int x13c; // 0x13c int x140; // 0x140 int x144; // 0x144 int x148; // 0x148 int x14c; // 0x14c int x150; // 0x150 int x154; // 0x154 int x158; // 0x158 int x15c; // 0x15c int x160; // 0x160 int x164; // 0x164 int x168; // 0x168 int x16c; // 0x16c int x170; // 0x170 int x174; // 0x174 int x178; // 0x178 int x17c; // 0x17c int x180; // 0x180 int x184; // 0x184 int x188; // 0x188 int x18c; // 0x18c int x190; // 0x190 int x194; // 0x194 int x198; // 0x198 int x19c; // 0x19c int x1a0; // 0x1a0 int x1a4; // 0x1a4 int x1a8; // 0x1a8 int x1ac; // 0x1ac int x1b0; // 0x1b0 int x1b4; // 0x1b4 int x1b8; // 0x1b8 int x1bc; // 0x1bc int x1c0; // 0x1c0 int x1c4; // 0x1c4 int x1c8; // 0x1c8 int x1cc; // 0x1cc int x1d0; // 0x1d0 int x1d4; // 0x1d4 int x1d8; // 0x1d8 int x1dc; // 0x1dc int x1e0; // 0x1e0 int x1e4; // 0x1e4 int x1e8; // 0x1e8 int x1ec; // 0x1ec int x1f0; // 0x1f0 int x1f4; // 0x1f4 int x1f8; // 0x1f8 int x1fc; // 0x1fc int x200; // 0x200 int x204; // 0x204 int x208; // 0x208 int x20c; // 0x20c int x210; // 0x210 int x214; // 0x214 int x218; // 0x218 int x21c; // 0x21c int x220; // 0x220 int x224; // 0x224 int x228; // 0x228 int x22c; // 0x22c int x230; // 0x230 int x234; // 0x234 int x238; // 0x238 int x23c; // 0x23c int x240; // 0x240 int x244; // 0x244 int x248; // 0x248 int x24c; // 0x24c int x250; // 0x250 int x254; // 0x254 int x258; // 0x258 int x25c; // 0x25c int x260; // 0x260 int x264; // 0x264 int x268; // 0x268 int x26c; // 0x26c int x270; // 0x270 int x274; // 0x274 int x278; // 0x278 int x27c; // 0x27c int x280; // 0x280 int x284; // 0x284 int x288; // 0x288 int x28c; // 0x28c int x290; // 0x290 int x294; // 0x294 int x298; // 0x298 int x29c; // 0x29c int x2a0; // 0x2a0 int x2a4; // 0x2a4 int x2a8; // 0x2a8 int x2ac; // 0x2ac int x2b0; // 0x2b0 int x2b4; // 0x2b4 int x2b8; // 0x2b8 int x2bc; // 0x2bc int x2c0; // 0x2c0 int x2c4; // 0x2c4 int x2c8; // 0x2c8 int x2cc; // 0x2cc int x2d0; // 0x2d0 int x2d4; // 0x2d4 int x2d8; // 0x2d8 int x2dc; // 0x2dc int x2e0; // 0x2e0 int x2e4; // 0x2e4 int x2e8; // 0x2e8 int x2ec; // 0x2ec int x2f0; // 0x2f0 int x2f4; // 0x2f4 int x2f8; // 0x2f8 int x2fc; // 0x2fc int x300; // 0x300 int x304; // 0x304 int x308; // 0x308 int x30c; // 0x30c int x310; // 0x310 int x314; // 0x314 int x318; // 0x318 int x31c; // 0x31c int x320; // 0x320 int x324; // 0x324 int x328; // 0x328 int x32c; // 0x32c int x330; // 0x330 int x334; // 0x334 int x338; // 0x338 int x33c; // 0x33c int x340; // 0x340 int x344; // 0x344 int x348; // 0x348 int x34c; // 0x34c int x350; // 0x350 int x354; // 0x354 int x358; // 0x358 int x35c; // 0x35c int x360; // 0x360 int x364; // 0x364 int x368; // 0x368 int x36c; // 0x36c int x370; // 0x370 int x374; // 0x374 CollData coll_data; // 0x378 -> 0x518 FighterData *fighter; // 0x518 int x51c; // 0x51c CameraBox *camerabox; // 0x520 int x524; // 0x524 int x528; // 0x528 int *script_parse; // 0x52c int x530; // 0x530 int x534; // 0x534 int x538; // 0x538 int x53c; // 0x53c int x540; // 0x540 int x544; // 0x544 ColorOverlay color; // 0x548 int x5c8; // 0x5c8 int x5cc; // 0x5cc int x5d0; // 0x5d0 itHit hitbox[4]; // 0x5d4 int xac4; // 0xac4 int xac8; // 0xac8 int hurt_status; // 0xacc int xad0; // 0xad0 int xad4; // 0xad4 int xad8; // 0xad8 int xadc; // 0xadc int xae0; // 0xae0 int xae4; // 0xae4 int xae8; // 0xae8 int xaec; // 0xaec int xaf0; // 0xaf0 int xaf4; // 0xaf4 int xaf8; // 0xaf8 int xafc; // 0xafc int xb00; // 0xb00 int xb04; // 0xb04 int xb08; // 0xb08 int xb0c; // 0xb0c int xb10; // 0xb10 int xb14; // 0xb14 int xb18; // 0xb18 int xb1c; // 0xb1c int xb20; // 0xb20 int xb24; // 0xb24 int xb28; // 0xb28 int xb2c; // 0xb2c int xb30; // 0xb30 int xb34; // 0xb34 int xb38; // 0xb38 int xb3c; // 0xb3c int xb40; // 0xb40 int xb44; // 0xb44 int xb48; // 0xb48 int xb4c; // 0xb4c int xb50; // 0xb50 int xb54; // 0xb54 int xb58; // 0xb58 int xb5c; // 0xb5c int xb60; // 0xb60 int xb64; // 0xb64 int xb68; // 0xb68 int xb6c; // 0xb6c int xb70; // 0xb70 int xb74; // 0xb74 int xb78; // 0xb78 int xb7c; // 0xb7c int xb80; // 0xb80 int xb84; // 0xb84 int xb88; // 0xb88 int xb8c; // 0xb8c int xb90; // 0xb90 int xb94; // 0xb94 int xb98; // 0xb98 int xb9c; // 0xb9c int xba0; // 0xba0 int xba4; // 0xba4 int xba8; // 0xba8 int xbac; // 0xbac int xbb0; // 0xbb0 int xbb4; // 0xbb4 int xbb8; // 0xbb8 int xbbc; // 0xbbc int xbc0; // 0xbc0 int xbc4; // 0xbc4 int xbc8; // 0xbc8 int xbcc; // 0xbcc int xbd0; // 0xbd0 int xbd4; // 0xbd4 int xbd8; // 0xbd8 int xbdc; // 0xbdc int xbe0; // 0xbe0 int xbe4; // 0xbe4 int xbe8; // 0xbe8 int xbec; // 0xbec int xbf0; // 0xbf0 int xbf4; // 0xbf4 int xbf8; // 0xbf8 int xbfc; // 0xbfc int xc00; // 0xc00 int xc04; // 0xc04 int xc08; // 0xc08 int xc0c; // 0xc0c int xc10; // 0xc10 int xc14; // 0xc14 int xc18; // 0xc18 float ecb_top; // 0xc1c float ecb_bottom; // 0xc20 float ecb_right; // 0xc24 float ecb_left; // 0xc28 int xc2c; // 0xc2c int xc30; // 0xc30 int xc34; // 0xc34 int xc38; // 0xc38 int xc3c; // 0xc3c int xc40; // 0xc40 int xc44; // 0xc44 int xc48; // 0xc48 int xc4c; // 0xc4c int xc50; // 0xc50 int xc54; // 0xc54 int xc58; // 0xc58 int xc5c; // 0xc5c int xc60; // 0xc60 int xc64; // 0xc64 int xc68; // 0xc68 int xc6c; // 0xc6c int xc70; // 0xc70 int xc74; // 0xc74 int xc78; // 0xc78 int xc7c; // 0xc7c int xc80; // 0xc80 int xc84; // 0xc84 int xc88; // 0xc88 int xc8c; // 0xc8c int xc90; // 0xc90 int xc94; // 0xc94 int xc98; // 0xc98 int dmg_total; // 0xc9c int dmg_recent; // 0xca0 int xca4; // 0xca4 int xca8; // 0xca8 int dmg_angle; // 0xcac int xcb0; // 0xcb0 int xcb4; // 0xcb4 int xcb8; // 0xcb8 int xcbc; // 0xcbc int xcc0; // 0xcc0 int xcc4; // 0xcc4 float dmg_kb; // 0xcc8 float dmg_direction; // 0xccc int xcd0; // 0xcd0 int xcd4; // 0xcd4 int xcd8; // 0xcd8 int xcdc; // 0xcdc int xce0; // 0xce0 int xce4; // 0xce4 int xce8; // 0xce8 GOBJ *dmgsource_fighter; // 0xcec GOBJ *dmgsource_item; // 0xcf0 int xcf4; // 0xcf4 int xcf8; // 0xcf8 int xcfc; // 0xcfc GOBJ *grabbedFighter; // 0xd00 int xd04; // 0xd04 int xd08; // 0xd08 int xd0c; // 0xd0c int xd10; // 0xd10 struct // cb { // void (*anim)(GOBJ *item); // 0xd14 void (*phys)(GOBJ *item); // 0xd18 void (*coll)(GOBJ *item); // 0xd1c void (*accessory)(GOBJ *item); // 0xd20 void *xd24; // 0xd24 void *xd28; // 0xd28 void *xd2c; // 0xd2c void *jumped_on; // 0xd30, runs when the item is "jumped on", 80269bac void *grabFt_onIt; // 0xd34, when grabbing a fighter, run this function on self void *grabFt_onFt; // 0xd38, when grabbing a fighter, run this function on fighter } cb; // float rotateSpeed; // 0xd3c int xd40; // 0xd40 float lifetime; // 0xd44 int xd48; // 0xd48 int xd4c; // 0xd4c int xd50; // 0xd50 int xd54; // 0xd54 int xd58; // 0xd58 int xd5c; // 0xd5c int xd60; // 0xd60 int xd64; // 0xd64 int xd68; // 0xd68 int xd6c; // 0xd6c int xd70; // 0xd70 int xd74; // 0xd74 int xd78; // 0xd78 int xd7c; // 0xd7c int xd80; // 0xd80 int xd84; // 0xd84 int xd88; // 0xd88 int xd8c; // 0xd8c int xd90; // 0xd90 int xd94; // 0xd94 int xd98; // 0xd98 int xd9c; // 0xd9c int xda0; // 0xda0 int xda4; // 0xda4 char xda8; // 0xda8 char xda9; // 0xda8 unsigned char xdaa1 : 1; // 0xda8 0x80 unsigned char xdaa2 : 1; // 0xda8 0x40 unsigned char xdaa3 : 1; // 0xda8 0x20 unsigned char xdaa4 : 1; // 0xda8 0x10 unsigned char xdaa5 : 1; // 0xda8 0x08 unsigned char xdaa6 : 1; // 0xda8 0x04 unsigned char xdaa7 : 1; // 0xda8 0x02 unsigned char visible : 1; // 0xda8 0x01 char xdab; // 0xda8 int scriptFlag1; // 0xdac int scriptFlag2; // 0xdb0 int scriptFlag3; // 0xdb4 int xdb8; // 0xdb8 int scriptFlag4; // 0xdbc int xdc0; // 0xdc0 int xdc4; // 0xdc4 u16 flags1 : 16; // 0xdc8 u16 xdca1 : 1; // 0xdca 0x80 u16 xdca2 : 1; // 0xdca 0x40 u16 xdca3 : 1; // 0xdca 0x20 u16 xdca4 : 1; // 0xdca 0x10 u16 xdca5 : 1; // 0xdca 0x08 u16 can_hold : 1; // 0xdca 0x04 u16 xdca7 : 1; // 0xdca 0x02 u16 rotateAxis : 3; // 0xdcb, u16 flags4 : 2; // 0xdcb, 0x30 u16 can_nudge : 1; // 0xdcb, 0x08 u16 xdcb_7 : 3; // 0xdcb, 0x07 unsigned char xdcc1 : 1; // 0xdcc, 0x80 unsigned char xdcc2 : 1; // 0xdcc, 0x40 unsigned char xdcc3 : 1; // 0xdcc, 0x20 unsigned char isCheckBlastzone : 1; // 0xdcc, 0x10 unsigned char isCheckRightBlastzone : 1; // 0xdcc, 0x08 unsigned char isCheckLeftBlastzone : 1; // 0xdcc, 0x04 unsigned char isCheckUpBlastzone : 1; // 0xdcc, 0x02 unsigned char isCheckDownBlastzone : 1; // 0xdcc, 0x01 unsigned char cam_kind : 2; // 0xdcd, 0xc0. indicates this item has a camera box unsigned char xdcd3 : 1; // 0xdcd, 0x20 unsigned char xdcd4 : 1; // 0xdcd, 0x10 unsigned char xdcd5 : 1; // 0xdcd, 0x08 unsigned char xdcd6 : 1; // 0xdcd, 0x04 unsigned char xdcd7 : 1; // 0xdcd, 0x02 unsigned char xdcd8 : 1; // 0xdcd, 0x01 unsigned char xdce1 : 1; // 0xdce, 0x80 unsigned char xdce2 : 1; // 0xdce, 0x40 unsigned char xdce3 : 1; // 0xdce, 0x20 unsigned char xdce4 : 1; // 0xdce, 0x10 unsigned char xdce5 : 1; // 0xdce, 0x08 unsigned char xdce6 : 1; // 0xdce, 0x04 unsigned char xdce7 : 1; // 0xdce, 0x02 unsigned char xdce8 : 1; // 0xdce, 0x01 unsigned char xdcf1 : 1; // 0xdcf, 0x80 unsigned char xdcf2 : 1; // 0xdcf, 0x40 unsigned char xdcf3 : 1; // 0xdcf, 0x20 unsigned char xdcf4 : 1; // 0xdcf, 0x10 unsigned char xdcf5 : 1; // 0xdcf, 0x08 unsigned char xdcf6 : 1; // 0xdcf, 0x04 unsigned char xdcf7 : 1; // 0xdcf, 0x02 unsigned char xdcf8 : 1; // 0xdcf, 0x01 int xdd0; // 0xdd0 int itemVar1; // 0xdd4 int itemVar2; // 0xdd8 int itemVar3; // 0xddc int itemVar4; // 0xde0 int itemVar5; // 0xde4 int itemVar6; // 0xde8 int itemVar7; // 0xdec int itemVar8; // 0xdf0 int itemVar9; // 0xdf4 int itemVar10; // 0xdf8 int itemVar11; // 0xdfc int itemVar12; // 0xe00 int xe04; // 0xe04 int xe08; // 0xe08 int xe0c; // 0xe0c int xe10; // 0xe10 int xe14; // 0xe14 int xe18; // 0xe18 int xe1c; // 0xe1c int xe20; // 0xe20 int xe24; // 0xe24 int xe28; // 0xe28 int xe2c; // 0xe2c int xe30; // 0xe30 int xe34; // 0xe34 int xe38; // 0xe38 int xe3c; // 0xe3c }; /*** Functions ***/ void Item_Hold(GOBJ *item, GOBJ *fighter, int boneID); void Item_Catch(GOBJ *fighter, int unk); void Items_StoreItemDataToCharItemTable(undefined4, int); void Items_StoreItemDataToCharItemTable2(int articleData, int articleID); void Items_StoreTimeout(GOBJ *item, float timeout); GOBJ *Item_CreateItem(SpawnItem *item_spawn); // sorry for confusion, use this one for best results GOBJ *Item_CreateItem1(SpawnItem *item_spawn); GOBJ *Item_CreateItem2(SpawnItem *item_spawn); GOBJ *Item_CreateItem3(SpawnItem *item_spawn); void Item_Destroy(GOBJ *item); int Item_CollGround_PassLedge(GOBJ *item, void *callback); int Item_CollGround_StopLedge(GOBJ *item, void *callback); int Item_CollAir(GOBJ *item, void *callback); void ItemStateChange(GOBJ *item, int stateID, int flags); int ItemFrameTimer(GOBJ *item); void Item_PlaceOnGroundBelow(GOBJ *item); int Item_CheckIfTouchingWall(GOBJ *item, float *unk[]); void Item_InitGrab(ItemData *item, int unk, void *OnItem, void *OnFighter); void Item_ResetAllHitPlayers(ItemData *item); int Item_CountActiveItems(int itemID); void Item_CopyDevelopState(GOBJ *item, GOBJ *fighter); int Items_DecLife(GOBJ *item); void GXLink_Item(GOBJ *gobj, int pass); void Item_UpdateSpin(GOBJ *item, float unk); void Item_EnableSpin(GOBJ *item); void Item_DisableSpin(GOBJ *item); void Item_SetLifeTimer(GOBJ *item, float lifetime); // sets frames until item is destroyed int Item_DecLifeTimer(GOBJ *item); // returns isEnd bool JOBJ *Item_GetBoneJOBJ(GOBJ *item, int bone_index); int Item_CheckIfEnabled(); // returns bool regarding if items are enabled for this match void Barrel_EnterBreak(GOBJ *item); #endif ================================================ FILE: MexTK/include/kirby.h ================================================ #ifndef MEX_H_KIRBY #define MEX_H_KIRBY #include "structs.h" #include "datatypes.h" #include "obj.h" #include "color.h" #include "effects.h" #include "match.h" #include "collision.h" struct FtVarKirby { int charVar1; // 0x222c int charVar2; // 0x2230 int charVar3; // 0x2234 int copy_index; // 0x2238 JOBJ *copy_jobj; // 0x223c FtParts ftparts_model; // 0x2240 FtDOBJUnk ftdobj_unk; // 0x2250 }; #endif ================================================ FILE: MexTK/include/match.h ================================================ #ifndef MEX_H_MATCH #define MEX_H_MATCH #include "structs.h" #include "datatypes.h" #include "obj.h" #include "fighter.h" // Match Data definitions #define MATCH_TIMER_FROZEN 0 #define MATCH_TIMER_HIDE 1 #define MATCH_TIMER_COUNTDOWN 2 #define MATCH_TIMER_COUNTUP 3 #define MATCH_MATCHTYPE_TIME 0 #define MATCH_MATCHTYPE_STOCK 1 #define MATCH_MATCHTYPE_COIN 2 #define MATCH_HUDPOS_NONE 0 #define MATCH_HUDPOS_ONE 1 #define MATCH_HUDPOS_TWO 2 #define MATCH_HUDPOS_THREE 3 #define MATCH_HUDPOS_FOUR 4 #define MATCH_HUDPOS_SIX 5 #define MATCH_HUDPOS_UNK 6 #define MATCH_HUDPOS_FOURCOMPACT 7 #define MATCH_PAUSEHUD_HIDE 1 #define MATCH_MATCHTYPE_STOCK 1 #define MATCH_MATCHTYPE_COIN 2 #define MATCH_ITEMFREQ_OFF -1 #define MATCH_ITEMFREQ_VERYLOW 0 #define MATCH_ITEMFREQ_LOW 1 #define MATCH_ITEMFREQ_MEDIUM 2 #define MATCH_ITEMFREQ_HIGH 3 #define MATCH_ITEMFREQ_VERYHIGH 4 /*** Structs ***/ struct MatchInit { // byte 0x0 unsigned char matchType : 3; unsigned char hudPos : 3; unsigned char timer : 2; // byte 0x1 unsigned char timer_unk2 : 1; unsigned char unk4 : 1; unsigned char hideReady : 1; unsigned char hideGo : 1; unsigned char isDisableMusic : 1; unsigned char unk3 : 1; unsigned char timer_unk : 1; unsigned char unk2 : 1; // byte 0x2 unsigned char unk9 : 1; unsigned char disableOffscreenDamage : 1; unsigned char unk8 : 1; unsigned char isSingleButtonMode : 1; unsigned char isDisablePause : 1; unsigned char unk7 : 1; unsigned char isCreateHUD : 1; unsigned char unk5 : 1; // byte 0x3 unsigned char isShowScore : 1; // 0x80 unsigned char isShowAnalogStick : 1; // 0x40 unsigned char isCheckForZRetry : 1; // 0x20 unsigned char isShowZRetry : 1; // 0x10 unsigned char isCheckForLRAStart : 1; // 0x08 unsigned char isShowLRAStart : 1; // 0x04 unsigned char isHidePauseHUD : 1; // 0x02 unsigned char timerRunOnPause : 1; // 0x01 //byte 0x4 unsigned char unk11 : 1; // 0x80 unsigned char isCheckStockSteal : 1; // 0x40 unsigned char isRunStockLogic : 1; // 0x20 unsigned char unk10 : 5; // 0x01 //byte 0x5 unsigned char isSkipEndCheck : 1; // 0x80 unsigned char isSkipUnkStockCheck : 1; // 0x40 unsigned char isDisableHit : 1; // 0x20 unsigned char unk12 : 5; // 0x01 // byte 0x6 u8 bombRain; // 0xFF //byte 0x7 u8 unk13; // 0xFF //byte 0x8 u8 isTeams; // 0xFF //byte 0x9 u8 isKOCounterActive; // 0xFF //byte 0xA u8 unk14; // 0xFF //byte 0xB u8 itemFreq; // 0xFF //byte 0xC u8 unk15; // 0xFF //byte 0xD u8 unk16; // 0xFF //byte 0xE u16 stage; // 0xFFFF //byte 0x10 int timerSeconds : 32; // 0xFFFFFFFF //byte 0x14 u8 timerSubSeconds; // 0xFF //0x18 int unk17; // 0xFFFFFFFF //0x1C unsigned long long itemSwitch : 64; // 0xFFFFFFFF FFFFFFFF //byte 0x24 int unk18; // 0xFFFFFFFF //0x28 float cameraShakeMult; //0x2C float unk19; //0x30 float unk20; //0x34 int x34; //0x38 int x38; //0x3C int x3c; //0x40 void *onStartMelee; //0x44 int unk21; //0x48 void *onCheckPause; //0x4C int unk22; //0x50 void *onMatchFrame1; //0x54 void *onMatchFrame2; //0x58 void *onMatchEnd; /* //0x5C int x5c; //0x60 int x60; //0x64 int x64; */ // player data PlayerData playerData[6]; }; struct MatchHUD { GOBJ *percent; GOBJ *insignia; u8 x8; u8 x9; u16 xa; u16 xc; u8 xe; u8 xf; unsigned char is_removed : 1; // 0x80 - 0x10 unsigned char x10_2 : 1; // 0x40 - 0x10 unsigned char x10_3 : 1; // 0x20 - 0x10 unsigned char x10_4 : 1; // 0x10 - 0x10 unsigned char x10_5 : 1; // 0x08 - 0x10 unsigned char x10_6 : 1; // 0x04 - 0x10 unsigned char x10_7 : 1; // 0x02 - 0x10 unsigned char x10_8 : 1; // 0x01 - 0x10 u8 x11; u8 x12; u8 x13; float x14[3]; float percent_digitpos[4]; // 3 digits and the percent sign int x34[8]; JOBJ *x54[5]; }; struct CameraBox { void *alloc; // 0x0 CameraBox *next; // 0x4 int kind; // 0x8 2 = only focus if close to center int flags; // 0xC Vec3 cam_pos; // 0x10 Vec3 bone_pos; // 0x1c float direction; // 0x28 float boundleft_curr; // 0x2C float boundright_curr; // 0x30 float boundtop_curr; // 0x34 float boundbottom_curr; // 0x38 float x3c; // 0x3c float boundleft_proj; // 0x40 float boundright_proj; // 0x44 float boundtop_proj; // 0x48 float boundbottom_proj; // 0x4c }; struct MatchCamera { int x0; // 0x0 int cam_kind; // 0x4 int x8; // 0x8 int xc; // 0xc int x10; // 0x10 int x14; // 0x14 int x18; // 0x18 int x1c; // 0x1c int x20; // 0x20 int x24; // 0x24 int x28; // 0x28 int x2c; // 0x2c int x30; // 0x30 int x34; // 0x34 int x38; // 0x38 int x3c; // 0x3c int x40; // 0x40 int x44; // 0x44 int x48; // 0x48 int x4c; // 0x4c int x50; // 0x50 int x54; // 0x54 int x58; // 0x58 int x5c; // 0x5c int x60; // 0x60 int x64; // 0x64 int x68; // 0x68 int x6c; // 0x6c int x70; // 0x70 int x74; // 0x74 int x78; // 0x78 int x7c; // 0x7c int x80; // 0x80 int x84; // 0x84 int x88; // 0x88 int x8c; // 0x8c int x90; // 0x90 int x94; // 0x94 int x98; // 0x98 int x9c; // 0x9c int xa0; // 0xa0 int xa4; // 0xa4 int xa8; // 0xa8 int xac; // 0xac int xb0; // 0xb0 int xb4; // 0xb4 int xb8; // 0xb8 int xbc; // 0xbc int xc0; // 0xc0 int xc4; // 0xc4 int xc8; // 0xc8 int xcc; // 0xcc int xd0; // 0xd0 int xd4; // 0xd4 int xd8; // 0xd8 int xdc; // 0xdc int xe0; // 0xe0 int xe4; // 0xe4 int xe8; // 0xe8 int xec; // 0xec int xf0; // 0xf0 int xf4; // 0xf4 int xf8; // 0xf8 int xfc; // 0xfc int x100; // 0x100 int x104; // 0x104 int x108; // 0x108 int x10c; // 0x10c int x110; // 0x110 int x114; // 0x114 int x118; // 0x118 int x11c; // 0x11c int x120; // 0x120 int x124; // 0x124 int x128; // 0x128 int x12c; // 0x12c int x130; // 0x130 int x134; // 0x134 int x138; // 0x138 int x13c; // 0x13c int x140; // 0x140 int x144; // 0x144 int x148; // 0x148 int x14c; // 0x14c int x150; // 0x150 int x154; // 0x154 int x158; // 0x158 int x15c; // 0x15c int x160; // 0x160 int x164; // 0x164 int x168; // 0x168 int x16c; // 0x16c int x170; // 0x170 int x174; // 0x174 int x178; // 0x178 int x17c; // 0x17c int x180; // 0x180 int x184; // 0x184 int x188; // 0x188 int x18c; // 0x18c int x190; // 0x190 int x194; // 0x194 int x198; // 0x198 int x19c; // 0x19c int x1a0; // 0x1a0 int x1a4; // 0x1a4 int x1a8; // 0x1a8 int x1ac; // 0x1ac int x1b0; // 0x1b0 int x1b4; // 0x1b4 int x1b8; // 0x1b8 int x1bc; // 0x1bc int x1c0; // 0x1c0 int x1c4; // 0x1c4 int x1c8; // 0x1c8 int x1cc; // 0x1cc int x1d0; // 0x1d0 int x1d4; // 0x1d4 int x1d8; // 0x1d8 int x1dc; // 0x1dc int x1e0; // 0x1e0 int x1e4; // 0x1e4 int x1e8; // 0x1e8 int x1ec; // 0x1ec int x1f0; // 0x1f0 int x1f4; // 0x1f4 int x1f8; // 0x1f8 int x1fc; // 0x1fc int x200; // 0x200 int x204; // 0x204 int x208; // 0x208 int x20c; // 0x20c int x210; // 0x210 int x214; // 0x214 int x218; // 0x218 int x21c; // 0x21c int x220; // 0x220 int x224; // 0x224 int x228; // 0x228 int x22c; // 0x22c int x230; // 0x230 int x234; // 0x234 int x238; // 0x238 int x23c; // 0x23c int x240; // 0x240 int x244; // 0x244 int x248; // 0x248 int x24c; // 0x24c int x250; // 0x250 int x254; // 0x254 int x258; // 0x258 int x25c; // 0x25c int x260; // 0x260 int x264; // 0x264 int x268; // 0x268 int x26c; // 0x26c int x270; // 0x270 int x274; // 0x274 int x278; // 0x278 int x27c; // 0x27c int x280; // 0x280 int x284; // 0x284 int x288; // 0x288 int x28c; // 0x28c int x290; // 0x290 int x294; // 0x294 int x298; // 0x298 int x29c; // 0x29c int x2a0; // 0x2a0 int x2a4; // 0x2a4 int x2a8; // 0x2a8 int x2ac; // 0x2ac int x2b0; // 0x2b0 int x2b4; // 0x2b4 int x2b8; // 0x2b8 int x2bc; // 0x2bc int x2c0; // 0x2c0 int x2c4; // 0x2c4 int x2c8; // 0x2c8 int x2cc; // 0x2cc int x2d0; // 0x2d0 int x2d4; // 0x2d4 int x2d8; // 0x2d8 int x2dc; // 0x2dc int x2e0; // 0x2e0 int x2e4; // 0x2e4 int x2e8; // 0x2e8 float freecam_tilt_vertical; // 0x2ec, uses radians int x2f0; // 0x2f0 int x2f4; // 0x2f4 float freecam_zoommax; // 0x2f8 float freecam_zoommin; // 0x2fc int x300; // 0x300 int x304; // 0x304 Vec3 freecam_pos; // 0x308 Vec3 freecam_offset; // 0x314 // 0x314 Vec2 freecam_rotate; // 0x320 Vec3 freecam_fov; // 0x328 int x334; // 0x334 int x338; // 0x338 int x33c; // 0x33c int x340; // 0x340 int x344; // 0x344 int x348; // 0x348 int x34c; // 0x34c int x350; // 0x350 int x354; // 0x354 int x358; // 0x358 int x35c; // 0x35c int x360; // 0x360 int x364; // 0x364 int x368; // 0x368 int x36c; // 0x36c int x370; // 0x370 int x374; // 0x374 int x378; // 0x378 int x37c; // 0x37c int x380; // 0x380 int x384; // 0x384 int x388; // 0x388 int x38c; // 0x38c int x390; // 0x390 int x394; // 0x394 char x398; // 0x398 unsigned char x399x80 : 1; unsigned char x399x40 : 1; unsigned char x399x20 : 1; unsigned char show_coll : 1; unsigned char x399x08 : 1; unsigned char x399x04 : 1; unsigned char x399x02 : 1; unsigned char x399x01 : 1; char x39a; // 0x39a char x39b; // 0x39b int x39c; // 0x39c int x3a0; // 0x3a0 int x3a4; // 0x3a4 int x3a8; // 0x3a8 int x3ac; // 0x3ac int x3b0; // 0x3b0 int x3b4; // 0x3b4 int x3b8; // 0x3b8 int x3bc; // 0x3bc int x3c0; // 0x3c0 int x3c4; // 0x3c4 int x3c8; // 0x3c8 int x3cc; // 0x3cc int x3d0; // 0x3d0 int x3d4; // 0x3d4 Vec3 devcam_pos; // 0x3d8 Vec3 devcam_rot; // 0x3e4 float devcam_fov; // 0x3f0 int x3f4; // 0x3f4 int x3f8; // 0x3f8 int x3fc; // 0x3fc }; struct MatchOffscreen { void *x0; void *x4; void *x8; unsigned char is_offscreen : 1; // 0xC, 0x80 unsigned char ignore_offscreen : 1; // 0xC, 0x40 unsigned char x3f : 6; // 0xC, 0x3f void *x10; }; struct Match // static match struct @ 8046b6a0 { u8 state; // 0x0 u8 pauser; // 0x1 int x4; // 0x4 int x8; // 0x8 int xc; // 0xc int x10; // 0x10 int x14; // 0x14 int x18; // 0x18 int x1c; // 0x1c int x20; // 0x20 int time_frames; // 0x24 int time_seconds; // 0x28 u16 time_ms; // 0x2c, counts frame 0-59 int x30; // 0x30 int x34; // 0x34 int x38; // 0x38 int x3c; // 0x3c int x40; // 0x40 int x44; // 0x44 int x48; // 0x48 int x4c; // 0x4c int x50; // 0x50 int x54; // 0x54 int x58; // 0x58 int x5c; // 0x5c int x60; // 0x60 int x64; // 0x64 int x68; // 0x68 int x6c; // 0x6c int x70; // 0x70 int x74; // 0x74 int x78; // 0x78 int x7c; // 0x7c int x80; // 0x80 int x84; // 0x84 int x88; // 0x88 int x8c; // 0x8c int x90; // 0x90 int x94; // 0x94 int x98; // 0x98 int x9c; // 0x9c int xa0; // 0xa0 int xa4; // 0xa4 int xa8; // 0xa8 int xac; // 0xac int xb0; // 0xb0 int xb4; // 0xb4 int xb8; // 0xb8 int xbc; // 0xbc int xc0; // 0xc0 int xc4; // 0xc4 int xc8; // 0xc8 int xcc; // 0xcc int xd0; // 0xd0 int xd4; // 0xd4 int xd8; // 0xd8 int xdc; // 0xdc int xe0; // 0xe0 int xe4; // 0xe4 int xe8; // 0xe8 int xec; // 0xec int xf0; // 0xf0 int xf4; // 0xf4 int xf8; // 0xf8 int xfc; // 0xfc int x100; // 0x100 int x104; // 0x104 int x108; // 0x108 int x10c; // 0x10c int x110; // 0x110 int x114; // 0x114 int x118; // 0x118 int x11c; // 0x11c int x120; // 0x120 int x124; // 0x124 int x128; // 0x128 int x12c; // 0x12c int x130; // 0x130 int x134; // 0x134 int x138; // 0x138 int x13c; // 0x13c int x140; // 0x140 int x144; // 0x144 int x148; // 0x148 int x14c; // 0x14c int x150; // 0x150 int x154; // 0x154 int x158; // 0x158 int x15c; // 0x15c int x160; // 0x160 int x164; // 0x164 int x168; // 0x168 int x16c; // 0x16c int x170; // 0x170 int x174; // 0x174 int x178; // 0x178 int x17c; // 0x17c int x180; // 0x180 int x184; // 0x184 int x188; // 0x188 int x18c; // 0x18c int x190; // 0x190 int x194; // 0x194 int x198; // 0x198 int x19c; // 0x19c int x1a0; // 0x1a0 int x1a4; // 0x1a4 int x1a8; // 0x1a8 int x1ac; // 0x1ac int x1b0; // 0x1b0 int x1b4; // 0x1b4 int x1b8; // 0x1b8 int x1bc; // 0x1bc int x1c0; // 0x1c0 int x1c4; // 0x1c4 int x1c8; // 0x1c8 int x1cc; // 0x1cc int x1d0; // 0x1d0 int x1d4; // 0x1d4 int x1d8; // 0x1d8 int x1dc; // 0x1dc int x1e0; // 0x1e0 int x1e4; // 0x1e4 int x1e8; // 0x1e8 int x1ec; // 0x1ec int x1f0; // 0x1f0 int x1f4; // 0x1f4 int x1f8; // 0x1f8 int x1fc; // 0x1fc int x200; // 0x200 int x204; // 0x204 int x208; // 0x208 int x20c; // 0x20c int x210; // 0x210 int x214; // 0x214 int x218; // 0x218 int x21c; // 0x21c int x220; // 0x220 int x224; // 0x224 int x228; // 0x228 int x22c; // 0x22c int x230; // 0x230 int x234; // 0x234 int x238; // 0x238 int x23c; // 0x23c int x240; // 0x240 int x244; // 0x244 int x248; // 0x248 int x24c; // 0x24c int x250; // 0x250 int x254; // 0x254 int x258; // 0x258 int x25c; // 0x25c int x260; // 0x260 int x264; // 0x264 int x268; // 0x268 int x26c; // 0x26c int x270; // 0x270 int x274; // 0x274 int x278; // 0x278 int x27c; // 0x27c int x280; // 0x280 int x284; // 0x284 int x288; // 0x288 int x28c; // 0x28c int x290; // 0x290 int x294; // 0x294 int x298; // 0x298 int x29c; // 0x29c int x2a0; // 0x2a0 int x2a4; // 0x2a4 int x2a8; // 0x2a8 int x2ac; // 0x2ac int x2b0; // 0x2b0 int x2b4; // 0x2b4 int x2b8; // 0x2b8 int x2bc; // 0x2bc int x2c0; // 0x2c0 int x2c4; // 0x2c4 int x2c8; // 0x2c8 int x2cc; // 0x2cc int x2d0; // 0x2d0 int x2d4; // 0x2d4 int x2d8; // 0x2d8 int x2dc; // 0x2dc int x2e0; // 0x2e0 int x2e4; // 0x2e4 int x2e8; // 0x2e8 int x2ec; // 0x2ec int x2f0; // 0x2f0 int x2f4; // 0x2f4 int x2f8; // 0x2f8 int x2fc; // 0x2fc int x300; // 0x300 int x304; // 0x304 int x308; // 0x308 int x30c; // 0x30c int x310; // 0x310 int x314; // 0x314 int x318; // 0x318 int x31c; // 0x31c int x320; // 0x320 int x324; // 0x324 int x328; // 0x328 int x32c; // 0x32c int x330; // 0x330 int x334; // 0x334 int x338; // 0x338 int x33c; // 0x33c int x340; // 0x340 int x344; // 0x344 int x348; // 0x348 int x34c; // 0x34c int x350; // 0x350 int x354; // 0x354 int x358; // 0x358 int x35c; // 0x35c int x360; // 0x360 int x364; // 0x364 int x368; // 0x368 int x36c; // 0x36c int x370; // 0x370 int x374; // 0x374 int x378; // 0x378 int x37c; // 0x37c int x380; // 0x380 int x384; // 0x384 int x388; // 0x388 int x38c; // 0x38c int x390; // 0x390 int x394; // 0x394 int x398; // 0x398 int x39c; // 0x39c int x3a0; // 0x3a0 int x3a4; // 0x3a4 int x3a8; // 0x3a8 int x3ac; // 0x3ac int x3b0; // 0x3b0 int x3b4; // 0x3b4 int x3b8; // 0x3b8 int x3bc; // 0x3bc int x3c0; // 0x3c0 int x3c4; // 0x3c4 int x3c8; // 0x3c8 int x3cc; // 0x3cc int x3d0; // 0x3d0 int x3d4; // 0x3d4 int x3d8; // 0x3d8 int x3dc; // 0x3dc int x3e0; // 0x3e0 int x3e4; // 0x3e4 int x3e8; // 0x3e8 int x3ec; // 0x3ec int x3f0; // 0x3f0 int x3f4; // 0x3f4 int x3f8; // 0x3f8 int x3fc; // 0x3fc int x400; // 0x400 int x404; // 0x404 int x408; // 0x408 int x40c; // 0x40c int x410; // 0x410 int x414; // 0x414 int x418; // 0x418 int x41c; // 0x41c int x420; // 0x420 int x424; // 0x424 int x428; // 0x428 int x42c; // 0x42c int x430; // 0x430 int x434; // 0x434 int x438; // 0x438 int x43c; // 0x43c int x440; // 0x440 int x444; // 0x444 int x448; // 0x448 int x44c; // 0x44c int x450; // 0x450 int x454; // 0x454 int x458; // 0x458 int x45c; // 0x45c int x460; // 0x460 int x464; // 0x464 int x468; // 0x468 int x46c; // 0x46c int x470; // 0x470 int x474; // 0x474 int x478; // 0x478 int x47c; // 0x47c int x480; // 0x480 int x484; // 0x484 int x488; // 0x488 int x48c; // 0x48c int x490; // 0x490 int x494; // 0x494 int x498; // 0x498 int x49c; // 0x49c int x4a0; // 0x4a0 int x4a4; // 0x4a4 int x4a8; // 0x4a8 int x4ac; // 0x4ac int x4b0; // 0x4b0 int x4b4; // 0x4b4 int x4b8; // 0x4b8 int x4bc; // 0x4bc int x4c0; // 0x4c0 int x4c4; // 0x4c4 int x4c8; // 0x4c8 int x4cc; // 0x4cc int x4d0; // 0x4d0 int x4d4; // 0x4d4 int x4d8; // 0x4d8 int x4dc; // 0x4dc int x4e0; // 0x4e0 int x4e4; // 0x4e4 int x4e8; // 0x4e8 int x4ec; // 0x4ec int x4f0; // 0x4f0 int x4f4; // 0x4f4 int x4f8; // 0x4f8 int x4fc; // 0x4fc int x500; // 0x500 int x504; // 0x504 int x508; // 0x508 int x50c; // 0x50c int x510; // 0x510 int x514; // 0x514 int x518; // 0x518 int x51c; // 0x51c int x520; // 0x520 int x524; // 0x524 int x528; // 0x528 int x52c; // 0x52c int x530; // 0x530 int x534; // 0x534 int x538; // 0x538 int x53c; // 0x53c int x540; // 0x540 int x544; // 0x544 int x548; // 0x548 int x54c; // 0x54c int x550; // 0x550 int x554; // 0x554 int x558; // 0x558 int x55c; // 0x55c int x560; // 0x560 int x564; // 0x564 int x568; // 0x568 int x56c; // 0x56c int x570; // 0x570 int x574; // 0x574 int x578; // 0x578 int x57c; // 0x57c int x580; // 0x580 int x584; // 0x584 int x588; // 0x588 int x58c; // 0x58c int x590; // 0x590 int x594; // 0x594 int x598; // 0x598 int x59c; // 0x59c int x5a0; // 0x5a0 int x5a4; // 0x5a4 int x5a8; // 0x5a8 int x5ac; // 0x5ac int x5b0; // 0x5b0 int x5b4; // 0x5b4 int x5b8; // 0x5b8 int x5bc; // 0x5bc int x5c0; // 0x5c0 int x5c4; // 0x5c4 int x5c8; // 0x5c8 int x5cc; // 0x5cc int x5d0; // 0x5d0 int x5d4; // 0x5d4 int x5d8; // 0x5d8 int x5dc; // 0x5dc int x5e0; // 0x5e0 int x5e4; // 0x5e4 int x5e8; // 0x5e8 int x5ec; // 0x5ec int x5f0; // 0x5f0 int x5f4; // 0x5f4 int x5f8; // 0x5f8 int x5fc; // 0x5fc int x600; // 0x600 int x604; // 0x604 int x608; // 0x608 int x60c; // 0x60c int x610; // 0x610 int x614; // 0x614 int x618; // 0x618 int x61c; // 0x61c int x620; // 0x620 int x624; // 0x624 int x628; // 0x628 int x62c; // 0x62c int x630; // 0x630 int x634; // 0x634 int x638; // 0x638 int x63c; // 0x63c int x640; // 0x640 int x644; // 0x644 int x648; // 0x648 int x64c; // 0x64c int x650; // 0x650 int x654; // 0x654 int x658; // 0x658 int x65c; // 0x65c int x660; // 0x660 int x664; // 0x664 int x668; // 0x668 int x66c; // 0x66c int x670; // 0x670 int x674; // 0x674 int x678; // 0x678 int x67c; // 0x67c int x680; // 0x680 int x684; // 0x684 int x688; // 0x688 int x68c; // 0x68c int x690; // 0x690 int x694; // 0x694 int x698; // 0x698 int x69c; // 0x69c int x6a0; // 0x6a0 int x6a4; // 0x6a4 int x6a8; // 0x6a8 int x6ac; // 0x6ac int x6b0; // 0x6b0 int x6b4; // 0x6b4 int x6b8; // 0x6b8 int x6bc; // 0x6bc int x6c0; // 0x6c0 int x6c4; // 0x6c4 int x6c8; // 0x6c8 int x6cc; // 0x6cc int x6d0; // 0x6d0 int x6d4; // 0x6d4 int x6d8; // 0x6d8 int x6dc; // 0x6dc int x6e0; // 0x6e0 int x6e4; // 0x6e4 int x6e8; // 0x6e8 int x6ec; // 0x6ec int x6f0; // 0x6f0 int x6f4; // 0x6f4 int x6f8; // 0x6f8 int x6fc; // 0x6fc int x700; // 0x700 int x704; // 0x704 int x708; // 0x708 int x70c; // 0x70c int x710; // 0x710 int x714; // 0x714 int x718; // 0x718 int x71c; // 0x71c int x720; // 0x720 int x724; // 0x724 int x728; // 0x728 int x72c; // 0x72c int x730; // 0x730 int x734; // 0x734 int x738; // 0x738 int x73c; // 0x73c int x740; // 0x740 int x744; // 0x744 int x748; // 0x748 int x74c; // 0x74c int x750; // 0x750 int x754; // 0x754 int x758; // 0x758 int x75c; // 0x75c int x760; // 0x760 int x764; // 0x764 int x768; // 0x768 int x76c; // 0x76c int x770; // 0x770 int x774; // 0x774 int x778; // 0x778 int x77c; // 0x77c int x780; // 0x780 int x784; // 0x784 int x788; // 0x788 int x78c; // 0x78c int x790; // 0x790 int x794; // 0x794 int x798; // 0x798 int x79c; // 0x79c int x7a0; // 0x7a0 int x7a4; // 0x7a4 int x7a8; // 0x7a8 int x7ac; // 0x7ac int x7b0; // 0x7b0 int x7b4; // 0x7b4 int x7b8; // 0x7b8 int x7bc; // 0x7bc int x7c0; // 0x7c0 int x7c4; // 0x7c4 int x7c8; // 0x7c8 int x7cc; // 0x7cc int x7d0; // 0x7d0 int x7d4; // 0x7d4 int x7d8; // 0x7d8 int x7dc; // 0x7dc int x7e0; // 0x7e0 int x7e4; // 0x7e4 int x7e8; // 0x7e8 int x7ec; // 0x7ec int x7f0; // 0x7f0 int x7f4; // 0x7f4 int x7f8; // 0x7f8 int x7fc; // 0x7fc int x800; // 0x800 int x804; // 0x804 int x808; // 0x808 int x80c; // 0x80c int x810; // 0x810 int x814; // 0x814 int x818; // 0x818 int x81c; // 0x81c int x820; // 0x820 int x824; // 0x824 int x828; // 0x828 int x82c; // 0x82c int x830; // 0x830 int x834; // 0x834 int x838; // 0x838 int x83c; // 0x83c int x840; // 0x840 int x844; // 0x844 int x848; // 0x848 int x84c; // 0x84c int x850; // 0x850 int x854; // 0x854 int x858; // 0x858 int x85c; // 0x85c int x860; // 0x860 int x864; // 0x864 int x868; // 0x868 int x86c; // 0x86c int x870; // 0x870 int x874; // 0x874 int x878; // 0x878 int x87c; // 0x87c int x880; // 0x880 int x884; // 0x884 int x888; // 0x888 int x88c; // 0x88c int x890; // 0x890 int x894; // 0x894 int x898; // 0x898 int x89c; // 0x89c int x8a0; // 0x8a0 int x8a4; // 0x8a4 int x8a8; // 0x8a8 int x8ac; // 0x8ac int x8b0; // 0x8b0 int x8b4; // 0x8b4 int x8b8; // 0x8b8 int x8bc; // 0x8bc int x8c0; // 0x8c0 int x8c4; // 0x8c4 int x8c8; // 0x8c8 int x8cc; // 0x8cc int x8d0; // 0x8d0 int x8d4; // 0x8d4 int x8d8; // 0x8d8 int x8dc; // 0x8dc int x8e0; // 0x8e0 int x8e4; // 0x8e4 int x8e8; // 0x8e8 int x8ec; // 0x8ec int x8f0; // 0x8f0 int x8f4; // 0x8f4 int x8f8; // 0x8f8 int x8fc; // 0x8fc int x900; // 0x900 int x904; // 0x904 int x908; // 0x908 int x90c; // 0x90c int x910; // 0x910 int x914; // 0x914 int x918; // 0x918 int x91c; // 0x91c int x920; // 0x920 int x924; // 0x924 int x928; // 0x928 int x92c; // 0x92c int x930; // 0x930 int x934; // 0x934 int x938; // 0x938 int x93c; // 0x93c int x940; // 0x940 int x944; // 0x944 int x948; // 0x948 int x94c; // 0x94c int x950; // 0x950 int x954; // 0x954 int x958; // 0x958 int x95c; // 0x95c int x960; // 0x960 int x964; // 0x964 int x968; // 0x968 int x96c; // 0x96c int x970; // 0x970 int x974; // 0x974 int x978; // 0x978 int x97c; // 0x97c int x980; // 0x980 int x984; // 0x984 int x988; // 0x988 int x98c; // 0x98c int x990; // 0x990 int x994; // 0x994 int x998; // 0x998 int x99c; // 0x99c int x9a0; // 0x9a0 int x9a4; // 0x9a4 int x9a8; // 0x9a8 int x9ac; // 0x9ac int x9b0; // 0x9b0 int x9b4; // 0x9b4 int x9b8; // 0x9b8 int x9bc; // 0x9bc int x9c0; // 0x9c0 int x9c4; // 0x9c4 int x9c8; // 0x9c8 int x9cc; // 0x9cc int x9d0; // 0x9d0 int x9d4; // 0x9d4 int x9d8; // 0x9d8 int x9dc; // 0x9dc int x9e0; // 0x9e0 int x9e4; // 0x9e4 int x9e8; // 0x9e8 int x9ec; // 0x9ec int x9f0; // 0x9f0 int x9f4; // 0x9f4 int x9f8; // 0x9f8 int x9fc; // 0x9fc int xa00; // 0xa00 int xa04; // 0xa04 int xa08; // 0xa08 int xa0c; // 0xa0c int xa10; // 0xa10 int xa14; // 0xa14 int xa18; // 0xa18 int xa1c; // 0xa1c int xa20; // 0xa20 int xa24; // 0xa24 int xa28; // 0xa28 int xa2c; // 0xa2c int xa30; // 0xa30 int xa34; // 0xa34 int xa38; // 0xa38 int xa3c; // 0xa3c int xa40; // 0xa40 int xa44; // 0xa44 int xa48; // 0xa48 int xa4c; // 0xa4c int xa50; // 0xa50 int xa54; // 0xa54 int xa58; // 0xa58 int xa5c; // 0xa5c int xa60; // 0xa60 int xa64; // 0xa64 int xa68; // 0xa68 int xa6c; // 0xa6c int xa70; // 0xa70 int xa74; // 0xa74 int xa78; // 0xa78 int xa7c; // 0xa7c int xa80; // 0xa80 int xa84; // 0xa84 int xa88; // 0xa88 int xa8c; // 0xa8c int xa90; // 0xa90 int xa94; // 0xa94 int xa98; // 0xa98 int xa9c; // 0xa9c int xaa0; // 0xaa0 int xaa4; // 0xaa4 int xaa8; // 0xaa8 int xaac; // 0xaac int xab0; // 0xab0 int xab4; // 0xab4 int xab8; // 0xab8 int xabc; // 0xabc int xac0; // 0xac0 int xac4; // 0xac4 int xac8; // 0xac8 int xacc; // 0xacc int xad0; // 0xad0 int xad4; // 0xad4 int xad8; // 0xad8 int xadc; // 0xadc int xae0; // 0xae0 int xae4; // 0xae4 int xae8; // 0xae8 int xaec; // 0xaec int xaf0; // 0xaf0 int xaf4; // 0xaf4 int xaf8; // 0xaf8 int xafc; // 0xafc int xb00; // 0xb00 int xb04; // 0xb04 int xb08; // 0xb08 int xb0c; // 0xb0c int xb10; // 0xb10 int xb14; // 0xb14 int xb18; // 0xb18 int xb1c; // 0xb1c int xb20; // 0xb20 int xb24; // 0xb24 int xb28; // 0xb28 int xb2c; // 0xb2c int xb30; // 0xb30 int xb34; // 0xb34 int xb38; // 0xb38 int xb3c; // 0xb3c int xb40; // 0xb40 int xb44; // 0xb44 int xb48; // 0xb48 int xb4c; // 0xb4c int xb50; // 0xb50 int xb54; // 0xb54 int xb58; // 0xb58 int xb5c; // 0xb5c int xb60; // 0xb60 int xb64; // 0xb64 int xb68; // 0xb68 int xb6c; // 0xb6c int xb70; // 0xb70 int xb74; // 0xb74 int xb78; // 0xb78 int xb7c; // 0xb7c int xb80; // 0xb80 int xb84; // 0xb84 int xb88; // 0xb88 int xb8c; // 0xb8c int xb90; // 0xb90 int xb94; // 0xb94 int xb98; // 0xb98 int xb9c; // 0xb9c int xba0; // 0xba0 int xba4; // 0xba4 int xba8; // 0xba8 int xbac; // 0xbac int xbb0; // 0xbb0 int xbb4; // 0xbb4 int xbb8; // 0xbb8 int xbbc; // 0xbbc int xbc0; // 0xbc0 int xbc4; // 0xbc4 int xbc8; // 0xbc8 int xbcc; // 0xbcc int xbd0; // 0xbd0 int xbd4; // 0xbd4 int xbd8; // 0xbd8 int xbdc; // 0xbdc int xbe0; // 0xbe0 int xbe4; // 0xbe4 int xbe8; // 0xbe8 int xbec; // 0xbec int xbf0; // 0xbf0 int xbf4; // 0xbf4 int xbf8; // 0xbf8 int xbfc; // 0xbfc int xc00; // 0xc00 int xc04; // 0xc04 int xc08; // 0xc08 int xc0c; // 0xc0c int xc10; // 0xc10 int xc14; // 0xc14 int xc18; // 0xc18 int xc1c; // 0xc1c int xc20; // 0xc20 int xc24; // 0xc24 int xc28; // 0xc28 int xc2c; // 0xc2c int xc30; // 0xc30 int xc34; // 0xc34 int xc38; // 0xc38 int xc3c; // 0xc3c int xc40; // 0xc40 int xc44; // 0xc44 int xc48; // 0xc48 int xc4c; // 0xc4c int xc50; // 0xc50 int xc54; // 0xc54 int xc58; // 0xc58 int xc5c; // 0xc5c int xc60; // 0xc60 int xc64; // 0xc64 int xc68; // 0xc68 int xc6c; // 0xc6c int xc70; // 0xc70 int xc74; // 0xc74 int xc78; // 0xc78 int xc7c; // 0xc7c int xc80; // 0xc80 int xc84; // 0xc84 int xc88; // 0xc88 int xc8c; // 0xc8c int xc90; // 0xc90 int xc94; // 0xc94 int xc98; // 0xc98 int xc9c; // 0xc9c int xca0; // 0xca0 int xca4; // 0xca4 int xca8; // 0xca8 int xcac; // 0xcac int xcb0; // 0xcb0 int xcb4; // 0xcb4 int xcb8; // 0xcb8 int xcbc; // 0xcbc int xcc0; // 0xcc0 int xcc4; // 0xcc4 int xcc8; // 0xcc8 int xccc; // 0xccc int xcd0; // 0xcd0 int xcd4; // 0xcd4 int xcd8; // 0xcd8 int xcdc; // 0xcdc int xce0; // 0xce0 int xce4; // 0xce4 int xce8; // 0xce8 int xcec; // 0xcec int xcf0; // 0xcf0 int xcf4; // 0xcf4 int xcf8; // 0xcf8 int xcfc; // 0xcfc int xd00; // 0xd00 int xd04; // 0xd04 int xd08; // 0xd08 int xd0c; // 0xd0c int xd10; // 0xd10 int xd14; // 0xd14 int xd18; // 0xd18 int xd1c; // 0xd1c int xd20; // 0xd20 int xd24; // 0xd24 int xd28; // 0xd28 int xd2c; // 0xd2c int xd30; // 0xd30 int xd34; // 0xd34 int xd38; // 0xd38 int xd3c; // 0xd3c int xd40; // 0xd40 int xd44; // 0xd44 int xd48; // 0xd48 int xd4c; // 0xd4c int xd50; // 0xd50 int xd54; // 0xd54 int xd58; // 0xd58 int xd5c; // 0xd5c int xd60; // 0xd60 int xd64; // 0xd64 int xd68; // 0xd68 int xd6c; // 0xd6c int xd70; // 0xd70 int xd74; // 0xd74 int xd78; // 0xd78 int xd7c; // 0xd7c int xd80; // 0xd80 int xd84; // 0xd84 int xd88; // 0xd88 int xd8c; // 0xd8c int xd90; // 0xd90 int xd94; // 0xd94 int xd98; // 0xd98 int xd9c; // 0xd9c int xda0; // 0xda0 int xda4; // 0xda4 int xda8; // 0xda8 int xdac; // 0xdac int xdb0; // 0xdb0 int xdb4; // 0xdb4 int xdb8; // 0xdb8 int xdbc; // 0xdbc int xdc0; // 0xdc0 int xdc4; // 0xdc4 int xdc8; // 0xdc8 int xdcc; // 0xdcc int xdd0; // 0xdd0 int xdd4; // 0xdd4 int xdd8; // 0xdd8 int xddc; // 0xddc int xde0; // 0xde0 int xde4; // 0xde4 int xde8; // 0xde8 int xdec; // 0xdec int xdf0; // 0xdf0 int xdf4; // 0xdf4 int xdf8; // 0xdf8 int xdfc; // 0xdfc int xe00; // 0xe00 int xe04; // 0xe04 int xe08; // 0xe08 int xe0c; // 0xe0c int xe10; // 0xe10 int xe14; // 0xe14 int xe18; // 0xe18 int xe1c; // 0xe1c int xe20; // 0xe20 int xe24; // 0xe24 int xe28; // 0xe28 int xe2c; // 0xe2c int xe30; // 0xe30 int xe34; // 0xe34 int xe38; // 0xe38 int xe3c; // 0xe3c int xe40; // 0xe40 int xe44; // 0xe44 int xe48; // 0xe48 int xe4c; // 0xe4c int xe50; // 0xe50 int xe54; // 0xe54 int xe58; // 0xe58 int xe5c; // 0xe5c int xe60; // 0xe60 int xe64; // 0xe64 int xe68; // 0xe68 int xe6c; // 0xe6c int xe70; // 0xe70 int xe74; // 0xe74 int xe78; // 0xe78 int xe7c; // 0xe7c int xe80; // 0xe80 int xe84; // 0xe84 int xe88; // 0xe88 int xe8c; // 0xe8c int xe90; // 0xe90 int xe94; // 0xe94 int xe98; // 0xe98 int xe9c; // 0xe9c int xea0; // 0xea0 int xea4; // 0xea4 int xea8; // 0xea8 int xeac; // 0xeac int xeb0; // 0xeb0 int xeb4; // 0xeb4 int xeb8; // 0xeb8 int xebc; // 0xebc int xec0; // 0xec0 int xec4; // 0xec4 int xec8; // 0xec8 int xecc; // 0xecc int xed0; // 0xed0 int xed4; // 0xed4 int xed8; // 0xed8 int xedc; // 0xedc int xee0; // 0xee0 int xee4; // 0xee4 int xee8; // 0xee8 int xeec; // 0xeec int xef0; // 0xef0 int xef4; // 0xef4 int xef8; // 0xef8 int xefc; // 0xefc int xf00; // 0xf00 int xf04; // 0xf04 int xf08; // 0xf08 int xf0c; // 0xf0c int xf10; // 0xf10 int xf14; // 0xf14 int xf18; // 0xf18 int xf1c; // 0xf1c int xf20; // 0xf20 int xf24; // 0xf24 int xf28; // 0xf28 int xf2c; // 0xf2c int xf30; // 0xf30 int xf34; // 0xf34 int xf38; // 0xf38 int xf3c; // 0xf3c int xf40; // 0xf40 int xf44; // 0xf44 int xf48; // 0xf48 int xf4c; // 0xf4c int xf50; // 0xf50 int xf54; // 0xf54 int xf58; // 0xf58 int xf5c; // 0xf5c int xf60; // 0xf60 int xf64; // 0xf64 int xf68; // 0xf68 int xf6c; // 0xf6c int xf70; // 0xf70 int xf74; // 0xf74 int xf78; // 0xf78 int xf7c; // 0xf7c int xf80; // 0xf80 int xf84; // 0xf84 int xf88; // 0xf88 int xf8c; // 0xf8c int xf90; // 0xf90 int xf94; // 0xf94 int xf98; // 0xf98 int xf9c; // 0xf9c int xfa0; // 0xfa0 int xfa4; // 0xfa4 int xfa8; // 0xfa8 int xfac; // 0xfac int xfb0; // 0xfb0 int xfb4; // 0xfb4 int xfb8; // 0xfb8 int xfbc; // 0xfbc int xfc0; // 0xfc0 int xfc4; // 0xfc4 int xfc8; // 0xfc8 int xfcc; // 0xfcc int xfd0; // 0xfd0 int xfd4; // 0xfd4 int xfd8; // 0xfd8 int xfdc; // 0xfdc int xfe0; // 0xfe0 int xfe4; // 0xfe4 int xfe8; // 0xfe8 int xfec; // 0xfec int xff0; // 0xff0 int xff4; // 0xff4 int xff8; // 0xff8 int xffc; // 0xffc int x1000; // 0x1000 int x1004; // 0x1004 int x1008; // 0x1008 int x100c; // 0x100c int x1010; // 0x1010 int x1014; // 0x1014 int x1018; // 0x1018 int x101c; // 0x101c int x1020; // 0x1020 int x1024; // 0x1024 int x1028; // 0x1028 int x102c; // 0x102c int x1030; // 0x1030 int x1034; // 0x1034 int x1038; // 0x1038 int x103c; // 0x103c int x1040; // 0x1040 int x1044; // 0x1044 int x1048; // 0x1048 int x104c; // 0x104c int x1050; // 0x1050 int x1054; // 0x1054 int x1058; // 0x1058 int x105c; // 0x105c int x1060; // 0x1060 int x1064; // 0x1064 int x1068; // 0x1068 int x106c; // 0x106c int x1070; // 0x1070 int x1074; // 0x1074 int x1078; // 0x1078 int x107c; // 0x107c int x1080; // 0x1080 int x1084; // 0x1084 int x1088; // 0x1088 int x108c; // 0x108c int x1090; // 0x1090 int x1094; // 0x1094 int x1098; // 0x1098 int x109c; // 0x109c int x10a0; // 0x10a0 int x10a4; // 0x10a4 int x10a8; // 0x10a8 int x10ac; // 0x10ac int x10b0; // 0x10b0 int x10b4; // 0x10b4 int x10b8; // 0x10b8 int x10bc; // 0x10bc int x10c0; // 0x10c0 int x10c4; // 0x10c4 int x10c8; // 0x10c8 int x10cc; // 0x10cc int x10d0; // 0x10d0 int x10d4; // 0x10d4 int x10d8; // 0x10d8 int x10dc; // 0x10dc int x10e0; // 0x10e0 int x10e4; // 0x10e4 int x10e8; // 0x10e8 int x10ec; // 0x10ec int x10f0; // 0x10f0 int x10f4; // 0x10f4 int x10f8; // 0x10f8 int x10fc; // 0x10fc int x1100; // 0x1100 int x1104; // 0x1104 int x1108; // 0x1108 int x110c; // 0x110c int x1110; // 0x1110 int x1114; // 0x1114 int x1118; // 0x1118 int x111c; // 0x111c int x1120; // 0x1120 int x1124; // 0x1124 int x1128; // 0x1128 int x112c; // 0x112c int x1130; // 0x1130 int x1134; // 0x1134 int x1138; // 0x1138 int x113c; // 0x113c int x1140; // 0x1140 int x1144; // 0x1144 int x1148; // 0x1148 int x114c; // 0x114c int x1150; // 0x1150 int x1154; // 0x1154 int x1158; // 0x1158 int x115c; // 0x115c int x1160; // 0x1160 int x1164; // 0x1164 int x1168; // 0x1168 int x116c; // 0x116c int x1170; // 0x1170 int x1174; // 0x1174 int x1178; // 0x1178 int x117c; // 0x117c int x1180; // 0x1180 int x1184; // 0x1184 int x1188; // 0x1188 int x118c; // 0x118c int x1190; // 0x1190 int x1194; // 0x1194 int x1198; // 0x1198 int x119c; // 0x119c int x11a0; // 0x11a0 int x11a4; // 0x11a4 int x11a8; // 0x11a8 int x11ac; // 0x11ac int x11b0; // 0x11b0 int x11b4; // 0x11b4 int x11b8; // 0x11b8 int x11bc; // 0x11bc int x11c0; // 0x11c0 int x11c4; // 0x11c4 int x11c8; // 0x11c8 int x11cc; // 0x11cc int x11d0; // 0x11d0 int x11d4; // 0x11d4 int x11d8; // 0x11d8 int x11dc; // 0x11dc int x11e0; // 0x11e0 int x11e4; // 0x11e4 int x11e8; // 0x11e8 int x11ec; // 0x11ec int x11f0; // 0x11f0 int x11f4; // 0x11f4 int x11f8; // 0x11f8 int x11fc; // 0x11fc int x1200; // 0x1200 int x1204; // 0x1204 int x1208; // 0x1208 int x120c; // 0x120c int x1210; // 0x1210 int x1214; // 0x1214 int x1218; // 0x1218 int x121c; // 0x121c int x1220; // 0x1220 int x1224; // 0x1224 int x1228; // 0x1228 int x122c; // 0x122c int x1230; // 0x1230 int x1234; // 0x1234 int x1238; // 0x1238 int x123c; // 0x123c int x1240; // 0x1240 int x1244; // 0x1244 int x1248; // 0x1248 int x124c; // 0x124c int x1250; // 0x1250 int x1254; // 0x1254 int x1258; // 0x1258 int x125c; // 0x125c int x1260; // 0x1260 int x1264; // 0x1264 int x1268; // 0x1268 int x126c; // 0x126c int x1270; // 0x1270 int x1274; // 0x1274 int x1278; // 0x1278 int x127c; // 0x127c int x1280; // 0x1280 int x1284; // 0x1284 int x1288; // 0x1288 int x128c; // 0x128c int x1290; // 0x1290 int x1294; // 0x1294 int x1298; // 0x1298 int x129c; // 0x129c int x12a0; // 0x12a0 int x12a4; // 0x12a4 int x12a8; // 0x12a8 int x12ac; // 0x12ac int x12b0; // 0x12b0 int x12b4; // 0x12b4 int x12b8; // 0x12b8 int x12bc; // 0x12bc int x12c0; // 0x12c0 int x12c4; // 0x12c4 int x12c8; // 0x12c8 int x12cc; // 0x12cc int x12d0; // 0x12d0 int x12d4; // 0x12d4 int x12d8; // 0x12d8 int x12dc; // 0x12dc int x12e0; // 0x12e0 int x12e4; // 0x12e4 int x12e8; // 0x12e8 int x12ec; // 0x12ec int x12f0; // 0x12f0 int x12f4; // 0x12f4 int x12f8; // 0x12f8 int x12fc; // 0x12fc int x1300; // 0x1300 int x1304; // 0x1304 int x1308; // 0x1308 int x130c; // 0x130c int x1310; // 0x1310 int x1314; // 0x1314 int x1318; // 0x1318 int x131c; // 0x131c int x1320; // 0x1320 int x1324; // 0x1324 int x1328; // 0x1328 int x132c; // 0x132c int x1330; // 0x1330 int x1334; // 0x1334 int x1338; // 0x1338 int x133c; // 0x133c int x1340; // 0x1340 int x1344; // 0x1344 int x1348; // 0x1348 int x134c; // 0x134c int x1350; // 0x1350 int x1354; // 0x1354 int x1358; // 0x1358 int x135c; // 0x135c int x1360; // 0x1360 int x1364; // 0x1364 int x1368; // 0x1368 int x136c; // 0x136c int x1370; // 0x1370 int x1374; // 0x1374 int x1378; // 0x1378 int x137c; // 0x137c int x1380; // 0x1380 int x1384; // 0x1384 int x1388; // 0x1388 int x138c; // 0x138c int x1390; // 0x1390 int x1394; // 0x1394 int x1398; // 0x1398 int x139c; // 0x139c int x13a0; // 0x13a0 int x13a4; // 0x13a4 int x13a8; // 0x13a8 int x13ac; // 0x13ac int x13b0; // 0x13b0 int x13b4; // 0x13b4 int x13b8; // 0x13b8 int x13bc; // 0x13bc int x13c0; // 0x13c0 int x13c4; // 0x13c4 int x13c8; // 0x13c8 int x13cc; // 0x13cc int x13d0; // 0x13d0 int x13d4; // 0x13d4 int x13d8; // 0x13d8 int x13dc; // 0x13dc int x13e0; // 0x13e0 int x13e4; // 0x13e4 int x13e8; // 0x13e8 int x13ec; // 0x13ec int x13f0; // 0x13f0 int x13f4; // 0x13f4 int x13f8; // 0x13f8 int x13fc; // 0x13fc int x1400; // 0x1400 int x1404; // 0x1404 int x1408; // 0x1408 int x140c; // 0x140c int x1410; // 0x1410 int x1414; // 0x1414 int x1418; // 0x1418 int x141c; // 0x141c int x1420; // 0x1420 int x1424; // 0x1424 int x1428; // 0x1428 int x142c; // 0x142c int x1430; // 0x1430 int x1434; // 0x1434 int x1438; // 0x1438 int x143c; // 0x143c int x1440; // 0x1440 int x1444; // 0x1444 int x1448; // 0x1448 int x144c; // 0x144c int x1450; // 0x1450 int x1454; // 0x1454 int x1458; // 0x1458 int x145c; // 0x145c int x1460; // 0x1460 int x1464; // 0x1464 int x1468; // 0x1468 int x146c; // 0x146c int x1470; // 0x1470 int x1474; // 0x1474 int x1478; // 0x1478 int x147c; // 0x147c int x1480; // 0x1480 int x1484; // 0x1484 int x1488; // 0x1488 int x148c; // 0x148c int x1490; // 0x1490 int x1494; // 0x1494 int x1498; // 0x1498 int x149c; // 0x149c int x14a0; // 0x14a0 int x14a4; // 0x14a4 int x14a8; // 0x14a8 int x14ac; // 0x14ac int x14b0; // 0x14b0 int x14b4; // 0x14b4 int x14b8; // 0x14b8 int x14bc; // 0x14bc int x14c0; // 0x14c0 int x14c4; // 0x14c4 int x14c8; // 0x14c8 int x14cc; // 0x14cc int x14d0; // 0x14d0 int x14d4; // 0x14d4 int x14d8; // 0x14d8 int x14dc; // 0x14dc int x14e0; // 0x14e0 int x14e4; // 0x14e4 int x14e8; // 0x14e8 int x14ec; // 0x14ec int x14f0; // 0x14f0 int x14f4; // 0x14f4 int x14f8; // 0x14f8 int x14fc; // 0x14fc int x1500; // 0x1500 int x1504; // 0x1504 int x1508; // 0x1508 int x150c; // 0x150c int x1510; // 0x1510 int x1514; // 0x1514 int x1518; // 0x1518 int x151c; // 0x151c int x1520; // 0x1520 int x1524; // 0x1524 int x1528; // 0x1528 int x152c; // 0x152c int x1530; // 0x1530 int x1534; // 0x1534 int x1538; // 0x1538 int x153c; // 0x153c int x1540; // 0x1540 int x1544; // 0x1544 int x1548; // 0x1548 int x154c; // 0x154c int x1550; // 0x1550 int x1554; // 0x1554 int x1558; // 0x1558 int x155c; // 0x155c int x1560; // 0x1560 int x1564; // 0x1564 int x1568; // 0x1568 int x156c; // 0x156c int x1570; // 0x1570 int x1574; // 0x1574 int x1578; // 0x1578 int x157c; // 0x157c int x1580; // 0x1580 int x1584; // 0x1584 int x1588; // 0x1588 int x158c; // 0x158c int x1590; // 0x1590 int x1594; // 0x1594 int x1598; // 0x1598 int x159c; // 0x159c int x15a0; // 0x15a0 int x15a4; // 0x15a4 int x15a8; // 0x15a8 int x15ac; // 0x15ac int x15b0; // 0x15b0 int x15b4; // 0x15b4 int x15b8; // 0x15b8 int x15bc; // 0x15bc int x15c0; // 0x15c0 int x15c4; // 0x15c4 int x15c8; // 0x15c8 int x15cc; // 0x15cc int x15d0; // 0x15d0 int x15d4; // 0x15d4 int x15d8; // 0x15d8 int x15dc; // 0x15dc int x15e0; // 0x15e0 int x15e4; // 0x15e4 int x15e8; // 0x15e8 int x15ec; // 0x15ec int x15f0; // 0x15f0 int x15f4; // 0x15f4 int x15f8; // 0x15f8 int x15fc; // 0x15fc int x1600; // 0x1600 int x1604; // 0x1604 int x1608; // 0x1608 int x160c; // 0x160c int x1610; // 0x1610 int x1614; // 0x1614 int x1618; // 0x1618 int x161c; // 0x161c int x1620; // 0x1620 int x1624; // 0x1624 int x1628; // 0x1628 int x162c; // 0x162c int x1630; // 0x1630 int x1634; // 0x1634 int x1638; // 0x1638 int x163c; // 0x163c int x1640; // 0x1640 int x1644; // 0x1644 int x1648; // 0x1648 int x164c; // 0x164c int x1650; // 0x1650 int x1654; // 0x1654 int x1658; // 0x1658 int x165c; // 0x165c int x1660; // 0x1660 int x1664; // 0x1664 int x1668; // 0x1668 int x166c; // 0x166c int x1670; // 0x1670 int x1674; // 0x1674 int x1678; // 0x1678 int x167c; // 0x167c int x1680; // 0x1680 int x1684; // 0x1684 int x1688; // 0x1688 int x168c; // 0x168c int x1690; // 0x1690 int x1694; // 0x1694 int x1698; // 0x1698 int x169c; // 0x169c int x16a0; // 0x16a0 int x16a4; // 0x16a4 int x16a8; // 0x16a8 int x16ac; // 0x16ac int x16b0; // 0x16b0 int x16b4; // 0x16b4 int x16b8; // 0x16b8 int x16bc; // 0x16bc int x16c0; // 0x16c0 int x16c4; // 0x16c4 int x16c8; // 0x16c8 int x16cc; // 0x16cc int x16d0; // 0x16d0 int x16d4; // 0x16d4 int x16d8; // 0x16d8 int x16dc; // 0x16dc int x16e0; // 0x16e0 int x16e4; // 0x16e4 int x16e8; // 0x16e8 int x16ec; // 0x16ec int x16f0; // 0x16f0 int x16f4; // 0x16f4 int x16f8; // 0x16f8 int x16fc; // 0x16fc int x1700; // 0x1700 int x1704; // 0x1704 int x1708; // 0x1708 int x170c; // 0x170c int x1710; // 0x1710 int x1714; // 0x1714 int x1718; // 0x1718 int x171c; // 0x171c int x1720; // 0x1720 int x1724; // 0x1724 int x1728; // 0x1728 int x172c; // 0x172c int x1730; // 0x1730 int x1734; // 0x1734 int x1738; // 0x1738 int x173c; // 0x173c int x1740; // 0x1740 int x1744; // 0x1744 int x1748; // 0x1748 int x174c; // 0x174c int x1750; // 0x1750 int x1754; // 0x1754 int x1758; // 0x1758 int x175c; // 0x175c int x1760; // 0x1760 int x1764; // 0x1764 int x1768; // 0x1768 int x176c; // 0x176c int x1770; // 0x1770 int x1774; // 0x1774 int x1778; // 0x1778 int x177c; // 0x177c int x1780; // 0x1780 int x1784; // 0x1784 int x1788; // 0x1788 int x178c; // 0x178c int x1790; // 0x1790 int x1794; // 0x1794 int x1798; // 0x1798 int x179c; // 0x179c int x17a0; // 0x17a0 int x17a4; // 0x17a4 int x17a8; // 0x17a8 int x17ac; // 0x17ac int x17b0; // 0x17b0 int x17b4; // 0x17b4 int x17b8; // 0x17b8 int x17bc; // 0x17bc int x17c0; // 0x17c0 int x17c4; // 0x17c4 int x17c8; // 0x17c8 int x17cc; // 0x17cc int x17d0; // 0x17d0 int x17d4; // 0x17d4 int x17d8; // 0x17d8 int x17dc; // 0x17dc int x17e0; // 0x17e0 int x17e4; // 0x17e4 int x17e8; // 0x17e8 int x17ec; // 0x17ec int x17f0; // 0x17f0 int x17f4; // 0x17f4 int x17f8; // 0x17f8 int x17fc; // 0x17fc int x1800; // 0x1800 int x1804; // 0x1804 int x1808; // 0x1808 int x180c; // 0x180c int x1810; // 0x1810 int x1814; // 0x1814 int x1818; // 0x1818 int x181c; // 0x181c int x1820; // 0x1820 int x1824; // 0x1824 int x1828; // 0x1828 int x182c; // 0x182c int x1830; // 0x1830 int x1834; // 0x1834 int x1838; // 0x1838 int x183c; // 0x183c int x1840; // 0x1840 int x1844; // 0x1844 int x1848; // 0x1848 int x184c; // 0x184c int x1850; // 0x1850 int x1854; // 0x1854 int x1858; // 0x1858 int x185c; // 0x185c int x1860; // 0x1860 int x1864; // 0x1864 int x1868; // 0x1868 int x186c; // 0x186c int x1870; // 0x1870 int x1874; // 0x1874 int x1878; // 0x1878 int x187c; // 0x187c int x1880; // 0x1880 int x1884; // 0x1884 int x1888; // 0x1888 int x188c; // 0x188c int x1890; // 0x1890 int x1894; // 0x1894 int x1898; // 0x1898 int x189c; // 0x189c int x18a0; // 0x18a0 int x18a4; // 0x18a4 int x18a8; // 0x18a8 int x18ac; // 0x18ac int x18b0; // 0x18b0 int x18b4; // 0x18b4 int x18b8; // 0x18b8 int x18bc; // 0x18bc int x18c0; // 0x18c0 int x18c4; // 0x18c4 int x18c8; // 0x18c8 int x18cc; // 0x18cc int x18d0; // 0x18d0 int x18d4; // 0x18d4 int x18d8; // 0x18d8 int x18dc; // 0x18dc int x18e0; // 0x18e0 int x18e4; // 0x18e4 int x18e8; // 0x18e8 int x18ec; // 0x18ec int x18f0; // 0x18f0 int x18f4; // 0x18f4 int x18f8; // 0x18f8 int x18fc; // 0x18fc int x1900; // 0x1900 int x1904; // 0x1904 int x1908; // 0x1908 int x190c; // 0x190c int x1910; // 0x1910 int x1914; // 0x1914 int x1918; // 0x1918 int x191c; // 0x191c int x1920; // 0x1920 int x1924; // 0x1924 int x1928; // 0x1928 int x192c; // 0x192c int x1930; // 0x1930 int x1934; // 0x1934 int x1938; // 0x1938 int x193c; // 0x193c int x1940; // 0x1940 int x1944; // 0x1944 int x1948; // 0x1948 int x194c; // 0x194c int x1950; // 0x1950 int x1954; // 0x1954 int x1958; // 0x1958 int x195c; // 0x195c int x1960; // 0x1960 int x1964; // 0x1964 int x1968; // 0x1968 int x196c; // 0x196c int x1970; // 0x1970 int x1974; // 0x1974 int x1978; // 0x1978 int x197c; // 0x197c int x1980; // 0x1980 int x1984; // 0x1984 int x1988; // 0x1988 int x198c; // 0x198c int x1990; // 0x1990 int x1994; // 0x1994 int x1998; // 0x1998 int x199c; // 0x199c int x19a0; // 0x19a0 int x19a4; // 0x19a4 int x19a8; // 0x19a8 int x19ac; // 0x19ac int x19b0; // 0x19b0 int x19b4; // 0x19b4 int x19b8; // 0x19b8 int x19bc; // 0x19bc int x19c0; // 0x19c0 int x19c4; // 0x19c4 int x19c8; // 0x19c8 int x19cc; // 0x19cc int x19d0; // 0x19d0 int x19d4; // 0x19d4 int x19d8; // 0x19d8 int x19dc; // 0x19dc int x19e0; // 0x19e0 int x19e4; // 0x19e4 int x19e8; // 0x19e8 int x19ec; // 0x19ec int x19f0; // 0x19f0 int x19f4; // 0x19f4 int x19f8; // 0x19f8 int x19fc; // 0x19fc int x1a00; // 0x1a00 int x1a04; // 0x1a04 int x1a08; // 0x1a08 int x1a0c; // 0x1a0c int x1a10; // 0x1a10 int x1a14; // 0x1a14 int x1a18; // 0x1a18 int x1a1c; // 0x1a1c int x1a20; // 0x1a20 int x1a24; // 0x1a24 int x1a28; // 0x1a28 int x1a2c; // 0x1a2c int x1a30; // 0x1a30 int x1a34; // 0x1a34 int x1a38; // 0x1a38 int x1a3c; // 0x1a3c int x1a40; // 0x1a40 int x1a44; // 0x1a44 int x1a48; // 0x1a48 int x1a4c; // 0x1a4c int x1a50; // 0x1a50 int x1a54; // 0x1a54 int x1a58; // 0x1a58 int x1a5c; // 0x1a5c int x1a60; // 0x1a60 int x1a64; // 0x1a64 int x1a68; // 0x1a68 int x1a6c; // 0x1a6c int x1a70; // 0x1a70 int x1a74; // 0x1a74 int x1a78; // 0x1a78 int x1a7c; // 0x1a7c int x1a80; // 0x1a80 int x1a84; // 0x1a84 int x1a88; // 0x1a88 int x1a8c; // 0x1a8c int x1a90; // 0x1a90 int x1a94; // 0x1a94 int x1a98; // 0x1a98 int x1a9c; // 0x1a9c int x1aa0; // 0x1aa0 int x1aa4; // 0x1aa4 int x1aa8; // 0x1aa8 int x1aac; // 0x1aac int x1ab0; // 0x1ab0 int x1ab4; // 0x1ab4 int x1ab8; // 0x1ab8 int x1abc; // 0x1abc int x1ac0; // 0x1ac0 int x1ac4; // 0x1ac4 int x1ac8; // 0x1ac8 int x1acc; // 0x1acc int x1ad0; // 0x1ad0 int x1ad4; // 0x1ad4 int x1ad8; // 0x1ad8 int x1adc; // 0x1adc int x1ae0; // 0x1ae0 int x1ae4; // 0x1ae4 int x1ae8; // 0x1ae8 int x1aec; // 0x1aec int x1af0; // 0x1af0 int x1af4; // 0x1af4 int x1af8; // 0x1af8 int x1afc; // 0x1afc int x1b00; // 0x1b00 int x1b04; // 0x1b04 int x1b08; // 0x1b08 int x1b0c; // 0x1b0c int x1b10; // 0x1b10 int x1b14; // 0x1b14 int x1b18; // 0x1b18 int x1b1c; // 0x1b1c int x1b20; // 0x1b20 int x1b24; // 0x1b24 int x1b28; // 0x1b28 int x1b2c; // 0x1b2c int x1b30; // 0x1b30 int x1b34; // 0x1b34 int x1b38; // 0x1b38 int x1b3c; // 0x1b3c int x1b40; // 0x1b40 int x1b44; // 0x1b44 int x1b48; // 0x1b48 int x1b4c; // 0x1b4c int x1b50; // 0x1b50 int x1b54; // 0x1b54 int x1b58; // 0x1b58 int x1b5c; // 0x1b5c int x1b60; // 0x1b60 int x1b64; // 0x1b64 int x1b68; // 0x1b68 int x1b6c; // 0x1b6c int x1b70; // 0x1b70 int x1b74; // 0x1b74 int x1b78; // 0x1b78 int x1b7c; // 0x1b7c int x1b80; // 0x1b80 int x1b84; // 0x1b84 int x1b88; // 0x1b88 int x1b8c; // 0x1b8c int x1b90; // 0x1b90 int x1b94; // 0x1b94 int x1b98; // 0x1b98 int x1b9c; // 0x1b9c int x1ba0; // 0x1ba0 int x1ba4; // 0x1ba4 int x1ba8; // 0x1ba8 int x1bac; // 0x1bac int x1bb0; // 0x1bb0 int x1bb4; // 0x1bb4 int x1bb8; // 0x1bb8 int x1bbc; // 0x1bbc int x1bc0; // 0x1bc0 int x1bc4; // 0x1bc4 int x1bc8; // 0x1bc8 int x1bcc; // 0x1bcc int x1bd0; // 0x1bd0 int x1bd4; // 0x1bd4 int x1bd8; // 0x1bd8 int x1bdc; // 0x1bdc int x1be0; // 0x1be0 int x1be4; // 0x1be4 int x1be8; // 0x1be8 int x1bec; // 0x1bec int x1bf0; // 0x1bf0 int x1bf4; // 0x1bf4 int x1bf8; // 0x1bf8 int x1bfc; // 0x1bfc int x1c00; // 0x1c00 int x1c04; // 0x1c04 int x1c08; // 0x1c08 int x1c0c; // 0x1c0c int x1c10; // 0x1c10 int x1c14; // 0x1c14 int x1c18; // 0x1c18 int x1c1c; // 0x1c1c int x1c20; // 0x1c20 int x1c24; // 0x1c24 int x1c28; // 0x1c28 int x1c2c; // 0x1c2c int x1c30; // 0x1c30 int x1c34; // 0x1c34 int x1c38; // 0x1c38 int x1c3c; // 0x1c3c int x1c40; // 0x1c40 int x1c44; // 0x1c44 int x1c48; // 0x1c48 int x1c4c; // 0x1c4c int x1c50; // 0x1c50 int x1c54; // 0x1c54 int x1c58; // 0x1c58 int x1c5c; // 0x1c5c int x1c60; // 0x1c60 int x1c64; // 0x1c64 int x1c68; // 0x1c68 int x1c6c; // 0x1c6c int x1c70; // 0x1c70 int x1c74; // 0x1c74 int x1c78; // 0x1c78 int x1c7c; // 0x1c7c int x1c80; // 0x1c80 int x1c84; // 0x1c84 int x1c88; // 0x1c88 int x1c8c; // 0x1c8c int x1c90; // 0x1c90 int x1c94; // 0x1c94 int x1c98; // 0x1c98 int x1c9c; // 0x1c9c int x1ca0; // 0x1ca0 int x1ca4; // 0x1ca4 int x1ca8; // 0x1ca8 int x1cac; // 0x1cac int x1cb0; // 0x1cb0 int x1cb4; // 0x1cb4 int x1cb8; // 0x1cb8 int x1cbc; // 0x1cbc int x1cc0; // 0x1cc0 int x1cc4; // 0x1cc4 int x1cc8; // 0x1cc8 int x1ccc; // 0x1ccc int x1cd0; // 0x1cd0 int x1cd4; // 0x1cd4 int x1cd8; // 0x1cd8 int x1cdc; // 0x1cdc int x1ce0; // 0x1ce0 int x1ce4; // 0x1ce4 int x1ce8; // 0x1ce8 int x1cec; // 0x1cec int x1cf0; // 0x1cf0 int x1cf4; // 0x1cf4 int x1cf8; // 0x1cf8 int x1cfc; // 0x1cfc int x1d00; // 0x1d00 int x1d04; // 0x1d04 int x1d08; // 0x1d08 int x1d0c; // 0x1d0c int x1d10; // 0x1d10 int x1d14; // 0x1d14 int x1d18; // 0x1d18 int x1d1c; // 0x1d1c int x1d20; // 0x1d20 int x1d24; // 0x1d24 int x1d28; // 0x1d28 int x1d2c; // 0x1d2c int x1d30; // 0x1d30 int x1d34; // 0x1d34 int x1d38; // 0x1d38 int x1d3c; // 0x1d3c int x1d40; // 0x1d40 int x1d44; // 0x1d44 int x1d48; // 0x1d48 int x1d4c; // 0x1d4c int x1d50; // 0x1d50 int x1d54; // 0x1d54 int x1d58; // 0x1d58 int x1d5c; // 0x1d5c int x1d60; // 0x1d60 int x1d64; // 0x1d64 int x1d68; // 0x1d68 int x1d6c; // 0x1d6c int x1d70; // 0x1d70 int x1d74; // 0x1d74 int x1d78; // 0x1d78 int x1d7c; // 0x1d7c int x1d80; // 0x1d80 int x1d84; // 0x1d84 int x1d88; // 0x1d88 int x1d8c; // 0x1d8c int x1d90; // 0x1d90 int x1d94; // 0x1d94 int x1d98; // 0x1d98 int x1d9c; // 0x1d9c int x1da0; // 0x1da0 int x1da4; // 0x1da4 int x1da8; // 0x1da8 int x1dac; // 0x1dac int x1db0; // 0x1db0 int x1db4; // 0x1db4 int x1db8; // 0x1db8 int x1dbc; // 0x1dbc int x1dc0; // 0x1dc0 int x1dc4; // 0x1dc4 int x1dc8; // 0x1dc8 int x1dcc; // 0x1dcc int x1dd0; // 0x1dd0 int x1dd4; // 0x1dd4 int x1dd8; // 0x1dd8 int x1ddc; // 0x1ddc int x1de0; // 0x1de0 int x1de4; // 0x1de4 int x1de8; // 0x1de8 int x1dec; // 0x1dec int x1df0; // 0x1df0 int x1df4; // 0x1df4 int x1df8; // 0x1df8 int x1dfc; // 0x1dfc int x1e00; // 0x1e00 int x1e04; // 0x1e04 int x1e08; // 0x1e08 int x1e0c; // 0x1e0c int x1e10; // 0x1e10 int x1e14; // 0x1e14 int x1e18; // 0x1e18 int x1e1c; // 0x1e1c int x1e20; // 0x1e20 int x1e24; // 0x1e24 int x1e28; // 0x1e28 int x1e2c; // 0x1e2c int x1e30; // 0x1e30 int x1e34; // 0x1e34 int x1e38; // 0x1e38 int x1e3c; // 0x1e3c int x1e40; // 0x1e40 int x1e44; // 0x1e44 int x1e48; // 0x1e48 int x1e4c; // 0x1e4c int x1e50; // 0x1e50 int x1e54; // 0x1e54 int x1e58; // 0x1e58 int x1e5c; // 0x1e5c int x1e60; // 0x1e60 int x1e64; // 0x1e64 int x1e68; // 0x1e68 int x1e6c; // 0x1e6c int x1e70; // 0x1e70 int x1e74; // 0x1e74 int x1e78; // 0x1e78 int x1e7c; // 0x1e7c int x1e80; // 0x1e80 int x1e84; // 0x1e84 int x1e88; // 0x1e88 int x1e8c; // 0x1e8c int x1e90; // 0x1e90 int x1e94; // 0x1e94 int x1e98; // 0x1e98 int x1e9c; // 0x1e9c int x1ea0; // 0x1ea0 int x1ea4; // 0x1ea4 int x1ea8; // 0x1ea8 int x1eac; // 0x1eac int x1eb0; // 0x1eb0 int x1eb4; // 0x1eb4 int x1eb8; // 0x1eb8 int x1ebc; // 0x1ebc int x1ec0; // 0x1ec0 int x1ec4; // 0x1ec4 int x1ec8; // 0x1ec8 int x1ecc; // 0x1ecc int x1ed0; // 0x1ed0 int x1ed4; // 0x1ed4 int x1ed8; // 0x1ed8 int x1edc; // 0x1edc int x1ee0; // 0x1ee0 int x1ee4; // 0x1ee4 int x1ee8; // 0x1ee8 int x1eec; // 0x1eec int x1ef0; // 0x1ef0 int x1ef4; // 0x1ef4 int x1ef8; // 0x1ef8 int x1efc; // 0x1efc int x1f00; // 0x1f00 int x1f04; // 0x1f04 int x1f08; // 0x1f08 int x1f0c; // 0x1f0c int x1f10; // 0x1f10 int x1f14; // 0x1f14 int x1f18; // 0x1f18 int x1f1c; // 0x1f1c int x1f20; // 0x1f20 int x1f24; // 0x1f24 int x1f28; // 0x1f28 int x1f2c; // 0x1f2c int x1f30; // 0x1f30 int x1f34; // 0x1f34 int x1f38; // 0x1f38 int x1f3c; // 0x1f3c int x1f40; // 0x1f40 int x1f44; // 0x1f44 int x1f48; // 0x1f48 int x1f4c; // 0x1f4c int x1f50; // 0x1f50 int x1f54; // 0x1f54 int x1f58; // 0x1f58 int x1f5c; // 0x1f5c int x1f60; // 0x1f60 int x1f64; // 0x1f64 int x1f68; // 0x1f68 int x1f6c; // 0x1f6c int x1f70; // 0x1f70 int x1f74; // 0x1f74 int x1f78; // 0x1f78 int x1f7c; // 0x1f7c int x1f80; // 0x1f80 int x1f84; // 0x1f84 int x1f88; // 0x1f88 int x1f8c; // 0x1f8c int x1f90; // 0x1f90 int x1f94; // 0x1f94 int x1f98; // 0x1f98 int x1f9c; // 0x1f9c int x1fa0; // 0x1fa0 int x1fa4; // 0x1fa4 int x1fa8; // 0x1fa8 int x1fac; // 0x1fac int x1fb0; // 0x1fb0 int x1fb4; // 0x1fb4 int x1fb8; // 0x1fb8 int x1fbc; // 0x1fbc int x1fc0; // 0x1fc0 int x1fc4; // 0x1fc4 int x1fc8; // 0x1fc8 int x1fcc; // 0x1fcc int x1fd0; // 0x1fd0 int x1fd4; // 0x1fd4 int x1fd8; // 0x1fd8 int x1fdc; // 0x1fdc int x1fe0; // 0x1fe0 int x1fe4; // 0x1fe4 int x1fe8; // 0x1fe8 int x1fec; // 0x1fec int x1ff0; // 0x1ff0 int x1ff4; // 0x1ff4 int x1ff8; // 0x1ff8 int x1ffc; // 0x1ffc int x2000; // 0x2000 int x2004; // 0x2004 int x2008; // 0x2008 int x200c; // 0x200c int x2010; // 0x2010 int x2014; // 0x2014 int x2018; // 0x2018 int x201c; // 0x201c int x2020; // 0x2020 int x2024; // 0x2024 int x2028; // 0x2028 int x202c; // 0x202c int x2030; // 0x2030 int x2034; // 0x2034 int x2038; // 0x2038 int x203c; // 0x203c int x2040; // 0x2040 int x2044; // 0x2044 int x2048; // 0x2048 int x204c; // 0x204c int x2050; // 0x2050 int x2054; // 0x2054 int x2058; // 0x2058 int x205c; // 0x205c int x2060; // 0x2060 int x2064; // 0x2064 int x2068; // 0x2068 int x206c; // 0x206c int x2070; // 0x2070 int x2074; // 0x2074 int x2078; // 0x2078 int x207c; // 0x207c int x2080; // 0x2080 int x2084; // 0x2084 int x2088; // 0x2088 int x208c; // 0x208c int x2090; // 0x2090 int x2094; // 0x2094 int x2098; // 0x2098 int x209c; // 0x209c int x20a0; // 0x20a0 int x20a4; // 0x20a4 int x20a8; // 0x20a8 int x20ac; // 0x20ac int x20b0; // 0x20b0 int x20b4; // 0x20b4 int x20b8; // 0x20b8 int x20bc; // 0x20bc int x20c0; // 0x20c0 int x20c4; // 0x20c4 int x20c8; // 0x20c8 int x20cc; // 0x20cc int x20d0; // 0x20d0 int x20d4; // 0x20d4 int x20d8; // 0x20d8 int x20dc; // 0x20dc int x20e0; // 0x20e0 int x20e4; // 0x20e4 int x20e8; // 0x20e8 int x20ec; // 0x20ec int x20f0; // 0x20f0 int x20f4; // 0x20f4 int x20f8; // 0x20f8 int x20fc; // 0x20fc int x2100; // 0x2100 int x2104; // 0x2104 int x2108; // 0x2108 int x210c; // 0x210c int x2110; // 0x2110 int x2114; // 0x2114 int x2118; // 0x2118 int x211c; // 0x211c int x2120; // 0x2120 int x2124; // 0x2124 int x2128; // 0x2128 int x212c; // 0x212c int x2130; // 0x2130 int x2134; // 0x2134 int x2138; // 0x2138 int x213c; // 0x213c int x2140; // 0x2140 int x2144; // 0x2144 int x2148; // 0x2148 int x214c; // 0x214c int x2150; // 0x2150 int x2154; // 0x2154 int x2158; // 0x2158 int x215c; // 0x215c int x2160; // 0x2160 int x2164; // 0x2164 int x2168; // 0x2168 int x216c; // 0x216c int x2170; // 0x2170 int x2174; // 0x2174 int x2178; // 0x2178 int x217c; // 0x217c int x2180; // 0x2180 int x2184; // 0x2184 int x2188; // 0x2188 int x218c; // 0x218c int x2190; // 0x2190 int x2194; // 0x2194 int x2198; // 0x2198 int x219c; // 0x219c int x21a0; // 0x21a0 int x21a4; // 0x21a4 int x21a8; // 0x21a8 int x21ac; // 0x21ac int x21b0; // 0x21b0 int x21b4; // 0x21b4 int x21b8; // 0x21b8 int x21bc; // 0x21bc int x21c0; // 0x21c0 int x21c4; // 0x21c4 int x21c8; // 0x21c8 int x21cc; // 0x21cc int x21d0; // 0x21d0 int x21d4; // 0x21d4 int x21d8; // 0x21d8 int x21dc; // 0x21dc int x21e0; // 0x21e0 int x21e4; // 0x21e4 int x21e8; // 0x21e8 int x21ec; // 0x21ec int x21f0; // 0x21f0 int x21f4; // 0x21f4 int x21f8; // 0x21f8 int x21fc; // 0x21fc int x2200; // 0x2200 int x2204; // 0x2204 int x2208; // 0x2208 int x220c; // 0x220c int x2210; // 0x2210 int x2214; // 0x2214 int x2218; // 0x2218 int x221c; // 0x221c int x2220; // 0x2220 int x2224; // 0x2224 int x2228; // 0x2228 int x222c; // 0x222c int x2230; // 0x2230 int x2234; // 0x2234 int x2238; // 0x2238 int x223c; // 0x223c int x2240; // 0x2240 int x2244; // 0x2244 int x2248; // 0x2248 int x224c; // 0x224c int x2250; // 0x2250 int x2254; // 0x2254 int x2258; // 0x2258 int x225c; // 0x225c int x2260; // 0x2260 int x2264; // 0x2264 int x2268; // 0x2268 int x226c; // 0x226c int x2270; // 0x2270 int x2274; // 0x2274 int x2278; // 0x2278 int x227c; // 0x227c int x2280; // 0x2280 int x2284; // 0x2284 int x2288; // 0x2288 int x228c; // 0x228c int x2290; // 0x2290 int x2294; // 0x2294 int x2298; // 0x2298 int x229c; // 0x229c int x22a0; // 0x22a0 int x22a4; // 0x22a4 int x22a8; // 0x22a8 int x22ac; // 0x22ac int x22b0; // 0x22b0 int x22b4; // 0x22b4 int x22b8; // 0x22b8 int x22bc; // 0x22bc int x22c0; // 0x22c0 int x22c4; // 0x22c4 int x22c8; // 0x22c8 int x22cc; // 0x22cc int x22d0; // 0x22d0 int x22d4; // 0x22d4 int x22d8; // 0x22d8 int x22dc; // 0x22dc int x22e0; // 0x22e0 int x22e4; // 0x22e4 int x22e8; // 0x22e8 int x22ec; // 0x22ec int x22f0; // 0x22f0 int x22f4; // 0x22f4 int x22f8; // 0x22f8 int x22fc; // 0x22fc int x2300; // 0x2300 int x2304; // 0x2304 int x2308; // 0x2308 int x230c; // 0x230c int x2310; // 0x2310 int x2314; // 0x2314 int x2318; // 0x2318 int x231c; // 0x231c int x2320; // 0x2320 int x2324; // 0x2324 int x2328; // 0x2328 int x232c; // 0x232c int x2330; // 0x2330 int x2334; // 0x2334 int x2338; // 0x2338 int x233c; // 0x233c int x2340; // 0x2340 int x2344; // 0x2344 int x2348; // 0x2348 int x234c; // 0x234c int x2350; // 0x2350 int x2354; // 0x2354 int x2358; // 0x2358 int x235c; // 0x235c int x2360; // 0x2360 int x2364; // 0x2364 int x2368; // 0x2368 int x236c; // 0x236c int x2370; // 0x2370 int x2374; // 0x2374 int x2378; // 0x2378 int x237c; // 0x237c int x2380; // 0x2380 int x2384; // 0x2384 int x2388; // 0x2388 int x238c; // 0x238c int x2390; // 0x2390 int x2394; // 0x2394 int x2398; // 0x2398 int x239c; // 0x239c int x23a0; // 0x23a0 int x23a4; // 0x23a4 int x23a8; // 0x23a8 int x23ac; // 0x23ac int x23b0; // 0x23b0 int x23b4; // 0x23b4 int x23b8; // 0x23b8 int x23bc; // 0x23bc int x23c0; // 0x23c0 int x23c4; // 0x23c4 int x23c8; // 0x23c8 int x23cc; // 0x23cc int x23d0; // 0x23d0 int x23d4; // 0x23d4 int x23d8; // 0x23d8 int x23dc; // 0x23dc int x23e0; // 0x23e0 int x23e4; // 0x23e4 int x23e8; // 0x23e8 int x23ec; // 0x23ec int x23f0; // 0x23f0 int x23f4; // 0x23f4 int x23f8; // 0x23f8 int x23fc; // 0x23fc int x2400; // 0x2400 int x2404; // 0x2404 int x2408; // 0x2408 int x240c; // 0x240c int x2410; // 0x2410 int x2414; // 0x2414 int x2418; // 0x2418 int x241c; // 0x241c int x2420; // 0x2420 int x2424; // 0x2424 int x2428; // 0x2428 int x242c; // 0x242c int x2430; // 0x2430 int x2434; // 0x2434 int x2438; // 0x2438 int x243c; // 0x243c int x2440; // 0x2440 int x2444; // 0x2444 int x2448; // 0x2448 int x244c; // 0x244c int x2450; // 0x2450 int x2454; // 0x2454 int x2458; // 0x2458 int x245c; // 0x245c int x2460; // 0x2460 int x2464; // 0x2464 int x2468; // 0x2468 int x246c; // 0x246c int x2470; // 0x2470 int x2474; // 0x2474 int x2478; // 0x2478 int x247c; // 0x247c int x2480; // 0x2480 int x2484; // 0x2484 int x2488; // 0x2488 int x248c; // 0x248c int x2490; // 0x2490 int x2494; // 0x2494 int x2498; // 0x2498 int x249c; // 0x249c int x24a0; // 0x24a0 int x24a4; // 0x24a4 int x24a8; // 0x24a8 int x24ac; // 0x24ac int x24b0; // 0x24b0 int x24b4; // 0x24b4 int x24b8; // 0x24b8 int x24bc; // 0x24bc int x24c0; // 0x24c0 int x24c4; // 0x24c4 MatchInit match; // 0x24c8 }; static Match *stc_match = 0x8046b6a0; static MatchCamera *stc_matchcam = 0x80452c68; static MatchHUD *stc_matchhud = 0x804a10c8; MatchOffscreen *stc_match_offscreen = 0x804a1df0; /*** Functions ***/ CameraBox *CameraBox_Alloc(); void CameraBox_Destroy(CameraBox *cam); void KOCount_Init(int updateCallback); void KOCount_Update(int KOs); void Stage_CameraLimitInitialization(); void Stage_BlastzoneInitialization(); void Match_SetEndGraphic(int graphic); void Match_EndImmediate(); void Match_EndVS(); void Match_FadeScreen(int time); int Match_CheckIfTeams(); int Match_CheckIfStock(); void Match_SetPostMatchSFX(int sfx); void Match_FreezeGame(int freeze_kind); void Match_UnfreezeGame(int freeze_kind); void Match_CreateHUD(int ply); void Match_HideHUD(); void Match_ShowHUD(); void Match_ShowTimer(); void Match_HideTimer(); void Match_CorrectCamera(); void Match_SetNormalCamera(); void Match_SetFreeCamera(int unk, int unk2); void Match_SetZoomCamera(int unk, int unk2); void Match_SetFixedCamera(); void Match_SetDevelopCamera(); void DevCam_AdjustRotate(COBJ *cobj, Vec3 *wobjpos, Vec3 *rotate, float stickX, float stickY); void DevCam_AdjustPan(COBJ *cobj, float stickX, float stickY); void DevCam_AdjustZoom(COBJ *cobj, float stickY); void ScreenFlash_Create(int kind, int unk); void ScreenRumble_Execute(int kind, Vec3 *pos); void Match_StoreGoCallback(GOBJ *gobj, void *cb); void Match_AdjustSoundOnPause(int is_pause); Vec3 *Match_GetPlayerHUDPos(int ply); COBJ *Match_GetCObj(); #endif ================================================ FILE: MexTK/include/math.h ================================================ #ifndef MEX_H_MATH #define MEX_H_MATH #include "structs.h" #include "datatypes.h" #define M_PI 3.14159265358979323846 #define M_1DEGREE 0.0174533 /*** Functions ***/ float atan(float in); float atan2(float y, float x); float sin(float x); float cos(float x); void MTXLookAt(Mtx *dest, Vec3 *eye, Vec3 *up, Vec3 *target); void VECNormalize(Vec3 *src, Vec3 *dest); void VECAdd(Vec3 *a, Vec3 *b, Vec3 *ab); void VECSubtract(Vec3 *a, Vec3 *b, Vec3 *a_b); void VECMultAndAdd(Vec3 *a, Vec3 *b); float VECDotProduct(Vec3 *a, Vec3 *b); void VECCrossProduct(Vec3 *a, Vec3 *b, Vec3 *axb); void MTXQuat(Vec4 *dest, Mtx *m); void HSD_MtxGetRotation(Mtx *m, Vec3 *dest); void MatToQuat(Mtx *m, Vec3 *dest); float sqrtf(float num); void MTXRotRad(Mtx m, char axis, f32 rad); #endif ================================================ FILE: MexTK/include/memcard.h ================================================ #ifndef MEX_H_MEMCARD #define MEX_H_MEMCARD #include "structs.h" #include "datatypes.h" #include "css.h" #define MEMCARD_BANNER_SIZE 0x1800 #define MEMCARD_ICON_SIZE 0x400 /*** Memcard Library ***/ void Memcard_InitWorkArea(); void Memcard_LoadAssets(int unk); Rules1 *Memcard_GetRules1(); void Memcard_InitSnapshotList(void *snap_data, void *snap_list); void Memcard_UpdateSnapshotList(int slot); void Memcard_CreateSnapshot(int slot, char *save_id, MemcardSave *memcard_save, MemcardUnk *memcard_unk, char *file_name, _HSD_ImageDesc *banner, _HSD_ImageDesc *icon, int unk); void Memcard_DeleteSnapshot(int slot, int index); void Memcard_LoadSnapshot(int slot, char *save_id, MemcardSave *memcard_save, char *file_name, _HSD_ImageDesc *banner, _HSD_ImageDesc *icon, int unk); int Memcard_CheckStatus(); // returns 11 when operation in effect void Memcard_RemovedCallback(); void Memcard_Deobfuscate(void *data, int size); /*** Structs ***/ struct Memcard { int unk0; //0x0 int unk1; //0x4 int unk2; //0x8 int unk3; //0xC int unk4; //0x10 int unk5; //0x14 int unk6; //0x18 int unk7; //0x1C int unk8; //0x20 int unk9; //0x24 int unk10; //0x28 int unk11; //0x2C int unk12; //0x30 int unk13; //0x34 int unk14; //0x38 int unk15; //0x3C int unk16; //0x40 int unk17; //0x44 int unk18; //0x48 int unk19; //0x4C int unk20; //0x50 int unk21; //0x54 int unk22; //0x58 int unk23; //0x5C int unk24; //0x60 int unk25; //0x64 int unk26; //0x68 int unk27; //0x6C int unk28; //0x70 int unk29; //0x74 int unk30; //0x78 int unk31; //0x7C int unk32; //0x80 int unk33; //0x84 int unk34; //0x88 int unk35; //0x8C int unk36; //0x90 int unk37; //0x94 int unk38; //0x98 int unk39; //0x9C int unk40; //0xA0 int unk41; //0xA4 int unk42; //0xA8 int unk43; //0xAC int unk44; //0xB0 int unk45; //0xB4 int unk46; //0xB8 int unk47; //0xBC int unk48; //0xC0 int unk49; //0xC4 int unk50; //0xC8 int unk51; //0xCC int unk52; //0xD0 int unk53; //0xD4 int unk54; //0xD8 int unk55; //0xDC int unk56; //0xE0 int unk57; //0xE4 int unk58; //0xE8 int unk59; //0xEC int unk60; //0xF0 int unk61; //0xF4 int unk62; //0xF8 int unk63; //0xFC int unk64; //0x100 int unk65; //0x104 int unk66; //0x108 int unk67; //0x10C int unk68; //0x110 int unk69; //0x114 int unk70; //0x118 int unk71; //0x11C int unk72; //0x120 int unk73; //0x124 int unk74; //0x128 int unk75; //0x12C int unk76; //0x130 int unk77; //0x134 int unk78; //0x138 int unk79; //0x13C int unk80; //0x140 int unk81; //0x144 int unk82; //0x148 int unk83; //0x14C int unk84; //0x150 int unk85; //0x154 int unk86; //0x158 int unk87; //0x15C int unk88; //0x160 int unk89; //0x164 int unk90; //0x168 int unk91; //0x16C int unk92; //0x170 int unk93; //0x174 int unk94; //0x178 int unk95; //0x17C int unk96; //0x180 int unk97; //0x184 int unk98; //0x188 int unk99; //0x18C int unk100; //0x190 int unk101; //0x194 int unk102; //0x198 int unk103; //0x19C int unk104; //0x1A0 int unk105; //0x1A4 int unk106; //0x1A8 int unk107; //0x1AC int unk108; //0x1B0 int unk109; //0x1B4 int unk110; //0x1B8 int unk111; //0x1BC int unk112; //0x1C0 int unk113; //0x1C4 int unk114; //0x1C8 int unk115; //0x1CC int unk116; //0x1D0 int unk117; //0x1D4 int unk118; //0x1D8 int unk119; //0x1DC int unk120; //0x1E0 int unk121; //0x1E4 int unk122; //0x1E8 int unk123; //0x1EC int unk124; //0x1F0 int unk125; //0x1F4 int unk126; //0x1F8 int unk127; //0x1FC int unk128; //0x200 int unk129; //0x204 int unk130; //0x208 int unk131; //0x20C int unk132; //0x210 int unk133; //0x214 int unk134; //0x218 int unk135; //0x21C int unk136; //0x220 int unk137; //0x224 int unk138; //0x228 int unk139; //0x22C int unk140; //0x230 int unk141; //0x234 int unk142; //0x238 int unk143; //0x23C int unk144; //0x240 int unk145; //0x244 int unk146; //0x248 int unk147; //0x24C int unk148; //0x250 int unk149; //0x254 int unk150; //0x258 int unk151; //0x25C int unk152; //0x260 int unk153; //0x264 int unk154; //0x268 int unk155; //0x26C int unk156; //0x270 int unk157; //0x274 int unk158; //0x278 int unk159; //0x27C int unk160; //0x280 int unk161; //0x284 int unk162; //0x288 int unk163; //0x28C int unk164; //0x290 int unk165; //0x294 int unk166; //0x298 int unk167; //0x29C int unk168; //0x2A0 int unk169; //0x2A4 int unk170; //0x2A8 int unk171; //0x2AC int unk172; //0x2B0 int unk173; //0x2B4 int unk174; //0x2B8 int unk175; //0x2BC int unk176; //0x2C0 int unk177; //0x2C4 int unk178; //0x2C8 int unk179; //0x2CC int unk180; //0x2D0 int unk181; //0x2D4 int unk182; //0x2D8 int unk183; //0x2DC int unk184; //0x2E0 int unk185; //0x2E4 int unk186; //0x2E8 int unk187; //0x2EC int unk188; //0x2F0 int unk189; //0x2F4 int unk190; //0x2F8 int unk191; //0x2FC int unk192; //0x300 int unk193; //0x304 int unk194; //0x308 int unk195; //0x30C int unk196; //0x310 int unk197; //0x314 int unk198; //0x318 int unk199; //0x31C int unk200; //0x320 int unk201; //0x324 int unk202; //0x328 int unk203; //0x32C int unk204; //0x330 int unk205; //0x334 int unk206; //0x338 int unk207; //0x33C int unk208; //0x340 int unk209; //0x344 int unk210; //0x348 int unk211; //0x34C int unk212; //0x350 int unk213; //0x354 int unk214; //0x358 int unk215; //0x35C int unk216; //0x360 int unk217; //0x364 int unk218; //0x368 int unk219; //0x36C int unk220; //0x370 int unk221; //0x374 int unk222; //0x378 int unk223; //0x37C int unk224; //0x380 int unk225; //0x384 int unk226; //0x388 int unk227; //0x38C int unk228; //0x390 int unk229; //0x394 int unk230; //0x398 int unk231; //0x39C int unk232; //0x3A0 int unk233; //0x3A4 int unk234; //0x3A8 int unk235; //0x3AC int unk236; //0x3B0 int unk237; //0x3B4 int unk238; //0x3B8 int unk239; //0x3BC int unk240; //0x3C0 int unk241; //0x3C4 int unk242; //0x3C8 int unk243; //0x3CC int unk244; //0x3D0 int unk245; //0x3D4 int unk246; //0x3D8 int unk247; //0x3DC int unk248; //0x3E0 int unk249; //0x3E4 int unk250; //0x3E8 int unk251; //0x3EC int unk252; //0x3F0 int unk253; //0x3F4 int unk254; //0x3F8 int unk255; //0x3FC int unk256; //0x400 int unk257; //0x404 int unk258; //0x408 int unk259; //0x40C int unk260; //0x410 int unk261; //0x414 int unk262; //0x418 int unk263; //0x41C int unk264; //0x420 int unk265; //0x424 int unk266; //0x428 int unk267; //0x42C int unk268; //0x430 int unk269; //0x434 int unk270; //0x438 int unk271; //0x43C int unk272; //0x440 int unk273; //0x444 int unk274; //0x448 int unk275; //0x44C int unk276; //0x450 int unk277; //0x454 int unk278; //0x458 int unk279; //0x45C int unk280; //0x460 int unk281; //0x464 int unk282; //0x468 int unk283; //0x46C int unk284; //0x470 int unk285; //0x474 int unk286; //0x478 int unk287; //0x47C int unk288; //0x480 int unk289; //0x484 int unk290; //0x488 int unk291; //0x48C int unk292; //0x490 int unk293; //0x494 int unk294; //0x498 int unk295; //0x49C int unk296; //0x4A0 int unk297; //0x4A4 int unk298; //0x4A8 int unk299; //0x4AC int unk300; //0x4B0 int unk301; //0x4B4 int unk302; //0x4B8 int unk303; //0x4BC int unk304; //0x4C0 int unk305; //0x4C4 int unk306; //0x4C8 int unk307; //0x4CC int unk308; //0x4D0 int unk309; //0x4D4 int unk310; //0x4D8 int unk311; //0x4DC int unk312; //0x4E0 int unk313; //0x4E4 int unk314; //0x4E8 int unk315; //0x4EC int unk316; //0x4F0 int unk317; //0x4F4 int unk318; //0x4F8 int unk319; //0x4FC int unk320; //0x500 int unk321; //0x504 int unk322; //0x508 int unk323; //0x50C int unk324; //0x510 int unk325; //0x514 int unk326; //0x518 int unk327; //0x51C int unk328; //0x520 int unk329; //0x524 int unk330; //0x528 int unk331; //0x52C CSSBackup EventBackup; //0x530 int unk335; //0x53C int unk336; //0x540 int unk337; //0x544 int unk338; //0x548 int unk339; //0x54C int unk340; //0x550 int unk341; //0x554 int unk342; //0x558 int unk343; //0x55C int unk344; //0x560 int unk345; //0x564 int unk346; //0x568 int unk347; //0x56C int unk348; //0x570 int unk349; //0x574 int unk350; //0x578 int unk351; //0x57C int unk352; //0x580 int unk353; //0x584 int unk354; //0x588 int unk355; //0x58C int unk356; //0x590 int unk357; //0x594 int unk358; //0x598 int unk359; //0x59C int unk360; //0x5A0 int unk361; //0x5A4 int unk362; //0x5A8 int unk363; //0x5AC int unk364; //0x5B0 int unk365; //0x5B4 int unk366; //0x5B8 int unk367; //0x5BC int unk368; //0x5C0 int unk369; //0x5C4 int unk370; //0x5C8 int unk371; //0x5CC int unk372; //0x5D0 int unk373; //0x5D4 int unk374; //0x5D8 int unk375; //0x5DC int unk376; //0x5E0 int unk377; //0x5E4 int unk378; //0x5E8 int unk379; //0x5EC int unk380; //0x5F0 int unk381; //0x5F4 int unk382; //0x5F8 int unk383; //0x5FC int unk384; //0x600 int unk385; //0x604 int unk386; //0x608 int unk387; //0x60C int unk388; //0x610 int unk389; //0x614 int unk390; //0x618 int unk391; //0x61C int unk392; //0x620 int unk393; //0x624 int unk394; //0x628 int unk395; //0x62C int unk396; //0x630 int unk397; //0x634 int unk398; //0x638 int unk399; //0x63C int unk400; //0x640 int unk401; //0x644 int unk402; //0x648 int unk403; //0x64C int unk404; //0x650 int unk405; //0x654 int unk406; //0x658 int unk407; //0x65C int unk408; //0x660 int unk409; //0x664 int unk410; //0x668 int unk411; //0x66C int unk412; //0x670 int unk413; //0x674 int unk414; //0x678 int unk415; //0x67C int unk416; //0x680 int unk417; //0x684 int unk418; //0x688 int unk419; //0x68C int unk420; //0x690 int unk421; //0x694 int unk422; //0x698 int unk423; //0x69C int unk424; //0x6A0 int unk425; //0x6A4 int unk426; //0x6A8 int unk427; //0x6AC int unk428; //0x6B0 int unk429; //0x6B4 int unk430; //0x6B8 int unk431; //0x6BC int unk432; //0x6C0 int unk433; //0x6C4 int unk434; //0x6C8 int unk435; //0x6CC int unk436; //0x6D0 int unk437; //0x6D4 int unk438; //0x6D8 int unk439; //0x6DC int unk440; //0x6E0 int unk441; //0x6E4 int unk442; //0x6E8 int unk443; //0x6EC int unk444; //0x6F0 int unk445; //0x6F4 int unk446; //0x6F8 int unk447; //0x6FC int unk448; //0x700 int unk449; //0x704 int unk450; //0x708 int unk451; //0x70C int unk452; //0x710 int unk453; //0x714 int unk454; //0x718 int unk455; //0x71C int unk456; //0x720 int unk457; //0x724 int unk458; //0x728 int unk459; //0x72C int unk460; //0x730 int unk461; //0x734 int unk462; //0x738 int unk463; //0x73C int unk464; //0x740 int unk465; //0x744 int unk466; //0x748 int unk467; //0x74C int unk468; //0x750 int unk469; //0x754 int unk470; //0x758 int unk471; //0x75C int unk472; //0x760 int unk473; //0x764 int unk474; //0x768 int unk475; //0x76C int unk476; //0x770 int unk477; //0x774 int unk478; //0x778 int unk479; //0x77C int unk480; //0x780 int unk481; //0x784 int unk482; //0x788 int unk483; //0x78C int unk484; //0x790 int unk485; //0x794 int unk486; //0x798 int unk487; //0x79C int unk488; //0x7A0 int unk489; //0x7A4 int unk490; //0x7A8 int unk491; //0x7AC int unk492; //0x7B0 int unk493; //0x7B4 int unk494; //0x7B8 int unk495; //0x7BC int unk496; //0x7C0 int unk497; //0x7C4 int unk498; //0x7C8 int unk499; //0x7CC int unk500; //0x7D0 int unk501; //0x7D4 int unk502; //0x7D8 int unk503; //0x7DC int unk504; //0x7E0 int unk505; //0x7E4 int unk506; //0x7E8 int unk507; //0x7EC int unk508; //0x7F0 int unk509; //0x7F4 int unk510; //0x7F8 int unk511; //0x7FC int unk512; //0x800 int unk513; //0x804 int unk514; //0x808 int unk515; //0x80C int unk516; //0x810 int unk517; //0x814 int unk518; //0x818 int unk519; //0x81C int unk520; //0x820 int unk521; //0x824 int unk522; //0x828 int unk523; //0x82C int unk524; //0x830 int unk525; //0x834 int unk526; //0x838 int unk527; //0x83C int unk528; //0x840 int unk529; //0x844 int unk530; //0x848 int unk531; //0x84C int unk532; //0x850 int unk533; //0x854 int unk534; //0x858 int unk535; //0x85C int unk536; //0x860 int unk537; //0x864 int unk538; //0x868 int unk539; //0x86C int unk540; //0x870 int unk541; //0x874 int unk542; //0x878 int unk543; //0x87C int unk544; //0x880 int unk545; //0x884 int unk546; //0x888 int unk547; //0x88C int unk548; //0x890 int unk549; //0x894 int unk550; //0x898 int unk551; //0x89C int unk552; //0x8A0 int unk553; //0x8A4 int unk554; //0x8A8 int unk555; //0x8AC int unk556; //0x8B0 int unk557; //0x8B4 int unk558; //0x8B8 int unk559; //0x8BC int unk560; //0x8C0 int unk561; //0x8C4 int unk562; //0x8C8 int unk563; //0x8CC int unk564; //0x8D0 int unk565; //0x8D4 int unk566; //0x8D8 int unk567; //0x8DC int unk568; //0x8E0 int unk569; //0x8E4 int unk570; //0x8E8 int unk571; //0x8EC int unk572; //0x8F0 int unk573; //0x8F4 int unk574; //0x8F8 int unk575; //0x8FC int unk576; //0x900 int unk577; //0x904 int unk578; //0x908 int unk579; //0x90C int unk580; //0x910 int unk581; //0x914 int unk582; //0x918 int unk583; //0x91C int unk584; //0x920 int unk585; //0x924 int unk586; //0x928 int unk587; //0x92C int unk588; //0x930 int unk589; //0x934 int unk590; //0x938 int unk591; //0x93C int unk592; //0x940 int unk593; //0x944 int unk594; //0x948 int unk595; //0x94C int unk596; //0x950 int unk597; //0x954 int unk598; //0x958 int unk599; //0x95C int unk600; //0x960 int unk601; //0x964 int unk602; //0x968 int unk603; //0x96C int unk604; //0x970 int unk605; //0x974 int unk606; //0x978 int unk607; //0x97C int unk608; //0x980 int unk609; //0x984 int unk610; //0x988 int unk611; //0x98C int unk612; //0x990 int unk613; //0x994 int unk614; //0x998 int unk615; //0x99C int unk616; //0x9A0 int unk617; //0x9A4 int unk618; //0x9A8 int unk619; //0x9AC int unk620; //0x9B0 int unk621; //0x9B4 int unk622; //0x9B8 int unk623; //0x9BC int unk624; //0x9C0 int unk625; //0x9C4 int unk626; //0x9C8 int unk627; //0x9CC int unk628; //0x9D0 int unk629; //0x9D4 int unk630; //0x9D8 int unk631; //0x9DC int unk632; //0x9E0 int unk633; //0x9E4 int unk634; //0x9E8 int unk635; //0x9EC int unk636; //0x9F0 int unk637; //0x9F4 int unk638; //0x9F8 int unk639; //0x9FC int unk640; //0xA00 int unk641; //0xA04 int unk642; //0xA08 int unk643; //0xA0C int unk644; //0xA10 int unk645; //0xA14 int unk646; //0xA18 int unk647; //0xA1C int unk648; //0xA20 int unk649; //0xA24 int unk650; //0xA28 int unk651; //0xA2C int unk652; //0xA30 int unk653; //0xA34 int unk654; //0xA38 int unk655; //0xA3C int unk656; //0xA40 int unk657; //0xA44 int unk658; //0xA48 int unk659; //0xA4C int unk660; //0xA50 int unk661; //0xA54 int unk662; //0xA58 int unk663; //0xA5C int unk664; //0xA60 int unk665; //0xA64 int unk666; //0xA68 int unk667; //0xA6C int unk668; //0xA70 int unk669; //0xA74 int unk670; //0xA78 int unk671; //0xA7C int unk672; //0xA80 int unk673; //0xA84 int unk674; //0xA88 int unk675; //0xA8C int unk676; //0xA90 int unk677; //0xA94 int unk678; //0xA98 int unk679; //0xA9C int unk680; //0xAA0 int unk681; //0xAA4 int unk682; //0xAA8 int unk683; //0xAAC int unk684; //0xAB0 int unk685; //0xAB4 int unk686; //0xAB8 int unk687; //0xABC int unk688; //0xAC0 int unk689; //0xAC4 int unk690; //0xAC8 int unk691; //0xACC int unk692; //0xAD0 int unk693; //0xAD4 int unk694; //0xAD8 int unk695; //0xADC int unk696; //0xAE0 int unk697; //0xAE4 int unk698; //0xAE8 int unk699; //0xAEC int unk700; //0xAF0 int unk701; //0xAF4 int unk702; //0xAF8 int unk703; //0xAFC int unk704; //0xB00 int unk705; //0xB04 int unk706; //0xB08 int unk707; //0xB0C int unk708; //0xB10 int unk709; //0xB14 int unk710; //0xB18 int unk711; //0xB1C int unk712; //0xB20 int unk713; //0xB24 int unk714; //0xB28 int unk715; //0xB2C int unk716; //0xB30 int unk717; //0xB34 int unk718; //0xB38 int unk719; //0xB3C int unk720; //0xB40 int unk721; //0xB44 int unk722; //0xB48 int unk723; //0xB4C int unk724; //0xB50 int unk725; //0xB54 int unk726; //0xB58 int unk727; //0xB5C int unk728; //0xB60 int unk729; //0xB64 int unk730; //0xB68 int unk731; //0xB6C int unk732; //0xB70 int unk733; //0xB74 int unk734; //0xB78 int unk735; //0xB7C int unk736; //0xB80 int unk737; //0xB84 int unk738; //0xB88 int unk739; //0xB8C int unk740; //0xB90 int unk741; //0xB94 int unk742; //0xB98 int unk743; //0xB9C int unk744; //0xBA0 int unk745; //0xBA4 int unk746; //0xBA8 int unk747; //0xBAC int unk748; //0xBB0 int unk749; //0xBB4 int unk750; //0xBB8 int unk751; //0xBBC int unk752; //0xBC0 int unk753; //0xBC4 int unk754; //0xBC8 int unk755; //0xBCC int unk756; //0xBD0 int unk757; //0xBD4 int unk758; //0xBD8 int unk759; //0xBDC int unk760; //0xBE0 int unk761; //0xBE4 int unk762; //0xBE8 int unk763; //0xBEC int unk764; //0xBF0 int unk765; //0xBF4 int unk766; //0xBF8 int unk767; //0xBFC int unk768; //0xC00 int unk769; //0xC04 int unk770; //0xC08 int unk771; //0xC0C int unk772; //0xC10 int unk773; //0xC14 int unk774; //0xC18 int unk775; //0xC1C int unk776; //0xC20 int unk777; //0xC24 int unk778; //0xC28 int unk779; //0xC2C int unk780; //0xC30 int unk781; //0xC34 int unk782; //0xC38 int unk783; //0xC3C int unk784; //0xC40 int unk785; //0xC44 int unk786; //0xC48 int unk787; //0xC4C int unk788; //0xC50 int unk789; //0xC54 int unk790; //0xC58 int unk791; //0xC5C int unk792; //0xC60 int unk793; //0xC64 int unk794; //0xC68 int unk795; //0xC6C int unk796; //0xC70 int unk797; //0xC74 int unk798; //0xC78 int unk799; //0xC7C int unk800; //0xC80 int unk801; //0xC84 int unk802; //0xC88 int unk803; //0xC8C int unk804; //0xC90 int unk805; //0xC94 int unk806; //0xC98 int unk807; //0xC9C int unk808; //0xCA0 int unk809; //0xCA4 int unk810; //0xCA8 int unk811; //0xCAC int unk812; //0xCB0 int unk813; //0xCB4 int unk814; //0xCB8 int unk815; //0xCBC int unk816; //0xCC0 int unk817; //0xCC4 int unk818; //0xCC8 int unk819; //0xCCC int unk820; //0xCD0 int unk821; //0xCD4 int unk822; //0xCD8 int unk823; //0xCDC int unk824; //0xCE0 int unk825; //0xCE4 int unk826; //0xCE8 int unk827; //0xCEC int unk828; //0xCF0 int unk829; //0xCF4 int unk830; //0xCF8 int unk831; //0xCFC int unk832; //0xD00 int unk833; //0xD04 int unk834; //0xD08 int unk835; //0xD0C int unk836; //0xD10 int unk837; //0xD14 int unk838; //0xD18 int unk839; //0xD1C int unk840; //0xD20 int unk841; //0xD24 int unk842; //0xD28 int unk843; //0xD2C int unk844; //0xD30 int unk845; //0xD34 int unk846; //0xD38 int unk847; //0xD3C int unk848; //0xD40 int unk849; //0xD44 int unk850; //0xD48 int unk851; //0xD4C int unk852; //0xD50 int unk853; //0xD54 int unk854; //0xD58 int unk855; //0xD5C int unk856; //0xD60 int unk857; //0xD64 int unk858; //0xD68 int unk859; //0xD6C int unk860; //0xD70 int unk861; //0xD74 int unk862; //0xD78 int unk863; //0xD7C int unk864; //0xD80 int unk865; //0xD84 int unk866; //0xD88 int unk867; //0xD8C int unk868; //0xD90 int unk869; //0xD94 int unk870; //0xD98 int unk871; //0xD9C int unk872; //0xDA0 int unk873; //0xDA4 int unk874; //0xDA8 int unk875; //0xDAC int unk876; //0xDB0 int unk877; //0xDB4 int unk878; //0xDB8 int unk879; //0xDBC int unk880; //0xDC0 int unk881; //0xDC4 int unk882; //0xDC8 int unk883; //0xDCC int unk884; //0xDD0 int unk885; //0xDD4 int unk886; //0xDD8 int unk887; //0xDDC int unk888; //0xDE0 int unk889; //0xDE4 int unk890; //0xDE8 int unk891; //0xDEC int unk892; //0xDF0 int unk893; //0xDF4 int unk894; //0xDF8 int unk895; //0xDFC int unk896; //0xE00 int unk897; //0xE04 int unk898; //0xE08 int unk899; //0xE0C int unk900; //0xE10 int unk901; //0xE14 int unk902; //0xE18 int unk903; //0xE1C int unk904; //0xE20 int unk905; //0xE24 int unk906; //0xE28 int unk907; //0xE2C int unk908; //0xE30 int unk909; //0xE34 int unk910; //0xE38 int unk911; //0xE3C int unk912; //0xE40 int unk913; //0xE44 int unk914; //0xE48 int unk915; //0xE4C int unk916; //0xE50 int unk917; //0xE54 int unk918; //0xE58 int unk919; //0xE5C int unk920; //0xE60 int unk921; //0xE64 int unk922; //0xE68 int unk923; //0xE6C int unk924; //0xE70 int unk925; //0xE74 int unk926; //0xE78 int unk927; //0xE7C int unk928; //0xE80 int unk929; //0xE84 int unk930; //0xE88 int unk931; //0xE8C int unk932; //0xE90 int unk933; //0xE94 int unk934; //0xE98 int unk935; //0xE9C int unk936; //0xEA0 int unk937; //0xEA4 int unk938; //0xEA8 int unk939; //0xEAC int unk940; //0xEB0 int unk941; //0xEB4 int unk942; //0xEB8 int unk943; //0xEBC int unk944; //0xEC0 int unk945; //0xEC4 int unk946; //0xEC8 int unk947; //0xECC int unk948; //0xED0 int unk949; //0xED4 int unk950; //0xED8 int unk951; //0xEDC int unk952; //0xEE0 int unk953; //0xEE4 int unk954; //0xEE8 int unk955; //0xEEC int unk956; //0xEF0 int unk957; //0xEF4 int unk958; //0xEF8 int unk959; //0xEFC int unk960; //0xF00 int unk961; //0xF04 int unk962; //0xF08 int unk963; //0xF0C int unk964; //0xF10 int unk965; //0xF14 int unk966; //0xF18 int unk967; //0xF1C int unk968; //0xF20 int unk969; //0xF24 int unk970; //0xF28 int unk971; //0xF2C int unk972; //0xF30 int unk973; //0xF34 int unk974; //0xF38 int unk975; //0xF3C int unk976; //0xF40 int unk977; //0xF44 int unk978; //0xF48 int unk979; //0xF4C int unk980; //0xF50 int unk981; //0xF54 int unk982; //0xF58 int unk983; //0xF5C int unk984; //0xF60 int unk985; //0xF64 int unk986; //0xF68 int unk987; //0xF6C int unk988; //0xF70 int unk989; //0xF74 int unk990; //0xF78 int unk991; //0xF7C int unk992; //0xF80 int unk993; //0xF84 int unk994; //0xF88 int unk995; //0xF8C int unk996; //0xF90 int unk997; //0xF94 int unk998; //0xF98 int unk999; //0xF9C int unk1000; //0xFA0 int unk1001; //0xFA4 int unk1002; //0xFA8 int unk1003; //0xFAC int unk1004; //0xFB0 int unk1005; //0xFB4 int unk1006; //0xFB8 int unk1007; //0xFBC int unk1008; //0xFC0 int unk1009; //0xFC4 int unk1010; //0xFC8 int unk1011; //0xFCC int unk1012; //0xFD0 int unk1013; //0xFD4 int unk1014; //0xFD8 int unk1015; //0xFDC int unk1016; //0xFE0 int unk1017; //0xFE4 int unk1018; //0xFE8 int unk1019; //0xFEC int unk1020; //0xFF0 int unk1021; //0xFF4 int unk1022; //0xFF8 int unk1023; //0xFFC int unk1024; //0x1000 int unk1025; //0x1004 int unk1026; //0x1008 int unk1027; //0x100C int unk1028; //0x1010 int unk1029; //0x1014 int unk1030; //0x1018 int unk1031; //0x101C int unk1032; //0x1020 int unk1033; //0x1024 int unk1034; //0x1028 int unk1035; //0x102C int unk1036; //0x1030 int unk1037; //0x1034 int unk1038; //0x1038 int unk1039; //0x103C int unk1040; //0x1040 int unk1041; //0x1044 int unk1042; //0x1048 int unk1043; //0x104C int unk1044; //0x1050 int unk1045; //0x1054 int unk1046; //0x1058 int unk1047; //0x105C int unk1048; //0x1060 int unk1049; //0x1064 int unk1050; //0x1068 int unk1051; //0x106C int unk1052; //0x1070 int unk1053; //0x1074 int unk1054; //0x1078 int unk1055; //0x107C int unk1056; //0x1080 int unk1057; //0x1084 int unk1058; //0x1088 int unk1059; //0x108C int unk1060; //0x1090 int unk1061; //0x1094 int unk1062; //0x1098 int unk1063; //0x109C int unk1064; //0x10A0 int unk1065; //0x10A4 int unk1066; //0x10A8 int unk1067; //0x10AC int unk1068; //0x10B0 int unk1069; //0x10B4 int unk1070; //0x10B8 int unk1071; //0x10BC int unk1072; //0x10C0 int unk1073; //0x10C4 int unk1074; //0x10C8 int unk1075; //0x10CC int unk1076; //0x10D0 int unk1077; //0x10D4 int unk1078; //0x10D8 int unk1079; //0x10DC int unk1080; //0x10E0 int unk1081; //0x10E4 int unk1082; //0x10E8 int unk1083; //0x10EC int unk1084; //0x10F0 int unk1085; //0x10F4 int unk1086; //0x10F8 int unk1087; //0x10FC int unk1088; //0x1100 int unk1089; //0x1104 int unk1090; //0x1108 int unk1091; //0x110C int unk1092; //0x1110 int unk1093; //0x1114 int unk1094; //0x1118 int unk1095; //0x111C int unk1096; //0x1120 int unk1097; //0x1124 int unk1098; //0x1128 int unk1099; //0x112C int unk1100; //0x1130 int unk1101; //0x1134 int unk1102; //0x1138 int unk1103; //0x113C int unk1104; //0x1140 int unk1105; //0x1144 int unk1106; //0x1148 int unk1107; //0x114C int unk1108; //0x1150 int unk1109; //0x1154 int unk1110; //0x1158 int unk1111; //0x115C int unk1112; //0x1160 int unk1113; //0x1164 int unk1114; //0x1168 int unk1115; //0x116C int unk1116; //0x1170 int unk1117; //0x1174 int unk1118; //0x1178 int unk1119; //0x117C int unk1120; //0x1180 int unk1121; //0x1184 int unk1122; //0x1188 int unk1123; //0x118C int unk1124; //0x1190 int unk1125; //0x1194 int unk1126; //0x1198 int unk1127; //0x119C int unk1128; //0x11A0 int unk1129; //0x11A4 int unk1130; //0x11A8 int unk1131; //0x11AC int unk1132; //0x11B0 int unk1133; //0x11B4 int unk1134; //0x11B8 int unk1135; //0x11BC int unk1136; //0x11C0 int unk1137; //0x11C4 int unk1138; //0x11C8 int unk1139; //0x11CC int unk1140; //0x11D0 int unk1141; //0x11D4 int unk1142; //0x11D8 int unk1143; //0x11DC int unk1144; //0x11E0 int unk1145; //0x11E4 int unk1146; //0x11E8 int unk1147; //0x11EC int unk1148; //0x11F0 int unk1149; //0x11F4 int unk1150; //0x11F8 int unk1151; //0x11FC int unk1152; //0x1200 int unk1153; //0x1204 int unk1154; //0x1208 int unk1155; //0x120C int unk1156; //0x1210 int unk1157; //0x1214 int unk1158; //0x1218 int unk1159; //0x121C int unk1160; //0x1220 int unk1161; //0x1224 int unk1162; //0x1228 int unk1163; //0x122C int unk1164; //0x1230 int unk1165; //0x1234 int unk1166; //0x1238 int unk1167; //0x123C int unk1168; //0x1240 int unk1169; //0x1244 int unk1170; //0x1248 int unk1171; //0x124C int unk1172; //0x1250 int unk1173; //0x1254 int unk1174; //0x1258 int unk1175; //0x125C int unk1176; //0x1260 int unk1177; //0x1264 int unk1178; //0x1268 int unk1179; //0x126C int unk1180; //0x1270 int unk1181; //0x1274 int unk1182; //0x1278 int unk1183; //0x127C int unk1184; //0x1280 int unk1185; //0x1284 int unk1186; //0x1288 int unk1187; //0x128C int unk1188; //0x1290 int unk1189; //0x1294 int unk1190; //0x1298 int unk1191; //0x129C int unk1192; //0x12A0 int unk1193; //0x12A4 int unk1194; //0x12A8 int unk1195; //0x12AC int unk1196; //0x12B0 int unk1197; //0x12B4 int unk1198; //0x12B8 int unk1199; //0x12BC int unk1200; //0x12C0 int unk1201; //0x12C4 int unk1202; //0x12C8 int unk1203; //0x12CC int unk1204; //0x12D0 int unk1205; //0x12D4 int unk1206; //0x12D8 int unk1207; //0x12DC int unk1208; //0x12E0 int unk1209; //0x12E4 int unk1210; //0x12E8 int unk1211; //0x12EC int unk1212; //0x12F0 int unk1213; //0x12F4 int unk1214; //0x12F8 int unk1215; //0x12FC int unk1216; //0x1300 int unk1217; //0x1304 int unk1218; //0x1308 int unk1219; //0x130C int unk1220; //0x1310 int unk1221; //0x1314 int unk1222; //0x1318 int unk1223; //0x131C int unk1224; //0x1320 int unk1225; //0x1324 int unk1226; //0x1328 int unk1227; //0x132C int unk1228; //0x1330 int unk1229; //0x1334 int unk1230; //0x1338 int unk1231; //0x133C int unk1232; //0x1340 int unk1233; //0x1344 int unk1234; //0x1348 int unk1235; //0x134C int unk1236; //0x1350 int unk1237; //0x1354 int unk1238; //0x1358 int unk1239; //0x135C int unk1240; //0x1360 int unk1241; //0x1364 int unk1242; //0x1368 int unk1243; //0x136C int unk1244; //0x1370 int unk1245; //0x1374 int unk1246; //0x1378 int unk1247; //0x137C int unk1248; //0x1380 int unk1249; //0x1384 int unk1250; //0x1388 int unk1251; //0x138C int unk1252; //0x1390 int unk1253; //0x1394 int unk1254; //0x1398 int unk1255; //0x139C int unk1256; //0x13A0 int unk1257; //0x13A4 int unk1258; //0x13A8 int unk1259; //0x13AC int unk1260; //0x13B0 int unk1261; //0x13B4 int unk1262; //0x13B8 int unk1263; //0x13BC int unk1264; //0x13C0 int unk1265; //0x13C4 int unk1266; //0x13C8 int unk1267; //0x13CC int unk1268; //0x13D0 int unk1269; //0x13D4 int unk1270; //0x13D8 int unk1271; //0x13DC int unk1272; //0x13E0 int unk1273; //0x13E4 int unk1274; //0x13E8 int unk1275; //0x13EC int unk1276; //0x13F0 int unk1277; //0x13F4 int unk1278; //0x13F8 int unk1279; //0x13FC int unk1280; //0x1400 int unk1281; //0x1404 int unk1282; //0x1408 int unk1283; //0x140C int unk1284; //0x1410 int unk1285; //0x1414 int unk1286; //0x1418 int unk1287; //0x141C int unk1288; //0x1420 int unk1289; //0x1424 int unk1290; //0x1428 int unk1291; //0x142C int unk1292; //0x1430 int unk1293; //0x1434 int unk1294; //0x1438 int unk1295; //0x143C int unk1296; //0x1440 int unk1297; //0x1444 int unk1298; //0x1448 int unk1299; //0x144C int unk1300; //0x1450 int unk1301; //0x1454 int unk1302; //0x1458 int unk1303; //0x145C int unk1304; //0x1460 int unk1305; //0x1464 int unk1306; //0x1468 int unk1307; //0x146C int unk1308; //0x1470 int unk1309; //0x1474 int unk1310; //0x1478 int unk1311; //0x147C int unk1312; //0x1480 int unk1313; //0x1484 int unk1314; //0x1488 int unk1315; //0x148C int unk1316; //0x1490 int unk1317; //0x1494 int unk1318; //0x1498 int unk1319; //0x149C int unk1320; //0x14A0 int unk1321; //0x14A4 int unk1322; //0x14A8 int unk1323; //0x14AC int unk1324; //0x14B0 int unk1325; //0x14B4 int unk1326; //0x14B8 int unk1327; //0x14BC int unk1328; //0x14C0 int unk1329; //0x14C4 int unk1330; //0x14C8 int unk1331; //0x14CC int unk1332; //0x14D0 int unk1333; //0x14D4 int unk1334; //0x14D8 int unk1335; //0x14DC int unk1336; //0x14E0 int unk1337; //0x14E4 int unk1338; //0x14E8 int unk1339; //0x14EC int unk1340; //0x14F0 int unk1341; //0x14F4 int unk1342; //0x14F8 int unk1343; //0x14FC int unk1344; //0x1500 int unk1345; //0x1504 int unk1346; //0x1508 int unk1347; //0x150C int unk1348; //0x1510 int unk1349; //0x1514 int unk1350; //0x1518 int unk1351; //0x151C int unk1352; //0x1520 int unk1353; //0x1524 int unk1354; //0x1528 int unk1355; //0x152C int unk1356; //0x1530 int unk1357; //0x1534 int unk1358; //0x1538 int unk1359; //0x153C int unk1360; //0x1540 int unk1361; //0x1544 int unk1362; //0x1548 int unk1363; //0x154C int unk1364; //0x1550 int unk1365; //0x1554 int unk1366; //0x1558 int unk1367; //0x155C int unk1368; //0x1560 int unk1369; //0x1564 int unk1370; //0x1568 int unk1371; //0x156C int unk1372; //0x1570 int unk1373; //0x1574 int unk1374; //0x1578 int unk1375; //0x157C int unk1376; //0x1580 int unk1377; //0x1584 int unk1378; //0x1588 int unk1379; //0x158C int unk1380; //0x1590 int unk1381; //0x1594 int unk1382; //0x1598 int unk1383; //0x159C int unk1384; //0x15A0 int unk1385; //0x15A4 int unk1386; //0x15A8 int unk1387; //0x15AC int unk1388; //0x15B0 int unk1389; //0x15B4 int unk1390; //0x15B8 int unk1391; //0x15BC int unk1392; //0x15C0 int unk1393; //0x15C4 int unk1394; //0x15C8 int unk1395; //0x15CC int unk1396; //0x15D0 int unk1397; //0x15D4 int unk1398; //0x15D8 int unk1399; //0x15DC int unk1400; //0x15E0 int unk1401; //0x15E4 int unk1402; //0x15E8 int unk1403; //0x15EC int unk1404; //0x15F0 int unk1405; //0x15F4 int unk1406; //0x15F8 int unk1407; //0x15FC int unk1408; //0x1600 int unk1409; //0x1604 int unk1410; //0x1608 int unk1411; //0x160C int unk1412; //0x1610 int unk1413; //0x1614 int unk1414; //0x1618 int unk1415; //0x161C int unk1416; //0x1620 int unk1417; //0x1624 int unk1418; //0x1628 int unk1419; //0x162C int unk1420; //0x1630 int unk1421; //0x1634 int unk1422; //0x1638 int unk1423; //0x163C int unk1424; //0x1640 int unk1425; //0x1644 int unk1426; //0x1648 int unk1427; //0x164C int unk1428; //0x1650 int unk1429; //0x1654 int unk1430; //0x1658 int unk1431; //0x165C int unk1432; //0x1660 int unk1433; //0x1664 int unk1434; //0x1668 int unk1435; //0x166C int unk1436; //0x1670 int unk1437; //0x1674 int unk1438; //0x1678 int unk1439; //0x167C int unk1440; //0x1680 int unk1441; //0x1684 int unk1442; //0x1688 int unk1443; //0x168C int unk1444; //0x1690 int unk1445; //0x1694 int unk1446; //0x1698 int unk1447; //0x169C int unk1448; //0x16A0 int unk1449; //0x16A4 int unk1450; //0x16A8 int unk1451; //0x16AC int unk1452; //0x16B0 int unk1453; //0x16B4 int unk1454; //0x16B8 int unk1455; //0x16BC int unk1456; //0x16C0 int unk1457; //0x16C4 int unk1458; //0x16C8 int unk1459; //0x16CC int unk1460; //0x16D0 int unk1461; //0x16D4 int unk1462; //0x16D8 int unk1463; //0x16DC int unk1464; //0x16E0 int unk1465; //0x16E4 int unk1466; //0x16E8 int unk1467; //0x16EC int unk1468; //0x16F0 int unk1469; //0x16F4 int unk1470; //0x16F8 int unk1471; //0x16FC int unk1472; //0x1700 int unk1473; //0x1704 int unk1474; //0x1708 int unk1475; //0x170C int unk1476; //0x1710 int unk1477; //0x1714 int unk1478; //0x1718 int unk1479; //0x171C int unk1480; //0x1720 int unk1481; //0x1724 int unk1482; //0x1728 int unk1483; //0x172C int unk1484; //0x1730 int unk1485; //0x1734 int unk1486; //0x1738 int unk1487; //0x173C int unk1488; //0x1740 int unk1489; //0x1744 int unk1490; //0x1748 int unk1491; //0x174C int unk1492; //0x1750 int unk1493; //0x1754 int unk1494; //0x1758 int unk1495; //0x175C int unk1496; //0x1760 int unk1497; //0x1764 int unk1498; //0x1768 int unk1499; //0x176C int unk1500; //0x1770 int unk1501; //0x1774 int unk1502; //0x1778 int unk1503; //0x177C int unk1504; //0x1780 int unk1505; //0x1784 int unk1506; //0x1788 int unk1507; //0x178C int unk1508; //0x1790 int unk1509; //0x1794 int unk1510; //0x1798 int unk1511; //0x179C int unk1512; //0x17A0 int unk1513; //0x17A4 int unk1514; //0x17A8 int unk1515; //0x17AC int unk1516; //0x17B0 int unk1517; //0x17B4 int unk1518; //0x17B8 int unk1519; //0x17BC int unk1520; //0x17C0 int unk1521; //0x17C4 int unk1522; //0x17C8 int unk1523; //0x17CC int unk1524; //0x17D0 int unk1525; //0x17D4 int unk1526; //0x17D8 int unk1527; //0x17DC int unk1528; //0x17E0 int unk1529; //0x17E4 int unk1530; //0x17E8 int unk1531; //0x17EC int unk1532; //0x17F0 int unk1533; //0x17F4 int unk1534; //0x17F8 int unk1535; //0x17FC int unk1536; //0x1800 int unk1537; //0x1804 int unk1538; //0x1808 int unk1539; //0x180C int unk1540; //0x1810 int unk1541; //0x1814 int unk1542; //0x1818 int unk1543; //0x181C int unk1544; //0x1820 int unk1545; //0x1824 int unk1546; //0x1828 int unk1547; //0x182C int unk1548; //0x1830 int unk1549; //0x1834 int unk1550; //0x1838 int unk1551; //0x183C int unk1552; //0x1840 int unk1553; //0x1844 int unk1554; //0x1848 int unk1555; //0x184C int unk1556; //0x1850 int unk1557; //0x1854 int unk1558; //0x1858 int unk1559; //0x185C int unk1560; //0x1860 int unk1561; //0x1864 int unk1562; //0x1868 int unk1563; //0x186C int unk1564; //0x1870 int unk1565; //0x1874 int unk1566; //0x1878 int unk1567; //0x187C int unk1568; //0x1880 int unk1569; //0x1884 int unk1570; //0x1888 int unk1571; //0x188C int unk1572; //0x1890 int unk1573; //0x1894 int unk1574; //0x1898 int unk1575; //0x189C int unk1576; //0x18A0 int unk1577; //0x18A4 int unk1578; //0x18A8 int unk1579; //0x18AC int unk1580; //0x18B0 int unk1581; //0x18B4 int unk1582; //0x18B8 int unk1583; //0x18BC int unk1584; //0x18C0 int unk1585; //0x18C4 int unk1586; //0x18C8 int unk1587; //0x18CC int unk1588; //0x18D0 int unk1589; //0x18D4 int unk1590; //0x18D8 int unk1591; //0x18DC int unk1592; //0x18E0 int unk1593; //0x18E4 int unk1594; //0x18E8 int unk1595; //0x18EC int unk1596; //0x18F0 int unk1597; //0x18F4 int unk1598; //0x18F8 int unk1599; //0x18FC int unk1600; //0x1900 int unk1601; //0x1904 int unk1602; //0x1908 int unk1603; //0x190C int unk1604; //0x1910 int unk1605; //0x1914 int unk1606; //0x1918 int unk1607; //0x191C int unk1608; //0x1920 int unk1609; //0x1924 int unk1610; //0x1928 int unk1611; //0x192C int unk1612; //0x1930 int unk1613; //0x1934 int unk1614; //0x1938 int unk1615; //0x193C int unk1616; //0x1940 int unk1617; //0x1944 int unk1618; //0x1948 int unk1619; //0x194C int unk1620; //0x1950 int unk1621; //0x1954 int unk1622; //0x1958 int unk1623; //0x195C int unk1624; //0x1960 int unk1625; //0x1964 int unk1626; //0x1968 int unk1627; //0x196C int unk1628; //0x1970 int unk1629; //0x1974 int unk1630; //0x1978 int unk1631; //0x197C int unk1632; //0x1980 int unk1633; //0x1984 int unk1634; //0x1988 int unk1635; //0x198C int unk1636; //0x1990 int unk1637; //0x1994 int unk1638; //0x1998 int unk1639; //0x199C int unk1640; //0x19A0 int unk1641; //0x19A4 int unk1642; //0x19A8 int unk1643; //0x19AC int unk1644; //0x19B0 int unk1645; //0x19B4 int unk1646; //0x19B8 int unk1647; //0x19BC int unk1648; //0x19C0 int unk1649; //0x19C4 int unk1650; //0x19C8 int unk1651; //0x19CC int unk1652; //0x19D0 int unk1653; //0x19D4 int unk1654; //0x19D8 int unk1655; //0x19DC int unk1656; //0x19E0 int unk1657; //0x19E4 int unk1658; //0x19E8 int unk1659; //0x19EC int unk1660; //0x19F0 int unk1661; //0x19F4 int unk1662; //0x19F8 int unk1663; //0x19FC int unk1664; //0x1A00 int unk1665; //0x1A04 int unk1666; //0x1A08 int unk1667; //0x1A0C int unk1668; //0x1A10 int unk1669; //0x1A14 int unk1670; //0x1A18 int unk1671; //0x1A1C int unk1672; //0x1A20 int unk1673; //0x1A24 int unk1674; //0x1A28 int unk1675; //0x1A2C int unk1676; //0x1A30 int unk1677; //0x1A34 int unk1678; //0x1A38 int unk1679; //0x1A3C int unk1680; //0x1A40 int unk1681; //0x1A44 int unk1682; //0x1A48 int unk1683; //0x1A4C int unk1684; //0x1A50 int unk1685; //0x1A54 int unk1686; //0x1A58 int unk1687; //0x1A5C int unk1688; //0x1A60 int unk1689; //0x1A64 int unk1690; //0x1A68 int unk1691; //0x1A6C int unk1692; //0x1A70 int unk1693; //0x1A74 int unk1694; //0x1A78 int unk1695; //0x1A7C int unk1696; //0x1A80 int unk1697; //0x1A84 int unk1698; //0x1A88 int unk1699; //0x1A8C int unk1700; //0x1A90 int unk1701; //0x1A94 int unk1702; //0x1A98 int unk1703; //0x1A9C int unk1704; //0x1AA0 int unk1705; //0x1AA4 int unk1706; //0x1AA8 int unk1707; //0x1AAC int unk1708; //0x1AB0 int unk1709; //0x1AB4 int unk1710; //0x1AB8 int unk1711; //0x1ABC int unk1712; //0x1AC0 int unk1713; //0x1AC4 int unk1714; //0x1AC8 int unk1715; //0x1ACC int unk1716; //0x1AD0 int unk1717; //0x1AD4 int unk1718; //0x1AD8 int unk1719; //0x1ADC int unk1720; //0x1AE0 int unk1721; //0x1AE4 int unk1722; //0x1AE8 int unk1723; //0x1AEC int unk1724; //0x1AF0 int unk1725; //0x1AF4 int unk1726; //0x1AF8 int unk1727; //0x1AFC int unk1728; //0x1B00 int unk1729; //0x1B04 int unk1730; //0x1B08 int unk1731; //0x1B0C int unk1732; //0x1B10 int unk1733; //0x1B14 int unk1734; //0x1B18 int unk1735; //0x1B1C int unk1736; //0x1B20 int unk1737; //0x1B24 int unk1738; //0x1B28 int unk1739; //0x1B2C int unk1740; //0x1B30 int unk1741; //0x1B34 int unk1742; //0x1B38 int unk1743; //0x1B3C int unk1744; //0x1B40 int unk1745; //0x1B44 int unk1746; //0x1B48 int unk1747; //0x1B4C int unk1748; //0x1B50 int unk1749; //0x1B54 int unk1750; //0x1B58 int unk1751; //0x1B5C int unk1752; //0x1B60 int unk1753; //0x1B64 int unk1754; //0x1B68 int unk1755; //0x1B6C int unk1756; //0x1B70 int unk1757; //0x1B74 int unk1758; //0x1B78 int unk1759; //0x1B7C int unk1760; //0x1B80 int unk1761; //0x1B84 int unk1762; //0x1B88 int unk1763; //0x1B8C int unk1764; //0x1B90 int unk1765; //0x1B94 int unk1766; //0x1B98 int unk1767; //0x1B9C int unk1768; //0x1BA0 int unk1769; //0x1BA4 int unk1770; //0x1BA8 int unk1771; //0x1BAC int unk1772; //0x1BB0 int unk1773; //0x1BB4 int unk1774; //0x1BB8 int unk1775; //0x1BBC int unk1776; //0x1BC0 int unk1777; //0x1BC4 int unk1778; //0x1BC8 int unk1779; //0x1BCC int unk1780; //0x1BD0 int unk1781; //0x1BD4 int unk1782; //0x1BD8 int unk1783; //0x1BDC int unk1784; //0x1BE0 int unk1785; //0x1BE4 int unk1786; //0x1BE8 int unk1787; //0x1BEC int unk1788; //0x1BF0 int unk1789; //0x1BF4 int unk1790; //0x1BF8 int unk1791; //0x1BFC int unk1792; //0x1C00 int unk1793; //0x1C04 int unk1794; //0x1C08 int unk1795; //0x1C0C int unk1796; //0x1C10 int unk1797; //0x1C14 int unk1798; //0x1C18 int unk1799; //0x1C1C int unk1800; //0x1C20 int unk1801; //0x1C24 int unk1802; //0x1C28 int unk1803; //0x1C2C int unk1804; //0x1C30 int unk1805; //0x1C34 int unk1806; //0x1C38 int unk1807; //0x1C3C int unk1808; //0x1C40 int unk1809; //0x1C44 int unk1810; //0x1C48 int unk1811; //0x1C4C int unk1812; //0x1C50 int unk1813; //0x1C54 int unk1814; //0x1C58 int unk1815; //0x1C5C int unk1816; //0x1C60 int unk1817; //0x1C64 int unk1818; //0x1C68 int unk1819; //0x1C6C int unk1820; //0x1C70 int unk1821; //0x1C74 int unk1822; //0x1C78 int unk1823; //0x1C7C int unk1824; //0x1C80 int unk1825; //0x1C84 int unk1826; //0x1C88 int unk1827; //0x1C8C int unk1828; //0x1C90 int unk1829; //0x1C94 int unk1830; //0x1C98 int unk1831; //0x1C9C int unk1832; //0x1CA0 int unk1833; //0x1CA4 int unk1834; //0x1CA8 int unk1835; //0x1CAC int unk1836; //0x1CB0 int unk1837; //0x1CB4 int unk1838; //0x1CB8 int unk1839; //0x1CBC int unk1840; //0x1CC0 int unk1841; //0x1CC4 int unk1842; //0x1CC8 int unk1843; //0x1CCC int unk1844; //0x1CD0 int unk1845; //0x1CD4 int unk1846; //0x1CD8 int unk1847; //0x1CDC int unk1848; //0x1CE0 int unk1849; //0x1CE4 int unk1850; //0x1CE8 int unk1851; //0x1CEC int unk1852; //0x1CF0 int unk1853; //0x1CF4 int unk1854; //0x1CF8 int unk1855; //0x1CFC int unk1856; //0x1D00 int unk1857; //0x1D04 int unk1858; //0x1D08 int unk1859; //0x1D0C int unk1860; //0x1D10 int unk1861; //0x1D14 int unk1862; //0x1D18 int unk1863; //0x1D1C int unk1864; //0x1D20 int unk1865; //0x1D24 int unk1866; //0x1D28 int unk1867; //0x1D2C int unk1868; //0x1D30 int unk1869; //0x1D34 int unk1870; //0x1D38 int unk1871; //0x1D3C int unk1872; //0x1D40 int unk1873; //0x1D44 int unk1874; //0x1D48 int unk1875; //0x1D4C int unk1876; //0x1D50 int unk1877; //0x1D54 int unk1878; //0x1D58 int unk1879; //0x1D5C int unk1880; //0x1D60 int unk1881; //0x1D64 int unk1882; //0x1D68 int unk1883; //0x1D6C int unk1884; //0x1D70 int unk1885; //0x1D74 int unk1886; //0x1D78 int unk1887; //0x1D7C int unk1888; //0x1D80 int unk1889; //0x1D84 int unk1890; //0x1D88 int unk1891; //0x1D8C int unk1892; //0x1D90 int unk1893; //0x1D94 int unk1894; //0x1D98 int unk1895; //0x1D9C int unk1896; //0x1DA0 int unk1897; //0x1DA4 int unk1898; //0x1DA8 int unk1899; //0x1DAC int unk1900; //0x1DB0 int unk1901; //0x1DB4 int unk1902; //0x1DB8 int unk1903; //0x1DBC int unk1904; //0x1DC0 int unk1905; //0x1DC4 int unk1906; //0x1DC8 int unk1907; //0x1DCC int unk1908; //0x1DD0 int unk1909; //0x1DD4 int unk1910; //0x1DD8 int unk1911; //0x1DDC int unk1912; //0x1DE0 int unk1913; //0x1DE4 int unk1914; //0x1DE8 int unk1915; //0x1DEC int unk1916; //0x1DF0 int unk1917; //0x1DF4 int unk1918; //0x1DF8 int unk1919; //0x1DFC int unk1920; //0x1E00 int unk1921; //0x1E04 int unk1922; //0x1E08 int unk1923; //0x1E0C int unk1924; //0x1E10 int unk1925; //0x1E14 int unk1926; //0x1E18 int unk1927; //0x1E1C int unk1928; //0x1E20 int unk1929; //0x1E24 int unk1930; //0x1E28 int unk1931; //0x1E2C int unk1932; //0x1E30 int unk1933; //0x1E34 int unk1934; //0x1E38 int unk1935; //0x1E3C int unk1936; //0x1E40 int unk1937; //0x1E44 int unk1938; //0x1E48 int unk1939; //0x1E4C int unk1940; //0x1E50 int unk1941; //0x1E54 int unk1942; //0x1E58 int unk1943; //0x1E5C int unk1944; //0x1E60 int unk1945; //0x1E64 int unk1946; //0x1E68 int unk1947; //0x1E6C int unk1948; //0x1E70 int unk1949; //0x1E74 int unk1950; //0x1E78 int unk1951; //0x1E7C int unk1952; //0x1E80 int unk1953; //0x1E84 int unk1954; //0x1E88 int unk1955; //0x1E8C int unk1956; //0x1E90 int unk1957; //0x1E94 int unk1958; //0x1E98 int unk1959; //0x1E9C int unk1960; //0x1EA0 int unk1961; //0x1EA4 int unk1962; //0x1EA8 int unk1963; //0x1EAC int unk1964; //0x1EB0 int unk1965; //0x1EB4 int unk1966; //0x1EB8 int unk1967; //0x1EBC int unk1968; //0x1EC0 int unk1969; //0x1EC4 int unk1970; //0x1EC8 int unk1971; //0x1ECC int unk1972; //0x1ED0 int unk1973; //0x1ED4 int unk1974; //0x1ED8 int unk1975; //0x1EDC int unk1976; //0x1EE0 int unk1977; //0x1EE4 int unk1978; //0x1EE8 int unk1979; //0x1EEC int unk1980; //0x1EF0 int unk1981; //0x1EF4 int unk1982; //0x1EF8 int unk1983; //0x1EFC int unk1984; //0x1F00 int unk1985; //0x1F04 int unk1986; //0x1F08 int unk1987; //0x1F0C int unk1988; //0x1F10 int unk1989; //0x1F14 int unk1990; //0x1F18 int unk1991; //0x1F1C int unk1992; //0x1F20 int TM_OSDEnabled; //0x1F24 u8 TM_OSDMax; //0x1F28 u8 TM_EventPage; //0x1F29 u8 TM_OSDRecommended; //0x1F2A int unk1995; //0x1F2C int unk1996; //0x1F30 int unk1997; //0x1F34 int unk1998; //0x1F38 int unk1999; //0x1F3C int unk2000; //0x1F40 int unk2001; //0x1F44 int unk2002; //0x1F48 int unk2003; //0x1F4C int unk2004; //0x1F50 int unk2005; //0x1F54 int unk2006; //0x1F58 int unk2007; //0x1F5C int unk2008; //0x1F60 int unk2009; //0x1F64 int unk2010; //0x1F68 int unk2011; //0x1F6C int unk2012; //0x1F70 int unk2013; //0x1F74 int unk2014; //0x1F78 int unk2015; //0x1F7C int unk2016; //0x1F80 int unk2017; //0x1F84 int unk2018; //0x1F88 int unk2019; //0x1F8C int unk2020; //0x1F90 int unk2021; //0x1F94 int unk2022; //0x1F98 int unk2023; //0x1F9C int unk2024; //0x1FA0 int unk2025; //0x1FA4 int unk2026; //0x1FA8 int unk2027; //0x1FAC int unk2028; //0x1FB0 int unk2029; //0x1FB4 int unk2030; //0x1FB8 int unk2031; //0x1FBC int unk2032; //0x1FC0 int unk2033; //0x1FC4 int unk2034; //0x1FC8 int unk2035; //0x1FCC int unk2036; //0x1FD0 int unk2037; //0x1FD4 int unk2038; //0x1FD8 int unk2039; //0x1FDC int unk2040; //0x1FE0 int unk2041; //0x1FE4 int unk2042; //0x1FE8 int unk2043; //0x1FEC int unk2044; //0x1FF0 int unk2045; //0x1FF4 int unk2046; //0x1FF8 int unk2047; //0x1FFC }; struct SnapshotInfo { int snap_id; u16 is_exist; u16 block_size; }; struct SnapshotList { int x0; int snap_num; int x8; int xc; SnapshotInfo snap_info[128]; }; struct MemSnapIconData { _HSD_ImageDesc *banner; _HSD_ImageDesc *icon; }; struct MemcardSave { int size; // size of the data, only used when writing to the card int x4; // unknown, is usually 3 void *data; // pointer to the save data int xc; // is -1 to signify end of data }; struct MemcardWork { void *work_area; // 0x0 void *buffer; // 0x4, temp transfer buffer used during CARDReads. is 0x2000 bytes int x8; // 0x8 int xc; // 0xc int x10; // 0x10 int x14; // 0x14 void *icon_data; // 0x18 void *banner_data; // 0x1c int x20; // 0x20 int x24; // 0x24 int x28; // 0x28 int x2c; // 0x2c int x30; // 0x30 int x34; // 0x34 int x38; // 0x38 int x3c; // 0x3c int x40; // 0x40 int x44; // 0x44 int x48; // 0x48 int x4c; // 0x4c int x50; // 0x50 int x54; // 0x54 int x58; // 0x58 int x5c; // 0x5c int x60; // 0x60 int x64; // 0x64 int x68; // 0x68 int x6c; // 0x6c int x70; // 0x70 int x74; // 0x74 int x78; // 0x78 int x7c; // 0x7c int x80; // 0x80 int x84; // 0x84 int x88; // 0x88 int x8c; // 0x8c int x90; // 0x90 CARDFileInfo card_file_x94; // 0x94 void *buffer_use; // 0xa8, temp transfer buffer used during CARDReads int xac; // 0xac int buffer_size; // 0xb0 CARDFileInfo card_file_info; // 0xb4 cancel vanilla memcard reads with this fileinfo int xc8; // 0xc8 int card_data_start; // 0xcc, data after header and banner and metadata int xd0; // 0xd0 int xd4; // 0xd4 int xd8; // 0xd8 int xdc; // 0xdc int xe0; // 0xe0 int xe4; // 0xe4 int xe8; // 0xe8 int xec; // 0xec int xf0; // 0xf0 int xf4; // 0xf4 int xf8; // 0xf8 int xfc; // 0xfc int x100; // 0x100 int x104; // 0x104 int x108; // 0x108 int x10c; // 0x10c int x110; // 0x110 int x114; // 0x114 int x118; // 0x118 int x11c; // 0x11c int x120; // 0x120 int x124; // 0x124 int x128; // 0x128 int x12c; // 0x12c int x130; // 0x130 int x134; // 0x134 int x138; // 0x138 int x13c; // 0x13c int x140; // 0x140 int x144; // 0x144 int x148; // 0x148 int x14c; // 0x14c int x150; // 0x150 int x154; // 0x154 int x158; // 0x158 int x15c; // 0x15c int x160; // 0x160 int x164; // 0x164 int x168; // 0x168 int x16c; // 0x16c int x170; // 0x170 int x174; // 0x174 int x178; // 0x178 int x17c; // 0x17c int x180; // 0x180 int x184; // 0x184 int x188; // 0x188 int x18c; // 0x18c int x190; // 0x190 int x194; // 0x194 int x198; // 0x198 int x19c; // 0x19c int x1a0; // 0x1a0 int x1a4; // 0x1a4 int x1a8; // 0x1a8 int x1ac; // 0x1ac int x1b0; // 0x1b0 int x1b4; // 0x1b4 int x1b8; // 0x1b8 int x1bc; // 0x1bc int x1c0; // 0x1c0 int x1c4; // 0x1c4 int x1c8; // 0x1c8 int x1cc; // 0x1cc int x1d0; // 0x1d0 int x1d4; // 0x1d4 int x1d8; // 0x1d8 int x1dc; // 0x1dc int x1e0; // 0x1e0 int x1e4; // 0x1e4 int x1e8; // 0x1e8 int x1ec; // 0x1ec int x1f0; // 0x1f0 int x1f4; // 0x1f4 int x1f8; // 0x1f8 int x1fc; // 0x1fc int x200; // 0x200 int x204; // 0x204 int x208; // 0x208 int x20c; // 0x20c int x210; // 0x210 int x214; // 0x214 int x218; // 0x218 int x21c; // 0x21c int x220; // 0x220 int x224; // 0x224 int x228; // 0x228 int x22c; // 0x22c int x230; // 0x230 int x234; // 0x234 int x238; // 0x238 int x23c; // 0x23c int x240; // 0x240 int x244; // 0x244 int x248; // 0x248 int x24c; // 0x24c int x250; // 0x250 int x254; // 0x254 int x258; // 0x258 int x25c; // 0x25c int x260; // 0x260 int x264; // 0x264 int x268; // 0x268 int x26c; // 0x26c int x270; // 0x270 int x274; // 0x274 int x278; // 0x278 int x27c; // 0x27c int x280; // 0x280 int x284; // 0x284 int x288; // 0x288 int x28c; // 0x28c int x290; // 0x290 int x294; // 0x294 int x298; // 0x298 int x29c; // 0x29c int x2a0; // 0x2a0 int x2a4; // 0x2a4 int x2a8; // 0x2a8 int x2ac; // 0x2ac int x2b0; // 0x2b0 int x2b4; // 0x2b4 int x2b8; // 0x2b8 int x2bc; // 0x2bc int x2c0; // 0x2c0 int x2c4; // 0x2c4 int x2c8; // 0x2c8 int x2cc; // 0x2cc int x2d0; // 0x2d0 int x2d4; // 0x2d4 int x2d8; // 0x2d8 int x2dc; // 0x2dc int x2e0; // 0x2e0 int x2e4; // 0x2e4 int x2e8; // 0x2e8 int x2ec; // 0x2ec int x2f0; // 0x2f0 int x2f4; // 0x2f4 int x2f8; // 0x2f8 int x2fc; // 0x2fc int x300; // 0x300 int x304; // 0x304 int x308; // 0x308 int x30c; // 0x30c int x310; // 0x310 int x314; // 0x314 int x318; // 0x318 int x31c; // 0x31c int x320; // 0x320 int x324; // 0x324 int x328; // 0x328 int x32c; // 0x32c int x330; // 0x330 int x334; // 0x334 int x338; // 0x338 int x33c; // 0x33c int x340; // 0x340 int x344; // 0x344 int x348; // 0x348 int x34c; // 0x34c int x350; // 0x350 int x354; // 0x354 int x358; // 0x358 int x35c; // 0x35c int x360; // 0x360 int x364; // 0x364 int x368; // 0x368 int x36c; // 0x36c int x370; // 0x370 int x374; // 0x374 int x378; // 0x378 int x37c; // 0x37c int x380; // 0x380 int x384; // 0x384 int x388; // 0x388 int x38c; // 0x38c int x390; // 0x390 int x394; // 0x394 int x398; // 0x398 int x39c; // 0x39c int x3a0; // 0x3a0 int x3a4; // 0x3a4 int x3a8; // 0x3a8 int x3ac; // 0x3ac int x3b0; // 0x3b0 int x3b4; // 0x3b4 int x3b8; // 0x3b8 int x3bc; // 0x3bc int x3c0; // 0x3c0 int x3c4; // 0x3c4 int x3c8; // 0x3c8 int x3cc; // 0x3cc int x3d0; // 0x3d0 int x3d4; // 0x3d4 int x3d8; // 0x3d8 int x3dc; // 0x3dc int x3e0; // 0x3e0 int x3e4; // 0x3e4 int x3e8; // 0x3e8 int x3ec; // 0x3ec int x3f0; // 0x3f0 int x3f4; // 0x3f4 int x3f8; // 0x3f8 int x3fc; // 0x3fc int x400; // 0x400 int x404; // 0x404 int x408; // 0x408 int x40c; // 0x40c int x410; // 0x410 int x414; // 0x414 int x418; // 0x418 int x41c; // 0x41c int x420; // 0x420 int x424; // 0x424 int x428; // 0x428 int x42c; // 0x42c int x430; // 0x430 int x434; // 0x434 int x438; // 0x438 int x43c; // 0x43c int x440; // 0x440 int x444; // 0x444 int x448; // 0x448 int x44c; // 0x44c int x450; // 0x450 int x454; // 0x454 int x458; // 0x458 int x45c; // 0x45c int x460; // 0x460 int x464; // 0x464 int x468; // 0x468 int x46c; // 0x46c int x470; // 0x470 int x474; // 0x474 int x478; // 0x478 int x47c; // 0x47c int x480; // 0x480 int x484; // 0x484 int x488; // 0x488 int x48c; // 0x48c int x490; // 0x490 int x494; // 0x494 int x498; // 0x498 int x49c; // 0x49c int x4a0; // 0x4a0 int x4a4; // 0x4a4 int x4a8; // 0x4a8 int x4ac; // 0x4ac int x4b0; // 0x4b0 int x4b4; // 0x4b4 int x4b8; // 0x4b8 int x4bc; // 0x4bc int x4c0; // 0x4c0 int x4c4; // 0x4c4 int x4c8; // 0x4c8 int x4cc; // 0x4cc int x4d0; // 0x4d0 int x4d4; // 0x4d4 int x4d8; // 0x4d8 int x4dc; // 0x4dc int x4e0; // 0x4e0 int x4e4; // 0x4e4 int x4e8; // 0x4e8 int x4ec; // 0x4ec int x4f0; // 0x4f0 int x4f4; // 0x4f4 int x4f8; // 0x4f8 int x4fc; // 0x4fc int x500; // 0x500 int x504; // 0x504 int x508; // 0x508 int x50c; // 0x50c int x510; // 0x510 int x514; // 0x514 int x518; // 0x518 int x51c; // 0x51c int x520; // 0x520 int x524; // 0x524 int x528; // 0x528 int x52c; // 0x52c int x530; // 0x530 int x534; // 0x534 int x538; // 0x538 int x53c; // 0x53c int x540; // 0x540 int x544; // 0x544 int x548; // 0x548 int x54c; // 0x54c int x550; // 0x550 int x554; // 0x554 int x558; // 0x558 int x55c; // 0x55c int x560; // 0x560 int x564; // 0x564 int x568; // 0x568 int x56c; // 0x56c int x570; // 0x570 int x574; // 0x574 int x578; // 0x578 int x57c; // 0x57c int x580; // 0x580 int x584; // 0x584 int x588; // 0x588 int x58c; // 0x58c int x590; // 0x590 int x594; // 0x594 int x598; // 0x598 int x59c; // 0x59c int x5a0; // 0x5a0 int x5a4; // 0x5a4 int x5a8; // 0x5a8 int x5ac; // 0x5ac int x5b0; // 0x5b0 int x5b4; // 0x5b4 int x5b8; // 0x5b8 int x5bc; // 0x5bc int x5c0; // 0x5c0 int x5c4; // 0x5c4 int x5c8; // 0x5c8 int x5cc; // 0x5cc int x5d0; // 0x5d0 int x5d4; // 0x5d4 int x5d8; // 0x5d8 int x5dc; // 0x5dc int x5e0; // 0x5e0 int x5e4; // 0x5e4 int x5e8; // 0x5e8 int x5ec; // 0x5ec int x5f0; // 0x5f0 int x5f4; // 0x5f4 int x5f8; // 0x5f8 int x5fc; // 0x5fc int x600; // 0x600 int x604; // 0x604 int x608; // 0x608 int x60c; // 0x60c int x610; // 0x610 int x614; // 0x614 int x618; // 0x618 int x61c; // 0x61c int x620; // 0x620 int x624; // 0x624 int x628; // 0x628 int x62c; // 0x62c int x630; // 0x630 int x634; // 0x634 int x638; // 0x638 int x63c; // 0x63c int x640; // 0x640 int x644; // 0x644 int x648; // 0x648 int x64c; // 0x64c int x650; // 0x650 int x654; // 0x654 int x658; // 0x658 int x65c; // 0x65c int x660; // 0x660 int x664; // 0x664 int x668; // 0x668 int x66c; // 0x66c int x670; // 0x670 int x674; // 0x674 int x678; // 0x678 int x67c; // 0x67c int x680; // 0x680 int x684; // 0x684 int x688; // 0x688 int x68c; // 0x68c int x690; // 0x690 int x694; // 0x694 int x698; // 0x698 int x69c; // 0x69c int x6a0; // 0x6a0 int x6a4; // 0x6a4 int x6a8; // 0x6a8 int x6ac; // 0x6ac int x6b0; // 0x6b0 int x6b4; // 0x6b4 int x6b8; // 0x6b8 int x6bc; // 0x6bc int x6c0; // 0x6c0 int x6c4; // 0x6c4 int x6c8; // 0x6c8 int x6cc; // 0x6cc int x6d0; // 0x6d0 int x6d4; // 0x6d4 int x6d8; // 0x6d8 int x6dc; // 0x6dc int x6e0; // 0x6e0 int x6e4; // 0x6e4 int x6e8; // 0x6e8 int x6ec; // 0x6ec int x6f0; // 0x6f0 int x6f4; // 0x6f4 int x6f8; // 0x6f8 int x6fc; // 0x6fc int x700; // 0x700 int x704; // 0x704 int x708; // 0x708 int x70c; // 0x70c int x710; // 0x710 int x714; // 0x714 int x718; // 0x718 int x71c; // 0x71c int x720; // 0x720 int x724; // 0x724 int x728; // 0x728 int x72c; // 0x72c int x730; // 0x730 int x734; // 0x734 int x738; // 0x738 int x73c; // 0x73c int x740; // 0x740 int x744; // 0x744 int x748; // 0x748 int x74c; // 0x74c int x750; // 0x750 int x754; // 0x754 int x758; // 0x758 int x75c; // 0x75c int x760; // 0x760 int x764; // 0x764 int x768; // 0x768 int x76c; // 0x76c int x770; // 0x770 int x774; // 0x774 int x778; // 0x778 int x77c; // 0x77c int x780; // 0x780 int x784; // 0x784 int x788; // 0x788 int x78c; // 0x78c int x790; // 0x790 int x794; // 0x794 int x798; // 0x798 int x79c; // 0x79c int x7a0; // 0x7a0 int x7a4; // 0x7a4 int x7a8; // 0x7a8 int x7ac; // 0x7ac int x7b0; // 0x7b0 int x7b4; // 0x7b4 int x7b8; // 0x7b8 int x7bc; // 0x7bc int x7c0; // 0x7c0 int x7c4; // 0x7c4 int x7c8; // 0x7c8 int x7cc; // 0x7cc int x7d0; // 0x7d0 int x7d4; // 0x7d4 int x7d8; // 0x7d8 int x7dc; // 0x7dc int x7e0; // 0x7e0 int x7e4; // 0x7e4 int x7e8; // 0x7e8 int x7ec; // 0x7ec int x7f0; // 0x7f0 int x7f4; // 0x7f4 int x7f8; // 0x7f8 int x7fc; // 0x7fc int x800; // 0x800 int x804; // 0x804 int x808; // 0x808 int x80c; // 0x80c int x810; // 0x810 int x814; // 0x814 int x818; // 0x818 int x81c; // 0x81c int x820; // 0x820 int x824; // 0x824 int x828; // 0x828 int x82c; // 0x82c int x830; // 0x830 int x834; // 0x834 int x838; // 0x838 int x83c; // 0x83c int x840; // 0x840 int x844; // 0x844 int x848; // 0x848 int x84c; // 0x84c int x850; // 0x850 int x854; // 0x854 int x858; // 0x858 int x85c; // 0x85c int x860; // 0x860 int x864; // 0x864 int x868; // 0x868 int x86c; // 0x86c int x870; // 0x870 int x874; // 0x874 int x878; // 0x878 int x87c; // 0x87c int x880; // 0x880 int x884; // 0x884 int x888; // 0x888 int x88c; // 0x88c int x890; // 0x890 int x894; // 0x894 int x898; // 0x898 int x89c; // 0x89c int x8a0; // 0x8a0 int x8a4; // 0x8a4 int x8a8; // 0x8a8 int is_done; // 0x8ac. operation callback sets this to 1 when the operation finishes }; struct MemcardUnk { u8 block_size; u8 x1; u8 x2; u8 x3; u8 x4; u8 x5; u8 x6; u8 x7; u8 x8; u8 x9; u8 xa[8]; }; struct MemcardInfo { void *snap_data; // 0x0 (should be 256,064 bytes) char file_name[32]; // should end with spaces char file_desc[32]; // should end with spaces MemSnapIconData *icon_data; // 0x44 SnapshotList *snap_list; // 0x48 (should be 2112 bytes) points to an allocation where info on the snapshots present on slot A exists int memcard_probe; // 0x4c 1 == is present. is updated every controller poll int x50; // 0x50 int x54; // 0x54 int x58; // 0x58 int x5c; // 0x5c int x60; // 0x60 int x64; // 0x64 int x68; // 0x68 int x6c; // 0x6c int x70; // 0x70 int x74; // 0x74 int x78; // 0x78 int x7c; // 0x7c int x80; // 0x80 int x84; // 0x84 int x88; // 0x88 int x8c; // 0x8c int x90; // 0x90 int x94; // 0x94 int x98; // 0x98 int x9c; // 0x9c int xa0; // 0xa0 int xa4; // 0xa4 int xa8; // 0xa8 int xac; // 0xac int xb0; // 0xb0 int xb4; // 0xb4 int xb8; // 0xb8 int xbc; // 0xbc int xc0; // 0xc0 int xc4; // 0xc4 int xc8; // 0xc8 int xcc; // 0xcc int xd0; // 0xd0 int xd4; // 0xd4 int xd8; // 0xd8 int xdc; // 0xdc int xe0; // 0xe0 int xe4; // 0xe4 int xe8; // 0xe8 int xec; // 0xec }; struct Rules1 { u8 x0; u8 x1; u8 x2; u8 x3; u8 x4; u8 handicap; u8 x6; u8 x7; u8 x8; u8 x9; u8 xa; u8 xb; u8 xc; }; /*** Static Variables ***/ static MemcardInfo *stc_memcard_info = 0x80433380; static MemcardUnk *stc_memcard_unk = 0x803bacc8; static MemcardWork *stc_memcard_work = 0x80432a68; int *stc_memcard_block_curr = R13 + (-0x3d20); int *stc_memcard_block_last = R13 + (-0x3d1c); int *stc_memcard_write_status = 0x804d1138; int *stc_CardXferredBytes = R13 + (-0x3D14); #endif ================================================ FILE: MexTK/include/mex.h ================================================ #ifndef MEX_H_MEX #define MEX_H_MEX #include "structs.h" #include "datatypes.h" #include "obj.h" #define DB_FLAG 0 enum MEX_GETDATA { MXDT_FTINTNUM, MXDT_FTEXTNUM, MXDT_FTICONNUM, MXDT_FTICONDATA, MXDT_GRINTNUM, MXDT_GREXTNUM, MXDT_GRICONNUM, MXDT_GRICONDATA, }; /*** Structs ***/ struct PRIM { void *data; }; struct Translation { float frame; float value; }; struct MEXPlaylist { u16 bgm; u16 chance; }; /*** Functions ***/ ArchiveInfo *MEX_LoadRelArchive(char *file, void *functions, char *symbol); void MEX_IndexFighterItem(int fighter_kind, void *itemdata, int item_id); void SpawnMEXEffect(int effectID, int fighter, int arg1, int arg2, int arg3, int arg4, int arg5); int MEX_GetItemExtID(GOBJ *gobj, int item_id); // gobj can be fighter or stage int MEX_GetFtItemID(int ft_kind, int item_id); // gobj can be fighter or stage int MEX_GetGrItemID(int item_id); // gobj can be fighter or stage void SFX_PlayStageSFX(int sfx_id); void *calloc(int size); PRIM *PRIM_NEW(int vert_count, int params1, int params2); void PRIM_CLOSE(); MEXPlaylist *MEX_GetPlaylist(); int MEX_GetStageItemExtID(int item_id); void KirbyStateChange(GOBJ *fighter, int state, float startFrame, float animSpeed, float animBlend); void *MEX_GetKirbyCpData(int copy_id); int MEX_GetCopyItemExtID(int copy_id, int item_id); void *MEX_GetData(int index); #endif ================================================ FILE: MexTK/include/obj.h ================================================ #ifndef MEX_H_OBJ #define MEX_H_OBJ #include "structs.h" #include "datatypes.h" #include "color.h" // JObj Flags #define JOBJ_SKELETON (1 << 0) #define JOBJ_SKELETON_ROOT (1 << 1) #define JOBJ_ENVELOPE_MODEL (1 << 2) #define JOBJ_CLASSICAL_SCALING (1 << 3) #define JOBJ_HIDDEN (1 << 4) #define JOBJ_PTCL (1 << 5) #define JOBJ_MTX_DIRTY (1 << 6) #define JOBJ_LIGHTING (1 << 7) #define JOBJ_TEXGEN (1 << 8) #define JOBJ_BILLBOARD (1 << 9) #define JOBJ_VBILLBOARD (2 << 9) #define JOBJ_HBILLBOARD (3 << 9) #define JOBJ_RBILLBOARD (4 << 9) #define JOBJ_INSTANCE (1 << 12) #define JOBJ_PBILLBOARD (1 << 13) #define JOBJ_SPLINE (1 << 14) #define JOBJ_FLIP_IK (1 << 15) #define JOBJ_SPECULAR (1 << 16) #define JOBJ_USE_QUATERNION (1 << 17) #define JOBJ_OPA (1 << 18) #define JOBJ_XLU (1 << 19) #define JOBJ_TEXEDGE (1 << 20) #define JOBJ_NULL (0 << 21) #define JOBJ_JOINT1 (1 << 21) #define JOBJ_JOINT2 (2 << 21) #define JOBJ_EFFECTOR (3 << 21) #define JOBJ_USER_DEFINED_MTX (1 << 23) #define JOBJ_MTX_INDEPEND_PARENT (1 << 24) #define JOBJ_MTS_INDEPEND_SRT (1 << 25) #define JOBJ_GENERALFLAG (1 << 26) #define JOBJ_GENERALFLAG2 (1 << 27) #define JOBJ_ROOT_OPA (1 << 28) #define JOBJ_ROOT_XLU (1 << 29) #define JOBJ_ROOT_TEXEDGE (1 << 30) #define JOBJ_31 (1 << 31) // MObj Flags #define MOBJ_ANIM 0x4 #define TOBJ_ANIM 0x10 #define ALL_ANIM 0x7FF #define HSD_A_M_AMBIENT_R 1 #define HSD_A_M_AMBIENT_G 2 #define HSD_A_M_AMBIENT_B 3 #define HSD_A_M_DIFFUSE_R 4 #define HSD_A_M_DIFFUSE_G 5 #define HSD_A_M_DIFFUSE_B 6 #define HSD_A_M_SPECULAR_R 7 #define HSD_A_M_SPECULAR_G 8 #define HSD_A_M_SPECULAR_B 9 #define HSD_A_M_ALPHA 10 #define HSD_A_M_PE_REF0 11 #define HSD_A_M_PE_REF1 12 #define HSD_A_M_PE_DSTALPHA 13 #define RENDER_DIFFUSE_SHIFT 0 #define RENDER_DIFFUSE_BITS (3 << RENDER_DIFFUSE_SHIFT) #define RENDER_DIFFUSE_MAT0 (0 << RENDER_DIFFUSE_SHIFT) #define RENDER_DIFFUSE_MAT (1 << RENDER_DIFFUSE_SHIFT) #define RENDER_DIFFUSE_VTX (2 << RENDER_DIFFUSE_SHIFT) #define RENDER_DIFFUSE_BOTH (3 << RENDER_DIFFUSE_SHIFT) #define RENDER_CONSTANT (1 << 0) #define RENDER_VERTEX (1 << 1) #define RENDER_DIFFUSE (1 << 2) #define RENDER_SPECULAR (1 << 3) #define CHANNEL_FIELD (RENDER_CONSTANT | RENDER_VERTEX | RENDER_DIFFUSE | RENDER_SPECULAR) #define RENDER_TEX0 (1 << 4) #define RENDER_TEX1 (1 << 5) #define RENDER_TEX2 (1 << 6) #define RENDER_TEX3 (1 << 7) #define RENDER_TEX4 (1 << 8) #define RENDER_TEX5 (1 << 9) #define RENDER_TEX6 (1 << 10) #define RENDER_TEX7 (1 << 11) #define RENDER_TEXTURES (RENDER_TEX0 | RENDER_TEX1 | RENDER_TEX2 | RENDER_TEX3 | RENDER_TEX4 | RENDER_TEX5 | RENDER_TEX6 | RENDER_TEX7) #define RENDER_TOON (1 << 12) #define RENDER_ALPHA_SHIFT 13 #define RENDER_ALPHA_BITS (3 << RENDER_ALPHA_SHIFT) #define RENDER_ALPHA_COMPAT (0 << RENDER_ALPHA_SHIFT) #define RENDER_ALPHA_MAT (1 << RENDER_ALPHA_SHIFT) #define RENDER_ALPHA_VTX (2 << RENDER_ALPHA_SHIFT) #define RENDER_ALPHA_BOTH (3 << RENDER_ALPHA_SHIFT) #define RENDER_SHADOW (1 << 26) #define RENDER_ZMODE_ALWAYS (1 << 27) #define RENDER_NO_ZUPDATE (1 << 29) #define RENDER_XLU (1 << 30) // DOBJ flags #define DOBJ_HIDDEN 1 /*** Structs ***/ struct GOBJ { short entity_class; // 0x0 char p_link; // 0x2 char gx_link; // 0x3. 0-63 are gx. 64+ are reserved for camera objects char p_priority; // 0x4 char gx_pri; // 0x5 char obj_kind; // 0x6 char data_kind; // 0x7 GOBJ *next; // 0x8 GOBJ *previous; // 0xC GOBJ *nextOrdered; // 0x10 GOBJ *previousOrdered; // 0x14 GOBJProc *proc; // 0x18 void *gx_cb; // 0x1C u64 cobj_links; // 0x20. this is used to know which cobj to render to void *hsd_object; // 0x28 void *userdata; // 0x2C int destructor_function; // 0x30 int unk_linked_list; // 0x34 }; struct GOBJProc { GOBJ *parent; GOBJProc *next; GOBJProc *prev; char s_link; // 0xC char flags; // 0xD GOBJ *parentGOBJ; // 0x10 void (*cb)(GOBJ *gobj); // function callback }; struct GOBJList { // pointed to @ -0x3e74(r13) // indexed by p_link GOBJ *x0; GOBJ *x4; GOBJ *x8; GOBJ *xc; GOBJ *x10; GOBJ *cobj; GOBJ *x18; GOBJ *x1c; GOBJ *fighter; GOBJ *item; GOBJ *x28; GOBJ *effect_model; // 0x2c GOBJ *effect_unk; // 0x30, used for blastzone effect GOBJ *x34; GOBJ *x38; GOBJ *x3c; GOBJ *x40; GOBJ *x44; GOBJ *match_cam; // 0x48, used for the match camera and shake gobjs }; struct GXList { // pointed to @ -0x3e80(r13) GOBJ *gx_render[63]; // pointer to 63 gobjs GOBJ *gx_camera; // pointer to the highest priority cobj gobj. they are linked together via the next member. }; struct TOBJ { int *parent; int x4; TOBJ *next; u32 id; //GXTexMapID u32 src; //GXTexGenSrc 0x10 u32 mtxid; // 0x14 Vec4 rotate; // 0x18 Vec3 scale; // 0x28 Vec3 translate; // 0x34 u32 wrap_s; // 0x40 GXTexWrapMode u32 wrap_t; // 0x44 GXTexWrapMode u8 repeat_s; // 0x48 u8 repeat_t; // 0x49 u16 anim_id; // 0x4A u32 flags; // 0x4C f32 blending; // 0x50 u32 magFilt; // 0x54 GXTexFilter struct _HSD_ImageDesc *imagedesc; // 0x58 struct _HSD_Tlut *tlut; // 0x5C struct _HSD_TexLODDesc *lod; // 0x60 AOBJ *aobj; // 0x64 struct _HSD_ImageDesc **imagetbl; struct _HSD_Tlut **tluttbl; u8 tlut_no; Mtx mtx; u32 coord; //GXTexCoordID struct _HSD_TObjTev *tev; }; struct AOBJ { u32 flags; f32 curr_frame; f32 rewind_frame; f32 end_frame; f32 framerate; struct _HSD_FObj *fobj; struct _HSD_Obj *hsd_obj; }; struct MOBJ { int *parent; u32 rendermode; TOBJ *tobj; HSD_Material *mat; struct _HSD_PEDesc *pe; AOBJ *aobj; /* struct _HSD_TObj *ambient_tobj; struct _HSD_TObj *specular_tobj; */ struct _HSD_TExpTevDesc *tevdesc; union _HSD_TExp *texp; struct _HSD_TObj *tobj_toon; struct _HSD_TObj *tobj_gradation; struct _HSD_TObj *tobj_backlight; f32 z_offset; }; struct JOBJDesc { char *class_name; //0x00 u32 flags; //0x04 struct JOBJDesc *child; //0x08 struct JOBJDesc *next; //0x0C union { struct _HSD_DObjDesc *dobjdesc; struct _HSD_Spline *spline; struct _HSD_SList *ptcl; } u; //0x10 Vec3 rotation; //0x14 - 0x1C Vec3 scale; //0x20 - 0x28 Vec3 position; //0x2C - 0x34 Mtx mtx; //0x38 struct _HSD_RObjDesc *robjdesc; //0x3C }; struct COBJDesc { char *class_name; //0x00 u16 flags; //0x04 u16 projection_type; //0x06 u16 viewport_left; //0x08 u16 viewport_right; //0x0A u16 viewport_top; //0x0C u16 viewport_bottom; //0x0E u32 scissor_lr; //0x10 u32 scissor_tb; //0x14 struct _HSD_WObjDesc *eye_desc; //0x18 struct _HSD_WObjDesc *interest_desc; //0x1C f32 roll; //0x20 Vec3 *vector; //0x24 f32 near; //0x28 f32 far; //0x2C union { struct { f32 fov; f32 aspect; } perspective; struct { f32 top; f32 bottom; f32 left; f32 right; } frustrum; struct { f32 top; f32 bottom; f32 left; f32 right; } ortho; } projection_param; }; struct DOBJ { int parent; DOBJ *next; //0x04 MOBJ *mobj; //0x08 int *pobj; //0x0C AOBJ *aobj; //0x10 u32 flags; //0x14 u32 unk; }; struct JOBJ { int hsd_info; //0x0 int class_parent; //0x4 JOBJ *sibling; //0x08 JOBJ *parent; //0x0C JOBJ *child; //0x10 int flags; //0x14 DOBJ *dobj; //0x18 Vec4 rot; //0x1C 0x20 0x24 0x28 Vec3 scale; //0x2C Vec3 trans; Mtx rotMtx; Vec3 *VEC; Mtx *MTX; AOBJ *aobj; int *RObj; JOBJDesc *desc; }; struct WOBJ { void *parent; u32 flags; //0x08 Vec3 pos; //0xC AOBJ *aobj; //0x18 void *robj; //0x1C }; struct COBJ { u64 parent; // 0x0 u32 flags; //0x08 f32 viewport_left; //0x0C f32 viewport_right; //0x10 f32 viewport_top; //0x14 f32 viewport_bottom; //0x18 u16 scissor_left; //0x1C u16 scissor_right; //0x1E u16 scissor_top; //0x20 u16 scissor_bottom; //0x22 WOBJ *eye_position; //0x24 WOBJ *interest; //0x28 union { f32 roll; //0x28 Vec3 up; //0x2C - 0x38 } u; f32 near; //0x3C f32 far; //0x40 union { struct { f32 fov; f32 aspect; } perspective; struct { f32 top; f32 bottom; f32 left; f32 right; } frustrum; struct { f32 top; f32 bottom; f32 left; f32 right; } ortho; } projection_param; u8 projection_type; //0x50 Mtx view_mtx; //0x54 AOBJ *aobj; //0x84 Mtx proj_mtx; //0x88 }; struct _HSD_ImageDesc { void *img_ptr; u16 width; u16 height; u32 format; u32 mipmap; f32 minLOD; f32 maxLOD; }; struct _HSD_LightPoint { f32 cutoff; u8 point_func; f32 ref_br; f32 ref_dist; u8 dist_func; }; struct _HSD_LightPointDesc { f32 cutoff; u8 point_func; f32 ref_br; f32 ref_dist; u8 dist_func; }; struct _HSD_LightSpot { f32 cutoff; u8 spot_func; f32 ref_br; f32 ref_dist; u8 dist_func; }; struct _HSD_LightSpotDesc { f32 cutoff; u8 spot_func; f32 ref_br; f32 ref_dist; u8 dist_func; }; struct _HSD_LightAttn { f32 a0; f32 a1; f32 a2; f32 k0; f32 k1; f32 k2; }; struct LOBJ { u64 parent; //0x00 u16 flags; //0x08 u16 priority; //0x0A struct LOBJ *next; //0x0C GXColor color; //0x10 GXColor hw_color; //0x14 WOBJ *position; //0x18 WOBJ *interest; //0x1C union { _HSD_LightPoint point; _HSD_LightSpot spot; _HSD_LightAttn attn; } u; f32 shininess; Vec3 lvec; struct AOBJ *aobj; u32 id; //GXLightID //GXLightObj lightobj; //0x50 u32 spec_id; //0x90 GXLightID //GXLightObj spec_lightobj; //0x94 }; struct JOBJAnimSet { JOBJDesc *jobj; void *animjoint; void *matanimjoint; void *shapeaninjoint; }; /*** Static Variables ***/ GOBJList **stc_gobj_list = R13 + (-0x3E74); u8 *obj_kind = R13 + -(0x3E55); /*** Functions ***/ int JOBJ_GetWorldPosition(JOBJ *source, Vec3 *add, Vec3 *dest); void JOBJ_SetMtxDirtySub(JOBJ *jobj); JOBJ *JOBJ_LoadJoint(JOBJDesc *joint); void JOBJ_RemoveAll(JOBJ *joint); void JOBJ_Remove(JOBJ *joint); void JOBJ_GetChild(JOBJ *joint, int ptr, int index, ...); void JOBJ_AddChild(JOBJ *parent, JOBJ *child); float JOBJ_GetCurrentMatAnimFrame(JOBJ *joint); void JOBJ_SetFlags(JOBJ *joint, int flags); void JOBJ_SetFlagsAll(JOBJ *joint, int flags); void JOBJ_ClearFlags(JOBJ *joint, int flags); void JOBJ_ClearFlagsAll(JOBJ *joint, int flags); void JOBJ_BillBoard(JOBJ *joint, Mtx *m, Mtx *mx); void JOBJ_RunAOBJCallback(JOBJ *joint, int unk, u16 flags, void *cb, int argkind, ...); // flags: 0x400 matanim, 0x20 jointanim, argkind specifies how to pop args off the va_list void JOBJ_Anim(JOBJ *joint); void JOBJ_AnimAll(JOBJ *joint); void JOBJ_AddAnimAll(JOBJ *joint, void *animjoint, void *matanimjoint, void *shapeanimjoint); void JOBJ_RemoveAnimAll(JOBJ *joint); void JOBJ_ReqAnim(JOBJ *joint, float frame); void JOBJ_ReqAnimByFlags(JOBJ *joint, int flags, float frame); void JOBJ_ReqAnimAll(JOBJ *joint, float unk); void JOBJ_ReqAnimAllByFlags(JOBJ *joint, int flags, float frame); float JOBJ_GetJointAnimFrameTotal(JOBJ *joint); float JOBJ_GetJointAnimNextFrame(JOBJ *joint); void JOBJ_SetAllMOBJFlags(JOBJ *joint, int flags); int JOBJ_CheckAObjEnd(JOBJ *joint); void AOBJ_ReqAnim(int *aobj, float unk); void AOBJ_StopAnim(JOBJ *jobj, int flags, int flags2); void AOBJ_SetRate(AOBJ *aobj, float rate); void DOBJ_SetFlags(DOBJ *dobj, int flags); void DOBJ_ClearFlags(DOBJ *dobj, int flags); COBJ *COBJ_LoadDesc(COBJDesc *cobj); COBJ *COBJ_LoadDescSetScissor(COBJDesc *cobj); COBJ *COBJ_GetMatchCamera(); void CObjThink_Common(GOBJ *gobj); GOBJ *GObj_Create(int type, int subclass, int flags); void GObj_Destroy(GOBJ *gobj); void GObj_AddGXLink(GOBJ *gobj, void *cb, int gx_link, int gx_pri); void GObj_DestroyGXLink(GOBJ *gobj); void GObj_GXReorder(GOBJ *gobj, int unk); void GObj_AddProc(GOBJ *gobj, void *callback, int priority); void GObj_RemoveProc(GOBJ *gobj); void GObj_AddObject(GOBJ *gobj, u8 unk, void *object); void GObj_FreeObject(GOBJ *gobj); void GObj_AddUserData(GOBJ *gobj, int userDataKind, void *destructor, void *userData); void GOBJ_InitCamera(GOBJ *gobj, void *cb, int gx_pri); void GXLink_Common(GOBJ *gobj, int pass); void GXLink_LObj(GOBJ *gobj, int pass); void GXLink_Fog(GOBJ *gobj, int pass); void *LObj_LoadDesc(void *lobjdesc); void *Fog_LoadDesc(void *fogdesc); DOBJ *JOBJ_GetDObj(JOBJ *jobj); void *MOBJ_SetAlpha(DOBJ *dobj); void GObj_CopyGXPri(GOBJ *target, GOBJ *source); #endif ================================================ FILE: MexTK/include/offsets.h ================================================ #ifndef MEX_H_OFFSETS #define MEX_H_OFFSETS #define R13 0x804db6a0 #define STAGE_CONST -0x4C08 // this is an offset used on dreamland, should be safe to use for custom stages #define MEMCARD -0x77C0 #define GOBJLIST -0x3E74 #define PLCO_SHIELDCOLORS -0x5190 #define PLCO_FTCOMMON -0x514C #define STAGE 0x8049e6c8 // this is the static stage struct, labelled Stage in this file #define EVMENU_ASSETS -0x4A08 #define HSD_UPDATE 0x80479d58 #define COLL_TEST -0x51f4 #define MATCH_HUD 0x804a10c8 #define COBJDESC_MATCHHUD 0x80b52980 #define MATCH_CAM 0x80452c68 #define MATCH 0x8046b6a0 #endif ================================================ FILE: MexTK/include/preload.h ================================================ #ifndef MEX_H_PRELOAD #define MEX_H_PRELOAD #include "structs.h" #include "datatypes.h" struct PreloadChar { int kind; u8 costume; }; struct Preload { int x0; int x4; u8 xc; int stage; PreloadChar fighters[8]; int defragNum; }; /*** Functions ***/ void Preload_Update(); // checks for new files to preload and begins loading them synchronously Preload *Preload_GetTable(); // gets preload table #endif ================================================ FILE: MexTK/include/result.h ================================================ #ifndef MEX_H_RESULT #define MEX_H_RESULT #include "structs.h" #include "datatypes.h" struct RstPlayer { u8 type; // x0 (0x00 is HMN, 0x01 is CPU, 0x02 is Demo, 0x03 n/a) u8 ext_id; // x1 (external fighter id) u8 kind; // x2 internal id u8 costume : 6; // x3 costume id u8 is_rumble : 1; // x3 rumble flag u8 is_stamina : 1; // x3 stamina flag u8 nametag; // x4 nametag index u8 x5; // x5 u8 x6; // x6 u8 team; // x7 team id u8 stock_num; // x8 remaining stocks u8 hp; // x9 remaining hp u8 sd_num; // xa times self destructed u8 fall_num; // xb times died u16 dmg_num; // unk u16 xe; // absolutely dont know, takes stick inputs and scene into account?? int x10; // unk int x14; // unk int x18; // unk int coins; // x1c int x20; // unk int x24; // unk int frames_alive; // unk int x2c; // unk int x30; // unk int x34; // unk int hits_landed; // x38 int attack_num; // x3c total attacks int x40; // unk int x44; // unk int x48; // unk int x4c; // unk int x50; // unk int x54; // unk int x58; // unk int x5c; // unk int x60; // unk int x64; // unk int x68; // unk int x6c; // unk int x70; // unk int x74; // unk int x78; // unk int x7c; // unk int x80; // unk int x84; // unk int x88; // unk int ledgegrab_num; // x8c int x90; // unk int x94; // unk int x98; // unk int x9c; // unk int xa0; // unk int xa4; // unk }; struct RstInit { int x0; u8 end_kind; // how the match ended. (0x2 = GAME!, 0x1 = TIME!, and 0x7 = no contest) u8 x5; // unk u8 match_kind; // 0 = ffa, 1 = teams int match_frames; // how many frames passed in the match u8 xc; // unk u8 winner_num; // is greater than 1 when a tie occurs u8 placings[4]; // array of player indices in order of placement int x10; // unk int x14; // unk int x18; // unk int x1c; // unk, totals up 0x88 of rstplayer u8 x20; // unk u8 x21; // unk u8 x22; // unk u8 x23; // unk int x24; // unk int x28; // unk int x2c; // unk int x30; // unk int x34; // unk int x38; // unk int x3c; // unk int x40; // unk int x44; // unk int x48; // unk int x4c; // unk int x50; // unk RstPlayer players[6]; // unk }; #endif ================================================ FILE: MexTK/include/scene.h ================================================ #ifndef MEX_H_SCENE #define MEX_H_SCENE #include "structs.h" #include "datatypes.h" #include "match.h" #include "result.h" // Scene Enums enum HEAP_KIND { HEAPKIND_UNK0, HEAPKIND_UNK1, HEAPKIND_UNK2, HEAPKIND_UNK3, HEAPKIND_UNK4, }; enum MINOR_KIND { MNRKIND_TITLE, // Title Screen MNRKIND_MNMA, // Main Menu MNRKIND_MATCH, // VS Dairantou (In-Game) MNRKIND_SUDDEATH, // Sudden Death Dairantou (In-Game) MNRKIND_TRAIN, // Training Mode Dairantou (In-Game) MNRKIND_RST, // Result Screen MNRKIND_X6, // MNRKIND_DB, // Debug Menu MNRKIND_CSS, // CSS MNRKIND_SSS, // SSS MNRKIND_XA, // MNRKIND_TYGAL, // Trophy Gallery MNRKIND_TYLOT, // Trophy Lottery MNRKIND_TYCOL, // Trophy Collection MNRKIND_ADVSPLSH, // Adventure Mode Splash Screen MNRKIND_TYFALL, // 1P Mode Trophy Falling Cutscene MNRKIND_ADVCGRT, // Adventure Mode Congratulations MNRKIND_VI1, // VisualScene_Luigi MNRKIND_VI2, // VisualScene_BrinstarLava MNRKIND_VI3, // VisualScene_PlanetExplode MNRKIND_VI4, // VisualScene_3KirbysSpawn MNRKIND_VI5, // VisualScene_GiantKirbySpawns MNRKIND_VI6, // VisualScene_StarFoxDialog MNRKIND_VI7, // VisualScene_FZeroRace MNRKIND_VI8, // VisualScene_MetalMarioLuigi MNRKIND_VI9, // VisualScene_BowserTrophyFalls MNRKIND_VI10, // VisualScene_GigaBowserTransformation MNRKIND_VI11, // VisualScene_GigaBowserDefeated MNRKIND_OP, // Opening Movie MNRKIND_1PENDMV, // 1P Mode End Movie MNRKIND_HOWMV, // How to Play Movie MNRKIND_OMAKE, // Special Movie MNRKIND_CLSCSPLSH, // TEST MNRKIND_ALSPLSH, // TEST MNRKIND_GMOV, // Game over MNRKIND_SOON, // coming soon MNRKIND_TOSETUP, // tournament setup MNRKIND_TOBRCK, // tourn bracket MNRKIND_TOUNK, // tourn unk MNRKIND_SPCLMSG, // special msg MNRKIND_PROG, // progressive MNRKIND_CHLG, // challenger MNRKIND_CARD, // memcard prompt MNRKIND_STAFF, // credits MNRKIND_CAMWARN, // camera mode memcard prompt MNRKIND_NULL, // terminator MNRKIND_SMSHDWNCSS, // custom smashdown css }; struct MajorScene { u8 is_preload; u8 major_id; void *onLoad; void *onExit; void *onBoot; void *MinorScene; // array of minor scenes }; struct MinorScene { u8 minor_id; // is 255 for last entry u8 heap_kind; // heap behavior void *minor_prep; // inits data for this minor (major exclusive) void *minor_decide; // decides next minor scene u8 minor_kind; // index for a re-useable list of scene functions. contains a load, think, and leave function. void *load_data; // points to static data used throughout this minor. other minors may use the same pointer to exchange data between minors void *unload_data; // points to static data used throughout this minor. other minors may use the same pointer to exchange data between minors }; struct ScDataVS { u8 x8; u8 x9; u8 xa; int xc; MatchInit match_init; }; struct ScDataRst { int x0; int x4; int x8; int xc; RstInit rst_init; }; void Scene_EnterMajor(int major_id); void CSS_DecideNext(MinorScene *minor_scene, ScDataVS *css_data); void CSS_ResetKOStars(); void CSS_InitMajorData(ScDataVS *major_data); void CSS_InitMinorData(MinorScene *minor_scene, ScDataVS *major_data, int css_kind); void SSS_InitMinorData(MinorScene *minor_scene, ScDataVS *major_data); void Match_InitMinorData(MinorScene *minor_scene, ScDataVS *major_data, void *init_cb, void *startmelee_cb); void Match_SetNametags(MatchInit *match_init); #endif ================================================ FILE: MexTK/include/stage.h ================================================ #ifndef MEX_H_STAGE #define MEX_H_STAGE #include "structs.h" #include "datatypes.h" #include "hsd.h" #include "obj.h" // map_gobjDesc Flags #define map_isBG 0x40000000 #define map_isUnk 0x80000000 enum GrInternal { GR_DUMMY, GR_TEST, GR_CASTLE, GR_RCRUISE, GR_KONGO, GR_GARDEN, GR_GREATBAY, GR_SHRINE, GR_ZEBES, GR_KRAID, GR_STORY, GR_YOSTER, GR_IZUMI, GR_GREENS, GR_CORNERIA, GR_VENOM, GR_PSTAD, GR_PURA, GR_MUTECITY, GR_BIGBLUE, GR_ONETT, GR_FOURSIDE, GR_ICEMT, GR_ICETOP, GR_MK1, GR_MK2, GR_AKANEIA, GR_FLATZONE, GR_OLDPU, GR_OLDSTORY, GR_OLDKONGO, GR_ADVKRAID, GR_ADVSHRINE, GR_ADVZR, GR_ADVBR, GR_ADVTE, GR_BATTLE, GR_FD, }; /*** Structs ***/ struct map_gobjDesc { void *(*onCreation)(GOBJ *map); void *onDeletion; void *onFrame; void *onUnk; int flags; }; struct map_gobjData { int x0; // 0x0 GOBJ *gobj; // 0x4 int x8; // 0x8 int xC; // 0xC unsigned char flagx80 : 1; // 0x80 unsigned char flagx40 : 1; // 0x40 unsigned char isFog : 1; // 0x20, checked @ 801c5e80 and 801c5f10 unsigned char flagx10 : 1; // 0x10 unsigned char flagx8 : 1; // 0x08 unsigned char gx_unk1 : 1; // 0x04, checked @ 801c5e9c unsigned char flagx2 : 1; // 0x02 unsigned char flagx1 : 1; // 0x01 unsigned char gx_unk2 : 3; // 0x80 unsigned char flag2x10 : 1; // 0x10 unsigned char flag2x08 : 1; // 0x08 unsigned char flag2x04 : 1; // 0x04, checked @ 801c5e9c unsigned char flag2x02 : 1; // 0x02 unsigned char flag2x01 : 1; // 0x01 int map_gobjID; // 0x14 int x18; // 0x18 int onUnk; // 0x1c int x20; // 0x20 int x24; // 0x24 int stateID; // 0x28 int facingDirection; // 0x2c int x30; // 0x30 int x34; // 0x34 float scale; // 0x38 int x3c; // 0x3c float selfVelX; // 0x40 float selfVelY; // 0x44 float selfVelZ; // 0x48 float posX; // 0x4c float posY; // 0x50 float posZ; // 0x54 int x58; // 0x58 int x5c; // 0x5c int x60; // 0x60 int x64; // 0x64 int x68; // 0x68 int x6c; // 0x6c int x70; // 0x70 int x74; // 0x74 int x78; // 0x78 int x7c; // 0x7c int x80; // 0x80 int x84; // 0x84 int x88; // 0x88 int x8c; // 0x8c int x90; // 0x90 int x94; // 0x94 int x98; // 0x98 int x9c; // 0x9c int xa0; // 0xa0 int xa4; // 0xa4 int xa8; // 0xa8 int xac; // 0xac int xb0; // 0xb0 int xb4; // 0xb4 int xb8; // 0xb8 int xbc; // 0xbc int xc0; // 0xc0 u8 xc4; // 0xc4 u8 xc5; // 0xc5 u8 xc6; // 0xc6 u8 xc7; // 0xc7 int xc8; // 0xc8 int xcc; // 0xcc int xd0; // 0xd0 int xd4; // 0xd4 int xd8; // 0xd8 int xdc; // 0xdc struct { int mapVar0; // 0xe0 int mapVar1; // 0xe4 int mapVar2; // 0xe8 int mapVar3; // 0xec int mapVar4; // 0xf0 int mapVar5; // 0xf4 int mapVar6; // 0xf8 int mapVar7; // 0xfc int x100; // 0x100 int x104; // 0x104 int x108; // 0x108 int x10c; // 0x10c int x110; // 0x110 int x114; // 0x114 int x118; // 0x118 int x11c; // 0x11c int x120; // 0x120 int x124; // 0x124 int x128; // 0x128 int x12c; // 0x12c int x130; // 0x130 int x134; // 0x134 int x138; // 0x138 int x13c; // 0x13c int x140; // 0x140 int x144; // 0x144 int x148; // 0x148 int x14c; // 0x14c int x150; // 0x150 int x154; // 0x154 int x158; // 0x158 int x15c; // 0x15c int x160; // 0x160 int x164; // 0x164 int x168; // 0x168 int x16c; // 0x16c int x170; // 0x170 int x174; // 0x174 int x178; // 0x178 int x17c; // 0x17c int x180; // 0x180 int x184; // 0x184 int x188; // 0x188 int x18c; // 0x18c int x190; // 0x190 int x194; // 0x194 int x198; // 0x198 int x19c; // 0x19c int x1a0; // 0x1a0 int x1a4; // 0x1a4 int x1a8; // 0x1a8 int x1ac; // 0x1ac int x1b0; // 0x1b0 int x1b4; // 0x1b4 int x1b8; // 0x1b8 int x1bc; // 0x1bc int x1c0; // 0x1c0 int x1c4; // 0x1c4 int x1c8; // 0x1c8 int x1cc; // 0x1cc int x1d0; // 0x1d0 int x1d4; // 0x1d4 int x1d8; // 0x1d8 int x1dc; // 0x1dc int x1e0; // 0x1e0 int x1e4; // 0x1e4 int x1e8; // 0x1e8 int x1ec; // 0x1ec int x1f0; // 0x1f0 int x1f4; // 0x1f4 int x1f8; // 0x1f8 int x1fc; // 0x1fc int x200; // 0x200 } map_struct; }; struct StageOnGO { StageOnGO *next; GOBJ *map_gobj; void *cb; }; struct Stage { float cam_LeftBound; // 0x0 float cam_RightBound; // 0x4 float cam_TopBound; // 0x8 float cam_BottomBound; // 0xc float cam_HorizOffset; // 0x10 float crowdReactStart; // 0x14, begins checking for crowd gasps below this position float fov_d; // 0x18 float fov_u; // 0x1c float fov_r; // 0x20, actually horizontal rotation? float fov_l; // 0x24 float x28; // 0x28 float x2c; // 0x2c float x30; // 0x30 float x34; // 0x34, camera distance min float x38; // 0x38 float x3c; // 0x3c float x40; // 0x40 int x44; // 0x44 int x48; // 0x48 int x4c; // 0x4c int x50; // 0x50 int x54; // 0x54 int x58; // 0x58 int x5c; // 0x5c int x60; // 0x60 int x64; // 0x64 int x68; // 0x68 int x6c; // 0x6c int x70; // 0x70 float blastzoneLeft; // 0x74 float blastzoneRight; // 0x78 float blastzoneTop; // 0x7c float blastzoneBottom; // 0x80 int flags; // 0x84 int stageID; // 0x88 int flags2; // 0x8c int x90; // 0x90 int x94; // 0x94 int hpsID; // 0x98 int x9c; // 0x9c int xa0; // 0xa0 int xa4; // 0xa4 int xa8; // 0xa8 int xac; // 0xac int xb0; // 0xb0 int xb4; // 0xb4 int xb8; // 0xb8 int xbc; // 0xbc int xc0; // 0xc0 int xc4; // 0xc4 int xc8; // 0xc8 int xcc; // 0xcc int xd0; // 0xd0 int xd4; // 0xd4 int xd8; // 0xd8 int xdc; // 0xdc int xe0; // 0xe0 int xe4; // 0xe4 int xe8; // 0xe8 int xec; // 0xec int xf0; // 0xf0 int xf4; // 0xf4 int xf8; // 0xf8 int xfc; // 0xfc int x100; // 0x100 int x104; // 0x104 int x108; // 0x108 int x10c; // 0x10c int x110; // 0x110 int x114; // 0x114 int x118; // 0x118 int x11c; // 0x11c int x120; // 0x120 int x124; // 0x124 int x128; // 0x128 int x12c; // 0x12c int x130; // 0x130 int x134; // 0x134 int x138; // 0x138 int x13c; // 0x13c int x140; // 0x140 int x144; // 0x144 int x148; // 0x148 int x14c; // 0x14c int x150; // 0x150 int x154; // 0x154 int x158; // 0x158 int x15c; // 0x15c int x160; // 0x160 int x164; // 0x164 int x168; // 0x168 int x16c; // 0x16c int x170; // 0x170 int x174; // 0x174 int x178; // 0x178 int x17c; // 0x17c GOBJ *map_gobjs[64]; JOBJ *general_points[256]; // 0x280 int x680; // 0x680 int x684; // 0x684 int x688; // 0x688 int x68c; // 0x68c int x690; // 0x690 int x694; // 0x694 int x698; // 0x698 int x69c; // 0x69c int x6a0; // 0x6a0 StageOnGO *on_go; // 0x6a4 int *itemData; // 0x6a8 int *coll_data; // 0x6ac int *grGroundParam; // 0x6b0 int *ALDYakuAll; // 0x6b4 int *map_ptcl; // 0x6b8 int *map_texg; // 0x6bc int *yakumono_param; // 0x6c0 int *map_plit; // 0x6c4 int *x6c8; // 0x6c8 void *quake_model_set; // 0x6cc int *x6d0; // 0x6d0 int *targetsRemaining; // 0x6d4 int x6d8; // 0x6d8 int x6dc; // 0x6dc int x6e0; // 0x6e0 int x6e4; // 0x6e4 int x6e8; // 0x6e8 int x6ec; // 0x6ec int x6f0; // 0x6f0 int x6f4; // 0x6f4 int x6f8; // 0x6f8 int x6fc; // 0x6fc int x700; // 0x700 int x704; // 0x704 int x708; // 0x708 int x70c; // 0x70c int x710; // 0x710 int x714; // 0x714 int x718; // 0x718 int x71c; // 0x71c int x720; // 0x720 int x724; // 0x724 int x728; // 0x728 int x72C; // 0x728 }; struct MapHead { int *general_points; int general_points_num; int *map_gobjs; // pointer to array of map_gobjs int map_gobj_num; int *splines; int splines_num; int *lights; int lights_num; }; struct StageFile { ArchiveInfo *archive_info; MapHead *map_head; }; /*** Functions ***/ StageFile *Stage_GetStageFiles(); // returns an array of StageFiles StageFile *Stage_GetStageFile(int mapgobj_index); // returns the StageFile the ID belongs to void Stage_AddFtChkDevice(GOBJ *map, int hazard_kind, void *check); void Stage_SetChkDevicePos(float y_pos); void Stage_GetChkDevicePos(float *y_pos, float *y_delta); float Stage_GetScale(); int *Stage_GetYakumonoParam(); void Stage_MapStateChange(GOBJ *map, int map_gobjID, int anim_id); void Dynamics_DecayWind(); GOBJ *Stage_CreateMapGObj(int mapgobjID); void Stage_DestroyMapGObj(GOBJ *map_gobj); void *GXLink_Stage(GOBJ *gobj, int pass); GOBJ *Stage_GetMapGObj(int mapgobjID); JOBJ *Stage_GetMapGObjJObj(GOBJ *mapgobj, int jointIndex); int Stage_GetLinesGroup(int line); int Stage_GetLinesDirection(int line); void Stage_SetGroundCallback(int line, void *userdata, void *callback); void Stage_SetCeilingCallback(int line, void *userdata, void *callback); void Stage_InitMovingColl(JOBJ *mapjoint, int mapgobjID); void Stage_UpdateMovingColl(GOBJ *mapgobj); Particle *Stage_SpawnEffectPos(int gfxID, int efFileID, Vec3 *pos); Particle *Stage_SpawnEffectJointPos(int gfxID, int efFileID, JOBJ *pos); Particle *Stage_SpawnEffectJointPos2(int gfxID, int efFileID, JOBJ *pos); GOBJ *Zako_Create(int item_id, Vec3 *pos, JOBJ *jobj, Vec3 *velocity, int isMovingItem); GOBJ *Stage_CreateMapItem(map_gobjData *map_data, int takeDamageSFXKind, int state, JOBJ *joint, Vec3 *pos, int unk_bool, void *onGiveDamage, void *onTakeDamage); // this function creates an item of id 0xA0, its a generic ID used across multiple stages. its mainly used for giving a joint a hurtbox/hitbox and an onTakeDamage callback. int Stage_CheckForNearbyFighters(Vec3 *pos, float radius); float Stage_GetBlastzoneRight(); float Stage_GetBlastzoneLeft(); float Stage_GetBlastzoneTop(); float Stage_GetBlastzoneBottom(); float Stage_GetCameraRight(); float Stage_GetCameraLeft(); float Stage_GetCameraTop(); float Stage_GetCameraBottom(); void Stage_GetGeneralPoint(int index, Vec3 *pos); void Stage_EnableLineGroup(int index); void Stage_DisableLineGroup(int index); int Stage_GetExternalID(); int Stage_ExternalToInternal(int ext_id); Stage *stc_stage = 0x8049e6c8; int *ftchkdevice_windnum = R13 + (-0x5128); int *ftchkdevice_grabnum = R13 + (-0x512C); int *ftchkdevice_dmgnum = R13 + (-0x5130); #endif ================================================ FILE: MexTK/include/structs.h ================================================ #ifndef MEX_H_STRUCTS #define MEX_H_STRUCTS /* * defines typedefs for structs used throughout m-ex */ // Basic Data Structs typedef struct Vec2 Vec2; typedef struct Vec3 Vec3; typedef struct Vec4 Vec4; // OS typedef struct OSInfo OSInfo; typedef struct OSCalendarTime OSCalendarTime; typedef struct CARDStat CARDStat; typedef struct CARDFileInfo CARDFileInfo; typedef struct RGB565 RGB565; // HSD Objects typedef struct GOBJ GOBJ; typedef struct GOBJProc GOBJProc; typedef struct GOBJList GOBJList; typedef struct GXList GXList; typedef struct JOBJ JOBJ; typedef struct JOBJDesc JOBJDesc; typedef struct DOBJ DOBJ; typedef struct TOBJ TOBJ; typedef struct AOBJ AOBJ; typedef struct MOBJ MOBJ; typedef struct WOBJ WOBJ; typedef struct COBJ COBJ; typedef struct COBJDesc COBJDesc; typedef struct _HSD_ImageDesc _HSD_ImageDesc; typedef struct _HSD_LightPoint _HSD_LightPoint; typedef struct _HSD_LightPointDesc _HSD_LightPointDesc; typedef struct _HSD_LightSpot _HSD_LightSpot; typedef struct _HSD_LightSpotDesc _HSD_LightSpotDesc; typedef struct _HSD_LightAttn _HSD_LightAttn; typedef struct LOBJ LOBJ; typedef struct JOBJAnimSet JOBJAnimSet; // Archive typedef struct ArchiveInfo ArchiveInfo; typedef struct MapHead MapHead; // Stage typedef struct Stage Stage; typedef struct StageOnGO StageOnGO; typedef struct map_gobjData map_gobjData; typedef struct map_gobjDesc map_gobjDesc; typedef struct StageFile StageFile; // Match typedef struct MatchInit MatchInit; typedef struct Match Match; typedef struct MatchHUD MatchHUD; typedef struct MatchCamera MatchCamera; typedef struct CameraBox CameraBox; typedef struct MatchOffscreen MatchOffscreen; // Text typedef struct Text Text; typedef struct TextAllocInfo TextAllocInfo; // DevText typedef struct DevText DevText; // Effects typedef struct Effect Effect; typedef struct Particle Particle; typedef struct Particle2 Particle2; typedef struct ptclGen ptclGen; typedef struct GeneratorAppSRT GeneratorAppSRT; // Color typedef struct GXColor GXColor; typedef struct ColorOverlay ColorOverlay; // Item typedef struct ItemData ItemData; typedef struct ItemState ItemState; typedef struct SpawnItem SpawnItem; typedef struct itData itData; typedef struct itCommonAttr itCommonAttr; typedef struct itHit itHit; // Fighter typedef struct FighterData FighterData; typedef struct FighterBone FighterBone; typedef struct Playerblock Playerblock; typedef struct PlayerData PlayerData; typedef struct MoveLogic MoveLogic; typedef struct SubactionHeader SubactionHeader; typedef struct ftHit ftHit; typedef struct HitVictim HitVictim; typedef struct FtHurt FtHurt; typedef struct ReflectDesc ReflectDesc; typedef struct ShieldDesc ShieldDesc; typedef struct AbsorbDesc AbsorbDesc; typedef struct CPU CPU; typedef struct ftData ftData; typedef struct ftCommonData ftCommonData; typedef struct ftChkDevice ftChkDevice; typedef struct FtSymbolLookup FtSymbolLookup; typedef struct FtSymbols FtSymbols; typedef struct FtParts FtParts; typedef struct FtPartsDesc FtPartsDesc; typedef struct FtDOBJUnk FtDOBJUnk; typedef struct FtPartsLookup FtPartsLookup; typedef struct FtDOBJUnk2 FtDOBJUnk2; typedef struct FtDOBJUnk3 FtDOBJUnk3; typedef struct FtDynamicBoneset FtDynamicBoneset; typedef struct FtDynamicRoot FtDynamicRoot; typedef struct FtDynamicHit FtDynamicHit; typedef struct DynamicsDesc DynamicsDesc; typedef struct DynamicsHitDesc DynamicsHitDesc; typedef struct DynamicsBehave DynamicsBehave; typedef struct ftDynamics ftDynamics; // Fighter States typedef struct FtCliffCatch FtCliffCatch; // CSS typedef struct CSSBackup CSSBackup; typedef struct MnSelectChrDataTable MnSelectChrDataTable; typedef struct VSMinorData VSMinorData; typedef struct CSSCursor CSSCursor; typedef struct CSSPuck CSSPuck; typedef struct MnSlChrData MnSlChrData; typedef struct MnSlChrIcon MnSlChrIcon; typedef struct MnSlChrDoor MnSlChrDoor; typedef struct MnSlChrTag MnSlChrTag; typedef struct MnSlChrTagData MnSlChrTagData; typedef struct MnSlChrKOStar MnSlChrKOStar; // Memcard typedef struct Memcard Memcard; typedef struct MemcardWork MemcardWork; typedef struct MemcardUnk MemcardUnk; typedef struct MemcardSave MemcardSave; typedef struct MemcardInfo MemcardInfo; typedef struct SnapshotInfo SnapshotInfo; typedef struct SnapshotList SnapshotList; typedef struct MemSnapIconData MemSnapIconData; typedef struct Rules1 Rules1; // Collision typedef struct CollData CollData; typedef struct ECBBones ECBBones; typedef struct DmgHazard DmgHazard; typedef struct CollLineInfo CollLineInfo; typedef struct CollLine CollLine; typedef struct CollVert CollVert; typedef struct CollDataStage CollDataStage; typedef struct CollGroupDesc CollGroupDesc; typedef struct CollGroup CollGroup; // HSD typedef struct HSD_Material HSD_Material; typedef struct HSD_Pad HSD_Pad; typedef struct HSD_Pads HSD_Pads; typedef struct HSD_Update HSD_Update; typedef struct HSD_VI HSD_VI; typedef struct HSD_ObjAllocData HSD_ObjAllocData; // Scene typedef struct MajorScene MajorScene; typedef struct MinorScene MinorScene; typedef struct ScDataVS ScDataVS; typedef struct ScDataRst ScDataRst; // Results typedef struct RstPlayer RstPlayer; typedef struct RstInit RstInit; // Preload typedef struct Preload Preload; typedef struct PreloadChar PreloadChar; // Kirby typedef struct FtVarKirby FtVarKirby; // Custom typedef struct PRIM PRIM; typedef struct MEXPlaylist MEXPlaylist; typedef struct Translation Translation; #endif ================================================ FILE: MexTK/include/text.h ================================================ #ifndef MEX_H_TEXT #define MEX_H_TEXT #include "structs.h" #include "datatypes.h" #include "obj.h" #include "color.h" /*** Structs ***/ struct TextAllocInfo { u8 *curr; u8 *start; int size; }; struct Text { Vec3 trans; // 0x0-0xC Vec2 aspect; // 0xC-0x14 int x14; int x18; int x1c; int x20; Vec2 scale; // 0x24-0x2C int x2C; GXColor color; Vec2 stretch; // 0x34-0x3C int x3c; // 0x3c int x40; // 0x40 int x44; // 0x44 u8 use_aspect; // 0x48 u8 kerning; // 0x49 u8 align; // 0x4a u8 x4b; u8 x4c; u8 hidden; // 0x4D u8 x4e; u8 sis_id; // 0x4F, id of the premade text file to use int x50; GOBJ *gobj; // 0x54 void *callback; // 0x58, read at 803a878c u8 *textAlloc; // 0x5C u8 *textAlloc2; // 0x60 TextAllocInfo *allocInfo; // 0x64 }; /*** Functions ***/ int Text_CreateCanvas(int unk, GOBJ *gobj, int text_gobjkind, int text_gobjsubclass, int text_gobjflags, int text_gxlink, int text_gxpri, int cobj_gxpri); // the optional gobj and cobj_gxlink are used to create a cobj as well. set gobj Text *Text_CreateText(int SisIndex, int canvasID); Text *Text_CreateText2(int SisIndex, int canvasID, float pos_x, float pos_y, float pos_z, float limit_x, float limit_y); void Text_Destroy(Text *text); int Text_AddSubtext(Text *text, float xPos, float yPos, char *string, ...); void Text_SetScale(Text *text, int subtext, float x, float y); void Text_SetColor(Text *text, int subtext, GXColor *color); void Text_SetPosition(Text *text, int subtext, float x, float y); void Text_SetText(Text *text, int subtext, char *string, ...); int Text_ConvertToMenuText(char *buffer, char *string); u8 *Text_Alloc(int size); void Text_DestroyAlloc(u8 *alloc); void Text_DestroyAllAlloc(Text *text); int Text_StringToMenuText(u8 *out, char *in); void Text_GX(GOBJ *gobj, int pass); void Text_LoadSdFile(int index, char *filename, char *symbol); void Text_SetSisText(Text *text, int text_index); #endif ================================================ FILE: MexTK/include/useful.h ================================================ #ifndef MEX_H_USEFUL #define MEX_H_USEFUL #include #include "structs.h" #include "datatypes.h" #include "fighter.h" #include "devtext.h" // OS Macros #define OSRoundUp32B(x) (((u32)(x) + 32 - 1) & ~(32 - 1)) #define OSRoundDown32B(x) (((u32)(x)) & ~(32 - 1)) #define OSRoundUp512B(x) (((u32)(x) + 512 - 1) & ~(512 - 1)) // using this for card reads #define OSRoundDown512B(x) (((u32)(x)) & ~(512 - 1)) // using this for card reads #define OSTicksToMilliseconds(ticks) ((ticks) / (os_info->bus_clock / 1000)) #define BitCheck(num, bit) !!((num) & (1 << (bit))) // returns 0 or 1 #define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) #define assert(msg) __assert(__FILENAME__, __LINE__, msg) #define divide_roundup(dividend, divisor) ((dividend + (divisor / 2)) / divisor) #define MTXDegToRad(a) ((a)*0.01745329252f) #define MTXRadToDeg(a) ((a)*57.29577951f) /** Console Definitions */ // #define OS_CONSOLE_RETAIL4 0x00000004 #define OS_CONSOLE_RETAIL3 0x00000003 #define OS_CONSOLE_RETAIL2 0x00000002 #define OS_CONSOLE_RETAIL1 0x00000001 #define OS_CONSOLE_DEVHW4 0x10000007 #define OS_CONSOLE_DEVHW3 0x10000006 #define OS_CONSOLE_DEVHW2 0x10000005 #define OS_CONSOLE_DEVHW1 0x10000004 #define OS_CONSOLE_MINNOW 0x10000003 #define OS_CONSOLE_ARTHUR 0x10000002 #define OS_CONSOLE_PC_EMULATOR 0x10000001 #define OS_CONSOLE_EMULATOR 0x10000000 #define OS_CONSOLE_DEVELOPMENT 0x10000000 // bit mask #define CARD_MAX_FILE 127 #define CARD_FILENAME_MAX 32 #define CARD_ICON_MAX 8 #define CARD_COMMENT_SIZE 64 #define CARD_WORKAREA_SIZE (5 * 8 * 1024) #define CARD_READ_SIZE 512 #define CARD_RESULT_UNLOCKED 1 #define CARD_RESULT_READY 0 #define CARD_RESULT_BUSY -1 #define CARD_RESULT_WRONGDEVICE -2 #define CARD_RESULT_NOCARD -3 #define CARD_RESULT_NOFILE -4 #define CARD_RESULT_IOERROR -5 #define CARD_RESULT_BROKEN -6 #define CARD_RESULT_EXIST -7 #define CARD_RESULT_NOENT -8 #define CARD_RESULT_INSSPACE -9 #define CARD_RESULT_NOPERM -10 #define CARD_RESULT_LIMIT -11 #define CARD_RESULT_NAMETOOLONG -12 #define CARD_RESULT_ENCODING -13 #define CARD_RESULT_CANCELED -14 #define CARD_RESULT_FATAL_ERROR -128 /*** Structs ***/ struct OSInfo { // info obtained from https://www.gc-forever.com/yagcd/chap4.html#sec4.2.1 char gameName[4]; // 0x80000000 char company[2]; // 0x80000004 u8 disk_id; // 0x80000006 u8 disk_version; // 0x80000007 u8 is_audiostream; // 0x80000008 u8 streambuffer_size; // 0x80000009 int xc; // 0x8000000C int x10; // 0x80000010 int x14; // 0x80000014 int x18; // 0x80000018 int dvd_magicword; // 0x8000001C int boot_magicword; // 0x80000020 int sys_version; // 0x80000024 int mem_size; // 0x80000028 int console_type; // 0x8000002C int arena_lo; // 0x80000030 int arena_hi; // 0x80000034 void *fst; // 0x80000038 int fst_maxsize; // 0x8000003C int x40; // 0x80000040 int x44; // 0x80000044 int x48; // 0x80000048 int x4C; // 0x8000004C int x50; // 0x80000050 int x54; // 0x80000054 int x58; // 0x80000058 int x5C; // 0x8000005C int x60; // 0x80000060 int x64; // 0x80000064 int x68; // 0x80000068 int x6C; // 0x8000006C int x70; // 0x80000070 int x74; // 0x80000074 int x78; // 0x80000078 int x7C; // 0x8000007C int x80; // 0x80000080 int x84; // 0x80000084 int x88; // 0x80000088 int x8C; // 0x8000008C int x90; // 0x80000090 int x94; // 0x80000094 int x98; // 0x80000098 int x9C; // 0x8000009C int xA0; // 0x800000A0 int xA4; // 0x800000A4 int xA8; // 0x800000A8 int xAC; // 0x800000AC int xB0; // 0x800000B0 int xB4; // 0x800000B4 int xB8; // 0x800000B8 int xBC; // 0x800000BC int xC0; // 0x800000C0 int xC4; // 0x800000C4 int xC8; // 0x800000C8 int tv_mode; // 0x800000CC int aram_size; // 0x800000D0 int xD4; // 0x800000D4 int xD8; // 0x800000D8 int xDC; // 0x800000DC int xE0; // 0x800000E0 int curr_osthread; // 0x800000E4 int xE8; // 0x800000E8 int xEC; // 0x800000EC int simulated_memsize; // 0x800000F0 void *dvd_BI2; // 0x800000F4 int bus_clock; // 0x800000F8 int cpu_clock; // 0x800000FC }; struct OSCalendarTime { int sec; // seconds after the minute [0, 61] int min; // minutes after the hour [0, 59] int hour; // hours since midnight [0, 23] int mday; // day of the month [1, 31] int mon; // month since January [0, 11] int year; // years in AD [1, ...] int wday; // days since Sunday [0, 6] int yday; // days since January 1 [0, 365] int msec; // milliseconds after the second [0,999] int usec; // microseconds after the millisecond [0,999] }; struct CARDStat { // read-only (Set by CARDGetStatus) char fileName[CARD_FILENAME_MAX]; u32 length; u32 time; // seconds since midnight 01/01/2000 u8 gameName[4]; u8 company[2]; // read/write (Set by CARDGetStatus/CARDSetStatus) u8 bannerFormat; u32 iconAddr; u16 iconFormat; u16 iconSpeed; u32 commentAddr; // read-only (Set by CARDGetStatus) u32 offsetBanner; u32 offsetBannerTlut; u32 offsetIcon[CARD_ICON_MAX]; u32 offsetIconTlut; u32 offsetData; }; struct CARDFileInfo { s32 chan; s32 fileNo; s32 offset; s32 length; u16 iBlock; u16 __padding; }; struct RGB565 { unsigned short r : 5; unsigned short g : 6; unsigned short b : 5; }; /*** Static Vars ***/ OSInfo *os_info = 0x80000000; /*** OS Library ***/ int OSGetTick(); u64 OSGetTime(); void OSTicksToCalendarTime(u64 time, OSCalendarTime *td); void OSReport(char *, ...); void __assert(char *file, int line, char *assert); int OSCheckHeap(int heap); int OSGetConsoleType(); void memcpy(void *dest, void *source, int size); void memset(void *dest, int fill, int size); s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat *stat); s32 CARDMountAsync(s32 chan, void *workArea, void *detachCallback, void *attachCallback); s32 CARDUnmount(s32 chan); s32 CARDOpen(s32 chan, char *fileName, CARDFileInfo *fileInfo); s32 CARDClose(CARDFileInfo *fileInfo); s32 CARDProbeEx(s32 chan, s32 *memSize, s32 *sectorSize); s32 CARDCheckAsync(s32 chan, void *callback); s32 CARDFreeBlocks(s32 chan, s32 *byteNotUsed, s32 *filesNotUsed); s32 CARDDeleteAsync(s32 chan, char *fileName, void *callback); s32 CARDCreateAsync(s32 chan, char *fileName, u32 size, CARDFileInfo *fileInfo, void *callback); s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat *stat, void *callback); s32 CARDRead(CARDFileInfo *fileInfo, void *buf, s32 length, s32 offset); void GXPixModeSync(); void GXInvalidateTexAll(); void DCFlushRange(void *startAddr, u32 nBytes); void TRK_FlushCache(void *startAddr, u32 nBytes); int memcmp(void *buf1, void *buf2, u32 nBytes); int GXGetTexBufferSize(u16 width, u16 height, u32 format, int mipmap, u8 max_lod); void GXSetDrawDone(); void GXWaitDrawDone(); void blr(); void blr2(); /*** HSD Library ***/ int HSD_GetHeapID(); void HSD_SetHeapID(int heap); /** String Library **/ #define vsprintf(buffer, format, args) _vsprintf(buffer, -1, format, args) int sprintf(char *s, const char *format, ...); int _vsprintf(char *str, int unk, const char *format, va_list arg); int strlen(char *str); char *strchr(char *str, char c); // searches for the first occurrence of the character c (an unsigned char) in the string pointed to by the argument str. int strcmp(char *str1, char *str2); int strncmp(char *str1, char *str2, int size); char *strcpy(char *dest, char *src); // copies the string pointed to, by src to dest. char *strncpy(char *dest, char *src, int size); // copies the string pointed to, by src to dest. unsigned long int strtoul(const char *str, char **endptr, int base); char *strcat(s, append) register char *s; register const char *append; { char *save = s; for (; *s; ++s) ; while (*s++ = *append++) ; return (save); } void SFX_Play(int sfxID); void SFX_PlayRaw(int sfx, int volume, int pan, int unk, int unk2); void SFX_PlayCommon(int sfxID); void SFX_PlayCrowd(int sfxID); void SFX_StopCrowd(); void SFX_StopAllFighterSFX(FighterData *fighter_data); void Music_Play(int hpsID); void BGM_Play(int hpsID); void DevelopMode_ResetCursorXY(DevText *text, int x, int y); void Develop_UpdateMatchHotkeys(); void Wind_Create(Vec3 *pos, int radius, float x, float y, float z); void Wind_StageCreate(Vec3 *pos, int duration, float radius, float lifetime, float angle); void Wind_FighterCreate(Vec3 *pos, int duration, float radius, float lifetime, float angle); int Pause_CheckStatus(int type); #endif ================================================ FILE: MexTK/itFunction.txt ================================================ item_state_table onspawn ondestroy onpickup ondrop onthrow ongivedamage ontakedamage onenterair onreflect onunk1 onunk2 onhitshieldbounce onhitshielddeterminedestroy onunk3 ================================================ FILE: MexTK/kbFunction.txt ================================================ onkirbyswallow onkirbyloseability kirbyspecialn kirbyspecialairn onkirbyhurt initcopyitems move_logic ================================================ FILE: MexTK/melee.link ================================================ 80016c64:File_LoadInitReturnSymbol 80380358:File_GetSymbol 80041c8c:Coll_ECBCurrToPrev 80041ee4:Coll_InitECB 80048160:Coll_CheckLedge 8004b21c:ECB_CollGround_PassLedge 800475f4:ECB_CollAir 801677f8:CSS_GetNametagRumble 8016795c:CSS_InitPlayerData 8022ba1c:CSS_CameraRotateThink 80302834:DevelopText_CreateDataTable 80302810:DevelopText_Activate 80302d4c:DevelopText_AddString 80302bb0:DevelopText_EraseAllText 80302b90:DevelopText_StoreBGColor 80302b00:DevelopText_HideText 80302ae0:DevelopText_HideBG 80302b10:DevelopText_StoreTextScale 80008fc8:Develop_DrawSphere 8005fddc:Effect_SpawnSync 800676f0:Effect_SpawnAsync 8009f834:Effect_SpawnFtEffectLookup 80278800:Effect_SpawnItEffectLookup 802787b4:Effect_SpawnItEffect 8005b880:Effect_DestroyAll 8039d5dc:Particle_DestroyAll 803a4344:psRemoveParticleAppSRT 8039d048:psDeletePntJObjwithParticle 8039d3ac:psKillGenerator 8005ba40:Effect_PauseAll 8005bac4:Effect_ResumeAll 800693ac:ActionStateChange 8006eba4:Subaction_Update 8006e7b8:Fighter_UpdateBonePos 80085e50:Animation_GetAddress 80085fd4:Fighter_GetSubactionHeader 8001e8f8:Animation_GetLength 800957f4:Fighter_EnterLightThrow 80090780:Fighter_EnterDamageFall 8008a2bc:Fighter_EnterWait 800cc730:Fighter_EnterFall 80096900:Fighter_EnterSpecialFall 80082b1c:Fighter_EnterLanding 800d5cb0:Fighter_EnterSpecialLanding 800d4f24:Fighter_EnterSleep 8009a804:Fighter_EnterCliffWait 800d4ff4:Fighter_EnterRebirth 800d5600:Fighter_EnterRebirthWait 800d54a4:Fighter_UpdateRebirthPlatformPos 80034110:Fighter_GetGObj 8003418c:Fighter_GetSubcharGObj 80031724:Fighter_GetPlayerblock 80036244:Fighter_GetStaleMoveTable 8007b760:Fighter_ApplyIntang 8003241c:Fighter_GetSlotType 80033bd8:Fighter_GetStocks 80034e8c:Fighter_SetFallNum 8007d5bc:Fighter_EnableECBBottomUpdate 8008dce0:Fighter_EnterDamageState 8007500c:Fighter_BoneLookup 8006cc7c:Fighter_GiveDamage 8006cf5c:Fighter_GiveHeal 80034330:Fighter_SetHUDDamage 80032828:Fighter_SetPosition 8007db58:Fighter_RunOnHitCallbacks 80033c60:Fighter_SetStocks 8006f238:FrameTimerCheck 8009a184:Fighter_EnterMiscPassState 80082708:Fighter_CollGround_PassLedge 80084104:Fighter_CollGround_StopLedge 800831cc:Fighter_CollAir_GrabLedgeWalljump 800822a4:Fighter_CollAir_GrabLedge 80082c74:Fighter_CollAir_IgnoreLedge 80081d0c:Fighter_CollAir_IgnoreLedge_NoCB 80081298:Fighter_IASACheck_CliffCatch 800cb870:Fighter_IASACheck_JumpAerial 800caed0:Fighter_IASACheck_JumpF 80099f1c:Fighter_IASACheck_PassConditions 800c97a8:Fighter_IASACheck_Turn 80084f3c:Fighter_PhysGround_ApplyFriction 8007d494:Fighter_PhysAir_ApplyGravity 8007cf58:Fighter_PhysAir_LimitVelocity 80085134:Fighter_Phys_UseAnimPos 80085154:Fighter_Phys_UseAnimPosAndStick 8007d7fc:Fighter_SetGrounded2 8007d5d4:Fighter_SetAirborne 8007d5d4:Fighter_LoseGroundJump 8007d5bc:Fighter_EnableCollUpdate 8007e2fc:Fighter_KillAllVelocity 8006eba4:Fighter_AdvanceScript 8007db24:Fighter_GFXRemoveAll 8007aef8:Fighter_EnableReflectUpdate 8007b23c:Fighter_CreateReflect 80075f48:Fighter_GetBoneRotation 80075af0:Fighter_RotateBone_Pitch 8007592c:Fighter_RotateBone_Yaw 80075cb4:Fighter_RotateBone_Roll 800881d8:Fighter_PlayVoiceSFX 800bffd0:Fighter_ApplyOverlay 800c0408:Fighter_UpdateOverlay 8008a6d8:Fighter_DisableBlend 8009e7b4:Fighter_UpdateDynamics 800b4a78:Fighter_ZeroCPUInputs 800921dc:Fighter_CreateShieldGFX 80091e78:Fighter_UpdateShieldGFX 80036538:Fighter_GetShieldColorIndex 8007f694:Fighter_GetBaseScale 800866a4:Fighter_SetScale 8009cf84:Fighter_InitDynamics 8009e0a8:Fighter_ProcDynamics 80074148:Fighter_InitPObj 80074170:Fighter_InitPObj2 80075650:Fighter_IndexFtPartsDObjs 8007487c:Fighter_InitFtPartsModel 8007d6a4:Fighter_SetGrounded 80081544:Fighter_MoveToCliff 80086a8c:Fighter_UpdateOnscreenBool 80380580:HSD_Randi 80380528:HSD_Randf 8037f1e4:HSD_MemAlloc 8037f1b0:HSD_Free 8037abc8:HSD_ObjAlloc 8037ad20:HSD_ObjFree 8026ab54:Item_Hold 80094818:Item_Catch 8026B3F8:Items_StoreItemDataToCharItemTable 8026B3F8:Items_StoreItemDataToCharItemTable2 80275158:Items_StoreTimeout 8026862c:Item_CreateItem 80268b18:Item_CreateItem1 80268b5c:Item_CreateItem2 80268b9c:Item_CreateItem3 8026a8ec:Item_Destroy 8026d62c:Item_CollGround_PassLedge 8026d8a4:Item_CollGround_StopLedge 8026e15c:Item_CollAir 80268e5c:ItemStateChange 80272c6c:ItemFrameTimer 80276174:Item_PlaceOnGroundBelow 80276348:Item_CheckIfTouchingWall 80274f28:Item_InitGrab 8027146c:Item_ResetAllHitPlayers 8026b3c0:Item_CountActiveItems 80225dd8:Item_CopyDevelopState 80273130:Items_DecLife 8026eecc:GXLink_Item 80274658:Item_UpdateSpin 802762bc:Item_EnableSpin 802762b0:Item_DisableSpin 80275158:Item_SetLifeTimer 80273130:Item_DecLifeTimer 80272cc0:Item_GetBoneJOBJ 80266f3c:Item_CheckIfEnabled 80029020:CameraBox_Alloc 800290d4:CameraBox_Destroy 802fa5bc:KOCount_Init 802fa2d0:KOCount_Update 801c39c0:Stage_CameraLimitInitialization 801c3bb4:Stage_BlastzoneInitialization 8016b33c:Match_SetEndGraphic 8016b328:Match_EndImmediate 8016c7f0:Match_EndVS 8002063c:Match_FadeScreen 8016b168:Match_CheckIfTeams 8016b094:Match_CheckIfStock 8016b364:Match_SetPostMatchSFX 801a4634:Match_FreezeGame 801a4674:Match_UnfreezeGame 802f6e1c:Match_CreateHUD 802f3394:Match_HideHUD 802f33cc:Match_ShowHUD 8002f3ac:Match_CorrectCamera 801650e8:Match_SetNormalCamera 801652b0:Match_SetFreeCamera 80165190:Match_SetZoomCamera 80165290:Match_SetFixedCamera 8003006c:Match_SetDevelopCamera 802279e8:DevCam_AdjustRotate 80227fe0:DevCam_AdjustPan 80227cac:DevCam_AdjustZoom 80021c48:ScreenFlash_Create 80030e44:ScreenRumble_Execute 801c10b8:Match_StoreGoCallback 80022e68:atan 80022c30:atan2 803263d4:sin 80326240:cos 80342734:MTXLookAt 80342db8:VECNormalize 80342d54:VECAdd 80342d78:VECSubtract 8000dc6c:VECMultAndAdd 80342e38:VECDotProduct 80342e58:VECCrossProduct 80342690:MTXQuat 80379c24:HSD_MtxGetRotation 8037e708:MatToQuat 8000d5bc:sqrtf 80342418:MTXRotRad 803d7058:MEX_IndexFighterItem 803d7060:SpawnMEXEffect 803d7064:MEX_GetItemExtID 803d7088:MEX_GetFtItemID 803d708C:MEX_GetGrItemID 803d7078:SFX_PlayStageSFX 803d706C:calloc 804DD84C:PRIM_NEW 804DD848:PRIM_CLOSE 803d707C:MEX_GetPlaylist 803d7064:MEX_GetStageItemExtID 803d7080:KirbyStateChange 803d7084:MEX_GetKirbyCpData 803d7088:MEX_GetCopyItemExtID 803d7094:MEX_GetData 8000b1cc:JOBJ_GetWorldPosition 803732e8:JOBJ_SetMtxDirtySub 80370e44:JOBJ_LoadJoint 80371590:JOBJ_RemoveAll 80371370:JOBJ_Remove 80011e24:JOBJ_GetChild 803717a8:JOBJ_AddChild 8022f298:JOBJ_GetCurrentMatAnimFrame 80371d00:JOBJ_SetFlags 80371d9c:JOBJ_SetFlagsAll 80371f00:JOBJ_ClearFlags 80371f9c:JOBJ_ClearFlagsAll 803740e8:JOBJ_BillBoard 80364c08:JOBJ_RunAOBJCallback 80370780:JOBJ_Anim 80370928:JOBJ_AnimAll 8036fb5c:JOBJ_AddAnimAll 8036f6b4:JOBJ_RemoveAnimAll 8036f934:JOBJ_ReqAnim 8036f718:JOBJ_ReqAnimByFlags 8036f8bc:JOBJ_ReqAnimAll 8036f7b0:JOBJ_ReqAnimAllByFlags 8000be40:JOBJ_GetJointAnimFrameTotal 8000bdb4:JOBJ_GetJointAnimNextFrame 801c8858:JOBJ_SetAllMOBJFlags 8036410c:AOBJ_ReqAnim 8036414c:AOBJ_StopAnim 8036530c:AOBJ_SetRate 8000b09c:JOBJ_CheckAObjEnd 8035ddb8:DOBJ_SetFlags 8035ddd0:DOBJ_ClearFlags 8036a590:COBJ_LoadDesc 80030a50:COBJ_GetMatchCamera 803910d8:CObjThink_Common 803901f0:GObj_Create 80390228:GObj_Destroy 8039069c:GObj_AddGXLink 8039084c:GObj_DestroyGXLink 8039063c:GObj_GXReorder 8038fd54:GObj_AddProc 8038fed4:GObj_RemoveProc 80390a70:GObj_AddObject 80390b0c:GObj_FreeObject 80390b68:GObj_AddUserData 8039075c:GOBJ_InitCamera 80391070:GXLink_Common 80391044:GXLink_LObj 8026407c:GXLink_Fog 803672dc:LObj_LoadDesc 8037dc38:Fog_LoadDesc 80018254:Preload_Update 8001822c:Preload_GetTable 801a42f8:Scene_EnterMajor 801a5680:CSS_DecideNext 801a55c4:CSS_ResetKOStars 80167b50:CSS_InitMajorData 801a5618:CSS_InitMinorData 801a5754:SSS_InitMinorData 801a583c:Match_InitMinorData 8016f088:Match_SetNametags 801c6324:Stage_GetStageFiles 801c6330:Stage_GetStageFile 800c07f8:Stage_AddFtChkDevice 801c438c:Stage_SetChkDevicePos 801c4368:Stage_GetChkDevicePos 801c0498:Stage_GetScale 801c49f8:Stage_GetYakumonoParam 801c8138:Stage_MapStateChange 800115f4:Dynamics_DecayWind 80223908:Stage_CreateMapGObj 801c4a08:Stage_DestroyMapGObj 801c5db0:GXLink_Stage 801c2ba4:Stage_GetMapGObj 801c3fa4:Stage_GetMapGObjJObj 80056b6c:Stage_GetLinesGroup 80054c6c:Stage_GetLinesDirection 800580c8:Stage_SetGroundCallback 800581a4:Stage_SetCeilingCallback 801c2ed0:Stage_InitMovingColl 801c2fe0:Stage_UpdateMovingColl 801c96f8:Stage_SpawnEffectPos 801c97dc:Stage_SpawnEffectJointPos 801c9808:Stage_SpawnEffectJointPos2 8004f008:GrColl_RaycastGround 80056c54:GrColl_CrawlGround 800567c0:GrColl_GetPosDifference 80054dfc:GrColl_GetLineSlope 80054ed8:GrColl_CheckIfLineEnabled 8027b5b0:Zako_Create 802e6aec:Stage_CreateMapItem 801c9ee8:Stage_CheckForNearbyFighters 80224b38:Stage_GetBlastzoneRight 80224b50:Stage_GetBlastzoneLeft 80224b68:Stage_GetBlastzoneTop 80224b80:Stage_GetBlastzoneBottom 80224a68:Stage_GetCameraRight 80224a54:Stage_GetCameraLeft 80224a80:Stage_GetCameraTop 80224a98:Stage_GetCameraBottom 801c2d24:Stage_GetGeneralPoint 80057638:Stage_EnableLineGroup 80057bc0:Stage_DisableLineGroup 80054158:GrColl_GetLedgeLeft 80053ff4:GrColl_GetLedgeRight 80053ecc:GrColl_GetLedgeLeft2 80053da4:GrColl_GetLedgeRight2 803a611c:Text_CreateCanvas 803a6754:Text_CreateText 803a5cc4:Text_Destroy 803a6b98:Text_AddSubtext 803a7548:Text_SetScale 803a74f0:Text_SetColor 803a746c:Text_SetPosition 803a70a0:Text_SetText 803a67ec:Text_ConvertToMenuText 803A5798:Text_Alloc 803a594c:Text_DestroyAlloc 803a5a2c:Text_DestroyAllAlloc 803a67ec:Text_StringToMenuText 803a84bc:Text_GX 803456A8:OSReport 800031f4:memcpy 80003100:memset 80005358:blr 8021b2d8:bp 801c53ec:SFX_Play 8038cff4:SFX_PlayRaw 80024030:SFX_PlayCommon 8002411c:SFX_PlayCrowd 80321ce8:SFX_StopCrowd 80088a50:SFX_StopAllFighterSFX 80023f28:Music_Play 80023f28:BGM_Play 80302a3c:DevelopMode_ResetCursorXY 80225754:Develop_UpdateMatchHotkeys 800119dc:Wind_Create 80011a50:Wind_StageCreate 800119dc:Wind_FighterCreate 801a45e8:Pause_CheckStatus 8001c550:Memcard_InitWorkArea 8001d164:Memcard_LoadAssets 803b31cc:Memcard_Deobfuscate 8023754c:Nametag_GetText 80026f2c:Audio_ResetCache 8002702c:Audio_QueueFileLoad 80027168:Audio_UpdateCache 80027648:Audio_SyncLoadAll 80016be0:File_Load 803a62a0:Text_LoadSdFile 8025f0e0:CSS_MenuModelThink 802602a0:CSS_CursorThink 80262648:CSS_PuckThink 80164840:Fighter_CheckUnlocked 802633b0:CSS_TagThink 803a5acc:Text_CreateText2 803a6368:Text_SetSisText 8025bd30:CSS_UpdateRulesText 8025d1c4:CSS_UpdateKOStars 80262f44:CSS_StartThink 801685d4:CSS_GetHandicapValue 8025ee8c:CSS_SetModeTexture 8015ecb0:BGM_GetMenuBGM 8015cc34:Memcard_GetRules1 80371bec:JOBJ_GetDObj 80363c2c:MOBJ_SetAlpha 8025fdec:CSS_ReturnPuck 8025fb50:CSS_SetRandomFighter 8025db34:CSS_UpdateCSP 80169238:CSS_GetCostumeNum 803909d8:GObj_CopyGXPri 80168c5c:CSS_PlayFighterName 80260094:CSS_CostumeChange 8025d5ac:CSS_UpdateCSPTexture 8003254c:Fighter_SetSlotType 8003345c:Fighter_GetControllerPort 80032330:Fighter_GetExternalID 80033198:Fighter_GetCostumeID 8008d7f0:Fighter_GetKnockbackAngle 800761c8:Fighter_UpdateCameraBox 8007af28:Fighter_SetAllHurtboxesNotUpdated 800a0da4:Fighter_UpdateHurtboxes 8006c5f4:Fighter_UpdateIK 800c0200:Fighter_ColorRemove 800a101c:Fighter_CPUInitialize 80033670:Fighter_GetCPUKind 80033548:Fighter_GetCPULevel 80160980:Fighter_GetName 800122c8:HSD_ImageDescCopyFromEFB 802f40b8:Match_ShowTimer 802f405c:Match_HideTimer 80024e84:Match_AdjustSoundOnPause 802f3424:Match_GetPlayerHUDPos 80030a50:Match_GetCObj 8001e218:Memcard_InitSnapshotList 80253e90:Memcard_UpdateSnapshotList 8001bb48:Memcard_CreateSnapshot 8001d5fc:Memcard_DeleteSnapshot 8001bf04:Memcard_LoadSnapshot 8001b6f8:Memcard_CheckStatus 8001a008:Memcard_RemovedCallback 803d7080:MEX_LoadRelArchive 80013b14:COBJ_LoadDescSetScissor 80225194:Stage_GetExternalID 8022519c:Stage_ExternalToInternal 8034c408:OSGetTick 8034c3f0:OSGetTime 8034c668:OSTicksToCalendarTime 80388220:__assert 80344168:OSCheckHeap 80342e94:OSGetConsoleType 803585f8:CARDGetStatus 80356688:CARDMountAsync 803568c4:CARDUnmount 80355f94:CARDProbeEx 80355f34:CARDCheckAsync 803532d4:CARDFreeBlocks 803582f0:CARDDeleteAsync 80000000:CARDCreateAsync 80358724:CARDSetStatusAsync 80357e88:CARDRead 80357534:CARDOpen 803576ac:CARDClose 8034480c:DCFlushRange 80328f50:TRK_FlushCache 803238c8:memcmp 8033e78c:GXGetTexBufferSize 8033cc38:GXSetDrawDone 8033ccd0:GXWaitDrawDone 800121fc:GX_AllocImageData 8033cd1c:GXPixModeSync 8033f270:GXInvalidateTexAll 803230a4:blr2 80375404:HSD_GetHeapID 8037540c:HSD_SetHeapID 80323cf4:sprintf 80323dc8:_vsprintf 80325b04:strlen 80325878:strchr 803258e8:strcmp 803258a8:strncmp 80325a50:strcpy 80325a0c:strncpy 80325b24:strtoul 802886c4:Barrel_EnterBreak 8018f674:Pad_GetRapidHeld 8022ba1c:MainMenu_CamRotateThink ================================================ FILE: MexTK/mex.h ================================================ #ifndef MEX_H #define MEX_H #include "include/structs.h" #include "include/datatypes.h" #include "include/audio.h" #include "include/archive.h" #include "include/boneset.h" #include "include/match.h" #include "include/collision.h" #include "include/color.h" #include "include/css.h" #include "include/devtext.h" #include "include/effects.h" #include "include/fighter.h" #include "include/hsd.h" #include "include/inline.h" #include "include/item.h" #include "include/kirby.h" #include "include/math.h" #include "include/memcard.h" #include "include/mex.h" #include "include/obj.h" #include "include/offsets.h" #include "include/preload.h" #include "include/result.h" #include "include/scene.h" #include "include/stage.h" #include "include/text.h" #include "include/useful.h" #endif ================================================ FILE: MexTK/mjFunction.txt ================================================ minor_scene major_load major_unload css_load sss_load ================================================ FILE: MexTK/mnFunction.txt ================================================ minor_think minor_load minor_unload ================================================ FILE: MexTK/tmFunction.txt ================================================ eventPages GetEventName GetEventDescription GetEventTut GetPageName GetPageEventNum GetTMVersShort GetTMVersLong GetTMCompile GetPageNum GetIsChooseCPU GetIsSelectStage GetFighter GetCPUFighter GetStage GetEventFile GetCSSFile EventInit OnSceneChange OnBoot OnStartMelee OnFileLoad Message_Display GetEventDesc ================================================ FILE: patch/events/lab/build.bat ================================================ xcopy /s /y "assets\labData.dat" "output/EvLab.dat" "../../../MexTK/MexTK.exe" -ff -i "source/lab.c" -s evFunction -dat "output/EvLab.dat" -t "../../../MexTK/evFunction.txt" -q -ow -w -c -l "../../../MexTK/melee.link" -op 1 "../../../MexTK/MexTK.exe" -trim "output/EvLab.dat" xcopy /s /y "assets\importData.dat" "output/EvLabCSS.dat" "../../../MexTK/MexTK.exe" -ff -i "source/lab_css.c" -s cssFunction -dat "output/EvLabCSS.dat" -t "../../../MexTK/cssFunction.txt" -q -ow -w -c -l "../../../MexTK/melee.link" -op 1 "../../../MexTK/MexTK.exe" -trim "output/EvLabCSS.dat" pause ================================================ FILE: patch/events/lab/notes.txt ================================================ Free Practice Menu -General Settings -Player Percent (int option) -CPU Percent (int option) -Move Staling -Frame Advance (uses L like ultimate) -Model Display -On -Off -Fighter Collision Display -Off -On -Environment Collision Display -Off -On -DI Display -Off -On -Input Display -Info Display -Toggle (On/Off) -Player -Row 1 -None -Position -State Name -Velocity - Self -Velocity - Knockback -Velocity - Animation -Engine LStick Values -System LStick Values -Engine RStick Values -System RStick Values -Engine Trigger Value -System Trigger Value -Ledgegrab Cooldown -Intangibility Remaining -Hitlag Remaining -Hitstun Remaining -Shield Health -Shield Stun Remaining -Grab Timer -ECB Lock Timer -ECB Bottom offset -Jumps Used -Walljumps Used -Jab Counter -Blastzone Left/Right -Blastzone Up/Down -Row 2 -Row 3 -Row 4 -Row 5 -Row 6 -Row 7 -Row 8 -CPU Settings -CPU Intangibility -Infinite Shields -Off -On Until Hit -On -Default Behavior -Stand -Shield -Crouch -Jump -Directional Influence -Random -Survival -Combo -Floorhug -None -Tech -Random -Neutral Tech -Tech Away -Tech Towards -None -Reset After Actionable -Off -On -Counter Action (ground) -None -Shield -Grab -Up B -Down B -Spotdodge -Roll Away -Roll Towards -Nair -Fair -Dair -Bair -Uair -Jump -Counter Action (air) -Airdodge -Jump Away -Jump Towards -Nair -Fair -Dair -Bair -Uair -Up B -Down B -Fastfall -Wiggle -Wiggle Fastfall -Counter After Hits (int option) -Counter After Frames (int option) -Replay Settings -Record Slot -Random -Slot 1 -Slot 2 -Slot 3 -Mode -Playback -Record -Reset After Playback -Off -On -Help -Exit ================================================ FILE: patch/events/lab/source/lab.c ================================================ #include "lab.h" static char nullString[] = " "; // CPU Action Definitions static CPUAction Lab_CPUActionShield[] = { { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 1, // is the last input 0, // specify stick direction }, { ASID_GUARDREFLECT, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 1, // is the last input 0, // specify stick direction }, { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionGrab[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_A | PAD_TRIGGER_R, // button to input 1, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_Z, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionUpB[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R | PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_KNEEBEND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 127, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_B, // button to input 1, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLE, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 127, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_B, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionDownB[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R | PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_X, // button to input 1, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLE, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value -127, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_B, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionSpotdodge[] = { { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value -127, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionRollAway[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 127, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 1, // is the last input STCKDIR_AWAY, // specify stick direction }, { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_GUARDREFLECT, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 127, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 1, // is the last input STCKDIR_AWAY, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionRollTowards[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 127, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 1, // is the last input STCKDIR_TOWARD, // specify stick direction }, { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_GUARDREFLECT, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 127, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 1, // is the last input STCKDIR_TOWARD, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionRollRandom[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 127, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 1, // is the last input STICKDIR_RDM, // specify stick direction }, { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_GUARDREFLECT, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 127, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 1, // is the last input STICKDIR_RDM, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionNair[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R | PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEAIR, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_A, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionFair[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R | PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEAIR, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 127, // c stick X value 0, // c stick Y value 0, // button to input 1, // is the last input 3, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionDair[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R | PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEAIR, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value -127, // c stick Y value 0, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionBair[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R | PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEAIR, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 127, // c stick X value 0, // c stick Y value 0, // button to input 1, // is the last input 4, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionUair[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R | PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEAIR, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 127, // c stick Y value 0, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionJump[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R | PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_X, // button to input 1, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEAIR, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value 0, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionJumpFull[] = { { ASID_GUARD, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R | PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_KNEEBEND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_X, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEAIR, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value 0, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionJumpAway[] = { { ASID_JUMPS, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 127, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value 0, // button to input 0, // is the last input 2, // specify stick direction }, { ASID_ACTIONABLE, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 127, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_X, // button to input 0, // is the last input STCKDIR_AWAY, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionJumpTowards[] = { { ASID_JUMPS, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 127, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value 0, // button to input 0, // is the last input 1, // specify stick direction }, { ASID_ACTIONABLE, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 127, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_X, // button to input 0, // is the last input STCKDIR_TOWARD, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionAirdodge[] = { { ASID_DAMAGEAIR, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 127, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value 0, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEAIR, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_TRIGGER_R, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionFFTumble[] = { { ASID_DAMAGEAIR, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value -127, // left stick Y value 0, // c stick X value 0, // c stick Y value 0, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionFFWiggle[] = { { ASID_DAMAGEAIR, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 127, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value 0, // button to input 0, // is the last input 0, // specify stick direction }, { ASID_ACTIONABLEAIR, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value -127, // left stick Y value 0, // c stick X value 0, // c stick Y value 0, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionJab[] = { { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_A, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionFTilt[] = { { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 80, // left stick X value 0, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_A, // button to input 1, // is the last input STCKDIR_TOWARD, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionUTilt[] = { { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 80, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_A, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionDTilt[] = { { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value -80, // left stick Y value 0, // c stick X value 0, // c stick Y value PAD_BUTTON_A, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionUSmash[] = { { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value 127, // c stick Y value 0, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionDSmash[] = { { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 0, // c stick X value -127, // c stick Y value 0, // button to input 1, // is the last input 0, // specify stick direction }, -1, }; static CPUAction Lab_CPUActionFSmash[] = { { ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last 0, // first possible frame to perform this action 0, // last possible frame to perfrom this action 0, // left stick X value 0, // left stick Y value 127, // c stick X value 0, // c stick Y value 0, // button to input 1, // is the last input STCKDIR_TOWARD, // specify stick direction }, -1, }; static CPUAction *Lab_CPUActions[] = { // none 0 0, // shield 1 &Lab_CPUActionShield, // grab 2 &Lab_CPUActionGrab, // up b 3 &Lab_CPUActionUpB, // down b 4 &Lab_CPUActionDownB, // spotdodge 5 &Lab_CPUActionSpotdodge, // roll away 6 &Lab_CPUActionRollAway, // roll towards 7 &Lab_CPUActionRollTowards, // roll random &Lab_CPUActionRollRandom, // nair 8 &Lab_CPUActionNair, // fair 9 &Lab_CPUActionFair, // dair 10 &Lab_CPUActionDair, // bair 11 &Lab_CPUActionBair, // uair 12 &Lab_CPUActionUair, // short hop 13 &Lab_CPUActionJump, // full hop 14 &Lab_CPUActionJumpFull, // jump away 15 &Lab_CPUActionJumpAway, // jump towards 16 &Lab_CPUActionJumpTowards, // airdodge 17 &Lab_CPUActionAirdodge, // fastfall 18 &Lab_CPUActionFFTumble, // wiggle fastfall 19 &Lab_CPUActionFFWiggle, // wiggle fastfall 19 &Lab_CPUActionJab, &Lab_CPUActionFTilt, &Lab_CPUActionUTilt, &Lab_CPUActionDTilt, &Lab_CPUActionUSmash, &Lab_CPUActionDSmash, &Lab_CPUActionFSmash, }; enum CPU_ACTIONS { CPUACT_NONE, CPUACT_SHIELD, CPUACT_GRAB, CPUACT_UPB, CPUACT_DOWNB, CPUACT_SPOTDODGE, CPUACT_ROLLAWAY, CPUACT_ROLLTOWARDS, CPUACT_ROLLRDM, CPUACT_NAIR, CPUACT_FAIR, CPUACT_DAIR, CPUACT_BAIR, CPUACT_UAIR, CPUACT_SHORTHOP, CPUACT_FULLHOP, CPUACT_JUMPAWAY, CPUACT_JUMPTOWARDS, CPUACT_AIRDODGE, CPUACT_FFTUMBLE, CPUACT_FFWIGGLE, CPUACT_JAB, CPUACT_FTILT, CPUACT_UTILT, CPUACT_DTILT, CPUACT_USMASH, CPUACT_DSMASH, CPUACT_FSMASH, }; static char *CPU_ACTIONS_NAMES[] = { "CPUACT_NONE", "CPUACT_SHIELD", "CPUACT_GRAB", "CPUACT_UPB", "CPUACT_DOWNB", "CPUACT_SPOTDODGE", "CPUACT_ROLLAWAY", "CPUACT_ROLLTOWARDS", "CPUACT_ROLLRDM", "CPUACT_NAIR", "CPUACT_FAIR", "CPUACT_DAIR", "CPUACT_BAIR", "CPUACT_UAIR", "CPUACT_SHORTHOP", "CPUACT_FULLHOP", "CPUACT_JUMPAWAY", "CPUACT_JUMPTOWARDS", "CPUACT_AIRDODGE", "CPUACT_FFTUMBLE", "CPUACT_FFWIGGLE", "CPUACT_JAB", "CPUACT_FTILT", "CPUACT_UTILT", "CPUACT_DTILT", "CPUACT_USMASH", "CPUACT_DSMASH", "CPUACT_FSMASH", }; static u8 GrAcLookup[] = {CPUACT_NONE, CPUACT_SPOTDODGE, CPUACT_SHIELD, CPUACT_GRAB, CPUACT_UPB, CPUACT_DOWNB, CPUACT_USMASH, CPUACT_DSMASH, CPUACT_FSMASH, CPUACT_ROLLAWAY, CPUACT_ROLLTOWARDS, CPUACT_ROLLRDM, CPUACT_NAIR, CPUACT_FAIR, CPUACT_DAIR, CPUACT_BAIR, CPUACT_UAIR, CPUACT_JAB, CPUACT_FTILT, CPUACT_UTILT, CPUACT_DTILT, CPUACT_SHORTHOP, CPUACT_FULLHOP}; static u8 AirAcLookup[] = {CPUACT_NONE, CPUACT_AIRDODGE, CPUACT_JUMPAWAY, CPUACT_JUMPTOWARDS, CPUACT_UPB, CPUACT_DOWNB, CPUACT_NAIR, CPUACT_FAIR, CPUACT_DAIR, CPUACT_BAIR, CPUACT_UAIR, CPUACT_FFTUMBLE, CPUACT_FFWIGGLE}; static u8 ShieldAcLookup[] = {CPUACT_NONE, CPUACT_GRAB, CPUACT_SHORTHOP, CPUACT_FULLHOP, CPUACT_SPOTDODGE, CPUACT_ROLLAWAY, CPUACT_ROLLTOWARDS, CPUACT_ROLLRDM, CPUACT_UPB, CPUACT_DOWNB, CPUACT_NAIR, CPUACT_FAIR, CPUACT_DAIR, CPUACT_BAIR, CPUACT_UAIR}; // Main Menu static char **LabOptions_OffOn[] = {"Off", "On"}; static EventOption LabOptions_Main[] = { { .option_kind = OPTKIND_MENU, // the type of option this is; menu, string list, integer list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = &LabMenu_General, // pointer to the menu that pressing A opens .option_name = {"General"}, // pointer to a string .desc = "Toggle player percent, overlays,\nframe advance, and camera settings.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_MENU, // the type of option this is; menu, string list, integers list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = &LabMenu_CPU, // pointer to the menu that pressing A opens .option_name = {"CPU Options"}, // pointer to a string .desc = "Configure CPU behavior.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_MENU, // the type of option this is; menu, string list, integers list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = &LabMenu_Record, // pointer to the menu that pressing A opens .option_name = "Recording", // pointer to a string .desc = "Record and playback inputs.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = 0, }, // info display { .option_kind = OPTKIND_MENU, // the type of option this is; menu, string list, integer list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = &LabMenu_InfoDisplay, // pointer to the menu that pressing A opens .option_name = "Info Display", // pointer to a string .desc = "Display various game information onscreen.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_FUNC, // the type of option this is; menu, string list, integers list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Help", // pointer to a string .desc = "D-Pad Left - Load State\nD-Pad Right - Save State\nD-Pad Down - Move CPU\nHold R in the menu for turbo.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = Lab_Exit, }, { .option_kind = OPTKIND_FUNC, // the type of option this is; menu, string list, integers list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Exit", // pointer to a string .desc = "Return to the Event Select Screen.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = 0, .onOptionSelect = Lab_Exit, }, }; static EventMenu LabMenu_Main = { .name = "Main Menu", // the name of this menu .option_num = sizeof(LabOptions_Main) / sizeof(EventOption), // number of options this menu contains .scroll = 0, // runtime variable used for how far down in the menu to start .state = 0, // bool used to know if this menu is focused, used at runtime .cursor = 0, // index of the option currently selected, used at runtime .options = &LabOptions_Main, // pointer to all of this menu's options .prev = 0, // pointer to previous menu, used at runtime }; // General static char **LabOptions_CamMode[] = {"Normal", "Zoom", "Fixed", "Advanced"}; static char **LabOptions_FrameAdvButton[] = {"L", "Z", "X", "Y"}; static EventOption LabOptions_General[] = { // frame advance { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabOptions_OffOn) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Frame Advance", // pointer to a string .desc = "Enable frame advance. Press to advance one\nframe. Hold to advance at normal speed.", // string describing what this option does .option_values = LabOptions_OffOn, // pointer to an array of strings .onOptionChange = Lab_ChangeFrameAdvance, }, // frame advance button { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabOptions_FrameAdvButton) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Frame Advance Button", // pointer to a string .desc = "Choose which button will advance the frame", // string describing what this option does .option_values = LabOptions_FrameAdvButton, // pointer to an array of strings .onOptionChange = 0, .disable = 1, }, // p1 percent { .option_kind = OPTKIND_INT, // the type of option this is; menu, string list, integer list, etc .value_num = 999, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Player Percent", // pointer to a string .desc = "Adjust the player's percent.", // string describing what this option does .option_values = "%d%%", // pointer to an array of strings .onOptionChange = Lab_ChangePlayerPercent, }, // model display { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = 2, // number of values for this option .option_val = 1, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Model Display", // pointer to a string .desc = "Toggle player and item model visibility.", // string describing what this option does .option_values = LabOptions_OffOn, // pointer to an array of strings .onOptionChange = Lab_ChangeModelDisplay, }, // fighter collision { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = 2, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Fighter Collision", // pointer to a string .desc = "Toggle hitbox and hurtbox visualization.\nYellow = hurt, red = hit, purple = grab, \nwhite = trigger, green = reflect,\nblue = shield/absorb.", // string describing what this option does .option_values = LabOptions_OffOn, // pointer to an array of strings .onOptionChange = Lab_ChangeHitDisplay, }, // environment collision { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = 2, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Environment Collision", // pointer to a string .desc = "Toggle environment collision visualization.\nAlso displays the players' ECB (environmental \ncollision box).", // string describing what this option does .option_values = LabOptions_OffOn, // pointer to an array of strings .onOptionChange = Lab_ChangeEnvCollDisplay, }, // camera mode { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabOptions_CamMode) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Camera Mode", // pointer to a string .desc = "Adjust the camera's behavior.\nIn advanced mode, use C-Stick while holding\nA/B/Y to pan, rotate and zoom, respectively.", // string describing what this option does .option_values = LabOptions_CamMode, // pointer to an array of strings .onOptionChange = Lab_ChangeCamMode, }, // hud { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = 2, // number of values for this option .option_val = 1, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "HUD", // pointer to a string .desc = "Toggle player percents and timer visibility.", // string describing what this option does .option_values = LabOptions_OffOn, // pointer to an array of strings .onOptionChange = Lab_ChangeHUD, }, // di display { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = 2, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "DI Display", // pointer to a string .desc = "Display knockback trajectories.\nUse frame advance to see the effects of DI\nin realtime during hitstop.", // string describing what this option does .option_values = LabOptions_OffOn, // pointer to an array of strings .onOptionChange = 0, }, // input display { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = 2, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Input Display", // pointer to a string .desc = "Display player inputs onscreen.", // string describing what this option does .option_values = LabOptions_OffOn, // pointer to an array of strings .onOptionChange = 0, }, // move staling { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = 2, // number of values for this option .option_val = 1, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Move Staling", // pointer to a string .desc = "Toggle the staling of moves. Attacks become \nweaker the more they are used.", // string describing what this option does .option_values = LabOptions_OffOn, // pointer to an array of strings .onOptionChange = 0, }, }; static EventMenu LabMenu_General = { .name = "General", // the name of this menu .option_num = sizeof(LabOptions_General) / sizeof(EventOption), // number of options this menu contains .scroll = 0, // runtime variable used for how far down in the menu to start .state = 0, // bool used to know if this menu is focused, used at runtime .cursor = 0, // index of the option currently selected, used at runtime .options = &LabOptions_General, // pointer to all of this menu's options .prev = 0, // pointer to previous menu, used at runtime }; // Info Display static char **LabValues_InfoDisplay[] = {"None", "Position", "State Name", "State Frame", "Velocity - Self", "Velocity - KB", "Velocity - Total", "Engine LStick", "System LStick", "Engine CStick", "System CStick", "Engine Trigger", "System Trigger", "Ledgegrab Timer", "Intangibility Timer", "Hitlag", "Hitstun", "Shield Health", "Shield Stun", "Grip Strength", "ECB Lock", "ECB Bottom", "Jumps", "Walljumps", "Jab Counter", "Line Info", "Blastzone Left/Right", "Blastzone Up/Down"}; static char **LabValues_InfoPresets[] = {"None", "Custom", "Ledge", "Damage"}; //static char **LabValues_InfoPosition[] = {"Top Left", "Top Mid", "Top Right", "Bottom Left", "Bottom Mid", "Bottom Right"}; static char **LabValues_InfoSize[] = {"Small", "Medium", "Large"}; static char **LabValues_InfoPlayers[] = {"Player 1", "Player 2", "Player 3", "Player 4"}; static EventOption LabOptions_InfoDisplay[] = { { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_InfoPlayers) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Player", // pointer to a string .desc = "Toggle which player's information to display.", // string describing what this option does .option_values = LabValues_InfoPlayers, // pointer to an array of strings .onOptionChange = Lab_ChangeInfoPlayer, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_InfoSize) / 4, // number of values for this option .option_val = 1, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Size", // pointer to a string .desc = "Change the size of the info display window.\nLarge is recommended for CRT.\nMedium/Small recommended for Dolphin Emulator.", // string describing what this option does .option_values = LabValues_InfoSize, // pointer to an array of strings .onOptionChange = Lab_ChangeInfoSizePos, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_InfoPresets) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Display Preset", // pointer to a string .desc = "Choose between pre-configured selections.", // string describing what this option does .option_values = LabValues_InfoPresets, // pointer to an array of strings .onOptionChange = Lab_ChangeInfoPreset, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_InfoDisplay) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Row 1", // pointer to a string .desc = "Adjust what is displayed in this row.", // string describing what this option does .option_values = LabValues_InfoDisplay, // pointer to an array of strings .onOptionChange = Lab_ChangeInfoRow, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_InfoDisplay) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Row 2", // pointer to a string .desc = "Adjust what is displayed in this row.", // string describing what this option does .option_values = LabValues_InfoDisplay, // pointer to an array of strings .onOptionChange = Lab_ChangeInfoRow, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_InfoDisplay) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Row 3", // pointer to a string .desc = "Adjust what is displayed in this row.", // string describing what this option does .option_values = LabValues_InfoDisplay, // pointer to an array of strings .onOptionChange = Lab_ChangeInfoRow, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_InfoDisplay) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Row 4", // pointer to a string .desc = "Adjust what is displayed in this row.", // string describing what this option does .option_values = LabValues_InfoDisplay, // pointer to an array of strings .onOptionChange = Lab_ChangeInfoRow, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_InfoDisplay) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Row 5", // pointer to a string .desc = "Adjust what is displayed in this row.", // string describing what this option does .option_values = LabValues_InfoDisplay, // pointer to an array of strings .onOptionChange = Lab_ChangeInfoRow, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_InfoDisplay) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Row 6", // pointer to a string .desc = "Adjust what is displayed in this row.", // string describing what this option does .option_values = LabValues_InfoDisplay, // pointer to an array of strings .onOptionChange = Lab_ChangeInfoRow, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_InfoDisplay) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Row 7", // pointer to a string .desc = "Adjust what is displayed in this row.", // string describing what this option does .option_values = LabValues_InfoDisplay, // pointer to an array of strings .onOptionChange = Lab_ChangeInfoRow, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_InfoDisplay) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Row 8", // pointer to a string .desc = "Adjust what is displayed in this row.", // string describing what this option does .option_values = LabValues_InfoDisplay, // pointer to an array of strings .onOptionChange = Lab_ChangeInfoRow, }, }; static EventMenu LabMenu_InfoDisplay = { .name = "Info Display", // the name of this menu .option_num = 11, // number of options this menu contains .scroll = 0, // runtime variable used for how far down in the menu to start .state = 0, // bool used to know if this menu is focused, used at runtime .cursor = 0, // index of the option currently selected, used at runtime .options = &LabOptions_InfoDisplay, // pointer to all of this menu's options .prev = 0, // pointer to previous menu, used at runtime }; // CPU static char **LabValues_Shield[] = {"Off", "On Until Hit", "On"}; static char **LabValues_CPUBehave[] = {"Stand", "Shield", "Crouch", "Jump"}; static char **LabValues_TDI[] = {"Random", "Inwards", "Outwards", "Floorhug", "Custom", "None"}; static char **LabValues_SDIFreq[] = {"None", "Low", "Medium", "High"}; static char **LabValues_SDIDir[] = {"Random", "Away", "Towards"}; static char **LabValues_Tech[] = {"Random", "Neutral", "Away", "Towards", "None"}; static char **LabValues_Getup[] = {"Random", "Stand", "Away", "Towards", "Attack"}; static char **LabValues_CounterGround[] = {"None", "Spotdodge", "Shield", "Grab", "Up B", "Down B", "Up Smash", "Down Smash", "Forward Smash", "Roll Away", "Roll Towards", "Roll Random", "Neutral Air", "Forward Air", "Down Air", "Back Air", "Up Air", "Jab", "Forward Tilt", "Up Tilt", "Down Tilt", "Short Hop", "Full Hop"}; static char **LabValues_CounterAir[] = {"None", "Airdodge", "Jump Away", "Jump Towards", "Up B", "Down B", "Neutral Air", "Forward Air", "Down Air", "Back Air", "Up Air", "Tumble Fastfall", "Wiggle Fastfall"}; static char **LabValues_CounterShield[] = {"None", "Grab", "Short Hop", "Full Hop", "Spotdodge", "Roll Away", "Roll Towards", "Roll Random", "Up B", "Down B", "Neutral Air", "Forward Air", "Down Air", "Back Air", "Up Air"}; static char **LabValues_GrabEscape[] = {"None", "Medium", "High", "Perfect"}; static EventOption LabOptions_CPU[] = { // cpu percent { .option_kind = OPTKIND_INT, // the type of option this is; menu, string list, integer list, etc .value_num = 999, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "CPU Percent", // pointer to a string .desc = "Adjust the CPU's percent.", // string describing what this option does .option_values = "%d%%", // pointer to an array of strings .onOptionChange = Lab_ChangeCPUPercent, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_CPUBehave) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Behavior", // pointer to a string .desc = "Adjust the CPU's default action.", // string describing what this option does .option_values = LabValues_CPUBehave, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_Shield) / 4, // number of values for this option .option_val = 1, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = {"Infinite Shields"}, // pointer to a string .desc = "Adjust how shield health deteriorates.", // string describing what this option does .option_values = LabValues_Shield, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = 2, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = {"Intangibility"}, // pointer to a string .desc = "Toggle the CPU's ability to take damage.", // string describing what this option does .option_values = LabOptions_OffOn, // pointer to an array of strings .onOptionChange = Lab_ChangeCPUIntang, }, // SDI Freq { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_SDIFreq) / 4, // number of values for this option .option_val = 2, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Smash DI Frequency", // pointer to a string .desc = "Adjust how often the CPU will alter their position\nduring hitstop.", // string describing what this option does .option_values = LabValues_SDIFreq, // pointer to an array of strings .onOptionChange = 0, }, // SDI Direction { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_SDIDir) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Smash DI Direction", // pointer to a string .desc = "Adjust the direction in which the CPU will alter \ntheir position during hitstop.", // string describing what this option does .option_values = LabValues_SDIDir, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_TDI) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Trajectory DI", // pointer to a string .desc = "Adjust how the CPU will alter their knockback\ntrajectory.", // string describing what this option does .option_values = LabValues_TDI, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_FUNC, // the type of option this is; menu, string list, integer list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Custom TDI", // pointer to a string .desc = "Create custom trajectory DI values for the\nCPU to perform.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = 0, .onOptionSelect = Lab_SelectCustomTDI, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_Tech) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Tech Option", // pointer to a string .desc = "Adjust what the CPU will do upon colliding\nwith the stage.", // string describing what this option does .option_values = LabValues_Tech, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_Getup) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Get Up Option", // pointer to a string .desc = "Adjust what the CPU will do after missing\na tech input.", // string describing what this option does .option_values = LabValues_Getup, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_GrabEscape) / 4, // number of values for this option .option_val = CPUMASH_HIGH, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Grab Escape", // pointer to a string .desc = "Adjust how the CPU will attempt to escape\ngrabs.", // string describing what this option does .option_values = LabValues_GrabEscape, // pointer to an array of strings .onOptionChange = 0, }, /* { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabOptions_OffOn) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Auto Reset", // pointer to a string .desc = "Automatically reset after the CPU is\nactionable.", // string describing what this option does .option_values = LabOptions_OffOn, // pointer to an array of strings .onOptionChange = 0, }, */ { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_CounterGround) / 4, // number of values for this option .option_val = 1, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Counter Action (Ground)", // pointer to a string .desc = "Select the action to be performed after a\ngrounded CPU's hitstun ends.", // string describing what this option does .option_values = LabValues_CounterGround, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_CounterAir) / 4, // number of values for this option .option_val = 1, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Counter Action (Air)", // pointer to a string .desc = "Select the action to be performed after an\nairborne CPU's hitstun ends.", // string describing what this option does .option_values = LabValues_CounterAir, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_CounterShield) / 4, // number of values for this option .option_val = 1, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Counter Action (Shield)", // pointer to a string .desc = "Select the action to be performed after the\nCPU's shield is hit.", // string describing what this option does .option_values = LabValues_CounterShield, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_INT, // the type of option this is; menu, string list, integer list, etc .value_num = 100, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Counter After Frames", // pointer to a string .desc = "Adjust the amount of actionable frames before \nthe CPU counters.", // string describing what this option does .option_values = "%d Frames", // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_INT, // the type of option this is; menu, string list, integer list, etc .value_num = 100, // number of values for this option .option_val = 1, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Counter After Hits", // pointer to a string .desc = "Adjust the amount of hits taken before the \nCPU counters.", // string describing what this option does .option_values = "%d Hits", // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_INT, // the type of option this is; menu, string list, integer list, etc .value_num = 100, // number of values for this option .option_val = 1, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Counter After Shield Hits", // pointer to a string .desc = "Adjust the amount of hits the CPU's shield\nwill take before they counter.", // string describing what this option does .option_values = "%d Hits", // pointer to an array of strings .onOptionChange = 0, }, }; static EventMenu LabMenu_CPU = { .name = "CPU Options", // the name of this menu .option_num = sizeof(LabOptions_CPU) / sizeof(EventOption), // number of options this menu contains .scroll = 0, // runtime variable used for how far down in the menu to start .state = 0, // bool used to know if this menu is focused, used at runtime .cursor = 0, // index of the option currently selected, used at runtime .options = &LabOptions_CPU, // pointer to all of this menu's options .prev = 0, // pointer to previous menu, used at runtime }; // Recording static char **LabValues_RecordSlot[] = {"Random", "Slot 1", "Slot 2", "Slot 3", "Slot 4", "Slot 5", "Slot 6"}; static char **LabValues_HMNRecordMode[] = {"Off", "Record", "Playback"}; static char **LabValues_CPURecordMode[] = {"Off", "Control", "Record", "Playback"}; static EventOption LabOptions_Record[] = { { .option_kind = OPTKIND_FUNC, // the type of option this is; menu, string list, integer list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Save Positions", // pointer to a string .desc = "Save the current fighter positions\nas the initial positions.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionSelect = Record_InitState, }, { .option_kind = OPTKIND_FUNC, // the type of option this is; menu, string list, integer list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Restore Positions", // pointer to a string .desc = "Load the saved fighter positions and \nstart the sequence from the beginning.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionSelect = Record_RestoreState, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_HMNRecordMode) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "HMN Mode", // pointer to a string .desc = "Toggle between recording and playback of\ninputs.", // string describing what this option does .option_values = LabValues_HMNRecordMode, // pointer to an array of strings .onOptionChange = Record_ChangeHMNMode, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_RecordSlot) / 4, // number of values for this option .option_val = 1, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "HMN Record Slot", // pointer to a string .desc = "Toggle which recording slot to save inputs \nto. Maximum of 6 and can be set to random \nduring playback.", // string describing what this option does .option_values = LabValues_RecordSlot, // pointer to an array of strings .onOptionChange = Record_ChangeHMNSlot, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_CPURecordMode) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "CPU Mode", // pointer to a string .desc = "Toggle between recording and playback of\ninputs.", // string describing what this option does .option_values = LabValues_CPURecordMode, // pointer to an array of strings .onOptionChange = Record_ChangeCPUMode, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabValues_RecordSlot) / 4, // number of values for this option .option_val = 1, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "CPU Record Slot", // pointer to a string .desc = "Toggle which recording slot to save inputs \nto. Maximum of 6 and can be set to random \nduring playback.", // string describing what this option does .option_values = LabValues_RecordSlot, // pointer to an array of strings .onOptionChange = Record_ChangeCPUSlot, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabOptions_OffOn) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Loop Input Playback", // pointer to a string .desc = "Loop the recorded inputs when they end.", // string describing what this option does .option_values = LabOptions_OffOn, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integer list, etc .value_num = sizeof(LabOptions_OffOn) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Auto Restore", // pointer to a string .desc = "Automatically restore saved positions \nafter the playback ends.", // string describing what this option does .option_values = LabOptions_OffOn, // pointer to an array of strings .onOptionChange = 0, }, { .option_kind = OPTKIND_FUNC, // the type of option this is; menu, string list, integer list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Export", // pointer to a string .desc = "Export the recording to a memory card\nfor later use or to share with others.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionSelect = Export_Init, }, }; static EventMenu LabMenu_Record = { .name = "Recording", // the name of this menu .option_num = sizeof(LabOptions_Record) / sizeof(EventOption), // number of options this menu contains .scroll = 0, // runtime variable used for how far down in the menu to start .state = 0, // bool used to know if this menu is focused, used at runtime .cursor = 0, // index of the option currently selected, used at runtime .options = &LabOptions_Record, // pointer to all of this menu's options .prev = 0, // pointer to previous menu, used at runtime }; // Static Variables static DIDraw didraws[6]; static GOBJ *infodisp_gobj; static RecData rec_data; static Savestate *rec_state; static _HSD_ImageDesc snap_image = {0}; static _HSD_ImageDesc resized_image = { .format = 4, .height = RESIZE_HEIGHT, .width = RESIZE_WIDTH, }; static u8 snap_status; static u8 export_status; static Arch_LabData *stc_lab_data; static char *tm_filename = "TMREC_%02d%02d%04d_%02d%02d%02d"; static char stc_save_name[32] = "Training Mode Input Recording "; static DevText *stc_devtext; static u8 stc_hmn_controller; // making this static so importing recording doesnt overwrite static u8 stc_cpu_controller; // making this static so importing recording doesnt overwrite static u8 stc_tdi_val_num; // number of custom tdi values set static s8 stc_tdi_vals[TDI_HITNUM][2][2]; // contains the custom tdi values static u8 stc_sdifreqs[] = {6, 4, 2}; // Static Export Variables static RecordingSave *stc_rec_save; static u32 stc_transfer_buf_size; static u8 *stc_transfer_buf; static MemcardSave memcard_save; static int chunk_num; static int save_pre_tick; static char *slots_names[] = {"A", "B"}; // lz77 functions credited to https://github.com/andyherbert/lz1 int x_to_the_n(int x, int n) { int i; /* Variable used in loop counter */ int number = 1; for (i = 0; i < n; ++i) number *= x; return (number); } u32 lz77_compress(u8 *uncompressed_text, u32 uncompressed_size, u8 *compressed_text, u8 pointer_length_width) { u16 pointer_pos, temp_pointer_pos, output_pointer, pointer_length, temp_pointer_length; u32 compressed_pointer, output_size, coding_pos, output_lookahead_ref, look_behind, look_ahead; u16 pointer_pos_max, pointer_length_max; pointer_pos_max = x_to_the_n(2, 16 - pointer_length_width); pointer_length_max = x_to_the_n(2, pointer_length_width); *((u32 *)compressed_text) = uncompressed_size; *(compressed_text + 4) = pointer_length_width; compressed_pointer = output_size = 5; for (coding_pos = 0; coding_pos < uncompressed_size; ++coding_pos) { pointer_pos = 0; pointer_length = 0; for (temp_pointer_pos = 1; (temp_pointer_pos < pointer_pos_max) && (temp_pointer_pos <= coding_pos); ++temp_pointer_pos) { look_behind = coding_pos - temp_pointer_pos; look_ahead = coding_pos; for (temp_pointer_length = 0; uncompressed_text[look_ahead++] == uncompressed_text[look_behind++]; ++temp_pointer_length) if (temp_pointer_length == pointer_length_max) break; if (temp_pointer_length > pointer_length) { pointer_pos = temp_pointer_pos; pointer_length = temp_pointer_length; if (pointer_length == pointer_length_max) break; } } coding_pos += pointer_length; if ((coding_pos == uncompressed_size) && pointer_length) { output_pointer = (pointer_length == 1) ? 0 : ((pointer_pos << pointer_length_width) | (pointer_length - 2)); output_lookahead_ref = coding_pos - 1; } else { output_pointer = (pointer_pos << pointer_length_width) | (pointer_length ? (pointer_length - 1) : 0); output_lookahead_ref = coding_pos; } *((u16 *)(compressed_text + compressed_pointer)) = output_pointer; compressed_pointer += 2; *(compressed_text + compressed_pointer++) = *(uncompressed_text + output_lookahead_ref); output_size += 3; } return output_size; } u32 lz77_decompress(u8 *compressed_text, u8 *uncompressed_text) { u8 pointer_length_width; u16 input_pointer, pointer_length, pointer_pos, pointer_length_mask; u32 compressed_pointer, coding_pos, pointer_offset, uncompressed_size; uncompressed_size = *((u32 *)compressed_text); pointer_length_width = *(compressed_text + 4); compressed_pointer = 5; pointer_length_mask = x_to_the_n(2, pointer_length_width) - 1; for (coding_pos = 0; coding_pos < uncompressed_size; ++coding_pos) { input_pointer = *((u16 *)(compressed_text + compressed_pointer)); compressed_pointer += 2; pointer_pos = input_pointer >> pointer_length_width; pointer_length = pointer_pos ? ((input_pointer & pointer_length_mask) + 1) : 0; if (pointer_pos) for (pointer_offset = coding_pos - pointer_pos; pointer_length > 0; --pointer_length) uncompressed_text[coding_pos++] = uncompressed_text[pointer_offset++]; *(uncompressed_text + coding_pos) = *(compressed_text + compressed_pointer++); } return coding_pos; } // Menu Callbacks void Lab_ChangePlayerPercent(GOBJ *menu_gobj, int value) { GOBJ *fighter = Fighter_GetGObj(0); FighterData *fighter_data = fighter->userdata; fighter_data->dmg.percent = value; Fighter_SetHUDDamage(0, value); return; } void Lab_ChangeFrameAdvance(GOBJ *menu_gobj, int value) { // remove colanim if toggling off if (value == 0) LabOptions_General[OPTGEN_FRAMEBTN].disable = 1; // apply colanim else LabOptions_General[OPTGEN_FRAMEBTN].disable = 0; return; } void Lab_ChangeCPUPercent(GOBJ *menu_gobj, int value) { GOBJ *fighter = Fighter_GetGObj(1); FighterData *fighter_data = fighter->userdata; fighter_data->dmg.percent = value; Fighter_SetHUDDamage(1, value); return; } void Lab_ChangeCPUIntang(GOBJ *menu_gobj, int value) { GOBJ *fighter = Fighter_GetGObj(1); FighterData *fighter_data = fighter->userdata; // remove colanim if toggling off if (value == 0) Fighter_ColorRemove(fighter_data, INTANG_COLANIM); // apply colanim else Fighter_ApplyOverlay(fighter_data, INTANG_COLANIM, 0); return; } void Lab_ChangeModelDisplay(GOBJ *menu_gobj, int value) { // loop through all fighters GOBJ **GOBJList = R13_PTR(-0x3E74); GOBJ *this_fighter = GOBJList[8]; while (this_fighter != 0) { // get data FighterData *thisFighterData = this_fighter->userdata; // toggle thisFighterData->show_model = value; // get next fighter this_fighter = this_fighter->next; } GOBJ *fighter = Fighter_GetGObj(0); FighterData *fighter_data = fighter->userdata; return; } void Lab_ChangeHitDisplay(GOBJ *menu_gobj, int value) { // loop through all fighters GOBJ **GOBJList = R13_PTR(-0x3E74); GOBJ *this_fighter = GOBJList[8]; while (this_fighter != 0) { // get data FighterData *thisFighterData = this_fighter->userdata; // toggle thisFighterData->show_hit = value; // get next fighter this_fighter = this_fighter->next; } GOBJ *fighter = Fighter_GetGObj(0); FighterData *fighter_data = fighter->userdata; return; } void Lab_ChangeEnvCollDisplay(GOBJ *menu_gobj, int value) { stc_matchcam->show_coll = value; return; } void Lab_ChangeCamMode(GOBJ *menu_gobj, int value) { MatchCamera *cam = MATCH_CAM; // normal cam if (value == 0) { Match_SetNormalCamera(); } // zoom cam else if (value == 1) { Match_SetFreeCamera(0, 3); cam->freecam_fov.X = 140; cam->freecam_rotate.Y = 10; } // fixed else if (value == 2) { Match_SetFixedCamera(); } else if (value == 3) { Match_SetDevelopCamera(); } Match_CorrectCamera(); return; } void Lab_ChangeInfoRow(GOBJ *menu_gobj, int value) { EventOption *idOptions = &LabOptions_InfoDisplay; // changed option, set preset to custom idOptions[OPTINF_PRESET].option_val = 1; } void Lab_ChangeInfoPreset(GOBJ *menu_gobj, int value) { static int idPresets[][8] = { // None { 0, 0, 0, 0, 0, 0, 0, 0, }, // Ledge { 2, 3, 8, 7, 14, 20, 21, 0, }, // Damage { 2, 3, 4, 5, 6, 15, 16, 18, }, }; EventOption *idOptions = &LabOptions_InfoDisplay; int *currPreset = 0; // check for NONE if (value == 0) currPreset = idPresets[0]; // check for preset value -= 2; if (value >= 0) { currPreset = idPresets[value + 1]; } // copy values if (currPreset != 0) { for (int i = 0; i < 8; i++) { idOptions[i + OPTINF_ROW1].option_val = currPreset[i]; } } } void Lab_ChangeInfoSizePos(GOBJ *menu_gobj, int value) { return; } void Lab_ChangeInfoPlayer(GOBJ *menu_gobj, int value) { return; } void Lab_ChangeHUD(GOBJ *menu_gobj, int value) { // toggle HUD u8 *hideHUD = (u8 *)(R13 + -0x4948); if (value == 0) { *hideHUD = 1; } else { *hideHUD = 0; } return; } void Lab_Exit(int value) { Match *match = MATCH; // end game match->state = 3; // cleanup Match_EndVS(); // Unfreeze LabOptions_General[OPTGEN_FRAME].option_val = 0; //HSD_Update *update = HSD_UPDATE; //update->pause_develop = 0; return; } // Event Functions GOBJ *InfoDisplay_Init() { // Create Info Display GOBJ GOBJ *idGOBJ = GObj_Create(0, 0, 0); InfoDisplayData *idData = calloc(sizeof(InfoDisplayData)); GObj_AddUserData(idGOBJ, 4, HSD_Free, idData); infodisp_gobj = idGOBJ; // Load jobj evMenu *menuAssets = event_vars->menu_assets; JOBJ *menu = JOBJ_LoadJoint(menuAssets->popup); idData->menuModel = menu; // Add to gobj GObj_AddObject(idGOBJ, 3, menu); // Add gxlink GObj_AddGXLink(idGOBJ, InfoDisplay_GX, GXLINK_INFDISP, GXPRI_INFDISP); // Save pointers to corners JOBJ *corners[4]; JOBJ_GetChild(menu, &corners, 2, 3, 4, 5, -1); idData->botLeftEdge = corners[0]; idData->botRightEdge = corners[1]; // move into position //menu->scale.X = INFDISP_SCALE; //menu->scale.Y = INFDISP_SCALE; //menu->scale.Z = INFDISP_SCALE; menu->trans.X = INFDISP_X; menu->trans.Y = INFDISP_Y; corners[0]->trans.X = 0; corners[1]->trans.X = INFDISP_WIDTH; corners[2]->trans.X = 0; corners[3]->trans.X = INFDISP_WIDTH; corners[0]->trans.Y = 0; corners[1]->trans.Y = 0; corners[2]->trans.Y = 0; corners[3]->trans.Y = 0; //JOBJ_SetFlags(menu, JOBJ_HIDDEN); menu->dobj->next->mobj->mat->alpha = 0.6; // Create text object int canvas_index = Text_CreateCanvas(2, idGOBJ, 14, 15, 0, GXLINK_INFDISPTEXT, GXPRI_INFDISPTEXT, 19); Text *text = Text_CreateText(2, canvas_index); text->kerning = 1; text->use_aspect = 1; text->aspect.X = 545; // Create subtexts for each row for (int i = 0; i < 8; i++) { Text_AddSubtext(text, 0, (INFDISPTEXT_YOFFSET * i), &nullString); } idData->text = text; // adjust size based on the console / settings if ((OSGetConsoleType() == OS_CONSOLE_DEVHW3) || (stc_HSD_VI->is_prog == 1)) // 480p / dolphin uses medium by default LabOptions_InfoDisplay[OPT_SCALE].option_val = 1; else // 480i on wii uses large (shitty composite!) LabOptions_InfoDisplay[OPT_SCALE].option_val = 2; // update size Lab_ChangeInfoSizePos(0, 0); // update to show/hide InfoDisplay_Think(idGOBJ); return idGOBJ; } void InfoDisplay_GX(GOBJ *gobj, int pass) { GXLink_Common(gobj, pass); return; } void InfoDisplay_Think(GOBJ *gobj) { static Vec2 stc_info_pos[] = { {-26.5, 21.5}, {-10, 21.5}, {6, 21.5}, {-26.5, -10.5}, {-10, -10.5}, {6, -10.5}, }; static float stc_info_scale[] = { 2, 3, 4, }; InfoDisplayData *idData = gobj->userdata; Text *text = idData->text; EventOption *idOptions = &LabOptions_InfoDisplay; if ((Pause_CheckStatus(1) != 2)) //&& (idOptions[OPTINF_TOGGLE].option_val == 1)) { // get the last row enabled int rowsEnabled = 8; while (rowsEnabled > 0) { if (idOptions[rowsEnabled - 1 + OPTINF_ROW1].option_val != 0) break; rowsEnabled--; } // if a row is enabled, display if (rowsEnabled != 0) { // show model and text JOBJ_ClearFlags(idData->menuModel, JOBJ_HIDDEN); idData->text->hidden = 0; // scale window Y based on rows enabled JOBJ *leftCorner = idData->botLeftEdge; JOBJ *rightCorner = idData->botRightEdge; float yPos = (rowsEnabled * INFDISP_BOTYOFFSET) + INFDISP_BOTY; leftCorner->trans.Y = yPos; rightCorner->trans.Y = yPos; JOBJ_SetMtxDirtySub(idData->menuModel); // update info display strings int ply = idOptions[OPTINF_PLAYER].option_val; GOBJ *fighter = Fighter_GetGObj(ply); FighterData *fighter_data; if (fighter != 0) fighter_data = fighter->userdata; for (int i = 0; i < 8; i++) { int value = idOptions[i + OPTINF_ROW1].option_val; // hide text if set to 0 or fighter DNE if ((idOptions[i + OPTINF_ROW1].option_val == 0) || fighter == 0) { Text_SetText(text, i, ""); } // display info else { switch (value) { case (INFDISPROW_POS): { Text_SetText(text, i, "Pos: (%+.3f , %+.3f)", fighter_data->phys.pos.X, fighter_data->phys.pos.Y); break; } case (INFDISPROW_STATE): { if (fighter_data->anim_id != -1) { SubactionHeader *subHeader = Fighter_GetSubactionHeader(fighter_data, fighter_data->anim_id); // extract state name from symbol int pos = 0; int posStart; int nameSize = 0; char *symbol = subHeader->symbol; for (int i = 0; pos < 50; pos++) { // search for "N_" if ((symbol[pos] == 'N') && (symbol[pos + 1] == '_')) { // posStart = beginning of state name pos++; posStart = pos + 1; // search for "_" for (int i = 0; pos < 50; pos++) { if (symbol[pos] == '_') { nameSize = pos - posStart; } } } } if (nameSize != 0) { // copy string char stateNameBuffer[50]; memcpy(&stateNameBuffer, &symbol[posStart], nameSize); stateNameBuffer[nameSize] = 0; Text_SetText(text, i, "State: %s", &stateNameBuffer); } } else Text_SetText(text, i, "State: %s", "Unknown"); break; } case (INFDISPROW_FRAME): { float *animStruct = fighter_data->anim_curr_flags_ptr; int frameCurr = 0; int frameTotal = 0; // if exists if (animStruct != 0) { // determine how many frames shield stun is float animFrameTotal = animStruct[2]; float animFrameCurr = fighter_data->stateFrame; float animSpeed = fighter_data->stateSpeed; frameTotal = (animFrameTotal / animSpeed); frameCurr = (animFrameCurr / animSpeed); } Text_SetText(text, i, "State Frame: %d/%d", frameCurr, frameTotal); break; } case (INFDISPROW_SELFVEL): { Text_SetText(text, i, "SelfVel: (%+.3f , %+.3f)", fighter_data->phys.self_vel.X, fighter_data->phys.self_vel.Y); break; } case (INFDISPROW_KBVEL): { Text_SetText(text, i, "KBVel: (%+.3f , %+.3f)", fighter_data->phys.kb_vel.X, fighter_data->phys.kb_vel.Y); break; } case (INFDISPROW_TOTALVEL): { Text_SetText(text, i, "TotalVel: (%+.3f , %+.3f)", fighter_data->phys.self_vel.X + fighter_data->phys.kb_vel.X, fighter_data->phys.self_vel.Y + fighter_data->phys.kb_vel.Y); break; } case (INFDISPROW_ENGLSTICK): { Text_SetText(text, i, "LStick: (%+.4f , %+.4f)", fighter_data->input.lstick_x, fighter_data->input.lstick_y); break; } case (INFDISPROW_SYSLSTICK): { HSD_Pad *pad = PadGet(ply, PADGET_MASTER); Text_SetText(text, i, "LStick Sys: (%+.4f , %+.4f)", pad->fstickX, pad->fstickY); break; } case (INFDISPROW_ENGCSTICK): { Text_SetText(text, i, "CStick: (%+.4f , %+.4f)", fighter_data->input.cstick_x, fighter_data->input.cstick_y); break; } case (INFDISPROW_SYSCSTICK): { HSD_Pad *pad = PadGet(ply, PADGET_MASTER); Text_SetText(text, i, "CStick Sys: (%+.4f , %+.4f)", pad->fsubstickX, pad->fsubstickY); break; } case (INFDISPROW_ENGTRIGGER): { Text_SetText(text, i, "Trigger: (%+.3f)", fighter_data->input.trigger); break; } case (INFDISPROW_SYSTRIGGER): { HSD_Pad *pad = PadGet(ply, PADGET_MASTER); Text_SetText(text, i, "Trigger Sys: (%+.3f , %+.3f)", pad->ftriggerLeft, pad->ftriggerRight); break; } case (INFDISPROW_LEDGECOOLDOWN): { Text_SetText(text, i, "Ledgegrab Timer: %d", fighter_data->ledge_cooldown); break; } case (INFDISPROW_INTANGREMAIN): { int intang = fighter_data->hurtstatus.respawn_intang_left; if (fighter_data->hurtstatus.ledge_intang_left > fighter_data->hurtstatus.respawn_intang_left) intang = fighter_data->hurtstatus.ledge_intang_left; Text_SetText(text, i, "Intangibility Timer: %d", intang); break; } case (INFDISPROW_HITSTOP): { Text_SetText(text, i, "Hitlag: %.0f", fighter_data->dmg.hitlag_frames); break; } case (INFDISPROW_HITSTUN): { // get hitstun float hitstun = 0; if (fighter_data->flags.hitstun == 1) hitstun = AS_FLOAT(fighter_data->state_var.stateVar1); Text_SetText(text, i, "Hitstun: %.0f", hitstun); break; } case (INFDISPROW_SHIELDHEALTH): { Text_SetText(text, i, "Shield Health: %.3f", fighter_data->shield.health); break; } case (INFDISPROW_SHIELDSTUN): { int stunTotal = 0; int stunLeft = 0; // check if taking shield stun if (fighter_data->state == ASID_GUARDSETOFF) { // determine how many frames shield stun is float frameTotal = JOBJ_GetJointAnimFrameTotal(fighter->hsd_object); float frameCurr = fighter_data->stateFrame; float animSpeed = fighter_data->stateSpeed; stunTotal = (frameTotal / animSpeed); stunLeft = stunTotal - (frameCurr / animSpeed); // 0 index stunTotal++; stunLeft++; } Text_SetText(text, i, "Shield Stun: %d/%d", stunLeft, stunTotal); break; } case (INFDISPROW_GRIP): { float grip = 0; if (fighter_data->grab.grab_victim != 0) { GOBJ *victim = fighter_data->grab.grab_victim; FighterData *victim_data = victim->userdata; grip = victim_data->grab.grab_timer; } Text_SetText(text, i, "Grip Strength: %.0f", grip); break; } case (INFDISPROW_ECBLOCK): { Text_SetText(text, i, "ECB Lock: %d", fighter_data->coll_data.ecb_lock); break; } case (INFDISPROW_ECBBOT): { Text_SetText(text, i, "ECB Bottom: %.3f", fighter_data->coll_data.ecbCurr_bot.Y); break; } case (INFDISPROW_JUMPS): { Text_SetText(text, i, "Jumps: %d/%d", fighter_data->jump.jumps_used, fighter_data->attr.max_jumps); break; } case (INFDISPROW_WALLJUMPS): { Text_SetText(text, i, "Walljumps: %d", fighter_data->jump.walljumps_used); break; } case (INFDISPROW_JAB): { Text_SetText(text, i, "Jab Counter: IDK"); break; } case (INFDISPROW_LINE): { CollData *colldata = &fighter_data->coll_data; int ground = -1; int ceil = -1; int left = -1; int right = -1; if ((colldata->envFlags & ECB_GROUND) != 0) ground = colldata->ground_index; if ((colldata->envFlags & ECB_CEIL) != 0) ceil = colldata->ceil_index; if ((colldata->envFlags & ECB_WALLLEFT) != 0) left = colldata->leftwall_index; if ((colldata->envFlags & ECB_WALLRIGHT) != 0) right = colldata->rightwall_index; Text_SetText(text, i, "Lines: G:%d, C:%d, L:%d, R:%d,", ground, ceil, left, right); break; } case (INFDISPROW_BLASTLR): { Stage *stage = STAGE; Text_SetText(text, i, "Blastzone L/R: (%+.3f,%+.3f)", stage->blastzoneLeft, stage->blastzoneRight); break; } case (INFDISPROW_BLASTUD): { Stage *stage = STAGE; Text_SetText(text, i, "Blastzone U/D: (%.2f,%.2f)", stage->blastzoneTop, stage->blastzoneBottom); break; } } } } // adjust scale JOBJ *info_jobj = idData->menuModel; Text *info_text = idData->text; Vec2 *pos = &info_jobj->trans; //Vec2 *pos = &stc_info_pos[LabOptions_InfoDisplay[OPTINF_POS].option_val]; float scale = stc_info_scale[LabOptions_InfoDisplay[OPTINF_SIZE].option_val]; // background scale info_jobj->scale.X = scale; info_jobj->scale.Y = scale; // text scale info_text->scale.X = ((scale / 4.0) * INFDISPTEXT_SCALE); info_text->scale.Y = ((scale / 4.0) * INFDISPTEXT_SCALE); /* // background position info_jobj->trans.X = pos->X; info_jobj->trans.Y = pos->Y; */ // text position info_text->trans.X = pos->X + (INFDISPTEXT_X * (scale / 4.0)); info_text->trans.Y = (pos->Y * -1) + (INFDISPTEXT_Y * (scale / 4.0)); // model color int info_player = LabOptions_InfoDisplay[OPTINF_PLAYER].option_val; GXColor *shield_color = *stc_shieldcolors; GXColor *border_color = &info_jobj->dobj->mobj->mat->diffuse; border_color->r = shield_color[info_player].r; border_color->g = shield_color[info_player].g; border_color->b = shield_color[info_player].b; // update jobj JOBJ_SetMtxDirtySub(info_jobj); } else { // hide model and text JOBJ_SetFlags(idData->menuModel, JOBJ_HIDDEN); idData->text->hidden = 1; } } else { // hide model and text JOBJ_SetFlags(idData->menuModel, JOBJ_HIDDEN); idData->text->hidden = 1; } return; } float Fighter_GetOpponentDir(FighterData *from, FighterData *to) { float dir = -1; Vec3 *from_pos = &from->phys.pos; Vec3 *to_pos = &to->phys.pos; if (from_pos->X <= to_pos->X) dir = 1; return dir; } int CPUAction_CheckMultipleState(GOBJ *cpu, int group_kind) { static u8 grActionable[] = {ASID_WAIT, ASID_WALKSLOW, ASID_WALKMIDDLE, ASID_WALKFAST, ASID_RUN, ASID_SQUATWAIT, ASID_OTTOTTOWAIT, ASID_GUARD}; static u8 airActionable[] = {ASID_JUMPF, ASID_JUMPB, ASID_JUMPAERIALF, ASID_JUMPAERIALB, ASID_FALL, ASID_FALLAERIALF, ASID_FALLAERIALB, ASID_DAMAGEFALL, ASID_DAMAGEFLYROLL, ASID_DAMAGEFLYTOP}; static u8 airDamage[] = {ASID_DAMAGEFLYHI, ASID_DAMAGEFLYN, ASID_DAMAGEFLYLW, ASID_DAMAGEFLYTOP, ASID_DAMAGEFLYROLL, ASID_DAMAGEFALL}; static u8 jumpStates[] = {ASID_JUMPF, ASID_JUMPB, ASID_JUMPAERIALF, ASID_JUMPAERIALB}; static u8 fallStates[] = {ASID_FALL, ASID_FALLAERIAL, ASID_FALLAERIALF, ASID_FALLAERIALB}; FighterData *cpu_data = cpu->userdata; int isActionable = 0; int cpu_state = cpu_data->state; // if 0, check the one that corresponds with ground state if (group_kind == 0) { group_kind = cpu_data->phys.air_state + 1; } // ground if (group_kind == 1) { // check ground actionable for (int i = 0; i < sizeof(grActionable); i++) { if (cpu_state == grActionable[i]) { isActionable = 1; break; } } // landing if ((cpu_data->state == ASID_LANDING) && (cpu_data->stateFrame >= cpu_data->attr.normal_landing_lag)) isActionable = 1; } // air else if (group_kind == 2) { // check air actionable for (int i = 0; i < sizeof(airActionable); i++) { if (cpu_state == airActionable[i]) { isActionable = 1; break; } } } // damage state that requires wiggling else if (group_kind == 3) { // check air actionable for (int i = 0; i < sizeof(airDamage); i++) { if (cpu_state == airDamage[i]) { isActionable = 1; break; } } } // jump states else if (group_kind == 4) { for (int i = 0; i < sizeof(jumpStates); i++) { if (cpu_state == jumpStates[i]) { isActionable = 1; break; } } } // fall states else if (group_kind == 5) { for (int i = 0; i < sizeof(fallStates); i++) { if (cpu_state == fallStates[i]) { isActionable = 1; break; } } } return isActionable; } int CPU_IsThrown(GOBJ *cpu) { FighterData *cpu_data = cpu->userdata; int is_thrown = 0; int cpu_state = cpu_data->state; // check if thrown if (((cpu_state >= ASID_THROWNF) && (cpu_state <= ASID_THROWNLW)) || (cpu_state == ASID_CAPTURECAPTAIN) || (cpu_state == ASID_THROWNKOOPAF) || (cpu_state == ASID_THROWNKOOPAB) || (cpu_state == ASID_THROWNKOOPAAIRF) || ((cpu_state >= ASID_THROWNFF) && (cpu_state <= ASID_THROWNFLW))) is_thrown = 1; return is_thrown; } int CPU_IsGrabbed(GOBJ *cpu) { FighterData *cpu_data = cpu->userdata; int is_grabbed = 0; int cpu_state = cpu_data->state; // check if thrown if ((cpu_state == ASID_CAPTUREWAITHI) || (cpu_state == ASID_CAPTUREWAITLW) || (cpu_state == ASID_CAPTUREWAITKOOPA) || (cpu_state == ASID_CAPTUREWAITKOOPAAIR) || (cpu_state == ASID_CAPTUREWAITKIRBY) || (cpu_state == ASID_DAMAGEICE) || (cpu_state == ASID_CAPTUREMASTERHAND) || (cpu_state == ASID_YOSHIEGG) || (cpu_state == ASID_CAPTUREKIRBYYOSHI) || (cpu_state == ASID_KIRBYYOSHIEGG) || (cpu_state == ASID_CAPTURELEADEAD) || (cpu_state == ASID_CAPTURELIKELIKE) || (cpu_state == ASID_CAPTUREWAITCRAZYHAND) || ((cpu_state >= ASID_SHOULDEREDWAIT) && (cpu_state <= ASID_SHOULDEREDTURN))) is_grabbed = 1; return is_grabbed; } int LCancel_CPUPerformAction(GOBJ *cpu, int action_id, GOBJ *hmn) { FighterData *cpu_data = cpu->userdata; FighterData *hmn_data = hmn->userdata; // get CPU action int action_done = 0; CPUAction *action_list = Lab_CPUActions[action_id]; int cpu_state = cpu_data->state; s16 cpu_frame = cpu_data->stateFrame; if (cpu_frame == -1) cpu_frame = 0; // clear inputs Fighter_ZeroCPUInputs(cpu_data); // if no action, report command as done if (action_id == 0) action_done = 1; // perform command else { // loop through all inputs int action_parse = 0; CPUAction *action_input = &action_list[action_parse]; while ((action_input != 0) && (action_input->state != 0xFFFF)) { int isState = 0; if ((action_input->state >= ASID_ACTIONABLE) && (action_input->state <= ASID_FALLS)) isState = CPUAction_CheckMultipleState(cpu, (action_input->state - ASID_ACTIONABLE)); else if (action_input->state == cpu_state) isState = 1; // check if this is the current state if (isState == 1) { // check if im on the right frame if (cpu_frame >= action_input->frameLow) { OSReport("exec input %d of %s\n", action_parse, CPU_ACTIONS_NAMES[action_id]); // perform this action s8 dir; int held = action_input->input; s8 lstickX = action_input->stickX; s8 lstickY = action_input->stickY; s8 cstickX = action_input->cstickX; s8 cstickY = action_input->cstickY; // stick direction switch (action_input->stickDir) { case (STCKDIR_NONE): { break; } case (STCKDIR_TOWARD): { dir = Fighter_GetOpponentDir(cpu_data, hmn_data); lstickX *= dir; cstickX *= dir; break; } case (STCKDIR_AWAY): { dir = Fighter_GetOpponentDir(cpu_data, hmn_data) * -1; lstickX *= dir; cstickX *= dir; break; } case (STCKDIR_FRONT): { dir = cpu_data->facing_direction; lstickX *= dir; cstickX *= dir; break; } case (STCKDIR_BACK): { dir = cpu_data->facing_direction; lstickX *= (dir * -1); cstickX *= (dir * -1); break; } case (STICKDIR_RDM): { // random direction if (HSD_Randi(2) == 0) dir = 1; else dir = -1; lstickX *= dir; cstickX *= dir; break; } } // perform this action cpu_data->cpu.held = held; cpu_data->cpu.lstickX = lstickX; cpu_data->cpu.lstickY = lstickY; cpu_data->cpu.cstickX = cstickX; cpu_data->cpu.cstickY = cstickY; // check if this was the last action if (action_input->isLast == 1) action_done = 1; break; } } // get next input action_parse++; action_input = &action_list[action_parse]; } } return action_done; } void LCancel_CPUThink(GOBJ *event, GOBJ *hmn, GOBJ *cpu) { // get gobjs data LCancelData *eventData = event->userdata; FighterData *hmn_data = hmn->userdata; FighterData *cpu_data = cpu->userdata; GOBJ **gobjlist = R13_PTR(GOBJLIST); int cpu_state = cpu_data->state; // noact cpu_data->cpu.ai = 15; // if first throw frame, advance hitnum int is_thrown = CPU_IsThrown(cpu); if ((is_thrown == 1) && (eventData->cpu_isthrown == 0)) { eventData->cpu_hitnum++; } eventData->cpu_isthrown = is_thrown; // ALWAYS CHECK FOR X AND OVERRIDE STATE // check if damaged if (cpu_data->flags.hitstun == 1) { eventData->cpu_hitkind = HITKIND_DAMAGE; // go to SDI state eventData->cpu_state = CPUSTATE_SDI; Fighter_ZeroCPUInputs(cpu_data); } // check if being held in a grab if (CPU_IsGrabbed(cpu) == 1) { eventData->cpu_state = CPUSTATE_GRABBED; } // check if being thrown if (is_thrown == 1) { eventData->cpu_state = CPUSTATE_TDI; } // check for shield hit if ((cpu_state == ASID_GUARDSETOFF) || ((cpu_data->kind == 0xE) && (cpu_state == 344))) { Fighter_ZeroCPUInputs(cpu_data); // check if new shield hit if (eventData->cpu_lastshieldstun != cpu_data->moveID) { eventData->cpu_lastshieldstun = cpu_data->moveID; eventData->cpu_hitshieldnum++; } eventData->cpu_hitkind = HITKIND_SHIELD; eventData->cpu_state = CPUSTATE_SDI; // go to Shield state //eventData->cpu_state = CPUSTATE_SHIELD; } // check for missed tech if ((cpu_state == ASID_DOWNBOUNDD) || (cpu_state == ASID_DOWNBOUNDU) || (cpu_state == ASID_DOWNWAITU) || (cpu_state == ASID_DOWNWAITD) || (cpu_state == ASID_PASSIVE) || (cpu_state == ASID_PASSIVESTANDB) || (cpu_state == ASID_PASSIVESTANDF)) eventData->cpu_state = CPUSTATE_GETUP; // check for cliffgrab if ((cpu_state == ASID_CLIFFWAIT)) eventData->cpu_state = CPUSTATE_RECOVER; // check if dead if (cpu_data->flags.dead == 1) goto CPUSTATE_ENTERSTART; // run CPU state logic switch (eventData->cpu_state) { // Initial State, hasn't been hit yet case (CPUSTATE_START): CPULOGIC_START: { // if in the air somehow, enter recovery if (cpu_data->phys.air_state == 1) { eventData->cpu_state = CPUSTATE_RECOVER; goto CPULOGIC_RECOVER; } // clear held inputs Fighter_ZeroCPUInputs(cpu_data); // perform default behavior int behavior = LabOptions_CPU[OPTCPU_BEHAVE].option_val; switch (behavior) { case (CPUBEHAVE_STAND): { break; } case (CPUBEHAVE_SHIELD): { // hold R cpu_data->cpu.held = PAD_TRIGGER_R; break; } case (CPUBEHAVE_CROUCH): { // hold down cpu_data->cpu.lstickY = -127; break; } case (CPUBEHAVE_JUMP): { // run jump command LCancel_CPUPerformAction(cpu, 12, hmn); break; } } break; } case (CPUSTATE_GRABBED): CPULOGIC_GRABBED: { // if no longer being grabbed, exit if (CPU_IsGrabbed(cpu) == 0) { eventData->cpu_state = CPUSTATE_RECOVER; goto CPULOGIC_RECOVER; } switch (LabOptions_CPU[OPTCPU_MASH].option_val) { case (CPUMASH_NONE): { Fighter_ZeroCPUInputs(cpu_data); break; } case (CPUMASH_MED): { if (HSD_Randi(100) <= CPUMASHRNG_MED) { // remove last frame inputs cpu_data->input.held = 0; cpu_data->input.lstick_x = 0; cpu_data->input.lstick_y = 0; // input cpu_data->cpu.held = PAD_BUTTON_A; cpu_data->cpu.lstickX = 127; } break; } case (CPUMASH_HIGH): { if (HSD_Randi(100) <= CPUMASHRNG_HIGH) { // remove last frame inputs cpu_data->input.held = 0; cpu_data->input.lstick_x = 0; cpu_data->input.lstick_y = 0; // input cpu_data->cpu.held = PAD_BUTTON_A; cpu_data->cpu.lstickX = 127; } break; } case (CPUMASH_PERFECT): { // remove last frame inputs cpu_data->input.held = 0; cpu_data->input.lstick_x = 0; cpu_data->input.lstick_y = 0; // input cpu_data->cpu.held = PAD_BUTTON_A; cpu_data->cpu.lstickX = 127; break; } } break; } case (CPUSTATE_SDI): CPULOGIC_SDI: { // if no more hitlag, enter tech state if (cpu_data->flags.hitlag == 0) { eventData->cpu_state = CPUSTATE_TECH; goto CPULOGIC_TECH; } // if final frame of hitlag, enter TDI state else if (cpu_data->dmg.hitlag_frames == 1) { eventData->cpu_state = CPUSTATE_TDI; goto CPULOGIC_TDI; } // update move instance if (eventData->cpu_lasthit != cpu_data->dmg.instancehitby) { eventData->cpu_sincehit = 0; eventData->cpu_hitnum++; eventData->cpu_lasthit = cpu_data->dmg.instancehitby; //OSReport("hit count %d/%d", eventData->cpu_hitnum, LabOptions_CPU[OPTCPU_CTRHITS].option_val); // decide random SDI direction for grounded cpu if ((LabOptions_CPU[OPTCPU_SDIFREQ].option_val != SDIFREQ_NONE) && (LabOptions_CPU[OPTCPU_SDIDIR].option_val == SDIDIR_RANDOM)) { eventData->cpu_sdidir = HSD_Randi(2); } } // to-do: shield SDI if ((cpu_data->state >= ASID_GUARDON) && (cpu_data->state <= ASID_GUARDREFLECT)) { ; } // perform SDI behavior else if (LabOptions_CPU[OPTCPU_SDIFREQ].option_val != SDIFREQ_NONE) { int chance = stc_sdifreqs[LabOptions_CPU[OPTCPU_SDIFREQ].option_val - 1]; // chance to SDI if (HSD_Randi(chance) == 0) { float angle, magnitude; switch (LabOptions_CPU[OPTCPU_SDIDIR].option_val) { case SDIDIR_RANDOM: { // when grounded, only left right if (cpu_data->phys.air_state == 0) { magnitude = 1; // decide left or right if (eventData->cpu_sdidir == 0) angle = 0; // right else angle = M_PI; // left } // when airborne, any direction else { // random input angle = HSD_Randi(360) * M_1DEGREE; magnitude = 0.49 + (HSD_Randf() * 0.51); } break; } case SDIDIR_AWAY: { // get angle from center bubble to hit collision angle = atan2(hmn_data->unk_hitbox.pos.Y - cpu_data->unk_hitbox.pos.Y, hmn_data->unk_hitbox.pos.X - cpu_data->unk_hitbox.pos.X); // flip angle += M_PI; while (angle > (M_PI * 2)) { angle -= (M_PI * 2); } magnitude = 1; break; } case SDIDIR_TOWARD: { // get angle from center bubble to hit collision angle = atan2(hmn_data->unk_hitbox.pos.Y - cpu_data->unk_hitbox.pos.Y, hmn_data->unk_hitbox.pos.X - cpu_data->unk_hitbox.pos.X); magnitude = 1; break; } } // store cpu_data->cpu.lstickX = cos(angle) * 127 * magnitude; cpu_data->cpu.lstickY = sin(angle) * 127 * magnitude; } } break; } case (CPUSTATE_TDI): CPULOGIC_TDI: { // if no more hitlag and not being thrown, enter tech state. this might never be hit, just being safe if ((cpu_data->flags.hitlag == 0) && (is_thrown == 0)) { eventData->cpu_state = CPUSTATE_TECH; goto CPULOGIC_TECH; } // if in shield, no need to TDI if ((cpu_data->state >= ASID_GUARDON) && (cpu_data->state <= ASID_GUARDREFLECT)) { break; } // get knockback value float kb_angle; if (is_thrown == 1) { // if being thrown, get knockback info from attacker FighterData *attacker_data = cpu_data->grab.grab_attacker->userdata; kb_angle = ((float)attacker_data->throw_hitbox[0].angle * M_1DEGREE) * (attacker_data->facing_direction); } else { // not being thrown, get knockback angle normally //kb_angle = Fighter_GetKnockbackAngle(cpu_data) * cpu_data->dmg.direction; kb_angle = atan2(cpu_data->phys.kb_vel.Y, cpu_data->phys.kb_vel.X); } // perform TDI behavior int tdi_kind = LabOptions_CPU[OPTCPU_TDI].option_val; TDI_SWITCH: switch (tdi_kind) { case (CPUTDI_RANDOM): { tdi_kind = HSD_Randi(CPUTDI_NUM - 1) + 1; goto TDI_SWITCH; } case (CPUTDI_IN): { /* NOTE: im using 94 degrees here because some moves like marth uthrow use this angle, and drawing the line at 90 would make inward DI cause the opponent to DI in the direction marth is facing and looks confusing */ float orig_dir; if ((kb_angle > (-94 * M_1DEGREE)) && (kb_angle <= (94 * M_1DEGREE))) orig_dir = -1; else orig_dir = 1; // get optimal tdi float tdi_angle = kb_angle + (orig_dir * -(M_PI / 2)); // convert to analog input cpu_data->cpu.lstickX = cos(tdi_angle) * 127; cpu_data->cpu.lstickY = sin(tdi_angle) * 127; break; } case (CPUTDI_OUT): TDI_OUT: { /* NOTE: im using 94 degrees here because some moves like marth uthrow use a 93 degree angle, and drawing the line at 90 would make inward DI cause the opponent to DI in the direction marth is facing and looks confusing */ float orig_dir; if ((kb_angle > (-94 * M_1DEGREE)) && (kb_angle <= (94 * M_1DEGREE))) orig_dir = -1; else orig_dir = 1; // get optimal tdi float tdi_angle = kb_angle + (orig_dir * M_PI / 2); // convert to analog input cpu_data->cpu.lstickX = cos(tdi_angle) * 127; cpu_data->cpu.lstickY = sin(tdi_angle) * 127; break; } case (CPUTDI_FLOORHUG): { // floothug = full ASDI down + outward DI cpu_data->cpu.cstickY = -127; goto TDI_OUT; break; } case (CPUTDI_CUSTOM): { int cpu_hitnum = eventData->cpu_hitnum; // ensure we have a DI input for this hitnum if (cpu_hitnum <= stc_tdi_val_num) { // get the stick values for this hit num cpu_hitnum--; s8 lstickX = stc_tdi_vals[cpu_hitnum][0][0]; s8 lstickY = stc_tdi_vals[cpu_hitnum][0][1]; s8 cstickX = stc_tdi_vals[cpu_hitnum][1][0]; s8 cstickY = stc_tdi_vals[cpu_hitnum][1][1]; cpu_data->cpu.lstickX = ((float)lstickX / 80) * 127.0; cpu_data->cpu.lstickY = ((float)lstickY / 80) * 127.0; cpu_data->cpu.cstickX = ((float)cstickX / 80) * 127.0; cpu_data->cpu.cstickY = ((float)cstickY / 80) * 127.0; // increment } break; } case (CPUTDI_NONE): { Fighter_ZeroCPUInputs(cpu_data); break; } } // this is kinda meh, maybe i can come up with something better later // spoof last input as current input as to not trigger SDI // also spoof input as held for more than the SDI window cpu_data->input.lstick_x = ((float)cpu_data->cpu.lstickX * 0.0078125); cpu_data->input.timer_lstick_tilt_x = 5; cpu_data->input.lstick_y = ((float)cpu_data->cpu.lstickY * 0.0078125); cpu_data->input.timer_lstick_tilt_y = 5; break; } case (CPUSTATE_TECH): CPULOGIC_TECH: { // if no more hitstun, go to counter if (cpu_data->flags.hitstun == 0) { // also reset stick timer (messes with airdodge wiggle) cpu_data->input.lstick_x = 0; cpu_data->input.timer_lstick_tilt_x = 254; eventData->cpu_state = CPUSTATE_COUNTER; goto CPULOGIC_COUNTER; } // perform tech behavior int tech_kind = LabOptions_CPU[OPTCPU_TECH].option_val; s8 dir; s8 stickX = 0; s8 sincePress = 0; s8 since2Press = -1; s8 sinceXSmash = -1; TECH_SWITCH: switch (tech_kind) { case (CPUTECH_RANDOM): { tech_kind = (HSD_Randi((sizeof(LabValues_Tech) / 4) - 1) + 1); goto TECH_SWITCH; break; } case (CPUTECH_NEUTRAL): { break; } case (CPUTECH_AWAY): { dir = Fighter_GetOpponentDir(cpu_data, hmn_data); stickX = 127 * (dir * -1); break; } case (CPUTECH_TOWARDS): { dir = Fighter_GetOpponentDir(cpu_data, hmn_data); stickX = 127 * (dir); break; } case (CPUTECH_NONE): { sincePress = -1; break; } } // input tech cpu_data->input.timer_LR = sincePress; cpu_data->input.sinceRapidLR = since2Press; cpu_data->cpu.lstickX = stickX; cpu_data->input.timer_lstick_smash_x = sinceXSmash; break; } case (CPUSTATE_GETUP): CPULOGIC_GETUP: { // if im in downwait, perform getup logic if ((cpu_data->state == ASID_DOWNWAITD) || (cpu_data->state == ASID_DOWNWAITU)) { // perform getup behavior int getup = LabOptions_CPU[OPTCPU_GETUP].option_val; s8 dir; int inputs = 0; s8 stickX = 0; s8 stickY = 0; GETUP_SWITCH: switch (getup) { case (CPUGETUP_RANDOM): { getup = (HSD_Randi((sizeof(LabValues_Tech) / 4) - 1) + 1); goto GETUP_SWITCH; break; } case (CPUGETUP_STAND): { stickY = 127; break; } case (CPUGETUP_TOWARD): { dir = Fighter_GetOpponentDir(cpu_data, hmn_data); stickX = 127 * (dir); break; } case (CPUGETUP_AWAY): { dir = Fighter_GetOpponentDir(cpu_data, hmn_data); stickX = 127 * (dir * -1); break; } case (CPUGETUP_ATTACK): { inputs = PAD_BUTTON_A; break; } } // input getup option cpu_data->cpu.held = inputs; cpu_data->cpu.lstickX = stickX; cpu_data->cpu.lstickY = stickY; } // if cpu is in any other down state, do nothing else if ((cpu_data->state >= ASID_DOWNBOUNDU) && (cpu_data->state <= ASID_DOWNSPOTD)) { break; } // if cpu is not in a down state, enter COUNTER else { eventData->cpu_state = CPUSTATE_COUNTER; goto CPULOGIC_COUNTER; break; } break; } case (CPUSTATE_COUNTER): CPULOGIC_COUNTER: { // check if the CPU has been actionable yet if (eventData->cpu_isactionable == 0) { // check if actionable if (CPUAction_CheckMultipleState(cpu, 0) == 0) { break; } else { eventData->cpu_isactionable = 1; // set actionable flag to begin running code eventData->cpu_groundstate = cpu_data->phys.air_state; // remember initial ground state } } // if started in the air, didnt finish action, but now grounded, perform ground action if ((eventData->cpu_groundstate == 1) && (cpu_data->phys.air_state == 0)) { eventData->cpu_groundstate = 0; } // increment frames since actionable eventData->cpu_sincehit++; // ensure hit count and frame count criteria are met int action_id; if (eventData->cpu_hitkind == HITKIND_DAMAGE) { if ((eventData->cpu_hitnum < LabOptions_CPU[OPTCPU_CTRHITS].option_val) || (eventData->cpu_sincehit < LabOptions_CPU[OPTCPU_CTRFRAMES].option_val)) { break; } // get counter action if (cpu_data->phys.air_state == 0 || (eventData->cpu_groundstate == 0)) // if am grounded or started grounded { int grndCtr = LabOptions_CPU[OPTCPU_CTRGRND].option_val; action_id = GrAcLookup[grndCtr]; } else if (cpu_data->phys.air_state == 1) // only if in the air at the time of hitstun ending { int airCtr = LabOptions_CPU[OPTCPU_CTRAIR].option_val; action_id = AirAcLookup[airCtr]; } } else if (eventData->cpu_hitkind == HITKIND_SHIELD) { // if the shield wasnt hit enough times, return to start if (eventData->cpu_hitshieldnum < LabOptions_CPU[OPTCPU_SHIELDHITS].option_val) { eventData->cpu_state = CPUSTATE_START; goto CPULOGIC_START; break; } // if this isnt the frame to counter, keep holding shield if (eventData->cpu_sincehit < LabOptions_CPU[OPTCPU_CTRFRAMES].option_val) { cpu_data->cpu.held = PAD_TRIGGER_R; break; } // get action to perform int shieldCtr = LabOptions_CPU[OPTCPU_CTRSHIELD].option_val; action_id = ShieldAcLookup[shieldCtr]; } else { // wasnt hit, fell or something idk. enter start again goto CPUSTATE_ENTERSTART; } // if none, enter recover if (action_id == 0) { eventData->cpu_state = CPUSTATE_RECOVER; goto CPULOGIC_RECOVER; } // perform counter behavior //OSReport("executing input"); if (LCancel_CPUPerformAction(cpu, action_id, hmn) == 1) { eventData->cpu_state = CPUSTATE_RECOVER; //goto CPULOGIC_RECOVER; } break; } case (CPUSTATE_RECOVER): CPULOGIC_RECOVER: { // if onstage, go back to start if (cpu_data->phys.air_state == 0) { CPUSTATE_ENTERSTART: // clear inputs // go to start eventData->cpu_state = CPUSTATE_START; eventData->cpu_hitshield = 0; eventData->cpu_hitnum = 0; eventData->cpu_sincehit = 0; eventData->cpu_hitshield = 0; eventData->cpu_lasthit = -1; eventData->cpu_lastshieldstun = -1; eventData->cpu_hitkind = -1; eventData->cpu_hitshieldnum = 0; eventData->cpu_isactionable = 0; goto CPULOGIC_START; } // recover with CPU AI cpu_data->cpu.ai = 0; break; } } // update isthrown eventData->cpu_isthrown = is_thrown; // update cpu_hitshield if (eventData->cpu_hitshield == 0) { GOBJ *fighter = gobjlist[8]; while (fighter != 0) { FighterData *fighter_data = fighter->userdata; // check if in guard off if (fighter_data->state == ASID_GUARDSETOFF) { eventData->cpu_hitshield = 1; break; } fighter = fighter->next; } } // update shield deterioration int infShield = LabOptions_CPU[OPTCPU_SHIELD].option_val; if (infShield == 1) { if (eventData->cpu_hitshield == 0) { // inf shield GOBJ *fighter = gobjlist[8]; while (fighter != 0) { FighterData *fighter_data = fighter->userdata; fighter_data->shield.health = 60; fighter = fighter->next; } } } else if (infShield == 2) { // inf shield GOBJ *fighter = gobjlist[8]; while (fighter != 0) { FighterData *fighter_data = fighter->userdata; fighter_data->shield.health = 60; fighter = fighter->next; } } return; } int Update_CheckPause() { HSD_Update *update = HSD_UPDATE; int isChange = 0; // get their pad int controller = Fighter_GetControllerPort(0); HSD_Pad *pad = PadGet(controller, PADGET_MASTER); // if event menu not showing, develop mode + pause input, toggle frame advance if ((Pause_CheckStatus(1) != 2) && (*stc_dblevel >= 3) && (pad->down & HSD_BUTTON_START)) { LabOptions_General[OPTGEN_FRAME].option_val ^= 1; Lab_ChangeFrameAdvance(0, LabOptions_General[OPTGEN_FRAME].option_val); isChange = 1; } // menu paused else if (LabOptions_General[OPTGEN_FRAME].option_val == 1) { // check if unpaused if (update->pause_develop != 1) { // pause isChange = 1; } } // menu unpaused else { // check if paused if (update->pause_develop == 1) { // unpause isChange = 1; } } return isChange; } int Update_CheckAdvance() { static int timer = 0; HSD_Update *update = HSD_UPDATE; int isAdvance = 0; int controller = Fighter_GetControllerPort(0); // get their pad HSD_Pad *pad = PadGet(controller, PADGET_MASTER); // get their advance input static int stc_advance_btns[] = {HSD_TRIGGER_L, HSD_TRIGGER_Z, HSD_BUTTON_X, HSD_BUTTON_Y}; int advance_btn = stc_advance_btns[LabOptions_General[OPTGEN_FRAMEBTN].option_val]; // check if holding L if ((pad->held & advance_btn)) { timer++; // advance if first press or holding more than 10 frames if (timer == 1 || timer > 30) { isAdvance = 1; // remove button input pad->down &= ~advance_btn; pad->held &= ~advance_btn; // if using L, remove analog press too if (LabOptions_CPU[OPTGEN_FRAMEBTN].option_val == 0) { pad->triggerLeft = 0; pad->ftriggerLeft = 0; } } } else { update->advance = 0; timer = 0; } return isAdvance; } void DIDraw_Init() { // Create DIDraw GOBJ GOBJ *didraw_gobj = GObj_Create(0, 0, 0); // Add gxlink GObj_AddGXLink(didraw_gobj, DIDraw_GX, 6, 0); // init didraw pointers for (int i = 0; i < 6; i++) { // for each subchar for (int j = 0; j < 2; j++) { didraws[i].num[j] = 0; didraws[i].vertices[j] = 0; } } return; } void DIDraw_Update() { static ECBBones ecb_bones_def = { .topY = 9, .botY = 2.5, .left = {-3.3, 5.7}, .right = {3.3, 5.7}, }; // if enabled and pause menu isnt shown, update di draw if ((LabOptions_General[OPTGEN_DI].option_val == 1)) // && (Pause_CheckStatus(1) != 2) { // loop through all fighters GOBJList *gobj_list = R13_PTR(GOBJLIST); GOBJ *fighter = gobj_list->fighter; while (fighter != 0) { FighterData *fighter_data = fighter->userdata; int ply = fighter_data->ply; DIDraw *didraw = &didraws[ply]; // if in hitlag and hitstun simulate and update trajectory if ((fighter_data->flags.hitlag == 1) && (fighter_data->flags.hitstun == 1)) { // free old if (didraw->vertices[ply] != 0) { HSD_Free(didraw->vertices[ply]); didraw->num[ply] = 0; didraw->vertices[ply] = 0; } //OSReport("######### BEGIN ##########\n"); // get player's inputs float lstickX; float lstickY; float cstickX; float cstickY; // for HMN players if (Fighter_GetSlotType(fighter_data->ply) == 0) { int input_kind; if (Pause_CheckStatus(0) == 1) // if frame advance enabled, use master inputs input_kind = PADGET_MASTER; else input_kind = PADGET_ENGINE; // no frame advance, use engine inputs HSD_Pad *pad = PadGet(fighter_data->player_controller_number, input_kind); lstickX = pad->fstickX; lstickY = pad->fstickY; cstickX = pad->fsubstickX; cstickY = pad->fsubstickY; } // for CPUs else { lstickX = fighter_data->input.lstick_x; lstickY = fighter_data->input.lstick_y; cstickX = fighter_data->input.cstick_x; cstickY = fighter_data->input.cstick_y; } // get kb vector Vec3 kb = fighter_data->phys.kb_vel; float kb_angle = atan2(kb.Y, kb.X); // init ASDI vector Vec3 asdi_orig; Vec3 asdi = {0, 0, 0}; // get fighter constants ftCommonData *ftCmDt = R13_PTR(PLCO_FTCOMMON); // Calculate ASDI float asdi_mag = pow(ftCmDt->asdi_mag, 2); float asdi_units = ftCmDt->asdi_units; // CStick has priority, check if mag > 0.7 if (pow(cstickX, 2) + (pow(cstickY, 2)) >= asdi_mag) { asdi.X = cstickX * asdi_units; asdi.Y = cstickY * asdi_units; } // now check if lstick mag > 0.7 else if (pow(lstickX, 2) + (pow(lstickY, 2)) >= asdi_mag) { asdi.X = lstickX * asdi_units; asdi.Y = lstickY * asdi_units; } // Remember original ASDI asdi_orig = asdi; //OSReport("ASDI: %f , %f\n", asdi.X, asdi.Y); // Calculate TDI //OSReport("KB Pre TDI: %f , %f\n", kb.X, kb.Y); if ((lstickX != 0) || (lstickY != 0)) // exclude input vector 0,0 { // kb vector must exceed 0.00001 float kb_mult = (kb.Y * kb.Y) + (kb.X * kb.X); if (kb_mult >= 0.00001) { // get values float tdi_input = pow((-1 * kb.X * lstickY) + (lstickX * kb.Y), 2) / kb_mult; float max_angle = ftCmDt->tdi_maxAngle * M_1DEGREE; float kb_mag = sqrtf(kb_mult); // check to negate Vec3 inputs = {lstickX, lstickY, 0}; Vec3 result; VECCrossProduct(&kb, &inputs, &result); if (result.Z < 0) tdi_input *= -1; // apply TDI kb_angle = (max_angle * tdi_input) + kb_angle; // New X KB kb.X = cos(kb_angle) * kb_mag; // New Y KB kb.Y = sin(kb_angle) * kb_mag; } } //OSReport("KB Post TDI: %f , %f\n", kb.X, kb.Y); //simulation variables int air_state = fighter_data->phys.air_state; float gravity = 0; Vec3 pos = fighter_data->phys.pos; ftCommonData *ftCommon = R13_PTR(-0x514C); float decay = ftCommon->kb_frameDecay; int hitstun_frames = AS_FLOAT(fighter_data->state_var.stateVar1); int vertices_num = 0; // used to track how many vertices will be needed int override_frames = 0; // used as an alternate countdown DIDrawCalculate *DICollData = calloc(sizeof(DIDrawCalculate) * hitstun_frames); CollData ecb; ECBBones ecb_bones; // init ecb struct Coll_InitECB(&ecb); if (fighter_data->phys.air_state == 0) // copy ecb struct if grounded { memcpy(&ecb.envFlags, &fighter_data->coll_data.envFlags, 0x28); } // simulate each frame of knockback for (int i = 0; i < hitstun_frames; i++) { // update bone positions. If loop count < noECBUpdate-remaining hitlag fraes, use current ECB bottom Y offset if (vertices_num < (fighter_data->coll_data.ecb_lock - fighter_data->dmg.hitlag_frames)) { ecb_bones.topY = fighter_data->coll_data.ecbCurr_top.Y; ecb_bones.botY = fighter_data->coll_data.ecbCurr_bot.Y; ecb_bones.left = fighter_data->coll_data.ecbCurr_left; ecb_bones.right = fighter_data->coll_data.ecbCurr_right; // if grounded, ECB bottom is 0 if (air_state == 0) { ecb_bones.botY = 0; } } else { // use default ecb size memcpy(&ecb_bones, &ecb_bones_def, sizeof(ECBBones)); } // update ecb topN position ecb.topN_Curr = pos; ecb.topN_CurrCorrect = pos; // apply ASDI pos.X += asdi.X; if (air_state != 0) // only apply Y asdi in the air { pos.Y += asdi.Y; } asdi.X = 0; // zero out ASDI asdi.Y = 0; // zero out ASDI // update gravity gravity -= fighter_data->attr.gravity; float terminal_velocity = fighter_data->attr.terminal_velocity * -1; if (gravity < terminal_velocity) gravity = terminal_velocity; // decay KB vector float angle = atan2(kb.Y, kb.X); kb.X = kb.X - (cos(angle) * decay); kb.Y = kb.Y - (sin(angle) * decay); // add knockback VECAdd(&pos, &kb, &pos); // apply gravity pos.Y += gravity; // ecb prev = ecb curr ecb.topN_Prev = ecb.topN_Curr; // ecb curr = new position ecb.topN_Curr = pos; // only run X collision checks because theyre expensive if (vertices_num >= DI_MaxColl) { DICollData[i].envFlags = 0; // spoof as not touching pos = ecb.topN_Curr; // position = projected } // update collision else { // ground coll if (air_state == 0) { int result = ECB_CollGround_PassLedge(&ecb, &ecb_bones); if (result == 0) { air_state = 1; } } // air coll else { ECB_CollAir(&ecb, &ecb_bones); } // get corrected position pos = ecb.topN_Curr; // increment collision ID ecb.coll_test += 1; // perform stage collision code if ((ecb.envFlags & ECB_GROUND) != 0) { // check if air->ground just occurred if (air_state == 1) { // set grounded air_state = 0; // check if over max horizontal velocity if (kb.X > ftCmDt->kb_maxVelX) kb.X = ftCmDt->kb_maxVelX; if (kb.X < -ftCmDt->kb_maxVelX) kb.X = -ftCmDt->kb_maxVelX; // adjust KB direction from slope kb.X *= ecb.ground_slope.Y; kb.Y *= ecb.ground_slope.X; // zero out gravity gravity = 0; // zero out Y KB kb.Y = 0; } } else if ((ecb.envFlags & ECB_CEIL) != 0) { // only run this code when in the air if (air_state == 1) { // combine KB and Gravity Vec3 kb_temp = kb; Vec3 vel_temp = {0, gravity, 0}; VECAdd(&vel_temp, &kb_temp, &vel_temp); // apply slope VECMultAndAdd(&vel_temp, &ecb.ceil_slope); // decay kb kb.X = vel_temp.X * ftCmDt->kb_bounceDecay; kb.Y = vel_temp.Y * ftCmDt->kb_bounceDecay; } } else if ((ecb.envFlags & (ECB_WALLLEFT | ECB_WALLRIGHT)) != 0) { // only run this code when in the air if (air_state == 1) { // get slope Vec3 *slope; if ((ecb.envFlags & ECB_WALLLEFT) != 0) { slope = &ecb.leftwall_slope; } else { slope = &ecb.rightwall_slope; } // combine KB and Gravity Vec3 kb_temp = kb; Vec3 vel_temp = {0, gravity, 0}; VECAdd(&vel_temp, &kb_temp, &vel_temp); // apply slope VECMultAndAdd(&vel_temp, slope); // decay kb kb.X = vel_temp.X * ftCmDt->kb_bounceDecay; kb.Y = vel_temp.Y * ftCmDt->kb_bounceDecay; // zero gravity gravity = 0; } } // check for slide off if (((ecb.envFlags & ECB_GROUND) == 0) && ((ecb.envFlags_prev & ECB_GROUND) != 0)) // not touching ground this frame, was touching last frame { if (override_frames == 0) override_frames = 5; // terminate in 5 frames } } //OSReport("Frame %d:\nPos: %f, %f\nKB: %f , %f\nVel: 0 , %f\n AirState: %d\n", vertices_num, pos.X, pos.Y, kb.X, kb.Y, gravity, air_state); // save this position DICollData[i].pos.X = pos.X; DICollData[i].pos.Y = pos.Y; DICollData[i].kb_Y = kb.Y; DICollData[i].ECBLeftY = ecb_bones.left.Y; DICollData[i].ECBTopY = ecb_bones.topY; // inc vertices count vertices_num++; // if override frames are set, decrement and exit if (override_frames > 0) { override_frames--; if (override_frames == 0) break; } } // alloc draw struct didraw->num[ply] = vertices_num + 2; // +2 for ASDI vertices // alloc vertices didraw->vertices[ply] = calloc(sizeof(Vec2) * (vertices_num + 2)); // save ASDI first didraw->vertices[ply][0].X = fighter_data->coll_data.topN_Curr.X; didraw->vertices[ply][0].Y = fighter_data->coll_data.topN_Curr.Y + fighter_data->coll_data.ecbCurr_left.Y; didraw->vertices[ply][1].X = fighter_data->coll_data.topN_Curr.X + asdi_orig.X; didraw->vertices[ply][1].Y = fighter_data->coll_data.topN_Curr.Y + fighter_data->coll_data.ecbCurr_left.Y + asdi_orig.Y; // save this info to the draw struct for (int i = 0; i < vertices_num; i++) { didraw->vertices[ply][i + 2].X = DICollData[i].pos.X; didraw->vertices[ply][i + 2].Y = DICollData[i].pos.Y + ((DICollData[i].ECBLeftY + DICollData[i].ECBTopY) / 2); // get vertex color static GXColor airColor = {0, 138, 255, 255}; static GXColor groundColor = {255, 255, 255, 255}; static GXColor ceilColor = {255, 0, 0, 255}; static GXColor wallColor = {0, 255, 0, 255}; GXColor *color; if ((ecb.envFlags & ECB_GROUND) != 0) color = &groundColor; else if ((ecb.envFlags & ECB_CEIL) != 0) color = &ceilColor; else if ((ecb.envFlags & ECB_WALLLEFT | ECB_WALLRIGHT) != 0) color = &wallColor; else color = &airColor; // set vertex color didraw->color.r = color->r; didraw->color.g = color->g; didraw->color.b = color->b; didraw->color.a = color->a; } // free the collision info HSD_Free(DICollData); } // if not in hitstun, zero out didraw else if (fighter_data->flags.hitstun == 0) { if (didraw->vertices[ply] != 0) { HSD_Free(didraw->vertices[ply]); didraw->num[ply] = 0; didraw->vertices[ply] = 0; } } fighter = fighter->next; } } // is off, remove all di draw else { // all slots for (int i = 0; i < 6; i++) { DIDraw *didraw = &didraws[i]; // all subchars for (int j = 0; j < 2; j++) { if (didraw->vertices[j] != 0) { HSD_Free(didraw->vertices[j]); didraw->num[j] = 0; didraw->vertices[j] = 0; } } } } return; } void DIDraw_GX() { // if toggle enabled if (LabOptions_General[OPTGEN_DI].option_val == 1) { // draw each for (int i = 0; i < 6; i++) { // for each subchar for (int j = 0; j < 2; j++) { DIDraw *didraw = &didraws[i]; // if it exists if (didraw->num != 0) { int vertex_num = didraw->num[j]; Vec2 *vertices = didraw->vertices[j]; // alloc prim PRIM *gx = PRIM_NEW(vertex_num, 0x001F1306, 0x00000C55); // draw each for (int k = 0; k < vertex_num; k++) { PRIM_DRAW(gx, vertices[k].X, vertices[k].Y, 0, 0x008affff); } // close PRIM_CLOSE(); } } } } return; } void Update_Camera() { // if camera is set to advanced if (LabOptions_General[OPTGEN_CAM].option_val == 3) { // Get player gobj GOBJ *fighter = Fighter_GetGObj(0); if (fighter != 0) { // get players inputs FighterData *fighter_data = fighter->userdata; HSD_Pad *pad = PadGet(fighter_data->player_controller_number, PADGET_MASTER); int held = pad->held; float stickX = pad->fsubstickX; float stickY = pad->fsubstickY; float deadzone = 0.2; if (fabs(stickX) < deadzone) stickX = 0; if (fabs(stickY) < deadzone) stickY = 0; // ensure stick exceeds deadzone if ((stickX != 0) || (stickY != 0)) { COBJ *cobj = COBJ_GetMatchCamera(); // adjust pan if ((held & HSD_BUTTON_A) != 0) { DevCam_AdjustPan(cobj, stickX * -1, stickY * -1); } // adjust zoom else if ((held & HSD_BUTTON_Y) != 0) { DevCam_AdjustZoom(cobj, stickY); } // adjust rotate else if ((held & HSD_BUTTON_B) != 0) { MatchCamera *matchCam = MATCH_CAM; DevCam_AdjustRotate(cobj, &matchCam->devcam_rot, &matchCam->devcam_pos, stickX, stickY); } } } } return; } void Lab_SelectCustomTDI(GOBJ *menu_gobj) { MenuData *menu_data = menu_gobj->userdata; EventMenu *curr_menu = menu_data->currMenu; evMenu *menuAssets = event_vars->menu_assets; GOBJ *event_gobj = event_vars->event_gobj; LCancelData *event_data = event_gobj->userdata; Arch_LabData *LabAssets = stc_lab_data; // set menu state to wait //curr_menu->state = EMSTATE_WAIT; // create bg gobj GOBJ *tdi_gobj = GObj_Create(0, 0, 0); TDIData *userdata = calloc(sizeof(TDIData)); GObj_AddUserData(tdi_gobj, 4, HSD_Free, userdata); // load menu joint JOBJ *tdi_joint = JOBJ_LoadJoint(menuAssets->menu); GObj_AddObject(tdi_gobj, 3, tdi_joint); // add to gobj GObj_AddGXLink(tdi_gobj, GXLink_Common, GXLINK_MENUMODEL, GXPRI_MENUMODEL); // add gx link menu_data->custom_gobj_think = CustomTDI_Update; // set callback // load current stick joints JOBJ *stick_joint = JOBJ_LoadJoint(stc_lab_data->stick); stick_joint->scale.X = 2; stick_joint->scale.Y = 2; stick_joint->scale.Z = 2; stick_joint->trans.X = -6; stick_joint->trans.Y = -6; userdata->stick_curr[0] = stick_joint; JOBJ_AddChild(tdi_gobj->hsd_object, stick_joint); // current c stick stick_joint = JOBJ_LoadJoint(stc_lab_data->cstick); stick_joint->scale.X = 2; stick_joint->scale.Y = 2; stick_joint->scale.Z = 2; stick_joint->trans.X = 6; stick_joint->trans.Y = -6; userdata->stick_curr[1] = stick_joint; JOBJ_AddChild(tdi_gobj->hsd_object, stick_joint); // create stick curr text Text *text_curr = Text_CreateText(2, menu_data->canvas_menu); userdata->text_curr = text_curr; // enable align and kerning text_curr->align = 0; text_curr->kerning = 1; // scale canvas text_curr->scale.X = MENU_CANVASSCALE; text_curr->scale.Y = MENU_CANVASSCALE; text_curr->trans.Z = MENU_TEXTZ; // create hit num Text_AddSubtext(text_curr, -50, 185, &nullString); // create lstick coords for (int i = 0; i < 2; i++) { Text_AddSubtext(text_curr, -400, (80 + i * 40), &nullString); } // create cstick coords for (int i = 0; i < 2; i++) { Text_AddSubtext(text_curr, 250, (80 + i * 40), &nullString); } // create prev sticks for (int i = 0; i < TDI_DISPNUM; i++) { // left stick JOBJ *prevstick_joint = JOBJ_LoadJoint(stc_lab_data->stick); prevstick_joint->scale.X = 1; prevstick_joint->scale.Y = 1; prevstick_joint->scale.Z = 1; prevstick_joint->rot.X = 0.4; prevstick_joint->trans.X = -22 + (i * (55 / TDI_DISPNUM)); prevstick_joint->trans.Y = 10; JOBJ_SetFlags(prevstick_joint, JOBJ_HIDDEN); userdata->stick_prev[i][0] = prevstick_joint; JOBJ_AddChild(tdi_gobj->hsd_object, prevstick_joint); // cstick prevstick_joint = JOBJ_LoadJoint(stc_lab_data->cstick); prevstick_joint->scale.X = 1; prevstick_joint->scale.Y = 1; prevstick_joint->scale.Z = 1; prevstick_joint->rot.X = 0.4; prevstick_joint->trans.X = -18 + (i * (55 / TDI_DISPNUM)); prevstick_joint->trans.Y = 8; JOBJ_SetFlags(prevstick_joint, JOBJ_HIDDEN); userdata->stick_prev[i][1] = prevstick_joint; JOBJ_AddChild(tdi_gobj->hsd_object, prevstick_joint); // create text Text_AddSubtext(text_curr, (-460 + (i * ((55 * 19.6) / TDI_DISPNUM))), -100, &nullString); } // create description text Text_AddSubtext(text_curr, -460, 240, "Input TDI angles for the CPU to use."); Text_AddSubtext(text_curr, -460, 285, "A = Save Input X = Delete Input B = Return"); // hide original menu event_vars->hide_menu = 1; // set pointers to custom gobj menu_data->custom_gobj = tdi_gobj; menu_data->custom_gobj_destroy = CustomTDI_Destroy; return; /* // Change color GXColor gx_color = TEXT_BGCOLOR; popup_joint->dobj->mobj->mat->diffuse = gx_color; */ } void CustomTDI_Update(GOBJ *gobj) { // get data TDIData *tdi_data = gobj->userdata; MenuData *menu_data = event_vars->menu_gobj->userdata; LCancelData *event_data = event_vars->event_gobj->userdata; // get pausing players inputs HSD_Pad *pad = PadGet(menu_data->controller_index, PADGET_MASTER); int inputs = pad->down; // if press A, save stick if ((inputs & HSD_BUTTON_A) != 0) { if (stc_tdi_val_num < TDI_HITNUM) { stc_tdi_vals[stc_tdi_val_num][0][0] = (pad->fstickX * 80); stc_tdi_vals[stc_tdi_val_num][0][1] = (pad->fstickY * 80); stc_tdi_vals[stc_tdi_val_num][1][0] = (pad->fsubstickX * 80); stc_tdi_vals[stc_tdi_val_num][1][1] = (pad->fsubstickY * 80); stc_tdi_val_num++; SFX_PlayCommon(1); } } // if press X, go back a hit if ((inputs & HSD_BUTTON_X) != 0) { if (stc_tdi_val_num > 0) { stc_tdi_val_num--; SFX_PlayCommon(0); } } // if press B, exit if ((inputs & HSD_BUTTON_B) != 0) { CustomTDI_Destroy(gobj); return; } // update curr lstick JOBJ *stick_curr = tdi_data->stick_curr[0]; stick_curr->rot.Y = pad->fstickX * 0.75; stick_curr->rot.X = pad->fstickY * 0.75 * -1; // update curr cstick stick_curr = tdi_data->stick_curr[1]; stick_curr->rot.Y = pad->fsubstickX * 0.75; stick_curr->rot.X = pad->fsubstickY * 0.75 * -1; // Update curr stick coordinates Text *text_curr = tdi_data->text_curr; Text_SetText(text_curr, 0, "Hit: %d", stc_tdi_val_num + 1); Text_SetText(text_curr, 1, "X: %+.4f", pad->fstickX); Text_SetText(text_curr, 2, "Y: %+.4f", pad->fstickY); Text_SetText(text_curr, 3, "X: %+.4f", pad->fsubstickX); Text_SetText(text_curr, 4, "Y: %+.4f", pad->fsubstickY); // display previous sticks for (int i = 0; i < TDI_DISPNUM; i++) { JOBJ *lstick_prev = tdi_data->stick_prev[i][0]; JOBJ *cstick_prev = tdi_data->stick_prev[i][1]; int this_hit = i; if (stc_tdi_val_num > TDI_DISPNUM) this_hit = (stc_tdi_val_num - TDI_DISPNUM + i); // show stick if (i < stc_tdi_val_num) { // remove hidden flag JOBJ_ClearFlags(lstick_prev, JOBJ_HIDDEN); JOBJ_ClearFlags(cstick_prev, JOBJ_HIDDEN); // update rotation lstick_prev->rot.Y = ((float)(stc_tdi_vals[this_hit][0][0]) * 1 / 80) * 0.75; lstick_prev->rot.X = ((float)(stc_tdi_vals[this_hit][0][1]) * 1 / 80) * 0.75 * -1; cstick_prev->rot.Y = ((float)(stc_tdi_vals[this_hit][1][0]) * 1 / 80) * 0.75; cstick_prev->rot.X = ((float)(stc_tdi_vals[this_hit][1][1]) * 1 / 80) * 0.75 * -1; // update text Text_SetText(text_curr, i + 5, "Hit %d", this_hit + 1); } // hide stick else { // set hidden flag JOBJ_SetFlags(lstick_prev, JOBJ_HIDDEN); JOBJ_SetFlags(cstick_prev, JOBJ_HIDDEN); Text_SetText(text_curr, i + 5, nullString); } } // update jobj JOBJ_SetMtxDirtySub(gobj->hsd_object); return; } void CustomTDI_Destroy(GOBJ *gobj) { // get data TDIData *tdi_data = gobj->userdata; MenuData *menu_data = event_vars->menu_gobj->userdata; LCancelData *event_data = event_vars->event_gobj->userdata; // set TDI to custom if (stc_tdi_val_num > 0) LabOptions_CPU[OPTCPU_TDI].option_val = CPUTDI_CUSTOM; else LabOptions_CPU[OPTCPU_TDI].option_val = CPUTDI_RANDOM; // free text Text_Destroy(tdi_data->text_curr); // destroy GObj_Destroy(gobj); // show menu event_vars->hide_menu = 0; menu_data->custom_gobj = 0; menu_data->custom_gobj_think = 0; menu_data->custom_gobj_destroy = 0; // play sfx SFX_PlayCommon(0); return; } void Inputs_GX(GOBJ *gobj, int pass) { // only render when enabled and unpaused if ((LabOptions_General[OPTGEN_INPUT].option_val == 1) && (Pause_CheckStatus(1) != 2)) { GXLink_Common(gobj, pass); } return; } void Inputs_Think(GOBJ *gobj) { InputData *input_data = gobj->userdata; // update controllers for (int i = 0; i < (sizeof(input_data->controller_joint) / 4); i++) { JOBJ *controller = input_data->controller_joint[i]; if (controller != 0) { // get port and controller data int port = Fighter_GetControllerPort(i); HSD_Pad *pad = PadGet(port, PADGET_ENGINE); // move lstick JOBJ *lstick_joint; JOBJ_GetChild(controller, &lstick_joint, 10, -1); lstick_joint->trans.X = (pad->fstickX * 2.3); lstick_joint->trans.Y = (pad->fstickY * 2.3); // move lstick JOBJ *rstick_joint; JOBJ_GetChild(controller, &rstick_joint, 8, -1); rstick_joint->trans.X = (pad->fsubstickX * 2.3); rstick_joint->trans.Y = (pad->fsubstickY * 2.3); // move ltrigger JOBJ *ltrig_joint; JOBJ_GetChild(controller, <rig_joint, button_lookup[BTN_L].jobj, -1); ltrig_joint->trans.X = (pad->ftriggerLeft * 0.5) + input_data->ltrig_origin.X; ltrig_joint->trans.Z = (pad->ftriggerLeft * 1.5) + input_data->ltrig_origin.Y; // move rtrigger JOBJ *rtrig_joint; JOBJ_GetChild(controller, &rtrig_joint, button_lookup[BTN_R].jobj, -1); rtrig_joint->trans.X = (pad->ftriggerRight * -0.5) + input_data->rtrig_origin.X; rtrig_joint->trans.Z = (pad->ftriggerRight * 1.5) + input_data->rtrig_origin.Y; // update button colors int held = pad->held; for (int i = 0; i < (BTN_NUM); i++) { // Get buttons jobj and dobj from the lookup table JOBJ *button_jobj; JOBJ_GetChild(controller, &button_jobj, button_lookup[i].jobj, -1); DOBJ *button_dobj = JOBJ_GetDObjChild(button_jobj, button_lookup[i].dobj); // check if button is pressed if (held & button_bits[i]) { // make white i guess for now GXColor color_pressed = INPUT_COLOR_PRESSED; button_dobj->mobj->mat->diffuse = color_pressed; } // not pressed, make the default color else { GXColor *color_released = &button_colors[i]; button_dobj->mobj->mat->diffuse = *color_released; } } JOBJ_SetMtxDirtySub(controller); } } // toggle visibility JOBJ *root = gobj->hsd_object; if ((LabOptions_General[OPTGEN_INPUT].option_val == 1) && (Pause_CheckStatus(1) != 2)) { Match_HideTimer(); JOBJ_ClearFlags(root, JOBJ_HIDDEN); } else if ((LabOptions_General[OPTGEN_INPUT].option_val == 0) && (Pause_CheckStatus(1) != 2)) { Match_ShowTimer(); JOBJ_SetFlags(root, JOBJ_HIDDEN); } /* // toggle timer visibility if (LabOptions_General[OPTGEN_INPUT].option_val == 1) Match_HideTimer(); else if (Pause_CheckStatus(1) != 2) Match_ShowTimer(); */ return; } void Inputs_Init() { // Create Input Display GOBJ GOBJ *input_gobj = GObj_Create(0, 0, 0); InputData *input_data = calloc(sizeof(InputData)); GObj_AddUserData(input_gobj, 4, HSD_Free, input_data); GObj_AddProc(input_gobj, Inputs_Think, 4); // alloc a dummy root jobj JOBJDesc *root_desc = calloc(sizeof(JOBJDesc)); root_desc->flags = JOBJ_ROOT_XLU | JOBJ_ROOT_TEXEDGE; root_desc->scale.X = 1; root_desc->scale.Y = 1; root_desc->scale.Z = 1; JOBJ *root = JOBJ_LoadJoint(root_desc); // init jobj pointers for (int i = 0; i < (sizeof(input_data->controller_joint) / 4); i++) { input_data->controller_joint[i] = 0; } // count humans in this match int hmn_count = 0; for (int i = 0; i < 4; i++) { if (Fighter_GetSlotType(i) == 0) hmn_count++; } // create X controllers int found_origin = 0; for (int i = 0; i < hmn_count; i++) { JOBJ *controller = JOBJ_LoadJoint(stc_lab_data->controller); // Load jobj input_data->controller_joint[i] = controller; // store jobj pointer // Add to root JOBJ_AddChild(root, controller); if (found_origin == 0) { // save trigger origins JOBJ *ltrig_jobj, *rtrig_jobj; JOBJ_GetChild(controller, <rig_jobj, button_lookup[BTN_L].jobj, -1); JOBJ_GetChild(controller, &rtrig_jobj, button_lookup[BTN_R].jobj, -1); input_data->ltrig_origin.X = ltrig_jobj->trans.X; input_data->ltrig_origin.Y = ltrig_jobj->trans.Z; input_data->rtrig_origin.X = rtrig_jobj->trans.X; input_data->rtrig_origin.Y = rtrig_jobj->trans.Z; found_origin = 1; } /* // adjust size based on the console / settings if ((OSGetConsoleType() == OS_CONSOLE_DEVHW3) || (stc_HSD_VI->is_prog == 1)) // 480p / dolphin uses medium by default LabOptions_InfoDisplay[OPT_SCALE].option_val = 1; else // 480i on wii uses large (shitty composite!) LabOptions_InfoDisplay[OPT_SCALE].option_val = 2; */ } GObj_AddObject(input_gobj, 3, root); // add to gobj GObj_AddGXLink(input_gobj, Inputs_GX, INPUT_GXLINK, INPUT_GXPRI); // add gx link return; } // Recording Functions GOBJ *Record_Init() { // Create GOBJ GOBJ *rec_gobj = GObj_Create(0, 7, 0); // Add per frame process GObj_AddProc(rec_gobj, Record_Think, 3); // create cobj GOBJ *cam_gobj = GObj_Create(19, 20, 0); COBJDesc ***dmgScnMdls = File_GetSymbol(ACCESS_PTR(0x804d6d5c), 0x803f94d0); COBJDesc *cam_desc = dmgScnMdls[1][0]; COBJ *rec_cobj = COBJ_LoadDesc(cam_desc); // init camera GObj_AddObject(cam_gobj, R13_U8(-0x3E55), rec_cobj); GOBJ_InitCamera(cam_gobj, Record_CObjThink, RECCAM_GXPRI); cam_gobj->cobj_links = RECCAM_COBJGXLINK; evMenu *menuAssets = event_vars->menu_assets; JOBJ *playback = JOBJ_LoadJoint(menuAssets->playback); // save seek jobj JOBJ *seek; JOBJ_GetChild(playback, &seek, REC_SEEKJOINT, -1); rec_data.seek_jobj = seek; // save left and right seek bounds JOBJ *seek_bound[2]; JOBJ_GetChild(playback, &seek_bound, REC_LEFTBOUNDJOINT, REC_RIGHTBOUNDJOINT, -1); Vec3 seek_bound_pos; JOBJ_GetWorldPosition(seek_bound[0], 0, &seek_bound_pos); rec_data.seek_left = seek_bound_pos.X; JOBJ_GetWorldPosition(seek_bound[1], 0, &seek_bound_pos); rec_data.seek_right = seek_bound_pos.X; // Add to gobj GObj_AddObject(rec_gobj, 3, playback); // Add gxlink GObj_AddGXLink(rec_gobj, Record_GX, REC_GXLINK, GXPRI_RECJOINT); // Create text int canvas_index = Text_CreateCanvas(2, rec_gobj, 14, 15, 0, REC_GXLINK, GXPRI_RECTEXT, 19); Text *text = Text_CreateText(2, canvas_index); text->align = 1; text->kerning = 1; text->scale.X = INFDISPTEXT_SCALE; text->scale.Y = INFDISPTEXT_SCALE; // Get text positions JOBJ *text_joint[2]; JOBJ_GetChild(playback, &text_joint, REC_LEFTTEXTJOINT, REC_RIGHTTEXTJOINT, -1); Vec3 text_left, text_right; JOBJ_GetWorldPosition(text_joint[0], 0, &text_left); JOBJ_GetWorldPosition(text_joint[1], 0, &text_right); // Create subtexts for each side Text_AddSubtext(text, (text_left.X * 25), -(text_left.Y * 25), &nullString); Text_AddSubtext(text, (text_right.X * 25), -(text_right.Y) * 25, &nullString); rec_data.text = text; // alloc rec_state rec_state = calloc(sizeof(Savestate)); // set as not exist rec_state->is_exist = 0; // disable menu options for (int i = 1; i < sizeof(LabOptions_Record) / sizeof(EventOption); i++) { LabOptions_Record[i].disable = 1; } // allocate input arrays for (int i = 0; i < REC_SLOTS; i++) { rec_data.hmn_inputs[i] = calloc(sizeof(RecInputData)); rec_data.cpu_inputs[i] = calloc(sizeof(RecInputData)); // init frame this recording starts on rec_data.hmn_inputs[i]->start_frame = -1; rec_data.cpu_inputs[i]->start_frame = -1; } // init memcard stuff Memcard_InitWorkArea(); Memcard_InitSnapshotList(HSD_MemAlloc(2112), HSD_MemAlloc(256064)); // Create snapshot cam snap_image.img_ptr = 0; GOBJ *snap_gobj = GObj_Create(18, 18, 0); GOBJ_InitCamera(snap_gobj, Snap_CObjThink, 4); GX_AllocImageData(&snap_image, EXP_SCREENSHOT_WIDTH, EXP_SCREENSHOT_HEIGHT, 4, 2006); export_status = EXSTAT_NONE; /* // init dev text int height = 18; int width = 28; int x = -50; int y = 410; DevText *dev_text = DevelopText_CreateDataTable(x, y, 0, width, height, HSD_MemAlloc(height * width * 2)); stc_devtext = dev_text; DevelopText_Activate(0, dev_text); dev_text->cursorBlink = 0; GXColor color = {21, 20, 59, 135}; DevelopText_StoreBGColor(dev_text, &color); DevelopText_StoreTextScale(dev_text, 7.5, 10); */ return rec_gobj; } void Record_CObjThink(GOBJ *gobj) { // hide UI if set to off if ((rec_state->is_exist == 1) && ((LabOptions_Record[OPTREC_CPUMODE].option_val != 0) || (LabOptions_Record[OPTREC_HMNMODE].option_val != 0))) { CObjThink_Common(gobj); } return; } void Record_GX(GOBJ *gobj, int pass) { // update UI position // the reason im doing this here is because i want it to update in the menu if (pass == 0) { // get hmn slot int hmn_slot = LabOptions_Record[OPTREC_HMNSLOT].option_val; if (hmn_slot == 0) // use random slot hmn_slot = rec_data.hmn_rndm_slot; else hmn_slot--; // get cpu slot int cpu_slot = LabOptions_Record[OPTREC_CPUSLOT].option_val; if (cpu_slot == 0) // use random slot cpu_slot = rec_data.cpu_rndm_slot; else cpu_slot--; RecInputData *hmn_inputs = rec_data.hmn_inputs[hmn_slot]; RecInputData *cpu_inputs = rec_data.cpu_inputs[cpu_slot]; JOBJ *seek = rec_data.seek_jobj; Text *text = rec_data.text; // get curr frame (the current position in the recording) int curr_frame = Record_GetCurrFrame(); int end_frame = Record_GetEndFrame(); // hide seek bar during recording if ((LabOptions_Record[OPTREC_CPUMODE].option_val == 2) || (LabOptions_Record[OPTREC_HMNMODE].option_val == 1)) { JOBJ_SetFlags(seek, JOBJ_HIDDEN); // correct record frame if (curr_frame >= REC_LENGTH) curr_frame = REC_LENGTH; // update seek bar frames Text_SetText(text, 0, "%d", curr_frame + 1); Text_SetText(text, 1, &nullString); // update color GXColor text_color; if (curr_frame == REC_LENGTH) { text_color.r = 255; text_color.g = 57; text_color.b = 62; } else if (((float)curr_frame / (float)REC_LENGTH) >= 0.75) { text_color.r = 255; text_color.g = 124; text_color.b = 36; } else { text_color.r = 255; text_color.g = 255; text_color.b = 255; } Text_SetColor(text, 0, &text_color); } // during playback else { JOBJ_ClearFlags(seek, JOBJ_HIDDEN); // if playing back with no recording, adjust both numbers int local_frame_seek = curr_frame + 1; if (curr_frame >= end_frame) { local_frame_seek = curr_frame + 1; end_frame = curr_frame + 1; } // update seek bar position float range = rec_data.seek_right - rec_data.seek_left; float curr_pos; curr_pos = (float)local_frame_seek / (float)end_frame; seek->trans.X = rec_data.seek_left + (curr_pos * range); JOBJ_ClearFlagsAll(seek, JOBJ_HIDDEN); JOBJ_SetMtxDirtySub(seek); // update seek bar frames Text_SetText(text, 0, "%d", local_frame_seek); Text_SetText(text, 1, "%d", end_frame); // if random playback, hide frame count and bar if ((LabOptions_Record[OPTREC_CPUSLOT].option_val == 0) || (LabOptions_Record[OPTREC_HMNSLOT].option_val == 0)) { Text_SetText(text, 1, "?"); // hide count JOBJ_SetFlagsAll(seek, JOBJ_HIDDEN); // hide bar } // update color GXColor text_color; text_color.r = 255; text_color.g = 255; text_color.b = 255; Text_SetColor(text, 0, &text_color); } } GXLink_Common(gobj, pass); return; } void Record_Think(GOBJ *rec_gobj) { // get current hmn recording slot int hmn_slot = LabOptions_Record[OPTREC_HMNSLOT].option_val; if (hmn_slot == 0) // use random slot hmn_slot = rec_data.hmn_rndm_slot; else hmn_slot--; // get current cpu recording slot int cpu_slot = LabOptions_Record[OPTREC_CPUSLOT].option_val; if (cpu_slot == 0) // use random slot cpu_slot = rec_data.cpu_rndm_slot; else cpu_slot--; RecInputData *hmn_inputs = rec_data.hmn_inputs[hmn_slot]; RecInputData *cpu_inputs = rec_data.cpu_inputs[cpu_slot]; // ensure the state exists if (rec_state->is_exist == 1) { // get longest recording int input_num = hmn_inputs->num; if (cpu_inputs->num > hmn_inputs->num) input_num = cpu_inputs->num; // get curr frame (the current position in the recording) int curr_frame = Record_GetCurrFrame(); int end_frame = Record_GetEndFrame(); // if at the end of the recording if ((input_num != 0) && (curr_frame >= end_frame)) { // but not during a recording/control if ((LabOptions_Record[OPTREC_HMNMODE].option_val != 1) && (LabOptions_Record[OPTREC_CPUMODE].option_val != 1) && (LabOptions_Record[OPTREC_CPUMODE].option_val != 2)) { // init flag int is_loop = 0; // check to auto reset if ((LabOptions_Record[OPTREC_AUTOLOAD].option_val == 1)) { event_vars->Savestate_Load(rec_state); event_vars->game_timer = rec_state->frame + 1; is_loop = 1; } // check to loop inputs else if ((LabOptions_Record[OPTREC_LOOP].option_val == 1)) { event_vars->game_timer = rec_state->frame + 1; is_loop = 1; } // if recording looped, check to re-roll random slot if (is_loop == 1) { // re-roll random slot if (LabOptions_Record[OPTREC_HMNSLOT].option_val == 0) { rec_data.hmn_rndm_slot = Record_GetRandomSlot(&rec_data.hmn_inputs); } if (LabOptions_Record[OPTREC_CPUSLOT].option_val == 0) { rec_data.cpu_rndm_slot = Record_GetRandomSlot(&rec_data.cpu_inputs); } } } } // check record mode for HMN int hmn_mode = LabOptions_Record[OPTREC_HMNMODE].option_val; if (hmn_mode > 0) // adjust mode hmn_mode++; Record_Update(0, hmn_inputs, hmn_mode); // check record mode for CPU int cpu_mode = LabOptions_Record[OPTREC_CPUMODE].option_val; Record_Update(1, cpu_inputs, cpu_mode); } /* GOBJ *cpu = Fighter_GetGObj(1); FighterData *cpu_data = cpu->userdata; DevText *dev_text = stc_devtext; // clear text DevelopText_EraseAllText(dev_text); DevelopMode_ResetCursorXY(dev_text, 0, 0); DevelopText_AddString(dev_text, "isthrown: %d\n", cpu_data->flags.is_thrown); */ return; } void Record_Update(int ply, RecInputData *input_data, int rec_mode) { GOBJ *fighter = Fighter_GetGObj(ply); FighterData *fighter_data = fighter->userdata; // get curr frame (the time since saving positions) int curr_frame = (event_vars->game_timer - rec_state->frame); // get the frame the recording starts on. i actually hate this code and need to change how this works int rec_start; if (input_data->start_frame == -1) // case 1: recording didnt start, use current frame { rec_start = curr_frame - 1; } else // case 2: recording has started, use the frame saved { rec_start = input_data->start_frame - rec_state->frame; } int end_frame = rec_start + input_data->num; // Get HSD Pad HSD_Pad *pad = PadGet(fighter_data->player_controller_number, PADGET_ENGINE); // if the current frame before the recording ends if ((curr_frame) < (rec_start + REC_LENGTH)) { switch (rec_mode) { case RECMODE_OFF: { break; } case RECMODE_CTRL: { break; } case RECMODE_REC: { // recording has started BUT the player has jumped back behind it, move the start frame back if ((input_data->start_frame == -1) || (curr_frame < rec_start)) { input_data->start_frame = (event_vars->game_timer - 1); rec_start = curr_frame - 1; } // store inputs int held = pad->held; RecInputs *inputs = &input_data->inputs[curr_frame - 1]; inputs->btn_a = !!((held)&HSD_BUTTON_A); inputs->btn_b = !!((held)&HSD_BUTTON_B); inputs->btn_x = !!((held)&HSD_BUTTON_X); inputs->btn_y = !!((held)&HSD_BUTTON_Y); inputs->btn_L = !!((held)&HSD_TRIGGER_L); inputs->btn_R = !!((held)&HSD_TRIGGER_R); inputs->btn_Z = !!((held)&HSD_TRIGGER_Z); inputs->btn_dpadup = !!((held)&HSD_BUTTON_DPAD_UP); inputs->stickX = pad->stickX; inputs->stickY = pad->stickY; inputs->substickX = pad->substickX; inputs->substickY = pad->substickY; // trigger - find the one pressed down more u8 trigger = pad->triggerLeft; if (pad->triggerRight > trigger) trigger = pad->triggerRight; inputs->trigger = trigger; // update input_num input_data->num = (curr_frame - rec_start); // clear inputs henceforth //memset(&input_data->inputs[curr_frame + 1], 0, (REC_LENGTH - curr_frame) * sizeof(RecInputs)); break; } case RECMODE_PLAY: { // ensure we have an input for this frame if ((curr_frame >= rec_start) && ((curr_frame - rec_start) <= (input_data->num))) { int held = 0; RecInputs *inputs = &input_data->inputs[curr_frame - 1]; // read inputs held |= inputs->btn_a << 8; held |= inputs->btn_b << 9; held |= inputs->btn_x << 10; held |= inputs->btn_y << 11; held |= inputs->btn_L << 6; held |= inputs->btn_R << 5; held |= inputs->btn_Z << 4; held |= inputs->btn_dpadup << 3; pad->held = held; // stick signed bytes pad->stickX = inputs->stickX; pad->stickY = inputs->stickY; pad->substickX = inputs->substickX; pad->substickY = inputs->substickY; // stick floats pad->fstickX = ((float)inputs->stickX / 80); pad->fstickY = ((float)inputs->stickY / 80); pad->fsubstickX = ((float)inputs->substickX / 80); pad->fsubstickY = ((float)inputs->substickY / 80); // trigger byte pad->triggerRight = inputs->trigger; pad->triggerLeft = 0; // trigger float pad->ftriggerRight = ((float)inputs->trigger / 255); pad->ftriggerLeft = 0; } break; } } } return; } void Record_InitState(GOBJ *menu_gobj) { if (event_vars->Savestate_Save(rec_state)) { Record_OnSuccessfulSave(); } return; } void Record_RestoreState(GOBJ *menu_gobj) { event_vars->Savestate_Load(rec_state); return; } void Record_ChangeHMNSlot(GOBJ *menu_gobj, int value) { // upon changing to random if (value == 0) { // if set to record if (LabOptions_Record[OPTREC_HMNMODE].option_val == 1) { // change to slot 1 LabOptions_Record[OPTREC_HMNSLOT].option_val = 1; } // update random slot else { rec_data.hmn_rndm_slot = Record_GetRandomSlot(&rec_data.hmn_inputs); } } // reload save event_vars->Savestate_Load(rec_state); return; } void Record_ChangeCPUSlot(GOBJ *menu_gobj, int value) { // upon changing to random if (value == 0) { // if set to record if (LabOptions_Record[OPTREC_CPUMODE].option_val == 2) { // change to slot 1 LabOptions_Record[OPTREC_CPUSLOT].option_val = 1; } // update random slot else { rec_data.cpu_rndm_slot = Record_GetRandomSlot(&rec_data.cpu_inputs); } } // reload save event_vars->Savestate_Load(rec_state); return; } void Record_ChangeHMNMode(GOBJ *menu_gobj, int value) { // upon changing to record if (value == 1) { // if set to random if (LabOptions_Record[OPTREC_HMNSLOT].option_val == 0) { LabOptions_Record[OPTREC_HMNSLOT].option_val = 1; } } // upon changing to playback if (value == 2) { event_vars->Savestate_Load(rec_state); } // disable loop options if recording is in use if ((LabOptions_Record[OPTREC_HMNMODE].option_val != 1) && (LabOptions_Record[OPTREC_CPUMODE].option_val != 2)) { LabOptions_Record[OPTREC_LOOP].disable = 0; LabOptions_Record[OPTREC_AUTOLOAD].disable = 0; } else { LabOptions_Record[OPTREC_LOOP].disable = 1; LabOptions_Record[OPTREC_AUTOLOAD].disable = 1; } return; } void Record_ChangeCPUMode(GOBJ *menu_gobj, int value) { // upon changing to record if (value == 2) { // if set to random if (LabOptions_Record[OPTREC_CPUSLOT].option_val == 0) { // change to slot 1 LabOptions_Record[OPTREC_CPUSLOT].option_val = 1; } } // upon toggling playback if (value == 3) { event_vars->Savestate_Load(rec_state); } // disable loop options if recording is in use if ((LabOptions_Record[OPTREC_HMNMODE].option_val != 1) && (LabOptions_Record[OPTREC_CPUMODE].option_val != 2)) { LabOptions_Record[OPTREC_LOOP].disable = 0; LabOptions_Record[OPTREC_AUTOLOAD].disable = 0; } else { LabOptions_Record[OPTREC_LOOP].disable = 1; LabOptions_Record[OPTREC_AUTOLOAD].disable = 1; } return; } int Record_GetRandomSlot(RecInputData **input_data) { // create array of slots in use u8 slot_num = 0; u8 arr[REC_SLOTS]; for (int i = 0; i < REC_SLOTS; i++) { // if this recording slot is in use if (input_data[i]->num != 0) { arr[slot_num] = i; slot_num++; } } // ensure at least one slot found if (slot_num == 0) { return 0; } // get random slot in use return arr[(HSD_Randi(slot_num))]; } int Record_GetCurrFrame() { return (event_vars->game_timer - 1) - rec_state->frame; } int Record_GetEndFrame() { // get hmn slot int hmn_slot = LabOptions_Record[OPTREC_HMNSLOT].option_val; if (hmn_slot == 0) // use random slot hmn_slot = rec_data.hmn_rndm_slot; else hmn_slot--; // get cpu slot int cpu_slot = LabOptions_Record[OPTREC_CPUSLOT].option_val; if (cpu_slot == 0) // use random slot cpu_slot = rec_data.cpu_rndm_slot; else cpu_slot--; int curr_frame = Record_GetCurrFrame(); RecInputData *hmn_inputs = rec_data.hmn_inputs[hmn_slot]; RecInputData *cpu_inputs = rec_data.cpu_inputs[cpu_slot]; // get what frame the longest recording ends on (savestate frame + recording start frame + recording time) int hmn_end_frame = 0; int cpu_end_frame = 0; if (hmn_inputs->start_frame != -1) // ensure a recording exists hmn_end_frame = (hmn_inputs->start_frame + hmn_inputs->num); if (cpu_inputs->start_frame != -1) // ensure a recording exists cpu_end_frame = (cpu_inputs->start_frame + cpu_inputs->num); // find the larger recording RecInputData *input_data = hmn_inputs; if (cpu_end_frame > hmn_end_frame) input_data = cpu_inputs; // get the frame the recording starts on. i actually hate this code and need to change how this works int rec_start; if (input_data->start_frame == -1) // case 1: recording didnt start, use current frame rec_start = curr_frame - 1; else // case 2: recording has started, use the frame saved rec_start = input_data->start_frame - rec_state->frame; // get end frame int end_frame = rec_start + input_data->num; return end_frame; } void Record_OnSuccessfulSave() { // enable other options for (int i = 1; i < sizeof(LabOptions_Record) / sizeof(EventOption); i++) { LabOptions_Record[i].disable = 0; } // clear slots for (int i = 0; i < REC_SLOTS; i++) { // clear data memset(rec_data.hmn_inputs[i], 0, sizeof(RecInputData)); memset(rec_data.cpu_inputs[i], 0, sizeof(RecInputData)); // init frame this recording starts on rec_data.hmn_inputs[i]->start_frame = -1; rec_data.cpu_inputs[i]->start_frame = -1; } // init settings LabOptions_Record[OPTREC_HMNMODE].option_val = 0; // set hmn to off LabOptions_Record[OPTREC_HMNSLOT].option_val = 1; // set hmn to slot 1 LabOptions_Record[OPTREC_CPUMODE].option_val = 0; // set cpu to off LabOptions_Record[OPTREC_CPUSLOT].option_val = 1; // set cpu to slot 1 // also save to personal savestate event_vars->Savestate_Save(event_vars->savestate); // take screenshot snap_status = 1; return; } void Memcard_Wait() { while (stc_memcard_work->is_done == 0) { blr2(); } return; } void Record_MemcardLoad(int slot, int file_no) { // search card for this save file u8 file_found = 0; char filename[32]; int file_size; s32 memSize, sectorSize; if (CARDProbeEx(slot, &memSize, §orSize) == CARD_RESULT_READY) { // mount card stc_memcard_work->is_done = 0; if (CARDMountAsync(slot, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY) { // check card Memcard_Wait(); stc_memcard_work->is_done = 0; if (CARDCheckAsync(slot, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); // search for nth file with name TM_DEBUG int tmrec_num = 0; for (int i = 0; i < CARD_MAX_FILE; i++) { CARDStat card_stat; if (CARDGetStatus(slot, i, &card_stat) == CARD_RESULT_READY) { // check company code if (strncmp(os_info->company, card_stat.company, sizeof(os_info->company)) == 0) { // check game name if (strncmp(os_info->gameName, card_stat.gameName, sizeof(os_info->gameName)) == 0) { // check file name if (strncmp("TMREC", card_stat.fileName, 5) == 0) { // if the desired file if (tmrec_num == file_no) { file_found = 1; memcpy(&filename, card_stat.fileName, sizeof(filename)); // copy filename to load after this file_size = card_stat.length; break; } // increment tmrec num tmrec_num++; } } } } } } CARDUnmount(slot); stc_memcard_work->is_done = 0; } } // if found, load it if (file_found == 1) { int load_pre_tick = OSGetTick(); // setup load MemcardSave memcard_save; memcard_save.data = HSD_MemAlloc(file_size); memcard_save.x4 = 3; memcard_save.size = file_size; memcard_save.xc = -1; Memcard_LoadSnapshot(slot, filename, &memcard_save, &stc_memcard_info->file_name, 0, 0, 0); // wait to load int memcard_status = Memcard_CheckStatus(); while (memcard_status == 11) { memcard_status = Memcard_CheckStatus(); } // if file loaded successfully if (memcard_status == 0) { // enable other options for (int i = 1; i < sizeof(LabOptions_Record) / sizeof(EventOption); i++) { LabOptions_Record[i].disable = 0; } // take screenshot snap_status = 1; // begin unpacking u8 *transfer_buf = memcard_save.data; ExportHeader *header = transfer_buf; u8 *compressed_recording = transfer_buf + header->lookup.ofst_recording; RGB565 *img = transfer_buf + header->lookup.ofst_screenshot; ExportMenuSettings *menu_settings = transfer_buf + header->lookup.ofst_menusettings; OSReport("rec: ft %d vs ft %d on stage %d\n", header->metadata.hmn, header->metadata.cpu, header->metadata.stage_internal); // decompress RecordingSave *loaded_recsave = calloc(sizeof(RecordingSave) * 1.06); lz77_decompress(compressed_recording, loaded_recsave); // copy buffer to savestate memcpy(rec_state, &loaded_recsave->savestate, sizeof(Savestate)); // restore controller indices rec_state->ft_state[0].player_block.controller = stc_hmn_controller; rec_state->ft_state[1].player_block.controller = stc_cpu_controller; // load state event_vars->Savestate_Load(rec_state); // copy recordings for (int i = 0; i < REC_SLOTS; i++) { memcpy(rec_data.hmn_inputs[i], &loaded_recsave->hmn_inputs[i], sizeof(RecInputData)); memcpy(rec_data.cpu_inputs[i], &loaded_recsave->cpu_inputs[i], sizeof(RecInputData)); } HSD_Free(loaded_recsave); // copy recording settings LabOptions_Record[OPTREC_HMNMODE].option_val = menu_settings->hmn_mode; LabOptions_Record[OPTREC_HMNSLOT].option_val = menu_settings->hmn_slot; LabOptions_Record[OPTREC_CPUMODE].option_val = menu_settings->cpu_mode; LabOptions_Record[OPTREC_CPUSLOT].option_val = menu_settings->cpu_slot; LabOptions_Record[OPTREC_LOOP].option_val = menu_settings->loop_inputs; LabOptions_Record[OPTREC_AUTOLOAD].option_val = menu_settings->auto_restore; // enter recording menu MenuData *menu_data = event_vars->menu_gobj->userdata; EventMenu *curr_menu = menu_data->currMenu; curr_menu->state = EMSTATE_OPENSUB; // update curr_menu EventMenu *next_menu = curr_menu->options[2].menu; next_menu->prev = curr_menu; next_menu->state = EMSTATE_FOCUS; curr_menu = next_menu; menu_data->currMenu = curr_menu; // save to personal savestate event_vars->Savestate_Save(event_vars->savestate); } HSD_Free(memcard_save.data); int load_post_tick = OSGetTick(); int load_time = OSTicksToMilliseconds(load_post_tick - load_pre_tick); OSReport("processed memcard load in %dms\n", load_time); } return; } int Record_MenuThink(GOBJ *menu_gobj) { int is_update = 1; // check to run export logic if (export_status != EXSTAT_NONE) { is_update = Record_ExportThink(); } return is_update; } void Record_StartExport(GOBJ *menu_gobj) { export_status = EXSTAT_REQSAVE; return; } void Snap_CObjThink(GOBJ *gobj) { // logic based on state switch (snap_status) { case (1): { // take snap HSD_ImageDescCopyFromEFB(&snap_image, 0, 0, 0); snap_status = 0; OSReport("got snap!\n"); break; } } return; } void Savestates_Update() { /* So i have code to do this in events.c that runs based a variable in the EventDesc, but i need to execute code directly after loading state so im just gonna do this here... */ // not when pause menu is showing if (Pause_CheckStatus(1) != 2) { // loop through all humans for (int i = 0; i < 6; i++) { // check if fighter exists GOBJ *fighter = Fighter_GetGObj(i); if (fighter != 0) { // get fighter data FighterData *fighter_data = fighter->userdata; HSD_Pad *pad = PadGet(fighter_data->ply, PADGET_MASTER); // check for savestate int blacklist = (HSD_BUTTON_DPAD_DOWN | HSD_BUTTON_DPAD_UP | HSD_TRIGGER_Z | HSD_TRIGGER_R | HSD_BUTTON_A | HSD_BUTTON_B | HSD_BUTTON_X | HSD_BUTTON_Y | HSD_BUTTON_START); if (((pad->down & HSD_BUTTON_DPAD_RIGHT) != 0) && ((pad->held & (blacklist)) == 0)) { // save state event_vars->Savestate_Save(event_vars->savestate); } else if (((pad->down & HSD_BUTTON_DPAD_LEFT) != 0) && ((pad->held & (blacklist)) == 0)) { // load state event_vars->Savestate_Load(event_vars->savestate); // re-roll random slot if (LabOptions_Record[OPTREC_HMNSLOT].option_val == 0) { rec_data.hmn_rndm_slot = Record_GetRandomSlot(&rec_data.hmn_inputs); } if (LabOptions_Record[OPTREC_CPUSLOT].option_val == 0) { rec_data.cpu_rndm_slot = Record_GetRandomSlot(&rec_data.cpu_inputs); } } } } } return; } // Export functions static char *keyboard_rows[2][4] = { {"1234567890", "qwertyuiop", "asdfghjkl-", "zxcvbnm,./"}, {"!@#$%^&*()", "QWERTYUIOP", "ASDFGHJKL: ", "ZXCVBNM<>?"}}; int RowPixelToBlockPixel(int pixel_x, int pixel_y, int width, int height) { // get block width and height int block_width = divide_roundup(width, 4); // get block num int block_num = ((pixel_y / 4) * block_width) + (pixel_x / 4); // get pixels x and y within this block int block_pos_x = pixel_x % 4; int block_pos_y = pixel_y % 4; // get block pixel index int block_pixel = (block_num * 16) + (block_pos_y * 4) + block_pos_x; return block_pixel; } void ImageScale(RGB565 *out_img, RGB565 *in_img, int OutWidth, int OutHeight, int InWidth, int InHeight) { int x_ratio = (InWidth / OutWidth); int y_ratio = (InHeight / OutHeight); int px, py; int in_pixel, out_pixel; for (int y = 0; y < (OutHeight); y++) { for (int x = 0; x < (OutWidth); x++) { px = x * x_ratio; py = y * y_ratio; in_pixel = RowPixelToBlockPixel(x, y, OutWidth, OutHeight); out_pixel = RowPixelToBlockPixel(px, py, InWidth, InHeight); out_img[in_pixel] = in_img[out_pixel]; } } return; } void Export_Init(GOBJ *menu_gobj) { MenuData *menu_data = menu_gobj->userdata; EventMenu *curr_menu = menu_data->currMenu; evMenu *menuAssets = event_vars->menu_assets; // create gobj GOBJ *export_gobj = GObj_Create(0, 0, 0); ExportData *export_data = calloc(sizeof(ExportData)); GObj_AddUserData(export_gobj, 4, HSD_Free, export_data); // load menu joint JOBJ *export_joint = JOBJ_LoadJoint(stc_lab_data->export_menu); GObj_AddObject(export_gobj, 3, export_joint); // add to gobj GObj_AddGXLink(export_gobj, GXLink_Common, GXLINK_MENUMODEL, GXPRI_MENUMODEL); // add gx link menu_data->custom_gobj_think = Export_Think; // set callback // save jobj pointers JOBJ_GetChild(export_joint, &export_data->memcard_jobj[0], EXP_MEMCARDAJOBJ, -1); JOBJ_GetChild(export_joint, &export_data->memcard_jobj[1], EXP_MEMCARDBJOBJ, -1); JOBJ_GetChild(export_joint, &export_data->screenshot_jobj, EXP_SCREENSHOTJOBJ, -1); JOBJ_GetChild(export_joint, &export_data->textbox_jobj, EXP_TEXTBOXJOBJ, -1); // hide all JOBJ_SetFlags(export_data->memcard_jobj[0], JOBJ_HIDDEN); JOBJ_SetFlags(export_data->memcard_jobj[1], JOBJ_HIDDEN); JOBJ_SetFlags(export_data->screenshot_jobj, JOBJ_HIDDEN); JOBJ_SetFlags(export_data->textbox_jobj, JOBJ_HIDDEN); // alloc a buffer for all of the recording data RecordingSave *temp_rec_save = calloc(sizeof(RecordingSave)); // copy match data to buffer memcpy(&temp_rec_save->match_data, &stc_match->match, sizeof(MatchInit)); // copy savestate to buffer memcpy(&temp_rec_save->savestate, rec_state, sizeof(Savestate)); // copy recordings for (int i = 0; i < REC_SLOTS; i++) { memcpy(&temp_rec_save->hmn_inputs[i], rec_data.hmn_inputs[i], sizeof(RecInputData)); memcpy(&temp_rec_save->cpu_inputs[i], rec_data.cpu_inputs[i], sizeof(RecInputData)); } // compress all recording data u8 *recording_buffer = calloc(sizeof(RecordingSave)); int compress_size = Export_Compress(recording_buffer, temp_rec_save, sizeof(RecordingSave)); HSD_Free(temp_rec_save); // free original data buffer // resize screenshot int img_size = GXGetTexBufferSize(RESIZE_WIDTH, RESIZE_HEIGHT, 4, 0, 0); RGB565 *orig_img = snap_image.img_ptr; RGB565 *new_img = calloc(img_size); export_data->scaled_image = new_img; ImageScale(new_img, orig_img, RESIZE_WIDTH, RESIZE_HEIGHT, EXP_SCREENSHOT_WIDTH, EXP_SCREENSHOT_HEIGHT); OSReport("scaled image to %d kb\n", (img_size / 1000)); resized_image.img_ptr = new_img; // store pointer to resized image export_data->screenshot_jobj->dobj->mobj->tobj->imagedesc = &resized_image; // replace pointer to imagedesc // get curr date OSCalendarTime td; OSTicksToCalendarTime(OSGetTime(), &td); // alloc a buffer to transfer to memcard stc_transfer_buf_size = sizeof(ExportHeader) + img_size + sizeof(ExportMenuSettings) + compress_size; stc_transfer_buf = calloc(stc_transfer_buf_size); // init header ExportHeader *header = stc_transfer_buf; header->metadata.version = REC_VERS; header->metadata.image_width = RESIZE_WIDTH; header->metadata.image_height = RESIZE_HEIGHT; header->metadata.image_fmt = 4; header->metadata.hmn = Fighter_GetExternalID(0); header->metadata.hmn_costume = Fighter_GetCostumeID(0); header->metadata.cpu = Fighter_GetExternalID(1); header->metadata.cpu_costume = Fighter_GetCostumeID(1); header->metadata.stage_external = Stage_GetExternalID(); header->metadata.stage_internal = Stage_ExternalToInternal(header->metadata.stage_external); header->metadata.month = td.mon + 1; header->metadata.day = td.mday; header->metadata.year = td.year; header->metadata.hour = td.hour; header->metadata.minute = td.min; header->metadata.second = td.sec; header->lookup.ofst_screenshot = sizeof(ExportHeader); header->lookup.ofst_recording = sizeof(ExportHeader) + img_size; header->lookup.ofst_menusettings = sizeof(ExportHeader) + img_size + compress_size; OSReport("prepared buffer of %d kb\n", (stc_transfer_buf_size / 1000)); // copy data to buffer // image memcpy(stc_transfer_buf + header->lookup.ofst_screenshot, new_img, img_size); // menu settings ExportMenuSettings *menu_settings = stc_transfer_buf + header->lookup.ofst_menusettings; menu_settings->hmn_mode = LabOptions_Record[OPTREC_HMNMODE].option_val; menu_settings->hmn_slot = LabOptions_Record[OPTREC_HMNSLOT].option_val; menu_settings->cpu_mode = LabOptions_Record[OPTREC_CPUMODE].option_val; menu_settings->cpu_slot = LabOptions_Record[OPTREC_CPUSLOT].option_val; menu_settings->loop_inputs = LabOptions_Record[OPTREC_LOOP].option_val; menu_settings->auto_restore = LabOptions_Record[OPTREC_AUTOLOAD].option_val; // recording data memcpy(stc_transfer_buf + header->lookup.ofst_recording, recording_buffer, compress_size); // compressed recording // free compresed data buffer HSD_Free(recording_buffer); // alloc filename buffer export_data->filename_buffer = calloc(32 + 2); // +2 for terminator and cursor // initialize memcard menu Export_SelCardInit(export_gobj); event_vars->hide_menu = 1; // hide original menu menu_data->custom_gobj = export_gobj; // set custom gobj menu_data->custom_gobj_think = Export_Think; // set think function menu_data->custom_gobj_destroy = Export_Destroy; // set destroy function return; } int Export_Think(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; int can_unpause = 0; switch (export_data->menu_index) { case (EXMENU_SELCARD): { can_unpause = Export_SelCardThink(export_gobj); break; } case (EXMENU_NAME): { can_unpause = Export_EnterNameThink(export_gobj); break; } case (EXMENU_CONFIRM): { can_unpause = Export_ConfirmThink(export_gobj); break; } } return can_unpause; } void Export_Destroy(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; MenuData *menu_data = event_vars->menu_gobj->userdata; switch (export_data->menu_index) { case (EXMENU_SELCARD): { Export_SelCardExit(export_gobj); break; } case (EXMENU_NAME): { Export_EnterNameExit(export_gobj); break; } } // free buffer allocs HSD_Free(stc_transfer_buf); HSD_Free(export_data->filename_buffer); HSD_Free(export_data->scaled_image); // destroy gobj GObj_Destroy(export_gobj); // show menu event_vars->hide_menu = 0; menu_data->custom_gobj = 0; menu_data->custom_gobj_think = 0; menu_data->custom_gobj_destroy = 0; return; } void Export_SelCardInit(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; MenuData *menu_data = event_vars->menu_gobj->userdata; // show menu jobjs JOBJ_ClearFlags(export_data->memcard_jobj[0], JOBJ_HIDDEN); JOBJ_ClearFlags(export_data->memcard_jobj[1], JOBJ_HIDDEN); // create text Text *text_misc = Text_CreateText(2, menu_data->canvas_menu); export_data->text_misc = text_misc; // enable align and kerning text_misc->align = 1; text_misc->kerning = 1; // scale canvas text_misc->scale.X = MENU_CANVASSCALE; text_misc->scale.Y = MENU_CANVASSCALE; text_misc->trans.Z = MENU_TEXTZ; // create title text Text *text_title = Text_CreateText(2, menu_data->canvas_menu); export_data->text_title = text_title; // enable align and kerning text_title->align = 0; text_title->kerning = 1; // scale canvas text_title->trans.X = -23; text_title->trans.Y = -18; text_title->scale.X = MENU_CANVASSCALE * 2; text_title->scale.Y = MENU_CANVASSCALE * 2; text_title->trans.Z = MENU_TEXTZ; // create desc text Text *text_desc = Text_CreateText(2, menu_data->canvas_menu); export_data->text_desc = text_desc; // enable align and kerning text_desc->align = 0; text_desc->kerning = 1; // scale canvas text_desc->trans.X = -23; text_desc->trans.Y = 12; text_desc->scale.X = MENU_CANVASSCALE; text_desc->scale.Y = MENU_CANVASSCALE; text_desc->trans.Z = MENU_TEXTZ; Text_AddSubtext(text_title, 0, 0, "Select a Memory Card"); // add title Text_AddSubtext(text_desc, 0, 0, ""); // add description // add dummy text Text_AddSubtext(text_misc, -165, 67, "Slot A"); Text_AddSubtext(text_misc, 165, 67, "Slot B"); // init memcard inserted status for (int i = 0; i < 2; i++) { export_data->is_inserted[i] = 0; } // init cursor export_data->menu_index = EXMENU_SELCARD; export_data->slot = 0; return; } int Export_SelCardThink(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; int req_blocks = (divide_roundup(stc_transfer_buf_size, 8192) + 1); // get pausing players inputs HSD_Pad *pad = PadGet(stc_hmn_controller, PADGET_MASTER); int inputs = pad->down; // update memcard info for (int i = 1; i >= 0; i--) { // probe slot u8 is_inserted; s32 memSize, sectorSize; if (CARDProbeEx(i, &memSize, §orSize) == CARD_RESULT_READY) { // if it was just inserted, get info if (export_data->is_inserted[i] == 0) { // mount card stc_memcard_work->is_done = 0; if (CARDMountAsync(i, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY) { // check card Memcard_Wait(); stc_memcard_work->is_done = 0; if (CARDCheckAsync(i, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); // if we get this far, a valid memcard is inserted is_inserted = 1; SFX_PlayCommon(2); //export_data->slot = i; // move cursor to this // get free blocks s32 byteNotUsed, filesNotUsed; if (CARDFreeBlocks(i, &byteNotUsed, &filesNotUsed) == CARD_RESULT_READY) { export_data->free_blocks[i] = (byteNotUsed / 8192); export_data->free_files[i] = filesNotUsed; } } else is_inserted = 0; CARDUnmount(i); stc_memcard_work->is_done = 0; } else is_inserted = 0; } else is_inserted = 1; } else is_inserted = 0; export_data->is_inserted[i] = is_inserted; } // if left if ((inputs & HSD_BUTTON_LEFT) || (inputs & HSD_BUTTON_DPAD_LEFT)) { if (export_data->slot > 0) { export_data->slot--; SFX_PlayCommon(2); } } // if right if ((inputs & HSD_BUTTON_RIGHT) || (inputs & HSD_BUTTON_DPAD_RIGHT)) { if (export_data->slot < 1) { export_data->slot++; SFX_PlayCommon(2); } } int cursor = export_data->slot; // if press A, if ((inputs & HSD_BUTTON_A) || (inputs & HSD_BUTTON_START)) { // ensure it can be saved if ((export_data->is_inserted[cursor] == 1) && (export_data->free_files[cursor] >= 1) && (export_data->free_blocks[cursor] >= req_blocks)) { // can save move to next screen Export_SelCardExit(export_gobj); // init next menu Export_EnterNameInit(export_gobj); SFX_PlayCommon(1); return; } else SFX_PlayCommon(3); } // if press B, if ((inputs & HSD_BUTTON_B)) { Export_Destroy(export_gobj); // play sfx SFX_PlayCommon(0); return; } // update selection Text *text = export_data->text_misc; for (int i = 0; i < 2; i++) { static GXColor white = {255, 255, 255, 255}; static GXColor yellow = {201, 178, 0, 255}; GXColor *color; // highlight cursor only if (export_data->slot == i) color = &yellow; else color = &white; Text_SetColor(text, i, color); } // update description Text *text_desc = export_data->text_desc; if (export_data->is_inserted[cursor] == 0) { Text_SetText(text_desc, 0, "No device is inserted in Slot %s.", slots_names[cursor]); } else if (export_data->free_files[cursor] < 1) { Text_SetText(text_desc, 0, "The memory card in Slot %s does not \nhave enough free files. 1 free file is \nrequired to save.", slots_names[cursor]); } else if (export_data->free_blocks[cursor] < req_blocks) { Text_SetText(text_desc, 0, "The memory card in Slot %s does not \nhave enough free blocks. %d blocks is \nrequired to save.", slots_names[cursor], req_blocks); } else { Text_SetText(text_desc, 0, "Slot %s: %d free blocks. %d blocks will be used.", slots_names[cursor], export_data->free_blocks[cursor], req_blocks); } return 1; } void Export_SelCardExit(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; // hide menu jobjs JOBJ_SetFlags(export_data->memcard_jobj[0], JOBJ_HIDDEN); JOBJ_SetFlags(export_data->memcard_jobj[1], JOBJ_HIDDEN); Text_Destroy(export_data->text_title); Text_Destroy(export_data->text_desc); Text_Destroy(export_data->text_misc); } void Export_EnterNameInit(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; MenuData *menu_data = event_vars->menu_gobj->userdata; // show menu jobjs JOBJ_ClearFlags(export_data->screenshot_jobj, JOBJ_HIDDEN); JOBJ_ClearFlags(export_data->textbox_jobj, JOBJ_HIDDEN); // create keyboard text Text *text_keyboard = Text_CreateText(2, menu_data->canvas_menu); export_data->text_keyboard = text_keyboard; // enable align and kerning text_keyboard->align = 1; text_keyboard->kerning = 1; // scale canvas text_keyboard->trans.X = EXP_KEYBOARD_X; text_keyboard->trans.Y = EXP_KEYBOARD_Y; text_keyboard->scale.X = MENU_CANVASSCALE * EXP_KEYBOARD_SIZE; text_keyboard->scale.Y = MENU_CANVASSCALE * EXP_KEYBOARD_SIZE; // init keyboard for (int i = 0; i < 4; i++) { // iterate through columns for (int j = 0; j < 10; j++) { Text_AddSubtext(text_keyboard, (-(9.0 / 2.0) * 60) + (j * 60), -80 + (i * 60), ""); } } export_data->key_cursor[0] = 0; export_data->key_cursor[1] = 0; export_data->caps_lock = 0; Export_EnterNameUpdateKeyboard(export_gobj); // create file details ExportHeader *header = stc_transfer_buf; char *stage_name = stage_names[header->metadata.stage_internal]; char *hmn_name = Fighter_GetName(header->metadata.hmn); char *cpu_name = Fighter_GetName(header->metadata.cpu); Text *text_filedetails = Text_CreateText(2, menu_data->canvas_menu); export_data->text_filedetails = text_filedetails; // enable align and kerning text_filedetails->align = 0; text_filedetails->kerning = 1; // scale canvas text_filedetails->trans.X = EXP_FILEDETAILS_X; text_filedetails->trans.Y = EXP_FILEDETAILS_Y; text_filedetails->scale.X = MENU_CANVASSCALE * EXP_FILEDETAILS_SIZE; text_filedetails->scale.Y = MENU_CANVASSCALE * EXP_FILEDETAILS_SIZE; Text_AddSubtext(text_filedetails, 0, 0, "Stage: %s\nHMN: %s\nCPU: %s\n\nSlot %s", stage_name, hmn_name, cpu_name, slots_names[export_data->slot]); // add title // create title text Text *text_title = Text_CreateText(2, menu_data->canvas_menu); export_data->text_title = text_title; // enable align and kerning text_title->align = 0; text_title->kerning = 1; // scale canvas text_title->trans.X = -23; text_title->trans.Y = -18; text_title->scale.X = MENU_CANVASSCALE * 2; text_title->scale.Y = MENU_CANVASSCALE * 2; text_title->trans.Z = MENU_TEXTZ; Text_AddSubtext(text_title, 0, 0, "Enter File Name"); // create desc text Text *text_desc = Text_CreateText(2, menu_data->canvas_menu); export_data->text_desc = text_desc; // enable align and kerning text_desc->align = 0; text_desc->kerning = 1; // scale canvas text_desc->trans.X = -23; text_desc->trans.Y = 12; text_desc->scale.X = MENU_CANVASSCALE; text_desc->scale.Y = MENU_CANVASSCALE; Text_AddSubtext(text_desc, 0, 0, "A: Select B: Backspace Y: Caps Start: Confirm"); // add description Text_AddSubtext(text_desc, 0, 40, " X: Space L: Cursor left R: Cursor right"); // add description // create filename Text *text_filename = Text_CreateText(2, menu_data->canvas_menu); export_data->text_filename = text_filename; // enable align and kerning text_filename->align = 0; text_filename->kerning = 1; text_filename->use_aspect = 1; GXColor filename_color = {225, 225, 225, 255}; text_filename->color = filename_color; // scale canvas text_filename->trans.X = EXP_FILENAME_X; text_filename->trans.Y = EXP_FILENAME_Y; text_filename->aspect.X = EXP_FILENAME_ASPECTX; text_filename->aspect.Y = EXP_FILENAME_ASPECTY; text_filename->scale.X = MENU_CANVASSCALE * EXP_FILENAME_SIZE; text_filename->scale.Y = MENU_CANVASSCALE * EXP_FILENAME_SIZE; // init filename buffer export_data->filename_buffer[0] = '_'; export_data->filename_buffer[1] = '\0'; Text_AddSubtext(text_filename, 0, 0, export_data->filename_buffer); // add title // init menu variables export_data->menu_index = EXMENU_NAME; export_data->filename_cursor = 0; return; } int Export_EnterNameThink(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; // get pausing players inputs HSD_Pad *pad = PadGet(stc_hmn_controller, PADGET_MASTER); int inputs = pad->rapidFire; int input_down = pad->down; u8 *cursor = export_data->key_cursor; int update_keyboard = 0; int update_filename = 0; char *filename_buffer = export_data->filename_buffer; // first ensure memcard is still inserted s32 memSize, sectorSize; if (CARDProbeEx(export_data->slot, &memSize, §orSize) != CARD_RESULT_READY) goto EXIT; // if left if ((inputs & HSD_BUTTON_LEFT) || (inputs & HSD_BUTTON_DPAD_LEFT)) { if (cursor[0] > 0) { cursor[0]--; } else { cursor[0] = (10 - 1); } update_keyboard = 1; } // if right else if ((inputs & HSD_BUTTON_RIGHT) || (inputs & HSD_BUTTON_DPAD_RIGHT)) { if (cursor[0] < (10 - 1)) { cursor[0]++; } else { cursor[0] = 0; } update_keyboard = 1; } // if up else if ((inputs & HSD_BUTTON_UP) || (inputs & HSD_BUTTON_DPAD_UP)) { if (cursor[1] > 0) { cursor[1]--; } else { cursor[1] = (4 - 1); } update_keyboard = 1; } // if down else if ((inputs & HSD_BUTTON_DOWN) || (inputs & HSD_BUTTON_DPAD_DOWN)) { if (cursor[1] < 4 - 1) { cursor[1]++; } else { cursor[1] = 0; } update_keyboard = 1; } // if A else if ((inputs & HSD_BUTTON_A)) { // check if any remaining characters if (export_data->filename_cursor < 32) { // get correct set of letters char **keyboard_letters = keyboard_rows[export_data->caps_lock]; // add character to buffer filename_buffer[export_data->filename_cursor] = keyboard_letters[cursor[1]][cursor[0]]; // add cursor and terminator filename_buffer[export_data->filename_cursor + 1] = '_'; filename_buffer[export_data->filename_cursor + 2] = '\0'; // inc cursor export_data->filename_cursor++; // update filename update_filename = 1; // remove caps lock export_data->caps_lock = 0; update_keyboard = 1; SFX_PlayCommon(1); } else { SFX_PlayCommon(3); } } // if B else if ((inputs & HSD_BUTTON_B)) { // check if can delete if (export_data->filename_cursor > 0) { // dec cursor export_data->filename_cursor--; // add cursor and terminator filename_buffer[export_data->filename_cursor] = '_'; filename_buffer[export_data->filename_cursor + 1] = '\0'; // update filename update_filename = 1; SFX_PlayCommon(0); } // exit here else if (input_down & HSD_BUTTON_B) { EXIT: Export_EnterNameExit(export_gobj); Export_SelCardInit(export_gobj); SFX_PlayCommon(0); return 0; } } // if Y if ((inputs & HSD_BUTTON_Y)) { // toggle capslock if (export_data->caps_lock == 0) export_data->caps_lock = 1; else export_data->caps_lock = 0; // update keyboard update_keyboard = 1; SFX_PlayCommon(1); } // if X if ((inputs & HSD_BUTTON_X)) { // check if any remaining characters if (export_data->filename_cursor < 32) { // add character to buffer filename_buffer[export_data->filename_cursor] = ' '; // add cursor and terminator filename_buffer[export_data->filename_cursor + 1] = '_'; filename_buffer[export_data->filename_cursor + 2] = '\0'; // inc cursor export_data->filename_cursor++; // update filename update_filename = 1; SFX_PlayCommon(1); } else { OSReport("max characters!\n"); } } // if START if ((inputs & HSD_BUTTON_START)) { // at least 1 character if (export_data->filename_cursor > 0) { Export_ConfirmInit(export_gobj); // play sfx SFX_PlayCommon(1); } else { SFX_PlayCommon(3); } return 0; } // update keyboard if (update_keyboard == 1) { Export_EnterNameUpdateKeyboard(export_gobj); SFX_PlayCommon(2); } // update filename if changed if (update_filename == 1) { Text_SetText(export_data->text_filename, 0, filename_buffer); } return 0; } void Export_EnterNameExit(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; // hide menu jobjs JOBJ_SetFlags(export_data->screenshot_jobj, JOBJ_HIDDEN); JOBJ_SetFlags(export_data->textbox_jobj, JOBJ_HIDDEN); Text_Destroy(export_data->text_title); Text_Destroy(export_data->text_desc); Text_Destroy(export_data->text_keyboard); Text_Destroy(export_data->text_filename); Text_Destroy(export_data->text_filedetails); } void Export_ConfirmInit(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; MenuData *menu_data = event_vars->menu_gobj->userdata; // create gobj GOBJ *confirm_gobj = GObj_Create(0, 0, 0); export_data->confirm_gobj = confirm_gobj; // load menu joint JOBJ *confirm_jobj = JOBJ_LoadJoint(stc_lab_data->export_popup); GObj_AddObject(confirm_gobj, 3, confirm_jobj); // add to gobj GObj_AddGXLink(confirm_gobj, GXLink_Common, GXLINK_MENUMODEL, GXPRI_POPUPMODEL); // add gx link // create text Text *confirm_text = Text_CreateText(2, menu_data->canvas_popup); export_data->confirm_text = confirm_text; // enable align and kerning confirm_text->align = 1; confirm_text->kerning = 1; // scale canvas confirm_text->trans.X = 0; confirm_text->trans.Y = 0; confirm_text->scale.X = MENU_CANVASSCALE; confirm_text->scale.Y = MENU_CANVASSCALE; confirm_text->trans.Z = MENU_TEXTZ; Text_AddSubtext(confirm_text, 0, -40, "Save File to Slot %s?", slots_names[export_data->slot]); int yes_subtext = Text_AddSubtext(confirm_text, -60, 20, "Yes"); GXColor yellow = {201, 178, 0, 255}; Text_SetColor(confirm_text, yes_subtext, &yellow); Text_AddSubtext(confirm_text, 60, 20, "No"); export_data->menu_index = EXMENU_CONFIRM; export_data->confirm_state = EXPOP_CONFIRM; export_data->confirm_cursor = 0; return 0; } int Export_ConfirmThink(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; // get pausing players inputs HSD_Pad *pad = PadGet(stc_hmn_controller, PADGET_MASTER); int inputs = pad->down; // if unplugged exit s32 memSize, sectorSize; if (CARDProbeEx(export_data->slot, &memSize, §orSize) != CARD_RESULT_READY) { Export_ConfirmExit(export_gobj); Export_EnterNameExit(export_gobj); // play sfx SFX_PlayCommon(0); } switch (export_data->confirm_state) { case (EXPOP_CONFIRM): { int update_cursor = 0; // if left if ((inputs & HSD_BUTTON_LEFT) || (inputs & HSD_BUTTON_DPAD_LEFT)) { if (export_data->confirm_cursor > 0) { export_data->confirm_cursor--; update_cursor = 1; } } // if right else if ((inputs & HSD_BUTTON_RIGHT) || (inputs & HSD_BUTTON_DPAD_RIGHT)) { if (export_data->confirm_cursor < 1) { export_data->confirm_cursor++; update_cursor = 1; } } // if b else if ((inputs & HSD_BUTTON_B)) { Export_ConfirmExit(export_gobj); // play sfx SFX_PlayCommon(0); return 0; } // if a else if ((inputs & HSD_BUTTON_A) || (inputs & HSD_BUTTON_START)) { // begin save if (export_data->confirm_cursor == 0) { MenuData *menu_data = event_vars->menu_gobj->userdata; // free current text Text_Destroy(export_data->confirm_text); // create text Text *confirm_text = Text_CreateText(2, menu_data->canvas_popup); export_data->confirm_text = confirm_text; // enable align and kerning confirm_text->align = 1; confirm_text->kerning = 1; // scale canvas confirm_text->trans.X = 0; confirm_text->trans.Y = 0; confirm_text->scale.X = MENU_CANVASSCALE; confirm_text->scale.Y = MENU_CANVASSCALE; confirm_text->trans.Z = MENU_TEXTZ; Text_AddSubtext(confirm_text, 0, -20, ""); export_data->confirm_state = EXPOP_SAVE; export_status = EXSTAT_REQSAVE; // play sfx SFX_PlayCommon(1); return 0; } // go back to keyboard menu else { Export_ConfirmExit(export_gobj); // play sfx SFX_PlayCommon(0); return 0; } } if (update_cursor == 1) { for (int i = 0; i < 2; i++) { static GXColor white = {255, 255, 255, 255}; static GXColor yellow = {201, 178, 0, 255}; GXColor *color; // highlight cursor only if (export_data->confirm_cursor == i) color = &yellow; else color = &white; Text_SetColor(export_data->confirm_text, i + 1, color); } SFX_PlayCommon(2); } break; } case (EXPOP_SAVE): { // wait for save to finish if (Export_Process(export_gobj) == 1) { Export_ConfirmExit(export_gobj); Export_Destroy(export_gobj); // play sfx SFX_PlayCommon(1); return 0; } break; } } return 0; } void Export_ConfirmExit(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; GObj_Destroy(export_data->confirm_gobj); Text_Destroy(export_data->confirm_text); export_data->menu_index = EXMENU_NAME; } void Export_EnterNameUpdateKeyboard(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; Text *text_keyboard = export_data->text_keyboard; u8 *cursor = export_data->key_cursor; // get correct set of letters char **keyboard_letters = keyboard_rows[export_data->caps_lock]; // iterate through rows for (int i = 0; i < 4; i++) { // iterate through columns for (int j = 0; j < 10; j++) { int this_subtext = (i * 10) + j; // update letter text char letter[2]; letter[0] = keyboard_letters[i][j]; letter[1] = '\0'; Text_SetText(text_keyboard, this_subtext, &letter); // update letter color static GXColor white = {255, 255, 255, 255}; static GXColor yellow = {201, 178, 0, 255}; GXColor *color; // check for cursor if ((cursor[0] == j) && (cursor[1] == i)) color = &yellow; else color = &white; Text_SetColor(text_keyboard, this_subtext, color); } } return; } int Export_Process(GOBJ *export_gobj) { ExportData *export_data = export_gobj->userdata; Text *text = export_data->confirm_text; int finished = 0; // if snapshot is processing, dont update switch (export_status) { case (EXSTAT_REQSAVE): { int slot = export_data->slot; save_pre_tick = OSGetTick(); // create filename string ExportHeader *header = stc_transfer_buf; char filename[32]; sprintf(filename, tm_filename, header->metadata.month, header->metadata.day, header->metadata.year, header->metadata.hour, header->metadata.minute, header->metadata.second); // generate filename based on date, time, fighters, and stage // save file name to metadata memcpy(&header->metadata.filename, export_data->filename_buffer, export_data->filename_cursor); // check if file exists and delete it s32 memSize, sectorSize; if (CARDProbeEx(slot, &memSize, §orSize) == CARD_RESULT_READY) { // mount card stc_memcard_work->is_done = 0; if (CARDMountAsync(slot, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY) { // check card Memcard_Wait(); stc_memcard_work->is_done = 0; if (CARDCheckAsync(slot, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); // get free blocks s32 byteNotUsed, filesNotUsed; if (CARDFreeBlocks(slot, &byteNotUsed, &filesNotUsed) == CARD_RESULT_READY) { // search for file with this name for (int i = 0; i < CARD_MAX_FILE; i++) { CARDStat card_stat; if (CARDGetStatus(slot, i, &card_stat) == CARD_RESULT_READY) { // check company code if (strncmp(os_info->company, card_stat.company, sizeof(os_info->company)) == 0) { // check game name if (strncmp(os_info->gameName, card_stat.gameName, sizeof(os_info->gameName)) == 0) { // check file name if (strncmp(&filename, card_stat.fileName, sizeof(filename)) == 0) { // delete CARDDeleteAsync(slot, &filename, Memcard_RemovedCallback); stc_memcard_work->is_done = 0; Memcard_Wait(); } } } } } } } CARDUnmount(slot); stc_memcard_work->is_done = 0; } } // setup save memcpy(stc_memcard_info->file_name, &stc_save_name, sizeof(stc_save_name)); memset(stc_memcard_info->file_desc, '\0', 32); // fill with spaces memcpy(stc_memcard_info->file_desc, export_data->filename_buffer, export_data->filename_cursor); // copy inputted name memcard_save.data = stc_transfer_buf; memcard_save.x4 = 3; memcard_save.size = stc_transfer_buf_size; memcard_save.xc = -1; Memcard_CreateSnapshot(slot, &filename, &memcard_save, stc_memcard_unk, stc_memcard_info->file_name, stc_lab_data->save_banner, stc_lab_data->save_icon, 0); // change status export_status = EXSTAT_SAVEWAIT; OSReport("now saving...\n"); break; } case (EXSTAT_SAVEWAIT): { // wait to finish writing if (Memcard_CheckStatus() != 11) { // change state export_status = EXSTAT_DONE; } else { OSReport("status %d // progress %d/%d\n", *stc_memcard_write_status, *stc_memcard_block_curr, *stc_memcard_block_last); if (*stc_memcard_write_status == 6) { Text_SetText(text, 0, "Writing Data..."); } else { Text_SetText(text, 0, "Creating File"); } } break; } case (EXSTAT_DONE): { export_status = EXSTAT_NONE; finished = 1; Text_Destroy(text); // done saving, output time int save_post_tick = OSGetTick(); int save_time = OSTicksToMilliseconds(save_post_tick - save_pre_tick); OSReport("wrote save in %dms\n", save_time); break; } } return finished; } int Export_Compress(u8 *dest, u8 *source, u32 size) { int pre_tick = OSGetTick(); int compress_size = lz77_compress(source, size, dest, 8); int post_tick = OSGetTick(); int time_dif = OSTicksToMilliseconds(post_tick - pre_tick); OSReport("compressed %d bytes to %d bytes (%.2fx) in %dms\n", size, compress_size, ((float)size / (float)compress_size), time_dif); return compress_size; } // Init Function void Event_Init(GOBJ *gobj) { LCancelData *eventData = gobj->userdata; EventDesc *eventInfo = eventData->eventInfo; GOBJ *hmn = Fighter_GetGObj(0); FighterData *hmn_data = hmn->userdata; GOBJ *cpu = Fighter_GetGObj(1); FighterData *cpu_data = cpu->userdata; // theres got to be a better way to do this... event_vars = *event_vars_ptr; // get this events assets stc_lab_data = File_GetSymbol(event_vars->event_archive, "labData"); // Init Info Display InfoDisplay_Init(); // Init DIDraw DIDraw_Init(); // Init Recording Record_Init(); // Init Input Display Inputs_Init(); // store hsd_update functions HSD_Update *hsd_update = HSD_UPDATE; hsd_update->checkPause = Update_CheckPause; hsd_update->checkAdvance = Update_CheckAdvance; // determine cpu controller stc_hmn_controller = Fighter_GetControllerPort(hmn_data->ply); u8 cpu_controller = 1; if (stc_hmn_controller != 0) cpu_controller = 0; stc_cpu_controller = cpu_controller; // set CPU AI to no_act 15 cpu_data->cpu.ai = 0; // check to immediately load recording if (*onload_fileno != -1) { Record_MemcardLoad(*onload_slot, *onload_fileno); } return; } // Update Function void Event_Update() { // update DI draw DIDraw_Update(); // update info display InfoDisplay_Think(infodisp_gobj); // update advanced cam Update_Camera(); // Check for savestates Savestates_Update(); } // Think Function void Event_Think(GOBJ *event) { LCancelData *eventData = event->userdata; // get fighter data GOBJ *hmn = Fighter_GetGObj(0); FighterData *hmn_data = hmn->userdata; GOBJ *cpu = Fighter_GetGObj(1); FighterData *cpu_data = cpu->userdata; HSD_Pad *pad = PadGet(hmn_data->player_controller_number, PADGET_ENGINE); // update menu's percent LabOptions_General[OPTGEN_HMNPCNT].option_val = hmn_data->dmg.percent; LabOptions_CPU[OPTCPU_PCNT].option_val = cpu_data->dmg.percent; // reset stale moves if (LabOptions_General[OPTGEN_STALE].option_val == 0) { for (int i = 0; i < 6; i++) { // check if fighter exists GOBJ *fighter = Fighter_GetGObj(i); if (fighter != 0) { // reset stale move table int *staleMoveTable = Fighter_GetStaleMoveTable(i); memset(staleMoveTable, 0, 0x2C); } } } // apply intangibility if (LabOptions_CPU[OPTCPU_INTANG].option_val == 1) { cpu_data->flags.no_reaction_always = 1; cpu_data->flags.nudge_disable = 1; cpu_data->grab.vuln = 0x1FF; cpu_data->dmg.percent = 0; Fighter_SetHUDDamage(cpu_data->ply, 0); // if new state, apply colanim if (cpu_data->TM.state_frame <= 1) { Fighter_ApplyOverlay(cpu_data, INTANG_COLANIM, 0); } } else { cpu_data->flags.no_reaction_always = 0; cpu_data->flags.nudge_disable = 0; } // Move CPU if (pad->down == PAD_BUTTON_DPAD_DOWN) { // ensure CPU is not dead if (cpu_data->flags.dead == 0) { // ensure player is grounded int isGround = 0; if (hmn_data->phys.air_state == 0) { // check for ground in front of player Vec3 coll_pos; int line_index; int line_kind; Vec3 line_unk; float fromX = (hmn_data->phys.pos.X) + (hmn_data->facing_direction * 16); float toX = fromX; float fromY = (hmn_data->phys.pos.Y + 5); float toY = fromY - 10; isGround = GrColl_RaycastGround(&coll_pos, &line_index, &line_kind, &line_unk, -1, -1, -1, 0, fromX, fromY, toX, toY, 0); if (isGround == 1) { // do this for every subfighter (thanks for complicated code ice climbers) int is_moved = 0; for (int i = 0; i < 2; i++) { GOBJ *this_fighter = Fighter_GetSubcharGObj(cpu_data->ply, i); if (this_fighter != 0) { FighterData *this_fighter_data = this_fighter->userdata; if ((this_fighter_data->flags.sleep == 0) && (this_fighter_data->flags.dead == 0)) { is_moved = 1; // place CPU here this_fighter_data->phys.pos = coll_pos; this_fighter_data->coll_data.ground_index = line_index; // facing player this_fighter_data->facing_direction = hmn_data->facing_direction * -1; // set grounded this_fighter_data->phys.air_state = 0; //Fighter_SetGrounded(this_fighter); // kill velocity Fighter_KillAllVelocity(this_fighter); // enter wait Fighter_EnterWait(this_fighter); // update ECB this_fighter_data->coll_data.topN_Curr = this_fighter_data->phys.pos; // move current ECB location to new position Coll_ECBCurrToPrev(&this_fighter_data->coll_data); this_fighter_data->cb.Coll(this_fighter); // update camera box Fighter_UpdateCameraBox(this_fighter); this_fighter_data->cameraBox->boundleft_curr = this_fighter_data->cameraBox->boundleft_proj; this_fighter_data->cameraBox->boundright_curr = this_fighter_data->cameraBox->boundright_proj; // init CPU logic (for nana's popo position history...) int cpu_kind = Fighter_GetCPUKind(this_fighter_data->ply); int cpu_level = Fighter_GetCPULevel(this_fighter_data->ply); Fighter_CPUInitialize(this_fighter_data, cpu_kind, cpu_level, 0); // place subfighter in the Z axis if (this_fighter_data->flags.ms == 1) { ftCommonData *ft_common = *stc_ftcommon; this_fighter_data->phys.pos.Z = ft_common->ms_zjostle_max * -1; } } } } if (is_moved == 1) { // reset CPU think variables eventData->cpu_state = CPUSTATE_START; eventData->cpu_hitshield = 0; eventData->cpu_hitnum = 0; eventData->cpu_sincehit = 0; eventData->cpu_hitshield = 0; eventData->cpu_lasthit = -1; eventData->cpu_lastshieldstun = -1; eventData->cpu_hitkind = -1; eventData->cpu_hitshieldnum = 0; eventData->cpu_isactionable = 0; // savestate event_vars->Savestate_Save(event_vars->savestate); } } } // play SFX if (isGround == 0) { SFX_PlayCommon(3); } else { SFX_Play(221); } } } // Adjust control of fighters switch (LabOptions_Record[OPTREC_CPUMODE].option_val) { case RECMODE_OFF: { // human is human hmn_data->player_controller_number = stc_hmn_controller; // cpu is cpu Fighter_SetSlotType(cpu_data->ply, 1); cpu_data->player_controller_number = stc_cpu_controller; break; } case RECMODE_PLAY: { // human is human hmn_data->player_controller_number = stc_hmn_controller; // cpu is hmn Fighter_SetSlotType(cpu_data->ply, 0); cpu_data->player_controller_number = stc_cpu_controller; break; } case RECMODE_CTRL: case RECMODE_REC: { // human is human hmn_data->player_controller_number = stc_cpu_controller; // cpu is hmn Fighter_SetSlotType(cpu_data->ply, 0); cpu_data->player_controller_number = stc_hmn_controller; break; } } // CPU Think if not using recording if ((LabOptions_Record[OPTREC_CPUMODE].option_val == 0) && (LabOptions_Record[OPTREC_HMNMODE].option_val == 0)) LCancel_CPUThink(event, hmn, cpu); return; } // Initial Menu static EventMenu *Event_Menu = &LabMenu_Main; ================================================ FILE: patch/events/lab/source/lab.h ================================================ #include "../../../../MexTK/mex.h" #include "../../../tmdata/source/events.h" // Labbing event // Custom TDI definitions #define TDI_HITNUM 10 #define TDI_DISPNUM 4 // menu model #define TDIMENU_SCALE 1 #define TDIMENU_X 0 #define TDIMENU_Y 0 #define TDIMENU_Z 0 #define TDIMENU_WIDTH 55 / TDIMENU_SCALE #define TDIMENU_HEIGHT 40 / TDIMENU_SCALE // menu text object #define TDITEXT_CANVASSCALE 0.05 #define TDITEXT_TEXTSCALE 1 #define TDITEXT_TEXTZ 0 // recording #define REC_VERS 1 /* Recording Version History: v0 = 3.0 Alpha 1-3. v1 = 3.0 Alpha 4. First version with importing UI. Added filename and match settings to metadata, menu settings and adjusted the playerblock and grab struct for the fighters. v2 = not released */ #define GXPRI_RECJOINT 80 #define REC_GXLINK 18 #define GXPRI_RECTEXT GXPRI_RECJOINT + 1 // cobj #define RECCAM_COBJGXLINK (1 << REC_GXLINK) #define RECCAM_GXPRI 8 // params #define REC_LENGTH (1 * 60 * 60) #define REC_SLOTS 6 #define REC_SEEKJOINT 7 #define REC_LEFTBOUNDJOINT 5 #define REC_RIGHTBOUNDJOINT 6 #define REC_LEFTTEXTJOINT 2 #define REC_RIGHTTEXTJOINT 3 // export enum export_status { EXSTAT_NONE, EXSTAT_REQSAVE, EXSTAT_SAVEWAIT, EXSTAT_DONE, }; enum export_menuindex { EXMENU_SELCARD, EXMENU_NAME, EXMENU_CONFIRM, }; enum export_popup { EXPOP_CONFIRM, EXPOP_SAVE, }; #define EXP_MEMCARDAJOBJ 9 #define EXP_MEMCARDBJOBJ 11 #define EXP_TEXTBOXJOBJ 12 #define EXP_SCREENSHOTJOBJ 18 #define EXP_KEYBOARD_X 0 #define EXP_KEYBOARD_Y 3.5 #define EXP_KEYBOARD_SIZE 1 #define EXP_FILEDETAILS_X -8 #define EXP_FILEDETAILS_Y -11.7 #define EXP_FILEDETAILS_SIZE 0.7 #define EXP_FILENAME_X -7 #define EXP_FILENAME_Y -4.8 #define EXP_FILENAME_ASPECTX 560 #define EXP_FILENAME_ASPECTY 100 #define EXP_FILENAME_SIZE 1 #define EXP_SCREENSHOT_WIDTH (640) #define EXP_SCREENSHOT_HEIGHT (480) #define RESIZE_MULT (0.15) #define RESIZE_WIDTH (EXP_SCREENSHOT_WIDTH * RESIZE_MULT) #define RESIZE_HEIGHT (EXP_SCREENSHOT_HEIGHT * RESIZE_MULT) // input display typedef struct ButtonLookup { u8 jobj; u8 dobj; } ButtonLookup; typedef enum buttons_enum { BTN_A, BTN_B, BTN_X, BTN_Y, BTN_START, BTN_DPADUP, BTN_DPADRIGHT, BTN_DPADLEFT, BTN_DPADDOWN, BTN_L, BTN_R, BTN_Z, BTN_NUM, } buttons_enum; static ButtonLookup button_lookup[] = { {1, 0}, // A {2, 0}, // B {3, 0}, // X {4, 0}, // Y {5, 0}, // Start {6, 1}, // Dpad Up {6, 2}, // Dpad Right {6, 3}, // Dpad Left {6, 4}, // Dpad Down {11, 0}, // L {12, 0}, // R {13, 0}, // Z }; static GXColor button_colors[] = { {50, 180, 50, 255}, // A {255, 50, 50, 255}, // B {127, 127, 127, 255}, // X {127, 127, 127, 255}, // Y {192, 192, 192, 255}, // Start {192, 192, 192, 255}, // Dpad Up {192, 192, 192, 255}, // Dpad Right {192, 192, 192, 255}, // Dpad Left {192, 192, 192, 255}, // Dpad Down {127, 127, 127, 255}, // L {127, 127, 127, 255}, // R {0, 0, 255, 255}, // Z }; static int button_bits[] = { HSD_BUTTON_A, // A HSD_BUTTON_B, // B HSD_BUTTON_X, // X HSD_BUTTON_Y, // Y HSD_BUTTON_START, // Start HSD_BUTTON_DPAD_UP, // Dpad Up HSD_BUTTON_DPAD_RIGHT, // Dpad Right HSD_BUTTON_DPAD_LEFT, // Dpad Left HSD_BUTTON_DPAD_DOWN, // Dpad Down HSD_TRIGGER_L, // L HSD_TRIGGER_R, // R HSD_TRIGGER_Z, // Z }; // GX #define INPUT_GXLINK 12 #define INPUT_GXPRI 80 // params #define INPUT_SHELL_JOBJ 14 #define INPUT_SHELL_DOBJ 0 #define INPUT_COLOR_PRESSED \ { \ 255, 255, 255, 255 \ } typedef struct Arch_ImportData { JOBJDesc *import_button; JOBJDesc *import_menu; COBJDesc *import_cam; JOBJDesc *import_popup; } Arch_ImportData; typedef struct Arch_LabData { JOBJDesc *stick; JOBJDesc *cstick; void *save_icon; void *save_banner; JOBJDesc *controller; JOBJDesc *export_menu; JOBJDesc *export_popup; } Arch_LabData; typedef struct LCancelData { EventDesc *eventInfo; u8 cpu_state; u8 cpu_hitshield; u8 cpu_hitnum; u8 cpu_sdidir; u8 cpu_sincehit; s16 cpu_lasthit; s16 cpu_lastshieldstun; // last move instance of the opponent in shield stun. used to tell how many times the shield was hit s8 cpu_hitkind; // how the CPU was hit, damage or shield u8 cpu_hitshieldnum; // times the CPUs shield was hit u8 cpu_isactionable; // flag that indicates if a cpu has become actionable u8 cpu_groundstate; // indicates if the player was touching ground upon being actionable s32 timer; u8 cpu_isthrown; // bool for if the cpu is being thrown GOBJ *rec_gobj; u8 hmn_controller; u8 cpu_controller; } LCancelData; typedef struct InfoDisplayData { JOBJ *menuModel; JOBJ *botLeftEdge; JOBJ *botRightEdge; Text *text; } InfoDisplayData; typedef struct DIDraw { int num[2]; // number of vertices Vec2 *vertices[2]; // pointer to vertex to draw GXColor color; // color of this vertex } DIDraw; typedef struct DIDrawCalculate { Vec2 pos; // position of vertices int envFlags; // environment flags float ECBTopY; // used for determining middle of body float ECBLeftY; // used for determining middle of body float kb_Y; // used to determine ceiling KOs } DIDrawCalculate; typedef struct TDIData { JOBJ *stick_curr[2]; JOBJ *stick_prev[6][2]; Text *text_curr; } TDIData; typedef struct CPUAction { u16 state; // state to perform this action. -1 for last u8 frameLow; // first possible frame to perform this action u8 frameHi; // last possible frame to perfrom this action s8 stickX; // left stick X value s8 stickY; // left stick Y value s8 cstickX; // c stick X value s8 cstickY; // c stick Y value int input; // button to input unsigned char isLast : 1; // flag to indicate this was the final input unsigned char stickDir : 3; // 0 = none, 1 = towards opponent, 2 = away from opponent, 3 = forward, 4 = backward } CPUAction; typedef struct RecInputs { unsigned char btn_dpadup : 1; unsigned char btn_a : 1; unsigned char btn_b : 1; unsigned char btn_x : 1; unsigned char btn_y : 1; unsigned char btn_L : 1; unsigned char btn_R : 1; unsigned char btn_Z : 1; s8 stickX; s8 stickY; s8 substickX; s8 substickY; u8 trigger; } RecInputs; typedef struct RecInputData { int start_frame; // the frame these inputs start on int num; RecInputs inputs[REC_LENGTH] } RecInputData; typedef struct RecData { int timer; // this is updated at runtime to know which frames inputs to use. int hmn_rndm_slot; RecInputData *hmn_inputs[REC_SLOTS]; int cpu_rndm_slot; RecInputData *cpu_inputs[REC_SLOTS]; JOBJ *seek_jobj; Text *text; float seek_left; float seek_right; } RecData; typedef struct RecordingSave { MatchInit match_data; // this will point to a struct containing match info Savestate savestate; RecInputData hmn_inputs[REC_SLOTS]; RecInputData cpu_inputs[REC_SLOTS]; } RecordingSave; typedef struct InputData { JOBJ *controller_joint[4]; Vec2 ltrig_origin; Vec2 rtrig_origin; } InputData; typedef struct ExportData { u16 menu_index; u16 menu_state; JOBJ *memcard_jobj[2]; JOBJ *screenshot_jobj; JOBJ *textbox_jobj; RGB565 *scaled_image; Text *text_title; Text *text_desc; Text *text_misc; int slot; u8 is_inserted[2]; int free_blocks[2]; int free_files[2]; Text *text_keyboard; Text *text_filename; Text *text_filedetails; u8 key_cursor[2]; u8 filename_cursor; u8 caps_lock; char *filename_buffer; GOBJ *confirm_gobj; Text *confirm_text; u8 confirm_cursor; u8 confirm_state; int hmn_id; int cpu_id; int stage_id; } ExportData; typedef struct ExportMenuSettings { u8 hmn_mode; u8 hmn_slot; u8 cpu_mode; u8 cpu_slot; u8 loop_inputs; u8 auto_restore; } ExportMenuSettings; typedef struct ExportHeader { struct rec_metadata // metadata { u16 version; u16 image_width; u16 image_height; u16 image_fmt; u8 hmn; u8 hmn_costume; u8 cpu; u8 cpu_costume; u16 stage_external; // instance of the stage u16 stage_internal; // unique stage u8 month; u8 day; u16 year; u8 hour; u8 minute; u8 second; char filename[32]; } metadata; struct // lookup { int ofst_screenshot; int ofst_recording; int ofst_menusettings; // to-do, add menu data offset } lookup; } ExportHeader; void Event_Init(GOBJ *gobj); void Event_Update(); void Event_Think(GOBJ *event); void Button_Think(GOBJ *button_gobj); void Lab_ChangePlayerPercent(GOBJ *menu_gobj, int value); void Lab_ChangeFrameAdvance(GOBJ *menu_gobj, int value); void Lab_ChangeCPUPercent(GOBJ *menu_gobj, int value); void Lab_ChangeCPUIntang(GOBJ *menu_gobj, int value); void Lab_ChangeModelDisplay(GOBJ *menu_gobj, int value); void Lab_ChangeHitDisplay(GOBJ *menu_gobj, int value); void Lab_ChangeEnvCollDisplay(GOBJ *menu_gobj, int value); void Lab_ChangeCamMode(GOBJ *menu_gobj, int value); void Lab_ChangeInfoPreset(GOBJ *menu_gobj, int value); void Lab_ChangeInfoRow(GOBJ *menu_gobj, int value); void Lab_ChangeInfoSizePos(GOBJ *menu_gobj, int value); void Lab_ChangeInfoPlayer(GOBJ *menu_gobj, int value); void Lab_ChangeHUD(GOBJ *menu_gobj, int value); void Lab_SelectCustomTDI(GOBJ *menu_gobj); void DIDraw_GX(); void Record_ChangeHMNSlot(GOBJ *menu_gobj, int value); void Record_ChangeCPUSlot(GOBJ *menu_gobj, int value); void Record_ChangeHMNMode(GOBJ *menu_gobj, int value); void Record_ChangeCPUMode(GOBJ *menu_gobj, int value); void Record_ChangeSlot(GOBJ *menu_gobj, int value); void Record_MemcardSave(GOBJ *menu_gobj); void Record_MemcardLoad(int slot, int file_no); void Record_InitState(GOBJ *menu_gobj); void Record_RestoreState(GOBJ *menu_gobj); void Record_CObjThink(GOBJ *gobj); void Record_GX(GOBJ *gobj, int pass); void Record_Think(GOBJ *rec_gobj); void Record_Update(int ply, RecInputData *inputs, int rec_mode); int Record_MenuThink(GOBJ *menu_gobj); int Record_OptimizedSave(Savestate *savestate); int Record_OptimizedLoad(Savestate *savestate); int Record_GetRandomSlot(RecInputData **input_data); int Record_GOBJToID(GOBJ *gobj); int Record_FtDataToID(FighterData *fighter_data); int Record_BoneToID(FighterData *fighter_data, JOBJ *bone); GOBJ *Record_IDToGOBJ(int id); FighterData *Record_IDToFtData(int id); JOBJ *Record_IDToBone(FighterData *fighter_data, int id); void Snap_CObjThink(GOBJ *gobj); void Record_StartExport(GOBJ *menu_gobj); void Export_Init(GOBJ *menu_gobj); int Export_Think(GOBJ *export_gobj); void Export_Destroy(GOBJ *export_gobj); void Export_SelCardInit(GOBJ *export_gobj); int Export_SelCardThink(GOBJ *export_gobj); int Export_Compress(u8 *dest, u8 *source, u32 size); void CustomTDI_Update(GOBJ *gobj); void CustomTDI_Destroy(GOBJ *gobj); void Lab_Exit(int value); void InfoDisplay_Think(GOBJ *gobj); void InfoDisplay_GX(GOBJ *gobj, int pass); static EventOption LabOptions_Main[]; static EventOption LabOptions_General[]; static EventOption LabOptions_InfoDisplay[]; static EventMenu LabMenu_General; static EventMenu LabMenu_InfoDisplay; static EventMenu LabMenu_CPU; static EventMenu LabMenu_Record; // info display #define GXPRI_INFDISP GXPRI_MENUMODEL - 2 #define GXLINK_INFDISP 12 #define GXPRI_INFDISPTEXT GXPRI_INFDISP + 1 #define GXLINK_INFDISPTEXT 12 // info display jobj #define INFDISP_WIDTH 6 #define INFDISP_SCALE 4 #define INFDISP_X -26.5 #define INFDISP_Y 21.5 #define INFDISP_Z 0.01 #define INFDISP_YOFFSET -2.5 #define INFDISP_BOTY -0.5 #define INFDISP_BOTYOFFSET -0.30 // info display text #define INFDISPTEXT_SCALE 0.04 #define INFDISPTEXT_X 1 #define INFDISPTEXT_Y 1 #define INFDISPTEXT_YOFFSET 30 // General Options enum gen_option { OPTGEN_FRAME, OPTGEN_FRAMEBTN, OPTGEN_HMNPCNT, OPTGEN_MODEL, OPTGEN_HIT, OPTGEN_COLL, OPTGEN_CAM, OPTGEN_HUD, OPTGEN_DI, OPTGEN_INPUT, OPTGEN_STALE, }; // CPU Options enum cpu_option { OPTCPU_PCNT, OPTCPU_BEHAVE, OPTCPU_SHIELD, OPTCPU_INTANG, OPTCPU_SDIFREQ, OPTCPU_SDIDIR, OPTCPU_TDI, OPTCPU_CUSTOMTDI, OPTCPU_TECH, OPTCPU_GETUP, OPTCPU_MASH, //OPTCPU_RESET, OPTCPU_CTRGRND, OPTCPU_CTRAIR, OPTCPU_CTRSHIELD, OPTCPU_CTRFRAMES, OPTCPU_CTRHITS, OPTCPU_SHIELDHITS, }; // SDI Freq enum sdi_freq { SDIFREQ_NONE, SDIFREQ_LOW, SDIFREQ_MED, SDIFREQ_HIGH, }; // SDI Freq enum sdi_dir { SDIDIR_RANDOM, SDIDIR_AWAY, SDIDIR_TOWARD, }; // Recording Options #define OPTREC_SAVE 0 #define OPTREC_LOAD 1 #define OPTREC_HMNMODE 2 #define OPTREC_HMNSLOT 3 #define OPTREC_CPUMODE 4 #define OPTREC_CPUSLOT 5 #define OPTREC_LOOP 6 #define OPTREC_AUTOLOAD 7 // Recording Modes #define RECMODE_OFF 0 #define RECMODE_CTRL 1 #define RECMODE_REC 2 #define RECMODE_PLAY 3 // Info Display Options //#define OPTINF_TOGGLE 0 #define OPTINF_PLAYER 0 #define OPTINF_SIZE 1 #define OPTINF_PRESET 2 #define OPTINF_ROW1 3 // Info Display Rows enum infdisp_rows { INFDISPROW_NONE, INFDISPROW_POS, INFDISPROW_STATE, INFDISPROW_FRAME, INFDISPROW_SELFVEL, INFDISPROW_KBVEL, INFDISPROW_TOTALVEL, INFDISPROW_ENGLSTICK, INFDISPROW_SYSLSTICK, INFDISPROW_ENGCSTICK, INFDISPROW_SYSCSTICK, INFDISPROW_ENGTRIGGER, INFDISPROW_SYSTRIGGER, INFDISPROW_LEDGECOOLDOWN, INFDISPROW_INTANGREMAIN, INFDISPROW_HITSTOP, INFDISPROW_HITSTUN, INFDISPROW_SHIELDHEALTH, INFDISPROW_SHIELDSTUN, INFDISPROW_GRIP, INFDISPROW_ECBLOCK, INFDISPROW_ECBBOT, INFDISPROW_JUMPS, INFDISPROW_WALLJUMPS, INFDISPROW_JAB, INFDISPROW_LINE, INFDISPROW_BLASTLR, INFDISPROW_BLASTUD, }; // CPU States enum cpu_state { CPUSTATE_START, CPUSTATE_GRABBED, CPUSTATE_SDI, CPUSTATE_TDI, CPUSTATE_TECH, CPUSTATE_GETUP, CPUSTATE_COUNTER, CPUSTATE_RECOVER, }; // Grab Escape Options enum cpu_mash { CPUMASH_NONE, CPUMASH_MED, CPUMASH_HIGH, CPUMASH_PERFECT, }; #define INTANG_COLANIM 10 // Grab Escape RNG Def #define CPUMASHRNG_MED 35 #define CPUMASHRNG_HIGH 55 // Behavior Definitions #define CPUBEHAVE_STAND 0 #define CPUBEHAVE_SHIELD 1 #define CPUBEHAVE_CROUCH 2 #define CPUBEHAVE_JUMP 3 // SDI Definitions #define CPUSDI_RANDOM 0 #define CPUSDI_NONE 1 // TDI Definitions #define CPUTDI_RANDOM 0 #define CPUTDI_IN 1 #define CPUTDI_OUT 2 #define CPUTDI_FLOORHUG 3 #define CPUTDI_CUSTOM 4 #define CPUTDI_NONE 5 #define CPUTDI_NUM 6 // Tech Definitions #define CPUTECH_RANDOM 0 #define CPUTECH_NEUTRAL 1 #define CPUTECH_AWAY 2 #define CPUTECH_TOWARDS 3 #define CPUTECH_NONE 4 // Getup Definitions #define CPUGETUP_RANDOM 0 #define CPUGETUP_STAND 1 #define CPUGETUP_AWAY 2 #define CPUGETUP_TOWARD 3 #define CPUGETUP_ATTACK 4 // Stick Direction Definitions enum STICKDIR { STCKDIR_NONE, STCKDIR_TOWARD, STCKDIR_AWAY, STCKDIR_FRONT, STCKDIR_BACK, STICKDIR_RDM, }; // Hit kind defintions #define HITKIND_DAMAGE 0 #define HITKIND_SHIELD 1 // DI Draw Constants #define DI_MaxColl 50 static char *stage_names[] = { "", "", "Princess Peach's Castle", "Rainbow Cruise", "Kongo Jungle", "Jungle Japes", "Great Bay", "Hyrule Temple", "Brinstar", "Brinstar Depths", "Yoshi's Story", "Yoshi's Island", "Fountain of Dreams", "Green Greens", "Corneria", "Venom", "Pokemon Stadium", "Poke Floats", "Mute City", "Big Blue", "Onett", "Fourside", "Icicle Mountain", "", "Mushroom Kingdom", "Mushroom Kingdom II", "", "Flat Zone", "Dream Land", "Yoshi's Island (64)", "Kongo Jungle (64)", "", "", "", "", "", "Battlefield", "Final Destination", }; // CSS Import s8 *onload_fileno = R13 + (-0x4670); s8 *onload_slot = R13 + (-0x466F); #define IMPORT_FILESPERPAGE 10 typedef enum ImportMenuStates { IMP_SELCARD, IMP_SELFILE, IMP_CONFIRM, }; typedef enum ImportConfirmKind { CFRM_LOAD, CFRM_OLD, CFRM_NEW, CFRM_DEL, CFRM_ERR, }; typedef struct FileInfo { char **file_name; // pointer to file name array int file_size; // number of files on card int file_no; // index of this file on the card } FileInfo; typedef struct ImportData { GOBJ *menu_gobj; u16 canvas; u8 menu_state; u8 cursor; u8 memcard_inserted[2]; // memcard inserted bools u16 memcard_free_files[2]; // free files on this card u16 memcard_free_blocks[2]; // free blocks on this card u16 memcard_slot; // selected slot JOBJ *memcard_jobj[2]; JOBJ *screenshot_jobj; JOBJ *scroll_jobj; JOBJ *scroll_top; JOBJ *scroll_bot; Text *title_text; Text *desc_text; Text *option_text; Text *filename_text; Text *fileinfo_text; int file_num; // number of files on card FileInfo *file_info; // pointer to file info array ExportHeader *header; // pointer to header array for the files on the current page u8 page; // file page u8 files_on_page; // number of files on the current page struct { GOBJ *gobj; // confirm gobj u16 canvas; u8 kind; // which kind of confirm dialog this is u8 cursor; Text *text; } confirm; struct { _HSD_ImageDesc *orig_image; // pointer to jobj's original image desc RGB565 *image; // pointer to 32 byte aligned image allocation (one being displayed) int loaded_num; // number of completed snaps loaded u8 load_inprogress; // bool for if a file is being loaded u8 file_loading; // page local index of the file being loaded void *file_data[IMPORT_FILESPERPAGE]; // pointer to each files data u8 is_loaded[IMPORT_FILESPERPAGE]; // bools for which snap has been loaded } snap; } ImportData; void Button_Create(); void Button_Think(GOBJ *button_gobj); void Menu_Confirm_Init(GOBJ *menu_gobj, int kind); void Menu_Confirm_Think(GOBJ *menu_gobj); void Menu_Confirm_Exit(GOBJ *menu_gobj); GOBJ *Menu_Create(); void Menu_Think(GOBJ *menu_gobj); #define MENUCAM_GXLINK 5 #define SIS_ID 0 ================================================ FILE: patch/events/lab/source/lab_css.c ================================================ #include "lab.h" // Static Variables static Arch_ImportData *stc_import_assets; static ImportData import_data; static char *slots_names[] = {"A", "B"}; static _HSD_ImageDesc image_desc = { .format = 4, .height = RESIZE_HEIGHT, .width = RESIZE_WIDTH, }; static GXColor text_white = {255, 255, 255, 255}; static GXColor text_gold = {255, 211, 0, 255}; // OnLoad void OnCSSLoad(ArchiveInfo *archive) { EventVars *event_vars = *event_vars_ptr; // get assets from this file stc_import_assets = File_GetSymbol(archive, "importData"); Button_Create(); // Create a cobj for the menu COBJ *cam_cobj = COBJ_LoadDesc(stc_import_assets->import_cam); GOBJ *cam_gobj = GObj_Create(2, 3, 128); GObj_AddObject(cam_gobj, R13_U8(-0x3E55), cam_cobj); GOBJ_InitCamera(cam_gobj, CObjThink_Common, 1); GObj_AddProc(cam_gobj, MainMenu_CamRotateThink, 5); cam_gobj->cobj_links = 1 << MENUCAM_GXLINK; // Create text canvas import_data.canvas = Text_CreateCanvas(SIS_ID, 0, 2, 3, 128, MENUCAM_GXLINK, 129, 0); import_data.confirm.canvas = Text_CreateCanvas(SIS_ID, 0, 2, 3, 128, MENUCAM_GXLINK, 131, 0); // allocate filename array import_data.file_info = calloc(CARD_MAX_FILE * sizeof(FileInfo)); // allocate 128 entries // allocate filename buffers for (int i = 0; i < CARD_MAX_FILE; i++) { import_data.file_info[i].file_name = calloc(CARD_FILENAME_MAX); } // alloc file header array import_data.header = calloc(IMPORT_FILESPERPAGE * sizeof(ExportHeader)); // alloc image (needs to be 32 byte aligned) import_data.snap.image = calloc(GXGetTexBufferSize(RESIZE_WIDTH, RESIZE_HEIGHT, 4, 0, 0)); // allocate 128 entries // HUGE HACK ALERT EventDesc *(*GetEventDesc)(int page, int event) = RTOC_PTR(TM_DATA + (24 * 4)); EventDesc *event_desc = GetEventDesc(1, 0); event_desc->isSelectStage = 1; event_desc->matchData->stage = -1; *onload_fileno = -1; return; } // Button Functions void Button_Create() { // Create GOBJ GOBJ *button_gobj = GObj_Create(4, 5, 0); GObj_AddGXLink(button_gobj, GXLink_Common, 1, 128); GObj_AddProc(button_gobj, Button_Think, 8); JOBJ *button_jobj = JOBJ_LoadJoint(stc_import_assets->import_button); GObj_AddObject(button_gobj, R13_U8(-0x3E55), button_jobj); // scale message jobj Vec3 *scale = &button_jobj->scale; // Create text object Text *button_text = Text_CreateText(SIS_ID, 0); button_text->kerning = 1; button_text->align = 1; button_text->use_aspect = 1; button_text->scale.X = (scale->X * 0.01) * 3; button_text->scale.Y = (scale->Y * 0.01) * 3; button_text->trans.X = button_jobj->trans.X + (0 * (scale->X / 4.0)); button_text->trans.Y = (button_jobj->trans.Y * -1) + (-1.6 * (scale->Y / 4.0)); Text_AddSubtext(button_text, 0, 0, "Import"); return; } void Button_Think(GOBJ *button_gobj) { #define BUTTON_WIDTH 5 #define BUTTON_HEIGHT 2.2 // init CSSCursor *this_cursor = stc_css_cursors[0]; // get the main player's hand cursor data Vec2 cursor_pos = this_cursor->pos; cursor_pos.X += 5; cursor_pos.Y -= 1; HSD_Pad *pads = stc_css_pad; HSD_Pad *this_pad = &pads[*stc_css_hmnport]; int down = this_pad->down; // get this cursors inputs JOBJ *button_jobj = button_gobj->hsd_object; // get jobj Vec3 *button_pos = &button_jobj->trans; // check if cursor is hovered over button if ((import_data.menu_gobj == 0) && (cursor_pos.X < (button_pos->X + BUTTON_WIDTH)) && (cursor_pos.X > (button_pos->X - BUTTON_WIDTH)) && (cursor_pos.Y < (button_pos->Y + BUTTON_HEIGHT)) && (cursor_pos.Y > (button_pos->Y - BUTTON_HEIGHT)) && (down & HSD_BUTTON_A)) { import_data.menu_gobj = Menu_Create(); SFX_PlayCommon(1); } return; } // Import Menu Functions GOBJ *Menu_Create() { // Create GOBJ GOBJ *menu_gobj = GObj_Create(4, 5, 0); GObj_AddGXLink(menu_gobj, GXLink_Common, MENUCAM_GXLINK, 128); GObj_AddProc(menu_gobj, Menu_Think, 1); JOBJ *menu_jobj = JOBJ_LoadJoint(stc_import_assets->import_menu); GObj_AddObject(menu_gobj, R13_U8(-0x3E55), menu_jobj); // save jobj pointers JOBJ_GetChild(menu_jobj, &import_data.memcard_jobj[0], 2, -1); JOBJ_GetChild(menu_jobj, &import_data.memcard_jobj[1], 4, -1); JOBJ_GetChild(menu_jobj, &import_data.screenshot_jobj, 6, -1); JOBJ_GetChild(menu_jobj, &import_data.scroll_jobj, 7, -1); JOBJ_GetChild(menu_jobj, &import_data.scroll_top, 9, -1); JOBJ_GetChild(menu_jobj, &import_data.scroll_bot, 10, -1); // hide all JOBJ_SetFlagsAll(import_data.memcard_jobj[0], JOBJ_HIDDEN); JOBJ_SetFlagsAll(import_data.memcard_jobj[1], JOBJ_HIDDEN); JOBJ_SetFlagsAll(import_data.screenshot_jobj, JOBJ_HIDDEN); JOBJ_SetFlagsAll(import_data.scroll_jobj, JOBJ_HIDDEN); // create title and desc text Text *title_text = Text_CreateText(SIS_ID, import_data.canvas); title_text->kerning = 1; title_text->use_aspect = 1; title_text->aspect.X = 305; title_text->trans.X = -28; title_text->trans.Y = -21; title_text->trans.Z = menu_jobj->trans.Z; title_text->scale.X = (menu_jobj->scale.X * 0.01) * 11; title_text->scale.Y = (menu_jobj->scale.Y * 0.01) * 11; Text_AddSubtext(title_text, 0, 0, "-"); import_data.title_text = title_text; Text *desc_text = Text_CreateText(SIS_ID, import_data.canvas); desc_text->kerning = 1; desc_text->use_aspect = 1; desc_text->aspect.X = 930; desc_text->trans.X = -28; desc_text->trans.Y = 14.5; desc_text->trans.Z = menu_jobj->trans.Z; desc_text->scale.X = (menu_jobj->scale.X * 0.01) * 5; desc_text->scale.Y = (menu_jobj->scale.Y * 0.01) * 5; Text_AddSubtext(desc_text, 0, 0, "-"); import_data.desc_text = desc_text; // save original snapshot imagedesc pointer import_data.snap.orig_image = import_data.screenshot_jobj->dobj->mobj->tobj->imagedesc; // disable inputs for CSS *stc_css_exitkind = 5; // init card select menu Menu_SelCard_Init(menu_gobj); return menu_gobj; } void Menu_Destroy(GOBJ *menu_gobj) { // run specific menu state code switch (import_data.menu_state) { case (IMP_SELCARD): { Menu_SelCard_Exit(menu_gobj); break; } case (IMP_SELFILE): { Menu_SelFile_Exit(menu_gobj); break; } } // destroy text Text_Destroy(import_data.title_text); import_data.title_text = 0; Text_Destroy(import_data.desc_text); import_data.desc_text = 0; // destroy gobj GObj_Destroy(menu_gobj); import_data.menu_gobj = 0; // enable CSS inputs *stc_css_exitkind = 0; *stc_css_delay = 0; return; } void Menu_Think(GOBJ *menu_gobj) { *stc_css_delay = 2; switch (import_data.menu_state) { case (IMP_SELCARD): { Menu_SelCard_Think(menu_gobj); break; } case (IMP_SELFILE): { Menu_SelFile_Think(menu_gobj); break; } case (IMP_CONFIRM): { Menu_Confirm_Think(menu_gobj); break; } } return; } // Select Card void Menu_SelCard_Init(GOBJ *menu_gobj) { // get jobj JOBJ *menu_jobj = menu_gobj->hsd_object; // init state and cursor import_data.menu_state = IMP_SELCARD; import_data.cursor = 0; // init memcard inserted state import_data.memcard_inserted[0] = 0; import_data.memcard_inserted[1] = 0; // show memcards JOBJ_ClearFlagsAll(import_data.memcard_jobj[0], JOBJ_HIDDEN); JOBJ_ClearFlagsAll(import_data.memcard_jobj[1], JOBJ_HIDDEN); // create memcard text Text *memcard_text = Text_CreateText(SIS_ID, import_data.canvas); memcard_text->kerning = 1; memcard_text->align = 1; memcard_text->trans.Z = menu_jobj->trans.Z + 2; memcard_text->scale.X = (menu_jobj->scale.X * 0.01) * 5; memcard_text->scale.Y = (menu_jobj->scale.Y * 0.01) * 5; import_data.option_text = memcard_text; Text_AddSubtext(memcard_text, -159, 45, "Slot A"); Text_AddSubtext(memcard_text, 159, 45, "Slot B"); // edit title Text_SetText(import_data.title_text, 0, "Select Memory Card"); // edit description Text_SetText(import_data.desc_text, 0, ""); return; } void Menu_SelCard_Think(GOBJ *menu_gobj) { // init int down = Pad_GetRapidHeld(*stc_css_hmnport); // update memcard info for (int i = 1; i >= 0; i--) { // probe slot u8 is_inserted; s32 memSize, sectorSize; if (CARDProbeEx(i, &memSize, §orSize) == CARD_RESULT_READY) { // if it was just inserted, get info if (import_data.memcard_inserted[i] == 0) { // mount card stc_memcard_work->is_done = 0; if (CARDMountAsync(i, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY) { // check card Memcard_Wait(); stc_memcard_work->is_done = 0; if (CARDCheckAsync(i, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); // if we get this far, a valid memcard is inserted is_inserted = 1; SFX_PlayCommon(2); //import_data.cursor = i; // move cursor to this // get free blocks s32 byteNotUsed, filesNotUsed; if (CARDFreeBlocks(i, &byteNotUsed, &filesNotUsed) == CARD_RESULT_READY) { import_data.memcard_free_blocks[i] = (byteNotUsed / 8192); import_data.memcard_free_files[i] = filesNotUsed; } } else is_inserted = 0; CARDUnmount(i); stc_memcard_work->is_done = 0; } else is_inserted = 0; } else is_inserted = 1; } else is_inserted = 0; import_data.memcard_inserted[i] = is_inserted; } // cursor movement if (down & (HSD_BUTTON_LEFT | HSD_BUTTON_DPAD_LEFT)) // check for cursor left { if (import_data.cursor > 0) { import_data.cursor--; SFX_PlayCommon(2); } } else if (down & (HSD_BUTTON_RIGHT | HSD_BUTTON_DPAD_RIGHT)) // check for cursor right { if (import_data.cursor < 1) { import_data.cursor++; SFX_PlayCommon(2); } } // highlight cursor for (int i = 0; i < 2; i++) { Text_SetColor(import_data.option_text, i, &text_white); } Text_SetColor(import_data.option_text, import_data.cursor, &text_gold); Text *desc_text = import_data.desc_text; int cursor = import_data.cursor; if (import_data.memcard_inserted[cursor] == 0) Text_SetText(desc_text, 0, "No device is inserted in Slot %s.", slots_names[cursor]); else Text_SetText(desc_text, 0, "Load recording from the memory card in Slot %s.", slots_names[cursor]); // check for exit if (down & HSD_BUTTON_B) { Menu_Destroy(menu_gobj); SFX_PlayCommon(0); } // check for A else if (down & HSD_BUTTON_A) { // check if valid memcard inserted if (import_data.memcard_inserted[cursor] == 0) SFX_PlayCommon(3); // is inserted else { import_data.memcard_slot = cursor; SFX_PlayCommon(1); Menu_SelCard_Exit(menu_gobj); Menu_SelFile_Init(menu_gobj); } } return; } void Menu_SelCard_Exit(GOBJ *menu_gobj) { JOBJ_SetFlagsAll(import_data.memcard_jobj[0], JOBJ_HIDDEN); JOBJ_SetFlagsAll(import_data.memcard_jobj[1], JOBJ_HIDDEN); // destroy memcard text Text_Destroy(import_data.option_text); import_data.option_text = 0; return; } // Select File void Menu_SelFile_Init(GOBJ *menu_gobj) { // get jobj JOBJ *menu_jobj = menu_gobj->hsd_object; // init state and cursor import_data.menu_state = IMP_SELFILE; import_data.cursor = 0; import_data.page = 0; // show memcards JOBJ_ClearFlagsAll(import_data.scroll_jobj, JOBJ_HIDDEN); JOBJ_ClearFlagsAll(import_data.screenshot_jobj, JOBJ_HIDDEN); // create file name text Text *filename_text = Text_CreateText(SIS_ID, import_data.canvas); filename_text->kerning = 1; filename_text->align = 0; filename_text->use_aspect = 1; filename_text->aspect.X = 525; filename_text->trans.X = -27.8; filename_text->trans.Y = -13.6; filename_text->trans.Z = menu_jobj->trans.Z; filename_text->scale.X = (menu_jobj->scale.X * 0.01) * 5; filename_text->scale.Y = (menu_jobj->scale.Y * 0.01) * 5; import_data.filename_text = filename_text; for (int i = 0; i < IMPORT_FILESPERPAGE; i++) { Text_AddSubtext(filename_text, 0, i * 40, ""); } #define FILEINFO_X 235 #define FILEINFO_Y -20 #define FILEINFO_YOFFSET 35 #define FILEINFO_STAGEY FILEINFO_Y #define FILEINFO_HMNY FILEINFO_STAGEY + FILEINFO_YOFFSET #define FILEINFO_CPUY FILEINFO_HMNY + FILEINFO_YOFFSET #define FILEINFO_DATEY FILEINFO_CPUY + (FILEINFO_YOFFSET * 2) #define FILEINFO_TIMEY FILEINFO_DATEY + FILEINFO_YOFFSET // create file info text Text *fileinfo_text = Text_CreateText(SIS_ID, import_data.canvas); fileinfo_text->kerning = 1; fileinfo_text->align = 0; fileinfo_text->use_aspect = 1; fileinfo_text->aspect.X = 300; fileinfo_text->trans.Z = menu_jobj->trans.Z; fileinfo_text->scale.X = (menu_jobj->scale.X * 0.01) * 4.5; fileinfo_text->scale.Y = (menu_jobj->scale.Y * 0.01) * 4.5; import_data.fileinfo_text = fileinfo_text; Text_AddSubtext(fileinfo_text, FILEINFO_X, FILEINFO_STAGEY, "Stage: "); Text_AddSubtext(fileinfo_text, FILEINFO_X, FILEINFO_HMNY, "HMN: "); Text_AddSubtext(fileinfo_text, FILEINFO_X, FILEINFO_CPUY, "CPU: "); Text_AddSubtext(fileinfo_text, FILEINFO_X, FILEINFO_DATEY, "Date: "); Text_AddSubtext(fileinfo_text, FILEINFO_X, FILEINFO_TIMEY, "Time: "); // edit title Text_SetText(import_data.title_text, 0, "Select Recording"); // edit description Text_SetText(import_data.desc_text, 0, "A = Select B = Return X = Delete"); // search card for save files import_data.file_num = 0; int slot = import_data.memcard_slot; char *filename[32]; int file_size; s32 memSize, sectorSize; if (CARDProbeEx(slot, &memSize, §orSize) == CARD_RESULT_READY) { // mount card stc_memcard_work->is_done = 0; if (CARDMountAsync(slot, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY) { // check card Memcard_Wait(); stc_memcard_work->is_done = 0; if (CARDCheckAsync(slot, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); // get free blocks s32 byteNotUsed, filesNotUsed; if (CARDFreeBlocks(slot, &byteNotUsed, &filesNotUsed) == CARD_RESULT_READY) { // search for files with name TMREC for (int i = 0; i < CARD_MAX_FILE; i++) { CARDStat card_stat; if (CARDGetStatus(slot, i, &card_stat) == CARD_RESULT_READY) { // check company code if (strncmp(os_info->company, card_stat.company, sizeof(os_info->company)) == 0) { // check game name if (strncmp(os_info->gameName, card_stat.gameName, sizeof(os_info->gameName)) == 0) { // check file name if (strncmp("TMREC", card_stat.fileName, 5) == 0) { OSReport("found recording file %s with size %d\n", card_stat.fileName, card_stat.length); import_data.file_info[import_data.file_num].file_size = card_stat.length; // save file size import_data.file_info[import_data.file_num].file_no = i; // save file no memcpy(import_data.file_info[import_data.file_num].file_name, card_stat.fileName, sizeof(card_stat.fileName)); // save file name import_data.file_num++; // increment file amount } } } } } } } CARDUnmount(slot); stc_memcard_work->is_done = 0; } } // init scroll bar according to import_data.file_num int page_total = import_data.file_num / (IMPORT_FILESPERPAGE + 1); if (page_total == 0) JOBJ_SetFlagsAll(import_data.scroll_jobj, JOBJ_HIDDEN); else import_data.scroll_bot->trans.Y = (-16.2 / (page_total + 1)); // display orig texture import_data.screenshot_jobj->dobj->mobj->tobj->imagedesc = import_data.snap.orig_image; // load in first page recordsings int page_result = Menu_SelFile_LoadPage(menu_gobj, 0); if (page_result == -1) { // create dialog Menu_Confirm_Init(menu_gobj, CFRM_ERR); SFX_PlayCommon(3); } return; } void Menu_SelFile_Think(GOBJ *menu_gobj) { // init int down = Pad_GetRapidHeld(*stc_css_hmnport); // first ensure memcard is still inserted s32 memSize, sectorSize; if (CARDProbeEx(import_data.memcard_slot, &memSize, §orSize) != CARD_RESULT_READY) goto EXIT; // if no files exist if (import_data.file_num == 0) { // check for exit if (down & (HSD_BUTTON_B | HSD_BUTTON_A)) goto EXIT; } // navigation think else { // cursor movement if (down & (HSD_BUTTON_UP | HSD_BUTTON_DPAD_UP)) // check for cursor up { // if cursor is at the top of the page, try to advance to prev if (import_data.cursor == 0) { // try to load prev page int page_result = Menu_SelFile_LoadPage(menu_gobj, import_data.page - 1); if (page_result == 1) // page loaded, update cursor { SFX_PlayCommon(2); import_data.cursor = (IMPORT_FILESPERPAGE - 1); import_data.page--; } else if (page_result == -1) { // create dialog Menu_Confirm_Init(menu_gobj, CFRM_ERR); SFX_PlayCommon(3); goto EXIT_FUNC; // gotos are weird but i couldnt think of another way } } // if cursor can be advanced else if (import_data.cursor > 0) { import_data.cursor--; SFX_PlayCommon(2); } } else if (down & (HSD_BUTTON_LEFT | HSD_BUTTON_DPAD_LEFT)) // check for cursor down { // try to load prev page int page_result = Menu_SelFile_LoadPage(menu_gobj, import_data.page - 1); if (page_result == 1) // page loaded, update cursor { SFX_PlayCommon(2); import_data.cursor = 0; import_data.page--; } else if (page_result == -1) { // create dialog Menu_Confirm_Init(menu_gobj, CFRM_ERR); SFX_PlayCommon(3); goto EXIT_FUNC; // gotos are weird but i couldnt think of another way } } else if (down & (HSD_BUTTON_DOWN | HSD_BUTTON_DPAD_DOWN)) // check for cursor down { // if cursor is at the end of the page, try to advance to next if (import_data.cursor == (IMPORT_FILESPERPAGE - 1)) { // try to load next page int page_result = Menu_SelFile_LoadPage(menu_gobj, import_data.page + 1); if (page_result == 1) // page loaded, update cursor { SFX_PlayCommon(2); import_data.cursor = 0; import_data.page++; } else if (page_result == -1) { // create dialog Menu_Confirm_Init(menu_gobj, CFRM_ERR); SFX_PlayCommon(3); goto EXIT_FUNC; // gotos are weird but i couldnt think of another way } } // if cursor can be advanced else if ((import_data.cursor < import_data.files_on_page - 1)) { import_data.cursor++; SFX_PlayCommon(2); } } else if (down & (HSD_BUTTON_RIGHT | HSD_BUTTON_DPAD_RIGHT)) // check for cursor right { // try to load next page int page_result = Menu_SelFile_LoadPage(menu_gobj, import_data.page + 1); if (page_result == 1) // page loaded, update cursor { SFX_PlayCommon(2); import_data.cursor = 0; import_data.page++; } else if (page_result == -1) { // create dialog Menu_Confirm_Init(menu_gobj, CFRM_ERR); SFX_PlayCommon(3); goto EXIT_FUNC; // gotos are weird but i couldnt think of another way } } // highlight cursor int cursor = import_data.cursor; for (int i = 0; i < IMPORT_FILESPERPAGE; i++) { Text_SetColor(import_data.filename_text, i, &text_white); } Text_SetColor(import_data.filename_text, cursor, &text_gold); // update file info text /* u8 *transfer_buf = import_data.snap.file_data[cursor]; ExportHeader *header = transfer_buf; u8 *compressed_recording = transfer_buf + header->lookup.ofst_recording; Text_SetText(import_data.fileinfo_text, 0, "Stage: %s", stage_names[header->metadata.stage_internal]); Text_SetText(import_data.fileinfo_text, 1, "HMN: %s", Fighter_GetName(header->metadata.hmn)); Text_SetText(import_data.fileinfo_text, 2, "CPU: %s", Fighter_GetName(header->metadata.cpu)); Text_SetText(import_data.fileinfo_text, 3, "Created: %d/%d/%d", 10, 30, 1995); */ // update file info text from header data int this_file_index = (import_data.page * IMPORT_FILESPERPAGE) + cursor; ExportHeader *header = &import_data.header[cursor]; // update file info text Text_SetText(import_data.fileinfo_text, 0, "Stage: %s", stage_names[header->metadata.stage_internal]); Text_SetText(import_data.fileinfo_text, 1, "HMN: %s", Fighter_GetName(header->metadata.hmn)); Text_SetText(import_data.fileinfo_text, 2, "CPU: %s", Fighter_GetName(header->metadata.cpu)); Text_SetText(import_data.fileinfo_text, 3, "Date: %d/%d/%d", header->metadata.month, header->metadata.day, header->metadata.year); Text_SetText(import_data.fileinfo_text, 4, "Time: %d:%02d:%02d", header->metadata.hour, header->metadata.minute, header->metadata.second); // async load snapshots Menu_SelFile_LoadAsyncThink(menu_gobj); // update file image // if this file is loaded if (import_data.snap.is_loaded[cursor] == 1) { // copy screenshot data to buffer void *file_data = import_data.snap.file_data[cursor]; RGB565 *img = file_data + header->lookup.ofst_screenshot; int img_size = GXGetTexBufferSize(header->metadata.image_width, header->metadata.image_height, 4, 0, 0); memcpy(import_data.snap.image, img, img_size); // copu image to 32 byte aligned buffer // invalidate cache DCFlushRange(import_data.snap.image, img_size); // display this texture image_desc.img_ptr = import_data.snap.image; // store pointer to resized image import_data.screenshot_jobj->dobj->mobj->tobj->imagedesc = &image_desc; // replace pointer to imagedesc } else { // display orig texture import_data.screenshot_jobj->dobj->mobj->tobj->imagedesc = import_data.snap.orig_image; } // check for exit if (down & HSD_BUTTON_B) { EXIT: SFX_PlayCommon(0); Menu_SelFile_Exit(menu_gobj); Menu_SelCard_Init(menu_gobj); } // check to delete else if (down & HSD_BUTTON_X) { Menu_Confirm_Init(menu_gobj, CFRM_DEL); SFX_PlayCommon(1); } // check for select else if (down & HSD_BUTTON_A) { int kind; // init confirm kind int vers = import_data.header[cursor].metadata.version; // get version number // check if version is compatible with this release if (vers == REC_VERS) kind = CFRM_LOAD; else if (vers > REC_VERS) kind = CFRM_NEW; else if (vers < REC_VERS) kind = CFRM_OLD; // open confirm dialog Menu_Confirm_Init(menu_gobj, kind); SFX_PlayCommon(1); } } EXIT_FUNC: return; } void Menu_SelFile_Exit(GOBJ *menu_gobj) { JOBJ_SetFlagsAll(import_data.scroll_jobj, JOBJ_HIDDEN); JOBJ_SetFlagsAll(import_data.screenshot_jobj, JOBJ_HIDDEN); // destroy option text Text_Destroy(import_data.filename_text); import_data.filename_text = 0; Text_Destroy(import_data.fileinfo_text); import_data.fileinfo_text = 0; // cancel card read if in progress int memcard_status = Memcard_CheckStatus(); if (memcard_status == 11) { // cancel read stc_memcard_work->card_file_info.length = -1; // wait for callback to fire // i do this because the callback will always set some // variable in the workarea regardless of its cancelled while (memcard_status == 11) { memcard_status = Memcard_CheckStatus(); } } // free prev buffers for (int i = 0; i < IMPORT_FILESPERPAGE; i++) { // if exists if (import_data.snap.file_data[i] != 0) { HSD_Free(import_data.snap.file_data[i]); import_data.snap.file_data[i] = 0; } } return; } int Menu_SelFile_LoadPage(GOBJ *menu_gobj, int page) { int result = 0; int files_on_page; int cursor = import_data.cursor; // start at cursor int page_total = import_data.file_num / IMPORT_FILESPERPAGE; // ensure page exists if ((page >= 0) && (page <= page_total)) { // determine files on page if (((page + 1) * IMPORT_FILESPERPAGE) < import_data.file_num) files_on_page = IMPORT_FILESPERPAGE; // page is filled with files else files_on_page = import_data.file_num - (page * IMPORT_FILESPERPAGE); // remaining files // ensure page has at least one recording if (files_on_page > 0) { // cancel card read if in progress int memcard_status = Memcard_CheckStatus(); if (memcard_status == 11) { // cancel read stc_memcard_work->card_file_info.length = -1; // wait for callback to fire while (memcard_status == 11) { memcard_status = Memcard_CheckStatus(); } } void *buffer = calloc(CARD_READ_SIZE); import_data.files_on_page = files_on_page; // update amount of files on page import_data.snap.loaded_num = 0; import_data.snap.load_inprogress = 0; for (int i = 0; i < IMPORT_FILESPERPAGE; i++) { import_data.snap.is_loaded[i] = 0; // init files as unloaded } result = 1; // set page as toggled int slot = import_data.memcard_slot; // update scroll bar position import_data.scroll_top->trans.Y = ((float)page / (float)(page_total)) * (import_data.scroll_bot->trans.Y); JOBJ_SetMtxDirtySub(menu_gobj->hsd_object); // free prev buffers for (int i = 0; i < IMPORT_FILESPERPAGE; i++) { // if exists if (import_data.snap.file_data[i] != 0) { HSD_Free(import_data.snap.file_data[i]); import_data.snap.file_data[i] = 0; } } // blank out all text for (int i = 0; i < IMPORT_FILESPERPAGE; i++) { Text_SetText(import_data.filename_text, i, ""); } // mount card s32 memSize, sectorSize; if (CARDProbeEx(slot, &memSize, §orSize) == CARD_RESULT_READY) { // mount card stc_memcard_work->is_done = 0; if (CARDMountAsync(slot, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); // check card stc_memcard_work->is_done = 0; if (CARDCheckAsync(slot, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); // begin loading this page's files for (int i = 0; i < files_on_page; i++) { // get file info int this_file_index = (page * IMPORT_FILESPERPAGE) + i; char *file_name = import_data.file_info[this_file_index].file_name; int file_size = import_data.file_info[this_file_index].file_size; int file_no = import_data.file_info[this_file_index].file_no; // get comment from card CARDFileInfo card_file_info; CARDStat card_stat; // get status if (CARDGetStatus(slot, file_no, &card_stat) == CARD_RESULT_READY) { // open card (get file info) if (CARDOpen(slot, file_name, &card_file_info) == CARD_RESULT_READY) { // try to get header if (CARDRead(&card_file_info, buffer, CARD_READ_SIZE, 0x1E00) == CARD_RESULT_READY) { // deobfuscate stupid melee bullshit Memcard_Deobfuscate(buffer, CARD_READ_SIZE); ExportHeader *header = buffer + 0x90; // get to header (need to find a less hardcoded way of doing this) // ensure header contains filename (REC_VERS 1+) if (header->metadata.version < 1) { result = -1; CARDClose(&card_file_info); break; } else { // save header memcpy(&import_data.header[i], header, sizeof(ExportHeader)); // print user file name Text_SetText(import_data.filename_text, i, header->metadata.filename); } } CARDClose(&card_file_info); } } /* // setup load MemcardSave stc_memcard_save; void *buffer = HSD_MemAlloc(file_size); // alloc buffer for this save import_data.snap.file_data[i] = buffer; // save buffer pointer stc_memcard_save.data = buffer; // store pointer to buffer for memcard load operation stc_memcard_save.x4 = 3; stc_memcard_save.size = file_size; stc_memcard_save.xc = -1; Memcard_LoadSnapshot(import_data.memcard_slot, file_name, &stc_memcard_save, &stc_memcard_info->file_name, 0, 0, 0); // wait to load int memcard_status = Memcard_CheckStatus(); while (memcard_status == 11) { memcard_status = Memcard_CheckStatus(); } // if file loaded successfully if (memcard_status == 0) Text_SetText(import_data.filename_text, i, &stc_memcard_info->file_name[32]); */ } } // unmount CARDUnmount(slot); stc_memcard_work->is_done = 0; } } // free temp read buffer HSD_Free(buffer); } } return result; } void Menu_SelFile_DeleteUnsupported(GOBJ *menu_gobj) { void *buffer = calloc(CARD_READ_SIZE); int slot = import_data.memcard_slot; // mount card s32 memSize, sectorSize; if (CARDProbeEx(slot, &memSize, §orSize) == CARD_RESULT_READY) { // mount card stc_memcard_work->is_done = 0; if (CARDMountAsync(slot, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); // check card stc_memcard_work->is_done = 0; if (CARDCheckAsync(slot, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); // loop through all detected TMREC files for (int i = 0; i < import_data.file_num; i++) { // get file info char *file_name = import_data.file_info[i].file_name; int file_size = import_data.file_info[i].file_size; CARDFileInfo card_file_info; /* so at this point, i have filenames for every TMREC file present on the memcard. all i have to do is: - cardopen each file - cardread the header - deobfuscate - check version - delete file using filename if its a bad file */ // open card (get file info) if (CARDOpen(slot, file_name, &card_file_info) == CARD_RESULT_READY) { // read header if (CARDRead(&card_file_info, buffer, CARD_READ_SIZE, 0x1E00) == CARD_RESULT_READY) { // deobfuscate stupid melee bullshit Memcard_Deobfuscate(buffer, CARD_READ_SIZE); ExportHeader *header = buffer + 0x90; // get to header (need to find a less hardcoded way of doing this) // check if unsupported version if (header->metadata.version < 1) { // delete this file stc_memcard_work->is_done = 0; if (CARDDeleteAsync(slot, file_name, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); } } } CARDClose(&card_file_info); } } } // unmount CARDUnmount(slot); stc_memcard_work->is_done = 0; } } // free temp read buffer HSD_Free(buffer); return; } int Menu_SelFile_DeleteFile(GOBJ *menu_gobj, int file_index) { int result = 0; int slot = import_data.memcard_slot; // mount card s32 memSize, sectorSize; if (CARDProbeEx(slot, &memSize, §orSize) == CARD_RESULT_READY) { // mount card stc_memcard_work->is_done = 0; if (CARDMountAsync(slot, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); // check card stc_memcard_work->is_done = 0; if (CARDCheckAsync(slot, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); // get file info char *file_name = import_data.file_info[file_index].file_name; int file_size = import_data.file_info[file_index].file_size; CARDFileInfo card_file_info; // open card (get file info) if (CARDOpen(slot, file_name, &card_file_info) == CARD_RESULT_READY) { // delete this file stc_memcard_work->is_done = 0; if (CARDDeleteAsync(slot, file_name, Memcard_RemovedCallback) == CARD_RESULT_READY) { Memcard_Wait(); result = 1; } CARDClose(&card_file_info); } } // unmount CARDUnmount(slot); stc_memcard_work->is_done = 0; } } return result; } void Menu_SelFile_LoadAsyncThink(GOBJ *menu_gobj) { // is there a load in progress? if (import_data.snap.load_inprogress == 1) { // is it done? if (Memcard_CheckStatus() != 11) { // increment number of loaded files import_data.snap.loaded_num++; // no more load in progress import_data.snap.load_inprogress = 0; // set as loaded import_data.snap.is_loaded[import_data.snap.file_loading] = 1; } } // check if any pending files to load if ((import_data.snap.load_inprogress == 0) && // checking inprogress again in case the code above set it to 0 this tick (import_data.snap.loaded_num < import_data.files_on_page)) { // find nearest unloaded file int file_to_load; int cursor = import_data.cursor; // check if cursor is loaded if (import_data.snap.is_loaded[cursor] == 0) file_to_load = cursor; // find nearest unloaded file else { // search for unloaded snap nearest to the cursor int search_up = cursor; int search_down = cursor; for (int i = 0; i < (IMPORT_FILESPERPAGE - 1); i++) { search_up--; search_down++; // if still on page if (search_up >= 0) { if (import_data.snap.is_loaded[search_up] == 0) { // load this next file_to_load = search_up; break; } } // if still on page if (search_down < IMPORT_FILESPERPAGE) { if (import_data.snap.is_loaded[search_down] == 0) { // load this next file_to_load = search_down; break; } } } } // get filename and size for this file int this_file_index = (import_data.page * IMPORT_FILESPERPAGE) + file_to_load; // page file index -> TMREC file index int file_size = import_data.file_info[this_file_index].file_size; char *file_name = import_data.file_info[this_file_index].file_name; // load next static MemcardSave stc_memcard_save; void *buffer = HSD_MemAlloc(file_size); // alloc buffer for this save import_data.snap.file_data[file_to_load] = buffer; // save buffer pointer stc_memcard_save.data = buffer; // store pointer to buffer for memcard load operation stc_memcard_save.x4 = 3; stc_memcard_save.size = file_size; stc_memcard_save.xc = -1; Memcard_LoadSnapshot(import_data.memcard_slot, file_name, &stc_memcard_save, &stc_memcard_info->file_name, 0, 0, 0); import_data.snap.load_inprogress = 1; import_data.snap.file_loading = file_to_load; } return; } // Confirm Dialog void Menu_Confirm_Init(GOBJ *menu_gobj, int kind) { // init cursor import_data.confirm.cursor = 0; import_data.menu_state = IMP_CONFIRM; import_data.confirm.kind = kind; // Create GOBJ GOBJ *confirm_gobj = GObj_Create(4, 5, 0); GObj_AddGXLink(confirm_gobj, GXLink_Common, MENUCAM_GXLINK, 130); JOBJ *confirm_jobj = JOBJ_LoadJoint(stc_import_assets->import_popup); GObj_AddObject(confirm_gobj, R13_U8(-0x3E55), confirm_jobj); import_data.confirm.gobj = confirm_gobj; // create text Text *text = Text_CreateText(SIS_ID, import_data.confirm.canvas); text->kerning = 1; text->align = 1; text->use_aspect = 1; text->aspect.X = 380; text->trans.Z = confirm_jobj->trans.Z; text->scale.X = (confirm_jobj->scale.X * 0.01) * 6; text->scale.Y = (confirm_jobj->scale.Y * 0.01) * 6; import_data.confirm.text = text; // decide text based on kind switch (kind) { case (CFRM_LOAD): { Text_AddSubtext(text, 0, -50, "Load this recording?"); Text_AddSubtext(text, -65, 20, "Yes"); Text_AddSubtext(text, 65, 20, "No"); break; } case (CFRM_OLD): { Text_AddSubtext(text, 0, -50, "Cannot load outdated recording."); Text_AddSubtext(text, 0, 20, "OK"); Text_SetColor(import_data.confirm.text, 1, &text_gold); break; } case (CFRM_NEW): { Text_AddSubtext(text, 0, -50, "Cannot load newer recording."); Text_AddSubtext(text, 0, 20, "OK"); Text_SetColor(import_data.confirm.text, 1, &text_gold); break; } case (CFRM_DEL): { Text_AddSubtext(text, 0, -50, "Delete this recording?"); Text_AddSubtext(text, -65, 20, "Yes"); Text_AddSubtext(text, 65, 20, "No"); break; } case (CFRM_ERR): { Text_AddSubtext(text, 0, -70, "Corrupted recording(s) detected."); Text_AddSubtext(text, 0, -35, "Would you like to delete them?"); Text_AddSubtext(text, -65, 40, "Yes"); Text_AddSubtext(text, 65, 40, "No"); break; } } return; } void Menu_Confirm_Think(GOBJ *menu_gobj) { // init int down = Pad_GetRapidHeld(*stc_css_hmnport); // first ensure memcard is still inserted s32 memSize, sectorSize; if (CARDProbeEx(import_data.memcard_slot, &memSize, §orSize) != CARD_RESULT_READY) goto EXIT; switch (import_data.confirm.kind) { case (CFRM_LOAD): { // cursor movement if (down & (HSD_BUTTON_RIGHT | HSD_BUTTON_DPAD_RIGHT)) // check for cursor right { if (import_data.confirm.cursor < 1) { import_data.confirm.cursor++; SFX_PlayCommon(2); } } else if (down & (HSD_BUTTON_LEFT | HSD_BUTTON_DPAD_LEFT)) // check for cursor down { if (import_data.confirm.cursor > 0) { import_data.confirm.cursor--; SFX_PlayCommon(2); } } // highlight cursor int cursor = import_data.confirm.cursor; for (int i = 0; i < 2; i++) { Text_SetColor(import_data.confirm.text, i + 1, &text_white); } Text_SetColor(import_data.confirm.text, cursor + 1, &text_gold); // check for exit if (down & HSD_BUTTON_B) { EXIT: Menu_Confirm_Exit(menu_gobj); SFX_PlayCommon(0); import_data.menu_state = IMP_SELFILE; } // check for select else if (down & HSD_BUTTON_A) { // check which option is selected if (cursor == 0) { // get variables and junk VSMinorData *css_minorscene = *stc_css_minorscene; int this_file_index = (import_data.page * IMPORT_FILESPERPAGE) + import_data.cursor; ExportHeader *header = &import_data.header[import_data.cursor]; Preload *preload = Preload_GetTable(); // get match data u8 hmn_kind = header->metadata.hmn; u8 hmn_costume = header->metadata.hmn_costume; u8 cpu_kind = header->metadata.cpu; u8 cpu_costume = header->metadata.cpu_costume; u16 stage_kind = header->metadata.stage_external; // determine which player index for hmn and cpu u8 hmn_index, cpu_index; if (*stc_css_hmnport > 0) { cpu_index = 0; hmn_index = 1; } else { hmn_index = 0; cpu_index = 1; } // set fighters css_minorscene->vs_data.match_init.playerData[hmn_index].kind = hmn_kind; css_minorscene->vs_data.match_init.playerData[hmn_index].costume = hmn_costume; // header->metadata.hmn_costume; preload->fighters[hmn_index].kind = hmn_kind; preload->fighters[hmn_index].costume = hmn_costume; css_minorscene->vs_data.match_init.playerData[cpu_index].kind = cpu_kind; css_minorscene->vs_data.match_init.playerData[cpu_index].costume = cpu_costume; // header->metadata.cpu_costume; preload->fighters[cpu_index].kind = cpu_kind; preload->fighters[cpu_index].costume = cpu_costume; // set stage css_minorscene->vs_data.match_init.stage = stage_kind; preload->stage = stage_kind; // load files Preload_Update(); // advance scene *stc_css_exitkind = 1; // HUGE HACK ALERT EventDesc *(*GetEventDesc)(int page, int event) = RTOC_PTR(TM_DATA + (24 * 4)); EventDesc *event_desc = GetEventDesc(1, 0); event_desc->isSelectStage = 0; event_desc->matchData->stage = stage_kind; *onload_fileno = this_file_index; *onload_slot = import_data.memcard_slot; SFX_PlayCommon(1); } else goto EXIT; } break; } case (CFRM_OLD): { // check for select if (down & (HSD_BUTTON_A | HSD_BUTTON_B)) { Menu_Confirm_Exit(menu_gobj); SFX_PlayCommon(0); import_data.menu_state = IMP_SELFILE; } break; } case (CFRM_NEW): { // check for select if (down & (HSD_BUTTON_A | HSD_BUTTON_B)) { Menu_Confirm_Exit(menu_gobj); SFX_PlayCommon(0); import_data.menu_state = IMP_SELFILE; } break; } case (CFRM_DEL): { // cursor movement if (down & (HSD_BUTTON_RIGHT | HSD_BUTTON_DPAD_RIGHT)) // check for cursor right { if (import_data.confirm.cursor < 1) { import_data.confirm.cursor++; SFX_PlayCommon(2); } } else if (down & (HSD_BUTTON_LEFT | HSD_BUTTON_DPAD_LEFT)) // check for cursor down { if (import_data.confirm.cursor > 0) { import_data.confirm.cursor--; SFX_PlayCommon(2); } } // highlight cursor int cursor = import_data.confirm.cursor; for (int i = 0; i < 2; i++) { Text_SetColor(import_data.confirm.text, i + 1, &text_white); } Text_SetColor(import_data.confirm.text, cursor + 1, &text_gold); // check for back if (down & HSD_BUTTON_B) { RETURN_TO_FILESEL: Menu_Confirm_Exit(menu_gobj); SFX_PlayCommon(0); import_data.menu_state = IMP_SELFILE; } // check for confirm else if (down & HSD_BUTTON_A) { if (cursor == 0) { SFX_PlayCommon(1); // delete selected recording int this_file_index = (import_data.page * IMPORT_FILESPERPAGE) + import_data.cursor; Menu_SelFile_DeleteFile(menu_gobj, this_file_index); // close dialog Menu_Confirm_Exit(menu_gobj); // reload selfile Menu_SelFile_Exit(menu_gobj); // close select file Menu_SelFile_Init(menu_gobj); // open select file } else goto RETURN_TO_FILESEL; } break; } case (CFRM_ERR): { // cursor movement if (down & (HSD_BUTTON_RIGHT | HSD_BUTTON_DPAD_RIGHT)) // check for cursor right { if (import_data.confirm.cursor < 1) { import_data.confirm.cursor++; SFX_PlayCommon(2); } } else if (down & (HSD_BUTTON_LEFT | HSD_BUTTON_DPAD_LEFT)) // check for cursor down { if (import_data.confirm.cursor > 0) { import_data.confirm.cursor--; SFX_PlayCommon(2); } } // highlight cursor int cursor = import_data.confirm.cursor; for (int i = 0; i < 2; i++) { Text_SetColor(import_data.confirm.text, i + 2, &text_white); } Text_SetColor(import_data.confirm.text, cursor + 2, &text_gold); // check for back if (down & HSD_BUTTON_B) { NO_DELETE_CORRUPT: Menu_Confirm_Exit(menu_gobj); // close dialog Menu_SelFile_Exit(menu_gobj); // close select file Menu_SelCard_Init(menu_gobj); // open select card SFX_PlayCommon(0); //import_data.menu_state = IMP_SELCARD; } // check for confirm else if (down & HSD_BUTTON_A) { if (cursor == 0) { SFX_PlayCommon(1); // delete bad recordings Menu_SelFile_DeleteUnsupported(menu_gobj); // close dialog Menu_Confirm_Exit(menu_gobj); // reload selfile Menu_SelFile_Exit(menu_gobj); // close select file Menu_SelFile_Init(menu_gobj); // open select file } else goto NO_DELETE_CORRUPT; } break; } } return; } void Menu_Confirm_Exit(GOBJ *menu_gobj) { // destroy option text Text_Destroy(import_data.confirm.text); import_data.confirm.text = 0; // destroy gobj GObj_Destroy(import_data.confirm.gobj); import_data.confirm.gobj = 0; return; } // Misc functions void Memcard_Wait() { while (stc_memcard_work->is_done == 0) { blr2(); } return; } ================================================ FILE: patch/events/lcancel/build.bat ================================================ xcopy /s /y "assets\lclData.dat" "output/EvLCl.dat" "../../../MexTK/MexTK.exe" -ff -i "source/lcancel.c" -s evFunction -dat "output/EvLCl.dat" -t "../../../MexTK/evFunction.txt" -q -ow -w -c -l "../../../MexTK/melee.link" -op 1 "../../../MexTK/MexTK.exe" -trim "output/EvLCl.dat" pause ================================================ FILE: patch/events/lcancel/source/lcancel.c ================================================ #include "lcancel.h" static char nullString[] = " "; // Main Menu static char **LcOptions_Barrel[] = {"Off", "Stationary", "Move"}; static char **LcOptions_HUD[] = {"On", "Off"}; static EventOption LcOptions_Main[] = { // Target { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integers list, etc .value_num = sizeof(LcOptions_Barrel) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Target", // pointer to a string .desc = "Enable a target to attack. Use DPad down to\nmanually move it.", // string describing what this option does .option_values = LcOptions_Barrel, // pointer to an array of strings .onOptionChange = 0, }, // HUD { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integers list, etc .value_num = sizeof(LcOptions_HUD) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "HUD", // pointer to a string .desc = "Toggle visibility of the HUD.", // string describing what this option does .option_values = LcOptions_HUD, // pointer to an array of strings .onOptionChange = 0, }, // Tips { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integers list, etc .value_num = sizeof(LcOptions_HUD) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Tips", // pointer to a string .desc = "Toggle the onscreen display of tips.", // string describing what this option does .option_values = LcOptions_HUD, // pointer to an array of strings .onOptionChange = Tips_Toggle, }, // Help { .option_kind = OPTKIND_FUNC, // the type of option this is; menu, string list, integers list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Help", // pointer to a string .desc = "L-canceling is performed by pressing L, R, or Z up to \n7 frames before landing from a non-special aerial\nattack. This will cut the landing lag in half, allowing \nyou to act sooner after attacking.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = 0, }, // Exit { .option_kind = OPTKIND_FUNC, // the type of option this is; menu, string list, integers list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Exit", // pointer to a string .desc = "Return to the Event Selection Screen.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = 0, .onOptionSelect = Event_Exit, }, }; static EventMenu LabMenu_Main = { .name = "L-Cancel Training", // the name of this menu .option_num = sizeof(LcOptions_Main) / sizeof(EventOption), // number of options this menu contains .scroll = 0, // runtime variable used for how far down in the menu to start .state = 0, // bool used to know if this menu is focused, used at runtime .cursor = 0, // index of the option currently selected, used at runtime .options = &LcOptions_Main, // pointer to all of this menu's options .prev = 0, // pointer to previous menu, used at runtime }; // Init Function void Event_Init(GOBJ *gobj) { LCancelData *event_data = gobj->userdata; EventDesc *event_desc = event_data->event_desc; GOBJ *hmn = Fighter_GetGObj(0); FighterData *hmn_data = hmn->userdata; //GOBJ *cpu = Fighter_GetGObj(1); //FighterData *cpu_data = cpu->userdata; // theres got to be a better way to do this... event_vars = *event_vars_ptr; // get l-cancel assets event_data->lcancel_assets = File_GetSymbol(event_vars->event_archive, "lclData"); // create HUD LCancel_Init(event_data); // set CPU AI to no_act 15 //cpu_data->cpu.ai = 0; return; } // Think Function void Event_Think(GOBJ *event) { LCancelData *event_data = event->userdata; // get fighter data GOBJ *hmn = Fighter_GetGObj(0); FighterData *hmn_data = hmn->userdata; //GOBJ *cpu = Fighter_GetGObj(1); //FighterData *cpu_data = cpu->userdata; HSD_Pad *pad = PadGet(hmn_data->player_controller_number, PADGET_ENGINE); /* // give intangibility to cpu cpu_data->flags.no_reaction_always = 1; cpu_data->flags.nudge_disable = 1; Fighter_ApplyOverlay(cpu_data, 9, 0); Fighter_UpdateOverlay(cpu); cpu_data->dmg.percent = 0; Fighter_SetHUDDamage(cpu_data->ply, 0); // Move CPU if (pad->down == PAD_BUTTON_DPAD_DOWN) { // ensure player is grounded int is_ground = 0; if (hmn_data->phys.air_state == 0) { // check for ground in front of player Vec3 coll_pos; int line_index; int line_kind; Vec3 line_unk; float from_x = (hmn_data->phys.pos.X) + (hmn_data->facing_direction * 16); float to_x = from_x; float from_y = (hmn_data->phys.pos.Y + 5); float to_y = from_y - 10; is_ground = GrColl_RaycastGround(&coll_pos, &line_index, &line_kind, &line_unk, -1, -1, -1, 0, from_x, from_y, to_x, to_y, 0); if (is_ground == 1) { // do this for every subfighter (thanks for complicated code ice climbers) int is_moved = 0; for (int i = 0; i < 2; i++) { GOBJ *this_fighter = Fighter_GetSubcharGObj(cpu_data->ply, i); if (this_fighter != 0) { FighterData *this_fighter_data = this_fighter->userdata; if ((this_fighter_data->flags.sleep == 0) && (this_fighter_data->flags.dead == 0)) { is_moved = 1; // place CPU here this_fighter_data->phys.pos = coll_pos; this_fighter_data->coll_data.ground_index = line_index; // facing player this_fighter_data->facing_direction = hmn_data->facing_direction * -1; // update camera box Fighter_UpdateCameraBox(this_fighter); this_fighter_data->cameraBox->boundleft_curr = this_fighter_data->cameraBox->boundleft_proj; this_fighter_data->cameraBox->boundright_curr = this_fighter_data->cameraBox->boundright_proj; // set grounded this_fighter_data->phys.air_state = 0; //Fighter_SetGrounded(this_fighter); // kill velocity Fighter_KillAllVelocity(this_fighter); // enter wait Fighter_EnterWait(this_fighter); // update ECB this_fighter_data->coll_data.topN_Curr = this_fighter_data->phys.pos; // move current ECB location to new position Coll_ECBCurrToPrev(&this_fighter_data->coll_data); this_fighter_data->cb.Coll(this_fighter); // init CPU logic (for nana's popo position history...) int cpu_kind = Fighter_GetCPUKind(this_fighter_data->ply); int cpu_level = Fighter_GetCPULevel(this_fighter_data->ply); Fighter_CPUInitialize(this_fighter_data, cpu_kind, cpu_level, 0); // place subfighter in the Z axis if (this_fighter_data->flags.ms == 1) { ftCommonData *ft_common = *stc_ftcommon; this_fighter_data->phys.pos.Z = ft_common->ms_zjostle_max * -1; } } } } if (is_moved == 1) { // savestate event_vars->Savestate_Save(event_vars->savestate); } } } // play SFX if (is_ground == 0) { SFX_PlayCommon(3); } else { SFX_Play(221); } } */ LCancel_Think(event_data, hmn_data); Barrel_Think(event_data); return; } void Event_Exit() { Match *match = MATCH; // end game match->state = 3; // cleanup Match_EndVS(); // unfreeze HSD_Update *update = HSD_UPDATE; update->pause_develop = 0; return; } // L-Cancel functions void LCancel_Init(LCancelData *event_data) { // create hud cobj GOBJ *hudcam_gobj = GObj_Create(19, 20, 0); ArchiveInfo **ifall_archive = 0x804d6d5c; COBJDesc ***dmgScnMdls = File_GetSymbol(*ifall_archive, 0x803f94d0); COBJDesc *cam_desc = dmgScnMdls[1][0]; COBJ *hud_cobj = COBJ_LoadDesc(cam_desc); // init camera GObj_AddObject(hudcam_gobj, R13_U8(-0x3E55), hud_cobj); GOBJ_InitCamera(hudcam_gobj, LCancel_HUDCamThink, 7); hudcam_gobj->cobj_links = 1 << 18; GOBJ *hud_gobj = GObj_Create(0, 0, 0); event_data->hud.gobj = hud_gobj; // Load jobj JOBJ *hud_jobj = JOBJ_LoadJoint(event_data->lcancel_assets->hud); GObj_AddObject(hud_gobj, 3, hud_jobj); GObj_AddGXLink(hud_gobj, GXLink_Common, 18, 80); /* // account for widescreen float aspect = (hud_cobj->projection_param.perspective.aspect / 1.216667) - 1; JOBJ *this_jobj; JOBJ_GetChild(hud_jobj, &this_jobj, 1, -1); this_jobj->trans.X += (this_jobj->trans.X * aspect); JOBJ_SetMtxDirtySub(hud_jobj); */ // create text canvas int canvas = Text_CreateCanvas(2, hud_gobj, 14, 15, 0, 18, 81, 19); event_data->hud.canvas = canvas; // init text Text **text_arr = &event_data->hud.text_time; for (int i = 0; i < 3; i++) { // Create text object Text *hud_text = Text_CreateText(2, canvas); text_arr[i] = hud_text; hud_text->kerning = 1; hud_text->align = 1; hud_text->use_aspect = 1; // Get position Vec3 text_pos; JOBJ *text_jobj; JOBJ_GetChild(hud_jobj, &text_jobj, 2 + i, -1); JOBJ_GetWorldPosition(text_jobj, 0, &text_pos); // adjust scale Vec3 *scale = &hud_jobj->scale; // text scale hud_text->scale.X = (scale->X * 0.01) * LCLTEXT_SCALE; hud_text->scale.Y = (scale->Y * 0.01) * LCLTEXT_SCALE; hud_text->aspect.X = 165; // text position hud_text->trans.X = text_pos.X + (scale->X / 4.0); hud_text->trans.Y = (text_pos.Y * -1) + (scale->Y / 4.0); // dummy text Text_AddSubtext(hud_text, 0, 0, "-"); } // save initial arrow position JOBJ *arrow_jobj; JOBJ_GetChild(hud_jobj, &arrow_jobj, LCLARROW_JOBJ, -1); event_data->hud.arrow_base_x = arrow_jobj->trans.X; event_data->hud.arrow_timer = 0; arrow_jobj->trans.X = 0; JOBJ_SetFlags(arrow_jobj, JOBJ_HIDDEN); return 0; } void LCancel_Think(LCancelData *event_data, FighterData *hmn_data) { // run tip logic Tips_Think(event_data, hmn_data); JOBJ *hud_jobj = event_data->hud.gobj->hsd_object; // log fastfall frame // if im in a fastfall-able state int state = hmn_data->state; //if ((state == ASID_JUMPF) || (state == ASID_JUMPB) || (state == ASID_JUMPAERIALF) || (state == ASID_JUMPAERIALB) || (state == ASID_FALL) || (state == ASID_FALLAERIAL) || ((state >= ASID_ATTACKAIRN) && (state <= ASID_ATTACKAIRLW)) { if (hmn_data->phys.self_vel.Y < 0) // can i fastfall? { // did i fastfall yet? if (hmn_data->flags.is_fastfall) event_data->is_fastfall = 1; // set as fastfall this session else event_data->fastfall_frame++; // increment frames } else // cant fastfall, reset frames { event_data->fastfall_frame = 0; } } // if aerial landing if (((hmn_data->state >= ASID_LANDINGAIRN) && (hmn_data->state <= ASID_LANDINGAIRLW)) && (hmn_data->TM.state_frame == 0)) { // increment total lcls event_data->hud.lcl_total++; // determine succession int is_fail = 1; if (hmn_data->input.timer_trigger_any_ignore_hitlag < 7) { is_fail = 0; event_data->hud.lcl_success++; } event_data->is_fail = is_fail; // save l-cancel bool // Play appropriate sfx if (is_fail == 0) SFX_PlayRaw(303, 255, 128, 20, 3); else SFX_PlayCommon(3); // update timing text int frame_box_id; if (hmn_data->input.timer_trigger_any_ignore_hitlag >= 30) { // update text Text_SetText(event_data->hud.text_time, 0, "No Press"); frame_box_id = 29; } else { Text_SetText(event_data->hud.text_time, 0, "%df/7f", hmn_data->input.timer_trigger_any_ignore_hitlag + 1); frame_box_id = hmn_data->input.timer_trigger_any_ignore_hitlag; } // update arrow JOBJ *arrow_jobj; JOBJ_GetChild(hud_jobj, &arrow_jobj, LCLARROW_JOBJ, -1); event_data->hud.arrow_prevpos = arrow_jobj->trans.X; event_data->hud.arrow_nextpos = event_data->hud.arrow_base_x - (frame_box_id * LCLARROW_OFFSET); JOBJ_ClearFlags(arrow_jobj, JOBJ_HIDDEN); event_data->hud.arrow_timer = LCLARROW_ANIMFRAMES; // Print airborne frames if (event_data->is_fastfall) Text_SetText(event_data->hud.text_air, 0, "%df", event_data->fastfall_frame - 1); else Text_SetText(event_data->hud.text_air, 0, "-"); event_data->is_fastfall = 0; // reset fastfall bool // Print succession float succession = ((float)event_data->hud.lcl_success / (float)event_data->hud.lcl_total) * 100.0; Text_SetText(event_data->hud.text_scs, 0, "%.1f%%", succession); // Play HUD anim JOBJ_RemoveAnimAll(hud_jobj); JOBJ_AddAnimAll(hud_jobj, 0, event_data->lcancel_assets->hudmatanim[is_fail], 0); JOBJ_ReqAnimAll(hud_jobj, 0); } // if autocancel landing if (((hmn_data->state == ASID_LANDING) && (hmn_data->TM.state_frame == 0)) && // if first frame of landing ((hmn_data->TM.state_prev[0] >= ASID_ATTACKAIRN) && (hmn_data->state <= ASID_ATTACKAIRLW))) // came from aerial attack { // state as autocancelled Text_SetText(event_data->hud.text_time, 0, "Auto-canceled"); // Play HUD anim JOBJ_RemoveAnimAll(hud_jobj); JOBJ_AddAnimAll(hud_jobj, 0, event_data->lcancel_assets->hudmatanim[2], 0); JOBJ_ReqAnimAll(hud_jobj, 0); } // update arrow animation if (event_data->hud.arrow_timer > 0) { // decrement timer event_data->hud.arrow_timer--; // get this frames position float time = 1 - ((float)event_data->hud.arrow_timer / (float)LCLARROW_ANIMFRAMES); float xpos = Bezier(time, event_data->hud.arrow_prevpos, event_data->hud.arrow_nextpos); // update position JOBJ *arrow_jobj; JOBJ_GetChild(hud_jobj, &arrow_jobj, LCLARROW_JOBJ, -1); // get timing bar jobj arrow_jobj->trans.X = xpos; JOBJ_SetMtxDirtySub(arrow_jobj); } // update HUD anim JOBJ_AnimAll(hud_jobj); return; } void LCancel_HUDCamThink(GOBJ *gobj) { // if HUD enabled and not paused if ((LcOptions_Main[1].option_val == 0) && (Pause_CheckStatus(1) != 2)) { CObjThink_Common(gobj); } return; } // Tips Functions void Tips_Toggle(GOBJ *menu_gobj, int value) { // destroy existing tips when disabling if (value == 1) event_vars->Tip_Destroy(); return; } void Tips_Think(LCancelData *event_data, FighterData *hmn_data) { if (LcOptions_Main[2].option_val == 0) { // shield tip if (event_data->tip.shield_isdisp == 0) // if not shown { // update tip conditions // look for a freshly buffered guard off if (((hmn_data->state == ASID_GUARDOFF) && (hmn_data->TM.state_frame == 0)) && // currently in guardoff first frame (hmn_data->TM.state_prev[0] == ASID_GUARD) && // was just in wait ((hmn_data->TM.state_prev[3] >= ASID_LANDINGAIRN) && (hmn_data->TM.state_prev[3] <= ASID_LANDINGAIRLW))) // was in aerial landing a few frames ago { // increment condition count event_data->tip.shield_num++; // if condition met X times, show tip if (event_data->tip.shield_num >= 3) { // display tip char *shield_string = "Tip:\nDon't hold the trigger! Quickly \npress and release to prevent \nshielding after landing."; if (event_vars->Tip_Display(5 * 60, shield_string)) { // set as shown //event_data->tip.shield_isdisp = 1; event_data->tip.shield_num = 0; } } } } // hitbox tip if (event_data->tip.hitbox_isdisp == 0) // if not shown { // update hitbox active bool if ((hmn_data->state >= ASID_ATTACKAIRN) && (hmn_data->state <= ASID_ATTACKAIRLW)) // check if currently in aerial attack) // check if in first frame of aerial attack { // reset hitbox bool on first frame of aerial attack if (hmn_data->TM.state_frame == 0) event_data->tip.hitbox_active = 0; // check if hitbox active for (int i = 0; i < (sizeof(hmn_data->hitbox) / sizeof(ftHit)); i++) { if (hmn_data->hitbox[i].active != 0) { event_data->tip.hitbox_active = 1; break; } } } // update tip conditions if ((hmn_data->state >= ASID_LANDINGAIRN) && (hmn_data->state <= ASID_LANDINGAIRLW) && (hmn_data->TM.state_frame == 0) && // is in aerial landing (event_data->is_fail == 0) && (event_data->tip.hitbox_active == 0)) // succeeded the last aerial landing { // increment condition count event_data->tip.hitbox_num++; // if condition met X times, show tip if (event_data->tip.hitbox_num >= 3) { // display tip char *hitbox_string = "Tip:\nDon't land too quickly! Make \nsure you land after the \nattack becomes active."; if (event_vars->Tip_Display(5 * 60, hitbox_string)) { // set as shown //event_data->tip.hitbox_isdisp = 1; event_data->tip.hitbox_num = 0; } } } } // fastfall tip if (event_data->tip.fastfall_isdisp == 0) // if not shown { // update fastfell bool if ((hmn_data->state >= ASID_ATTACKAIRN) && (hmn_data->state <= ASID_ATTACKAIRLW)) // check if currently in aerial attack) // check if in first frame of aerial attack { // reset hitbox bool on first frame of aerial attack if (hmn_data->TM.state_frame == 0) event_data->tip.fastfall_active = 0; // check if fastfalling if (hmn_data->flags.is_fastfall == 1) event_data->tip.fastfall_active = 1; } // update tip conditions if ((hmn_data->state >= ASID_LANDINGAIRN) && (hmn_data->state <= ASID_LANDINGAIRLW) && (hmn_data->TM.state_frame == 0) && // is in aerial landing ((hmn_data->input.timer_trigger_any_ignore_hitlag >= 7) && (hmn_data->input.timer_trigger_any_ignore_hitlag <= 15)) && // was early for an l-cancel (event_data->tip.fastfall_active == 0)) // succeeded the last aerial landing { // increment condition count event_data->tip.fastfall_num++; // if condition met X times, show tip if (event_data->tip.fastfall_num >= 3) { // display tip char *fastfall_string = "Tip:\nDon't forget to fastfall!\nIt will let you act sooner \nand help with your \ntiming."; if (event_vars->Tip_Display(5 * 60, fastfall_string)) { // set as shown //event_data->tip.hitbox_isdisp = 1; event_data->tip.fastfall_num = 0; } } } } // late tip if (event_data->tip.late_isdisp == 0) // if not shown { // update tip conditions if ((hmn_data->state >= ASID_LANDINGAIRN) && (hmn_data->state <= ASID_LANDINGAIRLW) && // is in aerial landing (event_data->is_fail == 1) && // failed the l-cancel (hmn_data->input.down & (HSD_TRIGGER_L | HSD_TRIGGER_R | HSD_TRIGGER_Z))) // was late for an l-cancel by pressing it just now { // increment condition count event_data->tip.late_num++; // if condition met X times, show tip if (event_data->tip.late_num >= 3) { // display tip char *late_string = "Tip:\nTry pressing the trigger a\nbit earlier, before the\nfighter lands."; if (event_vars->Tip_Display(5 * 60, late_string)) { // set as shown //event_data->tip.hitbox_isdisp = 1; event_data->tip.late_num = 0; } } } } } return; } // Barrel Functions void Barrel_Think(LCancelData *event_data) { GOBJ *barrel_gobj = event_data->barrel_gobj; switch (LcOptions_Main[0].option_val) { case (0): // off { // if spawned, remove if (barrel_gobj != 0) { Item_Destroy(barrel_gobj); event_data->barrel_gobj = 0; } break; } case (1): // stationary { // if not spawned, spawn if (barrel_gobj == 0) { // spawn barrel at center stage barrel_gobj = Barrel_Spawn(0); event_data->barrel_gobj = barrel_gobj; } ItemData *barrel_data = barrel_gobj->userdata; barrel_data->can_hold = 0; // check to move barrel // get fighter data GOBJ *hmn = Fighter_GetGObj(0); FighterData *hmn_data = hmn->userdata; if (hmn_data->input.down & PAD_BUTTON_DPAD_DOWN) { // ensure player is grounded int isGround = 0; if (hmn_data->phys.air_state == 0) { // check for ground in front of player Vec3 coll_pos; int line_index; int line_kind; Vec3 line_unk; float fromX = (hmn_data->phys.pos.X) + (hmn_data->facing_direction * 16); float toX = fromX; float fromY = (hmn_data->phys.pos.Y + 5); float toY = fromY - 10; isGround = GrColl_RaycastGround(&coll_pos, &line_index, &line_kind, &line_unk, -1, -1, -1, 0, fromX, fromY, toX, toY, 0); if (isGround == 1) { // update last pos event_data->barrel_lastpos = coll_pos; // place barrel here barrel_data->pos = coll_pos; barrel_data->coll_data.ground_index = line_index; // update ECB barrel_data->coll_data.topN_Curr = barrel_data->pos; // move current ECB location to new position Coll_ECBCurrToPrev(&barrel_data->coll_data); barrel_data->cb.coll(barrel_gobj); SFX_Play(221); } else { // play SFX SFX_PlayCommon(3); } } break; } } case (2): // move { // if not spawned, spawn if (barrel_gobj == 0) { // spawn barrel at center stage barrel_gobj = Barrel_Spawn(1); event_data->barrel_gobj = barrel_gobj; } ItemData *barrel_data = barrel_gobj->userdata; barrel_data->can_hold = 0; barrel_data->can_nudge = 0; break; } } return; } GOBJ *Barrel_Spawn(int pos_kind) { LCancelData *event_data = event_vars->event_gobj->userdata; Vec3 *barrel_lastpos = &event_data->barrel_lastpos; // determine position to spawn Vec3 pos; pos.Z = 0; switch (pos_kind) { case (0): // center stage { // get position int line_index; int line_kind; Vec3 line_angle; float from_x = 0; float to_x = from_x; float from_y = 6; float to_y = from_y - 1000; int is_ground = GrColl_RaycastGround(&pos, &line_index, &line_kind, &line_angle, -1, -1, -1, 0, from_x, from_y, to_x, to_y, 0); if (is_ground == 0) goto BARREL_RANDPOS; break; } case (1): // random pos { // setup time int raycast_num = 0; int raytime_start, raytime_end, raytime_time; raytime_start = OSGetTick(); BARREL_RANDPOS: { // get position int line_index; int line_kind; Vec3 line_angle; float from_x = Stage_GetCameraLeft() + (HSD_Randi(Stage_GetCameraRight() - Stage_GetCameraLeft())) + HSD_Randf(); float to_x = from_x; float from_y = Stage_GetCameraBottom() + (HSD_Randi(Stage_GetCameraTop() - Stage_GetCameraBottom())) + HSD_Randf(); float to_y = from_y - 1000; int is_ground = GrColl_RaycastGround(&pos, &line_index, &line_kind, &line_angle, -1, -1, -1, 0, from_x, from_y, to_x, to_y, 0); raycast_num++; if (is_ground == 0) goto BARREL_RANDPOS; // ensure it isnt too close to the previous float distance = sqrtf(pow((pos.X - barrel_lastpos->X), 2) + pow((pos.Y - barrel_lastpos->Y), 2)); if (distance < 25) goto BARREL_RANDPOS; // ensure left and right have ground Vec3 near_pos; float near_fromX = pos.X + 8; float near_fromY = pos.Y + 4; to_y = near_fromY - 4; is_ground = GrColl_RaycastGround(&near_pos, &line_index, &line_kind, &line_angle, -1, -1, -1, 0, near_fromX, near_fromY, near_fromX, to_y, 0); raycast_num++; if (is_ground == 0) goto BARREL_RANDPOS; near_fromX = pos.X - 8; is_ground = GrColl_RaycastGround(&near_pos, &line_index, &line_kind, &line_angle, -1, -1, -1, 0, near_fromX, near_fromY, near_fromX, to_y, 0); raycast_num++; if (is_ground == 0) goto BARREL_RANDPOS; // output num and time raytime_end = OSGetTick(); raytime_time = OSTicksToMilliseconds(raytime_end - raytime_start); OSReport("lcl: %d ray in %dms\n", raycast_num, raytime_time); break; } } } // spawn item SpawnItem spawnItem; spawnItem.parent_gobj = 0; spawnItem.parent_gobj2 = 0; spawnItem.it_kind = ITEM_BARREL; spawnItem.hold_kind = 0; spawnItem.unk2 = 0; spawnItem.pos = pos; spawnItem.pos2 = pos; spawnItem.vel.X = 0; spawnItem.vel.Y = 0; spawnItem.vel.Z = 0; spawnItem.facing_direction = 1; spawnItem.damage = 0; spawnItem.unk5 = 0; spawnItem.unk6 = 0; spawnItem.unk7 = 0x80; spawnItem.is_spin = 0; GOBJ *barrel_gobj = Item_CreateItem2(&spawnItem); Item_CollAir(barrel_gobj, Barrel_Null); // replace collision callback ItemData *barrel_data = barrel_gobj->userdata; barrel_data->it_cb = item_callbacks; barrel_data->camerabox->kind = 0; // update last barrel pos event_data->barrel_lastpos = pos; return barrel_gobj; } void Barrel_Null() { return; } void Barrel_Break(GOBJ *barrel_gobj) { ItemData *barrel_data = barrel_gobj->userdata; Effect_SpawnSync(1063, barrel_gobj, &barrel_data->pos); SFX_Play(251); ScreenRumble_Execute(2, &barrel_data->pos); JOBJ *barrel_jobj = barrel_gobj->hsd_object; JOBJ_SetFlagsAll(barrel_jobj, JOBJ_HIDDEN); barrel_data->xd0c = 2; barrel_data->self_vel.X = 0; barrel_data->self_vel.Y = 0; barrel_data->itemVar1 = 1; barrel_data->itemVar2 = 40; barrel_data->xdcf3 = 1; ItemStateChange(barrel_gobj, 7, 2); return; } int Barrel_OnHurt(GOBJ *barrel_gobj) { // get event data LCancelData *event_data = event_vars->event_gobj->userdata; switch (LcOptions_Main[0].option_val) { case (0): // off { break; } case (1): // stationary { break; } case (2): // move { // Break this barrel Barrel_Break(event_data->barrel_gobj); // spawn new barrel at a random position barrel_gobj = Barrel_Spawn(1); event_data->barrel_gobj = barrel_gobj; break; } } return 0; } int Barrel_OnDestroy(GOBJ *barrel_gobj) { // get event data LCancelData *event_data = event_vars->event_gobj->userdata; // if this barrel is still the current barrel if (barrel_gobj == event_data->barrel_gobj) event_data->barrel_gobj = 0; return 0; } static void *item_callbacks[] = { 0x803f58e0, 0x80287458, Barrel_OnDestroy, // onDestroy 0x80287e68, 0x80287ea8, 0x80287ec8, 0x80288818, Barrel_OnHurt, // onhurt 0x802889f8, 0x802888b8, 0x00000000, 0x00000000, 0x80288958, 0x80288c68, 0x803f5988, }; // Misc float Bezier(float time, float start, float end) { float bez = time * time * (3.0f - 2.0f * time); return bez * (end - start) + start; } // Initial Menu static EventMenu *Event_Menu = &LabMenu_Main; ================================================ FILE: patch/events/lcancel/source/lcancel.h ================================================ #include "../../../../MexTK/mex.h" #include "../../../tmdata/source/events.h" typedef struct LCancelData LCancelData; typedef struct LCancelAssets LCancelAssets; struct LCancelData { EventDesc *event_desc; LCancelAssets *lcancel_assets; GOBJ *barrel_gobj; Vec3 barrel_lastpos; u8 is_fail; // status of the last l-cancel u8 is_fastfall; // bool used to detect fastfall frame u8 fastfall_frame; // frame the player fastfell on struct { GOBJ *gobj; u16 lcl_success; u16 lcl_total; Text *text_time; Text *text_air; Text *text_scs; int canvas; float arrow_base_x; // starting X position of arrow float arrow_prevpos; float arrow_nextpos; int arrow_timer; } hud; struct { u8 shield_isdisp; // whether tip has been shown to the player u8 shield_num; // number of times condition has been met u8 hitbox_active; // whether or not the last aerial used had a hitbox active u8 hitbox_isdisp; // whether tip has been shown to the player u8 hitbox_num; // number of times condition has been met u8 fastfall_active; // whether or not the last aerial used had a hitbox active u8 fastfall_isdisp; // whether tip has been shown to the player u8 fastfall_num; // number of times condition has been met u8 late_isdisp; // whether tip has been shown to the player u8 late_num; // number of times condition has been met } tip; }; typedef struct LCancelAssets { JOBJ *hud; void **hudmatanim; // pointer to array }; #define LCLTEXT_SCALE 4.2 #define LCLARROW_ANIMFRAMES 4 #define LCLARROW_JOBJ 7 #define LCLARROW_OFFSET 0.365 static void *item_callbacks[]; float Bezier(float time, float start, float end); void Tips_Toggle(GOBJ *menu_gobj, int value); void LCancel_HUDCamThink(GOBJ *gobj); void Barrel_Think(LCancelData *event_data); void Barrel_Toggle(GOBJ *menu_gobj, int value); GOBJ *Barrel_Spawn(int pos_kind); void Barrel_Null(); void Event_Exit(); ================================================ FILE: patch/events/ledgedash/build.bat ================================================ xcopy /s /y "assets\ldshData.dat" "output/EvLdsh.dat" "../../../MexTK/MexTK.exe" -ff -i "source/ledgedash.c" -s evFunction -dat "output/EvLdsh.dat" -t "../../../MexTK/evFunction.txt" -q -ow -w -c -l "../../../MexTK/melee.link" -op 1 "../../../MexTK/MexTK.exe" -trim "output/EvLdsh.dat" pause ================================================ FILE: patch/events/ledgedash/source/ledgedash.c ================================================ #include "ledgedash.h" static char nullString[] = " "; static GXColor tmgbar_black = {40, 40, 40, 255}; static GXColor tmgbar_grey = {80, 80, 80, 255}; static GXColor tmgbar_blue = {128, 128, 255, 255}; static GXColor tmgbar_green = {128, 255, 128, 255}; static GXColor tmgbar_yellow = {255, 255, 128, 255}; static GXColor tmgbar_red = {255, 128, 128, 255}; static GXColor tmgbar_indigo = {255, 128, 255, 255}; static GXColor tmgbar_white = {255, 255, 255, 255}; static GXColor *tmgbar_colors[] = { &tmgbar_black, &tmgbar_grey, &tmgbar_green, &tmgbar_yellow, &tmgbar_indigo, &tmgbar_white, &tmgbar_red, }; // Main Menu static char **LdshOptions_Start[] = {"Ledge", "Respawn Platform"}; static char **LdshOptions_Reset[] = {"On", "Off"}; static char **LdshOptions_HUD[] = {"On", "Off"}; static EventOption LdshOptions_Main[] = { // Position { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integers list, etc .value_num = sizeof(LdshOptions_Start) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Starting Position", // pointer to a string .desc = "Choose where the fighter is placed \nafter resetting positions.", // string describing what this option does .option_values = LdshOptions_Start, // pointer to an array of strings .onOptionChange = Ledgedash_ToggleStartPosition, }, // Reset { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integers list, etc .value_num = sizeof(LdshOptions_Reset) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Auto-Reset", // pointer to a string .desc = "Toggle the automatic resetting of the \nfighter's position after ledgedash attempts.", // string describing what this option does .option_values = LdshOptions_Reset, // pointer to an array of strings .onOptionChange = Ledgedash_ToggleAutoReset, }, // HUD { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integers list, etc .value_num = sizeof(LdshOptions_HUD) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "HUD", // pointer to a string .desc = "Toggle visibility of the HUD.", // string describing what this option does .option_values = LdshOptions_HUD, // pointer to an array of strings .onOptionChange = 0, }, // Tips { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integers list, etc .value_num = sizeof(LdshOptions_HUD) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Tips", // pointer to a string .desc = "Toggle the onscreen display of tips.", // string describing what this option does .option_values = LdshOptions_HUD, // pointer to an array of strings .onOptionChange = Tips_Toggle, }, // Help { .option_kind = OPTKIND_FUNC, // the type of option this is; menu, string list, integers list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "About", // pointer to a string .desc = "Ledgedashing is the act of wavedashing onto stage from ledge.\nThis is most commonly done by dropping off ledge, double jumping \nimmediately, and quickly airdodging onto stage. Each input \nis performed quickly after the last, making it difficult and risky.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = 0, }, // Exit { .option_kind = OPTKIND_FUNC, // the type of option this is; menu, string list, integers list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Exit", // pointer to a string .desc = "Return to the Event Selection Screen.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = 0, .onOptionSelect = Event_Exit, }, }; static EventMenu LdshMenu_Main = { .name = "Ledgedash Training", // the name of this menu .option_num = sizeof(LdshOptions_Main) / sizeof(EventOption), // number of options this menu contains .scroll = 0, // runtime variable used for how far down in the menu to start .state = 0, // bool used to know if this menu is focused, used at runtime .cursor = 0, // index of the option currently selected, used at runtime .options = &LdshOptions_Main, // pointer to all of this menu's options .prev = 0, // pointer to previous menu, used at runtime }; // Init Function void Event_Init(GOBJ *gobj) { LedgedashData *event_data = gobj->userdata; // theres got to be a better way to do this... event_vars = *event_vars_ptr; // get assets event_data->assets = File_GetSymbol(event_vars->event_archive, "ldshData"); // standardize camera Stage *stage = stc_stage; float *unk_cam = 0x803bcca0; stc_stage->fov_r = 0; // no camera rotation stc_stage->x28 = 1; // pan value? stc_stage->x2c = 1; // pan value? stc_stage->x30 = 1; // pan value? stc_stage->x34 = 130; // zoom out unk_cam[0x40 / 4] = 30; // Init hitlog event_data->hitlog_gobj = Ledgedash_HitLogInit(); // Init HUD Ledgedash_HUDInit(event_data); // Init Fighter Ledgedash_FtInit(event_data); return; } // Think Function void Event_Think(GOBJ *event) { LedgedashData *event_data = event->userdata; // get fighter data GOBJ *hmn = Fighter_GetGObj(0); FighterData *hmn_data = hmn->userdata; HSD_Pad *pad = PadGet(hmn_data->player_controller_number, PADGET_ENGINE); // no ledgefall FtCliffCatch *ft_state = &hmn_data->state_var; if (hmn_data->state == ASID_CLIFFWAIT) ft_state->fall_timer = 2; Ledgedash_HUDThink(event_data, hmn_data); Ledgedash_HitLogThink(event_data, hmn); Ledgedash_ResetThink(event_data, hmn); Ledgedash_ChangeLedgeThink(event_data, hmn); return; } void Event_Exit() { Match *match = MATCH; // end game match->state = 3; // cleanup Match_EndVS(); // unfreeze HSD_Update *update = HSD_UPDATE; update->pause_develop = 0; return; } // Ledgedash functions void Ledgedash_HUDInit(LedgedashData *event_data) { // create hud cobj GOBJ *hudcam_gobj = GObj_Create(19, 20, 0); ArchiveInfo **ifall_archive = 0x804d6d5c; COBJDesc ***dmgScnMdls = File_GetSymbol(*ifall_archive, 0x803f94d0); COBJDesc *cam_desc = dmgScnMdls[1][0]; COBJ *hud_cobj = COBJ_LoadDesc(cam_desc); // init camera GObj_AddObject(hudcam_gobj, R13_U8(-0x3E55), hud_cobj); GOBJ_InitCamera(hudcam_gobj, Ledgedash_HUDCamThink, 7); hudcam_gobj->cobj_links = 1 << 18; GOBJ *hud_gobj = GObj_Create(0, 0, 0); event_data->hud.gobj = hud_gobj; // Load jobj JOBJ *hud_jobj = JOBJ_LoadJoint(event_data->assets->hud); GObj_AddObject(hud_gobj, 3, hud_jobj); GObj_AddGXLink(hud_gobj, GXLink_Common, 18, 80); // account for widescreen /* float aspect = (hud_cobj->projection_param.perspective.aspect / 1.216667) - 1; JOBJ *this_jobj; JOBJ_GetChild(hud_jobj, &this_jobj, 1, -1); this_jobj->trans.X += (this_jobj->trans.X * aspect); JOBJ_SetMtxDirtySub(hud_jobj); */ // create text canvas int canvas = Text_CreateCanvas(2, hud_gobj, 14, 15, 0, 18, 81, 19); event_data->hud.canvas = canvas; // init text Text **text_arr = &event_data->hud.text_angle; for (int i = 0; i < 2; i++) { // Create text object Text *hud_text = Text_CreateText(2, canvas); text_arr[i] = hud_text; hud_text->kerning = 1; hud_text->align = 1; hud_text->use_aspect = 1; // Get position Vec3 text_pos; JOBJ *text_jobj; JOBJ_GetChild(hud_jobj, &text_jobj, 2 + i, -1); JOBJ_GetWorldPosition(text_jobj, 0, &text_pos); // adjust scale Vec3 *scale = &hud_jobj->scale; // text scale hud_text->scale.X = (scale->X * 0.01) * LCLTEXT_SCALE; hud_text->scale.Y = (scale->Y * 0.01) * LCLTEXT_SCALE; hud_text->aspect.X = 165; // text position hud_text->trans.X = text_pos.X + (scale->X / 4.0); hud_text->trans.Y = (text_pos.Y * -1) + (scale->Y / 4.0); // dummy text Text_AddSubtext(hud_text, 0, 0, "-"); } // reset all bar colors JOBJ *timingbar_jobj; JOBJ_GetChild(hud_jobj, &timingbar_jobj, LCLJOBJ_BAR, -1); // get timing bar jobj DOBJ *d = timingbar_jobj->dobj; int count = 0; while (d != 0) { // if a box dobj if ((count >= 0) && (count < 30)) { // if mobj exists (it will) MOBJ *m = d->mobj; if (m != 0) { HSD_Material *mat = m->mat; // set alpha mat->alpha = 0.7; // set color mat->diffuse = tmgbar_black; } } // inc count++; d = d->next; } return 0; } void Ledgedash_HUDThink(LedgedashData *event_data, FighterData *hmn_data) { // run tip logic Tips_Think(event_data, hmn_data); JOBJ *hud_jobj = event_data->hud.gobj->hsd_object; // only run logic if ledge exists if (event_data->ledge_line != -1) { // increment timer event_data->hud.timer++; // check to initialize timer if ((hmn_data->state == ASID_CLIFFWAIT) && (hmn_data->TM.state_frame == 1)) { Ledgedash_InitVariables(event_data); event_data->tip.refresh_num++; } int curr_frame = event_data->hud.timer; // update action log if (curr_frame < (sizeof(event_data->hud.action_log) / sizeof(u8))) { // look for cliffwait if (hmn_data->state == ASID_CLIFFWAIT) { event_data->hud.action_log[curr_frame] = LDACT_CLIFFWAIT; } // look for release else if (hmn_data->state == ASID_FALL) { event_data->hud.is_release = 1; event_data->hud.action_log[curr_frame] = LDACT_FALL; } // look for jump else if ((hmn_data->state == ASID_JUMPAERIALF) || (hmn_data->state == ASID_JUMPAERIALB) || (((hmn_data->kind == 4) || (hmn_data->kind == 15)) && ((hmn_data->state >= 341) && (hmn_data->state <= 345)))) // check for kirby and jiggs jump { event_data->hud.is_jump = 1; event_data->hud.action_log[curr_frame] = LDACT_JUMP; } // look for airdodge else if (hmn_data->state == ASID_ESCAPEAIR) { //event_data->hud.is_airdodge = 1; event_data->hud.action_log[curr_frame] = LDACT_AIRDODGE; } // look for aerial else if (hmn_data->attack_kind != 1) { event_data->hud.is_aerial = 1; event_data->hud.action_log[curr_frame] = LDACT_ATTACK; } // look for land else if (((hmn_data->state == ASID_LANDING) || (hmn_data->state == ASID_LANDINGFALLSPECIAL)) || ((hmn_data->state == ASID_WAIT) && (hmn_data->TM.state_frame == 0) && ((hmn_data->TM.state_prev != ASID_LANDING) || (hmn_data->TM.state_prev != ASID_LANDINGFALLSPECIAL)))) // this is first frame of a no impact land { event_data->hud.is_land = 1; event_data->hud.action_log[curr_frame] = LDACT_LANDING; } } // grab airdodge angle if (event_data->hud.is_airdodge == 0) { if ((hmn_data->state == ASID_ESCAPEAIR) || (hmn_data->TM.state_prev[0] == ASID_ESCAPEAIR)) { // determine airdodge angle float angle = atan2(hmn_data->input.lstick_y, hmn_data->input.lstick_x) - -(M_PI / 2); // save airdodge angle event_data->hud.airdodge_angle = angle; event_data->hud.is_airdodge = 1; } } // look for actionable if (((event_data->hud.is_actionable == 0) && (event_data->hud.is_release == 1)) && (((((hmn_data->state == ASID_WAIT) && ((hmn_data->TM.state_prev[0] != ASID_LANDING) || (hmn_data->TM.state_prev[0] != ASID_LANDINGFALLSPECIAL)) && (hmn_data->TM.state_frame > 0)) || (hmn_data->TM.state_prev[0] == ASID_WAIT)) && (hmn_data->TM.state_frame <= 1)) || // prev frame too cause you can attack on the same frame ((hmn_data->state == ASID_LANDING) && (hmn_data->TM.state_frame >= hmn_data->attr.normal_landing_lag)) || ((hmn_data->TM.state_prev[0] == ASID_LANDING) && (hmn_data->TM.state_prev_frames[0] >= hmn_data->attr.normal_landing_lag)))) { event_data->hud.is_actionable = 1; event_data->hud.actionable_frame = event_data->hud.timer; // destroy any tips event_vars->Tip_Destroy(); // update bar colors JOBJ *timingbar_jobj; JOBJ_GetChild(hud_jobj, &timingbar_jobj, LCLJOBJ_BAR, -1); // get timing bar jobj DOBJ *d = timingbar_jobj->dobj; int count = 0; while (d != 0) { // if a box dobj if ((count >= 0) && (count < 30)) { // if mobj exists (it will) MOBJ *m = d->mobj; if (m != 0) { HSD_Material *mat = m->mat; int this_frame = 29 - count; GXColor *bar_color; // check if GALINT frame if ((this_frame >= curr_frame) && ((this_frame <= (curr_frame + hmn_data->hurtstatus.ledge_intang_left)))) bar_color = &tmgbar_blue; else bar_color = tmgbar_colors[event_data->hud.action_log[this_frame]]; mat->diffuse = *bar_color; } } // inc count++; d = d->next; } // output remaining airdodge angle if (event_data->hud.is_airdodge == 1) Text_SetText(event_data->hud.text_angle, 0, "%.2f", fabs(event_data->hud.airdodge_angle / M_1DEGREE)); else Text_SetText(event_data->hud.text_angle, 0, "-"); // output remaining GALINT void *matanim; Text *text_galint = event_data->hud.text_galint; if (hmn_data->hurtstatus.ledge_intang_left > 0) { SFX_Play(303); matanim = event_data->assets->hudmatanim[0]; Text_SetText(text_galint, 0, "%df", hmn_data->hurtstatus.ledge_intang_left); } else if (hmn_data->TM.vuln_frames < 25) { matanim = event_data->assets->hudmatanim[1]; Text_SetText(text_galint, 0, "-%df", hmn_data->TM.vuln_frames); } else { matanim = event_data->assets->hudmatanim[1]; Text_SetText(text_galint, 0, "-"); } // init hitbox num LdshHitlogData *hitlog_data = event_data->hitlog_gobj->userdata; hitlog_data->num = 0; // apply HUD animation JOBJ_RemoveAnimAll(hud_jobj); JOBJ_AddAnimAll(hud_jobj, 0, matanim, 0); JOBJ_ReqAnimAll(hud_jobj, 0); } } // update HUD anim JOBJ_AnimAll(hud_jobj); return; } void Ledgedash_HUDCamThink(GOBJ *gobj) { // if HUD enabled and not paused if ((LdshOptions_Main[2].option_val == 0) && (Pause_CheckStatus(1) != 2)) { CObjThink_Common(gobj); } return; } void Ledgedash_ResetThink(LedgedashData *event_data, GOBJ *hmn) { FighterData *hmn_data = hmn->userdata; JOBJ *hud_jobj = event_data->hud.gobj->hsd_object; // check if enabled and ledge exists if ((LdshOptions_Main[1].option_val == 0) && (event_data->ledge_line != -1)) { // check if reset timer is set if (event_data->reset_timer > 0) { // decrement reset timer event_data->reset_timer--; // if reset timer is up, go back to ledge if (event_data->reset_timer == 0) { Fighter_PlaceOnLedge(event_data, hmn, event_data->ledge_line, (float)event_data->ledge_dir); } } // check to set reset timner else if (event_data->hud.is_actionable) { event_data->reset_timer = 30; } else { int state = hmn_data->state; // reset actions if ((hmn_data->flags.dead == 1) || // if dead ((hmn_data->state == ASID_ESCAPEAIR) && (hmn_data->TM.state_frame >= 9)) || // missed airdodge ((((state >= ASID_CLIFFCLIMBSLOW) && (state <= ASID_CLIFFJUMPQUICK2)) || // reset if any other ledge action ((state >= ASID_ATTACKAIRN) && (state <= ASID_ATTACKAIRLW)) || ((hmn_data->phys.air_state == 0) && ((state != ASID_LANDING) && (state != ASID_LANDINGFALLSPECIAL) && (state != ASID_REBIRTHWAIT)))) && // reset if grounded non landing (hmn_data->TM.state_frame >= 7))) { // reset and play sfx Fighter_PlaceOnLedge(event_data, hmn, event_data->ledge_line, (float)event_data->ledge_dir); SFX_PlayCommon(3); } } } return; } void Ledgedash_InitVariables(LedgedashData *event_data) { event_data->hud.timer = 0; event_data->tip.is_input_release = 0; event_data->tip.is_input_jump = 0; event_data->tip.refresh_displayed = 0; event_data->hud.is_release = 0; event_data->hud.is_jump = 0; event_data->hud.is_airdodge = 0; event_data->hud.is_aerial = 0; event_data->hud.is_land = 0; event_data->hud.is_actionable = 0; // init action log for (int i = 0; i < sizeof(event_data->hud.action_log) / sizeof(u8); i++) { event_data->hud.action_log[i] = 0; } } // Menu Toggle functions void Ledgedash_ToggleStartPosition(GOBJ *menu_gobj, int value) { // get fighter data GOBJ *hmn = Fighter_GetGObj(0); LedgedashData *event_data = event_vars->event_gobj->userdata; Fighter_PlaceOnLedge(event_data, hmn, event_data->ledge_line, (float)event_data->ledge_dir); return; } void Ledgedash_ToggleAutoReset(GOBJ *menu_gobj, int value) { LedgedashData *event_data = event_vars->event_gobj->userdata; // enable camera if (value == 0) event_data->cam->kind = 0; // disable camera else event_data->cam->kind = 1; return; } // Hitlog functions GOBJ *Ledgedash_HitLogInit() { GOBJ *hit_gobj = GObj_Create(0, 0, 0); LdshHitlogData *hit_data = calloc(sizeof(LdshHitlogData)); GObj_AddUserData(hit_gobj, 4, HSD_Free, hit_data); GObj_AddGXLink(hit_gobj, Ledgedash_HitLogGX, 5, 0); // init array hit_data->num = 0; return hit_gobj; } void Ledgedash_HitLogThink(LedgedashData *event_data, GOBJ *hmn) { FighterData *hmn_data = hmn->userdata; LdshHitlogData *hitlog_data = event_data->hitlog_gobj->userdata; // log hitboxes if ((event_data->hud.is_actionable == 1) && (hmn_data->hurtstatus.ledge_intang_left > 0)) { // iterate through fighter hitboxes for (int i = 0; i < sizeof(hmn_data->hitbox) / sizeof(ftHit); i++) { ftHit *this_hit = &hmn_data->hitbox[i]; if ((this_hit->active != 0) && // if hitbox is active (hitlog_data->num < LDSH_HITBOXNUM)) // if not over max { // log info LdshHitboxData *this_ldsh_hit = &hitlog_data->hitlog[hitlog_data->num]; this_ldsh_hit->size = this_hit->size; this_ldsh_hit->pos_curr = this_hit->pos; this_ldsh_hit->pos_prev = this_hit->pos_prev; this_ldsh_hit->kind = this_hit->attribute; // increment hitboxes hitlog_data->num++; } } // iterate through items belonging to fighter GOBJList *gobj_list = *stc_gobj_list; GOBJ *this_item = gobj_list->item; while (this_item != 0) { ItemData *this_itemdata = this_item->userdata; // ensure belongs to the fighter if (this_itemdata->fighter == hmn) { // iterate through item hitboxes for (int i = 0; i < sizeof(hmn_data->hitbox) / sizeof(ftHit); i++) { itHit *this_hit = &this_itemdata->hitbox[i]; if ((this_hit->active != 0) && // if hitbox is active (hitlog_data->num < LDSH_HITBOXNUM)) // if not over max { // log info LdshHitboxData *this_ldsh_hit = &hitlog_data->hitlog[hitlog_data->num]; this_ldsh_hit->size = this_hit->size; this_ldsh_hit->pos_curr = this_hit->pos; this_ldsh_hit->pos_prev = this_hit->pos_prev; this_ldsh_hit->kind = this_hit->attribute; // increment hitboxes hitlog_data->num++; } } } this_item = this_item->next; } } return; } void Ledgedash_HitLogGX(GOBJ *gobj, int pass) { static GXColor hitlog_ambient = {128, 0, 0, 50}; static GXColor hit_diffuse = {255, 99, 99, 50}; static GXColor grab_diffuse = {255, 0, 255, 50}; static GXColor detect_diffuse = {255, 255, 255, 50}; LdshHitlogData *hitlog_data = gobj->userdata; for (int i = 0; i < hitlog_data->num; i++) { LdshHitboxData *this_ldsh_hit = &hitlog_data->hitlog[i]; // determine color GXColor *diffuse, *ambient; if (this_ldsh_hit->kind == 0) diffuse = &hit_diffuse; else if (this_ldsh_hit->kind == 8) diffuse = &grab_diffuse; else if (this_ldsh_hit->kind == 11) diffuse = &detect_diffuse; else diffuse = &hit_diffuse; Develop_DrawSphere(this_ldsh_hit->size, &this_ldsh_hit->pos_curr, &this_ldsh_hit->pos_prev, diffuse, &hitlog_ambient); } return; } // Fighter fuctions void Ledgedash_FtInit(LedgedashData *event_data) { GOBJ *hmn = Fighter_GetGObj(0); FighterData *hmn_data = hmn->userdata; // create camera box CameraBox *cam = CameraBox_Alloc(); cam->boundleft_proj = -10; cam->boundright_proj = 10; cam->boundtop_proj = 10; cam->boundbottom_proj = -10; cam->boundleft_curr = cam->boundleft_proj; cam->boundright_curr = cam->boundright_proj; cam->boundtop_curr = cam->boundtop_proj; cam->boundbottom_curr = cam->boundbottom_proj; event_data->cam = cam; // search for nearest ledge float ledge_dir; int line_index = Ledge_Find(0, 0, &ledge_dir); if (line_index != -1) Fighter_PlaceOnLedge(event_data, hmn, line_index, ledge_dir); else { event_data->cam->flags = 0; event_data->ledge_line = -1; event_vars->Tip_Display(500 * 60, "Error:\nIt appears there are no \nledges on this stage..."); } return; } void Ledgedash_ChangeLedgeThink(LedgedashData *event_data, GOBJ *hmn) { FighterData *hmn_data = hmn->userdata; if (hmn_data->input.down & (HSD_BUTTON_DPAD_LEFT | HSD_BUTTON_DPAD_RIGHT)) { // get current ledge position CollVert *collvert = *stc_collvert; CollLine *collline = *stc_collline; CollVert *this_vert; CollLine *this_line = &collline[event_data->ledge_line]; float ledge_pos; if (event_data->ledge_dir == -1) ledge_pos = collvert[this_line->info->vert_next].pos_curr.X; else if (event_data->ledge_dir == 1) ledge_pos = collvert[this_line->info->vert_prev].pos_curr.X; // find ledge float ledge_dir; int line_index = -1; if (hmn_data->input.down & HSD_BUTTON_DPAD_LEFT) line_index = Ledge_Find(-1, ledge_pos, &ledge_dir); else if (hmn_data->input.down & HSD_BUTTON_DPAD_RIGHT) line_index = Ledge_Find(1, ledge_pos, &ledge_dir); if (line_index != -1) Fighter_PlaceOnLedge(event_data, hmn, line_index, ledge_dir); else Fighter_PlaceOnLedge(event_data, hmn, event_data->ledge_line, (float)event_data->ledge_dir); } return; } int Ledge_Find(int search_dir, float xpos_start, float *ledge_dir) { // get line and vert pointers CollLine *collline = *stc_collline; CollVert *collvert = *stc_collvert; CollDataStage *coll_data = *stc_colldata; // get initial closest float xpos_closest; if (search_dir == -1) // search left xpos_closest = -5000; else if (search_dir == 1) // search right xpos_closest = 5000; else // search both xpos_closest = 5000; // look for the closest ledge CollLine *line_closest = 0; int index_closest = -1; int group_index = 0; // first ground link int group_num = coll_data->group_num; // ground link num CollGroup *this_group = *stc_firstcollgroup; while (this_group != 0) // loop through ground links { // 2 passes, one for ground and one for dynamic lines int line_index, line_num; for (int i = 0; i < 2; i++) { // first pass, use floors if (i == 0) { line_index = this_group->desc->floor_start; // first ground link line_num = line_index + this_group->desc->floor_num; // ground link num } // second pass, use dynamics else if (i == 1) { line_index = this_group->desc->dyn_start; // first ground link line_num = line_index + this_group->desc->dyn_num; // ground link num } // loop through lines while (line_index < line_num) { // get all data for this line CollLine *this_line = &collline[line_index]; // ??? i actually dont know why i cant access this directly CollLineInfo *this_lineinfo = this_line->info; // check if this link is a ledge if (this_lineinfo->is_ledge) { // check both sides of this ledge Vec3 ledge_pos; for (int j = 0; j < 2; j++) { // first pass, check left if (j == 0) { GrColl_GetLedgeLeft2(line_index, &ledge_pos); } else if (j == 1) { GrColl_GetLedgeRight2(line_index, &ledge_pos); } // is within the camera range if ((ledge_pos.X > Stage_GetCameraLeft()) && (ledge_pos.X < Stage_GetCameraRight()) && (ledge_pos.Y > Stage_GetCameraBottom()) && (ledge_pos.Y < Stage_GetCameraTop())) { // check for any obstructions float dir_mult; if (j == 0) // left ledge dir_mult = -1; else if (j == 1) // right ledge dir_mult = 1; int ray_index; int ray_kind; Vec2 ray_angle; Vec3 ray_pos; float from_x = ledge_pos.X + (2 * dir_mult); float to_x = from_x; float from_y = ledge_pos.Y + 5; float to_y = from_y - 10; int is_ground = GrColl_RaycastGround(&ray_pos, &ray_index, &ray_kind, &ray_angle, -1, -1, -1, 0, from_x, from_y, to_x, to_y, 0); if (is_ground == 0) { int is_closer = 0; if (search_dir == -1) // check if to the left { if ((ledge_pos.X > xpos_closest) && (ledge_pos.X < xpos_start)) is_closer = 1; } else if (search_dir == 1) // check if to the right { if ((ledge_pos.X < xpos_closest) && (ledge_pos.X > xpos_start)) is_closer = 1; } else // check if any direction { float dist_old = fabs(xpos_start - xpos_closest); float dist_new = fabs(xpos_start - ledge_pos.X); if (dist_new < dist_old) is_closer = 1; } // determine direction if (is_closer) { // now determine if this line is a ledge in this direction if (j == 0) // left ledge { CollLine *prev_line = &collline[this_lineinfo->line_prev]; // ??? i actually dont know why i cant access this directly if ((this_lineinfo->line_prev == -1) || (prev_line->is_rwall == 1)) // if prev line is a right wall / if prev line doesnt exist { // save info on this line xpos_closest = ledge_pos.X; // save left vert's X position line_closest = this_line; index_closest = line_index; *ledge_dir = 1; } } else if (j == 1) // right ledge { CollLine *next_line = &collline[this_lineinfo->line_next]; // ??? i actually dont know why i cant access this directly if ((this_lineinfo->line_prev == -1) || (next_line->is_lwall == 1)) // if prev line is a right wall / if prev line doesnt exist { // save info on this line xpos_closest = ledge_pos.X; // save left vert's X position line_closest = this_line; index_closest = line_index; *ledge_dir = -1; } } } } } } } line_index++; } } // get next this_group = this_group->next; } return index_closest; } void Fighter_PlaceOnLedge(LedgedashData *event_data, GOBJ *hmn, int line_index, float ledge_dir) { FighterData *hmn_data = hmn->userdata; // save ledge info event_data->ledge_line = line_index; event_data->ledge_dir = ledge_dir; // get ledge position Vec3 ledge_pos; if (ledge_dir > 0) GrColl_GetLedgeLeft2(line_index, &ledge_pos); else GrColl_GetLedgeRight2(line_index, &ledge_pos); // remove velocity hmn_data->phys.self_vel.X = 0; hmn_data->phys.self_vel.Y = 0; // restore tether hmn_data->flags.used_tether = 0; // check if starting on ledge if (LdshMenu_Main.options[0].option_val == 0) { // init refresh num event_data->tip.refresh_num = -1; // setting this to -1 because the per frame code will add 1 and make it 0 // Sleep first Fighter_EnterSleep(hmn, 0); Fighter_EnterRebirth(hmn); // place player on this ledge FtCliffCatch *ft_state = &hmn_data->state_var; hmn_data->facing_direction = ledge_dir; ft_state->ledge_index = line_index; // store line index Fighter_EnterCliffWait(hmn); ft_state->timer = 0; // spoof as on ledge for a frame already Fighter_LoseGroundJump(hmn_data); Fighter_EnableCollUpdate(hmn_data); Coll_CheckLedge(&hmn_data->coll_data); Fighter_MoveToCliff(hmn); Fighter_UpdatePosition(hmn); hmn_data->phys.self_vel.X = 0; hmn_data->phys.self_vel.Y = 0; ftCommonData *ftcommon = *stc_ftcommon; Fighter_ApplyIntang(hmn, ftcommon->cliff_invuln_time); } else { // init refresh num event_data->tip.refresh_num = 0; // setting this to -1 because the per frame code will add 1 and make it 0 // place player in a random position in respawn wait Fighter_EnterSleep(hmn, 0); Fighter_EnterRebirth(hmn); hmn_data->facing_direction = ledge_dir; // get random position float xpos_min = 40; float xpos_max = 65; float ypos_min = -30; float ypos_max = 30; hmn_data->phys.pos.X = ((ledge_dir * -1) * (xpos_min + HSD_Randi(xpos_max - xpos_min) + HSD_Randf())) + (ledge_pos.X); hmn_data->phys.pos.Y = ((ledge_dir * -1) * (ypos_min + HSD_Randi(ypos_max - ypos_min) + HSD_Randf())) + (ledge_pos.Y); // enter rebirth Fighter_EnterRebirthWait(hmn); hmn_data->cb.Phys = RebirthWait_Phys; hmn_data->cb.IASA = RebirthWait_IASA; Fighter_UpdateRebirthPlatformPos(hmn); Ledgedash_InitVariables(event_data); } // update camera box CameraBox *cam = event_data->cam; cam->cam_pos.X = ledge_pos.X + (ledge_dir * 20); cam->cam_pos.Y = ledge_pos.Y + 15; Fighter_UpdateCamera(hmn); // remove all particles for (int i = 0; i < PTCL_LINKMAX; i++) { Particle2 **ptcls = &stc_ptcl[i]; Particle2 *ptcl = *ptcls; while (ptcl != 0) { Particle2 *ptcl_next = ptcl->next; // begin destroying this particle // subtract some value, 8039c9f0 if (ptcl->x88 != 0) { int *arr = ptcl->x88; arr[0x50 / 4]--; } // remove from generator? 8039ca14 if (ptcl->gen != 0) psRemoveParticleAppSRT(ptcl); // delete parent jobj, 8039ca48 psDeletePntJObjwithParticle(ptcl); // update most recent ptcl pointer *ptcls = ptcl->next; // free alloc, 8039ca54 HSD_ObjFree(0x804d0f60, ptcl); // decrement ptcl total u16 ptclnum = *stc_ptclnum; ptclnum--; *stc_ptclnum = ptclnum; // get next ptcl = ptcl_next; } } /* // remove all generators with linkNo 2 (blastzone) ptclGen *gen = *stc_ptclgen; while (gen != 0) { // get next ptclGen *gen_next = gen->next; // if linkNo 2, destroy it if (gen->link_no == 2) { // set a flag for some reason gen->type |= 0x80; // kill gen gen = psKillGenerator(gen, *stc_ptclgencurr); } // save last *stc_ptclgencurr = gen; // get next gen = gen_next; } */ // remove all camera shake gobjs (p_link 18, entity_class 3) GOBJList *gobj_list = *stc_gobj_list; GOBJ *gobj = gobj_list->match_cam; while (gobj != 0) { GOBJ *gobj_next = gobj->next; // if entity class 3 (quake) if (gobj->entity_class == 3) { GObj_Destroy(gobj); } gobj = gobj_next; } return; } void Fighter_UpdatePosition(GOBJ *fighter) { FighterData *fighter_data = fighter->userdata; // Update Position (Copy Physics XYZ into all ECB XYZ) fighter_data->coll_data.topN_Curr.X = fighter_data->phys.pos.X; fighter_data->coll_data.topN_Curr.Y = fighter_data->phys.pos.Y; fighter_data->coll_data.topN_Prev.X = fighter_data->phys.pos.X; fighter_data->coll_data.topN_Prev.Y = fighter_data->phys.pos.Y; fighter_data->coll_data.topN_CurrCorrect.X = fighter_data->phys.pos.X; fighter_data->coll_data.topN_CurrCorrect.Y = fighter_data->phys.pos.Y; fighter_data->coll_data.topN_Proj.X = fighter_data->phys.pos.X; fighter_data->coll_data.topN_Proj.Y = fighter_data->phys.pos.Y; // Update Collision Frame ID fighter_data->coll_data.coll_test = *stc_colltest; // Adjust JObj position (code copied from 8006c324) JOBJ *fighter_jobj = fighter->hsd_object; fighter_jobj->trans.X = fighter_data->phys.pos.X; fighter_jobj->trans.Y = fighter_data->phys.pos.Y; fighter_jobj->trans.Z = fighter_data->phys.pos.Z; JOBJ_SetMtxDirtySub(fighter_jobj); // Update Static Player Block Coords Fighter_SetPosition(fighter_data->ply, fighter_data->flags.ms, &fighter_data->phys.pos); return; } void Fighter_UpdateCamera(GOBJ *fighter) { FighterData *fighter_data = fighter->userdata; // Update camerabox pos Fighter_UpdateCameraBox(fighter); // Update tween fighter_data->cameraBox->boundleft_curr = fighter_data->cameraBox->boundleft_proj; fighter_data->cameraBox->boundright_curr = fighter_data->cameraBox->boundright_proj; // update camera position Match_CorrectCamera(); // reset onscreen bool //Fighter_UpdateOnscreenBool(fighter); fighter_data->flags.is_offscreen = 0; } void RebirthWait_Phys(GOBJ *fighter) { FighterData *fighter_data = fighter->userdata; // infinite time fighter_data->state_var.stateVar1 = 2; return; } int RebirthWait_IASA(GOBJ *fighter) { FighterData *fighter_data = fighter->userdata; if (Fighter_IASACheck_JumpAerial(fighter)) { } else { ftCommonData *ftcommon = *stc_ftcommon; // check for lstick movement float stick_x = fabs(fighter_data->input.lstick_x); float stick_y = fighter_data->input.lstick_y; if ((stick_x > 0.2875) && (fighter_data->input.timer_lstick_tilt_x < 2) || (stick_y < (ftcommon->lstick_rebirthfall * -1)) && (fighter_data->input.timer_lstick_tilt_y < 4)) { Fighter_EnterFall(fighter); return 1; } } return 0; } int Fighter_CheckFall(FighterData *hmn_data) { int is_fall = 0; // look for Fall input float stick_x = fabs(hmn_data->input.lstick_x); float stick_y = hmn_data->input.lstick_y; if ((stick_x >= 0.2875) && (hmn_data->input.timer_lstick_tilt_x < 2) || (stick_y <= -0.2875) && (hmn_data->input.timer_lstick_tilt_y < 2)) { is_fall = 1; } return is_fall; } // Tips Functions void Tips_Toggle(GOBJ *menu_gobj, int value) { // destroy existing tips when disabling if (value == 1) event_vars->Tip_Destroy(); return; } void Tips_Think(LedgedashData *event_data, FighterData *hmn_data) { if (LdshOptions_Main[3].option_val == 0) { // check for early fall input in cliffcatch if ((event_data->tip.is_input_release == 0) && (hmn_data->state == ASID_CLIFFCATCH) && (Fighter_CheckFall(hmn_data) == 1)) { event_data->tip.is_input_release = 1; event_vars->Tip_Destroy(); // determine how many frames early float *anim_ptr = Animation_GetAddress(hmn_data, hmn_data->anim_id); float frame_total = anim_ptr[0x8 / 4]; float frames_early = frame_total - hmn_data->stateFrame; event_vars->Tip_Display(3 * 60, "Misinput:\nFell %d frames early.", (int)frames_early + 1); } // check for early fall input on cliffwait frame 0 if ((event_data->tip.is_input_release == 0) && (hmn_data->state == ASID_CLIFFWAIT) && (hmn_data->TM.state_frame == 1) && (Fighter_CheckFall(hmn_data) == 1)) { event_data->tip.is_input_release = 1; event_vars->Tip_Destroy(); event_vars->Tip_Display(LSDH_TIPDURATION, "Misinput:\nFell 1 frame early."); } // check for late fall input if ((event_data->tip.is_input_release == 0) && (hmn_data->state == ASID_CLIFFJUMPQUICK1) && (Fighter_CheckFall(hmn_data) == 1)) { event_data->tip.is_input_release = 1; event_vars->Tip_Destroy(); // jumped and fell on same frame if (hmn_data->TM.state_frame == 0) event_vars->Tip_Display(LSDH_TIPDURATION, "Misinput:\nInputted jump and fall \non the same frame."); // fell late else event_vars->Tip_Display(LSDH_TIPDURATION, "Misinput:\nJumped %d frame(s) early.", hmn_data->TM.state_frame); } // check for ledgedash without refreshing if ((event_data->tip.refresh_displayed == 0) && (event_data->hud.is_actionable == 1) && (event_data->tip.refresh_num == 0)) { event_data->tip.refresh_displayed = 1; // increment condition count event_data->tip.refresh_cond_num++; // after 3 conditions, display tip if (event_data->tip.refresh_cond_num >= 3) { // if tip is displayed, reset cond num if (event_vars->Tip_Display(5 * 60, "Warning:\nIt is higly recommended to\nre-grab ledge after \nbeing reset to simulate \na realistic scenario!")) event_data->tip.refresh_cond_num = 0; } } } return; } // Initial Menu static EventMenu *Event_Menu = &LdshMenu_Main; ================================================ FILE: patch/events/ledgedash/source/ledgedash.h ================================================ #include "../../../../MexTK/mex.h" #include "../../../tmdata/source/events.h" typedef struct LedgedashData LedgedashData; typedef struct LedgedashAssets LedgedashAssets; typedef struct LdshHitlogData LdshHitlogData; typedef struct LdshHitboxData LdshHitboxData; #define LSDH_TIPDURATION 1.7 * 60 #define LDSH_HITBOXNUM 30 * 4 #define LCLTEXT_SCALE 4.5 #define LCLJOBJ_BAR 4 struct LedgedashData { EventDesc *event_desc; LedgedashAssets *assets; s16 ledge_line; s16 ledge_dir; s16 reset_timer; GOBJ *hitlog_gobj; CameraBox *cam; struct { GOBJ *gobj; Text *text_angle; Text *text_galint; int canvas; int timer; float airdodge_angle; u8 is_release : 1; u8 is_jump : 1; u8 is_airdodge : 1; u8 is_aerial : 1; u8 is_land : 1; u8 is_actionable : 1; u16 release_frame; u16 jump_frame; u16 airdodge_frame; u16 aerial_frame; u16 land_frame; u16 actionable_frame; u8 action_log[30]; } hud; struct { s16 refresh_num; // number of times refreshed u8 refresh_cond_num; // number of times tip condition has been met u8 refresh_displayed : 1; u8 is_input_release : 1; u8 is_input_jump : 1; } tip; }; struct LedgedashAssets { JOBJ *hud; void **hudmatanim; // pointer to array }; struct LdshHitboxData { int kind; float size; Vec3 pos_curr; Vec3 pos_prev; }; struct LdshHitlogData { int num; LdshHitboxData hitlog[LDSH_HITBOXNUM]; }; typedef enum LDSH_ACTION { LDACT_NONE, LDACT_CLIFFWAIT, LDACT_FALL, LDACT_JUMP, LDACT_AIRDODGE, LDACT_ATTACK, LDACT_LANDING, }; void Event_Exit(); void Tips_Toggle(GOBJ *menu_gobj, int value); void Ledgedash_ToggleStartPosition(GOBJ *menu_gobj, int value); void Ledgedash_ToggleAutoReset(GOBJ *menu_gobj, int value); void Ledgedash_HUDCamThink(GOBJ *gobj); GOBJ *Ledgedash_HitLogInit(); void Ledgedash_HitLogGX(GOBJ *gobj, int pass); void RebirthWait_Phys(GOBJ *fighter); int RebirthWait_IASA(GOBJ *fighter); int Ledge_Find(int search_dir, float xpos_start, float *ledge_dir); ================================================ FILE: patch/events/wavedash/build.bat ================================================ SET "OUTPUT_FOLDER=output" SET "FILENAME=EvWdsh.dat" SET "SOURCEFILE=wavedash" SET "ASSETS=wdshData" xcopy /s /y "assets\%ASSETS%.dat" "%OUTPUT_FOLDER%/%FILENAME%" "../../../MexTK/MexTK.exe" -ff -i "source/%SOURCEFILE%.c" -s evFunction -dat "%OUTPUT_FOLDER%\%FILENAME%" -t "../../../MexTK/evFunction.txt" -q -ow -w -c -l "../../../MexTK/melee.link" -op 1 "../../../MexTK/MexTK.exe" -trim "%OUTPUT_FOLDER%\%FILENAME%" pause ================================================ FILE: patch/events/wavedash/source/wavedash.c ================================================ #include "wavedash.h" static char nullString[] = " "; // Main Menu static char **WdOptions_Target[] = {"Off", "On"}; static char **WdOptions_HUD[] = {"On", "Off"}; static EventOption WdOptions_Main[] = { // Target { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integers list, etc .value_num = sizeof(WdOptions_Target) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Target", // pointer to a string .desc = "Highlight an area of the stage to wavedash towards.", // string describing what this option does .option_values = WdOptions_Target, // pointer to an array of strings .onOptionChange = 0, }, // HUD { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integers list, etc .value_num = sizeof(WdOptions_HUD) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "HUD", // pointer to a string .desc = "Toggle visibility of the HUD.", // string describing what this option does .option_values = WdOptions_HUD, // pointer to an array of strings .onOptionChange = 0, }, // Tips { .option_kind = OPTKIND_STRING, // the type of option this is; menu, string list, integers list, etc .value_num = sizeof(WdOptions_HUD) / 4, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Tips", // pointer to a string .desc = "Toggle the onscreen display of tips.", // string describing what this option does .option_values = WdOptions_HUD, // pointer to an array of strings .onOptionChange = 0, }, // Help { .option_kind = OPTKIND_FUNC, // the type of option this is; menu, string list, integers list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Help", // pointer to a string .desc = "A wavedash is performed by air-dodging diagonally down\nas soon you leave the ground from a jump, causing the fighter\nto slide a short distance. This technique will allow you to quickly\nadjust your position and even attack while sliding.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = 0, }, // Exit { .option_kind = OPTKIND_FUNC, // the type of option this is; menu, string list, integers list, etc .value_num = 0, // number of values for this option .option_val = 0, // value of this option .menu = 0, // pointer to the menu that pressing A opens .option_name = "Exit", // pointer to a string .desc = "Return to the Event Selection Screen.", // string describing what this option does .option_values = 0, // pointer to an array of strings .onOptionChange = 0, .onOptionSelect = Event_Exit, }, }; static EventMenu WdMenu_Main = { .name = "Wavedash Training", // the name of this menu .option_num = sizeof(WdOptions_Main) / sizeof(EventOption), // number of options this menu contains .scroll = 0, // runtime variable used for how far down in the menu to start .state = 0, // bool used to know if this menu is focused, used at runtime .cursor = 0, // index of the option currently selected, used at runtime .options = &WdOptions_Main, // pointer to all of this menu's options .prev = 0, // pointer to previous menu, used at runtime }; // Init Function void Event_Init(GOBJ *gobj) { WavedashData *event_data = gobj->userdata; EventDesc *event_desc = event_data->event_desc; GOBJ *hmn = Fighter_GetGObj(0); FighterData *hmn_data = hmn->userdata; //GOBJ *cpu = Fighter_GetGObj(1); //FighterData *cpu_data = cpu->userdata; // theres got to be a better way to do this... event_vars = *event_vars_ptr; // get l-cancel assets event_data->assets = File_GetSymbol(event_vars->event_archive, "wdshData"); // create HUD Wavedash_Init(event_data); // init target Target_Init(event_data, hmn_data); return; } // Think Function void Event_Think(GOBJ *event) { WavedashData *event_data = event->userdata; GOBJ *hmn = Fighter_GetGObj(0); FighterData *hmn_data = hmn->userdata; // infinite shields hmn_data->shield.health = 60; Wavedash_Think(event_data, hmn_data); return; } void Event_Exit() { Match *match = MATCH; // end game match->state = 3; // cleanup Match_EndVS(); // unfreeze HSD_Update *update = HSD_UPDATE; update->pause_develop = 0; return; } // Event functions void Wavedash_Init(WavedashData *event_data) { // create hud cobj GOBJ *hudcam_gobj = GObj_Create(19, 20, 0); ArchiveInfo **ifall_archive = 0x804d6d5c; COBJDesc ***dmgScnMdls = File_GetSymbol(*ifall_archive, 0x803f94d0); COBJDesc *cam_desc = dmgScnMdls[1][0]; COBJ *hud_cobj = COBJ_LoadDesc(cam_desc); // init camera GObj_AddObject(hudcam_gobj, R13_U8(-0x3E55), hud_cobj); GOBJ_InitCamera(hudcam_gobj, Wavedash_HUDCamThink, 7); hudcam_gobj->cobj_links = 1 << 18; GOBJ *hud_gobj = GObj_Create(0, 0, 0); event_data->hud.gobj = hud_gobj; // Load jobj JOBJ *hud_jobj = JOBJ_LoadJoint(event_data->assets->hud); GObj_AddObject(hud_gobj, 3, hud_jobj); GObj_AddGXLink(hud_gobj, GXLink_Common, 18, 80); // create text canvas int canvas = Text_CreateCanvas(2, hud_gobj, 14, 15, 0, 18, 81, 19); event_data->hud.canvas = canvas; // init text Text **text_arr = &event_data->hud.text_timing; for (int i = 0; i < 3; i++) { // Create text object Text *hud_text = Text_CreateText(2, canvas); text_arr[i] = hud_text; hud_text->kerning = 1; hud_text->align = 1; hud_text->use_aspect = 1; // Get position Vec3 text_pos; JOBJ *text_jobj; JOBJ_GetChild(hud_jobj, &text_jobj, WDJOBJ_TEXT + i, -1); JOBJ_GetWorldPosition(text_jobj, 0, &text_pos); // adjust scale Vec3 *scale = &hud_jobj->scale; // text scale hud_text->scale.X = (scale->X * 0.01) * TEXT_SCALE; hud_text->scale.Y = (scale->Y * 0.01) * TEXT_SCALE; hud_text->aspect.X = 165; // text position hud_text->trans.X = text_pos.X + (scale->X / 4.0); hud_text->trans.Y = (text_pos.Y * -1) + (scale->Y / 4.0); // dummy text Text_AddSubtext(hud_text, 0, 0, "-"); } // init timer event_data->timer = -1; event_data->since_wavedash = 255; return 0; } void Wavedash_Think(WavedashData *event_data, FighterData *hmn_data) { // check to enter is_wavedashing if (event_data->is_wavedashing == 0) { // increment time since wavedash if (event_data->since_wavedash < 255) event_data->since_wavedash++; // check to enter wavedash state if ((hmn_data->state == ASID_LANDINGFALLSPECIAL) && hmn_data->TM.state_prev[2] == ASID_KNEEBEND) { event_data->is_wavedashing = 1; event_data->since_wavedash = 0; } // check to null timer if (((hmn_data->state >= ASID_WALKSLOW) && (hmn_data->state <= ASID_KNEEBEND)) || // no ground movement or jumping (hmn_data->phys.air_state == 1) || // airborne ((hmn_data->attack_kind >= ATKKIND_SPECIALN) && (hmn_data->attack_kind <= ATKKIND_SPECIALLW)) || // any special move ((hmn_data->state >= ASID_ESCAPEF) && (hmn_data->state >= ASID_ESCAPEB))) // rolls event_data->since_wavedash = 255; } // check to exit is_wavedashing if (event_data->is_wavedashing == 1) { if ((hmn_data->state != ASID_LANDINGFALLSPECIAL)) event_data->is_wavedashing = 0; } //OSReport("is_wavedashing: %d since_wavedash: %d", event_data->is_wavedashing, event_data->since_wavedash); JOBJ *hud_jobj = event_data->hud.gobj->hsd_object; // start sequence on jump squat if ((hmn_data->state == ASID_KNEEBEND) && (hmn_data->TM.state_frame == 0)) { event_data->is_airdodge = 0; // start timer event_data->timer = 0; // save line and position event_data->restore.pos.X = hmn_data->phys.pos.X; event_data->restore.pos.Y = hmn_data->phys.pos.Y; event_data->restore.line_index = hmn_data->coll_data.ground_index; } // if sequence started if (event_data->timer >= 0) { event_data->timer++; // inc timer // if grounded and not in kneebend, stop sequence if ((hmn_data->state != ASID_KNEEBEND) && (hmn_data->state != ASID_LANDINGFALLSPECIAL) && (hmn_data->phys.air_state == 0)) { event_data->timer = -1; event_data->is_airdodge = 0; event_data->is_early_airdodge = 0; } // run sequence logic else { // catch early airdodge input if (hmn_data->input.down & (PAD_TRIGGER_L | PAD_TRIGGER_R)) { event_data->airdodge_frame = event_data->timer; // save airdodge frame event_data->is_early_airdodge = 1; } // save airdodge angle if ((event_data->is_airdodge == 0) && (((hmn_data->state == ASID_ESCAPEAIR) && (hmn_data->TM.state_frame == 0)) || // if entered airdodge ((hmn_data->state == ASID_LANDINGFALLSPECIAL) && (hmn_data->TM.state_frame == 0) && (hmn_data->TM.state_prev[0] == ASID_ESCAPEAIR) && (hmn_data->TM.state_prev_frames[0] == 0)))) { // save airdodge angle float angle = atan2(hmn_data->input.lstick_y, hmn_data->input.lstick_x) - -(M_PI / 2); event_data->wd_angle = angle; event_data->is_early_airdodge = 0; event_data->is_airdodge = 1; event_data->airdodge_frame = event_data->timer; // save airdodge frame } int is_finished = 0; void *mat_anim = 0; // look for successful WD if ((hmn_data->state == ASID_LANDINGFALLSPECIAL) && (hmn_data->TM.state_frame == 0) && // is in special landing (hmn_data->TM.state_prev[0] == ASID_ESCAPEAIR) && // came from airdodge (hmn_data->TM.state_prev[2] == ASID_KNEEBEND)) // came from jump { is_finished = 1; mat_anim = event_data->assets->hudmatanim[0]; event_data->wd_succeeded++; // check for perfect //if (WdOptions_Main[0].option_val == 0) { if (event_data->airdodge_frame == ((int)hmn_data->attr.jump_startup_time + 1)) SFX_Play(303); } } // look for failed WD else if ((event_data->is_early_airdodge == 1) && (((hmn_data->state == ASID_JUMPF) || (hmn_data->state == ASID_JUMPB)) && (hmn_data->TM.state_frame >= 10)) || ((hmn_data->state == ASID_ESCAPEAIR) && (hmn_data->TM.state_frame >= 10) && (hmn_data->TM.state_prev[1] == ASID_KNEEBEND))) { is_finished = 1; mat_anim = event_data->assets->hudmatanim[1]; SFX_PlayCommon(3); // restore position int ray_index; int ray_kind; Vec2 ray_angle; Vec3 ray_pos; float from_x = event_data->restore.pos.X; float to_x = from_x; float from_y = event_data->restore.pos.Y + 3; float to_y = from_y - 6; int is_ground = GrColl_RaycastGround(&ray_pos, &ray_index, &ray_kind, &ray_angle, -1, -1, -1, 0, from_x, from_y, to_x, to_y, 0); if ((is_ground == 1) && (ray_index == event_data->restore.line_index)) { // do this for every subfighter (thanks for complicated code ice climbers) for (int i = 0; i < 2; i++) { GOBJ *this_fighter = Fighter_GetSubcharGObj(hmn_data->ply, i); if (this_fighter != 0) { FighterData *this_fighter_data = this_fighter->userdata; if ((this_fighter_data->flags.sleep == 0) && (this_fighter_data->flags.dead == 0)) { // place CPU here this_fighter_data->phys.pos = ray_pos; this_fighter_data->coll_data.ground_index = ray_index; // set grounded this_fighter_data->phys.air_state = 0; //Fighter_SetGrounded(this_fighter); // kill velocity Fighter_KillAllVelocity(this_fighter); // enter wait ActionStateChange(0, 1, -1, this_fighter, ASID_WAIT, 0, 0); this_fighter_data->stateBlend = 0; // update ECB this_fighter_data->coll_data.topN_Curr = this_fighter_data->phys.pos; // move current ECB location to new position Coll_ECBCurrToPrev(&this_fighter_data->coll_data); this_fighter_data->cb.Coll(this_fighter); // update camera box Fighter_UpdateCameraBox(this_fighter); this_fighter_data->cameraBox->boundleft_curr = this_fighter_data->cameraBox->boundleft_proj; this_fighter_data->cameraBox->boundright_curr = this_fighter_data->cameraBox->boundright_proj; // init CPU logic (for nana's popo position history...) int cpu_kind = Fighter_GetCPUKind(this_fighter_data->ply); int cpu_level = Fighter_GetCPULevel(this_fighter_data->ply); Fighter_CPUInitialize(this_fighter_data, cpu_kind, cpu_level, 0); // place subfighter in the Z axis if (this_fighter_data->flags.ms == 1) { ftCommonData *ft_common = *stc_ftcommon; this_fighter_data->phys.pos.Z = ft_common->ms_zjostle_max * -1; } } } } // update camera Match_CorrectCamera(); } } // update bar if (is_finished) { // reset variables event_data->timer = -1; event_data->is_airdodge = 0; event_data->is_early_airdodge = 0; // update bar frame colors JOBJ *arrow_jobj; JOBJ_GetChild(hud_jobj, &arrow_jobj, WDJOBJ_ARROW, -1); // get timing bar jobj // get in terms of bar timeframe int jump_frame = ((WDFRAMES - 1) / 2) - (int)hmn_data->attr.jump_startup_time; int input_frame = jump_frame + event_data->airdodge_frame - 1; // update arrow position if (input_frame < WDFRAMES) { event_data->hud.arrow_prevpos = arrow_jobj->trans.X; event_data->hud.arrow_nextpos = (-WDARROW_OFFSET * ((WDFRAMES - 1) / 2)) + (input_frame * 0.36); JOBJ_ClearFlags(arrow_jobj, JOBJ_HIDDEN); event_data->hud.arrow_timer = WDARROW_ANIMFRAMES; } // hide arrow for this wd attempt else { event_data->hud.arrow_timer = 0; arrow_jobj->trans.X = 0; JOBJ_SetFlags(arrow_jobj, JOBJ_HIDDEN); } // updating timing text if (input_frame < ((WDFRAMES - 1) / 2)) // is early Text_SetText(event_data->hud.text_timing, 0, "%df Early", ((WDFRAMES - 1) / 2) - input_frame); else if (input_frame == ((WDFRAMES - 1) / 2)) Text_SetText(event_data->hud.text_timing, 0, "Perfect"); else if (input_frame > ((WDFRAMES - 1) / 2)) Text_SetText(event_data->hud.text_timing, 0, "%df Late", input_frame - ((WDFRAMES - 1) / 2)); // update airdodge angle Text_SetText(event_data->hud.text_angle, 0, "%.2f", fabs(event_data->wd_angle / M_1DEGREE)); // update succession event_data->wd_attempted++; Text_SetText(event_data->hud.text_succession, 0, "%.2f%", ((float)event_data->wd_succeeded / (float)event_data->wd_attempted) * 100.0); // hide tip so bar is unobscured //event_vars->Tip_Destroy(); // apply HUD animation JOBJ_RemoveAnimAll(hud_jobj); JOBJ_AddAnimAll(hud_jobj, 0, mat_anim, 0); JOBJ_ReqAnimAll(hud_jobj, 0); } } } // update target Target_Manager(event_data, hmn_data); // run tip logic Tips_Think(event_data, hmn_data); // update HUD anim JOBJ_AnimAll(hud_jobj); // update arrow animation if (event_data->hud.arrow_timer > 0) { // decrement timer event_data->hud.arrow_timer--; // get this frames position float time = 1 - ((float)event_data->hud.arrow_timer / (float)WDARROW_ANIMFRAMES); float xpos = Bezier(time, event_data->hud.arrow_prevpos, event_data->hud.arrow_nextpos); // update position JOBJ *arrow_jobj; JOBJ_GetChild(hud_jobj, &arrow_jobj, WDJOBJ_ARROW, -1); // get timing bar jobj arrow_jobj->trans.X = xpos; JOBJ_SetMtxDirtySub(arrow_jobj); } return; } void Wavedash_HUDCamThink(GOBJ *gobj) { // if HUD enabled and not paused if ((WdOptions_Main[1].option_val == 0) && (Pause_CheckStatus(1) != 2)) { CObjThink_Common(gobj); } return; } float Bezier(float time, float start, float end) { float bez = time * time * (3.0f - 2.0f * time); return bez * (end - start) + start; } // Target functions void Target_Init(WavedashData *event_data, FighterData *hmn_data) { ftCommonData *ftcommon = *stc_ftcommon; float mag; // determine best wavedash distance (not taking into account friction doubling) mag = ftcommon->escapeair_vel * cos(atan2(-0.2875, 0.9500)); float wd_maxdstn = Target_GetWdashDistance(hmn_data, mag); OSReport("%s wd_maxdstn: %.2f\n", Fighter_GetName(Fighter_GetExternalID(hmn_data->ply)), wd_maxdstn); event_data->wd_maxdstn = wd_maxdstn; // determine scale based on wd distance float dist = event_data->wd_maxdstn; if (dist < TRGTSCL_DISTMIN) dist = TRGTSCL_DISTMIN; else if (dist > TRGTSCL_DISTMAX) dist = TRGTSCL_DISTMAX; event_data->target.scale = (((dist - TRGTSCL_DISTMIN) / (TRGTSCL_DISTMAX - TRGTSCL_DISTMIN)) * (TRGTSCL_SCALEMAX - TRGTSCL_SCALEMIN)) + TRGTSCL_SCALEMIN; // get width of the target JOBJ *target = JOBJ_LoadJoint(event_data->assets->target_jobj); // create dummy float scale = event_data->target.scale; // scale target->scale.X *= scale; target->scale.Z *= scale; // get children JOBJ *left_jobj, *right_jobj; JOBJ_GetChild(target, &left_jobj, TRGTJOBJ_LBOUND, -1); JOBJ_GetChild(target, &right_jobj, TRGTJOBJ_RBOUND, -1); // get offsets JOBJ_GetWorldPosition(left_jobj, 0, &event_data->target.left_offset); JOBJ_GetWorldPosition(right_jobj, 0, &event_data->target.right_offset); // free jobj JOBJ_RemoveAll(target); return; } void Target_Manager(WavedashData *event_data, FighterData *hmn_data) { GOBJ *target_gobj = event_data->target.gobj; switch (WdOptions_Main[0].option_val) { case (0): // off { // if spawned, remove if (target_gobj != 0) { Target_ChangeState(target_gobj, TRGSTATE_DESPAWN); event_data->target.gobj = 0; } break; } case (1): // on { // if not spawned, spawn if (target_gobj == 0) { if (hmn_data->phys.air_state == 0) { // spawn target target_gobj = Target_Spawn(event_data, hmn_data); event_data->target.gobj = target_gobj; } } // update target logic if (target_gobj != 0) { TargetData *target_data = target_gobj->userdata; // update fighter backed up position // restore position if not a wavedash // check current target state if (target_data->state == TRGSTATE_DESPAWN) { // create new one target_gobj = Target_Spawn(event_data, hmn_data); event_data->target.gobj = target_gobj; } } break; } } return; } GOBJ *Target_Spawn(WavedashData *event_data, FighterData *hmn_data) { Vec3 ray_angle; Vec3 ray_pos; int ray_index; float max = (event_data->wd_maxdstn * TRGT_RANGEMAX); float min = (event_data->wd_maxdstn * TRGT_RANGEMIN); // ensure min exists int min_exists = 0; min_exists += Target_CheckArea(event_data, hmn_data->coll_data.ground_index, &hmn_data->phys.pos, max, 0, 0, 0); min_exists += Target_CheckArea(event_data, hmn_data->coll_data.ground_index, &hmn_data->phys.pos, max * -1, 0, 0, 0); if (min_exists != 0) { // begin looking for valid ground at a random distance int is_ground = 0; while (is_ground != 1) { // select random direction float direction; int temp = HSD_Randi(2); if (temp == 0) direction = -1; else direction = 1; // random distance float distance = (HSD_Randf() * (max - min)) + min; // check if valid is_ground = Target_CheckArea(event_data, hmn_data->coll_data.ground_index, &hmn_data->phys.pos, distance * direction, &ray_index, &ray_pos, &ray_angle); } // create target gobj GOBJ *target_gobj = GObj_Create(10, 11, 0); // target data TargetData *target_data = calloc(sizeof(TargetData)); GObj_AddUserData(target_gobj, 4, HSD_Free, target_data); // add proc GObj_AddProc(target_gobj, Target_Think, 16); // create jobj JOBJ *target_jobj = JOBJ_LoadJoint(event_data->assets->target_jobj); GObj_AddObject(target_gobj, 3, target_jobj); GObj_AddGXLink(target_gobj, GXLink_Common, 5, 0); // scale target float scale = event_data->target.scale; target_jobj->scale.X *= scale; target_jobj->scale.Z *= scale; // move target target_jobj->trans.X = ray_pos.X; target_jobj->trans.Y = ray_pos.Y; target_jobj->trans.Z = ray_pos.Z; // adjust rotation based on line slope JOBJ *aura_jobj; JOBJ_GetChild(target_jobj, &aura_jobj, TRGTJOBJ_AURA, -1); aura_jobj->rot.Z = -1 * atan2(ray_angle.X, ray_angle.Y); // create camera box CameraBox *cam = CameraBox_Alloc(); cam->boundleft_proj = -10; cam->boundright_proj = 10; cam->boundtop_proj = 10; cam->boundbottom_proj = -10; // update camerabox position cam->cam_pos.X = target_jobj->trans.X; cam->cam_pos.Y = target_jobj->trans.Y + 15; cam->cam_pos.Z = target_jobj->trans.Z; // init target data Target_ChangeState(target_gobj, TRGSTATE_SPAWN); // enter spawn state target_data->cam = cam; // save camera target_data->line_index = ray_index; // save line index target_data->pos = ray_pos; // save position target_data->left = event_data->target.left_offset.X; target_data->right = event_data->target.right_offset.X; return target_gobj; } else { return 0; } } void Target_Think(GOBJ *target_gobj) { JOBJ *target_jobj = target_gobj->hsd_object; TargetData *target_data = target_gobj->userdata; WavedashData *event_data = event_vars->event_gobj->userdata; // update anim JOBJ_AnimAll(target_jobj); // ensure line still exists if (GrColl_CheckIfLineEnabled(target_data->line_index) == 0) { // enter exit state Target_ChangeState(target_gobj, TRGSTATE_DESPAWN); } // update target position (look into how fighters are rooted on ground) Vec3 pos_diff; GrColl_GetPosDifference(target_data->line_index, &target_data->pos, &pos_diff); VECAdd(&target_data->pos, &pos_diff, &target_data->pos); // update target orientation Vec3 slope; GrColl_GetLineSlope(target_data->line_index, &slope); JOBJ *aura_jobj; JOBJ_GetChild(target_jobj, &aura_jobj, TRGTJOBJ_AURA, -1); aura_jobj->rot.Z = -1 * atan2(slope.X, slope.Y); // update camerabox position CameraBox *cam = target_data->cam; cam->cam_pos.X = target_data->pos.X; cam->cam_pos.Y = target_data->pos.Y + 15; cam->cam_pos.Z = target_data->pos.Z; // update position target_jobj->trans = target_data->pos; JOBJ_SetMtxDirtySub(target_jobj); // state based logic switch (target_data->state) { case (TRGSTATE_SPAWN): { // check if ended if (JOBJ_CheckAObjEnd(target_jobj) == 0) Target_ChangeState(target_gobj, TRGSTATE_WAIT); break; } case (TRGSTATE_WAIT): { // get position Vec3 pos; JOBJ_GetWorldPosition(target_jobj, 0, &pos); // check for collision FighterData *hmn_data = Fighter_GetGObj(0)->userdata; Vec3 *ft_pos = &hmn_data->phys.pos; if ((hmn_data->phys.air_state == 0) && ((event_data->since_wavedash > 0) && (event_data->since_wavedash < 255) && (fabs(hmn_data->phys.self_vel.X) < 0.5)) && // check if a wavedash (ft_pos->X > (pos.X + target_data->left)) && (ft_pos->X < (pos.X + target_data->right)) && (ft_pos->Y > (pos.Y + -1)) && (ft_pos->Y < (pos.Y + 1))) { // sfx SFX_Play(173); Target_ChangeState(target_gobj, TRGSTATE_DESPAWN); } break; } case (TRGSTATE_DESPAWN): { // check if ended if (JOBJ_CheckAObjEnd(target_jobj) == 0) { // destroy camera CameraBox_Destroy(target_data->cam); // destroy this target GObj_Destroy(target_gobj); } break; } } return; } void Target_ChangeState(GOBJ *target_gobj, int state) { WavedashData *event_data = event_vars->event_gobj->userdata; TargetData *target_data = target_gobj->userdata; JOBJ *target_jobj = target_gobj->hsd_object; // update state target_data->state = state; // add anim JOBJ_AddAnimAll(target_jobj, event_data->assets->target_jointanim[state], event_data->assets->target_matanim[state], 0); JOBJ_ReqAnimAll(target_jobj, 0); // req anim return; } float Target_GetWdashDistance(FighterData *hmn_data, float mag) { float distance = 0; ftCommonData *ftcommon = *stc_ftcommon; // now simulate mag *= ftcommon->escapeair_veldecaymult; // first frame multiply by 0.9 ( in airdodge still) distance += mag; // subsequent, apply friction until at 0 while (mag > 0) { // get friction float friction = hmn_data->attr.ground_friction; if (mag > hmn_data->attr.walk_maximum_velocity) // double friction if speed > walk max speed friction *= ftcommon->friction_mult; // apply it mag -= friction; // ensure not under 0 if (mag < 0) mag = 0; distance += mag; } return distance; } int Target_CheckArea(WavedashData *event_data, int line, Vec3 *pos, float x_offset, int *ret_line, Vec3 *ret_pos, Vec3 *ret_slope) { int status = 0; // init int is_ground = 0; // check left is_ground += GrColl_CrawlGround(line, pos, ret_line, ret_pos, 0, ret_slope, x_offset + event_data->target.left_offset.X, 0); // check right is_ground += GrColl_CrawlGround(line, pos, ret_line, ret_pos, 0, ret_slope, x_offset + event_data->target.right_offset.X, 0); // check center is_ground += GrColl_CrawlGround(line, pos, ret_line, ret_pos, 0, ret_slope, x_offset + event_data->target.center_offset.X, 0); if (is_ground == 3) status = 1; return status; } // Tips Tips_Think(WavedashData *event_data, FighterData *hmn_data) { // only if enabled if (WdOptions_Main[2].option_val == 0) { // shield after wavedash // look successful wavedash if (event_data->since_wavedash <= 10) { // look for frame 1 of guard off if ((hmn_data->state == ASID_GUARDOFF) && (hmn_data->TM.state_frame == 0) && // just let go of shield ((hmn_data->TM.state_prev[0] == ASID_GUARD) && (hmn_data->TM.state_prev_frames[0] == 1))) // only guarded for 1 frame { event_data->tip.shield_num++; if (event_data->tip.shield_num >= 3) { event_vars->Tip_Display(5 * 60, "Tip:\nDon't hold the trigger! Quickly \npress and release to prevent \nshielding after wavedashing."); event_data->tip.shield_num = 0; } } } } return; } // Initial Menu static EventMenu *Event_Menu = &WdMenu_Main; ================================================ FILE: patch/events/wavedash/source/wavedash.h ================================================ #include "../../../../MexTK/mex.h" #include "../../../tmdata/source/events.h" #define TEXT_SCALE 4.2 #define WDJOBJ_TEXT 6 #define WDJOBJ_ARROW 3 #define WDARROW_OFFSET 0.36 #define WDARROW_ANIMFRAMES 4 #define WDFRAMES 15 #define TRGT_RANGEMAX 0.8 #define TRGT_RANGEMIN 0.55 #define TRGTJOBJ_AURA 3 #define TRGTJOBJ_LBOUND 4 #define TRGTJOBJ_RBOUND 5 #define TRGTSCL_DISTMIN 20 #define TRGTSCL_DISTMAX 50 #define TRGTSCL_SCALEMIN 1.0 #define TRGTSCL_SCALEMAX 1.7 typedef struct WavedashData WavedashData; typedef struct WavedashAssets WavedashAssets; typedef struct TargetData TargetData; struct WavedashData { EventDesc *event_desc; WavedashAssets *assets; struct { GOBJ *gobj; int canvas; Text *text_timing; Text *text_angle; Text *text_succession; float arrow_prevpos; float arrow_nextpos; int arrow_timer; } hud; struct { GOBJ *gobj; float scale; Vec3 left_offset; Vec3 center_offset; Vec3 right_offset; } target; struct { u8 shield_num; } tip; float wd_maxdstn; int timer; u8 airdodge_frame; u8 is_airdodge; u8 is_early_airdodge; u8 is_wavedashing; u8 since_wavedash; float wd_angle; int wd_attempted; int wd_succeeded; struct { u16 line_index; Vec2 pos; } restore; GXColor orig_colors[WDFRAMES]; }; struct WavedashAssets { JOBJ *hud; void **hudmatanim; // pointer to array JOBJ *target_jobj; void **target_jointanim; void **target_matanim; }; enum TargetState { TRGSTATE_SPAWN, TRGSTATE_WAIT, TRGSTATE_DESPAWN, }; struct TargetData { int state; Vec3 pos; int line_index; float left; float right; CameraBox *cam; }; float Bezier(float time, float start, float end); float Target_GetWdashDistance(FighterData *hmn_data, float mag); GOBJ *Target_Spawn(WavedashData *event_data, FighterData *fighter_data); int Target_CheckArea(WavedashData *event_data, int line, Vec3 *pos, float x_offset, int *ret_line, Vec3 *ret_pos, Vec3 *ret_slope); void Target_Think(GOBJ *target_gobj); void Wavedash_HUDCamThink(GOBJ *gobj); void Event_Exit(); ================================================ FILE: patch/tmdata/build.bat ================================================ xcopy /s /y "assets\evMenu.dat" "output/TmDt.dat" "../../MexTK/MexTK.exe" -ff -i "source/events.c" -s tmFunction -dat "output/TmDt.dat" -t "../../MexTK/tmFunction.txt" -q -ow -w -c -l "../../MexTK/melee.link" -op 1 "../../MexTK/MexTK.exe" -trim "output/TmDt.dat" pause ================================================ FILE: patch/tmdata/source/events.c ================================================ #include "events.h" #include void Event_Init(GOBJ *gobj) { int *EventData = gobj->userdata; EventDesc *event_desc = EventData[0]; return; } ///////////////////// // Mod Information // ///////////////////// static char TM_VersShort[] = TM_VERSSHORT "\n"; static char TM_VersLong[] = TM_VERSLONG "\n"; static char TM_Compile[] = "COMPILED: " __DATE__ " " __TIME__; static char nullString[] = " "; //////////////////////// /// Event Defintions /// //////////////////////// // Lab // Match Data static EventMatchData Lab_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = false, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = true, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = false, // 0x10 .isCheckForZRetry = false, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = -1, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc Lab = { // Event Name .eventName = "Training Lab\n", .eventDescription = "Free practice with\ncomplete control.\n", .eventTutorial = "", .eventFile = "EvLab", .eventCSSFile = "TM/EvLabCSS.dat", .isChooseCPU = true, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &Lab_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData LCancel_MatchData = { .timer = MATCH_TIMER_HIDE, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = false, .hideGo = true, .hideReady = true, .isCreateHUD = false, .isDisablePause = true, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = false, // 0x10 .isCheckForZRetry = false, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = -1, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc LCancel = { // Event Name .eventName = "L-Cancel Training\n", .eventDescription = "Practice L-Cancelling on\na stationary CPU.\n", .eventTutorial = "TvLC", .eventFile = "EvLcl", .isChooseCPU = false, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 15, .matchData = &LCancel_MatchData, .defaultOSD = 0xFFFFFFFF, }; // Ledgedash Training // Match Data static EventMatchData Ledgedash_MatchData = { .timer = MATCH_TIMER_HIDE, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = false, .hideGo = true, .hideReady = true, .isCreateHUD = false, .isDisablePause = true, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = false, // 0x10 .isCheckForZRetry = false, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = -1, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc Ledgedash = { .eventName = "Ledgedash Training\n", .eventDescription = "Practice Ledgedashes!\nUse D-Pad to change ledge.\n", .eventTutorial = "TvLedDa", .eventFile = "EvLdsh", .isChooseCPU = false, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 15, .matchData = &Ledgedash_MatchData, .defaultOSD = 0xFFFFFFFF, }; // Wavedash Training // Match Data static EventMatchData Wavedash_MatchData = { .timer = MATCH_TIMER_HIDE, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = false, .hideGo = true, .hideReady = true, .isCreateHUD = false, .isDisablePause = true, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = false, // 0x10 .isCheckForZRetry = false, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = -1, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc Wavedash = { .eventName = "Wavedash Training\n", .eventDescription = "Practice timing your wavedash,\na fundamental movement technique.\n", .eventTutorial = "TvWvDsh", .eventFile = "EvWdsh", .isChooseCPU = false, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 15, .matchData = &Wavedash_MatchData, .defaultOSD = 0xFFFFFFFF, }; // Combo Training // Match Data static EventMatchData Combo_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = -1, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc Combo = { .eventName = "Combo Training\n", .eventDescription = "L+DPad adjusts percent | DPadDown moves CPU\nDPad right/left saves and loads positions.", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = true, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &Combo_MatchData, .defaultOSD = 0xFFFFFFFF, }; // Attack On Shield Training // Match Data static EventMatchData AttackOnShield_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = -1, // 0xFF= .stage = 32, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc AttackOnShield = { .eventName = "Attack on Shield\n", .eventDescription = "Practice attacks on a shielding opponent\nPause to change their OoS option\n", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = true, .isSelectStage = false, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &AttackOnShield_MatchData, .defaultOSD = 0xFFFFFFFF, }; // Reversal Training // Match Data static EventMatchData Reversal_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = -1, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc Reversal = { .eventName = "Reversal Training\n", .eventDescription = "Practice OoS punishes! DPad left/right\nmoves characters close and further apart.", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = true, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &Reversal_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData SDI_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = 2, // 0xFF= .stage = 32, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc SDI = { .eventName = "SDI Training\n", .eventDescription = "Use Smash DI to escape\nFox's up-air attack!", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = false, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &SDI_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData Powershield_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = 20, // 0xFF= .stage = 32, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc Powershield = { .eventName = "Powershield Training\n", .eventDescription = "Powershield Falco's laser!\nPause to change to fire-rate.", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = false, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &Powershield_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData Ledgetech_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = 20, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc Ledgetech = { .eventName = "Ledge-Tech Training\n", .eventDescription = "Practice ledge-teching\nFalco's down-smash", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &Ledgetech_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData AmsahTech_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = 9, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc AmsahTech = { .eventName = "Amsah-Tech Training\n", .eventDescription = "Taunt to have Marth Up-B,\nthen ASDI down and tech!\n", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &AmsahTech_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData ShieldDrop_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = -1, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc ShieldDrop = { .eventName = "Shield Drop Training\n", .eventDescription = "Counter with a shield-drop aerial!\nDPad left/right moves players apart.", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = true, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &ShieldDrop_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData WaveshineSDI_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = 2, // 0xFF= .stage = 32, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc WaveshineSDI = { .eventName = "Waveshine SDI\n", .eventDescription = "Use Smash DI to get out\nof Fox's waveshine!", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = false, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &WaveshineSDI_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData SlideOff_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = 9, // 0xFF= .stage = 3, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc SlideOff = { .eventName = "Slide-Off Training\n", .eventDescription = "Use Slide-Off DI to slide off\nthe platform and counter attack!\n", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = false, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &SlideOff_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData GrabMash_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = 9, // 0xFF= .stage = 32, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc GrabMash = { .eventName = "Grab Mash Training\n", .eventDescription = "Mash buttons to escape the grab\nas quickly as possible!\n", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = false, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &GrabMash_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData TechCounter_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = 9, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc TechCounter = { .eventName = "Ledgetech Marth Counter\n", .eventDescription = "Practice ledge-teching\nMarth's counter!\n", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &TechCounter_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData ArmadaShine_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = 2, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc ArmadaShine = { .eventName = "Armada-Shine Training\n", .eventDescription = "Finish the enemy Fox\nwith an Armada Shine!", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &ArmadaShine_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData SideBSweet_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = 9, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc SideBSweet = { .eventName = "Side-B Sweetspot\n", .eventDescription = "Use a sweetspot Side-B to avoid Marth's\ndown-tilt and grab the ledge!", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &SideBSweet_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData EscapeSheik_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = 19, // 0xFF= .stage = 32, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc EscapeSheik = { .eventName = "Escape Sheik Techchase\n", .eventDescription = "Practice escaping the tech chase with a\nframe perfect shine or jab SDI!\n", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = false, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &EscapeSheik_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData Eggs_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = -1, // 0xFF= .stage = -1, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc Eggs = { .eventName = "Eggs-ercise\n", .eventDescription = "Break the eggs! Only strong hits will\nbreak them. DPad down = free practice.", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = true, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &Eggs_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData Multishine_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = -1, // 0xFF= .stage = 32, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc Multishine = { .eventName = "Shined Blind\n", .eventDescription = "How many shines can you\nperform in 10 seconds?", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = false, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &Multishine_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData Reaction_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = 2, // 0xFF= .stage = 32, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc Reaction = { .eventName = "Reaction Test\n", .eventDescription = "Test your reaction time by pressing\nany button when you see/hear Fox shine!", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = false, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &Reaction_MatchData, .defaultOSD = 0xFFFFFFFF, }; // L-Cancel Training // Match Data static EventMatchData Ledgestall_MatchData = { .timer = MATCH_TIMER_COUNTUP, .matchType = MATCH_MATCHTYPE_TIME, .isDisableMusic = true, .hideGo = true, .hideReady = true, .isCreateHUD = true, .isDisablePause = false, // byte 0x3 .timerRunOnPause = false, // 0x01 .isHidePauseHUD = true, // 0x02 .isShowLRAStart = true, // 0x04 .isCheckForLRAStart = true, // 0x08 .isShowZRetry = true, // 0x10 .isCheckForZRetry = true, // 0x20 .isShowAnalogStick = true, // 0x40 .isShowScore = false, // 0x80 .isRunStockLogic = false, // 0x20 .isDisableHit = false, // 0x20 .useKOCounter = false, .playerKind = -1, .cpuKind = -1, // 0xFF= .stage = 6, // 0xFFFF .timerSeconds = 0, // 0xFFFFFFFF .timerSubSeconds = 0, // 0xFF .onCheckPause = 0, .onMatchEnd = 0, }; // Event Struct static EventDesc Ledgestall = { .eventName = "Under Fire\n", .eventDescription = "Ledgestall to remain\ninvincible while the lava rises!\n", .eventTutorial = "TvLC", .eventFile = 0, .isChooseCPU = false, .isSelectStage = false, .use_savestates = false, .disable_hazards = true, .scoreType = 0, .callbackPriority = 3, .matchData = &Ledgestall_MatchData, .defaultOSD = 0xFFFFFFFF, }; /////////////////////// /// Page Defintions /// /////////////////////// // Minigames static EventDesc *Minigames_Events[] = { &Eggs, &Multishine, &Reaction, &Ledgestall, }; static EventPage Minigames_Page = { .name = "Minigames", .eventNum = (sizeof(Minigames_Events) / 4) - 1, .events = Minigames_Events, }; // Page 2 Events static EventDesc *General_Events[] = { &Lab, &LCancel, &Ledgedash, &Wavedash, &Combo, &AttackOnShield, &Reversal, &SDI, &Powershield, &Ledgetech, &AmsahTech, &ShieldDrop, &WaveshineSDI, &SlideOff, &GrabMash, }; static EventPage General_Page = { .name = "General Tech", (sizeof(General_Events) / 4) - 1, General_Events, }; // Page 3 Events static EventDesc *Spacie_Events[] = { &TechCounter, &ArmadaShine, &SideBSweet, &EscapeSheik, }; static EventPage Spacie_Page = { .name = "Spacie Tech", (sizeof(Spacie_Events) / 4) - 1, Spacie_Events, }; ////////////////// /// Page Order /// ////////////////// static EventPage **EventPages[] = { &Minigames_Page, &General_Page, &Spacie_Page, }; //////////////////////// /// Static Variables /// //////////////////////// static EventVars stc_event_vars = { .event_desc = 0, .menu_assets = 0, .event_gobj = 0, .menu_gobj = 0, .game_timer = 0, .hide_menu = 0, .Savestate_Save = Savestate_Save, .Savestate_Load = Savestate_Load, .Message_Display = Message_Display, .Tip_Display = Tip_Display, .Tip_Destroy = Tip_Destroy, .savestate = 0, }; static Savestate *stc_savestate; static EventDesc *static_eventInfo; static MenuData *static_menuData; static int show_console = 1; static int *eventDataBackup; static TipMgr stc_tipmgr; /////////////////////// /// Event Functions /// /////////////////////// void EventInit(int page, int eventID, MatchInit *matchData) { /* This function runs when leaving the main menu/css and handles setting up the match information, such as rules, players, stage. All of this data comes from the EventDesc in events.c */ // get event pointer EventDesc *event = GetEventDesc(page, eventID); //Init default match info matchData->timer_unk2 = 0; matchData->unk2 = 1; matchData->unk7 = 1; matchData->isCheckStockSteal = 1; matchData->unk10 = 3; matchData->isSkipEndCheck = 1; matchData->itemFreq = MATCH_ITEMFREQ_OFF; matchData->onStartMelee = EventLoad; //Copy event's match info struct EventMatchData *eventMatchData = event->matchData; matchData->timer = eventMatchData->timer; matchData->matchType = eventMatchData->matchType; matchData->isDisableMusic = eventMatchData->isDisableMusic; matchData->hideGo = eventMatchData->hideGo; matchData->hideReady = eventMatchData->hideReady; matchData->isCreateHUD = eventMatchData->isCreateHUD; matchData->isDisablePause = eventMatchData->isDisablePause; matchData->timerRunOnPause = eventMatchData->timerRunOnPause; matchData->isHidePauseHUD = eventMatchData->isHidePauseHUD; matchData->isShowLRAStart = eventMatchData->isShowLRAStart; matchData->isCheckForLRAStart = eventMatchData->isCheckForLRAStart; matchData->isShowZRetry = eventMatchData->isShowZRetry; matchData->isCheckForZRetry = eventMatchData->isCheckForZRetry; matchData->isShowAnalogStick = eventMatchData->isShowAnalogStick; matchData->isShowScore = eventMatchData->isShowScore; matchData->isRunStockLogic = eventMatchData->isRunStockLogic; matchData->isDisableHit = eventMatchData->isDisableHit; matchData->timerSeconds = eventMatchData->timerSeconds; matchData->timerSubSeconds = eventMatchData->timerSubSeconds; matchData->onCheckPause = eventMatchData->onCheckPause; matchData->onMatchEnd = eventMatchData->onMatchEnd; // Initialize all player data Memcard *memcard = R13_PTR(MEMCARD); CSSBackup eventBackup = memcard->EventBackup; for (int i = 0; i < 6; i++) { // initialize data CSS_InitPlayerData(&matchData->playerData[i]); // set to enter fall on match start matchData->playerData[i].isEntry = false; // copy nametag id for the player if (i == 0) { // Update the player's nametag ID matchData->playerData[i].nametag = eventBackup.nametag; // Update the player's rumble setting int tagRumble = CSS_GetNametagRumble(0, matchData->playerData[0].nametag); matchData->playerData[0].isRumble = tagRumble; } } // Determine player ports u8 hmn_port = *stc_css_hmnport + 1; u8 cpu_port = *stc_css_cpuport + 1; // Determine the Player s32 playerKind; s32 playerCostume; Preload *preload = Preload_GetTable(); // If fighter is -1, copy the player from event data if (eventMatchData->playerKind != -1) { playerKind = eventMatchData->playerKind; playerCostume = 0; } // use the fighter chosen on the CSS else { playerKind = preload->fighters[0].kind; playerCostume = preload->fighters[0].costume; } // Determine the CPU s32 cpuKind; s32 cpuCostume; // If isChooseCPU is true, use the selected CPU if (event->isChooseCPU == true) { cpuKind = preload->fighters[1].kind; cpuCostume = preload->fighters[1].costume; // change zelda to sheik if (cpuKind == 18) { cpuKind = 19; preload->fighters[1].kind = cpuKind; } } // If isChooseCPU is false, copy the CPU from event data else { cpuKind = eventMatchData->cpuKind; cpuCostume = 0; cpuCostume = 0; } // Check if CPU is using the same character and color as P1 if ((playerKind == cpuKind) && (playerCostume == cpuCostume)) { // this doesnt account for if theyre both using the last costume cpuCostume += 1; } // Copy player data to match info struct (update their rumble setting 801bb1ec) matchData->playerData[0].kind = playerKind; matchData->playerData[0].costume = playerCostume; matchData->playerData[0].status = 0; matchData->playerData[0].portNumberOverride = hmn_port; // Copy CPU if they exist for this event if (cpuKind != -1) { matchData->playerData[1].kind = cpuKind; matchData->playerData[1].costume = cpuCostume; matchData->playerData[1].status = 1; matchData->playerData[1].portNumberOverride = cpu_port; } // Determine the correct HUD position for this amount of players int hudPos = 0; for (int i = 0; i < 6; i++) { if (matchData->playerData[i].status != 3) hudPos++; } matchData->hudPos = hudPos; // Determine the Stage int stage; // If isSelectStage is true, use the selected stage if (event->isSelectStage == true) { stage = preload->stage; } // If isSelectStage is false, copy the stage from event data else { stage = eventMatchData->stage; } // Update match struct with this stage matchData->stage = stage; //Update preload table? (801bb63c) return; }; void EventLoad() { // get this event Memcard *memcard = R13_PTR(MEMCARD); int page = memcard->TM_EventPage; int eventID = memcard->EventBackup.event; EventDesc *event_desc = GetEventDesc(page, eventID); evFunction *evFunction = &stc_event_vars.evFunction; // clear evFunction memset(evFunction, 0, sizeof(*evFunction)); // append extension static char *extension = "TM/%s.dat"; char *buffer[20]; sprintf(buffer, extension, event_desc->eventFile); // load this events file ArchiveInfo *archive = MEX_LoadRelArchive(buffer, evFunction, "evFunction"); stc_event_vars.event_archive = archive; // Create this event's gobj int pri = event_desc->callbackPriority; void *cb = evFunction->Event_Think; GOBJ *gobj = GObj_Create(0, 7, 0); int *userdata = calloc(EVENT_DATASIZE); GObj_AddUserData(gobj, 4, HSD_Free, userdata); GObj_AddProc(gobj, cb, pri); // store pointer to the event's data userdata[0] = event_desc; // Create a gobj to track match time stc_event_vars.game_timer = 0; GOBJ *timer_gobj = GObj_Create(0, 7, 0); GObj_AddProc(timer_gobj, Event_IncTimer, 0); // init the pause menu GOBJ *menu_gobj = EventMenu_Init(event_desc, *evFunction->menu_start); // Init static structure containing event variables stc_event_vars.event_desc = event_desc; stc_event_vars.event_gobj = gobj; stc_event_vars.menu_gobj = menu_gobj; // init savestate struct stc_savestate = calloc(sizeof(Savestate)); eventDataBackup = calloc(EVENT_DATASIZE); stc_savestate->is_exist = 0; stc_event_vars.savestate = stc_savestate; // disable hazards if enabled if (event_desc->disable_hazards == 1) Hazards_Disable(); // Run this event's init function if (evFunction->Event_Init != 0) { evFunction->Event_Init(gobj); } // Store update function HSD_Update *update = HSD_UPDATE; update->onFrame = EventUpdate; return; }; void EventUpdate() { // get event info EventDesc *event_desc = stc_event_vars.event_desc; evFunction *evFunction = &stc_event_vars.evFunction; GOBJ *menu_gobj = stc_event_vars.menu_gobj; // run savestate logic if enabled if (event_desc->use_savestates == true) { Update_Savestates(); } // run menu logic if exists if (menu_gobj != 0) { // update menu EventMenu_Update(menu_gobj); } // run custom event update function if (evFunction->Event_Update != 0) { evFunction->Event_Update(); } else Develop_UpdateMatchHotkeys(); return; } ////////////////////// /// Hook Functions /// ////////////////////// void TM_ConsoleThink(GOBJ *gobj) { // init variables int *data = gobj->userdata; DevText *text = data[0]; // check to toggle console for (int i = 0; i < 4; i++) { HSD_Pad *pad = PadGet(i, PADGET_MASTER); if (pad->held & (HSD_TRIGGER_L | HSD_TRIGGER_R) && (pad->down & HSD_TRIGGER_Z)) { // toggle visibility text->show_text ^= 1; text->show_background ^= 1; show_console ^= 1; break; } } // clear text //DevelopText_EraseAllText(text); //DevelopMode_ResetCursorXY(text, 0, 0); } void TM_CreateConsole() { // init dev text GOBJ *gobj = GObj_Create(0, 0, 0); int *data = calloc(32); GObj_AddUserData(gobj, 4, HSD_Free, data); GObj_AddProc(gobj, TM_ConsoleThink, 0); DevText *text = DevelopText_CreateDataTable(13, 0, 0, 28, 8, HSD_MemAlloc(0x1000)); DevelopText_Activate(0, text); text->show_cursor = 0; data[0] = text; GXColor color = {21, 20, 59, 135}; DevelopText_StoreBGColor(text, &color); DevelopText_StoreTextScale(text, 10, 12); stc_event_vars.db_console_text = text; if (show_console != 1) { // toggle visibility DevelopText_HideBG(text); DevelopText_HideText(text); } return; } void OnFileLoad(ArchiveInfo *archive) // this function is run right after TmDt is loaded into memory on boot { // init event menu assets stc_event_vars.menu_assets = File_GetSymbol(archive, "evMenu"); // store pointer to static variables *event_vars_ptr = &stc_event_vars; event_vars = *event_vars_ptr; return; } void OnSceneChange() { // Hook exists at 801a4c94 TM_CreateWatermark(); #if TM_DEBUG == 2 TM_CreateConsole(); #endif return; }; void OnBoot() { // OSReport("hi this is boot\n"); return; }; void OnStartMelee() { Message_Init(); Tip_Init(); return; } /////////////////////////////// /// Miscellaneous Functions /// /////////////////////////////// int Savestate_Save(Savestate *savestate) { typedef struct BackupQueue { GOBJ *fighter; FighterData *fighter_data; } BackupQueue; #if TM_DEBUG > 0 int save_pre_tick = OSGetTick(); #endif // ensure no players are in problematic states int canSave = 1; GOBJ **gobj_list = R13_PTR(GOBJLIST); GOBJ *fighter = gobj_list[8]; while (fighter != 0) { FighterData *fighter_data = fighter->userdata; if ((fighter_data->cb.OnDeath != 0) || (fighter_data->cb.OnDeath2 != 0) || (fighter_data->cb.OnDeath3 != 0) || (fighter_data->heldItem != 0) || (fighter_data->x1978 != 0) || (fighter_data->accessory != 0) || ((fighter_data->kind == 8) && ((fighter_data->state >= 342) && (fighter_data->state <= 344)))) // hardcode ness' usmash because it doesnt destroy the yoyo via onhit callback... { // cannot save canSave = 0; break; } fighter = fighter->next; } // loop through all players int isSaved = 0; if (canSave == 1) { savestate->is_exist = 1; // save frame savestate->frame = stc_event_vars.game_timer; // save event data memcpy(&savestate->event_data, stc_event_vars.event_gobj->userdata, sizeof(savestate->event_data)); // backup all players for (int i = 0; i < 6; i++) { // get fighter gobjs BackupQueue queue[2]; for (int j = 0; j < 2; j++) { GOBJ *fighter = 0; FighterData *fighter_data = 0; // get fighter gobj and data if they exist fighter = Fighter_GetSubcharGObj(i, j); if (fighter != 0) fighter_data = fighter->userdata; // store fighter pointers queue[j].fighter = fighter; queue[j].fighter_data = fighter_data; } // if the main fighter exists if (queue[0].fighter != 0) { FtState *ft_state = &savestate->ft_state[i]; isSaved = 1; // save playerblock Playerblock *playerblock = Fighter_GetPlayerblock(queue[0].fighter_data->ply); memcpy(&ft_state->player_block, playerblock, sizeof(Playerblock)); // save stale moves int *stale_queue = Fighter_GetStaleMoveTable(queue[0].fighter_data->ply); memcpy(&ft_state->stale_queue, stale_queue, sizeof(ft_state->stale_queue)); // backup each subfighters data for (int j = 0; j < 2; j++) { // if exists if (queue[j].fighter != 0) { FtStateData *ft_data = &ft_state->data[j]; FighterData *fighter_data = queue[j].fighter_data; // backup to ft_state ft_data->is_exist = 1; ft_data->state = fighter_data->state; ft_data->facing_direction = fighter_data->facing_direction; ft_data->stateFrame = fighter_data->stateFrame; ft_data->stateSpeed = fighter_data->stateSpeed; ft_data->stateBlend = fighter_data->stateBlend; memcpy(&ft_data->phys, &fighter_data->phys, sizeof(fighter_data->phys)); // copy physics memcpy(&ft_data->color, &fighter_data->color, sizeof(fighter_data->color)); // copy color overlay memcpy(&ft_data->input, &fighter_data->input, sizeof(fighter_data->input)); // copy inputs memcpy(&ft_data->coll_data, &fighter_data->coll_data, sizeof(fighter_data->coll_data)); // copy collision memcpy(&ft_data->cameraBox, fighter_data->cameraBox, sizeof(CameraBox)); // copy camerabox memcpy(&ft_data->hitbox, &fighter_data->hitbox, sizeof(fighter_data->hitbox)); // copy hitbox memcpy(&ft_data->throw_hitbox, &fighter_data->throw_hitbox, sizeof(fighter_data->throw_hitbox)); // copy hitbox memcpy(&ft_data->unk_hitbox, &fighter_data->unk_hitbox, sizeof(fighter_data->unk_hitbox)); // copy hitbox memcpy(&ft_data->flags, &fighter_data->flags, sizeof(fighter_data->flags)); // copy flags memcpy(&ft_data->fighter_var, &fighter_data->fighter_var, sizeof(fighter_data->fighter_var)); // copy var memcpy(&ft_data->state_var, &fighter_data->state_var, sizeof(fighter_data->state_var)); // copy var memcpy(&ft_data->ftcmd_var, &fighter_data->ftcmd_var, sizeof(fighter_data->ftcmd_var)); // copy var memcpy(&ft_data->jump, &fighter_data->jump, sizeof(fighter_data->jump)); // copy var memcpy(&ft_data->smash, &fighter_data->smash, sizeof(fighter_data->smash)); // copy var memcpy(&ft_data->hurtstatus, &fighter_data->hurtstatus, sizeof(fighter_data->hurtstatus)); // copy var memcpy(&ft_data->shield, &fighter_data->shield, sizeof(fighter_data->shield)); // copy hitbox memcpy(&ft_data->shield_bubble, &fighter_data->shield_bubble, sizeof(fighter_data->shield_bubble)); // copy hitbox memcpy(&ft_data->reflect_bubble, &fighter_data->reflect_bubble, sizeof(fighter_data->reflect_bubble)); // copy hitbox memcpy(&ft_data->absorb_bubble, &fighter_data->absorb_bubble, sizeof(fighter_data->absorb_bubble)); // copy hitbox memcpy(&ft_data->reflect_hit, &fighter_data->reflect_hit, sizeof(fighter_data->reflect_hit)); // copy hitbox memcpy(&ft_data->absorb_hit, &fighter_data->absorb_hit, sizeof(fighter_data->absorb_hit)); // copy hitbox // copy dmg memcpy(&ft_data->dmg, &fighter_data->dmg, sizeof(fighter_data->dmg)); ft_data->dmg.source = GOBJToID(ft_data->dmg.source); // copy grab memcpy(&ft_data->grab, &fighter_data->grab, sizeof(fighter_data->grab)); ft_data->grab.grab_attacker = GOBJToID(ft_data->grab.grab_attacker); ft_data->grab.grab_victim = GOBJToID(ft_data->grab.grab_victim); // copy callbacks memcpy(&ft_data->cb, &fighter_data->cb, sizeof(fighter_data->cb)); // copy hitbox // convert hitbox pointers for (int k = 0; k < (sizeof(fighter_data->hitbox) / sizeof(ftHit)); k++) { ft_data->hitbox[k].bone = BoneToID(fighter_data, ft_data->hitbox[k].bone); for (int l = 0; l < (sizeof(fighter_data->hitbox->victims) / sizeof(HitVictim)); l++) // pointers to hitbox victims { ft_data->hitbox[k].victims[l].victim_data = FtDataToID(ft_data->hitbox[k].victims[l].victim_data); } } for (int k = 0; k < (sizeof(fighter_data->throw_hitbox) / sizeof(ftHit)); k++) { ft_data->throw_hitbox[k].bone = BoneToID(fighter_data, ft_data->throw_hitbox[k].bone); for (int l = 0; l < (sizeof(fighter_data->throw_hitbox->victims) / sizeof(HitVictim)); l++) // pointers to hitbox victims { ft_data->throw_hitbox[k].victims[l].victim_data = FtDataToID(ft_data->throw_hitbox[k].victims[l].victim_data); } } ft_data->unk_hitbox.bone = BoneToID(fighter_data, ft_data->unk_hitbox.bone); for (int k = 0; k < (sizeof(fighter_data->unk_hitbox.victims) / sizeof(HitVictim)); k++) // pointers to hitbox victims { ft_data->unk_hitbox.victims[k].victim_data = FtDataToID(ft_data->unk_hitbox.victims[k].victim_data); } // copy XRotN rotation s8 XRotN_id = Fighter_BoneLookup(fighter_data, XRotN); if (XRotN_id != -1) { ft_data->XRotN_rot = fighter_data->bones[XRotN_id].joint->rot; } } } } } } // Play SFX if (isSaved == 0) { SFX_PlayCommon(3); } if (isSaved == 1) { // play sfx SFX_PlayCommon(1); // if not in frame advance, flash screen. I wrote it like this because the second condition kept getting optimized out if ((Pause_CheckStatus(0) != 1)) { if ((Pause_CheckStatus(1) != 2)) { ScreenFlash_Create(2, 0); } } } #if TM_DEBUG > 0 int save_post_tick = OSGetTick(); int save_time = OSTicksToMilliseconds(save_post_tick - save_pre_tick); OSReport("processed save in %dms\n", save_time); #endif return isSaved; } int Savestate_Load(Savestate *savestate) { typedef struct BackupQueue { GOBJ *fighter; FighterData *fighter_data; } BackupQueue; #if TM_DEBUG > 0 int load_pre_tick = OSGetTick(); #endif // loop through all players int isLoaded = 0; for (int i = 0; i < 6; i++) { // get fighter gobjs BackupQueue queue[2]; for (int j = 0; j < 2; j++) { GOBJ *fighter = 0; FighterData *fighter_data = 0; // get fighter gobj and data if they exist fighter = Fighter_GetSubcharGObj(i, j); if (fighter != 0) fighter_data = fighter->userdata; // store fighter pointers queue[j].fighter = fighter; queue[j].fighter_data = fighter_data; } // if the main fighter and backup exists if ((queue[0].fighter != 0) && (savestate->ft_state[i].data[0].is_exist == 1)) { FtState *ft_state = &savestate->ft_state[i]; isLoaded = 1; // restore playerblock Playerblock *playerblock = Fighter_GetPlayerblock(queue[0].fighter_data->ply); GOBJ *fighter_gobj[2]; fighter_gobj[0] = playerblock->fighterData; fighter_gobj[1] = playerblock->fighterDataSub; memcpy(playerblock, &ft_state->player_block, sizeof(Playerblock)); playerblock->fighterData = fighter_gobj[0]; playerblock->fighterDataSub = fighter_gobj[1]; // restore stale moves int *stale_queue = Fighter_GetStaleMoveTable(queue[0].fighter_data->ply); memcpy(stale_queue, &ft_state->stale_queue, sizeof(ft_state->stale_queue)); // restore fighter data for (int j = 0; j < 2; j++) { GOBJ *fighter = queue[j].fighter; if (fighter != 0) { // get state FtStateData *ft_data = &ft_state->data[j]; FighterData *fighter_data = queue[j].fighter_data; // sleep Fighter_EnterSleep(fighter, 0); fighter_data->state = ft_data->state; fighter_data->facing_direction = ft_data->facing_direction; fighter_data->stateFrame = ft_data->stateFrame; fighter_data->stateSpeed = ft_data->stateSpeed; fighter_data->stateBlend = ft_data->stateBlend; // restore phys struct memcpy(&fighter_data->phys, &ft_data->phys, sizeof(fighter_data->phys)); // copy physics // restore inputs memcpy(&fighter_data->input, &ft_data->input, sizeof(fighter_data->input)); // copy inputs // restore coll data CollData *thiscoll = &fighter_data->coll_data; CollData *savedcoll = &ft_data->coll_data; GOBJ *gobj = thiscoll->gobj; // 0x0 JOBJ *joint_1 = thiscoll->joint_1; // 0x108 JOBJ *joint_2 = thiscoll->joint_2; // 0x10c JOBJ *joint_3 = thiscoll->joint_3; // 0x110 JOBJ *joint_4 = thiscoll->joint_4; // 0x114 JOBJ *joint_5 = thiscoll->joint_5; // 0x118 JOBJ *joint_6 = thiscoll->joint_6; // 0x11c JOBJ *joint_7 = thiscoll->joint_7; // 0x120 memcpy(&fighter_data->coll_data, &ft_data->coll_data, sizeof(fighter_data->coll_data)); // copy collision thiscoll->gobj = gobj; thiscoll->joint_1 = joint_1; thiscoll->joint_2 = joint_2; thiscoll->joint_3 = joint_3; thiscoll->joint_4 = joint_4; thiscoll->joint_5 = joint_5; thiscoll->joint_6 = joint_6; thiscoll->joint_7 = joint_7; // restore hitboxes memcpy(&fighter_data->hitbox, &ft_data->hitbox, sizeof(fighter_data->hitbox)); // copy hitbox memcpy(&fighter_data->throw_hitbox, &ft_data->throw_hitbox, sizeof(fighter_data->throw_hitbox)); // copy hitbox memcpy(&fighter_data->unk_hitbox, &ft_data->unk_hitbox, sizeof(fighter_data->unk_hitbox)); // copy hitbox // copy grab memcpy(&fighter_data->grab, &ft_data->grab, sizeof(fighter_data->grab)); fighter_data->grab.grab_attacker = IDToGOBJ(fighter_data->grab.grab_attacker); fighter_data->grab.grab_victim = IDToGOBJ(fighter_data->grab.grab_victim); // convert pointers for (int k = 0; k < (sizeof(fighter_data->hitbox) / sizeof(ftHit)); k++) { fighter_data->hitbox[k].bone = IDToBone(fighter_data, ft_data->hitbox[k].bone); for (int l = 0; l < (sizeof(fighter_data->hitbox->victims) / sizeof(HitVictim)); l++) // pointers to hitbox victims { fighter_data->hitbox[k].victims[l].victim_data = IDToFtData(ft_data->hitbox[k].victims[l].victim_data); } } for (int k = 0; k < (sizeof(fighter_data->throw_hitbox) / sizeof(ftHit)); k++) { fighter_data->throw_hitbox[k].bone = IDToBone(fighter_data, ft_data->throw_hitbox[k].bone); for (int l = 0; l < (sizeof(fighter_data->throw_hitbox->victims) / sizeof(HitVictim)); l++) // pointers to hitbox victims { fighter_data->throw_hitbox[k].victims[l].victim_data = IDToFtData(ft_data->throw_hitbox[k].victims[l].victim_data); } } fighter_data->unk_hitbox.bone = IDToBone(fighter_data, ft_data->unk_hitbox.bone); for (int k = 0; k < (sizeof(fighter_data->unk_hitbox.victims) / sizeof(HitVictim)); k++) // pointers to hitbox victims { fighter_data->unk_hitbox.victims[k].victim_data = IDToFtData(ft_data->unk_hitbox.victims[k].victim_data); } // restore fighter variables memcpy(&fighter_data->fighter_var, &ft_data->fighter_var, sizeof(fighter_data->fighter_var)); // copy hitbox // zero pointer to cached animations to force anim load (fixes fall crash) fighter_data->anim_curr_ARAM = 0; fighter_data->anim_persist_ARAM = 0; // enter backed up state GOBJ *anim_source = 0; if (fighter_data->flags.is_thrown == 1) anim_source = fighter_data->grab.grab_attacker; Fighter_SetAllHurtboxesNotUpdated(fighter); ActionStateChange(ft_data->stateFrame, ft_data->stateSpeed, -1, fighter, ft_data->state, 0, anim_source); fighter_data->stateBlend = 0; // restore XRotN rotation s8 XRotN_id = Fighter_BoneLookup(fighter_data, XRotN); if (XRotN_id != -1) { fighter_data->bones[XRotN_id].joint->rot = ft_data->XRotN_rot; } // restore state variables memcpy(&fighter_data->state_var, &ft_data->state_var, sizeof(fighter_data->state_var)); // copy hitbox // restore ftcmd variables memcpy(&fighter_data->ftcmd_var, &ft_data->ftcmd_var, sizeof(fighter_data->ftcmd_var)); // copy hitbox // restore damage variables memcpy(&fighter_data->dmg, &ft_data->dmg, sizeof(fighter_data->dmg)); // copy hitbox fighter_data->dmg.source = IDToGOBJ(fighter_data->dmg.source); // restore jump variables memcpy(&fighter_data->jump, &ft_data->jump, sizeof(fighter_data->jump)); // copy hitbox // restore flags memcpy(&fighter_data->flags, &ft_data->flags, sizeof(fighter_data->flags)); // copy hitbox // restore hurtstatus variables memcpy(&fighter_data->hurtstatus, &ft_data->hurtstatus, sizeof(fighter_data->hurtstatus)); // copy hitbox // update jobj position JOBJ *fighter_jobj = fighter->hsd_object; fighter_jobj->trans = fighter_data->phys.pos; // dirtysub their jobj JOBJ_SetMtxDirtySub(fighter_jobj); // update hurtbox position Fighter_UpdateHurtboxes(fighter_data); // remove color overlay Fighter_ColorRemove(fighter_data, 9); // restore color for (int k = 0; k < (sizeof(fighter_data->color) / sizeof(ColorOverlay)); k++) { ColorOverlay *thiscolor = &fighter_data->color[k]; ColorOverlay *savedcolor = &ft_data->color[k]; // backup nono pointers int *ptr1 = thiscolor->ptr1; int *ptr2 = thiscolor->ptr2; int *alloc = thiscolor->alloc; // mempcy entire memcpy(thiscolor, savedcolor, sizeof(ColorOverlay)); // restore nono pointers thiscolor->ptr1 = ptr1; thiscolor->ptr2 = ptr2; thiscolor->alloc = alloc; } // restore smash variables memcpy(&fighter_data->smash, &ft_data->smash, sizeof(fighter_data->smash)); // copy hitbox // restore shield/reflect/absorb variables memcpy(&fighter_data->shield, &ft_data->shield, sizeof(fighter_data->shield)); // copy hitbox memcpy(&fighter_data->shield_bubble, &ft_data->shield_bubble, sizeof(fighter_data->shield_bubble)); // copy hitbox memcpy(&fighter_data->reflect_bubble, &ft_data->reflect_bubble, sizeof(fighter_data->reflect_bubble)); // copy hitbox memcpy(&fighter_data->absorb_bubble, &ft_data->absorb_bubble, sizeof(fighter_data->absorb_bubble)); // copy hitbox memcpy(&fighter_data->reflect_hit, &ft_data->reflect_hit, sizeof(fighter_data->reflect_hit)); // copy hitbox memcpy(&fighter_data->absorb_hit, &ft_data->absorb_hit, sizeof(fighter_data->absorb_hit)); // copy hitbox // restore callback functions memcpy(&fighter_data->cb, &ft_data->cb, sizeof(fighter_data->cb)); // copy hitbox // stop player SFX SFX_StopAllFighterSFX(fighter_data); // update colltest frame fighter_data->coll_data.coll_test = *stc_colltest; // restore camera box CameraBox *thiscam = fighter_data->cameraBox; CameraBox *savedcam = &ft_data->cameraBox; void *alloc = thiscam->alloc; CameraBox *next = thiscam->next; memcpy(thiscam, savedcam, sizeof(CameraBox)); // copy camerabox thiscam->alloc = alloc; thiscam->next = next; // update their IK Fighter_UpdateIK(fighter); // if shield is up, update shield if ((fighter_data->state >= ASID_GUARDON) && (fighter_data->state <= ASID_GUARDREFLECT)) { // get gfx ID int shieldGFX; static u16 ShieldGFXLookup[] = {1047, 1048, -1, 1049, -1}; // covers GUARDON -> GUARDREFLECT shieldGFX = ShieldGFXLookup[fighter_data->state - ASID_GUARDON]; // create GFX int color_index = Fighter_GetShieldColorIndex(fighter_data->ply); GXColor *shieldColors = R13_PTR(-0x5194); GXColor *shieldColor = &shieldColors[color_index]; JOBJ *shieldBone = fighter_data->bones[fighter_data->ftData->modelLookup[0x11]].joint; int shieldColorParam = (shieldColor->r << 16) | (shieldColor->b << 8) | (shieldColor->g); Effect_SpawnSync(shieldGFX, fighter, shieldBone, shieldColorParam); Fighter_UpdateShieldGFX(fighter, 1); } // process dynamics #if TM_DEBUG > 0 int dyn_pre_tick = OSGetTick(); #endif int dyn_proc_num = 45; // simulate dynamics a bunch to fall in place for (int d = 0; d < dyn_proc_num; d++) { Fighter_ProcDynamics(fighter); } #if TM_DEBUG > 0 int dyn_post_tick = OSGetTick(); int dyn_time = OSTicksToMilliseconds(dyn_post_tick - dyn_pre_tick); OSReport("processed dyn %d times in %dms\n", dyn_proc_num, dyn_time); #endif // remove all items belonging to this fighter GOBJList *gobj_list = *stc_gobj_list; GOBJ *item = gobj_list->item; while (item != 0) { // get next GOBJ *next_item = item->next; // check to delete ItemData *item_data = item->userdata; if (fighter == item_data->fighter) { // destroy it Item_Destroy(item); } item = next_item; } } } sizeof(FtStateData); // check to recreate HUD MatchHUD *hud = &stc_matchhud[i]; // check if fighter is perm dead if (Match_CheckIfStock() == 1) { // remove HUD if no stocks left if (Fighter_GetStocks(i) <= 0) { hud->is_removed = 0; } } // check to create it if (hud->is_removed == 1) { Match_CreateHUD(i); } // snap camera to the new positions Match_CorrectCamera(); // stop crowd cheer SFX_StopCrowd(); } } // Restore event data and Play SFX if (isLoaded == 0) { SFX_PlayCommon(3); } if (isLoaded == 1) { // restore frame Match *match = stc_match; match->time_frames = savestate->frame; stc_event_vars.game_timer = savestate->frame; // update timer int frames = match->time_frames - 1; // this is because the scenethink function runs once before the gobj procs do match->time_seconds = frames / 60; match->time_ms = frames % 60; // restore event data memcpy(stc_event_vars.event_gobj->userdata, &savestate->event_data, sizeof(savestate->event_data)); // remove all particles for (int i = 0; i < PTCL_LINKMAX; i++) { Particle2 **ptcls = &stc_ptcl[i]; Particle2 *ptcl = *ptcls; while (ptcl != 0) { Particle2 *ptcl_next = ptcl->next; // begin destroying this particle // subtract some value, 8039c9f0 if (ptcl->x88 != 0) { int *arr = ptcl->x88; arr[0x50 / 4]--; } // remove from generator? 8039ca14 if (ptcl->gen != 0) psRemoveParticleAppSRT(ptcl); // delete parent jobj, 8039ca48 psDeletePntJObjwithParticle(ptcl); // update most recent ptcl pointer *ptcls = ptcl->next; // free alloc, 8039ca54 HSD_ObjFree(0x804d0f60, ptcl); // decrement ptcl total u16 ptclnum = *stc_ptclnum; ptclnum--; *stc_ptclnum = ptclnum; // get next ptcl = ptcl_next; } } /* // remove all generators with linkNo 2 (blastzone) ptclGen *gen = *stc_ptclgen; while (gen != 0) { // get next ptclGen *gen_next = gen->next; // if linkNo 2, destroy it if (gen->link_no == 2) { // set a flag for some reason gen->type |= 0x80; // kill gen gen = psKillGenerator(gen, *stc_ptclgencurr); } // save last *stc_ptclgencurr = gen; // get next gen = gen_next; } */ // remove all camera shake gobjs (p_link 18, entity_class 3) GOBJList *gobj_list = *stc_gobj_list; GOBJ *gobj = gobj_list->match_cam; while (gobj != 0) { GOBJ *gobj_next = gobj->next; // if entity class 3 (quake) if (gobj->entity_class == 3) { GObj_Destroy(gobj); } gobj = gobj_next; } // play sfx SFX_PlayCommon(0); } #if TM_DEBUG > 0 int load_post_tick = OSGetTick(); int load_time = OSTicksToMilliseconds(load_post_tick - load_pre_tick); OSReport("processed load in %dms\n", load_time); sizeof(FtState); #endif return isLoaded; } void Update_Savestates() { // not when pause menu is showing if (Pause_CheckStatus(1) != 2) { // loop through all humans for (int i = 0; i < 6; i++) { // check if fighter exists GOBJ *fighter = Fighter_GetGObj(i); if (fighter != 0) { // get fighter data FighterData *fighter_data = fighter->userdata; HSD_Pad *pad = PadGet(fighter_data->ply, PADGET_MASTER); // check for savestate int blacklist = (HSD_BUTTON_DPAD_DOWN | HSD_BUTTON_DPAD_UP | HSD_TRIGGER_Z | HSD_TRIGGER_R | HSD_BUTTON_A | HSD_BUTTON_B | HSD_BUTTON_X | HSD_BUTTON_Y | HSD_BUTTON_START); if (((pad->down & HSD_BUTTON_DPAD_RIGHT) != 0) && ((pad->held & (blacklist)) == 0)) { // save state Savestate_Save(stc_savestate); } else if (((pad->down & HSD_BUTTON_DPAD_LEFT) != 0) && ((pad->held & (blacklist)) == 0)) { // load state Savestate_Load(stc_savestate); } } } } return; } int GOBJToID(GOBJ *gobj) { // ensure valid pointer if (gobj == 0) return -1; // ensure its a fighter if (gobj->entity_class != 4) return -1; // access the data FighterData *ft_data = gobj->userdata; u8 ply = ft_data->ply; u8 ms = ft_data->flags.ms; return ((ply << 4) | ms); } int FtDataToID(FighterData *fighter_data) { // ensure valid pointer if (fighter_data == 0) return -1; // ensure its a fighter if (fighter_data->fighter == 0) return -1; // get ply and ms u8 ply = fighter_data->ply; u8 ms = fighter_data->flags.ms; return ((ply << 4) | ms); } int BoneToID(FighterData *fighter_data, JOBJ *bone) { // ensure bone exists if (bone == 0) return -1; int bone_id = -1; // painstakingly look for a match for (int i = 0; i < fighter_data->bone_num; i++) { if (bone == fighter_data->bones[i].joint) { bone_id = i; break; } } #if TM_DEBUG > 0 // no bone found if (bone_id == -1) { assert("no bone found"); } #endif return bone_id; } GOBJ *IDToGOBJ(int id) { // ensure valid pointer if (id == -1) return 0; // get ply and ms u8 ply = (id >> 4) & 0xF; u8 ms = id & 0xF; // get the gobj for this fighter GOBJ *gobj = Fighter_GetSubcharGObj(ply, ms); return gobj; } FighterData *IDToFtData(int id) { // ensure valid pointer if (id == -1) return 0; // get ply and ms u8 ply = (id >> 4) & 0xF; u8 ms = id & 0xF; // get the gobj for this fighter GOBJ *gobj = Fighter_GetSubcharGObj(ply, ms); FighterData *fighter_data = gobj->userdata; return fighter_data; } JOBJ *IDToBone(FighterData *fighter_data, int id) { // ensure valid pointer if (id == -1) return 0; // get the bone JOBJ *bone = fighter_data->bones[id].joint; return bone; } void Event_IncTimer(GOBJ *gobj) { stc_event_vars.game_timer++; return; } void TM_CreateWatermark() { // create text canvas int canvas = Text_CreateCanvas(10, 0, 9, 13, 0, 14, 0, 19); // create text Text *text = Text_CreateText(10, canvas); // enable align and kerning text->align = 2; text->kerning = 1; // scale canvas text->scale.X = 0.4; text->scale.Y = 0.4; text->trans.X = 615; text->trans.Y = 446; // print string int shadow = Text_AddSubtext(text, 2, 2, TM_VersShort); GXColor shadow_color = {0, 0, 0, 0}; Text_SetColor(text, shadow, &shadow_color); int shadow1 = Text_AddSubtext(text, 2, -2, TM_VersShort); Text_SetColor(text, shadow1, &shadow_color); int shadow2 = Text_AddSubtext(text, -2, 2, TM_VersShort); Text_SetColor(text, shadow2, &shadow_color); int shadow3 = Text_AddSubtext(text, -2, -2, TM_VersShort); Text_SetColor(text, shadow3, &shadow_color); Text_AddSubtext(text, 0, 0, TM_VersShort); return; } void Hazards_Disable() { // get stage id int stage_internal = Stage_ExternalToInternal(Stage_GetExternalID()); int is_fixwind = 0; switch (stage_internal) { case (GR_STORY): { // remove shyguy map gobj proc GOBJ *shyguy_gobj = Stage_GetMapGObj(3); GObj_RemoveProc(shyguy_gobj); // remove randall GOBJ *randall_gobj = Stage_GetMapGObj(2); Stage_DestroyMapGObj(randall_gobj); is_fixwind = 1; break; } case (GR_PSTAD): { // remove map gobj proc GOBJ *map_gobj = Stage_GetMapGObj(2); GObj_RemoveProc(map_gobj); is_fixwind = 1; break; } case (GR_OLDPU): { // remove map gobj proc GOBJ *map_gobj = Stage_GetMapGObj(7); GObj_RemoveProc(map_gobj); // remove map gobj proc map_gobj = Stage_GetMapGObj(6); GObj_RemoveProc(map_gobj); // set wind hazard num to 0 *ftchkdevice_windnum = 0; break; } case (GR_FD): { // set bg skip flag GOBJ *map_gobj = Stage_GetMapGObj(3); map_gobjData *map_data = map_gobj->userdata; map_data->xc4 |= 0x40; // remove on-go function that changes this flag StageOnGO *on_go = stc_stage->on_go; stc_stage->on_go = on_go->next; HSD_Free(on_go); break; } } // Certain stages have an essential ragdoll function // in their map_gobj think function. If the think function is removed, // the ragdoll function must be re-scheduled to function properly. if (is_fixwind == 1) { GOBJ *wind_gobj = GObj_Create(3, 5, 0); GObj_AddProc(wind_gobj, Dynamics_DecayWind, 4); } } // Message Functions void Message_Init() { // create cobj GOBJ *cam_gobj = GObj_Create(19, 20, 0); COBJDesc *cam_desc = stc_event_vars.menu_assets->hud_cobjdesc; COBJ *cam_cobj = COBJ_LoadDescSetScissor(cam_desc); cam_cobj->scissor_bottom = 400; // init camera GObj_AddObject(cam_gobj, R13_U8(-0x3E55), cam_cobj); //R13_U8(-0x3E55) GOBJ_InitCamera(cam_gobj, Message_CObjThink, MSG_COBJLGXPRI); cam_gobj->cobj_links = MSG_COBJLGXLINKS; // Create manager GOBJ GOBJ *mgr_gobj = GObj_Create(0, 7, 0); MsgMngrData *mgr_data = calloc(sizeof(MsgMngrData)); GObj_AddUserData(mgr_gobj, 4, HSD_Free, mgr_data); GObj_AddProc(mgr_gobj, Message_Manager, 18); // create text canvas int canvas = Text_CreateCanvas(2, mgr_gobj, 14, 15, 0, MSG_GXLINK, MSGTEXT_GXPRI, 19); mgr_data->canvas = canvas; // store cobj mgr_data->cobj = cam_cobj; // store gobj pointer stc_msgmgr = mgr_gobj; return; } GOBJ *Message_Display(int msg_kind, int queue_num, int msg_color, char *format, ...) { va_list args; MsgMngrData *mgr_data = stc_msgmgr->userdata; // Create GOBJ GOBJ *msg_gobj = GObj_Create(0, 7, 0); MsgData *msg_data = calloc(sizeof(MsgData)); GObj_AddUserData(msg_gobj, 4, HSD_Free, msg_data); GObj_AddGXLink(msg_gobj, GXLink_Common, MSG_GXLINK, MSG_GXPRI); JOBJ *msg_jobj = JOBJ_LoadJoint(stc_event_vars.menu_assets->message); GObj_AddObject(msg_gobj, R13_U8(-0x3E55), msg_jobj); msg_data->lifetime = MSG_LIFETIME; msg_data->kind = msg_kind; msg_data->state = MSGSTATE_SHIFT; msg_data->anim_timer = MSGTIMER_SHIFT; msg_jobj->scale.X = MSGJOINT_SCALE; msg_jobj->scale.Y = MSGJOINT_SCALE; msg_jobj->scale.Z = MSGJOINT_SCALE; msg_jobj->trans.X = MSGJOINT_X; msg_jobj->trans.Y = MSGJOINT_Y; msg_jobj->trans.Z = MSGJOINT_Z; // Create text object Text *msg_text = Text_CreateText(2, mgr_data->canvas); msg_data->text = msg_text; msg_text->kerning = 1; msg_text->align = 1; msg_text->use_aspect = 1; msg_text->color = stc_msg_colors[msg_color]; // adjust scale Vec3 scale = msg_jobj->scale; // background scale msg_jobj->scale = scale; // text scale msg_text->scale.X = (scale.X * 0.01) * MSGTEXT_BASESCALE; msg_text->scale.Y = (scale.Y * 0.01) * MSGTEXT_BASESCALE; msg_text->aspect.X = MSGTEXT_BASEWIDTH; JOBJ_SetMtxDirtySub(msg_jobj); // build string char buffer[(MSG_LINEMAX * MSG_CHARMAX) + 1]; va_start(args, format); vsprintf(buffer, format, args); va_end(args); char *msg = &buffer; // count newlines int line_num = 1; int line_length_arr[MSG_LINEMAX]; char *msg_cursor_prev, *msg_cursor_curr; // declare char pointers msg_cursor_prev = msg; msg_cursor_curr = strchr(msg_cursor_prev, '\n'); // check for occurrence while (msg_cursor_curr != 0) // if occurrence found, increment values { // check if exceeds max lines if (line_num >= MSG_LINEMAX) assert("MSG_LINEMAX exceeded!"); // Save information about this line line_length_arr[line_num - 1] = msg_cursor_curr - msg_cursor_prev; // determine length of the line line_num++; // increment number of newlines found msg_cursor_prev = msg_cursor_curr + 1; // update prev cursor msg_cursor_curr = strchr(msg_cursor_prev, '\n'); // check for another occurrence } // get last lines length msg_cursor_curr = strchr(msg_cursor_prev, 0); line_length_arr[line_num - 1] = msg_cursor_curr - msg_cursor_prev; // copy each line to an individual char array char *msg_cursor = &msg; for (int i = 0; i < line_num; i++) { // check if over char max u8 line_length = line_length_arr[i]; if (line_length > MSG_CHARMAX) assert("MSG_CHARMAX exceeded!"); // copy char array char msg_line[MSG_CHARMAX + 1]; memcpy(msg_line, msg, line_length); // add null terminator msg_line[line_length] = '\0'; // increment msg msg += (line_length + 1); // +1 to skip past newline // print line int y_base = (line_num - 1) * ((-1 * MSGTEXT_YOFFSET) / 2); int y_delta = (i * MSGTEXT_YOFFSET); Text_AddSubtext(msg_text, 0, y_base + y_delta, msg_line); } // Add to queue Message_Add(msg_gobj, queue_num); return msg_gobj; } void Message_Manager(GOBJ *mngr_gobj) { MsgMngrData *mgr_data = mngr_gobj->userdata; // Iterate through each queue for (int i = 0; i < MSGQUEUE_NUM; i++) { GOBJ **msg_queue = &mgr_data->msg_queue[i]; // anim update (time based logic) for (int j = (MSGQUEUE_SIZE - 2); j >= 0; j--) // iterate through backwards (because deletions) { GOBJ *this_msg_gobj = msg_queue[j]; // if message exists if (this_msg_gobj != 0) { MsgData *this_msg_data = this_msg_gobj->userdata; Text *this_msg_text = this_msg_data->text; JOBJ *this_msg_jobj = this_msg_gobj->hsd_object; // check if the message moved this frame if (this_msg_data->orig_index != j) { this_msg_data->orig_index = j; // moved so update this this_msg_data->state = MSGSTATE_SHIFT; // enter shift this_msg_data->anim_timer = MSGTIMER_SHIFT; // shift timer } // decrement state timer if above 0 if (this_msg_data->anim_timer > 0) this_msg_data->anim_timer--; switch (this_msg_data->state) { case (MSGSTATE_WAIT): case (MSGSTATE_SHIFT): { // increment alive time this_msg_data->alive_timer++; // if lifetime is ended, enter delete state if (this_msg_data->alive_timer >= this_msg_data->lifetime) { // if using frame advance, instantly remove this message if (Pause_CheckStatus(0) == 1) { Message_Destroy(msg_queue, j); } else { this_msg_data->state = MSGSTATE_DELETE; this_msg_data->anim_timer = MSGTIMER_DELETE; } } break; } case (MSGSTATE_DELETE): { // if timer is ended, remove the message if ((this_msg_data->anim_timer <= 0)) { Message_Destroy(msg_queue, j); } break; } } } } // position update (update messages' onscreen positions) for (int j = 0; j < MSGQUEUE_SIZE; j++) { GOBJ *this_msg_gobj = msg_queue[j]; // if message exists if (this_msg_gobj != 0) { MsgData *this_msg_data = this_msg_gobj->userdata; Text *this_msg_text = this_msg_data->text; JOBJ *this_msg_jobj = this_msg_gobj->hsd_object; // Get the onscreen position for this queue Vec3 base_pos; Vec3 this_msg_pos; float pos_delta = stc_msg_queue_offsets[i]; if (i < 6) { Vec3 *hud_pos = Match_GetPlayerHUDPos(i); base_pos.X = hud_pos->X; base_pos.Y = hud_pos->Y + MSG_HUDYOFFSET; base_pos.Z = hud_pos->Z; } else if (i == MSGQUEUE_GENERAL) { base_pos = stc_msg_queue_general_pos; } this_msg_pos.X = base_pos.X; // Get this messages position switch (this_msg_data->state) { case (MSGSTATE_WAIT): case (MSGSTATE_SHIFT): { // get time float t = (((float)MSGTIMER_SHIFT - this_msg_data->anim_timer) / MSGTIMER_SHIFT); // get initial and final position for animation float final_pos = base_pos.Y + ((float)j * pos_delta); float initial_pos = base_pos.Y + ((float)this_msg_data->prev_index * pos_delta); if (Pause_CheckStatus(0) == 1) // if using frame advance, do not animate { this_msg_pos.Y = final_pos; } else { this_msg_pos.Y = (BezierBlend(t) * (final_pos - initial_pos)) + initial_pos; } Vec3 scale = this_msg_jobj->scale; // BG position this_msg_jobj->trans.X = this_msg_pos.X; this_msg_jobj->trans.Y = this_msg_pos.Y; // text position this_msg_text->trans.X = this_msg_pos.X + (MSGTEXT_BASEX * (scale.X / 4.0)); this_msg_text->trans.Y = (this_msg_pos.Y * -1) + (MSGTEXT_BASEY * (scale.Y / 4.0)); // adjust bar JOBJ *bar; JOBJ_GetChild(this_msg_jobj, &bar, 4, -1); bar->trans.X = (float)(this_msg_data->lifetime - this_msg_data->alive_timer) / (float)this_msg_data->lifetime; break; } case (MSGSTATE_DELETE): { // get time float t = ((this_msg_data->anim_timer) / (float)MSGTIMER_DELETE); Vec3 *scale = &this_msg_jobj->scale; Vec3 *pos = &this_msg_jobj->trans; // BG scale scale->Y = BezierBlend(t); // text scale this_msg_text->scale.Y = (scale->Y * 0.01) * MSGTEXT_BASESCALE; // text position this_msg_text->trans.Y = (pos->Y * -1) + (MSGTEXT_BASEY * (scale->Y / 4.0)); break; } } JOBJ_SetMtxDirtySub(this_msg_jobj); } } } } void Message_Destroy(GOBJ **msg_queue, int msg_num) { GOBJ *msg_gobj = msg_queue[msg_num]; MsgData *msg_data = msg_gobj->userdata; // Destroy text Text *text = msg_data->text; if (text != 0) Text_Destroy(text); // Destroy GOBJ GObj_Destroy(msg_gobj); // null pointer msg_queue[msg_num] = 0; // shift others for (int i = (msg_num); i < (MSGQUEUE_SIZE - 1); i++) { msg_queue[i] = msg_queue[i + 1]; // update its prev pos GOBJ *this_msg_gobj = msg_queue[i]; if (this_msg_gobj != 0) { MsgData *this_msg_data = this_msg_gobj->userdata; this_msg_data->prev_index = i + 1; // prev position } } return; } void Message_Add(GOBJ *msg_gobj, int queue_num) { MsgData *msg_data = msg_gobj->userdata; MsgMngrData *mgr_data = stc_msgmgr->userdata; GOBJ **msg_queue = &mgr_data->msg_queue[queue_num]; // ensure this queue exists if (queue_num >= MSGQUEUE_NUM) assert("queue_num over!"); // remove any existing messages of this kind for (int i = 0; i < MSGQUEUE_SIZE; i++) { GOBJ *this_msg_gobj = msg_queue[i]; // if it exists if (this_msg_gobj != 0) { MsgData *this_msg_data = this_msg_gobj->userdata; // Remove this message if its of the same kind if ((this_msg_data->kind == msg_data->kind)) { Message_Destroy(msg_queue, i); // remove the message and shift others // if the message we're replacing is the most recent message, instantly // remove the old one and do not animate the new one if (i == 0) { msg_data->state = MSGSTATE_WAIT; msg_data->anim_timer = 0; } } } } // first remove last message in the queue if (msg_queue[MSGQUEUE_SIZE - 1] != 0) { Message_Destroy(msg_queue, MSGQUEUE_SIZE - 1); } // shift other messages for (int i = (MSGQUEUE_SIZE - 2); i >= 0; i--) { // shift message msg_queue[i + 1] = msg_queue[i]; // update its prev pos GOBJ *this_msg_gobj = msg_queue[i + 1]; if (this_msg_gobj != 0) { MsgData *this_msg_data = this_msg_gobj->userdata; this_msg_data->prev_index = i; // prev position } } // add this new message msg_queue[0] = msg_gobj; // set prev pos to -1 (slides in) msg_data->prev_index = -1; msg_data->orig_index = 0; return; } void Message_CObjThink(GOBJ *gobj) { if (Pause_CheckStatus(1) != 2) CObjThink_Common(gobj); return; } float BezierBlend(float t) { return t * t * (3.0f - 2.0f * t); } // Tips Functions void Tip_Init() { // init static struct memset(&stc_tipmgr, 0, sizeof(TipMgr)); // create tipmgr gobj GOBJ *tipmgr_gobj = GObj_Create(0, 7, 0); GObj_AddProc(tipmgr_gobj, Tip_Think, 18); return; } void Tip_Think(GOBJ *gobj) { GOBJ *tip_gobj = stc_tipmgr.gobj; stc_event_vars.menu_assets->tip_jobj; // update tip if (tip_gobj != 0) { // update anim JOBJ_AnimAll(tip_gobj->hsd_object); // update text position JOBJ *tip_jobj; Vec3 tip_pos; JOBJ_GetChild(tip_gobj->hsd_object, &tip_jobj, TIP_TXTJOINT, -1); JOBJ_GetWorldPosition(tip_jobj, 0, &tip_pos); Text *tip_text = stc_tipmgr.text; tip_text->trans.X = tip_pos.X + (0 * (tip_jobj->scale.X / 4.0)); tip_text->trans.Y = (tip_pos.Y * -1) + (0 * (tip_jobj->scale.Y / 4.0)); // state logic switch (stc_tipmgr.state) { case (0): // in { // if anim is done, enter wait if (JOBJ_CheckAObjEnd(tip_gobj->hsd_object) == 0) stc_tipmgr.state = 1; // enter wait break; } case (1): // wait { // sub timer stc_tipmgr.lifetime--; if (stc_tipmgr.lifetime <= 0) { // apply exit anim JOBJ *tip_root = tip_gobj->hsd_object; JOBJ_RemoveAnimAll(tip_root); JOBJ_AddAnimAll(tip_root, stc_event_vars.menu_assets->tip_jointanim[1], 0, 0); JOBJ_ReqAnimAll(tip_root, 0); stc_tipmgr.state = 2; // enter wait } break; } case (2): // out { // if anim is done, destroy if (JOBJ_CheckAObjEnd(tip_gobj->hsd_object) == 0) { // remove text Text_Destroy(stc_tipmgr.text); GObj_Destroy(stc_tipmgr.gobj); stc_tipmgr.gobj = 0; } break; } } } return; } int Tip_Display(int lifetime, char *fmt, ...) { #define TIP_TXTSIZE 4.7 #define TIP_TXTSIZEX TIP_TXTSIZE * 0.85 #define TIP_TXTSIZEY TIP_TXTSIZE #define TIP_TXTASPECT 2430 #define TIP_LINEMAX 5 #define TIP_CHARMAX 48 va_list args; // if tip exists if (stc_tipmgr.gobj != 0) { // if tip is in the process of exiting if (stc_tipmgr.state == 2) { // remove text Text_Destroy(stc_tipmgr.text); GObj_Destroy(stc_tipmgr.gobj); stc_tipmgr.gobj = 0; } // if is active onscreen do nothing else return 0; } MsgMngrData *msgmngr_data = stc_msgmgr->userdata; // using message canvas cause there are so many god damn text canvases // Create bg GOBJ *tip_gobj = GObj_Create(0, 0, 0); stc_tipmgr.gobj = tip_gobj; GObj_AddGXLink(tip_gobj, GXLink_Common, MSG_GXLINK, 80); JOBJ *tip_jobj = JOBJ_LoadJoint(stc_event_vars.menu_assets->tip_jobj); GObj_AddObject(tip_gobj, R13_U8(-0x3E55), tip_jobj); // account for widescreen /* float aspect = (msgmngr_data->cobj->projection_param.perspective.aspect / 1.216667) - 1; tip_jobj->trans.X += (tip_jobj->trans.X * aspect); JOBJ_SetMtxDirtySub(tip_jobj); */ // Create text object Text *tip_text = Text_CreateText(2, msgmngr_data->canvas); stc_tipmgr.text = tip_text; stc_tipmgr.lifetime = lifetime; stc_tipmgr.state = 0; tip_text->kerning = 1; tip_text->align = 0; tip_text->use_aspect = 1; // adjust text scale Vec3 scale = tip_jobj->scale; // background scale tip_jobj->scale = scale; // text scale tip_text->scale.X = (scale.X * 0.01) * TIP_TXTSIZEX; tip_text->scale.Y = (scale.Y * 0.01) * TIP_TXTSIZEY; tip_text->aspect.X = (TIP_TXTASPECT / TIP_TXTSIZEX); // apply enter anim JOBJ_RemoveAnimAll(tip_jobj); JOBJ_AddAnimAll(tip_jobj, stc_event_vars.menu_assets->tip_jointanim[0], 0, 0); JOBJ_ReqAnimAll(tip_jobj, 0); // build string char buffer[(TIP_LINEMAX * TIP_CHARMAX) + 1]; va_start(args, fmt); vsprintf(buffer, fmt, args); va_end(args); char *msg = &buffer; // count newlines int line_num = 1; int line_length_arr[TIP_LINEMAX]; char *msg_cursor_prev, *msg_cursor_curr; // declare char pointers msg_cursor_prev = msg; msg_cursor_curr = strchr(msg_cursor_prev, '\n'); // check for occurrence while (msg_cursor_curr != 0) // if occurrence found, increment values { // check if exceeds max lines if (line_num >= TIP_LINEMAX) assert("TIP_LINEMAX exceeded!"); // Save information about this line line_length_arr[line_num - 1] = msg_cursor_curr - msg_cursor_prev; // determine length of the line line_num++; // increment number of newlines found msg_cursor_prev = msg_cursor_curr + 1; // update prev cursor msg_cursor_curr = strchr(msg_cursor_prev, '\n'); // check for another occurrence } // get last lines length msg_cursor_curr = strchr(msg_cursor_prev, 0); line_length_arr[line_num - 1] = msg_cursor_curr - msg_cursor_prev; // copy each line to an individual char array char *msg_cursor = &msg; for (int i = 0; i < line_num; i++) { // check if over char max u8 line_length = line_length_arr[i]; if (line_length > TIP_CHARMAX) assert("TIP_CHARMAX exceeded!"); // copy char array char msg_line[TIP_CHARMAX + 1]; memcpy(msg_line, msg, line_length); // add null terminator msg_line[line_length] = '\0'; // increment msg msg += (line_length + 1); // +1 to skip past newline // print line int y_delta = (i * MSGTEXT_YOFFSET); Text_AddSubtext(tip_text, 0, y_delta, msg_line); } return 1; // tip created } void Tip_Destroy() { // check if tip exists and isnt in exit state, enter exit if ((stc_tipmgr.gobj != 0) && (stc_tipmgr.state != 2)) { // apply exit anim JOBJ *tip_root = stc_tipmgr.gobj->hsd_object; JOBJ_RemoveAnimAll(tip_root); JOBJ_AddAnimAll(tip_root, stc_event_vars.menu_assets->tip_jointanim[1], 0, 0); JOBJ_ReqAnimAll(tip_root, 0); JOBJ_RunAOBJCallback(tip_root, 6, 0xfb7f, AOBJ_SetRate, 1, (float)2); stc_tipmgr.state = 2; // enter wait } return; } //////////////////////////// /// Event Menu Functions /// //////////////////////////// GOBJ *EventMenu_Init(EventDesc *event_desc, EventMenu *start_menu) { // Ensure this event has a menu if (start_menu == 0) return 0; // Create a cobj for the event menu COBJDesc ***dmgScnMdls = File_GetSymbol(ACCESS_PTR(0x804d6d5c), 0x803f94d0); COBJDesc *cam_desc = dmgScnMdls[1][0]; COBJ *cam_cobj = COBJ_LoadDesc(cam_desc); GOBJ *cam_gobj = GObj_Create(19, 20, 0); GObj_AddObject(cam_gobj, R13_U8(-0x3E55), cam_cobj); GOBJ_InitCamera(cam_gobj, CObjThink_Common, MENUCAM_GXPRI); cam_gobj->cobj_links = MENUCAM_COBJGXLINK; // Create menu gobj GOBJ *gobj = GObj_Create(0, 0, 0); MenuData *menuData = calloc(sizeof(MenuData)); GObj_AddUserData(gobj, 4, HSD_Free, menuData); // store pointer to the gobj's data menuData->event_desc = event_desc; // Add gx_link GObj_AddGXLink(gobj, GXLink_Common, GXLINK_MENUMODEL, GXPRI_MENUMODEL); // Create 2 text canvases (menu and popup) menuData->canvas_menu = Text_CreateCanvas(2, cam_gobj, 9, 13, 0, GXLINK_MENUTEXT, GXPRI_MENUTEXT, MENUCAM_GXPRI); menuData->canvas_popup = Text_CreateCanvas(2, cam_gobj, 9, 13, 0, GXLINK_MENUTEXT, GXPRI_POPUPTEXT, MENUCAM_GXPRI); // Init currMenu menuData->currMenu = start_menu; // set menu as not hidden stc_event_vars.hide_menu = 0; return gobj; }; void EventMenu_Update(GOBJ *gobj) { //MenuCamData *camData = gobj->userdata; MenuData *menuData = gobj->userdata; EventDesc *event_desc = menuData->event_desc; EventMenu *currMenu = menuData->currMenu; int update_menu = 1; // if a custom menu is in use, run its function if (menuData->custom_gobj_think != 0) { update_menu = menuData->custom_gobj_think(menuData->custom_gobj); } // if this menu has an upate function, run its function else if ((menuData->isPaused == 1) && (currMenu->menu_think != 0)) { update_menu = currMenu->menu_think(gobj); } if (update_menu == 1) { // Check if being pressed int isPress = 0; for (int i = 0; i < 6; i++) { // humans only if (Fighter_GetSlotType(i) == 0) { GOBJ *fighter = Fighter_GetGObj(i); FighterData *fighter_data = fighter->userdata; int controller_index = Fighter_GetControllerPort(i); HSD_Pad *pad = PadGet(controller_index, PADGET_MASTER); // in develop mode, use X+DPad up if (*stc_dblevel >= 3) { if ((pad->held & HSD_BUTTON_X) && (pad->down & HSD_BUTTON_DPAD_UP)) { isPress = 1; menuData->controller_index = controller_index; break; } } else { if ((pad->down & HSD_BUTTON_START) != 0) { isPress = 1; menuData->controller_index = controller_index; break; } } } } // change pause state if (isPress != 0) { // pause game if (menuData->isPaused == 0) { // set state menuData->isPaused = 1; // Create menu EventMenu_CreateModel(gobj, currMenu); EventMenu_CreateText(gobj, currMenu); EventMenu_UpdateText(gobj, currMenu); if (currMenu->state == EMSTATE_OPENPOP) { EventOption *currOption = &currMenu->options[currMenu->cursor]; EventMenu_CreatePopupModel(gobj, currMenu); EventMenu_CreatePopupText(gobj, currMenu); EventMenu_UpdatePopupText(gobj, currOption); } // Freeze the game Match_FreezeGame(1); SFX_PlayCommon(5); Match_HideHUD(); Match_AdjustSoundOnPause(1); } // unpause game else { menuData->isPaused = 0; // destroy menu EventMenu_DestroyMenu(gobj); // Unfreeze the game Match_UnfreezeGame(1); Match_ShowHUD(); Match_AdjustSoundOnPause(0); } } // run menu logic if the menu is shown else if ((menuData->isPaused == 1) && (stc_event_vars.hide_menu == 0)) { // Get the current menu EventMenu *currMenu = menuData->currMenu; // menu think if (currMenu->state == EMSTATE_FOCUS) { // check to run custom menu think function EventMenu_MenuThink(gobj, currMenu); } // popup think else if (currMenu->state == EMSTATE_OPENPOP) EventMenu_PopupThink(gobj, currMenu); } } return; } void EventMenu_MenuGX(GOBJ *gobj, int pass) { if (stc_event_vars.hide_menu == 0) GXLink_Common(gobj, pass); return; } void EventMenu_TextGX(GOBJ *gobj, int pass) { if (stc_event_vars.hide_menu == 0) Text_GX(gobj, pass); return; } void EventMenu_MenuThink(GOBJ *gobj, EventMenu *currMenu) { MenuData *menuData = gobj->userdata; EventDesc *event_desc = menuData->event_desc; // get player who paused u8 pauser = menuData->controller_index; // get their inputs HSD_Pad *pad = PadGet(pauser, PADGET_MASTER); int inputs_rapid = Pad_GetRapidHeld(pauser); //pad->rapidFire; int inputs_held = pad->held; int inputs = inputs_rapid; if ((inputs_held & HSD_TRIGGER_R) != 0) inputs = inputs_held; // get menu variables int isChanged = 0; s32 cursor = currMenu->cursor; s32 scroll = currMenu->scroll; EventOption *currOption = &currMenu->options[cursor + scroll]; s32 cursor_min = 0; s32 option_num = currMenu->option_num; s32 cursor_max = option_num; if (cursor_max > MENU_MAXOPTION) cursor_max = MENU_MAXOPTION; // get option variables s16 option_val = currOption->option_val; s16 value_min = 0; s16 value_max = currOption->value_num; // check for dpad down if (((inputs & HSD_BUTTON_DOWN) != 0) || ((inputs & HSD_BUTTON_DPAD_DOWN) != 0)) { // loop to find next option int count = 1; // int cursor_next = 0; // how much to move the cursor by while (((cursor + count + scroll) < option_num)) { // option exists, check if its enabled if (currMenu->options[cursor + count + scroll].disable == 0) { cursor_next = count; break; } // option is disabled, loop count++; } // if another option exists, move down if (cursor_next > 0) { cursor += cursor_next; // cursor is in bounds, move down if (cursor < cursor_max) { isChanged = 1; // update cursor currMenu->cursor = cursor; // also play sfx SFX_PlayCommon(2); } // cursor overflowed, correct it else { // adjust scroll -= (cursor_max - (cursor + 1)); cursor = (cursor_max - 1); // update cursor currMenu->cursor = cursor; currMenu->scroll = scroll; isChanged = 1; // also play sfx SFX_PlayCommon(2); } } } // check for dpad up else if (((inputs & HSD_BUTTON_UP) != 0) || ((inputs & HSD_BUTTON_DPAD_UP) != 0)) { // loop to find next option int count = 1; // int cursor_next = 0; // how much to move the cursor by while (((cursor + scroll - count) >= 0)) { // option exists, check if its enabled if (currMenu->options[cursor + scroll - count].disable == 0) { cursor_next = count; break; } // option is disabled, loop count++; } // if another option exists, move up if (cursor_next > 0) { cursor -= cursor_next; // cursor is in bounds, move up if (cursor >= 0) { isChanged = 1; // update cursor currMenu->cursor = cursor; // also play sfx SFX_PlayCommon(2); } // cursor overflowed, correct it else { // adjust scroll += cursor; // effectively scroll up by adding a negative number cursor = 0; // cursor is positioned at 0 // update cursor currMenu->cursor = cursor; currMenu->scroll = scroll; isChanged = 1; // also play sfx SFX_PlayCommon(2); } } } // check for left else if (((inputs & HSD_BUTTON_LEFT) != 0) || ((inputs & HSD_BUTTON_DPAD_LEFT) != 0)) { if ((currOption->option_kind == OPTKIND_STRING) || (currOption->option_kind == OPTKIND_INT) || (currOption->option_kind == OPTKIND_FLOAT)) { option_val -= 1; if (option_val >= value_min) { isChanged = 1; // also play sfx SFX_PlayCommon(2); // update val currOption->option_val = option_val; // run on change function if it exists if (currOption->onOptionChange != 0) currOption->onOptionChange(gobj, currOption->option_val); } } } // check for right else if (((inputs & HSD_BUTTON_RIGHT) != 0) || ((inputs & HSD_BUTTON_DPAD_RIGHT) != 0)) { // check for valid option kind if ((currOption->option_kind == OPTKIND_STRING) || (currOption->option_kind == OPTKIND_INT) || (currOption->option_kind == OPTKIND_FLOAT)) { option_val += 1; if (option_val < value_max) { isChanged = 1; // also play sfx SFX_PlayCommon(2); // update val currOption->option_val = option_val; // run on change function if it exists if (currOption->onOptionChange != 0) currOption->onOptionChange(gobj, currOption->option_val); } } } // check for A else if (inputs_rapid & HSD_BUTTON_A) { // check to advance a menu if ((currOption->option_kind == OPTKIND_MENU)) { // access this menu currMenu->state = EMSTATE_OPENSUB; // update currMenu EventMenu *nextMenu = currMenu->options[cursor + scroll].menu; nextMenu->prev = currMenu; nextMenu->state = EMSTATE_FOCUS; currMenu = nextMenu; menuData->currMenu = currMenu; // recreate everything EventMenu_DestroyMenu(gobj); EventMenu_CreateModel(gobj, currMenu); EventMenu_CreateText(gobj, currMenu); EventMenu_UpdateText(gobj, currMenu); // also play sfx SFX_PlayCommon(1); } /* // check to create a popup if ((currOption->option_kind == OPTKIND_STRING) || (currOption->option_kind == OPTKIND_INT)) { // access this menu currMenu->state = EMSTATE_OPENPOP; // init cursor and scroll value s32 cursor = 0; s32 scroll = currOption->option_val; // correct scroll s32 max_scroll; if (currOption->value_num <= MENU_POPMAXOPTION) max_scroll = 0; else max_scroll = currOption->value_num - MENU_POPMAXOPTION; // check if scrolled too far if (scroll > max_scroll) { cursor = scroll - max_scroll; scroll = max_scroll; } // update cursor and scroll menuData->popup_cursor = cursor; menuData->popup_scroll = scroll; // create popup menu and update EventMenu_CreatePopupModel(gobj, currMenu); EventMenu_CreatePopupText(gobj, currMenu); EventMenu_UpdatePopupText(gobj, currOption); // also play sfx SFX_PlayCommon(1); } */ // check to run a function if ((currOption->option_kind == OPTKIND_FUNC) && (currOption->onOptionSelect != 0)) { // execute function currOption->onOptionSelect(gobj); // update text EventMenu_UpdateText(gobj, currMenu); // also play sfx SFX_PlayCommon(1); } } // check to go back a menu else if (inputs_rapid & HSD_BUTTON_B) { // check if a prev menu exists EventMenu *prevMenu = currMenu->prev; if (prevMenu != 0) { // clear previous menu EventMenu *prevMenu = currMenu->prev; currMenu->prev = 0; // reset this menu's cursor currMenu->scroll = 0; currMenu->cursor = 0; // update currMenu currMenu = prevMenu; menuData->currMenu = currMenu; // close this menu currMenu->state = EMSTATE_FOCUS; // recreate everything EventMenu_DestroyMenu(gobj); EventMenu_CreateModel(gobj, currMenu); EventMenu_CreateText(gobj, currMenu); EventMenu_UpdateText(gobj, currMenu); // also play sfx SFX_PlayCommon(0); } /* // no previous menu, unpause else { SFX_PlayCommon(0); menuData->isPaused = 0; // destroy menu EventMenu_DestroyMenu(gobj); // Unfreeze the game Match_UnfreezeGame(1); Match_ShowHUD(); Match_AdjustSoundOnPause(0); } */ } // if anything changed, update text if (isChanged != 0) { // update menu EventMenu_UpdateText(gobj, currMenu); } return; } void EventMenu_PopupThink(GOBJ *gobj, EventMenu *currMenu) { MenuData *menuData = gobj->userdata; EventDesc *event_desc = menuData->event_desc; // get player who paused u8 pauser = menuData->controller_index; // get their inputs HSD_Pad *pad = PadGet(pauser, PADGET_MASTER); int inputs_rapid = pad->rapidFire; int inputs_held = pad->held; int inputs = inputs_rapid; if ((inputs_held & HSD_TRIGGER_R) != 0) inputs = inputs_held; // get option variables int isChanged = 0; s32 cursor = menuData->popup_cursor; s32 scroll = menuData->popup_scroll; EventOption *currOption = &currMenu->options[currMenu->cursor + currMenu->scroll]; s32 value_num = currOption->value_num; s32 cursor_min = 0; s32 cursor_max = value_num; if (cursor_max > MENU_POPMAXOPTION) { cursor_max = MENU_POPMAXOPTION; } // check for dpad down if (((inputs & HSD_BUTTON_DOWN) != 0) || ((inputs & HSD_BUTTON_DPAD_DOWN) != 0)) { cursor += 1; // cursor is in bounds, move down if (cursor < cursor_max) { isChanged = 1; // update cursor menuData->popup_cursor = cursor; // also play sfx SFX_PlayCommon(2); } // cursor overflowed, check to scroll else { // cursor+scroll is in bounds, increment scroll if ((cursor + scroll) < value_num) { // adjust scroll++; cursor--; // update cursor menuData->popup_cursor = cursor; menuData->popup_scroll = scroll; isChanged = 1; // also play sfx SFX_PlayCommon(2); } } } // check for dpad up else if (((inputs & HSD_BUTTON_UP) != 0) || ((inputs & HSD_BUTTON_DPAD_UP) != 0)) { cursor -= 1; // cursor is in bounds, move up if (cursor >= 0) { isChanged = 1; // update cursor menuData->popup_cursor = cursor; // also play sfx SFX_PlayCommon(2); } // cursor overflowed, check to scroll else { // scroll is in bounds, decrement scroll if (scroll > 0) { // adjust scroll--; cursor++; // update cursor menuData->popup_cursor = cursor; menuData->popup_scroll = scroll; isChanged = 1; // also play sfx SFX_PlayCommon(2); } } } // check for A else if ((inputs_rapid & HSD_BUTTON_A) != 0) { // update option_val currOption->option_val = cursor + scroll; // run on change function if it exists if (currOption->onOptionChange != 0) currOption->onOptionChange(gobj, currOption->option_val); EventMenu_DestroyPopup(gobj); // update menu EventMenu_UpdateText(gobj, currMenu); // play sfx SFX_PlayCommon(1); } // check to go back a menu else if ((inputs_rapid & HSD_BUTTON_B) != 0) { EventMenu_DestroyPopup(gobj); // update menu EventMenu_UpdateText(gobj, currMenu); // play sfx SFX_PlayCommon(0); } // if anything changed, update text if (isChanged != 0) { // update menu EventMenu_UpdatePopupText(gobj, currOption); } return; } void EventMenu_CreateModel(GOBJ *gobj, EventMenu *menu) { MenuData *menuData = gobj->userdata; // create options background evMenu *menuAssets = stc_event_vars.menu_assets; JOBJ *jobj_options = JOBJ_LoadJoint(menuAssets->menu); // Add to gobj GObj_AddObject(gobj, 3, jobj_options); GObj_DestroyGXLink(gobj); GObj_AddGXLink(gobj, EventMenu_MenuGX, GXLINK_MENUMODEL, GXPRI_MENUMODEL); // JOBJ array for getting the corner joints JOBJ *corners[4]; // create a border and arrow for every row s32 option_num = menu->option_num; if (option_num > MENU_MAXOPTION) option_num = MENU_MAXOPTION; for (int i = 0; i < option_num; i++) { // create a border jobj JOBJ *jobj_border = JOBJ_LoadJoint(menuAssets->popup); // attach to root jobj JOBJ_AddChild(gobj->hsd_object, jobj_border); // move it into position JOBJ_GetChild(jobj_border, &corners, 2, 3, 4, 5, -1); // Modify scale and position jobj_border->trans.Z = ROWBOX_Z; jobj_border->scale.X = 1; jobj_border->scale.Y = 1; jobj_border->scale.Z = 1; corners[0]->trans.X = -(ROWBOX_WIDTH / 2) + ROWBOX_X; corners[0]->trans.Y = (ROWBOX_HEIGHT / 2) + ROWBOX_Y + (i * ROWBOX_YOFFSET); corners[1]->trans.X = (ROWBOX_WIDTH / 2) + ROWBOX_X; corners[1]->trans.Y = (ROWBOX_HEIGHT / 2) + ROWBOX_Y + (i * ROWBOX_YOFFSET); corners[2]->trans.X = -(ROWBOX_WIDTH / 2) + ROWBOX_X; corners[2]->trans.Y = -(ROWBOX_HEIGHT / 2) + ROWBOX_Y + (i * ROWBOX_YOFFSET); corners[3]->trans.X = (ROWBOX_WIDTH / 2) + ROWBOX_X; corners[3]->trans.Y = -(ROWBOX_HEIGHT / 2) + ROWBOX_Y + (i * ROWBOX_YOFFSET); JOBJ_SetFlags(jobj_border, JOBJ_HIDDEN); DOBJ_SetFlags(jobj_border->dobj, DOBJ_HIDDEN); jobj_border->dobj->next->mobj->mat->alpha = 0.6; //GXColor border_color = ROWBOX_COLOR; //jobj_border->dobj->next->mobj->mat->diffuse = border_color; // store pointer menuData->row_joints[i][0] = jobj_border; // create an arrow jobj JOBJ *jobj_arrow = JOBJ_LoadJoint(menuAssets->arrow); // attach to root jobj JOBJ_AddChild(gobj->hsd_object, jobj_arrow); // move it into position jobj_arrow->trans.X = TICKBOX_X; jobj_arrow->trans.Y = TICKBOX_Y + (i * ROWBOX_YOFFSET); jobj_arrow->trans.Z = ROWBOX_Z; jobj_arrow->scale.X = TICKBOX_SCALE; jobj_arrow->scale.Y = TICKBOX_SCALE; jobj_arrow->scale.Z = TICKBOX_SCALE; // change color //GXColor gx_color = {30, 40, 50, 255}; //jobj_arrow->dobj->next->mobj->mat->diffuse = gx_color; JOBJ_SetFlags(jobj_arrow, JOBJ_HIDDEN); // store pointer menuData->row_joints[i][1] = jobj_arrow; } // create a highlight jobj JOBJ *jobj_highlight = JOBJ_LoadJoint(menuAssets->popup); // remove outline DOBJ_SetFlags(jobj_highlight->dobj, DOBJ_HIDDEN); // attach to root jobj JOBJ_AddChild(gobj->hsd_object, jobj_highlight); // move it into position JOBJ_GetChild(jobj_highlight, &corners, 2, 3, 4, 5, -1); // Modify scale and position jobj_highlight->trans.Z = MENUHIGHLIGHT_Z; jobj_highlight->scale.X = MENUHIGHLIGHT_SCALE; jobj_highlight->scale.Y = MENUHIGHLIGHT_SCALE; jobj_highlight->scale.Z = MENUHIGHLIGHT_SCALE; corners[0]->trans.X = -(MENUHIGHLIGHT_WIDTH / 2) + MENUHIGHLIGHT_X; corners[0]->trans.Y = (MENUHIGHLIGHT_HEIGHT / 2) + MENUHIGHLIGHT_Y; corners[1]->trans.X = (MENUHIGHLIGHT_WIDTH / 2) + MENUHIGHLIGHT_X; corners[1]->trans.Y = (MENUHIGHLIGHT_HEIGHT / 2) + MENUHIGHLIGHT_Y; corners[2]->trans.X = -(MENUHIGHLIGHT_WIDTH / 2) + MENUHIGHLIGHT_X; corners[2]->trans.Y = -(MENUHIGHLIGHT_HEIGHT / 2) + MENUHIGHLIGHT_Y; corners[3]->trans.X = (MENUHIGHLIGHT_WIDTH / 2) + MENUHIGHLIGHT_X; corners[3]->trans.Y = -(MENUHIGHLIGHT_HEIGHT / 2) + MENUHIGHLIGHT_Y; GXColor highlight = MENUHIGHLIGHT_COLOR; jobj_highlight->dobj->next->mobj->mat->alpha = 0.6; jobj_highlight->dobj->next->mobj->mat->diffuse = highlight; menuData->highlight_menu = jobj_highlight; // check to create scroll bar if (menuData->currMenu->option_num > MENU_MAXOPTION) { // create scroll bar JOBJ *scroll_jobj = JOBJ_LoadJoint(menuAssets->scroll); // attach to root jobj JOBJ_AddChild(gobj->hsd_object, scroll_jobj); // move it into position JOBJ_GetChild(scroll_jobj, &corners, 2, 3, -1); // scale scrollbar accordingly scroll_jobj->scale.X = MENUSCROLL_SCALE; scroll_jobj->scale.Y = MENUSCROLL_SCALEY; scroll_jobj->scale.Z = MENUSCROLL_SCALE; scroll_jobj->trans.X = MENUSCROLL_X; scroll_jobj->trans.Y = MENUSCROLL_Y; scroll_jobj->trans.Z = MENUSCROLL_Z; menuData->scroll_top = corners[0]; menuData->scroll_bot = corners[1]; GXColor highlight = MENUSCROLL_COLOR; scroll_jobj->dobj->next->mobj->mat->alpha = 0.6; scroll_jobj->dobj->next->mobj->mat->diffuse = highlight; // calculate scrollbar size int max_steps = menuData->currMenu->option_num - MENU_MAXOPTION; float botPos = MENUSCROLL_MAXLENGTH + (max_steps * MENUSCROLL_PEROPTION); if (botPos > MENUSCROLL_MINLENGTH) botPos = MENUSCROLL_MINLENGTH; // set size corners[1]->trans.Y = botPos; } else { menuData->scroll_bot = 0; menuData->scroll_top = 0; } return; } void EventMenu_CreateText(GOBJ *gobj, EventMenu *menu) { // Get event info MenuData *menuData = gobj->userdata; EventDesc *event_desc = menuData->event_desc; Text *text; int subtext; int canvasIndex = menuData->canvas_menu; s32 cursor = menu->cursor; // free text if it exists if (menuData->text_name != 0) { // free text Text_Destroy(menuData->text_name); menuData->text_name = 0; Text_Destroy(menuData->text_value); menuData->text_value = 0; Text_Destroy(menuData->text_title); menuData->text_title = 0; Text_Destroy(menuData->text_desc); menuData->text_desc = 0; } if (menuData->text_popup != 0) { Text_Destroy(menuData->text_popup); menuData->text_popup = 0; } /******************* *** Create Title *** *******************/ text = Text_CreateText(2, canvasIndex); text->gobj->gx_cb = EventMenu_TextGX; menuData->text_title = text; // enable align and kerning text->align = 0; text->kerning = 1; text->use_aspect = 1; // scale canvas text->scale.X = MENU_CANVASSCALE; text->scale.Y = MENU_CANVASSCALE; text->trans.Z = MENU_TEXTZ; text->aspect.X = MENU_TITLEASPECT; // output menu title float optionX = MENU_TITLEXPOS; float optionY = MENU_TITLEYPOS; subtext = Text_AddSubtext(text, optionX, optionY, &nullString); Text_SetScale(text, subtext, MENU_TITLESCALE, MENU_TITLESCALE); /************************** *** Create Description *** *************************/ text = Text_CreateText(2, canvasIndex); text->gobj->gx_cb = EventMenu_TextGX; menuData->text_desc = text; /******************* *** Create Names *** *******************/ text = Text_CreateText(2, canvasIndex); text->gobj->gx_cb = EventMenu_TextGX; menuData->text_name = text; // enable align and kerning text->align = 0; text->kerning = 1; text->use_aspect = 1; // scale canvas text->scale.X = MENU_CANVASSCALE; text->scale.Y = MENU_CANVASSCALE; text->trans.Z = MENU_TEXTZ; text->aspect.X = MENU_NAMEASPECT; // Output all options s32 option_num = menu->option_num; if (option_num > MENU_MAXOPTION) option_num = MENU_MAXOPTION; for (int i = 0; i < option_num; i++) { // output option name float optionX = MENU_OPTIONNAMEXPOS; float optionY = MENU_OPTIONNAMEYPOS + (i * MENU_TEXTYOFFSET); subtext = Text_AddSubtext(text, optionX, optionY, &nullString); } /******************** *** Create Values *** ********************/ text = Text_CreateText(2, canvasIndex); text->gobj->gx_cb = EventMenu_TextGX; menuData->text_value = text; // enable align and kerning text->align = 1; text->kerning = 1; text->use_aspect = 1; // scale canvas text->scale.X = MENU_CANVASSCALE; text->scale.Y = MENU_CANVASSCALE; text->trans.Z = MENU_TEXTZ; text->aspect.X = MENU_VALASPECT; // Output all values for (int i = 0; i < option_num; i++) { // output option value float optionX = MENU_OPTIONVALXPOS; float optionY = MENU_OPTIONVALYPOS + (i * MENU_TEXTYOFFSET); subtext = Text_AddSubtext(text, optionX, optionY, &nullString); } return; } void EventMenu_UpdateText(GOBJ *gobj, EventMenu *menu) { // Get event info MenuData *menuData = gobj->userdata; EventDesc *event_desc = menuData->event_desc; s32 cursor = menu->cursor; s32 scroll = menu->scroll; s32 option_num = menu->option_num; if (option_num > MENU_MAXOPTION) option_num = MENU_MAXOPTION; Text *text; // Update Title text = menuData->text_title; Text_SetText(text, 0, menu->name); // Update Description Text_Destroy(menuData->text_desc); // i think its best to recreate it... text = Text_CreateText(2, menuData->canvas_menu); text->gobj->gx_cb = EventMenu_TextGX; menuData->text_desc = text; EventOption *currOption = &menu->options[menu->cursor + menu->scroll]; #define DESC_TXTSIZEX 5 #define DESC_TXTSIZEY 5 #define DESC_TXTASPECT 885 #define DESC_LINEMAX 4 #define DESC_CHARMAX 100 #define DESC_YOFFSET 30 text->kerning = 1; text->align = 0; text->use_aspect = 1; // scale canvas text->scale.X = 0.01 * DESC_TXTSIZEX; text->scale.Y = 0.01 * DESC_TXTSIZEY; text->trans.X = MENU_DESCXPOS; text->trans.Y = MENU_DESCYPOS; text->trans.Z = MENU_TEXTZ; text->aspect.X = (DESC_TXTASPECT); char *msg = currOption->desc; // count newlines int line_num = 1; int line_length_arr[DESC_LINEMAX]; char *msg_cursor_prev, *msg_cursor_curr; // declare char pointers msg_cursor_prev = msg; msg_cursor_curr = strchr(msg_cursor_prev, '\n'); // check for occurrence while (msg_cursor_curr != 0) // if occurrence found, increment values { // check if exceeds max lines if (line_num >= DESC_LINEMAX) assert("DESC_LINEMAX exceeded!"); // Save information about this line line_length_arr[line_num - 1] = msg_cursor_curr - msg_cursor_prev; // determine length of the line line_num++; // increment number of newlines found msg_cursor_prev = msg_cursor_curr + 1; // update prev cursor msg_cursor_curr = strchr(msg_cursor_prev, '\n'); // check for another occurrence } // get last lines length msg_cursor_curr = strchr(msg_cursor_prev, 0); line_length_arr[line_num - 1] = msg_cursor_curr - msg_cursor_prev; // copy each line to an individual char array char *msg_cursor = &msg; for (int i = 0; i < line_num; i++) { // check if over char max u8 line_length = line_length_arr[i]; if (line_length > DESC_CHARMAX) assert("DESC_CHARMAX exceeded!"); // copy char array char msg_line[DESC_CHARMAX + 1]; memcpy(msg_line, msg, line_length); // add null terminator msg_line[line_length] = '\0'; // increment msg msg += (line_length + 1); // +1 to skip past newline // print line int y_delta = (i * DESC_YOFFSET); Text_AddSubtext(text, 0, y_delta, msg_line); } /* Update Names */ // Output all options text = menuData->text_name; for (int i = 0; i < option_num; i++) { // get this option EventOption *currOption = &menu->options[scroll + i]; // output option name int optionVal = currOption->option_val; Text_SetText(text, i, currOption->option_name); // output color GXColor color; if (currOption->disable == 0) { color.r = 255; color.b = 255; color.g = 255; color.a = 255; } else { color.r = 128; color.b = 128; color.g = 128; color.a = 0; } Text_SetColor(text, i, &color); } /* Update Values */ // Output all values text = menuData->text_value; for (int i = 0; i < option_num; i++) { // get this option EventOption *currOption = &menu->options[scroll + i]; int optionVal = currOption->option_val; // hide row models JOBJ_SetFlags(menuData->row_joints[i][0], JOBJ_HIDDEN); JOBJ_SetFlags(menuData->row_joints[i][1], JOBJ_HIDDEN); // if this option has string values if (currOption->option_kind == OPTKIND_STRING) { // output option value Text_SetText(text, i, currOption->option_values[optionVal]); // show box JOBJ_ClearFlags(menuData->row_joints[i][0], JOBJ_HIDDEN); } // if this option has int values else if (currOption->option_kind == OPTKIND_INT) { // output option value Text_SetText(text, i, currOption->option_values, optionVal); // show box JOBJ_ClearFlags(menuData->row_joints[i][0], JOBJ_HIDDEN); } // if this option is a menu or function else if ((currOption->option_kind == OPTKIND_MENU) || (currOption->option_kind == OPTKIND_FUNC)) { Text_SetText(text, i, &nullString); // show arrow //JOBJ_ClearFlags(menuData->row_joints[i][1], JOBJ_HIDDEN); } // output color GXColor color; if (currOption->disable == 0) { color.r = 255; color.b = 255; color.g = 255; color.a = 255; } else { color.r = 128; color.b = 128; color.g = 128; color.a = 0; } Text_SetColor(text, i, &color); } // update cursor position JOBJ *highlight_joint = menuData->highlight_menu; highlight_joint->trans.Y = cursor * MENUHIGHLIGHT_YOFFSET; // update scrollbar position if (menuData->scroll_top != 0) { float curr_steps = menuData->currMenu->scroll; float max_steps; if (menuData->currMenu->option_num < MENU_MAXOPTION) max_steps = 0; else max_steps = menuData->currMenu->option_num - MENU_MAXOPTION; // scrollTop = -1 * ((curr_steps/max_steps) * (botY - -10)) menuData->scroll_top->trans.Y = -1 * (curr_steps / max_steps) * (menuData->scroll_bot->trans.Y - MENUSCROLL_MAXLENGTH); } // update jobj JOBJ_SetMtxDirtySub(gobj->hsd_object); return; } void EventMenu_DestroyMenu(GOBJ *gobj) { MenuData *menuData = gobj->userdata; // userdata // remove Text_Destroy(menuData->text_name); menuData->text_name = 0; // remove Text_Destroy(menuData->text_value); menuData->text_value = 0; // remove Text_Destroy(menuData->text_title); menuData->text_title = 0; // remove Text_Destroy(menuData->text_desc); menuData->text_desc = 0; // if popup box exists if (menuData->text_popup != 0) EventMenu_DestroyPopup(gobj); // if custom menu gobj exists if (menuData->custom_gobj != 0) { // run on destroy function if (menuData->custom_gobj_destroy != 0) menuData->custom_gobj_destroy(menuData->custom_gobj); // null pointers menuData->custom_gobj = 0; menuData->custom_gobj_destroy = 0; menuData->custom_gobj_think = 0; } // set menu as visible stc_event_vars.hide_menu = 0; // remove jobj GObj_FreeObject(gobj); //GObj_DestroyGXLink(gobj); return; } void EventMenu_CreatePopupModel(GOBJ *gobj, EventMenu *menu) { // init variables MenuData *menuData = gobj->userdata; // userdata s32 cursor = menu->cursor; EventOption *option = &menu->options[cursor]; // create options background evMenu *menuAssets = stc_event_vars.menu_assets; // create popup gobj GOBJ *popup_gobj = GObj_Create(0, 0, 0); // load popup joint JOBJ *popup_joint = JOBJ_LoadJoint(menuAssets->popup); // Get each corner's joints JOBJ *corners[4]; JOBJ_GetChild(popup_joint, &corners, 2, 3, 4, 5, -1); // Modify scale and position popup_joint->scale.X = POPUP_SCALE; popup_joint->scale.Y = POPUP_SCALE; popup_joint->scale.Z = POPUP_SCALE; popup_joint->trans.Z = POPUP_Z; corners[0]->trans.X = -(POPUP_WIDTH / 2); corners[0]->trans.Y = (POPUP_HEIGHT / 2); corners[1]->trans.X = (POPUP_WIDTH / 2); corners[1]->trans.Y = (POPUP_HEIGHT / 2); corners[2]->trans.X = -(POPUP_WIDTH / 2); corners[2]->trans.Y = -(POPUP_HEIGHT / 2); corners[3]->trans.X = (POPUP_WIDTH / 2); corners[3]->trans.Y = -(POPUP_HEIGHT / 2); /* // Change color GXColor gx_color = TEXT_BGCOLOR; popup_joint->dobj->mobj->mat->diffuse = gx_color; */ // add to gobj GObj_AddObject(popup_gobj, 3, popup_joint); // add gx link GObj_AddGXLink(popup_gobj, EventMenu_MenuGX, GXLINK_POPUPMODEL, GXPRI_POPUPMODEL); // save pointer menuData->popup = popup_gobj; // adjust scrollbar scale // position popup X and Y (based on cursor value) popup_joint->trans.X = POPUP_X; popup_joint->trans.Y = POPUP_Y + (POPUP_YOFFSET * cursor); // create a highlight jobj JOBJ *jobj_highlight = JOBJ_LoadJoint(menuAssets->popup); // attach to root jobj JOBJ_AddChild(popup_gobj->hsd_object, jobj_highlight); // move it into position JOBJ_GetChild(jobj_highlight, &corners, 2, 3, 4, 5, -1); // Modify scale and position jobj_highlight->trans.Z = POPUPHIGHLIGHT_Z; jobj_highlight->scale.X = 1; jobj_highlight->scale.Y = 1; jobj_highlight->scale.Z = 1; corners[0]->trans.X = -(POPUPHIGHLIGHT_WIDTH / 2) + POPUPHIGHLIGHT_X; corners[0]->trans.Y = (POPUPHIGHLIGHT_HEIGHT / 2) + POPUPHIGHLIGHT_Y; corners[1]->trans.X = (POPUPHIGHLIGHT_WIDTH / 2) + POPUPHIGHLIGHT_X; corners[1]->trans.Y = (POPUPHIGHLIGHT_HEIGHT / 2) + POPUPHIGHLIGHT_Y; corners[2]->trans.X = -(POPUPHIGHLIGHT_WIDTH / 2) + POPUPHIGHLIGHT_X; corners[2]->trans.Y = -(POPUPHIGHLIGHT_HEIGHT / 2) + POPUPHIGHLIGHT_Y; corners[3]->trans.X = (POPUPHIGHLIGHT_WIDTH / 2) + POPUPHIGHLIGHT_X; corners[3]->trans.Y = -(POPUPHIGHLIGHT_HEIGHT / 2) + POPUPHIGHLIGHT_Y; GXColor highlight = POPUPHIGHLIGHT_COLOR; jobj_highlight->dobj->next->mobj->mat->alpha = 0.6; jobj_highlight->dobj->next->mobj->mat->diffuse = highlight; menuData->highlight_popup = jobj_highlight; return; } void EventMenu_CreatePopupText(GOBJ *gobj, EventMenu *menu) { // init variables MenuData *menuData = gobj->userdata; s32 cursor = menu->cursor; EventOption *option = &menu->options[cursor]; int subtext; int canvasIndex = menuData->canvas_popup; s32 value_num = option->value_num; if (value_num > MENU_POPMAXOPTION) value_num = MENU_POPMAXOPTION; /////////////////// // Create Values // /////////////////// Text *text = Text_CreateText(2, canvasIndex); text->gobj->gx_cb = EventMenu_TextGX; menuData->text_popup = text; // enable align and kerning text->align = 1; text->kerning = 1; // scale canvas text->scale.X = POPUP_CANVASSCALE; text->scale.Y = POPUP_CANVASSCALE; text->trans.Z = POPUP_TEXTZ; // determine base Y value float baseYPos = POPUP_OPTIONVALYPOS + (cursor * MENU_TEXTYOFFSET); // Output all values for (int i = 0; i < value_num; i++) { // output option value float optionX = POPUP_OPTIONVALXPOS; float optionY = baseYPos + (i * POPUP_TEXTYOFFSET); subtext = Text_AddSubtext(text, optionX, optionY, &nullString); } return; } void EventMenu_UpdatePopupText(GOBJ *gobj, EventOption *option) { // init variables MenuData *menuData = gobj->userdata; // userdata s32 cursor = menuData->popup_cursor; s32 scroll = menuData->popup_scroll; s32 value_num = option->value_num; if (value_num > MENU_POPMAXOPTION) value_num = MENU_POPMAXOPTION; /////////////////// // Update Values // /////////////////// Text *text = menuData->text_popup; // update int list if (option->option_kind == OPTKIND_INT) { // Output all values for (int i = 0; i < value_num; i++) { // output option value Text_SetText(text, i, "%d", scroll + i); } } // update string list else if (option->option_kind == OPTKIND_STRING) { // Output all values for (int i = 0; i < value_num; i++) { // output option value Text_SetText(text, i, option->option_values[scroll + i]); } } // update cursor position JOBJ *highlight_joint = menuData->highlight_popup; highlight_joint->trans.Y = cursor * POPUPHIGHLIGHT_YOFFSET; JOBJ_SetMtxDirtySub(highlight_joint); return; } void EventMenu_DestroyPopup(GOBJ *gobj) { MenuData *menuData = gobj->userdata; // userdata // remove text Text_Destroy(menuData->text_popup); menuData->text_popup = 0; // destory gobj GObj_Destroy(menuData->popup); menuData->popup = 0; // also change the menus state EventMenu *currMenu = menuData->currMenu; currMenu->state = EMSTATE_FOCUS; } /////////////////////////////// /// Member-Access Functions /// /////////////////////////////// EventDesc *GetEventDesc(int page, int event) { EventPage *thisPage = EventPages[page]; EventDesc *thisEvent = thisPage->events[event]; return (thisEvent); } char *GetEventName(int page, int event) { EventDesc *thisEvent = GetEventDesc(page, event); return (thisEvent->eventName); } char *GetEventDescription(int page, int event) { EventDesc *thisEvent = GetEventDesc(page, event); return (thisEvent->eventDescription); } char *GetEventTut(int page, int event) { EventDesc *thisEvent = GetEventDesc(page, event); return (thisEvent->eventTutorial); } char *GetPageName(int page) { EventPage *thisPage = EventPages[page]; return (thisPage->name); } char *GetEventFile(int page, int event) { EventDesc *thisEvent = GetEventDesc(page, event); return (thisEvent->eventFile); } char *GetCSSFile(int page, int event) { EventDesc *thisEvent = GetEventDesc(page, event); return (thisEvent->eventCSSFile); } int GetPageEventNum(int page) { EventPage *thisPage = EventPages[page]; return (thisPage->eventNum); } char *GetTMVersShort() { return (TM_VersShort); } char *GetTMVersLong() { return (TM_VersLong); } char *GetTMCompile() { return (TM_Compile); } int GetPageNum() { int pageNum = (sizeof(EventPages) / 4) - 1; return (pageNum); } u8 GetIsChooseCPU(int page, int event) { EventDesc *thisEvent = GetEventDesc(page, event); return (thisEvent->isChooseCPU); } u8 GetIsSelectStage(int page, int event) { EventDesc *thisEvent = GetEventDesc(page, event); return (thisEvent->isSelectStage); } s8 GetFighter(int page, int event) { EventDesc *thisEvent = GetEventDesc(page, event); return (thisEvent->matchData->playerKind); } s8 GetCPUFighter(int page, int event) { EventDesc *thisEvent = GetEventDesc(page, event); return (thisEvent->matchData->cpuKind); } s16 GetStage(int page, int event) { EventDesc *thisEvent = GetEventDesc(page, event); return (thisEvent->matchData->stage); } ================================================ FILE: patch/tmdata/source/events.h ================================================ #include "../../../MexTK/mex.h" #define TM_VERSSHORT "TM v3.0-a8" #define TM_VERSLONG "Training Mode v3.0 Alpha 8" #define TM_DEBUG 0 // 0 = release (no logging), 1 = OSReport logs, 2 = onscreen logs #define EVENT_DATASIZE 512 #define TM_DATA -(50 * 4) - 4 #define MENU_MAXOPTION 9 #define MENU_POPMAXOPTION 5 #define TMLOG(...) DevelopText_AddString(event_vars->db_console_text, __VA_ARGS__) // disable all logs in release mode #if TM_DEBUG == 0 #define OSReport (void)sizeof #define TMLOG (void)sizeof //#define assert (void)sizeof #endif // use OSReport for all logs #if TM_DEBUG == 1 #define OSReport OSReport #endif // use TMLog for all logs #if TM_DEBUG == 2 #define OSReport TMLOG #endif // Custom File Structs typedef struct evMenu { JOBJDesc *menu; JOBJDesc *popup; JOBJDesc *scroll; JOBJDesc *check; JOBJDesc *arrow; JOBJDesc *playback; JOBJDesc *message; COBJDesc *hud_cobjdesc; JOBJ *tip_jobj; void **tip_jointanim; // pointer to array } evMenu; // Structure Definitions typedef struct EventMenu EventMenu; typedef struct EventMatchData { unsigned int timer : 2; unsigned int matchType : 3; unsigned int isDisableMusic : 1; unsigned int hideGo : 1; unsigned int hideReady : 1; unsigned int isCreateHUD : 1; unsigned int isDisablePause : 1; unsigned int timerRunOnPause : 1; // 0x01 unsigned int isHidePauseHUD : 1; // 0x02 unsigned int isShowLRAStart : 1; // 0x04 unsigned int isCheckForLRAStart : 1; // 0x08 unsigned int isShowZRetry : 1; // 0x10 unsigned int isCheckForZRetry : 1; // 0x20 unsigned int isShowAnalogStick : 1; // 0x40 unsigned int isShowScore : 1; // 0x80 unsigned int isRunStockLogic : 1; // 0x20 unsigned int isDisableHit : 1; // 0x20 unsigned int useKOCounter : 1; s8 playerKind; // -1 = use selected fighter s8 cpuKind; // -1 = no CPU s16 stage; // -1 = use selected stage unsigned int timerSeconds : 32; // 0xFFFFFFFF unsigned int timerSubSeconds : 8; // 0xFF void *onCheckPause; void *onMatchEnd; } EventMatchData; typedef struct EventDesc { char *eventName; char *eventDescription; char *eventTutorial; char *eventFile; char *eventCSSFile; u8 isChooseCPU : 1; u8 isSelectStage : 1; u8 use_savestates : 1; // enables dpad left and right savestates u8 disable_hazards : 1; // removes stage hazards u8 scoreType; u8 callbackPriority; EventMatchData *matchData; int defaultOSD; } EventDesc; typedef struct EventPage { char *name; int eventNum; EventDesc **events; } EventPage; typedef struct EventOption { u8 option_kind; // the type of option this is; string, integers, etc u8 disable; // boolean for disabling the option u16 value_num; // number of values u16 option_val; // value of this option EventMenu *menu; // pointer to the menu that pressing A opens char *option_name; // pointer to the name of this option char *desc; // pointer to the description string for this option void **option_values; // pointer to an array of strings void (*onOptionChange)(GOBJ *menu_gobj, int value); // function that runs when option is changed GOBJ *(*onOptionSelect)(GOBJ *menu_gobj); // function that runs when option is selected } EventOption; struct EventMenu { char *name; // name of this menu u8 option_num; // number of options this menu contains u8 scroll; // u8 state; // bool used to know if this menu is focused u8 cursor; // index of the option currently selected EventOption *options; // pointer to all of this menu's options EventMenu *prev; // pointer to previous menu, used at runtime int (*menu_think)(GOBJ *menu_gobj); // function that runs every frame of this menu. returns a bool which indicates if basic menu code should be execution }; typedef struct MenuData { EventDesc *event_desc; EventMenu *currMenu; u16 canvas_menu; u16 canvas_popup; u8 isPaused; u8 controller_index; // index of the controller who paused Text *text_name; Text *text_value; Text *text_popup; Text *text_title; Text *text_desc; u16 popup_cursor; u16 popup_scroll; GOBJ *popup; evMenu *menu_assets; JOBJ *row_joints[MENU_MAXOPTION][2]; // pointers to row jobjs JOBJ *highlight_menu; // pointer to the highlight jobj JOBJ *highlight_popup; // pointer to the highlight jobj JOBJ *scroll_top; JOBJ *scroll_bot; GOBJ *custom_gobj; // onSelect gobj int (*custom_gobj_think)(GOBJ *custom_gobj); // per frame function. Returns bool indicating if the program should check to unpause void *(*custom_gobj_destroy)(GOBJ *custom_gobj); // on destroy function } MenuData; typedef struct FtStateData { int is_exist; int state; float facing_direction; float stateFrame; float stateSpeed; float stateBlend; Vec4 XRotN_rot; // XRotN struct { // Vec3 anim_vel; // 0x74 Vec3 self_vel; // 0x80 Vec3 kb_vel; // 0x8C int x98; // 0x98 int x9c; // 0x9C int xa0; // 0xA0 int xa4; // 0xA4 int xa8; // 0xA8 int xac; // 0xAC Vec3 pos; // 0xb0 Vec3 pos_prev; // 0xBC Vec3 pos_delta; // 0xC8 Vec3 unknownD4; // 0xD4 int air_state; // 0xE0 float horzitonal_velocity_queue_will_be_added_to_0xec; // 0xE4 float vertical_velocity_queue_will_be_added_to_0xec; // 0xE8 Vec3 selfVelGround; // 0xEC int unknownF8; // 0xF8 int unknownFC; // 0xFC int unknown100; // 0x100 } phys; // ColorOverlay color[3]; struct { // float lstick_x; // 0x620 float lstick_y; // 0x624 float lstick_prev_x; // 0x628 float lstick_prev_y; // 0x62C int unknown630; // 0x630 int unknown634; // 0x634 float cstick_x; // 0x638 float cstick_y; // 0x63C int x640; // 0x640 int unknown644; // 0x644 int unknown648; // 0x648 int unknown64C; // 0x64C float trigger; // 0x650 int unknown654; // 0x654 int unknown658; // 0x658 int held; // 0x65C int held_prev; // 0x660 int unknown664; // 0x664 int pressed; // 0x668 int unknown66C; // 0x66C char timer_lstick_tilt_x; // 0x670 char timer_lstick_tilt_y; // 0x671 char timer_trigger_analog; // 0x672 char timer_lstick_smash_x; // 0x673 char timer_lstick_smash_y; // 0x674 char timer_trigger_digital; // 0x675 char timer_lstick_any_x; // 0x676 char timer_lstick_any_y; // 0x677 char timer_trigger_any; // 0x678 char x679; // 0x679 char x67A; // 0x67A char x67B; // 0x67B char timer_a; // 0x67C char timer_b; // 0x67D char timer_xy; // 0x67E char timer_z; // 0x67F char timer_LR; // 0x680 char timer_padup; // 0x681 char timer_paddown; // 0x682 char timer_item_release; // 0x683 char sinceRapidLR; // 0x684 char timer_unk2; // 0x685 char timer_unk3; // 0x686 char timer_unk4; // 0x687 char timer_sideb; // 0x688 char timer_neutralb; // 0x689 char timer_unk5; // 0x68A char timer_unk6; // 0x68B } input; // CollData coll_data; CameraBox cameraBox; ftHit hitbox[4]; ftHit throw_hitbox[2]; ftHit unk_hitbox; struct { unsigned char throw_1 : 1; // 0x80 - x2210 unsigned char throw_2 : 1; // 0x40 - x2210 unsigned char throw_3 : 1; // 0x20 - x2210 unsigned char throw_release : 1; // 0x10 - x2210. also used to change users direction during aerial attacks unsigned char throw_turn : 1; // 0x8 - x2210 unsigned char throw_6 : 1; // 0x4 - x2210 unsigned char throw_7 : 1; // 0x2 - x2210 unsigned char throw_8 : 1; // 0x1 - x2210 float throw_timerval; // equal to script_event_timer of the attacker unsigned char x2218_1 : 1; // 0x80 - x2218 unsigned char x2218_2 : 1; // 0x40 - x2218 unsigned char x2218_3 : 1; // 0x20 - x2218 unsigned char reflect_enable : 1; // 0x10 - x2218 unsigned char reflect_nochangeowner : 1; // 0x8 - x2218 unsigned char x2218_6 : 1; // 0x4 - x2218 unsigned char absorb_enable : 1; // 0x2 - x2218 unsigned char absorb_unk : 1; // 0x1 - x2218 unsigned char shield : 1; // is shielding bool. 0x80 - 0x2219 unsigned char immune : 1; // 0x40 - 0x2219 unsigned char x2219_3 : 1; // 0x20 - 0x2219 unsigned char hitbox_active : 1; // 0x10 - 0x2219 unsigned char x2219_5 : 1; // 0x8 - 0x2219 unsigned char freeze : 1; // 0x4 - 0x2219 unsigned char hitlag_unk : 1; // 0x2 - 0x2219 unsigned char hitlag_unk2 : 1; // 0x1 - 0x2219 unsigned char x221a_1 : 1; // 0x80 - 0x221a unsigned char x221a_2 : 1; // 0x40 - 0x221a unsigned char hitlag : 1; // 0x20 - 0x221a unsigned char x221a_4 : 1; // 0x10 - 0x221a unsigned char fastfall : 1; // 0x8 - 0x221a unsigned char no_hurt_script : 1; // 0x4 - 0x221a unsigned char x221a_7 : 1; // 0x2 - 0x221a unsigned char gfx_persist : 1; // 0x1 - 0x221a unsigned char shield_enable : 1; // 0x80 - 0x221b unsigned char shield_x40 : 1; // 0x40 - 0x221b unsigned char shield_x20 : 1; // 0x20 - 0x221b unsigned char shield_x10 : 1; // 0x10 - 0x221b unsigned char shield_x8 : 1; // 0x8 - 0x221b unsigned char x221b_6 : 1; // 0x4 - 0x221b unsigned char x221b_7 : 1; // 0x2 - 0x221b unsigned char x221b_8 : 1; // 0x1 - 0x221b unsigned char x221c_1 : 1; // 0x80 - 0x221c unsigned char x221c_2 : 1; // 0x40 - 0x221c unsigned char x221c_3 : 1; // 0x20 - 0x221c unsigned char x221c_4 : 1; // 0x10 - 0x221c unsigned char x221c_5 : 1; // 0x8 - 0x221c unsigned char x221c_6 : 1; // 0x4 - 0x221c unsigned char hitstun : 1; // 0x2 - 0x221c unsigned char x221c_8 : 1; // 0x1 = 0x221c unsigned char x221d_1 : 1; // 0x80 - 0x221d unsigned char x221d_2 : 1; // 0x40 - 0x221d unsigned char x221d_3 : 1; // 0x20 - 0x221d unsigned char input_enable : 1; // 0x10 - 0x221d unsigned char x221d_5 : 1; // 0x8 - 0x221d unsigned char nudge_disable : 1; // 0x4 - 0x221d unsigned char ground_ignore : 1; // 0x2 - 0x221d unsigned char x221d_8 : 1; // 0x1 - 0x221d unsigned char invisible : 1; // 0x80 - 0x221e unsigned char x221e_2 : 1; // 0x40 - 0x221e unsigned char x221e_3 : 1; // 0x20 - 0x221e unsigned char isItemVisible : 1; // 0x10 - 0x221e unsigned char x221e_5 : 1; // 0x8 - 0x221e unsigned char x221e_6 : 1; // 0x4 - 0x221e unsigned char x221e_7 : 1; // 0x2 - 0x221e unsigned char x221e_8 : 1; // 0x1 - 0x221e unsigned char mag_glass : 1; // 0x80 - 0x221f unsigned char dead : 1; // 0x40 - 0x221f unsigned char x221f_3 : 1; // 0x20 - 0x221f unsigned char sleep : 1; // 0x10 unsigned char ms : 1; // ms = master/slave. is 1 when the player is a slave unsigned char x221f_6 : 1; unsigned char x221f_7 : 1; unsigned char x221f_8 : 1; char flags_2220; // 0x2220 char flags_2221; // 0x2221 char flags_2222; // 0x2222 char flags_2223; // 0x2223 unsigned char x2224_1 : 1; // 0x80 - 0x2224 unsigned char x2224_2 : 1; // 0x40 - 0x2224 unsigned char stamina_dead : 1; // 0x20 - 0x2224 unsigned char x2224_4 : 1; // 0x10 - 0x2224 unsigned char x2224_5 : 1; // 0x8 - 0x2224 unsigned char x2224_6 : 1; // 0x4 - 0x2224 unsigned char x2224_7 : 1; // 0x2 - 0x2224 unsigned char x2224_8 : 1; // 0x1 - 0x2224 char flags_2225; // 0x2225 unsigned char x2226_1 : 1; // 0x80 - 0x2226 unsigned char x2226_2 : 1; // 0x40 - 0x2226 unsigned char is_thrown : 1; // 0x20 - 0x2226 unsigned char x2226_4 : 1; // 0x10 - 0x2226 unsigned char x2226_5 : 1; // 0x8 - 0x2226 unsigned char x2226_6 : 1; // 0x4 - 0x2226 unsigned char x2226_7 : 1; // 0x2 - 0x2226 unsigned char x2226_8 : 1; // 0x1 - 0x2226 char flags_2227; // 0x2227 char flags_2228; // 0x2228 unsigned char x2229_1 : 1; // 0x80 - 0x2229 unsigned char x2229_2 : 1; // 0x40 - 0x2229 unsigned char x2229_3 : 1; // 0x20 - 0x2229 unsigned char x2229_4 : 1; // 0x10 - 0x2229 unsigned char x2229_5 : 1; // 0x8 - 0x2229 unsigned char x2229_6 : 1; // 0x4 - 0x2229 unsigned char x2229_7 : 1; // 0x2 - 0x2229 unsigned char no_reaction_always : 1; // 0x1 - 0x2229 char flags_222A; // 0x222A char flags_222B; // 0x222B } flags; // struct { int charVar1; // 0x222c int charVar2; // 0x2230 int charVar3; // 0x2234 int charVar4; // 0x2238 int charVar5; // 0x223c int charVar6; // 0x2240 int charVar7; // 0x2244 int charVar8; // 0x2248 int charVar9; // 0x224c int charVar10; // 0x2250 int charVar11; // 0x2254 int charVar12; // 0x2258 int charVar13; // 0x225c int charVar14; // 0x2260 int charVar15; // 0x2264 int charVar16; // 0x2268 int charVar17; // 0x226c int charVar18; // 0x2270 int charVar19; // 0x2274 int charVar20; // 0x2278 int charVar21; // 0x227c int charVar22; // 0x2280 int charVar23; // 0x2284 int charVar24; // 0x2288 int charVar25; // 0x228c int charVar26; // 0x2290 int charVar27; // 0x2294 int charVar28; // 0x2298 int charVar29; // 0x229c int charVar30; // 0x22a0 int charVar31; // 0x22a4 int charVar32; // 0x22a8 int charVar33; // 0x22ac int charVar34; // 0x22b0 int charVar35; // 0x22b4 int charVar36; // 0x22b8 int charVar37; // 0x22bc int charVar38; // 0x22c0 int charVar39; // 0x22c4 int charVar40; // 0x22c8 int charVar41; // 0x22cc int charVar42; // 0x22d0 int charVar43; // 0x22d4 int charVar44; // 0x22d8 int charVar45; // 0x22dc int charVar46; // 0x22e0 int charVar47; // 0x22e4 int charVar48; // 0x22e8 int charVar49; // 0x22ec int charVar50; // 0x22f0 int charVar51; // 0x22f4 int charVar52; // 0x22f8 } fighter_var; struct { // int stateVar1; // 0x2340 int stateVar2; // 0x2344 int stateVar3; // 0x2348 int stateVar4; // 0x234c int stateVar5; // 0x2350 int stateVar6; // 0x2354 int stateVar7; // 0x2358 int stateVar8; // 0x235c int stateVar9; // 0x2360 int stateVar10; // 0x2364 int stateVar11; // 0x2368 int stateVar12; // 0x236c int stateVar13; // 0x2370 int stateVar14; // 0x2374 int stateVar15; // 0x2378 int stateVar16; // 0x237c int stateVar17; // 0x2380 int stateVar18; // 0x2384 } state_var; // struct { // int subactionFlag0; // 0x2200 int subactionFlag1; // 0x2204 int subactionFlag2; // 0x2208 int subactionFlag3; // 0x220C } ftcmd_var; // struct { // int behavior; // 0x182c float percent; // 0x1830 int x1834; // 0x1834 float percent_temp; // 0x1838 float applied; // 0x183c int x1840; // 0x1840 float direction; // 0x1844 int kb_angle; // 0x1848 int damaged_hurtbox; // 0x184c float force_applied; // 0x1850 Vec3 collpos; // 0x1854 int dealt; // 0x1860 int x1864; // 0x1864 GOBJ *source; // 0x1868 int x186c; // 0x186c int x1870; // 0x1870 int x1874; // 0x1874 int x1878; // 0x1878 int x187c; // 0x187c int x1880; // 0x1880 int x1884; // 0x1884 int x1888; // 0x1888 int x188c; // 0x188c int x1890; // 0x1890 int x1894; // 0x1894 int x1898; // 0x1898 int x189c; // 0x189c int x18a0; // 0x18a0 float kb_mag; // 0x18a4 kb magnitude int x18a8; // 0x18a8 int time_since_hit; // 0x18ac in frames int x18b0; // 0x18b0 float armor; // 0x18b4 int x18b8; // 0x18b8 int x18bc; // 0x18bc int x18c0; // 0x18c0 int source_ply; // 0x18c4 damage source ply number int x18c8; // 0x18c8 int x18cc; // 0x18cc int x18d0; // 0x18d0 int x18d4; // 0x18d4 int x18d8; // 0x18d8 int x18dc; // 0x18dc int x18e0; // 0x18e0 int x18e4; // 0x18e4 int x18e8; // 0x18e8 u16 instancehitby; // 0x18ec. Last Move Instance This Player Was Hit by int x18f0; // 0x18f0 int x18f4; // 0x18f4 u8 x18f8; // 0x18f8 u8 x18f9; // 0x18f8 u16 model_shift_frames; // 0x18f8 int x18fc; // 0x18fc int x1900; // 0x1900 int x1904; // 0x1904 int x1908; // 0x1908 int x190c; // 0x190c int x1910; // 0x1910 int x1914; // 0x1914 int x1918; // 0x1918 int x191c; // 0x191c int x1920; // 0x1920 int x1924; // 0x1924 int x1928; // 0x1928 int x192c; // 0x192c int x1930; // 0x1930 int x1934; // 0x1934 int x1938; // 0x1938 int x193c; // 0x193c int x1940; // 0x1940 int x1944; // 0x1944 int x1948; // 0x1948 int x194c; // 0x194c int x1950; // 0x1950 int x1954; // 0x1954 int x1958; // 0x1958 float hitlag_frames; // 0x195c } dmg; // struct { // float grab_timer; // 0x1a4c int x1a50; // 0x1a50 int x1a54; // 0x1a54 GOBJ *grab_attacker; // 0x1a58 GOBJ *grab_victim; // 0x1a5c int x1a60; // 0x1a60 int x1a64; // 0x1a64 u16 x1a68; // 0x1a68 u16 vuln; // 0x1a6a int x1a6c; // 0x1a6c int x1a70; // 0x1a70 int x1a74; // 0x1a74 int x1a78; // 0x1a78 int x1a7c; // 0x1a7c int x1a80; // 0x1a80 int x1a84; // 0x1a84 } grab; // struct // 0x1968 { // char jumps_used; // 0x1968 char walljumps_used; // 0x1969 } jump; struct // 0x2114 { int state; // 0x2114 0 = none, 1 = pre-charge, 2 = charging, 3 = release int frame; // 0x2118 number of frames fighter has charged for float hold_frame; // 0x211c frame that charge begins/ends float dmg_mult; // 0x2120 damage multiplier float speed_mult; // 0x2124 speed multiplier? int x2128; // 0x2128 int x212c; // 0x212c int is_sfx_played; // 0x2130 bool for smash sfx? u8 vibrate_frame; // 0x2134 u8 x2135; // 0x2135 float since_hitbox; // 0x2138 } smash; struct // 0x1988 { // int script; // 0x1988 int game; // 0x198c int ledge_intang_left; // 0x1990 int respawn_intang_left; // 0x1994 } hurtstatus; struct { float health; // 0x1998 float lightshield_amt; // 0x199c int dmg_taken; // 0x19a0, seems to be all damage taken during the frame, is reset at the end of the frame int dmg_taken2; // 0x19a4, idk there so many of these GOBJ *dmg_source; // 0x19a8, points to the entity that hit the shield float hit_direction; // 0x19ac int hit_attr; // 0x19b0, attribute of the hitbox that collided float x19b4; // 0x19b4 float x19b8; // 0x19b8 int dmg_taken3; // 0x19bc, seems to be the most recent amount of damage taken } shield; struct { JOBJ *bone; // 0x19c0 unsigned char is_checked : 1; // 0x19d0 0x80. is checked for collision when 0 Vec3 pos; // 19d4 Vec3 offset; // 0x19d4 float size_mult; // 0x19e0 } shield_bubble; struct { JOBJ *bone; // 0x19e4 unsigned char is_checked : 1; // 0x19d0 0x80. is checked for collision when 0 Vec3 pos; // 0x19d4 Vec3 offset; // 0x19f8 float size_mult; // 0x1a04 } reflect_bubble; struct { JOBJ *bone; // 0x1a08 unsigned char is_checked : 1; // 0x1a0c 0x80. is checked for collision when 0 Vec3 pos; // 0x1a10 Vec3 offset; // 0x1a1c float size_mult; // 0x1a28 } absorb_bubble; struct { // float hit_direction; // 0x1a2c int max_dmg; // 0x1a30 float dmg_mult; // 0x1a34 int is_break; // 0x1a38 } reflect_hit; // struct { // int x1a3c; // 0x1a3c float hit_direction; // 0x1a40 int dmg_taken; // 0x1a44 int hits_taken; // 0x1a48 } absorb_hit; // struct { void (*OnGrabFighter_Self)(GOBJ *fighter); // 0x2190 void (*x2194)(GOBJ *fighter); // 0x2194 void (*OnGrabFighter_Victim)(GOBJ *fighter); // 0x2198 void (*IASA)(GOBJ *fighter); // 0x219C void (*Anim)(GOBJ *fighter); // 0x21A0 void (*Phys)(GOBJ *fighter); // 0x21a4 void (*Coll)(GOBJ *fighter); // 0x21a8 void (*Cam)(GOBJ *fighter); // 0x21ac void (*Accessory1)(GOBJ *fighter); // 0x21b0 void (*Accessory2)(GOBJ *fighter); // 0x21b4 void (*Accessory3)(GOBJ *fighter); // 0x21b8 void (*Accessory4)(GOBJ *fighter); // 0x21bc void (*OnGiveDamage)(GOBJ *fighter); // 0x21c0 void (*OnShieldHit)(GOBJ *fighter); // 0x21c4 void (*OnReflectHit)(GOBJ *fighter); // 0x21c8 void (*x21cc)(GOBJ *fighter); // 0x21cc void (*EveryHitlag)(GOBJ *fighter); // 0x21d0 void (*EnterHitlag)(GOBJ *fighter); // 0x21d4 void (*ExitHitlag)(GOBJ *fighter); // 0x21d8 void (*OnTakeDamage)(GOBJ *fighter); // 0x21dc void (*OnDeath)(GOBJ *fighter); // 0x21e0 void (*OnDeath2)(GOBJ *fighter); // 0x21e4 void (*OnDeath3)(GOBJ *fighter); // 0x21e8 void (*OnActionStateChange)(GOBJ *fighter); // 0x21ec void (*OnTakeDamage2)(GOBJ *fighter); // 0x21f0 void (*OnHurtboxDetect)(GOBJ *fighter); // 0x21f4 void (*OnSpin)(GOBJ *fighter); // 0x21f8 } cb; } FtStateData; typedef struct FtState { FtStateData data[2]; Playerblock player_block; int stale_queue[11]; } FtState; typedef struct Savestate { int is_exist; int frame; u8 event_data[EVENT_DATASIZE]; FtState ft_state[6]; } Savestate; typedef struct evFunction { void (*Event_Init)(GOBJ *event); void (*Event_Update)(); void (*Event_Think)(GOBJ *event); EventMenu **menu_start; } evFunction; typedef struct EventVars { EventDesc *event_desc; // event information evMenu *menu_assets; // menu assets GOBJ *event_gobj; // event gobj GOBJ *menu_gobj; // event menu gobj int game_timer; // amount of game frames passed u8 hide_menu; // enable this to hide the base menu. used for custom menus. int (*Savestate_Save)(Savestate *savestate); // function pointer to save state int (*Savestate_Load)(Savestate *savestate); // function pointer to load state GOBJ *(*Message_Display)(int msg_kind, int queue_num, int msg_color, char *format, ...); // function pointer to display message int *(*Tip_Display)(int lifetime, char *fmt, ...); void (*Tip_Destroy)(); // function pointer to destroy tip Savestate *savestate; // points to the events main savestate evFunction evFunction; // event specific functions ArchiveInfo *event_archive; // event archive header DevText *db_console_text; } EventVars; // Function prototypes EventDesc *GetEventDesc(int page, int event); void EventInit(int page, int eventID, MatchInit *matchData); void EventLoad(); GOBJ *EventMenu_Init(EventDesc *event_desc, EventMenu *start_menu); void EventMenu_Think(GOBJ *eventMenu, int pass); void EventMenu_COBJThink(GOBJ *gobj); void EventMenu_Draw(GOBJ *eventMenu); int Text_AddSubtextManual(Text *text, char *string, int posx, int posy, int scalex, int scaley); EventMenu *EventMenu_GetCurrentMenu(GOBJ *gobj); int Savestate_Save(Savestate *savestate); int Savestate_Load(Savestate *savestate); void Update_Savestates(); int GOBJToID(GOBJ *gobj); int FtDataToID(FighterData *fighter_data); int BoneToID(FighterData *fighter_data, JOBJ *bone); GOBJ *IDToGOBJ(int id); FighterData *IDToFtData(int id); JOBJ *IDToBone(FighterData *fighter_data, int id); void EventUpdate(); void Event_IncTimer(GOBJ *gobj); void Test_Think(GOBJ *gobj); static EventDesc *static_eventInfo; static MenuData *static_menuData; static EventVars stc_event_vars; static int *eventDataBackup; static EventVars **event_vars_ptr = 0x803d7054; //R13 + (-0x4730) static EventVars *event_vars; // EventOption option_kind definitions #define OPTKIND_MENU 0 #define OPTKIND_STRING 1 #define OPTKIND_INT 2 #define OPTKIND_FLOAT 3 #define OPTKIND_FUNC 4 // EventMenu state definitions #define EMSTATE_FOCUS 0 #define EMSTATE_OPENSUB 1 #define EMSTATE_OPENPOP 2 #define EMSTATE_WAIT 3 // pauses menu logic, used for when a custom window is being shown // GX Link args #define GXLINK_MENUMODEL 12 #define GXPRI_MENUMODEL 80 #define GXLINK_MENUTEXT 12 #define GXPRI_MENUTEXT GXPRI_MENUMODEL + 1 // popup menu #define GXPRI_POPUPMODEL GXPRI_MENUTEXT + 1 #define GXLINK_POPUPMODEL 12 #define GXPRI_POPUPTEXT GXPRI_POPUPMODEL + 1 #define GXLINK_POPUPTEXT 12 // cobj #define MENUCAM_COBJGXLINK (1 << GXLINK_MENUMODEL) | (1 << GXLINK_MENUTEXT) | (1 << GXLINK_POPUPMODEL) | (1 << GXLINK_POPUPTEXT) #define MENUCAM_GXPRI 9 // menu model #define OPT_SCALE 1 #define OPT_X 0 //0.5 #define OPT_Y -1 #define OPT_Z 0 #define OPT_WIDTH 55 / OPT_SCALE #define OPT_HEIGHT 40 / OPT_SCALE // menu text object #define MENU_CANVASSCALE 0.05 #define MENU_TEXTSCALE 1 #define MENU_TEXTZ 0 // menu title #define MENU_TITLEXPOS -430 #define MENU_TITLEYPOS -366 #define MENU_TITLESCALE 2.3 #define MENU_TITLEASPECT 870 // menu description #define MENU_DESCXPOS -21.5 #define MENU_DESCYPOS 12 #define MENU_DESCSCALE 1 // menu option name #define MENU_OPTIONNAMEXPOS -430 #define MENU_OPTIONNAMEYPOS -230 #define MENU_NAMEASPECT 440 // menu option value #define MENU_OPTIONVALXPOS 250 #define MENU_OPTIONVALYPOS -230 #define MENU_TEXTYOFFSET 50 #define MENU_VALASPECT 280 // menu highlight #define MENUHIGHLIGHT_SCALE 1 // OPT_SCALE #define MENUHIGHLIGHT_HEIGHT ROWBOX_HEIGHT #define MENUHIGHLIGHT_WIDTH (OPT_WIDTH * 0.785) #define MENUHIGHLIGHT_X OPT_X #define MENUHIGHLIGHT_Y 10.8 //10.3 #define MENUHIGHLIGHT_Z 0.01 #define MENUHIGHLIGHT_YOFFSET ROWBOX_YOFFSET #define MENUHIGHLIGHT_COLOR \ { \ 255, 211, 0, 255 \ } // menu scroll #define MENUSCROLL_SCALE 2 // OPT_SCALE #define MENUSCROLL_SCALEY 1.105 * MENUSCROLL_SCALE // OPT_SCALE #define MENUSCROLL_X 22.5 #define MENUSCROLL_Y 12 #define MENUSCROLL_Z 0.01 #define MENUSCROLL_PEROPTION 1 #define MENUSCROLL_MINLENGTH -1 #define MENUSCROLL_MAXLENGTH -10 #define MENUSCROLL_COLOR \ { \ 255, 211, 0, 255 \ } // row jobj #define ROWBOX_HEIGHT 2.3 #define ROWBOX_WIDTH 18 #define ROWBOX_X 12.5 //13 #define ROWBOX_Y 10.8 //10.3 #define ROWBOX_Z 0 #define ROWBOX_YOFFSET -2.5 #define ROWBOX_COLOR \ { \ 104, 105, 129, 100 \ } // arrow jobj #define TICKBOX_SCALE 1.8 #define TICKBOX_X 11.7 #define TICKBOX_Y 11.7 // popup model #define POPUP_WIDTH ROWBOX_WIDTH #define POPUP_HEIGHT 19 #define POPUP_SCALE 1 #define POPUP_X 12.5 #define POPUP_Y 8.3 #define POPUP_Z 0.01 #define POPUP_YOFFSET -2.5 // popup text object #define POPUP_CANVASSCALE 0.05 #define POPUP_TEXTSCALE 1 #define POPUP_TEXTZ 0.01 // popup text #define POPUP_OPTIONVALXPOS 250 #define POPUP_OPTIONVALYPOS -280 #define POPUP_TEXTYOFFSET 50 // popup highlight #define POPUPHIGHLIGHT_HEIGHT ROWBOX_HEIGHT #define POPUPHIGHLIGHT_WIDTH (POPUP_WIDTH * 0.785) #define POPUPHIGHLIGHT_X 0 #define POPUPHIGHLIGHT_Y 5 #define POPUPHIGHLIGHT_Z 1 #define POPUPHIGHLIGHT_YOFFSET ROWBOX_YOFFSET #define POPUPHIGHLIGHT_COLOR \ { \ 255, 211, 0, 255 \ } // Message void Message_Init(); GOBJ *Message_Display(int msg_kind, int queue_num, int msg_color, char *format, ...); void Message_Manager(GOBJ *mngr_gobj); void Message_Destroy(GOBJ **msg_queue, int msg_num); void Message_Add(GOBJ *msg_gobj, int queue_num); void Message_CObjThink(GOBJ *gobj); float BezierBlend(float t); #define MSGQUEUE_NUM 7 #define MSGQUEUE_SIZE 5 #define MSGQUEUE_GENERAL 6 enum MsgState { MSGSTATE_WAIT, MSGSTATE_SHIFT, MSGSTATE_DELETE, }; enum MsgArea { MSGKIND_P1, MSGKIND_P2, MSGKIND_P3, MSGKIND_P4, MSGKIND_P5, MSGKIND_P6, MSGKIND_GENERAL, }; typedef struct MsgData { Text *text; // text pointer int kind; // the type of message this is int state; // unused atm int prev_index; // used to animate the messages position during shifts int orig_index; // used to tell if the message moved throughout the course of the frame int anim_timer; // used to track animation frame int lifetime; // amount of frames after spawning to kill this message int alive_timer; // amount of frames this message has been alive for } MsgData; typedef struct MsgMngrData { COBJ *cobj; int state; int canvas; GOBJ *msg_queue[MSGQUEUE_NUM][MSGQUEUE_SIZE]; // array 7 is for miscellaneous messages, not related to a player } MsgMngrData; static GOBJ *stc_msgmgr; static float stc_msg_queue_offsets[] = {5.15, 5.15, 5.15, 5.15, 5.15, 5.15, -5.15}; // Y offsets for each message in the queue static Vec3 stc_msg_queue_general_pos = {-21, 18.5, 0}; enum MsgColors { MSGCOLOR_WHITE, MSGCOLOR_GREEN, MSGCOLOR_RED, MSGCOLOR_YELLOW }; static GXColor stc_msg_colors[] = { {255, 255, 255, 255}, {141, 255, 110, 255}, {255, 162, 186, 255}, {255, 240, 0, 255}, }; #define MSGTIMER_SHIFT 6 #define MSGTIMER_DELETE 6 #define MSG_LIFETIME (2 * 60) #define MSG_LINEMAX 3 // lines per message #define MSG_CHARMAX 32 // characters per line #define MSG_HUDYOFFSET 8 #define MSGJOINT_SCALE 3 #define MSGJOINT_X 0 #define MSGJOINT_Y 0 #define MSGJOINT_Z 0 #define MSGTEXT_BASESCALE 1.4 #define MSGTEXT_BASEWIDTH (330 / MSGTEXT_BASESCALE) #define MSGTEXT_BASEX 0 #define MSGTEXT_BASEY -1 #define MSGTEXT_YOFFSET 30 // GX stuff #define MSG_GXLINK 13 #define MSG_GXPRI 80 #define MSGTEXT_GXPRI MSG_GXPRI + 1 #define MSG_COBJLGXLINKS (1 << MSG_GXLINK) #define MSG_COBJLGXPRI 8 typedef struct TipMgr { GOBJ *gobj; // tip gobj Text *text; // tip text object int state; // state this tip is in. 0 = in, 1 = wait, 2 = out int lifetime; // tips time spent onscreen } TipMgr; int Tip_Display(int lifetime, char *fmt, ...); void Tip_Destroy(); // 0 = immediately destroy, 1 = force exit void Tip_Think(GOBJ *gobj); #define TIP_TXTJOINT 2