[
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# Custom for Visual Studio\n*.cs     diff=csharp\n\n# Standard to msysgit\n*.doc\t diff=astextplain\n*.DOC\t diff=astextplain\n*.docx diff=astextplain\n*.DOCX diff=astextplain\n*.dot  diff=astextplain\n*.DOT  diff=astextplain\n*.pdf  diff=astextplain\n*.PDF\t diff=astextplain\n*.rtf\t diff=astextplain\n*.RTF\t diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "# Windows thumbnail cache files\nThumbs.db\nehthumbs.db\nehthumbs_vista.db\n\n# Folder config file\nDesktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n\n# =========================\n# Operating System Files\n# =========================\nASM/Misc/Store Version Number.asm\nASM/Misc/Overwrite Compile Date.asm\n\n# ==========================\n# Project files\n# ==========================\nBuild\\ TM\\ Codeset/mac/gecko\nAdditional\\ ISO\\ Files/codes.gct\nAdditional\\ ISO\\ Files/Start.dol\n\n\n# Mac files\n.DS_Store\n"
  },
  {
    "path": "ASM/Additional Codes/Allow Staling in Develop Mode.asm",
    "content": "#To be inserted at 80089250\n\nb 0x8\n"
  },
  {
    "path": "ASM/Additional Codes/Better Camera/C-Stick Pans Camera.asm",
    "content": "#To be inserted at 8002cb30\n.include \"../../Globals.s\"\n\n.set Player,5\n.set FloatPointer,6\n\n#Float regs\n.set Deadzone,5\n.set DeadzoneNeg,6\n.set PlayerY,7\n.set PlayerX,8\n\n#Get Float Pointer\n  bl  Floats\n  mflr FloatPointer\n#Get Player Input Struct\n  load r3,0x804C1FAC\n  lbz\tr4, 0x02C5 (r31)\n  mulli Player, r4, 0x44\n  add Player, r3, Player\n#Get Deadzone Value from PlCo\n  lwz\tr3, -0x514C (r13)\n  lfs Deadzone, 0(r3)\n  fneg DeadzoneNeg, Deadzone\n\nCheckYDeadzone:\n#Check Y Value\n  lfs PlayerY, 0x2C(Player)\n  fcmpo cr0, PlayerY, DeadzoneNeg\n  ble- StoreY\n  fcmpo cr0, PlayerY, Deadzone\n  blt- CheckXDeadzone\n\nStoreY:\n  lfs f1, 0x318(r31) #Get X\n  lfs f2, 0x330(r31) #Get zoom level\n  lfs f3, 0x0(FloatPointer)    #Get multiplier\n  fdivs f3,f2,f3   #Zoom * var\n  fmuls PlayerY,PlayerY,f3   #Stick axis * zoomed\n  fadds f1,f1,PlayerY   #Add to X\n  stfs f1, 0x318(r31)  #Store\n\nCheckXDeadzone:\n  lfs PlayerY, 0x28(Player)\n  fcmpo cr0, PlayerY, DeadzoneNeg\n  ble- StoreX\n  fcmpo cr0, PlayerY, Deadzone\n  blt- Exit\n\nStoreX:\n  lfs f1, 0x314(r31)\n  lfs f2, 0x330(r31) #Get zoom level\n  lfs f3, 0x0(FloatPointer)    #Get multiplier\n  fdivs f3,f2,f3   #Zoom * var\n  fmuls PlayerY,PlayerY,f3   #Stick axis * zoomed\n  fadds f1,f1,PlayerY   #Add to Y\n  stfs f1, 0x314(r31)\n  b Exit\n\nFloats:\nblrl\n.float 125\n\nExit:\nlbz\tr0, 0x02C5 (r31)\n"
  },
  {
    "path": "ASM/Additional Codes/Better Camera/CStickPanOffscreen/Bottom.asm",
    "content": "#To be inserted at 8002c6e4\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/Better Camera/CStickPanOffscreen/Left.asm",
    "content": "#To be inserted at 8002c6bc\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/Better Camera/CStickPanOffscreen/Right.asm",
    "content": "#To be inserted at 8002c6a8\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/Better Camera/CStickPanOffscreen/Top.asm",
    "content": "#To be inserted at 8002c6d0\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/Better Camera/SnapToOffscreenPlayers/Always Onscreen.asm",
    "content": "#To be inserted at 8002cf34\n.include \"../../../Globals.s\"\n\n.set REG_Pauser,31\n.set REG_Count,30\n\nbackup\n\n#Get player port who paused\n  load r3,0x8046b6a0\n  lbz REG_Pauser,0x1(r3)\n\n#Search all players for this port\n  li  REG_Count,0\nLoop:\n  mr  r3,REG_Count\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  cmpwi r3,0\n  beq IncLoop\n#Check their port to see if it matches\n  mr  r3,REG_Count\n  branchl r12,0x8003345c\n  cmpw  r3,REG_Pauser\n  beq FoundPauser\nIncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,4\n  blt Loop\n  b Dead\n\nFoundPauser:\n#Check if player is alive\n  mr  r3,REG_Count\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  lwz r3,0x2C(r3)\n  lbz r3,0x221F(r3)\n  rlwinm. r3,r3,0,25,25\n  bne Dead\n\nAlive:\n  li  r3,0\n  b Exit\nDead:\n  li  r3,1\nExit:\n  restore\n"
  },
  {
    "path": "ASM/Additional Codes/Better Camera/SnapToOffscreenPlayers/Snap.asm",
    "content": "#To be inserted at 8002c5f0\n.include \"../../../Globals.s\"\n\n\n.set REG_Pauser,31\n.set REG_Count,30\n\nbackup\n\n#Get player port who paused\n  load r3,0x8046b6a0\n  lbz REG_Pauser,0x1(r3)\n\n#Search all players for this port\n  li  REG_Count,0\nLoop:\n  mr  r3,REG_Count\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  cmpwi r3,0\n  beq IncLoop\n#Check their port to see if it matches\n  mr  r3,REG_Count\n  branchl r12,0x8003345c\n  cmpw  r3,REG_Pauser\n  beq FoundPauser\nIncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,4\n  blt Loop\n  b Dead\n\nFoundPauser:\n#Check if player is alive\n  mr  r3,REG_Count\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  lwz r3,0x2C(r3)\n  lbz r3,0x221F(r3)\n  rlwinm. r3,r3,0,25,25\n  bne Dead\n\nAlive:\n  restore\n  branch r12,0x8002c644\nDead:\nExit:\n  restore\n  lfs\tf0, 0x000C (r26)\n"
  },
  {
    "path": "ASM/Additional Codes/Better Camera/Unrestricted Camera.asm",
    "content": "#To be inserted at 8002f5bc\nloc_0x0:\n  lis r3, 0x8048\n  lbz r3, -25240(r3)\n  rlwinm. r3, r3, 0, 30, 30\n  beq- loc_0x48\n  lis r3, 0x8048\n  lbz r3, -25296(r3)\n  cmpwi r3, 0x1C\n  beq- loc_0x48\n  li r3, 0x0\n  stw r3, 760(r31)\n  lis r3, 0x4700\n  stw r3, 744(r31)\n  stw r3, 748(r31)\n  stw r3, 752(r31)\n  stw r3, 756(r31)\n  stw r3, 764(r31)\n  lis r3, 0x8003\n  b loc_0x50\n\nloc_0x48:\n  lis r3, 0x8003\n  stfs f1, 764(r31)\n\nloc_0x50:\n\n"
  },
  {
    "path": "ASM/Additional Codes/Boot to CSS/Boot to Main Menu Or CSS.s",
    "content": "#To be inserted at 801BFA20\n.include \"../../Globals.s\"\n\n  li  r3,2\n"
  },
  {
    "path": "ASM/Additional Codes/Boot to Event Mode/Boot to Main Menu Or CSS.asm",
    "content": "#To be inserted at 801BFA20\n.include \"../../Globals.s\"\n\n.set LoopCount,12\n.set InputStruct,11\n\n#Check if any player is pressing Z\n  li  LoopCount,0\n  load InputStruct,InputStructStart\n#Loop through inputs\nInputLoop:\n  mulli\tr0, LoopCount, 68\n  add\t  r3, r0, InputStruct\n  lwz\t  r3, 0 (r3)\n  rlwinm. r0,r3,0,21,21     #Check For X\n  bne LoadCSS\n  addi LoopCount,LoopCount,1\n  cmpwi LoopCount,4\n  blt InputLoop\n  b LoadEventMenu\n\nLoadCSS:\n#Play SFX\n  li  r3,1\n  branchl r12,SFX_MenuCommonSound\n  li  r3,2\n  b Exit\n\n#Boot to Event Menu\nLoadEventMenu:\n  li\tr3, 1\n\nExit:\n"
  },
  {
    "path": "ASM/Additional Codes/Boot to Event Mode/Main Menu Starts at Event Mode.asm",
    "content": "#To be inserted at 801b02dc\n.include \"../../Globals.s\"\n\n.set entity,31\n.set player,31\n.set playerdata,31\n\n#Spoof current (soon to be previous) screen\n  li\tr3,Scene.EventMode\n  load\tr4,SceneController\n  stb\tr3,Scene.CurrentMajor(r4)\n\n  li\tr3,0x00\n"
  },
  {
    "path": "ASM/Additional Codes/CSS KO Star Codes/Calculate KO Stars Upon Exiting Dairantou.asm",
    "content": "#To be inserted at 8016ebac\n.include \"../../Globals.s\"\n\n#Check if VS Mode\n  load r3,SceneController\n  lbz r3,Scene.CurrentMajor(r3)\n  cmpwi r3,Scene.VSMode\n  bne Exit\n\n#Init Struct?\n  load\tr3,0x803dda00\t\t#Get Some Scene Struct\n  branchl\tr12,0x801a5f00\t\t#Wipe and Copy Match Info\n\n#Update KO Star Count\n  load\tr3,0x803dda00\t\t#Get Some Scene Struct\n  lwz\tr4, -0x77C0 (r13) #Get SSS Struct\n  addi\tr4, r4, 1424\n  li  r5,0              #Next Minor Scene\n  branchl\tr12,0x801a5f64\t\t#Update KO Stars\n\n#Update VS Records\n  load\tr3,0x8047c028\t\t#Get Match Info\n  branchl\tr12,0x801623a4\t\t#Update VS Records\n\nExit:\n  lwz\tr0, 0x001C (sp)\n  lwz\tr31, 0x0014 (sp)\n"
  },
  {
    "path": "ASM/Additional Codes/CSS KO Star Codes/Disable KO Star Deletion When Leaving CSS.asm",
    "content": "#To be inserted at 801a5600\n.include \"../../Globals.s\"\n\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/Collision Link Draw Order Fix [Punkline]/New Draw Location.asm",
    "content": "#To be inserted at 80030288\n.include \"../../Globals.s\"\n\nbranchl r12,0x80030A78\ncmpwi r3, 0\nbeq- _return\n# checks for collision link display flag\n\n  _if_drawing_stage_collisions:\n  branchl r12, 0x80059e60\n  # moves post-process drawing call to before player draw\n  # causes geometry to be drawn on black/white screen, if enabled simultaneously\n\n_return:\nlbz    r0, 0 (r31)\n"
  },
  {
    "path": "ASM/Additional Codes/Collision Link Draw Order Fix [Punkline]/Remove Original Draw.asm",
    "content": "#To be inserted at 8005a2ec\n.include \"../../Globals.s\"\n\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/DEBUGLOG.s",
    "content": "#To be inserted at 801a4cb4\n.include \"../Globals.s\"\n\n.set GObj_Create,0x803901f0\n.set GObj_AddUserData,0x80390b68\n.set GObj_AddProc,0x8038fd54\n.set HSD_MemAlloc,0x8037f1e4\n.set DevelopText_CreateDataTable,0x80302834\n.set DevelopText_Activate,0x80302810\n.set DevelopText_AddString,0x80302be4\n.set DevelopText_EraseAllText,0x80302bb0\n.set DevelopMode_Text_ResetCursorXY,0x80302a3c\n.set sprintf,0x80323cf4\n\n.set  REG_DevelopText,31\n.set  REG_GObjData,30\n.set  REG_GObj,29\n\nbackup\n\n#Create Rectangle\n  li  r3,0x348\n  branchl r12,HSD_MemAlloc\n  mr  r8,r3\n  li  r3,6\n  li  r4,0\n  li  r5,0\n  li  r6,20\n  li  r7,7\n  branchl r12,DevelopText_CreateDataTable\n  mr  REG_DevelopText,r3\n#Activate Text\n  lwz\tr3, -0x4884 (r13)\n  mr  r4,REG_DevelopText\n  branchl r12,DevelopText_Activate\n#Hide blinking cursor\n  li  r3,0\n  stb r3,0x26(REG_DevelopText)\n#Create Background GObj\n  li  r3,0\n  li  r4,0\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n#Allocate Space\n\tli\tr3,64\n\tbranchl r12,HSD_MemAlloc\n\tmr\tREG_GObjData,r3\n#Zero\n\tli\tr4,64\n\tbranchl r12,ZeroAreaLength\n#Initialize\n\tmr\tr6,REG_GObjData\n\tmr\tr3,REG_GObj\n\tli\tr4,4\n\tload\tr5,HSD_Free\n\tbranchl r12,GObj_AddUserData\n#Add Process\n\tmr\tr3,REG_GObj\n\tbl\tDebugLogThink\n\tmflr r4\n\tli\tr5,0\n\tbranchl r12,GObj_AddProc\n#Store pointer to dev text\n  stw REG_DevelopText,0x0(REG_GObjData)\n  b Exit\n\n########################################\nDebugLogThink:\nblrl\n.set  REG_GObjData,31\nbackup\n\nlwz REG_GObjData,0x2C(r3)\n\n#/*\n#Erase all text\n  lwz  r3,0x0(REG_GObjData)\n  branchl r12,DevelopText_EraseAllText\n  lwz  r3,0x0(REG_GObjData)\n  li  r4,0\n  li  r5,0\n  branchl r12,DevelopMode_Text_ResetCursorXY\n#*/\n\n#Check heap\n  lwz\tr3, -0x58A0 (r13)\n  branchl r12,0x80344168\n  mr  r5,r3\n#Display\n  lwz  r3,0x0(REG_GObjData)\n  bl  String\n  mflr  r4\n  branchl r12,0x80302d4c#DevelopText_AddString\n\nDebugLogThink_Exit:\nrestore\nblr\n\n#########################################\nString:\nblrl\n.string \"%d\\n bytes free\" #08X\\n\n.align 2\n\nExit:\nrestore\nli\tr0, 0\n\n/*\nload  r4,0xCC002002\nlhz r3,0x0(r4)\nori r3,r3,0x4\nsth r3,0x0(r4)\n\nli\tr3, 1\n*/\n"
  },
  {
    "path": "ASM/Additional Codes/DPad Down to Random Stage.s",
    "content": "#To be inserted at 8026325c\n.include \"../Globals.s\"\n\n#Get Random Stage Byte\nload r4,0x8045BF17\n\n#Check for DPad Down\n  rlwinm.\tr0, r7, 0, 29, 29\n  beq CheckForStart\n  li r3,0x1\n  stb r3,0x0(r4)\n  branch r12,0x80263264\n\nCheckForStart:\n#Check for Start\n  rlwinm.\tr0, r7, 0, 19, 19\n  beq Exit\n  li r3,0x0\n  stb r3,0x0(r4)\n\n#Original Codeline\nExit:\n  rlwinm.\tr0, r7, 0, 19, 19\n"
  },
  {
    "path": "ASM/Additional Codes/Debug Mode Codes/Debug Language is English by Default.asm",
    "content": "#To be inserted at 803fa258\n.long 0x00000001"
  },
  {
    "path": "ASM/Additional Codes/Debug Mode Codes/Exiting Debug Goes to Main Menu.asm",
    "content": "#To be inserted at 801B0A14\nli\tr3, 1\n"
  },
  {
    "path": "ASM/Additional Codes/Debug Mode Codes/Tournament Mode Goes to Debug.asm",
    "content": "#To be inserted at 8022D638\nli\tr0, 6"
  },
  {
    "path": "ASM/Additional Codes/Default Tournament Settings/4 Stocks.asm",
    "content": "#To be inserted at 803D4A4C\n.long 0x04000A00"
  },
  {
    "path": "ASM/Additional Codes/Default Tournament Settings/8 Minutes.asm",
    "content": "#To be inserted at 803D4A50\n.long 0x08010100"
  },
  {
    "path": "ASM/Additional Codes/Default Tournament Settings/No Items.asm",
    "content": "#To be inserted at 803D4A60\n.long 0xFF000000"
  },
  {
    "path": "ASM/Additional Codes/Default Tournament Settings/Stock Mode.asm",
    "content": "#To be inserted at 803D4A48\n.long 0x00340000\n"
  },
  {
    "path": "ASM/Additional Codes/Default Tournament Settings/Tournament Stages.asm",
    "content": "#To be inserted at 803D4A78\n.long 0xE70000B0"
  },
  {
    "path": "ASM/Additional Codes/Delete Bootup OSReports.asm",
    "content": "#To be inserted at 80160154\n.include \"../Globals.s\"\n\n# Remove all previous OSReports\n  load r3,0x804cf7e8\n  li  r4,0\n  stw r4,0xC(r3)\n\nli\tr0, 0"
  },
  {
    "path": "ASM/Additional Codes/Disable CSS Anim Loop.s",
    "content": "#To be inserted at 80263384\n\nb 0x10"
  },
  {
    "path": "ASM/Additional Codes/Disable FoD Reflection.asm",
    "content": "#To be inserted at 8008114c\n.include \"../Globals.s\"\n\n.set REG_ReflectCallback,31\n\n#Save reflection callback\n  mr  r3,r0\n  backup\n  mr  REG_ReflectCallback,r3\n#Count player gobjs\n  branchl r12,0x800860c4 #CountPlayers\n\n#Check if 4 or more\n  cmpwi r3,4\n  blt ShowReflect\n#Dont draw reflection\n  li  r3,0\n  b Exit\n\nShowReflect:\n  mr  r3,REG_ReflectCallback\n  b Exit\n\nExit:\n  restore\n  mr  r0,r3\n  lwz r4,GObj_Lists(r13)\n  lwz\tr3, 0x0020 (r4)\n"
  },
  {
    "path": "ASM/Additional Codes/Disable FoD in Doubles.asm",
    "content": "#To be inserted at 80266ce0\n.include \"../Globals.s\"\n\n#######################################\n## Runs During CSS -> SSS Transition ##\n#######################################\n\n.set REG_RandomStageField,5\n.set REG_RulesPointer,6\n\n#Ensure only all other legal stages are enabled\n#Get Random Stage Select Bitflags\n  lwz\tREG_RulesPointer, -0x77C0 (r13)\n  addi\tREG_RulesPointer, REG_RulesPointer, 7344\n  lwz\tREG_RandomStageField,0x18(REG_RulesPointer)\n#Check if only all legal stages are on\n  load r3,0xE70000B0\n  xor. r3,r3,REG_RandomStageField\n  beq CheckForTeams\n#Check if the only other stage off is FoD\n  cmpwi r3,0x20\n  beq CheckForTeams\n  b Exit\n\nCheckForTeams:\n#Get Teams On/Off Bool\n  lwz\tr3, -0x49F0 (r13)\n  lbz\tr3,0x18(r3)\n#Check If Teams is On or Off\n  cmpwi\tr3,0x1\n  beq\tDoubles\n\nSingles:\n#Flip FoD Bit On in Random Stage Bitflag (FoD is bit #26)\n  li\tr3,0x1\n  rlwimi\tREG_RandomStageField,r3,5,26,26\n  stw\tREG_RandomStageField,0x18(REG_RulesPointer)\n  b\tExit\n\nDoubles:\n#Flip FoD Bit Off in Random Stage Bitflag (FoD is bit #26)\n  li\tr3,0x0\n  rlwimi\tREG_RandomStageField,r3,5,26,26\n  stw\tREG_RandomStageField,0x18(REG_RulesPointer)\n  b\tExit\n\nExit:\nli\tr3, 1\n"
  },
  {
    "path": "ASM/Additional Codes/Disable Item Spawn in Develop Mode.asm",
    "content": "#To be inserted at 80226530\n.include \"../Globals.s\"\n\n  nop\n"
  },
  {
    "path": "ASM/Additional Codes/Disable Item Spawn in Develop Mode.s",
    "content": "#To be inserted at 80226530\n.include \"../Globals.s\"\n\n  nop\n"
  },
  {
    "path": "ASM/Additional Codes/Disable Rumble on Unplug.asm",
    "content": "#To be inserted at 803775a4\n.include \"../Globals.s\"\n\n#Check if unplugged\n  lbz\tr3, 0x000A (r25)  #current read\n  extsb  r3,r3\n  cmpwi r3,-1\n  bne Original\n  lbz r3, 0x0041 (r26)  #prev read\n  extsb.  r3,r3\n  bne Original\n#Disable rumble\n  mr  r3,r24\n  li  r4,0\n  branchl r12,Rumble_StoreRumbleFlag\n\nOriginal:\n  lbz\tr0, 0x000A (r25)\n"
  },
  {
    "path": "ASM/Additional Codes/Disable Special Records/Disable Special Messages.asm",
    "content": "#To be inserted at 80173eec\nblr\n"
  },
  {
    "path": "ASM/Additional Codes/Disable Special Records/Disable Trophy Messages.asm",
    "content": "#To be inserted at 80172898\nblr\n"
  },
  {
    "path": "ASM/Additional Codes/Display Animation Name for Special Moves in Develop Mode/Display Animation Name for Special Moves in Develop Mode.asm",
    "content": "#To be inserted at 80226acc\n.include \"../../Globals.s\"\n\n.set entity,31\n.set playerdata,28\n.set player,29\n\n#Get Animation Data Pointer\nmr\tr3,playerdata\nlwz\tr4,0x14(playerdata)\nbranchl\tr12,0x80085fd4\n\n#Get Move Name String\nlwz\tr3,0x0(r3)\n\n#Get Start of Move Name\nStringSearchLoop:\nlbzu\tr4,0x1(r3)\ncmpwi\tr4,0x4E\t\t#Check For \"N\"\nbne\tStringSearchLoop\nlbzu\tr4,0x1(r3)\ncmpwi\tr4,0x5F\t\t#Check for Underscore\nbne\tStringSearchLoop\naddi\tr3,r3,0x1\t\t#Start of Move Name in r3\n\n#Copy Move Name To Cut Off \"fiagtree\" Text\nbl\tStringSpace\nmflr\tr5\nsubi\tr4,r5,0x1\nsubi\tr3,r3,0x1\nStringCopyLoop:\nlbzu\tr6,0x1(r3)\ncmpwi\tr6,0x5F\t\t#Check for Underscore\nbeq\tExitCopyLoop\nstbu\tr6,0x1(r4)\nb\tStringCopyLoop\n\nExitCopyLoop:\nli\tr3,0x0\nstbu\tr3,0x1(r4)\nmr\tr4,r5\nb\texit\n\nStringSpace:\nblrl\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n\nexit:\nmr\tr3,r31\ncrclr \t6\n"
  },
  {
    "path": "ASM/Additional Codes/Display Ungrabbable Hurtboxes/Main.asm",
    "content": "#To be inserted at 8000a284\n.include \"../../Globals.s\"\n\n#Check if vuln\n  cmpwi r6,0\n  bne Exit\n#Check if this is an ungrabbable hurtbox\n  lwz r0,0x48(r28)\n  cmpwi r0,0\n  bne Exit\n#Override color\n  bl  Color\n  mflr  r3\n  b Skip\n\nColor:\nblrl\n.long 0xAB27FF80\n\nExit:\n  lwz\tr3, 0 (r3)\nSkip:\n"
  },
  {
    "path": "ASM/Additional Codes/Enable 1P in VS Mode No Time.asm",
    "content": "#To be inserted at 80263064\n.include \"../Globals.s\"\n\n.set  REG_ReadyPlayers,31\n\nbackup\n\n#Backup players\n  mr  REG_ReadyPlayers,r4\n#Check if mode is set to time\n  branchl r12,LoadRulesSettingsPointer1\n  lbz r4,0x2(r3)\n  cmpwi r4,0\n  bne Check2Players\n#Check if time is set to none\n  lbz r4,0x3(r3)\n  cmpwi r4,0\n  bne Check2Players\nCheck1Player:\n#Check for 1 players\n  cmpwi REG_ReadyPlayers,1\n  b Exit\nCheck2Players:\n#Check for 2 players\n  cmpwi REG_ReadyPlayers,2\n\nExit:\n  restore\n"
  },
  {
    "path": "ASM/Additional Codes/Enable C Stick Always/Enable CStick for CPU in Debug.asm",
    "content": "#To be inserted at 8006ae00\nnop"
  },
  {
    "path": "ASM/Additional Codes/Enable C Stick Always/Rotate Camera with Dpad Down and C Stick - Initiate.asm",
    "content": "#To be inserted at 802274f0\n.include \"../../Globals.s\"\n\n#Get Inputs\n  load  r4,0x804c1fac\n  mulli r3,r30,68\n  add r3,r3,r4\n\n#Check for dpad down\n  lwz r3,0x0(r3)\n  rlwinm. r3,r3,0,29,29\n  bne Original\n\n#Exit\n  branch r12,0x802275f4\n\nOriginal:\n  lfs\tf0, -0x3CA4 (rtoc)\n"
  },
  {
    "path": "ASM/Additional Codes/Enable C Stick Always/Rotate Camera with Dpad Down and C Stick.asm",
    "content": "#To be inserted at 80227b70\n.include \"../../Globals.s\"\n\n#Get Inputs\n  load  r4,0x804c1fac\n  add r4,r4,r5\n\n#Check for dpad down\n  lwz r4,0x0(r4)\n  rlwinm. r4,r4,0,29,29\n  bne Original\n\n#Exit\n  branch r12,0x80227b98\n\nOriginal:\n  lfs\tf0, -0x3CA4 (rtoc)\n"
  },
  {
    "path": "ASM/Additional Codes/Enable C Stick Always/Single Player Always Returns False.asm",
    "content": "#To be inserted at 8016B480\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/Enable C Stick Always/Spoof Debug Level as 0 for Human C Stick Inputs.asm",
    "content": "#To be inserted at 8006AE90\nli\tr0, 0"
  },
  {
    "path": "ASM/Additional Codes/Faster CSS Load.asm",
    "content": "#To be inserted at 802641B0\nli\tr0, 1"
  },
  {
    "path": "ASM/Additional Codes/Frame Advance Audio.s",
    "content": "#To be inserted at 80359750\n.include \"../Globals.s\"\n\n  load r5,0x80479d48\n\n# If game unpaused, play sound\n  lbz r3,0x20(r5)\n  rlwinm. r0,r3,0,0x1\n  beq Original\n\n# Game is paused, check if advancing this frame\n  lbz r3,0x22(r5)\n  rlwinm. r0,r3,0,0x1\n  bne Original\n\n# Skip audio update\n  branch r12,0x80359830\n\nOriginal:\n  mr\tr3, r30"
  },
  {
    "path": "ASM/Additional Codes/GX Draw/Main.s",
    "content": "#To be inserted at 80080e40\n.include \"../../Globals.s\"\n\n.set  REG_PlayerData,30\n.set  REG_Interrupt,28\n\nbackup\n\n#check for renderpass 2\n  cmpwi r29,2\n  bne Exit\n\n  bl  FirefoxTrajectory\n  bl  DIDraw\n  b Exit\n\n#region Firefox Trajectory\nFirefoxTrajectory_Constants:\nblrl\n\n.set\tECB_TopY,0x0 #scale * value\n.set\tECB_BottomY,0x4 #neg(scale * vlaue)\n.set\tECB_LeftX,0x8 #neg(scale * vlaue)\n.set\tECB_LeftY,0xC #0\n.set\tECB_RightX,0x10 #scale * value\n.set\tECB_RightY,0x14 #0\n.set\tFinalAnimYDifference,0x18\n.set  Float2,0x1C\n.set  FirefoxDrawZ,0x20\n.set  LineColor,0x24\n.set  LeftWallColor,0x28\n.set  RightWallColor,0x2C\n.set  CeilingColor,0x30\n.set  GroundColor,0x34\n.float 9\n.float 2.5\n.float -3.3\n.float 5.7\n.float 3.3\n.float 5.7\n.float 0.4\n.float 2\n.float 10\n.byte 0, 138, 255, 255\n.byte 12, 255, 41, 255\n.byte 12, 255, 41, 255\n.byte 255, 55, 55, 255\n.byte 255, 255, 255, 255\n\n.set StackSize,0x300\n.set Stack_BackedUpReg,0x8\n  .set Stack_BackedUpReg_Length,0x30\n.set Stack_BackedUpFloats, (Stack_BackedUpReg+Stack_BackedUpReg_Length)\n  .set Stack_BackedUpFloats_Length,0x14\n.set Stack_ECBBoneStruct, (Stack_BackedUpFloats+Stack_BackedUpFloats_Length)\n  .set Stack_ECBBoneStruct_Length,0x18\n.set Stack_ECBStruct, (Stack_ECBBoneStruct+Stack_ECBBoneStruct_Length)\n  .set Stack_ECBStruct_Length,0x1AC\n.set Stack_MiscSpace, (Stack_ECBStruct+Stack_ECBStruct_Length)\n\n#gprs\n.set REG_EventConstants,31\n.set REG_ECBStruct,20\n.set REG_ECBBoneStruct,21\n.set REG_LoopCount,22\n.set REG_GX,23\n.set REG_CObjBackup,24\n\n#fprs\n.set REG_arctan,31\n.set REG_XComp,30\n.set REG_YComp,31\n.set REG_XPerFrame,29\n.set REG_YPerFrame,28\n.set REG_CurrXPos,27\n.set REG_CurrYPos,26\n\n#constants\n.set RandomAngleRange,20\n\nFirefoxTrajectory:\n  mflr r0\n  stw r0, 0x4(r1)\n  stwu\tr1,-StackSize(r1)\t# make space for 12 registers\n  stmw  r20,Stack_BackedUpReg(r1)\n\n#Check for firefox trajectory\n  lwz r3,0x4(REG_PlayerData)\n  cmpwi r3,Fox.Int\n  beq FirefoxTrajectory_isSpacie\n  cmpwi r3,Falco.Int\n  beq FirefoxTrajectory_isSpacie\n  b FirefoxTrajectory_Exit\n\nFirefoxTrajectory_isSpacie:\n#Check if in up b hold\n  lwz r3,0x10(REG_PlayerData)\n  cmpwi r3,353\n  beq FirefoxTrajectory_isFirefoxHold\n  cmpwi r3,354\n  beq FirefoxTrajectory_isFirefoxHold\n  b FirefoxTrajectory_Exit\nFirefoxTrajectory_isFirefoxHold:\n\n#Get Floats\n  bl  FirefoxTrajectory_Constants\n  mflr  REG_EventConstants\n\n#If frame advance && HMN, use HW inputs\n  li  r3,0\n  branchl r12,0x801a45e8\n  cmpwi r3,1\n  bne FirefoxTrajectory_PBInputs\n  lbz r3,0xC(REG_PlayerData)\n  branchl r12,0x8003241c\n  cmpwi r3,0x0\n  bne FirefoxTrajectory_PBInputs\nFirefoxTrajectory_HWInputs:\n  load  r3,HSD_InputStructStart\n  lbz r4,0x618(REG_PlayerData)\n  mulli r4,r4,68\n  add r3,r3,r4\n\tlfs\tREG_XComp,InputStruct_LeftAnalogXFloat(r3)\n\tlfs\tREG_YComp,InputStruct_LeftAnalogYFloat(r3)\n#If Holding A, override and use PB Inputs\n  lwz r0,InputStruct_HeldButtons(r3)\n  rlwinm. r0,r0,0,0x100\n  bne FirefoxTrajectory_PBInputs\n#Now apply deadzone\n  lfs\tf0, -0x778C (rtoc)\n  lwz\tr3, -0x514C (r13)\n  lfs\tf1, 0 (r3)\n  fmr f2,REG_XComp\n  fcmpo cr0,f2,f0\n  bge 0x8\n  fneg  f2,f2\n  fcmpo cr0,f2,f1\n  bge 0x8\n  lfs\tREG_XComp, -0x778C (rtoc)\n  fmr f2,REG_YComp\n  fcmpo cr0,f2,f0\n  bge 0x8\n  fneg  f2,f2\n  fcmpo cr0,f2,f1\n  bge 0x8\n  lfs\tREG_YComp, -0x778C (rtoc)\n  b FirefoxTrajectory_GetInputsEnd\nFirefoxTrajectory_PBInputs:\n\tlfs\tREG_XComp,0x620(REG_PlayerData)\n\tlfs\tREG_YComp,0x624(REG_PlayerData)\nFirefoxTrajectory_GetInputsEnd:\n#Get atan2\n\tfmr\tf1,REG_YComp\n\tlfs\tf2,0x2C(REG_PlayerData)\n\tfmuls\tf2,f2,REG_XComp\n\tbranchl\tr12,0x80022c30\n\tfmr\tREG_arctan,f1\n#Get XComp\n\tfmr\tf1,REG_arctan\n\tbranchl\tr12,0x80326240\n\tfmr\tREG_XComp,f1\n\tfmr\tf1,REG_arctan\n\tbranchl\tr12,0x803263d4\n\tfmr\tREG_YComp,f1\n#Get Firefox distance per frame\n\tlwz\tr3, 0x02D4 (REG_PlayerData)\n\tlfs\tf1, 0x0074 (r3)\n\tlfs\tf0, 0x002C (REG_PlayerData)\n\tfmuls\tf1,f1,REG_XComp\n\tfmuls\tREG_XPerFrame,f1,f0\n\tlfs\tf1, 0x0074 (r3)\n\tfmuls\tREG_YPerFrame,f1,REG_YComp\n#Create an ECB struct on the stack\n\taddi\tREG_ECBBoneStruct,sp,Stack_ECBBoneStruct\n\taddi\tREG_ECBStruct,sp,Stack_ECBStruct\n\tmr\tr3,REG_ECBStruct\n\tbranchl\tr12,0x80041ee4\n#Create ECB Bone struct\n/*\n0x00 = ECB Current Top Y Offset scale * value\n0x04 = ECB Current Bottom Y Offset neg(scale * vlaue)\n0x08 = ECB Current Left X Offset neg(scale * vlaue)\n0x0C = ECB Current Left Y Offset 0\n0x10 = ECB Current Right X Offset scale * value\n0x14 = ECB Current Right Y Offset 0\n*/\n#Copy Struct\n\tmr\tr3,REG_ECBBoneStruct\n\taddi\tr4,REG_EventConstants,ECB_TopY\n\tli\tr5,0x18\n\tbranchl\tr12,memcpy\n#Place Current XY into struct\n\tlfs\tREG_CurrXPos,0xB0(REG_PlayerData)\n\tlfs\tREG_CurrYPos,0xB4(REG_PlayerData)\n#Subtract 0.4 to account for the frame of animation left in this state\n\tlfs\tf1,FinalAnimYDifference(REG_EventConstants)\n\tfsubs\tREG_CurrYPos,REG_CurrYPos,f1\n\tlfs\tf1,0xB8(REG_PlayerData)\n\tstfs\tf1,0x24(REG_ECBStruct)\n#Init Loop\n\tli\tREG_LoopCount,0\n#Init GX Prim\n  lwz\tr5, 0x02D4 (REG_PlayerData)\n  lfs\tf1, 0x0068 (r5)\n  fctiwz  f1,f1\n  stfd  f1,Stack_MiscSpace(sp)\n  lwz r3,Stack_MiscSpace+4(sp)\n  load  r4,0x001F1305\n  load  r5,0x00001455\n  branchl r12,prim.new\n  mr  REG_GX,r3\nFirefoxTrajectory_CollisionLoop:\n#Store current position\n\tstfs\tREG_CurrXPos,0x4(REG_ECBStruct)\n\tstfs\tREG_CurrYPos,0x8(REG_ECBStruct)\n  lfs\tf1, -0x778C (rtoc)\n  stfs\tf1,0xC(REG_ECBStruct)\n#Check if frame X or greater\n  lwz\tr5, 0x02D4 (REG_PlayerData)\n  lfs f1,0x70(r5)\n  fctiwz  f1,f1\n  stfd  f1,Stack_MiscSpace(sp)\n  lwz r3,Stack_MiscSpace+4(sp)\n\tcmpw\tREG_LoopCount,r3\n\tblt\tFirefoxTrajectory_CollisionLoop_SkipDecay\nFirefoxTrajectory_CollisionLoop_Decay:\n\tlfs\tf1,0x78(r5)\n\tfmuls\tf1,f1,REG_XComp\n\tlfs\tf2, 0x002C (REG_PlayerData)\n\tfmuls\tf1,f1,f2\n\tfsubs\tREG_XPerFrame,REG_XPerFrame,f1\n\tlfs\tf1,0x78(r5)\n\tfmuls\tf1,f1,REG_YComp\n\tfsubs\tREG_YPerFrame,REG_YPerFrame,f1\nFirefoxTrajectory_CollisionLoop_SkipDecay:\n#Shift previous positions down\n  lfs f1,0x4(REG_ECBStruct)\n  lfs f2,0x8(REG_ECBStruct)\n  lfs f3,0xC(REG_ECBStruct)\n  stfs f1,0x1C(REG_ECBStruct)\n  stfs f2,0x20(REG_ECBStruct)\n  stfs f3,0x24(REG_ECBStruct)\n#Store next position\n\tfadds\tf1,REG_CurrXPos,REG_XPerFrame\n\tstfs\tf1,0x4(REG_ECBStruct)\n\tfadds\tf1,REG_CurrYPos,REG_YPerFrame\n\tstfs\tf1,0x8(REG_ECBStruct)\n\tlfs\tf1, -0x778C (rtoc)\n\tstfs\tf1,0xC(REG_ECBStruct)\n#Run collision\n\tmr\tr3,REG_ECBStruct\n\tmr\tr4,REG_ECBBoneStruct\n\tbranchl\tr12,0x800475f4#0x800473cc\n#Drop through platforms\n  cmpwi r3,0\n  beq FirefoxTrajectory_CollisionLoop_SkipPlatform\n  mr  r3,REG_ECBStruct\n  branchl r12,0x8004cbc0\n  cmpwi r3,0\n  beq FirefoxTrajectory_CollisionLoop_SkipPlatform\n  lwz\tr0, 0x014C (REG_ECBStruct)\n  stw\tr0, 0x003C (REG_ECBStruct)\nFirefoxTrajectory_CollisionLoop_SkipPlatform:\n#Get new position\n\tlfs\tREG_CurrXPos,0x4(REG_ECBStruct)\n\tlfs\tREG_CurrYPos,0x8(REG_ECBStruct)\n#Inc Collision ID\n  lwz r3,0x38(REG_ECBStruct)\n  addi  r3,r3,1\n  stw r3,0x38(REG_ECBStruct)\n#Determine line color\n  lwz r3,0x134(REG_ECBStruct)\n  rlwinm. r0,r3,0,0x8000\n  bne FirefoxTrajectory_CollisionLoop_TouchingGround\n  rlwinm. r0,r3,0,0x6000\n  bne FirefoxTrajectory_CollisionLoop_TouchingCeiling\n  rlwinm. r0,r3,0,0x20\n  bne FirefoxTrajectory_CollisionLoop_TouchingLeftWall\n  rlwinm. r0,r3,0,0x40\n  bne FirefoxTrajectory_CollisionLoop_TouchingLRightWall\nFirefoxTrajectory_CollisionLoop_TouchingNothing:\n  lwz r4,LineColor(REG_EventConstants)\n  b FirefoxTrajectory_CollisionLoop_GetColorEnd\nFirefoxTrajectory_CollisionLoop_TouchingGround:\n  lwz r4,GroundColor(REG_EventConstants)\n  b FirefoxTrajectory_CollisionLoop_GetColorEnd\nFirefoxTrajectory_CollisionLoop_TouchingCeiling:\n  lwz r4,CeilingColor(REG_EventConstants)\n  b FirefoxTrajectory_CollisionLoop_GetColorEnd\nFirefoxTrajectory_CollisionLoop_TouchingLeftWall:\n  lwz r4,LeftWallColor(REG_EventConstants)\n  b FirefoxTrajectory_CollisionLoop_GetColorEnd\nFirefoxTrajectory_CollisionLoop_TouchingLRightWall:\n  lwz r4,RightWallColor(REG_EventConstants)\n  b FirefoxTrajectory_CollisionLoop_GetColorEnd\nFirefoxTrajectory_CollisionLoop_GetColorEnd:\n#Draw this point\n  lfs f1,0x84(REG_ECBStruct)\n  fadds f1,REG_CurrXPos,f1\n  lfs f2,0x88(REG_ECBStruct)\n  lfs f3,Float2(REG_EventConstants)\n  fdivs f2,f2,f3\n  fadds f2,REG_CurrYPos,f2\n  lfs f3,FirefoxDrawZ(REG_EventConstants)\n  mr  r3,REG_GX\n  stfs  f1,0x0(r3)\n  stfs  f2,0x0(r3)\n  stfs  f3,0x0(r3)\n  stw   r4,0x0(r3)\n#Inc Loop\n\taddi\tREG_LoopCount,REG_LoopCount,1\n  lwz\tr5, 0x02D4 (REG_PlayerData)\n  lfs\tf1, 0x0068 (r5)\n  fctiwz  f1,f1\n  stfd  f1,Stack_MiscSpace(sp)\n  lwz r3,Stack_MiscSpace+4(sp)\n\tcmpw\tREG_LoopCount,r3\n\tblt\tFirefoxTrajectory_CollisionLoop\n#End Loop\n  branchl r12,prim.close\n\nFirefoxTrajectory_Exit:\n  lmw  r20,Stack_BackedUpReg(r1)\n  lwz r0, StackSize+4(r1)\n  addi\tr1,r1,StackSize\t# release the space\n  mtlr r0\n  blr\n\n####################################################\n#endregion\n\n#region DI Draw\nDIDraw_Constants:\nblrl\n\n.set\tECB_TopY,0x0 #scale * value\n.set\tECB_BottomY,0x4 #neg(scale * vlaue)\n.set\tECB_LeftX,0x8 #neg(scale * vlaue)\n.set\tECB_LeftY,0xC #0\n.set\tECB_RightX,0x10 #scale * value\n.set\tECB_RightY,0x14 #0\n.set  FirefoxDrawZ,0x18\n.set  AliveLineColor,0x1C\n.set  DeadLineColor,0x20\n.set  LeftWallColor,0x24\n.set  RightWallColor,0x28\n.set  CeilingColor,0x2C\n.set  GroundColor,0x30\n.set  ASDIColor,0x34\n.float 9\n.float 2.5\n.float -3.3\n.float 5.7\n.float 3.3\n.float 5.7\n.float 10\n.byte 0, 138, 255, 255\n.byte 255, 55, 55, 255\n.byte 12, 255, 41, 255\n.byte 12, 255, 41, 255\n.byte 255, 0, 255, 255\n.byte 255, 255, 255, 255\n.byte 255, 86, 20, 255\n\n.set StackSize,0x300\n.set Stack_BackedUpReg,0x8\n  .set Stack_BackedUpReg_Length,0x30\n.set Stack_BackedUpFloats, (Stack_BackedUpReg+Stack_BackedUpReg_Length)\n  .set Stack_BackedUpFloats_Length,0x14\n.set Stack_ECBBoneStruct, (Stack_BackedUpFloats+Stack_BackedUpFloats_Length)\n  .set Stack_ECBBoneStruct_Length,0x18\n.set Stack_ECBStruct, (Stack_ECBBoneStruct+Stack_ECBBoneStruct_Length)\n  .set Stack_ECBStruct_Length,0x1AC\n.set Stack_ASDIBackup, (Stack_ECBStruct+Stack_ECBStruct_Length)\n  .set  Stack_ASDIBackup_Length,0x8\n.set Stack_MiscSpace, (Stack_ASDIBackup+Stack_ASDIBackup_Length)\n\n#gprs\n.set REG_EventConstants,31\n.set REG_ECBStruct,20\n.set REG_ECBBoneStruct,21\n.set REG_LoopCount,22\n.set REG_GX,23\n.set REG_HeldInputs,24\n.set REG_GroundState,24\n.set REG_CollisionInfo,25\n.set REG_Temp,26            #this register is used for the draw loop, make sure to change both\n.set REG_OverrideRemainingFrames,27\n\n#fprs\n.set REG_arctan,31\n.set REG_XComp,30\n.set REG_YComp,29\n.set REG_KnockbackX,28\n.set REG_KnockbackY,27\n.set REG_CurrXPos,26\n.set REG_CurrYPos,25\n.set REG_DIInput,24\n.set REG_KnockbackMag,23\n.set REG_CStickX,22\n.set REG_CStickY,21\n.set REG_ASDIX,22\n.set REG_ASDIY,21\n.set REG_Gravity,30\n\n#constants\n.set MaxColl,40\n\nDIDraw:\n  mflr r0\n  stw r0, 0x4(r1)\n  stwu\tr1,-StackSize(r1)\t# make space for 12 registers\n  stmw  r20,Stack_BackedUpReg(r1)\n\n#Check for DI Draw\n\tlbz\tr3,0x221A(REG_PlayerData)\t\t\t#Check If in Hitlag\n\trlwinm.\tr3,r3,0,0x20\n  beq DIDraw_Exit\n\tlbz\tr3, 0x221C (REG_PlayerData)\n\trlwinm.\tr0,r3,0,0x2\n  beq DIDraw_Exit\n\n#Get Floats\n  bl  DIDraw_Constants\n  mflr  REG_EventConstants\n\n#region GetInputs\n#If frame advance && HMN, use HW inputs\n  li  r3,0\n  branchl r12,0x801a45e8\n  cmpwi r3,1\n  bne DIDraw_PBInputs\n  lbz r3,0xC(REG_PlayerData)\n  branchl r12,0x8003241c\n  cmpwi r3,0x0\n  bne DIDraw_PBInputs\nDIDraw_HWInputs:\n  load  r3,HSD_InputStructStart\n  lbz r4,0x618(REG_PlayerData)\n  mulli r4,r4,68\n  add r3,r3,r4\n#If Holding A, override and use PB Inputs\n  lwz r0,InputStruct_HeldButtons(r3)\n  rlwinm. r0,r0,0,0x100\n  bne DIDraw_PBInputs\n\tlfs\tREG_XComp,InputStruct_LeftAnalogXFloat(r3)\n\tlfs\tREG_YComp,InputStruct_LeftAnalogYFloat(r3)\n  lfs\tREG_CStickX,InputStruct_RightAnalogXFloat(r3)\n  lfs\tREG_CStickY,InputStruct_RightAnalogYFloat(r3)\n#Get L/R input\n  lwz REG_HeldInputs,InputStruct_HeldButtons(r3)\n  rlwinm. r0,REG_HeldInputs,0,0x20\n  bne DIDraw_HWInputs_PressingLR\n  rlwinm. r0,REG_HeldInputs,0,0x40\n  bne DIDraw_HWInputs_PressingLR\nDIDraw_HWInputs_NoLR:\n  li  REG_HeldInputs,0\n  b 0x8\nDIDraw_HWInputs_PressingLR:\n  lis REG_HeldInputs,0x8000\n#Now apply analog deadzone\n  lfs\tf0, -0x778C (rtoc)\n  lwz\tr3, -0x514C (r13)\n  lfs\tf1, 0 (r3)\n  fmr f2,REG_XComp\n  fcmpo cr0,f2,f0\n  bge 0x8\n  fneg  f2,f2\n  fcmpo cr0,f2,f1\n  bge 0x8\n  lfs\tREG_XComp, -0x778C (rtoc)\n  fmr f2,REG_YComp\n  fcmpo cr0,f2,f0\n  bge 0x8\n  fneg  f2,f2\n  fcmpo cr0,f2,f1\n  bge 0x8\n  lfs\tREG_YComp, -0x778C (rtoc)\n#Now apply cstick deadzone\n  lfs\tf0, -0x778C (rtoc)\n  lwz\tr3, -0x514C (r13)\n  lfs\tf1, 0 (r3)\n  fmr f2,REG_CStickX\n  fcmpo cr0,f2,f0\n  bge 0x8\n  fneg  f2,f2\n  fcmpo cr0,f2,f1\n  bge 0x8\n  lfs\tREG_CStickX, -0x778C (rtoc)\n  fmr f2,REG_CStickY\n  fcmpo cr0,f2,f0\n  bge 0x8\n  fneg  f2,f2\n  fcmpo cr0,f2,f1\n  bge 0x8\n  lfs\tREG_CStickY, -0x778C (rtoc)\n  b DIDraw_GetInputsEnd\nDIDraw_PBInputs:\n\tlfs\tREG_XComp,0x620(REG_PlayerData)\n\tlfs\tREG_YComp,0x624(REG_PlayerData)\n  lwz REG_HeldInputs,0x65C(REG_PlayerData)\n\tlfs\tREG_CStickX,0x638(REG_PlayerData)\n\tlfs\tREG_CStickY,0x63C(REG_PlayerData)\nDIDraw_GetInputsEnd:\n#endregion\n\n#Get original KB vector\n  lfs REG_KnockbackX,0x8C(REG_PlayerData)\n  lfs REG_KnockbackY,0x90(REG_PlayerData)\n\n#Calculate player's influence over trajectory\n#region GetArctan\nDIDraw_GetArctan:\n#Get atan2\n\tfmr\tf1,REG_KnockbackY\n\tfmr\tf2,REG_KnockbackX\n\tbranchl\tr12,0x80022c30\n\tfmr\tREG_arctan,f1\n#Do something\n  fmuls f1,REG_KnockbackY,REG_KnockbackY\n  fmadds  REG_KnockbackMag,REG_KnockbackX,REG_KnockbackX,f1\n  lfs\tf0, -0x750C (rtoc)\n  fcmpo cr0,REG_KnockbackMag,f0\n  ble DIDraw_SkipUnk\n#Do a bunch of stuff\n  frsqrte\tf2,REG_KnockbackMag\n  lfd\tf4, -0x74E0 (rtoc)\n  lfd\tf3, -0x74D8 (rtoc)\n  fmul\tf0,f2,f2\n  fmul\tf2,f4,f2\n  fnmsub\tf0,REG_KnockbackMag,f0,f3\n  fmul\tf2,f2,f0\n  fmul\tf0,f2,f2\n  fmul\tf2,f4,f2\n  fnmsub\tf0,REG_KnockbackMag,f0,f3\n  fmul\tf2,f2,f0\n  fmul\tf0,f2,f2\n  fmul\tf2,f4,f2\n  fnmsub\tf0,REG_KnockbackMag,f0,f3\n  fmul\tf0,f2,f0\n  fmul\tf0,REG_KnockbackMag,f0\n  frsp\tf0,f0\n  fmr REG_KnockbackMag,f0\nDIDraw_SkipUnk:\n#endregion\n#region CalculateASDI\nDIDraw_CalculateASDI:\n#CStick has priority\n#Check if cstick magnitude > 0.7\n  fmuls f1,REG_CStickX,REG_CStickX\n  fmuls f0,REG_CStickY,REG_CStickY\n  lwz\tr3, -0x514C (r13)\n  lfs\tf2, 0x04B0 (r3)\n  fadds\tf1,f1,f0\n  fmuls\tf0,f2,f2\n  fcmpo\tcr0,f1,f0\n  bge DIDraw_CalculateASDICStickApply\n#Now check left stick\n  fmuls f1,REG_YComp,REG_YComp\n  fmuls f2,REG_XComp,REG_XComp\n  lwz\tr3, -0x514C (r13)\n  lfs\tf0, 0x04B0 (r3)\n  fmuls f0,f0,f0\n  fadds f1,f1,f2\n  fcmpo cr0,f1,f0\n  blt  DIDraw_CalculateASDINone\nDIDraw_CalculateASDILeftStickApply:\n#Multiply by 3\n  lfs\tf1, 0x04BC (r3)\n  fmuls REG_ASDIX,REG_XComp,f1\n  fmuls REG_ASDIY,REG_YComp,f1\n  b DIDraw_CalculateASDIEnd\nDIDraw_CalculateASDINone:\n#Null ASDI\n  lfs\tREG_ASDIX, -0x750C (rtoc)\n  lfs\tREG_ASDIY, -0x750C (rtoc)\n  b DIDraw_CalculateASDIEnd\nDIDraw_CalculateASDICStickApply:\n#Multiply by 3\n  lfs\tf1, 0x04BC (r3)\n  fmuls REG_ASDIX,REG_CStickX,f1\n  fmuls REG_ASDIY,REG_CStickY,f1\nDIDraw_CalculateASDIEnd:\n#Save these values for later\n  stfs  REG_ASDIX,Stack_ASDIBackup+0(sp)\n  stfs  REG_ASDIY,Stack_ASDIBackup+4(sp)\n#endregion\n#region CalculateKBReduction\nDIDraw_CalculateKBReduction:\n#Check if holding L/R/Z\n  rlwinm. r0,REG_HeldInputs,0,0x80000000\n  beq DIDraw_CalculateKBReductionEnd\n  lwz\tr3, -0x514C (r13)\n  lfs\tf0, 0x01AC (r3)\n  fmuls REG_KnockbackMag,f0,REG_KnockbackMag\n  fmr  f1,REG_arctan\n  branchl r12,cos\n  fmuls REG_KnockbackX,f1,REG_KnockbackMag\n  fmr  f1,REG_arctan\n  branchl r12,sin\n  fmuls REG_KnockbackY,f1,REG_KnockbackMag\n#Get new atan2\n\tfmr\tf1,REG_KnockbackY\n\tfmr\tf2,REG_KnockbackX\n\tbranchl\tr12,0x80022c30\n\tfmr\tREG_arctan,f1\nDIDraw_CalculateKBReductionEnd:\n#endregion\n#region CalculateDI\nDIDraw_CalculateDI:\n#If grounded, skip DI\n  lwz r3,0xE0(REG_PlayerData)\n  cmpwi r3,0\n  beq DIDraw_CalculateDIEnd\n#If both inputting nothing, skip DI\n  lfs\tf1, -0x750C (rtoc)\n  fcmpo cr0,f1,REG_XComp\n  bne DIDraw_IsInputting\n  fcmpo cr0,f1,REG_YComp\n  beq DIDraw_CalculateDIEnd\nDIDraw_IsInputting:\n#If some condition is met, skip DI\n  lfs\tf0, -0x74E8 (rtoc)\n  fneg  f1,REG_KnockbackX\n  fmuls f1,f1,f1\n  fmuls f2,REG_KnockbackY,REG_KnockbackY\n  fadds f1,f1,f2\n  fcmpo cr0,f1,f0\n  blt DIDraw_CalculateDIEnd\n#Get DI value\n  fneg  f2,REG_KnockbackX\n  fmuls f2,f2,REG_YComp\n  fmuls f3,REG_KnockbackY,REG_XComp\n  fadds f2,f2,f3\n  fmuls f2,f2,f2\n  fdivs REG_DIInput,f2,f1\n  lfs\tf4, -0x750C (rtoc)\n#Cross product\n  stfs  REG_XComp,Stack_MiscSpace+0(sp)\n  stfs  REG_YComp,Stack_MiscSpace+4(sp)\n  lfs f0, -0x750C (rtoc)\n  stfs  f0,Stack_MiscSpace+8(sp)\n  addi  r3,REG_PlayerData,0x8C\n  addi  r4,sp,Stack_MiscSpace+0\n  addi  r5,sp,Stack_MiscSpace+12\n  branchl r12,0x80342e58\n#Check if over 0\n  lfs\tf0, -0x750C (rtoc)\n  lfs f1,Stack_MiscSpace+20(sp)\n  fcmpo cr0,f1,f0\n  bge 0x8\n  fneg  REG_DIInput,REG_DIInput\n#Apply new angle\n  lwz\tr3, -0x514C (r13)\n  lfs\tf2, -0x7510 (rtoc)\n  lfs\tf0, 0x01A8 (r3)\n  fmuls\tf0,f2,f0\n  fmadds\tREG_arctan,f0,REG_DIInput,REG_arctan\n  fmr f1,REG_arctan\n  branchl r12,cos\n  fmuls REG_KnockbackX,REG_KnockbackMag,f1\n  fmr f1,REG_arctan\n  branchl r12,sin\n  fmuls REG_KnockbackY,REG_KnockbackMag,f1\nDIDraw_CalculateDIEnd:\n#endregion\n\n#Perform collision checks for each frame of hitstun\n#region DIDraw_Collision\n\n#region DIDraw_CollisionLoop_Init\nDIDraw_CollisionLoop_Init:\n#Create an ECB struct on the stack\n\taddi\tREG_ECBBoneStruct,sp,Stack_ECBBoneStruct\n\taddi\tREG_ECBStruct,sp,Stack_ECBStruct\n\tmr\tr3,REG_ECBStruct\n\tbranchl\tr12,0x80041ee4\n#Get Current XY\n\tlfs\tREG_CurrXPos,0xB0(REG_PlayerData)\n\tlfs\tREG_CurrYPos,0xB4(REG_PlayerData)\n#Init Loop\n\tli\tREG_LoopCount,0\n  lfs REG_Gravity,-0x750C (rtoc)\n  lwz  REG_GroundState,0xE0(REG_PlayerData)\n  li  REG_OverrideRemainingFrames,0\n#Allocate collision info struct\n  lfs f1,0x2340(REG_PlayerData)\n  fctiwz  f1,f1\n  stfd  f1,Stack_MiscSpace(sp)\n  lwz  r3,Stack_MiscSpace+4(sp)\n  mulli r3,r3,CollInfo_Length       #backing up X bytes per collision check\n  addi  r3,r3,0x4        #small header containing the amount of collision checks\n  branchl r12,HSD_MemAlloc\n  mr  REG_CollisionInfo,r3\n#Init collision info struct\n  li  r3,-1               #init as 0 checks\n  stw r3,0x0(REG_CollisionInfo)\n#If grounded, copy over ground ECB data\n  cmpwi REG_GroundState,0\n  bne DIDraw_DrawTrajectory_SkipCopyGroundData\n  addi  r3,REG_ECBStruct,0x130\n  addi  r4,REG_PlayerData,0x820\n  li  r5,0x28\n  branchl r12,memcpy\nDIDraw_DrawTrajectory_SkipCopyGroundData:\n#endregion\n#region DIDraw_CollisionLoop_Start\nDIDraw_CollisionLoop:\n\n#region Initalize ECB Bone Positions\n#Create ECB Bone struct\n#If loop count < noECBUpdate-remaining hitlag fraes, use current ECB bottom Y offset\n  lwz r3,0x88C(REG_PlayerData)\n  lfs f1,0x195C(REG_PlayerData)\n  fctiwz  f1,f1\n  stfd  f1,Stack_MiscSpace(sp)\n  lwz r4,Stack_MiscSpace+0x4(sp)\n  sub r3,r3,r4\n  cmpw  REG_LoopCount,r3\n  blt DIDraw_CollisionLoop_ECBBonesUseCurrent\n#Copy Struct\n\tmr\tr3,REG_ECBBoneStruct\n\taddi\tr4,REG_EventConstants,ECB_TopY\n\tli\tr5,0x18\n\tbranchl\tr12,memcpy\n#If the player is grounded, ECB bottom is 0\n  cmpwi REG_GroundState,0\n  bne DIDraw_CollisionLoop_ECBBonesEnd\n  lfs\tf1, -0x750C (rtoc)\n  stfs f1,0x04(REG_ECBBoneStruct)\n  b DIDraw_CollisionLoop_ECBBonesEnd\nDIDraw_CollisionLoop_ECBBonesUseCurrent:\n#Use Current Bone Positions\n  lfs f1,0x778(REG_PlayerData)\n  stfs f1,0x00(REG_ECBBoneStruct)\n  lfs f1,0x780(REG_PlayerData)\n  stfs f1,0x04(REG_ECBBoneStruct)\n  lfs f1,0x78C(REG_PlayerData)\n  stfs f1,0x08(REG_ECBBoneStruct)\n  lfs f1,0x790(REG_PlayerData)\n  stfs f1,0x0C(REG_ECBBoneStruct)\n  lfs f1,0x784(REG_PlayerData)\n  stfs f1,0x10(REG_ECBBoneStruct)\n  lfs f1,0x788(REG_PlayerData)\n  stfs f1,0x14(REG_ECBBoneStruct)\n  b DIDraw_CollisionLoop_ECBBonesEnd\nDIDraw_CollisionLoop_ECBBonesEnd:\n#Store current position\n  lfs\tf1, -0x750C (rtoc)\n\tstfs\tREG_CurrXPos,0x4(REG_ECBStruct)\n\tstfs\tREG_CurrYPos,0x8(REG_ECBStruct)\n  stfs\tf1,0xC(REG_ECBStruct)\n\tstfs\tREG_CurrXPos,0x10(REG_ECBStruct)\n\tstfs\tREG_CurrYPos,0x14(REG_ECBStruct)\n  stfs\tf1,0x18(REG_ECBStruct)\n#endregion\n\n#region Apply ASDI\nDIDraw_CollisionLoop_ApplyASDI:\n#Apply ASDI X\n  fadds REG_CurrXPos,REG_CurrXPos,REG_ASDIX\n#Only apply ASDI Y if in the air\n  cmpwi REG_GroundState,0\n  beq 0x8\n  fadds REG_CurrYPos,REG_CurrYPos,REG_ASDIY\n#Null ASDI\n  lfs\tREG_ASDIX, -0x750C (rtoc)\n  lfs\tREG_ASDIY, -0x750C (rtoc)\n#endregion\n\n#region Decay Knockback\n#Apply either gravity or traction\n  cmpwi REG_GroundState,1\n  bne DIDraw_CollisionLoop_DecayGrounded\nDIDraw_CollisionLoop_DecayAerial:\n#Account for gravity\n  lfs\tf1, 0x016C (REG_PlayerData)\n  lfs\tf2, 0x0170 (REG_PlayerData)\n  fneg  f2,f2\n  fsubs REG_Gravity,REG_Gravity,f1\n  fcmpo\tcr0,REG_Gravity,f2\n  bge 0x8\n  fmr REG_Gravity,f2\n#Decay KB Vector\n  fmr f1,REG_KnockbackY\n  fmr f2,REG_KnockbackX\n  branchl r12,0x80022c30    #Get arctan of the KB vector\n  fmr  REG_arctan,f1\n#Decay X KB\n  branchl r12,cos\n  lwz\tr3, -0x514C (r13)\n  lfs\tf2, 0x0204 (r3)\n  fnmsubs\tREG_KnockbackX,f2,f1,REG_KnockbackX\n#Decay Y KB\n  fmr f1,REG_arctan\n  branchl r12,sin\n  lwz\tr3, -0x514C (r13)\n  lfs\tf2, 0x0204 (r3)\n  fnmsubs\tREG_KnockbackY,f2,f1,REG_KnockbackY\n  b DIDraw_CollisionLoop_DecayEnd\nDIDraw_CollisionLoop_DecayGrounded:\n#Get Ground Friction's multipllier\n  lwz r3,0x4(REG_PlayerData)\n  cmpwi r3,Popo.Int\n  beq DIDraw_CollisionLoop_DecayGrounded_isICs\n  cmpwi r3,Nana.Int\n  beq DIDraw_CollisionLoop_DecayGrounded_isICs\n#Get grounds friction multiplier\n  lfs\tf1, -0x7A38 (rtoc)\n  lwz\tr0, 0x014C (REG_ECBStruct)\n  cmpwi r0,-1\n  beq DIDraw_CollisionLoop_DecayGrounded_isICs\n  lwz r3,0x150(REG_ECBStruct)\n  branchl r12,0x800569ec    #Get ground's friction multiplier\n  b 0x8\nDIDraw_CollisionLoop_DecayGrounded_isICs:\n  lfs\tf1, -0x7A38 (rtoc)\n#Account for friction\n  lfs\tf0, 0x128 (REG_PlayerData)\n  fmuls\tf1,f0,f1\n  lwz\tr4, -0x514C (r13)\n  lfs\tf0, 0x0200 (r4)\n  fmuls f0,f1,f0\n#Apply Friction to knockback\n  lfs\tf2, -0x76B0 (rtoc)\n  fcmpo cr0,REG_KnockbackX,f2\n  bge DIDraw_CollisionLoop_DecayGrounded_Subtract\n  fadds f0,f0,REG_KnockbackX\n  fmr REG_KnockbackX,f0\n  fcmpo cr0,f0,f2\n  ble DIDraw_CollisionLoop_DecayGroundedEnd\n  fmr REG_KnockbackX,f2\n  b DIDraw_CollisionLoop_DecayGroundedEnd\nDIDraw_CollisionLoop_DecayGrounded_Subtract:\n  fsubs\tf0,REG_KnockbackX,f0\n  fmr REG_KnockbackX,f0\n  fcmpo cr0,f0,f2\n  bge DIDraw_CollisionLoop_DecayGroundedEnd\n  fmr REG_KnockbackX,f2\n  b DIDraw_CollisionLoop_DecayGroundedEnd\nDIDraw_CollisionLoop_DecayGroundedEnd:\nDIDraw_CollisionLoop_DecayEnd:\n#endregion\n\n#region Shift Positions\n#Shift previous positions down\n  lfs f1,0x4(REG_ECBStruct)\n  lfs f2,0x8(REG_ECBStruct)\n  lfs f3,0xC(REG_ECBStruct)\n  stfs f1,0x1C(REG_ECBStruct)\n  stfs f2,0x20(REG_ECBStruct)\n  stfs f3,0x24(REG_ECBStruct)\n#Store next position\n\tfadds\tf1,REG_CurrXPos,REG_KnockbackX\n\tstfs\tf1,0x4(REG_ECBStruct)\n\tfadds\tf1,REG_CurrYPos,REG_KnockbackY\n  fadds f1,f1,REG_Gravity\n\tstfs\tf1,0x8(REG_ECBStruct)\n\tlfs\tf1, -0x778C (rtoc)\n\tstfs\tf1,0xC(REG_ECBStruct)\n#endregion\n\n#region Run Collision Check\n\n.if MaxColl>=0\n#Only run X collision checks because theyre expensive\n  cmpwi REG_LoopCount,MaxColl\n  blt DIDraw_CollisionLoop_DetermineCollision\n#Spoof as not touching anything\n  li  r3,0\n  stw r3,0x134(REG_ECBStruct)\n\tlfs\tREG_CurrXPos,0x4(REG_ECBStruct)\n\tlfs\tREG_CurrYPos,0x8(REG_ECBStruct)\n#If grounded and max collision checks, just stop updating position\n  cmpwi REG_GroundState,0\n  bne  DIDraw_CollisionLoop_StageBehaviorEnd\n  li  REG_OverrideRemainingFrames,1\n  b DIDraw_CollisionLoop_StageBehaviorEnd\n.endif\n\nDIDraw_CollisionLoop_DetermineCollision:\n#Run collision\n  cmpwi REG_GroundState,1\n  beq DIDraw_CollisionLoop_AerialCollision\nDIDraw_CollisionLoop_GroundCollision:\n#Grounded Collision\n\tmr\tr3,REG_ECBStruct\n\tmr\tr4,REG_ECBBoneStruct\n\tbranchl\tr12,0x8004b21c\n  xori  REG_GroundState,r3,0x1\n  b DIDraw_CollisionLoop_CollisionEnd\nDIDraw_CollisionLoop_AerialCollision:\n#Aerial Collision\n\tmr\tr3,REG_ECBStruct\n\tmr\tr4,REG_ECBBoneStruct\n\tbranchl\tr12,0x800475f4\nDIDraw_CollisionLoop_CollisionEnd:\n#endregion\n\n#region Stage Collision Behavior\n#Get new position\n\tlfs\tREG_CurrXPos,0x4(REG_ECBStruct)\n\tlfs\tREG_CurrYPos,0x8(REG_ECBStruct)\n#Inc Collision ID\n  lwz r3,0x38(REG_ECBStruct)\n  addi  r3,r3,1\n  stw r3,0x38(REG_ECBStruct)\n#Determine line collision behavior\n  lwz r3,0x134(REG_ECBStruct)\n  rlwinm. r0,r3,0,0x8000\n  bne DIDraw_CollisionLoop_TouchingGround\n  rlwinm. r0,r3,0,0x6000\n  bne DIDraw_CollisionLoop_TouchingCeiling\n  rlwinm. r0,r3,0,0x20\n  bne DIDraw_CollisionLoop_TouchingWall\n  rlwinm. r0,r3,0,0x40\n  bne DIDraw_CollisionLoop_TouchingWall\nDIDraw_CollisionLoop_TouchingNothing:\n  b DIDraw_CollisionLoop_StageBehaviorEnd\n\n#region Touching Ground\nDIDraw_CollisionLoop_TouchingGround:\n#If grounded, dont run KB manip code\n  cmpwi REG_GroundState,0\n  beq DIDraw_CollisionLoop_StageBehaviorEnd\n#Check if over max horizontal velocity\n  lwz\tr4, -0x514C (r13)\n  lfs\tf1, 0x0164 (r4)\n  fcmpo cr0,REG_KnockbackX,f1\n  ble 0x8\n  fmr REG_KnockbackX,f1\n  fneg  f1,f1\n  fcmpo cr0,REG_KnockbackX,f1\n  bge 0x8\n  fmr REG_KnockbackX,f1\n#Adjust KB\n  lfs f1,0x158(REG_ECBStruct)\n  fmuls REG_KnockbackX,REG_KnockbackX,f1\n  lfs f1,0x154(REG_ECBStruct)\n  fneg  f1,f1\n  fmuls REG_KnockbackY,REG_KnockbackX,f1\n#REMOVE ALL Y KB?\n  lfs\tREG_KnockbackY, -0x750C (rtoc)\n#Set as grounded\n  li  REG_GroundState,0\n  b DIDraw_CollisionLoop_StageBehaviorEnd\n#endregion\n#region Touching Ceiling\nDIDraw_CollisionLoop_TouchingCeiling:\n#If grounded, dont run KB manip code\n  cmpwi REG_GroundState,0\n  beq DIDraw_CollisionLoop_StageBehaviorEnd\n#Self-Induced velocity\n  lfs\tf1, -0x750C (rtoc)\n  stfs f1,Stack_MiscSpace+0x0(sp)\n  stfs REG_Gravity,Stack_MiscSpace+0x4(sp)\n#KB-Induced\n  stfs REG_KnockbackX,Stack_MiscSpace+0x8(sp)\n  stfs REG_KnockbackY,Stack_MiscSpace+0xC(sp)\n#Add vectors\n  addi  r3,sp,Stack_MiscSpace+0x0\n  addi  r4,sp,Stack_MiscSpace+0x8\n  branchl r12,0x8000d4a0\n#Unk\n  addi  r3,sp,Stack_MiscSpace+0x0\n  addi  r4,REG_ECBStruct,0x190\n  branchl r12,0x8000dc6c\n#Decay KB\n  lwz\tr3, -0x514C (r13)\n  lfs\tf1, 0x01BC (r3)\n  lfs f2,Stack_MiscSpace+0x0(sp)\n  lfs f3,Stack_MiscSpace+0x4(sp)\n  fmuls REG_KnockbackX,f1,f2\n  fmuls REG_KnockbackY,f1,f3\n  b DIDraw_CollisionLoop_StageBehaviorEnd\n#endregion\n#region Touching Wall\nDIDraw_CollisionLoop_TouchingWall:\n#If grounded, dont run KB manip code\n  cmpwi REG_GroundState,0\n  beq DIDraw_CollisionLoop_StageBehaviorEnd\n#Get walls data\n  lwz r3,0x134(REG_ECBStruct)\n  rlwinm. r0,r3,0,0x20\n  bne DIDraw_CollisionLoop_LeftWallsData\n  rlwinm. r0,r3,0,0x40\n  bne DIDraw_CollisionLoop_RightWallsData\nDIDraw_CollisionLoop_RightWallsData:\n  addi  REG_Temp,REG_ECBStruct,380\n  b 0x8\nDIDraw_CollisionLoop_LeftWallsData:\n  addi  REG_Temp,REG_ECBStruct,360\n#Self-Induced velocity\n  lfs\tf1, -0x750C (rtoc)\n  stfs f1,Stack_MiscSpace+0x0(sp)\n  stfs REG_Gravity,Stack_MiscSpace+0x4(sp)\n#KB-Induced\n  stfs REG_KnockbackX,Stack_MiscSpace+0x8(sp)\n  stfs REG_KnockbackY,Stack_MiscSpace+0xC(sp)\n#Add vectors\n  addi  r3,sp,Stack_MiscSpace+0x0\n  addi  r4,sp,Stack_MiscSpace+0x8\n  branchl r12,0x8000d4a0\n#Unk\n  addi  r3,sp,Stack_MiscSpace+0x0\n  mr  r4,REG_Temp\n  branchl r12,0x8000dc6c\n#Decay KB\n  lwz\tr3, -0x514C (r13)\n  lfs\tf1, 0x01BC (r3)\n  lfs f2,Stack_MiscSpace+0x0(sp)\n  lfs f3,Stack_MiscSpace+0x4(sp)\n  fmuls REG_KnockbackX,f1,f2\n  fmuls REG_KnockbackY,f1,f3\n  lfs\tREG_Gravity, -0x6DA0 (rtoc)\n  b DIDraw_CollisionLoop_StageBehaviorEnd\n#endregion\nDIDraw_CollisionLoop_StageBehaviorEnd:\n#endregion\n\n#region Ground to Air Check\n.if MaxColl>=0\nDIDraw_CollisionLoop_GroundToAirCheck:\n.set  GroundToAirRemainingFrames,5\n#Ensure not touching ground this frame\n  lwz r3,0x134(REG_ECBStruct)\n  rlwinm. r0,r3,0,0x8000\n  bne DIDraw_CollisionLoop_GroundToAirCheckEnd\n#Ensure was touching ground last frame\n  lwz r3,0x138(REG_ECBStruct)\n  rlwinm. r0,r3,0,0x8000\n  beq DIDraw_CollisionLoop_GroundToAirCheckEnd\n#Check if over MaxColl\n  cmpwi REG_LoopCount,MaxColl\n  blt DIDraw_CollisionLoop_GroundToAirCheckEnd\n#Check if REG_OverrideRemainingFrames is already set\n  cmpwi REG_OverrideRemainingFrames,0\n  bgt DIDraw_CollisionLoop_GroundToAirCheckEnd\n#Set REG_OverrideRemainingFrames\n  li  REG_OverrideRemainingFrames,GroundToAirRemainingFrames\nDIDraw_CollisionLoop_GroundToAirCheckEnd:\n.endif\n#endregion\n\n#region Save Collision Info\n.set  CollInfo_Length,0x18\n.set  CollInfo_XPos,0x0\n.set  CollInfo_YPos,0x4\n.set  CollInfo_EnvBitfield,0x8\n.set  CollInfo_ECBTopY,0xC\n.set  CollInfo_ECBLeftY,0x10\n.set  CollInfo_KnockbackY,0x14\n#Update collision check count\n  stw REG_LoopCount,0x0(REG_CollisionInfo)\n#Get this frames offset in info struct\n  addi  r3,REG_CollisionInfo,0x4    #skip past header\n  mulli r4,REG_LoopCount,CollInfo_Length\n  add r3,r3,r4\n#Store data\n  stfs  REG_CurrXPos,CollInfo_XPos(r3)\n  stfs  REG_CurrYPos,CollInfo_YPos(r3)\n  lwz r4,0x134(REG_ECBStruct)\n  stw  r4,CollInfo_EnvBitfield(r3)\n  lfs f1,0x88(REG_ECBStruct)\n  stfs  f1,CollInfo_ECBTopY(r3)\n  lfs f1,0xA0(REG_ECBStruct)\n  stfs  f1,CollInfo_ECBLeftY(r3)\n  stfs  REG_KnockbackY,CollInfo_KnockbackY(r3)\n#endregion\n\nDIDraw_CollisionLoop_IncLoop:\n#Check override frames first\n  cmpwi REG_OverrideRemainingFrames,0\n  ble DIDraw_CollisionLoop_IncLoopNoOverride\n#Decrement override frames\n  subi  REG_OverrideRemainingFrames,REG_OverrideRemainingFrames,1\n  cmpwi REG_OverrideRemainingFrames,0\n  bgt DIDraw_CollisionLoop_IncLoopNoOverride\n#Override and exit loop prematurely\n  b DIDraw_CollisionLoop_IncLoopEnd\nDIDraw_CollisionLoop_IncLoopNoOverride:\n#Inc Loop\n\taddi\tREG_LoopCount,REG_LoopCount,1\n  lfs f1,0x2340(REG_PlayerData)\n  fctiwz  f1,f1\n  stfd  f1,Stack_MiscSpace(sp)\n  lwz  r3,Stack_MiscSpace+4(sp)\n\tcmpw\tREG_LoopCount,r3\n\tblt\tDIDraw_CollisionLoop\nDIDraw_CollisionLoop_IncLoopEnd:\n/*\n.if MaxColl>=0\n#Output collision checks count\n  bl  DIDraw_CollisionLoop_Text\n  mflr  r3\n  lwz r4,TM_GameFrameCounter(r13)\n  mr  r5,REG_LoopCount\n  branchl r12,OSReport\n  b DIDraw_CollisionLoop_TextEnd\nDIDraw_CollisionLoop_Text:\nblrl\n.string \"frame %d performed %d collision checks\\n\"\n.align 2\nDIDraw_CollisionLoop_TextEnd:\n.endif\n*/\n#endregion\n#endregion\n\n#Draw out each frame of hitstun\n#region DIDraw_Draw\n.set REG_FramesCollisionInfo,26\n.set REG_LineColor,27\n\n#region DIDraw_DrawLoop_Init\nDIDraw_DrawLoop_Init:\n#Init Loop\n\tli\tREG_LoopCount,0\n#Init GX Prim\n  lwz r3,0x0(REG_CollisionInfo)\n  addi  r3,r3,2        #collision frames + 2 for ASDI frames\n  load  r4,0x001F1306\n  load  r5,0x00000C55\n  branchl r12,prim.new\n  mr  REG_GX,r3\n#Get line color (check if results in death)\n.set REG_DeathLoopCount,28\n  li  REG_DeathLoopCount,0\nDIDraw_DrawLoop_Init_DeathLoop:\n  addi  r3,REG_CollisionInfo,0x4\n  mulli r4,REG_DeathLoopCount,CollInfo_Length\n  add  r3,r3,r4                     #get last frames info\n  lfs REG_CurrXPos,CollInfo_XPos(r3)\n  lfs REG_CurrYPos,CollInfo_YPos(r3)\n  lfs REG_KnockbackY,CollInfo_KnockbackY(r3)\n  branchl r12,0x80224b38            #right blastzone\n  fcmpo cr0,REG_CurrXPos,f1\n  bgt DIDraw_DrawLoop_Init_Dead\n  branchl r12,0x80224b50            #left blastzone\n  fcmpo cr0,REG_CurrXPos,f1\n  blt DIDraw_DrawLoop_Init_Dead\n  branchl r12,0x80224b80            #bottom blastzone\n  fcmpo cr0,REG_CurrYPos,f1\n  blt DIDraw_DrawLoop_Init_Dead\n  branchl r12,0x80224b68            #top blastzone\n  fcmpo cr0,REG_CurrYPos,f1\n  ble DIDraw_DrawLoop_Init_DeathLoop_Inc\n  cmpwi REG_GroundState,0\n  beq DIDraw_DrawLoop_Init_Dead\n  lwz\tr3, -0x514C (r13)\n  lfs\tf0, 0x04F0 (r3)\n  fcmpo cr0,REG_KnockbackY,f0\n  ble DIDraw_DrawLoop_Init_DeathLoop_Inc\nDIDraw_DrawLoop_Init_Dead:\n  lwz REG_LineColor,DeadLineColor(REG_EventConstants)\n  b DIDraw_DrawLoop_Init_DeathLoop_Exit\nDIDraw_DrawLoop_Init_DeathLoop_Inc:\n  addi  REG_DeathLoopCount,REG_DeathLoopCount,1\n  lwz r3,0x0(REG_CollisionInfo)\n  cmpw  REG_DeathLoopCount,r3\n  blt DIDraw_DrawLoop_Init_DeathLoop\n#Is alive, make blue\n  lwz REG_LineColor,AliveLineColor(REG_EventConstants)\nDIDraw_DrawLoop_Init_DeathLoop_Exit:\n#Draw the ASDI\n#Get original ASDI values\n  lfs  REG_ASDIX,Stack_ASDIBackup+0(sp)\n  lfs  REG_ASDIY,Stack_ASDIBackup+4(sp)\n#If no ASDI, use blue\n  lfs\tf0, -0x750C (rtoc)\n  fcmpo cr0,REG_ASDIX,f0\n  bne DIDraw_DrawLoop_Init_HasASDI\n  lfs\tf0, -0x750C (rtoc)\n  fcmpo cr0,REG_ASDIY,f0\n  bne DIDraw_DrawLoop_Init_HasASDI\n  mr  r4,REG_LineColor\n  b 0x8\nDIDraw_DrawLoop_Init_HasASDI:\n  lwz r4,ASDIColor(REG_EventConstants)\n#Draw starting point\n  lfs f1,0x6F4(REG_PlayerData)      #X = TopN X\n  lfs f2,0x790(REG_PlayerData)      #Y = ECBLeftY + TopN Y\n  lfs f3,0x6F8(REG_PlayerData)\n  fadds f2,f2,f3\n  lfs f3,FirefoxDrawZ(REG_EventConstants)\n  stfs  f1,0x0(REG_GX)\n  stfs  f2,0x0(REG_GX)\n  stfs  f3,0x0(REG_GX)\n  stw   r4,0x0(REG_GX)\n#Draw end point\n  lfs f1,0x6F4(REG_PlayerData)      #X = TopN X\n  fadds f1,f1,REG_ASDIX\n  lfs f2,0x790(REG_PlayerData)      #Y = ECBLeftY + TopN Y\n  lfs f3,0x6F8(REG_PlayerData)\n  fadds f2,f2,f3\n  fadds f2,f2,REG_ASDIY\n  lfs f3,FirefoxDrawZ(REG_EventConstants)\n  stfs  f1,0x0(REG_GX)\n  stfs  f2,0x0(REG_GX)\n  stfs  f3,0x0(REG_GX)\n  stw   r4,0x0(REG_GX)\n\n#endregion\n#region DIDraw_DrawLoop_Start\nDIDraw_DrawLoop:\n#Get this frames offset in info struct\n  addi  r3,REG_CollisionInfo,0x4    #skip past header\n  mulli r4,REG_LoopCount,CollInfo_Length\n  add REG_FramesCollisionInfo,r3,r4\n\n#region DIDraw_DrawLoop_DetermineColor\n#Determine line collision behavior\n  lwz r3,CollInfo_EnvBitfield(REG_FramesCollisionInfo)\n  rlwinm. r0,r3,0,0x8000\n  bne DIDraw_DrawLoop_TouchingGround\n  rlwinm. r0,r3,0,0x6000\n  bne DIDraw_DrawLoop_TouchingCeiling\n  rlwinm. r0,r3,0,0x20\n  bne DIDraw_DrawLoop_TouchingLeftWall\n  rlwinm. r0,r3,0,0x40\n  bne DIDraw_DrawLoop_TouchingRightWall\nDIDraw_DrawLoop_TouchingNothing:\n  mr  r4,REG_LineColor\n  b DIDraw_DrawLoop_GetColorEnd\nDIDraw_DrawLoop_TouchingGround:\n  lwz r4,GroundColor(REG_EventConstants)\n  b DIDraw_DrawLoop_GetColorEnd\nDIDraw_DrawLoop_TouchingCeiling:\n  lwz r4,CeilingColor(REG_EventConstants)\n  b DIDraw_DrawLoop_GetColorEnd\nDIDraw_DrawLoop_TouchingLeftWall:\n  lwz r4,LeftWallColor(REG_EventConstants)\n  b DIDraw_DrawLoop_GetColorEnd\nDIDraw_DrawLoop_TouchingRightWall:\n  lwz r4,RightWallColor(REG_EventConstants)\n  b DIDraw_DrawLoop_GetColorEnd\nDIDraw_DrawLoop_GetColorEnd:\n#endregion\n\n#Draw this point\n  lfs f1,CollInfo_XPos(REG_FramesCollisionInfo)      #X = TopN X\n  /*\n  lfs f2,CollInfo_ECBLeftY(REG_FramesCollisionInfo)  #Y = ECBLeftY + TopN Y\n  lfs f3,CollInfo_YPos(REG_FramesCollisionInfo)\n  fadds f2,f2,f3\n  */\n  lfs f2,0x790(REG_PlayerData)\n  lfs f3,CollInfo_YPos(REG_FramesCollisionInfo)\n  fadds f2,f2,f3\n  lfs f3,FirefoxDrawZ(REG_EventConstants)\n  mr  r3,REG_GX\n  stfs  f1,0x0(r3)\n  stfs  f2,0x0(r3)\n  stfs  f3,0x0(r3)\n  stw   r4,0x0(r3)\n#Inc Loop\n\taddi\tREG_LoopCount,REG_LoopCount,1\n  lwz r3,0x0(REG_CollisionInfo)\n\tcmpw\tREG_LoopCount,r3\n\tblt\tDIDraw_DrawLoop\n#Free collision struct\n  mr  r3,REG_CollisionInfo\n  branchl r12,HSD_Free\n#End Loop\n  branchl r12,prim.close\n#endregion\n\n#endregion\n\nDIDraw_Exit:\n  lmw  r20,Stack_BackedUpReg(r1)\n  lwz r0, StackSize+4(r1)\n  addi\tr1,r1,StackSize\t# release the space\n  mtlr r0\n  blr\n\n####################################################\n#endregion\n\nExit:\n#Return\n  restore\n  mr\tr3, r28\n"
  },
  {
    "path": "ASM/Additional Codes/Game Modes/All Star Test/Disable Invisible Melee.s",
    "content": "#To be inserted at 801ba5d0\n.include \"../../../Globals.s\"\n\n.set  REG_MinorData,31\n.set  REG_IronManData,30\n.set  REG_MatchData,29\n.set IronManData,0x8040a5e0\n\nbackup\n\n  mr  REG_MinorData,r3\n\n#Get Match Data\n  lwz\tREG_MatchData, -0x77C0 (r13)\n  addi\tREG_MatchData, REG_MatchData, 4624\n  load  REG_IronManData,IronManData\n\n#Destroy Existing Heap\n\n#Reset cache\n  branchl r12,0x80018c6c\n  branchl r12,0x80018254\n  li  r3,4\n  branchl r12,0x80017700\n\nIronMan_SetupMatchInit:\n.set  REG_Count,20\n.set  REG_PlayerCount,21\n.set  REG_Port,22\n#Init\n  li  REG_PlayerCount,0\n  li  REG_Count,0\nIronMan_SetupMatchLoop:\n  mr  r3,REG_MatchData\n  mr  r4,REG_Count\n  bl  GetPlayersMatchInfo       #Get the players data\n  cmpwi r3,-1\n  beq IronMan_SetupMatchEnd\n#Set the first character as the current character\n  mr  REG_Port,r4\n  mulli r5,REG_PlayerCount,0x1C\n  add  r5,r5,REG_IronManData\n  lbz r6,0x0(r5)               #Get the next iron man character\n  addi  r5,r5,1\n  lbzx  r5,r6,r5\n  stb r5,0x0(r3)                #Store character to match data\n  stb REG_PlayerCount,0x3(r3)   #Store costume to match data\n#Get Prelod Table\n  load  r3,0x8043208c\n  mulli r4,REG_Port,0x8\n  add r4,r3,r4\n  stw r5,0x0(r4)                 #Store to preload table\n  stb REG_PlayerCount,0x4(r4)                  #Store costume\n  addi  REG_PlayerCount,REG_PlayerCount,1\n\nIronMan_SetupMatchIncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,6\n  blt IronMan_SetupMatchLoop\n\nIronMan_SetupMatchEnd:\n#Now get a random stage\n  branchl r12,0x8025bbd4\n  sth r3,0x16(REG_MatchData)\n  load  r4,0x80432088\n  stw r3,0x0(r4)                #Store to prelaod\n#Request preload\n  branchl r12,0x80018254\n\n#Store Pointer to onStartMelee function\n  lwz\tr4, -0x77C0 (r13)\n  addi\tr4, r4, 4624\n  bl  IronMan_Init\n  mflr r5\n  stw r5,0x4C(r4)\n  b InjectionExit\n\n#region IronMan_Init\nIronMan_Init:\nblrl\n\n.set REG_GObj,31\n.set REG_Data,30\n\n.set DataSize,64\n\nbackup\n\n#Create GObj\n  li  r3,22\n  li  r4,0\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n\n#Alloc Mem\n  li  r3,DataSize\n  branchl r12,HSD_MemAlloc\n  mr  REG_Data,r3\n\n#Zero Data\n  mr  r3,REG_Data\n  li  r4,DataSize\n  branchl r12,ZeroAreaLength\n\n#Attach Data\n  mr  r3,REG_GObj\n  li  r4,14\n  load r5,HSD_Free\n  mr  r6,REG_Data\n  branchl r12,GObj_AddUserData\n\n#Attach Process\n  mr  r3,REG_GObj\n  bl  IronMan_Think\n  mflr r4\n  li  r5,23\n  branchl r12,GObj_AddProc\n\n#Create Text\n.set  REG_Count,20\n.set  REG_IronManData,21\n.set  REG_PlayerCount,22\n.set  REG_Temp,23\n.set  REG_Text,24\n#Init\n  li  REG_PlayerCount,0\n  li  REG_Count,0\n  load  REG_IronManData,IronManData\nIronMan_Init_AdjustStocksLoop:\n#Check if exists\n  mr  r3,REG_Count\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  cmpwi r3,0\n  beq IronMan_Init_AdjustStocksIncLoop\n#Increment player count\n  addi  REG_PlayerCount,REG_PlayerCount,1\n  subi  r4,REG_PlayerCount,1\n  mulli r4,r4,0x1C\n  add REG_Temp,r4,REG_IronManData\n#Create Text\n  li  r3,2\n  load  r4,0x804a1f58\n  lwz r4,0x0(r4)\n  branchl r12,Text_CreateTextStruct\n  mr  REG_Text,r3\n  addi r3,REG_GObjData,OFST_TextPointers\n  mulli r4,REG_Count,4\n  stwx  REG_Text,r3,r4\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x1\n\tstb r4,0x49(REG_Text)\n#SET TEXT TO CENTER AROUND X LOCATION\n\tli r4,0x1\n\tstb r4,0x4A(REG_Text)\n#Update Text Contents\n\tload\tr4,0x804a0ff0\n\tmulli\tr3,REG_Count,0xC\t\t\t#HUD Info is 0xC Long Per Player\n\tlfsx\tf1,r3,r4\t\t\t        #Get This Players HUD Info\n  bl  ScorePosition\n  mflr  r5\n  lfs f2,0x0(r5)\n  mr  r3,REG_Text\n  bl  ScoreText\n  mflr  r4\n  lbz r5,0x0(REG_Temp)\n  extsb r5,r5\n  addi  r5,r5,1\n  branchl r12,Text_InitializeSubtext\n#Update Size\n  mr  r3,REG_Text\n  li  r4,0\n  lfs\tf1, -0x1DB4 (rtoc)\n  lfs\tf2, -0x1DB4 (rtoc)\n  branchl r12,Text_UpdateSubtextSize\nIronMan_Init_AdjustStocksIncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,6\n  blt IronMan_Init_AdjustStocksLoop\n\nIronMan_InitExit:\nrestore\nblr\n\n#endregion\n\n#region IronMan_Think\nIronMan_Think:\nblrl\n\n#Registers\n.set  REG_GObj,31\n.set  REG_GObjData,30\n.set  REG_IronManData,29\n\n#Offsets\n.set OFST_TextPointers,0x0\n.set OFST_IsSpawning,0x18\n  .set OFST_IsSpawningLength,0x2\n\n#Constants\n.set EndTimer,60\n\nbackup\n\n#Init Pointers\n  mr  REG_GObj,r3\n  lwz REG_GObjData,0x2C(REG_GObj)\n  load  REG_IronManData,IronManData\n\n#Set match bits to not declare player defeated\n  branchl r12,0x8016ae38\n  li  r4,0\n  stb r4,0x5(r3)\n\n\n#Check if match is pending a character load\n.set  REG_Count,20\n#Init\n  li  REG_Count,0\n#Check if pending a load\nIronMan_Think_CheckForPendingSpawnLoop:\n  addi  r3,REG_GObjData,OFST_IsSpawning\n  mulli r4,REG_Count,OFST_IsSpawningLength\n  add r4,r3,r4\n  lhz  r3,0x0(r4)\n  cmpwi r3,0\n  beq IronMan_Think_CheckForPendingSpawnIncLoop\n#Check if load is finished\n  subi  r3,r3,1\n  sth  r3,0x0(r4)\n  cmpwi r3,0\n  bgt IronMan_Think_CheckForPendingSpawnIncLoop\n#Spawn in player\n  load  r3,0x80480590         #Match info\n  mulli r4,REG_Count,0x24\n  add r4,r3,r4\n  mr  r3,REG_Count\n  branchl r12,0x8016eddc\n#Enter in Rebirth\n  mr  r3,REG_Count\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n\tli r4,0x1\n\tbranchl\tr12,0x800bfd9c\nIronMan_Think_CheckForPendingSpawnIncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,6\n  blt IronMan_Think_CheckForPendingSpawnLoop\nIronMan_Think_CheckForPendingSpawnEnd:\n\nIronMan_Think_DeathCheckInit:\n.set  REG_Count,20\n.set  REG_SomeoneDied,21\n.set  REG_PlayerCount,22\n.set  REG_PlayerData,23\n.set  REG_IronManLineup,24\n#Init\n  li  REG_PlayerCount,0\n  li  REG_Count,0\n  li  REG_SomeoneDied,0\nIronMan_Think_DeathCheckLoop:\n#Check if exists\n  mr  r3,REG_Count\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  mr. REG_PlayerData,r3\n  beq IronMan_Think_DeathCheckIncLoop\n#Increment player count\n  addi  REG_PlayerCount,REG_PlayerCount,1\n#Update stock counter in ironman data\n  mr  r3,REG_Count\n  branchl r12,PlayerBlock_LoadStocksLeft\n  subi  r4,REG_PlayerCount,1\n  mulli r4,r4,0x1C\n  add REG_IronManLineup,r4,REG_IronManData\n  stb r3,0x1B(REG_IronManLineup)\n#Check if no stocks left\n  cmpwi r3,0\n  bgt IronMan_Think_DeathCheckIncLoop\n#Decrement their ironman index\n  lbz r3,0x0(REG_IronManLineup)\n  subi  r3,r3,1\n  stb r3,0x0(REG_IronManLineup)\n#Check if theyre completely dead\n  extsb r3,r3\n  cmpwi r3,0\n  blt IronMan_Think_DeathCheckEndGame\n#Give them max stocks\n  lwz\tr3, -0x77C0 (r13)\n  lbz\tr3,6228(r3)\n  stb r3,0x1B(REG_IronManLineup)\n#Despawn this player\n  mr  r3,REG_Count\n  branchl r12,0x8016ef98\n#Remove all of their items\n\n#Kill all of their SFX\n\n#Setup spawn struct\n  lbz r3,0x0(REG_IronManLineup)\n  addi  r4,REG_IronManLineup,1\n  lbzx  r5,r3,r4\n  load  r3,0x80480590         #Match info\n  mulli r4,REG_Count,0x24\n  add r4,r3,r4\n  stb r5,0x0(r4)                #Store character to match data\n  stb REG_Count,0x3(r4)         #Store costume to match data\n#Begin Preloading next character\n  mr  r3,r5\n  mr  r4,REG_Count\n  bl  LoadCharacter\n#Start Preload\n#Set isSpawning flag\n  addi  r3,REG_GObjData,OFST_IsSpawning\n  mulli r4,REG_Count,OFST_IsSpawningLength\n  add r4,r3,r4\n  li  r3,3*60\n  sth  r3,0x0(r4)\n#Update Text\n#Get text pointer\n  addi r3,REG_GObjData,OFST_TextPointers\n  mulli r4,REG_Count,4\n  lwzx  r3,r3,r4\n  li  r4,0\n  bl  ScoreText\n  mflr  r5\n  lbz r6,0x0(REG_IronManLineup)\n  extsb r6,r6\n  addi  r6,r6,1\n  branchl r12,Text_UpdateSubtextContents\n  b IronMan_Think_DeathCheckIncLoop\nIronMan_Think_DeathCheckEndGame:\n#This player is out of characters, display GAME\n  li  r3,5\n  branchl r12,0x8016b33c\n#Delay\n  li  r3,40\n  branchl r12,0x8016b378\n#End game\n  branchl r12,0x8016b328\n#Destroy GObj\n  mr  r3,REG_GObj\n  branchl r12,GObj_Destroy\n  b IronMan_ThinkExit\nIronMan_Think_DeathCheckIncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,6\n  blt IronMan_Think_DeathCheckLoop\n\nIronMan_ThinkExit:\nrestore\nblr\n\n#endregion\n\n###############################################################\nScoreText:\nblrl\n.string \"%d Left\"\n.align 2\n\nScorePosition:\nblrl\n.float -15.5\n###############################################################\nGetPlayersMatchInfo:\n.set  REG_LoopCount,9\n.set  REG_Count,10\n.set  REG_MatchData,11\n.set  REG_Player,12\n\n#Backup\n  addi  REG_MatchData,r3,0x68\n  mr  REG_Player,r4\n  li  REG_Count,0\n  li  REG_LoopCount,0\n\nGetPlayersMatchInfo_Loop:\n  lbz r3,0x1(REG_MatchData)\n  cmpwi r3,0x3\n  beq GetPlayersMatchInfo_IncLoop\n#Check if this is the desired player\n  cmpw  REG_Count,REG_Player\n  beq GetPlayersMatchInfo_Exit\n  addi  REG_Count,REG_Count,1\nGetPlayersMatchInfo_IncLoop:\n  addi  REG_MatchData,REG_MatchData,0x24\n  addi  REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt GetPlayersMatchInfo_Loop\n#Not Found\n  li  r3,-1\n  b GetPlayersMatchInfo_Blr\n\nGetPlayersMatchInfo_Exit:\n  mr  r3,REG_MatchData\n  mr  r4,REG_LoopCount\nGetPlayersMatchInfo_Blr:\n  blr\n\n###############################################################\n\nLoadCharacter:\n.set  REG_ExtCharID,31\n.set  REG_CostumeID,30\n\n#Init\n  backup\n  mr  REG_ExtCharID,r3\n  mr  REG_CostumeID,r4\n\n#Store to preload table\n  load  r3,0x8043209c\n  mulli r4,REG_CostumeID,0x8\n  add r4,r3,r4\n  stw REG_ExtCharID,0x0(r4)                 #Store to preload table\n  stb REG_CostumeID,0x4(r4)                 #Store costume\n  branchl r12,0x80018254\n\n#Load present characters SFX\nLoadCharacter_DeathCheckSFXLoad:\n.set  REG_SFXLoopCount,25\n.set  REG_SFXMatchInfo,26\n.set  REG_AudioBit1,27\n.set  REG_AudioBit2,28\n  li  REG_SFXLoopCount,0\n  li  REG_AudioBit1,0\n  li  REG_AudioBit2,0\n  load  REG_SFXMatchInfo,0x80480590         #Match info\nLoadCharacter_DeathCheckSFXLoadLoop:\n  mulli r3,REG_SFXLoopCount,0x24\n  add r3,r3,REG_SFXMatchInfo\n  lbz r3,0x0(r3)\n  extsb r3,r3\n  branchl r12,0x80026e84\n  or  REG_AudioBit1,REG_AudioBit1,r3\n  or  REG_AudioBit2,REG_AudioBit2,r4\nLoadCharacter_DeathCheckSFXLoadIncLoop:\n  addi  REG_SFXLoopCount,REG_SFXLoopCount,1\n  cmpwi REG_SFXLoopCount,6\n  blt LoadCharacter_DeathCheckSFXLoadLoop\n#Unk\n  li  r3,28\n  branchl r12,0x80026f2c\n#Request the SFX load\n  li  r3,4\n  mr  r5,REG_AudioBit1\n  mr  r6,REG_AudioBit2\n  branchl r12,0x8002702c\n  branchl r12,0x80027168\n\nLoadCharacter_Exit:\n  restore\n  blr\n\n###############################################################\n\nInjectionExit:\n  mr  r3,REG_MinorData\n  restore\n  li  r5,0\n  li  r6,0\n"
  },
  {
    "path": "ASM/Additional Codes/Game Modes/All Star Test/Initialize Lineups.s",
    "content": "#To be inserted at 801ba544\n.include \"../../../Globals.s\"\n\n.set  REG_MinorData,31\n.set  REG_IronManData,30\n.set  REG_MatchData,29\n\n.set IronManData,0x8040a5e0\n\nbackup\n\n#Save r3, cant get it otherwise\n  mr  REG_MinorData,r3\n#Get iron man data\n  load  REG_IronManData,IronManData\n#Get Match data\n  lwz REG_MatchData,0x14(REG_MinorData)\n\nIronMan_InitLineupInit:\n.set  REG_Count,20\n#Init\n  li  REG_Count,0\nIronMan_InitLineupLoop:\n  mr  r3,REG_MatchData\n  mr  r4,REG_Count\n  bl  GetPlayersMatchInfo       #Get the players data\n  cmpwi r3,-1\n  beq IronMan_InitLineupEnd\n#Create Lineup\n  mulli r3,REG_Count,0x1C\n  add r3,r3,REG_IronManData\n  bl  CreateLineupArray\n\nIronMan_InitLineupIncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,6\n  blt IronMan_InitLineupLoop\nIronMan_InitLineupEnd:\n\n#Set match bits to skip game end checks (doing this myself)\n  li  r3,0x80\n  stb r3,0x15(REG_MatchData)\n\n#Next Minor in-game\n  load  r3,SceneController\n  li  r4,1\n  stb r4,Scene.CurrentMinor(r3)\nb Exit\n\n###############################################################\nCreateLineupArray:\n.set  REG_Array,31\n.set  REG_BaseArray,30\n.set  REG_Index,29\n\n#backup\n  backup\n  mr  REG_Array,r3\n#Initialize Runtime Index\n  li  r3,25\n  stb r3,0x0(REG_Array)\n#Initialzie Stock Counter\n  lwz\tr3, -0x77C0 (r13)\n  lbz\tr3,6228(r3)\n  stb r3,0x1B(REG_Array)\n  addi  REG_Array,REG_Array,1\n#Get base array\n  bl  IronManArray\n  mflr  REG_BaseArray\n#Copy Lineup Array\n  mr  r3,REG_Array\n  mr  r4,REG_BaseArray\n  li  r5,26\n  branchl r12,memcpy\n\n#Initialize Shuffle Index\n  li  REG_Index,25\nCreateLineupArray_Loop:\n#Get random number between 0-25\n  li  r3,26\n  branchl r12,HSD_Randi\n#Swap the current index with this element\n  lbzx  r4,r3,REG_Array\n  lbzx  r5,REG_Index,REG_Array\n  stbx  r4,REG_Index,REG_Array\n  stbx  r5,r3,REG_Array\n#Decrement index\n  subi  REG_Index,REG_Index,1\n  cmpwi REG_Index,0\n  bge CreateLineupArray_Loop\n\nCreateLineupArray_Exit:\n  restore\n  blr\n\n###############################################################\nGetPlayersMatchInfo:\n.set  REG_LoopCount,9\n.set  REG_Count,10\n.set  REG_MatchData,11\n.set  REG_Player,12\n\n#Backup\n  addi  REG_MatchData,r3,0x70\n  mr  REG_Player,r4\n  li  REG_Count,0\n  li  REG_LoopCount,0\n\nGetPlayersMatchInfo_Loop:\n  lbz r3,0x1(REG_MatchData)\n  cmpwi r3,0x3\n  beq GetPlayersMatchInfo_IncLoop\n#Check if this is the desired player\n  cmpw  REG_Count,REG_Player\n  beq GetPlayersMatchInfo_Exit\n  addi  REG_Count,REG_Count,1\nGetPlayersMatchInfo_IncLoop:\n  addi  REG_MatchData,REG_MatchData,0x24\n  addi  REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt GetPlayersMatchInfo_Loop\n#Not Found\n  li  r3,-1\n  b GetPlayersMatchInfo_Blr\n\nGetPlayersMatchInfo_Exit:\n  mr  r3,REG_MatchData\n  mr  r4,REG_LoopCount\nGetPlayersMatchInfo_Blr:\n  blr\n\n###############################################################\n\nIronManArray:\nblrl\n.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\n.align 2\n\n###############################################################\n\nExit:\n  mr  r3,REG_MinorData\n  restore\n  lwz\tr4, -0x77C0 (r13)\n"
  },
  {
    "path": "ASM/Additional Codes/Game Modes/Chess Melee.asm",
    "content": "#To be inserted at 801b8c74\n.include \"../../Globals.s\"\n\n#Store Pointer to onStartMelee function\n  lwz\tr4, -0x77C0 (r13)\n  addi\tr4, r4, 1752\n  bl  ChessMelee_Init\n  mflr r5\n  stw r5,0x44(r4)\n  b InjectionExit\n\n#region ChessMelee_Init\nChessMelee_Init:\nblrl\n\n.set REG_GObj,31\n.set REG_Data,30\n\n.set DataSize,64\n\nbackup\n\n#Create GObj\n  li  r3,22\n  li  r4,23\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n\n#Alloc Mem\n  li  r3,DataSize\n  branchl r12,HSD_MemAlloc\n  mr  REG_Data,r3\n\n#Zero Data\n  mr  r3,REG_Data\n  li  r4,DataSize\n  branchl r12,ZeroAreaLength\n\n#Attach Data\n  mr  r3,REG_GObj\n  li  r4,14\n  load r5,HSD_Free\n  mr  r6,REG_Data\n  branchl r12,GObj_AddUserData\n\n#Attach Process\n  mr  r3,REG_GObj\n  bl  ChessMelee_Think\n  mflr r4\n  li  r5,23\n  branchl r12,GObj_AddProc\n\nChessMelee_InitExit:\nrestore\nblr\n\n#endregion\n\n#region ChessMelee_Think\nChessMelee_Think:\nblrl\n\n#Registers\n.set REG_GObj,31\n.set REG_GObjData,30\n\n#Data Offsets\n.set GameState,0x0    #byte\n.set FrozenTimer,0x1  #half\n\n#Definitions\n#GameState\n  .set InProgress,0x0\n  .set Frozen,0x1\n\n#Constants\n  .set FreezeFrames, 1 * 60\n\nbackup\n\n#Init Pointers\n  mr  REG_GObj,r3\n  lwz REG_GObjData,0x2C(REG_GObj)\n\n#Check state of game\n  lbz r3,GameState(REG_GObjData)\n  cmpwi r3,InProgress\n  beq ChessMelee_Think_InProgress\n  cmpwi r3,Frozen\n  beq ChessMelee_Think_Frozen\n  b ChessMelee_ThinkExit\n\n#region InProgress\nChessMelee_Think_InProgress:\n.set REG_LoopCount,29\n#Check For Dead Players\n  li  REG_LoopCount,0\n\nChessMelee_Think_InProgressLoop:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne ChessMelee_Think_InProgressIncLoop\n#Get Players Data\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  lwz r3,0x2C(r3)\n#Check If Player is still active (not sleep)\n  lbz r4,0x221F(r3)\n  rlwinm. r4,r4,0,27,27\n  bne ChessMelee_Think_InProgressIncLoop\n#Check if READY,GO is over\n  lbz r4,0x221D(r3)\n  rlwinm. r4,r4,0,28,28\n  bne ChessMelee_Think_InProgressIncLoop\n#Check if Blastzone code is being skipped\n  lbz r4,0x2219(r3)\n  rlwinm. r4,r4,0,25,25\n  beq ChessMelee_Think_InProgressIncLoop\n#Rebirth gets here too, check if NOT rebirth/rebirthWait\n  lwz r4,0x10(r3)\n  cmpwi r4,ASID_Rebirth\n  beq ChessMelee_Think_InProgressIncLoop\n  cmpwi r4,ASID_RebirthWait\n  beq ChessMelee_Think_InProgressIncLoop\n#If in any Star KO State, enter them into DeadUp\n  cmpwi r4,ASID_DeadUpStar\n  beq ChessMelee_Think_InProgressEnterDeadUp\n  cmpwi r4,ASID_DeadUpStarIce\n  beq ChessMelee_Think_InProgressEnterDeadUp\n  cmpwi r4,ASID_DeadUpFall\n  beq ChessMelee_Think_InProgressEnterDeadUp\n  b  ChessMelee_Think_FreezeOtherPlayers\nChessMelee_Think_InProgressEnterDeadUp:\n#Enter DeadUp\n  lwz r3,0x0(r3)\n  branchl r12,0x800d3e40\n  b ChessMelee_Think_FreezeOtherPlayers\n\nChessMelee_Think_InProgressIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt ChessMelee_Think_InProgressLoop\n#No players dead, exit think function\n  b ChessMelee_ThinkExit\n\nChessMelee_Think_FreezeOtherPlayers:\n#Freeze all other players\n.set REG_DeadPlayer,29\n.set REG_LoopCount,28\n.set REG_PlayerGObj,27\n.set REG_PlayerData,26\n\n#Check For Dead Players\n  li  REG_LoopCount,0\nChessMelee_Think_FreezeOtherPlayersLoop:\n#Check if this is the dead player\n  cmpw REG_LoopCount,REG_DeadPlayer\n  bne ChessMelee_Think_FreezeOtherPlayers_NotDeadPlayer\nChessMelee_Think_FreezeOtherPlayers_NotDeadPlayer:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne ChessMelee_Think_FreezeOtherPlayersIncLoop\n#Get Players Data\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n  lwz REG_PlayerData,0x2C(REG_PlayerGObj)\n#Check If Player is still active (not sleep)\n  lbz r4,0x221F(REG_PlayerData)\n  rlwinm. r4,r4,0,27,27\n  bne ChessMelee_Think_FreezeOtherPlayersIncLoop\n#Freeze Player\n  li\tr5,1\n  lbz\tr4,0x2219(REG_PlayerData)\n  rlwimi r4,r5,2,29,29\n  stb\tr4,0x2219(REG_PlayerData)\n#Remove any hitlag\n  li  r4,0\n  stw r4,0x195C(REG_PlayerData)\n  stw r4,0x1958(REG_PlayerData)\n#Skip Blastzone and Hitbox Collision Detection Code\n  lbz r3,0x2219(REG_PlayerData)\n  li  r4,1\n  rlwimi r3,r4,6,25,25\n  stb r3,0x2219(REG_PlayerData)\n#Freeze GFX if not dead\n  lbz r3,0x221E(REG_PlayerData)\n  rlwinm. r0,r3,0,24,24\n  bne ChessMelee_Think_FreezeOtherPlayersIncLoop\n  mr  r3,REG_PlayerGObj\n  branchl r12,0x8005ba40\n\nChessMelee_Think_FreezeOtherPlayersIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt ChessMelee_Think_FreezeOtherPlayersLoop\n\n#Start Frozen Timer\n  li  r3,FreezeFrames\n  sth r3,FrozenTimer(REG_GObjData)\n#Change State\n  li  r3,Frozen\n  stb r3,GameState(REG_GObjData)\n\n  b ChessMelee_ThinkExit\n\n#endregion\n\n#region Frozen\nChessMelee_Think_Frozen:\n#Decrement timer\n  lhz r3,FrozenTimer(REG_GObjData)\n  subi  r3,r3,1\n  sth r3,FrozenTimer(REG_GObjData)\n#Check if up\n  cmpwi r3,0\n  bne ChessMelee_ThinkExit\n\n#Timer up, enter everyone into rebirth\n.set REG_LoopCount,29\n.set REG_PlayerGObj,28\n#Check For Dead Players\n  li  REG_LoopCount,0\nChessMelee_Think_FrozenLoop:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne ChessMelee_Think_FrozenIncLoop\n#Get Players GObj\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n#Check If Player is still active (not sleep)\n  lbz r4,0x221F(r3)\n  rlwinm. r4,r4,0,27,27\n  bne ChessMelee_Think_FrozenIncLoop\n#Remove Items + Etc\n  mr  r3,REG_PlayerGObj\n  branchl r12,0x800d331c\n#Enter into Sleep\n  mr  r3,REG_PlayerGObj\n\tli r4,0x1\n\tbranchl\tr12,0x800bfd9c\n\nChessMelee_Think_FrozenIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt ChessMelee_Think_FrozenLoop\n\n#Enter InProgress Game State\n  li  r3,InProgress\n  stb r3,GameState(REG_GObjData)\n  b ChessMelee_ThinkExit\n\n#endregion\n\nChessMelee_ThinkExit:\nrestore\nblr\n\n#endregion\n\nInjectionExit:\n  li  r6,0\n"
  },
  {
    "path": "ASM/Additional Codes/Game Modes/Chess Melee.s",
    "content": "#To be inserted at 801b8c74\n.include \"../../Globals.s\"\n\n#Store Pointer to onStartMelee function\n  lwz\tr4, -0x77C0 (r13)\n  addi\tr4, r4, 1752\n  bl  ChessMelee_Init\n  mflr r5\n  stw r5,0x44(r4)\n  b InjectionExit\n\n#region ChessMelee_Init\nChessMelee_Init:\nblrl\n\n.set REG_GObj,31\n.set REG_Data,30\n\n.set DataSize,64\n\nbackup\n\n#Create GObj\n  li  r3,22\n  li  r4,23\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n\n#Alloc Mem\n  li  r3,DataSize\n  branchl r12,HSD_MemAlloc\n  mr  REG_Data,r3\n\n#Zero Data\n  mr  r3,REG_Data\n  li  r4,DataSize\n  branchl r12,ZeroAreaLength\n\n#Attach Data\n  mr  r3,REG_GObj\n  li  r4,14\n  load r5,HSD_Free\n  mr  r6,REG_Data\n  branchl r12,GObj_AddUserData\n\n#Attach Process\n  mr  r3,REG_GObj\n  bl  ChessMelee_Think\n  mflr r4\n  li  r5,23\n  branchl r12,GObj_AddProc\n\nChessMelee_InitExit:\nrestore\nblr\n\n#endregion\n\n#region ChessMelee_Think\nChessMelee_Think:\nblrl\n\n#Registers\n.set REG_GObj,31\n.set REG_GObjData,30\n\n#Data Offsets\n.set GameState,0x0    #byte\n.set FrozenTimer,0x1  #half\n\n#Definitions\n#GameState\n  .set InProgress,0x0\n  .set Frozen,0x1\n\n#Constants\n  .set FreezeFrames, 1 * 60\n\nbackup\n\n#Init Pointers\n  mr  REG_GObj,r3\n  lwz REG_GObjData,0x2C(REG_GObj)\n\n#Check state of game\n  lbz r3,GameState(REG_GObjData)\n  cmpwi r3,InProgress\n  beq ChessMelee_Think_InProgress\n  cmpwi r3,Frozen\n  beq ChessMelee_Think_Frozen\n  b ChessMelee_ThinkExit\n\n#region InProgress\nChessMelee_Think_InProgress:\n.set REG_LoopCount,29\n#Check For Dead Players\n  li  REG_LoopCount,0\n\nChessMelee_Think_InProgressLoop:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne ChessMelee_Think_InProgressIncLoop\n#Get Players Data\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  lwz r3,0x2C(r3)\n#Check If Player is still active (not sleep)\n  lbz r4,0x221F(r3)\n  rlwinm. r4,r4,0,27,27\n  bne ChessMelee_Think_InProgressIncLoop\n#Check if READY,GO is over\n  lbz r4,0x221D(r3)\n  rlwinm. r4,r4,0,28,28\n  bne ChessMelee_Think_InProgressIncLoop\n#Check if Blastzone code is being skipped\n  lbz r4,0x2219(r3)\n  rlwinm. r4,r4,0,25,25\n  beq ChessMelee_Think_InProgressIncLoop\n#Rebirth gets here too, check if NOT rebirth/rebirthWait\n  lwz r4,0x10(r3)\n  cmpwi r4,ASID_Rebirth\n  beq ChessMelee_Think_InProgressIncLoop\n  cmpwi r4,ASID_RebirthWait\n  beq ChessMelee_Think_InProgressIncLoop\n#If in any Star KO State, enter them into DeadUp\n  cmpwi r4,ASID_DeadUpStar\n  beq ChessMelee_Think_InProgressEnterDeadUp\n  cmpwi r4,ASID_DeadUpStarIce\n  beq ChessMelee_Think_InProgressEnterDeadUp\n  cmpwi r4,ASID_DeadUpFall\n  beq ChessMelee_Think_InProgressEnterDeadUp\n  b  ChessMelee_Think_FreezeOtherPlayers\nChessMelee_Think_InProgressEnterDeadUp:\n#Enter DeadUp\n  lwz r3,0x0(r3)\n  branchl r12,0x800d3e40\n  b ChessMelee_Think_FreezeOtherPlayers\n\nChessMelee_Think_InProgressIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt ChessMelee_Think_InProgressLoop\n#No players dead, exit think function\n  b ChessMelee_ThinkExit\n\nChessMelee_Think_FreezeOtherPlayers:\n#Freeze all other players\n.set REG_DeadPlayer,29\n.set REG_LoopCount,28\n.set REG_PlayerGObj,27\n.set REG_PlayerData,26\n\n#Check For Dead Players\n  li  REG_LoopCount,0\nChessMelee_Think_FreezeOtherPlayersLoop:\n#Check if this is the dead player\n  cmpw REG_LoopCount,REG_DeadPlayer\n  bne ChessMelee_Think_FreezeOtherPlayers_NotDeadPlayer\nChessMelee_Think_FreezeOtherPlayers_NotDeadPlayer:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne ChessMelee_Think_FreezeOtherPlayersIncLoop\n#Get Players Data\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n  lwz REG_PlayerData,0x2C(REG_PlayerGObj)\n#Check If Player is still active (not sleep)\n  lbz r4,0x221F(REG_PlayerData)\n  rlwinm. r4,r4,0,27,27\n  bne ChessMelee_Think_FreezeOtherPlayersIncLoop\n#Freeze Player\n  li\tr5,1\n  lbz\tr4,0x2219(REG_PlayerData)\n  rlwimi r4,r5,2,29,29\n  stb\tr4,0x2219(REG_PlayerData)\n#Remove any hitlag\n  li  r4,0\n  stw r4,0x195C(REG_PlayerData)\n  stw r4,0x1958(REG_PlayerData)\n#Skip Blastzone and Hitbox Collision Detection Code\n  lbz r3,0x2219(REG_PlayerData)\n  li  r4,1\n  rlwimi r3,r4,6,25,25\n  stb r3,0x2219(REG_PlayerData)\n#Freeze GFX if not dead\n  lbz r3,0x221E(REG_PlayerData)\n  rlwinm. r0,r3,0,24,24\n  bne ChessMelee_Think_FreezeOtherPlayersIncLoop\n  mr  r3,REG_PlayerGObj\n  branchl r12,0x8005ba40\n\nChessMelee_Think_FreezeOtherPlayersIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt ChessMelee_Think_FreezeOtherPlayersLoop\n\n#Start Frozen Timer\n  li  r3,FreezeFrames\n  sth r3,FrozenTimer(REG_GObjData)\n#Change State\n  li  r3,Frozen\n  stb r3,GameState(REG_GObjData)\n\n  b ChessMelee_ThinkExit\n\n#endregion\n\n#region Frozen\nChessMelee_Think_Frozen:\n#Decrement timer\n  lhz r3,FrozenTimer(REG_GObjData)\n  subi  r3,r3,1\n  sth r3,FrozenTimer(REG_GObjData)\n#Check if up\n  cmpwi r3,0\n  bne ChessMelee_ThinkExit\n\n#Timer up, enter everyone into rebirth\n.set REG_LoopCount,29\n.set REG_PlayerGObj,28\n#Check For Dead Players\n  li  REG_LoopCount,0\nChessMelee_Think_FrozenLoop:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne ChessMelee_Think_FrozenIncLoop\n#Get Players GObj\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n#Check If Player is still active (not sleep)\n  lbz r4,0x221F(r3)\n  rlwinm. r4,r4,0,27,27\n  bne ChessMelee_Think_FrozenIncLoop\n#Remove Items + Etc\n  mr  r3,REG_PlayerGObj\n  branchl r12,0x800d331c\n#Enter into Sleep\n  mr  r3,REG_PlayerGObj\n\tli r4,0x1\n\tbranchl\tr12,0x800bfd9c\n\nChessMelee_Think_FrozenIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt ChessMelee_Think_FrozenLoop\n\n#Enter InProgress Game State\n  li  r3,InProgress\n  stb r3,GameState(REG_GObjData)\n  b ChessMelee_ThinkExit\n\n#endregion\n\nChessMelee_ThinkExit:\nrestore\nblr\n\n#endregion\n\nInjectionExit:\n  li  r6,0\n"
  },
  {
    "path": "ASM/Additional Codes/Game Modes/Iron Man/Disable Invisible Melee.asm",
    "content": "#To be inserted at 801ba3d4\n.include \"../../../Globals.s\"\n\n.set  REG_MinorData,31\n.set  REG_IronManData,30\n.set  REG_MatchData,29\n.set IronManData,0x8040a5e0\n\nbackup\n\n  mr  REG_MinorData,r3\n\n#Get Match Data\n  lwz\tREG_MatchData, -0x77C0 (r13)\n  addi\tREG_MatchData, REG_MatchData, 2064\n  load  REG_IronManData,IronManData\n\n#Reset cache\n  branchl r12,0x80018c6c\n  branchl r12,0x80018254\n  li  r3,4\n  branchl r12,0x80017700\n\nIronMan_SetupMatchInit:\n.set  REG_Count,20\n.set  REG_PlayerCount,21\n.set  REG_Port,22\n#Init\n  li  REG_PlayerCount,0\n  li  REG_Count,0\nIronMan_SetupMatchLoop:\n  mr  r3,REG_MatchData\n  mr  r4,REG_Count\n  bl  GetPlayersMatchInfo       #Get the players data\n  cmpwi r3,-1\n  beq IronMan_SetupMatchEnd\n#Set the first character as the current character\n  mr  REG_Port,r4\n  mulli r5,REG_PlayerCount,0x1C\n  add  r5,r5,REG_IronManData\n  lbz r6,0x0(r5)               #Get the next iron man character\n  addi  r5,r5,1\n  lbzx  r5,r6,r5\n  stb r5,0x0(r3)                #Store character to match data\n  stb REG_PlayerCount,0x3(r3)   #Store costume to match data\n#Get Prelod Table\n  load  r3,0x8043208c\n  mulli r4,REG_Port,0x8\n  add r4,r3,r4\n  stw r5,0x0(r4)                 #Store to preload table\n  stb REG_PlayerCount,0x4(r4)                  #Store costume\n  addi  REG_PlayerCount,REG_PlayerCount,1\n\nIronMan_SetupMatchIncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,6\n  blt IronMan_SetupMatchLoop\n\nIronMan_SetupMatchEnd:\n#Now get a random stage\n  branchl r12,0x8025bbd4\n  sth r3,0x16(REG_MatchData)\n  load  r4,0x80432088\n  stw r3,0x0(r4)                #Store to prelaod\n#Request preload\n  branchl r12,0x80018254\n\n#Store Pointer to onStartMelee function\n  lwz\tr4, -0x77C0 (r13)\n  addi\tr4, r4, 2064\n  bl  IronMan_Init\n  mflr r5\n  stw r5,0x4C(r4)\n  b InjectionExit\n\n#region IronMan_Init\nIronMan_Init:\nblrl\n\n.set REG_GObj,31\n.set REG_Data,30\n\n.set DataSize,64\n\nbackup\n\n#Create GObj\n  li  r3,22\n  li  r4,0\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n\n#Alloc Mem\n  li  r3,DataSize\n  branchl r12,HSD_MemAlloc\n  mr  REG_Data,r3\n\n#Zero Data\n  mr  r3,REG_Data\n  li  r4,DataSize\n  branchl r12,ZeroAreaLength\n\n#Attach Data\n  mr  r3,REG_GObj\n  li  r4,14\n  load r5,HSD_Free\n  mr  r6,REG_Data\n  branchl r12,GObj_AddUserData\n\n#Attach Process\n  mr  r3,REG_GObj\n  bl  IronMan_Think\n  mflr r4\n  li  r5,23\n  branchl r12,GObj_AddProc\n\nIronMan_InitExit:\nrestore\nblr\n\n#endregion\n\n#region IronMan_Think\nIronMan_Think:\nblrl\n\n#Registers\n.set  REG_GObj,31\n.set  REG_GObjData,30\n.set  REG_IronManData,29\n\n#Offsets\n.set OFST_EndTimer,0x0\n.set OFST_FirstFrame,0x1\n.set OFST_TextPointers,0x4\n\n#Constants\n.set EndTimer,60\n\nbackup\n\n#Init Pointers\n  mr  REG_GObj,r3\n  lwz REG_GObjData,0x2C(REG_GObj)\n  load  REG_IronManData,IronManData\n\n#Restore stocks on the first frame\n  lbz r3,OFST_FirstFrame(REG_GObjData)\n  cmpwi r3,0\n  bne IronMan_Think_SkipFirstFrame\nIronMan_Think_AdjustStocksInit:\n.set  REG_Count,20\n.set  REG_SomeoneDied,21\n.set  REG_PlayerCount,22\n.set  REG_Temp,23\n.set  REG_Text,24\n#Init\n  li  REG_PlayerCount,0\n  li  REG_Count,0\n  li  REG_SomeoneDied,0\nIronMan_Think_AdjustStocksLoop:\n#Check if exists\n  mr  r3,REG_Count\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  cmpwi r3,0\n  beq IronMan_Think_AdjustStocksIncLoop\n#Increment player count\n  addi  REG_PlayerCount,REG_PlayerCount,1\n#Update stocks\n  subi  r4,REG_PlayerCount,1\n  mulli r4,r4,0x1C\n  add REG_Temp,r4,REG_IronManData\n  lbz r4,0x1B(REG_Temp)\n  mr  r3,REG_Count\n  branchl r12,0x80033c60\n#Create Text\n  li  r3,2\n  load  r4,0x804a1f58\n  lwz r4,0x0(r4)\n  branchl r12,Text_CreateTextStruct\n  mr  REG_Text,r3\n  addi r3,REG_GObjData,OFST_TextPointers\n  mulli r4,REG_Count,4\n  stwx  REG_Text,r3,r4\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x1\n\tstb r4,0x49(REG_Text)\n#SET TEXT TO CENTER AROUND X LOCATION\n\tli r4,0x1\n\tstb r4,0x4A(REG_Text)\n#Update Text Contents\n\tload\tr4,0x804a0ff0\n\tmulli\tr3,REG_Count,0xC\t\t\t#HUD Info is 0xC Long Per Player\n\tlfsx\tf1,r3,r4\t\t\t        #Get This Players HUD Info\n  bl  ScorePosition\n  mflr  r5\n  lfs f2,0x0(r5)\n  mr  r3,REG_Text\n  bl  ScoreText\n  mflr  r4\n  lbz r5,0x0(REG_Temp)\n  extsb r5,r5\n  addi  r5,r5,1\n  branchl r12,Text_InitializeSubtext\n#Update Size\n  mr  r3,REG_Text\n  li  r4,0\n  lfs\tf1, -0x1DB4 (rtoc)\n  lfs\tf2, -0x1DB4 (rtoc)\n  branchl r12,Text_UpdateSubtextSize\nIronMan_Think_AdjustStocksIncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,6\n  blt IronMan_Think_AdjustStocksLoop\n#Set as not first frame\n  li  r3,1\n  stb r3,OFST_FirstFrame(REG_GObjData)\nIronMan_Think_SkipFirstFrame:\n\n#Check if match is frozen\n  lbz r3,OFST_EndTimer(REG_GObjData)\n  cmpwi r3,0\n  beq IronMan_Think_NotFrozen\n#Subtract by 1\n  subi  r3,r3,1\n  stb r3,OFST_EndTimer(REG_GObjData)\n  cmpwi r3,0\n  bgt IronMan_ThinkExit\n#Fade screen\n  li  r3,60\n  branchl r12,0x8002063c\n#Destroy GObj\n  mr  r3,REG_GObj\n  branchl r12,GObj_Destroy\n  b IronMan_ThinkExit\nIronMan_Think_NotFrozen:\n\nIronMan_Think_DeathCheckInit:\n.set  REG_Count,20\n.set  REG_SomeoneDied,21\n.set  REG_PlayerCount,22\n#Init\n  li  REG_PlayerCount,0\n  li  REG_Count,0\n  li  REG_SomeoneDied,0\nIronMan_Think_DeathCheckLoop:\n#Check if exists\n  mr  r3,REG_Count\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  cmpwi r3,0\n  beq IronMan_Think_DeathCheckIncLoop\n#Increment player count\n  addi  REG_PlayerCount,REG_PlayerCount,1\n#Update stock counter in ironman data\n  mr  r3,REG_Count\n  branchl r12,PlayerBlock_LoadStocksLeft\n  subi  r4,REG_PlayerCount,1\n  mulli r4,r4,0x1C\n  add r4,r4,REG_IronManData\n  stb r3,0x1B(r4)\n#Check if no stocks left\n  cmpwi r3,0\n  bgt IronMan_Think_DeathCheckIncLoop\n#Set someonedied flag\n  li  REG_SomeoneDied,1\n#Decrement their ironman index\n  lbz r3,0x0(r4)\n  subi  r3,r3,1\n  stb r3,0x0(r4)\n#Give them max stocks\n  lwz\tr3, -0x77C0 (r13)\n  lbz\tr3,6228(r3)\n  stb r3,0x1B(r4)\n#Update Text\n#Get text pointer\n  addi r3,REG_GObjData,OFST_TextPointers\n  mulli r4,REG_Count,4\n  lwzx  r3,r3,r4\n#Get iron man index\n  subi  r4,REG_PlayerCount,1\n  mulli r4,r4,0x1C\n  add REG_Temp,r4,REG_IronManData\n  li  r4,0\n  bl  ScoreText\n  mflr  r5\n  lbz r6,0x0(REG_Temp)\n  extsb r6,r6\n  addi  r6,r6,1\n  branchl r12,Text_UpdateSubtextContents\n#Check if theyre completely dead\n  lbz r3,0x0(REG_Temp)\n  extsb r3,r3\n  cmpwi r3,0\n  bge IronMan_Think_DeathCheckIncLoop\n#This player is out of characters, display GAME\n  li  r3,5\n  branchl r12,0x8016b33c\n#Delay\n  li  r3,40\n  branchl r12,0x8016b378\n#End game\n  branchl r12,0x8016b328\n#Destroy GObj\n  mr  r3,REG_GObj\n  branchl r12,GObj_Destroy\n  b IronMan_ThinkExit\nIronMan_Think_DeathCheckIncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,6\n  blt IronMan_Think_DeathCheckLoop\n\n#Check if someone died\n  cmpwi REG_SomeoneDied,0\n  beq IronMan_ThinkExit\n#Start ending this match now\n  li  r3,EndTimer\n  stb r3,OFST_EndTimer(REG_GObjData)\n#Freeze Game\n  li  r3,8\n  branchl r12,0x8016b33c\n  branchl r12,0x8016b328\n\nIronMan_ThinkExit:\nrestore\nblr\n\n#endregion\n\n###############################################################\nScoreText:\nblrl\n.string \"%d Left\"\n.align 2\n\nScorePosition:\nblrl\n.float -15.5\n###############################################################\nGetPlayersMatchInfo:\n.set  REG_LoopCount,9\n.set  REG_Count,10\n.set  REG_MatchData,11\n.set  REG_Player,12\n\n#Backup\n  addi  REG_MatchData,r3,0x68\n  mr  REG_Player,r4\n  li  REG_Count,0\n  li  REG_LoopCount,0\n\nGetPlayersMatchInfo_Loop:\n  lbz r3,0x1(REG_MatchData)\n  cmpwi r3,0x3\n  beq GetPlayersMatchInfo_IncLoop\n#Check if this is the desired player\n  cmpw  REG_Count,REG_Player\n  beq GetPlayersMatchInfo_Exit\n  addi  REG_Count,REG_Count,1\nGetPlayersMatchInfo_IncLoop:\n  addi  REG_MatchData,REG_MatchData,0x24\n  addi  REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt GetPlayersMatchInfo_Loop\n#Not Found\n  li  r3,-1\n  b GetPlayersMatchInfo_Blr\n\nGetPlayersMatchInfo_Exit:\n  mr  r3,REG_MatchData\n  mr  r4,REG_LoopCount\nGetPlayersMatchInfo_Blr:\n  blr\n\n###############################################################\n\nInjectionExit:\n  mr  r3,REG_MinorData\n  restore\n  li  r6,0\n"
  },
  {
    "path": "ASM/Additional Codes/Game Modes/Iron Man/Initialize Lineups.asm",
    "content": "#To be inserted at 801ba344\n.include \"../../../Globals.s\"\n\n.set  REG_MinorData,31\n.set  REG_IronManData,30\n.set  REG_MatchData,29\n\n.set IronManData,0x8040a5e0\n\nbackup\n\n#Save r3, cant get it otherwise\n  mr  REG_MinorData,r3\n#Get iron man data\n  load  REG_IronManData,IronManData\n#Get Match data\n  lwz REG_MatchData,0x14(REG_MinorData)\n\nIronMan_InitLineupInit:\n.set  REG_Count,20\n#Init\n  li  REG_Count,0\nIronMan_InitLineupLoop:\n  mr  r3,REG_MatchData\n  mr  r4,REG_Count\n  bl  GetPlayersMatchInfo       #Get the players data\n  cmpwi r3,-1\n  beq IronMan_InitLineupEnd\n#Create Lineup\n  mulli r3,REG_Count,0x1C\n  add r3,r3,REG_IronManData\n  bl  CreateLineupArray\n\nIronMan_InitLineupIncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,6\n  blt IronMan_InitLineupLoop\nIronMan_InitLineupEnd:\n\n#Set match bits to skip game end checks (doing this myself)\n  li  r3,0x80\n  stb r3,0x5(REG_MatchData)\n#Set score display on\n\n\n#Next Minor in-game\n  load  r3,SceneController\n  li  r4,1\n  stb r4,Scene.CurrentMinor(r3)\nb Exit\n\n###############################################################\nCreateLineupArray:\n.set  REG_Array,31\n.set  REG_BaseArray,30\n.set  REG_Index,29\n\n#backup\n  backup\n  mr  REG_Array,r3\n#Initialize Runtime Index\n  li  r3,25\n  stb r3,0x0(REG_Array)\n#Initialzie Stock Counter\n  lwz\tr3, -0x77C0 (r13)\n  lbz\tr3,6228(r3)\n  stb r3,0x1B(REG_Array)\n  addi  REG_Array,REG_Array,1\n#Get base array\n  bl  IronManArray\n  mflr  REG_BaseArray\n#Copy Lineup Array\n  mr  r3,REG_Array\n  mr  r4,REG_BaseArray\n  li  r5,26\n  branchl r12,memcpy\n\n#Initialize Shuffle Index\n  li  REG_Index,25\nCreateLineupArray_Loop:\n#Get random number between 0-25\n  li  r3,26\n  branchl r12,HSD_Randi\n#Swap the current index with this element\n  lbzx  r4,r3,REG_Array\n  lbzx  r5,REG_Index,REG_Array\n  stbx  r4,REG_Index,REG_Array\n  stbx  r5,r3,REG_Array\n#Decrement index\n  subi  REG_Index,REG_Index,1\n  cmpwi REG_Index,0\n  bge CreateLineupArray_Loop\n\nCreateLineupArray_Exit:\n  restore\n  blr\n\n###############################################################\nGetPlayersMatchInfo:\n.set  REG_LoopCount,9\n.set  REG_Count,10\n.set  REG_MatchData,11\n.set  REG_Player,12\n\n#Backup\n  addi  REG_MatchData,r3,0x70\n  mr  REG_Player,r4\n  li  REG_Count,0\n  li  REG_LoopCount,0\n\nGetPlayersMatchInfo_Loop:\n  lbz r3,0x1(REG_MatchData)\n  cmpwi r3,0x3\n  beq GetPlayersMatchInfo_IncLoop\n#Check if this is the desired player\n  cmpw  REG_Count,REG_Player\n  beq GetPlayersMatchInfo_Exit\n  addi  REG_Count,REG_Count,1\nGetPlayersMatchInfo_IncLoop:\n  addi  REG_MatchData,REG_MatchData,0x24\n  addi  REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt GetPlayersMatchInfo_Loop\n#Not Found\n  li  r3,-1\n  b GetPlayersMatchInfo_Blr\n\nGetPlayersMatchInfo_Exit:\n  mr  r3,REG_MatchData\n  mr  r4,REG_LoopCount\nGetPlayersMatchInfo_Blr:\n  blr\n\n###############################################################\n\nIronManArray:\nblrl\n.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\n.align 2\n\n###############################################################\n\nExit:\n  mr  r3,REG_MinorData\n  restore\n  lwz\tr4, -0x77C0 (r13)\n"
  },
  {
    "path": "ASM/Additional Codes/Game Modes/Iron Man/Load Next Match.asm",
    "content": "#To be inserted at 801ba410\n.include \"../../../Globals.s\"\n\n.set  REG_MatchData,31\n.set  REG_IronManData,30\n.set  IronManData,0x8040a5e0\n\nbackup\n\n#Get Match Data\n  lwz REG_MatchData,-0x20(r3)\n  load  REG_IronManData,IronManData\n\n#Check if LRAStarted\n  lwz r3,0x14(r3)\n  lbz r3,0x10(r3)\n  cmpwi r3,7\n  beq ReturnToCSS\n\n#Set the first character as the current character\n  addi  r5,REG_IronManData,0x0\n  lbz r6,0x0(r5)               #Get the next iron man character\n  extsb r0,r6\n  cmpwi r0,-1\n  beq ReturnToCSS\n#Now do p2\n  addi  r5,REG_IronManData,0x1C\n  lbz r6,0x0(r5)               #Get the next iron man character\n  extsb r0,r6\n  cmpwi r0,-1\n  beq ReturnToCSS\n\n#Load match scene again\n  li  r3,2\n  branchl r12,0x801a42a0\n  b InjectionExit\n\nReturnToCSS:\n  li  r3,0\n  branchl r12,0x801a42a0\n  b InjectionExit\n\nInjectionExit:\n  restore\n"
  },
  {
    "path": "ASM/Additional Codes/Game Modes/Rotations Melee.asm",
    "content": "#To be inserted at 801b9090\n.include \"../../Globals.s\"\n\n#Store Pointer to onStartMelee function\n  lwz\tr4, -0x77C0 (r13)\n  addi\tr4, r4, 3992\n  bl  Rotations_Init\n  mflr r5\n  stw r5,0x44(r4)\n  b InjectionExit\n\n#region Rotations_Init\nRotations_Init:\nblrl\n\n.set REG_GObj,31\n.set REG_Data,30\n\n.set DataSize,64\n\nbackup\n\n#Create GObj\n  li  r3,22\n  li  r4,23\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n\n#Alloc Mem\n  li  r3,DataSize\n  branchl r12,HSD_MemAlloc\n  mr  REG_Data,r3\n\n#Zero Data\n  mr  r3,REG_Data\n  li  r4,DataSize\n  branchl r12,ZeroAreaLength\n\n#Attach Data\n  mr  r3,REG_GObj\n  li  r4,14\n  load r5,HSD_Free\n  mr  r6,REG_Data\n  branchl r12,GObj_AddUserData\n\n#Attach Process\n  mr  r3,REG_GObj\n  bl  Rotations_Think\n  mflr r4\n  li  r5,23\n  branchl r12,GObj_AddProc\n\nRotations_InitExit:\nrestore\nblr\n\n#endregion\n\n#region Rotations_Think\nRotations_Think:\nblrl\n\n#Registers\n.set REG_GObj,31\n.set REG_GObjData,30\n\n#Data Offsets\n.set GameState,0x0    #byte\n.set P1Slot,0x1       #byte\n.set P2Slot,0x2       #byte\n.set LastPlayerSpawned,0x3  #byte\n\n#Definitions\n#GameState\n  .set FirstFrame,0x0\n  .set InProgress,0x1\n\n#Constants\n  .set FreezeFrames, 1 * 60\n\nbackup\n\n#Init Pointers\n  mr  REG_GObj,r3\n  lwz REG_GObjData,0x2C(REG_GObj)\n\n#Check state of game\n  lbz r3,GameState(REG_GObjData)\n  cmpwi r3,FirstFrame\n  beq Rotations_Think_FirstFrame\n  cmpwi r3,InProgress\n  beq Rotations_Think_InProgress\n\n#region FirstFrame\nRotations_Think_FirstFrame:\n#Ensure over 2 players are present\n  branchl r12,0x8016b558\n  cmpwi r3,3\n  bge Rotations_Think_FirstFrameContinue\n#Destroy Think Function\n  mr  r3,REG_GObj\n  branchl r12,0x80390228\n  b Rotations_ThinkExit\n\nRotations_Think_FirstFrameContinue:\n.set REG_LoopCount,29\n.set REG_PlayerSlotIndex,28\n#Init Loop\n  li  REG_LoopCount,0\n  li  REG_PlayerSlotIndex,0\nRotations_Think_FirstFrameLoop:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne Rotations_Think_FirstFrameIncLoop\n#Player exists, store to data\n  addi r3,REG_GObjData,P1Slot\n  stbx REG_LoopCount,REG_PlayerSlotIndex,r3\n#Store as last player spawned\n  stb REG_LoopCount,LastPlayerSpawned(REG_GObjData)\n#Now do next player\n  addi REG_PlayerSlotIndex,REG_PlayerSlotIndex,1\n#Check if finished doing both players\n  cmpwi REG_PlayerSlotIndex,2\n  bge Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop\nRotations_Think_FirstFrameIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt Rotations_Think_FirstFrameLoop\n\n#Now sleep the other players\nRotations_Think_FirstFrameSleepRemainingPlayersLoop:\n.set REG_PlayerGObj,27\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop\n#Get players GObj\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n#Sleep player\n  branchl r12,0x800bfd04\n#Check if they have a follower\n  lwz r3,0x2C(REG_PlayerGObj)\n  lbz r3,0x2222(r3)\n  rlwinm.\tr0, r3, 30, 31, 31\n  beq Rotations_Think_FirstFrameSleepRemainingPlayers_DestroyHUD\n#Get Follower GObj\n  mr  r3,REG_LoopCount\n  li  r4,1\n  branchl r12,0x8003418c\n#SLeep them as well\n  branchl r12,0x800bfd04\nRotations_Think_FirstFrameSleepRemainingPlayers_DestroyHUD:\n#Destroy their percent HUD\n  load r3,0x804a10c8\n  mulli r4,REG_LoopCount,100\n  add r3,r3,r4\n  lbz\tr4, 0x0010 (r3)\n  li  r5,1\n  rlwimi r4,r5,7,24,24\n  rlwimi r4,r5,6,25,25\n  stb\tr4, 0x0010 (r3)\n\nRotations_Think_FirstFrameSleepRemainingPlayersIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt Rotations_Think_FirstFrameSleepRemainingPlayersLoop\n\n#Change state to every frame\n  li  r3,InProgress\n  stb r3,GameState(REG_GObjData)\n\n  b Rotations_ThinkExit\n#endregion\n\n#region InProgress\nRotations_Think_InProgress:\n#Check For Dead Players\n.set REG_PlayerSlot,29\n.set REG_PlayerSlotIndex,28\n.set REG_PlayerGObj,27\n#Init Loop\n  li  REG_PlayerSlotIndex,0\n\n#################################\n## Check For Dead Players Loop ##\n#################################\nRotations_Think_InProgressLoop:\n#Get Players Slot\n  addi r3,REG_GObjData,P1Slot\n  lbzx  REG_PlayerSlot,REG_PlayerSlotIndex,r3\n#Get Players GObj\n  mr  r3,REG_PlayerSlot\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n  lwz r3,0x2C(r3)\n#Check If Player is still active (not sleep)\n  lbz r4,0x221F(r3)\n  rlwinm. r4,r4,0,27,27\n  bne Rotations_Think_InProgressIncLoop\n#Check if READY,GO is over\n  lbz r4,0x221D(r3)\n  rlwinm. r4,r4,0,28,28\n  bne Rotations_Think_InProgressIncLoop\n#Check if Blastzone code is being skipped\n  lbz r4,0x2219(r3)\n  rlwinm. r4,r4,0,25,25\n  beq Rotations_Think_InProgressIncLoop\n#Rebirth gets here too, check if NOT rebirth/rebirthWait\n  lwz r4,0x10(r3)\n  cmpwi r4,ASID_Rebirth\n  beq Rotations_Think_InProgressIncLoop\n  cmpwi r4,ASID_RebirthWait\n  beq Rotations_Think_InProgressIncLoop\n#If in any Star KO State, enter them into DeadUp\n  cmpwi r4,ASID_DeadUpStar\n  beq Rotations_Think_InProgressEnterDeadUp\n  cmpwi r4,ASID_DeadUpStarIce\n  beq Rotations_Think_InProgressEnterDeadUp\n  cmpwi r4,ASID_DeadUpFall\n  beq Rotations_Think_InProgressEnterDeadUp\n  b  Rotations_Think_InProgressCheckDeadFrame\nRotations_Think_InProgressEnterDeadUp:\n#Enter DeadUp\n  mr  r3,REG_PlayerGObj\n  branchl r12,0x800d3e40\n  b Rotations_Think_InProgressIncLoop\nRotations_Think_InProgressCheckDeadFrame:\n#Here we know the player is in a dead state\n#Ensure he is in frame X of the dead animation\n  lwz r3,0x2C(REG_PlayerGObj)\n  lwz r4,0x2340(r3)\n  cmpwi r4,1\n  bgt Rotations_Think_InProgressIncLoop\n\n#################################\n## Search For Next Player Loop ##\n#################################\nRotations_Think_InProgressSearchForNextPlayer:\n.set REG_LoopCount,26\n.set REG_OtherPlayerSlot,25\n.set REG_LastPlayerSpawned,24\n\n#Get other player\n  xori r3,REG_PlayerSlotIndex,0x1\n  addi r4,REG_GObjData,P1Slot\n  lbzx REG_OtherPlayerSlot,r3,r4\n#Loop starts at LastPlayerSpawned+1\n  lbz REG_LastPlayerSpawned,LastPlayerSpawned(REG_GObjData)\n  mr REG_LoopCount,REG_LastPlayerSpawned\n  b Rotations_Think_InProgressSearchForNextPlayerIncLoop\nRotations_Think_InProgressSearchForNextPlayerLoop:\n#Player who just died is in REG_PlayerSlot\n#Player who is alive is in REG_OtherPlayerSlot\n#Check if player is present\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne Rotations_Think_InProgressSearchForNextPlayerIncLoop\n#Ensure this isnt the player who just died\n  cmpw REG_LoopCount,REG_PlayerSlot\n  beq Rotations_Think_InProgressSearchForNextPlayerIncLoop\n#Ensure this isnt the other player\n  cmpw REG_LoopCount,REG_OtherPlayerSlot\n  beq Rotations_Think_InProgressSearchForNextPlayerIncLoop\n#This is a unique player, check if they have stock remainings\n  mr  r3,REG_LoopCount\n  branchl r12,0x80033bd8\n  cmpwi r3,0\n  ble Rotations_Think_InProgressSearchForNextPlayerIncLoop\n#Get GObj First\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n#Respawn\n\tli r4,0x1\n\tbranchl\tr12,0x800bfd9c\n#Save their slot to the GObjData\n  addi r3,REG_GObjData,P1Slot\n  stbx REG_LoopCount,REG_PlayerSlotIndex,r3\n#Save this as the last player spawned\n  stb REG_LoopCount,LastPlayerSpawned(REG_GObjData)\n#Now enter the recently deceased player into perm sleep\n  mr  r3,REG_PlayerGObj\n  branchl r12,0x800bfd04\n#Check if they have a follower\n  lwz r4,0x2C(REG_PlayerGObj)\n  lbz r3,0x2222(r4)\n  rlwinm.\tr0, r3, 30, 31, 31\n  beq Rotations_Think_InProgressIncLoop\n#Get Follower GObj\n  lbz r3,0xC(r4)\n  li  r4,1\n  branchl r12,0x8003418c\n#SLeep them as well\n  branchl r12,0x800bfd04\n  b Rotations_Think_InProgressIncLoop\nRotations_Think_InProgressSearchForNextPlayerIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt Rotations_Think_InProgressSearchForNextPlayerIncLoopCheckIfDone\n#Player count is over 6, loop back to 0\n  li  REG_LoopCount,0\nRotations_Think_InProgressSearchForNextPlayerIncLoopCheckIfDone:\n#Now check if we did a full loop\n  cmpw REG_LoopCount,REG_LastPlayerSpawned\n  bne Rotations_Think_InProgressSearchForNextPlayerLoop\n#If we get here, no other players are reported as alive, so do nothing for normal respawn behvior\n\nRotations_Think_InProgressIncLoop:\n  addi REG_PlayerSlotIndex,REG_PlayerSlotIndex,1\n  cmpwi REG_PlayerSlotIndex,2\n  blt Rotations_Think_InProgressLoop\n#Neither player is dead, exit think function\n  b Rotations_ThinkExit\n\n#endregion\n\nRotations_ThinkExit:\nrestore\nblr\n\n#endregion\n\nInjectionExit:\n  li  r6,0\n"
  },
  {
    "path": "ASM/Additional Codes/Game Modes/Rotations Melee.s",
    "content": "#To be inserted at 801b9090\n.include \"../../Globals.s\"\n\n#Store Pointer to onStartMelee function\n  lwz\tr4, -0x77C0 (r13)\n  addi\tr4, r4, 3992\n  bl  Rotations_Init\n  mflr r5\n  stw r5,0x44(r4)\n  b InjectionExit\n\n#region Rotations_Init\nRotations_Init:\nblrl\n\n.set REG_GObj,31\n.set REG_Data,30\n\n.set DataSize,64\n\nbackup\n\n#Create GObj\n  li  r3,22\n  li  r4,23\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n\n#Alloc Mem\n  li  r3,DataSize\n  branchl r12,HSD_MemAlloc\n  mr  REG_Data,r3\n\n#Zero Data\n  mr  r3,REG_Data\n  li  r4,DataSize\n  branchl r12,ZeroAreaLength\n\n#Attach Data\n  mr  r3,REG_GObj\n  li  r4,14\n  load r5,HSD_Free\n  mr  r6,REG_Data\n  branchl r12,GObj_AddUserData\n\n#Attach Process\n  mr  r3,REG_GObj\n  bl  Rotations_Think\n  mflr r4\n  li  r5,23\n  branchl r12,GObj_AddProc\n\nRotations_InitExit:\nrestore\nblr\n\n#endregion\n\n#region Rotations_Think\nRotations_Think:\nblrl\n\n#Registers\n.set REG_GObj,31\n.set REG_GObjData,30\n\n#Data Offsets\n.set GameState,0x0    #byte\n.set P1Slot,0x1       #byte\n.set P2Slot,0x2       #byte\n.set LastPlayerSpawned,0x3  #byte\n\n#Definitions\n#GameState\n  .set FirstFrame,0x0\n  .set InProgress,0x1\n\n#Constants\n  .set FreezeFrames, 1 * 60\n\nbackup\n\n#Init Pointers\n  mr  REG_GObj,r3\n  lwz REG_GObjData,0x2C(REG_GObj)\n\n#Check state of game\n  lbz r3,GameState(REG_GObjData)\n  cmpwi r3,FirstFrame\n  beq Rotations_Think_FirstFrame\n  cmpwi r3,InProgress\n  beq Rotations_Think_InProgress\n\n#region FirstFrame\nRotations_Think_FirstFrame:\n#Ensure over 2 players are present\n  branchl r12,0x8016b558\n  cmpwi r3,3\n  bge Rotations_Think_FirstFrameContinue\n#Destroy Think Function\n  mr  r3,REG_GObj\n  branchl r12,0x80390228\n  b Rotations_ThinkExit\n\nRotations_Think_FirstFrameContinue:\n.set REG_LoopCount,29\n.set REG_PlayerSlotIndex,28\n#Init Loop\n  li  REG_LoopCount,0\n  li  REG_PlayerSlotIndex,0\nRotations_Think_FirstFrameLoop:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne Rotations_Think_FirstFrameIncLoop\n#Player exists, store to data\n  addi r3,REG_GObjData,P1Slot\n  stbx REG_LoopCount,REG_PlayerSlotIndex,r3\n#Store as last player spawned\n  stb REG_LoopCount,LastPlayerSpawned(REG_GObjData)\n#Now do next player\n  addi REG_PlayerSlotIndex,REG_PlayerSlotIndex,1\n#Check if finished doing both players\n  cmpwi REG_PlayerSlotIndex,2\n  bge Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop\nRotations_Think_FirstFrameIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt Rotations_Think_FirstFrameLoop\n\n#Now sleep the other players\nRotations_Think_FirstFrameSleepRemainingPlayersLoop:\n.set REG_PlayerGObj,27\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop\n#Get players GObj\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n#Sleep player\n  branchl r12,0x800bfd04\n#Check if they have a follower\n  lwz r3,0x2C(REG_PlayerGObj)\n  lbz r3,0x2222(r3)\n  rlwinm.\tr0, r3, 30, 31, 31\n  beq Rotations_Think_FirstFrameSleepRemainingPlayers_DestroyHUD\n#Get Follower GObj\n  mr  r3,REG_LoopCount\n  li  r4,1\n  branchl r12,0x8003418c\n#SLeep them as well\n  branchl r12,0x800bfd04\nRotations_Think_FirstFrameSleepRemainingPlayers_DestroyHUD:\n#Destroy their percent HUD\n  load r3,0x804a10c8\n  mulli r4,REG_LoopCount,100\n  add r3,r3,r4\n  lbz\tr4, 0x0010 (r3)\n  li  r5,1\n  rlwimi r4,r5,7,24,24\n  rlwimi r4,r5,6,25,25\n  stb\tr4, 0x0010 (r3)\n\nRotations_Think_FirstFrameSleepRemainingPlayersIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt Rotations_Think_FirstFrameSleepRemainingPlayersLoop\n\n#Change state to every frame\n  li  r3,InProgress\n  stb r3,GameState(REG_GObjData)\n\n  b Rotations_ThinkExit\n#endregion\n\n#region InProgress\nRotations_Think_InProgress:\n#Check For Dead Players\n.set REG_PlayerSlot,29\n.set REG_PlayerSlotIndex,28\n.set REG_PlayerGObj,27\n#Init Loop\n  li  REG_PlayerSlotIndex,0\n\n#################################\n## Check For Dead Players Loop ##\n#################################\nRotations_Think_InProgressLoop:\n#Get Players Slot\n  addi r3,REG_GObjData,P1Slot\n  lbzx  REG_PlayerSlot,REG_PlayerSlotIndex,r3\n#Get Players GObj\n  mr  r3,REG_PlayerSlot\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n  lwz r3,0x2C(r3)\n#Check If Player is still active (not sleep)\n  lbz r4,0x221F(r3)\n  rlwinm. r4,r4,0,27,27\n  bne Rotations_Think_InProgressIncLoop\n#Check if READY,GO is over\n  lbz r4,0x221D(r3)\n  rlwinm. r4,r4,0,28,28\n  bne Rotations_Think_InProgressIncLoop\n#Check if Blastzone code is being skipped\n  lbz r4,0x2219(r3)\n  rlwinm. r4,r4,0,25,25\n  beq Rotations_Think_InProgressIncLoop\n#Rebirth gets here too, check if NOT rebirth/rebirthWait\n  lwz r4,0x10(r3)\n  cmpwi r4,ASID_Rebirth\n  beq Rotations_Think_InProgressIncLoop\n  cmpwi r4,ASID_RebirthWait\n  beq Rotations_Think_InProgressIncLoop\n#If in any Star KO State, enter them into DeadUp\n  cmpwi r4,ASID_DeadUpStar\n  beq Rotations_Think_InProgressEnterDeadUp\n  cmpwi r4,ASID_DeadUpStarIce\n  beq Rotations_Think_InProgressEnterDeadUp\n  cmpwi r4,ASID_DeadUpFall\n  beq Rotations_Think_InProgressEnterDeadUp\n  b  Rotations_Think_InProgressCheckDeadFrame\nRotations_Think_InProgressEnterDeadUp:\n#Enter DeadUp\n  mr  r3,REG_PlayerGObj\n  branchl r12,0x800d3e40\n  b Rotations_Think_InProgressIncLoop\nRotations_Think_InProgressCheckDeadFrame:\n#Here we know the player is in a dead state\n#Ensure he is in frame X of the dead animation\n  lwz r3,0x2C(REG_PlayerGObj)\n  lwz r4,0x2340(r3)\n  cmpwi r4,1\n  bgt Rotations_Think_InProgressIncLoop\n\n#################################\n## Search For Next Player Loop ##\n#################################\nRotations_Think_InProgressSearchForNextPlayer:\n.set REG_LoopCount,26\n.set REG_OtherPlayerSlot,25\n.set REG_LastPlayerSpawned,24\n\n#Get other player\n  xori r3,REG_PlayerSlotIndex,0x1\n  addi r4,REG_GObjData,P1Slot\n  lbzx REG_OtherPlayerSlot,r3,r4\n#Loop starts at LastPlayerSpawned+1\n  lbz REG_LastPlayerSpawned,LastPlayerSpawned(REG_GObjData)\n  mr REG_LoopCount,REG_LastPlayerSpawned\n  b Rotations_Think_InProgressSearchForNextPlayerIncLoop\nRotations_Think_InProgressSearchForNextPlayerLoop:\n#Player who just died is in REG_PlayerSlot\n#Player who is alive is in REG_OtherPlayerSlot\n#Check if player is present\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne Rotations_Think_InProgressSearchForNextPlayerIncLoop\n#Ensure this isnt the player who just died\n  cmpw REG_LoopCount,REG_PlayerSlot\n  beq Rotations_Think_InProgressSearchForNextPlayerIncLoop\n#Ensure this isnt the other player\n  cmpw REG_LoopCount,REG_OtherPlayerSlot\n  beq Rotations_Think_InProgressSearchForNextPlayerIncLoop\n#This is a unique player, check if they have stock remainings\n  mr  r3,REG_LoopCount\n  branchl r12,0x80033bd8\n  cmpwi r3,0\n  ble Rotations_Think_InProgressSearchForNextPlayerIncLoop\n#Get GObj First\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n#Respawn\n\tli r4,0x1\n\tbranchl\tr12,0x800bfd9c\n#Save their slot to the GObjData\n  addi r3,REG_GObjData,P1Slot\n  stbx REG_LoopCount,REG_PlayerSlotIndex,r3\n#Save this as the last player spawned\n  stb REG_LoopCount,LastPlayerSpawned(REG_GObjData)\n#Now enter the recently deceased player into perm sleep\n  mr  r3,REG_PlayerGObj\n  branchl r12,0x800bfd04\n#Check if they have a follower\n  lwz r4,0x2C(REG_PlayerGObj)\n  lbz r3,0x2222(r4)\n  rlwinm.\tr0, r3, 30, 31, 31\n  beq Rotations_Think_InProgressIncLoop\n#Get Follower GObj\n  lbz r3,0xC(r4)\n  li  r4,1\n  branchl r12,0x8003418c\n#SLeep them as well\n  branchl r12,0x800bfd04\n  b Rotations_Think_InProgressIncLoop\nRotations_Think_InProgressSearchForNextPlayerIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt Rotations_Think_InProgressSearchForNextPlayerIncLoopCheckIfDone\n#Player count is over 6, loop back to 0\n  li  REG_LoopCount,0\nRotations_Think_InProgressSearchForNextPlayerIncLoopCheckIfDone:\n#Now check if we did a full loop\n  cmpw REG_LoopCount,REG_LastPlayerSpawned\n  bne Rotations_Think_InProgressSearchForNextPlayerLoop\n#If we get here, no other players are reported as alive, so do nothing for normal respawn behvior\n\nRotations_Think_InProgressIncLoop:\n  addi REG_PlayerSlotIndex,REG_PlayerSlotIndex,1\n  cmpwi REG_PlayerSlotIndex,2\n  blt Rotations_Think_InProgressLoop\n#Neither player is dead, exit think function\n  b Rotations_ThinkExit\n\n#endregion\n\nRotations_ThinkExit:\nrestore\nblr\n\n#endregion\n\nInjectionExit:\n  li  r6,0\n"
  },
  {
    "path": "ASM/Additional Codes/Game Modes/Tag Melee.asm",
    "content": "#To be inserted at 801b8e80\n.include \"../../Globals.s\"\n\n#Store Pointer to onStartMelee function\n  lwz\tr4, -0x77C0 (r13)\n  addi\tr4, r4, 3672\n  bl  TagMelee_Init\n  mflr r5\n  stw r5,0x44(r4)\n  b InjectionExit\n\n#region TagMelee_Init\nTagMelee_Init:\nblrl\n\n.set REG_GObj,31\n.set REG_Data,30\n\n.set DataSize,64\n\nbackup\n\n#Create GObj\n  li  r3,22\n  li  r4,23\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n\n#Alloc Mem\n  li  r3,DataSize\n  branchl r12,HSD_MemAlloc\n  mr  REG_Data,r3\n\n#Zero Data\n  mr  r3,REG_Data\n  li  r4,DataSize\n  branchl r12,ZeroAreaLength\n\n#Attach Data\n  mr  r3,REG_GObj\n  li  r4,14\n  load r5,HSD_Free\n  mr  r6,REG_Data\n  branchl r12,GObj_AddUserData\n\n#Attach Process\n  mr  r3,REG_GObj\n  bl  TagMelee_Think\n  mflr r4\n  li  r5,23\n  branchl r12,GObj_AddProc\n\nTagMelee_InitExit:\nrestore\nblr\n\n#endregion\n\n#region TagMelee_Think\nTagMelee_Think:\nblrl\n\n#Registers\n.set REG_GObj,31\n.set REG_GObjData,30\n\n#Data Offsets\n.set GameState,0x0    #byte\n.set ItSlot,0x1       #byte\n.set Timer,0x2        #half\n\n#Definitions\n#GameState\n  .set Start,0x0\n  .set InProgress,0x1\n  .set Frozen,0x2\n\n#Constants\n  .set FreezeFrames, 1 * 60\n\nbackup\n\n#Init Pointers\n  mr  REG_GObj,r3\n  lwz REG_GObjData,0x2C(REG_GObj)\n\n#Check state of game\n  lbz r3,GameState(REG_GObjData)\n  cmpwi r3,Start\n  beq TagMelee_Think_Start\n  cmpwi r3,InProgress\n  beq TagMelee_Think_InProgress\n  cmpwi r3,Frozen\n  beq TagMelee_Think_Frozen\n\n#region Start\nTagMelee_Think_Start:\n\n.set REG_LoopCount,29\n.set REG_TotalPlayerCount,28\n\n#########################################\n## Start by counting all alive players ##\n#########################################\n#Init Loop\n  li  REG_LoopCount,0\n  li  REG_TotalPlayerCount,0\nTagMelee_Think_StartCountAllPlayers:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne TagMelee_Think_StartCountAllPlayersIncLoop\n#Check if player has stocks remaining\n  mr  r3,REG_LoopCount\n  branchl r12,0x80033bd8\n  cmpwi r3,0\n  ble TagMelee_Think_StartCountAllPlayersIncLoop\n#Get Players GObj\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  lwz r3,0x2C(r3)\n#Check if READY,GO is over\n  lbz r4,0x221D(r3)\n  rlwinm. r4,r4,0,28,28\n  bne TagMelee_ThinkExit\n#Player exists, increment total count\n  addi REG_TotalPlayerCount,REG_TotalPlayerCount,1\nTagMelee_Think_StartCountAllPlayersIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt TagMelee_Think_StartCountAllPlayers\n\n#############################\n## Now get a random player ##\n#############################\n.set REG_RandomPlayer,27\n\n  mr  r3,REG_TotalPlayerCount\n  branchl r12,HSD_Randi\n  mr  REG_RandomPlayer,r3\n\n#######################################\n## Get the corresponding player slot ##\n#######################################\n#Init Loop\n  li  REG_LoopCount,0\n  li  REG_TotalPlayerCount,0\nTagMelee_Think_StartGetItSlot:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne TagMelee_Think_StartGetItSlotIncLoop\n#Check if player has stocks remaining\n  mr  r3,REG_LoopCount\n  branchl r12,0x80033bd8\n  cmpwi r3,0\n  ble TagMelee_Think_StartGetItSlotIncLoop\n#Is this who im looking for?\n  cmpw REG_RandomPlayer,REG_TotalPlayerCount\n  beq TagMelee_Think_StartFoundIt\n#Player exists, increment total count\n  addi REG_TotalPlayerCount,REG_TotalPlayerCount,1\nTagMelee_Think_StartGetItSlotIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt TagMelee_Think_StartGetItSlot\n\n###################\n## Store as \"it\" ##\n###################\n\nTagMelee_Think_StartFoundIt:\n  stb REG_LoopCount,ItSlot(REG_GObjData)\n\n.set TimerMin, 10 * 60\n.set TimerMax, 30 * 60\n\n#Start random timer\n  li  r3,TimerMax-TimerMin\n  branchl r12,HSD_Randi\n  addi r3,r3,TimerMin\n  sth r3,Timer(REG_GObjData)\n\n#Change state to InProgress\n  li  r3,InProgress\n  stb r3,GameState(REG_GObjData)\n\nb TagMelee_Think_InProgress\n\n#endregion\n\n#region InProgress\nTagMelee_Think_InProgress:\n\n.set REG_LoopCount,29\n.set REG_TotalPlayerCount,28\n#Init Loop\n  li  REG_LoopCount,0\n  li  REG_TotalPlayerCount,0\nTagMelee_Think_PunishPlayers:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne TagMelee_Think_PunishPlayersIncLoop\n#Check if player has stocks remaining\n  mr  r3,REG_LoopCount\n  branchl r12,0x80033bd8\n  cmpwi r3,0\n  ble TagMelee_Think_PunishPlayersIncLoop\n#Ensure this player os not it\n  lbz r3,ItSlot(REG_GObjData)\n  cmpw r3,REG_LoopCount\n  beq TagMelee_Think_PunishPlayersIncLoop\n#Get this players gobj\n  mr  r3,REG_LoopCount\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  mr  REG_PlayerGObj,r3\n  lwz REG_PlayerData,0x2C(REG_PlayerGObj)\n#Check if they have a victim\n  lwz r3,0x2094(REG_PlayerData)\n  cmpwi r3,0\n  beq TagMelee_Think_PunishPlayersIncLoop\n#If victim is not it, give the damage they just dealt\n  lwz r4,0x2C(r3)\n\n\nTagMelee_Think_PunishPlayersIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt TagMelee_Think_PunishPlayers\n\n##################\n## Monitor \"It\" ##\n##################\nTagMelee_Think_InProgressMonitorIt:\n#Get Players GObj\n  lbz r3,ItSlot(REG_GObjData)\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n#Check if player died\n#Check if Blastzone code is being skipped\n  lwz r3,0x2C(REG_PlayerGObj)\n  lbz r4,0x2219(r3)\n  rlwinm. r4,r4,0,25,25\n  beq TagMelee_Think_InProgressMonitorItCheckForVictim\n#Rebirth gets here too, check if NOT rebirth/rebirthWait\n  lwz r4,0x10(r3)\n  cmpwi r4,ASID_Rebirth\n  beq TagMelee_Think_InProgressMonitorItCheckForVictim\n  cmpwi r4,ASID_RebirthWait\n  beq TagMelee_Think_InProgressMonitorItCheckForVictim\n#If in any Star KO State, enter them into DeadUp\n  cmpwi r4,ASID_DeadUpStar\n  beq TagMelee_Think_InProgressEnterDeadUp\n  cmpwi r4,ASID_DeadUpStarIce\n  beq TagMelee_Think_InProgressEnterDeadUp\n  cmpwi r4,ASID_DeadUpFall\n  beq TagMelee_Think_InProgressEnterDeadUp\n  b  TagMelee_Think_InProgressFreezeAllPlayers\nTagMelee_Think_InProgressEnterDeadUp:\n#Enter DeadUp\n  lwz r3,0x0(r3)\n  branchl r12,0x800d3e40\n  b TagMelee_Think_InProgressFreezeAllPlayers\nTagMelee_Think_InProgressMonitorItCheckForVictim:\n#Check if player has a victim\n  lwz r3,0x2C(REG_PlayerGObj)\n  lwz r4,0x2094(r3)\n  cmpwi r4,0\n  beq TagMelee_Think_InProgressNoTag\n#Ensure there is no hitbox exception (this should catch Thrown hitboxes)\n  lwz r5,0x1198(r3)\n  cmpwi r5,0\n  bne TagMelee_Think_InProgressRemoveVictim\n#Get the victims damage source\n  lwz r5,0x2C(r4)\n  lwz r5,0x1868(r5)\n#Check if source pointer exists\n  cmpwi r5,0x0\n  beq TagMelee_Think_InProgressRemoveVictim\n#Check if source pointer is live (check userdata pointer)\n  lwz r6,0x2C(r5)\n  cmpwi r6,0        #if not, item most likely was removed on hit, so assume it was an item\n  beq TagMelee_Think_InProgressRemoveVictim\n#Check if they were hit by an \"item\"\n  lhz r6,0x0(r5)\n  cmpwi r6,6\n  beq TagMelee_Think_InProgressNoTag\n  b TagMelee_Think_InProgressSetNewIt\n\n/*  bne TagMelee_Think_InProgressSetNewIt\n#Check if hitbox is still active\n  lwz r6,0x2C(r5)\n  addi r6,r6,0x5D4    #Start of hitbox struct\n  lwz r5,0x0(r6)      #check if hitbox is active\n  cmpwi r5,0x0\n  beq TagMelee_Think_InProgressSetNewIt\n#Ensure it was non reflectable\n  lbz r5,0x42(r6)     #get collision bools\n  rlwinm.\tr5, r5, 29, 31, 31\n  bne\tTagMelee_Think_InProgressNoTag\n*/\n\nTagMelee_Think_InProgressRemoveVictim:\n  li  r4,0\n  stw r4,0x2094(r3)\n  b TagMelee_Think_InProgressNoTag\n\nTagMelee_Think_InProgressSetNewIt:\n#Set this as new \"it\"\n  mr  REG_PlayerGObj,r4\n  lwz r3,0x2C(r4)\n  lbz r4,0xC(r3)\n  stb r4,ItSlot(REG_GObjData)\n\nTagMelee_Think_InProgressNoTag:\n#Apply GFX to \"it\"\n  lwz r3,0x2C(REG_PlayerGObj)\n  li\tr4,0x23\t\t# darkness body aura\n  li\tr5,0\n  branchl r12,0x800bffd0\n  lwz r4,0x2C(REG_PlayerGObj)\n  li\tr3,0\n  stw\tr3,0x430(r4)\n\n  lhz r3,Timer(REG_GObjData)\n  subi r3,r3,1\n  sth r3,Timer(REG_GObjData)\n#Check if up\n  cmpwi r3,0\n  bgt TagMelee_ThinkExit\n\n#Timer up, kill \"it\"\n  addi  r3,REG_PlayerGObj,0\n  branchl r12,0x800d3e40\n\n########################\n## Freeze All Players ##\n########################\n\n.set REG_LoopCount,29\n.set REG_TotalPlayerCount,28\n.set REG_PlayerGObj,27\n.set REG_PlayerData,26\nTagMelee_Think_InProgressFreezeAllPlayers:\n#Init Loop\n  li  REG_LoopCount,0\n  li  REG_TotalPlayerCount,0\nTagMelee_Think_InProgressFreezeAllPlayersLoop:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne TagMelee_Think_InProgressFreezeAllPlayersIncLoop\n#Check if player has stocks remaining\n  mr  r3,REG_LoopCount\n  branchl r12,0x80033bd8\n  cmpwi r3,0\n  ble TagMelee_Think_InProgressFreezeAllPlayersIncLoop\n#Player exists, get pointers\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n  lwz REG_PlayerData,0x2C(REG_PlayerGObj)\n#Freeze bool\n  li\tr5,1\n  lbz\tr4,0x2219(REG_PlayerData)\n  rlwimi r4,r5,2,29,29\n  stb\tr4,0x2219(REG_PlayerData)\n#Remove any hitlag\n  li  r4,0\n  stw r4,0x195C(REG_PlayerData)\n  stw r4,0x1958(REG_PlayerData)\n#Skip Blastzone and Hitbox Collision Detection Code\n  lbz r3,0x2219(REG_PlayerData)\n  li  r4,1\n  rlwimi r3,r4,6,25,25\n  stb r3,0x2219(REG_PlayerData)\n#Freeze GFX if not dead\n  lbz r3,0x221E(REG_PlayerData)\n  rlwinm. r0,r3,0,24,24\n  bne TagMelee_Think_InProgressFreezeAllPlayersIncLoop\n  mr  r3,REG_PlayerGObj\n  branchl r12,0x8005ba40\n\nTagMelee_Think_InProgressFreezeAllPlayersIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt TagMelee_Think_InProgressFreezeAllPlayersLoop\n\n#Set timer\n  li  r3,60\n  sth r3,Timer(REG_GObjData)\n\n#Change state to frozen\n  li  r3,Frozen\n  stb r3,GameState(REG_GObjData)\n  b TagMelee_ThinkExit\n\n\n#endregion\n\n#region Frozen\nTagMelee_Think_Frozen:\n#Dec Timer\n  lhz r3,Timer(REG_GObjData)\n  subi r3,r3,1\n  sth r3,Timer(REG_GObjData)\n#Check if up\n  cmpwi r3,0\n  bgt TagMelee_ThinkExit\n\n#Respawn all\n.set REG_LoopCount,29\n.set REG_TotalPlayerCount,28\n.set REG_PlayerGObj,27\n\n#Init Loop\n  li  REG_LoopCount,0\n  li  REG_TotalPlayerCount,0\nTagMelee_Think_FrozenRespawnAllPlayersLoop:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne TagMelee_Think_FrozenRespawnAllPlayersIncLoop\n#Check if player has stocks remaining\n  mr  r3,REG_LoopCount\n  branchl r12,0x80033bd8\n  cmpwi r3,0\n  ble TagMelee_Think_FrozenRespawnAllPlayersIncLoop\n#Get data\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n#Remove Items + Etc\n  mr  r3,REG_PlayerGObj\n  branchl r12,0x800d331c\n#Enter into Sleep\n  mr  r3,REG_PlayerGObj\n\tli r4,0x1\n\tbranchl\tr12,0x800bfd9c\nTagMelee_Think_FrozenRespawnAllPlayersIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt TagMelee_Think_FrozenRespawnAllPlayersLoop\n\n#Change state to start\n  li  r3,Start\n  stb r3,GameState(REG_GObjData)\n  b TagMelee_ThinkExit\n\n#endregion\n\nTagMelee_ThinkExit:\nrestore\nblr\n\n#endregion\n\nInjectionExit:\n  li  r6,0\n"
  },
  {
    "path": "ASM/Additional Codes/Game Modes/Tag Melee.s",
    "content": "#To be inserted at 801b8e80\n.include \"../../Globals.s\"\n\n#Store Pointer to onStartMelee function\n  lwz\tr4, -0x77C0 (r13)\n  addi\tr4, r4, 3672\n  bl  TagMelee_Init\n  mflr r5\n  stw r5,0x44(r4)\n  b InjectionExit\n\n#region TagMelee_Init\nTagMelee_Init:\nblrl\n\n.set REG_GObj,31\n.set REG_Data,30\n\n.set DataSize,64\n\nbackup\n\n#Create GObj\n  li  r3,22\n  li  r4,23\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n\n#Alloc Mem\n  li  r3,DataSize\n  branchl r12,HSD_MemAlloc\n  mr  REG_Data,r3\n\n#Zero Data\n  mr  r3,REG_Data\n  li  r4,DataSize\n  branchl r12,ZeroAreaLength\n\n#Attach Data\n  mr  r3,REG_GObj\n  li  r4,14\n  load r5,HSD_Free\n  mr  r6,REG_Data\n  branchl r12,GObj_AddUserData\n\n#Attach Process\n  mr  r3,REG_GObj\n  bl  TagMelee_Think\n  mflr r4\n  li  r5,23\n  branchl r12,GObj_AddProc\n\nTagMelee_InitExit:\nrestore\nblr\n\n#endregion\n\n#region TagMelee_Think\nTagMelee_Think:\nblrl\n\n#Registers\n.set REG_GObj,31\n.set REG_GObjData,30\n\n#Data Offsets\n.set GameState,0x0    #byte\n.set ItSlot,0x1       #byte\n.set Timer,0x2        #half\n\n#Definitions\n#GameState\n  .set Start,0x0\n  .set InProgress,0x1\n  .set Frozen,0x2\n\n#Constants\n  .set FreezeFrames, 1 * 60\n\nbackup\n\n#Init Pointers\n  mr  REG_GObj,r3\n  lwz REG_GObjData,0x2C(REG_GObj)\n\n#Check state of game\n  lbz r3,GameState(REG_GObjData)\n  cmpwi r3,Start\n  beq TagMelee_Think_Start\n  cmpwi r3,InProgress\n  beq TagMelee_Think_InProgress\n  cmpwi r3,Frozen\n  beq TagMelee_Think_Frozen\n\n#region Start\nTagMelee_Think_Start:\n\n.set REG_LoopCount,29\n.set REG_TotalPlayerCount,28\n\n#########################################\n## Start by counting all alive players ##\n#########################################\n#Init Loop\n  li  REG_LoopCount,0\n  li  REG_TotalPlayerCount,0\nTagMelee_Think_StartCountAllPlayers:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne TagMelee_Think_StartCountAllPlayersIncLoop\n#Check if player has stocks remaining\n  mr  r3,REG_LoopCount\n  branchl r12,0x80033bd8\n  cmpwi r3,0\n  ble TagMelee_Think_StartCountAllPlayersIncLoop\n#Get Players GObj\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  lwz r3,0x2C(r3)\n#Check if READY,GO is over\n  lbz r4,0x221D(r3)\n  rlwinm. r4,r4,0,28,28\n  bne TagMelee_ThinkExit\n#Player exists, increment total count\n  addi REG_TotalPlayerCount,REG_TotalPlayerCount,1\nTagMelee_Think_StartCountAllPlayersIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt TagMelee_Think_StartCountAllPlayers\n\n#############################\n## Now get a random player ##\n#############################\n.set REG_RandomPlayer,27\n\n  mr  r3,REG_TotalPlayerCount\n  branchl r12,HSD_Randi\n  mr  REG_RandomPlayer,r3\n\n#######################################\n## Get the corresponding player slot ##\n#######################################\n#Init Loop\n  li  REG_LoopCount,0\n  li  REG_TotalPlayerCount,0\nTagMelee_Think_StartGetItSlot:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne TagMelee_Think_StartGetItSlotIncLoop\n#Check if player has stocks remaining\n  mr  r3,REG_LoopCount\n  branchl r12,0x80033bd8\n  cmpwi r3,0\n  ble TagMelee_Think_StartGetItSlotIncLoop\n#Is this who im looking for?\n  cmpw REG_RandomPlayer,REG_TotalPlayerCount\n  beq TagMelee_Think_StartFoundIt\n#Player exists, increment total count\n  addi REG_TotalPlayerCount,REG_TotalPlayerCount,1\nTagMelee_Think_StartGetItSlotIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt TagMelee_Think_StartGetItSlot\n\n###################\n## Store as \"it\" ##\n###################\n\nTagMelee_Think_StartFoundIt:\n  stb REG_LoopCount,ItSlot(REG_GObjData)\n\n.set TimerMin, 10 * 60\n.set TimerMax, 30 * 60\n\n#Start random timer\n  li  r3,TimerMax-TimerMin\n  branchl r12,HSD_Randi\n  addi r3,r3,TimerMin\n  sth r3,Timer(REG_GObjData)\n\n#Change state to InProgress\n  li  r3,InProgress\n  stb r3,GameState(REG_GObjData)\n\nb TagMelee_Think_InProgress\n\n#endregion\n\n#region InProgress\nTagMelee_Think_InProgress:\n\n.set REG_LoopCount,29\n.set REG_TotalPlayerCount,28\n#Init Loop\n  li  REG_LoopCount,0\n  li  REG_TotalPlayerCount,0\nTagMelee_Think_PunishPlayers:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne TagMelee_Think_PunishPlayersIncLoop\n#Check if player has stocks remaining\n  mr  r3,REG_LoopCount\n  branchl r12,0x80033bd8\n  cmpwi r3,0\n  ble TagMelee_Think_PunishPlayersIncLoop\n#Ensure this player os not it\n  lbz r3,ItSlot(REG_GObjData)\n  cmpw r3,REG_LoopCount\n  beq TagMelee_Think_PunishPlayersIncLoop\n#Get this players gobj\n  mr  r3,REG_LoopCount\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  mr  REG_PlayerGObj,r3\n  lwz REG_PlayerData,0x2C(REG_PlayerGObj)\n#Check if they have a victim\n  lwz r3,0x2094(REG_PlayerData)\n  cmpwi r3,0\n  beq TagMelee_Think_PunishPlayersIncLoop\n#If victim is not it, give the damage they just dealt\n  lwz r4,0x2C(r3)\n\n\nTagMelee_Think_PunishPlayersIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt TagMelee_Think_PunishPlayers\n\n##################\n## Monitor \"It\" ##\n##################\nTagMelee_Think_InProgressMonitorIt:\n#Get Players GObj\n  lbz r3,ItSlot(REG_GObjData)\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n#Check if player died\n#Check if Blastzone code is being skipped\n  lwz r3,0x2C(REG_PlayerGObj)\n  lbz r4,0x2219(r3)\n  rlwinm. r4,r4,0,25,25\n  beq TagMelee_Think_InProgressMonitorItCheckForVictim\n#Rebirth gets here too, check if NOT rebirth/rebirthWait\n  lwz r4,0x10(r3)\n  cmpwi r4,ASID_Rebirth\n  beq TagMelee_Think_InProgressMonitorItCheckForVictim\n  cmpwi r4,ASID_RebirthWait\n  beq TagMelee_Think_InProgressMonitorItCheckForVictim\n#If in any Star KO State, enter them into DeadUp\n  cmpwi r4,ASID_DeadUpStar\n  beq TagMelee_Think_InProgressEnterDeadUp\n  cmpwi r4,ASID_DeadUpStarIce\n  beq TagMelee_Think_InProgressEnterDeadUp\n  cmpwi r4,ASID_DeadUpFall\n  beq TagMelee_Think_InProgressEnterDeadUp\n  b  TagMelee_Think_InProgressFreezeAllPlayers\nTagMelee_Think_InProgressEnterDeadUp:\n#Enter DeadUp\n  lwz r3,0x0(r3)\n  branchl r12,0x800d3e40\n  b TagMelee_Think_InProgressFreezeAllPlayers\nTagMelee_Think_InProgressMonitorItCheckForVictim:\n#Check if player has a victim\n  lwz r3,0x2C(REG_PlayerGObj)\n  lwz r4,0x2094(r3)\n  cmpwi r4,0\n  beq TagMelee_Think_InProgressNoTag\n#Ensure there is no hitbox exception (this should catch Thrown hitboxes)\n  lwz r5,0x1198(r3)\n  cmpwi r5,0\n  bne TagMelee_Think_InProgressRemoveVictim\n#Get the victims damage source\n  lwz r5,0x2C(r4)\n  lwz r5,0x1868(r5)\n#Check if source pointer exists\n  cmpwi r5,0x0\n  beq TagMelee_Think_InProgressRemoveVictim\n#Check if source pointer is live (check userdata pointer)\n  lwz r6,0x2C(r5)\n  cmpwi r6,0        #if not, item most likely was removed on hit, so assume it was an item\n  beq TagMelee_Think_InProgressRemoveVictim\n#Check if they were hit by an \"item\"\n  lhz r6,0x0(r5)\n  cmpwi r6,6\n  beq TagMelee_Think_InProgressNoTag\n  b TagMelee_Think_InProgressSetNewIt\n\n/*  bne TagMelee_Think_InProgressSetNewIt\n#Check if hitbox is still active\n  lwz r6,0x2C(r5)\n  addi r6,r6,0x5D4    #Start of hitbox struct\n  lwz r5,0x0(r6)      #check if hitbox is active\n  cmpwi r5,0x0\n  beq TagMelee_Think_InProgressSetNewIt\n#Ensure it was non reflectable\n  lbz r5,0x42(r6)     #get collision bools\n  rlwinm.\tr5, r5, 29, 31, 31\n  bne\tTagMelee_Think_InProgressNoTag\n*/\n\nTagMelee_Think_InProgressRemoveVictim:\n  li  r4,0\n  stw r4,0x2094(r3)\n  b TagMelee_Think_InProgressNoTag\n\nTagMelee_Think_InProgressSetNewIt:\n#Set this as new \"it\"\n  mr  REG_PlayerGObj,r4\n  lwz r3,0x2C(r4)\n  lbz r4,0xC(r3)\n  stb r4,ItSlot(REG_GObjData)\n\nTagMelee_Think_InProgressNoTag:\n#Apply GFX to \"it\"\n  lwz r3,0x2C(REG_PlayerGObj)\n  li\tr4,0x23\t\t# darkness body aura\n  li\tr5,0\n  branchl r12,0x800bffd0\n  lwz r4,0x2C(REG_PlayerGObj)\n  li\tr3,0\n  stw\tr3,0x430(r4)\n\n  lhz r3,Timer(REG_GObjData)\n  subi r3,r3,1\n  sth r3,Timer(REG_GObjData)\n#Check if up\n  cmpwi r3,0\n  bgt TagMelee_ThinkExit\n\n#Timer up, kill \"it\"\n  addi  r3,REG_PlayerGObj,0\n  branchl r12,0x800d3e40\n\n########################\n## Freeze All Players ##\n########################\n\n.set REG_LoopCount,29\n.set REG_TotalPlayerCount,28\n.set REG_PlayerGObj,27\n.set REG_PlayerData,26\nTagMelee_Think_InProgressFreezeAllPlayers:\n#Init Loop\n  li  REG_LoopCount,0\n  li  REG_TotalPlayerCount,0\nTagMelee_Think_InProgressFreezeAllPlayersLoop:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne TagMelee_Think_InProgressFreezeAllPlayersIncLoop\n#Check if player has stocks remaining\n  mr  r3,REG_LoopCount\n  branchl r12,0x80033bd8\n  cmpwi r3,0\n  ble TagMelee_Think_InProgressFreezeAllPlayersIncLoop\n#Player exists, get pointers\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n  lwz REG_PlayerData,0x2C(REG_PlayerGObj)\n#Freeze bool\n  li\tr5,1\n  lbz\tr4,0x2219(REG_PlayerData)\n  rlwimi r4,r5,2,29,29\n  stb\tr4,0x2219(REG_PlayerData)\n#Remove any hitlag\n  li  r4,0\n  stw r4,0x195C(REG_PlayerData)\n  stw r4,0x1958(REG_PlayerData)\n#Skip Blastzone and Hitbox Collision Detection Code\n  lbz r3,0x2219(REG_PlayerData)\n  li  r4,1\n  rlwimi r3,r4,6,25,25\n  stb r3,0x2219(REG_PlayerData)\n#Freeze GFX if not dead\n  lbz r3,0x221E(REG_PlayerData)\n  rlwinm. r0,r3,0,24,24\n  bne TagMelee_Think_InProgressFreezeAllPlayersIncLoop\n  mr  r3,REG_PlayerGObj\n  branchl r12,0x8005ba40\n\nTagMelee_Think_InProgressFreezeAllPlayersIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt TagMelee_Think_InProgressFreezeAllPlayersLoop\n\n#Set timer\n  li  r3,60\n  sth r3,Timer(REG_GObjData)\n\n#Change state to frozen\n  li  r3,Frozen\n  stb r3,GameState(REG_GObjData)\n  b TagMelee_ThinkExit\n\n\n#endregion\n\n#region Frozen\nTagMelee_Think_Frozen:\n#Dec Timer\n  lhz r3,Timer(REG_GObjData)\n  subi r3,r3,1\n  sth r3,Timer(REG_GObjData)\n#Check if up\n  cmpwi r3,0\n  bgt TagMelee_ThinkExit\n\n#Respawn all\n.set REG_LoopCount,29\n.set REG_TotalPlayerCount,28\n.set REG_PlayerGObj,27\n\n#Init Loop\n  li  REG_LoopCount,0\n  li  REG_TotalPlayerCount,0\nTagMelee_Think_FrozenRespawnAllPlayersLoop:\n#Check Players Presence\n  mr  r3,REG_LoopCount\n  branchl r12,0x800322c0\n  cmpwi r3,0x2\n  bne TagMelee_Think_FrozenRespawnAllPlayersIncLoop\n#Check if player has stocks remaining\n  mr  r3,REG_LoopCount\n  branchl r12,0x80033bd8\n  cmpwi r3,0\n  ble TagMelee_Think_FrozenRespawnAllPlayersIncLoop\n#Get data\n  mr  r3,REG_LoopCount\n  branchl r12,0x80034110\n  mr  REG_PlayerGObj,r3\n#Remove Items + Etc\n  mr  r3,REG_PlayerGObj\n  branchl r12,0x800d331c\n#Enter into Sleep\n  mr  r3,REG_PlayerGObj\n\tli r4,0x1\n\tbranchl\tr12,0x800bfd9c\nTagMelee_Think_FrozenRespawnAllPlayersIncLoop:\n  addi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,6\n  blt TagMelee_Think_FrozenRespawnAllPlayersLoop\n\n#Change state to start\n  li  r3,Start\n  stb r3,GameState(REG_GObjData)\n  b TagMelee_ThinkExit\n\n#endregion\n\nTagMelee_ThinkExit:\nrestore\nblr\n\n#endregion\n\nInjectionExit:\n  li  r6,0\n"
  },
  {
    "path": "ASM/Additional Codes/Hide Nametag When Invisible.asm",
    "content": "#To be inserted at 802fccd8\n.include \"../Globals.s\"\n\n#Check if Doubles\n  load r3,0x8046b6a0\n  lbz r3,0x24D0(r3)\n  cmpwi r3, 0x1\n  beq Original\n#Get PLayer\n  lbz r3, 0(r31)\n  branchl r12,0x80034110\n#Get Player Data\n  lwz r4,0x2C(r3)\n#Check if Mewtwo\n  lwz r3,0x4(r4)\n  cmpwi r3,0x10\n  bne NotMewtwoAridodge\n#Check if Airdodging\n  lwz r3,0x10(r4)\n  cmpwi r3,0xEC\n  beq HideNametag\nNotMewtwoAridodge:\n#Get Invis Bit\n  lbz r3,0x221E(r4)\n  rlwinm. r3, r3, 0, 24, 24\n  beq- Original\nHideNametag:\n#Is Invisible, Hide Tag\n  lis r12, 0x802F\n  ori r12, r12, 0xCCC8\n  mtctr r12\n  bctr\n\nOriginal:\n  cmplwi\tr30, 0\n"
  },
  {
    "path": "ASM/Additional Codes/Hide Player GFX When Hitboxes Enabled/Hide GFX When Hitboxes Enabled.asm",
    "content": "#To be inserted at 8005FE30\n.include \"../../Globals.s\"\n\n#Check if a GObj was sent as an arg\n  cmpwi r4,0\n  beq Original\n#Check if this is a player GObj\n  lhz r8,0x0(r4)\n  cmpwi r8,0x4\n  beq Fighter\n  cmpwi r8,0x6\n  beq Item\n  b Original\n\nFighter:\n#Get player's hitbox visibility flag\n  lwz r8,0x2C(r4)\n  lbz r8,0x21FC(r8)\n  rlwinm. r8,r8,0,30,30\n  beq Original\n  b Skip\n\nItem:\n#Get item's hitbox visibility flag\n  lwz r8,0x2C(r4)\n  lbz r8,0xDAA(r8)\n  rlwinm. r8,r8,0,30,30\n  beq Original\n  b Skip\n\nSkip:\n  li  r3,0\n  branch  r12,0x80061d40\n\nOriginal:\n  addi\tr28, r3, 0\n"
  },
  {
    "path": "ASM/Additional Codes/Hide Player GFX When Hitboxes Enabled/Hide OnHit GFX When Hitboxes Enabled 2.asm",
    "content": "#To be inserted at 8007a430\n.include \"../../Globals.s\"\n\n#Get player's hitbox visibility flag\n  lwz\tr12, 0x002C (r30)\n  lbz r12,0x21FC(r12)\n  rlwinm. r12,r12,0,30,30\n  beq Original\n  branch  r12,0x8007a6a8\n\nOriginal:\n  lwz\tr0, 0x0030 (r17)\n"
  },
  {
    "path": "ASM/Additional Codes/Hide Player GFX When Hitboxes Enabled/Hide OnHit GFX When Hitboxes Enabled.asm",
    "content": "#To be inserted at 8007a180\n.include \"../../Globals.s\"\n\n#Get player's hitbox visibility flag\n  lbz r0,0x21FC(r6)\n  rlwinm. r0,r0,0,30,30\n  beq Original\n  branch  r12,0x8007a6a8\n\nOriginal:\n  lwz\tr0, 0x0030 (r4)\n"
  },
  {
    "path": "ASM/Additional Codes/Hitbox Color Changes Based On Damage.asm",
    "content": "#To be inserted at 80009fa4\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n .macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n.set playerdata,31\n\n\n#r0 is free\n#r5 is free\n\n#18 = 0\n\n#5 = 187\n\n#minimum GB value - (damage * (minimum GB value /max damage)\n\n#Get Values\nlfs\tf5,0xC(r3)\t\t#Get Hitbox Damage\nbl\tFloats\nmflr\tr5\nlfs\tf6,0x0(r5)\t\t#Min GB Value\nlfs\tf7,0x4(r5)\t\t#Damage Value for Lightest Color\nlfs\tf8,0x8(r5)\t\t#Damage Value for Darkest Color\n\n\n#Check If Does Over Max Damage Accounted For\nfcmpo\tcr0,f5,f8\nblt\tCheckMin\nli\tr6,0x0\nb\tStoreGandB\n\nCheckMin:\n#Check If Does Under Min Damage Accounted For\nfcmpo\tcr0,f5,f7\nbgt\tFormula\nlfs\tf8,0x0(r5)\t\t#Value for Lightest Color\nb\tConvertToDecimal\n\n#Formula\nFormula:\nfsubs   f8,f8,f7\nfsubs\tf5,f5,f7\nfsubs   f7,f7,f7\nfdivs\tf8,f6,f8\t\t#(minimum GB value /max damage)\nfmuls\tf8,f5,f8\t\t#(damage * (minimum GB value /damage range)\nfsubs\tf8,f6,f8\t\t#minimum GB value - (damage * (minimum GB value /damage range)\n\n#Convert To Decimal\nConvertToDecimal:\nfctiwz\tf5,f8\nstfd\tf5,-0xC(sp)\nlwz\tr6,-0x8(sp)\t\t#Get Hitbox Damage as Int\n\n#Store As G and B Value\nStoreGandB:\nsubi\tr5, r13, 32768\t\t#Get Hitbox Color in DOL\nstb\tr6,0x1(r5)\t\t#G\nstb\tr6,0x2(r5)\t\t#B\n\n\nb\texit\n\nFloats:\nblrl\n.long 0x43580000\t#Min GB Value 187\n.long 0x40A00000\t#Damage Value for Lightest Color 5\n.long 0x41900000 #Damage Value for Darkest Color 18\n\n\nexit:\n"
  },
  {
    "path": "ASM/Additional Codes/Hold A+B for Salty Runback + Hold A+X for Random Stage + Skip Result Screen.asm",
    "content": "#To be inserted at 801a5b14\n.include \"../Globals.s\"\n\n.set REG_LoopCount,29\n\n#Init loop\n  li  REG_LoopCount,0\nLoop:\n#Get players inputs\n  mr  r3,REG_LoopCount\n  branchl r12,0x801a3680\n\n#Check Inputs\n  rlwinm. r0, r4, 0, 23, 23 #check A\n  beq- LoopInc\n  rlwinm. r0, r4, 0, 22, 22 #check B\n  bne- Runback\n  rlwinm. r0, r4, 0, 21, 21 #check X\n  bne RandomStage\n\nLoopInc:\n  addi  REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,4\n  blt Loop\n  b LoadCSS\n\nRunback:\n  li r27,0x2 #reload match scene\n  b exit\n\nRandomStage:\n  branchl r12,0x802599EC #get random stage ID\n\n#convert SSS ID to internal stage ID\n  load r4,0x803f06D0   #load stage ID table\n  mulli\tr3, r3, 28     #stage ID to offset\n  add r4,r4,r3         #add to start of table\n  lbz r3,0xB(r4)       #get internal stage ID\n#Store to match struct\n  load r4,0x8045AC64     #load VS match struct\n  sth r3,0x2(r4)             #store stage half to struct\n#Store to preload table\n  load r4,0x8043207c         #Preload Cache\n  stw r3,0xC(r4)             #Store to Preload Cache\n#Request Load\n  branchl r12,0x80018254\n\n  li r27,0x2                  #reload match scene\n  b exit\n\nLoadCSS:\n  li r27,0 # 4 is results\n\nexit:\nOriginal:\n  li\tr29, 0\n"
  },
  {
    "path": "ASM/Additional Codes/Hold Z for Rapid Frame Advance/New Inputs Don't Reset Rapid Timer.s",
    "content": "#To be inserted at 80377944\n.include \"../../Globals.s\"\n\n#Check if nothing is pressed\n  lwz\tr0, 0x0000 (r26)\n  cmpwi r0,0\n  beq Exit\n\n#If something is pressed, dont reset timer\n  branch r12,0x80377984\n\nExit:\nlwz\tr0, 0x0008 (r26)\n"
  },
  {
    "path": "ASM/Additional Codes/Hold Z for Rapid Frame Advance/P1 - Check Rapid Fire Input.asm",
    "content": "#To be inserted at 8016bbd4\nlwz\tr0, 0x000C (r4)\n"
  },
  {
    "path": "ASM/Additional Codes/Hold Z for Rapid Frame Advance/P2 - Check Rapid Fire Input.asm",
    "content": "#To be inserted at 8016bc00\nlwz\tr0, 0x000C (r4)\n"
  },
  {
    "path": "ASM/Additional Codes/Hold Z for Rapid Frame Advance/P3 - Check Rapid Fire Input.asm",
    "content": "#To be inserted at 8016bc2c\nlwz\tr0, 0x000C (r4)\n"
  },
  {
    "path": "ASM/Additional Codes/Hold Z for Rapid Frame Advance/P4 - Check Rapid Fire Input.asm",
    "content": "#To be inserted at 8016bc58\nlwz\tr0, 0x000C (r4)\n"
  },
  {
    "path": "ASM/Additional Codes/Idle Screen/Main.asm",
    "content": "#To be inserted at 80302788\n.include \"../../Globals.s\"\n\n.set  IdleThreshold, (3*60) * 60\n\n.set  REG_DevelopText,31\n.set  REG_GObjData,30\n.set  REG_GObj,29\n.set  REG_Floats,28\n\nbackup\n\n  bl  Floats\n  mflr  REG_Floats\n\n#Create Rectangle\n  li  r3,32\n  branchl r12,HSD_MemAlloc\n  mr  r8,r3\n  li  r3,20\n  li  r4,-25\n  li  r5,-25\n  li  r6,1\n  li  r7,1\n  branchl r12,DevelopText_CreateDataTable\n  mr  REG_DevelopText,r3\n#Activate Text\n  lwz\tr3, -0x4884 (r13)\n  mr  r4,REG_DevelopText\n  branchl r12,DevelopText_Activate\n#Hide blinking cursor\n  li  r3,0\n  stb r3,0x26(REG_DevelopText)\n#Change BG Color\n  mr  r3,REG_DevelopText\n  addi  r4,REG_Floats,TextBG\n  branchl r12,DevelopText_StoreBGColor\n#Hide Filter\n  mr  r3,REG_DevelopText\n  branchl r12,DevelopText_HideBG\n#Set Stretch\n  lfs f1,TextScale_X(REG_Floats)\n  stfs f1,0x8(REG_DevelopText)\n  lfs f1,TextScale_Y(REG_Floats)\n  stfs f1,0xC(REG_DevelopText)\n#Create Background GObj\n  li  r3,0\n  li  r4,0\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n#Allocate Space\n\tli\tr3,64\n\tbranchl r12,HSD_MemAlloc\n\tmr\tREG_GObjData,r3\n#Zero\n\tli\tr4,64\n\tbranchl r12,ZeroAreaLength\n#Initialize\n\tmr\tr6,REG_GObjData\n\tmr\tr3,REG_GObj\n\tli\tr4,4\n\tload\tr5,HSD_Free\n\tbranchl r12,GObj_AddUserData\n#Add Process\n\tmr\tr3,REG_GObj\n\tbl\tIdleThink\n\tmflr r4\n\tli\tr5,0\n  branchl r12,GObj_AddProc\n#Store pointer to dev text\n  stw REG_DevelopText,0x0(REG_GObjData)\n  b Injection_Exit\n\nIdleThink:\nblrl\n.set  REG_GObjData,31\n.set  REG_Floats,30\n\n.set  IdleData_Text,0x0\n.set  IdleData_State,0x4\n.set  IdleData_VolumeBackup,0x8\n.set  IdleData_IdleCounter,0xC\n\n  backup\n\n#Init\n  lwz REG_GObjData,0x2C(r3)\n  bl  Floats\n  mflr  REG_Floats\n\n#Check if already muted\n  lwz r3,IdleData_State(REG_GObjData)\n  cmpwi r3,0x0\n  bne IdleThink_CheckToUnmute\n\nIdleThink_CheckToMute:\n#Check if anyone is inputting on this frame\n  li  r3,4\n  branchl r12,Inputs_GetPlayerHeldInputs\n  cmpwi r4,0\n  beq IdleThink_CheckToMute_IncTimer\nIdleThink_CheckToMute_ResetTimer:\n  li  r3,0\n  stw r3,IdleData_IdleCounter(REG_GObjData)\n  b IdleThink_Exit\nIdleThink_CheckToMute_IncTimer:\n  lwz r3,IdleData_IdleCounter(REG_GObjData)\n  addi  r3,r3,1\n  stw r3,IdleData_IdleCounter(REG_GObjData)\n  cmpwi r3,IdleThreshold\n  blt IdleThink_Exit\n#Mute Music\n  lwz r4,-0x7E1C(r13)\n  stw r4,IdleData_VolumeBackup(REG_GObjData)\n  li  r3,0\n  branchl r12,cvt_sll_flt\n  lfs f2,VolumeMultiplier(REG_Floats)\n  fmuls f1,f1,f2\n  branchl r12,cvt_fp2unsigned\n  stw r3,-0x7E1C(r13)\n#Display filter\n  lwz  r3,IdleData_Text(REG_GObjData)\n  branchl r12,DevelopText_ShowBG\n#Change state\n  li  r3,1\n  stw r3,IdleData_State(REG_GObjData)\n#Reset Timer\n  li  r3,0\n  stw r3,IdleData_IdleCounter(REG_GObjData)\n  b IdleThink_Exit\n\nIdleThink_CheckToUnmute:\n#Check if anyone is inputting on this frame\n  li  r3,4\n  branchl r12,Inputs_GetPlayerHeldInputs\n  cmpwi r4,0\n  beq IdleThink_Exit\n#Unmute music\n  lwz r3,IdleData_VolumeBackup(REG_GObjData)\n  stw r3,-0x7E1C(r13)\n#Hide Filter\n  lwz  r3,IdleData_Text(REG_GObjData)\n  branchl r12,DevelopText_HideBG\n#Change state\n  li  r3,0\n  stw r3,IdleData_State(REG_GObjData)\n  b IdleThink_Exit\n\nIdleThink_Exit:\n  restore\n  blr\n\n######################\nFloats:\nblrl\n.set TextScale_X,0x0\n.set TextScale_Y,0x4\n.set TextBG,0x8\n.set VolumeMultiplier,0xC\n.float 1000\n.float 1000\n.byte 0,0,0,130\n.float 0.3\n######################\n\nInjection_Exit:\n  restore\n  mr\tr3, r31\n"
  },
  {
    "path": "ASM/Additional Codes/Initialize Stage Data.asm",
    "content": "#To be inserted at 801c154c\n.include \"../Globals.s\"\n\n#Initialize data\n  li  r4,516\n  branchl r12,ZeroAreaLength\n\nExit:\n  cmplwi\tr26, 0\n"
  },
  {
    "path": "ASM/Additional Codes/Kill Zoom/Main.s",
    "content": "#To be inserted at 8016e5a8\n.include \"../../Globals.s\"\n\n\nCreateProc:\n.set  REG_Data,31\n.set  REG_GObj,30\n\nbackup\n\n#Create GObj\n  li\tr3,4\t    \t#GObj Type (4 is the player type, this should ensure it runs before any player animations)\n  li\tr4,0\t  \t  #On-Pause Function (dont run on pause)\n  li\tr5,0        #object priority\n  branchl\tr12,GObj_Create\n  mr  REG_GObj,r3\n\n#Alloc Mem\n  li  r3,32\n  branchl r12,HSD_MemAlloc\n  mr  REG_Data,r3\n\n#Zero Data\n  mr  r3,REG_Data\n  li  r4,32\n  branchl r12,ZeroAreaLength\n\n#Attach Data\n  mr  r3,REG_GObj\n  li  r4,14\n  load r5,HSD_Free\n  mr  r6,REG_Data\n  branchl r12,GObj_AddUserData\n\n#Create Proc\n  bl  KillZoomThink\n  mflr r4         #Function\n  li  r5,14       #Priority\n  branchl\tr12,GObj_AddProc\n\nb CreateProc_Exit\n\n#############################################################\nKillZoomThink:\nblrl\n\n.set  REG_GObjData,31\n.set  REG_PlayerData,30\n.set  REG_PlayerGObj,29\n.set  REG_Constants,28\n\n#Init\n  backup\n  lwz REG_GObjData,0x2C(r3)\n  bl  Constants\n  mflr  REG_Constants\n\n#Ensure match type is stock\n  branchl r12,0x8016ae50\n  lbz r0,0x4(r3)\n  rlwinm. r0,r0,0,0x20\n  bne KillZoomThink_IsStock\n  branchl r12,0x8016b094\n  cmpwi r3,0\n  beq KillZoomThink_Exit\n\nKillZoomThink_IsStock:\n#Check if currently zooming\n  load  r3,0x80452c68\n  lwz r0,0x4(r3)\n  cmpwi r0,6\n  bne LoopThroughPlayers_GetFirstPlayer\n#Decrement Freeze Timer\n  lwz r3,0x0(REG_GObjData)\n  subi  r3,r3,1\n  stw r3,0x0(REG_GObjData)\n  cmpwi r3,0\n  bgt KillZoomThink_Exit\n#Resume Game Speed\n  li  r3,1\n  branchl r12,0x801a4674\n#Restore camera to normal\n  branchl r12,0x8015cc14\n  b KillZoomThink_Exit\n#Loop through all players\nLoopThroughPlayers_GetFirstPlayer:\n  lwz\tr3, -0x3E74 (r13)\n  lwz\tREG_PlayerGObj, 0x0020 (r3)\n  b\tLoopThroughPlayers_CheckIfPlayerExists\nLoopThroughPlayers_GetNextPlayer:\n  lwz\tREG_PlayerGObj,0x8(REG_PlayerGObj)\nLoopThroughPlayers_CheckIfPlayerExists:\n  cmpwi\tREG_PlayerGObj,0x0\n  beq\tKillZoomThink_Exit\n  lwz\tREG_PlayerData,0x2C(REG_PlayerGObj)\n\n#Ensure not in sleep\n  lbz\tr3, 0x221F(REG_PlayerData)\n  rlwinm. r0,r3,0,0x10\n  bne LoopThroughPlayers_GetNextPlayer\n#Ensure not a follower\n  rlwinm.\tr0, r3, 29, 31, 31\n  beq\tFollowerSkip\n#Check If Follower\n  lbz r3,0xC(REG_PlayerData)\n  branchl r12, PlayerBlock_LoadExternalCharID\n  load\tr4,0x803bcde0\t\t\t   #pdLoadCommonData table\n  mulli\tr0, r3, 3\t\t\t       #struct length\n  add\tr3,r4,r0\t\t\t         #get characters entry\n  lbz\tr0, 0x2(r3)\t\t\t     #get subchar functionality\n  cmpwi\tr0,0x0\t\t\t         #if a follower, exit\n  beq\tLoopThroughPlayers_GetNextPlayer\nFollowerSkip:\n#Check if in hitstun\n  lbz\tr3, 0x221C(REG_PlayerData)\n  rlwinm. r0,r3,0,0x2\n  beq LoopThroughPlayers_GetNextPlayer\n#Check if in hitlag\n  lbz\tr3, 0x221A(REG_PlayerData)\n  rlwinm. r0,r3,0,0x20\n  beq LoopThroughPlayers_GetNextPlayer\n#Check if last frame of hitlag\n\tlfs\tf1,-0x7418(rtoc)\t\t          #1fp\n\tlfs\tf2,0x195C(REG_PlayerData)\t\t  #hitlag frames left\n\tfcmpo\tcr0,f1,f2\n\tbne\tLoopThroughPlayers_GetNextPlayer\n#Check if will die from this hit\n  mr  r3,REG_PlayerData\n  bl  DIDraw\n  cmpwi r3,0\n  beq LoopThroughPlayers_GetNextPlayer\n#Check if last stock\n  lbz r3,0xC(REG_PlayerData)\n  branchl r12,PlayerBlock_LoadStocksLeft\n  cmpwi r3,1\n  beq KillZoomThink_KOZoom\n  b KillZoomThink_KOFlash\n\nKillZoomThink_KOZoom:\n.set  ZoomInFrames,6\n.set  FreezeFrames,ZoomInFrames+20\n\n#Zoom in on this player\n  lwz r3,0x10B0(REG_PlayerData)\n  stw r3,0x80(sp)\n  lwz r3,0x10B4(REG_PlayerData)\n  stw r3,0x84(sp)\n  lwz r3,0x10B8(REG_PlayerData)\n  stw r3,0x88(sp)\n  addi  r3,sp,0x80\n  lwz r4,0x1868(REG_PlayerData)\n  cmpwi r4,0x0\n  beq KillZoomThink_HitByNonPlayer\n  lhz r5,0x0(r4)\n  cmpwi r5,0x4\n  beq  KillZoomThink_HitByPlayer\n#Just use the victims sphere\nKillZoomThink_HitByNonPlayer:\n  addi  r3,sp,0x80\n  b KillZoomThink_ZoomInOnCoordinates\nKillZoomThink_HitByPlayer:\n  lwz r4,0x2C(r4)\n  addi  r4,r4,0x10B0\n  branchl r12,0x8000d46c      #Add vectors\n  lfs f1,Divisor(REG_Constants)\n  lfs f2,0x80(sp)\n  fdivs f2,f2,f1\n  stfs  f2,0x80(sp)\n  lfs f2,0x84(sp)\n  fdivs f2,f2,f1\n  stfs  f2,0x84(sp)\n  lfs f2,0x88(sp)\n  fdivs f2,f2,f1\n  stfs  f2,0x88(sp)\n  addi  r3,sp,0x80\nKillZoomThink_ZoomInOnCoordinates:\n#Set coordinates\n  branchl r12,0x8002e818\n#Adjust Zoom value\n  lfs f1,ZoomValue(REG_Constants)\n  stfs  f1,0x88(sp)\n  addi  r3,sp,0x80\n  branchl r12,0x8002ea64\n#Adjust frames to zoom in\n  li  r3,ZoomInFrames\n  branchl r12,0x8002f0e4\n#Set Freeze Frames\n  li  r3,FreezeFrames\n  stw r3,0x0(REG_GObjData)\n#Freeze Game\n  li  r3,1\n  branchl r12,0x801a4634\n#Play SFX\n  li  r3,0xDF\n  branchl r12,SFX_PlaySoundAtFullVolume\n#Spawn GFX\n  lwz r3,0x0(REG_PlayerData)\n  li  r4,0x1b3\n  li  r5,3\n  li  r6,0\n  li  r7,0\n  addi  r8,sp,0x80\n  addi  r9,sp,0x8C\n#Setup stack\n  li r0,0\n  stw r0,0x0(r8) #z scatter\n  stw r0,0x4(r8) #y scatter\n  stw r0,0x8(r8) #z scatter\n  li r0,0\n  stw r0,0x0(r9) #X offset\n  stw r0,0x4(r9) #y offset\n  stw r0,0x8(r9) #z offset\n  branchl r12,0x8009f834\n#Spawn GFX\n  lwz r3,0x0(REG_PlayerData)\n  li  r4,0xd5\n  li  r5,3\n  li  r6,0\n  li  r7,0\n  addi  r8,sp,0x80\n  addi  r9,sp,0x8C\n#Setup stack\n  li r0,0\n  stw r0,0x0(r8) #z scatter\n  stw r0,0x4(r8) #y scatter\n  stw r0,0x8(r8) #z scatter\n  li r0,0\n  stw r0,0x0(r9) #X offset\n  stw r0,0x4(r9) #y offset\n  stw r0,0x8(r9) #z offset\n  branchl r12,0x8009f834\n  b KillZoomThink_Exit\n\nKillZoomThink_KOFlash:\n#Play SFX\n  li  r3,0x122 #12a #122 #0xff\n  branchl r12,SFX_PlaySoundAtFullVolume\n#Spawn GFX\n  lwz r3,0x0(REG_PlayerData)\n  li  r4,0x8e\n  li  r5,3\n  li  r6,0\n  li  r7,0\n  addi  r8,sp,0x80\n  addi  r9,sp,0x8C\n#Setup stack\n  li r0,0\n  stw r0,0x0(r8) #z scatter\n  stw r0,0x4(r8) #y scatter\n  stw r0,0x8(r8) #z scatter\n  li r0,0\n  stw r0,0x0(r9) #X offset\n  stw r0,0x4(r9) #y offset\n  stw r0,0x8(r9) #z offset\n  branchl r12,0x8009f834\n#Spawn GFX\n  lwz r3,0x0(REG_PlayerData)\n  li  r4,0x1e4\n  li  r5,3\n  li  r6,0\n  li  r7,0\n  addi  r8,sp,0x80\n  addi  r9,sp,0x8C\n#Setup stack\n  li r0,0\n  stw r0,0x0(r8) #z scatter\n  stw r0,0x4(r8) #y scatter\n  stw r0,0x8(r8) #z scatter\n  li r0,0\n  stw r0,0x0(r9) #X offset\n  stw r0,0x4(r9) #y offset\n  stw r0,0x8(r9) #z offset\n  branchl r12,0x8009f834\n\nKillZoomThink_Exit:\n  restore\n  blr\n\n#region DI Draw\nDIDraw_Constants:\nblrl\n\n.set\tECB_TopY,0x0 #scale * value\n.set\tECB_BottomY,0x4 #neg(scale * vlaue)\n.set\tECB_LeftX,0x8 #neg(scale * vlaue)\n.set\tECB_LeftY,0xC #0\n.set\tECB_RightX,0x10 #scale * value\n.set\tECB_RightY,0x14 #0\n.set  FirefoxDrawZ,0x18\n.set  AliveLineColor,0x1C\n.set  DeadLineColor,0x20\n.set  LeftWallColor,0x24\n.set  RightWallColor,0x28\n.set  CeilingColor,0x2C\n.set  GroundColor,0x30\n.set  ASDIColor,0x34\n.float 9\n.float 2.5\n.float -3.3\n.float 5.7\n.float 3.3\n.float 5.7\n.float 10\n.byte 0, 138, 255, 255\n.byte 255, 55, 55, 255\n.byte 12, 255, 41, 255\n.byte 12, 255, 41, 255\n.byte 255, 0, 255, 255\n.byte 255, 255, 255, 255\n.byte 255, 86, 20, 255\n\n.set StackSize,0x300\n.set Stack_BackedUpReg,0x8\n  .set Stack_BackedUpReg_Length,0x30\n.set Stack_BackedUpFloats, (Stack_BackedUpReg+Stack_BackedUpReg_Length)\n  .set Stack_BackedUpFloats_Length,0x14\n.set Stack_ECBBoneStruct, (Stack_BackedUpFloats+Stack_BackedUpFloats_Length)\n  .set Stack_ECBBoneStruct_Length,0x18\n.set Stack_ECBStruct, (Stack_ECBBoneStruct+Stack_ECBBoneStruct_Length)\n  .set Stack_ECBStruct_Length,0x1AC\n.set Stack_ASDIBackup, (Stack_ECBStruct+Stack_ECBStruct_Length)\n  .set  Stack_ASDIBackup_Length,0x8\n.set Stack_MiscSpace, (Stack_ASDIBackup+Stack_ASDIBackup_Length)\n\n#gprs\n.set REG_EventConstants,31\n.set REG_PlayerData,30\n.set REG_ECBStruct,20\n.set REG_ECBBoneStruct,21\n.set REG_LoopCount,22\n.set REG_GX,23\n.set REG_HeldInputs,24\n.set REG_GroundState,24\n.set REG_CollisionInfo,25\n.set REG_Temp,26            #this register is used for the draw loop, make sure to change both\n.set REG_OverrideRemainingFrames,27\n\n#fprs\n.set REG_arctan,31\n.set REG_XComp,30\n.set REG_YComp,29\n.set REG_KnockbackX,28\n.set REG_KnockbackY,27\n.set REG_CurrXPos,26\n.set REG_CurrYPos,25\n.set REG_DIInput,24\n.set REG_KnockbackMag,23\n.set REG_CStickX,22\n.set REG_CStickY,21\n.set REG_ASDIX,22\n.set REG_ASDIY,21\n.set REG_Gravity,30\n\n#constants\n.set MaxColl,40\n\nDIDraw:\n  mflr r0\n  stw r0, 0x4(r1)\n  stwu\tr1,-StackSize(r1)\t# make space for 12 registers\n  stmw  r20,Stack_BackedUpReg(r1)\n\n#backup\n  mr  REG_PlayerData,r3\n\n#Get Floats\n  bl  DIDraw_Constants\n  mflr  REG_EventConstants\n\n#region GetInputs\nDIDraw_PBInputs:\n\tlfs\tREG_XComp,0x620(REG_PlayerData)\n\tlfs\tREG_YComp,0x624(REG_PlayerData)\n  lwz REG_HeldInputs,0x65C(REG_PlayerData)\n\tlfs\tREG_CStickX,0x638(REG_PlayerData)\n\tlfs\tREG_CStickY,0x63C(REG_PlayerData)\n#endregion\n\n#Get original KB vector\n  lfs REG_KnockbackX,0x8C(REG_PlayerData)\n  lfs REG_KnockbackY,0x90(REG_PlayerData)\n\n#Calculate player's influence over trajectory\n#region GetArctan\nDIDraw_GetArctan:\n#Get atan2\n\tfmr\tf1,REG_KnockbackY\n\tfmr\tf2,REG_KnockbackX\n\tbranchl\tr12,0x80022c30\n\tfmr\tREG_arctan,f1\n#Do something\n  fmuls f1,REG_KnockbackY,REG_KnockbackY\n  fmadds  REG_KnockbackMag,REG_KnockbackX,REG_KnockbackX,f1\n  lfs\tf0, -0x750C (rtoc)\n  fcmpo cr0,REG_KnockbackMag,f0\n  ble DIDraw_SkipUnk\n#Do a bunch of stuff\n  frsqrte\tf2,REG_KnockbackMag\n  lfd\tf4, -0x74E0 (rtoc)\n  lfd\tf3, -0x74D8 (rtoc)\n  fmul\tf0,f2,f2\n  fmul\tf2,f4,f2\n  fnmsub\tf0,REG_KnockbackMag,f0,f3\n  fmul\tf2,f2,f0\n  fmul\tf0,f2,f2\n  fmul\tf2,f4,f2\n  fnmsub\tf0,REG_KnockbackMag,f0,f3\n  fmul\tf2,f2,f0\n  fmul\tf0,f2,f2\n  fmul\tf2,f4,f2\n  fnmsub\tf0,REG_KnockbackMag,f0,f3\n  fmul\tf0,f2,f0\n  fmul\tf0,REG_KnockbackMag,f0\n  frsp\tf0,f0\n  fmr REG_KnockbackMag,f0\nDIDraw_SkipUnk:\n#endregion\n#region CalculateASDI\nDIDraw_CalculateASDI:\n#CStick has priority\n#Check if cstick magnitude > 0.7\n  fmuls f1,REG_CStickX,REG_CStickX\n  fmuls f0,REG_CStickY,REG_CStickY\n  lwz\tr3, -0x514C (r13)\n  lfs\tf2, 0x04B0 (r3)\n  fadds\tf1,f1,f0\n  fmuls\tf0,f2,f2\n  fcmpo\tcr0,f1,f0\n  bge DIDraw_CalculateASDICStickApply\n#Now check left stick\n  fmuls f1,REG_YComp,REG_YComp\n  fmuls f2,REG_XComp,REG_XComp\n  lwz\tr3, -0x514C (r13)\n  lfs\tf0, 0x04B0 (r3)\n  fmuls f0,f0,f0\n  fadds f1,f1,f2\n  fcmpo cr0,f1,f0\n  blt  DIDraw_CalculateASDINone\nDIDraw_CalculateASDILeftStickApply:\n#Multiply by 3\n  lfs\tf1, 0x04BC (r3)\n  fmuls REG_ASDIX,REG_XComp,f1\n  fmuls REG_ASDIY,REG_YComp,f1\n  b DIDraw_CalculateASDIEnd\nDIDraw_CalculateASDINone:\n#Null ASDI\n  lfs\tREG_ASDIX, -0x750C (rtoc)\n  lfs\tREG_ASDIY, -0x750C (rtoc)\n  b DIDraw_CalculateASDIEnd\nDIDraw_CalculateASDICStickApply:\n#Multiply by 3\n  lfs\tf1, 0x04BC (r3)\n  fmuls REG_ASDIX,REG_CStickX,f1\n  fmuls REG_ASDIY,REG_CStickY,f1\nDIDraw_CalculateASDIEnd:\n#Save these values for later\n  stfs  REG_ASDIX,Stack_ASDIBackup+0(sp)\n  stfs  REG_ASDIY,Stack_ASDIBackup+4(sp)\n#endregion\n#region CalculateKBReduction\nDIDraw_CalculateKBReduction:\n#Check if holding L/R/Z\n  rlwinm. r0,REG_HeldInputs,0,0x80000000\n  beq DIDraw_CalculateKBReductionEnd\n  lwz\tr3, -0x514C (r13)\n  lfs\tf0, 0x01AC (r3)\n  fmuls REG_KnockbackMag,f0,REG_KnockbackMag\n  fmr  f1,REG_arctan\n  branchl r12,cos\n  fmuls REG_KnockbackX,f1,REG_KnockbackMag\n  fmr  f1,REG_arctan\n  branchl r12,sin\n  fmuls REG_KnockbackY,f1,REG_KnockbackMag\n#Get new atan2\n\tfmr\tf1,REG_KnockbackY\n\tfmr\tf2,REG_KnockbackX\n\tbranchl\tr12,0x80022c30\n\tfmr\tREG_arctan,f1\nDIDraw_CalculateKBReductionEnd:\n#endregion\n#region CalculateDI\nDIDraw_CalculateDI:\n#If grounded, skip DI\n  lwz r3,0xE0(REG_PlayerData)\n  cmpwi r3,0\n  beq DIDraw_CalculateDIEnd\n#If both inputting nothing, skip DI\n  lfs\tf1, -0x750C (rtoc)\n  fcmpo cr0,f1,REG_XComp\n  bne DIDraw_IsInputting\n  fcmpo cr0,f1,REG_YComp\n  beq DIDraw_CalculateDIEnd\nDIDraw_IsInputting:\n#If some condition is met, skip DI\n  lfs\tf0, -0x74E8 (rtoc)\n  fneg  f1,REG_KnockbackX\n  fmuls f1,f1,f1\n  fmuls f2,REG_KnockbackY,REG_KnockbackY\n  fadds f1,f1,f2\n  fcmpo cr0,f1,f0\n  blt DIDraw_CalculateDIEnd\n#Get DI value\n  fneg  f2,REG_KnockbackX\n  fmuls f2,f2,REG_YComp\n  fmuls f3,REG_KnockbackY,REG_XComp\n  fadds f2,f2,f3\n  fmuls f2,f2,f2\n  fdivs REG_DIInput,f2,f1\n  lfs\tf4, -0x750C (rtoc)\n#Cross product\n  stfs  REG_XComp,Stack_MiscSpace+0(sp)\n  stfs  REG_YComp,Stack_MiscSpace+4(sp)\n  lfs f0, -0x750C (rtoc)\n  stfs  f0,Stack_MiscSpace+8(sp)\n  addi  r3,REG_PlayerData,0x8C\n  addi  r4,sp,Stack_MiscSpace+0\n  addi  r5,sp,Stack_MiscSpace+12\n  branchl r12,0x80342e58\n#Check if over 0\n  lfs\tf0, -0x750C (rtoc)\n  lfs f1,Stack_MiscSpace+20(sp)\n  fcmpo cr0,f1,f0\n  bge 0x8\n  fneg  REG_DIInput,REG_DIInput\n#Apply new angle\n  lwz\tr3, -0x514C (r13)\n  lfs\tf2, -0x7510 (rtoc)\n  lfs\tf0, 0x01A8 (r3)\n  fmuls\tf0,f2,f0\n  fmadds\tREG_arctan,f0,REG_DIInput,REG_arctan\n  fmr f1,REG_arctan\n  branchl r12,cos\n  fmuls REG_KnockbackX,REG_KnockbackMag,f1\n  fmr f1,REG_arctan\n  branchl r12,sin\n  fmuls REG_KnockbackY,REG_KnockbackMag,f1\nDIDraw_CalculateDIEnd:\n#endregion\n\n#Perform collision checks for each frame of hitstun\n#region DIDraw_Collision\n\n#region DIDraw_CollisionLoop_Init\nDIDraw_CollisionLoop_Init:\n#Create an ECB struct on the stack\n\taddi\tREG_ECBBoneStruct,sp,Stack_ECBBoneStruct\n\taddi\tREG_ECBStruct,sp,Stack_ECBStruct\n\tmr\tr3,REG_ECBStruct\n\tbranchl\tr12,0x80041ee4\n#Get Current XY\n\tlfs\tREG_CurrXPos,0xB0(REG_PlayerData)\n\tlfs\tREG_CurrYPos,0xB4(REG_PlayerData)\n#Init Loop\n\tli\tREG_LoopCount,0\n  lfs REG_Gravity,-0x750C (rtoc)\n  lwz  REG_GroundState,0xE0(REG_PlayerData)\n  li  REG_OverrideRemainingFrames,0\n#Allocate collision info struct\n  lfs f1,0x2340(REG_PlayerData)\n  fctiwz  f1,f1\n  stfd  f1,Stack_MiscSpace(sp)\n  lwz  r3,Stack_MiscSpace+4(sp)\n  mulli r3,r3,CollInfo_Length       #backing up X bytes per collision check\n  addi  r3,r3,0x4        #small header containing the amount of collision checks\n  branchl r12,HSD_MemAlloc\n  mr  REG_CollisionInfo,r3\n#Init collision info struct\n  li  r3,-1               #init as 0 checks\n  stw r3,0x0(REG_CollisionInfo)\n#If grounded, copy over ground ECB data\n  cmpwi REG_GroundState,0\n  bne DIDraw_DrawTrajectory_SkipCopyGroundData\n  addi  r3,REG_ECBStruct,0x130\n  addi  r4,REG_PlayerData,0x820\n  li  r5,0x28\n  branchl r12,memcpy\nDIDraw_DrawTrajectory_SkipCopyGroundData:\n#endregion\n#region DIDraw_CollisionLoop_Start\nDIDraw_CollisionLoop:\n\n#region Initalize ECB Bone Positions\n#Create ECB Bone struct\n#If loop count < noECBUpdate-remaining hitlag fraes, use current ECB bottom Y offset\n  lwz r3,0x88C(REG_PlayerData)\n  lfs f1,0x195C(REG_PlayerData)\n  fctiwz  f1,f1\n  stfd  f1,Stack_MiscSpace(sp)\n  lwz r4,Stack_MiscSpace+0x4(sp)\n  sub r3,r3,r4\n  cmpw  REG_LoopCount,r3\n  blt DIDraw_CollisionLoop_ECBBonesUseCurrent\n#Copy Struct\n\tmr\tr3,REG_ECBBoneStruct\n\taddi\tr4,REG_EventConstants,ECB_TopY\n\tli\tr5,0x18\n\tbranchl\tr12,memcpy\n#If the player is grounded, ECB bottom is 0\n  cmpwi REG_GroundState,0\n  bne DIDraw_CollisionLoop_ECBBonesEnd\n  lfs\tf1, -0x750C (rtoc)\n  stfs f1,0x04(REG_ECBBoneStruct)\n  b DIDraw_CollisionLoop_ECBBonesEnd\nDIDraw_CollisionLoop_ECBBonesUseCurrent:\n#Use Current Bone Positions\n  lfs f1,0x778(REG_PlayerData)\n  stfs f1,0x00(REG_ECBBoneStruct)\n  lfs f1,0x780(REG_PlayerData)\n  stfs f1,0x04(REG_ECBBoneStruct)\n  lfs f1,0x78C(REG_PlayerData)\n  stfs f1,0x08(REG_ECBBoneStruct)\n  lfs f1,0x790(REG_PlayerData)\n  stfs f1,0x0C(REG_ECBBoneStruct)\n  lfs f1,0x784(REG_PlayerData)\n  stfs f1,0x10(REG_ECBBoneStruct)\n  lfs f1,0x788(REG_PlayerData)\n  stfs f1,0x14(REG_ECBBoneStruct)\n  b DIDraw_CollisionLoop_ECBBonesEnd\nDIDraw_CollisionLoop_ECBBonesEnd:\n#Store current position\n  lfs\tf1, -0x750C (rtoc)\n\tstfs\tREG_CurrXPos,0x4(REG_ECBStruct)\n\tstfs\tREG_CurrYPos,0x8(REG_ECBStruct)\n  stfs\tf1,0xC(REG_ECBStruct)\n\tstfs\tREG_CurrXPos,0x10(REG_ECBStruct)\n\tstfs\tREG_CurrYPos,0x14(REG_ECBStruct)\n  stfs\tf1,0x18(REG_ECBStruct)\n#endregion\n\n#region Apply ASDI\nDIDraw_CollisionLoop_ApplyASDI:\n#Apply ASDI X\n  fadds REG_CurrXPos,REG_CurrXPos,REG_ASDIX\n#Only apply ASDI Y if in the air\n  cmpwi REG_GroundState,0\n  beq 0x8\n  fadds REG_CurrYPos,REG_CurrYPos,REG_ASDIY\n#Null ASDI\n  lfs\tREG_ASDIX, -0x750C (rtoc)\n  lfs\tREG_ASDIY, -0x750C (rtoc)\n#endregion\n\n#region Decay Knockback\n#Apply either gravity or traction\n  cmpwi REG_GroundState,1\n  bne DIDraw_CollisionLoop_DecayGrounded\nDIDraw_CollisionLoop_DecayAerial:\n#Account for gravity\n  lfs\tf1, 0x016C (REG_PlayerData)\n  lfs\tf2, 0x0170 (REG_PlayerData)\n  fneg  f2,f2\n  fsubs REG_Gravity,REG_Gravity,f1\n  fcmpo\tcr0,REG_Gravity,f2\n  bge 0x8\n  fmr REG_Gravity,f2\n#Decay KB Vector\n  fmr f1,REG_KnockbackY\n  fmr f2,REG_KnockbackX\n  branchl r12,0x80022c30    #Get arctan of the KB vector\n  fmr  REG_arctan,f1\n#Decay X KB\n  branchl r12,cos\n  lwz\tr3, -0x514C (r13)\n  lfs\tf2, 0x0204 (r3)\n  fnmsubs\tREG_KnockbackX,f2,f1,REG_KnockbackX\n#Decay Y KB\n  fmr f1,REG_arctan\n  branchl r12,sin\n  lwz\tr3, -0x514C (r13)\n  lfs\tf2, 0x0204 (r3)\n  fnmsubs\tREG_KnockbackY,f2,f1,REG_KnockbackY\n  b DIDraw_CollisionLoop_DecayEnd\nDIDraw_CollisionLoop_DecayGrounded:\n#Get Ground Friction's multipllier\n  lwz r3,0x4(REG_PlayerData)\n  cmpwi r3,Popo.Int\n  beq DIDraw_CollisionLoop_DecayGrounded_isICs\n  cmpwi r3,Nana.Int\n  beq DIDraw_CollisionLoop_DecayGrounded_isICs\n#Get grounds friction multiplier\n  lfs\tf1, -0x7A38 (rtoc)\n  lwz\tr0, 0x014C (REG_ECBStruct)\n  cmpwi r0,-1\n  beq DIDraw_CollisionLoop_DecayGrounded_isICs\n  lwz r3,0x150(REG_ECBStruct)\n  branchl r12,0x800569ec    #Get ground's friction multiplier\n  b 0x8\nDIDraw_CollisionLoop_DecayGrounded_isICs:\n  lfs\tf1, -0x7A38 (rtoc)\n#Account for friction\n  lfs\tf0, 0x128 (REG_PlayerData)\n  fmuls\tf1,f0,f1\n  lwz\tr4, -0x514C (r13)\n  lfs\tf0, 0x0200 (r4)\n  fmuls f0,f1,f0\n#Apply Friction to knockback\n  lfs\tf2, -0x76B0 (rtoc)\n  fcmpo cr0,REG_KnockbackX,f2\n  bge DIDraw_CollisionLoop_DecayGrounded_Subtract\n  fadds f0,f0,REG_KnockbackX\n  fmr REG_KnockbackX,f0\n  fcmpo cr0,f0,f2\n  ble DIDraw_CollisionLoop_DecayGroundedEnd\n  fmr REG_KnockbackX,f2\n  b DIDraw_CollisionLoop_DecayGroundedEnd\nDIDraw_CollisionLoop_DecayGrounded_Subtract:\n  fsubs\tf0,REG_KnockbackX,f0\n  fmr REG_KnockbackX,f0\n  fcmpo cr0,f0,f2\n  bge DIDraw_CollisionLoop_DecayGroundedEnd\n  fmr REG_KnockbackX,f2\n  b DIDraw_CollisionLoop_DecayGroundedEnd\nDIDraw_CollisionLoop_DecayGroundedEnd:\nDIDraw_CollisionLoop_DecayEnd:\n#endregion\n\n#region Shift Positions\n#Shift previous positions down\n  lfs f1,0x4(REG_ECBStruct)\n  lfs f2,0x8(REG_ECBStruct)\n  lfs f3,0xC(REG_ECBStruct)\n  stfs f1,0x1C(REG_ECBStruct)\n  stfs f2,0x20(REG_ECBStruct)\n  stfs f3,0x24(REG_ECBStruct)\n#Store next position\n\tfadds\tf1,REG_CurrXPos,REG_KnockbackX\n\tstfs\tf1,0x4(REG_ECBStruct)\n\tfadds\tf1,REG_CurrYPos,REG_KnockbackY\n  fadds f1,f1,REG_Gravity\n\tstfs\tf1,0x8(REG_ECBStruct)\n\tlfs\tf1, -0x778C (rtoc)\n\tstfs\tf1,0xC(REG_ECBStruct)\n#endregion\n\n#region Run Collision Check\n\n.if MaxColl>=0\n#Only run X collision checks because theyre expensive\n  cmpwi REG_LoopCount,MaxColl\n  blt DIDraw_CollisionLoop_DetermineCollision\n#Spoof as not touching anything\n  li  r3,0\n  stw r3,0x134(REG_ECBStruct)\n\tlfs\tREG_CurrXPos,0x4(REG_ECBStruct)\n\tlfs\tREG_CurrYPos,0x8(REG_ECBStruct)\n#If grounded and max collision checks, just stop updating position\n  cmpwi REG_GroundState,0\n  bne  DIDraw_CollisionLoop_StageBehaviorEnd\n  li  REG_OverrideRemainingFrames,1\n  b DIDraw_CollisionLoop_StageBehaviorEnd\n.endif\n\nDIDraw_CollisionLoop_DetermineCollision:\n#Run collision\n  cmpwi REG_GroundState,1\n  beq DIDraw_CollisionLoop_AerialCollision\nDIDraw_CollisionLoop_GroundCollision:\n#Grounded Collision\n\tmr\tr3,REG_ECBStruct\n\tmr\tr4,REG_ECBBoneStruct\n\tbranchl\tr12,0x8004b21c\n  xori  REG_GroundState,r3,0x1\n  b DIDraw_CollisionLoop_CollisionEnd\nDIDraw_CollisionLoop_AerialCollision:\n#Aerial Collision\n\tmr\tr3,REG_ECBStruct\n\tmr\tr4,REG_ECBBoneStruct\n\tbranchl\tr12,0x800475f4\nDIDraw_CollisionLoop_CollisionEnd:\n#endregion\n\n#region Stage Collision Behavior\n#Get new position\n\tlfs\tREG_CurrXPos,0x4(REG_ECBStruct)\n\tlfs\tREG_CurrYPos,0x8(REG_ECBStruct)\n#Inc Collision ID\n  lwz r3,0x38(REG_ECBStruct)\n  addi  r3,r3,1\n  stw r3,0x38(REG_ECBStruct)\n#Determine line collision behavior\n  lwz r3,0x134(REG_ECBStruct)\n  rlwinm. r0,r3,0,0x8000\n  bne DIDraw_CollisionLoop_TouchingGround\n  rlwinm. r0,r3,0,0x6000\n  bne DIDraw_CollisionLoop_TouchingCeiling\n  rlwinm. r0,r3,0,0x20\n  bne DIDraw_CollisionLoop_TouchingWall\n  rlwinm. r0,r3,0,0x40\n  bne DIDraw_CollisionLoop_TouchingWall\nDIDraw_CollisionLoop_TouchingNothing:\n  b DIDraw_CollisionLoop_StageBehaviorEnd\n\n#region Touching Ground\nDIDraw_CollisionLoop_TouchingGround:\n#If grounded, dont run KB manip code\n  cmpwi REG_GroundState,0\n  beq DIDraw_CollisionLoop_StageBehaviorEnd\n/*\n#End check\n  li  REG_OverrideRemainingFrames,1\n*/\n#Check if over max horizontal velocity\n  lwz\tr4, -0x514C (r13)\n  lfs\tf1, 0x0164 (r4)\n  fcmpo cr0,REG_KnockbackX,f1\n  ble 0x8\n  fmr REG_KnockbackX,f1\n  fneg  f1,f1\n  fcmpo cr0,REG_KnockbackX,f1\n  bge 0x8\n  fmr REG_KnockbackX,f1\n#Adjust KB\n  lfs f1,0x158(REG_ECBStruct)\n  fmuls REG_KnockbackX,REG_KnockbackX,f1\n  lfs f1,0x154(REG_ECBStruct)\n  fneg  f1,f1\n  fmuls REG_KnockbackY,REG_KnockbackX,f1\n#REMOVE ALL Y KB?\n  lfs\tREG_KnockbackY, -0x750C (rtoc)\n#Set as grounded\n  li  REG_GroundState,0\n  b DIDraw_CollisionLoop_StageBehaviorEnd\n#endregion\n#region Touching Ceiling\nDIDraw_CollisionLoop_TouchingCeiling:\n#If grounded, dont run KB manip code\n  cmpwi REG_GroundState,0\n  beq DIDraw_CollisionLoop_StageBehaviorEnd\n#End check\n  li  REG_OverrideRemainingFrames,1\n/*\n#Self-Induced velocity\n  lfs\tf1, -0x750C (rtoc)\n  stfs f1,Stack_MiscSpace+0x0(sp)\n  stfs REG_Gravity,Stack_MiscSpace+0x4(sp)\n#KB-Induced\n  stfs REG_KnockbackX,Stack_MiscSpace+0x8(sp)\n  stfs REG_KnockbackY,Stack_MiscSpace+0xC(sp)\n#Add vectors\n  addi  r3,sp,Stack_MiscSpace+0x0\n  addi  r4,sp,Stack_MiscSpace+0x8\n  branchl r12,0x8000d4a0\n#Unk\n  addi  r3,sp,Stack_MiscSpace+0x0\n  addi  r4,REG_ECBStruct,0x190\n  branchl r12,0x8000dc6c\n#Decay KB\n  lwz\tr3, -0x514C (r13)\n  lfs\tf1, 0x01BC (r3)\n  lfs f2,Stack_MiscSpace+0x0(sp)\n  lfs f3,Stack_MiscSpace+0x4(sp)\n  fmuls REG_KnockbackX,f1,f2\n  fmuls REG_KnockbackY,f1,f3\n*/\n  b DIDraw_CollisionLoop_StageBehaviorEnd\n#endregion\n#region Touching Wall\nDIDraw_CollisionLoop_TouchingWall:\n#If grounded, dont run KB manip code\n  cmpwi REG_GroundState,0\n  beq DIDraw_CollisionLoop_StageBehaviorEnd\n#End check\n  li  REG_OverrideRemainingFrames,1\n/*\n#Get walls data\n  lwz r3,0x134(REG_ECBStruct)\n  rlwinm. r0,r3,0,0x20\n  bne DIDraw_CollisionLoop_LeftWallsData\n  rlwinm. r0,r3,0,0x40\n  bne DIDraw_CollisionLoop_RightWallsData\nDIDraw_CollisionLoop_RightWallsData:\n  addi  REG_Temp,REG_ECBStruct,380\n  b 0x8\nDIDraw_CollisionLoop_LeftWallsData:\n  addi  REG_Temp,REG_ECBStruct,360\n#Self-Induced velocity\n  lfs\tf1, -0x750C (rtoc)\n  stfs f1,Stack_MiscSpace+0x0(sp)\n  stfs REG_Gravity,Stack_MiscSpace+0x4(sp)\n#KB-Induced\n  stfs REG_KnockbackX,Stack_MiscSpace+0x8(sp)\n  stfs REG_KnockbackY,Stack_MiscSpace+0xC(sp)\n#Add vectors\n  addi  r3,sp,Stack_MiscSpace+0x0\n  addi  r4,sp,Stack_MiscSpace+0x8\n  branchl r12,0x8000d4a0\n#Unk\n  addi  r3,sp,Stack_MiscSpace+0x0\n  mr  r4,REG_Temp\n  branchl r12,0x8000dc6c\n#Decay KB\n  lwz\tr3, -0x514C (r13)\n  lfs\tf1, 0x01BC (r3)\n  lfs f2,Stack_MiscSpace+0x0(sp)\n  lfs f3,Stack_MiscSpace+0x4(sp)\n  fmuls REG_KnockbackX,f1,f2\n  fmuls REG_KnockbackY,f1,f3\n  lfs\tREG_Gravity, -0x6DA0 (rtoc)\n*/\n  b DIDraw_CollisionLoop_StageBehaviorEnd\n#endregion\nDIDraw_CollisionLoop_StageBehaviorEnd:\n#endregion\n\n#region Ground to Air Check\n.if MaxColl>=0\nDIDraw_CollisionLoop_GroundToAirCheck:\n.set  GroundToAirRemainingFrames,5\n#Ensure not touching ground this frame\n  lwz r3,0x134(REG_ECBStruct)\n  rlwinm. r0,r3,0,0x8000\n  bne DIDraw_CollisionLoop_GroundToAirCheckEnd\n#Ensure was touching ground last frame\n  lwz r3,0x138(REG_ECBStruct)\n  rlwinm. r0,r3,0,0x8000\n  beq DIDraw_CollisionLoop_GroundToAirCheckEnd\n#End check\n  li  REG_OverrideRemainingFrames,1\n/*\n#Check if over MaxColl\n  cmpwi REG_LoopCount,MaxColl\n  blt DIDraw_CollisionLoop_GroundToAirCheckEnd\n#Check if REG_OverrideRemainingFrames is already set\n  cmpwi REG_OverrideRemainingFrames,0\n  bgt DIDraw_CollisionLoop_GroundToAirCheckEnd\n#Set REG_OverrideRemainingFrames\n  li  REG_OverrideRemainingFrames,GroundToAirRemainingFrames\n*/\nDIDraw_CollisionLoop_GroundToAirCheckEnd:\n.endif\n#endregion\n\n#region Save Collision Info\n.set  CollInfo_Length,0x18\n.set  CollInfo_XPos,0x0\n.set  CollInfo_YPos,0x4\n.set  CollInfo_EnvBitfield,0x8\n.set  CollInfo_ECBTopY,0xC\n.set  CollInfo_ECBLeftY,0x10\n.set  CollInfo_KnockbackY,0x14\n#Update collision check count\n  stw REG_LoopCount,0x0(REG_CollisionInfo)\n#Get this frames offset in info struct\n  addi  r3,REG_CollisionInfo,0x4    #skip past header\n  mulli r4,REG_LoopCount,CollInfo_Length\n  add r3,r3,r4\n#Store data\n  stfs  REG_CurrXPos,CollInfo_XPos(r3)\n  stfs  REG_CurrYPos,CollInfo_YPos(r3)\n  lwz r4,0x134(REG_ECBStruct)\n  stw  r4,CollInfo_EnvBitfield(r3)\n  lfs f1,0x88(REG_ECBStruct)\n  stfs  f1,CollInfo_ECBTopY(r3)\n  lfs f1,0xA0(REG_ECBStruct)\n  stfs  f1,CollInfo_ECBLeftY(r3)\n  stfs  REG_KnockbackY,CollInfo_KnockbackY(r3)\n#endregion\n\nDIDraw_CollisionLoop_IncLoop:\n#Check override frames first\n  cmpwi REG_OverrideRemainingFrames,0\n  ble DIDraw_CollisionLoop_IncLoopNoOverride\n#Decrement override frames\n  subi  REG_OverrideRemainingFrames,REG_OverrideRemainingFrames,1\n  cmpwi REG_OverrideRemainingFrames,0\n  bgt DIDraw_CollisionLoop_IncLoopNoOverride\n#Override and exit loop prematurely\n  b DIDraw_CollisionLoop_IncLoopEnd\nDIDraw_CollisionLoop_IncLoopNoOverride:\n#Inc Loop\n\taddi\tREG_LoopCount,REG_LoopCount,1\n#Check if non-meteor cancellable\n  lbz r3,0x235A(REG_PlayerData)\n  cmpwi r3,1\n  bne DIDraw_CollisionLoop_IncLoopCheckHitstunFrames\n  lwz\tr3, -0x514C (r13)\n  lwz\tr3, 0x07F0 (r3)\n  cmpw  REG_LoopCount,r3\n  bgt DIDraw_CollisionLoop_IncLoopEnd\nDIDraw_CollisionLoop_IncLoopCheckHitstunFrames:\n  lfs f1,0x2340(REG_PlayerData)\n  fctiwz  f1,f1\n  stfd  f1,Stack_MiscSpace(sp)\n  lwz  r3,Stack_MiscSpace+4(sp)\n\tcmpw\tREG_LoopCount,r3\n\tblt\tDIDraw_CollisionLoop\nDIDraw_CollisionLoop_IncLoopEnd:\n/*\n.if MaxColl>=0\n#Output collision checks count\n  bl  DIDraw_CollisionLoop_Text\n  mflr  r3\n  lwz r4,TM_GameFrameCounter(r13)\n  mr  r5,REG_LoopCount\n  branchl r12,OSReport\n  b DIDraw_CollisionLoop_TextEnd\nDIDraw_CollisionLoop_Text:\nblrl\n.string \"frame %d performed %d collision checks\\n\"\n.align 2\nDIDraw_CollisionLoop_TextEnd:\n.endif\n*/\n#endregion\n#endregion\n\n#region DIDraw_DeathCheck\nDIDraw_DrawLoop_Init:\n.set REG_DeathLoopCount,28\n  li  REG_DeathLoopCount,0\nDIDraw_DrawLoop_Init_DeathLoop:\n  addi  r3,REG_CollisionInfo,0x4\n  mulli r4,REG_DeathLoopCount,CollInfo_Length\n  add  r3,r3,r4                     #get last frames info\n  lfs REG_CurrXPos,CollInfo_XPos(r3)\n  lfs REG_CurrYPos,CollInfo_YPos(r3)\n  lfs REG_KnockbackY,CollInfo_KnockbackY(r3)\n  branchl r12,0x80224b38            #right blastzone\n  fcmpo cr0,REG_CurrXPos,f1\n  bgt DIDraw_DrawLoop_Init_Dead\n  branchl r12,0x80224b50            #left blastzone\n  fcmpo cr0,REG_CurrXPos,f1\n  blt DIDraw_DrawLoop_Init_Dead\n  branchl r12,0x80224b80            #bottom blastzone\n  fcmpo cr0,REG_CurrYPos,f1\n  blt DIDraw_DrawLoop_Init_Dead\n  branchl r12,0x80224b68            #top blastzone\n  fcmpo cr0,REG_CurrYPos,f1\n  ble DIDraw_DrawLoop_Init_DeathLoop_Inc\n  cmpwi REG_GroundState,0\n  beq DIDraw_DrawLoop_Init_Dead\n  lwz\tr3, -0x514C (r13)\n  lfs\tf0, 0x04F0 (r3)\n  fcmpo cr0,REG_KnockbackY,f0\n  ble DIDraw_DrawLoop_Init_DeathLoop_Inc\nDIDraw_DrawLoop_Init_Dead:\n  li  r3,1\n  b DIDraw_DrawLoop_Init_DeathLoop_Exit\nDIDraw_DrawLoop_Init_DeathLoop_Inc:\n  addi  REG_DeathLoopCount,REG_DeathLoopCount,1\n  lwz r3,0x0(REG_CollisionInfo)\n  cmpw  REG_DeathLoopCount,r3\n  blt DIDraw_DrawLoop_Init_DeathLoop\n#Is alive, make blue\n  li  r3,0\nDIDraw_DrawLoop_Init_DeathLoop_Exit:\n#endregion\n\nDIDraw_Exit:\n  lmw  r20,Stack_BackedUpReg(r1)\n  lwz r0, StackSize+4(r1)\n  addi\tr1,r1,StackSize\t# release the space\n  mtlr r0\n  blr\n\n####################################################\n#endregion\n\nConstants:\nblrl\n.set  ZoomValue,0x0\n.set  Divisor,0x4\n.float 100\n.float 2\n\nCreateProc_Exit:\n  restore\n  lmw\tr24, 0x0038 (sp)\n"
  },
  {
    "path": "ASM/Additional Codes/Kill Zoom/Rumble During MH Zoom.s",
    "content": "#To be inserted at 8002e6e0\n.include \"../../Globals.s\"\n\nsubi  sp,sp,0x30\n\n#Get some camera data\n  addi  r3,sp,0x1C\n  load  r4,0x80452c7c\n  branchl r12,0x8002958c\n\n#Get rumble data\n  addi  r3,sp,0x1C\n  branchl r12,0x8002a28c\n\n#Apply rumble\n  addi  r3,sp,0x1C\n  load  r4,0x80452c7c\n  branchl r12,0x8002a0c0\n\naddi  sp,sp,0x30\n\nlwz\tr0, 0x003C (sp)\n"
  },
  {
    "path": "ASM/Additional Codes/L+R+A Returns to CSS During SSS.asm",
    "content": "#To be inserted at 8025B8BC\n.include \"../Globals.s\"\n\n#Load first minor of current major\n  load r3,SceneController\n  lbz r3,0x0(r3)\n"
  },
  {
    "path": "ASM/Additional Codes/Lag Reduction Prompt/Main.asm",
    "content": "#To be inserted at 801bf930\n.include \"../../Globals.s\"\n\n#Parameters\n.set  PromptSceneID,8 #0\n.set  ExitSceneID,40\n.set  PromptCommonSceneID,10\n.set  InitialSelection,0\n#Function Addresses\n.set  PostRetraceCallback,0x800195fc\n.set  UnkPadStruct,0x804329f0\n\n#region Init New Scenes\n.set  REG_MinorSceneStruct,31\n\n#Init and backup\n  backup\n\n#Init LagPrompt major struct\n  li  r3,PromptSceneID\n  bl  LagPrompt_MinorSceneStruct\n  mflr  r4\n  bl  LagPrompt_SceneLoad\n  mflr  r5\n  bl  InitializeMajorSceneStruct\n#Override LagPrompt SceneLoad\n  li  r3,PromptCommonSceneID\n  branchl r12,0x801a4ce0\n  bl  LagPrompt_SceneLoad\n  mflr  r4\n  stw r4,0x8(r3)\n\n\n  b CheckProgressive\n\n#region PointerConvert\nPointerConvert:\n  lwz r4,0x0(r3)          #Load bl instruction\n  rlwinm r5,r4,8,25,29    #extract opcode bits\n  cmpwi r5,0x48           #if not a bl instruction, exit\n  bne PointerConvert_Exit\n  rlwinm  r4,r4,0,6,29  #extract offset bits\n  extsh r4,r4\n  add r4,r4,r3\n  stw r4,0x0(r3)\nPointerConvert_Exit:\n  blr\n#endregion\n#region InitializeMajorSceneStruct\nInitializeMajorSceneStruct:\n.set  REG_MajorScene,31\n.set  REG_MinorStruct,30\n.set  REG_SceneLoad,29\n\n#Init\n  backup\n  mr  REG_MajorScene,r3\n  mr  REG_MinorStruct,r4\n  mr  REG_SceneLoad,r5\n\n#Get major scene struct\n  branchl r12,0x801a50ac\nGetMajorStruct_Loop:\n  lbz\tr4, 0x0001 (r3)\n  cmpw r4,REG_MajorScene\n  beq GetMajorStruct_Exit\n  addi  r3,r3,20\n  b GetMajorStruct_Loop\nGetMajorStruct_Exit:\n\nInitMinorSceneStruct:\n.set  REG_MinorStructParse,20\n  stw REG_MinorStruct,0x10(r3)\n  mr  REG_MinorStructParse,REG_MinorStruct\nInitMinorSceneStruct_Loop:\n#Check if valid entry\n  lbz r3,0x0(REG_MinorStructParse)\n  extsb r3,r3\n  cmpwi r3,-1\n  beq InitMinorSceneStruct_Exit\n#Convert Pointers\n  addi  r3,REG_MinorStructParse,0x4\n  bl  PointerConvert\n  addi  r3,REG_MinorStructParse,0x8\n  bl  PointerConvert\n  addi  REG_MinorStructParse,REG_MinorStructParse,0x18\n  b InitMinorSceneStruct_Loop\nInitMinorSceneStruct_Exit:\n\n  restore\n  blr\n#endregion\n#endregion\n\n#region LagPrompt\n\n#region LagPrompt_SceneLoad\n############################################\n\n#region LagPrompt_SceneLoad_Data\nLagPrompt_SceneLoad_TextProperties:\nblrl\n.set PromptX,0x0\n.set PromptY,0x4\n.set ZOffset,0x8\n.set CanvasScaling,0xC\n.set Scale,0x10\n.set YesX,0x14\n.set YesY,0x18\n.set YesScale,0x1C\n.set NoX,0x20\n.set NoY,0x24\n.set NoScale,0x28\n.set HighlightColor,0x2C\n.set NonHighlightColor,0x30\n.float 315     \t\t\t   #REG_TextGObj X pos\n.float 200  \t\t\t\t\t   #REG_TextGObj Y pos\n.float 0     \t\t     \t #Z offset\n.float 1   \t\t\t\t     #Canvas Scaling\n.float 1\t\t\t\t\t    \t#Text scale\n.float 265              #Yes X pos\n.float 300              #Yes Y pos\n.float 1              #Yes scale\n.float 365              #No X pos\n.float 300              #No Y pos\n.float 1              #No scale\n.byte 251,199,57,255\t\t#highlighted color\n.byte 170,170,170,255\t  #nonhighlighted color\n\nLagPrompt_SceneLoad_TopText:\nblrl\n.ascii \"Are you using HDMI\"\n.short 0x8148\n.byte 0\n.align 2\n\nLagPrompt_SceneLoad_Yes:\nblrl\n.string \"Yes\"\n.align 2\n\nLagPrompt_SceneLoad_No:\nblrl\n.string \"No\"\n.align 2\n\n#GObj Offsets\n  .set OFST_TextGObj,0x0\n  .set OFST_Selection,0x4\n\n#endregion\n#region LagPrompt_SceneLoad\nLagPrompt_SceneLoad:\nblrl\n\n#Init\n  backup\n\nLagPrompt_SceneLoad_CreateText:\n.set REG_GObjData,27\n.set REG_GObj,28\n.set REG_SubtextID,29\n.set REG_TextProp,30\n.set REG_TextGObj,31\n\n#GET PROPERTIES TABLE\n\tbl LagPrompt_SceneLoad_TextProperties\n\tmflr REG_TextProp\n\n#Create canvas\n  li  r3,0\n  li  r4,0\n  li  r5,9\n  li  r6,13\n  li  r7,0\n  li  r8,14\n  li  r9,0\n  li  r10,19\n  branchl r12,0x803a611c\n\n########################\n## Create Text Object ##\n########################\n\n#CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3\n\tli r3,0\n\tli r4,0\n\tbranchl r12,Text_CreateTextStruct\n#BACKUP STRUCT POINTER\n\tmr REG_TextGObj,r3\n  stw REG_TextGObj,0x0(REG_GObjData)\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x1\n\tstb r4,0x49(REG_TextGObj)\n#SET TEXT TO CENTER AROUND X LOCATION\n\tli r4,0x1\n\tstb r4,0x4A(REG_TextGObj)\n#Store Base Z Offset\n\tlfs f1,ZOffset(REG_TextProp) #Z offset\n\tstfs f1,0x8(REG_TextGObj)\n#Scale Canvas Down\n  lfs f1,CanvasScaling(REG_TextProp)\n  stfs f1,0x24(REG_TextGObj)\n  stfs f1,0x28(REG_TextGObj)\n\n#Create Prompt\n#Initialize Subtext\n\tmr \tr3,REG_TextGObj\t\t#struct pointer\n\tbl LagPrompt_SceneLoad_TopText\n  mflr  r4\n\tlfs\tf1,PromptX(REG_TextProp)\n  lfs\tf2,PromptY(REG_TextProp)\n\tbranchl r12,0x803a6b98\n  mr  REG_SubtextID,r3\n#Change Text Scale\n\tmr \tr3,REG_TextGObj\t\t#struct pointer\n\tmr\tr4,REG_SubtextID\n\tlfs \tf1,Scale(REG_TextProp) \t\t#X offset of REG_TextGObj\n\tlfs \tf2,Scale(REG_TextProp)\t  \t#Y offset of REG_TextGObj\n\tbranchl r12,Text_UpdateSubtextSize\n\n#Create Yes\n#Initialize Subtext\n\tmr \tr3,REG_TextGObj\t\t#struct pointer\n\tbl LagPrompt_SceneLoad_Yes\n  mflr  r4\n\tlfs\tf1,YesX(REG_TextProp)\n  lfs\tf2,YesY(REG_TextProp)\n\tbranchl r12,0x803a6b98\n  mr  REG_SubtextID,r3\n#Change Text Scale\n\tmr \tr3,REG_TextGObj\t\t#struct pointer\n\tmr\tr4,REG_SubtextID\n\tlfs \tf1,YesScale(REG_TextProp) \t\t#X offset of REG_TextGObj\n\tlfs \tf2,YesScale(REG_TextProp)\t  \t#Y offset of REG_TextGObj\n\tbranchl r12,Text_UpdateSubtextSize\n\n#Create No\n#Initialize Subtext\n\tmr \tr3,REG_TextGObj\t\t#struct pointer\n\tbl LagPrompt_SceneLoad_No\n  mflr  r4\n\tlfs\tf1,NoX(REG_TextProp)\n  lfs\tf2,NoY(REG_TextProp)\n\tbranchl r12,0x803a6b98\n  mr  REG_SubtextID,r3\n#Change Text Scale\n\tmr \tr3,REG_TextGObj\t\t#struct pointer\n\tmr\tr4,REG_SubtextID\n\tlfs \tf1,NoScale(REG_TextProp) \t\t#X offset of REG_TextGObj\n\tlfs \tf2,NoScale(REG_TextProp)\t  \t#Y offset of REG_TextGObj\n\tbranchl r12,Text_UpdateSubtextSize\n\n#Create GObj\n  li  r3, 13\n  li  r4,14\n  li  r5,0\n  branchl r12, GObj_Create\n  mr  REG_GObj,r3\n#Allocate Space\n\tli\tr3,64\n\tbranchl r12,HSD_MemAlloc\n\tmr\tREG_GObjData,r3\n#Zero\n\tli\tr4,64\n\tbranchl r12,ZeroAreaLength\n#Initialize\n\tmr\tr6,REG_GObjData\n\tmr\tr3,REG_GObj\n\tli\tr4,4\n\tload\tr5,0x8037f1b0\n\tbranchl r12,GObj_AddUserData\n#Add Proc\n  mr  r3,REG_GObj\n  bl  LagPrompt_SceneThink\n  mflr  r4      #Function to Run\n  li  r5,0      #Priority\n  branchl r12, GObj_AddProc\n\n#Store text gobj pointer\n  stw REG_TextGObj,OFST_TextGObj(REG_GObjData)\n#Init Selection value\n  li  r3,InitialSelection\n  stb r3,OFST_Selection(REG_GObjData)\n\n#Highlight selection\n  mr  r3,REG_TextGObj\n  li  r4,InitialSelection+1\n  addi  r5,REG_TextProp,HighlightColor\n  branchl r12,Text_ChangeTextColor\n\nLagPrompt_SceneLoad_Exit:\n  restore\n  blr\n#endregion\n\n############################################\n#endregion\n#region LagPrompt_SceneThink\nLagPrompt_SceneThink:\nblrl\n\n.set REG_TextProp,28\n.set REG_Inputs,29\n.set REG_GObjData,30\n.set REG_GObj,31\n\n#Init\n  backup\n  mr  REG_GObj,r3\n  lwz REG_GObjData,0x2C(REG_GObj)\n  bl  LagPrompt_SceneLoad_TextProperties\n  mflr  REG_TextProp\n\n#region Adjust Selection\n#Adjust Menu Choice\n#Get all player inputs\n  li  r3,4\n  branchl r12,0x801a36c0\n  mr  REG_Inputs,r3\n#Check for movement to the right\n  rlwinm. r0,REG_Inputs,0,0x80\n  beq LagPrompt_SceneThink_SkipRight\n#Adjust cursor\n  lbz r3,OFST_Selection(REG_GObjData)\n  addi  r3,r3,1\n  stb r3,OFST_Selection(REG_GObjData)\n  extsb r3,r3\n  cmpwi r3,1\n  ble LagPrompt_SceneThink_HighlightSelection\n  li  r3,1\n  stb r3,OFST_Selection(REG_GObjData)\n  b LagPrompt_SceneThink_CheckForA\nLagPrompt_SceneThink_SkipRight:\n#Check for movement to the left\n  rlwinm. r0,REG_Inputs,0,0x40\n  beq LagPrompt_SceneThink_CheckForA\n#Adjust cursor\n  lbz r3,OFST_Selection(REG_GObjData)\n  subi  r3,r3,1\n  stb r3,OFST_Selection(REG_GObjData)\n  extsb r3,r3\n  cmpwi r3,0\n  bge LagPrompt_SceneThink_HighlightSelection\n  li  r3,0\n  stb r3,OFST_Selection(REG_GObjData)\n  b LagPrompt_SceneThink_CheckForA\n\nLagPrompt_SceneThink_HighlightSelection:\n#Unhighlight both options\n  lwz r3,OFST_TextGObj(REG_GObjData)\n  li  r4,1\n  addi  r5,REG_TextProp,NonHighlightColor\n  branchl r12,Text_ChangeTextColor\n  lwz r3,OFST_TextGObj(REG_GObjData)\n  li  r4,2\n  addi  r5,REG_TextProp,NonHighlightColor\n  branchl r12,Text_ChangeTextColor\n#Highlight selection\n  lwz r3,OFST_TextGObj(REG_GObjData)\n  lbz r4,OFST_Selection(REG_GObjData)\n  addi  r4,r4,1\n  addi  r5,REG_TextProp,HighlightColor\n  branchl r12,Text_ChangeTextColor\n#Play SFX\n  branchl r12,0x80174380\n#endregion\n#region Check for Confirmation\nLagPrompt_SceneThink_CheckForA:\n  li  r3,4\n  branchl r12,0x801a36a0\n  rlwinm. r0,r4,0,0x100\n  bne LagPrompt_SceneThink_Confirmed\n  rlwinm. r0,r4,0,0x1000\n  bne LagPrompt_SceneThink_Confirmed\n  b LagPrompt_SceneThink_Exit\nLagPrompt_SceneThink_Confirmed:\n#Play Menu Sound\n  branchl r12,0x80174338\n#If yes, apply lag reduction\n  lbz r3,OFST_Selection(REG_GObjData)\n  cmpwi r3,0\n  bne LagPrompt_SceneThink_ExitScene\n#endregion\n#region Apply Code\n.set  REG_GeckoCode,12\n#Apply lag reduction\n  bl  LagReductionGeckoCode\n  mflr  r3\n  bl  ApplyGeckoCode\n#Reset some pad variables to cancel the current alarm\n  load  r3,UnkPadStruct\n  li  r4,0\n  stw r4,0x4(r3)\n  stw r4,0x44(r3)\n#Set new post retrace callback\n  load  r3,PostRetraceCallback\n  branchl r12,0x80375934\n#Now flush the instruction cache\n  lis r3,0x8000\n  load r4,0x3b722c    #might be overkill but flush the entire dol file\n  branchl r12,0x80328f50\n#endregion\n\nLagPrompt_SceneThink_ExitScene:\n  branchl r12,0x801a4b60\n\nLagPrompt_SceneThink_Exit:\n  restore\n  blr\n#endregion\n#region LagPrompt_SceneDecide\nLagPrompt_SceneDecide:\n  backup\n\n#Exit Scene\n  li  r3,ExitSceneID\n  branchl r12,0x801a42e8\n#Change Major\n  branchl r12,0x801a42d4\n\nLagPrompt_SceneDecide_Exit:\n  restore\n  blr\n############################################\n#endregion\n#region LagReductionGeckoCode\nLagReductionGeckoCode:\nblrl\n.long 0x04019860\n.long 0x4BFFFD9D\n.long 0x041a4c24\n.long 0xC0429A7C\n.long 0xFF000000\n#endregion\n#region ApplyGeckoCode\nApplyGeckoCode:\n.set  REG_GeckoCode,12\n  mr  REG_GeckoCode,r3\n\nApplyGeckoCode_Loop:\n  lbz r3,0x0(REG_GeckoCode)\n  cmpwi r3,0x4\n  beq ApplyGeckoCode_04\n  cmpwi r3,0xFF\n  beq ApplyGeckoCode_Exit\n  b ApplyGeckoCode_Exit\nApplyGeckoCode_04:\n  lwz r3,0x0(REG_GeckoCode)\n  rlwinm r3,r3,0,8,31\n  oris  r3,r3,0x8000\n  lwz r4,0x4(REG_GeckoCode)\n  stw r4,0x0(r3)\n  addi REG_GeckoCode,REG_GeckoCode,0x8\n  b ApplyGeckoCode_Loop\nApplyGeckoCode_Exit:\nblr\n\n#endregion\n\n#endregion\n\n#region MinorSceneStruct\nLagPrompt_MinorSceneStruct:\nblrl\n#Lag Prompt\n.byte 0                     #Minor Scene ID\n.byte 00                    #Amount of persistent heaps\n.align 2\n.long 0x00000000            #ScenePrep\nbl  LagPrompt_SceneDecide   #SceneDecide\n.byte PromptCommonSceneID   #Common Minor ID\n.align 2\n.long 0x00000000            #Minor Data 1\n.long 0x00000000            #Minor Data 2\n#End\n.byte -1\n.align 2\n\n#endregion\n\nCheckProgressive:\n#Check if progressive is enabled\n  branchl r12,0x80349278\n  cmpwi r3,0\n  beq NoProgressive\nIsProgressive:\n#Load LagPrompt\n  li\tr3, PromptSceneID\n  b Injection_Exit\nNoProgressive:\n#Exit Scene\n  li  r3,ExitSceneID\n\nInjection_Exit:\n  restore\n"
  },
  {
    "path": "ASM/Additional Codes/Last Unplug Closes All CSS Doors.asm",
    "content": "#To be inserted at 802605e4\n.include \"../Globals.s\"\n\nbackup\n\n#Check if all controllers are unplugged\n  load  r3,HSD_Pad+0x144\n  li  r4,0\nUnplugLoop:\n  mulli r5,r4,68\n  add r5,r5,r3\n  lbz r5,0x41(r5)\n  extsb. r5,r5\n  beq Exit\n  addi  r4,r4,1\n  cmpwi r4,4\n  blt UnplugLoop\n\n.set  REG_LoopCount,31\n.set  REG_DoorStruct,30\n#All are unplugged, close all doors\n  load  REG_DoorStruct,CSS_DoorStructs\n  li  REG_LoopCount,0\nDoorUpdateLoop:\n#Change State\n  mulli r3,REG_LoopCount,0x24\n  add r3,r3,REG_DoorStruct\n  li  r4,3\n  stb r4,CSSDoor_State(r3)\n#Update Door State\n  mr  r3,REG_LoopCount\n  branchl r12,CSS_UpdateCSPInfo\n#Inc Loop\n  addi  REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,4\n  blt DoorUpdateLoop\n\nExit:\n  restore\n  lbz\tr0, 0x0004 (r31)\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/8Characters1.asm",
    "content": "#To be inserted at 8023c710\n.include \"../../../Globals.s\"\n\ncmplwi r3, 7\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/8Characters2.asm",
    "content": "#To be inserted at 8023c320\n.include \"../../../Globals.s\"\n\ncmplwi r3, 7\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/8Characters3.asm",
    "content": "#To be inserted at 8023c6c4\n.include \"../../../Globals.s\"\n\ncmplwi r3, 7\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/8Characters4.asm",
    "content": "#To be inserted at 8023cf9c\n.include \"../../../Globals.s\"\n\ncmpwi r27, 0x8\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/Adjust Cursor Position.asm",
    "content": "#To be inserted at 8023E0A4\n.include \"../../../Globals.s\"\n\n  fsubs f0, f0, f2\n  bl  Floats\n  mflr  r4\n  lfs f1, 0(r4)\n  fdivs f0, f0, f1\n  b Exit\n\nFloats:\nblrl\n.float 2\n\nExit:\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/Character Spacing.asm",
    "content": "#To be inserted at 8023cf74\n.include \"../../../Globals.s\"\n\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/Copy 8 Characters1.asm",
    "content": "#To be inserted at 8023cb08\n.include \"../../../Globals.s\"\n\n  li  r10,0\n  mr  r9,r6\n  b GetTag_Loop\nGetTag_IncLoop:\n  stb r3,0x0(r7)\n  addi  r5,r5,1\n  addi  r7,r7,1\n  addi  r9,r9,1\nGetTag_Loop:\n  lbz r3,0x0(r9)\n  cmpwi r3,0\n  bne GetTag_IncLoop\n#Check if all 8 letters are read\n  addi  r6,r6,3\n  mr  r9,r6\n  addi  r10,r10,1\n  cmpwi r10,8\n  blt GetTag_Loop\n  li  r4,0\n  branch  r12,0x8023cbec\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/Copy 8 Characters2.asm",
    "content": "#To be inserted at 8023c02c\n.include \"../../../Globals.s\"\n\n.set  REG_Source,4\n.set  REG_Dest,7\n.set  REG_CharCount,8\n.set  REG_SourceCopied,9\n\n  li  r10,0\n  li  REG_CharCount,0\n  addi  REG_Dest,r30,408\n  mr  REG_SourceCopied,REG_Source\n  b GetTag_Loop\nGetTag_IncLoop:\n  stb r3,0x0(REG_Dest)\n  addi  REG_CharCount,REG_CharCount,1\n  addi  REG_Dest,REG_Dest,1\n  addi  REG_SourceCopied,REG_SourceCopied,1\nGetTag_Loop:\n  lbz r3,0x0(REG_SourceCopied)\n  cmpwi r3,0\n  bne GetTag_IncLoop\n#Check if all 8 letters are read\n  addi  REG_Source,REG_Source,3\n  mr  REG_SourceCopied,REG_Source\n  addi  r10,r10,1\n  cmpwi r10,8\n  blt GetTag_Loop\n  mr  r7,REG_CharCount\n  branch  r12,0x8023c118\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/Disable Tag Rumble - Ignore Tag Rumble.asm",
    "content": "#To be inserted at 80167810\n.include \"../../../Globals.s\"\n\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/Disable Tag Rumble - Init.asm",
    "content": "#To be inserted at 8023c12c\n.include \"../../../Globals.s\"\n\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/Disable Tag Rumble - RumbleLoad.asm",
    "content": "#To be inserted at 80248c8c\n.include \"../../../Globals.s\"\n\nli  r3,0\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/Disable Tag Rumble - RumbleThink.asm",
    "content": "#To be inserted at 802477f8\n.include \"../../../Globals.s\"\n\nli  r3,0\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/8 Letter Tags/ZeroNametagText.asm",
    "content": "#To be inserted at 8023e9e4\n.include \"../../../Globals.s\"\n\n  li  r3,0\n  subi  r4,r31,3\n  li  r5,0\nLoop:\n  stbu  r3,0x3(r4)\nLoop_Inc:\n  addi  r5,r5,1\n  cmpwi r5,8\n  blt Loop\n  \n  mr\tr3, r15\n"
  },
  {
    "path": "ASM/Additional Codes/Longer Nametags/Scale Nametag BG/Main.asm",
    "content": "#To be inserted at 802fcfc8\n.include \"../../../Globals.s\"\n\n#Original\n  stfs\tf0, 0x002C (r28)\n\n#Check if HMN\n  mr  r3,r27\n  branchl r12,PlayerBlock_LoadSlotType\n  cmpwi r3,0\n  bne Exit\n#Get nametag ID\n  mr  r3,r27\n  branchl r12,PlayerBlock_LoadNameTagSlot #0x8003556c\n  cmpwi r3,120\n  beq Exit\n#Get nametag text\n  branchl r12,Nametag_LoadNametagSlotText #0x8023754c\n\n#Count letters\n  subi  r3,r3,2\n  li  r5,0\nCountLetterLoop:\n  lbzu  r4,0x2(r3)\n  cmpwi r4,0\n  beq CountLetterLoop_Exit\n  addi  r5,r5,1\n  b CountLetterLoop\nCountLetterLoop_Exit:\n#Normal size if 4 or less\n  cmpwi r5,4\n  ble Exit\n#Cast to float\n  li  r3,0\n  subi  r4,r5,4\n  branchl r12,cvt_sll_flt\n  bl  Floats\n  mflr  r3\n  lfs f2,0x0(r3)\n  lfs f3,0x2C(r28)\n  fdivs f2,f3,f2\n  fmuls f1,f1,f2\n  fadds f1,f1,f3\n  stfs\tf1, 0x002C (r28)\n  b Exit\n\nFloats:\n  blrl\n  .float 4\n\n  Exit:\n"
  },
  {
    "path": "ASM/Additional Codes/Misc Hitbox Visualizer/Always Draw TopN For Items.asm",
    "content": "#To be inserted at 800593b0\n.include \"../../Globals.s\"\n\nbackup\n\nlwz r31,0x2C(r28)\n\n#Draw TopN\n  lwz\tr10, -0x7920 (rtoc)\n  lwz\tr9, -0x791C (rtoc)\n  lwz\tr8, -0x7918 (rtoc)\n  lwz\tr7, -0x7914 (rtoc)\n  lwz\tr6, -0x7910 (rtoc)\n  lwz\tr5, -0x790C (rtoc)\n  lwz\tr4, -0x7908 (rtoc)\n  lwz\tr0, -0x7924 (rtoc)\n  stw\tr10, 0x00DC (sp)\n  stw\tr9, 0x00D8 (sp)\n  stw\tr8, 0x00D4 (sp)\n  stw\tr7, 0x00D0 (sp)\n  stw\tr6, 0x00CC (sp)\n  stw\tr5, 0x00C8 (sp)\n  stw\tr4, 0x00C4 (sp)\n  stw\tr0, 0x00C0 (sp)\n  branchl r12,0x80058ACC\n  li\tr3, 168\n  li\tr4, 0\n  li\tr5, 4\n  branchl r12,0x8033D0DC\n  lfs\tf3, 0x4C (r31)    #X offset?\n  lfs\tf2, -0x7964 (rtoc)\n  lfs\tf4, 0x50 (r31)    #Y offset?\n  fsubs\tf1,f3,f2\n  lfs\tf5, 0x54 (r31)    #Z Offset\n  fadds\tf0,f2,f3\n  fsubs\tf6,f4,f2\n  stfs\tf1, -0x8000 (r30)\n  fadds\tf1,f2,f4\n  stfs\tf4, -0x8000 (r30)\n  stfs\tf5, -0x8000 (r30)\n  stfs\tf0, -0x8000 (r30)\n  stfs\tf4, -0x8000 (r30)\n  stfs\tf5, -0x8000 (r30)\n  stfs\tf3, -0x8000 (r30)\n  stfs\tf6, -0x8000 (r30)\n  stfs\tf5, -0x8000 (r30)\n  stfs\tf3, -0x8000 (r30)\n  stfs\tf1, -0x8000 (r30)\n  stfs\tf5, -0x8000 (r30)\n\nExit:\n  restore\n  branch r12,0x800593d0\n"
  },
  {
    "path": "ASM/Additional Codes/Misc Hitbox Visualizer/Display Chain ECBs - GObj 7.asm",
    "content": "#To be inserted at 800593dc\n.include \"../../Globals.s\"\n\n.set  REG_CurrentGObj,31\n.set  REG_GX,30\n\nbackup\n\n  lis  REG_GX,0xcc01\n\n#Draw location of all chains (0x28)\n  lwz\tr3, -0x3E74 (r13)\n  lwz REG_CurrentGObj,0x28(r3)\n  b Loop_CheckNext\n\nLoop:\n.set  REG_CurrentGObjData,29\n\n#Get Data\n  lwz REG_CurrentGObjData,0x2C(REG_CurrentGObj)\n/*\n#Draw TopN\n  lwz\tr10, -0x7920 (rtoc)\n  lwz\tr9, -0x791C (rtoc)\n  lwz\tr8, -0x7918 (rtoc)\n  lwz\tr7, -0x7914 (rtoc)\n  lwz\tr6, -0x7910 (rtoc)\n  lwz\tr5, -0x790C (rtoc)\n  lwz\tr4, -0x7908 (rtoc)\n  lwz\tr0, -0x7924 (rtoc)\n  stw\tr10, 0x00DC (sp)\n  stw\tr9, 0x00D8 (sp)\n  stw\tr8, 0x00D4 (sp)\n  stw\tr7, 0x00D0 (sp)\n  stw\tr6, 0x00CC (sp)\n  stw\tr5, 0x00C8 (sp)\n  stw\tr4, 0x00C4 (sp)\n  stw\tr0, 0x00C0 (sp)\n  branchl r12,0x80058ACC\n  li\tr3, 168\n  li\tr4, 0\n  li\tr5, 4\n  branchl r12,0x8033D0DC\n  lfs\tf3, 0x4C (REG_CurrentGObjData)    #X offset?\n  lfs\tf2, -0x7964 (rtoc)\n  lfs\tf4, 0x50 (REG_CurrentGObjData)    #Y offset?\n  fsubs\tf1,f3,f2\n  lfs\tf5, 0x54 (REG_CurrentGObjData)    #Z Offset\n  fadds\tf0,f2,f3\n  fsubs\tf6,f4,f2\n  stfs\tf1, -0x8000 (r30)\n  fadds\tf1,f2,f4\n  stfs\tf4, -0x8000 (r30)\n  stfs\tf5, -0x8000 (r30)\n  stfs\tf0, -0x8000 (r30)\n  stfs\tf4, -0x8000 (r30)\n  stfs\tf5, -0x8000 (r30)\n  stfs\tf3, -0x8000 (r30)\n  stfs\tf6, -0x8000 (r30)\n  stfs\tf5, -0x8000 (r30)\n  stfs\tf3, -0x8000 (r30)\n  stfs\tf1, -0x8000 (r30)\n  stfs\tf5, -0x8000 (r30)\n*/\n#Check if collision is up to date\n  lwz\tr0, -0x51F4 (r13)\n  lwz\tr4, 0x0038+48 (REG_CurrentGObjData)\n  cmpw  r0,r4\n  bne Loop_Inc\n#Draw ECB\n  addi  r3,REG_CurrentGObjData,48\n  branchl r12,0x80058b5c\n#Check if more\nLoop_Inc:\n  lwz REG_CurrentGObj,0x8(REG_CurrentGObj)\nLoop_CheckNext:\n  cmpwi REG_CurrentGObj,0\n  bne Loop\n\nExit:\n  restore\n  lmw\tr26, 0x0118 (sp)\n"
  },
  {
    "path": "ASM/Additional Codes/Misc Hitbox Visualizer/Main.asm",
    "content": "#To be inserted at 80080638\n.include \"../../Globals.s\"\n\n.set  REG_PlayerData,31\n.set  REG_ItemGObj,30\n.set  REG_ItemData,29\n\nbackup\n\n#Check char\n  lwz r3,0x4(REG_PlayerData)\n  cmpwi r3,Link.Int\n  beq Link\n  cmpwi r3,Popo.Int\n  beq Nana\n  /*\n  cmpwi r3,Pikachu.Int\n  beq Pikachu\n  cmpwi r3,Pichu.Int\n  beq Pikachu\n  */\n  b Exit\n##########################\nLink:\n#Check if boomerang exists\n  lwz REG_ItemGObj,0x2234(REG_PlayerData)\n  cmpwi REG_ItemGObj,0\n  beq Link_NoBoomerang\n#Check if in state 3 (returning)\n  lwz REG_ItemData,0x2C(REG_ItemGObj)\n  lwz r3,0x24(REG_ItemData)\n  cmpwi r3,3\n  bne Link_NoBoomerang\n#Draw circle of 6 radius around links current position\n  lfs f1,0xB0(REG_PlayerData)\n  stfs f1,0x80(sp)\n  lfs f1,0xB4(REG_PlayerData)\n  lwz r3,0x2D4(REG_PlayerData)\n  lfs f2,0x28(r3)\n  fadds f1,f1,f2\n  stfs f1,0x84(sp)\n  lfs f1,0xB8(REG_PlayerData)\n  stfs f1,0x88(sp)\n  addi  r3,sp,0x80\n  lwz r4,0xC4(REG_ItemData)\n  lwz r4,0x4(r4)\n  lfs f1,0x2C(r4)\n  bl  DrawBubble\nLink_NoBoomerang:\n/*\n#Check if chain exists\n  lwz REG_ItemGObj,0x2238(REG_PlayerData)\n  cmpwi REG_ItemGObj,0\n  beq Link_NoChain\n#Check if in state 8 (hangwait)\n  lwz REG_ItemData,0x2C(REG_ItemGObj)\n  lwz r3,0x24(REG_ItemData)\n  cmpwi r3,8\n  bne Link_NoChain\n#Draw circle of 6 radius around the end of the hook\n  lfs f1,0xB0(REG_PlayerData)\n  stfs f1,0x80(sp)\n  lfs f1,0xB4(REG_PlayerData)\n  lwz r3,0x2D4(REG_PlayerData)\n  lfs f2,0x28(r3)\n  fadds f1,f1,f2\n  stfs f1,0x84(sp)\n  lfs f1,0xB8(REG_PlayerData)\n  stfs f1,0x88(sp)\n  addi  r3,sp,0x80\n  lwz r4,0xC4(REG_ItemData)\n  lwz r4,0x4(r4)\n  lfs f1,0x40(r4)\n  bl  DrawBubble\n*/\n\nLink_NoChain:\n  b Exit\n\n##########################\n\nNana:\n#up b nana search radius\n  lwz r3,0x10(REG_PlayerData)\n  cmpwi r3,0x160\n  beq Nana_UpB\n  cmpwi r3,0x15B\n  beq Nana_UpB\n  b Nana_NoUpB\n\nNana_UpB:\n#Check if frame 4\n  li  r3,0\n  li  r4,4\n  branchl r12,cvt_sll_flt\n  lfs f2,0x894(REG_PlayerData)\n  fcmpo cr0,f1,f2\n  bne Nana_NoUpB\n\n#Draw circle\n  addi  r3,REG_PlayerData,0xB0\n  lwz r4,0x2D4(REG_PlayerData)\n  lfs f1,0x7C(r4)\n  bl  DrawBubble\n\nNana_NoUpB:\n  b Exit\n\n##########################\n/*\nPikachu:\n#Check AS\n  lwz r3,0x10(REG_PlayerData)\n  cmpwi r3,0x168\n  beq Pikachu_DownB\n  cmpwi r3,0x15C\n  beq Pikachu_DownB\n  b Pikachu_NoDownB\n#Get thunder position\n  lwz r3,0x2340(REG_PlayerData)\n  cmpwi r3,0\n  beq Pikachu_NoDownB\n  addi  r4,sp,0x80\n  branchl r12,0x802b1fe8\n*/\n\n\nPikachu_NoDownB:\n  b Exit\n\n##########################\n\nDrawBubble:\nbackup\nmr  r4,r3\nbl  BubbleColors\nmflr  r5\naddi  r6,r5,4\nbranchl r12,0x80008fc8\nrestore\nblr\n\nBubbleColors:\nblrl\n.byte 255,255,255,128\n.byte 128,0,0,128\n##########################\n\nExit:\n#Return\n  restore\n  lbz\tr0, 0x221D (r31)\n"
  },
  {
    "path": "ASM/Additional Codes/Neutral Respawn.asm",
    "content": "#To be inserted at 8016721c\n.include \"../Globals.s\"\n\n.set PlayerSlot,27\n.set StaticBlock,26\n.set SpawnTable,25\n.set SpawnOrder,24\n.set SpawnID,23\n\nbackup\n\n#Don't run in singleplayer\n  branchl r12,0x8016b41c\n  cmpwi r3,0\n  bne Original\n#Don't run for players 5 and 6\n  cmpwi PlayerSlot,5\n  bge Original\n\n#Get static block\n  mr  r3,PlayerSlot\n  branchl r12,Playerblock_LoadStaticBlock\n  mr  StaticBlock,r3\n\n#Get Neutral Spawn Table\n  bl NeutralRespawnTable\n  mflr SpawnTable\n\n#Get this players spawn order\n  mr  r3,PlayerSlot\n  bl  GetSpawnOrder\n  mr  SpawnOrder,r3\n\n#Get stage ID\n  lwz\t\tr6,-0x6CB8 (r13)\n  li    r5,0\n#Get stage's spawn info\nStageSearchLoop:\n  mulli r4,r5,0x5         #table length\n  add   r4,r4,SpawnTable  #get stage start\n  lbz   r3,0x0(r4)        #get stage ID\n  extsb r3,r3\n  cmpwi r3,-1             #check for end of table\n  beq   Original\n  cmpw  r3,r6             #check for matching stage ID\n  addi  r5,r5,1           #inc count\n  bne   StageSearchLoop\n\n#Get ID\n  addi r4,r4,1            #Skip past stage ID\n  lbzx r3,SpawnOrder,r4\n\n  b Exit\n\n######################\nGetSpawnOrder:\n.set LoopCount,31\n.set SpawnOrder,30\n.set PlayerSlot,28\n\nbackup\n#Init variables\n  mr  PlayerSlot,r3\n  li  SpawnOrder,0\n  li  LoopCount,0\n\n#Start Loop\nGetSpawnOrder_Loop:\n#Load slot type\n  mr  r3,LoopCount\n  branchl r12,PlayerBlock_LoadSlotType\n  cmpwi r3,0x1\n  bgt GetSpawnOrder_IncLoop      #If >1, no player present\n#Player is present, check if this is the one were looking for\n  cmpw PlayerSlot,LoopCount\n  beq GetSpawnOrder_Exit\n#Increment offset\n  addi  SpawnOrder,SpawnOrder,1\n\nGetSpawnOrder_IncLoop:\n  addi LoopCount,LoopCount,1\n  cmpwi LoopCount,4\n  ble GetSpawnOrder_Loop\n\nGetSpawnOrder_Exit:\n  mr  r3,SpawnOrder    #Return spawn order\n  restore\n  blr\n######################\nNeutralRespawnTable:\nblrl\n#FD\n.byte 0x20                  #Stage ID\n.byte 0x00,0x01,0x02,0x03   #Nuetral Spawn Index\n#Battlefield\n.byte 0x1F                  #Stage ID\n.byte 0x02,0x03,0x00,0x01   #Nuetral Spawn Index\n#Yoshi's Story\n.byte 0x08                  #Stage ID\n.byte 0x00,0x01,0x03,0x02   #Nuetral Spawn Index\n#Dream Land\n.byte 0x1C                  #Stage ID\n.byte 0x01,0x03,0x00,0x02   #Nuetral Spawn Index\n#FoD\n.byte 0x02                  #Stage ID\n.byte 0x00,0x01,0x02,0x03   #Nuetral Spawn Index\n#Pokemon Stadium\n.byte 0x03                  #Stage ID\n.byte 0x00,0x01,0x02,0x03   #Nuetral Spawn Index\n#Terminator\n.byte 0xFF\n.align 2\n######################\n\nOriginal:\nrestore\naddi\tr3, r27, 0\nb Skip\nExit:\nrestore\nSkip:\n"
  },
  {
    "path": "ASM/Additional Codes/Neutral Respawn.s",
    "content": "#To be inserted at 8016721c\n.include \"../Globals.s\"\n\n.set PlayerSlot,27\n.set StaticBlock,26\n.set SpawnTable,25\n.set SpawnOrder,24\n.set SpawnID,23\n\nbackup\n\n#Don't run in singleplayer\n  branchl r12,0x8016b41c\n  cmpwi r3,0\n  bne Original\n#Don't run for players 5 and 6\n  cmpwi PlayerSlot,5\n  bge Original\n\n#Get static block\n  mr  r3,PlayerSlot\n  branchl r12,Playerblock_LoadStaticBlock\n  mr  StaticBlock,r3\n\n#Get Neutral Spawn Table\n  bl NeutralRespawnTable\n  mflr SpawnTable\n\n#Get this players spawn order\n  mr  r3,PlayerSlot\n  bl  GetSpawnOrder\n  mr  SpawnOrder,r3\n\n#Get stage ID\n  lwz\t\tr6,-0x6CB8 (r13)\n  li    r5,0\n#Get stage's spawn info\nStageSearchLoop:\n  mulli r4,r5,0x5         #table length\n  add   r4,r4,SpawnTable  #get stage start\n  lbz   r3,0x0(r4)        #get stage ID\n  extsb r3,r3\n  cmpwi r3,-1             #check for end of table\n  beq   Original\n  cmpw  r3,r6             #check for matching stage ID\n  addi  r5,r5,1           #inc count\n  bne   StageSearchLoop\n\n#Get ID\n  addi r4,r4,1            #Skip past stage ID\n  lbzx r3,SpawnOrder,r4\n\n  b Exit\n\n######################\nGetSpawnOrder:\n.set LoopCount,31\n.set SpawnOrder,30\n.set PlayerSlot,28\n\nbackup\n#Init variables\n  mr  PlayerSlot,r3\n  li  SpawnOrder,0\n  li  LoopCount,0\n\n#Start Loop\nGetSpawnOrder_Loop:\n#Load slot type\n  mr  r3,LoopCount\n  branchl r12,PlayerBlock_LoadSlotType\n  cmpwi r3,0x1\n  bgt GetSpawnOrder_IncLoop      #If >1, no player present\n#Player is present, check if this is the one were looking for\n  cmpw PlayerSlot,LoopCount\n  beq GetSpawnOrder_Exit\n#Increment offset\n  addi  SpawnOrder,SpawnOrder,1\n\nGetSpawnOrder_IncLoop:\n  addi LoopCount,LoopCount,1\n  cmpwi LoopCount,4\n  ble GetSpawnOrder_Loop\n\nGetSpawnOrder_Exit:\n  mr  r3,SpawnOrder    #Return spawn order\n  restore\n  blr\n######################\nNeutralRespawnTable:\nblrl\n#FD\n.byte 0x20                  #Stage ID\n.byte 0x00,0x01,0x02,0x03   #Nuetral Spawn Index\n#Battlefield\n.byte 0x1F                  #Stage ID\n.byte 0x02,0x03,0x00,0x01   #Nuetral Spawn Index\n#Yoshi's Story\n.byte 0x08                  #Stage ID\n.byte 0x00,0x01,0x03,0x02   #Nuetral Spawn Index\n#Dream Land\n.byte 0x1C                  #Stage ID\n.byte 0x01,0x03,0x00,0x02   #Nuetral Spawn Index\n#FoD\n.byte 0x02                  #Stage ID\n.byte 0x00,0x01,0x02,0x03   #Nuetral Spawn Index\n#Pokemon Stadium\n.byte 0x03                  #Stage ID\n.byte 0x00,0x01,0x02,0x03   #Nuetral Spawn Index\n#Terminator\n.byte 0xFF\n.align 2\n######################\n\nOriginal:\nrestore\naddi\tr3, r27, 0\nb Skip\nExit:\nrestore\nSkip:\n"
  },
  {
    "path": "ASM/Additional Codes/Neutral Spawn.asm",
    "content": "#To be inserted at 8016e510\n.include \"../Globals.s\"\n\n\n.set MatchInfo,31\n.set SpawnTable,30\n.set REG_PlayerSlot,28\n\nbackup\n\n#Don't run in singleplayer\n  branchl r12,0x8016b41c\n  cmpwi r3,0\n  bne Exit\n#Don't run for players 5 and 6\n  cmpwi REG_PlayerSlot,5\n  bge Exit\n\n#Check if teams\n  lbz\tr3, 0x24D0 (MatchInfo)\n  cmpwi r3,1\n  beq isTeams\n\n#region isSingles\nisSingles:\n#Get this players spawn order\n.set LoopCount,26\n.set SpawnOrder,25\n  li  SpawnOrder,0\n  li  LoopCount,0\nisSingles_Loop:\n#Load slot type\n  mr  r3,LoopCount\n  branchl r12,PlayerBlock_LoadSlotType\n  cmpwi r3,0x3\n  beq isSingles_IncLoop      #If =3, no player present\n#Player is present, check if this is the one were looking for\n  cmpw REG_PlayerSlot,LoopCount\n  beq isSingles_Exit\n#Increment offset\n  addi  SpawnOrder,SpawnOrder,1\nisSingles_IncLoop:\n  addi LoopCount,LoopCount,1\n  cmpwi LoopCount,4\n  ble isSingles_Loop\nisSingles_Exit:\n  mr  r3,REG_PlayerSlot\n  mr  r4,SpawnOrder\n  lbz\tr5, 0x24D0 (MatchInfo)\n  bl  SetSpawn\n  b Exit\n#endregion\n\n#region isTeams\nisTeams:\nCheckIf2v2:\n.set REG_TeamID,26\n  li  REG_TeamID,0\nCheckIf2v2_Loop:\n#Check how many players are on this team\n  GetTeamCount:\n  .set REG_Count,25\n  .set REG_TeamMembers,24\n    li  REG_TeamMembers,0\n    li  REG_Count,0\n  GetTeamCount_Loop:\n  #Load slot type\n    mr  r3,REG_Count\n    branchl r12,PlayerBlock_LoadSlotType\n    cmpwi r3,0x3\n    beq GetTeamCount_IncLoop      #If =3, no player present\n  #Get Team\n    mr  r3,REG_Count\n    branchl r12,0x80033370\n    cmpw  r3,REG_TeamID\n    bne GetTeamCount_IncLoop\n  #Increment team members\n    addi  REG_TeamMembers,REG_TeamMembers,1\n  GetTeamCount_IncLoop:\n    addi  REG_Count,REG_Count,1\n    cmpwi REG_Count,4\n    blt GetTeamCount_Loop\n#If =1 or >2, exit\n  cmpwi REG_TeamMembers,1\n  beq Exit\n  cmpwi REG_TeamMembers,2\n  bgt Exit\nCheckIf2v2_IncLoop:\n  addi  REG_TeamID,REG_TeamID,1\n  cmpwi REG_TeamID,3\n  blt CheckIf2v2_Loop\n\n\n#Create an array\nCreateTeamArray:\n.set REG_TeamID,25\n.set REG_TeamArray,26\n.set REG_ArraySize,24\n  li  REG_TeamID,0\n  addi  REG_TeamArray,sp,0x80\n  li  REG_ArraySize,0\nCreateTeamArray_Loop:\n#Check how many players are on this team\n  CheckTeam:\n  .set REG_Count,23\n  .set REG_TeamMembers,22\n    li  REG_TeamMembers,0\n    li  REG_Count,0\n  CheckTeam_Loop:\n  #Load slot type\n    mr  r3,REG_Count\n    branchl r12,PlayerBlock_LoadSlotType\n    cmpwi r3,0x3\n    beq CheckTeam_IncLoop      #If =3, no player present\n  #Get Team\n    mr  r3,REG_Count\n    branchl r12,0x80033370\n    cmpw  r3,REG_TeamID\n    bne CheckTeam_IncLoop\n  #Add to array\n    stbx  REG_Count,REG_ArraySize,REG_TeamArray\n    addi  REG_ArraySize,REG_ArraySize,1\n  CheckTeam_IncLoop:\n    addi  REG_Count,REG_Count,1\n    cmpwi REG_Count,4\n    blt CheckTeam_Loop\nCreateTeamArray_IncLoop:\n  addi  REG_TeamID,REG_TeamID,1\n  cmpwi REG_TeamID,3\n  blt CreateTeamArray_Loop\n\n#Now search for this players ID\nSearchForPlayerID:\n.set  REG_Count,25\n  li  REG_Count,0\nSearchForPlayerID_Loop:\n  lbzx  r3,REG_Count,REG_TeamArray\n  cmpw  r3,REG_PlayerSlot\n  beq SearchForPlayerID_Exit\nSearchForPlayerID_IncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,4\n  blt SearchForPlayerID_Loop\nSearchForPlayerID_Exit:\n  mr  r3,REG_PlayerSlot\n  mr  r4,REG_Count\n  lbz\tr5, 0x24D0 (MatchInfo)\n  bl  SetSpawn\n  b Exit\n#endregion\n\n#region SetSpawn\nSetSpawn:\n.set  REG_PlayerSlot,31\n.set  REG_SpawnID,30\n.set  REG_IsTeams,29\n.set  REG_SpawnTable,28\n\n#Init\n  backup\n  mr  REG_PlayerSlot,r3\n  mr  REG_SpawnID,r4\n  mr  REG_IsTeams,r5\n\n#Get Neutral Spawn Table\n  bl NeutralSpawnTable\n  mflr REG_SpawnTable\n\n#Get stage ID\n  lwz\t\tr6,-0x6CB8 (r13)\n  li    r5,0\n#Get stage's spawn info\nSetSpawn_StageSearchLoop:\n  lwz   r3,StageID(REG_SpawnTable)            #get stage ID\n  cmpwi r3,-1                     #check for end of table\n  beq   SetSpawn_NotFound\n  cmpw  r3,r6             #check for matching stage ID\n  beq SetSpawn_FoundStage\n  addi  REG_SpawnTable,REG_SpawnTable,EntryLength\n  b SetSpawn_StageSearchLoop\n\nSetSpawn_FoundStage:\n#Get Players Spawn Point and Facing Direction Pointer\n  addi REG_SpawnTable,REG_SpawnTable,SpawnData      #Skip past stage ID\n  mulli r3,REG_IsTeams,SpawnDataLength\n  add REG_SpawnTable,REG_SpawnTable,r3              #Get to teams/singles data\n  mulli r3,REG_SpawnID,SpawnDataLengthPerPlayer     #Get to this players data\n  add REG_SpawnTable,REG_SpawnTable,r3\n\n#Set players new spawn coordinates\n  addi  r4,sp,0x80\n  lfs f1,SpawnX(REG_SpawnTable)\n  stfs  f1,0x0(r4)\n  lfs f1,SpawnY(REG_SpawnTable)\n  stfs  f1,0x4(r4)\n  li  r3,0\n  stw  r3,0x8(r4)\n  mr  r3,REG_PlayerSlot\n  branchl r12,0x80032768\n  b SetSpawn_UpdateFacingDirection\n\nSetSpawn_NotFound:\n#If singles, use spawn order\n  cmpwi REG_IsTeams,1\n  beq SetSpawn_NotFound_Teams\n  mr  r3,REG_SpawnID\n  b SetSpawn_NotFound_UpdatePosition\nSetSpawn_NotFound_Teams:\n  bl  NeutralSpawnTable_NotFound\n  mflr  r3\n  lbzx  r3,r3,REG_SpawnID\n  b SetSpawn_NotFound_UpdatePosition\nSetSpawn_NotFound_UpdatePosition:\n#Get XYZ from spawn ID\n  addi  r4,sp,0x80\n  branchl r12,0x80224e64\n#Set new XYZ spawn\n  mr  r3,REG_PlayerSlot\n  addi  r4,sp,0x80\n  branchl r12,0x80032768\n  b SetSpawn_UpdateFacingDirection\n\nSetSpawn_UpdateFacingDirection:\n#Load X Position\n  mr  r3,REG_PlayerSlot\n  addi  r4,sp,0x80\n  branchl r12,0x800326cc\n  lfs f1,0x80(sp)\n#Compare to 0\n  lfs\tf0, -0x5718 (rtoc)\n  fcmpo cr0,f1,f0\n  ble SetSpawn_UpdateFacingDirection_FacingRight\nSetSpawn_UpdateFacingDirection_FacingLeft:\n  lfs\tf1, -0x5708 (rtoc)\n  b SetSpawn_UpdateFacingDirection_Store\nSetSpawn_UpdateFacingDirection_FacingRight:\n  lfs\tf1, -0x5734 (rtoc)\nSetSpawn_UpdateFacingDirection_Store:\n#Update Facing Direction\n  mr  r3,REG_PlayerSlot\n  branchl r12,0x80033094\n\nSetSpawn_AdjustEntryFrames:\n  mr  r3,REG_PlayerSlot\n  mulli r4,REG_SpawnID,5\n  branchl r12,0x80035fdc\n\nSetSpawn_Exit:\n  restore\n  blr\n#endregion\n\n######################\nNeutralSpawnTable:\nblrl\n.set  EntryLength,0x4 + SpawnDataLength * 2\n.set  SpawnDataLength,0x8 *4\n.set  SpawnDataLengthPerPlayer,0x8\n\n.set  StageID,0x0\n.set  SpawnData,0x4\n  .set  SpawnX,0x0\n  .set  SpawnY,0x4\n\n#FD\n.long 0x20                  #Stage ID\n  #Singles Data\n    .float -60,10\n    .float 60,10\n    .float -20,10\n    .float 20,10\n  #Teams Data\n    .float -20,10\n    .float -60,10\n    .float 20,10\n    .float 60,10\n#Battlefield\n.long 0x1F                  #Stage ID\n  #Singles Data\n    .float -38.8,35.2\n    .float 38.8,35.2\n    .float 0,8\n    .float 0,62.4\n  #Teams Data\n    .float -38.8,35.2\n    .float -38.8,5\n    .float 38.8,35.2\n    .float 38.8,5\n#Yoshi's Story\n.long 0x08                  #Stage ID\n  #Singles Data\n    .float -42,26.6\n    .float 42,28\n    .float 0,46.9\n    .float 0,4.9\n  #Teams Data\n    .float -42,26.6\n    .float -42,5\n    .float 42,28\n    .float 42,5\n#Dream Land\n.long 0x1C                  #Stage ID\n  #Singles Data\n    .float -46.6,37.2\n    .float 47.4,37.3\n    .float 0,7\n    .float 0,58.5\n  #Teams Data\n    .float -46.6,37.2\n    .float -46.6,5\n    .float 47.4,37.3\n    .float 47.4,5\n#FoD\n.long 0x02                  #Stage ID\n  #Singles Data\n    .float -41.25,21\n    .float 41.25,27\n    .float 0,5.25\n    .float 0,48\n  #Teams Data\n    .float -41.25,21\n    .float -41.25,5\n    .float 41.25,27\n    .float 41.25,5\n#Pokemon Stadium\n.long 0x03                  #Stage ID\n  #Singles Data\n    .float -40,32\n    .float 40,32\n    .float 70,7\n    .float -70,7\n  #Teams Data\n    .float -40,32\n    .float -40,5\n    .float 40,32\n    .float 40,5\n#Terminator\n.long -1\n.align 2\n\nNeutralSpawnTable_NotFound:\nblrl\n#Doubles\n.long 0x00030102\n.align 2\n######################\n\nExit:\n  restore\n  lbz\tr0, 0x24D0 (r31)\n"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Clear Bootup OSReports.asm",
    "content": "#To be inserted at 80160154\n.include \"../../Globals.s\"\n\n# Remove all previous OSReports\n  load r3,0x804cf7e8\n  li  r4,0\n  stw r4,0xC(r3)\n\nli\tr0, 0"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Disable Brinstar OSReport.asm",
    "content": "#To be inserted at 801fe738\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Disable Effect AnimList OSReport.asm",
    "content": "#To be inserted at 800a0080\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Disable Fourside OSReport.asm",
    "content": "#To be inserted at 801f3500\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Disable Fourside OSReport2.asm",
    "content": "#To be inserted at 801f35c0\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Disable PS OSReport.asm",
    "content": "#To be inserted at 801c3a84\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Disable YoshisIsland OSReport.asm",
    "content": "#To be inserted at 80202a40\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Disable mpcoll OSReport.asm",
    "content": "#To be inserted at 8005a2f8\n\nb 0x30\n"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Dont Output Compile Date on Assert.asm",
    "content": "#To be inserted at 80228aec\nnop"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Dont Output Compile Date on Invalid Read.asm",
    "content": "#To be inserted at 80228bf0\nnop"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Enable OSReport Print to Screen.asm",
    "content": "#To be inserted at 80397878\nb 0x20C"
  },
  {
    "path": "ASM/Additional Codes/On Crash/LRZ Shows Advanced Details/Any Debug Level Displays Advanced Details.s",
    "content": "#To be inserted at 80394eac\n.include \"../../../Globals.s\"\n\nnop\n"
  },
  {
    "path": "ASM/Additional Codes/On Crash/LRZ Shows Advanced Details/Check for LRZ.s",
    "content": "#To be inserted at 80395704\n.include \"../../../Globals.s\"\n\n#Get Held Buttons\n  lwz r3,0xC0(r30)\n#Check for LRZ\n  cmpwi r3,0x70\n  beq  PressedButtons\n#Not Pressing LRZ\n  branch r12,0x80395728\n\nPressedButtons:\n"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Only Show First 8 Lines of Stack.asm",
    "content": "#To be inserted at 80394afc\ncmpwi\tr29, 8"
  },
  {
    "path": "ASM/Additional Codes/On Crash/Reboot With LRAStart.asm",
    "content": "#To be inserted at 80397c10\n.include \"../../Globals.s\"\n\n# Get inputs\nlwz r3,0xC0(r31)\nrlwinm. r0,r3,0,0x20\nbeq Exit\nrlwinm. r0,r3,0,0x40\nbeq Exit\nrlwinm. r0,r3,0,0x100\nbeq Exit\nrlwinm. r0,r3,0,0x1000\nbeq Exit\n\n#Reboot\nli  r3,0\nli  r4,0\nli  r5,0\nbranchl r12,0x8034844c\n\nExit:\nlbz\tr0, 0 (r31)"
  },
  {
    "path": "ASM/Additional Codes/Output File Load Times/Output Load Time.s",
    "content": "#To be inserted at 8001674c\n.include \"../../Globals.s\"\n\n.set  REG_Tick,20\n.set  REG_FileSize,21\n.set  REG_FileName,30\n\nbackup\n\n#Get Prev Tick\n\tlwz\tr3,-8(rtoc)\n#Get Current Tick\n\tmftbl\tr4\n#Find Difference\n\tsub\tr3,r4,r3\n#Convert to ms\n#Get Clock Bus\n\tload \tr4,0x800000f8\n\tlwz \tr4,0x0(r4)\n#Clock Bus / 4\n\tli\tr5,4\n\tdivw \tr4,r4,r5\n#Divided by 1000\n\tli\tr5,1000\n\tdivw\tr4,r4,r5\n#divided by ticks\n\tdivw\tREG_Tick,r3,r4\n\n#Get file size\n  mr  r3,r30\n  branchl r12,0x800163d8\n  mr  REG_FileSize,r3\n\n#OSReport Difference\n\tbl\tOSReportString\n\tmflr\tr3\n  mr  r4,REG_FileName\n  li  r5,1000\n  divw  r5,REG_FileSize,r5\n  mr  r6,REG_Tick\n\tbranchl r12,0x803456a8\n\tb\tExit\n\nOSReportString:\nblrl\n.string \"%s (%dkb) loaded in %dms\\n\"\n.align 2\n#*************************************************\nExit:\nrestore\nlmw\tr27, 0x001C (sp)\n"
  },
  {
    "path": "ASM/Additional Codes/Output File Load Times/Save Tick.s",
    "content": "#To be inserted at 80016714\n.include \"../../Globals.s\"\n\nmftbl\tr4\nstw\tr4,-8(rtoc)\n\nlwz\tr4, 0 (r28)\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (1).asm",
    "content": "#To be inserted @ 800C2D3C\n\nloc_0x0:\n  lis r0, 0x800C\n  ori r0, r0, 0x2690\n  mtlr r0\n  blrl\n  addi r5, r24, 0x1\n  lis r0, 0x800C\n  ori r0, r0, 0x2DA4\n  mtctr r0\n  bctr\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (10).asm",
    "content": "#To be inserted @ 800c26c0\n\n  rlwinm r3, r30, 19, 31, 31\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (11).asm",
    "content": "#To be inserted @ 800c272c\n\n  rlwinm r3, r30, 2, 30, 31\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (12).asm",
    "content": "#To be inserted @ 800C268C\n\nloc_0x0:\n  mflr r0\n  stw r0, 4(r1)\n  stwu r1, -16384(r1)\n  stmw r30, 16(r1)\n  mr r30, r3\n  mr r31, r4\n  lis r0, 0x800C\n  li r3, 0x1\n  ori r0, r0, 0x2678\n  mtctr r0\n  bctr\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (13).asm",
    "content": "#To be inserted @ 800C2690\n\nloc_0x0:\n  mflr r0\n  stw r0, 4(r1)\n  stwu r1, -16384(r1)\n  lis r0, 0x8033\n  ori r0, r0, 0xC3C8\n  mtlr r0\n  blrl\n  lis r0, 0x800C\n  ori r0, r0, 0x2D40\n  mtctr r0\n  bctr\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (14).asm",
    "content": "#To be inserted @ 800C2DA0\n\nloc_0x0:\n  lwz r0, 0x4004(r1)\n  addi r1, r1, 0x4000\n  mtlr r0\n  blr\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (15).asm",
    "content": "#To be inserted @ 802EAA38\n\n  lfd f1, -32608(r2)\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (16).asm",
    "content": "#To be inserted @ 802E8D68\n\nlfd f1, -32608(r2)\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (17).asm",
    "content": "#To be inserted @ 804DD860\n\n.long 0x00101303\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (18).asm",
    "content": "#To be inserted @ 804DD864\n\n.long 0x00001455\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (19).asm",
    "content": "#To be inserted @ 800C2674\n\nloc_0x0:\n  lwz r3, -8576(r2)\n  lwz r4, -8572(r2)\n  lis r0, 0x800C\n  ori r0, r0, 0x268C\n  mtlr r0\n  blrl\n  lis r0, 0x800C\n  ori r0, r0, 0x2738\n  mtctr r0\n  lbz r0, 8449(r28)\n  bctr\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (2).asm",
    "content": "#To be inserted @ 802E8B48\n\nlfd f1, -32608(r2)\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (20).asm",
    "content": "#To be inserted @ 800C2734\n\nloc_0x0:\n  lmw r30, 16(r1)\n  lwz r0, 0x4004(r1)\n  addi r1, r1, 0x4000\n  mtlr r0\n  blr\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (3).asm",
    "content": "#To be inserted @ 804DD848\n\nloc_0x0:\n  lis r0, 0x8036\n  ori r3, r0, 0x1FC4\n  mtctr r3\n  li r3, -1\n  bctr\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (4).asm",
    "content": "#To be inserted @ 804DD84C\n\nloc_0x0:\n  mflr r0\n  stw r0, 4(r1)\n  stwu r1, -64(r1)\n  stmw r29, 16(r1)\n  mr r30, r3\n  mr r31, r4\n  mr r3, r4\n  mr r4, r5\n  lis r0, 0x800C\n  ori r0, r0, 0x268C\n  mtlr r0\n  blrl\n  lis r0, 0x800C\n  ori r0, r0, 0x2690\n  mtlr r0\n  blrl\n  rlwinm r3, r31, 0, 24, 31\n  cmpwi r3, 0x5\n  blt+ loc_0x84\n  cmpwi r3, 0x7\n  bgt- loc_0x84\n  rlwinm r3, r31, 16, 22, 31\n  li r4, 0x5\n  beq- loc_0x74\n  lis r0, 0x8033\n  ori r0, r0, 0xD240\n  mtlr r0\n  blrl\n  b loc_0x84\n\nloc_0x74:\n  lis r0, 0x8033\n  ori r0, r0, 0xD298\n  mtlr r0\n  blrl\n\nloc_0x84:\n  rlwinm r3, r31, 3, 24, 28\n  addi r3, r3, 0x80\n  li r4, 0x0\n  rlwinm r5, r30, 0, 16, 31\n  lis r0, 0x8033\n  ori r0, r0, 0xD0DC\n  mtlr r0\n  blrl\n  lis r3, 0xCC01\n  subi r3, r3, 0x8000\n  lmw r29, 16(r1)\n  lwz r0, 0x44(r1)\n  addi r1, r1, 0x40\n  mtlr r0\n  blr\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (5).asm",
    "content": "#To be inserted @ 800C2684\n\nloc_0x0:\n  rlwinm r3, r31, 20, 30, 31\n  rlwinm r4, r31, 24, 29, 31\n  rlwinm r5, r31, 28, 29, 31\n  rlwinm r6, r31, 0, 28, 31\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (6).asm",
    "content": "#To be inserted @ 800c2688\n\nb 0xC\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (7).asm",
    "content": "#To be inserted @ 800c26b0\n\nrlwinm r3, r30, 20, 31, 31\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (8).asm",
    "content": "#To be inserted @ 800c26b4\n\nrlwinm r4, r30, 24, 29, 31\n"
  },
  {
    "path": "ASM/Additional Codes/PRIM LITE/PRIM (9).asm",
    "content": "#To be inserted @ 800c26b8\n\nrlwinm r5, r30, 21, 31, 31\n"
  },
  {
    "path": "ASM/Additional Codes/Pad - Update During Frame Advance.asm",
    "content": "#To be inserted at 801a4e48\n\n# doing this to make the menu inputs work with the TM menu\n# while the engine is paused. not sure if there are any\n# side effects to doing this but it seems to work??\n\nnop"
  },
  {
    "path": "ASM/Additional Codes/Pause During Game Start/Check to Pause.asm",
    "content": "#To be inserted at 8016CA9C\nnop"
  },
  {
    "path": "ASM/Additional Codes/Pause During Game Start/Check to Pause.s",
    "content": "#To be inserted at 8016CA9C\nnop"
  },
  {
    "path": "ASM/Additional Codes/Pause During Game Start/Check to Unpause.asm",
    "content": "#To be inserted at 8016CC1C\nnop"
  },
  {
    "path": "ASM/Additional Codes/Pause During Game Start/Check to Unpause.s",
    "content": "#To be inserted at 8016CC1C\nnop"
  },
  {
    "path": "ASM/Additional Codes/Physics Display/Main.asm",
    "content": "#To be inserted at 80225554\n.include \"../../Globals.s\"\n\n.set GObj_Create,0x803901f0\n.set GObj_AddUserData,0x80390b68\n.set GObj_AddProc,0x8038fd54\n.set HSD_MemAlloc,0x8037f1e4\n.set DevelopText_CreateDataTable,0x80302834\n.set DevelopText_Activate,0x80302810\n.set DevelopText_AddString,0x80302be4\n.set DevelopText_FormatAndPrint,0x80302d4c\n.set DevelopText_EraseAllText,0x80302bb0\n.set DevelopMode_Text_ResetCursorXY,0x80302a3c\n.set DevelopText_StoreBGColor,0x80302b90\n.set DevelopText_HideText,0x80302b00\n.set DevelopText_HideBG,0x80302ae0\n.set DevelopText_ShowText,0x80302af0\n.set DevelopText_ShowBG,0x80302ad0\n.set DevelopText_StoreTextScale,0x80302b10\n.set DevelopText_ResetCursorX,0x80302a88\n.set sprintf,0x80323cf4\n\n.set  WindowData_Text,0x0\n.set  WindowData_State,0x4\n\n.set  REG_DevelopText,31\n.set  REG_GObjData,30\n.set  REG_GObj,29\n\nstw\tr0, -0x4B7C (r13)\n\nbackup\n\n#Create Rectangle\n  li  r3,0x1000\n  branchl r12,HSD_MemAlloc\n  mr  r8,r3\n  li  r3,12\n  li  r4,0\n  li  r5,0\n  li  r6,39\n  li  r7,10\n  branchl r12,DevelopText_CreateDataTable\n  mr  REG_DevelopText,r3\n#Activate Text\n  lwz\tr3, -0x4884 (r13)\n  mr  r4,REG_DevelopText\n  branchl r12,DevelopText_Activate\n#Hide blinking cursor\n  li  r3,0\n  stb r3,0x26(REG_DevelopText)\n#Change BG Color\n  mr  r3,REG_DevelopText\n  bl  BGColor\n  mflr  r4\n  branchl r12,DevelopText_StoreBGColor\n#Hide by default\n  mr  r3,REG_DevelopText\n  branchl r12,DevelopText_HideText\n  mr  r3,REG_DevelopText\n  branchl r12,DevelopText_HideBG\n#Change Text Size\n  mr  r3,REG_DevelopText\n  bl  TextFloats\n  mflr  r4\n  lfs f1,0x0(r4)\n  lfs f2,0x4(r4)\n  branchl r12,DevelopText_StoreTextScale\n#Create Background GObj\n  li  r3,0\n  li  r4,0\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n#Allocate Space\n\tli\tr3,64\n\tbranchl r12,HSD_MemAlloc\n\tmr\tREG_GObjData,r3\n#Zero\n\tli\tr4,64\n\tbranchl r12,ZeroAreaLength\n#Initialize\n\tmr\tr6,REG_GObjData\n\tmr\tr3,REG_GObj\n\tli\tr4,4\n\tload\tr5,HSD_Free\n\tbranchl r12,GObj_AddUserData\n#Add Process\n\tmr\tr3,REG_GObj\n\tbl\tDebugLogThink\n\tmflr r4\n\tli\tr5,7\n  li  r6,0\n  branchl r12,GObj_AddGXLink\n\t#branchl r12,GObj_AddProc\n#Store pointer to dev text\n  stw REG_DevelopText,WindowData_Text(REG_GObjData)\n#Initialize State\n  li  r3,0\n  stw r3,WindowData_State(REG_GObjData)\n  b Exit\n\n\n\n\n\n\n\n\n\n\n########################################\nTextFloats:\nblrl\n.float 7.5\n.float 10\n########################################\n\n\n\n\n\n\n\n\n\n\nDebugLogThink:\nblrl\n.set  REG_GObjData,31\n.set  REG_PlayerData,30\nbackup\n\n#Only run during pass 0\n  cmpwi r4,0\n  bne DebugLogThink_Exit\n\nlwz REG_GObjData,0x2C(r3)\n\n#Check for state change\n  bl GetInputs\n  rlwinm. r0,r3,0,0x200\n  beq DebugLogThink_StateChangeEnd\n  bl GetInputs\n  rlwinm. r0,r4,0,0x2\n  beq DebugLogThink_StateChangeEnd\n#Inc state\n  lwz r3,WindowData_State(REG_GObjData)\n  addi  r3,r3,1\n  stw r3,WindowData_State(REG_GObjData)\n  cmpwi r3,4\n  ble DebugLogThink_ShowWindow\n#Loop back to hidden\n  li  r3,0\n  stw r3,WindowData_State(REG_GObjData)\n#Hide\n  lwz r3,WindowData_Text(REG_GObjData)\n  branchl r12,DevelopText_HideText\n  lwz r3,WindowData_Text(REG_GObjData)\n  branchl r12,DevelopText_HideBG\n  b DebugLogThink_StateChangeEnd\nDebugLogThink_ShowWindow:\n#Show\n  lwz r3,WindowData_Text(REG_GObjData)\n  branchl r12,DevelopText_ShowText\n  lwz r3,WindowData_Text(REG_GObjData)\n  branchl r12,DevelopText_ShowBG\nDebugLogThink_StateChangeEnd:\n\n#Check to update text\n  lwz r3,WindowData_State(REG_GObjData)\n  cmpwi r3,0\n  beq DebugLogThink_Exit\n\n#Erase all text\n  lwz  r3,WindowData_Text(REG_GObjData)\n  branchl r12,DevelopText_EraseAllText\n  lwz  r3,WindowData_Text(REG_GObjData)\n  li  r4,0\n  li  r5,0\n  branchl r12,DevelopMode_Text_ResetCursorXY\n\n#Output player number\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_Player\n  mflr r4\n  lwz r5,WindowData_State(REG_GObjData)\n  branchl r12,DevelopText_FormatAndPrint\n\n#Get current player data\n  lwz r3,WindowData_State(REG_GObjData)\n  subi  r3,r3,1\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  cmpwi r3,0\n  beq DebugLogThink_Exit\n#Backup data\n  lwz  REG_PlayerData,0x2C(r3)\n\n#vprintf string\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_LStick\n  mflr r4\n  lfs f1,0x620(REG_PlayerData)\n  lfs f2,0x624(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n\n#vprintf string\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_RStick\n  mflr r4\n  lfs f1,0x638(REG_PlayerData)\n  lfs f2,0x63C(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n\n#vprintf string\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_CVel\n  mflr r4\n  lfs f1,0x80(REG_PlayerData)\n  lfs f2,0x84(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n#vprintf string\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_KBVel\n  mflr r4\n  lfs f1,0x8C(REG_PlayerData)\n  lfs f2,0x90(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n#vprintf string\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_Pos\n  mflr r4\n  lfs f1,0xB0(REG_PlayerData)\n  lfs f2,0xB4(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n\n#Output ECB Lock info\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_ECBLock\n  mflr  r4\n  lwz r5,0x88C(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n#Output ECB Bottom info\n  lwz  r3,WindowData_Text(REG_GObjData)\n  li  r4,18\n  branchl r12,DevelopText_ResetCursorX\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_ECBBottom\n  mflr  r4\n  lfs f1,0x780(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n\n#Output State info\n  mr  r3,REG_PlayerData\n  addi  r4,sp,0x88\n  bl  GetStateInfo\n  stfs  f1,0x80(sp)\n  stfs  f2,0x84(sp)\n  mr  r5,r3\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_State\n  mflr  r4\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n#Move cursor\n  lwz  r3,WindowData_Text(REG_GObjData)\n  li  r4,25\n  branchl r12,DevelopText_ResetCursorX\n#Output frames\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_StateFrame\n  mflr  r4\n  lfs  f1,0x80(sp)\n  lfs  f2,0x84(sp)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n\nDebugLogThink_Exit:\nrestore\nblr\n\n#############################\nString_Player:\nblrl\n.string \"Player %d    X        Y\\n\"\n.align 2\nString_LStick:\nblrl\n.string \"LStick:  %1.4f   %1.4f\\n\"\n.align 2\nString_RStick:\nblrl\n.string \"RStick:  %1.4f   %1.4f\\n\"\n.align 2\nString_CVel:\nblrl\n.string \"SelfVel: %3.4f   %3.4f\\n\"\n.align 2\nString_KBVel:\nblrl\n.string \"KBVel:   %3.4f   %3.4f\\n\"\n.align 2\nString_XVel:\nblrl\n.string \"XVel:    %3.4f   %3.4f\\n\"\n.align 2\nString_Pos:\nblrl\n.string \"Pos:     %3.4f   %3.4f\\n\\n\"\n.align 2\nString_State:\nblrl\n.string \"State: %s\"\n.align 2\nString_StateFrame:\nblrl\n.string \"f: %03.2f/%1.0f\"\n.align 2\nString_ECBBottom:\nblrl\n.string \"ECB_Bot: %03.2f\\n\\n\"\n.align 2\nString_ECBLock:\nblrl\n.string \"ECB_Lock: %d\"\n.align 2\n\n\nBGColor:\nblrl\n.byte 21,20,59,135\n###############################\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nGetInputs:\n.set  REG_InputStruct,11\n.set  REG_Count,10\n.set  REG_HeldInputs,9\n.set  REG_InstantInputs,8\n\n#Load Input Struct\n  load  REG_InputStruct,0x804c1fac\n\n#Init loop\n  li  REG_Count,0\n  li  REG_HeldInputs,0\n  li  REG_InstantInputs,0\nGetInputs_Loop:\n#Get to inputs\n  mulli r3,REG_Count,68\n  add r5,r3,REG_InputStruct\n#Grab Inputs\n  lwz r3,0x0(r5)\n  lwz r4,0xC(r5)\n#OR all inputs\n  or  REG_HeldInputs,REG_HeldInputs,r3\n  or  REG_InstantInputs,REG_InstantInputs,r4\n#Inc\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,4\n  blt GetInputs_Loop\nGetInputs_Exit:\n  mr  r3,REG_HeldInputs\n  mr  r4,REG_InstantInputs\n  blr\n######################################\nGetStateInfo:\n.set REG_PlayerData,31\n.set REG_StateString,30\n\nbackup\n\n  mr  REG_PlayerData,r3\n  mr  REG_StateString,r4\n\n#Check if common move\n  lwz r3,0x10(REG_PlayerData)\n  cmpwi r3,341\n  bge GetStateInfo_SpecialMove\n\nGetStateInfo_SharedMove:\n  mulli r3,r3,4\n  lwz\tr4, -0x4B78 (r13)\n  lwzx  r4,r3,r4\n  mr  r3,REG_StateString\n  branchl r12,strcpy\n  b GetStateInfo_GetRemainingFrames\n\nGetStateInfo_SpecialMove:\n#Get Animation Data Pointer\n  mr\tr3,REG_PlayerData\n  lwz\tr4,0x14(REG_PlayerData)\n  branchl\tr12,0x80085fd4\n\n#Get Move Name String\n  lwz\tr3,0x0(r3)\n  cmpwi r3,0\n  beq GetStateInfo_Unknown\n#Get Start of Move Name\nGetStateInfo_StringSearchLoop:\n  lbzu\tr4,0x1(r3)\n  cmpwi\tr4,0x4E\t\t#Check For \"N\"\n  bne\tGetStateInfo_StringSearchLoop\n  lbzu\tr4,0x1(r3)\n  cmpwi\tr4,0x5F\t\t#Check for Underscore\n  bne\tGetStateInfo_StringSearchLoop\n  addi\tr3,r3,0x1\t\t#Start of Move Name in r3\n#Copy Move Name To Cut Off \"fiagtree\" Text\n  subi\tr4,REG_StateString,0x1\n  subi\tr3,r3,0x1\n  GetStateInfo_StringCopyLoop:\n  lbzu\tr6,0x1(r3)\n  cmpwi\tr6,0x5F\t\t#Check for Underscore\n  beq\tGetStateInfo_ExitCopyLoop\n  stbu\tr6,0x1(r4)\n  b\tGetStateInfo_StringCopyLoop\nGetStateInfo_ExitCopyLoop:\n  li\tr3,0x0\n  stbu\tr3,0x1(r4)\n  b GetStateInfo_GetRemainingFrames\nGetStateInfo_Unknown:\n  bl  GetStateInfo_UnkString\n  mflr  r4\n  mr  r3,REG_StateString\n  branchl r12,strcpy\n\nGetStateInfo_GetRemainingFrames:\n#Get Remaining Frames\n\tlwz  r3,0x590(REG_PlayerData)\t\t\t#get anim data\n\tlfs  f2,0x008(r3)\t\t\t#get anim length (float)\n\nGetStateInfo_Exit:\n  mr  r3,REG_StateString\n  lfs f1,0x894(REG_PlayerData)\n  restore\n  blr\n##########################################\nGetStateInfo_UnkString:\nblrl\n.string \"UnkState\"\n.align 2\n##########################################\n\nExit:\nrestore\n"
  },
  {
    "path": "ASM/Additional Codes/Physics Display/Main.s",
    "content": "#To be inserted at 80225554\n.include \"../../Globals.s\"\n\n.set GObj_Create,0x803901f0\n.set GObj_AddUserData,0x80390b68\n.set GObj_AddProc,0x8038fd54\n.set HSD_MemAlloc,0x8037f1e4\n.set DevelopText_CreateDataTable,0x80302834\n.set DevelopText_Activate,0x80302810\n.set DevelopText_AddString,0x80302be4\n.set DevelopText_FormatAndPrint,0x80302d4c\n.set DevelopText_EraseAllText,0x80302bb0\n.set DevelopMode_Text_ResetCursorXY,0x80302a3c\n.set DevelopText_StoreBGColor,0x80302b90\n.set DevelopText_HideText,0x80302b00\n.set DevelopText_HideBG,0x80302ae0\n.set DevelopText_ShowText,0x80302af0\n.set DevelopText_ShowBG,0x80302ad0\n.set DevelopText_StoreTextScale,0x80302b10\n.set DevelopText_ResetCursorX,0x80302a88\n.set sprintf,0x80323cf4\n\n.set  WindowData_Text,0x0\n.set  WindowData_State,0x4\n\n.set  REG_DevelopText,31\n.set  REG_GObjData,30\n.set  REG_GObj,29\n\nstw\tr0, -0x4B7C (r13)\n\nbackup\n\n#Create Rectangle\n  li  r3,0x1000\n  branchl r12,HSD_MemAlloc\n  mr  r8,r3\n  li  r3,12\n  li  r4,0\n  li  r5,0\n  li  r6,39\n  li  r7,10\n  branchl r12,DevelopText_CreateDataTable\n  mr  REG_DevelopText,r3\n#Activate Text\n  lwz\tr3, -0x4884 (r13)\n  mr  r4,REG_DevelopText\n  branchl r12,DevelopText_Activate\n#Hide blinking cursor\n  li  r3,0\n  stb r3,0x26(REG_DevelopText)\n#Change BG Color\n  mr  r3,REG_DevelopText\n  bl  BGColor\n  mflr  r4\n  branchl r12,DevelopText_StoreBGColor\n#Hide by default\n  mr  r3,REG_DevelopText\n  branchl r12,DevelopText_HideText\n  mr  r3,REG_DevelopText\n  branchl r12,DevelopText_HideBG\n#Change Text Size\n  mr  r3,REG_DevelopText\n  bl  TextFloats\n  mflr  r4\n  lfs f1,0x0(r4)\n  lfs f2,0x4(r4)\n  branchl r12,DevelopText_StoreTextScale\n#Create Background GObj\n  li  r3,0\n  li  r4,0\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n#Allocate Space\n\tli\tr3,64\n\tbranchl r12,HSD_MemAlloc\n\tmr\tREG_GObjData,r3\n#Zero\n\tli\tr4,64\n\tbranchl r12,ZeroAreaLength\n#Initialize\n\tmr\tr6,REG_GObjData\n\tmr\tr3,REG_GObj\n\tli\tr4,4\n\tload\tr5,HSD_Free\n\tbranchl r12,GObj_AddUserData\n#Add Process\n\tmr\tr3,REG_GObj\n\tbl\tDebugLogThink\n\tmflr r4\n\tli\tr5,7\n  li  r6,0\n  branchl r12,GObj_AddGXLink\n\t#branchl r12,GObj_AddProc\n#Store pointer to dev text\n  stw REG_DevelopText,WindowData_Text(REG_GObjData)\n#Initialize State\n  li  r3,0\n  stw r3,WindowData_State(REG_GObjData)\n  b Exit\n\n\n\n\n\n\n\n\n\n\n########################################\nTextFloats:\nblrl\n.float 7.5\n.float 10\n########################################\n\n\n\n\n\n\n\n\n\n\nDebugLogThink:\nblrl\n.set  REG_GObjData,31\n.set  REG_PlayerData,30\nbackup\n\n#Only run during pass 0\n  cmpwi r4,0\n  bne DebugLogThink_Exit\n\nlwz REG_GObjData,0x2C(r3)\n\n#Check for state change\n  bl GetInputs\n  rlwinm. r0,r3,0,0x200\n  beq DebugLogThink_StateChangeEnd\n  bl GetInputs\n  rlwinm. r0,r4,0,0x2\n  beq DebugLogThink_StateChangeEnd\n#Inc state\n  lwz r3,WindowData_State(REG_GObjData)\n  addi  r3,r3,1\n  stw r3,WindowData_State(REG_GObjData)\n  cmpwi r3,4\n  ble DebugLogThink_ShowWindow\n#Loop back to hidden\n  li  r3,0\n  stw r3,WindowData_State(REG_GObjData)\n#Hide\n  lwz r3,WindowData_Text(REG_GObjData)\n  branchl r12,DevelopText_HideText\n  lwz r3,WindowData_Text(REG_GObjData)\n  branchl r12,DevelopText_HideBG\n  b DebugLogThink_StateChangeEnd\nDebugLogThink_ShowWindow:\n#Show\n  lwz r3,WindowData_Text(REG_GObjData)\n  branchl r12,DevelopText_ShowText\n  lwz r3,WindowData_Text(REG_GObjData)\n  branchl r12,DevelopText_ShowBG\nDebugLogThink_StateChangeEnd:\n\n#Check to update text\n  lwz r3,WindowData_State(REG_GObjData)\n  cmpwi r3,0\n  beq DebugLogThink_Exit\n\n#Erase all text\n  lwz  r3,WindowData_Text(REG_GObjData)\n  branchl r12,DevelopText_EraseAllText\n  lwz  r3,WindowData_Text(REG_GObjData)\n  li  r4,0\n  li  r5,0\n  branchl r12,DevelopMode_Text_ResetCursorXY\n\n#Output player number\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_Player\n  mflr r4\n  lwz r5,WindowData_State(REG_GObjData)\n  branchl r12,DevelopText_FormatAndPrint\n\n#Get current player data\n  lwz r3,WindowData_State(REG_GObjData)\n  subi  r3,r3,1\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  cmpwi r3,0\n  beq DebugLogThink_Exit\n#Backup data\n  lwz  REG_PlayerData,0x2C(r3)\n\n#vprintf string\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_LStick\n  mflr r4\n  lfs f1,0x620(REG_PlayerData)\n  lfs f2,0x624(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n\n#vprintf string\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_RStick\n  mflr r4\n  lfs f1,0x638(REG_PlayerData)\n  lfs f2,0x63C(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n\n#vprintf string\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_CVel\n  mflr r4\n  lfs f1,0x80(REG_PlayerData)\n  lfs f2,0x84(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n#vprintf string\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_KBVel\n  mflr r4\n  lfs f1,0x8C(REG_PlayerData)\n  lfs f2,0x90(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n#vprintf string\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_Pos\n  mflr r4\n  lfs f1,0xB0(REG_PlayerData)\n  lfs f2,0xB4(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n\n#Output ECB Lock info\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_ECBLock\n  mflr  r4\n  lwz r5,0x88C(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n#Output ECB Bottom info\n  lwz  r3,WindowData_Text(REG_GObjData)\n  li  r4,18\n  branchl r12,DevelopText_ResetCursorX\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_ECBBottom\n  mflr  r4\n  lfs f1,0x780(REG_PlayerData)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n\n#Output State info\n  mr  r3,REG_PlayerData\n  addi  r4,sp,0x88\n  bl  GetStateInfo\n  stfs  f1,0x80(sp)\n  stfs  f2,0x84(sp)\n  mr  r5,r3\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_State\n  mflr  r4\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n#Move cursor\n  lwz  r3,WindowData_Text(REG_GObjData)\n  li  r4,25\n  branchl r12,DevelopText_ResetCursorX\n#Output frames\n  lwz  r3,WindowData_Text(REG_GObjData)\n  bl  String_StateFrame\n  mflr  r4\n  lfs  f1,0x80(sp)\n  lfs  f2,0x84(sp)\n  crset 6\n  branchl r12,DevelopText_FormatAndPrint\n\nDebugLogThink_Exit:\nrestore\nblr\n\n#############################\nString_Player:\nblrl\n.string \"Player %d    X        Y\\n\"\n.align 2\nString_LStick:\nblrl\n.string \"LStick:  %1.4f   %1.4f\\n\"\n.align 2\nString_RStick:\nblrl\n.string \"RStick:  %1.4f   %1.4f\\n\"\n.align 2\nString_CVel:\nblrl\n.string \"SelfVel: %3.4f   %3.4f\\n\"\n.align 2\nString_KBVel:\nblrl\n.string \"KBVel:   %3.4f   %3.4f\\n\"\n.align 2\nString_XVel:\nblrl\n.string \"XVel:    %3.4f   %3.4f\\n\"\n.align 2\nString_Pos:\nblrl\n.string \"Pos:     %3.4f   %3.4f\\n\\n\"\n.align 2\nString_State:\nblrl\n.string \"State: %s\"\n.align 2\nString_StateFrame:\nblrl\n.string \"f: %03.2f/%1.0f\"\n.align 2\nString_ECBBottom:\nblrl\n.string \"ECB_Bot: %03.2f\\n\\n\"\n.align 2\nString_ECBLock:\nblrl\n.string \"ECB_Lock: %d\"\n.align 2\n\n\nBGColor:\nblrl\n.byte 21,20,59,135\n###############################\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nGetInputs:\n.set  REG_InputStruct,11\n.set  REG_Count,10\n.set  REG_HeldInputs,9\n.set  REG_InstantInputs,8\n\n#Load Input Struct\n  load  REG_InputStruct,0x804c1fac\n\n#Init loop\n  li  REG_Count,0\n  li  REG_HeldInputs,0\n  li  REG_InstantInputs,0\nGetInputs_Loop:\n#Get to inputs\n  mulli r3,REG_Count,68\n  add r5,r3,REG_InputStruct\n#Grab Inputs\n  lwz r3,0x0(r5)\n  lwz r4,0xC(r5)\n#OR all inputs\n  or  REG_HeldInputs,REG_HeldInputs,r3\n  or  REG_InstantInputs,REG_InstantInputs,r4\n#Inc\n  addi  REG_Count,REG_Count,1\n  cmpwi REG_Count,4\n  blt GetInputs_Loop\nGetInputs_Exit:\n  mr  r3,REG_HeldInputs\n  mr  r4,REG_InstantInputs\n  blr\n######################################\nGetStateInfo:\n.set REG_PlayerData,31\n.set REG_StateString,30\n\nbackup\n\n  mr  REG_PlayerData,r3\n  mr  REG_StateString,r4\n\n#Check if common move\n  lwz r3,0x10(REG_PlayerData)\n  cmpwi r3,341\n  bge GetStateInfo_SpecialMove\n\nGetStateInfo_SharedMove:\n  mulli r3,r3,4\n  lwz\tr4, -0x4B78 (r13)\n  lwzx  r4,r3,r4\n  mr  r3,REG_StateString\n  branchl r12,strcpy\n  b GetStateInfo_GetRemainingFrames\n\nGetStateInfo_SpecialMove:\n#Get Animation Data Pointer\n  mr\tr3,REG_PlayerData\n  lwz\tr4,0x14(REG_PlayerData)\n  branchl\tr12,0x80085fd4\n\n#Get Move Name String\n  lwz\tr3,0x0(r3)\n  cmpwi r3,0\n  beq GetStateInfo_Unknown\n#Get Start of Move Name\nGetStateInfo_StringSearchLoop:\n  lbzu\tr4,0x1(r3)\n  cmpwi\tr4,0x4E\t\t#Check For \"N\"\n  bne\tGetStateInfo_StringSearchLoop\n  lbzu\tr4,0x1(r3)\n  cmpwi\tr4,0x5F\t\t#Check for Underscore\n  bne\tGetStateInfo_StringSearchLoop\n  addi\tr3,r3,0x1\t\t#Start of Move Name in r3\n#Copy Move Name To Cut Off \"fiagtree\" Text\n  subi\tr4,REG_StateString,0x1\n  subi\tr3,r3,0x1\n  GetStateInfo_StringCopyLoop:\n  lbzu\tr6,0x1(r3)\n  cmpwi\tr6,0x5F\t\t#Check for Underscore\n  beq\tGetStateInfo_ExitCopyLoop\n  stbu\tr6,0x1(r4)\n  b\tGetStateInfo_StringCopyLoop\nGetStateInfo_ExitCopyLoop:\n  li\tr3,0x0\n  stbu\tr3,0x1(r4)\n  b GetStateInfo_GetRemainingFrames\nGetStateInfo_Unknown:\n  bl  GetStateInfo_UnkString\n  mflr  r4\n  mr  r3,REG_StateString\n  branchl r12,strcpy\n\nGetStateInfo_GetRemainingFrames:\n#Get Remaining Frames\n\tlwz  r3,0x590(REG_PlayerData)\t\t\t#get anim data\n\tlfs  f2,0x008(r3)\t\t\t#get anim length (float)\n\nGetStateInfo_Exit:\n  mr  r3,REG_StateString\n  lfs f1,0x894(REG_PlayerData)\n  restore\n  blr\n##########################################\nGetStateInfo_UnkString:\nblrl\n.string \"UnkState\"\n.align 2\n##########################################\n\nExit:\nrestore\n"
  },
  {
    "path": "ASM/Additional Codes/QWERTY Keyboard.s",
    "content": "#To be inserted at 803edc1c\n.long 0x804D4DD4 \n.long 0x804D4CAC \n.long 0x804D4CAC \n.long 0x804D4D98 \n.long 0x804D4D9C \n.long 0x804D4DE8 \n.long 0x804D4E24 \n.long 0x804D4CAC \n.long 0x804D4DA8 \n.long 0x804D4DAC \n.long 0x804D4DA0 \n.long 0x804D4E38 \n.long 0x804D4CAC \n.long 0x804D4DB8 \n.long 0x804D4DBC \n.long 0x804D4E3C \n.long 0x804D4D90 \n.long 0x804D4E10 \n.long 0x804D4DC8 \n.long 0x804D4DCC \n.long 0x804D4DEC \n.long 0x804D4DB0 \n.long 0x804D4DFC \n.long 0x804D4DDC \n.long 0x804D4DE0 \n.long 0x804D4D94 \n.long 0x804D4DC0 \n.long 0x804D4E20 \n.long 0x804D4DF0 \n.long 0x804D4DF4 \n.long 0x804D4DB4 \n.long 0x804D4DD0 \n.long 0x804D4E28 \n.long 0x804D4E04 \n.long 0x804D4E08 \n.long 0x804D4DE4 \n.long 0x804D4DF8 \n.long 0x804D4E0C \n.long 0x804D4E18 \n.long 0x804D4E1C \n.long 0x804D4E14 \n.long 0x804D4DA4 \n.long 0x804D4E00 \n.long 0x804D4E2C \n.long 0x804D4E30 \n.long 0x804D4DC4 \n.long 0x804D4E34 \n.long 0x804D4DD8 \n.long 0x804D4E40 \n.long 0x804D4E44\n\n\n"
  },
  {
    "path": "ASM/Additional Codes/Random CSS Music v2/random music modification.asm",
    "content": "#To be inserted at 8015ecec\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\naddi sp,sp,-0x4\nmflr r0\nstw r0,0(sp)\n.endm\n\n.macro restore\nlwz r0,0(sp)\nmtlr r0\naddi sp,sp,0x4\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n\nli r3,0x3\nbranchl r12,HSD_Randi\n\ncmpwi r3,0x0\nbeq MainMenu1\ncmpwi r3,0x1\nbeq MainMenu2\ncmpwi r3,0x2\nbeq Trophy\n\nMainMenu1:\nli r0,0x34\nb done\n\nMainMenu2:\nli r0,0x36\nb done\n\nTrophy:\nli r0,0x35\nb done\n\ndone:\nstb\tr0, 0x0001 (r31)\nbranch r12, 0x8015ed1c\n"
  },
  {
    "path": "ASM/Additional Codes/Random CSS Music v2/roll on bootup.asm",
    "content": "#To be inserted at 801a45a8\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\naddi sp,sp,-0x4\nmflr r0\nstw r0,0(sp)\n.endm\n\n.macro restore\nlwz r0,0(sp)\nmtlr r0\naddi sp,sp,0x4\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n\nbranchl r12,0x8015ecbc\n\noriginal:\nli\tr0, 45\n"
  },
  {
    "path": "ASM/Additional Codes/Random CSS Music v2/roll on match end.asm",
    "content": "#To be inserted at 8016eba8\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n\nbranchl r12,0x8015ecbc\n\noriginal:\nlwz\tr0, 0x001C (sp)\n"
  },
  {
    "path": "ASM/Additional Codes/Randomize Hitboxes Each Stock/Randomize Hitbox Values.s",
    "content": "#To be inserted at 80071240\n.include \"../../Globals.s\"\n\n.set  REG_Script,29\n.set  REG_FighterGObj,28\n.set  REG_Sum,30\n.set  REG_Free2,31\n\n# first add up the entire subaction data\n  lwz r3, 0x0008 (REG_Script)\n  li  r4,0\n  li  REG_Sum,0\nAddLoop:\n  lwz r5,0x0(r3)\n  add REG_Sum,REG_Sum,r5\nAddLoopInc:\n  addi  r4,r4,1\n  addi  r3,r3,4\n  cmpwi r4,5\n  blt AddLoop\n\n# get 16 bit int from this (shitty hash)\n.set  REG_Hash,30\n  sth REG_Sum,0x03C(sp)\n  lhz REG_Hash,0x03C(sp)\n\n# get random damage\n\n# get random angle\n\n# get random KB\n\n\n# exit\n  b Original\n\n\nOriginal:\n  lwz\tr4, 0x0008 (REG_Script)\n"
  },
  {
    "path": "ASM/Additional Codes/Rumble Off/Rumble Off.asm",
    "content": "#To be inserted at 803d4a70\n\n.long 0x00000000\n"
  },
  {
    "path": "ASM/Additional Codes/Skip Memcard Prompt/Skip Memcard Prompt.asm",
    "content": "#To be inserted at 801af6f4\n.include \"../../Globals.s\"\n\n.set MEMCARD_NONE,0xF\n.set MEMCARD_NONE2,0xD\n\n#Check if no memcard inserted\n  cmpwi r29,MEMCARD_NONE\n  beq NoMemcard\n  cmpwi r29,MEMCARD_NONE2\n  beq NoMemcard\n  b Original\n\nNoMemcard:\n#Exit memcard think and disable saving\n  branch r12,0x801b01ac\n\nOriginal:\n  cmpwi r29,0\n"
  },
  {
    "path": "ASM/Additional Codes/Stage Music = 50 50.asm",
    "content": "#To be inserted at 801C26B0\nli\tr0, 50"
  },
  {
    "path": "ASM/Additional Codes/Toggle Focused Player in Develop Mode Camera/Switch Focused Player in Develop Mode.asm",
    "content": "#To be inserted at 802276f4\n.include \"../../Globals.s\"\n\n.set REG_Inputs,31\n.set REG_FocusedPlayer,30\n.set REG_CameraStruct,29\n.set REG_Additive,28\n\nbackup\n\n#Get Current Focused Player\n  load REG_CameraStruct,0x80453004\n  lwz  REG_FocusedPlayer,0x4(REG_CameraStruct)\n\n#Init REG_Additive\n  li  REG_Additive,0\n\n#Check Dpad Left\nCheckDPadLeft:\n  rlwinm. r0,REG_Inputs,0,25,25\n  beq CheckDPadRight\n#Pressing Left\n  li  REG_Additive,-1\n  b GetNextPlayer\n#Check Dpad Right\nCheckDPadRight:\n  rlwinm. r0,REG_Inputs,0,26,26\n  beq GetNextPlayer\n#Pressing Right\n  li  REG_Additive,1\n  b GetNextPlayer\n\nGetNextPlayer:\n  cmpwi REG_Additive,0\n  beq Exit\nGetNextPlayerLoop:\n  add REG_FocusedPlayer,REG_FocusedPlayer,REG_Additive\n#Check if Under 4\n  cmpwi REG_FocusedPlayer,4\n  blt GetNextPlayer_Under4\n#Loop around back to 0\n  li  REG_FocusedPlayer,0\nGetNextPlayer_Under4:\n#Check if Over 4\n  cmpwi REG_FocusedPlayer,0\n  bge GetNextPlayer_CheckIfExists\n#Loop around back to 3\n  li  REG_FocusedPlayer,3\nGetNextPlayer_CheckIfExists:\n  mr  r3,REG_FocusedPlayer\n  branchl r12,0x80034110\n  cmpwi r3,0x0\n  beq GetNextPlayerLoop\n\n#Store New Focused Player\nstw REG_FocusedPlayer,0x4(REG_CameraStruct)\n\nExit:\n  restore\n  branchl r12,0x80030a50\n"
  },
  {
    "path": "ASM/Additional Codes/Toggle Focused Player in Develop Mode Camera/WIP/Init CameraMode Struct When Develop is Enabled.s",
    "content": "#To be inserted at 8016e898\n.include \"../../Globals.s\"\n\nlwz\tr0, -0x6C98 (r13)\ncmpwi r0,3\nblt Original\n\nbranchl r12,0x8002fc7c\n\nOriginal:\nlis\tr3, 0x8047\n"
  },
  {
    "path": "ASM/Additional Codes/Toggle Rumble From CSS/Toggle Rumble From CSS.asm",
    "content": "#To be inserted at 802608D8\n.include \"../../Globals.s\"\n\n#CREDIT: Dan Salvato\n\nloc_0x0:\n  lbz r3, 7(r31)\n  cmpwi r3, 0x0\n  bne- loc_0x98\n  lbz r4, 4(r31)\n  mr r23, r4\n  lwz r0, -30656(r13)\n  add r3, r0, r4\n  lbz r5, 7360(r3)\n  rlwinm. r0, r28, 0, 28, 28\n  bne- loc_0x34\n  rlwinm. r0, r28, 0, 29, 29\n  bne- loc_0x68\n  b loc_0xDC\n\nloc_0x34:\n  cmplwi r5, 1\n  beq- loc_0xDC\n  mr r3, r23\n  li r4, 0x0\n  li r5, 0xE\n  li r6, 0x0\n  subi r7, r13, 0x66B0\n  branchl r12,0x80378430\n  li r4, 0x1\n  b loc_0x74\n\nloc_0x68:\n  cmplwi r5, 0\n  beq- loc_0xDC\n  li r4, 0x0\n\nloc_0x74:\n  mr r3, r23\n  branchl r12,0x8015ED4C\n  li r4, 0x1\n  stb r4, 7(r31)\n  lis r4, 0xC040\n  stw r4, 20(r31)\n\nloc_0x98:\n  lfs f1, 20(r31)\n  lfs f2, -29172(r2)\n  lfs f0, 12(r31)\n  fadds f0, f1, f0\n  stfs f0, 12(r31)\n  fneg f3, f1\n  fcmpo cr0, f3, f1\n  bgt- loc_0xBC\n  fmuls f3, f3, f2\n\nloc_0xBC:\n  stfs f3, 20(r31)\n  blt- loc_0xDC\n  lfs f4, -32168(r2)\n  fcmpo cr0, f3, f4\n  bgt- loc_0xDC\n  li r4, 0x0\n  stw r4, 20(r31)\n  stb r4, 7(r31)\n\nloc_0xDC:\n  lbz r4, 4(r31)\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Characters/Spoof All Characters as Unlocked.asm",
    "content": "#To be inserted at 80164b14\nli\tr3, 1\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Characters/Spoof Individual Characters as Unlocked.asm",
    "content": "#To be inserted at 801648f4\nli\tr3, 1\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Rules/Unlock Random Stage Select.asm",
    "content": "#To be inserted at 8015ee4c\nli\tr3, 1\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Rules/Unlock Score Display.asm",
    "content": "#To be inserted at 8015ee14\nli\tr3, 1\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Special Messages/Special Messages 1.asm",
    "content": "#To be inserted at 8015d968\n.include \"../../../Globals.s\"\n\nli  r3,1\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Special Messages/Special Messages 2.asm",
    "content": "#To be inserted at 8015d9d8\n.include \"../../../Globals.s\"\n\nli  r3,1\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Special Messages/Spoof No Pending Messages 2.asm",
    "content": "#To be inserted at 8017229c\n.include \"../../../Globals.s\"\n\nli  r3,0\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Special Messages/Spoof No Pending Messages.asm",
    "content": "#To be inserted at 801737b0\n.include \"../../../Globals.s\"\n\nli  r3,0\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Stages/Spoof All Stages Unlocked.asm",
    "content": "#To be inserted at 80164658\nli\tr3, 1\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Stages/Spoof Individual Stage Unlocked.asm",
    "content": "#To be inserted at 801644e8\nli\tr3, 1"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Trophies/Fill Save Data.asm",
    "content": "#To be inserted at 8015f6f8\n.include \"../../../Globals.s\"\n\n#Get trophy data\n  lwz\tr3, -0x77C0 (r13)\n  addi\tr3, r3, 7376\n#Set trophy count\n  li  r4,293\n  sth r4,0x0(r3)\n#Set individual trophies as unlocked\n  addi r3,r3,4\n  li  r4,99\n  li  r5,0x24f\n  branchl r12,memset\n\nExit:\n  cmpwi\tr25, 0\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Trophies/Have 99 of Every Trophy.asm",
    "content": "#To be inserted at 8030490c\nli\tr3, 99\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All Trophies/Spoof All Trophies as Unlocked.asm",
    "content": "#To be inserted at 803044f0\nli\tr3, 1\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock All-Star.asm",
    "content": "#To be inserted at 8015ee98\nli\tr3, 1\n"
  },
  {
    "path": "ASM/Additional Codes/Unlock Everything/Unlock Sound Test.asm",
    "content": "#To be inserted at 8015eddc\nli\tr3, 1\n"
  },
  {
    "path": "ASM/Additional Codes/Unplugging Closes CSS Door.asm",
    "content": "#To be inserted at 802605fc\n.include \"../Globals.s\"\n  li  r6,3\n"
  },
  {
    "path": "ASM/Additional Codes/Use Save Banner #1.asm",
    "content": "#To be inserted at 8001c838\n.include \"../Globals.s\"\n\n.set entity,31\n.set player,31\n\n#Check if Memcard\n\tlis\tr3,0x8000\n\tlwz\tr3,0x0(r3)\n\tload\tr4,0x47544d45\t\t\t#GTME\n\tcmpw\tr3,r4\n\tbeq\tISO\n\nMemcard:\n  li\tr0, 2\n  b Exit\n\nISO:\n  li\tr0, 1\nExit:\n"
  },
  {
    "path": "ASM/Additional Codes/Winners Names are Gold on CSS/Change Name Color.asm",
    "content": "#To be inserted at 80265220\n.include \"../../Globals.s\"\n\n#Check If Player Won Last Game\n  mr  r3,r29\n  bl  CheckIfWonLastGame\n  cmpwi r3,0x0\n  beq Exit\n\n#Change Text Color\n  lwz\tr3, 0 (r27)\n  li  r4,0\n  load r5,0xFFD70000\n  stw r5,0x100(sp)\n  addi r5,sp,0x100\n  branchl r12,0x803a74f0\n  b Exit\n\n#########################################################\n\nCheckIfWonLastGame:\n.set MatchEndStruct,31\n.set MatchEndPlayerStruct,30\n.set PlayerSlot,29\n\nbackup\n\nmr  PlayerSlot,r3\nload  MatchEndStruct,0x80479da4\nmulli MatchEndPlayerStruct,PlayerSlot,0xA8\nadd   MatchEndPlayerStruct,MatchEndPlayerStruct,MatchEndStruct\n\n#Check if last game data exists\n  lbz r3,0x4(MatchEndStruct)\n  cmpwi r3,0x0\n  beq  CheckIfWonLastGame_DidNotWin\n\n#Check if last game was same Mode (Teams/FFA)\n  load r3,0x8046b6a0\n  lbz r3,0x24D0(r3)\n  lbz r4,0x6(MatchEndStruct)\n  cmpw r3,r4\n  bne CheckIfWonLastGame_DidNotWin\n\n#Check if player partook in last game\n  lbz r3,0x58(MatchEndPlayerStruct)\n  cmpwi r3,3\n  beq CheckIfWonLastGame_DidNotWin\n\n#Check if last game was an LRA Start\n  lbz r3,0x4(MatchEndStruct)\n  cmpwi r3,0x7\n  bne CheckIfWonLastGame_CheckForTeams\n  #Check if this was a team LRA Start\n    lbz r3,0x6(MatchEndStruct)\n    cmpwi r3,0x1\n    bne CheckIfWonLastGame_FFA_LRAStart\n    CheckIfWonLastGame_Team_LRAStart:\n    #Check who LRA started\n      lbz r3,0x0(MatchEndStruct)\n    #Get his team ID\n      mulli r3,r3,0xA8\n      add   r3,r3,MatchEndStruct\n      lbz   r3,0x5F(r3)\n    #Get current players team ID\n      lbz   r4,0x5F(MatchEndPlayerStruct)\n    #Check If Same Team\n      cmpw  r3,r4\n      beq CheckIfWonLastGame_DidNotWin\n      b CheckIfWonLastGame_Won\n\n    CheckIfWonLastGame_FFA_LRAStart:\n    #Check who LRA started\n      lbz r3,0x0(MatchEndStruct)\n      #If this player did, return 0\n        cmpw r3,PlayerSlot\n        beq CheckIfWonLastGame_DidNotWin\n        b CheckIfWonLastGame_Won\n\nCheckIfWonLastGame_CheckForTeams:\n#Check if Teams Match\n  lbz r3,0x6(MatchEndStruct)\n  cmpwi r3,0x1\n  bne CheckIfWonLastGame_FFA\n  #If so find winning team\n    mr  r3,MatchEndStruct\n    branchl r12,0x801654a0\n  #Check this players team\n    lbz   r4,0x5F(MatchEndPlayerStruct)\n  #If this player was on winning team, return 1, if not return 0\n    cmpw r3,r4\n    beq CheckIfWonLastGame_Won\n    b CheckIfWonLastGame_DidNotWin\n\nCheckIfWonLastGame_FFA:\n#Check If Player Won\n  lbz   r3,0x5D(MatchEndPlayerStruct)\n   #if so return 1, if not return 0\n   cmpwi  r3,0\n   beq  CheckIfWonLastGame_Won\n   b CheckIfWonLastGame_DidNotWin\n\nCheckIfWonLastGame_DidNotWin:\nli  r3,0\nb 0x8\nCheckIfWonLastGame_Won:\nli  r3,1\n\nrestore\nblr\n\n#########################################################\n\nExit:\n  lbz\tr0, -0x49AB (r13)\n"
  },
  {
    "path": "ASM/Additional Codes/Winners Names are Gold on CSS/Remember Who LRA Started.asm",
    "content": "#To be inserted at 8016ea30\n.include \"../../Globals.s\"\n\n#Original Codeline\n  stb\tr0, 0x0010 (r30)\n\n#Check If LRA Start\n  cmpwi r0,0x7\n  bne Exit\n#Find Who LRA Started\n  load r4,0x8046b6a0\n  lbz r4,0x1(r4)\n  stb r4,0xC(r30)\n\nExit:\n"
  },
  {
    "path": "ASM/Additional Codes/XYDisablesStart/Main.asm",
    "content": "#To be inserted at 803775bc\n.include \"../../Globals.s\"\n\n#Check if pressing start\n  rlwinm. r3,r0,0,0x1000\n  beq Injection_Exit\n  #Check if also holding X+Y\n  rlwinm. r3,r0,0,0xC00\n  beq Injection_Exit\n#Remove the start input\n  li  r3,0\n  rlwimi  r0,r3,12,0x1000\nInjection_Exit:\n#store their instant input\n  stw\tr0, 0 (r26)\n"
  },
  {
    "path": "ASM/Globals.s",
    "content": "#####################\n## Melee Variables ##\n#####################\n#Static Memory Locations\n.set pdLoadCommonData,0x803bcde0\n.set InputStructStart,0x804c21cc\n  .set InputStruct_HeldButtons,0x0\n  .set InputStruct_HeldButtonsPrevFrame,0x4\n  .set InputStruct_InstantButtons,0x8\n  .set InputStruct_RapidFireButtons,0xC\n  .set InputStruct_InstantReleasedButtons,0x10\n  .set InputStruct_RapidFireCounter,0x14\n  .set InputStruct_LeftAnalogX,0x18\n  .set InputStruct_LeftAnalogY,0x19\n  .set InputStruct_RightAnalogX,0x1A\n  .set InputStruct_RightAnalogY,0x1B\n  .set InputStruct_LeftTrigger,0x1C\n  .set InputStruct_RightTrigger,0x1D\n  .set InputStruct_LeftAnalogXFloat,0x20\n  .set InputStruct_LeftAnalogYFloat,0x24\n  .set InputStruct_RightAnalogXFloat,0x28\n  .set InputStruct_RightAnalogYFloat,0x2C\n  .set InputStruct_IsPlugged,0x41\n  .set InputStruct_Length,68\n.set HSD_InputStructStart,0x804c1fac\n.set PreloadTable,0x80432078\n  .set Preload_Stage,0x10\n.set CSS_CursorPointers,0x804a0bc0\n.set HSD_Pad,0x804c1f78\n.set CSS_DoorStructs,0x803f0dfc\n  .set  CSSDoor_State,0xB\n\n#r13 Offsets\n.set MemcardData,-0x77C0\n.set DEBUGLV,-0x6C98\n.set CSS_Data,-0x49F0\n.set CSS_UnkGObj,-0x49E4\n.set CSS_UnkJObj,-0x49E0\n.set CSS_PointerToDatNodes,-0x49C8    #these are initialized to at 80266970\n.set CSS_MainPlayerPort,-0x49B0\n.set CSS_CPUPlayerPort,-0x49AF\n.set CSS_StartCountdown,-0x49AE\n.set CSS_Unk,-0x49AC\n.set CSS_MaxPlayers,-0x49AB\n.set CSS_Unk,-0x49AA\n.set CSS_SinglePlayerPortNumber,-0x4DE0\n.set HPS_Unk,-0x3F44\n.set HPS_CurrentSongEntryNum,-0x3F3C\n.set HPS_Unk,-0x3F14\n.set GObj_CurrentProc,-0x3E68\n.set HSDPerf_,0x0\n.set Hitbox_DamageLog,-0x5148     #Num of solid hits dealt by the player this check\n.set Hitbox_TipLog,-0x5144        #Num of phantom hits dealt by the player this check\n.set StageID_External,-0x6CB8\n.set Stage_LedgeInfo,-0x51E8\n.set Stage_LineInfo,-0x51EC       #ctrl f \"stage line counts\" in melee notes.txt for detailed info\n.set Stage_PositionHazardCount,-0x5128\n.set Stage_GrabHazardCount,-0x512C\n.set Stage_DamageHazardCount,-0x5130\n.set Audio_NextAreaInSSMHeap,-0x5258\n.set Audio_UnkConstant,-0x5250\n.set Audio_TotalSSMMemory,-0x5268\n.set GObj_Lists,-0x3E74\n\n.set TM_FrozenToggle,-0x4F8C\n.set TM_GameFrameCounter,-0x49a8\n\n#Scene Struct\n.set SceneController,0x80479D30\n  .set Scene.CurrentMajor,0x0\n  .set Scene.PendingMajor,0x1\n  .set Scene.PreviousMajor,0x2\n  .set Scene.CurrentMinor,0x3\n  .set Scene.PendingMinor,0x4\n  .set Scene.PreviousMinor,0x5\n#Scene ID's\n.set Scene.TitleScreen,0x00\n.set Scene.MainMenu,0x01\n.set Scene.VSMode,0x02\n.set Scene.ClassicMode,0x03\n.set Scene.AdventureMode,0x04\n.set Scene.AllStarMode,0x05\n.set Scene.MainDebugMenu,0x06\n.set Scene.SoundTestDebugMenu,0x07\n.set Scene.HanyuTestCSS,0x08\n.set Scene.HanyuTestSSS,0x09\n.set Scene.CameraModeMemcardPrompt,0x0A\n.set Scene.TrophyGallery,0x0B\n.set Scene.TrophyLottery,0x0C\n.set Scene.TrophyCollection,0x0D\n.set Scene.DebugDiarantou,0x0E\n.set Scene.TargetTest,0x0F\n.set Scene.SuperSuddenDeath,0x10\n.set Scene.InvisibleMelee,0x11\n.set Scene.SloMoMelee,0x12\n.set Scene.LightningMelee,0x13\n.set Scene.ChallengerApproaching,0x14\n.set Scene.ClassicModeEnding,0x15\n.set Scene.AdventureModeEnding,0x16\n.set Scene.AllStarModeEnding,0x17\n.set Scene.OpeningMovie,0x18\n.set Scene.VisualSceneDebug,0x19\n.set Scene.1PEndingDebug,0x1A\n.set Scene.TournamentMode,0x1B\n.set Scene.TrainingMode,0x1C\n.set Scene.TinyMelee,0x1D\n.set Scene.GiantMelee,0x1E\n.set Scene.StaminaMode,0x1F\n.set Scene.HomeRunContest,0x20\n.set Scene.10ManMelee,0x21\n.set Scene.100ManMelee,0x22\n.set Scene.3MinuteMelee,0x23\n.set Scene.15MinuteMelee,0x24\n.set Scene.EndlessMelee,0x25\n.set Scene.CruelMelee,0x26\n.set Scene.ProgressiveScanPrompt,0x27\n.set Scene.BootUp,0x28\n.set Scene.MemcardPropmt,0x29\n.set Scene.FixedCamera,0x2A\n.set Scene.EventMode,0x2B\n.set Scene.SingleButton,0x2C\n\n####################\n## Function Names ##\n####################\n\n.set ActionStateChange,0x800693ac\n.set OSReport,0x803456a8\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set AS_Wait,0x8008a2bc\n.set AS_Fall,0x800cc730\n.set AS_Catch,0x800d8c54\n.set AS_Guard,0x800939b4\n.set HSD_MemAlloc,0x8037f1e4\n.set HSD_JObjLoadJoint,0x80370e44\n.set memcpy,0x800031f4\n.set strcpy,0x80325a50\n.set ZeroAreaLength,0x8000c160\n.set CreateCameraBox,0x80029020\n.set FrameSpeedChange,0x8006f190\n.set HUD_KOCounter_UpdateKOs,0x802fa2d0\n.set Playerblock_StoreTimesR3KilledR4,0x80034fa8\n.set Playerblock_LoadTimesR3KilledR4,0x80034f24\n.set SFX_PlaySoundAtFullVolume,0x801c53ec\n.set SFX_MenuCommonSound,0x80024030\n.set AS_Rebirth,0x800d4ff4\n.set Stage_GetLeftOfLineCoordinates,0x80053ecc\n.set Stage_GetRightOfLineCoordinates,0x80053da4\n.set AS_RebirthWait,0x800d5600\n.set RebirthPlatform_UpdatePosition,0x800d54a4\n.set AS_CliffWait,0x8009a804\n.set Air_StoreBool_LoseGroundJump_NoECBfor10Frames,0x8007d5d4\n.set DataOffset_ECBBottomUpdateEnable,0x8007d5bc\n.set MovePlayerToLedge,0x80081544\n.set ApplyIntangibility,0x8007b760\n.set ApplyInvincibility,0x8007b7a4\n.set GFX_RemoveAll,0x8007db24\n.set PlayerBlock_LoadMainCharDataOffset,0x80034110\n.set PlayerBlock_SetDamage,0x80034330\n.set PlayerBlock_LoadDamage,0x800342b4\n.set StageInfo_CameraLimitLeft_Load,0x80224a54\n.set StageInfo_CameraLimitRight_Load,0x80224a68\n.set StageInfo_CameraLimitTop_Load,0x80224a80\n.set StageInfo_CameraLimitBottom_Load,0x80224a98\n.set Stage_map_gobj_Load,0x801c2ba4\n.set Stage_map_gobj_LoadJObj,0x801c3fa4\n.set Stage_Destroy_map_gobj,0x801c4a08\n.set EntityItemSpawn,0x80268b18\n.set MatchInfo_LoadSeconds,0x8016aeec\n.set MatchInfo_LoadSubSeconds,0x8016aefc\n.set EventMatch_OnWinCondition,0x801bc4f4\n.set Events_GetEventSavedScore,0x8015cf5c\n.set Events_SetEventSavedScore,0x8015cf70\n.set Textures_DisplayEffectTextures,0x8005fddc\n.set AS_GrabOpponent,0x800d9ce8\n.set AS_Grabbed,0x800daadc\n.set AS_CatchWait,0x800da1d8\n.set AS_SquatWait,0x800d62c4\n.set AS_Sleep,0x800d4f24\n.set SetAsGrounded,0x8007d7fc\n.set FrameSpeedChange,0x8006f190\n.set EnvironmentCollision_WaitLanding,0x80084280\n.set Air_SetAsGrounded,0x8007d6a4\n.set CPU_JoystickXAxis_Convert,0x800a17e4\n.set CPU_JoystickYAxis_Convert,0x800a1874\n.set Joystick_Angle_Retrieve,0x8007d9d4\n.set GFX_UpdatePlayerGFX,0x800c0408\n.set cos,0x80326240\n.set sin,0x803263d4\n.set fmod,0x80364340\n.set sqrt,0x8000d5bc\n.set HSD_Free,0x8037f1b0\n.set GObj_Create,0x803901f0\n.set GObj_AddUserData,0x80390b68\n.set GObj_Destroy,0x80390228\n.set GObj_AddProc,0x8038fd54\n.set GObj_RemoveProc,0x8038fed4\n.set GObj_StorePointerToJObj,0x80390a70\n.set GObj_AddGXLink,0x8039069c\n.set HSD_JObjSetMtxDirtySub,0x803732e8\n.set DevelopMode_FrameAdvanceCheck,0x801a45e8\n.set MatchInfo_StockModeCheck,0x8016b094\n.set PlayerBlock_LoadStocksLeft,0x80033bd8\n.set PlayerBlock_LoadSlotType,0x8003241c\n.set Playerblock_LoadStaticBlock,0x80031724\n.set Text_CreateTextStruct,0x803a6754\n.set Text_InitializeSubtext,0x803a6b98\n.set Text_UpdateSubtextSize,0x803a7548\n.set Text_UpdateSubtextPosition,0x803a746c\n.set Text_UpdateSubtextContents,0x803a70a0\n.set Text_ChangeTextColor,0x803a74f0\n.set Text_RemoveText,0x803a5cc4\n.set strlen,0x80325b04\n.set PlayerBlock_LoadExternalCharID,0x80032330\n.set PlayerBlock_GotoStaleMoveEntry_0xBC,0x80036244\n.set InitializePlayerDataValues,0x80068354\n.set Event_GetEventSavedScore,0x8015cf5c\n.set Events_CheckIfEventWasPlayedYet,0x8015cefc\n.set Events_SetEventAsPlayed,0x8015ceb4\n.set Events_StoreEventScore,0x8015cf70\n.set Interrupt_AerialJumpGoTo,0x800cb870\n.set PlayerBlock_UpdateXYCoords,0x80032828\n.set Raycast_GroundLine,0x8004f008\n.set Camera_UpdatePlayerCameraBoxPosition,0x800761c8\n.set Camera_CorrectPosition,0x8002f3ac\n.set ItemCollision_Egg,0x802895a8\n.set SFX_StopAllCharacterSFX,0x80088a50\n.set SFXManager_StopSFXIfPlaying,0x80321ce8\n.set memset,0x80003100\n.set Ragdoll_WindDecayThink,0x800115f4\n.set Inputs_GetPlayerHeldInputs,0x801a3680\n.set Inputs_GetPlayerInstantInputs,0x801a36a0\n.set Inputs_GetPlayerRapidInputs,0x801a36c0\n.set DevelopText_CreateDataTable,0x80302834\n.set DevelopText_Activate,0x80302810\n.set DevelopText_AddString,0x80302be4\n.set DevelopText_EraseAllText,0x80302bb0\n.set DevelopMode_Text_ResetCursorXY,0x80302a3c\n.set DevelopText_StoreBGColor,0x80302b90\n.set DevelopText_HideBG,0x80302ae0\n.set DevelopText_ShowBG,0x80302ad0\n.set cvt_sll_flt,0x80322da0\n.set cvt_fp2unsigned,0x803228c0\n.set sprintf,0x80323cf4\n.set PlayerBlock_LoadNameTagSlot,0x8003556c\n.set Nametag_LoadNametagSlotText,0x8023754c\n.set LoadRulesSettingsPointer1,0x8015cc34\n.set CSS_UpdateCSPInfo,0x8025db34\n.set Rumble_StoreRumbleFlag,0x8015ed4c\n\n#Custom Functions\n.set TextCreateFunction,0x80005928\n.set GetCustomEventPageName,0x8000552c\n.set SearchStringTable,0x80005530\n.set GetNumOfEventsOnCurrentPage,0x80005534\n.set GetEventTutorialFileName,0x80005538\n.set prim.new,0x804DD84C\n.set prim.close,0x804DD848\n\n#Character External IDs\n.set CaptainFalcon.Ext,0x0\n.set DK.Ext,0x1\n.set Fox.Ext,0x2\n.set GaW.Ext,0x3\n.set Kirby.Ext,0x4\n.set Bowser.Ext,0x5\n.set Link.Ext,0x6\n.set Luigi.Ext,0x7\n.set Mario.Ext,0x8\n.set Marth.Ext,0x9\n.set Mewtwo.Ext,0xA\n.set Ness.Ext,0xB\n.set Peach.Ext,0xC\n.set Pikachu.Ext,0xD\n.set IceClimbers.Ext,0xE\n.set Jigglypuff.Ext,0xF\n.set Samus.Ext,0x10\n.set Yoshi.Ext,0x11\n.set Zelda.Ext,0x12\n.set Sheik.Ext,0x13\n.set Falco.Ext,0x14\n.set YLink.Ext,0x15\n.set Doc.Ext,0x16\n.set Roy.Ext,0x17\n.set Pichu.Ext,0x18\n.set Ganondorf.Ext,0x19\n\n#Character Internal IDs\n.set Mario.Int,0x0\n.set Fox.Int,0x1\n.set CaptainFalcon.Int,0x2\n.set DK.Int,0x3\n.set Kirby.Int,0x4\n.set Bowser.Int,0x5\n.set Link.Int,0x6\n.set Sheik.Int,0x7\n.set Ness.Int,0x8\n.set Peach.Int,0x9\n.set Popo.Int,0xA\n.set Nana.Int,0xB\n.set Pikachu.Int,0xC\n.set Samus.Int,0xD\n.set Yoshi.Int,0xE\n.set Jigglypuff.Int,0xF\n.set Mewtwo.Int,0x10\n.set Luigi.Int,0x11\n.set Marth.Int,0x12\n.set Zelda.Int,0x13\n.set YLink.Int,0x14\n.set Doc.Int,0x15\n.set Falco.Int,0x16\n.set Pichu.Int,0x17\n.set GaW.Int,0x18\n.set Ganondorf.Int,0x19\n.set Roy.Int,0x1A\n\n/*\n#Character CSS ID\n.set Doc_CSSID,0x0\n.set Mario_CSSID,0x1\n.set Luigi_CSSID,0x2\n.set Bowser_CSSID,0x3\n.set Peach_CSSID,0x4\n.set Yoshi_CSSID,0x5\n.set DK_CSSID,0x6\n.set CaptainFalcon_CSSID,0x7\n.set Ganondorf_CSSID,0x8\n.set Falco_CSSID,0x9\n.set Fox_CSSID,0xA\n.set Ness_CSSID,0xB\n.set IceClimbers_CSSID,0xC\n.set Kirby_CSSID,0xD\n.set Samus_CSSID,0xE\n.set Zelda_CSSID,0xF\n.set Link_CSSID,0x10\n.set YLink_CSSID,0x11\n.set Pichu_CSSID,0x12\n.set Pikachu_CSSID,0x13\n.set Jigglypuff_CSSID,0x14\n.set Mewtwo_CSSID,0x15\n.set GaW_CSSID,0x16\n.set Marth_CSSID,0x17\n.set Roy_CSSID,0x18\n*/\n\n#Character CSS Bitflag IDs\n#(used for TM's lookup tables for displaying CSS icons)\n.set Doc_CSSID,0x1\n.set Mario_CSSID,0x2\n.set Luigi_CSSID,0x4\n.set Bowser_CSSID,0x8\n.set Peach_CSSID,0x10\n.set Yoshi_CSSID,0x20\n.set DK_CSSID,0x40\n.set CaptainFalcon_CSSID,0x80\n.set Ganondorf_CSSID,0x100\n.set Falco_CSSID,0x200\n.set Fox_CSSID,0x400\n.set Ness_CSSID,0x800\n.set IceClimbers_CSSID,0x1000\n.set Kirby_CSSID,0x2000\n.set Samus_CSSID,0x4000\n.set Zelda_CSSID,0x8000\n.set Link_CSSID,0x10000\n.set YLink_CSSID,0x20000\n.set Pichu_CSSID,0x40000\n.set Pikachu_CSSID,0x80000\n.set Jigglypuff_CSSID,0x100000\n.set Mewtwo_CSSID,0x200000\n.set GaW_CSSID,0x400000\n.set Marth_CSSID,0x800000\n.set Roy_CSSID,0x1000000\n\n#Stage External IDs\n.set FoD,0x2\n.set PokemonStadium,0x3\n.set PeachsCastle,0x4\n.set KongoJungle,0x5\n.set Brinstar,0x6\n.set Corneria,0x7\n.set YoshiStory,0x8\n.set Onett,0x9\n.set MuteCity,0xA\n.set RainbowCruise,0xB\n.set JungleJapes,0xC\n.set GreatBay,0xD\n.set HyruleTemple,0xE\n.set BrinstarDepths,0xF\n.set YoshiIsland,0x10\n.set GreenGreens,0x11\n.set Fourside,0x12\n.set MushroomKingdomI,0x13\n.set MushroomKingdomII,0x14\n.set Akaneia,0x15\n.set Venom,0x16\n.set PokeFloats,0x17\n.set BigBlue,0x18\n.set IcicleMountain,0x19\n.set IceTop,0x1A\n.set FlatZone,0x1B\n.set DreamLand,0x1C\n.set YoshiIsland64,0x1D\n.set KongoJungle64,0x1E\n.set Battlefield,0x1F\n.set FinalDestination,0x20\n\n#Button Definitions\n.set PAD_BUTTON_LEFT,0x40000\n.set PAD_BUTTON_RIGHT,0x80000\n.set PAD_BUTTON_DOWN,0x20000\n.set PAD_BUTTON_UP,0x10000\n.set PAD_BUTTON_DPAD_LEFT,0x0001\n.set PAD_BUTTON_DPAD_RIGHT,0x0002\n.set PAD_BUTTON_DPAD_DOWN,0x0004\n.set PAD_BUTTON_DPAD_UP,0x0008\n.set PAD_TRIGGER_Z,0x0010\n.set PAD_TRIGGER_R,0x0020\n.set PAD_TRIGGER_L,0x0040\n.set PAD_BUTTON_A,0x0100\n.set PAD_BUTTON_B,0x0200\n.set PAD_BUTTON_X,0x0400\n.set PAD_BUTTON_Y,0x0800\n.set PAD_BUTTON_START,0x1000\n\n#SFX Definitions\n.set SFX_cs_cancel,0xac\n.set SFX_cs_decide,0xad\n.set SFX_cs_mv,0xae\n.set SFX_cs_beep1,0xaf\n\n#########################\n## Playerblock Offsets ##\n#########################\n\n#Misc\n  .set ControllerPort,0x618\n  .set CostumeID,0x619\n#Input Data\n  .set HeldButtons,0x65C\n  .set InstantButtons,0x668\n  .set AnalogX,0x620\n  .set AnalogY,0x624\n#Animation Data\n  .set CurrentFrame,0x894\n#CPU AI Data\n  .set CPU_HeldButtons,0x1A88\n  .set CPU_AnalogX,0x1A8C\n  .set CPU_AnalogY,0x1A8D\n  .set CPU_CStickX,0x1A8E\n  .set CPU_CStickY,0x1A8F\n  .set CPU_LAnalog,0x1A90\n  .set CPU_RAnalog,0x1A91\n\n#############################\n## Player Action State IDs ##\n#############################\n.set ASID_DeadDown, 0x00\n.set ASID_DeadLeft, 0x01\n.set ASID_DeadRight, 0x02\n.set ASID_DeadUp, 0x03\n.set ASID_DeadUpStar, 0x04\n.set ASID_DeadUpStarIce, 0x05\n.set ASID_DeadUpFall, 0x06\n.set ASID_DeadUpFallHitCamera, 0x07\n.set ASID_DeadUpFallHitCameraFlat, 0x08\n.set ASID_DeadUpFallIce, 0x09\n.set ASID_DeadUpFallHitCameraIce, 0x0A\n.set ASID_Sleep, 0x0B\n.set ASID_Rebirth, 0x0C\n.set ASID_RebirthWait, 0x0D\n.set ASID_Wait, 0x0E\n.set ASID_WalkSlow, 0x0F\n.set ASID_WalkMiddle, 0x10\n.set ASID_WalkFast, 0x11\n.set ASID_Turn, 0x12\n.set ASID_TurnRun, 0x13\n.set ASID_Dash, 0x14\n.set ASID_Run, 0x15\n.set ASID_RunDirect, 0x16\n.set ASID_RunBrake, 0x17\n.set ASID_KneeBend, 0x18\n.set ASID_JumpF, 0x19\n.set ASID_JumpB, 0x1A\n.set ASID_JumpAerialF, 0x1B\n.set ASID_JumpAerialB, 0x1C\n.set ASID_Fall, 0x1D\n.set ASID_FallF, 0x1E\n.set ASID_FallB, 0x1F\n.set ASID_FallAerial, 0x20\n.set ASID_FallAerialF, 0x21\n.set ASID_FallAerialB, 0x22\n.set ASID_FallSpecial, 0x23\n.set ASID_FallSpecialF, 0x24\n.set ASID_FallSpecialB, 0x25\n.set ASID_DamageFall, 0x26\n.set ASID_Squat, 0x27\n.set ASID_SquatWait, 0x28\n.set ASID_SquatRv, 0x29\n.set ASID_Landing, 0x2A\n.set ASID_LandingFallSpecial, 0x2B\n.set ASID_Attack11, 0x2C\n.set ASID_Attack12, 0x2D\n.set ASID_Attack13, 0x2E\n.set ASID_Attack100Start, 0x2F\n.set ASID_Attack100Loop, 0x30\n.set ASID_Attack100End, 0x31\n.set ASID_AttackDash, 0x32\n.set ASID_AttackS3Hi, 0x33\n.set ASID_AttackS3HiS, 0x34\n.set ASID_AttackS3S, 0x35\n.set ASID_AttackS3LwS, 0x36\n.set ASID_AttackS3Lw, 0x37\n.set ASID_AttackHi3, 0x38\n.set ASID_AttackLw3, 0x39\n.set ASID_AttackS4Hi, 0x3A\n.set ASID_AttackS4HiS, 0x3B\n.set ASID_AttackS4S, 0x3C\n.set ASID_AttackS4LwS, 0x3D\n.set ASID_AttackS4Lw, 0x3E\n.set ASID_AttackHi4, 0x3F\n.set ASID_AttackLw4, 0x40\n.set ASID_AttackAirN, 0x41\n.set ASID_AttackAirF, 0x42\n.set ASID_AttackAirB, 0x43\n.set ASID_AttackAirHi, 0x44\n.set ASID_AttackAirLw, 0x45\n.set ASID_LandingAirN, 0x46\n.set ASID_LandingAirF, 0x47\n.set ASID_LandingAirB, 0x48\n.set ASID_LandingAirHi, 0x49\n.set ASID_LandingAirLw, 0x4A\n.set ASID_DamageHi1, 0x4B\n.set ASID_DamageHi2, 0x4C\n.set ASID_DamageHi3, 0x4D\n.set ASID_DamageN1, 0x4E\n.set ASID_DamageN2, 0x4F\n.set ASID_DamageN3, 0x50\n.set ASID_DamageLw1, 0x51\n.set ASID_DamageLw2, 0x52\n.set ASID_DamageLw3, 0x53\n.set ASID_DamageAir1, 0x54\n.set ASID_DamageAir2, 0x55\n.set ASID_DamageAir3, 0x56\n.set ASID_DamageFlyHi, 0x57\n.set ASID_DamageFlyN, 0x58\n.set ASID_DamageFlyLw, 0x59\n.set ASID_DamageFlyTop, 0x5A\n.set ASID_DamageFlyRoll, 0x5B\n.set ASID_LightGet, 0x5C\n.set ASID_HeavyGet, 0x5D\n.set ASID_LightThrowF, 0x5E\n.set ASID_LightThrowB, 0x5F\n.set ASID_LightThrowHi, 0x60\n.set ASID_LightThrowLw, 0x61\n.set ASID_LightThrowDash, 0x62\n.set ASID_LightThrowDrop, 0x63\n.set ASID_LightThrowAirF, 0x64\n.set ASID_LightThrowAirB, 0x65\n.set ASID_LightThrowAirHi, 0x66\n.set ASID_LightThrowAirLw, 0x67\n.set ASID_HeavyThrowF, 0x68\n.set ASID_HeavyThrowB, 0x69\n.set ASID_HeavyThrowHi, 0x6A\n.set ASID_HeavyThrowLw, 0x6B\n.set ASID_LightThrowF4, 0x6C\n.set ASID_LightThrowB4, 0x6D\n.set ASID_LightThrowHi4, 0x6E\n.set ASID_LightThrowLw4, 0x6F\n.set ASID_LightThrowAirF4, 0x70\n.set ASID_LightThrowAirB4, 0x71\n.set ASID_LightThrowAirHi4, 0x72\n.set ASID_LightThrowAirLw4, 0x73\n.set ASID_HeavyThrowF4, 0x74\n.set ASID_HeavyThrowB4, 0x75\n.set ASID_HeavyThrowHi4, 0x76\n.set ASID_HeavyThrowLw4, 0x77\n.set ASID_SwordSwing1, 0x78\n.set ASID_SwordSwing3, 0x79\n.set ASID_SwordSwing4, 0x7A\n.set ASID_SwordSwingDash, 0x7B\n.set ASID_BatSwing1, 0x7C\n.set ASID_BatSwing3, 0x7D\n.set ASID_BatSwing4, 0x7E\n.set ASID_BatSwingDash, 0x7F\n.set ASID_ParasolSwing1, 0x80\n.set ASID_ParasolSwing3, 0x81\n.set ASID_ParasolSwing4, 0x82\n.set ASID_ParasolSwingDash, 0x83\n.set ASID_HarisenSwing1, 0x84\n.set ASID_HarisenSwing3, 0x85\n.set ASID_HarisenSwing4, 0x86\n.set ASID_HarisenSwingDash, 0x87\n.set ASID_StarRodSwing1, 0x88\n.set ASID_StarRodSwing3, 0x89\n.set ASID_StarRodSwing4, 0x8A\n.set ASID_StarRodSwingDash, 0x8B\n.set ASID_LipStickSwing1, 0x8C\n.set ASID_LipStickSwing3, 0x8D\n.set ASID_LipStickSwing4, 0x8E\n.set ASID_LipStickSwingDash, 0x8F\n.set ASID_ItemParasolOpen, 0x90\n.set ASID_ItemParasolFall, 0x91\n.set ASID_ItemParasolFallSpecial, 0x92\n.set ASID_ItemParasolDamageFall, 0x93\n.set ASID_LGunShoot, 0x94\n.set ASID_LGunShootAir, 0x95\n.set ASID_LGunShootEmpty, 0x96\n.set ASID_LGunShootAirEmpty, 0x97\n.set ASID_FireFlowerShoot, 0x98\n.set ASID_FireFlowerShootAir, 0x99\n.set ASID_ItemScrew, 0x9A\n.set ASID_ItemScrewAir, 0x9B\n.set ASID_DamageScrew, 0x9C\n.set ASID_DamageScrewAir, 0x9D\n.set ASID_ItemScopeStart, 0x9E\n.set ASID_ItemScopeRapid, 0x9F\n.set ASID_ItemScopeFire, 0xA0\n.set ASID_ItemScopeEnd, 0xA1\n.set ASID_ItemScopeAirStart, 0xA2\n.set ASID_ItemScopeAirRapid, 0xA3\n.set ASID_ItemScopeAirFire, 0xA4\n.set ASID_ItemScopeAirEnd, 0xA5\n.set ASID_ItemScopeStartEmpty, 0xA6\n.set ASID_ItemScopeRapidEmpty, 0xA7\n.set ASID_ItemScopeFireEmpty, 0xA8\n.set ASID_ItemScopeEndEmpty, 0xA9\n.set ASID_ItemScopeAirStartEmpty, 0xAA\n.set ASID_ItemScopeAirRapidEmpty, 0xAB\n.set ASID_ItemScopeAirFireEmpty, 0xAC\n.set ASID_ItemScopeAirEndEmpty, 0xAD\n.set ASID_LiftWait, 0xAE\n.set ASID_LiftWalk1, 0xAF\n.set ASID_LiftWalk2, 0xB0\n.set ASID_LiftTurn, 0xB1\n.set ASID_GuardOn, 0xB2\n.set ASID_Guard, 0xB3\n.set ASID_GuardOff, 0xB4\n.set ASID_GuardSetOff, 0xB5\n.set ASID_GuardReflect, 0xB6\n.set ASID_DownBoundU, 0xB7\n.set ASID_DownWaitU, 0xB8\n.set ASID_DownDamageU, 0xB9\n.set ASID_DownStandU, 0xBA\n.set ASID_DownAttackU, 0xBB\n.set ASID_DownFowardU, 0xBC\n.set ASID_DownBackU, 0xBD\n.set ASID_DownSpotU, 0xBE\n.set ASID_DownBoundD, 0xBF\n.set ASID_DownWaitD, 0xC0\n.set ASID_DownDamageD, 0xC1\n.set ASID_DownStandD, 0xC2\n.set ASID_DownAttackD, 0xC3\n.set ASID_DownFowardD, 0xC4\n.set ASID_DownBackD, 0xC5\n.set ASID_DownSpotD, 0xC6\n.set ASID_Passive, 0xC7\n.set ASID_PassiveStandF, 0xC8\n.set ASID_PassiveStandB, 0xC9\n.set ASID_PassiveWall, 0xCA\n.set ASID_PassiveWallJump, 0xCB\n.set ASID_PassiveCeil, 0xCC\n.set ASID_ShieldBreakFly, 0xCD\n.set ASID_ShieldBreakFall, 0xCE\n.set ASID_ShieldBreakDownU, 0xCF\n.set ASID_ShieldBreakDownD, 0xD0\n.set ASID_ShieldBreakStandU, 0xD1\n.set ASID_ShieldBreakStandD, 0xD2\n.set ASID_FuraFura, 0xD3\n.set ASID_Catch, 0xD4\n.set ASID_CatchPull, 0xD5\n.set ASID_CatchDash, 0xD6\n.set ASID_CatchDashPull, 0xD7\n.set ASID_CatchWait, 0xD8\n.set ASID_CatchAttack, 0xD9\n.set ASID_CatchCut, 0xDA\n.set ASID_ThrowF, 0xDB\n.set ASID_ThrowB, 0xDC\n.set ASID_ThrowHi, 0xDD\n.set ASID_ThrowLw, 0xDE\n.set ASID_CapturePulledHi, 0xDF\n.set ASID_CaptureWaitHi, 0xE0\n.set ASID_CaptureDamageHi, 0xE1\n.set ASID_CapturePulledLw, 0xE2\n.set ASID_CaptureWaitLw, 0xE3\n.set ASID_CaptureDamageLw, 0xE4\n.set ASID_CaptureCut, 0xE5\n.set ASID_CaptureJump, 0xE6\n.set ASID_CaptureNeck, 0xE7\n.set ASID_CaptureFoot, 0xE8\n.set ASID_EscapeF, 0xE9\n.set ASID_EscapeB, 0xEA\n.set ASID_Escape, 0xEB\n.set ASID_EscapeAir, 0xEC\n.set ASID_ReboundStop, 0xED\n.set ASID_Rebound, 0xEE\n.set ASID_ThrownF, 0xEF\n.set ASID_ThrownB, 0xF0\n.set ASID_ThrownHi, 0xF1\n.set ASID_ThrownLw, 0xF2\n.set ASID_ThrownLwWomen, 0xF3\n.set ASID_Pass, 0xF4\n.set ASID_Ottotto, 0xF5\n.set ASID_OttottoWait, 0xF6\n.set ASID_FlyReflectWall, 0xF7\n.set ASID_FlyReflectCeil, 0xF8\n.set ASID_StopWall, 0xF9\n.set ASID_StopCeil, 0xFA\n.set ASID_MissFoot, 0xFB\n.set ASID_CliffCatch, 0xFC\n.set ASID_CliffWait, 0xFD\n.set ASID_CliffClimbSlow, 0xFE\n.set ASID_CliffClimbQuick, 0xFF\n.set ASID_CliffAttackSlow, 0x100\n.set ASID_CliffAttackQuick, 0x101\n.set ASID_CliffEscapeSlow, 0x102\n.set ASID_CliffEscapeQuick, 0x103\n.set ASID_CliffJumpSlow1, 0x104\n.set ASID_CliffJumpSlow2, 0x105\n.set ASID_CliffJumpQuick1, 0x106\n.set ASID_CliffJumpQuick2, 0x107\n.set ASID_AppealR, 0x108\n.set ASID_AppealL, 0x109\n.set ASID_ShoulderedWait, 0x10A\n.set ASID_ShoulderedWalkSlow, 0x10B\n.set ASID_ShoulderedWalkMiddle, 0x10C\n.set ASID_ShoulderedWalkFast, 0x10D\n.set ASID_ShoulderedTurn, 0x10E\n.set ASID_ThrownFF, 0x10F\n.set ASID_ThrownFB, 0x110\n.set ASID_ThrownFHi, 0x111\n.set ASID_ThrownFLw, 0x112\n.set ASID_CaptureCaptain, 0x113\n.set ASID_CaptureYoshi, 0x114\n.set ASID_YoshiEgg, 0x115\n.set ASID_CaptureKoopa, 0x116\n.set ASID_CaptureDamageKoopa, 0x117\n.set ASID_CaptureWaitKoopa, 0x118\n.set ASID_ThrownKoopaF, 0x119\n.set ASID_ThrownKoopaB, 0x11A\n.set ASID_CaptureKoopaAir, 0x11B\n.set ASID_CaptureDamageKoopaAir, 0x11C\n.set ASID_CaptureWaitKoopaAir, 0x11D\n.set ASID_ThrownKoopaAirF, 0x11E\n.set ASID_ThrownKoopaAirB, 0x11F\n.set ASID_CaptureKirby, 0x120\n.set ASID_CaptureWaitKirby, 0x121\n.set ASID_ThrownKirbyStar, 0x122\n.set ASID_ThrownCopyStar, 0x123\n.set ASID_ThrownKirby, 0x124\n.set ASID_BarrelWait, 0x125\n.set ASID_Bury, 0x126\n.set ASID_BuryWait, 0x127\n.set ASID_BuryJump, 0x128\n.set ASID_DamageSong, 0x129\n.set ASID_DamageSongWait, 0x12A\n.set ASID_DamageSongRv, 0x12B\n.set ASID_DamageBind, 0x12C\n.set ASID_CaptureMewtwo, 0x12D\n.set ASID_CaptureMewtwoAir, 0x12E\n.set ASID_ThrownMewtwo, 0x12F\n.set ASID_ThrownMewtwoAir, 0x130\n.set ASID_WarpStarJump, 0x131\n.set ASID_WarpStarFall, 0x132\n.set ASID_HammerWait, 0x133\n.set ASID_HammerWalk, 0x134\n.set ASID_HammerTurn, 0x135\n.set ASID_HammerKneeBend, 0x136\n.set ASID_HammerFall, 0x137\n.set ASID_HammerJump, 0x138\n.set ASID_HammerLanding, 0x139\n.set ASID_KinokoGiantStart, 0x13A\n.set ASID_KinokoGiantStartAir, 0x13B\n.set ASID_KinokoGiantEnd, 0x13C\n.set ASID_KinokoGiantEndAir, 0x13D\n.set ASID_KinokoSmallStart, 0x13E\n.set ASID_KinokoSmallStartAir, 0x13F\n.set ASID_KinokoSmallEnd, 0x140\n.set ASID_KinokoSmallEndAir, 0x141\n.set ASID_Entry, 0x142\n.set ASID_EntryStart, 0x143\n.set ASID_EntryEnd, 0x144\n.set ASID_DamageIce, 0x145\n.set ASID_DamageIceJump, 0x146\n.set ASID_CaptureMasterhand, 0x147\n.set ASID_CapturedamageMasterhand, 0x148\n.set ASID_CapturewaitMasterhand, 0x149\n.set ASID_ThrownMasterhand, 0x14A\n.set ASID_CaptureKirbyYoshi, 0x14B\n.set ASID_KirbyYoshiEgg, 0x14C\n.set ASID_CaptureLeadead, 0x14D\n.set ASID_CaptureLikelike, 0x14E\n.set ASID_DownReflect, 0x14F\n.set ASID_CaptureCrazyhand, 0x150\n.set ASID_CapturedamageCrazyhand, 0x151\n.set ASID_CapturewaitCrazyhand, 0x152\n.set ASID_ThrownCrazyhand, 0x153\n.set ASID_BarrelCannonWait, 0x154\n\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n/*\n.macro branchl reg, address\n.long \\address ^ 0x80<<24 | 0xC8<<24\n.endm\n*/\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n .macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro backupall\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r3,0x8(r1)\n.endm\n\n.macro restoreall\nlmw  r3,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n"
  },
  {
    "path": "ASM/m-ex/Custom Playerdata Variables/Adjust Size.asm",
    "content": "#To be inserted @ 800679bc\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\nli\tr4, FighterDataTotalSize\n"
  },
  {
    "path": "ASM/m-ex/Custom Playerdata Variables/Initialize Extended Playerblock Values (Result Screen).asm",
    "content": "#To be inserted at 800BE830\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n#Backup Data Pointer After Creation\naddi\tr30, r3, 0\n\n#Get Player Data Length\n  load\tr4,0x80458fd0\n  lwz\tr4,0x20(r4)\n#Zero Entire Data Block\n  branchl\tr12,0x8000c160\n\n\nexit:\nmr\tr3,r30\nlis\tr4, 0x8046\n"
  },
  {
    "path": "ASM/m-ex/Custom Playerdata Variables/Initialize Extended Playerblock Values.asm",
    "content": "#To be inserted at 80068eec\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n#Backup Data Pointer After Creation\n  addi\tr30, r3, 0\n\n#Get Player Data Length\n  load\tr4,0x80458fd0\n  lwz\tr4,0x20(r4)\n#Zero Entire Data Block\n  branchl\tr12,0x8000c160\n\nexit:\n  mr\tr3,r30\n  lis\tr4, 0x8046\n"
  },
  {
    "path": "ASM/m-ex/Custom Playerdata Variables/OwnsAnim/Check Animation Owner.s",
    "content": "#To be inserted @ 8006fe20\n.include \"../../../Globals.s\"\n.include \"../../Header.s\"\n\n.set  REG_PlayerData,3\n\n#Check if anim is coming from opponent\n  lwz r0,MEX_AnimOwner(REG_PlayerData)\n  cmpwi r0,0\n"
  },
  {
    "path": "ASM/m-ex/Custom Playerdata Variables/OwnsAnim/Store Animation Owner.s",
    "content": "#To be inserted @ 80069ce0\n.include \"../../../Globals.s\"\n.include \"../../Header.s\"\n\n.set  REG_OpponentGObj,23\n.set  REG_PlayerData,26\n\n#Check if anim is coming from opponent\n  cmpwi REG_OpponentGObj,0\n  beq OwnsAnim\n\nNoOwnsAnim:\n  li  r3,1\n  stw r3,MEX_AnimOwner(REG_PlayerData)\n  b Exit\nOwnsAnim:\n  li  r3,0\n  stw r3,MEX_AnimOwner(REG_PlayerData)\n\nExit:\n  cmplwi\tr23, 0\n"
  },
  {
    "path": "ASM/m-ex/Header.s",
    "content": "#Constants\n.set  PersonalEffectStart,5000  # used for stage effects, need to rework this?\n.set  EffMdlStart,5000\n.set  PtclGenStart,6000\n.set  CpEffMdlStart,7000\n.set  CpPtclGenStart,8000\n.set  MEXEffectEnd,9000\n\n.set  CustomItemStart,237\n.set  RandomIconID,30\n.set  HUD_Stride,3   #im changing this from 3 because 2 seems to work with hsdraw\n.set  OFST_mexMapData,--0x4A08\n.set  OFST_mexSelectChr,-0x4A0C\n\n#Derived Constants\n.set  SSM_MaxID,100 * 10000\n\n#Custom Functions\n.set Audio_RequestSSMLoad,0x803d705C\n.set  GetGrFunction,0x803d7068\n.set itFunctionInit,0x803d7070\n.set Reloc,0x803d7074\n.set  SFX_PlayStageSFX,0x803d7078\n.set  GetStockFrame,0x803d7060\n.set  MenuThink,0x803d7090\n\n#Custom Static Variables\n.set  PersistHeapNum, 5 + 2\n\n#mexSelectChr Offsets\n.set  OFST_mexSelectChr,-0x472C\n.set  OFST_mexSelectChr_IconJoint,-0x4728 #originally SceneLoad_Adventure mode static pointers (8031dea0)\n.set  OFST_stc_icons,-0x4724            # TODO: THIS WILL BREAK STUFF, FIND A BETTER SPOT\n.set  OFST_eblm_matanimjoint,-0x4720    # TODO: THIS WILL BREAK STUFF, FIND A BETTER SPOT \n.set  OFST_mexMenu,-0x4720 \n.set  SlChr_IconModel,0x0\n.set  SlChr_IconAnimJoint,0x4\n.set  SlChr_IconMatAnim,0x8\n.set  SlChr_CSPMatAnim,0xC\n.set  SlChr_CSPStride,0x10\n\n#mexMenu Offsets\n.set  mexMenu_MenuNameFrames,0x0\n.set  mexMenu_MenuDef,0x4\n  .set  MenuDefStride,0x14\n  .set  MenuDef_PreviewFrames, 0x0\n  .set  MenuDef_Unused, 0x4\n  .set  MenuDef_OptDef, 0x8\n    .set  OptDefStride,8\n    .set  OptDef_Kind, 0x0      # byte\n    .set  OptDef_ID, 0x1        # byte\n    .set  OptDef_Text,0x2       # byte\n    .set  OptDef_NameFrame,0x3  # byte\n    .set  OptDef_PreviewFrame,0x4  # byte\n  .set  MenuDef_OptNum, 0xC # byte\n  .set  MenuDef_PrevMenu, 0xD # byte\n  .set  MenuDef_NameFrame, 0xE  # byte\n  .set  MenuDef_HueIndex, 0xF  # byte\n  .set  MenuDef_Callback, 0x10\n.set  mexMenu_DescSis,0x8\n  .set  OptDef_TextSisID, 1\n.set  mexMenu_MnOptMatAnimJoint,0xC\n.set  mexMenu_MnNameMatAnimJoint,0x10\n\n#Stc_icon Offsets\n.set  StcIcons_ReservedFrames,0x0\n.set  StcIcons_Stride,0x2\n.set  StcIcons_MatAnimJoint,0x4\n.set  StcIcons_EggNum,0x8\n.set  StcIcons_Eggs,0xC\n\n#Eggs\n.set Eggs_Stride, 0x8\n.set Eggs_StockID,0x0\n.set Eggs_Input,0x1\n.set Eggs_Name,0x4\n\n#BGM in IfAll\n.set BGMBG_Joint,0x0\n.set BMGBG_AnimJoint,0x4\n\n#effBehaviorTable\n.set effBhv_ptclGenNum,0x8\n.set effBhv_ptclGenBhv,0xC\n  .set effMdlBhv_Stride,0x1\n.set effBhv_effMdlNum,0x0\n.set effBhv_effMdlBhv,0x4\n  .set effMdlBhv_Stride,0x1\n\n#Scene Data\n.set  MajorStride,0x18\n.set  MinorTypeStride,0x14\n\n#Archive Offsets\n.set  Arch_Metadata,0x0\n  .set  Arch_Metadata_VersionMajor,0x0\n  .set  Arch_Metadata_VersionMinor,0x1\n  .set  Arch_Metadata_FtIntNum,0x4\n  .set  Arch_Metadata_FtExtNum,0x8\n  .set  Arch_Metadata_CSSIconCount,0xC\n  .set  Arch_Metadata_GrIntNum,0x10\n  .set  Arch_Metadata_GrExtNum,0x14\n  .set  Arch_Metadata_SSSIconCount,0x18\n  .set  Arch_Metadata_SSMCount,0x1C\n  .set  Arch_Metadata_BGMCount,0x20\n  .set  Arch_Metadata_EffectCount,0x24\n  .set  Arch_Metadata_BootScene,0x28\n  .set  Arch_Metadata_TermMajor,0x2C\n  .set  Arch_Metadata_TermMinor,0x30\n.set  Arch_Menu,0x4\n  .set  Arch_Menu_MenuParam,0x0\n    .set  MenuParam_HandScale,0x0\n  .set  Arch_Menu_CSS,0x4\n  .set  Arch_Menu_SSS,0x8\n    .set  SSS_Stride,0x20\n.set  Arch_Fighter,0x8\n  .set  Arch_Fighter_NameText,0x0\n  .set  Arch_Fighter_CharFiles,0x4\n  .set  Arch_Fighter_InsigniaIDs,0x8\n  .set  Arch_Fighter_DefineIDs,0xC\n  .set  Arch_Fighter_CostumeIDs,0x10\n  .set  Arch_Fighter_CostumeFileSymbols,0x14\n  .set  Arch_Fighter_FtDemo_SymbolNames,0x18\n  .set  Arch_Fighter_AnimFiles,0x1C\n  .set  Arch_Fighter_AnimCounts,0x20\n  .set  Arch_Fighter_EffectFileIDs,0x24\n  .set  Arch_Fighter_GmRst_AnimFiles,0x28\n  .set  Arch_Fighter_GmRst_Scale,0x2C\n  .set  Arch_Fighter_GmRst_VictoryTheme,0x30\n  .set  Arch_Fighter_AnnouncerCall,0x34\n  .set  Arch_Fighter_SSMFileIDs,0x38\n  .set  Arch_Fighter_RuntimeCostumePointers,0x3C\n  .set  Arch_Fighter_ftDataPointers,0x40\n    .set  ftDataPointers_Stride,8\n  .set  Arch_Fighter_onWallJump,0x44\n  .set  Arch_Fighter_GmRstPointers,0x48\n    .set  GmRstPointers_Stride,8\n  .set  Arch_Fighter_MEXItemLookup,0x4C\n    .set  MEXItemLookup_Stride,8\n  .set  Arch_Fighter_TargetStage, 0x50\n  .set  Arch_Fighter_BGM, 0x54\n    .set BGM_Stride, 0x4\n  .set  Arch_Fighter_ViWaitFileNames, 0x58\n  .set  Arch_Fighter_EndClassic, 0x5C\n  .set  Arch_Fighter_EndAdventure, 0x60\n  .set  Arch_Fighter_EndAllStar, 0x64\n  .set  Arch_Fighter_EndMovie, 0x68\n  .set  Arch_Fighter_RaceTimes, 0x6C\n    .set RaceTimes_Stride,0x4\n.set  Arch_FighterFunc,0xC\n  .set  Arch_FighterFunc_onLoad,0x0\n  .set  Arch_FighterFunc_onDeath,0x4\n  .set  Arch_FighterFunc_onUnknown,0x8\n  .set  Arch_FighterFunc_MoveLogic,0xC\n  .set  Arch_FighterFunc_SpecialN,0x10\n  .set  Arch_FighterFunc_SpecialNAir,0x14\n  .set  Arch_FighterFunc_SpecialS,0x18\n  .set  Arch_FighterFunc_SpecialSAir,0x1C\n  .set  Arch_FighterFunc_SpecialHi,0x20\n  .set  Arch_FighterFunc_SpecialHiAir,0x24\n  .set  Arch_FighterFunc_SpecialLw,0x28\n  .set  Arch_FighterFunc_SpecialLwAir,0x2C\n  .set  Arch_FighterFunc_onAbsorb,0x30\n  .set  Arch_FighterFunc_OnItemPickup,0x34\n  .set  Arch_FighterFunc_onMakeItemInvisible,0x38\n  .set  Arch_FighterFunc_onMakeItemVisible,0x3C\n  .set  Arch_FighterFunc_OnItemRelease,0x40\n  .set  Arch_FighterFunc_OnItemPickup2,0x44\n  .set  Arch_FighterFunc_onUnknownItemRelated,0x48\n  .set  Arch_FighterFunc_onUnknownCharacterModelFlags1,0x4C\n  .set  Arch_FighterFunc_onUnknownCharacterModelFlags2,0x50\n  .set  Arch_FighterFunc_onKnockbackEnter,0x54\n  .set  Arch_FighterFunc_onKnockbackExit,0x58\n  .set  Arch_FighterFunc_onFrame,0x5C\n  .set  Arch_FighterFunc_onActionStateChange,0x60\n  .set  Arch_FighterFunc_onReapplyAttr,0x64\n  .set  Arch_FighterFunc_onModelRender,0x68\n  .set  Arch_FighterFunc_onShadowRender,0x6C\n  .set  Arch_FighterFunc_onUnknownMultijump,0x70\n  .set  Arch_FighterFunc_onActionStateChangeWhileEyeTextureIsChanged,0x74\n  .set  Arch_FighterFunc_onTwoEntryTable,0x78\n  .set  Arch_FighterFunc_onFloat,0x7C\n  .set  Arch_FighterFunc_onDoubleJump,0x80\n  .set  Arch_FighterFunc_onZair,0x84\n  .set  Arch_FighterFunc_onLanding,0x88\n  .set  Arch_FighterFunc_onFSmash,0x8C\n  .set  Arch_FighterFunc_onUSmash,0x90\n  .set  Arch_FighterFunc_onDSmash,0x94\n  .set  Arch_FighterFunc_onGetExtResultAnim,0x98\n  .set  Arch_FighterFunc_onIndexExtResultAnim,0x9C\n  .set  Arch_FighterFunc_MoveLogicDemo,0xA0\n.set  Arch_FGM,0x10\n  .set  Arch_FGM_Files,0x0\n  .set  Arch_FGM_Flags,0x4\n  .set  Arch_FGM_LookupTable,0x8\n  .set  Arch_FGM_RuntimeStruct,0xC\n    .set  Arch_SSMRuntimeStruct_Header,0x0\n    .set  Arch_SSMRuntimeStruct_ToLoadOrig,0x4\n    .set  Arch_SSMRuntimeStruct_ToLoadCopy,0x8\n    .set  Arch_SSMRuntimeStruct_IsLoadedOrig,0xC\n    .set  Arch_SSMRuntimeStruct_IsLoadedCopy,0x10\n    .set  Arch_SSMRuntimeStruct_Footer,0x14\n.set  Arch_BGM,0x14\n  .set  Arch_BGM_Files,0x0\n  .set  Arch_BGM_MenuPlaylist,0x4\n  .set  Arch_BGM_MenuPlaylistNum,0x8\n  .set  Arch_BGM_Labels,0xC\n.set  Arch_Effect,0x18\n  .set  Effect_Files,0x0\n  .set  Effect_RuntimeUnk1,0x4\n  .set  Effect_RuntimeUnk3,0x8\n  .set  Effect_RuntimeTexGrNum,0xC\n  .set  Effect_RuntimeTexGrData,0x10\n  .set  Effect_RuntimeUnk4,0x14\n  .set  Effect_RuntimePtclLast,0x18\n  .set  Effect_RuntimePtclData,0x1C\n  .set  Effect_effBehaviorTable,0x20    #indexed by fighter ID, points to their effBehaviorTable symbol\n.set  Arch_ItemsAdded,0x1C\n  .set  Arch_ItemsAdded_Common,0x0\n  .set  Arch_ItemsAdded_Fighter,0x4\n  .set  Arch_ItemsAdded_Pokemon,0x8\n  .set  Arch_ItemsAdded_Stages,0xC\n  .set  Arch_ItemsAdded_Custom,0x10\n  #.set  Arch_ItemsAdded_Unk,0x14\n  .set  Arch_ItemsAdded_RuntimeIndex,0x14\n.set  Arch_Kirby,0x20\n  .set  Arch_Kirby_AbilityFileNames,0x0\n  .set  Arch_Kirby_AbilityRuntimeStruct,0x4\n  .set  Arch_Kirby_AbilityCostumeFileNames,0x8\n  .set  Arch_Kirby_AbilityCostumeRuntimeStruct,0xC\n  .set  Arch_Kirby_EffectIDs,0x10\n  .set  Arch_Kirby_FtCmdRuntime,0x14\n.set  Arch_KirbyFunction,0x24\n  .set  Arch_KirbyFunction_OnAbilityGain,0x0\n  .set  Arch_KirbyFunction_OnAbilityLose,0x4\n  .set  Arch_Kirby_SpecialN,0x8\n  .set  Arch_Kirby_SpecialNAir,0xC\n  .set  Arch_Kirby_OnHit,0x10\n  .set  Arch_Kirby_InitItem,0x14\n  .set  Arch_Kirby_MoveLogicRuntime,0x18\n.set  Arch_Map,0x28\n  .set  Arch_Map_StageIDs,0x0\n  .set  Arch_Map_Audio,0x4\n  .set  Arch_Map_LineTypeData,0x8\n  .set  Arch_Map_StageItemLookup,0xC\n    .set  StageItemLookup_Stride,0x8\n  .set  Arch_Map_StageEffectLookup,0x10\n  .set  Arch_Map_Playlists,0x14\n    .set  Playlists_Stride,0x8\n.set  Arch_grFunction,0x2C\n.set  Arch_Scene,0x30\n  .set  Scene_Major,0x0\n  .set  Scene_Minor,0x4\n\n#Offsets\n.set  OFST_MnSlChrIconData,0x0\n.set  OFST_MnSlChrNames,0x4\n.set  OFST_MnSlChrDefineIDs,0x8\n.set  OFST_MnSlChrCostumeFileSymbols,0xC\n.set  OFST_MnSlChrCharFileNames,0x10\n.set  OFST_MnSlChrAnimFileNames,0x14\n.set  OFST_MnSlChrEffectFileIDs,0x18\n.set  OFST_MnSlChrEffectFilesSymbols,0x1C\n.set  OFST_MnSlChrSSMFileIDs,0x20\n.set  OFST_MnSlChrSSMFileNames,0x24\n.set  OFST_MnSlChrAnimCount,0x28\n.set  OFST_FighterMoveLogic,0x2C\n.set  OFST_FighterOnLoad,0x30\n.set  OFST_FighterOnDeath,0x34\n.set  OFST_FighterSpecialLw,0x38\n.set  OFST_FighterSpecialLwAir,0x3C\n.set  OFST_FighterSpecialS,0x40\n.set  OFST_FighterSpecialSAir,0x44\n.set  OFST_FighterSpecialN,0x48\n.set  OFST_FighterSpecialNAir,0x4C\n.set  OFST_FighterSpecialHi,0x50\n.set  OFST_FighterSpecialHiAir,0x54\n.set  OFST_MnSlChrCostumeIDs,0x58\n.set  OFST_Char_CostumeRuntimePointers,0x5C\n.set  OFST_SSMStruct,0x60\n.set  OFST_SSMIDDef,0x64\n.set  OFST_SSMBankSizes,0x68\n.set  OFST_GmRstAnimFileNames,0x6C\n.set  OFST_GmRstInsigniaIDs,0x70\n.set  OFST_GmRstScale,0x74\n.set  OFST_FtDemoSymbols,0x78\n.set  OFST_SFXNameDef,0x7C\n.set  OFST_GmRstVictoryTheme,0x80\n.set  OFST_effBehaviorTable,0x84\n.set  OFST_ItemsAdded,0x88\n.set  OFST_ItemIndex,0x8C #unused\n.set  OFST_AudioGroups,0x90\n.set  OFST_BGMFileNames,0x94\n.set  OFST_ftDataPointers,0x98\n.set  OFST_onFloat,0x9C\n.set  OFST_onDoubleJump,0xA0\n.set  OFST_onZair,0xA4\n.set  OFST_onLanding,0xA8\n.set  OFST_onWallJump,0xAC\n.set  OFST_GmRstPointers,0xB0\n.set  OFST_onFSmash,0xB4\n.set  OFST_onUSmash,0xB8\n.set  OFST_onDSmash,0xBC\n.set  OFST_FighterOnItemPickup,0xC0\n.set  OFST_FighterOnItemPickup2,0xC4\n.set  OFST_FighterOnItemRelease,0xC8\n.set  OFST_FighterBGM, OFST_FighterOnItemRelease + 0x4\n.set  OFST_FighterViWaitFileNames, OFST_FighterBGM + 0x4\n.set  OFST_MajorScenes, OFST_FighterViWaitFileNames + 0x4\n.set  OFST_MinorScenes, OFST_MajorScenes + 0x4\n.set  OFST_PtclRuntime1, OFST_MinorScenes + 0x4\n.set  OFST_PtclRuntime3, OFST_PtclRuntime1 + 0x4\n.set  OFST_PtclRuntimeTexGrNum, OFST_PtclRuntime3 + 0x4\n.set  OFST_PtclRuntimeTexGrData, OFST_PtclRuntimeTexGrNum + 0x4\n.set  OFST_PtclRuntime4, OFST_PtclRuntimeTexGrData + 0x4\n.set  OFST_PtclRuntimePtclLast, OFST_PtclRuntime4 + 0x4\n.set  OFST_PtclRuntimePtclData, OFST_PtclRuntimePtclLast + 0x4\n#Chr\n.set  OFST_Menu_Param,OFST_PtclRuntimePtclData+0x4\n#Map\n.set  OFST_Menu_SSS,OFST_Menu_Param+0x4\n.set  OFST_Map_StageIDs,OFST_Menu_SSS+0x4\n.set  OFST_Map_Audio,OFST_Map_StageIDs+0x4\n.set  OFST_grFunction,OFST_Map_Audio+0x4\n.set  OFST_LineTypeData,OFST_grFunction+0x4\n#Kirby\n.set  OFST_KirbyHatFileNames,OFST_LineTypeData+0x4\n.set  OFST_KirbyHatCostumeFileNames,OFST_KirbyHatFileNames+0x4\n.set  OFST_KirbyHatEffectFileIDs,OFST_KirbyHatCostumeFileNames+0x4\n.set  OFST_KirbyAbilityCostumeRuntimeStruct,OFST_KirbyHatEffectFileIDs+0x4\n.set  OFST_KirbyAbilityRuntimeStruct,OFST_KirbyAbilityCostumeRuntimeStruct+0x4\n.set  OFST_KirbyFtCmdRuntime, OFST_KirbyAbilityRuntimeStruct + 0x4\n.set  OFST_KirbyOnAbilityGain,OFST_KirbyFtCmdRuntime+0x4\n.set  OFST_KirbyOnAbilityLose,OFST_KirbyOnAbilityGain+0x4\n.set  OFST_KirbySpecialN,OFST_KirbyOnAbilityLose+0x4\n.set  OFST_KirbySpecialNAir,OFST_KirbySpecialN+0x4\n.set  OFST_KirbyOnHit,OFST_KirbySpecialNAir+0x4\n.set  OFST_KirbyInitItem,OFST_KirbyOnHit+0x4\n.set  OFST_KirbyMoveLogicRuntime, OFST_KirbyInitItem + 0x4\n#Metadata\n.set  OFST_Metadata_FtIntNum,OFST_KirbyMoveLogicRuntime+0x4\n.set  OFST_Metadata_FtExtNum,OFST_Metadata_FtIntNum+0x4\n.set  OFST_Metadata_CSSIconCount,OFST_Metadata_FtExtNum+0x4\n.set  OFST_Metadata_SSSIconCount,OFST_Metadata_CSSIconCount+0x4\n.set  OFST_Metadata_SSMCount,OFST_Metadata_SSSIconCount+0x4\n.set  OFST_Metadata_BGMCount,OFST_Metadata_SSMCount+0x4\n.set  OFST_Metadata_EffectCount,OFST_Metadata_BGMCount+0x4\n.set  OFST_MetaData_TermMajor,OFST_Metadata_EffectCount + 0x4\n.set  OFST_MetaData_TermMinor,OFST_MetaData_TermMajor + 0x4\n.set  OFST_MetaData_GrIntNum,OFST_MetaData_TermMinor+0x4\n.set  OFST_MetaData_GrExtNum,OFST_MetaData_GrIntNum+0x4\n.set  OFST_Metadata,OFST_MetaData_GrExtNum+0x4\n.set  OFST_mexData,OFST_Metadata+0x4\n\n#Gross bullshit I don't want here\n.set  OFST_EasterEgg,OFST_mexData + 0x4\n.set  OFST_HeapRuntime,OFST_EasterEgg + 0x8\n\n\n# Fighter Data Sizes\n.set  FighterDataOrigSize, 0x23ec\n.set  MEX_FighterDataSize, 0xC       # mex needs additional 0x4 bytes\n.set  TM_FighterDataSize, 0x34       # TM needs additional 0x34 bytes\n.set  FighterDataTotalSize, FighterDataOrigSize + MEX_FighterDataSize + TM_FighterDataSize\n\n# Fighter Data Start\n.set FighterDataStart, 0x0\n.set MEX_FighterDataStart, FighterDataStart + FighterDataOrigSize\n.set TM_FighterDataStart, MEX_FighterDataStart + MEX_FighterDataSize\n\n# Fighter Data Vairables\n\n#MEX\n.set  MEX_AnimOwner,MEX_FighterDataStart + 0x0  #4 bytes\n.set  MEX_UCFCurrX, MEX_AnimOwner + 0x4   #1 byte\n.set  MEX_UCFPrevX, MEX_UCFCurrX + 0x1   #1 byte\n.set  MEX_UCF2fX, MEX_UCFPrevX + 0x1   #1 byte\n.set  MEX_align, MEX_UCF2fX + 0x1   #1 byte\n\n#TM\n## Dedicated ##\n.set TM_FramesinCurrentAS, TM_FighterDataStart + 0x0    #half\n.set TM_ShieldFrames, TM_FramesinCurrentAS + 0x2    #half\n.set TM_PrevASSlots, 6\n.set TM_PrevASStart, TM_ShieldFrames + 0x2       #halves\n  .set CurrentAS,0x10\n  .set TM_OneASAgo,TM_PrevASStart+0x0\n  .set TM_TwoASAgo,TM_OneASAgo+0x2\n  .set TM_ThreeASAgo,TM_TwoASAgo+0x2\n  .set TM_FourASAgo,TM_ThreeASAgo+0x2\n  .set TM_FiveASAgo,TM_FourASAgo+0x2\n  .set TM_SixASAgo,TM_FiveASAgo+0x2\n.set TM_FramesInPrevASStart,TM_SixASAgo + 0x2    #halves\n  .set TM_FramesinOneASAgo,TM_FramesInPrevASStart+0x0\n  .set TM_FramesinTwoASAgo,TM_FramesinOneASAgo+0x2\n  .set TM_FramesinThreeASAgo,TM_FramesinTwoASAgo+0x2\n  .set TM_FramesinFourASAgo,TM_FramesinThreeASAgo+0x2\n  .set TM_FramesinFiveASAgo,TM_FramesinFourASAgo+0x2\n  .set TM_FramesinSixASAgo,TM_FramesinFiveASAgo+0x2\n.set TM_PreviousMoveInstanceHitBy,TM_FramesinSixASAgo + 0x2  #half\n.set TM_TangibleFrameCount, TM_PreviousMoveInstanceHitBy + 0x2        #half\n.set TM_CanFastfallFrameCount, TM_TangibleFrameCount + 0x2        #half\n.set TM_align, TM_CanFastfallFrameCount + 0x2        #half\n.set TM_PostHitstunFrameCount, TM_align + 0x2     #word\n.set TM_PlayerWhoShieldedAttack, TM_PostHitstunFrameCount + 0x4   #word\n.set  TM_AnimCallback, TM_PlayerWhoShieldedAttack + 0x4\n## Volatile ##\n.set  TM_VolatileStart, TM_AnimCallback + 0x4\n#Airdodge\n  .set TM_AirdodgeAngle,TM_VolatileStart + 0x0\n#Damage\n  .set TM_SuccessfulSDIInputs,TM_VolatileStart + 0x0\n  .set TM_TotalSDIInputs,TM_SuccessfulSDIInputs + 0x2\n\n/*\n#SSM Struct Offsets\n#Header\n.set  SSM_Header_OFST,0x0\n  .set  SSM_Header_Length,45*4\n#Disposable Orig\n.set  SSM_ToLoadOrig_OFST, SSM_Header_OFST + SSM_Header_Length\n  .set  SSM_ToLoadOrig_Length, (56 + NumOfAddedChars) * 4\n#Disposable Copy\n.set  SSM_ToLoadCopy_OFST, SSM_ToLoadOrig_OFST + SSM_ToLoadOrig_Length\n  .set  SSM_ToLoadCopy_Length, (56 + NumOfAddedChars) * 4\n#Persist Orig\n.set  SSM_IsLoadedOrig_OFST, SSM_ToLoadCopy_OFST + SSM_ToLoadCopy_Length\n  .set  SSM_IsLoadedOrig_Length, (56 + NumOfAddedChars) * 4\n#Persist Copy\n.set  SSM_IsLoadedCopy_OFST, SSM_IsLoadedOrig_OFST + SSM_IsLoadedOrig_Length\n  .set  SSM_IsLoadedCopy_Length, (56 + NumOfAddedChars) * 4\n#Unk\n.set  SSM_Footer_OFST, SSM_IsLoadedCopy_OFST + SSM_IsLoadedCopy_Length\n  .set  SSM_Footer_Length, (56 + NumOfAddedChars) * 4\n*/\n"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/Audio_RequestFileLoad_Rewrite.asm",
    "content": "#To be inserted @ 803d705c\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set  REG_SSMID,3\n.set  REG_ToLoadOrig,12\n\n#Check if null ssm ID\n  cmpwi  REG_SSMID,55\n  beq Exit\n\n#Get Disposable Orig\n  lwz REG_ToLoadOrig,OFST_SSMStruct(rtoc)\n  lwz REG_ToLoadOrig,Arch_SSMRuntimeStruct_ToLoadOrig(REG_ToLoadOrig)\n#Queue up ssm load\n  li  r4,1\n  mulli REG_SSMID,REG_SSMID,4\n  stwx  r4,REG_SSMID,REG_ToLoadOrig\n\nExit:\n  blr\n"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/Get MxDt Data.asm",
    "content": "#To be inserted @ 803d7094\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\nbackup\n\n# check if over\n  cmpwi  r3,8\n  bge Assert\n\n# get jump table\n  bl  SkipJumpTable\n#*****************************#\nbl  FtIntNum\nbl  FtExtNum\nbl  FtIconNum\nbl  MnSlChrIcon\nbl  GrIntNum\nbl  GrExtNum\nbl  GrIconNum\nbl  MnSlMpIcon\n#*****************************#\nSkipJumpTable:\n#Get effect type\n  mflr\tr4\t\t#Jump Table Start in r4\n#Get Event Code Pointer\n  mulli\tr5,r3,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n  add\tr4,r4,r5\t\t#Gets ASCII Address in r4\n  mtctr\tr4\n  bctr\n\n\nFtIntNum:\n  lwz r3,OFST_Metadata_FtIntNum(rtoc)\n  b Exit\nFtExtNum:\n  lwz r3,OFST_Metadata_FtExtNum(rtoc)\n  b Exit\nFtIconNum:\n  lwz r3,OFST_Metadata_CSSIconCount(rtoc)\n  b Exit\nMnSlChrIcon:\n  lwz r3,OFST_MnSlChrIconData(rtoc)\n  b Exit\nGrIntNum:\n  lwz r3,OFST_MetaData_GrIntNum(rtoc)\n  b Exit\nGrExtNum:\n  lwz r3,OFST_MetaData_GrExtNum(rtoc)\n  b Exit\nGrIconNum:\n  lwz r3,OFST_Metadata_SSSIconCount(rtoc)\n  b Exit\nMnSlMpIcon:\n  lwz r3,OFST_Menu_SSS(rtoc)\n  b Exit\n\n#############################################\nAssert:\n#OSReport\n  mr r4,r3\n  bl  ErrorString\n  mflr  r3\n  branchl r12,0x803456a8\n#Assert\n  bl  Assert_Name\n  mflr  r3\n  li  r4,0\n  load  r5,0x804d3940\n  branchl r12,0x80388220\nAssert_Name:\nblrl\n.string \"m-ex\"\n.align 2\nErrorString:\nblrl\n.string \"error: MEX_GetData() does not have data for id %d\\n\"\n.align 2\n###############################################\n\n\nExit:\n  restore\n  blr"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/Get grFunction.asm",
    "content": "#To be inserted @ 803d7068\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set  REG_Temp,12\n.set  REG_Dest,3\n\nload  REG_Temp,0x8049e6c8\nlwz REG_Temp,0x88(REG_Temp)\nmulli REG_Temp,REG_Temp,4\nlwz REG_Dest,OFST_grFunction(rtoc)\nlwzx  REG_Dest,REG_Dest,REG_Temp\nlwz REG_Dest,0x4(REG_Dest)\nblr\n"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/GetFtItemID.asm",
    "content": "#To be inserted @ 803d7088\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set  REG_FighterID,31\n.set  REG_ArticleID,30\n.set  REG_ID,29\n.set  REG_MEXItemLookup,28\n\nbackup\n\n#Backup args\n  mr  REG_FighterID,r3\n  mr  REG_ArticleID,r4\n\n# Get table\n  lwz r3,OFST_mexData(rtoc)\n  lwz r3,Arch_Fighter(r3)\n  lwz r3,Arch_Fighter_MEXItemLookup(r3)\n  mulli r4,REG_FighterID,MEXItemLookup_Stride\n  add REG_MEXItemLookup,r3,r4\n#Check if exists\n  lwz r3,0x0(REG_MEXItemLookup)\n  cmpw  REG_ArticleID,r3\n  bge DoesNotExist\n#Get external item ID from internal\n  lwz r3,0x4(REG_MEXItemLookup)\n  mulli r4,REG_ArticleID,2\n  lhzx r3,r3,r4\n  b Exit\n\n#############################################\nDoesNotExist:\n#OSReport\n  bl  ErrorString\n  mflr  r3\n  mr r4,REG_FighterID\n  mr  r5,REG_ArticleID\n  branchl r12,0x803456a8\n#Assert\n  bl  Assert_Name\n  mflr  r3\n  li  r4,0\n  load  r5,0x804d3940\n  branchl r12,0x80388220\nAssert_Name:\nblrl\n.string \"m-ex\"\n.align 2\nErrorString:\nblrl\n.string \"error: fighter %d does not have item %d\\n\"\n.align 2\n###############################################\n\nExit:\n  restore\n  blr\n"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/GetGrItemID.asm",
    "content": "#To be inserted @ 803d708C\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set  REG_FighterID,31\n.set  REG_ArticleID,30\n.set  REG_ID,29\n.set  REG_MEXItemLookup,28\n\nbackup\n\n#Backup args\n  mr  REG_ArticleID,r3\n\n# Get stage ID\n  load  r3,0x8049e6c8\n  lwz REG_ID,0x88(r3)\n#Get table from mxdt\n  lwz r3,OFST_mexData(rtoc)\n  lwz r3,Arch_Map(r3)\n  lwz r3,Arch_Map_StageItemLookup(r3)\n  mulli r4,REG_ID,MEXItemLookup_Stride\n  add REG_MEXItemLookup,r3,r4\n#Check if exists\n  lwz r3,0x0(REG_MEXItemLookup)\n  cmpw  REG_ArticleID,r3\n  bge DoesNotExist\n#Get external item ID from internal\n  lwz r3,0x4(REG_MEXItemLookup)\n  mulli r4,REG_ArticleID,2\n  lhzx r3,r3,r4\n  b Exit\n\n#############################################\nDoesNotExist:\n#OSReport\n  bl  ErrorString\n  mflr  r3\n  mr r4,REG_ID\n  mr  r5,REG_ArticleID\n  branchl r12,0x803456a8\n#Assert\n  bl  Assert_Name\n  mflr  r3\n  li  r4,0\n  load  r5,0x804d3940\n  branchl r12,0x80388220\nAssert_Name:\nblrl\n.string \"m-ex\"\n.align 2\nErrorString:\nblrl\n.string \"error: stage %d does not have item %d\\n\"\n.align 2\n###############################################\n\nExit:\n  restore\n  blr\n"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/GetKirbyCpData.asm",
    "content": "#To be inserted @ 803d7084\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\nmulli r3,r3,0x4\nlwz  r4,OFST_KirbyAbilityRuntimeStruct(rtoc)\nlwzx  r3,r3,r4\nblr"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/GetMEXItemID.asm",
    "content": "#To be inserted @ 803d7064\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set  REG_GObj,31\n.set  REG_ArticleID,30\n.set  REG_ID,29\n.set  REG_MEXItemLookup,28\n\nbackup\n\n#Backup args\n  mr  REG_GObj,r3\n  mr  REG_ArticleID,r4\n\n#Check if player or stage\n  lhz r3,0x0(REG_GObj)\n  cmpwi r3,4\n  beq isPlayer\n  cmpwi r3,3\n  beq isStage\n  b Unsupported\n\nisPlayer:\n#Get internal ID\n  lwz r3,0x2C(REG_GObj)\n  lwz REG_ID,0x4(r3)\n#Get table from mxdt\n  lwz r3,OFST_mexData(rtoc)\n  lwz r3,Arch_Fighter(r3)\n  lwz r3,Arch_Fighter_MEXItemLookup(r3)\n  b Continue\n\nisStage:\n  load  r3,0x8049e6c8\n  lwz REG_ID,0x88(r3)\n#Get table from mxdt\n  lwz r3,OFST_mexData(rtoc)\n  lwz r3,Arch_Map(r3)\n  lwz r3,Arch_Map_StageItemLookup(r3)\n  b Continue\n\nContinue:\n  mulli r4,REG_ID,MEXItemLookup_Stride\n  add REG_MEXItemLookup,r3,r4\n#Check if exists\n  lwz r3,0x0(REG_MEXItemLookup)\n  cmpw  REG_ArticleID,r3\n  bgt DoesNotExist\n#Get external item ID from internal\n  lwz r3,0x4(REG_MEXItemLookup)\n  mulli r4,REG_ArticleID,2\n  lhzx r3,r3,r4\n  b Exit\n\n#############################################\nDoesNotExist:\n#OSReport\n  bl  ErrorString\n  mflr  r3\n  mr r4,REG_ID\n  mr  r5,REG_ArticleID\n  branchl r12,0x803456a8\n#Assert\n  bl  Assert_Name\n  mflr  r3\n  li  r4,0\n  load  r5,0x804d3940\n  branchl r12,0x80388220\nAssert_Name:\nblrl\n.string \"m-ex\"\n.align 2\nErrorString:\nblrl\n.string \"error: fighter %d does not have article ID %d\\n\"\n.align 2\n###############################################\n\nUnsupported:\n  li  r3,-1\n\nExit:\n  restore\n  blr\n"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/GetMEXPlaylist.asm",
    "content": "#To be inserted @ 803d707C\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set REG_StageExtID,11\n.set REG_Playlist,10\n\n  backup\n\n#Check if this stage has a playlist\n  load r3,0x8049e6c8\n  lwz   r3,0x88(r3)\n  lwz r4,OFST_mexData(rtoc)\n  lwz r4,Arch_Map(r4)\n  lwz r4,Arch_Map_Playlists(r4)\n  mulli r3,r3,Playlists_Stride\n  add REG_Playlist,r3,r4\n\n#Start of playlist\n  lwz r3,0x4(REG_Playlist)\n  restore\n  blr"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/Index Fighter Item.asm",
    "content": "#To be inserted @ 803d7058\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set  REG_FighterID,31\n.set  REG_ArticleData,30\n.set  REG_ArticleID,29\n.set  REG_MEXItemLookup,27\n\nbackup\n\n#Backup args\n  mr  REG_FighterID,r3\n  mr  REG_ArticleData,r4\n  mr  REG_ArticleID,r5\n\n#Get table from mxdt\n  lwz r3,OFST_mexData(rtoc)\n  lwz r3,Arch_Fighter(r3)\n  lwz r3,Arch_Fighter_MEXItemLookup(r3)\n  mulli r4,REG_FighterID,MEXItemLookup_Stride\n  add REG_MEXItemLookup,r3,r4\n#Check if MxDt has an entry for this item\n  lwz r3,0x0(REG_MEXItemLookup)\n  cmpw  REG_ArticleID,r3\n  bge DoesNotExist\n\nIndex:\n#Get external item ID from internal\n  lwz r3,0x4(REG_MEXItemLookup)\n  mulli r4,REG_ArticleID,2\n  lhzx r3,r3,r4\n#Get runtime index\n  lwz r4,OFST_ItemsAdded(rtoc)\n  lwz r4,Arch_ItemsAdded_RuntimeIndex(r4)\n#Correctly index item\n  subi  r3,r3,CustomItemStart\n#Store article data\n  mulli r3,r3,4\n  stwx  REG_ArticleData,r3,r4\n  b Exit\n\n#############################################\nDoesNotExist:\n#OSReport\n  bl  ErrorString_NoItem\n  mflr  r3\n  mr  r4,REG_ArticleID\n  mr  r5,REG_FighterID\n  branchl r12,0x803456a8\n#Assert\n  bl  Assert_Name\n  mflr  r3\n  li  r4,0\n  load  r5,0x804d3940\n  branchl r12,0x80388220\nAssert_Name:\nblrl\n.string \"m-ex\"\n.align 2\nErrorString_NoItem:\nblrl\n.string \"error: MxDt does not contain item %d for fighter %d\\n\"\n.align 2\n###############################################\n\nExit:\n  restore\n  blr\n"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/Init itFunction.asm",
    "content": "#To be inserted @ 803d7070\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n/*\nr3 = file header\nr4 = index\nr5 = fighter/stage\n*/\n\n.set  REG_Index,31\n.set  REG_Type,30\n.set  REG_itFunction,29\n\n#ftX struct\n  .set  ftX_Code,0x0\n  .set  ftX_InstructionRelocTable,0x4\n  .set  ftX_InstructionRelocTableCount,0x8\n  .set  ftX_FunctionRelocTable,0xC\n    .set  FunctionRelocTable_ReplaceThis,0x0\n    .set  FunctionRelocTable_ReplaceWith,0x4\n  .set  ftX_FunctionRelocTableCount,0x10\n\nbackup\nmr  REG_Index,r4\nmr  REG_Type,r5\n\n#Get symbol offset from file\n  bl  itFunctionString\n  mflr  r4\n  branchl r12,0x80380358\n  mr.  REG_itFunction,r3\n  beq itFunction_NoItem\n\n#Loop through all items\n.set  REG_ItemCount,20\n.set  REG_LoopCount,21\n  lwz REG_ItemCount,0x0(REG_itFunction)\n  li  REG_LoopCount,0\n  cmpwi REG_ItemCount,0\n  beq itFunction_NoItem\nitFunction_Init:\n#Get this item\n.set  REG_ThisItem,22\n  addi r3,REG_itFunction,0x4\n  mulli r4,REG_LoopCount,4\n  lwzx  REG_ThisItem,r3,r4\n#Ensure it exists\n  cmpwi REG_ThisItem,0\n  beq itFunction_InitLoop\n#Reloc\n  lwz r3,ftX_InstructionRelocTableCount(REG_ThisItem)  #count\n  lwz r4,ftX_Code(REG_ThisItem)  #code\n  lwz r5,ftX_InstructionRelocTable(REG_ThisItem)  #reloc table\n  branchl r12,Reloc\n#Copy function pointers - init\n.set  REG_ThisOffset,12\n.set  REG_FuncPtrs,11\n.set  REG_Code,10\n.set  REG_ItemTable,9\n.set  REG_Count,8\n#Get external item ID from internal\n  mr  r3,REG_Index\n  mr  r4,REG_Type\n  mr  r5,REG_LoopCount\n  bl  Item_GetItemTableFromInternal\n  mr  REG_ItemTable,r3\n#Init\n  lwz REG_FuncPtrs,ftX_FunctionRelocTable(REG_ThisItem)\n  lwz REG_Code,0x0(REG_ThisItem)\n  li  REG_Count,0\n  b itFunction_Overload_CheckLoop\nitFunction_Overload_Loop:\n  mulli r4,REG_Count,8\n  add  r5,r4,REG_FuncPtrs\n#Convert to code offset\n  lwz r3,0x4(r5)\n  add r3,r3,REG_Code\n#get offset\n  lwz r4,0x0(r5)\n  mulli r4,r4,4\n#Store to item table\n  stwx  r3,r4,REG_ItemTable\nitFunction_Overload_IncLoop:\n  addi  REG_Count,REG_Count,1\nitFunction_Overload_CheckLoop:\n  lwz r3,ftX_FunctionRelocTableCount(REG_ThisItem)\n  cmpw REG_Count,r3\n  blt itFunction_Overload_Loop\n\nitFunction_InitLoop:\n  addi  REG_LoopCount,REG_LoopCount,1\n  cmpw  REG_LoopCount,REG_ItemCount\n  blt itFunction_Init\n  li  r3,1\n  b Exit\n\nitFunction_NoItem:\n  li  r3,0\n  b Exit\n\nitFunctionString:\nblrl\n.string \"itFunction\"\n.align 2\n\n\nItem_GetItemTableFromInternal:\n.set  REG_ArticleID,12\n.set  REG_Index,11\n.set  REG_Type,10\n#Init\n  mr  REG_Index,r3\n  mr  REG_Type,r4\n  mr  REG_ArticleID,r5\n#Get external item ID from internal\n  cmpwi REG_Type,1\n  beq Item_GetItemTableFromInternal_Stage\nItem_GetItemTableFromInternal_Fighter:\n  lwz r3,OFST_mexData(rtoc)\n  lwz r3,Arch_Fighter(r3)\n  lwz r3,Arch_Fighter_MEXItemLookup(r3)\n  b Item_GetItemTableFromInternal_GetID\nItem_GetItemTableFromInternal_Stage:\n  lwz r3,OFST_mexData(rtoc)\n  lwz r3,Arch_Map(r3)\n  lwz r3,Arch_Map_StageItemLookup(r3)\n  b Item_GetItemTableFromInternal_GetID\nItem_GetItemTableFromInternal_GetID:\n  mulli r4,REG_Index,MEXItemLookup_Stride\n  add r3,r3,r4\n  lwz r3,0x4(r3)\n#Ensure item table exists\n  cmpwi r3,0\n  beq DoesNotExist\n#Get item ID\n  mulli r4,REG_ArticleID,2\n  lhzx r3,r3,r4\n#Get item's table\n  lwz r4,OFST_ItemsAdded(rtoc)\n  cmpwi r3,43\n  blt CommonItems\n  cmpwi r3,161\n  blt FighterItems\n  cmpwi r3,208\n  blt PokemonItems\n  cmpwi r3,CustomItemStart\n  blt StageItems\n  b CustomItems\nCommonItems:\n  lwz r4,Arch_ItemsAdded_Common(r4)\n  b GetTable\nFighterItems:\n  subi  r3,r3,43\n  lwz r4,Arch_ItemsAdded_Fighter(r4)\n  b GetTable\nPokemonItems:\n  subi  r3,r3,161\n  lwz r4,Arch_ItemsAdded_Pokemon(r4)\n  b GetTable\nStageItems:\n  subi  r3,r3,208\n  lwz r4,Arch_ItemsAdded_Stages(r4)\n  b GetTable\nCustomItems:\n  subi  r3,r3,CustomItemStart\n  lwz r4,Arch_ItemsAdded_Custom(r4)\n  b GetTable\n\nGetTable:\n  mulli r3,r3,0x3C\n  add  r3,r3,r4\n  blr\n###########################################\n\nDoesNotExist:\n\n#Get Object Kind string\n  cmpwi REG_Type, 1\n  beq DoesNotExist_Stage\nDoesNotExist_Fighter:\n  bl  ErrorString_Fighter\n  mflr r4\n  b DoesNotExist_OSReport\nDoesNotExist_Stage:\n  bl  ErrorString_Stage\n  mflr r4\n  b DoesNotExist_OSReport\nDoesNotExist_OSReport:\n  bl  ErrorString\n  mflr  r3\n  mr  r5,REG_Index\n  branchl r12,0x803456a8\n#Assert\n  bl  Assert_Name\n  mflr  r3\n  li  r4,0\n  load  r5,0x804d3940\n  branchl r12,0x80388220\nAssert_Name:\nblrl\n.string \"m-ex\"\n.align 2\nErrorString:\nblrl\n.string \"error: MxDt does not contain any items for %s %d\\n\"\n.align 2\nErrorString_Fighter:\nblrl\n.string \"fighter\"\n.align 2\nErrorString_Stage:\nblrl\n.string \"stage\"\n.align 2\n###############################################\n\nExit:\n  restore\n  blr\n"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/KirbyStateChange.asm",
    "content": "#To be inserted @ 803d7080\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n# void KirbyStateChange(GOBJ *fighter, int state, float startFrame, float animSpeed, float animBlend)\n\n.set  REG_GObj,31\n.set  REG_State,30\n.set  REG_FighterData,29\n.set  REG_StateMoveLogic,28\n.set  REG_FtCmd,27\n.set  REG_AbilityID,26\n.set  REG_Frame,31\n.set  REG_Speed,30\n.set  REG_Blend,29\n\n# Init\n  backup\n  stfs  REG_Speed,0x80(sp)\n  stfs  REG_Blend,0x84(sp)\n  stfs  REG_State,0x88(sp)\n  mr  REG_GObj,r3\n  mr  REG_State,r4\n  fmr  REG_Frame,f1\n  fmr  REG_Speed,f2\n  fmr  REG_Blend,f3\n  lwz REG_FighterData,0x2C(REG_GObj)\n\n# Check if Kirby\n  lwz r3,0x4(REG_FighterData)\n  cmpwi r3,4\n  bne NotKirby\n\n# Get current ability ID\n  lwz REG_AbilityID,0x2238(REG_FighterData)  \n\n# Get this states move logic\n  lwz r3,OFST_KirbyMoveLogicRuntime(rtoc)\n  mulli r4,REG_AbilityID,0x4\n  lwzx  r3,r3,r4    # get this abilities move logic pointer\n  cmpwi r3,0\n  beq NoMoveLogic\n  mulli r4,REG_State,0x20   # get this states move logic\n  add REG_StateMoveLogic,r3,r4\n\n# Get this states ftcmd\n  lwz r3,OFST_KirbyFtCmdRuntime(rtoc)\n  mulli r4,REG_AbilityID,0x4\n  lwzx  r3,r3,r4    # get this abilities ftcmd pointer\n  cmpwi r3,0\n  beq NoFtCmd\n  lwz r4,0x0(REG_StateMoveLogic)  # get this states animation\n  mulli r4,r4,0x18   # get this states ftcmd\n  add REG_FtCmd,r3,r4\n\n# Enter Dummy State\n  mr  r3,REG_GObj \n  li  r4,0XEF        # dummy state id\n  lis  r5,0x2000  # no anim update\n  li  r6,0        # no source gobj\n  fmr f1,REG_Frame\n  fmr f2,REG_Speed\n  fmr f3,REG_Blend\n  branchl r12,ActionStateChange\n\n# Spoof anim ID as not -1 (so the animation is updated each frame)\n  li  r3,0\n  stw r3,0x14(REG_FighterData)\n\n# Spoof state as ItemScopeFire\n  li  r3,0xA0\n  stw r3,0x10(REG_FighterData)\n\n# Spoof current anim offset as -1 (will always result in a cache miss for the next anim load)\n  li  r3,-1\n  stw r3,0x5A4(REG_FighterData)\n\n# Store pointer to figatree animation symbol\n  lwz r3,0x4(REG_FtCmd)\n  cmpwi r3,0\n  beq NoAnim\n  stw r3,0x590(REG_FighterData)\n\n/*\n# Load animation data from source  \n  mr  r3, REG_FighterData         # anim dest\n  mr  r4, REG_AbilityGObjData     # anim source\n  lwz r5,0x0(REG_StateMoveLogic)  # anim ID\n  branchl r12,0x80085cd8\n*/\n\n# Store subaction pointer\n  lwz r3,0xC(REG_FtCmd)                    # script data\n  stw r3,0x3EC(REG_FighterData)\n\n# Enter animation \n  lwz r3,0x590(REG_FighterData)\n  mr  r3,REG_GObj\n  fmr f1,REG_Frame\n  fmr f2,REG_Speed\n  fmr f3,REG_Blend\n  branchl r12,0x8006ebe8\n\n# Unk\n  li  r3,0\n  stw r3,0x3E4(REG_FighterData)\n\n# Increment state frame info\n  mr  r3,REG_GObj\n  branchl r12,0x8006e9b4\n\n# Subaction update stuff\n  lfs\tf0, -0x778C (rtoc)\n  fcmpo cr0,f0,REG_Frame\n  bne SubactionSkip\nSubactionStart:\n  mr  r3,REG_GObj\n  branchl r12,0x800c0408  # update colanims\n  mr  r3,REG_GObj\n  branchl r12,0x80073240  # update subaction unk\n  b SubactionEnd\nSubactionSkip:\n  mr  r3,REG_GObj\n  branchl r12,0x80073354\nSubactionEnd:\n\n# Copy callbacks from source\n  lwz r3,0xC(REG_StateMoveLogic)  # unk callback\n  stw r3,0x21A0(REG_FighterData)\n  lwz r3,0x10(REG_StateMoveLogic) # unk callback\n  stw r3,0x219C(REG_FighterData)\n  lwz r3,0x14(REG_StateMoveLogic) # unk callback\n  stw r3,0x21A4(REG_FighterData)\n  lwz r3,0x18(REG_StateMoveLogic) # unk callback\n  stw r3,0x21A8(REG_FighterData)\n  lwz r3,0x1C(REG_StateMoveLogic) # unk callback\n  stw r3,0x21AC(REG_FighterData)\n\n  b Exit\n\n#############################################\nNoMoveLogic:\n#OSReport\n  bl  NoMoveLogicString\n  mflr  r3\n  lwz r4,OFST_KirbyHatFileNames(rtoc)\n  mulli r5,REG_AbilityID,8\n  lwzx  r4,r4,r5\n  branchl r12,0x803456a8\n  b Assert\nNoMoveLogicString:\nblrl\n.string \"error: kbfunction in %s missing move_logic table\\n\"\n.align 2\n###############################################\n\nNoFtCmd:\n#OSReport\n  bl  NoFtCmdString\n  mflr  r3\n  lwz r4,OFST_KirbyHatFileNames(rtoc)\n  mulli r5,REG_AbilityID,8\n  lwzx  r4,r4,r5\n  branchl r12,0x803456a8\n  b Assert\nNoFtCmdString:\nblrl\n.string \"error: %s missing ftcmd symbol\\n\"\n.align 2\n\n###############################################\n\nNoAnim:\n#OSReport\n  bl  NoAnimString\n  mflr  r3\n  lwz r4,OFST_KirbyHatFileNames(rtoc)\n  mulli r5,REG_AbilityID,8\n  lwzx  r4,r4,r5\n  mr  r5,REG_State\n  branchl r12,0x803456a8\n  b Assert\nNoAnimString:\nblrl\n.string \"error: ftcmd in %s missing animation for state %d\\n\"\n.align 2\n\n###############################################\n\nNotKirby:\n#OSReport\n  bl  NotKirbyString\n  mflr  r3\n  lwz r4,0x4(REG_FighterData)\n  branchl r12,0x803456a8\n  b Assert\nNotKirbyString:\nblrl\n.string \"error: fighter %d is not kirby\\n\"\n.align 2\n###############################################\n\nAssert:\n  bl  Assert_Name\n  mflr  r3\n  li  r4,0\n  load  r5,0x804d3940\n  branchl r12,0x80388220\nAssert_Name:\nblrl\n.string \"m-ex\"\n.align 2\n###############################################\n\nError:\n  b 0x0\n\nExit:\n  lfs  REG_Speed,0x80(sp)\n  lfs  REG_Blend,0x84(sp)\n  lfs  REG_State,0x88(sp)\n  restore\n  blr\n"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/LoadRELDAT.asm",
    "content": "#To be inserted @ 803d7080\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n# args are\n# r3 = file name\n# r4 = array to store function pointers to\n# r5 = symbol\n\n# returns\n# r3 = file data\n\n.set  REG_FileName,31\n.set  REG_Return,30\n.set  REG_Symbol,29\n.set  REG_FileSize,28\n.set  REG_File,27\n.set  REG_Header,26\n.set  REG_mexData,25\n\nbackup\nmr  REG_FileName,r3\nmr  REG_Return,r4\nmr  REG_Symbol,r5\n\n#Load file\n  mr r3, REG_FileName\n  addi\tr4, sp, 0x80\n  mr r5, REG_Symbol\n  li r6,0\n  branchl\tr12,0x80016c64\n  mr REG_Header,r3\n#Check if exists\n  lwz  REG_mexData,0x80(sp)\n  cmpwi REG_mexData,0\n  beq mexPatch_Skip\n#Reloc\n  lwz r3,ftX_InstructionRelocTableCount(REG_mexData)  #count\n  lwz r4,ftX_Code(REG_mexData)                        #code\n  lwz r5,ftX_InstructionRelocTable(REG_mexData)       #reloc table\n  branchl r12,Reloc\n#Overload\n  mr  r3,REG_mexData\n  mr  r4,REG_Return\n  bl  Overload\nmexPatch_Skip:\n\n#Flush instruction cache so code can be run from this file\n  lwz  r3,0x20(REG_Header)   # file start\n  lwz  r4,0x0(REG_Header)   # file size \n  branchl r12,0x80328f50\n\n  mr r3,REG_Header\n  restore\n  blr\n\n###########################################\n\n#ftX struct\n  .set  ftX_Code,0x0\n  .set  ftX_InstructionRelocTable,0x4\n  .set  ftX_InstructionRelocTableCount,0x8\n  .set  ftX_FunctionRelocTable,0xC\n    .set  FunctionRelocTable_ReplaceThis,0x0\n    .set  FunctionRelocTable_ReplaceWith,0x4\n  .set  ftX_FunctionRelocTableCount,0x10\n\nOverload:\n# r3 = ftX\n# r4 = table\n#Copy function pointers - init\n.set  REG_ftX,12\n.set  REG_ThisElement,11\n.set  REG_Code,10\n.set  REG_OverloadTable,9\n.set  REG_Count,8\n.set  REG_RelocTable,7\n  mr  REG_ftX,r3\n  mr  REG_OverloadTable,r4\n  lwz REG_RelocTable,ftX_FunctionRelocTable(REG_ftX)\n  lwz REG_Code,0x0(REG_ftX)\n  li  REG_Count,0\n  b Overload_CheckLoop\nOverload_Loop:\n#Get this element\n  mulli r3,REG_Count,8\n  add REG_ThisElement,r3,REG_RelocTable\n\nOverload_TableIndex:\n#Get ram offset for this function\n  lwz r3,FunctionRelocTable_ReplaceWith(REG_ThisElement)\n  add r3,r3,REG_Code\n#Update table\n  lwz r4,FunctionRelocTable_ReplaceThis(REG_ThisElement)\n  mulli r4,r4,4\n  stwx  r3,r4,REG_OverloadTable\n  b Overload_IncLoop\n\nOverload_IncLoop:\n  addi  REG_Count,REG_Count,1\nOverload_CheckLoop:\n  lwz r3,ftX_FunctionRelocTableCount(REG_ftX)\n  cmpw  REG_Count,r3\n  blt Overload_Loop\nOverload_Exit:\n  blr\n############################################"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/MenuThink.asm",
    "content": "#To be inserted @ 803d7090\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n# slippi hack\n.set OFST_R13_SWITCH_TO_ONLINE_SUBMENU,-0x49ec # Function used to switch\n\n.set  REG_GObj,31\n.set  REG_MenuData,30\n.set  REG_Inputs,29\n.set  REG_MenuDef,28\n.set  REG_OptDef,27\n.set  REG_ThisOpt,26\n.set  REG_ThisMenu,25\n\n# init\n  backup\n  mr  REG_GObj,r3\n  load  REG_MenuData,0x804a04f0\n# Get menu def\n  lwz r3,OFST_mexMenu(r13)\n  lwz r3,mexMenu_MenuDef(r3)\n  lbz\tr0, 0 (REG_MenuData)\n  mulli\tr0, r0, MenuDefStride\n  add REG_MenuDef,r3,r0\n# Get opt def\n  lwz REG_OptDef,MenuDef_OptDef(REG_MenuDef)\n\n# Decrement lockout\n  lhz r3,-0x4AD8(r13)\n  cmpwi r3,0\n  ble SkipLockoutDec\n  subi  r3,r3,1\n  sth r3,-0x4AD8(r13)\n  b Exit\nSkipLockoutDec:\n\n# Get inputs\n  li  r3,4\n  branchl r12,0x80229624\n  mr  REG_Inputs,r3\n  stw\tREG_Inputs, 0x000C (REG_MenuData)\n  li  r3,0\n  stw\tr3, 0x0008 (REG_MenuData)\n\n# Check for A\n  rlwinm. r0,REG_Inputs,0,0x10\n  beq NoA\n# SFX\n  li\tr3, 1\n  branchl r12,0x80024030\n# Store Input Lockout\n  li  r3,5\n  sth r3,-0x4AD8(r13)\n# Store menu leave animation direction\n  li  r3,1\n  stb\tr3, 0x0011 (REG_MenuData)\n# Get this option\n  lhz\tr3, 0x2 (REG_MenuData)  # current cursor\n  mulli r3,r3,OptDefStride\n  add REG_ThisOpt,r3,REG_OptDef\n# Get option kind\n  lbz r3,OptDef_Kind(REG_ThisOpt)\n  cmpwi r3,0\n  beq Enter_Menu\n  cmpwi r3,1\n  beq Enter_Scene\n  b Exit\n\nEnter_Menu:\n# Get this menu\n  lwz r3,OFST_mexMenu(r13)\n  lwz r3,mexMenu_MenuDef(r3)\n  lbz\tr0, OptDef_ID (REG_ThisOpt)\n  mulli\tr0, r0, MenuDefStride\n  add REG_ThisMenu,r3,r0\n\n# Check if event mode...\n  lbz r3,OptDef_ID(REG_ThisOpt)\n  cmpwi r3,7\n  bne Enter_MenuNoEvent\n# Handle event mode\n  lwz r12,MenuDef_Callback(REG_ThisMenu)\n  cmpwi r12,0\n  beq Enter_MenuNoCB\n  mtctr r12\n  li  r3,0\n  li  r4,1\n  bctrl\n# Delete this menu gobj\n  mr  r3,REG_GObj\n  branchl r12,0x80390228\n  b Exit\nEnter_MenuNoEvent:\n\n# Check if slippi menu...\n  lbz r3,OptDef_ID(REG_ThisOpt)\n  cmpwi r3,8\n  bne Enter_MenuNoSlippi\n# Handle slippi menu init\n  lwz r12,OFST_R13_SWITCH_TO_ONLINE_SUBMENU(r13)\n  mtctr r12\n  bctrl\n  b Exit\nEnter_MenuNoSlippi:\n\n# Check if multiman menu...\n  lbz r3,OptDef_ID(REG_ThisOpt)\n  cmpwi r3,33\n  bne Enter_MenuNoMultiman\n# Handle multiman menu init\n  li r3,0\n  branchl r12,0x8024cd64\n# Delete this menu gobj\n  mr  r3,REG_GObj\n  branchl r12,0x80390228\n  b Exit\nEnter_MenuNoMultiman:\n\nEnter_MenuNoSpecial:\n# check for custom callback\n  lwz r3,MenuDef_Callback(REG_ThisMenu)\n  cmpwi r3,0\n  beq Enter_MenuNoCB\n  mtctr r3\n  bctrl\n# Delete this menu gobj\n  mr  r3,REG_GObj\n  branchl r12,0x80390228\n  b Exit\nEnter_MenuNoCB:\n\n# set prev menu\n  lbz\tr3, 0x0 (REG_MenuData)\n  stb\tr3, 0x1 (REG_MenuData)\n# new curr menu\n  lbz r3,OptDef_ID(REG_ThisOpt)\n  stb\tr3, 0x0 (REG_MenuData)\n\n# determine cursor value for next menu\n  .set  REG_Count,20\n  .set  REG_OptNum,11\n  li  REG_Count,0\n  lwz r3,OFST_mexMenu(r13)\n  lwz r3,mexMenu_MenuDef(r3)\n  lbz\tr0, 0 (REG_MenuData)\n  mulli\tr0, r0, MenuDefStride\n  add r3,r3,r0\n  lbz REG_OptNum,MenuDef_OptNum(r3)\nSearchNextCursor__Loop:\n# check if unlocked\n  lbz\tr3, 0 (REG_MenuData)\n  mr r4,REG_Count  # option ID\n  branchl r12,0x80229938\n  cmpwi r3,0\n  beq SearchNextCursor__IncLoop\n# set cursor\n  sth\tREG_Count, 0x2 (REG_MenuData)  # current cursor\n  b SearchNextCursor__Exit\nSearchNextCursor__IncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpw  REG_Count,REG_OptNum\n  blt SearchNextCursor__Loop\nSearchNextCursor__Exit:\n\n# Switch menu \n  li  r3,1    # forward\n  branchl r12,0x8022b3a0\n# Some proc thing\n  branchl r12,0x80390cd4\n# Delete this menu gobj\n  mr  r3,REG_GObj\n  branchl r12,0x80390228\n# Get next menu\n  lwz r3,OFST_mexMenu(r13)\n  lwz r3,mexMenu_MenuDef(r3)\n  lbz\tr0, 0x0 (REG_MenuData)\n  mulli\tr0, r0, MenuDefStride\n  add REG_MenuDef,r3,r0\n# Create next menu gobj\n  li  r3,0\n  li  r4,1\n  li  r5,128\n  branchl r12,0x803901f0\n# Set this proc\n  load  r4,MenuThink\n  li  r5,0\n  branchl r12,0x8038fd54\n# Adjust this proc?\n  lwz\tr4, -0x3E64 (r13)\n  lbz\tr0, 0x000D (r3)\n  rlwimi\tr0, r4, 4, 26, 27\n  stb\tr0, 0x000D (r3)\n  b Exit\n\nEnter_Scene:\n# Get scene data\n  branchl r12,0x801a4b9c\n# Store scene ID\n  lbz r0,OptDef_ID(REG_ThisOpt)\n  stb r0,0x0(r3)\n# Change minor\n  branchl r12,0x801a4b60\n  b Exit\nNoA:\n\n# Check for B\n  rlwinm. r0,REG_Inputs,0,0x20\n  beq NoB\n# SFX\n  li\tr3, 0\n  branchl r12,0x80024030\n\n# Check for title screen\n  lbz r3,MenuDef_PrevMenu(REG_MenuDef)\n  extsb r3,r3\n  cmpwi r3,-1\n  bne Return_NoTitle\n# Get scene data\n  branchl r12,0x801a4b9c\n# Store scene ID\n  li  r0,0\n  stb r0,0x0(r3)\n# Change minor\n  branchl r12,0x801a4b60\n  b Exit\nReturn_NoTitle:\n\n# Store menu leave animation direction\n  li  r3,0\n  stb\tr3, 0x0011 (REG_MenuData)\n\n# set prev menu\n  lbz\tr3, 0x0 (REG_MenuData)\n  stb\tr3, 0x1 (REG_MenuData)\n# new curr menu\n  lbz r3,MenuDef_PrevMenu(REG_MenuDef)\n  stb\tr3, 0x0 (REG_MenuData)\n\n# determine cursor value for prev menu\n  .set  REG_Count,12\n  .set  REG_OptNum,11\n  .set  REG_OptDef,10\n  .set  REG_PrevMenuID,9\n  li  REG_Count,0\n  lbz REG_PrevMenuID, 0x1 (REG_MenuData)\n# Get menu def for prev menu\n  lwz r3,OFST_mexMenu(r13)\n  lwz r3,mexMenu_MenuDef(r3)\n  lbz\tr0, 0 (REG_MenuData)\n  mulli\tr0, r0, MenuDefStride\n  add r3,r3,r0\n  lbz REG_OptNum,MenuDef_OptNum(r3)\n  lwz REG_OptDef,MenuDef_OptDef(r3)\nSearchPrevCursor_Loop:\n# Get this optdef\n  mulli r0,REG_Count,OptDefStride\n  add r3,REG_OptDef,r0\n# check if menu\n  lbz r0,OptDef_Kind(r3)\n  cmpwi r0,0\n  bne SearchPrevCursor_IncLoop\n# get menu ID\n  lbz r0,OptDef_ID(r3)\n  cmpw r0,REG_PrevMenuID\n  bne SearchPrevCursor_IncLoop\n# set cursor\n  sth\tREG_Count, 0x2 (REG_MenuData)  # current cursor\n  b SearchPrevCursor_Exit\nSearchPrevCursor_IncLoop:\n  addi  REG_Count,REG_Count,1\n  cmpw  REG_Count,REG_OptNum\n  blt SearchPrevCursor_Loop\nSearchPrevCursor_Exit:\n\n# Switch menu \n  li  r3,3    # backward\n  branchl r12,0x8022b3a0\n# Some proc thing\n  branchl r12,0x80390cd4\n# Delete this menu gobj\n  mr  r3,REG_GObj\n  branchl r12,0x80390228\n# Create next menu gobj\n  li  r3,0\n  li  r4,1\n  li  r5,128\n  branchl r12,0x803901f0\n# Set this proc\n  load  r4,MenuThink\n  li  r5,0\n  branchl r12,0x8038fd54\n# Adjust this proc?\n  lwz\tr4, -0x3E64 (r13)\n  lbz\tr0, 0x000D (r3)\n  rlwimi\tr0, r4, 4, 26, 27\n  stb\tr0, 0x000D (r3)\n\n\n\n  b Exit\nNoB:\n\n# Check for Up\n  rlwinm. r0,REG_Inputs,0,0x1\n  beq NoUp\n# SFX\n  li\tr3, 2\n  branchl r12,0x80024030\nCursorUpInitLoop:\n.set  REG_TempCursor, 20\n  lhz\tREG_TempCursor, 0x2 (REG_MenuData)  # current cursor\nCursorUpLoop:\n# Move cursor\n  subi  REG_TempCursor,REG_TempCursor,1\n  extsh r0,REG_TempCursor\n  cmpwi r0,-1\n  bgt CursorUp_NoAdjust\n# Get last option\n  lbz r3,MenuDef_OptNum(REG_MenuDef)\n  subi  REG_TempCursor,r3,1\nCursorUp_NoAdjust:\n# Check if option exists\n  lbz\tr3, 0x0 (REG_MenuData)\n  mr  r4,REG_TempCursor\n  branchl r12,0x80229938\n  cmpwi r3,0\n  beq CursorUpLoop\nCursorUp_Store:\n  sth\tREG_TempCursor, 0x2 (REG_MenuData)  # current cursor\n  b Exit\nNoUp:\n\n# Check for Down\n  rlwinm. r0,REG_Inputs,0,0x2\n  beq NoDown\n# SFX\n  li\tr3, 2\n  branchl r12,0x80024030\nCursorDownInitLoop:\n.set  REG_TempCursor, 20\n  lhz\tREG_TempCursor, 0x2 (REG_MenuData)  # current cursor\nCursorDownLoop:\n# Move cursor\n  addi  REG_TempCursor,REG_TempCursor,1\n  lbz r4,MenuDef_OptNum(REG_MenuDef)\n  cmpw REG_TempCursor,r4\n  blt CursorDown_NoAdjust\n# Get first option\n  li  REG_TempCursor,0  \nCursorDown_NoAdjust:\n# Check if option exists\n  lbz\tr3, 0x0 (REG_MenuData)\n  mr  r4,REG_TempCursor\n  branchl r12,0x80229938\n  cmpwi r3,0\n  beq CursorDownLoop\nCursorDown_Store:\n  sth\tREG_TempCursor, 0x2 (REG_MenuData)  # current cursor\n  b Exit\nNoDown:\n\nExit:\n  restore\n  blr"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/Reloc.asm",
    "content": "#To be inserted @ 803d7074\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n###########################################\n#Intialize pointers\n.set  REG_Count,12\n.set  REG_Code,11\n.set  REG_RelocTable,10\n  mr REG_Count,r3\n  mr REG_Code,r4\n  mr REG_RelocTable,r5\nReloc_Loop:\n.set  REG_CodePointer,9\n.set  REG_FuncPointer,8\n.set  REG_Flag,7\n  lwz r3,0x0(REG_RelocTable)\n  rlwinm  REG_Flag,r3,8,0x000000FF            #get flag\n  rlwinm  r3,r3,0,0x00FFFFFF\n  add REG_CodePointer,r3,REG_Code             #get code offset\n\n#First check if a bl to an dol address\n  lwz r3,0x4(REG_RelocTable)\n  rlwinm  r0,r3,8,0x000000F0\n  cmpwi r0,0x80 \n  beq Reloc_DOLAddr\nReloc_CodeAddr:\n  add REG_FuncPointer,r3,REG_Code             #get func offset\n  b Reloc_CheckType\nReloc_DOLAddr:\n  lwz REG_FuncPointer,0x4(REG_RelocTable)             #get func offset\n\nReloc_CheckType:\n#Check flag type\n  cmpwi REG_Flag,1\n  beq Reloc_StaticAddress\n  cmpwi REG_Flag,4\n  beq Reloc_LoadAddress\n  cmpwi REG_Flag,6\n  beq Reloc_LoadAddress\n  cmpwi REG_Flag,10\n  beq Reloc_Branch\n  cmpwi REG_Flag,26\n  beq Reloc_Relative32Bit\n  b Reloc_IncLoop\nReloc_StaticAddress:\n  #lwz r3,0x0(REG_FuncPointer)\n  stw REG_FuncPointer,0x0(REG_CodePointer)\n  b Reloc_IncLoop\n############################################\nReloc_LoadAddress:\n#Now check if the low bits are signed\n  rlwinm.  r3,REG_FuncPointer,17,0x1\n  beq Reloc_CheckFlag\n#Adjust this address to load a negative offset\n.set  REG_NewHigh,6\n.set  REG_NewLow,5\n#High bits\n  rlwinm  r3,REG_FuncPointer,16,0x0000FFFF\n  addi  r3,r3,1\n  slwi  REG_NewHigh,r3,16\n#Low bits\n  sub r3,REG_FuncPointer,REG_NewHigh\n  rlwinm  REG_NewLow,r3,0,0x0000FFFF\n  or  REG_FuncPointer,REG_NewHigh,REG_NewLow\nReloc_CheckFlag:\n#Check flag type\n  cmpwi REG_Flag,4\n  beq Reloc_Low16\n  cmpwi REG_Flag,6\n  beq Reloc_High16\nReloc_High16:\n  rlwinm  r3,REG_FuncPointer,16,0x0000FFFF\n  b Reloc_Store\nReloc_Low16:\n  rlwinm  r3,REG_FuncPointer,0,0x0000FFFF\n  b Reloc_Store\nReloc_Store:\n  sth r3,0x0(REG_CodePointer)\n  b Reloc_IncLoop\n############################################\nReloc_Branch:\n#Store branch to this code\n  sub r3,REG_FuncPointer,REG_CodePointer                          #Difference relative to branch addr\n  rlwinm  r3,r3,0,6,29                  #extract bits for offset\n  lwz r4,0x0(REG_CodePointer)         #place branch instruction\n  or  r3,r3,r4\n  stw r3,0x0(REG_CodePointer)         #place branch instruction\n  b Reloc_IncLoop\n############################################\nReloc_Relative32Bit:\n#Store offset?\n#Store branch to this code\n  sub r3,REG_FuncPointer,REG_CodePointer                          #Difference relative to branch addr\n  stw r3,0x0(REG_CodePointer)         #place branch instruction\n  b Reloc_IncLoop\n############################################\nReloc_IncLoop:\n  addi  REG_RelocTable,REG_RelocTable,8\n  subi  REG_Count,REG_Count,1\n  cmpwi REG_Count,0\n  bgt Reloc_Loop\n  blr\n##############################################"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/SFX_PlayStageSFX.asm",
    "content": "#To be inserted @ 803d7078\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set  REG_SFXID,31\n\nbackup\n\n#r3 = stage SFX ID\n  mr  REG_SFXID,r3\n\n#Get current stage internal ID\n  load  r3,0x8049e6c8\n  lwz r3,0x88(r3)\n#Get stage's ssm ID\n  lwz r4,OFST_Map_Audio(rtoc)\n  mulli r3,r3,3\n  add r3,r3,r4\n  lbz r3,0x0(r3)\n#Multiply by 10000\n  mulli r3,r3,10000\n#Add SFX ID\n  add r3,r3,REG_SFXID\n#Play SFX\n  branchl r12,0x801c53ec\n\nExit:\n  restore\n  blr\n"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/SpawnMEXEffect.s",
    "content": "#To be inserted @ 803d7060\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set  REG_EffectID,31\n.set  REG_PlayerGObj,30\n.set  REG_Arg1,29\n.set  REG_Arg2,28\n.set  REG_Arg3,27\n.set  REG_Arg4,26\n.set  REG_Arg5,26\n\n.set  REG_PlayerData,21\n.set  REG_MEXEffectLookup,20\n\nbackup\n\n#effect id = 5000 + charEffectID\n  addi  r3,r3,PersonalEffectStart\n  branchl r12,0x8005fddc\n\nExit:\n  restore\n  blr\n"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/SpawnMEXItem.asm",
    "content": "#To be inserted @ 80268648\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set  REG_GObj,31\n.set  REG_ItemSpawnStruct,30\n.set  REG_PlayerData,29\n.set  REG_MEXItemLookup,28\n.set  REG_ArticleID,27\n\nbackup\n\n#Check if article >=5000\n  lwz REG_ArticleID,0x8(REG_ItemSpawnStruct)\n  cmpwi REG_ArticleID,5000\n  blt Exit\n#Index\n  subi  REG_ArticleID,REG_ArticleID,5000\n#Check if player or stage\n  lwz REG_GObj,0x0(REG_ItemSpawnStruct)\n  cmpwi REG_GObj,0\n  beq IsStageItem\n  lhz r3,0x0(REG_GObj)\n  cmpwi r3,4\n  beq IsFighterItem\n  cmpwi r3,3\n  beq IsStageItem\n  b Unsupported\n\nIsFighterItem:\n#Get Fighter MEX Item Lookup\n  lwz r3,OFST_mexData(rtoc)\n  lwz r3,Arch_Fighter(r3)\n  lwz r3,Arch_Fighter_MEXItemLookup(r3)\n#Get index (fighter internal ID)\n  lwz r4,0x2C(REG_GObj)\n  lwz r4,0x4(r4)\n  b GetMEXItemID\nIsStageItem:\n#Get index (stage internal ID)\n  lwz r3,OFST_mexData(rtoc)\n  lwz r3,Arch_Map(r3)\n  lwz r3,Arch_Map_StageItemLookup(r3)\n#No player gobj passed in, assuming this is a stage item\n  load  r4,0x8049e6c8\n  lwz r4,0x88(r4)\nGetMEXItemID:\n#Get table from mxdt\n  mulli r4,r4,MEXItemLookup_Stride\n  add REG_MEXItemLookup,r3,r4\n#Check if exists\n  lwz r3,0x0(REG_MEXItemLookup)\n  cmpw  REG_ArticleID,r3\n  bge DoesNotExist\n\nSpawnItem:\n#Get external item ID from internal\n  lwz r3,0x4(REG_MEXItemLookup)\n  mulli r4,REG_ArticleID,2\n  lhzx r3,r3,r4\n  stw r3,0x8(REG_ItemSpawnStruct)\n  b Exit\n\n#############################################\nDoesNotExist:\n#OSReport\n  bl  ErrorString\n  mflr  r3\n  mr  r4,REG_ArticleID\n  branchl r12,0x803456a8\n#Assert\n  bl  Assert_Name\n  mflr  r3\n  li  r4,0\n  load  r5,0x804d3940\n  branchl r12,0x80388220\nAssert_Name:\nblrl\n.string \"m-ex\"\n.align 2\nErrorString:\nblrl\n.string \"error: MxDt does not have article ID %d\\n\"\n.align 2\n###############################################\nUnsupported:\n\nExit:\n  restore\n  lwz\tr3, 0x000C (r30)\n"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/Stock Icon Get Frame.asm",
    "content": "#To be inserted @ 803d7060\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set  REG_InternalID,31\n.set  REG_CostumeID,30\n.set  REG_StcIcons,29\n.set  REG_InternalIDCount,28\n\n.set  masterHand,6\n.set  crazyHand,5\n.set  wireMale,4\n.set  wireFemale,3\n.set  gigabowser,2\n.set  sandbag,1\n\n\n# init\n  backup\n  mr  REG_InternalID,r3\n  mr  REG_CostumeID,r4\n\n# Check if custom symbol exists\n  lwz REG_StcIcons,OFST_stc_icons(r13)\n  cmpwi REG_StcIcons,0\n  beq Exit\n\n#Check if a special character\n  lwz REG_InternalIDCount,OFST_Metadata_FtIntNum(rtoc)\n  subi  r3,REG_InternalIDCount,masterHand\n  cmpw REG_InternalID,r3\n  blt NormalCharacter\n  subi  r3,REG_InternalIDCount,sandbag\n  cmpw REG_InternalID,r3\n  bgt NormalCharacter\n# get special fighter frame\n  subi  r3,REG_InternalIDCount,masterHand\n  sub r3,REG_InternalID,r3\n  bl  SpecialCharacterFrames\n  mflr  r4\n  lbzx  r3,r3,r4\n  b  CastToFloat\n\n# stock frame = reserved + costume * stride + extID\nNormalCharacter:\n  lhz r3,StcIcons_ReservedFrames(REG_StcIcons)\n  lhz r4,StcIcons_Stride(REG_StcIcons)\n  mullw r4,r4,REG_CostumeID\n  add r3,r3,r4\n  add r3,r3,REG_InternalID\n\n# cast to float\nCastToFloat:\n  xoris r3,r3,0x8000\n  lfd\tf1, -0x35F8 (rtoc)\n  stw r3,0x84(sp)\n  lis r3,0x4330\n  stw r3,0x80(sp)\n  lfd f2,0x80(sp)\n  fsubs f1,f2,f1\n  b Exit\n\nSpecialCharacterFrames:\nblrl\n.byte 3  #master hand\n.byte 2  #crazy hand\n.byte 1  #wire male male\n.byte 1  #wire female\n.byte 5  #giga bowser\n.byte 6  #sandbag\n.align 2\n\nExit:\n  restore\n  blr"
  },
  {
    "path": "ASM/m-ex/Standalone Functions/calloc.asm",
    "content": "#To be inserted @ 803d706C\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set  REG_Size,31\n.set  REG_Alloc,30\n\n#init\n  backup\n  mr  REG_Size,r3\n#alloc\n  branchl r12,HSD_MemAlloc\n  mr  REG_Alloc,r3\n#clear\n  li  r4,0\n  mr  r5,REG_Size\n  branchl r12,0x80003100\n#Exit\n  mr  r3,REG_Alloc\n  restore\n  blr\n"
  },
  {
    "path": "ASM/m-ex/UCF 0.8/Codes.txt",
    "content": "C20CA1E8 0000002B #UCF DB.asm\nD01F002C 7C0802A6\n90010004 9421FF00\nBE810008 48000121\n7FC802A6 C03F0894\nC05E0000 FC011040\n40820118 808DB0F4\nC03F0620 FC200A10\nC044003C FC011040\n41800100 887F0670\n2C030002 408000F4\n887F221F 54600739\n408200E8 3C60804B\n60632FF8 8BA30001\n387DFFFE 889F0618\n4800008D 7C7C1B78\n7FA3EB78 889F0618\n4800007D 7C7C1850\n7C6319D6 2C0315F9\n408100B0 38000001\n901F2358 901F2340\n809F0004 2C04000A\n40A20098 887F000C\n38800001 3D808003\n618C4780 7D8903A6\n4E800421 2C030000\n41820078 8083002C\n80841ECC C03F002C\nD0240018 C05E0004\nFC011040 4181000C\n38600080 48000008\n3860007F 98640006\n48000048 7C852378\n3863FFFF 2C030000\n40800008 38630005\n3C808045 6084BF10\n1C630030 7C841A14\n1C65000C 7C841A14\n88640002 7C630774\n4E800020 4E800021\n40000000 00000000\nBA810008 80010104\n38210100 7C0803A6\n60000000 00000000\nC20998A4 00000026 #UCF SD.asm\n7C0802A6 90010004\n9421FF00 BE810008\n7C7E1B78 83FE002C\n480000DD 7FA802A6\nC03F063C 806DAEB4\nC0030314 FC010040\n408100E4 C03F0620\n48000071 D0210090\nC03F0624 48000065\nC0410090 EC4200B2\nEC210072 EC21102A\nC05D000C FC011040\n418000B4 889F0670\n2C040003 408100A8\nC01D0010 C03F0624\nFC000840 40800098\nBA810008 80010104\n38210100 7C0803A6\n8061001C 83E10014\n38210018 38630008\n7C6803A6 4E800020\nFC000A10 C03D0000\nEC000072 C03D0004\nEC000828 FC00001E\nD8010080 80610084\n38630002 3C004330\nC85D0014 6C638000\n90010080 90610084\nC8210080 EC011028\nC03D0000 EC200824\n4E800020 4E800021\n42A00000 37270000\n43300000 3F800000\nBF4CCCCD 43300000\n80000000 7FC3F378\n7FE4FB78 BA810008\n80010104 38210100\n7C0803A6 00000000\nC22669EC 0000001B #UCF Text.asm\n7C0802A6 90010004\n9421FF00 BE810008\n48000089 7FC802A6\n38600000 38800000\n3DC0803A 61CE6664\n7DC903A6 4E800421\n7C7F1B78 38800001\n989F0049 38800001\n989F004A C03E000C\nD03F0024 D03F0028\n7FE3FB78 48000059\n7C8802A6 C03E0000\nC05E0004 3DC0803A\n61CE6B54 7DC903A6\n4E800421 7C641B78\n7FE3FB78 C03E0008\nC05E0008 3D80803A\n618C74FC 7D8903A6\n4E800421 48000028\n4E800021 42180000\nC3898000 3EE66666\n3DCCCCCD 4E800021\n55434620 302E3734\n00000000 BA810008\n80010104 38210100\n7C0803A6 38980000\n60000000 00000000"
  },
  {
    "path": "ASM/m-ex/UCF 0.8/UCF DB.asm",
    "content": "#To be inserted at 800C9A44\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set REG_PlayerData,31\n.set REG_Floats,30\n.set REG_InputIndex,29\n.set REG_PrevInput,28\n\nNTSC102:\n\t.set\tInjection,0x800C9A44\n\t.set\tOFST_PlCo,-0x514C\n\t.set\tInputIndex,0x804c1f78\n\t.set\tInputArray,0x8046b108\n\t.set\tPlayerBlock_LoadPlayerGObj,0x8003418c\n/*\nNTSC101:\n\t.set\tInjection,0x800C97D0\n\t.set\tOFST_PlCo,-0x514C\n\t.set\tInputIndex,0x804c1258\n\t.set\tInputArray,0x8046a428\n\t.set\tPlayerBlock_LoadPlayerGObj,0x8003418C\nNTSC100:\n\t.set\tInjection,0x800C968C\n\t.set\tOFST_PlCo,-0x514C\n\t.set\tInputIndex,0x804bfdf8\n\t.set\tInputArray,0x80469140\n\t.set\tPlayerBlock_LoadPlayerGObj,0x8003410C\nPAL100:\n\t.set\tInjection,0x800CA1E8\n\t.set\tOFST_PlCo,-0x4F0C\n\t.set\tInputIndex,0x804b2ff8\n\t.set\tInputArray,0x8045bf10\n\t.set\tPlayerBlock_LoadPlayerGObj,0x80034780\n*/\n\n#Original codeline\n\tstfs f0,0x2C(REG_PlayerData)    # Entry point, store new facing direction\n\n#Init\n\tbackup\n\tbl\tFloats\n\tmflr\tREG_Floats\n\nCHECK_IF_SLOW_TURN:\n\tlfs f1,0x894(REG_PlayerData)  \t\t\t\t\t\t\t# Check if 2nd frame of turn\n\tlfs\tf2,OFST_SlowTurnFrame(REG_Floats)\t\t\t\t# 2fp\n\tfcmpo\tcr0,f1,f2\n\tbne Injection_Exit\n\nCHECK_SMASH_TURN_INPUT_CONDITIONS:\n\tlwz r4,OFST_PlCo(r13)\n\tlfs f1,0x0620(REG_PlayerData)\n\tfabs f1,f1\n\tlfs f2,0x3C(r4)\t\t\t\t#PlCo constant 0.8\n\tfcmpo cr0,f1,f2\t\t\t\t# Load control stick x-inputs and compare to 0.8\n\tblt Injection_Exit\n#Check that cardinal direction not held 2+ frames\n\tlbz r3,0x0670(REG_PlayerData)\n\tcmpwi r3,2\n\tbge- Injection_Exit\t\t# Skip if no dash input\n\nSKIP_IF_NANA:\n\tlbz r3,0x221f(REG_PlayerData)    # load flags\n\trlwinm. r0,r3,0,28,28    # (08) = secondary character\n\tbne Injection_Exit\n\nBEGIN_HW_INPUTS:\n\nLOAD_2_FRAMES_PAST_INPUTS:\n\tlbz\tREG_PrevInput, MEX_UCF2fX (REG_PlayerData)\n\textsb\tREG_PrevInput,REG_PrevInput\n\t\nLOAD_CURRENT_FRAME_INPUT:\n\tlbz r3, MEX_UCFCurrX (REG_PlayerData)\n\textsb r3,r3\n\nCALCULATE_DIFFERENCE:\n\tsub\tr3,REG_PrevInput,r3\n\tmullw r3, r3, r3  # Take square to get positive value for comparison\nTHRESHOLD_TEST:\n\tcmpwi r3, 3600   # compare square of input difference between current frame and 2 frames ago to square of 60 (formerly 75 because different units)\n\tble- Injection_Exit\n\nCHANGE_TO_SMASH_TURN:\n\tli r0, 1\n\tstw r0, 0x2358(REG_PlayerData)\n\tstw r0, 0x2340(REG_PlayerData)   # Change smash turn and can dash flags\n#Check if Popo\n\tlwz\tr4,0x4(REG_PlayerData)\t# Load character id\n\tcmpwi\tr4,0xA    \t\t\t\t\t\t# Check if Popo\n\tbne+ Injection_Exit\t\t\t\t\t# Skip if not Popo\n#Get Nana's Block From Popo's in r4\n\tlbz\tr3,0xC(REG_PlayerData)\t\t#P1 Slot\n\tli\tr4,0x1\t\t#Subchar Bool\n\tbranchl\tr12,PlayerBlock_LoadPlayerGObj\n\tcmpwi\tr3,0x0\n\tbeq\tInjection_Exit\n\tlwz\tr4,0x2C(r3)\n#Adjust Nana's inputs\n\tlwz r4,0x1ECC(r4) # Load address where popos inputs were last stored\n\tlfs\tf1,0x2C(REG_PlayerData)    # get popos facing direction\n\tstfs f1,0x18(r4)  \t\t\t\t\t\t# Store popos direction for nana\n#Check which direction popo turned\n\tlfs\tf2,OFST_ZeroFP(REG_Floats)\t\t\t\t#0fp\n\tfcmpo\tcr0,f1,f2\n\tbgt- POPO_TURNED_RIGHT\n\tli r3,0x80      \t\t# leftward 1.0\n\tb StoreNanaDirection\nPOPO_TURNED_RIGHT:\n\tli r3,0x7f\t\t\t\t\t#rightward 1.0\nStoreNanaDirection:\n\tstb r3,0x6(r4) \t\t\t# Store rightward 1.0 input for Nana\n\tb\tInjection_Exit\n\nFloats:\n.set\tOFST_SlowTurnFrame,0x0\n.set\tOFST_ZeroFP,0x4\nblrl\n\t.float 2\n\t.float 0\n\t.align 2\n###################\n\nInjection_Exit:\n\trestore\n"
  },
  {
    "path": "ASM/m-ex/UCF 0.8/UCF SD.asm",
    "content": "#To be inserted at 800998A4\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set  REG_PlayerData,31\n.set  REG_PlayerGObj,30\n.set  REG_Floats,29\n\nNTSC102:\n\t.set\tInjection,0x800998A4\n\t.set\tOFST_PlCo,-0x514C\n/*\nNTSC101:\n\t.set\tInjection,0x800996E0\n\t.set\tOFST_PlCo,-0x514C\nNTSC100:\n\t.set\tInjection,0x800995F8\n\t.set\tOFST_PlCo,-0x514C\nPAL100:\n\t.set\tInjection,0x80099F5C\n\t.set\tOFST_PlCo,-0x4F0C\n*/\nbackup\n\n#Init\n  mr  REG_PlayerGObj,r3\n  lwz REG_PlayerData,0x2C(REG_PlayerGObj)\n  bl  Floats\n  mflr  REG_Floats\n\n#Check if cstick is\n  lfs f1, 0x63C (REG_PlayerData)\n  lwz\tr3, OFST_PlCo (r13)\n  lfs f0, 0x314 (r3)\n  fcmpo cr0, f1, f0\n  ble- EnterSpotdodge\n\n#Check if left stick X is ?\n  lfs f1, 0x620(REG_PlayerData)\n  bl  DoSomething\n  stfs  f1,0x90(sp)\n#Check if left stick Y is ?\n  lfs f1, 0x624(REG_PlayerData)\n  bl  DoSomething\n  lfs  f2,0x90(sp)\n\n#Check if stick was pushed slow enough?\n  fmuls f2, f2, f2\n  fmuls f1, f1, f1\n  fadds f1, f1, f2\n  lfs f2,OFST_1fp(REG_Floats)\n  fcmpo cr0, f1, f2\n  blt EnterSpotdodge\n#Check if stick has been pushed horizontally for over 3 frames\n  lbz r4, 0x670(REG_PlayerData)\n  cmpwi r4, 3\n  ble- EnterSpotdodge\n#Check if stick Y is below -0.8\n  lfs f0,OFST_Unk4(REG_Floats)\n  lfs f1, 0x624(REG_PlayerData)\n  fcmpo cr0, f0, f1\n  bge- EnterSpotdodge\n\n#Exit spotdodge function without entering the state\n# this is very hacky and is how UCF 0.73 functions.\n# the reason this is used is because the spotdodge function is called\n# from 2 different places, so instead of making 2 injections, this is done.\n\trestore\n\tlwz\tr3, 0x001C (sp)\n\tlwz\tr31, 0x0014 (sp)\n\taddi\tsp, sp, 24\n\taddi\tr3,r3,0x8\t\t\t#skip to the end of the function we are coming from\n\tmtlr\tr3\n\tblr\n\n#############################\nDoSomething:\n#f1 = input\n\n  fabs f0, f1\n#Multiply by 80\n  lfs f1,OFST_Unk1(REG_Floats)\n  fmuls f0, f0, f1\n#Subtract 0.0001\n  lfs f1,OFST_Unk2(REG_Floats)\n  fsubs f0, f0, f1\n#Floor value\n  fctiwz  f0,f0\n  stfd  f0,0x80(sp)\n  lwz r3,0x84(sp)\n#Add 2\n  addi  r3,r3,2\n#Cast back\n  lis\tr0, 0x4330\n  lfd\tf2, OFST_MagicNumber (REG_Floats)\n  xoris\tr3, r3,0x8000\n  stw\tr0,0x80(sp)\n  stw\tr3,0x84(sp)\n  lfd\tf1,0x80(sp)\n  fsubs\tf0,f1,f2\t\t#Convert To Float\n#Divide by 80\n  lfs f1,OFST_Unk1(REG_Floats)\n  fdivs f1, f0, f1\n#Exit\n  blr\n#############################\n\nFloats:\nblrl\n.set  OFST_Unk1,0x0\n.set  OFST_Unk2,0x4\n.set  OFST_Unk3,0x8\n.set  OFST_1fp,0xC\n.set  OFST_Unk4,0x10\n.set  OFST_MagicNumber,0x14\n.float 80\n.long 0x37270000\n.float 176\n.float 1\n.float -0.8\n.long 0x43300000\n.long 0x80000000\n\nEnterSpotdodge:\n  mr\tr3, REG_PlayerGObj\n\tmr\tr4,\tREG_PlayerData\n  restore\n"
  },
  {
    "path": "ASM/m-ex/UCF 0.8/UCF Store Inputs CPU.asm",
    "content": "#To be inserted at 8006adf4\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n# Original Line\n\tstfs\tf1, 0x0624 (r31)\n\n# Update array of previous inputs\n\tlbz\tr3, MEX_UCFPrevX(r31)\n\tstb\tr3, MEX_UCF2fX(r31)\n\tlbz\tr3, MEX_UCFCurrX(r31)\n\tstb\tr3, MEX_UCFPrevX(r31)\n\n# Store current\n\tlbz\tr3, 0x1A8C (r31)\n\tstb\tr3, MEX_UCFCurrX(r31)"
  },
  {
    "path": "ASM/m-ex/UCF 0.8/UCF Store Inputs.asm",
    "content": "#To be inserted at 8006ae8c\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n# Original Line\n\tstfs\tf0, 0x0624 (r31)\n\n# Update array of previous inputs\n\tlbz\tr4, MEX_UCFPrevX(r31)\n\tstb\tr4, MEX_UCF2fX(r31)\n\tlbz\tr4, MEX_UCFCurrX(r31)\n\tstb\tr4, MEX_UCFPrevX(r31)\n\n# Store current\n\tlbz\tr4,0x18(r3)\n\tstb\tr4, MEX_UCFCurrX(r31)"
  },
  {
    "path": "ASM/m-ex/UCF 0.8/UCF Text.asm",
    "content": "#To be inserted @ 802662D0\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n.set REG_TextGObj,31\n.set REG_TextProperties,30\n\n\nNTSC102:\n\t.set\tInjection,0x802662D0\n\t.set\tText_CreateTextGObj,0x803a6754\n\t.set\tText_InitializeSubtext,0x803a6b98\n\t.set\tText_UpdateSubtextSize,0x803a7548\n/*\nNTSC101:\n\t.set\tInjection,0x80265B34\n\t.set\tText_CreateTextGObj,0x803A5A74\n\t.set\tText_InitializeSubtext,0x803A5EB8\n\t.set\tText_UpdateSubtextSize,0x803A6868\nNTSC100:\n\t.set\tInjection,0x80264FB8\n\t.set\tText_CreateTextGObj,0x803A4890\n\t.set\tText_InitializeSubtext,0x803A4CD4\n\t.set\tText_UpdateSubtextSize,0x803A5684\n\nPAL100:\n\t.set\tInjection,0x802669EC\n\t.set\tText_CreateTextGObj,0x803A6664\n\t.set\tText_InitializeSubtext,0x803a6b54\n\t.set\tText_UpdateSubtextSize,0x803A74FC\n*/\nbackup\n\n#GET PROPERTIES TABLE\n\tbl TEXTPROPERTIES\n\tmflr REG_TextProperties\n\n########################\n## Create Text Object ##\n########################\n\n#CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3\n\tli r3,0\n\tli r4,0\n\tbranchl r14,Text_CreateTextGObj\n\n#BACKUP STRUCT POINTER\n\tmr REG_TextGObj,r3\n\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x1\n\tstb r4,0x49(REG_TextGObj)\n\n#SET TEXT TO CENTER AROUND X LOCATION\n\tli r4,0x1\n\tstb r4,0x4A(REG_TextGObj)\n\n#Scale Canvas Down\n\tlfs f1,0xC(REG_TextProperties)\n\tstfs f1,0x24(REG_TextGObj)\n\tstfs f1,0x28(REG_TextGObj)\n\n####################################\n## INITIALIZE PROPERTIES AND TEXT ##\n####################################\n\n#Initialize Line of Text\n\tmr r3,REG_TextGObj       #struct pointer\n\tbl \tTEXT\n\tmflr \tr4\t\t#pointer to ASCII\n\tlfs f1,0x0(REG_TextProperties) #X offset of REG_TextGObj\n\tlfs f2,0x4(REG_TextProperties) #Y offset of REG_TextGObj\n\tbranchl r14,Text_InitializeSubtext\n\n#Set Size/Scaling\n  mr  r4,r3\n  mr\tr3,REG_TextGObj\n\tlfs   f1,0x8(REG_TextProperties) #get REG_TextGObj scaling value from table\n\tlfs   f2,0x8(REG_TextProperties) #get REG_TextGObj scaling value from table\n  branchl\tr12,Text_UpdateSubtextSize\n\nb end\n\n\n#**************************************************#\nTEXTPROPERTIES:\nblrl\n.float 38\t\t\t#x offset\n.float -275\t\t#y offset\n.float 0.45\t\t#REG_TextGObj scaling\n.float 0.1\t\t#canvas scaling\n\n\nTEXT:\nblrl\n.string \"UCF 0.8\"\n.align 2\n\n#**************************************************#\nend:\nrestore\n\naddi\tr4, r24, 0\n"
  },
  {
    "path": "ASM/m-ex/UCF 0.8/UCF Tumble.asm",
    "content": "#To be inserted at 800908f4\n.include \"../../Globals.s\"\n.include \"../Header.s\"\n\n  .set REG_PlayerData,31\n  .set REG_InputIndex,30\n  .set REG_PrevInput,29\n  .set REG_HSDPad,28\n\n.set  OFST_PlCo,-0x514C\n.set  HSD_Pad,0x804c1f78 #r31 @ 0x80377DC0\n\n  backup\n\n  #Cardinal direction held check:\n  # 0 = successful vanilla wiggle (branch out with cr0 less than bit true)\n  # 1 = continue to check additional conditions\n  # 2+ = wiggle fail due to input held, (branch out with cr0 less than bit false)\n\n    cmpwi r3, 1\n    bne- END\n\n  #Ensure last frame < 0.8\n    lfs f1,0x628(REG_PlayerData)\n    fabs f1,f1\n    lwz r3,OFST_PlCo(r13)\n    lfs f2,0x210(r3)\n    fcmpo cr0,f1,f2\n    bge END\n\n  BEGIN_HW_INPUTS:\n  \n  LOAD_2_FRAMES_PAST_INPUTS:\n    lbz\tREG_PrevInput, MEX_UCF2fX (REG_PlayerData)\n    extsb\tREG_PrevInput,REG_PrevInput\n\n  LOAD_CURRENT_FRAME_INPUT:\n    lbz r3, MEX_UCFCurrX (REG_PlayerData)\n    extsb r3,r3\n\n  CALCULATE_DIFFERENCE:\n      sub\t  r3,REG_PrevInput,r3\n      mullw r3, r3, r3  # Take square to get positive value for comparison\n  THRESHOLD_TEST:\n      li r4, 3600   # compare square of input difference between current frame and 2 frames ago to square of 60 (formerly 75 because different units)\n      cmpw r4, r3\n      b END\n\n  END:\n    restore"
  },
  {
    "path": "ASM/training-mode/Custom Events/A+B to Reset Event/Check for Reset on Game End.asm",
    "content": "#To be inserted at 801bba38\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n#Get all players inputs\n  li  r3,4\n  branchl r12,0x801a3680\n\n#Check Inputs\n  rlwinm. r0, r4, 0, 23, 23 #check A\n  beq- Original\n  rlwinm. r0, r4, 0, 22, 22 #check B\n  beq- Original\n\nRunback:\n  branch r12,0x801bb7a0\n\nOriginal:\n  li\tr3, 1\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/A+B to Reset Event/Check for Reset on LRAStart.asm",
    "content": "#To be inserted at 801bb844\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n#Get all players inputs\n  li  r3,4\n  branchl r12,0x801a3680\n\n#Check Inputs\n  rlwinm. r0, r4, 0, 23, 23 #check A\n  beq- Original\n  rlwinm. r0, r4, 0, 22, 22 #check B\n  beq- Original\n\nRunback:\n  branch r12,0x801bb7a0\n\nOriginal:\n  li\tr3, 1\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/CSS and SSS/Add SSS To Event Match Scene List.asm",
    "content": "#To be inserted at 801a44bc\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n##################################################\n\n#Overwrite Event Scene List\nbl\tEventSceneList\nmflr\tr3\nload\tr4,0x803db010\nstw\tr3,0x0(r4)\n\n#Overwrite SSS_SceneDecide\nbl\tSSS_SceneDecide\nmflr\tr4\nstw\tr4,0x38(r3)\n\n\n\n#Overwrite MainMenu Scene List\nbl\tMainMenuSceneList\nmflr\tr3\nload\tr4,0x803dae44\nstw\tr3,0x0(r4)\n\n#Overwrite Credits_SceneDecide\nbl\tCredits_SceneDecide\nmflr\tr4\nstw\tr4,0x20(r3)\nb\texit\n\n###############################################\n\n#Event Scene List Pointer @ 0x803db010\nEventSceneList:\nblrl\n\n#CSS\n.long 0x00030000\n.long 0x801baa60\n.long 0x801baad0\n.long 0x08000000\n.long 0x80497758\n.long 0x80497758\n\n#In-Match\n.long 0x01030000\n.long 0x801bad70\n.long 0x801bb758\n.long 0x02000000\n.long 0x804978a0\n.long 0x804979d8\n\n#SSS\n.long 0x02030000\n.long 0x801b1eb8\n.long 0x801b1eec\n.long 0x09000000\n.long 0x80497758\n.long 0x80497758\n\n.long 0xFF000000\n\n################################\n\nSSS_SceneDecide:\nblrl\nbackup\n\n#Get Minor Scenes Data Pointer\nlwz\tr3, 0x0014 (r3)\n\n#Get Method of Leaving SSS\nlbz\tr0, 0x0004 (r3)\ncmpwi\tr0,0x0\nbeq\tSSS_SceneDecide_BackToCSS\n\nSSS_SceneDecide_AdvanceToMatch:\n#Match Minor ID\nli\tr3,0x2\nb\tSSS_SceneDecide_Exit\n\nSSS_SceneDecide_BackToCSS:\nli\tr3,0x1\n\nSSS_SceneDecide_Exit:\n#Store Next Minor\nload\tr4,SceneController\nstb\tr3,0x5(r4)\n\nrestore\nblr\n\n################################\n\n\n\n\n\n\n\n################################\nMainMenuSceneList:\nblrl\n\n#MainMenu\n.long 0x00020000\n.long 0x801b0ff8\n.long 0x801b138c\n.long 0x01000000\n.long 0x804d68b8\n.long 0x804d68bc\n\n#Credits\n.long 0x01030000\n.long 0x00000000\n.long 0xFFFFFFFF\n.long 0x2B000000\n.long 0x00000000\n.long 0x00000000\n\n.long 0xFF000000\n\n################################\nCredits_SceneDecide:\nblrl\n\n#Store Next Minor\nload\tr4,SceneController\nli\tr3,0x0\nstb\tr3,0x5(r4)\n\nblr\n\n#################################\n\nexit:\nmr\tr3, r30\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/CSS and SSS/Backup HMN And CPU Choices/Backup Event CPU.asm",
    "content": "#To be inserted at 801bab18\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n#Get Backup Location\n  lwz\tr9, -0x77C0 (r13)\n  addi r9,r9,3344\n#Backup HMN Character Choice\n  lwz r3,CSS_Data(r13)      #CSS Match Info\n  addi r4,r9,104            #Character Backup Location\n  li  r5,0                  #Unk Backup Location\n  addi r6,r9,107            #Costume Backup Location\n  addi r7,r9,114            #Nametag Backup Location\n  li  r8,0                  #Unk Backup Location\n  branchl r12,0x801b0730\n\n#Also copy to Event's CSS Backup Data for compatibility\n#Get Backup Location\n  lwz\tr9, -0x77C0 (r13)\n  addi\tr9, r9, 1328\n#Backup HMN Character Choice\n  lwz r3,CSS_Data(r13)      #CSS Match Info\n  addi r4,r9,2            #Character Backup Location\n  li  r5,0                  #Unk Backup Location\n  addi r6,r9,3            #Costume Backup Location\n  addi r7,r9,4            #Nametag Backup Location\n  li  r8,0                  #Unk Backup Location\n  branchl r12,0x801b0730\n\n#Get Backup Location\n  lwz\tr9, -0x77C0 (r13)\n  addi r9,r9,3344\n#Backup CPU Character Choice\n  lwz r3,CSS_Data(r13)      #CSS Match Info\n  addi r4,r9,140            #Character Backup Location\n  li  r5,0                  #Unk Backup Location\n  addi r6,r9,143            #Costume Backup Location\n  addi r7,r9,150            #Nametag Backup Location\n  li  r8,0                  #Unk Backup Location\n  branchl r12,0x801b07e8\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/CSS and SSS/Backup HMN And CPU Choices/Restore Event CPU.asm",
    "content": "#To be inserted at 801baa98\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n#Get Backup Location\n  lwz\tr9, -0x77C0 (r13)\n  addi r9,r9,3344\n#Restore HMN Character Choice\n  load r3,0x80497758        #CSS Match Info\n  #mr  r4,r4                 #CSS Type\n  lbz r5,104(r9)            #Character Backup\n  li  r6,0                  #Unk\n  lbz r7,107(r9)           #Costume Backup\n  lbz r8,114(r9)           #Nametag Backup Location\n  li  r9,0                  #Unk Backup Location\n  lbz\tr10, 0x0006 (r31)     #Player who accessed CSS\n  branchl r12,0x801b06b0\n\n#Get Backup Location\n  lwz\tr9, -0x77C0 (r13)\n  addi r9,r9,3344\n#Backup CPU Character Choice\n  load r3,0x80497758        #CSS Match Info\n  lbz r4,140(r9)           #Character Backup\n  li  r5,1                 #Unk\n  lbz r6,143(r9)           #Costume Backup\n  lbz r7,150(r9)           #Nametag Backup\n  li  r8,0\n  lbz\tr9, 0x0006 (r31)     #Player who accessed CSS\n  branchl r12,0x801b07b4\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/CSS and SSS/Display Event Name on CSS.asm",
    "content": "#To be inserted at 80264504\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set text,31\n.set textProperties,30\n.set EventName,29\n\n#r24 = text struct\n#r27 = Event ID\n\n#Ensure this is event mode\n  load r3,SceneController\n  lbz r3,Scene.CurrentMajor(r3)\n  cmpwi r3,Scene.EventMode\n  bne Original\n\n#Check For Custom Event\n  lwz r3,MemcardData(r13)\n  lbz r3,CurrentEventPage(r3)\n  lwz\tr4, -0x77C0 (r13)\n  lbz\tr4, 0x0535 (r4)         #get event ID\n  rtocbl r12,TM_GetEventName\n\n#Save Text\n  mr  EventName,r3\n\n#GET PROPERTIES TABLE\n\tbl TEXTPROPERTIES\n\tmflr textProperties\n\n########################\n## Create Text Object ##\n########################\n\n#CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3\n\tli r3,0\n\tli r4,0\n\tbranchl r12,0x803a6754\n\n#BACKUP STRUCT POINTER\n\tmr text,r3\n\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x1\n\tstb r4,0x49(text)\n\n#SET TEXT TO CENTER AROUND X LOCATION\n\tli r4,0x1\n\tstb r4,0x4A(text)\n\n#Scale Canvas Down\n\tlfs f1,0xC(textProperties)\n\tstfs f1,0x24(text)\n\tstfs f1,0x28(text)\n\n####################################\n## INITIALIZE PROPERTIES AND TEXT ##\n####################################\n\n#Initialize Line of Text\n\tmr r3,text       #struct pointer\n\tmr \tr4,EventName\t\t#pointer to ASCII\n\tlfs f1,0x0(textProperties) #X offset of text\n\tlfs f2,0x4(textProperties) #Y offset of text\n\tbranchl r12,0x803a6b98\n\n#Set Size/Scaling\n  mr  r4,r3\n  mr\tr3,text\n\tlfs   f1,0x8(textProperties) #get text scaling value from table\n\tlfs   f2,0x8(textProperties) #get text scaling value from table\n  branchl\tr12,0x803a7548\n\nb Original\n\n\n#**************************************************#\nTEXTPROPERTIES:\nblrl\n\n.float 38      #x offset\n.float -245    #y offset\n.float 0.65    #text scaling\n.float 0.1     #canvas scaling\n\n#**************************************************#\n\nVanillaEvent:\nOriginal:\n  li\tr3, 4\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/CSS and SSS/Load CSS + Preload CPU.asm",
    "content": "#To be inserted at 801baa80\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set  REG_Stage,26\n.set  REG_CPU,27\n.set  REG_CSSType,28\n.set  EventID,29\n.set  PageID,30\n.set  REG_SceneData,31\n\nbackup\n\n#Save scene data\n  mr  REG_SceneData,r3\n#Get Current Event Number\n  lwz\tr4, -0x77C0 (r13)\n  lbz\tEventID, 0x0535 (r4)\n#Get Current Page in\n  lwz r4,MemcardData(r13)\n  lbz PageID,CurrentEventPage(r4)\n\n#Get this events CSS Type\n  mr  r3,PageID\n  mr  r4,EventID\n  rtocbl  r12,TM_GetIsChooseCPU\n  cmpwi r3,0x0\n  beq EventCSS\nTrainingCSS:\n  li  REG_CSSType,0x17\n  b CheckToPreloadCPU\nEventCSS:\n  li  REG_CSSType,14\n  b CheckToPreloadCPU\n\n\nCheckToPreloadCPU:\n#Check if this event has a pre-determined CPU\n  mr  r3,PageID\n  mr  r4,EventID\n  rtocbl  r12,TM_GetCPUFighter\n  extsb REG_CPU,r3\nCheckToPreloadStage:\n#Check if this event has a pre-determined stage\n  mr  r3,PageID\n  mr  r4,EventID\n  rtocbl  r12,TM_GetStage\n  extsb REG_Stage,r3\n\nUpdatePreloadTable:\n#Store Preload\n  load r3,PreloadTable\n  cmpwi REG_CPU,-1\n  beq UpdatePreloadTable_CheckStage\n  stw REG_CPU,0x1C(r3)   #p2 character\nUpdatePreloadTable_CheckStage:\n  cmpwi REG_Stage,-1\n  beq Exit\n  stw REG_Stage,0x10(r3)   #stage\n  b Exit\n\nExit:\n  mr  r4,REG_CSSType       #Return CSS Choice\n  mr  r3,REG_SceneData     #Restore scene data\n  restore\n  lbz\tr5, 0x0002 (r31)     #get r5 again since we clobbered it\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/CSS and SSS/Load SSS For Certain Events.asm",
    "content": "#To be inserted at 801bab28\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nstb\tr0, 0x000A (r31)\n\n#Get Event ID\n\tlwz\tr3, -0x77C0 (r13)\n\tlbz\tr4, 0x0535 (r3)\n  lbz r3,CurrentEventPage(r3)\n#Check if this event has a SSS\n\trtocbl\tr12,TM_GetIsSelectStage\n\tcmpwi\tr3,0\n\tbeq\toriginal\n\nSSS:\n#Store SSS as Next Scene\n  load\tr3,SceneController\n  li\tr4,0x3\n  stb\tr4,0x5(r3)\n\noriginal:\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/CSS and SSS/Toggle CSS Icon Vibibility/Toggle CSS Icon Vibibility.asm",
    "content": "#To be inserted at 80264578\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\nbackup\n\n.set REG_GObj,31\n.set REG_Data,30\n.set REG_Whitelist,29\n\n#Ensure this is event mode\n  load r3,SceneController\n  lbz r3,Scene.CurrentMajor(r3)\n  cmpwi r3,Scene.EventMode\n  bne Original\n\n#Create GObj\n  li  r3,4\n  li  r4,5\n  li  r5,0\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n\n#Create Data\n  li  r3,8\n  branchl r12,HSD_MemAlloc\n  mr  REG_Data,r3\n\n#Attach Data\n  mr  r3,REG_GObj\n  li  r4,14\n  load r5,HSD_Free\n  mr  r6,REG_Data\n  branchl r12,GObj_AddUserData\n\n#Attach Process\n  bl  ToggleCSSIcon\n  mflr r4\n  li  r5,2      #Priority (after CSS_BigFunctionMonitorInputsAndMore)\n  branchl r12,GObj_AddProc\n\n#Store Whitelist to GObj Data\n  bl  GetCharacterList\n  stw r3,0x0(REG_Data)\n  mr  REG_Whitelist,r3\n#Check if exists\n  cmpwi REG_Whitelist,-1\n  beq Original\n\n#Make P1 Undecided\n  lwz r20,CSS_Data(r13)      #CSS Match Info\n  addi r4,r20,0x70           #Get Player Info Start\n  lhz r5,0x0(r20)            #Get Player in control of CSS\n  subi r5,r5,1               #Zero index cause Yasuyuki Nagashima is dumb\n  mulli r5,r5,36\n  add r4,r4,r5               #r4 now contains the players info\n#Check if 0x21 (N/A)\n  li  r3,0x21\n  stb r3,0x0(r4)\n\n# COME BACK TO THIS CODE WHEN I MAKE AN EVENT\n# THAT HAS A SELECT AMOUNT OF CPU'S AVAILABLE\n/*\nCheckCPU:\n#Ensure CPU is a whitelisted character\n  lwz r20,CSS_Data(r13)      #CSS Match Info\n  addi r4,r20,0x78           #Get Player Info Start\n  lhz r5,0x0(r20)            #Get Player in control of CSS\n  subic. r5,r5,1             #Zero index cause Yasuyuki Nagashima is dumb\n  bne 0x8\n  li  r5,1\n  b 0x8\n  li  r5,0\n  mulli r5,r5,36\n  add r4,r4,r5               #r4 now contains the players info\n  addi  r3,REG_Whitelist,4   #CPU whitelist\n  bl  CheckWhitelist\n*/\nb Original\n\n#######################\nToggleCSSIcon:\nblrl\n.set REG_Whitelist,31\n\nbackup\n\n#Get Whitelist\n  lwz r3,0x2C(r3)\n  lwz REG_Whitelist,0x0(r3)\n#Check if whitelist exists\n  cmpwi REG_Whitelist,-1\n  beq ToggleCSSIcon_Exit\n\nToggleCSSIcon_Start:\n#Get P1's Cursor Data\n  load r3,CSS_CursorPointers      #Load CSS Cursor Pointers\n  lwz r5,0x0(r3)                  #Get P1's Cursor Data\n\n#Check if holding a puck\n  lbz r3,0x5(r5)          #Check hand state\n  cmpwi r3,0x1\n  bne ToggleCSSIcon_HoldingP1Puck\n#Check if holding P1's puck\n  lbz r3,0x6(r5)\n  cmpwi r3,0x0\n  beq ToggleCSSIcon_HoldingP1Puck\n#Check if holding CPU's puck\n  cmpwi r3,0x1\n  beq ToggleCSSIcon_HoldingCPUPuck\n  b ToggleCSSIcon_Exit\n\nToggleCSSIcon_HoldingP1Puck:\n  mr  r3,REG_Whitelist\n  bl ToggleCSSIcon_ToggleSelectedIcons\n  b ToggleCSSIcon_Exit\n\nToggleCSSIcon_HoldingCPUPuck:\n  addi r3,REG_Whitelist,0x4     #CPU List is at 0x4\n  bl\tToggleCSSIcon_ToggleSelectedIcons\n  b ToggleCSSIcon_Exit\n\nToggleCSSIcon_Exit:\n  restore\n  blr\n\n#******************************#\n\n############################\n## Show Whitelisted Chars ##\n############################\nToggleCSSIcon_ToggleSelectedIcons:\n\n.set REG_IconDataStart,31\n.set REG_Whitelist,30\n.set REG_IconData,29\n.set REG_VisibilityBool,28\n.set REG_LoopCount,27\n\nbackup\n\nToggleCSSIcon_ToggleSelectedIconsInit:\n#Init Stuff\n  lwz  REG_Whitelist,0x0(r3)\n  li  REG_LoopCount,25\n  load REG_IconDataStart,0x803f0b24\n  b ToggleCSSIcon_ToggleSelectedIconsIncLoop\nToggleCSSIcon_ToggleSelectedIconsLoop:\n#Get Icons Data\n  mulli r3,REG_LoopCount,0x1C\n  add REG_IconData,r3,REG_IconDataStart\n#Check if icon should be visible\n  li\tr3, 1\n  slw\tr0, r3, REG_LoopCount\n  and.\tr0, r0, REG_Whitelist\n  bne\tToggleCSSIcon_ToggleSelectedIcons_Display\nToggleCSSIcon_ToggleSelectedIcons_Hide:\n  li  REG_VisibilityBool,0\n  b 0x8\nToggleCSSIcon_ToggleSelectedIcons_Display:\n  li  REG_VisibilityBool,1\n#Set Invisible\n  #Get JObj\n    lwz\tr3, -0x49E0 (r13)\n    addi r4,sp,0x80\n    lbz r5,0x5(REG_IconData)\n    crclr 6\n    li  r6,-1\n    branchl r12,0x80011e24\n  #Toggle invisibility flag\n    lwz r3,0x80(sp)\n    li  r5,1\n    cmpwi REG_VisibilityBool,0\n    beq 0x8\n    li  r5,0\n    lwz r4,0x14(r3)\n    rlwimi r4,r5,4,27,27\n    stw r4,0x14(r3)\n#Set interactable\n  li  r3,0\n  cmpwi REG_VisibilityBool,0\n  beq 0x8\n  li  r3,2\n  stb r3,0x2(REG_IconData)\nToggleCSSIcon_ToggleSelectedIconsIncLoop:\n  subi REG_LoopCount,REG_LoopCount,1\n  cmpwi REG_LoopCount,0\n  bge ToggleCSSIcon_ToggleSelectedIconsLoop\n\nToggleCSSIcon_ToggleSelectedIconsExit:\n  restore\n  blr\n\n#######################\nGetCharacterList:\nbackup\n\n.set EventID,31\n.set PageID,30\n\n#Get Hovered Over Event ID in r23\n\tlwz\tr4, -0x77C0 (r13)\n\tlbz\tEventID, 0x0535 (r4)\n#Get Current Page\n  lbz PageID,CurrentEventPage(r4)\n\n#Get pointer page's string array\n\tbl\tGetCharacterList_SkipJumpTable\n##### Page List #######\n  EventJumpTable\n#######################\n\nGetCharacterList_SkipJumpTable:\n  mflr\tr4\t\t#Jump Table Start in r4\n  mulli\tr5,PageID,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n  add\tr6,r4,r5\t\t#Gets Address in r6\n\n#Loop Through Whitelisted Events\nGetCharacterList_Loop:\n  lbzu\tr3,0x0(r6)\n  extsb\tr0,r3\n  cmpwi\tr0,-1\n  beq\tGetCharacterList_Failed\n  cmpw\tr3,EventID\n  beq\tGetCharacterList_Success\n  addi r6,r6,0x9\n  b\tGetCharacterList_Loop\n\nGetCharacterList_Failed:\nli  r3,-1\nb GetCharacterList_Exit\n\nGetCharacterList_Success:\naddi  r3,r6,1\n\nGetCharacterList_Exit:\nrestore\nblr\n#######################\nCheckWhitelist:\nbackup\n\n.set REG_PlayerPointer,31\n.set REG_Whitelist,30\n.set REG_CSSID,29\n\n#Backup registers\n  mr REG_Whitelist,r3\n  mr REG_PlayerPointer,r4\n\n#Check if no character selected\n\n\n#Get CSS ID From External\n  bl  ExternalToCSSID\n  mflr r3\n  lbz r4,0x0(REG_PlayerPointer)\n  lbzx REG_CSSID,r4,r3\n\n\nCheckWhitelist_Exit:\n  restore\n  blr\n\n#######################\n#******************************#\n  EventPlayableCharacters\n#******************************#\nExternalToCSSID:\nblrl\n.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\n.align 2\n#******************************#\nOriginal:\n  restore\n  lbz\tr4, -0x3E57 (r13)\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Credits Codes/Don't Display Info In TM Credits.asm",
    "content": "#To be inserted at 801abb1c\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set player,31\n.set playerdata,31\n\nload\tr3,SceneController\nlbz\tr3,0x0(r3)\ncmpwi\tr3,0x1\nbne\texit\n\nbranch\tr12,0x801abdf4\n\nexit:\nlwz\tr3, 0 (r23)\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Credits Codes/Don't Display Titles In Training Mode Credits.asm",
    "content": "#To be inserted at 801aae50\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set player,31\n.set playerdata,31\n.set text,31\n\nload\tr5,SceneController\nlbz\tr5,0x0(r5)\ncmpwi\tr5,0x1\t\t#Main Menu\nbeq\tSkip\nbranchl\tr12,0x803a6368\n\nSkip:\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Credits Codes/Swap Out Credit Names in TM Credits.asm",
    "content": "#To be inserted at 801aac60\n#80100000\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nb\tFunctionStart\n\nNames:\nblrl\n.string \"Charlotte\"\n.string \"Hugh N\"\n.string \"HARB\"\n.string \"Cyrus R\"\n.string \"ravecake\"\n.string \"Jeremy\"\n.string \"Dominick T\"\n.string \"Robert P\"\n.string \"Jonathan B\"\n.string \"Daniel F\"\n.string \"Marshall Z\"\n.string \"Thomas B\"\n.string \"Rishi\"\n.string \"KELLZ\"\n.string \"Turkey\"\n.string \"Outside\"\n.string \"Jesse\"\n.string \"BenSW\"\n.string \"Setchi \"\n.string \"Jimmy M\"\n.string \"Micah S\"\n.string \"Avi\"\n.string \"YungZunga\"\n.string \"Randle J\"\n.string \"Andreas H\"\n.string \"Calszone\"\n.string \"Riley D\"\n.string \"Anthony C\"\n.string \"Kevin T\"\n.string \"Zane R\"\n.string \"Gage K\"\n.string \"Ari\"\n.string \"Vitral\"\n.string \"CF True\"\n.string \"yardsale\"\n.string \"James L\"\n.string \"Zach N\"\n.string \"Sir Lemon\"\n.string \"Matt B\"\n.string \"Max S\"\n.string \"RealDingos \"\n.string \"Wasif R\"\n.string \"femboy uwu\"\n.string \"Spencer G\"\n.string \"Ben A\"\n.string \"William R\"\n.string \"KJH\"\n.string \"Reeve\"\n.string \"Christian A\"\n.string \"Esteban H\"\n.string \"Forrest G\"\n.string \"Aiden C\"\n.string \"Grolex\"\n.string \"Manuel P\"\n.string \"Methorphan\"\n.string \"bofftarget\"\n.string \"Mark M\"\n.string \"Reece E\"\n.string \"Ka Ming AC\"\n.string \"BONSAI BOYS\"\n.string \"Jean T\"\n.string \"Jon\"\n.string \"Stuart K\"\n.string \"Mike R\"\n.string \"James\"\n.string \"Miller T\"\n.string \"Darren M\"\n.string \"ShaggyJ\"\n.string \"Bryan K\"\n.string \"Collin B\"\n.string \"Lucas S\"\n.string \"jeremiah K\"\n.string \"Will A\"\n.string \"Eacab\"\n.string \"Maccrea P\"\n.string \"Justin H\"\n.string \"Zach J\"\n.string \"Brandt W\"\n.string \"Gene K\"\n.string \"Jaycob A\"\n.string \"Joseph R\"\n.string \"blandeezy\"\n.string \"Vim\"\n.string \"roob adoob\"\n.string \"Sami B\"\n.string \"Blake P\"\n.string \"Charlon\"\n.string \"Aldrin R\"\n.string \"Jane L\"\n.string \"Martin R\"\n.string \"Stephane S\"\n.string \"Greg W\"\n.string \"Delano W\"\n.string \"Kyle S\"\n.string \"K OBrien\"\n.string \"Albert Z\"\n.string \"Lykon\"\n.string \"Benjamin E\"\n.string \"Dave S\"\n.string \"Jordan J\"\n.string \"Gear\"\n.string \"Fritz\"\n.string \"Jeff J\"\n.string \"Dalton G\"\n.string \"Trevor C\"\n.string \"Chad S\"\n.string \"Brit B\"\n.string \"Austin D\"\n.string \"Micah W\"\n.string \"Jonathon M\"\n.string \"Jason V\"\n.string \"Marvin S\"\n.string \"Glenn T\"\n.string \"Jordan M\"\n.string \"Bj C\"\n.string \"Lucio\"\n.string \"Benno K\"\n.string \"Bernando B\"\n.string \"Kaveh A\"\n.string \"Thomas R\"\n.string \"Austin L\"\n.string \"Brennan R\"\n.string \"Anthony G\"\n.string \"Ryan M\"\n.string \"Tony K\"\n.string \"Shane K\"\n.string \"Andrew W\"\n.string \"Vincent T\"\n.string \"Ali S\"\n.string \"Nathan H\"\n.string \"Maxime C\"\n.string \"Riley B\"\n.string \"cagliostro9\"\n.string \"Jonathan M\"\n.string \"Rafa M\"\n.string \"Lucuius M\"\n.string \"Julie M\"\n.string \"Sergio D\"\n.string \"Andre MLO\"\n.string \"Juan D\"\n.string \"Andrew Y\"\n.string \"Fabadam\"\n.string \"Tony R\"\n.string \"Daniel C\"\n.string \"Derex E\"\n.string \"Chris C\"\n.string \"Samuel CD\"\n.string \"Melee Stats\"\n.string \"George G\"\n.string \"Joey A\"\n.string \"Stephan M\"\n.string \"Jason S\"\n.string \"Kris S\"\n.string \"Mikey R\"\n.string \"Jake M\"\n.string \"Liam M\"\n.string \"Andy C\"\n.string \"Sunset\"\n.string \"Dylan M\"\n.string \"Will N\"\n.string \"+\"\n.string \"Matthew L\"\n.string \"Matthew P\"\n.string \"Aiden F\"\n.string \"Michael O\"\n.string \"Drew D\"\n.string \"Tyler M\"\n.string \"+\"\n.string \"masafumsa\"\n.string \"Nathan S\"\n.string \"Quentin F\"\n.string \"Bobby Scar\"\n.string \"OuterHalo\"\n.string \"Max R\"\n.string \"TruckJitsu\"\n.string \"Seth M\"\n.string \"Jamie C\"\n.string \"Eddie A\"\n.string \"Cody N\"\n.string \"Joel\"\n.string \"Kalvar\"\n.string \"Armando C\"\n.string \"+\"\n.string \"+\"\n.string \"Special Thanks\"\n.string \"Achilles\"\n.string \"Dan Salvato\"\n.string \"Punkline\"\n.string \"DRGN\"\n.string \"Fizzi\"\n.string \"Minute Melee\"\n.string \"Dolphin-Emu\"\n.string \"Gecko OS\"\n.string \"\"\n.string \"\"\n.string \"\"\n.string \"Thanks to all my patrons\nwho supported this project!\n\nwww.twitter.com/UnclePunch_\nwww.patreon.com/UnclePunch\"\n.align 2\n\nFunctionStart:\n.set FirstNameToReplace,2\n.set LastNameToReplace,196\n\n.set text,30\n\nbackup\n\n#Check For TM Credits\n  load\tr3,SceneController\n  lbz\tr3,0x0(r3)\n  cmpwi\tr3,0x1\n  bne\tExit\n\n#Only Display After the First 2 Names\nCheckWhitelist:\n  lwz\tr3, -0x4eac (r13)\n  cmpwi\tr3,FirstNameToReplace\n  blt\tExit\n  cmpwi\tr3,LastNameToReplace\n  bgt\tExit\n\n#Create Text\n  li  r3,0\n  li  r4,0\n  branchl r12,0x803a6754\n  mr  text,r3\n#Init Some Values\n  li  r0,1\n  stb r0,0x4C(text)\n  stb r0,0x4A(text)\n  stb r0,0x49(text)\n  stfs\tf30, 0x0024 (text)\n  stfs\tf29, 0x0028 (text)\n  lfs\tf1, -0x4F10 (rtoc)\n  lfs\tf2, -0x4F0C (rtoc)\n  lfs\tf3, -0x4F08 (rtoc)\n  stfs f1,0x00(text)\n  stfs f2,0x04(text)\n  stfs f1,0x08(text)\n  stfs f1,0x0C(text)\n  stfs f3,0x10(text)\n#Store Pointer\n  lwz\tr3, -0x4EA8 (r13)\n  stwx\ttext, r3, r31\n\nConvertToMenuText:\n#Get Text As Menu Text\n  lwz\tr3, -0x4EAC (r13)\n  bl  Names\n  mflr r4\n  branchl r12,SearchStringTable\n  mr  r4,r3\n  addi r3,sp,0x40\n  branchl\tr12,0x803a67ec\n  mr  r20,r3              #Backup text length\n\n#Get Text Struct Pointer\n  lwz\tr3, -0x4EA8 (r13)\n  lwzx\ttext, r3, r31\n#Get Allocation Info Pointer\n  lwz r21,0x64(text)\n#Check To Adjust Allocation\n  lwz\tr22, 0x0004 (r21)     #Get old menu text allocation\n  lwz\tr0, 0 (r21)\n  lwz\tr4, 0x0008 (r21)      #Get size of allocation\n  sub\tr3, r0, r22\n  addi\tr0, r3, 17\n  add\tr0, r20, r0\n  cmplw\tr4, r0\n  bge-\t NoAdjustAllocation\n  sub\tr0, r0, r4\n  rlwinm\tr3, r0, 25, 7, 31\n  addi\tr0, r3, 1\n  rlwinm\tr0, r0, 7, 0, 24\n  add\tr0, r4, r0\n  stw\tr0, 0x0008 (r21)\n  lwz\tr3, 0x0008 (r21)\n  branchl r12,0x803A5798\n  addi\tr5, r22, 0\n  addi\tr4, r3, 0\n  li\tr7, 0\n  b\t\tReAllocateLoop_Inc\nReAllocateLoop:\n  lbz\tr0, 0 (r5)\n  addi\tr7, r7, 1\n  addi\tr5, r5, 1\n  stb\tr0, 0 (r4)\n  addi\tr4, r4, 1\nReAllocateLoop_Inc:\n  lwz\tr6, 0x0004 (r21)\n  lwz\tr0, 0 (r21)\n  sub\tr6, r0, r6\n  addi\tr0, r6, 1\n  cmpw\tr7, r0\n  blt+\tReAllocateLoop\n  stw\tr3, 0x0004 (r21)\n  stw\tr3, 0x005C (text)\n  lwz\tr0, 0 (r21)\n  sub\tr0, r0, r22\n  add\tr0, r3, r0\n  stw\tr0, 0 (r21)\n  mr\tr3, r22\n  branchl r12,0x803A594C\nNoAdjustAllocation:\n#Copy new text to text struct\n  lwz r3,0x5C(text)\n  addi r4,sp,0x40\n  mr  r5,r20\n  branchl r12,memcpy\n\n#Add Terminator\n  li r3,0x1900\n  lwz r4,0x5C(text)\n  sthx r3,r20,r4\n  b CustomExit\n\nCustomExit:\n#Inc Name Count\nlwz\tr3, -0x4eac (r13)\naddi\tr3,r3,0x1\nstw\tr3, -0x4eac (r13)\n\nrestore\nbranch r12,0x801aadb8\n\n\n\nExit:\nlwz\tr3, -0x4eac (r13)\naddi\tr3,r3,0x1\nstw\tr3, -0x4eac (r13)\nrestore\nlfs\tf1, -0x4F10 (rtoc)\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Custom Event Code - Legacy.s",
    "content": "#To be inserted at 801bb128\n.include \"../Globals.s\"\n\n#r25 = event ID\n#r26 = final match struct\n#r28 = same as r26\n#r29 = event struct index (0x0 of this, then 0x8 of that to get the specifics)\n\n#region Event and Menu GObj Data Structs\n#Event GObj Data Struct\n.set EventData_DataSize,0x50\n.set EventData_MenuDataPointer,(EventData_DataSize-0x4)\n.set EventData_SaveStateStruct,0x10\n\n#Menu GObj Data Struct\n.set MenuData_DataSize,0x50\n.set MenuData_EventDataPointer,(MenuData_DataSize-0x4)\n.set MenuData_WindowOptionCountPointer,0x0\n.set MenuData_ASCIIStructPointer,0x4\n.set MenuData_OptionMenuMemory,0x8\n.set MenuData_OptionMenuToggled,0x28\n#endregion\n\n#region Init Custom Event\n#################\n## Custom Code ##\n#################\n\n#all registers free\n\n\t#1 PLAYER, NO ITEMS, TIME COUNTING UP\n\tlwz\tr9,0x0(r29)\t\t#get event pointers\n\n\t#ZERO OUT p2-p6 STRUCT\n\tli\tr4,0x0\n\tstw\tr4,0x18(r9)\n\tstw\tr4,0x1C(r9)\n\tstw\tr4,0x20(r9)\n\tstw\tr4,0x24(r9)\n\tstw\tr4,0x28(r9)\n\n\t#Disable All-Star Flag\n\tli\tr3,0x0\n\tstb\tr3,0x0(r9)\n\n\t#P1 = Choose Char + Normal Modifiers\n\tbl\tP1Struct\n\tmflr\tr3\n\tstw\tr3,0x14(r9)\n\n\t#STORE MATCH SETTINGS\n\tload\tr3,0x0BB0027C\t\t#HUD and timer behavior\n\tstw\tr3,0x0(r26)\n\tload\tr3,0x90800000\n\tstw\tr3,0x4(r26)\t\t#think functions\n\tli\tr3,0xFF\n\tstb\tr3,0xB(r26)\t\t#items to none\n\tli\tr3,0x0\n\tstw\tr3,0x10(r26)\t\t#time amount\n\n\t#STORE UNLIM STOCKS\n\tli\tr3,0xFF\n\tstb\tr3,0x62(r26)\t\t#p1 stocks\n\n\t#SET FALL FLAG\n\tli\tr3,0x0\n\tstb\tr3,0x6C(r26)\n\n  #SET FFA FLAG\n  li  r3,0\n  stb r3,0x8(r26)\n\n  #Store SSS Stage\n  load\tr3,0x80497758\n  lha\tr4, 0x001E (r3)\n  sth\tr4,0xE(r26)\n\n#Get Event Code\n  bl  SkipPageList\n\n##### Page List #######\n\tEventJumpTable\n#######################\nMinigames:\nbl\tEggs\nbl\tMultishine\nbl\tReaction\nbl\tLedgeStall\n.long -1\n#######################\nGeneralTech:\nbl\tLCancel\nbl\tLedgedash\nbl\tComboTraining\nbl\tAttackOnShield\nbl\tReversal\nbl\tSDITraining\nbl\tPowershield\nbl\tLedgetech\nbl\tAmsahTech\nbl\tShieldDrop\nbl\tWaveshineSDI\nbl\tSlideOff\nbl\tGrabMashOut\n.long -1\n#######################\nSpacieTech:\nbl  LedgetechCounter\nbl\tArmadaShine\nbl\tSideBSweetspot\nbl\tEscapeSheik\n.long -1\n#######################\n\nSkipPageList:\n#Get Page Jump Table\n  mflr\tr4\t\t#Jump Table Start in r4\n#Get Current Page\n  lwz r3,MemcardData(r13)\n  lbz r3,CurrentEventPage(r3)\n  mulli\tr5,r3,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n  add\tr4,r4,r5\t\t#Gets ASCII Address in r4\n#Get Event Code Pointer\n  mulli\tr5,r25,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n\tcmpwi r5,-1\n\tbeq\tEventNoExist\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n  add\tr4,r4,r5\t\t#Gets ASCII Address in r4\n  mtctr\tr4\n  bctr\n\nEventNoExist:\n\tb\texit\n#endregion\n\n###############\n## Minigames ##\n###############\n\n#region Eggs-ercise\n#########################\n## Eggs-ercise HIJACK INFO ##\n#########################\n\nEggs:\n\n#COUNT DOWN TIME\n\tli\tr3,0x6\n\tstb\tr3,0x0(r26)\n\n#1 Minute On the Clock\n\tli\tr3,60\n\tstw\tr3,0x10(r26)\n\n#Store Match Type to READY, GO!\n\tli\tr3,0x80\n\tstb\tr3,0x1(r26)\n\n#SET EVENT TYPE TO KOs\n\tload\tr5,0x8045abf0\t\t#Static Match Struct\n\tlbz\tr3,0xB(r5)\t\t#Get Event Score Behavior Byte\n\tli\tr4,0x0\n\trlwimi\tr3,r4,1,30,30\t\t#Zero Out Time Bit\n\tstb\tr3,0xB(r5)\t\t#Set Event Score Behavior Byte\n\n#1 Player\n\tlwz r4,0x0(r29)\n\tli\tr3,0x20\n\tstb\tr3,0x1(r4)\n\n#STORE THINK FUNCTION\n\tbl\tEggsLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Eggs-ercise LOAD FUNCT ##\n\t########################\n\tEggsLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n    #r3 = function to run each frame\n    #r4 = priority\n    #r5 = pointer to Window and Option Count\n    #r6 = pointer to ASCII struct\n\tbl\tEggsThink\n\tmflr\tr3\n\tli\tr4,9\t\t#Priority (After Interrupt)\n  bl\tEggsWindowInfo\n  mflr\tr5\n  bl\tEggsWindowText\n  mflr\tr6\n\tbl\tCreateEventThinkFunction\n\n\tbl\tInitializeHighScore\n\n\tb\tEggsLoadExit\n\n\n\t\t#########################\n\t\t## Eggs-ercise THINK FUNCT ##\n\t\t#########################\n\n    #Registers\n    .set EventData,31\n    .set MenuData,26\n    .set P1Data,27\n    .set P1GObj,28\n\n    #Offsets\n\t\t.set\tDamageThreshold,(MenuData_OptionMenuMemory+0x2) +0x0\n\t\t.set\tDamageThresholdToggled,(MenuData_OptionMenuToggled) +0x0\n\n\t\tEggsThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#Get and Backup Event Data\n\t\tmr\tr30,r3\t\t\t#r30 = think entity\n\t\tlwz\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n    lwz MenuData,EventData_MenuDataPointer(EventData)\n\n\t\t#Get Player Data\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n\n\t\t#No Staling\n\t\tbl\tResetStaleMoves\n\n\t\t#Check If Free Practice\n\t\tlbz\tr3,0x5(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tEggsSkipFreePracticeCheck\n\t\t#Check DPad Down\n\t\tlwz\tr0,0x668(r27)\n\t\trlwinm.\tr0,r0,0,29,29\n\t\tbeq\tEggsSkipFreePracticeCheck\n\t\t#Toggle Free Practice On\n\t\tli\tr3,0x1\n\t\tstb\tr3,0x5(r31)\n\t\t#Timer Now Counts Up\n\t\tload\tr3,0x8046b6a0\n\t\tlbz\tr0,0x24C8(r3)\n\t\tli\tr4,1\n\t\trlwimi\tr0,r4,0,31,31\n\t\tstb\tr0,0x24C8(r3)\n\t\t#Play Sound To Indicate\n\t\tli\tr3,0x82\n\t\tbranchl\tr12,SFX_PlaySoundAtFullVolume\n\t\tEggsSkipFreePracticeCheck:\n\n    #Check If Toggled\n      lbz r3,DamageThresholdToggled(MenuData)\n\t\t  cmpwi\tr3,0x0\n\t\t  beq\tEggsSkipToggleCheck\n\t\t#Check If Already Free Practice\n\t\t  lbz\tr3,0x5(r31)\n\t\t  cmpwi\tr3,0x0\n\t\t  bne\tEggsSkipToggleCheck\n\t\t#Make Free Practice\n\t\t  li\tr3,0x1\n\t\t  stb\tr3,0x5(r31)\n\t\t#Timer Now Counts Up\n\t\t  load\tr3,0x8046b6a0\n\t\t  lbz\tr0,0x24C8(r3)\n\t\t  li\tr4,1\n\t\t  rlwimi\tr0,r4,0,31,31\n\t\t  stb\tr0,0x24C8(r3)\n\t\t#Play Sound To Indicate\n\t\t  li\tr3,0x82\n\t\t  branchl\tr12,SFX_PlaySoundAtFullVolume\n    EggsSkipToggleCheck:\n\n\t\t#Check For First Frame\n\t\tlbz\tr3,0x4(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tEggsNotFirstFrame\n\n\t\t\t#Check If Player Can Move\n\t\t\tli\tr3,0x0\n\t\t\tbranchl\tr12,PlayerBlock_LoadMainCharDataOffset\t #get player block\n\t\t\tlwz\tr3,0x2c(r3)\t\t#player data in r29\n\n\t\t\tlbz\tr3,0x221D(r3)\n\t\t\trlwinm.\tr3,r3,0,28,28\n\t\t\tbne\tEggsThinkExit\n\n\t\t\t#Set First Frame Over\n\t\t\tli\tr3,0x1\n\t\t\tstb\tr3,0x4(r31)\n\t\t\tEggsNotFirstFrame:\n\n\t\t#Check If Target is Spawned\n\t\tEggsTargetCheck:\n    #Check If Pointer is Stored\n\t\t  lwz\tr3,0x0(r31)\n\t\t  cmpwi\tr3,0x0\n\t\t  beq\tEggsThinkSpawn\n    #Check if Item GObj is live\n      lwz r3,0x2C(r3)\n      cmpwi r3,0x0\n      beq EggsThinkSpawn\n      b   EggsThinkSkipSpawn\n\n################\n# Spawn Target #\n################\n\n.set LeftCameraBound,20\n.set RightCameraBound,21\n.set TopCameraBound,22\n.set BottomCameraBound,23\n\n    EggsThinkSpawn:\n    .if debug==1\n      li r24,0      #Init loop count\n    .endif\n\n    EggsThinkSpawnLoop:\n\n    .if debug==1\n      addi r24,r24,1  #Inc Loop Count\n    .endif\n\n    #Get OnScreen Boundaries\n    #Left Camera\n      branchl r12,StageInfo_CameraLimitLeft_Load\n      fctiwz f1,f1\n      stfd f1,0x80(sp)\n      lwz LeftCameraBound,0x84(sp)\n    #Right Camera\n      branchl r12,StageInfo_CameraLimitRight_Load\n      fctiwz f1,f1\n      stfd f1,0x80(sp)\n      lwz RightCameraBound,0x84(sp)\n    #Top Camera\n      branchl r12,StageInfo_CameraLimitTop_Load\n      fctiwz f1,f1\n      stfd f1,0x80(sp)\n      lwz TopCameraBound,0x84(sp)\n    #Bottom Camera\n      branchl r12,StageInfo_CameraLimitBottom_Load\n      fctiwz f1,f1\n      stfd f1,0x80(sp)\n      lwz BottomCameraBound,0x84(sp)\n\n    #Get Random Velocity\n\t\t\tbranchl\tr12,HSD_Randf\n      fmr f20,f1\n      li  r3,2\n      bl  IntToFloat\n      fadds f20,f20,f1\n\n    #Get Random X Value Between These\n      mr  r3,LeftCameraBound\n      mr  r4,RightCameraBound\n      bl  RandFloat\n      fmr f21,f1\n\n    #Get Random Y Value Between These\n      mr   r3,BottomCameraBound\n      subi  r4,TopCameraBound,70        #Minus 40 so it doesnt fly up offscreen\n      bl  RandFloat\n      fmr f22,f1\n\n    .set EggSpawnGroundWidth,8\n    #Check If Egg is Above Ground\n      fmr f1,f21\n      fmr f2,f22\n      bl  FindGroundUnderCoordinate\n      cmpwi r3,0x0\n      beq EggsThinkSpawnLoop\n    #Check Left\n      li  r3,EggSpawnGroundWidth\n      bl  IntToFloat\n      fsubs f1,f21,f1\n      fmr f2,f22\n      bl  FindGroundUnderCoordinate\n      cmpwi r3,0x0\n      beq EggsThinkSpawnLoop\n    #Check Right\n      li  r3,EggSpawnGroundWidth\n      bl  IntToFloat\n      fadds f1,f21,f1\n      fmr f2,f22\n      bl  FindGroundUnderCoordinate\n      cmpwi r3,0x0\n      beq EggsThinkSpawnLoop\n\n    .if debug==1\n      #OSReport Loop Count\n        load r3,0x803ead3c\n        mr r4,r24\n        branchl r12,OSReport\n    .endif\n\n\t\t\tSpawnEgg:\n\t\t\taddi\tr3,sp,0x80\n\t\t\tli\tr4,0x0\n\t\t\tstw\tr4,0x0(r3)\t#Player Pointer\n\t\t\tstw\tr4,0x4(r3)\t#Player Pointer\n\t\t\tli\tr4,0x03\n\t\t\tstw\tr4,0x8(r3)\t#Item ID\n\t\t\tlfs\tf0, -0x2858 (rtoc)\n\t\t\tstfs\tf21,0x14(r3)\t#X Coord\n\t\t\tstfs\tf22,0x18(r3)\t#Y Coord\n\t\t\tstfs\tf0,0x1C(r3)\t#Z Coord\n\t\t\tstfs\tf21,0x20(r3)\t#X Coord\n\t\t\tstfs\tf22,0x24(r3)\t#Y Coord\n\t\t\tstfs\tf0,0x28(r3)\t#Z Coord\n\t\t\tstfs\tf0,0x2C(r3)\t#Unk\n\t\t\tstfs\tf0,0x30(r3)\t#Unk\n\t\t\tstfs\tf0,0x34(r3)\t#X Vel\n\t\t\tstfs\tf0,0x38(r3)\t#Y Vel\n\t\t\tli\tr4,0x1\n\t\t\tsth\tr4,0x3C(r3)\n\t\t\tbranchl\tr12,EntityItemSpawn\n\t\t\tmr\tr29,r3\t\t#Backup Entity Pointer\n\n\t\t\tstw\tr29,0x0(r31)\t\t#Store Pointer To Target In Event Think\n\n\t\t\t#Store Pointer To Event Think In Target\n\t\t\tlwz\tr4,0x2C(r29)\n\t\t\tstw\tr31,0xDDC(r4)\n\n\t\t\t#Store Y Velocity\n\t\t\tstfs\tf20,0x44(r4)\n\n\t\t\t#Get OnDestroy\n\t\t\tlwz\tr4,0x2C(r29)\n\t\t\tlwz\tr4,0xB8(r4)\n\n\t\t\t#Store OnCollision\n\t\t\tbl\tEggs_OnCollision\n\t\t\tmflr\tr3\n\t\t\tstw\tr3,0x1C(r4)\n\n\t\t\t#Create Camera Box\n\t\t\tbranchl\tr12,CreateCameraBox\n\t\t\t#Attach to Entity\n\t\t\tlwz\tr4,0x2c(r29)\n\t\t\tstw\tr3, 0x0520 (r4)\n\t\t\t#Enable Camera Box Bit\n\t\t\tlbz\tr0, 0x0DCD (r4)\n\t\t\tli\tr5,0x22\n\t\t\trlwimi\tr0, r5, 5, 24, 25\n\t\t\tstb\tr0, 0x0DCD (r4)\n\t\t\t#Copy Some Stuff To Camera Box\n\t\t\tlwz\tr4, -0x4978 (r13)\n\t\t\tlfs\tf0, 0x014C (r4)\n\t\t\tstfs\tf0, 0x0040 (r3)\n\t\t\tlfs\tf0, 0x0150 (r4)\n\t\t\tstfs\tf0, 0x0044 (r3)\n\t\t\tlfs\tf0, 0x0154 (r4)\n\t\t\tstfs\tf0, 0x0048 (r3)\n\t\t\tlfs\tf0, 0x0158 (r4)\n\t\t\tstfs\tf0, 0x004C (r3)\n\n\t\t\t#Never Timeout\n\t\t\tlwz\tr5, 0x002C (r29)\n\t\t\tlbz\tr3,0xDD0(r5)\n\t\t\tli\tr4,0x1\n\t\t\trlwimi\tr3,r4,4,27,27\n\t\t\tstb\tr3,0xDD0(r5)\n\n\t\t\t#Not Grabbable\n\t\t\tlbz\tr3, 0x0DCA (r5)\n\t\t\tli\tr4,0x0\n\t\t\trlwimi\tr3,r4,2,29,29\n\t\t\tstb\tr3, 0x0DCA (r5)\n\n\t\t\t#Un-Nudgeable?\n\t\t\tlbz\tr3, 0x0DCB (r5)\n\t\t\tli\tr4,0x0\n\t\t\trlwimi\tr3,r4,3,28,28\n\t\t\tstb\tr3, 0x0DCB (r5)\n\n      EggsThinkSkipSpawn:\n      #Not Grabbable Every Frame\n      lwz\tr5,0x0(r31)\n      lwz\tr5,0x2c(r5)\n      lbz\tr3, 0x0DCA (r5)\n      li\tr4,0x0\n      rlwimi\tr3,r4,2,29,29\n      stb\tr3, 0x0DCA (r5)\n\n      #Update HUD Score\n      li\tr3,0\n      li\tr4,5\n      branchl\tr12,Playerblock_LoadTimesR3KilledR4\n      branchl\tr12,HUD_KOCounter_UpdateKOs\n\n      #Check If Free Practice\n        lbz\tr3,0x5(r31)\n        cmpwi\tr3,0x0\n        bne\tEggsThinkExit\n      #Check For TimeUp\n        branchl\tr12,MatchInfo_LoadSeconds\t\t#Seconds Left\n        cmpwi\tr3,0x0\n        bne\tEggsThinkExit\n        branchl\tr12,MatchInfo_LoadSubSeconds\t\t#Sub-Seconds Left\n        cmpwi\tr3,59\n        bne\tEggsThinkExit\n      #On Event End\n        mr\tr3,r30\n        branchl\tr12,EventMatch_OnWinCondition\t\t\t#EventMatch_OnWinCondition\n\nEggsThinkExit:\n  mr  r3,MenuData\n  bl  ClearToggledOptions\n  restore\n  blr\n\n\n\t\t\tEggs_OnCollision:\n\t\t\tblrl\n\n      #First check if this is an event\n        load r4,SceneController\n        lbz r4,Scene.CurrentMajor(r4)\n        cmpwi r4,Scene.EventMode\n        bne Eggs_OnCollisionOriginalFunction\n      #Now check if its eggs-ercise\n        lwz\tr4, -0x77C0 (r13)\n        lbz\tr4, 0x0535 (r4)         #get event ID\n        cmpwi r4,Event_Eggs\n        beq Eggs_OnCollisionStart\n\n      Eggs_OnCollisionOriginalFunction:\n      #Go to the original egg break function\n        branch r12,ItemCollision_Egg\n\n      Eggs_OnCollisionStart:\n  \t\t\tbackup\n  \t\t\tmr\tr30,r3\n  \t\t\tlwz\tr31,0x2C(r3)\t\t\t#Get Data\n\n\t\t\t#Check If Any Attack Should Break\n  \t\t\tlwz\tr3,0xDDC(r31)\t\t\t         #Get Event Data\n        lwz r3,EventData_MenuDataPointer(r3)     #Get Menu Data\n  \t\t\tlbz\tr3,DamageThreshold(r3)\t\t\t#Damage Behavior\n  \t\t\tcmpwi\tr3,0x1\n  \t\t\tbeq\tEggs_OnCollisionBreakEgg\n\t\t\t#Check Damage Dealt Before Exploding\n  \t\t\tlwz\tr3,0xCA0(r31)\n  \t\t\tcmpwi\tr3,11\n  \t\t\tblt\tEgg_OnCollisionExit\n\n\t\t\tEggs_OnCollisionBreakEgg:\n\t\t\t#Increment Score\n  \t\t\tli\tr3,0\n  \t\t\tli\tr4,0\n  \t\t\tli\tr5,5\n  \t\t\tbranchl\tr12,Playerblock_StoreTimesR3KilledR4\n\n\t\t\t#Display Effect\n  \t\t\tli\tr3,1232\n  \t\t\tmr\tr4,r30\n  \t\t\taddi\tr5, r31, 76\n  \t\t\tcrclr\t6\n  \t\t\tbranchl\tr12,Textures_DisplayEffectTextures\n\n\t\t\t#Play Pop Sound\n  \t\t\tmr\tr3,r31\n  \t\t\tli\tr4,244\n  \t\t\tli\tr5,127\n  \t\t\tli\tr6,64\n  \t\t\tbranchl\tr12,0x8026ae84\n\n\t\t\t#Explode\n  \t\t\tmr\tr3,r30\n  \t\t\tbranchl\tr12,0x80289158\n\n\t\t\t#Spawn New Egg\n  \t\t\tlwz\tr3,0xDDC(r31)\t\t\t#Get Event Think\n  \t\t\tli\tr4,0x0\t\t\t#Get 0\n  \t\t\tstw\tr4,0x0(r3)\t\t\t#Zero Pointer\n\n\t\t\tEgg_OnCollisionExit:\n  \t\t\tli\tr3,0x0\n\t\t\tEgg_OnCollisionExitSkip:\n  \t\t\trestore\n  \t\t\tblr\n\nEggsLoadExit:\nrestore\nblr\n\n####################################################\n\nEggsWindowInfo:\nblrl\n#amount of options, amount of options in each window\n\n.long 0x0001FFFF  #1 window, Smash Attack has 2 options\n\n####################################################\n\nEggsWindowText:\nblrl\n\n######################\n## Damage Threshold ##\n######################\n\n#Window Title = Damage Threshold\n.long 0x44616d61\n.long 0x67652054\n.long 0x68726573\n.long 0x686f6c64\n.long 0x\n\n#Option 1 = 12+ Damage\n.long 0x3132817B\n.long 0x2044616d\n.long 0x61676500\n.long 0x\n.long 0x\n\n#Option 2 = Any Damage\n.long 0x416e7920\n.long 0x44616d61\n.long 0x67650000\n.long 0x\n.long 0x\n\n\n################################################################################\n################################################################################\n\n#endregion\n\n#region Multishine\n#########################\n## Multishine HIJACK INFO ##\n#########################\n\nMultishine:\n#COUNT DOWN TIME\n\tli\tr3,0x6\n\tstb\tr3,0x0(r26)\n\n#10 Seconds On the Clock\n\tli\tr3,10\n\tstw\tr3,0x10(r26)\n\n#Store Match Type to READY, GO!\n\tli\tr3,0x80\n\tstb\tr3,0x1(r26)\n\n#SET EVENT TYPE TO KOs\n\tload\tr5,0x8045abf0\t\t#Static Match Struct\n\tlbz\tr3,0xB(r5)\t\t#Get Event Score Behavior Byte\n\tli\tr4,0x0\n\trlwimi\tr3,r4,1,30,30\t\t#Zero Out Time Bit\n\tstb\tr3,0xB(r5)\t\t#Set Event Score Behavior Byte\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,FinalDestination\t\t\t#Use FD\n\tload r7,EventOSD_Multishine\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo Bool\n\tbl\tInitializeMatch\n\n#1 Player\n\tlwz r4,0x0(r29)\n\tli\tr3,0x20\n\tstb\tr3,0x1(r9)\n\n#STORE THINK FUNCTION\n\tbl\tMultishineLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\n\t########################\n\t## Multishine LOAD FUNCT ##\n\t########################\n\tMultishineLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tMultishineThink\n\tmflr\tr3\n\tli\tr4,17\t\t#Priority (After Everything)\n  li  r5,0    #No Option Menu\n\tli\tr6,0\n\tbl\tCreateEventThinkFunction\n\n\tbl\tInitializeHighScore\n\n\tb\tMultishineLoadExit\n\n\t\t#########################\n\t\t## Multishine THINK FUNCT ##\n\t\t#########################\n\n\t\tMultishineThink:\n\t\tblrl\n\n    .set EventData,31\n    .set Event,30\n    .set P1Data,27\n    .set P1GObj,28\n\n\t\tbackup\n\n\t\tmr\tEvent,r3\n\t\tlwz\tEventData,0x2c(Event)\n\n    bl GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n\n\t#First Frame Actions\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tMultishineNotFirstFrame\n  #Init Positions\n    bl  PlacePlayersCenterStage\n\tMultishineNotFirstFrame:\n\n\t#Check for grounded or aerial shine, frame 1\n\t\tlwz r3,0x10(P1Data)\n\t\tcmpwi r3,0x168\n\t\tbeq Multishine_IsShining\n\t\tcmpwi r3,0x16D\n\t\tbeq Multishine_IsShining\n\t\tb\tMultishine_SkipShineCheck\n\tMultishine_IsShining:\n\t#Check for frame 1\n\t\tlhz r3,FramesinCurrentAS(P1Data)\n\t\tcmpwi r3,0\n\t\tbne Multishine_SkipShineCheck\n\t#Increment Score\n  \tli\tr3,0\n  \tli\tr4,0\n  \tli\tr5,5\n  \tbranchl\tr12,Playerblock_StoreTimesR3KilledR4\n\tMultishine_SkipShineCheck:\n\n\t#Check For TimeUp\n  \tbranchl\tr12,MatchInfo_LoadSeconds\t\t#Seconds Left\n    cmpwi\tr3,0x0\n    bne\tMultishineThinkExit\n    branchl\tr12,MatchInfo_LoadSubSeconds\t\t#Sub-Seconds Left\n    cmpwi\tr3,59\n    bne\tMultishineThinkExit\n  #On Event End\n    mr\tr3,Event\n    branchl\tr12,EventMatch_OnWinCondition\t\t\t#EventMatch_OnWinCondition\n\n\tMultishineThinkExit:\n  #Update HUD Score\n  \tli\tr3,0\n  \tli\tr4,5\n    branchl\tr12,Playerblock_LoadTimesR3KilledR4\n    branchl\tr12,HUD_KOCounter_UpdateKOs\n\n\tMultishineLoadExit:\n\trestore\n\tblr\n\n\n\n\n################################################################################\n################################################################################\n#endregion\n\n#region Reaction\n#########################\n## Reaction HIJACK INFO ##\n#########################\n\nReaction:\n#SET EVENT TYPE TO KOs\n\tload\tr5,0x8045abf0\t\t#Static Match Struct\n\tlbz\tr3,0xB(r5)\t\t#Get Event Score Behavior Byte\n\tli\tr4,0x0\n\trlwimi\tr3,r4,1,30,30\t\t#Zero Out Time Bit\n\tstb\tr3,0xB(r5)\t\t#Set Event Score Behavior Byte\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Fox.Ext\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,FinalDestination\t\t\t#Use FD\n\tload r7,EventOSD_Reaction\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo Bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\n\tbl\tReactionLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\n\t########################\n\t## Reaction LOAD FUNCT ##\n\t########################\n\tReactionLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tReactionThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (Interrupt)\n  li  r5,0    #No Option Menu\n\tli\tr6,0\n\tbl\tCreateEventThinkFunction\n\n\tb\tReactionLoadExit\n\n\t\t#########################\n\t\t## Reaction THINK FUNCT ##\n\t\t#########################\n\n\t\tReactionThink:\n\t\tblrl\n\n    .set EventData,31\n    .set Event,30\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n\t\t#Constants\n\t\t.set ShineTimerMax,7*60\n\t\t.set ShineTimerMin,3*60\n\t\t.set ResetTimer,1*60\n\n\t\t#GObj Data Offsets\n\t\t.set OFST_ShineTimer,0x0\n\t\t.set OFST_ResetTimer,0x2\n\t\t.set OFST_ReactionTimer,0x4\n\n\n\t\tbackup\n\n\t\tmr\tEvent,r3\n\t\tlwz\tEventData,0x2c(Event)\n\n    bl\tGetAllPlayerPointers\n    mr\tP1GObj,r3\n    mr\tP1Data,r4\n    mr\tP2GObj,r5\n    mr\tP2Data,r6\n\n\t#First Frame Actions\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tReactionNotFirstFrame\n  #Init Positions\n    bl  PlacePlayersCenterStage\n\t#Savestate\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\n\t\tbl\tSaveState_Save\n\t#Set Initial Timer\n\t\tli\tr3,ShineTimerMax - ShineTimerMin\n\t\tbranchl r12,HSD_Randi\n\t\taddi r3,r3,ShineTimerMin\n\t\tsth r3,OFST_ShineTimer(EventData)\n\t#Initialize Reaction Timer\n\t\tli\tr3,-1\n\t\tsth r3,OFST_ReactionTimer(EventData)\n\t#Stop Music\n\t\tli\tr3,0\n\t\tli\tr4,2\n\t\tbranchl r12,0x80025064\n\tReactionNotFirstFrame:\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t#Give Intangibility to both chars\n\t\tmr\tr3,P1GObj\n\t\tli\tr4,1\n\t\tbranchl r12,ApplyIntangibility\n\t\tmr\tr3,P2GObj\n\t\tli\tr4,1\n\t\tbranchl r12,ApplyIntangibility\n\n\t#Check post countdown timer\n\t\tlhz r3,OFST_ResetTimer(EventData)\n\t\tcmpwi r3,0\n\t\tble Reaction_SkipResetTimer\n\t#Dec timer, if 0 reset\n\t\tsubi r3,r3,1\n\t\tsth r3,OFST_ResetTimer(EventData)\n\t\tcmpwi r3,0\n\t\tbeq Reaction_Reset\n\t\tb\tReactionThinkExit\n\tReaction_SkipResetTimer:\n\n\t#Check shine countdown timer\n\t\tlhz r3,OFST_ShineTimer(EventData)\n\t\tcmpwi r3,0\n\t\tble Reaction_SkipShineTimer\n\t#Dec timer, if 0 perform move\n\t\tsubi r3,r3,1\n\t\tsth r3,OFST_ShineTimer(EventData)\n\t\tcmpwi r3,0\n\t\tbgt ReactionThink_CheckIfActedEarly\n\t#Perform down b\n\t\tmr\tr3,P2GObj\n\t\tbranchl r12,0x800e8560\n\t#Start reaction timer\n\t\tli\tr3,0\n\t\tsth\tr3,OFST_ReactionTimer(EventData)\n\t\tb\tReactionThinkExit\n\nReactionThink_CheckIfActedEarly:\n\t#Check if P1 acted early\n\t\tlwz\tr3,0x10(P1Data)\n\t\tcmpwi r3,ASID_Wait\n\t\tbeq ReactionThinkExit\n\t#Play Error Noise\n\t\tli\tr3,0xAF\n\t\tbl\tPlaySFX\n\t#Set Timer\n\t\tli\tr3,ResetTimer-40\n\t\tsth r3,OFST_ResetTimer(EventData)\n\t\tb\tReactionThinkExit\n\nReaction_SkipShineTimer:\n\n\t#Check reaction timer\n\t\tlhz r3,OFST_ReactionTimer(EventData)\n\t\textsh r3,r3\n\t\tcmpwi r3,0\n\t\tblt Reaction_SkipReactionTimer\n\t#Poll Inputs Again\n\t\t#branchl r12,0x80377ce8\n\t#Check if P1 Reacted\n\t\tlbz r3,0x618(P1Data)\n\t\tload r4,InputStructStart\n\t\tmulli\tr3,r3,68\n\t\tadd\tr3,r3,r4\n\t\tlwz r3,0x8(r3)\n\t\tcmpwi r3,0\n\t\tbeq Reaction_SkipReactionTimer\n\t#Output reaction time\n\t\tmr\tr3,P1Data\t\t\t#p1 (no offsetting window)\n\t\tli\tr4,120\t\t\t#text timeout\n\t\tli\tr5,0\t\t\t#Area to Display (0-2)\n\t\tli\tr6,OSD.Miscellaneous\t\t\t#Window ID (Unique to This Display)\n\t\tbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\n\t\tmr\tr20,r3\t\t\t#backup text pointer\n\t#Decide Color\n\t\tlhz r3,OFST_ReactionTimer(EventData)\n\t\tcmpwi\tr3,15\n\t\tble\tReaction_Good\n\tReaction_Bad:\n\t\tload\tr3,0xffa2baff\t\t\t#Red\n\t\tb\tReaction_StoreTextColor\n\tReaction_Good:\n\t\tload\tr3,0x8dff6eff\t\t\t#green\n\tReaction_StoreTextColor:\n\t\tstw\tr3,0x30(r20)\n\n\t#Create Text 1\n\t\tmr \tr3,r20\t\t\t#text pointer\n\t\tbl\tReaction_TopText\n\t\tmflr\tr4\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,Text_InitializeSubtext\n\n\t#Create Text 2\n\t\tmr \tr3,r20\t\t\t#text pointer\n\t\tbl\tReaction_BottomText\n\t\tmflr\tr4\n\t\tlhz\tr5,OFST_ReactionTimer(EventData)\n\t\taddi r5,r5,1\t\t\t\t\t\t\t\t#0-index is scary\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,Text_InitializeSubtext\n\n\t#Start post countdown timer\n\t\tli\tr3,ResetTimer\n\t\tsth r3,OFST_ResetTimer(EventData)\n\t\tb\tReactionLoadExit\n\tReaction_SkipReactionTimer:\n\t#Inc timer\n\t\tlhz r3,OFST_ReactionTimer(EventData)\n\t\taddi r3,r3,1\n\t\tsth r3,OFST_ReactionTimer(EventData)\n\t\tb\tReactionThinkExit\n\n\tReaction_Reset:\n\t#Load State\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tSaveState_Load\n\t#Reset Variables\n\t#Set Initial Timer\n\t\tli\tr3,ShineTimerMax - ShineTimerMin\n\t\tbranchl r12,HSD_Randi\n\t\taddi r3,r3,ShineTimerMin\n\t\tsth r3,OFST_ShineTimer(EventData)\n\t#Reset Timer\n\t\tli\tr3,0\n\t\tsth\tr3,OFST_ResetTimer(EventData)\n\t#Initialize Reaction Timer\n\t\tli\tr3,-1\n\t\tsth r3,OFST_ReactionTimer(EventData)\n\n\tReactionThinkExit:\n\tReactionLoadExit:\n\trestore\n\tblr\n\nReaction_TopText:\nblrl\n.string \"Reaction Time:\"\n.align 2\n\nReaction_BottomText:\nblrl\n.string \"%d Frames\"\n.align 2\n\n################################################################################\n################################################################################\n#endregion\n\n#region Ledge Stall\n###########################\n## Ledge Stall HIJACK INFO ##\n###########################\n\nLedgeStall:\n#Store Match Type to READY, GO!\n\tli\tr3,0x80\n\tstb\tr3,0x1(r26)\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\n\tli\tr6,Brinstar\t\t\t\t\t\t\t\t\t\t#stage\n\tload r7,EventOSD_LedgeStall\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#1 Player\n\tlwz r4,0x0(r29)\n\tli\tr3,0x20\n\tstb\tr3,0x1(r4)\n\n#STORE THINK FUNCTION\nLedgeStallStoreThink:\n\tbl\tLedgeStallLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## \t\t\tLedge Stall LOAD FUNCT \t\t##\n##################################\nLedgeStallLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tLedgeStallThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\n#Destroy Lava map_gobj proc\n\tli\tr3,8\t\t\t\t#lava's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,GObj_RemoveProc\n/*\n#Make Lava transparent\n\tli\tr3,8\t\t\t\t#lava's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n\tli\tr4,0\n\tbranchl r12,Stage_map_gobj_LoadJObj\n\tli\tr5,1\n\tlwz r4,0x14(r3)\n\trlwimi r4,r5,29,2,2\n\trlwimi r4,r5,28,3,3\n\trlwimi r4,r5,19,12,12\n\tstw r4,0x14(r3)\n\tlwz r3,0x18(r3)\n\tlwz r3,0x8(r3)\n\tlwz r4,0x4(r3)\n\trlwimi r4,r5,29,2,2\n\trlwimi r4,r5,30,1,1\n\tstw r4,0x4(r3)\n\tlwz r3,0xC(r3)\n\tload r4,0x3f000000\n\tstw r4,0xC(r3)\n*/\n#Get map_gobj\n\tli\tr3,6\t\t\t\t#platform's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n#Get platform flesh item pointer\n\tlwz r3,0x2C(r3)\n\tlwz r3,0xE4(r3)\n\tlwz r3,0x2C(r3)\n#Set Hurtbox as intangible\n\tli\tr4,2\n\tstw r4,0xACC(r3)\n\n#Create Camera Box\n\tbranchl\tr12,CreateCameraBox\n\tmr\tr20,r3\n#Get Stage's Ledge IDs\n\tlwz\t\tr3,-0x6CB8 (r13)\t\t\t#External Stage ID\n\tbl\t\tLedgedashCliffIDs\n\tmflr  r4\n\tmulli\tr3,r3,0x2\n\tlhzx\tr3,r3,r4\n#Get Ledge Coordinates\n\trlwinm\tr3,r3,24,24,31\n\taddi\tr4,sp,0xD0\n\tbranchl\tr12,Stage_GetLeftOfLineCoordinates\n#Position Base of CameraBox behind the ledge\n.set CameraBoxXOffset,35\n.set CameraBoxYOffset,20\n\tli\tr3,CameraBoxXOffset\n\tbl\tIntToFloat\n\tlfs f2,0xD0(sp)\t\t#Ledge X\n\tfadds f1,f1,f2\n\tstfs f1,0x10(r20)  #Camera X Position\n\tli\tr3,CameraBoxYOffset\n\tbl\tIntToFloat\n\tlfs f2,0xD4(sp)\t\t#Ledge Y\n\tfadds f1,f1,f2\n\tstfs f1,0x14(r20)  #Camera Y Position\n#Make Boundaries around ledge position\n#Left Bound\n\tli\tr3,-10\n\tbl\tIntToFloat\n\tstfs\tf1,0x40(r20)\n#Right Bound\n\tli\tr3,10\n\tbl\tIntToFloat\n\tstfs\tf1,0x44(r20)\n#Top Bound\n\tli\tr3,10\n\tbl\tIntToFloat\n\tstfs\tf1,0x48(r20)\n#Lower Bound\n\tli\tr3,-10\n\tbl\tIntToFloat\n\tstfs\tf1,0x4C(r20)\n\n#Set Camera To Be Zoomed Out More\n\tload\tr4,0x8049e6c8\n\tload\tr3,0x3FE66666\n\tstw\tr3,0x28(r4)\n\n\tb\tLedgeStallThink_Exit\n\n###########################################\nLedgeStallThink_Constants:\nblrl\n.set LavaRiseRate,0x0\n.set LavaMaxY,0x4\n\n.float 0.4\n.float 10\n###########################################\n\n###################################\n## Ledge Stall THINK FUNCT ##\n###################################\n\nLedgeStallThink:\n\tblrl\n\n#Registers\n\t.set REG_EventConstants,25\n  .set REG_MenuData,26\n  .set REG_EventData,31\n\t.set REG_EventGObj,24\n  .set REG_P1Data,27\n  .set REG_P1GObj,28\n\t.set REG_P2Data,29\n\t.set REG_P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set EventState_LavaDelay,0x0\n\t\t.set EventState_LavaRiseThink,0x1\n\t\t.set EventState_Reset,0x2\n\t.set Timer,0x1\n\t.set LavaTimer,0x2\n\t.set SurvivalTime,0x4\n\t.set LavaPosition,0x8\n\n#Constants\n\t.set ResetTimer,30\n\t.set LavaStartY,-100\n\t.set LavaStartTimer,123\n\t.set SuvivalTime_CountInterval,5\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tmr\tREG_EventGObj,r3\n\tlwz\tREG_EventData,0x2c(REG_EventGObj)\t\t\t#backup data pointer in r31\n\n#Get Player Pointers\n  bl GetAllPlayerPointers\n  mr REG_P1GObj,r3\n  mr REG_P1Data,r4\n  mr REG_P2GObj,r5\n  mr REG_P2Data,r6\n\n#Get Menu and Constants Pointers\n  lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData)\n\tbl\tLedgeStallThink_Constants\n\tmflr REG_EventConstants\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tLedgeStallThink_Start\n\t#Init Positions\n\t\tmr\tr3,REG_P1GObj\n\t\tmr\tr4,REG_EventData\n\t\tbl\tLedgeStall_InitializePositions\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\nLedgeStallThink_Start:\n\n#Check if player was damaged or died\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_DamageHi1\n\tblt LedgeStallThink_DamageCheckSkip\n\tcmpwi r3,ASID_DamageFlyRoll\n\tbgt LedgeStallThink_DamageCheckSkip\n\tb\tLedgeStallThink_TookDamage\nLedgeStallThink_DamageCheckSkip:\n\tlbz r3,0x221F(REG_P1Data)\n\trlwinm. r0,r3,0,25,25\n\tbeq LedgeStallThink_DeadCheckSkip\nLedgeStallThink_TookDamage:\n#Check if took damage already\n\tlbz\tr3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt LedgeStallThink_DeadCheckSkip\n#Set Reset Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n#Play Crowd SFX\n\t#li\tr3,0x13D\n\t#bl\tPlaySFX\n#Advance State\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\nLedgeStallThink_DeadCheckSkip:\n\nLedgeStallThink_SwitchCase:\n#Switch Case\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_LavaDelay\n\tbeq LedgeStallThink_LavaDelay\n\tcmpwi r3,EventState_LavaRiseThink\n\tbeq LedgeStallThink_LavaRiseThink\n\tcmpwi r3,EventState_Reset\n\tbeq LedgeStallThink_Reset\n\tb\tLedgeStallThink_CheckTimer\n\n#region LedgeStallThink_LavaDelay\nLedgeStallThink_LavaDelay:\n#Reset Timer back to 0\n\tli\tr3,0\n\tload r4,0x8046b6a0\n\tstw r3,0x28(r4)\t\t#seconds\n\tsth r3,0x2C(r4)\t\t#subseconds\n\n#Decrement Lava Timer\n\tlhz r3,LavaTimer(REG_EventData)\n\tsubi r3,r3,1\n\tsth r3,LavaTimer(REG_EventData)\n#Check if up\n\tcmpwi r3,0\n\tbgt LedgeStallThink_CheckTimer\n#Advance State\n\tli\tr3,EventState_LavaRiseThink\n\tstb r3,EventState(REG_EventData)\n\tb LedgeStallThink_LavaRiseThink\n#endregion\n\n#region LedgeStallThink_LavaRiseThink\nLedgeStallThink_LavaRiseThink:\n#Ensure player is in the lava before incrementing survival time\n\tlfs f1,LavaPosition(REG_EventData)\n\tlfs f2,0xB4(REG_P1Data)\n\tfcmpo cr0,f2,f1\n\tbge LedgeStallThink_LavaRiseThink_NotInLava\n#Increment Score\n\tlwz r3,SurvivalTime(REG_EventData)\n\taddi r3,r3,1\n\tstw r3,SurvivalTime(REG_EventData)\nLedgeStallThink_LavaRiseThink_SkipScoreIncrement:\n\n#Play HRC SFX every X score\n\tli\tr3,SuvivalTime_CountInterval\n\tbl\tIntToFloat\n\tfmr f2,f1\n\tlwz r3,SurvivalTime(REG_EventData)\n\tsubi r3,r3,1\n\tbl\tIntToFloat\n\tbranchl r12,fmod\n\tfmr f2,f1\n\tli\tr3,0\n\tbl\tIntToFloat\n\tfcmpo cr0,f2,f1\n\tbne LedgeStallThink_LavaRiseThink_SkipSFX\n#Play SFX\n\tli\tr3,0xBB\n\tbl\tPlaySFX\n\tli\tr3,0xBB\n\tbl\tPlaySFX\nLedgeStallThink_LavaRiseThink_SkipSFX:\n\tb\tLedgeStallThink_LavaRiseThink_NotInLavaSkip\n\nLedgeStallThink_LavaRiseThink_NotInLava:\n#Reset Timer back to 0\n\tli\tr3,0\n\tload r4,0x8046b6a0\n\tstw r3,0x28(r4)\t\t#seconds\n\tsth r3,0x2C(r4)\t\t#subseconds\n#Set survival time to 0\n\tstw r3,SurvivalTime(REG_EventData)\nLedgeStallThink_LavaRiseThink_NotInLavaSkip:\n\n#Check if lava is at max height\n\tlfs f1,LavaPosition(REG_EventData)\n\tlfs f2,LavaMaxY(REG_EventConstants)\n\tfcmpo cr0,f1,f2\n\tbge LedgeStallThink_LavaRiseThink_SkipLavaRise\n#Raise Lava\n\tlfs f2,LavaRiseRate(REG_EventConstants)\n\tfadds f1,f1,f2\n\tstfs f1,LavaPosition(REG_EventData)\n\tbl\tLedgestall_UpdateLavaPosition\nLedgeStallThink_LavaRiseThink_SkipLavaRise:\n\n\tb\tLedgeStallThink_CheckTimer\n#endregion\n\n#region LedgeStallThink_Reset\nLedgeStallThink_Reset:\n#Effectively pause timer\n\tload r4,0x8046b6a0\n\tlwz r3,0x28(r4)\t\t#seconds\n\tcmpwi r3,0\n\tbeq LedgeStallThink_NoSecondCarryover\n\tlhz r3,0x2C(r4)\t\t#subseconds\n\tcmpwi r3,0\n\tbne LedgeStallThink_NoSecondCarryover\n\tli\tr3,0x3B\n\tsth r3,0x2C(r4)\t\t#subseconds\n\tlwz r3,0x28(r4)\t\t#seconds\n\tsubi r3,r3,1\n\tstw r3,0x28(r4)\t\t#seconds\n\tb\tLedgeStallThink_CheckTimer\nLedgeStallThink_NoSecondCarryover:\n\tlhz r3,0x2C(r4)\t\t#subseconds\n\tsubi r3,r3,1\n\tsth r3,0x2C(r4)\t\t#subseconds\n\tb\tLedgeStallThink_CheckTimer\n\n#endregion\n\nLedgeStallThink_CheckTimer:\n#Check if timer exists\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tble LedgeStallThink_Exit\n#Decrement timer\n\tsubi r3,r3,1\n\tstb r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt LedgeStallThink_Exit\n\n\n#Pasue game\n\tlfs\tf1, -0x4D68 (rtoc)\n\tbranchl r12,0x8016b274\t\t\t\t#Pause game engine\n#Check if player had any score when taking damage\n\tlwz r3,SurvivalTime(REG_EventData)\n\tcmpwi r3,0\n\tble LedgeStallThink_Failure\nLedgeStallThink_Success:\n#Get current high score\n\tlwz\tr3,-0x77C0 (r13)\n\tlbz r20,0x535(r3)\n\tmr\tr3,r20\n\tbranchl r12,Events_GetEventSavedScore\n\tlwz r4,SurvivalTime(REG_EventData)\n\tcmpw r4,r3\n\tble LedgeStallThink_Success_NoHighScore\nLedgeStallThink_Success_NewHighScore:\n\tli\tr3,2\n\tbranchl r12,0x8016b33c\t\t\t\t#Display Success + SFX\n\tload r3,0x9c40\n\tbranchl r12,0x8016b350\n\tli\tr3,325\n\tbranchl r12,0x8016b364\t\t\t\t#queue crowd cheer after Success\n\tbranchl r12,0x8016b328\t\t\t\t#set game as ended\n\tmr\tr3,r20\t\t\t\t\t\t\t\t\t\t#update score\n\tlwz r4,SurvivalTime(REG_EventData)\n\tbranchl r12,Events_SetEventSavedScore\n\tmr\tr3,r20\t\t\t\t\t\t\t\t\t\t#set event as played\n\tbranchl r12,0x8015ceb4\n\tb\tLedgeStallThink_Success_DestroyGObj\nLedgeStallThink_Success_NoHighScore:\n\tli\tr3,2\n\tbranchl r12,0x8016b33c\t\t\t\t#Display New Record + SFX\n\tli\tr3,324\n\tbranchl r12,0x8016b364\t\t\t\t#queue crowd cheer after New Record\n\tbranchl r12,0x8016b328\t\t\t\t#set game as ended\n\tb\tLedgeStallThink_Success_DestroyGObj\n\nLedgeStallThink_Failure:\n\tli\tr3,6\n\tbranchl r12,0x8016b33c\t\t\t\t#Display Failure + SFX\n\tli\tr3,328\n\tbranchl r12,0x8016b364\t\t\t\t#queue crowd sigh after failure\n\tli\tr3,40\n\tbranchl r12,0x8016b378\t\t\t\t#frames to linger?\n\tbranchl r12,0x8016b328\t\t\t\t#set game as ended\n\tb\tLedgeStallThink_Success_DestroyGObj\n\nLedgeStallThink_Success_DestroyGObj:\n\tmr\tr3,REG_EventGObj\n\tbranchl r12,GObj_Destroy\t\t\t#destroy event gobj\n\tb\tLedgeStallThink_Exit\n\nLedgeStallThink_Restore:\n#Restore State\n\taddi r3,REG_EventData,EventData_SaveStateStruct\n\tli\tr4,1\n\tbl\tSaveState_Load\n#Init Positions Again\n\tmr\tr3,REG_P1GObj\n\tmr\tr4,REG_EventData\n\tbl\tLedgeStall_InitializePositions\n#Enable Inputs\n\tlbz r3,0x221D(REG_P1Data)\n\tli\tr4,0\n\trlwimi r3,r4,3,28,28\n\tstb r3,0x221D(REG_P1Data)\n#Shorten Timer\n\tli\tr3,0\n\tsth r3,LavaTimer(REG_EventData)\nLedgeStallThink_Exit:\n\trestore\n\tblr\n\n################################\n\nLedgeStall_InitializePositions:\nbackup\n\n.set REG_P1GObj,30\n.set REG_P1Data,29\n.set REG_EventData,28\n.set REG_map_gobj,27\n.set REG_map_gobj_JObj,26\n\n#Init Registers\n  mr\tREG_P1GObj,r3\n  lwz REG_P1Data,0x2C(REG_P1GObj)\n\tmr\tREG_EventData,r4\n\n#Place on left ledge\n\tmr\tr3,REG_P1GObj\n\tli\tr4,0\n\tbl\tPlaceOnLedge\n\n#Update Camera\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdateCameraBox\n\n#Init Lava Y\n\tli\tr3,LavaStartY\n\tbl\tIntToFloat\n\tstfs f1,LavaPosition(REG_EventData)\n\tbl\tLedgestall_UpdateLavaPosition\n\n#Reset Variables\n\tli\tr3,EventState_LavaDelay\n\tstb r3,EventState(REG_EventData)\n\tli\tr3,0\n\tstb r3,Timer(REG_EventData)\n\tstw r3,SurvivalTime(REG_EventData)\n\n#Init Lava Start Timer\n\tli\tr3,LavaStartTimer\n\tsth r3,LavaTimer(REG_EventData)\n\nLedgeStall_InitializePositions_Exit:\n\trestore\n\tblr\n\n#####################################\nLedgestall_UpdateLavaPosition:\nbackup\n\n.set REG_LavaY,31\n.set REG_map_gobj_JObj,30\n\n#Backup args\n\tstfs f1,0x80(sp)\n\n#Get Lava map_gobj\n\tli\tr3,8\t\t\t\t#lava's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n#Get JObj\n\tli\tr4,0\n\tbranchl r12,Stage_map_gobj_LoadJObj\n\tmr\tREG_map_gobj_JObj,r3\n\n#Get 55f (jobj doesnt line up with actual position)\n\tli\tr3,55\n\tbl\tIntToFloat\n#Update JObj Y position\n\tlfs f2,0x80(sp)\n\tfadds f1,f1,f2\n\tstfs f1,0x3C(REG_map_gobj_JObj)\n#DirtySub\n\tmr\tr3,REG_map_gobj_JObj\n\tbranchl r12,HSD_JObjSetMtxDirtySub\n\n#Adjust hitbox position\n\tlfs f1,0x80(sp)\n\tbranchl r12,0x801c438c\n\nLedgestall_UpdateLavaPosition_Exit:\nrestore\nblr\n\n#endregion\n\n##################\n## General Tech ##\n##################\n\n#region L-Cancel Training\n#########################\n## L Cancel HIJACK INFO ##\n#########################\n\nLCancel:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t\t#Use SSS Stage\n\tload r7,EventOSD_LCancel\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo Bool\n\tbl\tInitializeMatch\n\n#Make P2 a human\n\tlwz r3,0x0(r29)\n\tlwz r3,0x18(r3)\n\tli\tr4,0\n\tstb r4,0x1(r3)\n\n#STORE THINK FUNCTION\nbl\tLCancelLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\n\t########################\n\t## L Cancel LOAD FUNCT ##\n\t########################\n\tLCancelLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tLCancelThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  li  r5,0    #No Option Menu\n\tbl\tCreateEventThinkFunction\n\n\tb\tLCancelLoadExit\n\n\n\n\t\t#########################\n\t\t## L Cancel THINK FUNCT ##\n\t\t#########################\n\n\t\tLCancelThink:\n\t\tblrl\n\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n\t\tbackup\n\n\t\tlwz\tEventData,0x2c(r3)\n\n    bl GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tLCancelNotFirstFrame\n\n    #Init Positions\n      bl  PlacePlayersCenterStage\n\t\t#Check if P2-P4 Is Using the Event\n\t\t\tli\tr4,0x1\t\t#Make CPU Controlled by P2\n\t\t\tlbz\tr3, -0x5108 (r13)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tLCancelIsP1\n\t\t\tli\tr4,0x0\n    LCancelIsP1:\n\t\t\tstb\tr4,0x618(r29)\n    #Clear Inputs\n      bl  RemoveFirstFrameInputs\n    #Save State\n      addi r3,EventData,EventData_SaveStateStruct\n\t\t\tli\tr4,1\t\t\t\t\t\t\t\t\t#Override failsafe code\n      bl  SaveState_Save\n\t\tLCancelNotFirstFrame:\n\n\t\t#Check For P2 Dpad Down Press\n\t\t\tlwz\tr3,0x668(r29)\t\t\t\t\t#Inputs\n\t\t\trlwinm.\tr0,r3,0,29,29\n\t\t\tbeq\tLCancelThink_CheckForInvinc\n\t\t#Toggle Invinc Bit\n\t\t\tlbz\tr3,0x0(r31)\n\t\t\tnand \t3,3,3\n\t\t\tstb\tr3,0x0(r31)\n\n\n\n\t\tLCancelThink_CheckForInvinc:\n\t\t\tlbz\tr3,0x0(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tLCancelThink_RemoveInvincibility\n\t\t#Give No Knockback To P2\n\t\t\tlbz r3,0x2220(P2Data)\n\t\t\tli\tr4,1\n\t\t\trlwimi r3,r4,4,27,27\n\t\t\tstb r3,0x2220(P2Data)\n\t\t#Ignore Grabs\n\t\t\tli\tr3,0x1FF\n\t\t\tsth r3,0x1A6A(P2Data)\n\t\t#Ignore Percent\n\t\t\tli\tr3,0\n\t\t\tbl\tIntToFloat\n\t\t\tstfs f1,0x1830(P2Data)\n\t\t\tlbz r3,0xC(P2Data)\n\t\t\tli\tr4,0\n\t\t\tli\tr5,0\n\t\t\tbranchl r12,0x80034418\n\t\t#Un-nudgeable\n\t\t\tli\tr3,0x1\n\t\t\tlbz\tr0, 0x221D (P2Data)\n\t\t\trlwimi\tr0,r3,2,29,29\n\t\t\tstb\tr0, 0x221D (P2Data)\n\t\t#Apply Overlay\n\t\t\tmr\tr3,P2Data\n\t\t\tli\tr4,9\n\t\t\tli\tr5,0\n\t\t\tbranchl r12,0x800bffd0\n\t\t\tb\tLCancelThink_SkipInvincibility\n\t\tLCancelThink_RemoveInvincibility:\n\t\t#Give Invincibility To P2\n\t\t\tlbz r3,0x2220(P2Data)\n\t\t\tli\tr4,0\n\t\t\trlwimi r3,r4,4,27,27\n\t\t\tstb r3,0x2220(P2Data)\n\t\t#Allow Grabs\n\t\t\t#li\tr3,0x0\n\t\t\t#sth r3,0x1A6A(P2Data)\n\t\t#Allow Percent\n\t\t\t#li\tr3,1\n\t\t\t#bl\tIntToFloat\n\t\t\t#stfs f1,0x182C(P2Data)\n\t\t#Nudgeable\n\t\t\tli\tr3,0x0\n\t\t\tlbz\tr0, 0x221D (P2Data)\n\t\t\trlwimi\tr0,r3,2,29,29\n\t\t\tstb\tr0, 0x221D (P2Data)\n\t\t#Remove Overlay\n\t\t\tmr\tr3,P2Data\n\t\t\tli\tr4,9\n\t\t\tbranchl r12,0x800c0200\n\t\tLCancelThink_SkipInvincibility:\n\n\t\tLCancelThink_CheckForSaveState:\n\t\t#Check For Savestates\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tCheckForSaveAndLoad\n\n    mr  r3,P1GObj\n    mr  r4,P2GObj\n    addi r5,EventData,EventData_SaveStateStruct\n\t\tbl\tMoveCPU\n\t\tbl\tGiveFullShields\n\t\taddi r3,EventData,EventData_SaveStateStruct+(1*0x8)\n\t\tbl\tDPadCPUPercent\n\t\tbl\tUpdateAllGFX\n\n\tLCancelLoadExit:\n\trestore\n\tblr\n\n\n\n\n################################################################################\n################################################################################\n#endregion\n\n#region Ledgedash Training\n\n###########################\n## Ledgedash HIJACK INFO ##\n###########################\n\nLedgedash:\n\n#SET EVENT TYPE TO KOs\n\tload\tr5,0x8045abf0\t\t#Static Match Struct\n\tlbz\tr3,0xB(r5)\t\t#Get Event Score Behavior Byte\n\tli\tr4,0x0\n\trlwimi\tr3,r4,1,30,30\t\t#Zero Out Time Bit\n\tstb\tr3,0xB(r5)\t\t#Set Event Score Behavior Byte\n\n#Make HUD Centered For 1P and No Timer\n\tli\tr3,0x0430\n\tsth\tr3,0x0(r26)\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t\t#Use SSS Stage\n\tload r7,EventOSD_Ledgedash\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo Bool\n\tbl\tInitializeMatch\n\n#1 Player\n\tlwz r4,0x0(r29)\n\tli\tr3,0x20\n\tstb\tr3,0x1(r9)\n\n#STORE THINK FUNCTION\nLedgedashStoreThink:\nbl\tLedgedashLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Ledgedash LOAD FUNCT ##\n\t########################\n\tLedgedashLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tLedgedashThink\n\tmflr\tr3\n\tli\tr4,9\t\t#Priority (After Interrupt)\n  bl  LedgedashWindowInfo\n  mflr r5\n  bl LedgedashWindowText\n  mflr r6\n\tbl\tCreateEventThinkFunction\n\n\tbl\tInitializeHighScore\n\n#Remove randall\n\tlwz\tr3,StageID_External(r13)\n\tcmpwi\tr3,YoshiStory\n\tbne\tLedgedashLoad_SkipRemoveRandall\n#Get randall's map_gobj\n\tli\tr3,2\t\t\t\t#randalls map_gobj is 2\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,Stage_Destroy_map_gobj\nLedgedashLoad_SkipRemoveRandall:\n\n\tb\tLedgedashLoadExit\n\n\n\t\t#########################\n\t\t## Ledgedash THINK FUNCT ##\n\t\t#########################\n\n    #Registers\n    .set REG_EventData,31\n    .set MenuData,27\n    .set P1GObj,30\n    .set P1Data,29\n\n    #Offsets\n\t\t.set firstFrameFlag,0x0\n\t\t.set eventState,0x1\n\t\t.set hitboxFoundFlag,0x2\n    .set currentLedge,0x3\n\t\t.set timer,0x4\n\t\t.set CameraBox,0x8\n\t\t.set StartingLocation,(MenuData_OptionMenuMemory+0x2+0x0)\n\t\t.set AutoRestore,(MenuData_OptionMenuMemory+0x2+0x1)\n    .set StartingLocationToggled,(MenuData_OptionMenuToggled+0x0)\n\t\t.set AutoRestoreToggled,(MenuData_OptionMenuToggled+0x1)\n\n\t\tLedgedashThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tREG_EventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\t\tlwz   MenuData,EventData_MenuDataPointer(REG_EventData)\n\n    bl    GetAllPlayerPointers\n\t\tmr\t\tP1GObj,r3\t\t\t#player block in r30\n\t\tmr\t\tP1Data,r4\t\t\t#player data in r29\n\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tLedgedashThinkMain\n\n\t\t\t#Create Camera Box\n\t\t\t\tbranchl\tr12,CreateCameraBox\n\t\t\t\tstw r3,CameraBox(r31)\n\t\t\t#Place on Ledge\n\t\t\t\tmr r3,REG_EventData\n\t\t\t\tli\tr4,0\n\t\t\t\tbl\tLedgedash_PlaceOnLedge\n\t\t\t#Set Camera To Be Zoomed Out More\n\t\t\t\tload\tr4,0x8049e6c8\n\t\t\t\tload\tr3,0x3FE66666\n\t\t\t\tstw\tr3,0x28(r4)\n\t\t\t#Set Tangible Frames High So It Doesn't Constantly Show\n\t\t\t\tli\tr3,100\n\t\t\t\tstw\tr3,0x2408(r29)\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n\t\t\t#Save State\n\t\t\t\taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n\t\t\t\tbl\tSaveState_Save\n\n\t\t\t#Set Frame 1 As Over\n\t\t\t\tli\t\tr3,0x1\n\t\t\t\tstb\t\tr3,firstFrameFlag(r31)\n\n\n\t\tLedgedashThinkMain:\n\n\t\t#Update HUD Score\n\t\tlhz\tr3,-0x4ea8(r13)\n\t\tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\n\t\t#Check If Toggled Starting Location\n\t\t\tlbz r3,StartingLocationToggled(MenuData)\n      cmpwi r3,0x0\n\t\t\tbeq\tLedgedash_SkipToggledLoadState\n\t\t\tb\t\tLedgedash_LoadState\n\t\tLedgedash_SkipToggledLoadState:\n\n\t\t#Reset If Anyone Dies\n\t\t\tbl\tIsAnyoneDead\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tLedgedash_LoadState\n\n\t\t#Infinite Time While on Rebirth Platform\n\t\t\tlwz\tr3,0x10(P1Data)\n\t\t\tcmpwi\tr3,0xD\n\t\t\tbne\tLedgedashSkipRebirthTimer\n\t\t\tli\tr3,0x2\n\t\t\tstw\tr3,0x2340(P1Data)\n\t\tLedgedashSkipRebirthTimer:\n\n    #Infinite Time While Holding Ledge\n      lwz\tr3,0x10(P1Data)\n      cmpwi\tr3,0xFD\n      bne\tLedgedashSkipCliffTimer\n      li  r3,2\n      bl  IntToFloat\n      stfs f1,0x2344(P1Data)\n    LedgedashSkipCliffTimer:\n\n\t\t#Make sure nothing else besides Z is held\n\t\t\tlhz\tr3,0x662(P1Data)\n\t\t\trlwinm.  r0,r3,0,27,27\n      bne 0xC\n      cmpwi r3,0x0\n\t\t\tbne GetProgressAndAS\n\t\t#CHECK FOR DPAD TO CHANGE LEDGE\n\t\t\tlwz\tr3,0x668(P1Data)\t\t\t#Get DPad\n\t\t\trlwinm.\tr0,r3,0,30,30\n\t\t\tbeq\tLedgedash_CheckLeft\n\t\t#Load Most Recent State\n\t\t\taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\tbl\t\tSaveState_Load\n\t\t#Place on Right Ledge\n\t\t\tmr r3,REG_EventData\n\t\t\tli\tr4,1\n\t\t\tbl\tLedgedash_PlaceOnLedge\n\t\t#Save State\n\t\t\taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\tli\tr4,1\t\t\t#Override failsafe code\n\t\t\tbl\t\tSaveState_Save\n\t\t\tb\tLedgedash_LoadState\n\t\tLedgedash_CheckLeft:\n\t\t\trlwinm.\tr0,r3,0,31,31\n\t\t\tbeq\tGetProgressAndAS\n\t\t#Load Most Recent State\n\t\t\taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\tbl\t\tSaveState_Load\n\t\t#Place on Left Ledge\n\t\t\tmr r3,REG_EventData\n\t\t\tli\tr4,0\n\t\t\tbl\tLedgedash_PlaceOnLedge\n\t\t#Save State\n\t\t\taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\tli\tr4,1\t\t\t#Override failsafe code\n\t\t\tbl\t\tSaveState_Save\n\t\t\tb\tLedgedash_LoadState\n\n\t\tGetProgressAndAS:\n\t\t#Check If AutoRestore is enabled\n\t\t\tlbz\tr3,AutoRestore(MenuData)\n\t\t\tcmpwi r3,0x1\n\t\t\tbeq\tLedgedashThinkEnd\n\t\t#Check If Timer Is Set\n\t\t\tlbz\tr3,timer(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbgt\tLedgedash_CheckToReset\n\t\t#Get Progress + AS\n\t\t\tlbz\tr3,eventState(r31)\t\t#Progress Byte\n\n\t\tbl\tLedgedashSkipJumpTable\n\t\tbl\tLedgedashProg0\n\t\tbl\tLedgedashProg1\n\t\tbl\tLedgedashProg2\n\t\tbl\tLedgedashProg3\n\t\tbl\tLedgedashProg4\n\n\t\tLedgedashSkipJumpTable:\n\t\tmflr\tr4\t\t#Jump Table Start in r4\n\t\tmulli\tr5,r3,0x4\t\t#Each Pointer is 0x4 Long\n\t\tlwzx\tr3,r4,r5\t\t#Get bl Instruction\n\t\trlwinm\tr3,r3,0,6,29\t\t#Mask Bits 6-29 (the offset)\n\t\tadd\tr3,r4,r3\t\t#Gets Address in r3\n\t\tadd\tr3,r3,r5\t\t#Offset From Start Of Jump Table\n\n\t\t#Init Loop\n\t\tsubi\tr3,r3,0x2\n\t\tlwz\tr6,0x10(r29)\t\t#AS\n\n\t\t#Check For BlackListed AS\n\t\t## Terminator = FFFF\n\t\t## Jump to    = 7FXX\n\t\tLedgedashASCheckLoop:\n\t\t\tlhzu\tr4,0x2(r3)\t\t#Get Next Value\n\t\t\textsb\tr0,r4\n\t\t\tcmpwi\tr0,-1\t\t#Check For Terminator\n\t\t\tbeq\tLedgedash_ResetProg\n\t\t\trlwinm\tr0,r4,0,15,23\t\t#Isolate Left Half\n\t\t\tcmpwi\tr0,0x7F00\t\t#Check If New \"Jump To\"\n\t\t\tbne\tLedgedashCompareAS\n\t\t\trlwinm\tr5,r4,0,24,31\t\t#Isolate Right Half to r5\n\t\t\tb\tLedgedashASCheckLoop\n\t\tLedgedashCompareAS:\n\t\t\tcmpw\tr6,r4\n\t\t\tbne\tLedgedashASCheckLoop\n\t\t\tstb\tr5,0x1(r31)\t\t#Progress Byte\n\t\t\tb\tLedgedashThinkEnd\n\n\n\t\tLedgedashThinkEnd:\n\t    mr  r3,MenuData\n\t    bl  ClearToggledOptions\n\t\t\trestore\n\t\t\tblr\n\n\n\t\t####################\n\t\t## Reset Progress ##\n\t\t####################\n\n\t\tLedgedash_ResetProg:\n\t\t#Check If On Ground\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tLedgedash_Reset\n\t\t#Check If Dead\n\t\t\tlbz\tr3,0x221F(r29)\n\t\t\trlwinm.\tr3,r3,0,25,25\n\t\t\tbne\tLedgedash_Reset\n\t\t#Check If Frame 9 Of Wrong Move\n\t\t\tli\tr3,9\n\t\t\tbl\tIntToFloat\n\t\t\tlfs\tf2,0x894(r29)\t\t#Frames in State\n\t\t\tfcmpo\tcr0,f2,f1\n\t\t\tblt\tLedgedashThinkEnd\n\n\t\tLedgedash_Reset:\n\t\t#Play Success or Failure Noise\n\t\t\tlhz\tr3,TM_OneASAgo(r29)\t\t\t#Check Prev AS\n\t\t\tcmpwi\tr3,ASID_LandingFallSpecial\t\t\t#If Landing, Success\n\t\t\tbeq\tLedgedash_PlaySuccess\n\t\t\tcmpwi\tr3,ASID_Wait\t\t\t#If Wait, Success (Frame Perfect Action)\n\t\t\tbeq\tLedgedash_PlaySuccess\n\n\t\t\tlwz\tr3,CurrentAS(r29)\n\t\t\tcmpwi\tr3,ASID_Landing\t\t\t#If Aerial Interrupt, Check If Can IASA Yet\n\t\t\tbeq\tLedgedash_AerialInterruptCheck\n\t\t\tcmpwi\tr3,ASID_Wait\t\t\t#If No Impact Land, Success\n\t\t\tbeq\tLedgedash_PlaySuccess\n\n\t\tb\tLedgedash_PlayFailure\n\n\t\tLedgedash_AerialInterruptCheck:\n\t\t#Check If Coming From an Aerial Attack\n\t\tlhz\tr3,TM_OneASAgo(r29)\t\t\t#Check Prev AS\n\t\tcmpwi\tr3,ASID_AttackAirN\n\t\tblt\tLedgedash_PlayFailure\n\t\tcmpwi\tr3,ASID_AttackAirLw\n\t\tbgt\tLedgedash_PlayFailure\n\n\t\t#Check If Interruptable Yet\n\t\tlfs\tf2,0x1F4(r29)\t\t\t#Check Which Frame Landing is Interruptable\n\t\tli\tr3,1\n\t\tbl\tIntToFloat\n\t\tfsubs\tf1,f2,f1\t\t\t#Sub 1 Because Order of Operations\n\t\tlfs\tf2,0x894(r29)\t\t\t#Check Current Frame\n\t\tfcmpo\tcr0,f2,f1\n\t\tblt\tLedgedashThinkEnd\n\n\t\tLedgedash_PlaySuccess:\n\t\t#Increment Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\t#Check To Make New High Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tlhz\tr4,-0x4ea6(r13)\n\t\t\tcmpw\tr3,r4\n\t\t\tble\tLedgedash_PlaySuccess_PlaySound\n\t\t#Copy To High Score\n\t\t\tsth\tr3,-0x4ea6(r13)\n\t\tLedgedash_PlaySuccess_PlaySound:\n\t\t#Play Sound\n\t\t\tli\t\tr3,0xAD\n\t\t\tbl PlaySFX\n\t\t#Set Timer\n\t\t\tli\tr3,30\n\t\t\tstb\tr3,timer(r31)\n\t\t\tb\tLedgedashThinkEnd\n\n\t\tLedgedash_PlayFailure:\n\t\t#Reset Score\n\t\t\tli\tr3,0\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\t#Play Sound\n\t\t\tli\tr3,0xAF\n\t\t\tLedgedash_PlaySound:\n\t\t\tbl PlaySFX\n\t\t#Place on Ledge\n\t\t\tmr r3,REG_EventData\n\t\t\tlbz\tr4,currentLedge(REG_EventData)\n      bl Ledgedash_PlaceOnLedge\n\t\t\tb\tLedgedash_LoadState\n\n\n\t\tLedgedash_CheckToReset:\n\t\tlbz\tr3,timer(r31)\t\t\t\t#Check If Timer is Set\n\t\tcmpwi\tr3,0x0\n\t\tble\tLedgedashThinkEnd\n\n\t\tLedgedash_CheckForInvincibleMove:\n\t\tlbz\tr3,hitboxFoundFlag(r31)\t\t\t\t#Check If Hitbox Was Already Found\n\t\tcmpwi\tr3,0x1\n\t\tbeq\tLedgedash_DecrementTimer\n\t\tlwz\tr3,0x1990(r29)\t\t\t\t#Check If Char is Invincible\n\t\tcmpwi\tr3,0x0\n\t\tble\tLedgedash_DecrementTimer\n\t\tmr\tr3,r30\t\t\t\t#Check If a Hitbox is Active\n\t\tbl\tCheckForActiveHitboxes\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tLedgedash_DecrementTimer\n\t\tli\tr3,0xAA\t\t\t\t#Play Sound\n\t\tbranchl\tr12,SFX_PlaySoundAtFullVolume\n\t\tli\tr3,1\t\t\t\t#Mark As Found\n\t\tstb\tr3,hitboxFoundFlag(r31)\n\n\t\tLedgedash_DecrementTimer:\n\t\t\tlbz\tr3,timer(r31)\n\t\t\tsubi\tr3,r3,0x1\t\t\t#Decrement\n\t\t\tstb\tr3,timer(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbgt\tLedgedashThinkEnd\n    #Load State (to cleanup volatile entities)\n      addi r3,REG_EventData,EventData_SaveStateStruct\n      bl\t\tSaveState_Load\n\t\t#Place on Ledge\n\t\t\tmr r3,REG_EventData\n\t\t\tlbz\tr4,currentLedge(REG_EventData)\n      bl\tLedgedash_PlaceOnLedge\n    #Save State\n      addi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\tli\tr4,1\t\t\t\t\t\t\t#Override failsafe code\n      bl\t\tSaveState_Save\n\n\t\tLedgedash_LoadState:\n\t\t#Reset all event variables\n\t\t\tli\t\tr3,0x0\n\t\t\tstb\t\tr3,eventState(r31)\t\t\t\t#Progress Byte\n\t\t\tstb\t\tr3,hitboxFoundFlag(r31)\t\t#Invincible Move Bool\n\t\t\tstb\t\tr3,timer(r31)\t\t\t\t\t\t\t#Timer\n\t\t\taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\tbl\t\tSaveState_Load\n\t\t#Create Respawn Platform If Enabled\n\t\t\tlbz\t\tr3,StartingLocation(MenuData)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tLedgedash_LoadState_SkipRespawnPlatform\n\t\t#Remember Facing Direction (Rebirth changes this)\n\t\t\tlfs\tf31,0x2C(r29)\n\t\t#Enter P1 Into Rebirth Again\n\t\t\tmr\tr3,r30\n\t\t\tbranchl\tr12,AS_Rebirth\n\t\t#Restore Facing Direction\n\t\t\tstfs\tf31,0x2C(r29)\n\t\t#Randomize Location\n\t\t#Get Stage's Ledges\n\t\t\tlwz\t\tr3,-0x6CB8 (r13)\t\t\t#External Stage ID\n\t\t\tbl\t\tLedgedashCliffIDs\n\t\t\tmflr  r4\n\t\t\tmulli\tr3,r3,0x2\n\t\t\tlhzx\tr3,r3,r4\n\t\t#Get Correct Ledge From Facing Direction\n\t\t\tlfs\tf1, 0x002C (r29)\n\t\t\tlfs\tf0, -0x7660 (rtoc)\n\t\t\tfcmpo\tcr0,f1,f0\n\t\t\tble\tLedgedash_LoadState_GetRightLedge\n\t\tLedgedash_LoadState_GetLeftLedge:\n\t\t#Get Ledge X and Y Coordinates\n\t\t\trlwinm\tr3,r3,24,24,31\n\t\t\taddi\tr4,sp,0x80\n\t\t\tbranchl\tr12,Stage_GetLeftOfLineCoordinates\n\t\t\tb\tLedgedash_LoadState_RandomizePosition\n\t\tLedgedash_LoadState_GetRightLedge:\n\t\t#Get Ledge X and Y Coordinates\n\t\t\trlwinm\tr3,r3,0,24,31\n\t\t\taddi\tr4,sp,0x80\n\t\t\tbranchl\tr12,Stage_GetRightOfLineCoordinates\n\t\tLedgedash_LoadState_RandomizePosition:\n\t\t#Get Random Distance from this\n\t\t\t.set RandomDistanceMinX,30\n\t\t\t.set RandomDistanceMaxX,55\n\t\t\t.set RandomDistanceMinY,-30\n\t\t\t.set RandomDistanceMaxY,30\n\t\t\tli\tr3,RandomDistanceMinX\n\t\t\tli\tr4,RandomDistanceMaxX\n\t\t\tbl\tRandFloat\n\t\t\tfmr\tf31,f1\n\t\t\tli\tr3,RandomDistanceMinY\n\t\t\tli\tr4,RandomDistanceMaxY\n\t\t\tbl\tRandFloat\n\t\t\tfmr\tf30,f1\n\t\t#Add to Ledge Coordinates\n\t\t\tlfs\tf1,0x2C(r29)\t#Facing Direction\n\t\t\tfneg f1,f1\n\t\t\tfmuls f31,f1,f31\n\t\t\tlfs\tf0,0x80(sp)\t\t#Ledge X\n\t\t\tfadds f31,f0,f31\n\t\t\tlfs\tf1,0x84(sp)\t\t#Ledge Y\n\t\t\tfadds f30,f1,f30\n\t\t#Store to Player Block\n\t\t\tstfs f31,0xB0(r29)\n\t\t\tstfs f30,0xB4(r29)\n\t\t#Enter RebirthWait\n\t\t\tmr\t\tr3,r30\n\t\t\tbranchl\t\tr12,AS_RebirthWait\n\t\t#Store Blr as Physics\n\t\t\tbl\t\tBlrFunctionPointer\n\t\t\tmflr\t\tr3\n\t\t\tstw\t\tr3,0x21A4(r29)\n\t\t#Store Custom RebirthWait Interrupt\n\t\t\tbl\tCustom_InterruptRebirthWait\n\t\t\tmflr\tr3\n\t\t\tstw\t\tr3,0x219C(r29)\n    #Update RebirthPlat Position\n      mr  r3,P1GObj\n      branchl r12,RebirthPlatform_UpdatePosition\n\n\t\tLedgedash_LoadState_SkipRespawnPlatform:\n      mr  r3,r30\n      bl  UpdatePosition\n    #Update Camera Box\n      mr  r3,P1GObj\n      bl  UpdateCameraBox\n\n\t\tb\t\tLedgedashThinkEnd\n\n\n\t\t#####################\n\t\t## PlaceAboveLedge ##\n\t\t#####################\n\t\tLedgedash_PlaceOnLedge:\n    backup\n\n\t\t.set\tREG_EventData,31\n\t\t.set\tREG_P1GObj,30\n\t\t.set\tREG_P1Data,29\n\t\t.set\tREG_LedgeID,28\n\t\t.set\tREG_CameraBox,28\n\n\t\t#Init\n\t\t\tmr\tREG_EventData,r3\n\t\t\tmr\tREG_LedgeID,r4\n\t\t\tstb\tREG_LedgeID,currentLedge(REG_EventData)\n\t\t#Get P1 data\n\t\t\tli\tr3,0\n\t\t\tbranchl\tr12,PlayerBlock_LoadMainCharDataOffset\n\t\t\tmr\tREG_P1GObj,r3\n\t\t\tlwz\tREG_P1Data,0x2C(REG_P1GObj)\n\n\t\t#Place on ledge\n\t\t\tmr\tr3,REG_P1GObj\n\t\t\tmr\tr4,REG_LedgeID\n\t\t\tbl\tPlaceOnLedge\n\n\t\t#RESET PROGRESS\n\t\t\tli\t\tr3,0x0\n\t\t\tstb\t\tr3,eventState(REG_EventData)\n\n\t\t#Get Stage's Ledge IDs\n\t\t\tlwz\t\tr3,-0x6CB8 (r13)\t\t\t#External Stage ID\n\t\t\tbl\t\tLedgedashCliffIDs\n\t\t\tmflr  r4\n\t\t\tmulli\tr3,r3,0x2\n\t\t\tlhzx\tr3,r3,r4\n\t\t#Get Requested Ledge\n\t\t\tcmpwi REG_LedgeID,0x0\n\t\t\tbeq\tLedgedash_PlaceOnLedge_GetLeftLedgeID\n\t\tLedgedash_PlaceOnLedge_GetRightLedgeID:\n\t\t\trlwinm\tr21,r3,0,24,31\n\t\t\tb\tLedgedash_PlaceOnLedge_SkipLedgeID\n\t\tLedgedash_PlaceOnLedge_GetLeftLedgeID:\n\t\t\trlwinm\tr21,r3,24,24,31\n\t\tLedgedash_PlaceOnLedge_SkipLedgeID:\n\n\t\t#Adjust Ledge Camera Box Accordingly\n\t\t#Get Ledge Coordinates\n\t\t\tmr\tr3,r21\n\t\t\taddi\tr4,sp,0xD0\n\t\t\tlfs\tf1, 0x002C (REG_P1Data)\n\t\t\tlfs\tf0, -0x7660 (rtoc)\n\t\t\tfcmpo\tcr0,f1,f0\n\t\t\tble Ledgedash_PlaceOnLedge_CameraBoxRightLedge\n\t\tLedgedash_PlaceOnLedge_CameraBoxLeftLedge:\n\t\t\tbranchl\tr12,Stage_GetLeftOfLineCoordinates\n\t\t\tb\tLedgedash_PlaceOnLedge_UpdateCameraBox\n\t\tLedgedash_PlaceOnLedge_CameraBoxRightLedge:\n\t\t\tbranchl r12,Stage_GetRightOfLineCoordinates\n\t\tLedgedash_PlaceOnLedge_UpdateCameraBox:\n\t\t#Get CameraBox\n\t\t\tlwz REG_CameraBox,CameraBox(REG_EventData)\n\t\t#Position Base of CameraBox behind the ledge\n\t\t.set CameraBoxXOffset,35\n\t\t.set CameraBoxYOffset,20\n\t\t\tli\tr3,CameraBoxXOffset\n\t\t\tbl\tIntToFloat\n\t\t\tlfs f2,0xD0(sp)\t\t#Ledge X\n\t\t\tlfs f3,0x2C(REG_P1Data)\n\t\t\tfmadds f1,f1,f3,f2\n\t\t\tstfs f1,0x10(REG_CameraBox)  #Camera X Position\n\t\t\tli\tr3,CameraBoxYOffset\n\t\t\tbl\tIntToFloat\n\t\t\tlfs f2,0xD4(sp)\t\t#Ledge Y\n\t\t\tfadds f1,f1,f2\n\t\t\tstfs f1,0x14(REG_CameraBox)  #Camera Y Position\n\t\t#Make Boundaries around ledge position\n\t\t#Left Bound\n\t\t\tli\tr3,-10\n\t\t\tbl\tIntToFloat\n\t\t\tstfs\tf1,0x40(REG_CameraBox)\n\t\t#Right Bound\n\t\t\tli\tr3,10\n\t\t\tbl\tIntToFloat\n\t\t\tstfs\tf1,0x44(REG_CameraBox)\n\t\t#Top Bound\n\t\t\tli\tr3,10\n\t\t\tbl\tIntToFloat\n\t\t\tstfs\tf1,0x48(REG_CameraBox)\n\t\t#Lower Bound\n\t\t\tli\tr3,-10\n\t\t\tbl\tIntToFloat\n\t\t\tstfs\tf1,0x4C(REG_CameraBox)\n\n    #Update Camera Box\n      mr  r3,REG_P1GObj\n      bl  UpdateCameraBox\n\n\t\trestore\n\t\tblr\n\n####################################\n\nLedgedashCliffIDs:\nblrl\n.long 0xFFFFFFFF #Dummy, TEST\n.long 0x03073336 #FoD, Pokemon Stadium\n.long 0x030D2945 #Peach's Castle, Kongo Jungle\n.long 0x0511091A #Brinstar, Corneria\n.long 0x02061517 #Yoshi's Story, Onett\n.long 0x0000434C #Mute City, Rainbow Cruise\n.long 0x00000000 #Jungle Japes, Great Bay\n.long 0x0E0D0000 #Hyrule Temple, Brinstar Depths\n.long 0x00051E2E #Yoshi's Island, Green Greens\n.long 0x0C0E0204 #Fourside, MKI\n.long 0x03050000 #MKII, Akaneia\n.long 0x06120000 #Venom, PokeFloats\n.long 0xD7E20000 #Big Blue, Icicle Mountain\n.long 0x00000000 #Icetop, Flatzone\n.long 0x0305030B #Dream Land, Yoshis Island 64\n.long 0x06100005 #Kongo Jungle 64, Battlefield\n.long 0x00020101 #Final Destination\n\n\n\n####################################\n#CliffWait -> Fall\nLedgedashProg0:\n#*********************#\n.hword 0x7F00\n.hword ASID_CliffCatch,ASID_CliffWait\n.hword ASID_RebirthWait\n#*********************#\n.hword 0x7F01\n.hword ASID_Fall\n#*********************#\n.hword 0x7F02\n.hword ASID_JumpAerialF,ASID_JumpAerialB\n#*********************#\n.hword -1\n.align 2\n\n#Fall -> JumpAerial\nLedgedashProg1:\n.hword 0x7F00\n.hword ASID_CliffCatch,ASID_CliffWait\n#*********************#\n.hword 0x7F01\n.hword ASID_Fall,ASID_PassiveWallJump\n#*********************#\n.hword 0x7F02\n.hword ASID_JumpAerialF,ASID_JumpAerialB\n.hword ASID_FallSpecial,ASID_CliffJumpSlow2\n.hword ASID_FallAerial,0x17E\n.hword 0x166,0x167\n.hword 0x170,0x164\n.hword 0x155,0x15e\n.hword 0x15f,0x160\n.hword 0x16B,0x171\n.hword 0x15C,0x16D\n.hword 0x165,0x16E\n.hword 0x168,0x161\n.hword 0x176,0x15D\n.hword 0x169,0x162\n#*********************#\n.hword -1\n.align 2\n\n\n#JumpAerial -> Airdodge\nLedgedashProg2:\n#*********************#\n.hword 0x7F02\n.hword ASID_JumpAerialF,ASID_PassiveWallJump\n.hword ASID_JumpAerialB,ASID_Fall\n.hword ASID_FallSpecial,ASID_CliffJumpSlow2\n.hword ASID_FallAerial,0x17E\n.hword 0x167,0x170\n.hword 0x164,0x162\n.hword 0x15e,0x15f\n.hword 0x160,0x16B\n.hword 0x171,0x15C\n.hword 0x16D,0x16E\n.hword 0x165,0x168\n.hword 0x161,0x176\n.hword 0x15D,0x155\n.hword 0x169,0x166\n#*********************#\n.hword 0x7F03\n.hword ASID_EscapeAir,ASID_AttackAirB\n.hword ASID_AttackAirB,ASID_AttackAirU\n.hword ASID_AttackAirD,ASID_AttackAirF\n.hword ASID_AttackAirN,ASID_LandingFallSpecial\n#*********************#\n.hword 0x7F00\n.hword ASID_CliffCatch\n#*********************#\n.hword -1\n.align 2\n\n#Airdodge -> Landing\nLedgedashProg3:\n#*********************#\n.hword 0x7F03\n.hword 0xAA\t\t#i think this is just a placeholder, could prob remove but w/e\n#*********************#\n.hword 0x7F04\n.hword ASID_LandingFallSpecial,ASID_Landing\n#*********************#\n.hword -1\n.align 2\n\n\n#Landing -> Wait\nLedgedashProg4:\n#*********************#\n.hword 0x7F04\n.hword ASID_LandingFallSpecial\n#*********************#\n.hword 0x7F02\n.hword ASID_Fall\n#*********************#\n.hword -1\n.align 2\n\n\n####################################\n\nLedgedashWindowInfo:\nblrl\n.long 0x010101FF  #1 window, Respawn Platform has 2 options, AutoRestore has 2 options\n\nLedgedashWindowText:\nblrl\n\n#Option Title = Starting Location\n.string \"Starting Location\"\n.align 2\n\n#Option 1 = Ledge\n.string \"Ledge\"\n.align 2\n\n#Option 2 = Respawn Platform\n.string \"Respawn Platform\"\n.align 2\n\n#Option Title = AutoRestore\n.string \"AutoRestore\"\n.align 2\n\n#Option 1 = On\n.string \"On\"\n.align 2\n\n#Option 2 = Off\n.string \"Off\"\n.align 2\n\n\n####################################\n\nLedgedashLoadExit:\nrestore\nblr\n\n#endregion\n\n#region SDI Training\n##############################\n## SDI Training HIJACK INFO ##\n##############################\n\nSDITraining:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Fox.Ext\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,FinalDestination\t\t\t#Use SSS Stage\n\tload r7,EventOSD_SDI\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#Make default color\n\tlwz\tr3,0x0(r29)\n\tlwz\tr3,0x18(r3)\t\t#p2 pointer\n\tli  r4,0x0\n\tstb r4,0x3(r3)    #Default color\n\n#STORE THINK FUNCTION\nSDITrainingStoreThink:\nbl\tSDITrainingLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\n\t########################\n\t## SDI Training LOAD FUNCT ##\n\t########################\n\tSDITrainingLoad:\n\tblrl\n\n\tbackup\n\n\tbl\tInitializeHighScore\n\n\t#Schedule Think\n\tbl\tSDITrainingThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  li  r5,0    #No Option Menu\n\tbl\tCreateEventThinkFunction\n\n\tb\tSDITrainingLoadExit\n\n\n\t\t#########################\n\t\t## SDI Training THINK FUNCT ##\n\t\t#########################\n\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n\t\tSDITrainingThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tli\tr3,0xF\n\t\tstw\tr3,0x1A94(r29)\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tSDITrainingThinkMain\n\n  \t\t\tbl\tSDITrainingFloats\n  \t\t\tmflr\tr3\n  \t\t\tbl\tEvent_EnterGrab\n\t\t\t#Store 999 To Breakout\n  \t\t\tlis\tr3,0x4461\n  \t\t\tstw\tr3,0x1A4C(r27)\n\t\t\t#Give Percent\n  \t\t\tbl\tSDITrainingStartingPercents\n  \t\t\tmflr\tr4\n  \t\t\tlwz\tr3,0x4(r27)\t\t#Get Char ID\n  \t\t\tlbzx\tr3,r3,r4\t\t#Get Percent\n  \t\t\tload\tr4,0x80453080\t\t#P1 Static Block\n  \t\t\tsth\tr3,0x60(r4)\t\t#Store Percent Int To Display Value\n  \t\t\tsth\tr3,0x62(r4)\t\t#Store Percent Int To Display Value (Subchar)\n  \t\t\tbl\tIntToFloat\n  \t\t\tstfs\tf1,0x1830(r27)\t\t#Store to Actual Damage Value\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n\t\t\t#Save State\n  \t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n  \t\t\tbl\tSaveState_Save\n\t\t\t#Random Start Time\n  \t\t\tli\tr3,60\n  \t\t\tbranchl\tr12,HSD_Randi\n  \t\t\tli\tr4,0\n  \t\t\tsub\tr3,r4,r3\n  \t\t\tstw\tr3,0x4(r31)\t\t#Reset Timer\n\n\n\t\tSDITrainingThinkMain:\n\n\t\t#Inc Timer\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tstw\tr3,0x4(r31)\n\n\t\t#Check If SDI'd UpAir (Damage_LightHit + No Hitstun)\n\t\t#Check If Already Incremented\n\t\t\tlbz\tr3,0xA(r31)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbeq\tSDITraining_SkipSDICheck\n\t\t#Check AS\n\t\t\tlwz\tr3,0x10(r27)\n\t\t\tcmpwi\tr3,0x55\n\t\t\tbne\tSDITraining_SkipSDICheck\n\t\t#Check For Hitstun\n\t\t\tlbz\tr3, 0x221C (r27)\n\t\t\trlwinm.\tr0, r3, 31, 31, 31\n\t\t\tbne\tSDITraining_SkipSDICheck\n\t\t#Set Flag\n\t\t\tli\tr3,0x1\n\t\t\tstb\tr3,0xA(r31)\n\t\t#Play Sound\n\t\t\tli\t\tr3,0xAD\n\t\t\tbl PlaySFX\n\t\t#Increment Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\t#Check To Make New High Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tlhz\tr4,-0x4ea6(r13)\n\t\t\tcmpw\tr3,r4\n\t\t\tble\tSDITraining_SkipSDICheck\n\t\t#Copy To High Score\n\t\t\tsth\tr3,-0x4ea6(r13)\n\t\tSDITraining_SkipSDICheck:\n\n\t\t#Check If Missed SDI\t(Fox in UpAir + P1 in Damage Heavy State)\n\t\t#Check If Fox Is Up-Airing\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x44\n\t\t\tbne\tSDITraining_SkipMissedSDICheck\n\t\t#Check If P1 is in Hitlag\n\t\t\tlbz\tr3,0x221A(r27)\t\t\t#Check If in Hitlag\n\t\t\trlwinm.\tr3,r3,0,26,26\n\t\t\tbeq\tSDITraining_SkipMissedSDICheck\n\t\t#Check If Fox is Past Frame 11\n\t\t\tli\tr3,11\n\t\t\tbl\tIntToFloat\n\t\t\tlfs\tf2,0x894(r29)\n\t\t\tfcmpo\tcr0,f2,f1\n\t\t\tblt\tSDITraining_SkipMissedSDICheck\n\t\t#Reset Score\n\t\t\tli\tr3,0\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\tSDITraining_SkipMissedSDICheck:\n\n\t\t#Update Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\n\t\t#Check State\n\t\t\tlbz\tr3,0x8(r31)\n\t\t\tcmpwi\tr3,0\n\t\t\tbeq\tSDITrainingUpThrowThink\n\t\t\tcmpwi\tr3,1\n\t\t\tbeq\tSDITrainingFollowOpponentThink\n\t\t\tcmpwi\tr3,2\n\t\t\tbeq\tSDITrainingJumpThink\n\t\t\tcmpwi\tr3,3\n\t\t\tbeq\tSDITrainingUpAirThink\n\t\t\tcmpwi\tr3,4\n\t\t\tbeq\tSDITrainingCheckForReset\n\n\n#******************************************************#\n\n\t\tSDITrainingUpThrowThink:\n\t\t#Check Timer\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tblt\tSDITrainingThinkExit\n\t\t#Check If In Wait\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0xE\n\t\t\tbne\tSDITrainingUpThrowThink_InputUpThrow\n\n\t\t\t#Advance to Next State\n\t\t\t\tli\tr3,0x1\n\t\t\t\tstb\tr3,0x8(r31)\n\t\t\t\tb\tSDITrainingFollowOpponentThink\n\n\t\tSDITrainingUpThrowThink_InputUpThrow:\n\t\t#UpThrow\n\t\t\tli\tr3,127\n\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\tb\tSDITrainingThinkExit\n\n#******************************************************#\n\n\t\tSDITrainingFollowOpponentThink:\n\n\t\tSDITrainingFollowOpponentThink_CheckIfAirbourne:\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbne\tSDITrainingFollowOpponentThink_CheckDistance\n\t\t\tli\tr3,0x2\n\t\t\tstb\tr3,0x8(r31)\n\t\t\tb\tSDITrainingJumpThink\n\n\t\tSDITrainingFollowOpponentThink_CheckDistance:\n\t\t\t#Determine Which Distance Value\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x14\n\t\t\tbne\t0xC\n\t\t\tli\tr3,15\n\t\t\tb\t0x8\n\t\t\tli\tr3,10\n\t\t\tbl\tSDITrainingInputTowardsOpponent\n\t\t#Check If Already Jumping, If So Follow Through\n\t\t\tlwz\tr4,0x10(r29)\n\t\t\tcmpwi\tr4,0x18\n\t\t\tbeq\tSDITrainingFollowOpponentThink_CheckIfJumping\n\t\t\tcmpwi\tr3,0x1\t\t\t#Checks If In Range of Opponent\n\t\t\tbne\tSDITrainingThinkExit\n\n\t\t#Check If Jumping\n\t\tSDITrainingFollowOpponentThink_CheckIfJumping:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x18\n\t\t\tbne\tSDITrainingFollowOpponentThink_InputJump\n\t\t#If Less than 32 Mm Away, Short Hop\n\t\t\tlfs\tf1,0xB4(r27)\t\t#P1 X Coord\n\t\t\tlfs\tf2,0xB4(r29)\t\t#P2 X Coord\n\t\t\tfsubs\tf3,f2,f1\t\t#Get Difference\n\t\t\tli\tr3,32\n\t\t\tbl\tIntToFloat\n\t\t\tfabs\tf2,f3\n\t\t\tfcmpo\tcr0,f2,f1\n\t\t\tblt\tSDITrainingThinkExit\n\n\t\t#Input Jump\n\t\tSDITrainingFollowOpponentThink_InputJump:\n\t\t\tli\tr3,0x800\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tSDITrainingThinkExit\n\n#******************************************************#\n\n\t\tSDITrainingJumpThink:\n\t\t#Follow Opponent\n\t\t\tli\tr3,5\n\t\t\tbl\tSDITrainingInputTowardsOpponent\n\t\t#When Less Than 35 Mm Away in the Y Direction, Up Air\n\t\t\tlfs\tf1,0xB4(r27)\t\t#P1 X Coord\n\t\t\tlfs\tf2,0xB4(r29)\t\t#P2 X Coord\n\t\t\tfsubs\tf3,f2,f1\t\t#Get Difference\n\t\t\tli\tr3,35\n\t\t\tbl\tIntToFloat\n\t\t\tfabs\tf2,f3\n\t\t\tfcmpo\tcr0,f2,f1\n\t\t\tbgt\tSDITrainingJumpThink_CheckToDJ\n\t\t#Input UpAir\n\t\t\tli\tr3,127\n\t\t\tstb\tr3,0x1A8F(r29)\n\t\t#Set Timer To Reset\n\t\t\tli\tr3,60\n\t\t\tstb\tr3,0x9(r31)\n\t\t#Advance State\n\t\t\tli\tr3,0x3\n\t\t\tstb\tr3,0x8(r31)\n\t\t\tb\tSDITrainingUpAirThink\n\n\t\tSDITrainingJumpThink_CheckToDJ:\n\t\t#If in Frame X Of Jump, DJ\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x19\n\t\t\tbeq\tSDITrainingJumpThink_CheckToDJ_InJump\n\t\t\tcmpwi\tr3,0x1A\n\t\t\tbeq\tSDITrainingJumpThink_CheckToDJ_InJump\n\t\t\tb\tSDITrainingThinkExit\n\t\t\tSDITrainingJumpThink_CheckToDJ_InJump:\n\t\t\tli\tr3,4\n\t\t\tbl\tIntToFloat\n\t\t\tlfs\tf2,0x894(r29)\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tbne\tSDITrainingThinkExit\n\t\t#Enter DJ\n\t\t\tli\tr3,0x800\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tSDITrainingThinkExit\n\n#******************************************************#\n\n\t\tSDITrainingUpAirThink:\n\t\t#Check If UpAir Hitboxes Are Over\n\t\t\tli\tr3,12\n\t\t\tbl\tIntToFloat\n\t\t\tlfs\tf2,0x894(r29)\n\t\t\tfcmpo\tcr0,f2,f1\n\t\t\tbge\tSDITrainingCheckForReset\n\t\t#Follow Opponent\n\t\t\tli\tr3,5\n\t\t\tbl\tSDITrainingInputTowardsOpponent\n\t\t#Check If Back On Ground\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tSDITrainingCheckForReset\n\t\t#Advance State\n\t\t\tli\tr3,0x4\n\t\t\tstb\tr3,0x8(r31)\n\t\t\tb\tSDITrainingCheckForReset\n\n#******************************************************#\n\nSDITrainingInputTowardsOpponent:\n#Returns a bool indicating if the character is within range\n\nbackup\n\nmr\tr31,r3\t\t\t#Backup Distance Threshold\n\n#Get X Distance\n\tlfs\tf1,0xB0(r27)\t\t#P1 X Coord\n\tlfs\tf2,0xB0(r29)\t\t#P2 X Coord\n\tfsubs\tf3,f2,f1\t\t#Get Difference\n#If Within 4 Mm, Jump\n\tmr\tr3,r31\n\tbl\tIntToFloat\n\tfabs\tf2,f3\n\tfcmpo\tcr0,f2,f1\n\tbgt\tSDITrainingFollowOpponentThink_InputTowardsOpponent\n\tli\tr3,0x1\n\tb\tSDITrainingInputTowardsOpponent_Exit\n\nSDITrainingFollowOpponentThink_InputTowardsOpponent:\n#Push Towards Opponent's Direction\n\tbl\tGetDirectionInRelationToP1\n\tmulli\tr3,r3,-1\t\t#Negate This\n\tli\tr4,127\n\tmullw\tr3,r3,r4\n\tstb\tr3,0x1A8C(r29)\n\tli\tr3,0x0\n\nSDITrainingInputTowardsOpponent_Exit:\n\trestore\n\tblr\n\n#******************************************************#\n\n\n\t\tSDITrainingCheckForReset:\n\t\t\tlbz\tr3,0x9(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tSDITrainingThinkExit\n\t\t\tsubi\tr3,r3,0x1\n\t\t\tstb\tr3,0x9(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tSDITrainingThinkExit\n\t\t#Load State\n\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\tbl\tSaveState_Load\n\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\tbl\tSaveState_Load\n\t\t#Random Timer\n\t\t\tli\tr3,60\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tmulli\tr3,r3,-1\n\t\t\tstw\tr3,0x4(r31)\n\t\t#Reset State\n\t\t\tli\tr3,0\n\t\t\tstb\tr3,0x8(r31)\n\t\t#Reset SDI'd Flag\n\t\t\tli\tr3,0x0\n\t\t\tstb\tr3,0xA(r31)\n\n\t\tSDITrainingThinkExit:\n\t\trestore\n\t\tblr\n\n##############\n\nEvent_EnterGrab:\nbackup\n\nmr\tr20,r3\n\n#Move P1\nlfs\tf1,0x0(r20)\nstfs\tf1,0xB0(r27)\nlfs\tf1,0x4(r20)\nstfs\tf1,0xB4(r27)\nmr\tr3,r28\nbl  UpdatePosition\nmr\tr3,r28\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0\nbeq\tEvent_EnterGrab_MoveP2\n#Move Subchar\nlfs\tf1,0x0(r20)\nstfs\tf1,0xB0(r5)\nlfs\tf1,0x4(r20)\nstfs\tf1,0xB4(r5)\nbl  UpdatePosition\n\n\nEvent_EnterGrab_MoveP2:\n#Move P2\nlfs\tf1,0x8(r20)\nstfs\tf1,0xB0(r29)\nlfs\tf1,0xC(r20)\nstfs\tf1,0xB4(r29)\nmr\tr3,r30\nbl  UpdatePosition\nmr\tr3,r30\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0\nbeq\tEvent_EnterGrab_EnterGrabAS\n#Move Subchar\nlfs\tf1,0x8(r20)\nstfs\tf1,0xB0(r5)\nlfs\tf1,0xC(r20)\nstfs\tf1,0xB4(r5)\nbl  UpdatePosition\n\nEvent_EnterGrab_EnterGrabAS:\n#Store P1 into P2 Grab Pointer\nstw\tr28,0x1A58(r29)\n\n#Enter P2 Into Grab\nmr\tr3,r30\t\t\t#P2 Enters Grab\nbranchl\tr12,AS_GrabOpponent\n\n#Enter P1 Into Grabbed\nmr\tr3,r28\t\t\t#P1 Grabbed\nmr\tr4,r30\t\t\t#P2 = Grabber\nbranchl\tr12,AS_Grabbed\n\n#Enter P2 Into GrabWait\nmr\tr3,r30\t\t\t#P2 Enters GrabWait\nbranchl\tr12,AS_CatchWait\n\n#Enter P2 Into Grounded\nmr\tr3,r29\nbranchl\tr12,SetAsGrounded\n\n#Remove P2's GFX Pointer That Is Crashing the Game\nli\tr3,0x0\nstw\tr3,0x60C(r29)\n\nrestore\nblr\n\n##############\n\nSDITrainingStartingPercents:\nblrl\n.long 0x085F8040 # Mario = 8 / Fox = 95 / Falcon = 70 / DK = 25\n.long 0x0030190F # Kirby = 0 / Bowser = 25 / Link = 25 / Sheik = 15\n.long 0x00000000 # Ness = 0 / Peach = 0 / Popo = 0 / Nana = 0\n.long 0x08050F00 # Pikachu = 8 / Samus = 5 / Yoshi = 15 / Jiggs = 0\n.long 0x00001400 # Mewtwo = 0 / Luigi = 0 / Marth = 20 / Zelda = 0\n.long 0x19085F00 # YLink = 25 / Doc = 8 / Falco = 95 / Pichu = 0\n.long 0x002D3A00 # GaW = 0 / Ganon = 45 / Roy = 58\n\nSDITrainingFloats:\nblrl\n.long 0xC02CCCCD\t\t#P1 X Position\n.long 0x00000000\t\t#P1 Y Position\n.long 0x4144CCCD\t\t#P2 X Position\n.long 0x00000000\t\t#P2 Y Position\n\nSDITrainingLoadExit:\nrestore\nblr\n\n\n\n\n################################################################################\n################################################################################\n#endregion\n\n#region Reversal Training\n#########################\n## Reversal HIJACK INFO ##\n#########################\n\nReversal:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t\t#Use SSS Stage\n\tload r7,EventOSD_Reversal\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nbl\tReversalLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Reversal LOAD FUNCT ##\n\t########################\n\tReversalLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tReversalThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  bl\tReversalWindowInfo\n  mflr\tr5\n  bl\tReversalWindowText\n  mflr\tr6\n\tbl\tCreateEventThinkFunction\n\n\tb\tReversalLoadExit\n\n\n\t\t#########################\n\t\t## Reversal THINK FUNCT ##\n\t\t#########################\n\n    .set MenuData,26\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n\t\t.set firstFrameFlag,0x0\n\t\t.set timer,0x4\n\t\t.set CPUAttack,(MenuData_OptionMenuMemory+0x2)+(0x0)\n\t\t.set P1FacingDirection,(MenuData_OptionMenuMemory+0x2)+(0x1)\n\t\t.set CPUFacingDirection,(MenuData_OptionMenuMemory+0x2)+(0x2)\n    .set CPUAttackToggled,MenuData_OptionMenuToggled+(0x0)\n    .set P1FacingDirectionToggled,MenuData_OptionMenuToggled+(0x1)\n    .set CPUFacingDirectionToggled,MenuData_OptionMenuToggled+(0x2)\n\t\t.set AerialThinkStruct,0x20\n\n\t\tReversalThink:\n\t\tblrl\n\n    .set EventData,31\n\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n    lwz MenuData,EventData_MenuDataPointer(EventData)\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tli\tr3,0xF\n\t\tstb\tr3,0x1A94(r29)\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tReversalThinkMain\n\n  \t\t\t#bl\tReversal_Floats\n  \t\t\t#mflr r3\n  \t\t\t#bl\tInitializePositions\n      #Move PLayers Center Stage\n        bl  PlacePlayersCenterStage\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n      #SaveState\n        addi  r3,EventData,0x10       #SaveState start\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n  \t\t\tbl\tSaveState_Save\n\t\t\t#Set Frame 1 As Over\n  \t\t\tli\t\tr3,0x1\n  \t\t\tstb\t\tr3,0x0(r31)\n\t\t\t#Set Timer to -60\n  \t\t\tli\t\tr3,-60\n  \t\t\tstw\t\tr3,0x4(r31)\n\n\n\t\tReversalThinkMain:\n\n\t\tbl\tGiveFullShields\n\n    #Reset when menu is toggled\n      lbz r3,P1FacingDirectionToggled(MenuData)\n  \t\tcmpwi\tr3,0x0\n  \t\tbne\tReversalReset\t\t\t#Only Run When Hovered Over Facing Direction\n      lbz r3,CPUFacingDirectionToggled(MenuData)\n  \t\tcmpwi\tr3,0x0\n  \t\tbne\tReversalReset\t\t\t#Only Run When Hovered Over Facing Direction\n      lbz r3,CPUAttackToggled(MenuData)\n      cmpwi r3,0x0\n      bne ReversalReset\n\t\tReversalSkipFacingReset:\n\n\t\t#Move Players Apart With DPad\n      addi  r3,EventData,0x10       #SaveState start\n  \t\tbl\tAdjustResetDistance\n  \t\tcmpwi\tr3,-1\n  \t\tbne\tReversalReset\n\n\t\tReversalThinkSequence:\n\n\t\t#Increment Timer\n\t\tlwz\tr20,0x4(r31)\t\t#get timer\n\t\taddi\tr20,r20,0x1\n\t\tstw\tr20,0x4(r31)\t\t#store timer\n\n\t\t#Give Invincibility in Wait, Squat Reverse, IASA Flag Flipped\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xE\n\t\tbeq\tReversalGiveInvincibility\n\t\tcmpwi\tr3,0x29\n\t\tbeq\tReversalGiveInvincibility\n\t\tlbz\tr3, 0x2218 (r29)\n\t\trlwinm.\tr3, r3, 25, 31, 31\n\t\tbne\tReversalGiveInvincibility\n\t\tb\tReversalCheckToAttack\n\n\t\tReversalGiveInvincibility:\n\t\tmr\tr3,r30\n\t\tli\tr4,0x2\n\t\tbl\tGiveInvincibility\n\n\t\t#Check To Attack\n\t\tReversalCheckToAttack:\n\t\t#Check Timer\n\t\t\tcmpwi\tr20,45\n\t\t\tblt\tReversalThinkExit\n\t\t#Check If Attack is Over\n\t\t\tlbz r3,AerialThinkStruct(r31)\n\t\t\tcmpwi r3,0x0\n\t\t\tbne ReversalCheckToReset\n\n\n\t\tReversalDecideSmashAttack:\n\t\tlbz\tr3,CPUAttack(MenuData)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tReversalRandomSmashAttack\n\t\tcmpwi\tr3,0x1\n\t\tbeq\tReversalFSmash\n\t\tcmpwi\tr3,0x2\n\t\tbeq\tReversalDSmash\n\t\tcmpwi\tr3,0x3\n\t\tbeq\tReversalUSmash\n\t\tcmpwi r3,0x4\n\t\tbeq\tReversalRandomAerial\n\t\tcmpwi r3,0x5\n\t\tbeq\tReversalNair\n\t\tcmpwi r3,0x6\n\t\tbeq\tReversalFair\n\t\tcmpwi r3,0x7\n\t\tbeq\tReversalDair\n\t\tcmpwi\tr3,0x8\n\t\tbeq\tReversalFTilt\n\t\tcmpwi\tr3,0x9\n\t\tbeq\tReversalDTilt\n\t\tcmpwi\tr3,0xA\n\t\tbeq\tReversalUTilt\n\n\t\tReversalRandomSmashAttack:\n\t\t\tli\tr3,3\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tmr\tr21,r3\n\t\t#Check If Move is Blacklisted\n\t\t\tlwz\tr4,0x4(r29)\t\t#Char ID\n\t\t\tbl\tReversal_Blacklist\n\t\t\tmflr\tr5\t\t#Get Frame Data Table\n\t\t\tmulli\tr4,r4,0x4\t\t#Get Characters Offset\n\t\t\tadd\tr4,r4,r5\t\t#Get Characters Table Entry Start\n\t\t\tlbzx\tr4,r21,r4\t\t#Get Moves Entry\n\t\t\tcmpwi\tr4,0x1\t\t#Is Move BlackListed?\n\t\t\tbeq\tReversalRandomSmashAttack\n\n\t\t#Perform Move\n\t\t\tcmpwi\tr21,0x0\n\t\t\tbeq\tReversalFSmash\n\t\t\tcmpwi\tr21,0x1\n\t\t\tbeq\tReversalUSmash\n\t\t\tcmpwi\tr21,0x2\n\t\t\tbeq\tReversalDSmash\n\t\tReversalFSmash:\n\t\t#Input Atack\n\t\t\tli\tr3,127\t\t#Forward\n\t\t\tlfs\tf1,0x2C(r29)\t\t#Facing Direction\n\t\t\tfctiwz\tf1,f1\n\t\t\tstfd\tf1,0xF0(sp)\n\t\t\tlwz\tr4,0xF4(sp)\n\t\t\tmullw\tr3,r3,r4\t\t#Forward * facing direction\n\t\t\tstb\tr3,0x1A8E(r29)\n\t\t#Set Attack as ended\n\t\t\tli\tr3,0x1\n\t\t\tstb r3,AerialThinkStruct(r31)\n\t\t\tb\tReversalCheckToReset\n\t\tReversalUSmash:\n\t\t\tli\tr3,127\n\t\t\tstb\tr3,0x1A8F(r29)\n\t\t\tb\tReversalCheckToReset\n\t\t#Set Attack as ended\n\t\t\tli\tr3,0x1\n\t\t\tstb r3,AerialThinkStruct(r31)\n\t\tReversalDSmash:\n\t\t\tli\tr3,-127\n\t\t\tstb\tr3,0x1A8F(r29)\n\t\t#Set Attack as ended\n\t\t\tli\tr3,0x1\n\t\t\tstb r3,AerialThinkStruct(r31)\n\t\t\tb\t\tReversalCheckToReset\n\t\tReversalRandomAerial:\n\t\t#Perform Aerial\n\t\t\tmr\t\tr3,r30\n\t\t\taddi\tr4,r31,AerialThinkStruct\n\t\t\tli\t\tr5,0\t\t#Random Aerial\n\t\t\tbl\t\tPerformAerialThink\n\t\t\tb\t\tReversalCheckToReset\n\t\tReversalNair:\n\t\tReversalFair:\n\t\tReversalDair:\n\t\t#Perform Aerial\n\t\t\tsubi\tr5,r3,0x4\n\t\t\tmr\t\tr3,r30\n\t\t\taddi\tr4,r31,AerialThinkStruct\n\t\t\tbl\t\tPerformAerialThink\n\t\t\tb\t\tReversalCheckToReset\n\t\tReversalFTilt:\n\t\t\tli\tr3,45\n\t\t\tlfs\tf1,0x2C(r29)\t\t#Facing Direction\n\t\t\tfctiwz\tf1,f1\n\t\t\tstfd\tf1,0xF0(sp)\n\t\t\tlwz\tr4,0xF4(sp)\n\t\t\tmullw\tr3,r3,r4\t\t#Forward * facing direction\n\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\tli\tr3,0x100\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t#Set Attack as ended\n\t\t\tli\tr3,0x1\n\t\t\tstb r3,AerialThinkStruct(r31)\n\t\t\tb\tReversalCheckToReset\n\t\tReversalUTilt:\n\t\t\tli\tr3,45\n\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\tli\tr3,0x100\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t#Set Attack as ended\n\t\t\tli\tr3,0x1\n\t\t\tstb r3,AerialThinkStruct(r31)\n\t\t\tb\tReversalCheckToReset\n\t\tReversalDTilt:\n\t\t\tli\tr3,-45\n\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\tli\tr3,0x100\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t#Set Attack as ended\n\t\t\tli\tr3,0x1\n\t\t\tstb r3,AerialThinkStruct(r31)\n\t\t\tb\tReversalCheckToReset\n\n\n\t\tReversalCheckToReset:\n\t\t\tcmpwi\tr20,150\t\t#Restore After 120 Frames\n\t\t\tblt\tReversalThinkExit\n\t\tReversalReset:\n    ReversalSwap:\n    #I fucking hate this code, i need to clean this up at some point.\n    #Get leftmost player pointer in r20, rightmost in r21\n      addi r5,EventData,0x10\n      lwz r3,0x0(r5)\n      lfs f1,0xB0(r3)\n      lwz r4,0x8(r5)\n      lfs f2,0xB0(r4)\n      fcmpo cr0,f1,f2\n      bgt 0x10\n      mr r20,r3\n      mr r21,r4\n      b 0xC\n      mr r20,r4\n      mr r21,r3\n    #Get which side to start on\n      li\tr3,2        #0 = p1 on left, 1 = p1 on right\n      branchl r12,HSD_Randi\n      cmpwi r3,0x0\n      bne ReversalReset_RightSide\n    ReversalReset_LeftSide:\n    #Swap Position\n      addi r5,EventData,0x10\n      #Get Leftmost Chars Position\n        li  r3,1\n        bl  IntToFloat\n        fmr f2,f1\n        lfs f3,0xB0(r20)\n        lfs f4,0xB4(r20)\n      #Get Rightmost Chars Position\n        li  r3,-1\n        bl  IntToFloat\n        fmr f5,f1\n        lfs f6,0xB0(r21)\n        lfs f7,0xB4(r21)\n      #Store to P1 Data\n        lwz r3,0x0(r5)\n        stfs f2,0x2C(r3)\n        stfs f3,0xB0(r3)\n        stfs f4,0xB4(r3)\n      #Store to P2 Data\n        lwz r3,0x8(r5)\n        stfs f5,0x2C(r3)\n        stfs f6,0xB0(r3)\n        stfs f7,0xB4(r3)\n        b ReversalReset_SwapEnd\n    ReversalReset_RightSide:\n      addi r5,EventData,0x10\n      #Get Leftmost Chars Position\n        li  r3,1\n        bl  IntToFloat\n        fmr f2,f1\n        lfs f3,0xB0(r20)\n        lfs f4,0xB4(r20)\n      #Get Rightmost Chars Position\n        li  r3,-1\n        bl  IntToFloat\n        fmr f5,f1\n        lfs f6,0xB0(r21)\n        lfs f7,0xB4(r21)\n      #Store to P2 Data\n        lwz r3,0x8(r5)\n        stfs f2,0x2C(r3)\n        stfs f3,0xB0(r3)\n        stfs f4,0xB4(r3)\n      #Store to P1 Data\n        lwz r3,0x0(r5)\n        stfs f5,0x2C(r3)\n        stfs f6,0xB0(r3)\n        stfs f7,0xB4(r3)\n    ReversalReset_SwapEnd:\n    ReversalAdjustP1Direction:\n\t\t#Adjust P1 Facing Direction Based on Preference\n      addi r5,EventData,0x10\n\t\t\tlbz\tr3,P1FacingDirection(MenuData)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbne\tReversalAdjustP1Direction_Skip\n\t\t#Invert P1 Facing Direction\n\t\t\tlwz\tr3,0x0(r5)\n\t\t\tlfs\tf1,0x2C(r3)\n\t\t\tfneg\tf1,f1\n\t\t\tstfs\tf1,0x2C(r3)\n    ReversalAdjustP1Direction_Skip:\n\t\t#Adjust CPU Facing Direction Based on Preference\n\t\tReversalAdjustCPUDirection:\n\t\t\tlbz\tr3,CPUFacingDirection(MenuData)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbne\tReversalAdjustCPUDirection_Skip\n\t\t#Invert P2 Facing Direction\n\t\t\tlwz\tr3,0x8(r5)\n\t\t\tlfs\tf1,0x2C(r3)\n\t\t\tfneg\tf1,f1\n\t\t\tstfs\tf1,0x2C(r3)\n    ReversalAdjustCPUDirection_Skip:\n\t\t#Restore\n\t\tReversalLoadState:\n\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\tbl\tSaveState_Load\n\t\t#Reset Timer\n\t\t\tli\tr3,30\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tli\tr4,0\n\t\t\tsub\tr3,r4,r3\n\t\t\tstw\tr3,0x4(r31)\n\t\t#Reset AerialThinkStruct\n\t\t\tli\tr3,0x0\n\t\t\tstw r3,AerialThinkStruct(r31)\n\n\t\tReversalThinkExit:\n      mr  r3,MenuData\n      bl  ClearToggledOptions\n\t\t\tbl\tUpdateAllGFX\n\t\t\trestore\n\t\t\tblr\n\n\n#################################\n\nReversal_Floats:\nblrl\n.long 0xC0F9999A\t\t#P1 X Position\n.long 0x40F9999A\t\t#P2 X Position\n.long 0x38d1b717\t\t#FD Floor Y Coord\n.long 0x38d1b717\t\t#FD Floor Y Coord\n\n#################################\n\nReversal_Blacklist:\nblrl\n#Mario\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Fox\n.long 0x01000000 \t#FSmash USmash DSmash\n\n#Cptn Falcon\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#DK\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#Kirby\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Bowser\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#link\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Sheik\n.long 0x01000000\t\t#FSmash USmash DSmash\n\n#Ness\n.long 0x00010100\t\t#FSmash USmash DSmash\n\n#Peach\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#Popo\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Nana\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Pikachu\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Samus\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#Yoshi\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#Jiggs\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#mewtwo\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#Luigi\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Marth\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#Zelda\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#YLink\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Doc\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Falco\n.long 0x01000000\t\t#FSmash USmash DSmash\n\n#Pichu\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#GaW\n.long 0x00000100\t\t#FSmash USmash DSmash\n\n#Ganon\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Roy\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n####################################################\n\nReversalWindowInfo:\nblrl\n#amount of options, amount of options in each window\n\n.long 0x020A0101  #3 window, Smash Attack has 11 options, Facing Direction Has 2\n\n####################################################\n\nReversalWindowText:\nblrl\n\n########\n## DI ##\n########\n\n#Window Title = CPU Attack\n.long 0x43505520\n.long 0x41747461\n.long 0x636b0000\n\n#Option 1 = Random Smash Attack\n.long 0x52616e64\n.long 0x6f6d2053\n.long 0x6d617368\n.long 0x20417474\n.long 0x61636b00\n\n#Option 2 = Forward Smash\n.long 0x466f7277\n.long 0x61726420\n.long 0x536d6173\n.long 0x68000000\n\n#Option 3 = Down Smash\n.long 0x446f776e\n.long 0x20536d61\n.long 0x73680000\n\n#Option 4 = Up Smash\n.long 0x55702053\n.long 0x6d617368\n.long 0x\n\n#Option 5 = Random Aerial\n.long 0x52616e64\n.long 0x6f6d2041\n.long 0x65726961\n.long 0x6c000000\n\n#Option 6 = Fair\n.long 0x46616972\n.long 0x\n\n#Option 7 = Nair\n.long 0x4e616972\n.long 0x\n\n#Option 8 = Dair\n.long 0x44616972\n.long 0x\n\n#Option 9 = FTilt\n.long 0x4654696c\n.long 0x74000000\n\n#Option 10 = DTilt\n.long 0x4454696c\n.long 0x74000000\n\n#Option 11 = UTilt\n.long 0x5554696c\n.long 0x74000000\n\n#########$$$#############\n## P1 Facing Direction ##\n##########$$$############\n\n#Window Title = Facing Direction\n.long 0x50312046\n.long 0x6163696e\n.long 0x67204469\n.long 0x72656374\n.long 0x696f6e00\n\n#Option 1 = Towards\n.long 0x546f7761\n.long 0x72647300\n.long 0x\n.long 0x\n.long 0x\n\n#Option 2 = Away\n.long 0x41776179\n.long 0x\n.long 0x\n.long 0x\n.long 0x\n\n#########$$$##############\n## CPU Facing Direction ##\n##########$$$#############\n\n#Window Title = CP Facing Direction\n.long 0x43502046\n.long 0x6163696e\n.long 0x67204469\n.long 0x72656374\n.long 0x696f6e00\n\n\n#Option 1 = Towards\n.long 0x546f7761\n.long 0x72647300\n.long 0x\n.long 0x\n.long 0x\n\n#Option 2 = Away\n.long 0x41776179\n.long 0x\n.long 0x\n.long 0x\n.long 0x\n\n####################################################\n\nReversalLoadExit:\nrestore\nblr\n\n\n\n################################################################################\n################################################################################\n#endregion\n\n#region Powershield Training\n#########################\n## Powershield HIJACK INFO ##\n#########################\n\nPowershield:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Falco.Ext\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,FinalDestination\t\t\t#Use SSS Stage\n\tload r7,EventOSD_Powershield\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nbl\tPowershieldLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Powershield LOAD FUNCT ##\n\t########################\n\tPowershieldLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tPowershieldThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  bl\tPowershieldWindowInfo\n  mflr\tr5\n  bl\tPowershieldWindowText\n  mflr\tr6\n\tbl\tCreateEventThinkFunction\n\n\tbl\tInitializeHighScore\n\n\tb\tPowershieldLoadExit\n\n\n\t\t#########################\n\t\t## Powershield THINK FUNCT ##\n\t\t#########################\n\n    #Registers\n    .set MenuData,26\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n    #Offsets\n\t\t.set FireSpeed,(MenuData_OptionMenuMemory+0x2)+0x0\n\n\t\tPowershieldThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n    lwz   MenuData,EventData_MenuDataPointer(EventData)\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#Make P2 A Follower (No Nudge)\n\t\t#li\tr3,0x8\n\t\t#stb\tr3,0x221F(r29)\n\t\tli\tr3,0x1\n\t\tlbz\tr0, 0x221D (r29)\n\t\trlwimi\tr0,r3,2,29,29\n\t\tstb\tr0, 0x221D (r29)\n\n\t\t#Update GFX\n\t\tmr\tr3,r30\n\t\tbl\tUpdateAllGFX\n\n\t\t#Give Invincibility To P2\n\t\tmr\tr3,r30\n\t\tli\tr4,0x2\n\t\tbl\tGiveInvincibility\n\n\t\t#Reset All Stale Moves\n\t\tbl\tResetStaleMoves\n\n\t\t#DPad Changes Falco's Side\n\t\tlhz\tr3,0x662(r27)\t\t\t#Get Held Buttons\n\t\trlwinm.  r0,r3,0,27,27\n    bne 0xC\n    cmpwi r3,0x0\n\t\tbne\tPowershield_SkipPositionChange\n\t\t#CHECK FOR DPAD TO CHANGE Side\n\t\tlwz\tr3,0x668(r27)\t\t\t#Get DPad\n\t\trlwinm.\tr0,r3,0,30,30\n\t\tbeq\tPowershield_CheckLeft\n\t\tlwz\tr3,0x10(r31)\t\t\t#P1's Backup\n\t\tlfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tfabs\tf1,f1\n\t\tstfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tlfs\tf1,0x2C(r3)\t\t\t#Facing\n\t\tfabs\tf1,f1\n\t\tfneg\tf1,f1\t\t\t#Negate Always\n\t\tstfs\tf1,0x2C(r3)\t\t\t#Facing\n\n\t\tlwz\tr3,0x18(r31)\t\t\t#P2's Backup\n\t\tlfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tfabs\tf1,f1\n\t\tfneg\tf1,f1\t\t\t#Negate Always\n\t\tstfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tlfs\tf1,0x2C(r3)\t\t\t#Facing\n\t\tfabs\tf1,f1\t\t\t#Always Positive\n\t\tstfs\tf1,0x2C(r3)\t\t\t#Facing\n\t\tb\tPowershieldRestore\n\n\t\tPowershield_CheckLeft:\n\t\trlwinm.\tr0,r3,0,31,31\n\t\tbeq\tPowershield_SkipPositionChange\n\t\tlwz\tr3,0x10(r31)\t\t\t#P1's Backup\n\t\tlfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tfabs\tf1,f1\n\t\tfneg\tf1,f1\t\t\t#Negate Always\n\t\tstfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tlfs\tf1,0x2C(r3)\t\t\t#Facing\n\t\tfabs\tf1,f1\t\t\t#Always Positive\n\t\tstfs\tf1,0x2C(r3)\t\t\t#Facing\n\n\t\tlwz\tr3,0x18(r31)\t\t\t#P2's Backup\n\t\tlfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tfabs\tf1,f1\n\t\tstfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tlfs\tf1,0x2C(r3)\t\t\t#Facing\n\t\tfabs\tf1,f1\n\t\tfneg\tf1,f1\t\t\t#Negate Always\n\t\tstfs\tf1,0x2C(r3)\t\t\t#Facing\n\t\tb\tPowershieldRestore\n\t\tPowershield_SkipPositionChange:\n\n\t\t#Act Out Of Laser Hit\n\t\tbl\tActOutOfLaserHitDisplay\n\n\t\t#Check For Powershield Reflect\n\t\t#Check For Shield Action State\n\t\t\tlwz\tr3,0x10(r27)\n\t\t\tcmpwi\tr3,0xB6\t\t#Shield Start\n\t\t\tbne\tPowershield_SkipPowershieldCheck\n\t\t#Check For Powershield Bool\n\t\t\tlwz\tr3,0x2368(r27)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tPowershield_SkipPowershieldCheck\n\t\t#Remove Flag\n\t\t\tli\tr3,0x0\n\t\t\tstw\tr3,0x2368(r27)\n\t\t#Increment Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\t#Check To Make New High Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tlhz\tr4,-0x4ea6(r13)\n\t\t\tcmpw\tr3,r4\n\t\t\tble\tPowershield_SkipPowershieldCheck\n\t\t#Copy To High Score\n\t\t\tsth\tr3,-0x4ea6(r13)\n\t\tPowershield_SkipPowershieldCheck:\n\n\t\t#Check For Powershield Miss\n\t\t#Check For Shield Stun\n\t\t\tlwz\tr3,0x10(r27)\n\t\t\tcmpwi\tr3,0xB5\t\t#Shield Stun\n\t\t\tbeq\tPowershield_ResetScore\n\t\t#Check For Hitstun\n\t\t\tlbz\tr3, 0x221C (r27)\n\t\t\trlwinm.\tr0, r3, 31, 31, 31\n\t\t\tbne\tPowershield_ResetScore\n\t\t\tb\tPowershield_SkipMissedPowershieldCheck\n\t\tPowershield_ResetScore:\n\t\t#Reset Score\n\t\t\tli\tr3,0\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\tPowershield_SkipMissedPowershieldCheck:\n\n\t\t#Update HUD Score\n\t\tlhz\tr3,-0x4ea8(r13)\n\t\tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tPowershieldThinkMain\n\n\t\t#Set Timer to -60\n\t\tli\t\tr3,-60\n\t\tstw\t\tr3,0x4(r31)\n\t\t#Fix Inputs\n\t\tbl\tCurrentInputsAsLastFramesInputs\n\t\t#SaveState\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n\t\tbl\tSaveState_Save\n\n\n\t\tPowershieldThinkMain:\n\t\tbl\tGiveFullShields\n\n\t\tPowershieldThinkSequence:\n\t\t#Increment Timer\n\t\tlwz\tr20,0x4(r31)\t\t#get timer\n\t\taddi\tr20,r20,0x1\n\t\tstw\tr20,0x4(r31)\t\t#store timer\n\n\t\t#KneeBend(shorthop)\n\t\tcmpwi\tr20,0\n\t\tblt\tPowershieldThinkExit\n\t\tbne\tPowershieldSkipJump\n\t\tli\tr3,0x800\n\t\tstw\tr3,0x1A88(r29)\n\t\tb\tPowershieldThinkExit\n\n\t\t#Get Random Laser Timing in JumpF\n\t\tPowershieldSkipJump:\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x19\n\t\tbne\tPowershieldSkipLaser\n\t\tli\tr3,4\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x894(r29)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbne\tPowershieldThinkExit\n\t\t#Random Laser Timing\n\t\tli\tr3,2\n\t\tbranchl\tr12,HSD_Randi\n\t\taddi\tr3,r3,5\t\t#Start on Frame 5\n\t\tstw\tr3,0x8(r31)\n\t\t#Input Laser\n\t\tli\tr3,0x200\n\t\tstw\tr3,0x1A88(r29)\n\t\tb\tPowershieldThinkExit\n\n\t\tPowershieldSkipLaser:\n\t\t#Check if in Laser Shoot\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x159\n\t\tbne\tPowershieldCheckForIASA\n\t\t#Check in on the right frame\n\t\tlwz\tr3,0x8(r31)\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x894(r29)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbne\tPowershieldCheckForIASA\n\t\t#Input a FF\n\t\tli\tr3,-127\n\t\tstb\tr3,0x1A8D(r29)\n\t\tb\tPowershieldThinkExit\n\n\n\t\tPowershieldCheckForIASA:\n\t\t#Check if in Landing\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x2A\n\t\tbne\tPowershieldThinkExit\n\t\t#Check If Can Interrupt\n\t\tli\tr3,3\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x894(r29)\n\t\tfcmpo\tcr0,f2,f1\n\t\tblt\tPowershieldThinkExit\n\t\tbne\tPowershieldRandom\n\t\tli\tr3,14\n\t\tbranchl\tr12,HSD_Randi\n\t\taddi\tr3,r3,15\n\t\tstb\tr3,0xF(r31)\n\t\t#Get Interval\n\t\tlbz\tr3,FireSpeed(MenuData)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tPowershieldRandom\n\t\tcmpwi\tr3,0x1\n\t\tbeq\tPowershieldSlow\n\t\tcmpwi\tr3,0x2\n\t\tbeq\tPowershieldMedium\n\t\tcmpwi\tr3,0x3\n\t\tbeq\tPowershieldFast\n\t\tcmpwi\tr3,0x4\n\t\tbeq\tPowershieldVeryFast\n\n\t\tPowershieldRandom:\n\t\tlbz\tr3,0xF(r31)\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x894(r29)\n\t\tfcmpo\tcr0,f2,f1\n\t\tblt\tPowershieldThinkExit\n\t\tli\tr3,-1\n\t\tstw\tr3,0x4(r31)\n\t\tb\tPowershieldThinkExit\n\n\t\tPowershieldSlow:\n\t\t#Reset Timer\n\t\tli\tr3,-30\n\t\tstw\tr3,0x4(r31)\n\t\tb\tPowershieldThinkExit\n\n\t\tPowershieldMedium:\n\t\t#Reset Timer\n\t\tli\tr3,-15\n\t\tstw\tr3,0x4(r31)\n\t\tb\tPowershieldThinkExit\n\n\t\tPowershieldFast:\n\t\t#Reset Timer\n\t\tli\tr3,-8\n\t\tstw\tr3,0x4(r31)\n\t\tb\tPowershieldThinkExit\n\n\t\tPowershieldVeryFast:\n\t\t#Reset Timer\n\t\tli\tr3,-1\n\t\tstw\tr3,0x4(r31)\n\t\tb\tPowershieldThinkExit\n\n\t\tPowershieldThinkExit:\n    mr  r3,MenuData\n    bl  ClearToggledOptions\n\t\trestore\n\t\tblr\n\n\nPowershieldLoadExit:\nrestore\nblr\n\n##################################\n\nPowershieldRestore:\naddi r3,EventData,EventData_SaveStateStruct\nbl\tSaveState_Load\naddi r3,EventData,EventData_SaveStateStruct\nbl\tSaveState_Load\nb\tPowershieldThinkExit\n\n##################################\n\nPowershieldWindowInfo:\nblrl\n.long 0x00040000\t\t#1 window, 5 options\n\nPowershieldWindowText:\nblrl\n\n#Title\n.long 0x46697265\n.long 0x20537065\n.long 0x65640000\n.long 0x00000000\n.long 0x00000000\n\n#Random\n.long 0x52616e64\n.long 0x6f6d0000\n.long 0x\n.long 0x\n.long 0x\n\n#Slow\n.long 0x536c6f77\n.long 0x\n.long 0x\n.long 0x\n.long 0x\n\n#Medium\n.long 0x4d656469\n.long 0x756d0000\n.long 0x\n.long 0x\n.long 0x\n\n#Fast\n.long 0x46617374\n.long 0x\n.long 0x\n.long 0x\n.long 0x\n\n#Very Fast\n.long 0x56657279\n.long 0x20466173\n.long 0x74000000\n.long 0x\n.long 0x\n\n\n\n##################################\n\n\n\n\n################################################################################\n################################################################################\n#endregion\n\n#region Shield Drop Training\n#########################\n## Shield Drop HIJACK INFO ##\n#########################\n\nShieldDrop:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,Battlefield\t\t\t\t#Use SSS Stage\n\tload r7,EventOSD_ShieldDrop\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nbl\tShieldDropLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Shield Drop LOAD FUNCT ##\n\t########################\n\tShieldDropLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tShieldDropThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  bl\tShieldDropWindowInfo\n  mflr\tr5\n  bl\tShieldDropWindowText\n  mflr\tr6\n\tbl\tCreateEventThinkFunction\n\n\tb\tShieldDropLoadExit\n\n\n\t\t##########################\n\t\t## Shield Drop THINK FUNCT ##\n\t\t##########################\n\n    #Registers\n    .set MenuData,26\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n    #Offsets\n\t\t.set FacingDirection,(MenuData_OptionMenuMemory+0x2)+0x0\n    .set FacingDirectionToggled,(MenuData_OptionMenuToggled)+0x0\n\n\t\tShieldDropThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n    lwz   MenuData,EventData_MenuDataPointer(EventData)\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tShieldDropThinkMain\n\n\t\t\t#Set Frame 1 As Over\n  \t\t\tli\tr3,0x1\n  \t\t\tstb\tr3,0x0(r31)\n  \t\t\tbl\tShieldDrop_Floats\n  \t\t\tmflr\tr3\n  \t\t\tbl\tInitializePositions\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n\t\t\t#Store Y Position to Last Known Y Position\n  \t\t\tlfs\tf1,0xB4(r29)\n  \t\t\tstfs\tf1,0x834(r29)\n\t\t\t#Save State\n  \t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n  \t\t\tbl\tSaveState_Save\n\t\t\t#Set Timer to -60\n  \t\t\tli\tr3,-60\n  \t\t\tstw\tr3,0x4(r31)\n\n\n\n\t\tShieldDropThinkMain:\n\t\t.set AerialThinkStruct,0x8\n\n\t\tbl\tGiveFullShields\n\n\t\tlbz r3,FacingDirectionToggled(MenuData)\n\t\tcmpwi\tr3,0\t\t\t#Check If Toggled An Option\n\t\tbne\tShieldDropReset\n    lbz r3,FacingDirectionToggled(MenuData)\n\t\tcmpwi\tr3,0\t\t\t#Check If Toggled An Option\n\t\tbne\tShieldDropReset\n\n\t\t#Move Players Apart With DPad\n    addi  r3,EventData,0x10       #SaveState start\n\t\tbl\tAdjustResetDistance\n\t\tcmpwi\tr3,-1\n\t\tbne\tShieldDropReset\n\n\t\tShieldDropThinkSequence:\n\t\t#Increment Timer\n\t\tlwz\tr20,0x4(r31)\t\t#get timer\n\t\taddi\tr20,r20,0x1\n\t\tstw\tr20,0x4(r31)\t\t#store timer\n\n\t\t#Check if In Wait\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0xE\n\t\t\tbne ShieldDropNoIntangibility\n\t\t#Give Intangibility in Wait\n\t\t\tmr\tr3,r30\n\t\t\tli\tr4,0x2\n\t\t\tbl\tGiveInvincibility\n\t\tShieldDropNoIntangibility:\n\n\t\t#Check To Start Aerial\n\t\tcmpwi\tr20,40\n\t\tblt\tShieldDropThinkExit\n\n\t\t#Perform Aerial\n\t\t\tmr\tr3,r30\n\t\t\taddi\tr4,r31,AerialThinkStruct\n\t\t\tli\t\tr5,0\t\t#Random Attack\n\t\t\tbl\tPerformAerialThink\n\n\t\tShieldDropCheckToShield:\n\t\t#Check If CPU is done with Aerial Sequence\n\t\t\tlbz\tr3,AerialThinkStruct(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tShieldDropCheckToReset\n\t\t#Hold Shield\n\t\t\tli\tr3,0xC0\t\t#Hit L\n\t\t\tstw\tr3,0x1A88(r29)\t\t#Hold Shield\n\n\t\tShieldDropCheckToReset:\n\t\tcmpwi\tr20,140\n\t\tbne\tShieldDropThinkExit\n\t\tShieldDropReset:\n\t\t#Randomize Position\n\t\tli\tr3,0x1\t\t\t#Opposing Sides of Stage\n\t\tbl\tRandomize_LeftorRightSide\n\t\t#Adjust Facing Direction Based on Preference\n\t\tlbz\tr3,FacingDirection(MenuData)\n\t\tcmpwi\tr3,0x1\n\t\tbne\tShieldDropLoadState\n\t\t#Invert P1 Facing Direction\n\t\tlwz\tr3,0x10(r31)\n\t\tlfs\tf1,0x2C(r3)\n\t\tfneg\tf1,f1\n\t\tstfs\tf1,0x2C(r3)\n\t\tShieldDropLoadState:\n\t\t#Backup P1 Analog Timers\n\t\tlwz\tr23,0x620(r27)\n\t\tlwz\tr24,0x624(r27)\n\t\t#Restore\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tSaveState_Load\n\t\t#Restore P1 Analog Timers\n\t\tlwz\tr23,0x620(r27)\n\t\tlwz\tr24,0x624(r27)\n\t\t#Reset Timer\n\t\tli\tr3,50\n\t\tbranchl\tr12,HSD_Randi\n\t\tli\tr4,0\n\t\tsub\tr3,r4,r3\n\t\tstw\tr3,0x4(r31)\n\t\t#Reset Aerial Move Think Struct\n\t\tli\tr3,0\n\t\tstw\tr3,AerialThinkStruct(r31)\n\n\t\tShieldDropThinkExit:\n    mr  r3,MenuData\n    bl  ClearToggledOptions\n\t\tbl\tUpdateAllGFX\n\t\trestore\n\t\tblr\n\n#################################\n\nShieldDrop_Floats:\nblrl\n.long 0xC0F9999A\t\t#P1 X Position\n.long 0x40F9999A\t\t#P2 X Position\n.long 0x425999b4\t\t#Top Plat Y Position\n.long 0x425999b4\t\t#Top Plat Y Position\n.long 0x3E99999A  #Y Vel to Attack\n.long 0x40A00000  #Distance from Ground to L Cancel\n\n#################################\n\nShieldDropWindowInfo:\nblrl\n\n.long 0x0001FFFF  #1 Window, Facing Direction Has 2 Options\n\n################################\n\nShieldDropWindowText:\nblrl\n\n######################\n## Facing Direction ##\n######################\n\n#Window Title = Facing Direction\n.long 0x46616369\n.long 0x6e672044\n.long 0x69726563\n.long 0x74696f6e\n.long 0x\n\n#Option 1 = Towards\n.long 0x546f7761\n.long 0x72647300\n.long 0x\n.long 0x\n.long 0x\n\n#Option 2 = Away\n.long 0x41776179\n.long 0x\n.long 0x\n.long 0x\n.long 0x\n\n\n#################################\n\nShieldDropLoadExit:\nrestore\nblr\n\n################################################################################\n#endregion\n\n#region Attack on Shield\n#########################\n## Attack On Shield HIJACK INFO ##\n#########################\n\nAttackOnShield:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,FinalDestination\t\t#Use SSS Stage\n\tload r7,EventOSD_AttackOnShield\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\n\tbl\tAttackOnShieldLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Attack On Shield LOAD FUNCT ##\n\t########################\n\tAttackOnShieldLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tAttackOnShieldThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  bl\tAttackOnShieldWindowInfo\n  mflr\tr5\n  bl\tAttackOnShieldWindowText\n  mflr\tr6\n\tbl\tCreateEventThinkFunction\n\n\n\tb\tAttackOnShieldLoadExit\n\n\n\t\t#########################\n\t\t## Attack On Shield THINK FUNCT ##\n\t\t#########################\n\n    #Registers\n    .set MenuData,26\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n\t\t.set firstFrameFlag,0x0\n\t\t.set timer,0x4\n\t\t.set OoSOption,MenuData_OptionMenuMemory+0x2 + 0x0\n  \t.set OoSOptionToggled,MenuData_OptionMenuToggled + 0x0\n\n\t\tAttackOnShieldThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n    lwz MenuData,EventData_MenuDataPointer(EventData)\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n  \t\tbl\tCheckIfFirstFrame\n  \t\tcmpwi\tr3,0x0\n  \t\tbeq\tAttackOnShieldThinkMain\n\t\t\t#Set Frame 1 As Over\n  \t\t\tli\t\tr3,0x1\n  \t\t\tstb\t\tr3,0x0(r31)\n  \t\t\tbl\t\tAttackOnShield_Floats\n  \t\t\tmflr\tr3\n  \t\t\tbl\t\tInitializePositions\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n\t\t\t#Save State\n  \t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n  \t\t\tbl\t\tSaveState_Save\n\n\n\n\t\tAttackOnShieldThinkMain:\n\t\tbl\tGiveFullShields\n\n\t\t#Reset If Anyone Dies\n\t\tbl\tIsAnyoneDead\n\t\tcmpwi\tr3,0x0\n\t\tbne\tAttackOnShieldRestoreState\n\n\t\tAttackOnShieldThinkSequence:\n\n      lbz r3,OoSOptionToggled(MenuData)\n\t\t\tcmpwi\tr3,0\n\t\t\tbeq\tAttackOnShieldNoOptionToggled\n\t\t#Clear Last AS So CPU Doesnt Act Immediately\n\t\t\tli\tr3,0\n\t\t\tsth\tr3,TM_OneASAgo(r29)\n\t\tAttackOnShieldNoOptionToggled:\n\n\t\t#Get Floats\n\t\tbl\tAttackOnShield_Floats\n\t\tmflr\tr21\n\t\t#Get Frames as Int\n\t\tlfs\tf1,0x894(r29)\n\t\tfctiwz\tf1,f1\n\t\tstfd\tf1,0xF0(sp)\n\t\tlwz\tr22,0xF4(sp)\n\n\t\t#Check If Perfroming OoS Option\n\t\tlwz\tr3,0x4(r31)\n\t\tcmpwi\tr3,0x0\n\t\tble\tAttackOnShieldShieldWait\n\t\t#Branch To OoSThink\n\t\tlbz\tr3,OoSOption(MenuData)\n\t\tcmpwi\tr3,0x1\n\t\tbeq\tAttackOnShieldNairThink\n\t\tcmpwi\tr3,0x2\n\t\tbeq\tAttackOnShieldUpBThink\n\t\tcmpwi r3,0x3\n\t\tbeq AttackOnShieldUpSmashThink\n\t\tcmpwi\tr3,0x4\n\t\tbeq\tAttackOnShieldShineThink\n    cmpwi\tr3,0x7\n\t\tbeq\tAttackOnShieldWavedashThink\n\t\tb\tAttackOnShieldShieldWait\n\n\t\t\tAttackOnShieldNairThink:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x19\n\t\t\tbne\tAttackOnShieldCheckToReset\n\t\t\t#Input Nair\n\t\t\tli\tr3,0x100\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tAttackOnShieldCheckToReset\n\n\t\t\tAttackOnShieldUpBThink:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x18\n\t\t\tbne\tAttackOnShieldCheckToReset\n\t\t\tli\tr3,127\n\t\t\tstb\tr3,0x1A8D(r29)\t\t\t#Press Up\n\t\t\tli\tr3,0x200\n\t\t\tstw\tr3,0x1A88(r29)\t\t\t#Press B\n\t\t\tb\tAttackOnShieldCheckToReset\n\n\t\t\tAttackOnShieldUpSmashThink:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x18\n\t\t\tbne\tAttackOnShieldCheckToReset\n\t\t\tli\tr3,127\n\t\t\tstb\tr3,0x1A8D(r29)\t\t\t#Press Up\n\t\t\tli\tr3,0x100\n\t\t\tstw\tr3,0x1A88(r29)\t\t\t#Press A\n\t\t\tb\tAttackOnShieldCheckToReset\n\n\t\t\tAttackOnShieldShineThink:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x19\n\t\t\tbne\tAttackOnShieldCheckToReset\n\t\t\t#Input Shine\n\t\t\tli\tr3,-127\n\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\tli\tr3,0x200\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tAttackOnShieldCheckToReset\n\n      AttackOnShieldWavedashThink:\n      lwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x19\n\t\t\tbne\tAttackOnShieldCheckToReset\n      #Get Random Airdodge Angle\n  \t\t\tli\tr3,30\t\t#30 Different Angles\n  \t\t\tbranchl\tr12,HSD_Randi\n  \t\t\taddi\tr3,r3,310\t\t#Start at 310°\n  \t\t\tbl\tComboTrainingDecideStickAngle_ConvertAngle\n        mr  r20,r3\n  \t\t#Joystick X = X Component * (OpponentDirection)\n        bl  GetDirectionInRelationToP1\n  \t\t\tmullw\tr3,r3,r20\n  \t\t\tstb\tr3,0x1A8C(r29)\n  \t\t#Joystick Y = Y Component\n  \t\t\tstb\tr4,0x1A8D(r29)\n  \t\t#Press L To Wavedash\n  \t\t\tli\tr3,0xC0\n  \t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tAttackOnShieldCheckToReset\n\n\t\tAttackOnShieldShieldWait:\n\t\t#Always Hold L\n\t\tli\tr3,0xC0\t\t#Hit L\n\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\n\t\t#Check If Got Shield Poked\n\t\t#Hitlag\n\t\t\tlbz\tr3,0x221A(r29)\t\t\t#Check If in Hitlag\n\t\t\trlwinm.\tr3,r3,0,26,26\n\t\t\tbeq\tAttackOnShieldCheckForShieldHit\n\t\t#Damage State\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x4B\n\t\t\tblt\tAttackOnShieldCheckForShieldHit\n\t\t\tcmpwi\tr3,0x5B\n\t\t\tbgt\tAttackOnShieldCheckForShieldHit\n\t\t#Was Hit, Start Reset Timer\n\t\t\tli\tr3,48\t\t#Init Timer\n\t\t\tstw\tr3,0x4(r31)\n\t\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldCheckForShieldHit:\n\t\t#Check If In ShieldWait (0xb3)\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xB3\n\t\tbne\tAttackOnShieldCheckToReset\n\t\t#Check If Was Just in ShieldStun\n\t\tlhz\tr3,TM_OneASAgo(r29)\n\t\tcmpwi\tr3,0xB5\n\t\tbne\tAttackOnShieldCheckToReset\n\t\t#Input OoS Option\n\t\tlbz\tr3,OoSOption(MenuData)\n\t\tcmpwi \tr3,0x0\n\t\tbeq\tAttackOnShieldInputGrab\n\t\tcmpwi \tr3,0x1\n\t\tbeq\tAttackOnShieldNair\n\t\tcmpwi \tr3,0x2\n\t\tbeq\tAttackOnShieldUpB\n\t\tcmpwi\t\tr3,0x3\n\t\tbeq AttackOnShieldUpSmash\n\t\tcmpwi \tr3,0x4\n\t\tbeq\tAttackOnShieldShine\n\t\tcmpwi \tr3,0x5\n\t\tbeq\tAttackOnShieldSpotdodge\n\t\tcmpwi \tr3,0x6\n\t\tbeq\tAttackOnShieldRoll\n    cmpwi \tr3,0x7\n\t\tbeq\tAttackOnShieldWavedash\n\t\tcmpwi \tr3,0x8\n\t\tbeq\tAttackOnShieldNone\n\n\t\tAttackOnShieldInputGrab:\n\t\tli\tr3,0x1C0\n\t\tstw\tr3,0x1A88(r29)\t\t#Press R+A\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldNair:\n\t\tli\tr3,0xCC0\n\t\tstw\tr3,0x1A88(r29)\t\t#Press X/Y\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldUpB:\n\t\tli\tr3,127\n\t\tstb\tr3,0x1A8D(r29)\t\t#Press Up\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldUpSmash:\n\t\tli\tr3,127\n\t\tstb\tr3,0x1A8D(r29)\t\t#Press Up\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldShine:\n\t\tli\tr3,0xCC0\n\t\tstw\tr3,0x1A88(r29)\t\t#Press X/Y\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldSpotdodge:\n\t\tli\tr3,-127\n\t\tstb\tr3,0x1A8D(r29)\t\t#Press Down\n\t\tli\tr3,0xC0\n\t\tstw\tr3,0x1A88(r29)\t\t#Press R\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldRoll:\n\t\tli\tr3,0xC0\n\t\tstw\tr3,0x1A88(r29)\t\t#Press R\n\t\t#Push Towards Opponent's Direction\n\t\tbl\tGetDirectionInRelationToP1\n\t\tli\tr4,127\n\t\tmullw\tr3,r3,r4\n\t\tstb\tr3,0x1A8C(r29)\t\t#Press Away\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n    AttackOnShieldWavedash:\n    li\tr3,0xCC0\n\t\tstw\tr3,0x1A88(r29)\t\t#Press X/Y\n    li\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldNone:\n\t\tb\tAttackOnShieldThinkExit\n\n\t\t#Check To Reset\n\t\tAttackOnShieldCheckToReset:\n\t\tlwz\tr3,0x4(r31)\t\t#get timer\t#Get Timer\n\t\tcmpwi\tr3,0x0\t\t#Check if >0\n\t\tble\tAttackOnShieldThinkExit\n\t\t#Dec Timer\n\t\tsubi\tr3,r3,0x1\n\t\tstw\tr3,0x4(r31)\t\t#store timer\n\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\tbne\tAttackOnShieldThinkExit\t#Exit If Not\n\n\t\t#Randomize P1's X Coord\n\t\t#Get Random X Coord\n\t\tlbz\tr23,0x10(r21)\t\t#Starting X Coord\n\t\tlbz\tr24,0x11(r21)\t\t#Furthest X Coord\n\t\tsub\tr3,r24,r23\t\t#Get Range\n\t\tbranchl\tr12,HSD_Randi\t\t#Get Random Number in Between\n\t\tadd\tr3,r3,r23\t\t#Add to Starting Coord\n\t\t#Cast to Float\n\t\tbl  IntToFloat\n\t\tlwz\tr3,0x10(r31)\t\t#P1 Backup\n\t\tstfs\tf1,0xB0(r3)\t\t#P1 Backup X Pos\n\t\tli\tr3,0x1\t\t\t#Opposing Sides of Stage\n\t\tbl\tRandomize_LeftorRightSide\n\n\t\tAttackOnShieldRestoreState:\n\t\t#Restore State\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tSaveState_Load\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldThinkExit:\n    mr  r3,MenuData\n    bl  ClearToggledOptions\n\t\trestore\n\t\tblr\n\n\n#################################\n\nAttackOnShield_Floats:\nblrl\n.long 0xC1A00000\t\t#P1 X Position\n.long 0x41A00000\t\t#P2 X Position\n.long 0x38d1b717\t\t#FD Floor Y Coord\n.long 0x38d1b717\t\t#FD Floor Y Coord\n.long 0x14460000    #P1 X Rand Pos Range\n\n#################################\n\nAttackOnShieldWindowInfo:\nblrl\n#amount of options, amount of options in each window\n\n.long 0x0008FFFF  #1 window, OoS Option has 10 options\n\n####################################################\n\nAttackOnShieldWindowText:\nblrl\n\n################\n## OoS Option ##\n################\n\n#Window Title = OoS Option\n.long 0x4f6f5320\n.long 0x4f707469\n.long 0x6f6e0000\n\n#Option 1 = Grab\n.long 0x47726162\n.long 0x00000000\n\n#Option 2 = Nair\n.long 0x4e616972\n.long 0x00000000\n\n#Option 3 = Up B\n.long 0x55702042\n.long 0x00000000\n\n#Option 5 = Up Smash\n.long 0x55702d53\n.long 0x6d617368\n.long 0x\n\n#Option 6 = Shine\n.long 0x5368696e\n.long 0x65000000\n\n#Option 7 = Spotdodge\n.long 0x53706f74\n.long 0x646f6467\n.long 0x65000000\n\n#Option 8 = Roll Away\n.long 0x526f6c6c\n.long 0x20417761\n.long 0x79000000\n\n#Option 9 = Wavedash Away\n.long 0x57617665\n.long 0x64617368\n.long 0x20417761\n.long 0x79000000\n\n#Option 10 = None\n.long 0x4E6F6E65\n.long 0x00000000\n\nAttackOnShieldLoadExit:\nrestore\nblr\n\n\n################################################################################\n#endregion\n\n#region Ledgetech Training\n#########################\n## Ledgetech HIJACK INFO ##\n#########################\n\nLedgetech:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Falco.Ext\t\t\t\t\t#Use chosen CPU\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_LedgeTech\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#BUFF DEFENSE RATIO\nlis\tr3,0x3f00\nstw\tr3,0x14(r20)\n\n#STORE THINK FUNCTION\nLedgetechStoreThink:\nbl\tLedgetechLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Ledgetech LOAD FUNCT ##\n\t########################\n\tLedgetechLoad:\n\tblrl\n\n\tbackup\n\n\tbl\tInitializeHighScore\n\n\t#Schedule Think\n\tbl\tLedgetechThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  li  r5,0    #No Option Menu\n\tbl\tCreateEventThinkFunction\n\n\tb\tLedgetechLoadExit\n\n\n\t\t#########################\n\t\t## Ledgetech THINK FUNCT ##\n\t\t#########################\n\n\n\t\tLedgetechThink:\n\t\tblrl\n\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n    .set EventData,31\n\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tLedgetechThinkMain\n\n    #Clear Inputs\n      bl  RemoveFirstFrameInputs\n    #Random Side of Stage\n      li  r3,2\n      branchl r12,HSD_Randi\n      bl  Ledgetech_InitializePositions\n\t\t#Enter SquatWait\n\t\t  mr r3,P2GObj\n\t\t  branchl r12,AS_SquatWait\n\t\t#P1 Has 90%\n\t\t\tli\tr3,90\n\t\t\tload\tr4,0x80453080\t\t#P1 Static Block\n\t\t\tsth\tr3,0x60(r4)\t\t#Store Percent Int To Display Value\n\t\t\tlis\tr3,0x42B4\n\t\t\tstw\tr3,0x1830(r27)\n    #Always Hold Down (Crouch Cancel)\n      li\tr3,-127\n      stb\tr3,0x1A8D(P2Data)\n\t\t#Save State\n\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\tli\tr4,1\t\t\t#Override failsafe\n\t\t\tbl\t\tSaveState_Save\n\n\n\n\t\tLedgetechThinkMain:\n\t\tbl\tGiveFullShields\n\n\t\tLedgetechThinkSequence:\n\t\t#Get Floats\n\t\tbl\tLedgetech_Floats\n\t\tmflr\tr21\n\n\t\t#Reset if P1 Is In a Dead State\n\t\tlbz\tr3,0x221F(r27)\n\t\trlwinm.\tr3,r3,0,25,25\n\t\tbne\tLedgetechRestoreState\n\n\t\t#D-Pad Left Restores State\n\t\tlwz\tr3,0x668(r27)\n\t\trlwinm.\tr0, r3, 0, 31, 31\n\t\tbne\tLedgetechRestoreState\n\n\t\t#Always Hold Down (Crouch Cancel)\n\t\tli\tr3,-127\n\t\tstb\tr3,0x1A8D(r29)\n\n\t\t#Start Timer When Leaving Rebirth Plat\n\t\tlbz\tr3,0x8(r31)\t\t#Check If Left Plat Already\n\t\tcmpwi\tr3,0x0\n\t\tbne\tLedgetechSkipTimerStart\n\t\tlwz\tr3,0x10(r27)\n\t\tcmpwi\tr3,0xD\n\t\tbeq\tLedgetechIncreaseRespawnPlatTime\n\t\t#Set Flag\n\t\tli\tr3,0x1\n\t\tstb\tr3,0x8(r31)\n\t\t#Remove Invinc\n\t\tli\tr3,0x0\n\t\tstw\tr3,0x198C(r27)\n\t\tstw\tr3,0x1990(r27)\n\t\tstw\tr3,0x1994(r27)\n\t\tmr\tr3,r28\n\t\tbranchl\tr12,GFX_RemoveAll\n\t\t#Set Timer\n\t\tli\tr3,180\n\t\tstw\tr3,0x4(r31)\n\t\tb\tLedgetechSkipTimerStart\n\n\t\tLedgetechIncreaseRespawnPlatTime:\n\t\tli\tr3,0x2\n\t\tstw\tr3,0x2340(r27)\n\t\tLedgetechSkipTimerStart:\n\n\t\t#Freeze Falco On Frame X\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x40\n\t\tbne\tLedgetechSkipFalcoFreze\n\t\tli\tr3,0x6\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x894(r29)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbne\tLedgetechSkipFalcoFreze\n\t\tli\tr3,0\n\t\tbl\tIntToFloat\n\t\tmr\tr3,r30\n\t\tbranchl\tr12,FrameSpeedChange\n\t\tLedgetechSkipFalcoFreze:\n\n\n\t\t#If Player 1 Ledge Tech's, Set Timer to 2 Seconds\n\t\t#Check Gatekeeper Flag\n\t\t\tlbz\tr3,0xA(r31)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbeq\tLedgetech_UpdateLedgetechFlags\n\n\t\t#Check For Tech\n\t\t\tlwz\tr3,0x10(r27)\n\t\t\tcmpwi\tr3,0xCA\n\t\t\tbeq\tLedgetechWallTeched\n\t\t\tcmpwi\tr3,0xCB\n\t\t\tbeq\tLedgetechWallTeched\n\t\t\tb\tLedgetech_UpdateLedgetechFlags\n\t\tLedgetechWallTeched:\n\t\t\t#Extend Timer\n\t\t\t\tli\tr3,180\n\t\t\t\tstw\tr3,0x4(r31)\n\t\t\t#Set Tech Bool\n\t\t\t\tli\tr3,1\n\t\t\t\tstb\tr3,0x9(r31)\n\t\t\t#Set Gatekeeper Flag\n\t\t\t\tli\tr3,1\n\t\t\t\tstb\tr3,0xA(r31)\n\n\t\tLedgetech_UpdateLedgetechFlags:\n\t\t#Check If Still Ledgeteching\n\t\t\tlwz\tr3,0x10(r27)\n\t\t\tcmpwi\tr3,0xCA\n\t\t\tbeq\tLedgetechUpdateScore\n\t\t\tcmpwi\tr3,0xCB\n\t\t\tbeq\tLedgetechUpdateScore\n\t\t#Not Ledgeteching, Remove Gatekeeper Flag\n\t\t\tli\tr3,0\n\t\t\tstb\tr3,0xA(r31)\n\t\t\tb\tLedgetechUpdateScoreHUD\n\n\t\tLedgetechUpdateScore:\n\t\t#Check To Increment Score\n\t\t#Check Ledgetech Bool\n\t\t\tlbz\tr3,0x9(r31)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbne\tLedgetechUpdateScoreHUD\n\t\t#Reset LedgeTech Bool\n\t\t\tli\tr3,0\n\t\t\tstb\tr3,0x9(r31)\n\t\t#Increment Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\t#Check To Make New High Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tlhz\tr4,-0x4ea6(r13)\n\t\t\tcmpw\tr3,r4\n\t\t\tble\tLedgetechUpdateScoreHUD\n\t\t#Copy To High Score\n\t\t\tsth\tr3,-0x4ea6(r13)\n\n\t\tLedgetechUpdateScoreHUD:\n\t\t#Update HUD Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\n\n\t\t#Unfreeze Falco On Hit\n\t\tli\tr3,0x0\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x89C(r29)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbne\tLedgetechSkipFalcoUnfreeze\n\t\tlwz\tr3,0x988(r29)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tLedgetechSkipFalcoUnfreeze\n\t\tli\tr3,1\n\t\tbl\tIntToFloat\n\t\tmr\tr3,r30\n\t\tbranchl\tr12,FrameSpeedChange\n\t\tLedgetechSkipFalcoUnfreeze:\n\n\t\tLedgetechCheckIfCrouching:\n\t\t#Only Attempt to DSmash in Squat and SquatWait\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x27\n\t\tbeq\tLedgetechCheckDistance\n\t\tcmpwi\tr3,0x28\n\t\tbeq\tLedgetechCheckDistance\n\t\tb\tLedgetechCheckToReset\n\t\tLedgetechCheckDistance:\n\t\t#Distance Formula\t(Get Distance in f1)\n\t\taddi r3,r29,0xB0 #P2 Positon\n\t\taddi r4,r27,0xB0 #P1 Position\n\t\tbl\tGetDistance\n\t\tlfs\tf2,0x0(r21)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbgt\tLedgetechCheckToReset\n\t\t#Enter DSmash\n\t\tli\tr3,-127\n\t\tstb\tr3,0x1A8F(r29)\n\t\t#Initiate Reset Timer\n\t\tlwz\tr3,0x4(r31)\t\t#Get Timer\n\t\tcmpwi\tr3,0x0\t\t#If Already Set, Skip\n\t\tbne\tLedgetechCheckToReset\n\t\tli\tr3,60\n\t\tstw\tr3,0x4(r31)\n\n\n\n\t\t#Check To Reset\n\t\tLedgetechCheckToReset:\n\t\tlwz\tr3,0x4(r31)\t\t#get timer\t#Get Timer\n\t\tcmpwi\tr3,0x0\t\t#Check if >0\n\t\tble\tLedgetechThinkExit\n\t\t#Dec Timer\n\t\tsubi\tr3,r3,0x1\n\t\tstw\tr3,0x4(r31)\t\t#store timer\n\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\tbne\tLedgetechThinkExit\t#Exit If Not\n\n\t\tLedgetechRestoreState:\n\t  #Restore State\n    \taddi r3,EventData,EventData_SaveStateStruct\n    \tbl\tSaveState_Load\n    #Random Side of Stage\n      li  r3,2\n      branchl r12,HSD_Randi\n      bl  Ledgetech_InitializePositions\n\t\t#Enter SquatWait\n\t\t  mr r3,P2GObj\n\t\t  branchl r12,AS_SquatWait\n\n\t\t#Set Timer\n\t\tli\tr3,0\n\t\tstw\tr3,0x4(r31)\n\t\t#Reset Rebirth Plat Fall Flag\n\t\tstb\tr3,0x8(r31)\n\t\t#Reset Tech and Gatekeeper Flag\n\t\tstb\tr3,0x9(r31)\n\t\tstb\tr3,0xA(r31)\n\t\t#Reset Score\n\t\tli\tr3,0\n\t\tsth\tr3,-0x4ea8(r13)\n\t\tb\tLedgetechThinkExit\n\n\t\tLedgetechThinkExit:\n\t\trestore\n\t\tblr\n\n#################################\n\nLedgetech_Floats:\nblrl\n.float 35.0\t\t#Distance to Initiate DSmash\n\n#################################\n\nBlrFunctionPointer:\nblrl\nblr\n\n#################################\n\nLedgetech_InitializePositions:\nbackup\n\n.set LedgeSide,20\n\n#Backup Ledge Side\n\tmr\tLedgeSide,r3\n\n#Change Facing Directions\n  cmpwi LedgeSide,0x0\n  beq\tLedgetech_InitializePositions_GetLeftLedgeID\nLedgetech_InitializePositions_GetRightLedgeID:\n #Change Facing Direction\n\tli\tr3,-1\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(P1Data)\n  li\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(P2Data)\n\tb\tLedgetech_InitializePositions_DirectionChangeEnd\nLedgetech_InitializePositions_GetLeftLedgeID:\n#Change Facing Direction\n\tli\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(P1Data)\n  li\tr3,-1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(P2Data)\nLedgetech_InitializePositions_DirectionChangeEnd:\n\n#Get Ledge Coordinates\n\tmr\tr3,LedgeSide\n\taddi r4,sp,0x80\n\tbl\tGetLedgeCoordinates\n\nLedgetech_InitializePositions_StorePosition:\n#Place P2 a few Mm behind it\n  li  r3,10\n  bl  IntToFloat\n  lfs f2,0x2C(P2Data)\n  fmuls f1,f1,f2\n  lfs f2,0x80(sp)\n  fsubs f1,f2,f1\n  stfs f1,0xB0(P2Data)\n  lfs f1,0x84(sp)\n  stfs f1,0xB4(P2Data)\n#Find Ground Below Player\n  mr  r3,P2GObj\n  bl  FindGroundNearPlayer\n  cmpwi r3,0    #Check if ground was found\n  beq Ledgetech_InitializePositions_SkipGroundCorrection\n  stfs f1,0xB0(P2Data)\n  stfs f2,0xB4(P2Data)\n  stw r4,0x83C(P2Data)\n  Ledgetech_InitializePositions_SkipGroundCorrection:\n#Enter into Wait\n  mr  r3,P2GObj\n  branchl r12,AS_Wait\n#Update Position\n  mr  r3,P2GObj\n  bl  UpdatePosition\n#Update ECB Values for the ground ID\n  mr r3,P2GObj\n  branchl r12,EnvironmentCollision_WaitLanding\n#Set Grounded\n  mr r3,P2Data\n  branchl r12,Air_SetAsGrounded\n#Update Camera\n  mr r3,P2GObj\n  bl  UpdateCameraBox\n\n#Enter Rebirth\n  lwz\tr26,0x2C(P1Data)\n  mr\t\tr3,P1GObj\n  branchl\t\tr12,AS_Rebirth\n  stw\tr26,0x2C(P1Data)\n#Place P1 a few Mm in front of it\n  li  r3,60\n  bl  IntToFloat\n  lfs f2,0x2C(P1Data)\n  fmuls f1,f1,f2\n  lfs f2,0x80(sp)\n  fsubs f1,f2,f1\n  stfs f1,0xB0(P1Data)\n  lfs f1,0x84(sp)\n  stfs f1,0xB4(P1Data)\n#Enter RebirthWait\n  mr\t\tr3,P1GObj\n  branchl\t\tr12,AS_RebirthWait\n#Update Position\n  mr  r3,P1GObj\n  bl  UpdatePosition\n#Store Blr as Physics\n\tbl\t\tBlrFunctionPointer\n\tmflr\t\tr3\n\tstw\t\tr3,0x21A4(P1Data)\n#Store Custom RebirthWait Interrupt\n\tbl\tCustom_InterruptRebirthWait\n\tmflr\tr3\n\tstw\t\tr3,0x219C(P1Data)\n#Update RebirthPlat Position\n  mr  r3,P1GObj\n  branchl r12,RebirthPlatform_UpdatePosition\n#Update Camera\n  mr r3,P1GObj\n  bl  UpdateCameraBox\n\nrestore\nblr\n\n#################################\n\nLedgetechLoadExit:\nrestore\nblr\n\n\n\n###################################################\n#endregion\n\n#region Amsah Tech\n#########################\n## Amsah Tech HIJACK INFO ##\n#########################\n\nAmsahTech:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t#Send match struct\n\tli\tr5,9\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,-1\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_AmsahTech\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nbl\tAmsahTechLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Amsah Tech LOAD FUNCT ##\n\t########################\n\tAmsahTechLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tAmsahTechThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  li  r5,0    #No Option Menu\n\tbl\tCreateEventThinkFunction\n\n\tb\tAmsahTechLoadExit\n\n\n\t\t#########################\n\t\t## Amsah Tech THINK FUNCT ##\n\t\t#########################\n\n    .set EventData,31\n    .set P1Gobj,28\n    .set P1Data,27\n    .set P2GObj,30\n    .set P2Data,29\n\n    #Offsets\n    .set Timer,0x8\n\n\t\tAmsahTechThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tAmsahTechThinkMain\n\n      #Move Players\n        bl  PlacePlayersCenterStage\n\t\t\t#P1 Has 120%\n  \t\t\tli\tr3,120\n  \t\t\tload\tr4,0x80453080\t\t#P1 Static Block\n  \t\t\tsth\tr3,0x60(r4)\t\t#Store Percent Int To Display Value\n  \t\t\tbl\tIntToFloat\n  \t\t\tstfs\tf1,0x1830(P1Data)\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n\t\t\t#Save State\n  \t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n  \t\t\tbl\tSaveState_Save\n\n\n\n\t\tAmsahTechThinkMain:\n\n\t\t#Make P2 A Follower (No Nudge)\n\t\t#li\tr3,0x8\n\t\t#stb\tr3,0x221F(r29)\n\t\tli\tr3,0x1\n\t\tlbz\tr0, 0x221D (r29)\n\t\trlwimi\tr0,r3,2,29,29\n\t\tstb\tr0, 0x221D (r29)\n\n\t\t#Give Invincibility To P2\n\t\tmr\tr3,r30\n\t\tli\tr4,0x2\n\t\tbl\tGiveInvincibility\n\n\t\t#Update GFX\n\t\tmr\tr3,r30\n\t\tbl\tUpdateAllGFX\n\n\t\t#Reset If Anyone Dies\n\t\tbl\tIsAnyoneDead\n\t\tcmpwi\tr3,0x0\n\t\tbne\tAmsahTechRestoreState\n\n\t\tAmsahTechThinkSequence:\n\t\t#Get Floats\n\t\tbl\tAmsahTech_Floats\n\t\tmflr\tr21\n\n\t\t#Check If Timer Started Already\n\t\tlwz\tr3,0x4(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tAmsahTechCheckUpBTimer\n\n\t\t#Check For P1 Taunt\n\t\tlwz\tr3,0x10(r27)\n\t\tcmpwi\tr3,0x108\n\t\tbeq\tAmsahTechIsTaunting\n\t\tcmpwi\tr3,0x109\n\t\tbeq\tAmsahTechIsTaunting\n\n\t\t#Check For Doc Taunt\n\t\tlwz\tr3,0x4(r27)\n\t\tcmpwi\tr3,0x15\n\t\tbne\tAmsahTechCheckYLink\n\t\t#Check For AS 155\n\t\tlwz\tr3,0x10(r27)\n\t\tcmpwi\tr3,0x155\n\t\tbeq\tAmsahTechIsTaunting\n\n\t\t#Check For YLink Taunt\n\t\tAmsahTechCheckYLink:\n\t\tlwz\tr3,0x4(r27)\n\t\tcmpwi\tr3,0x14\n\t\tbne\tAmsahTechCheckUpBTimer\n\t\t#Check For AS 156\n\t\tlwz\tr3,0x10(r27)\n\t\tcmpwi\tr3,0x156\n\t\tbeq\tAmsahTechIsTaunting\n\t\tb\tAmsahTechCheckUpBTimer\n\n\t\tAmsahTechIsTaunting:\n  #Check for Frame 1 of Taunt\n    lhz r3,0x23EC(P1Data)\n    cmpwi r3,0x1\n    bne AmsahTechCheckUpBTimer\n  #Check If UpB Timer is Set\n\t\tlwz\tr3,0x8(r31)\n\t\tcmpwi\tr3,0x0\t\t#Timer Already Set\n\t\tbne\tAmsahTechCheckUpBTimer\n\t\t#Check If Marth is In Wait\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xE\n\t\tbne\tAmsahTechCheckUpBTimer\n\n  #Move Marth X Mm in front of P1, facing him\n  #Get Position\n    li  r3,10\n    bl  IntToFloat          #Offset from P1\n    lfs f3,0xB0(P1Data)     #P1 X\n    lfs f2,0xB4(P1Data)     #P1 Y\n    lfs f4,0x2C(P1Data)     #Facing Direction\n    fmuls f1,f1,f4\n    fadds f1,f1,f3\n  #Check If P2 Will Be Grounded\n    li  r3,0\n    bl  FindGroundNearPlayer\n    cmpwi r3,0    #Check if ground was found\n    beq AmsahTech_NoGroundFound\n    stfs f1,0xB0(P2Data)\n    stfs f2,0xB4(P2Data)\n    stw r4,0x83C(P2Data)\n    lfs f1,0x2C(P1Data)\n    fneg f1,f1\n    stfs f1,0x2C(P2Data)\n  #Enter Wait\n    mr  r3,P2GObj\n    branchl r12,AS_Wait\n  #Update Position\n    mr  r3,P2GObj\n    bl  UpdatePosition\n  #Update ECB Values for the ground ID\n    mr r3,P2GObj\n    branchl r12,EnvironmentCollision_WaitLanding\n  #Set Grounded\n    mr r3,P2Data\n    branchl r12,Air_SetAsGrounded\n  #Set UpB Timer\n    li\tr3,30\n    stw\tr3,Timer(EventData)\n  #Store To Backups as Well\n    lwz\tr3,0x18(EventData)\t\t#P2 Backup\n    lfs\tf1,0xB0(P2Data)\t     \t#Get P2 X\n    stfs\tf1,0xB0(r3)\t       \t#Store to P2 Backup\n    lfs\tf1,0xB4(P2Data)\t     \t#Get P2 Y\n    stfs\tf1,0xB4(r3)\t       \t#Store to P2 Backup\n    lfs\tf1,0x2C(P2Data)\t     \t#Get P2 Facing\n    stfs\tf1,0x2C(r3)\t       \t#Store to P2 Backup\n    lwz r4,0x83C(P2Data)      #Get P2 Ground ID\n    stw r4,0x83C(r3)          #Store to P2 Backup\n    lwz\tr3,0x10(EventData)\t\t#P1 Backup\n    lfs\tf1,0xB0(P1Data)\t    \t#Get P1 X\n    stfs\tf1,0xB0(r3)\t       \t#Store to P1 Backup\n    lfs\tf1,0xB4(P1Data)\t    \t#Get P1 X\n    stfs\tf1,0xB4(r3)\t       \t#Store to P1 Backup\n    lfs\tf1,0x2C(P1Data)\t     \t#Get P1 Facing\n    stfs\tf1,0x2C(r3)\t\t      #Store to P1 Backup\n    lwz r4,0x83C(P1Data)      #Get P1 Ground ID\n    stw r4,0x83C(r3)          #Store to P1 Backup\n  \tmr\tr3,P1GObj\n  \tbl\tCheckIfPlayerHasAFollower\n  \tcmpwi\tr3,0x0\n  \tbeq\tAmsahTechNoSubchar\n  \tlwz\tr3,0x14(EventData)\t\t#P1 Subchar Backup\n  \tlfs\tf1,0xB0(r4)\t\t#Get P1 Subchar X\n  \tstfs\tf1,0xB0(r3)\t\t#Store to P1 Subchar Backup\n  \tlfs\tf1,0x2C(r4)\t\t#Get P1 Subchar Facing\n  \tstfs\tf1,0x2C(r3)\t\t#Store to P1 Subchar Backup\n\tAmsahTechNoSubchar:\n    b AmsahTechCheckToReset\n\n  AmsahTech_NoGroundFound:\n  #Play Error SFX\n    li\tr3,0xAF\n    bl PlaySFX\n    b AmsahTechCheckToReset\n\n\t\tAmsahTechCheckUpBTimer:\n\t\t#Check For UpBTimer\n\t\tlwz\tr3,0x8(r31)\n\t\tcmpwi\tr3,0x0\t\t#No UpB Timer Set Yet\n\t\tble\tAmsahTechCheckToReset\n\t\t#Dec Timer\n\t\tsubi\tr3,r3,0x1\n\t\tstw\tr3,0x8(r31)\t\t#store timer\n\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\tbne\tAmsahTechCheckToReset\t#Exit If Not\n\t\t#Move Marth in Front of P1 Again (Fox's\n\t\tlfs\tf1,0xB0(r27)\t\t#Get P1 X\n\t\tlfs\tf2,0x2C(r27)\t\t#Get P1 Facing\n\t\tlfs\tf3,0x10(r21)\t\t#Get Marth Distance\n\t\tfmuls\tf2,f2,f3\t\t#Distance * Facing Direction\n\t\tfadds\tf1,f1,f2\t\t#P1.X + (Distance * Facing Direction)\n\t\tstfs\tf1,0xB0(r29)\t\t#Store Position to P2\n\t\t#Enter UpB\n\t\tli\tr3,0x200\n\t\tstw\tr3,0x1A88(r29)\n\t\tli\tr3,127\n\t\tstb\tr3,0x1A8D(r29)\n\t\t#Initiate Reset Timer\n\t\tli\tr3,120\n\t\tstw\tr3,0x4(r31)\n\n\t\t#Check To Reset\n\t\tAmsahTechCheckToReset:\n\t\tlwz\tr3,0x4(r31)\t\t#get timer\t#Get Timer\n\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\tble\tAmsahTechThinkExit\n\t\t#Dec Timer\n\t\tsubi\tr3,r3,0x1\n\t\tstw\tr3,0x4(r31)\t\t#store timer\n\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\tbne\tAmsahTechThinkExit\t#Exit If Not\n\n\t\tAmsahTechRestoreState:\n\t\t#Restore State\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tSaveState_Load\n\t\t#Restore Timers Just In Case\n\t\tli\tr3,0x0\n\t\tstw\tr3,0x4(r31)\n\t\tstw\tr3,0x8(r31)\n\n\t\tAmsahTechThinkExit:\n\t\trestore\n\t\tblr\n\n#################################\n\nAmsahTech_Floats:\nblrl\n.long 0x4308ca0c\t\t#P1 X Position\n.long 0x42942371\t\t#P2 X Position\n.long 0x00000000  #P1 Y Position\n.long 0x38d1b717\t\t#FD Floor Y Coord\n.long 0x41800000 \t#Distance to place Marth from P1\n.long 0x428C0000  #FD Stage Boundary X\n\n#################################\n\nAmsahTechLoadExit:\nrestore\nblr\n\n\n\n###########################################\n#endregion\n\n#region Combo Training\n################################\n## Combo Training HIJACK INFO ##\n################################\n\nComboTraining:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,-1\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_ComboTraining\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nbl\tComboTrainingLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Combo Training LOAD FUNCT ##\n\t########################\n\tComboTrainingLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tComboTrainingThink\n\tmflr\tr3\n\tli\tr4,3\t\t\t\t\t\t\t\t\t\t\t\t#Priority (After Interrupt)\n  bl\tComboTrainingWindowInfo\t\t\t#r4 = pointer to option info\n  mflr\tr5\n  bl\tComboTrainingWindowText\t\t\t#r5 = pointer to ASCII struct\n  mflr\tr6\n\tbl\tCreateEventThinkFunction\n\n\tbl\tInitializeHighScore\n\n\tb\tComboTrainingLoadExit\n\n\n\t\t#########################\n\t\t## Combo Training THINK FUNCT ##\n\t\t#########################\n\n    #Registers\n    .set MenuData,26\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n    #Offsets\n\t\t.set EventState,0x8\n\t\t.set DIBehavior,(MenuData_OptionMenuMemory+0x2)+0x0\n\t\t.set SDIBehavior,(MenuData_OptionMenuMemory+0x2)+0x1\n\t\t.set TechOption,(MenuData_OptionMenuMemory+0x2)+0x2\n\t\t.set PostHitstunAction,(MenuData_OptionMenuMemory+0x2)+0x3\n\t\t.set GrabMashout,(MenuData_OptionMenuMemory+0x2)+0x4\n    .set DIBehaviorToggled,(MenuData_OptionMenuToggled)+0x0\n\t\t.set SDIBehaviorToggled,(MenuData_OptionMenuToggled)+0x1\n\t\t.set TechOptionToggled,(MenuData_OptionMenuToggled)+0x2\n\t\t.set PostHitstunActionToggled,(MenuData_OptionMenuToggled)+0x3\n\t\t.set GrabMashoutToggled,(MenuData_OptionMenuToggled)+0x4\n\n\t\t#Definitions\n\t\t#DIBehavior\n\t\t\t.set DI_Random,0x0\n\t\t\t.set DI_Survival,0x1\n\t\t\t.set DI_ComboDI,0x2\n\t\t\t.set DI_SlightDIRandom,0x3\n\t\t\t.set DI_SlightDIInwards,0x4\n\t\t\t.set DI_DownAndAway,0x5\n\t\t\t.set DI_None,0x6\n\t\t#SDIBehavior\n\t\t\t.set SDI_33Percent,0x0\n\t\t\t.set SDI_66Percent,0x1\n\t\t\t.set SDI_Always,0x2\n\t\t\t.set SDI_None,0x3\n\n\t\tComboTrainingThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tr31,0x2c(r3)\t\t\t#backup data pointer in r31\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n    lwz MenuData,EventData_MenuDataPointer(EventData)\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tComboTrainingThinkMain\n\n        bl  PlacePlayersCenterStage\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n\t\t\t#Save State\n  \t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n  \t\t\tbl\tSaveState_Save\n\t\t\t#Init Score Count\n  \t\t\tlhz\tr3,-0x4ea8(r13)\n  \t\t\tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\n\n\t\tComboTrainingThinkMain:\n\n\t\t#Set Combo As Score\n\t\t\tli\tr3,0x0\n\t\t\tbranchl\tr12,0x8004134c\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\t#Check To Make New High Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tlhz\tr4,-0x4ea6(r13)\n\t\t\tcmpw\tr3,r4\n\t\t\tble\tComboTraining_SkipNewHighscore\n\t\t#Copy To High Score\n\t\t\tsth\tr3,-0x4ea6(r13)\n\t\tComboTraining_SkipNewHighscore:\n\n\t\t#Update HUD Score\n\t\tlhz\tr3,-0x4ea8(r13)\n\t\tcmpwi\tr3,0x1\n\t\tblt\tComboTraining_SkipHUDUpdate\n\t\tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\t\tComboTraining_SkipHUDUpdate:\n\n\t\t#DPad Right Makes New Savestate\n\t\t#Check If Trying to SaveState\n\t\tlwz\tr3,0x668(r27)\n\t\trlwinm.\tr0,r3,0,30,30\n\t\tbeq\tComboTraining_CheckForSaveAndLoad\n\t\t#Only Allow a Save If Event State is 0\n\t\tlbz\tr3,EventState(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tComboTraining_SkipCheckForSaveAndLoad\n\t\t#Only Allow a Save If P2 is in Wait\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xE\n\t\tbne\tComboTraining_SkipCheckForSaveAndLoad\n\t\tComboTraining_CheckForSaveAndLoad:\n\t\taddi\tr3,EventData,0x10\n\t\tbl\tCheckForSaveAndLoad\n\t\t#Check If Loaded Successfully\n\t\tcmpwi\tr3,0x1\n\t\tbne\tComboTraining_SkipCheckForSaveAndLoad\n\t\t#Restore Event State And Timer\n\t\tli\tr3,0x0\n\t\tstb\tr3,EventState(r31)\n\t\tstw\tr3,0x4(r31)\n\t\tComboTraining_SkipCheckForSaveAndLoad:\n\n\t\t#DPad Down Moves CPU In Front\n\t\t#Only If Event State = 0\n\t\tlbz\tr3,EventState(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tComboTrainingSkipMoveCPU\n    mr  r3,P1GObj\n    mr  r4,P2GObj\n    addi r5,EventData,0x10\n\t\tbl\tMoveCPU\n\t\tComboTrainingSkipMoveCPU:\n\n\t\t#L+DPad Controls CPU Percent\n\t\taddi r3,EventData,EventData_SaveStateStruct+(1*0x8)\n\t\tbl\tDPadCPUPercent\n\n\t\tbl\tGiveFullShields\n\n\t\t#Reset If Anyone Dies\n\t\tbl\tIsAnyoneDead\n\t\tcmpwi\tr3,0x0\n\t\tbne\tComboTrainingRestoreState\n\n\n\t############################\n\t## Check If Was Hit Again ##\n\t############################\n\n\t#Don't Run If Over 6 Frames in Escape Air\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xEC\n\t\tbne\tComboTrainingCheckIfP2isGrabbed\n\t\tli\tr3,6\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x894(r29)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbge\tComboTrainingCheckState\n\t#Check If P2 is Grabbed (Any Grab State)\n\tComboTrainingCheckIfP2isGrabbed:\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xDF\n\t\tblt\tComboTrainingStartCheckIfHit\n\t\tcmpwi\tr3,0xE8\n\t\tbgt\tComboTrainingStartCheckIfHit\n\t\tb\tComboTrainingChangeToRandomDIandTech\n\t#Check If P2 is Hit\n\tComboTrainingStartCheckIfHit:\n\t\tlbz\tr3,0x221A(r29)\t\t\t#Check If in Hitlag\n\t\trlwinm.\tr3,r3,0,26,26\n\t\tbne\tComboTrainingCheckIfBeingHit\n\t\tb\tComboTrainingCheckState\n\t\tComboTrainingCheckIfBeingHit:\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,ASID_DamageHi1\n\t\tblt\tComboTrainingCheckState\n\t\tcmpwi\tr3,ASID_DamageFlyRoll\n\t\tbgt\tComboTrainingCheckState\n\t\tComboTrainingChangeToRandomDIandTech:\n\t#Change To DI and Tech\n\t\tli\tr3,0x1\n\t\tstb\tr3,EventState(r31)\n\t\tb\tComboTrainingInputDIAndTech\n\n#Get Which State\nComboTrainingCheckState:\n\tlbz\tr3,EventState(r31)\n\tcmpwi\tr3,0x0\n\tbeq\tComboTrainingStart\n\tcmpwi\tr3,0x1\n\tbeq\tComboTrainingInputDIAndTech\n\tcmpwi\tr3,0x2\n\tbeq\tComboTrainingPostHitstun\n\n\nComboTrainingStart:\n\tb\tComboTrainingCheckToReset\n\nComboTrainingInputDIAndTech:\n\tbl\tComboTrainingCheckExitStates\n\tcmpwi\tr3,0x0\n\tbeq\tComboTrainingInputDIAndTechNoJiggs\n\tb\tComboTrainingChangeStateToPostHitstun\n\n\nComboTrainingInputDIAndTechNoJiggs:\n\tlwz\tr3,0x10(r29)\n\tcmpwi\tr3,0xB8\t\t#Missed Tech, Needs to Input a Roll or Attack\n\tbeq\tComboTrainingMissedTechThink\n\tcmpwi\tr3,0xC0\t\t#Missed Tech, Needs to Input a Roll or Attack\n\tbeq\tComboTrainingMissedTechThink\n#Check If Still Grabbed\n\tcmpwi r3,ASID_ShoulderedWait\n\tblt ComboTraining_GrabCheckSkipShoulder\n\tcmpwi r3,ASID_ShoulderedTurn\n\tble ComboTrainingMashOutOfGrab\nComboTraining_GrabCheckSkipShoulder:\n\tcmpwi\tr3,ASID_CaptureKoopa\n\tblt\tComboTraining_GrabCheckSkipKoopaLw\n\tcmpwi\tr3,ASID_CaptureWaitKoopa\n\tble\tComboTrainingMashOutOfGrab\nComboTraining_GrabCheckSkipKoopaLw:\n\tcmpwi\tr3,ASID_CaptureKoopaAir\n\tblt\tComboTraining_GrabCheckSkipKoopaAir\n\tcmpwi\tr3,ASID_CaptureWaitKoopaAir\n\tble\tComboTrainingMashOutOfGrab\nComboTraining_GrabCheckSkipKoopaAir:\n\tcmpwi\tr3,ASID_CapturePulledHi\t\t#CapturePulledLow\n\tblt\tComboTraining_GrabCheckSkipGrabbed\n\tcmpwi\tr3,ASID_CaptureFoot \t\t#CapturePulledHi\n\tble\tComboTrainingMashOutOfGrab\nComboTraining_GrabCheckSkipGrabbed:\n\tb\tComboTrainingDecideInputs\n\n#When Grabbed\n#Check Mash Out Behavior\nComboTrainingMashOutOfGrab:\n\tlbz\tr3,GrabMashout(MenuData)\n\tcmpwi\tr3,0x0\n\tbeq\tComboTrainingInputDIAndTech_RandomMash\n\tcmpwi\tr3,0x1\n\tbeq\tComboTrainingInputDIAndTech_RandomMash_AnalogInput\n\tcmpwi\tr3,0x2\t\t\t\t\t\t\t\t#No Mash\n\tbeq\tComboTrainingCheckToReset\n\n\n\t#Random Mash Out\n\tComboTrainingInputDIAndTech_RandomMash:\n\t#Only start randomly mashing after a few frames (to simulate human reaction)\n\t\tlwz r3,0x10(r29)\n\t\tcmpwi\tr3,ASID_CapturePulledHi\t\t#CapturePulledLow\n\t\tblt\tComboTrainingInputDIAndTech_RandomMashStart\n\t\tcmpwi\tr3,ASID_CaptureFoot \t\t#CapturePulledHi\n\t\tbgt\tComboTrainingInputDIAndTech_RandomMashStart\n\t#In a normal grab state, should wait a few frames before starting to mash\n\n\tComboTrainingInputDIAndTech_RandomMashStart:\n\t\tli\tr3,10\t\t\t\t\t\t\t\t\t\t#1- Numbers\n\t\tbranchl\tr12,HSD_Randi\n\t\tcmpwi\tr3,7\t\t\t\t\t\t\t\t\t#7 and below are no input\n\t\tble\tComboTrainingCheckToReset\n\t\tcmpwi\tr3,8\t\t\t\t\t\t\t\t\t#8 = Button Only, 9 = Both Analog and Button\n\t\tbeq\tComboTrainingInputDIAndTech_RandomMash_ButtonPress\n\n\tComboTrainingInputDIAndTech_RandomMash_AnalogInput:\n\t\tli\tr3,127\n\t\tstb\tr3,0x1A8C(r29)\t\t\t#Push Analog Stick Forward\n\t\tli\tr3,-1\n\t\tstb\tr3,0x1A50(r29)\t\t\t#Spoof Analog Stick as First Frame Pushed\n\n\tComboTrainingInputDIAndTech_RandomMash_ButtonPress:\n\t\t#Input Button Press\n\t\tli\tr3,0x100\n\t\tstw\tr3,0x1A88(r29)\t\t\t#Press A\n\t\tli\tr3,0\n\t\tstw\tr3,0x65C(r29)\t\t\t#Spoof Prev Frame Buttons as Nothing Pushed\n\n\t\tb\tComboTrainingCheckToReset\n\n\n\t\tComboTrainingChangeStateToPostHitstun:\n\t\t#Change State\n\t\tli\tr3,0x2\n\t\tstb\tr3,EventState(r31)\n\t\tb\tComboTrainingPostHitstun\n\n\n\n\n\n\t\tComboTrainingDecideInputs:\n\n\n\t\t#CHECK TO DI ATTACK\n\t\tComboTrainingDIThrowsAndHits:\n\t\t#Check If in Hitlag\n\t\t\tlbz\tr3,0x221A(r29)\n\t\t\trlwinm.\tr3,r3,0,26,26\n\t\t\tbeq\tComboTrainingCheckIfBeingThrown\n\t\t#Check If In Last Frame of Hitlag\n\t\t\tlfs\tf1,-0x7418(rtoc)\t\t#1fp\n\t\t\tlfs\tf2,0x195C(r29)\t\t  #hitlag frames left\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tbne\tComboTrainingCheckToReset\n\t\t#Check If Attack Was Strong\n\t\t#DI Attack\n\t\t\tlbz\tr3,DIBehavior(MenuData)\t\t#Get DI Behavior\n\t\t\tcmpwi\tr3,DI_SlightDIInwards\t\t#Check If Slight In\n\t\t\tbne\t0x8\n\t\t\tli\tr3,0x0\t\t#Override To Never Slight DI In Attacks\n\t\t\tb\t0x8\n\t\t\tli\tr3,0x2\n\t\t\tbl\tComboTrainingDecideStickAngle\n\t\t#SDI Attack\n\t\t\tlbz\tr3,SDIBehavior(MenuData)\t\t#Get SDI Behavior\n\t\t\tcmpwi\tr3,SDI_None\t\t#No SDI\n\t\t\tbeq\tComboTrainingNoSDI\n\t\t\tcmpwi\tr3,SDI_Always\t\t#Always SDI\n\t\t\tbeq\tComboTrainingCheckToReset\n\n\t\t\tli\tr3,0x3\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tlbz\tr4,SDIBehavior(MenuData)\t\t#Get SDI Behavior\n\t\t\tcmpwi\tr4,SDI_33Percent\n\t\t\tbeq\tComboTraining33PercentSDI\n\t\t\tcmpwi\tr4,SDI_66Percent\n\t\t\tbeq\tComboTraining66PercentSDI\n\t\t\tComboTraining33PercentSDI:\n\t\t\tli\tr4,0\n\t\t\tb\tComboTrainingCompareSDIChance\n\t\t\tComboTraining66PercentSDI:\n\t\t\tli\tr4,1\n\t\t\tb\tComboTrainingCompareSDIChance\n\n\t\t\tComboTrainingCompareSDIChance:\n\t\t\tcmpw\tr3,r4\n\t\t\tble\tComboTrainingGetChanceToTech\n\t\t#Don't SDI\n\t\tComboTrainingNoSDI:\n\t\t\tmr\tr3,r29\n\t\t\tbranchl\tr12,CPU_JoystickXAxis_Convert\n\t\t\tstfs\tf1,0x620(r29)\n\t\t\tmr\tr3,r29\n\t\t\tbranchl\tr12,CPU_JoystickYAxis_Convert\n\t\t\tstfs\tf1,0x624(r29)\n\t\t\tb\tComboTrainingGetChanceToTech\n\n\n\n\n\n\t\t#CHECK TO DI A THROW\n\t\tComboTrainingCheckIfBeingThrown:\n\t\t#Check If Being Thrown\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0xEF\n\t\t\tblt\tComboTrainingCheckToJumpOutOfHitstun\n\t\t\tcmpwi\tr3,0xF3\n\t\t\tbgt\tComboTrainingCheckToJumpOutOfHitstun\n\t\tComboTrainingInputDI:\n\t\t\tlbz\tr3,DIBehavior(MenuData)\n\t\t\tbl\tComboTrainingDecideStickAngle\n\t\t\tb\tComboTrainingCheckToReset\n\n\n\n\n\n\n\t\t#NOT BEING THROWN OR LAST FRAME OF HITLAG\n\t\t#CHECK TO JUMP OUT OF HITSTUN AND BECOME INVINCIBLE\n\t\tComboTrainingCheckToJumpOutOfHitstun:\n\t\t#Check If in Damage State\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x26\t\t#Tumble\n\t\tbeq\tComboTrainingCheckIfInAir\n\t\tcmpwi\tr3,0x4B\n\t\tblt\tComboTrainingCheckToReset\n\t\tcmpwi\tr3,0x5B\n\t\tbgt\tComboTrainingCheckToReset\n\n\t\t#IN A DAMAGE STATE\n\t\t#Check If In Air\n\t\tComboTrainingCheckIfInAir:\n\t\tlwz\tr3,0xE0(r29)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tComboTrainingDamageGrounded\n\n\t\t#IN THE AIR\n\t\t#Check If Still in Hitstun\n\t\tlbz\tr3,0x221C(r29)\n\t\trlwinm.\tr3,r3,0,30,30\n\t\tbne\tComboTrainingGetChanceToTech\n\n\t\t#NOT IN HITSTUN\n\t\t#Check Post Hitstun Behavior\n\t\tlbz\tr3,PostHitstunAction(MenuData)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tComboTrainingAirdodge\n\t\tcmpwi\tr3,0x1\n\t\tbeq\tComboTrainingJumpAndInvincible\n\t\tcmpwi\tr3,0x2\n\t\tbeq\tComboTrainingAerialAttack\n\n\t\t\tComboTrainingJumpAndInvincible:\n\t\t\t#Always Jump\n\t\t\t#li\tr3,0\n\t\t\t#stw\tr3,0x1A8C(r29)\t\t#Nuetralize Stick Inputs\n\t\t\t#i\tr3,0x400\n\t\t\t#stw\tr3,0x1A88(r29)\t\t#X Button\n\t\t\tb\tComboTrainingChangeStateToPostHitstun\n\n\t\t\tComboTrainingAirdodge:\n\t\t\t#Wiggle Out of Hitstun\n\t\t\tli\tr3,127\n\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\t#Last Frame's Stick Was Centered\n\t\t\tli\tr3,0x0\n\t\t\tstw\tr3,0x628(r29)\n\t\t\tstw\tr3,0x62C(r29)\n\t\t\t#Stick Frame Timer Reset\n\t\t\tli\tr3,255\n\t\t\tstb\tr3,0x670(r29)\n\t\t\t#Change State\n\t\t\tli\tr3,0x2\n\t\t\tstb r3,0x8(r31)\n\t\t\tb\tComboTrainingPostHitstun\n\n\t\t\tComboTrainingAerialAttack:\n\t\t\t#li\tr3,0x100\n\t\t\t#stw\tr3,0x1A88(r29)\t\t#Nair\n\t\t\t#Change State\n\t\t\tli\tr3,0x2\n\t\t\tstb\tr3,EventState(r31)\n\t\t\tb\tComboTrainingPostHitstun\n\n\n\n\t\t#CHECK TO BECOME INVINCIBLE OUT OF GROUNDED LIGHT DAMAGE STATES\n\t\tComboTrainingDamageGrounded:\n\t\t#Check For Hitstun (Can Act Out of Certain Light Damage States)\n\t\tlbz\tr3,0x221C(r29)\n\t\trlwinm.\tr3,r3,0,30,30\n\t\tbne\tComboTrainingCheckToReset\n\t\t#Grounded, No Hitstun Left, Become Invincible and Spotdodge\n\t\t\t#Check Post Hitstun Behavior\n\t\t\tlbz\tr3,PostHitstunAction(MenuData)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingGroundedSpotdodge\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbeq\tComboTrainingGroundedInvincibility\n\t\t\tcmpwi\tr3,0x2\n\t\t\tbeq\tComboTrainingGroundedAttack\n\n\t\t\tComboTrainingGroundedInvincibility:\n\t\t\tb\tComboTrainingChangeStateToPostHitstun\n\n\t\t\tComboTrainingGroundedSpotdodge:\n\t\t\tli\tr3,0xC0\t\t#Hit L\n\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\tli\tr3,-127\t\t#Hold Down\n\t\t\tstb r3,0x1A8D(r29)\t\t#Stick Y\n\t\t\tb\tComboTrainingChangeStateToPostHitstun\n\n\t\t\tComboTrainingGroundedAttack:\n\t\t\t#li\tr3,0x100\t\t#Hit A\n\t\t\t#stw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\tb\tComboTrainingChangeStateToPostHitstun\n\n\n\n\n\tComboTrainingGetChanceToTech:\n\t#INPUT A TECH WHEN IN AERIAL HITSTUN\n\t\tlbz\tr3,TechOption(MenuData)\t\t#Get Tech Behavior\n\t\tcmpwi\tr3,0x0\t\t#Random Tech (Original Behavior)\n\t\tbeq\tComboTrainingRandomTech\n\t\tcmpwi\tr3,0x1\t\t#Miss Tech\n\t\tbeq\tComboTrainingMissTech\n\t\tcmpwi\tr3,0x2\n\t\tbeq\tComboTrainingTechInPlace\n\t\tcmpwi\tr3,0x3\n\t\tbeq\tComboTrainingTechTowards\n\t\tcmpwi\tr3,0x4\n\t\tbeq\tComboTrainingTechAway\n\n\tComboTrainingRandomTech:\n\t#Reset Tech Cooldown Window Constantly\n\t\tli\tr3,0x1\n\t\tstb\tr3,0x680(r29)\t\t#Frames Since Pressed L/R\n\t\tli\tr3,0xFF\n\t\tstb\tr3,0x684(r29)\t\t#L/R Lockout Window\n\t#Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise)\n\t\tlbz\tr3,0x221A(r29)\n\t\trlwinm.\tr3,r3,0,26,26\n\t\tbne\tComboTrainingCheckToReset\n\t#Tech Random Side\n\tComboTrainingRandomTech_GetStickAngle:\n\t\tli\tr3,4\t\t\t\t\t\t\t\t\t#Decide between left right and center and none\n\t\tbranchl\tr12,HSD_Randi\n\t\tcmpwi r3,0x0\n\t\tbeq ComboTrainingRandomTech_TechInPlace\n\t\tcmpwi r3,0x1\n\t\tbeq ComboTrainingRandomTech_TechLeft\n\t\tcmpwi r3,0x2\n\t\tbeq ComboTrainingRandomTech_TechRight\n\t\tcmpwi r3,0x3\n\t\tbeq ComboTrainingMissTech\n\n\tComboTrainingRandomTech_TechInPlace:\n\t\tli\tr3,0\n\t\tstb r3,0x1A8C(r29)\n\t\tstb r3,0x1A8D(r29)\n\t\tb\tComboTrainingCheckToReset\n\tComboTrainingRandomTech_TechLeft:\n\t\tli\tr3,-127\n\t\tstb r3,0x1A8C(r29)\n\t\tb\tComboTrainingCheckToReset\n\tComboTrainingRandomTech_TechRight:\n\t\tli\tr3,127\n\t\tstb r3,0x1A8C(r29)\n\t\tb\tComboTrainingCheckToReset\n\tComboTrainingMissTech:\n\t\tli\tr3,0x0\n\t\tstw\tr3,0x1A88(r29)\n\t#Fail Tech Cooldown\n\t\tli\tr3,0xFF\n\t\tstb\tr3,0x680(r29)\n\t\tli\tr3,0x00\n\t\tstb\tr3,0x684(r29)\n\t\tb\tComboTrainingCheckToReset\n\n\tComboTrainingTechInPlace:\n\t\t#Hold L\n\t\tli\tr3,0xC0\n\t\tstw\tr3,0x1A88(r29)\n\t#Reset Tech Cooldown Window Constantly\n\t\tli\tr3,0x0\n\t\tstb\tr3,0x680(r29)\n\t\tli\tr3,0xFF\n\t\tstb\tr3,0x684(r29)\n\t#Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise)\n\t\tlbz\tr3,0x221A(r29)\n\t\trlwinm.\tr3,r3,0,26,26\n\t\tbne\tComboTrainingCheckToReset\n\t\tli\tr3,0x0\n\t\tstb\tr3,0x1A8C(r29)\n\t\tb\tComboTrainingCheckToReset\n\n\t\tComboTrainingTechTowards:\n\t\t#Hold L\n\t\tli\tr3,0xC0\n\t\tstw\tr3,0x1A88(r29)\n\t\t#Reset Tech Cooldown Window Constantly\n\t\tli\tr3,0x0\n\t\tstb\tr3,0x680(r29)\n\t\tli\tr3,0xFF\n\t\tstb\tr3,0x684(r29)\n\t\t#Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise)\n\t\tlbz\tr3,0x221A(r29)\n\t\trlwinm.\tr3,r3,0,26,26\n\t\tbne\tComboTrainingCheckToReset\n\t\t#Push Towards Opponent's Direction\n\t\tbl\tGetDirectionInRelationToP1\n\t\tmulli\tr3,r3,-1\t\t#Negate This\n\t\tli\tr4,127\n\t\tmullw\tr3,r3,r4\n\t\tstb\tr3,0x1A8C(r29)\n\t\tb\tComboTrainingCheckToReset\n\n\t\tComboTrainingTechAway:\n\t\t#Hold L\n\t\tli\tr3,0xC0\n\t\tstw\tr3,0x1A88(r29)\n\t\t#Reset Tech Cooldown Window Constantly\n\t\tli\tr3,0x0\n\t\tstb\tr3,0x680(r29)\n\t\tli\tr3,0xFF\n\t\tstb\tr3,0x684(r29)\n\t\t#Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise)\n\t\tlbz\tr3,0x221A(r29)\n\t\trlwinm.\tr3,r3,0,26,26\n\t\tbne\tComboTrainingCheckToReset\n\t\tbl\tGetDirectionInRelationToP1\n\t\tli\tr4,127\n\t\tmullw\tr3,r3,r4\n\t\tstb\tr3,0x1A8C(r29)\n\t\tb\tComboTrainingCheckToReset\n\n\t\t#INPUT AN ATTACK OR DIRECTION WHEN MISSED A TECH\n\t\tComboTrainingMissedTechThink:\n\t\t\tli\tr3,4\t\t#1/4 chance to getup attack\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingMissedTech_GetupAttack\n\t\t#No Getup Attack, Input Random Direction\n\t\t\tli r3,0\n\t\t\tbl\tComboTrainingDecideStickAngle\n\t\t\tb\t\tComboTrainingCheckToReset\n\t\t#Input Getup Attack\n\t\tComboTrainingMissedTech_GetupAttack:\n\t\t\tli\tr3,0x100\t\t#Press A To Getup Attack\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tComboTrainingCheckToReset\n\n\n\n\t\t########################\n\t\t## Post Hitstun Think ##\n\t\t########################\n\n\n\t\tComboTrainingPostHitstun:\n\n\t\t#Check Post Hitstun Behavior\n\t\tlbz\tr3,PostHitstunAction(MenuData)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\t\tComboTrainingPostHitstun_AirdodgeSpotdodge\n\t\tcmpwi\tr3,0x1\n\t\tbeq\t\tComboTrainingPostHitstun_GiveInvinc\n\t\tcmpwi\tr3,0x2\n\t\tbeq\t\tComboTrainingPostHitstun_Attack\n\n\t\t\tComboTrainingPostHitstun_GiveInvinc:\n\t\t\t#Constantly Press Jump If In The Air\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingPostHitstun_GiveInvinc_ApplyInvinc\n\t\t\tli\tr3,0x800\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\t#Clear Prev Frame Jump Input\n\t\t\tli\tr3,0x0\n\t\t\tstw\tr3,0x668(r29)\n\t\t\t#Apply Invinc\n\t\t\tComboTrainingPostHitstun_GiveInvinc_ApplyInvinc:\n\t\t\tmr\tr3,r30\n\t\t\tli\tr4,30\n\t\t\tbranchl\tr12,ApplyIntangibility\n\t\t\t#UpdateGFX\n\t\t\tmr\tr3,r30\n\t\t\tbranchl\tr12,GFX_UpdatePlayerGFX\n\t\t\t#Set Timer if Not Set\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbgt\tComboTrainingCheckToReset\n\t\t\t#Set Timer\n\t\t\tli\tr3,30\n\t\t\tstw\tr3,0x4(r31)\n\t\t\tb\tComboTrainingCheckToReset\n\n\t\t#****************************************************************#\n\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge:\n\t\t\t#Check If In Airdodge\n\t\t\t#Check If In Gained Invuln From Air/Spotdodge\n\t\t\tlwz\tr3,0x1988(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge\n\t\t\tb\tComboTrainingPostHitstun_EnteredAirdodgeSpotdodge\n\t\t\tComboTrainingPostHitstun_EnteredAirdodgeSpotdodge:\n\t\t\t#Set Timer if Not Set\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbgt\tComboTrainingCheckToReset\n\t\t\t#Set Timer\n\t\t\tli\tr3,30\n\t\t\tstw\tr3,0x4(r31)\n\t\t\t#Give Invince and Exit\n\t\t\tb\tComboTrainingCheckToReset\n\n\t\t#****************************************************************#\n\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge:\n\t\t\t#If in An Exit State, Reset State\n\t\t\tbl\tComboTrainingCheckExitStates\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState\n\t\t\t#Except Fall\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x1D\n\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState\n\t\t\t#Except Landing\n\t\t\tcmpwi\tr3,0x2A\n\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState\n\t\t\t#Except Wait\n\t\t\tcmpwi\tr3,0xE\n\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState\n\t\t\t#Set Timer if Not Set\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbgt\tComboTrainingCheckToReset\n\t\t\t#Set Timer\n\t\t\tli\tr3,30\n\t\t\tstw\tr3,0x4(r31)\n\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState:\n\t\t\t#Check If in Air\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_CheckToSpotdodge\n\t\t\t#Check If In DamageLightHit With No Hitstun Left (Same interrupts as Fall)\n\t\t\t\tlwz\tr3,0x10(r29)\n\t\t\t\tcmpwi\tr3,0x56\n\t\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_InputAirdodge\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckToWiggleOut:\n\t\t\t#Check If In Damage States\n\t\t\t\tlwz\tr3,0x10(r29)\n\t\t\t\tcmpwi\tr3,0x4B\n\t\t\t\tblt\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckForFall\n\t\t\t\tcmpwi\tr3,0x5B\n\t\t\t\tbgt\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckForFall\n\t\t\t#Wiggle Out to Enter Fall\n\t\t\t\tli\tr3,127\n\t\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\t\tb\tComboTrainingCheckToReset\n\t\t\t#Check If In Fall\n\t\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckForFall:\n\t\t\t\tlwz\tr3,0x10(r29)\n\t\t\t\tcmpwi\tr3,0x1D\n\t\t\t\tbne\tComboTrainingCheckToReset\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_InputAirdodge:\n\t\t\t#Airdodge\n\t\t\t\tli\tr3,0\n\t\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\t\tli\tr3,0xC0\n\t\t\t\tstw\tr3,0x1A88(r29)\n\t\t\t#Clear Buttons From Last Frame\n\t\t\t\tli\tr3,0x0\n\t\t\t\tstw\tr3,0x65C(r29)\n\t\t\t\tb\tComboTrainingCheckToReset\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_CheckToSpotdodge:\n\t\t\t#Check If Grounded and Actionable\n\t\t\t\tlwz\tr3,0x10(r29)\n\t\t\t\tcmpwi\tr3,0xE\t\t#Wait\n\t\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_Spotdodge\n\t\t\t\tcmpwi\tr3,0xB6\t\t#Shielding\n\t\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_Spotdodge\n\t\t\t\tcmpwi\tr3,0x2A\t\t#Land\n\t\t\t\tbne\tComboTrainingCheckToReset\n\t\t\t\t#Check If Can Interrupt Land\n\t\t\t\t\tlfs\tf1,0x894(r29)\n\t\t\t\t\tlfs\tf2,0x1F4(r29)\n\t\t\t\t\tfcmpo\tcr0,f1,f2\n\t\t\t\t\tblt\tComboTrainingCheckToReset\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_Spotdodge:\n\t\t\t#Clear Buttons From Last Frame\n\t\t\tli\tr3,0x0\n\t\t\tstw\tr3,0x65C(r29)\n\t\t\t#Input Spotdodge\n\t\t\tli\tr3,0xC0\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tli\tr3,-127\n\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\tb\tComboTrainingCheckToReset\n\n\t\t#****************************************************************#\n\n\t\t\tComboTrainingPostHitstun_Attack:\n\n\t\t\t#Clear Buttons From Last Frame\n\t\t\tli\tr3,0x0\n\t\t\tstw\tr3,0x65C(r29)\n\n\t\t\t#Get Air or Ground\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingPostHitstun_AttackGround\n\n\t\t\tComboTrainingPostHitstun_AttackAir:\n\t\t\tbl\tComboTrainingAttackList\n\t\t\tmflr\tr5\n\t\t\tlwz\tr4,0x4(r29)\n\t\t\tlbzx\tr3,r4,r5\n\t\t\trlwinm\tr3,r3,0,28,31\t\t#Get Right Bits\n\t\t\tb\tComboTrainingPostHitstun_Attack_BranchToAttack\n\n\t\t\tComboTrainingPostHitstun_AttackGround:\n\t\t\tbl\tComboTrainingAttackList\n\t\t\tmflr\tr5\n\t\t\tlwz\tr4,0x4(r29)\n\t\t\tlbzx\tr3,r4,r5\n\t\t\trlwinm\tr3,r3,28,28,31\t\t#Get Left Bits\n\t\t\tb\tComboTrainingPostHitstun_Attack_BranchToAttack\n\n\n\t\t\tComboTrainingPostHitstun_Attack_BranchToAttack:\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_A\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_ForwardA\n\t\t\tcmpwi\tr3,0x2\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_BackA\n\t\t\tcmpwi\tr3,0x3\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_DownA\n\t\t\tcmpwi\tr3,0x4\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_UpA\n\t\t\tcmpwi\tr3,0x5\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_DownSmash\n\t\t\tcmpwi\tr3,0x6\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_UpB\n\t\t\tcmpwi\tr3,0x7\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_DownB\n\n\t\t\t\tComboTrainingPostHitstun_Attack_A:\n\t\t\t\tli\tr3,0x100\t\t#Hit A\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_ForwardA:\n\t\t\t\t#Push Towards Opponent's Direction\n\t\t\t\tbl\tGetDirectionInRelationToP1\n\t\t\t\tmulli\tr3,r3,-1\t\t#Negate This\n\t\t\t\tli\tr4,60\n\t\t\t\tmullw\tr3,r3,r4\n\t\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\t\tli\tr3,0x100\t\t#Hit A\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_BackA:\n\t\t\t\t#Push Away Opponent's Direction\n\t\t\t\tbl\tGetDirectionInRelationToP1\n\t\t\t\tli\tr4,60\n\t\t\t\tmullw\tr3,r3,r4\n\t\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\t\tli\tr3,0x100\t\t#Hit A\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_DownA:\n\t\t\t\tli\tr3,60\n\t\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\t\tli\tr3,0x100\t\t#Hit A\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_UpA:\n\t\t\t\tli\tr3,60\n\t\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\t\tli\tr3,0x100\t\t#Hit A\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_DownSmash:\n\t\t\t\tli\tr3,-127\n\t\t\t\tstb\tr3,0x1A8F(r29)\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_UpB:\n\t\t\t\tli\tr3,127\n\t\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\t\tli\tr3,0x200\t\t#Hit B\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_DownB:\n\t\t\t\tli\tr3,-127\n\t\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\t\tli\tr3,0x200\t\t#Hit B\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\n\n\t\t\t#Search For Active Hitbox\n\t\t\tComboTrainingPostHitstun_Attack_CheckForHitbox:\n\t\t\tmr\tr3,r30\n\t\t\tbl\tCheckForActiveHitboxes\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tComboTrainingPostHitstun_GiveInvinc_ApplyInvinc\n\t\t\t#Harcoded Fox Grounded Shine Check =(\n\t\t\tlwz\tr3,0x4(r29)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_CheckForGroundShine\n\t\t\tcmpwi\tr3,0x16\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_CheckForGroundShine\n\t\t\t#Hardcoded Puff Rest Check =(\n\t\t\tcmpwi\tr3,0xF\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_CheckForRest\n\t\t\tb\tComboTrainingCheckToReset\n\t\t\tComboTrainingPostHitstun_Attack_CheckForGroundShine:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x168\n\t\t\tbeq\tComboTrainingPostHitstun_GiveInvinc_ApplyInvinc\n\t\t\tb\tComboTrainingCheckToReset\n\t\t\tComboTrainingPostHitstun_Attack_CheckForRest:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x171\n\t\t\tbeq\tComboTrainingPostHitstun_GiveInvinc_ApplyInvinc\n\t\t\tb\tComboTrainingCheckToReset\n\n\n\t\t#****************************************************************#\n\n\t\t#Check To Reset\n\t\tComboTrainingCheckToReset:\n\t\tlwz\tr3,0x4(r31)\t\t#get timer\n\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\tble\tComboTrainingThinkExit\n\t\t#Dec Timer\n\t\tsubi\tr3,r3,0x1\n\t\tstw\tr3,0x4(r31)\t\t#store timer\n\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\tbne\tComboTrainingThinkExit\t#Exit If Not\n\n\t\tComboTrainingRestoreState:\n\t\t#Restore State\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tSaveState_Load\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tSaveState_Load\n\t\t#Reset State ID\n\t\tli\tr3,0x0\n\t\tstb\tr3,EventState(r31)\n\t\tComboTrainingThinkExit:\n    mr  r3,MenuData\n    bl  ClearToggledOptions\n\t\tbl\tUpdateAllGFX\n\t\trestore\n\t\tblr\n\n#################################\n\nComboTraining_StartingGroundIDs:\nblrl\n#Ground IDs to start on\n.long 0xFFFFFFFF #Dummy, TEST\n.long 0x00050022 #FoD, Pokemon Stadium\n.long 0x00050037 #Peach's Castle, Kongo Jungle\n.long 0x000B0012 #Brinstar, Corneria\n.long 0x00030019 #Yoshi's Story, Onett\n.long 0x00000048 #Mute City, Rainbow Cruise\n.long 0x00000024 #Jungle Japes, Great Bay\n.long 0x00190007 #Hyrule Temple, Brinstar Depths\n.long 0x000E0026 #Yoshi's Island, Green Greens\n.long 0x00040003 #Fourside, MKI\n.long 0x00040000 #MKII, Akaneia\n.long 0x00010105 #Venom, PokeFloats\n.long 0x00D9015B #Big Blue, Icicle Mountain\n.long 0x00000064 #Icetop, Flatzone\n.long 0x00040009 #Dream Land, Yoshis Island 64\n.long 0x000b0001 #Kongo Jungle 64, Battlefield\n.long 0x00010000 #Final Destination\n#################################\n\nComboTrainingDecideStickAngle:\n#Decide Stick Angle\nbackup\n\n#Clear Stick Inputs Just in Case\nli\tr4,0x0\nstb\tr4,0x1A8C(r29)\nstb\tr4,0x1A8D(r29)\n\n#Check Which Type Of DI To Perform\ncmpwi\tr3,DI_Random\nbeq\tComboTrainingDecideStickAngle_RandomDI\ncmpwi\tr3,DI_Survival\nbeq\tComboTrainingDecideStickAngle_SurvivalDI\ncmpwi\tr3,DI_ComboDI\nbeq\tComboTrainingDecideStickAngle_ComboDI\ncmpwi\tr3,DI_SlightDIRandom\nbeq\tComboTrainingDecideStickAngle_RandomDI_SlightDI\ncmpwi\tr3,DI_SlightDIInwards\nbeq\tComboTrainingDecideStickAngle_SlightDIInwards\ncmpwi\tr3,DI_DownAndAway\nbeq\tComboTrainingDecideStickAngle_DownAwayDI\ncmpwi\tr3,DI_None\nbeq\tComboTrainingDecideStickAngle_NoDI\n\n###############\n## Random DI ##\n###############\n\n#Roll RNG\nComboTrainingDecideStickAngle_RandomDI:\n\tli\tr3,6\n\tbranchl\tr12,HSD_Randi\n\tcmpwi\tr3,0x0\n\tbeq\tComboTrainingDecideStickAngle_RandomDI_TrulyRandom\n\tcmpwi\tr3,0x1\n\tbeq\tComboTrainingDecideStickAngle_ComboDI\n\tcmpwi\tr3,0x2\n\tbeq\tComboTrainingDecideStickAngle_SurvivalDI\n\tcmpwi r3,0x3\n\tbeq ComboTrainingDecideStickAngle_RandomDI_SlightDI\n\tcmpwi r3,0x4\n\tbeq\tComboTrainingDecideStickAngle_DownAwayDI\n\tcmpwi\tr3,0x5\n\tbeq\tComboTrainingDecideStickAngle_NoDI\n\nComboTrainingDecideStickAngle_RandomDI_TrulyRandom:\n.set Combo_RandomAnalogMin, 36\n.set Combo_RandomAnalogMax, 127\n\n#Get X magnitude\n\tli\tr3,Combo_RandomAnalogMax - Combo_RandomAnalogMin\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,Combo_RandomAnalogMin\n\tstb r3,0x1A8C(r29)\n#Chance to negate\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0x0\n\tbeq 0x10\n\tlbz r3,0x1A8C(r29)\n\tneg r3,r3\n\tstb r3,0x1A8C(r29)\n#Get Y magnitude\n\tli\tr3,Combo_RandomAnalogMax - Combo_RandomAnalogMin\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,Combo_RandomAnalogMin\n\tstb r3,0x1A8D(r29)\n#Chance to negate\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0x0\n\tbeq 0x10\n\tlbz r3,0x1A8D(r29)\n\tneg r3,r3\n\tstb r3,0x1A8D(r29)\n\tb\tComboTrainingDecideStickAngleExit\n\nComboTrainingDecideStickAngle_RandomDI_SlightDI:\n.set Combo_SlightAnalogMin, 36\n.set Combo_SlightAnalogMax, 66\n\n#Get X magnitude\n\tli\tr3,Combo_SlightAnalogMax - Combo_SlightAnalogMin\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,Combo_RandomAnalogMin\n\tstb r3,0x1A8C(r29)\n#Chance to negate\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0x0\n\tbeq 0x10\n\tlbz r3,0x1A8C(r29)\n\tneg r3,r3\n\tstb r3,0x1A8C(r29)\n#Get Y magnitude\n\tli\tr3,Combo_SlightAnalogMax - Combo_SlightAnalogMin\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,Combo_SlightAnalogMin\n\tstb r3,0x1A8D(r29)\n#Chance to negate\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0x0\n\tbeq 0x10\n\tlbz r3,0x1A8D(r29)\n\tneg r3,r3\n\tstb r3,0x1A8D(r29)\n\tb\tComboTrainingDecideStickAngleExit\n\n#######################\n## Slight DI Towards ##\n#######################\n\nComboTrainingDecideStickAngle_SlightDIInwards:\n\n#Get Random Stick X Input 86-105, 86-95 go in front, 96-105 go behind shiek\nli\tr3,19\nbranchl\tr12,HSD_Randi\naddi\tr3,r3,86\t\t#Start at 86\nlfs\tf1,0x2C(r27)\nfneg\tf1,f1\nfctiwz\tf1,f1\nstfd\tf1,0xF0(sp)\nlwz\tr4,0xF4(sp)\t\t#Facing direction as int\nmullw\tr3,r3,r4\nstb\tr3,0x1A8C(r29)\nb\tComboTrainingDecideStickAngleExit\n\n#################\n## Survival DI ##\n#################\n\nComboTrainingDecideStickAngle_SurvivalDI:\n#Check If In Throw\nbl\tComboTrainingCheckForThrowAngle\ncmpwi\tr3,-1\nbne\tComboTrainingDecideStickAngle_SurvivalDI_UsingThrowAngle\n#Get Knockback Angle\nlwz\tr3,0x1848(r29)\nComboTrainingDecideStickAngle_SurvivalDI_UsingThrowAngle:\n\n#Get Perpendicular Angle\n#Get Damage Direction\ncmpwi\tr3,0x169\t\t#Check For Sakurai Angle\nbne\t0xC\nli\tr3,0x2D\nli\tr4,0x2D\ncmpwi\tr3,90\nbge\tComboTrainingDecideStickAngle_SurvivalDI_Above90\nb\tComboTrainingDecideStickAngle_SurvivalDI_RightSide\nComboTrainingDecideStickAngle_SurvivalDI_Above90:\ncmpwi\tr3,269\nblt\tComboTrainingDecideStickAngle_SurvivalDI_LeftSide\nComboTrainingDecideStickAngle_SurvivalDI_RightSide:\naddi\tr3,r3,90\ncmpwi\tr3,360\nblt\t0x8\nsubi\tr3,r3,360\nb\tComboTrainingDecideStickAngle_SurvivalDI_GetXY\nComboTrainingDecideStickAngle_SurvivalDI_LeftSide:\nsubi\tr3,r3,90\ncmpwi\tr3,0\nbgt\t0x8\naddi\tr3,r3,360\nb\tComboTrainingDecideStickAngle_SurvivalDI_GetXY\n\nComboTrainingDecideStickAngle_SurvivalDI_GetXY:\nbl\tComboTrainingDecideStickAngle_ConvertAngle\nstb\tr3,0x1A8C(r29)\nstb\tr4,0x1A8D(r29)\nbl\tGetDirectionInRelationToP1\n#mulli\tr3,r3,-1\t\t#Negate This Value\nlbz\tr4,0x1A8C(r29)\nmullw\tr3,r3,r4\nstb\tr3,0x1A8C(r29)\t\t#Point Towards Opponent\nb\tComboTrainingDecideStickAngleExit\n\n##############\n## Combo DI ##\n##############\n\nComboTrainingDecideStickAngle_ComboDI:\n\n#Check If In Throw\nbl\tComboTrainingCheckForThrowAngle\ncmpwi\tr3,-1\nbne\tComboTrainingDecideStickAngle_ComboDI_UsingThrowAngle\n#Get Knockback Angle\nlwz\tr3,0x1848(r29)\nComboTrainingDecideStickAngle_ComboDI_UsingThrowAngle:\nmr\tr24,r3\t\t#Backup Original Angle We're Using\n\n#Get Perpendicular Angle\n#Get Damage Direction\ncmpwi\tr3,0x169\t\t#Check For Sakurai Angle\nbne\t0xC\nli\tr3,0x2D\nli\tr4,0x2D\ncmpwi\tr3,90\nbge\tComboTrainingDecideStickAngle_ComboDI_Above90\nb\tComboTrainingDecideStickAngle_ComboDI_RightSide\nComboTrainingDecideStickAngle_ComboDI_Above90:\ncmpwi\tr3,269\nblt\tComboTrainingDecideStickAngle_ComboDI_LeftSide\nComboTrainingDecideStickAngle_ComboDI_RightSide:\nsubi\tr3,r3,90\ncmpwi\tr3,0\nbgt\t0x8\naddi\tr3,r3,360\nb\tComboTrainingDecideStickAngle_ComboDI_GetXY\nComboTrainingDecideStickAngle_ComboDI_LeftSide:\naddi\tr3,r3,90\ncmpwi\tr3,360\nblt\t0x8\nsubi\tr3,r3,360\nb\tComboTrainingDecideStickAngle_ComboDI_GetXY\n\nComboTrainingDecideStickAngle_ComboDI_GetXY:\nbl\tComboTrainingDecideStickAngle_ConvertAngle\nstb\tr3,0x1A8C(r29)\nstb\tr4,0x1A8D(r29)\n\n#If In a Throw, Always DI The Direction Of The Angle\nlwz\tr3,0x10(r29)\ncmpwi\tr3,0xEF\nblt\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionNoThrow\ncmpwi\tr3,0xF3\nbgt\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionNoThrow\n\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow:\ncmpwi\tr24,90\nbge\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_Above90\nb\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_Above90:\ncmpwi\tr3,269\nblt\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide\n\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide:\n#Always Facing Direction\n\nli\tr3,0x0\nbl\tIntToFloat\nlfs\tf2,0x2C(r27)\nfcmpo\tcr0,f2,f1\nbgt\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_Abs\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_AbsNeg:\nlbz\tr3,0x1A8C(r29)\nextsb\tr3,r3\nbl\tIntToFloat\nfabs\tf1,f1\nfneg\tf1,f1\nb\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_StoreX\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_Abs:\nlbz\tr3,0x1A8C(r29)\nextsb\tr3,r3\nbl\tIntToFloat\nfabs\tf1,f1\nb\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_StoreX\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_StoreX:\nfctiwz\tf1,f1\nstfd\tf1,0xF0(sp)\nlwz\tr3,0xF4(sp)\nstb\tr3,0x1A8C(r29)\nb\tComboTrainingDecideStickAngleExit\n\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide:\n#Always Opposite My Facing Direction\n\nli\tr3,0x0\nbl\tIntToFloat\nlfs\tf2,0x2C(r27)\nfcmpo\tcr0,f2,f1\nbgt\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_AbsNeg\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_Abs:\nlbz\tr3,0x1A8C(r29)\nextsb\tr3,r3\nbl\tIntToFloat\nfabs\tf1,f1\nb\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_StoreX\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_AbsNeg:\nlbz\tr3,0x1A8C(r29)\nextsb\tr3,r3\nbl\tIntToFloat\nfabs\tf1,f1\nfneg\tf1,f1\nb\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_StoreX\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_StoreX:\nfctiwz\tf1,f1\nstfd\tf1,0xF0(sp)\nlwz\tr3,0xF4(sp)\nstb\tr3,0x1A8C(r29)\nb\tComboTrainingDecideStickAngleExit\n\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionNoThrow:\nbl\tGetDirectionInRelationToP1\n#mulli\tr3,r3,-1\t\t#Negate This Value\nlbz\tr4,0x1A8C(r29)\nmullw\tr3,r3,r4\nstb\tr3,0x1A8C(r29)\t\t#Point Towards Opponent\nb\tComboTrainingDecideStickAngleExit\n\n######################\n## Down And Away DI ##\n######################\n\nComboTrainingDecideStickAngle_DownAwayDI:\n#Load X Value\n\tbl\tGetDirectionInRelationToP1\n#Point Away From P1\n\tli\tr4,89\n\tmullw\tr3,r3,r4\n\tstb\tr3, 0x1A8C (r29)\n#Load Y Value\n\tli\tr3,-89\n\tstb\tr3, 0x1A8D (r29)\n#C-Stick Down\n\tli\tr3,-127\n\tstb\tr3, 0x1A8F (r29)\n\nb\tComboTrainingDecideStickAngleExit\n\n###########\n## No DI ##\n###########\n\nComboTrainingDecideStickAngle_NoDI:\n\nComboTrainingDecideStickAngleExit:\nrestore\nblr\n\n\n#######################################################\n\nComboTrainingDecideStickAngle_ConvertAngle:\n#Convert New Angle To Float\nbackup\n\nbl\t\tIntToFloat\n\n#Get Pi/180\nlfs\tf2,-0x7510(rtoc)\n\n#Get Angle As Radian\nfmuls\tf31,f1,f2\n\n#Get 127 as Float\nli\tr3,127\nbl\t\tIntToFloat\nfmr\t\tf30,f1\n\n#Convert To X and Y Components\nfmr\tf1,f31\nbranchl\tr12,cos\t\t#load cosine function\nfmuls\tf1,f1,f30\t\t#Get X Component As Float\nfctiwz\tf1,f1\nstfd\tf1,0xF0(sp)\nlwz\tr20,0xF4(sp)\n\nfmr\tf1,f31\nbranchl\tr12,sin\t#load sine function\nfmuls\tf1,f1,f30\t\t#Get X Component As Float\nfctiwz\tf1,f1\nstfd\tf1,0xF0(sp)\nlwz\tr21,0xF4(sp)\n\n#Clamp Deadzones\nComboTrainingDecideStickAngle_ConvertAngle_ClampX:\nmr\tr3,r20\nbl\tIntToFloat\nfabs\tf3,f1\nli\tr3,36\nbl\tIntToFloat\nfcmpo\tcr0,f3,f1\nbge\tComboTrainingDecideStickAngle_ConvertAngle_ClampY\nli\tr20,0x0\n\nComboTrainingDecideStickAngle_ConvertAngle_ClampY:\nmr\tr3,r21\nbl\tIntToFloat\nfabs\tf3,f1\nli\tr3,36\nbl\tIntToFloat\nfcmpo\tcr0,f3,f1\nbge\tComboTrainingDecideStickAngle_ConvertAngle_Exit\nli\tr21,0x0\n\nComboTrainingDecideStickAngle_ConvertAngle_Exit:\n#Return X Y Stick Values\nmr\tr3,r20\nmr\tr4,r21\n\nrestore\nblr\n\n##############################################################\n\nComboTrainingCheckForThrowAngle:\n#Check If In Throw First (Must Retrieve Angle Manually)\nlwz\tr3,0x10(r29)\t\t#CPU AS\ncmpwi\tr3,0xEF\nblt\tComboTrainingCheckForThrowAngle_NoThrow\ncmpwi\tr3,0xF3\nbgt\tComboTrainingCheckForThrowAngle_NoThrow\n\n#Get Throw Angle\naddi\tr4,r27,0xdf4\t\t#P1 Throw Hitbox Info?\nlwz\tr3,0x20(r4)\t\t#Throw Angle\nb\tComboTrainingCheckForThrowAngle_NoThrowExit\n\nComboTrainingCheckForThrowAngle_NoThrow:\nli\tr3,-1\n\nComboTrainingCheckForThrowAngle_NoThrowExit:\nblr\n\n####################################################\n\nComboTrainingCheckExitStates:\n\n#Check For Exit States\n\tlwz\tr3,0x10(r29)\n\tcmpwi\tr3,0xE\t\t#Wait\n\tbeq\tComboTrainingCheckExitStates_ExitState\n\tcmpwi\tr3,0x1D\t\t#Fall\n\tbeq\tComboTrainingCheckExitStates_ExitState\n\tcmpwi\tr3,0x1B\t\t#DJ\n\tbeq\tComboTrainingCheckExitStates_ExitState\n\tcmpwi\tr3,0xFD\t\t#CliffWait\n\tbeq\tComboTrainingCheckExitStates_ExitState\n\tcmpwi\tr3,0xF5\t\t#Teeter\n\tbeq\tComboTrainingCheckExitStates_ExitState\n\tcmpwi\tr3,0x1C\t\t#JumpB Aerial\n\tbeq\tComboTrainingCheckExitStates_ExitState\n\tcmpwi\tr3,0x2A\t\t#Land\n\tbne\tComboTrainingCheckExitStates_CheckJiggsJump\n\t\t#Check If Can Interrupt Land\n\t\tlfs\tf1,0x894(r29)\n\t\tlfs\tf2,0x1F4(r29)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbge\tComboTrainingCheckExitStates_ExitState\n\n\tComboTrainingCheckExitStates_CheckJiggsJump:\n\tlwz\tr4,0x4(r29)\n\tcmpwi\tr4,0xF\t\t#Check If Jiggs\n\tbne\tComboTrainingCheckExitStates_NoExitState\n\t\tcmpwi\tr3,0x155\n\t\tbeq\tComboTrainingCheckExitStates_ExitState\n\nComboTrainingCheckExitStates_NoExitState:\nli\tr3,0x0\nb\tComboTrainingCheckExitStates_Exit\n\nComboTrainingCheckExitStates_ExitState:\nli\tr3,0x1\nb\tComboTrainingCheckExitStates_Exit\n\nComboTrainingCheckExitStates_Exit:\nblr\n\n####################################################\n\nComboTrainingWindowInfo:\nblrl\n#amount of options, amount of options in each window\n\n.long 0x04060304  #5 windows, DI has 7 options, SDI has 4 Options, Tech Has 5 Options\n.long 0x02020000  #PostHitstun has 3 options, Mash has 3 options\n\n####################################################\n\nComboTrainingWindowText:\nblrl\n\n########\n## DI ##\n########\n\n#Window Title = DI Behavior\n.string \"DI Behavior\"\n.align 2\n\n#Option 1 = Random DI\n.string \"Random DI\"\n.align 2\n\n#Option 2 = Survival DI\n.string \"Survival DI\"\n.align 2\n\n#Option 3 = Combo DI\n.string \"Combo DI\"\n.align 2\n\n#Option 4 = Slight DI Random\n.string \"Slight DI Random\"\n.align 2\n\n#Option 5 = Slight DI Towards\n.string \"Slight DI Towards\"\n.align 2\n\n#Option 6 = Down and Away DI\n.string \"Down and Away DI\"\n.align 2\n\n#Option 6 = No DI\n.string \"No DI\"\n.align 2\n\n#########\n## SDI ##\n#########\n\n#SDI Behavior\n.long 0x53444920\n.long 0x42656861\n.long 0x76696f72\n.long 0x00000000\n\n#Option 1 = 33% Chance to SDI\n.long 0x33338193\n.long 0x20436861\n.long 0x6e636520\n.long 0x746f2053\n.long 0x44490000\n\n#Option 2 = 66% Chance to SDI\n.long 0x36368193\n.long 0x20436861\n.long 0x6e636520\n.long 0x746f2053\n.long 0x44490000\n\n#Option 3 = Always SDI\n.long 0x416c7761\n.long 0x79732053\n.long 0x44490000\n\n#Option 4 = No SDI\n.long 0x4e6f2053\n.long 0x44490000\n\n#################\n## Tech Option ##\n#################\n\n#Tech Option\n.long 0x54656368\n.long 0x204f7074\n.long 0x696f6e00\n\n#Option 1 = Random\n.long 0x52616e64\n.long 0x6f6d0000\n\n#Option 2 = Missed Tech\n.long 0x4d697373\n.long 0x65642054\n.long 0x65636800\n\n#Option 3 = Tech In Place\n.long 0x54656368\n.long 0x20496e20\n.long 0x506c6163\n.long 0x65000000\n\n#Option 4 = Tech In\n.long 0x54656368\n.long 0x20496e00\n\n#Option 5 = Tech Away\n.long 0x54656368\n.long 0x20417761\n.long 0x79000000\n\n\n#################\n## Tech Option ##\n#################\n\n#Post Hitstun Action\n.long 0x506f7374\n.long 0x20486974\n.long 0x7374756e\n.long 0x20416374\n.long 0x696f6e00\n\n#Airdodge/Spotdodge\n.long 0x41697264\n.long 0x6f646765\n.long 0x815e5370\n.long 0x6f74646f\n.long 0x64676500\n\n#Invincible\n.long 0x496e7669\n.long 0x6e636962\n.long 0x6c650000\n\n#Attack\n.long 0x41747461\n.long 0x636b0000\n\n\n###################\n## Grab Mash-Out ##\n###################\n\n#Grab Mash-Out\n.long 0x47726162\n.long 0x204d6173\n.long 0x682d4f75\n.long 0x74000000\n.long 0x\n\n#Random Mash\n.long 0x52616e64\n.long 0x6f6d204d\n.long 0x61736800\n.long 0x\n.long 0x\n\n#Frame Perfect\n.long 0x4672616d\n.long 0x65205065\n.long 0x72666563\n.long 0x74000000\n.long 0x\n\n#No Mash-Out\n.long 0x4e6f204d\n.long 0x6173682d\n.long 0x4f757400\n.long 0x\n.long 0x\n\n####################################################\n\nComboTrainingAttackList:\nblrl\n.long 0x00700466\n.long 0x02660000\n.long 0x30000303\n.long 0x04660073\n.long 0x30000152\n.long 0x00007000\n.long 0x660400FF\n\n####################################################\n\n\n\nComboTrainingLoadExit:\nrestore\nblr\n\n##################################################\n#endregion\n\n#region Waveshine SDI\n#########################\n## Waveshine SDI HIJACK INFO ##\n#########################\n\nWaveshineSDI:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Fox.Ext\t\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,FinalDestination\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_WaveshineSDI\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nWaveshineSDIStoreThink:\n\tbl\tWaveshineSDILoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Waveshine SDI LOAD FUNCT ##\n\t########################\n\tWaveshineSDILoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tWaveshineSDIThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\n/*\n\t#Make Long Destination\n\t#Get Stage DAT Pointer\n\tload\tr3,0x80432290\n\tlwz\tr3,0x10(r3)\n\tlwz\tr6,0x4(r3)\n  lis r3, 0x4040\n  li r5, 0x0\n  ori r4, r5, 0xF488\n  stwx r3, r6, r4\n  ori r4, r5, 0xF4CC\n  stwx r3, r6, r4\n  ori r4, r5, 0xF4D0\n  stwx r3, r6, r4\n  ori r4, r5, 0xF590\n  stwx r3, r6, r4\n  lis r4, 0x1\n  ori r4, r4, 0x88\n  stwx r3, r6, r4\n  lis r4, 0x1\n  ori r4, r4, 0x608\n  stwx r3, r6, r4\n  lis r3, 0x4248\n  ori r4, r5, 0xF4D8\n  stwx r3, r6, r4\n  lis r4, 0x5\n  ori r4, r4, 0x1B90\n  stwx r5, r6, r4\n  lis r5, 0x5\n  lis r3, 0xC3AA\n  ori r3, r3, 0x91EC\n  ori r4, r5, 0x1F20\n  stwx r3, r6, r4\n  lis r3, 0x43AA\n  ori r3, r3, 0x91EC\n  ori r4, r5, 0x1F60\n  stwx r3, r6, r4\n  lis r3, 0xC3D0\n  ori r3, r3, 0x91EC\n  ori r4, r5, 0x1FA0\n  stwx r3, r6, r4\n  lis r3, 0x43D0\n  ori r3, r3, 0x91EC\n  ori r4, r5, 0x1FE0\n  stwx r3, r6, r4\n*/\n\n\tb\tWaveshineSDILoadExit\n\n\n\t\t#########################\n\t\t## Waveshine SDI THINK FUNCT ##\n\t\t#########################\n\n\n\t\tWaveshineSDIThink:\n\t\t\tblrl\n\n      .set EventData,31\n      .set P1Data,27\n      .set P1GObj,28\n      .set P2Data,29\n      .set P2GObj,30\n\n\t\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n      bl  GetAllPlayerPointers\n      mr P1GObj,r3\n      mr P1Data,r4\n      mr P2GObj,r5\n      mr P2Data,r6\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tWaveshineSDIThinkMain\n\n\t\t\t\t#Set Frame 1 As Over\n\t\t\t\t\tli\t\tr3,0x1\n\t\t\t\t\tstb\t\tr3,0x0(r31)\n\t\t\t\t#Set Facing Directions\n\t\t\t\t\tlis\tr3,0x3f80\n\t\t\t\t\tstw\tr3,0x2C(r29)\n\t\t\t\t\tlis\tr3,0xBf80\n\t\t\t\t\tstw\tr3,0x2C(r27)\n\t\t\t\t#Initlize Positions\n\t\t\t\t\tbl\tWaveshineSDI_Floats\n\t\t\t\t\tmflr\tr3\n\t\t\t\t\tbl\tInitializePositions\n        #Clear Inputs\n          bl  RemoveFirstFrameInputs\n\t\t\t\t#Store Ground As Last Known Position\n\t\t\t\t\tlfs\tf1, 0x00B4 (r29)\n\t\t\t\t\tstfs\tf1, 0x0834 (r29)\n\t\t\t\t#Save State\n\t\t\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n\t\t\t\t\tbl\tSaveState_Save\n\t\t\t\t#Set Timer to -60\n\t\t\t\t\tli\t\tr3,-60\n\t\t\t\t\tstw\t\tr3,0x4(r31)\n\n\n\n\t\tWaveshineSDIThinkMain:\n\t\tWaveshineSDIThinkSequence:\n\t\t#Inc Timer\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tstw\tr3,0x4(r31)\n\n\t\t#Get Floats\n\t\t\tbl\tWaveshineSDI_Floats\n\t\t\tmflr\tr21\n\n\t\t#Check Timer\n\t\t\tcmpwi\tr3,0x0\n\t\t\tblt\tWaveshineSDICheckToReset\n\n\t\t#Check If Edge Of Stage\n\t\t\tlfs\tf1,0xB0(r29)\t\t#P1 X Coord\n\t\t\tlfs\tf2,0x18(r21)\t\t#Max X Coord\n\t\t\tfabs\tf1,f1\n\t\t\tfabs\tf2,f2\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tblt\tWaveshineSDISkipBoundaryCheck\n\t\t#Freeze Fox If So\n\t\t\tlbz\tr0,0x2219(r29)\n\t\t\tli\tr3,1\n\t\t\trlwimi\tr0,r3,2,29,29\n\t\t\tstb\tr0,0x2219(r29)\n\t\t\tlwz \tr3,0xC(r31)\n\t\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\t\tbgt\tWaveshineSDICheckToReset\n\t\t\tli\tr3,60\t\t#Set Timer If Not Set Yet\n\t\t\tstw\tr3,0xC(r31)\n\t\t\tb\tWaveshineSDICheckToReset\n\t\tWaveshineSDISkipBoundaryCheck:\n\n\t\t#Check If Fox Grabbed Marth\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0xD8\n\t\t\tbne\tWaveshineSDICheckDrillOrWaveshine\n\t\t\tlwz\tr3,0xC(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbgt\tWaveshineSDICheckDrillOrWaveshine\n\t\t\tli\tr3,60\n\t\t\tstw\tr3,0xC(r31)\n\n\t\t#Check If Drilling or Waveshining\n\t\t\tWaveshineSDICheckDrillOrWaveshine:\n\t\t\tlbz\tr3,0x8(r31)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbge\tWaveshineSDIWaveshineThink\n\n\t\t#Run Drill Code\n\t\t\tWaveshineSDIDrillThink:\n\t\t\tlwz\tr3,0x10(r29)\n\n\t\tWaveshineSDIDrillThink_CheckToJump:\n\t\t\tcmpwi\tr3,0xE\n\t\t\tbne\tWaveshineSDIDrillThink_CheckToDair\n\t\t\tli\tr3,0x400\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tWaveshineSDICheckToReset\n\n\t\tWaveshineSDIDrillThink_CheckToDair:\n\t\t\tcmpwi\tr3,0x19\n\t\t\tbne\tWaveshineSDI_CheckToFF\n\t\t\tli\tr3,-127\n\t\t\tstb\tr3,0x1A8F(r29)\n\t\t\tb\tWaveshineSDICheckToReset\n\n\t\tWaveshineSDI_CheckToFF:\n\t\t#Check If Drilling\n\t\t\tcmpwi\tr3,0x45\n\t\t\tbne\tWaveshineSDICheckToReset\n\t\t#Joystick X = 36 * Facing Direction (Drift Forward during drill\n\t\t\tlfs\tf1,0x2C(r29)\n\t\t\tfctiwz\tf1,f1\n\t\t\tstfd\tf1,0xF0(sp)\n\t\t\tlwz\tr4,0xF4(sp)\n\t\t\tli\tr3,36\t\t#X Stick\n\t\t\tmullw\tr3,r3,r4\n\t\t\tstb\tr3,0x1A8C(r29)\n\t\t#Check If Already FF'ing\n\t\t\tlbz\tr3,0x221A(r29)\n\t\t\trlwinm.\tr3,r3,0,28,28\n\t\t\tbne\tWaveshineSDICheckToLCancel\n\t\t#Check If Falling\n\t\t\tlfs\tf2,0x84(r29)\n\t\t\tlfs\tf0, -0x76B0 (rtoc)\n\t\t\tfcmpo\tcr0,f2,f0\n\t\t\tbge\tWaveshineSDICheckToReset\n\t\t#Input Down to FF\n\t\t\tli\tr3,-127\n\t\t\tstb\tr3,0x1A8D(r29)\t\t#Ananlog Y\n\n\t\tWaveshineSDICheckToLCancel:\n\t\t#Check If Under 5Mm Above Ground\n\t\t\tlfs\tf2,0xB4(r29)\n\t\t\tlfs\tf0,0x834(r29)\t\t#Last Grounded Y Pos\n\t\t\tfsubs\tf2,f2,f0\t\t#Distance from Floor\n\t\t\tlfs\tf0,0x10(r21)\t\t#5 fp\n\t\t\tfcmpo\tcr0,f2,f0\t\t#If less than 5 Mm away, Input L Cancel\n\t\t\tbgt\tWaveshineSDICheckToReset\n\t\t\tli\tr3,0xC0\t\t#Hit L\n\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\tli\tr3,0x1\t\t#Set Start Waveshine Flag\n\t\t\tstb\tr3,0x8(r31)\n\t\t\tb\tWaveshineSDICheckToReset\n\n\n\t\t#Run Waveshine Code\n\t\tWaveshineSDIWaveshineThink:\n\t\t\tlwz\tr3,0x10(r29)\n\n\n\t\t#Shine If In Wait\n\t\t\tcmpwi\tr3,0xE\n\t\t\tbne\tWaveshineSDICheckToJump\n\t\t#Check If First Shine Or FollowUp Shine\n\t\t\tlbz\tr4,0x8(r31)\n\t\t\tcmpwi\tr4,0x2\n\t\t\tbeq\tWaveshineSDIWaveshine_FollowOpponent\n\t\t#Input Shine\n\t\t\tli\tr3,-127\n\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\tli\tr3,0x200\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t#Set Flag as Mid-Waveshine\n\t\t\tli\tr3,0x2\n\t\t\tstb\tr3,0x8(r31)\n\t\t#Get JC Timing\n\t\t\tli\tr3,3\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tstb\tr3,0x9(r31)\n\t\t\tb\tWaveshineSDICheckToReset\n\n\t\t#Jump If In Shine Loop\n\t\tWaveshineSDICheckToJump:\n\t\t#Check\n\t\t\t#Check For Shine Loop\n\t\t\t\tcmpwi\tr3,0x169\n\t\t\t\tbne\tWaveshineSDICheckToAirdodge\n\t\t\t#Check For JC Frame\n\t\t\t\tlbz\tr3,0x9(r31)\t\t#Get JC Timing\n\t\t\t\tbl\tIntToFloat\n\t\t\t\tlfs\tf2,0x894(r29)\n\t\t\t\tfcmpo\tcr0,f1,f2\n\t\t\t\tbne\tWaveshineSDICheckToReset\n\t\t\t#Jump\n\t\t\t\tli\tr3,0x400\n\t\t\t\tstw\tr3,0x1A88(r29)\n\t\t\t\tb\tWaveshineSDICheckToReset\n\n\t\t#Airdodge If In JumpF\n\t\tWaveshineSDICheckToAirdodge:\n\t\t\tcmpwi\tr3,0x19\n\t\t\tbne\tWaveshineSDIWaveshine_CheckIfFollowingOpponent\n\t\t#Get Random Airdodge Angle\n\t\t\tli\tr3,30\t\t#30 Different Angles\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\taddi\tr3,r3,310\t\t#Start at 310°\n\t\t\tbl\tComboTrainingDecideStickAngle_ConvertAngle\n\t\t#Joystick X = X Component * Facing Direction\n\t\t\tlfs\tf1,0x2C(r29)\n\t\t\tfctiwz\tf1,f1\n\t\t\tstfd\tf1,0xF0(sp)\n\t\t\tlwz\tr5,0xF4(sp)\n\t\t\tmullw\tr3,r3,r5\n\t\t\tstb\tr3,0x1A8C(r29)\n\t\t#Joystick Y = Y Component\n\t\t\tstb\tr4,0x1A8D(r29)\n\t\t#Press L To Wavedash\n\t\t\tli\tr3,0xC0\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tWaveshineSDICheckToReset\n\n\t\tWaveshineSDIWaveshine_CheckIfFollowingOpponent:\n\t\t\tcmpwi\tr3,0xf\t\t#Check if Walking\n\t\t\tblt\tWaveshineSDICheckIfInTeeter\n\t\t\tcmpwi\tr3,0x11\t\t#Check if Walking\n\t\t\tbgt\tWaveshineSDICheckIfInTeeter\n\t\t\tb\tWaveshineSDIWaveshine_FollowOpponent\n\n\t\tWaveshineSDICheckIfInTeeter:\n\t\t\tcmpwi\tr3,0xf5\n\t\t\tbne\tWaveshineSDICheckToReset\n\t\t\tb\tWaveshineSDIRestoreState\n\n\t\tWaveshineSDIWaveshine_FollowOpponent:\n\t\t#Determine Distance From Opponent\n\t\t\tlfs\tf1,0xB0(r27)\n\t\t\tlfs\tf2,0xB0(r29)\n\t\t\tfsubs\tf1,f1,f2\n\t\t\tlfs\tf2,-0x7414(rtoc)\t\t#0f\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tbge\tWaveshineSDIWaveshine_FollowOpponent_FacingRight\n\n\t\tWaveshineSDIWaveshine_FollowOpponent_FacingLeft:\n\t\t#Check If Close Enough To Shine\n\t\t\tlfs\tf2,0x14(r21)\n\t\t\tfneg\tf2,f2\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tblt\tWaveshineSDIWaveshine_FollowOpponent_WalkTowards\n\t\t\tb\tWaveshineSDIWaveshine_FollowOpponent_EnterShine\n\t\t\t#b\tWaveshineSDIWaveshine_FollowOpponent_CheckMarth\n\t\tWaveshineSDIWaveshine_FollowOpponent_FacingRight:\n\t\t\tlfs\tf2,0x14(r21)\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tbgt\tWaveshineSDIWaveshine_FollowOpponent_WalkTowards\n\t\t\tb\tWaveshineSDIWaveshine_FollowOpponent_EnterShine\n\t\t#Check Opponent\n\t\tWaveshineSDIWaveshine_FollowOpponent_CheckMarth:\n\t\t\tlwz\tr3,0x4(r27)\n\t\t\tcmpwi\tr3,0x12\t\t#Marth\n\t\t\tbeq\tWaveshineSDIWaveshine_FollowOpponent_EnterGrab\n\t\tWaveshineSDIWaveshine_FollowOpponent_EnterShine:\n\t\t\t#Shine\n\t\t\t\tli\tr3,-127\n\t\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\t\tli\tr3,0x200\n\t\t\t\tstw\tr3,0x1A88(r29)\n\t\t\t#Get JC Timing\n\t\t\t\tli\tr3,3\n\t\t\t\tbranchl\tr12,HSD_Randi\n\t\t\t\tstb\tr3,0x9(r31)\n\t\t\t\tb\tWaveshineSDICheckToReset\n\t\tWaveshineSDIWaveshine_FollowOpponent_EnterGrab:\n\t\t\tli\tr3,0x1C0\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tWaveshineSDICheckToReset\n\t\tWaveshineSDIWaveshine_FollowOpponent_WalkTowards:\n\t\t#Walk Towards Opponent\n\t\t#Stick Forward\n\t\t\tlfs\tf1,0x2C(r29)\n\t\t\tfctiwz\tf2,f1\n\t\t\tstfd\tf2,0xF0(sp)\n\t\t\tlwz\tr4,0xF4(sp)\n\t\t\tli\tr3,127\t\t#X Stick\n\t\t\tmullw\tr3,r3,r4\n\t\t\tstb\tr3,0x1A8C(r29)\n\t\t#Override Analog Smash Counter So Always Walking (Set Facing As Prev X Input)\n\t\t\tstfs\tf1,0x620(r29)\n\t\t\tb\tWaveshineSDICheckToReset\n\n\n\t\t#Initiate Reset Timer\n\t\t\tli\tr3,120\n\t\t\tstw\tr3,0xC(r31)\n\n\t\t#Check To Reset\n\t\tWaveshineSDICheckToReset:\n\t\t\tlwz\tr3,0xC(r31)\t\t#get timer\t#Get Timer\n\t\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\t\tble\tWaveshineSDIThinkExit\n\t\t#Dec Timer\n\t\t\tsubi\tr3,r3,0x1\n\t\t\tstw\tr3,0xC(r31)\t\t#store timer\n\t\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\t\tbne\tWaveshineSDIThinkExit\t#Exit If Not\n\t\tWaveshineSDIRestoreState:\n\t\t#Invert Facing Directions\n\t\t\tlwz\tr4,0x10(r31)\n\t\t\tlwz\tr5,0x18(r31)\n\t\t\tlfs\tf1,0x2C(r4)\n\t\t\tfneg\tf1,f1\n\t\t\tstfs\tf1,0x2C(r4)\n\t\t\tlfs\tf1,0x2C(r5)\n\t\t\tfneg\tf1,f1\n\t\t\tstfs\tf1,0x2C(r5)\n\t\t\t#Invert X Positions\n\t\t\tlfs\tf1,0xB0(r4)\n\t\t\tfneg\tf1,f1\n\t\t\tstfs\tf1,0xB0(r4)\n\t\t\tlfs\tf1,0xB0(r5)\n\t\t\tfneg\tf1,f1\n\t\t\tstfs\tf1,0xB0(r5)\n\t\t#Restore State\n\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\tbl\tSaveState_Load\n\t\t#Reset Timer\n\t\t\tli\tr3,60\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tli\tr4,0\n\t\t\tsub\tr3,r4,r3\n\t\t\tstw\tr3,0x4(r31)\n\t\t#Reset Mid-Waveshine Flag\n\t\t\tli\tr3,0x0\n\t\t\tstb\tr3,0x8(r31)\n\n\t\tWaveshineSDIThinkExit:\n\t\trestore\n\t\tblr\n\n#################################\n\nWaveshineSDI_Floats:\nblrl\n.long 0xC28C0000\t\t#P1 X Position\n.long 0xc2982e6c \t#P2 X Position\n.long 0x38d1b717  #P1 Y Position\n.long 0x38d1b717\t\t#FD Floor Y Coord\n.long 0x40A00000  #5fp\n.long 0x40F00000  #Distance From Opponent to Waveshine\n.long 0x42A00000  #X Coord To Stop\n\n#################################\n\nWaveshineSDILoadExit:\nrestore\nblr\n\n##################################################\n#endregion\n\n#region Slide Off\n###########################\n## Slide Off HIJACK INFO ##\n###########################\n\nSlideOff:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Marth.Ext\n\tli\tr6,PokemonStadium\t\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_SlideOff\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nSlideOffStoreThink:\n\tbl\tSlideOffLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## \t\t\tSlide Off LOAD FUNCT \t\t##\n##################################\nSlideOffLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tSlideOffThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\tb\tSlideOffThink_Exit\n\n###################################\n## Slide Off THINK FUNCT ##\n###################################\n\nSlideOffThink:\n\tblrl\n\n#Registers\n\t.set REG_EventConstants,25\n  .set REG_MenuData,26\n  .set REG_EventData,31\n  .set REG_P1Data,27\n  .set REG_P1GObj,28\n\t.set REG_P2Data,29\n\t.set REG_P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set EventState_Hitstun,0x0\n\t\t.set EventState_DetermineAttack,0x1\n\t\t.set EventState_AttackThink,0x2\n\t\t.set EventState_Shield,0x3\n\t.set Timer,0x1\n\t.set P1State,0x2\n\t\t.set P1State_Wait,0x0\n\t\t.set P1State_Attacking,0x1\n\t.set AttackTimer,0x3\n\n#Constants\n\t.set ResetTimer,40\n\t.set AngleLo,83\n\t.set AngleHi,100\n\t.set MagLo,65\n\t.set MagHi,75\n\t.set HitlagFrames,12\n\t.set PercentLo,40\n\t.set PercentHi,40\n\t.set FramesBeforeHitbox,7\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tlwz\tREG_EventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n#Get Player Pointers\n  bl GetAllPlayerPointers\n  mr REG_P1GObj,r3\n  mr REG_P1Data,r4\n  mr REG_P2GObj,r5\n  mr REG_P2Data,r6\n\n#Get Menu and Constants Pointers\n  lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData)\n\tbl\tSlideOffThink_Constants\n\tmflr REG_EventConstants\n\n\tbl\tStoreCPUTypeAndZeroInputs\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tSlideOffThink_Start\n\t#Init Positions\n\t\tmr\tr3,REG_P1GObj\n\t\tmr\tr4,REG_P2GObj\n\t\tbl\tSlideOff_InitializePositions\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\n\t#Init State\n\t\tli\tr3,EventState_Hitstun\n\t\tstb\tr3,EventState(REG_EventData)\nSlideOffThink_Start:\n\n#Reset if anyone died\n\tbl\tIsAnyoneDead\n\tcmpwi r3,0\n\tbne SlideOffThink_Restore\n\nSlideOffThink_CheckIfFailed:\n#Check if failed the slide off (in non-hitlag damage state)\n#EventState > EventState_Hitstun\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_Hitstun\n\tble SlideOffThink_CheckIfFailed_End\n#Check for hitlag\n\tlbz r3,0x221A(REG_P1Data)\n\trlwinm. r3,r3,0,26,26\n\tbne SlideOffThink_CheckIfFailed_End\n#Check if in hitstun\n\tlbz r3,0x221C(REG_P1Data)\n\trlwinm. r3,r3,0,30,30\n\tbeq SlideOffThink_CheckIfFailed_End\n#Check if player has been in this state for over 5 frames\n\tlhz r3,FramesinCurrentAS(REG_P1Data)\n\tcmpwi r3,5\n\tblt SlideOffThink_CheckIfFailed_End\n#Check if timer has started\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt SlideOffThink_CheckTimer\n#Start Timer\n\tli\tr3,10\n\tstb r3,Timer(REG_EventData)\nSlideOffThink_CheckIfFailed_End:\n\nSlideOffThink_CheckIfCPUDamaged:\n\tlwz\tr3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_DamageHi1\n\tblt\tSlideOffThink_CheckIfCPUDamaged_End\n\tcmpwi r3,ASID_DamageFlyRoll\n\tbgt\tSlideOffThink_CheckIfCPUDamaged_End\n#Check if timer has started\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt SlideOffThink_CheckIfCPUDamaged_End\n#Start Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\nSlideOffThink_CheckIfCPUDamaged_End:\n\nSlideOffThink_SwitchCase:\n#Switch Case\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_Hitstun\n\tbeq SlideOffThink_Hitstun\n\tcmpwi r3,EventState_DetermineAttack\n\tbeq SlideOffThink_DetermineAttackorShield\n\tcmpwi r3,EventState_AttackThink\n\tbeq SlideOffThink_AttackThink\n\tcmpwi r3,EventState_Shield\n\tbeq SlideOffThink_Shield\n\tb\tSlideOffThink_CheckTimer\n\n#region SlideOffThink_Hitstun\nSlideOffThink_Hitstun:\n#Check if still in ThrowHi\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_ThrowHi\n\tbeq SlideOffThink_CheckTimer\n\n#Check if P1 is in a tech/mistech state\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_DownBoundU\n\tblt SlideOffThink_CheckTimer\n\tcmpwi r3,ASID_PassiveStandB\n\tbgt SlideOffThink_CheckTimer\n\n#Change state to attack\n\tli\tr3,EventState_DetermineAttack\n\tstb\tr3,EventState(EventData)\n\tb\tSlideOffThink_CheckTimer\n\n#endregion\n\n#region SlideOffThink_DetermineAttackorShield\nSlideOffThink_DetermineAttackorShield:\n/*\n#Ensure facing correct direction\n#Get Values\n\tlfs f1,0xB0(REG_P2Data)\t\t\t\t#p2 position\n\tlfs f2,0x2C(REG_P2Data)\t\t\t\t#p2 direction\n\tlfs f4,TriggerBoxXMin(REG_EventConstants)\n\tlfs f5,TriggerBoxXMax(REG_EventConstants)\n\tlfs f6,0xB0(REG_P1Data)\n#Check X\n\tfmadds f3,f2,f4,f1\t\t\t\t#XMin\n\tfmadds f4,f2,f5,f1\t\t\t\t#XMax\n#Make sure player is not behind marths range\n\tlfs f1,-0x68E0 (rtoc)\t\t\t#fp 0\n\tfcmpo cr0,f2,f1\n\tbge SlideOffThink_Attck_FacingRight\nSlideOffThink_Attck_FacingLeft:\n\tli\tr3,1\n\tfcmpo cr0,f6,f3\n\tbge SlideOffThink_Attck_InputTurn\n\tb\tSlideOffThink_Attck_SkipDirectionChange\nSlideOffThink_Attck_FacingRight:\n\tli\tr3,-1\n\tfcmpo cr0,f6,f3\n\tble SlideOffThink_Attck_InputTurn\n\tb\tSlideOffThink_Attck_SkipDirectionChange\nSlideOffThink_Attck_InputTurn:\n#Check if already turning\n\tlwz r4,0x10(REG_P2Data)\n\tcmpwi r4,ASID_Turn\n\tbeq SlideOffThink_Attck_SkipDirectionChange\n#Input turn\n\tmulli r3,r3,36\n\tstb r3,CPU_AnalogX(REG_P2Data)\nSlideOffThink_Attck_SkipDirectionChange:\n*/\n\nSlideOffThink_DetermineAttackorShield_SkipFailCheck:\n\n#Decide to shield or attack\n\tlfs f1,0xB4(REG_P2Data)\t\t\t\t#p2 position\n\tlfs f2,TriggerBoxYMin(REG_EventConstants)\n\tlfs f3,TriggerBoxYMax(REG_EventConstants)\n\tlfs f4,0xB4(REG_P1Data)\t\t\t\t#p1 position\n\tfadds f2,f1,f2\t\t\t\t\t\t#YMin\n\tfadds f3,f1,f3\t\t\t\t\t\t#YMax\n#Check if P1 is above YMax\n\tfcmpo cr0,f4,f3\n\tbge SlideOffThink_DetermineAttackorShield_AboveTriggerBox\n#Check if P1 is below YMin\n\tfcmpo cr0,f4,f2\n\tbge SlideOffThink_DetermineAttackorShield_CheckToAttack_CanAttack\nSlideOffThink_DetermineAttackorShield_EnterShield:\n#Change Event State\n\tli\tr3,EventState_Shield\n\tstb\tr3,EventState(REG_EventData)\n#Start Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n\tb\tSlideOffThink_Shield\n\nSlideOffThink_DetermineAttackorShield_AboveTriggerBox:\n#Check if timer has started\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt SlideOffThink_CheckTimer\n#Start Timer\n\tli\tr3,10\n\tstb r3,Timer(REG_EventData)\n\tb\tSlideOffThink_CheckTimer\n\nSlideOffThink_DetermineAttackorShield_CheckToAttack_CanAttack:\n#Get P1's State\n\tlwz r3,0x10(REG_P1Data)\n#Ensure we have the frame data for this state\n\tcmpwi r3,ASID_DownBoundU\n\tblt SlideOffThink_DetermineAttackorShield_CheckToAttack_StartAttack\n\tcmpwi r3,ASID_PassiveStandB\n\tbgt SlideOffThink_DetermineAttackorShield_CheckToAttack_StartAttack\n#If DownWait or Bound, dont do anything\n\tcmpwi r3,ASID_DownWaitD\n\tbeq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd\n\tcmpwi r3,ASID_DownWaitU\n\tbeq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd\n\tcmpwi r3,ASID_DownBoundD\n\tbeq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd\n\tcmpwi r3,ASID_DownBoundU\n\tbeq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd\n#Get the frame data to use\n\tsubi r3,r3,ASID_DownBoundU\n\taddi r4,REG_EventConstants,VulnFrameData\n\tlbzx r3,r3,r4\n#Marth takes 8 frames for his utilt hitbox to appear, so subtract 8\n\tsubi r3,r3,FramesBeforeHitbox\n#Use the custom playerblock offset to check P1's frame count\n\tlhz r4,FramesinCurrentAS(REG_P1Data)\n\tcmpw r4,r3\n\tblt SlideOffThink_DetermineAttackorShield_CheckToAttackEnd\n#Time to attack\nSlideOffThink_DetermineAttackorShield_CheckToAttack_StartAttack:\n\tli\tr3,EventState_AttackThink\n\tstb r3,EventState(REG_EventData)\n\tb\tSlideOffThink_DetermineAttackorShield_CheckToAttackEnd\nSlideOffThink_DetermineAttackorShield_CheckToAttackEnd:\n\tb\tSlideOffThink_CheckTimer\n\n#endregion\n\n#region SlideOffThink_AttackThink\nSlideOffThink_AttackThink:\n#Get Inputs for this frame\n\tmr\tr3,REG_P2Data\n\tbl\tSlideOffThink_AttackInputs\n\tmflr r4\n\tlbz r5,AttackTimer(REG_EventData)\n\tbl\tPlaybackInputSequence\n\n#Always succeed LCancel\n\tli\tr3,0\n\tstb r3,0x67F(REG_P2Data)\n\n#Remove Hitbox ID 1,2 and 3 (problematic for getting slideoff)\n\tmr\tr3,REG_P2GObj\n\tli\tr4,1\n\tbranchl r12,0x8007afc8\n\tmr\tr3,REG_P2GObj\n\tli\tr4,2\n\tbranchl r12,0x8007afc8\n\tmr\tr3,REG_P2GObj\n\tli\tr4,3\n\tbranchl r12,0x8007afc8\n\n#Exit AttackThink when returning to Wait\n\tlbz r3,AttackTimer(REG_EventData)\n\tcmpwi r3,0\n\tble SlideOffThink_AttackThink_Exit\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_Wait\n\tbeq SlideOffThink_AttackThink_Reset\n\tcmpwi r3,ASID_Landing\n\tbne SlideOffThink_AttackThink_Exit\n#Now check if interruptable\n\tlwz\tr3, 0x2340 (REG_P2Data)\n\tcmpwi r3,0\n\tbeq SlideOffThink_AttackThink_Exit\n#Check if this frame is interruptable\n\tlfs f1,0x1f4 (REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tlhz r4,FramesinCurrentAS(REG_P2Data)\n\tcmpw r4,r3\n\tblt SlideOffThink_AttackThink_Exit\n\nSlideOffThink_AttackThink_Reset:\n\tli\tr3,EventState_DetermineAttack\t\t\t#event state\n\tstb r3,EventState(REG_EventData)\n\tli\tr3,0\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#reset timer\n\tstb r3,AttackTimer(REG_EventData)\n\tb\tSlideOffThink_CheckTimer\n\nSlideOffThink_AttackThink_Exit:\n#Check if in Hitlag\n\tlbz r3,0x221A(REG_P2Data)\n\trlwinm. r3,r3,0,26,26\n\tbne SlideOffThink_CheckTimer\n#Increment Attack Timer\n\tlbz r3,AttackTimer(REG_EventData)\n\taddi r3,r3,1\n\tstb r3,AttackTimer(REG_EventData)\n\tb\tSlideOffThink_CheckTimer\n#endregion\n\n#region SlideOffThink_Shield\nSlideOffThink_Shield:\n#Hold Shield\n\tli\tr3,PAD_TRIGGER_R\n\tstw\tr3,CPU_HeldButtons(REG_P2Data)\n\tb\tSlideOffThink_CheckTimer\n#endregion\n\nSlideOffThink_CheckTimer:\n#Check if timer exists\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tble SlideOffThink_Exit\n#Decrement timer\n\tsubi r3,r3,1\n\tstb r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt SlideOffThink_Exit\n\nSlideOffThink_Restore:\n#Restore State\n\taddi r3,REG_EventData,EventData_SaveStateStruct\n\tli\tr4,1\n\tbl\tSaveState_Load\n#Init Positions Again\n\tmr\tr3,REG_P1GObj\n\tmr\tr4,REG_P2GObj\n\tbl\tSlideOff_InitializePositions\n#Reset Variables\n\tli\tr3,0\n\tstb r3,EventState(REG_EventData)\n\tstb r3,Timer(REG_EventData)\n\tstb r3,P1State(REG_EventData)\n\tstb r3,AttackTimer(REG_EventData)\n\nSlideOffThink_Exit:\n\trestore\n\tblr\n\n################################\n\nSlideOffThink_Constants:\nblrl\n.set MarthUTiltFrame,8\n.set P1X,0x0\n.set P1Y,0x4\n.set P2X,0x8\n.set P2Y,0xC\n.set UThrowStartFrame,0x10\n.set DamageFlyTopStartFrame,0x14\n.set MagnitudeScalar,0x18\n.set MagnitudeScalar2,0x1C\n.set MagnitudeScalar3,0x20\n.set TriggerBoxXMin,0x24\n.set TriggerBoxXMax,0x28\n.set TriggerBoxYMin,0x2C\n.set TriggerBoxYMax,0x30\n.set VulnFrameData,0x34\n.set Unk,0x48\n\n.float -37.7\t\t#p1 x\n.float 21.2\t\t\t#p1 y\n.float -41.1\t\t#p2 x\n.float 0\t\t\t\t#p2 y\n.float 13\t\t\t\t#marth upthrow starting frame\n.float 2\t\t\t\t#p1 damageflytop starting frame\n.float 0.1\t\t\t#baseline for mag scaling\n.float 1\t\t\t\t#mag scaling constant\n.float 0.4\t\t\t#mag scaling constant\n.float -8\t\t\t\t#xmin\n.float 20\t\t\t\t#xmax\n.float 18\t\t\t\t#ymin\n.float 30\t\t\t\t#ymax\n##########################################\n.set TechVuln,24-4\n.set TechRollVuln,23\n.set KnockdownVuln,23\n.set GetupVuln,23\n.set GetupRollForwardVuln,20-1\n.set GetupRollBackwardVuln,30-3\n.set GetupAttackVuln,27\n\n.byte KnockdownVuln\t\t\t\t\t#DownBoundU\n.byte 0\t\t\t\t\t\t\t\t\t\t\t#DownWaitU\n.byte 0\t\t\t\t\t\t\t\t\t\t\t#DownDamageU\n.byte GetupVuln\t\t\t\t\t\t\t#DownStandU\n.byte GetupAttackVuln\t\t\t\t#DownAttackU\n.byte GetupRollForwardVuln\t#DownForwardU\n.byte GetupRollBackwardVuln\t#DownBackU\n.byte -1\t\t\t\t\t\t\t\t\t\t#DownSpotU (unused state)\n.byte KnockdownVuln\t\t\t\t\t#DownBoundD\n.byte 0\t\t\t\t\t\t\t\t\t\t\t#DownWaitD\n.byte 0\t\t\t\t\t\t\t\t\t\t\t#DownDamageD\n.byte GetupVuln\t\t\t\t\t\t\t#DownStandD\n.byte GetupAttackVuln\t\t\t\t#DownAttackD\n.byte GetupRollForwardVuln\t#DownForwardD\n.byte GetupRollBackwardVuln\t#DownBackD\n.byte -1\t\t\t\t\t\t\t\t\t\t#DownSpotD (unused state)\n.byte TechVuln\t\t\t\t\t\t\t#Passive\n.byte TechRollVuln\t\t\t\t\t#PassiveStandF\n.byte TechRollVuln\t\t\t\t\t#PassiveStandB\n.align 2\n###########################################\nSlideOffThink_AttackInputs:\nblrl\n.byte 0\n.long PAD_BUTTON_X\n.byte 0,0,0,0\n\n.byte 4\n.long 0\n.byte 0,0,0,127\n\n.byte 26\n.long PAD_TRIGGER_L\n.byte 0,-127,0,0\n\n.byte -1\n.align 2\n\n#################################\n\nSlideOff_InitializePositions:\nbackup\n\n #Change Facing Direction\n\tli\tr3,-1\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n  li\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\n\n#Get Starting Coordinates\n\tlfs f1,P1X(REG_EventConstants)\n\tstfs f1,0xB0(REG_P1Data)\n\tlfs f1,P1Y(REG_EventConstants)\n\tstfs f1,0xB4(REG_P1Data)\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdatePosition\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdateCameraBox\n\n\tlfs f1,P2X(REG_EventConstants)\n\tstfs f1,0xB0(REG_P2Data)\n\tlfs f1,P2Y(REG_EventConstants)\n\tstfs f1,0xB4(REG_P2Data)\n\tmr\tr3,REG_P2GObj\n\tbl\tPlacePlayerOnGround\n\tmr\tr3,REG_P2GObj\n\tbl\tUpdateCameraBox\n\n#P2 enters UpThrow\n\tmr\tr3,REG_P2GObj\n\tli\tr4,ASID_ThrowHi\n\tli\tr5,0\n\tli\tr6,0\n\tlwz r7,0x10C(REG_P1Data)\t\t#determine speed from weight\n\tlwz r7,0x0(r7)\n\tlfs f1,0x88(r7)\n\tlfs\tf2, -0x68DC (rtoc)\n\tlwz\tr7, -0x514C (r13)\n\tlfs\tf0, 0x037C (r7)\n\tfmuls\tf0,f1,f0\n\tfdivs\tf2,f2,f0\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#anim speed\n\tlfs\tf3, -0x68E0 (rtoc)\t\t\t\t\t\t\t\t\t\t\t#frame blend\n\tlfs f1,UThrowStartFrame(REG_EventConstants)\t#starting frame\n\tbranchl r12,ActionStateChange\n\n#P1 enters DamageFlyTop\n\tmr\tr3,REG_P1GObj\n\tli\tr4,ASID_DamageFlyTop\n\tli\tr5,0x40\n\tli\tr6,0\n\tlfs\tf1,DamageFlyTopStartFrame (REG_EventConstants)\n\tlfs\tf2, -0x73D0 (rtoc)\n\tlfs\tf3, -0x750C (rtoc)\n\tbranchl r12,ActionStateChange\n\n#Scale KB Magnitude based on characters weight\n\tli\tr3,MagLo\n\tbl\tIntToFloat\n\tlfs f2,MagnitudeScalar(REG_EventConstants)\n\tlfs f3,0x16C(REG_P1Data)\n\tlfs f4,MagnitudeScalar2(REG_EventConstants)\n\tlfs f5,MagnitudeScalar3(REG_EventConstants)\n\tfdivs f2,f3,f2\n\tfsubs f2,f2,f4\n\tfmuls f2,f2,f5\n\tfmuls f2,f2,f1\n\tfadds f1,f1,f2\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r20,0x84(sp)\n\n\tli\tr3,MagHi\n\tbl\tIntToFloat\n\tlfs f2,MagnitudeScalar(REG_EventConstants)\n\tlfs f3,0x16C(REG_P1Data)\n\tlfs f4,MagnitudeScalar2(REG_EventConstants)\n\tlfs f5,MagnitudeScalar3(REG_EventConstants)\n\tfdivs f2,f3,f2\n\tfsubs f2,f2,f4\n\tfmuls f2,f2,f5\n\tfmuls f2,f2,f1\n\tfadds f1,f1,f2\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r21,0x84(sp)\n\n#Enter into knockback\n\tmr\tr3,REG_P1GObj\n\tli\tr4,AngleLo\n\tli\tr5,AngleHi\n\tmr\tr6,r20\n\tmr\tr7,r21\n\tbl\tEnterKnockback\n\n#Override hitstun amount\n\tli\tr3,50\n\tbl\tIntToFloat\n\tstfs f1,0x2340(REG_P1Data)\n\n#Give 7 Frames of Hitlag to Each\n\tli\tr3,HitlagFrames\n\tbl\tIntToFloat\n\tstfs f1,0x195C(REG_P1Data)\n\tlbz r0,0x221A(REG_P1Data)\n\tli\tr3,1\n\trlwimi r0,r3,5,26,26\n\tstb r0,0x221A(REG_P1Data)\n\tlbz r0,0x2219(REG_P1Data)\n\tli\tr3,1\n\trlwimi r0,r3,2,29,29\n\tstb r0,0x2219(REG_P1Data)\n\tli\tr3,HitlagFrames\n\tbl\tIntToFloat\n\tstfs f1,0x195C(REG_P2Data)\n\tlbz r0,0x221A(REG_P2Data)\n\tli\tr3,1\n\trlwimi r0,r3,5,26,26\n\tstb r0,0x221A(REG_P2Data)\n\tlbz r0,0x2219(REG_P2Data)\n\tli\tr3,1\n\trlwimi r0,r3,2,29,29\n\tstb r0,0x2219(REG_P2Data)\n\n#Random percent between 10-25\n\tli\tr3,PercentHi-PercentLo\n\tbranchl r12,HSD_Randi\n\taddi r4,r3,PercentLo\n\tlbz r3,0xC(REG_P1Data)\n\tbranchl r12,PlayerBlock_SetDamage\n\nSlideOff_InitializePositions_Exit:\n\trestore\n\tblr\n\n#endregion\n\n#region Grab Mash Out\n###########################\n## Grab Mash Out HIJACK INFO ##\n###########################\n\nGrabMashOut:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Marth.Ext\n\tli\tr6,FinalDestination\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_GrabMashOut\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nGrabMashOutStoreThink:\n\tbl\tGrabMashOutLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## \t\t\tGrab Mash Out LOAD FUNCT \t\t##\n##################################\nGrabMashOutLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tGrabMashOutThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\tb\tGrabMashOutThink_Exit\n\n###################################\n## Grab Mash Out THINK FUNCT ##\n###################################\n\nGrabMashOutThink:\n\tblrl\n\n#Registers\n\t.set REG_EventConstants,25\n  .set REG_MenuData,26\n  .set REG_EventData,31\n  .set REG_P1Data,27\n  .set REG_P1GObj,28\n\t.set REG_P2Data,29\n\t.set REG_P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set EventState_ThrowDelay,0x0\n\t\t.set EventState_MashOutThink,0x1\n\t\t.set EventState_Reset,0x2\n\t.set Timer,0x1\n\t.set ThrowTimer,0x2\n\t.set GrabBreakout,0x4\n\n#Constants\n\t.set ResetTimer,80\n\t.set PercentLo,0\n\t.set PercentHi,80\n\t.set ThrowTimerLo,40\n\t.set ThrowTimerHi,100\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tlwz\tREG_EventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n#Get Player Pointers\n  bl GetAllPlayerPointers\n  mr REG_P1GObj,r3\n  mr REG_P1Data,r4\n  mr REG_P2GObj,r5\n  mr REG_P2Data,r6\n\n#Get Menu and Constants Pointers\n  lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData)\n\tbl\tGrabMashOutThink_Constants\n\tmflr REG_EventConstants\n\n\tbl\tStoreCPUTypeAndZeroInputs\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tGrabMashOutThink_Start\n\t#Init Positions\n\t\tmr\tr3,REG_P1GObj\n\t\tmr\tr4,REG_P2GObj\n\t\tmr\tr5,REG_EventData\n\t\tbl\tGrabMashOut_InitializePositions\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\nGrabMashOutThink_Start:\n\n#Reset if anyone died\n\tbl\tIsAnyoneDead\n\tcmpwi r3,0\n\tbne GrabMashOutThink_Restore\n\nGrabMashOutThink_SwitchCase:\n#Switch Case\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_ThrowDelay\n\tbeq GrabMashOutThink_ThrowDelay\n\tcmpwi r3,EventState_MashOutThink\n\tbeq GrabMashOutThink_MashOutThink\n\tcmpwi r3,EventState_Reset\n\tbeq GrabMashOutThink_Reset\n\tb\tGrabMashOutThink_CheckTimer\n\n#region GrabMashOutThink_ThrowDelay\nGrabMashOutThink_ThrowDelay:\n#Check to grab\n\tlhz r3,ThrowTimer(REG_EventData)\n\tsubi r3,r3,1\n\tsth r3,ThrowTimer(REG_EventData)\n\tcmpwi r3,0\n\tbne GrabMashOutThink_ThrowDelay_TimerSkip\n#Input grab\n\tli\tr3,PAD_BUTTON_A | PAD_TRIGGER_R\n\tstw r3,CPU_HeldButtons(REG_P2Data)\nGrabMashOutThink_ThrowDelay_TimerSkip:\n\n#Check if P1 was grabbed\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_CaptureWaitLw\n\tbeq GrabMashOutThink_ThrowDelay_Grabbed\n\tcmpwi r3,ASID_CaptureWaitHi\n\tbeq GrabMashOutThink_ThrowDelay_Grabbed\n#If just grabbed, skip\n\tcmpwi r3,ASID_CapturePulledLw\n\tbeq GrabMashOutThink_CheckTimer\n\tcmpwi r3,ASID_CapturePulledHi\n\tbeq GrabMashOutThink_CheckTimer\n#Check if P1 acted early\n\tcmpwi r3,ASID_Wait\n\tbne GrabMashOutThink_ThrowDelay_ActedEarly\n\tb\tGrabMashOutThink_CheckTimer\n\nGrabMashOutThink_ThrowDelay_Grabbed:\n#Get breakout timer\n\tlfs f1,0x2354(REG_P1Data)\n\tstfs f1,GrabBreakout(REG_EventData)\n#Change state to attack\n\tli\tr3,EventState_MashOutThink\n\tstb\tr3,EventState(EventData)\n\tb\tGrabMashOutThink_CheckTimer\nGrabMashOutThink_ThrowDelay_ActedEarly:\n#Play Error Noise\n\tli\tr3,0xAF\n\tbl\tPlaySFX\n#Set Timer\n\tli\tr3,ResetTimer-40\n\tstb r3,Timer(REG_EventData)\n#Change state to reset\n\tli\tr3,EventState_Reset\n\tstb\tr3,EventState(EventData)\n\tb\tGrabMashOutThink_CheckTimer\n\n#endregion\n\n#region GrabMashOutThink_MashOutThink\nGrabMashOutThink_MashOutThink:\n#Wait for P1 to be in CaptureCut\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_CaptureJump\n\tbeq GrabMashOutThink_BrokeOut\n\tcmpwi r3,ASID_CaptureCut\n\tbeq GrabMashOutThink_BrokeOut\n\tb GrabMashOutThink_CheckTimer\n\nGrabMashOutThink_BrokeOut:\n#Set reset timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n#Advance State\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n\tb\tGrabMashOutThink_CheckTimer\n\n#endregion\n\n#region GrabMashOutThink_Reset\nGrabMashOutThink_Reset:\n\tb\tGrabMashOutThink_CheckTimer\n#endregion\n\nGrabMashOutThink_CheckTimer:\n#Check if timer exists\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tble GrabMashOutThink_Exit\n#Decrement timer\n\tsubi r3,r3,1\n\tstb r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt GrabMashOutThink_Exit\n\nGrabMashOutThink_Restore:\n#Restore State\n\taddi r3,REG_EventData,EventData_SaveStateStruct\n\tli\tr4,1\n\tbl\tSaveState_Load\n#Init Positions Again\n\tmr\tr3,REG_P1GObj\n\tmr\tr4,REG_P2GObj\n\tmr\tr5,REG_EventData\n\tbl\tGrabMashOut_InitializePositions\n\nGrabMashOutThink_Exit:\n\trestore\n\tblr\n\n################################\n\nGrabMashOutThink_Constants:\nblrl\n.set P1X,0x0\n.set P1Y,0x4\n.set P2X,0x8\n.set P2Y,0xC\n\n.float -8\t\t#p1 x\n.float  0\t\t#p1 y\n.float  8\t\t#p2 x\n.float  0\t\t#p2 y\n###########################################\n\nGrabMashOut_TopText:\nblrl\n.string \"Escaped Grab\"\n.align 2\n\nGrabMashOut_BottomText:\nblrl\n.string \"Frame %d/%d\"\n.align 2\n###########################################\n\nGrabMashOut_InitializePositions:\nbackup\n\n.set REG_FacingDirection,31\t\t#1 = p1 facing right, -1 = p1 facing left\n.set REG_P1GObj,30\n.set REG_P1Data,29\n.set REG_P2GObj,28\n.set REG_P2Data,27\n.set REG_EventData,26\n\n#Init Registers\n  mr\tREG_P1GObj,r3\n  lwz REG_P1Data,0x2C(REG_P1GObj)\n  mr\tREG_P2GObj,r4\n  lwz REG_P2Data,0x2C(REG_P2GObj)\n\tmr\tREG_EventData,r5\n\nGrabMashOut_InitializePositions_DetermineFacingDirection:\n#Determine Facing Direction\n\tli\tREG_FacingDirection,1\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0\n\tbeq GrabMashOut_InitializePositions_DetermineFacingDirection_End\n\tli\tREG_FacingDirection,-1\nGrabMashOut_InitializePositions_DetermineFacingDirection_End:\n\n #Apply Facing Directions\n\tmr\tr3,REG_FacingDirection\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n  mulli\tr3,REG_FacingDirection,-1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\n\n#Get Starting Coordinates\n\tlfs f1,P1X(REG_EventConstants)\n\tlfs f2,P1Y(REG_EventConstants)\n\tcmpwi REG_FacingDirection,0\n\tblt GrabMashOut_InitializePositions_P1FacingLeft\n\tstfs f1,0xB0(REG_P1Data)\n\tstfs f2,0xB4(REG_P1Data)\n\tb\tGrabMashOut_InitializePositions_RightPosition\nGrabMashOut_InitializePositions_P1FacingLeft:\n\tstfs f1,0xB0(REG_P2Data)\n\tstfs f2,0xB4(REG_P2Data)\nGrabMashOut_InitializePositions_RightPosition:\n\tlfs f1,P2X(REG_EventConstants)\n\tlfs f2,P2Y(REG_EventConstants)\n\tcmpwi REG_FacingDirection,0\n\tblt GrabMashOut_InitializePositions_P2FacingRight\n\tstfs f1,0xB0(REG_P2Data)\n\tstfs f2,0xB4(REG_P2Data)\n\tb\tGrabMashOut_InitializePositions_FacingEnd\nGrabMashOut_InitializePositions_P2FacingRight:\n\tstfs f1,0xB0(REG_P1Data)\n\tstfs f2,0xB4(REG_P1Data)\nGrabMashOut_InitializePositions_FacingEnd:\n\n#Update Positions\n\tmr\tr3,REG_P1GObj\n\tbl\tPlacePlayerOnGround\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdateCameraBox\n\tmr\tr3,REG_P2GObj\n\tbl\tPlacePlayerOnGround\n\tmr\tr3,REG_P2GObj\n\tbl\tUpdateCameraBox\n\n#Enter P1 Into Wait\n\tmr\tr3,REG_P1GObj\n\tbranchl\tr12,AS_Wait\n#Enter P2 Into Wait\n\tmr\tr3,REG_P2GObj\n\tbranchl\tr12,AS_Wait\n\n#Random percent\n\tli\tr3,PercentHi-PercentLo\n\tbranchl r12,HSD_Randi\n\taddi r4,r3,PercentLo\n\tlbz r3,0xC(REG_P1Data)\n\tbranchl r12,PlayerBlock_SetDamage\n\n#Reset Variables\n\tli\tr3,EventState_ThrowDelay\n\tstb r3,EventState(REG_EventData)\n\tli\tr3,0\n\tstb r3,Timer(REG_EventData)\n#Init Throw Timer\n\tli\tr3,ThrowTimerHi-ThrowTimerLo\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,ThrowTimerLo\n\tsth r3,ThrowTimer(REG_EventData)\n\nGrabMashOut_InitializePositions_Exit:\n\trestore\n\tblr\n\n#endregion\n\n#region SDI IC DThrow Dair\n#########################\n## Event 16 HIJACK INFO ##\n#########################\n\nEvent16:\n#STORE STAGE\nli\tr3,0x20\nsth\tr3,0xE(r26)\n\nli\tr5,0xE\t\t#Ice Climbers\n\n#STORE CPU\nbl\tP2Struct\nmflr\tr3\nlwz\tr4,0x0(r29)\nstw\tr3,0x18(r4)\t\t#p2 pointer\nstb\tr5,0x0(r3)\t\t#make top tier p2\nli\tr5,0x1\t\t#make CPU controlled\nstb\tr5,0x1(r3)\n\n#SPAWN 2 PLAYERS\nli\tr3,0x40\nstb\tr3,0x1(r4)\n\n#STORE THINK FUNCTION\nbl\tEvent16Load\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t#########################\n\t## Event 16 LOAD FUNCT ##\n\t#########################\n\tEvent16Load:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tEvent16Think\n\tmflr\tr3\n  li  r4,3\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\n\tb\tEvent16LoadExit\n\n\n\t\t##########################\n\t\t## Event 16 THINK FUNCT ##\n\t\t##########################\n\n\n\t\tEvent16Think:\n\t\tblrl\n\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n      bl  GetAllPlayerPointers\n      mr P1GObj,r3\n      mr P1Data,r4\n      mr P2GObj,r5\n      mr P2Data,r6\n\n\t\tli\tr3,0xF\n\t\tstw\tr3,0x1A94(r29)\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tEvent16ThinkMain\n\n\t\t\t\t#Set Frame 1 As Over\n\t\t\t\t\tli\t\tr3,0x1\n\t\t\t\t\tstb\t\tr3,0x0(r31)\n\t\t\t\t#Set Facing Directions\n\t\t\t\t\tlis\tr3,0x3f80\n\t\t\t\t\tstw\tr3,0x2C(r29)\n\t\t\t\t\tlis\tr3,0xBf80\n\t\t\t\t\tstw\tr3,0x2C(r27)\n\t\t\t\t#Initlize Positions\n\t\t\t\t\tbl\tEvent16_Floats\n\t\t\t\t\tmflr\tr3\n\t\t\t\t\tbl\tEvent_EnterGrab\n        #Clear Inputs\n          bl  RemoveFirstFrameInputs\n\t\t\t\t#Store Ground As Last Known Position\n\t\t\t\t\tlfs\tf1, 0x00B4 (r29)\n\t\t\t\t\tstfs\tf1, 0x0834 (r29)\n\t\t\t\t#Save State\n\t\t\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n\t\t\t\t\tbl\tSaveState_Save\n\n\n\t\tEvent16ThinkMain:\n\n\n\n\t\tEvent16ThinkExit:\n\t\trestore\n\t\tblr\n\n#################################################\n\nEvent16_Floats:\nblrl\n.long 0x4144CCCD \t#P1 X Position\n.long 0x00000000\t\t#P1 Y Position\n.long 0xC02CCCCD\t\t#P2 X Position\n.long 0x00000000\t\t#P2 Y Position\n\n#################################################\n\nEvent16LoadExit:\nrestore\nblr\n\n##################################################\n#endregion\n\n##############\n## Fox Tech ##\n##############\n\n#region Ledgetech Counter\n###################################\n## Ledgetech Counter HIJACK INFO ##\n###################################\n\nLedgetechCounter:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Marth.Ext\t\t\t\t\t\t\t\t\t#Use marth\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_LedgetechCounter\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nLedgetechCounterStoreThink:\n\tbl\tLedgetechCounterLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## Ledgetech Counter LOAD FUNCT ##\n##################################\nLedgetechCounterLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tLedgetechCounterThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\tb\tLedgetechCounterThink_Exit\n\n###################################\n## Ledgetech Counter THINK FUNCT ##\n###################################\n\nLedgetechCounterThink:\n\tblrl\n\n#Registers\n\t.set EventConstants,25\n  .set MenuData,26\n  .set EventData,31\n  .set P1Data,27\n  .set P1GObj,28\n\t.set P2Data,29\n\t.set P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set EventState_OnRebirthPlat,0x0\n\t\t.set EventState_Recovering,0x1\n\t.set MarthState,0x1\n\t\t.set MarthState_Wait,0x0\n\t\t.set MarthState_Attacked,0x1\n\t.set Timer,0x2\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n  bl  GetAllPlayerPointers\n  mr P1GObj,r3\n  mr P1Data,r4\n  mr P2GObj,r5\n  mr P2Data,r6\n\n  lwz MenuData,EventData_MenuDataPointer(EventData)\n\n\tbl\tLedgetechCounter_Constants\n\tmflr EventConstants\n\n\tbl\tStoreCPUTypeAndZeroInputs\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tLedgetechCounterThink_Start\n\t#Random Side of Stage\n\t\tli  r3,2\n\t\tbranchl r12,HSD_Randi\n\t\tbl  Ledgetech_InitializePositions\n\t#Move Marth forward a bit\n\t\tlfs f1,0x2C(P2Data)\n\t\tlfs f2,0x4(EventConstants)\n\t\tfmuls f1,f1,f2\n\t\tlfs f2,0xB0(P2Data)\n\t\tfadds f1,f1,f2\n\t\tstfs f1,0xB0(P2Data)\n\t#Move Falco down a bit\n\t\tlfs f1,0x8(EventConstants)\n\t\tlfs f2,0xB4(P1Data)\n\t\tfadds f1,f1,f2\n\t\tstfs f1,0xB4(P1Data)\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\n\t#Init Score Count\n  \tlhz\tr3,-0x4ea8(r13)\n  \tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\nLedgetechCounterThink_Start:\n\n#Reset if anyone died\n\tbl\tIsAnyoneDead\n\tcmpwi r3,0\n\tbne LedgetechCounterThink_Restore\n\n#Switch case for state of event\n\tlbz r3,EventState(EventData)\n\tcmpwi r3,EventState_OnRebirthPlat\n\tbeq LedgetechCounterThink_OnRebirthPlat\n\tcmpwi r3,EventState_Recovering\n\tbeq LedgetechCounterThink_Recovering\n\tb\tLedgetechCounterThink_CheckForTimer\n\n###########################################\nLedgetechCounterThink_OnRebirthPlat:\n#Check if exited RebirthWait\n\tlwz r3,0x10(P1Data)\n\tcmpwi r3,ASID_RebirthWait\n\tbeq LedgetechCounterThink_OnRebirthPlat_ExtendTimer\n#Change Event State\n\tli\tr3,EventState_Recovering\n\tstb r3,EventState(EventData)\n\tb\tLedgetechCounterThink_CheckForTimer\nLedgetechCounterThink_OnRebirthPlat_ExtendTimer:\n#Extend RebithWait Timer\n\tli\tr3,2\n\tstw r3,0x2340(P1Data)\n\tb\tLedgetechCounterThink_CheckForTimer\n###########################################\n\n###########################################\nLedgetechCounterThink_Recovering:\n#Check if marth acted already\n\tlbz r3,MarthState(EventData)\n\tcmpwi r3,MarthState_Wait\n\tbne LedgetechCounterThink_CheckForTimer\n\n#Check P1s Distance from Marth\n\taddi r3,P1Data,0xB0\n\taddi r4,P2Data,0xB0\n\tbl\tGetDistance\n\tlfs f2,0x0(EventConstants)\n\tfcmpo cr0,f1,f2\n\tbgt LedgetechCounterThink_CheckForTimer\n#P1 is in range, use down B\n\tli\tr3,0x200\n\tstw r3,CPU_HeldButtons(P2Data)\n\tli\tr3,-127\n\tstb r3,CPU_AnalogY(P2Data)\n#Set as attacking\n\tli\tr3,MarthState_Attacked\n\tstb r3,MarthState(EventData)\n#Start Timer\n\tli\tr3,70\n\tstb r3,Timer(EventData)\n\n\tb\tLedgetechCounterThink_CheckForTimer\n############################################\n\nLedgetechCounterThink_CheckForTimer:\n#Check Timer\n\tlbz r3,Timer(EventData)\n\tcmpwi r3,0\n\tbeq LedgetechCounterThink_Exit\n#Decrement\n\tsubi r3,r3,1\n\tstb r3,Timer(EventData)\n\tcmpwi r3,0\n\tbne LedgetechCounterThink_Exit\n\nLedgetechCounterThink_Restore:\n#Load State\n  addi r3,EventData,EventData_SaveStateStruct\n  bl\tSaveState_Load\n#Random Side of Stage\n\tli  r3,2\n\tbranchl r12,HSD_Randi\n\tbl  Ledgetech_InitializePositions\n#Move Marth forward a bit\n\tlfs f1,0x2C(P2Data)\n\tlfs f2,0x4(EventConstants)\n\tfmuls f1,f1,f2\n\tlfs f2,0xB0(P2Data)\n\tfadds f1,f1,f2\n\tstfs f1,0xB0(P2Data)\n#Move Falco down a bit\n\tlfs f1,0x8(EventConstants)\n\tlfs f2,0xB4(P1Data)\n\tfadds f1,f1,f2\n\tstfs f1,0xB4(P1Data)\n\n#Reset Variables\n\tli\tr3,EventState_OnRebirthPlat\n\tstb r3,EventState(EventData)\n\tli\tr3,MarthState_Wait\n\tstb r3,MarthState(EventData)\n\tli\tr3,0\n\tstb r3,Timer(EventData)\n\nLedgetechCounterThink_Exit:\n\trestore\n\tblr\n\n\n######\nLedgetechCounter_Constants:\nblrl\n.float 33\t\t#Mm away from fox to init counter\n.float 5\t\t#Mm to move marth forward after placing on ledge\n.float -15\t\t#Mm to move spacies down after placing in the air\n######\n\n#endregion\n\n#region Armada Shine\n###################################\n## Armada Shine HIJACK INFO ##\n###################################\n\nArmadaShine:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Fox.Ext\t\t\t\t\t\t\t\t\t\t#Use fox\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_ArmadaShine\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nArmadaShineStoreThink:\n\tbl\tArmadaShineLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## Armada Shine LOAD FUNCT ##\n##################################\nArmadaShineLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tArmadaShineThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\n#Remove randall\n\tlwz\tr3,StageID_External(r13)\n\tcmpwi\tr3,YoshiStory\n\tbne\tLedgedashLoad_SkipRemoveRandall\n#Get randall's map_gobj\n\tli\tr3,2\t\t\t\t#randalls map_gobj is 2\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,Stage_Destroy_map_gobj\n\n\tb\tArmadaShineThink_Exit\n\n###################################\n## Armada Shine THINK FUNCT ##\n###################################\n\nArmadaShineThink:\n\tblrl\n\n#Registers\n\t.set REG_EventConstants,25\n  .set REG_MenuData,26\n  .set REG_EventData,31\n  .set REG_P1Data,27\n  .set REG_P1GObj,28\n\t.set REG_P2Data,29\n\t.set REG_P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set\tEventState_Hitstun,0x0\n\t\t.set\tEventState_Falling,0x1\n\t\t.set\tEventState_RecoverStart,0x2\n\t\t.set\tEventState_RecoverEnd,0x3\n\t\t.set\tEventState_Reset,0x4\n\t.set Timer,0x1\n\n#Constants\n.set ResetTimer,80\n.set\tQuickResetTimer,30\n.set PercentLo,0\n.set PercentHi,60\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tlwz\tREG_EventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n#Get Player Pointers\n  bl GetAllPlayerPointers\n  mr REG_P1GObj,r3\n  mr REG_P1Data,r4\n  mr REG_P2GObj,r5\n  mr REG_P2Data,r6\n\n#Get Menu and Constants Pointers\n  lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData)\n\tbl\tArmadaShineThink_Constants\n\tmflr REG_EventConstants\n\n\tbl\tStoreCPUTypeAndZeroInputs\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tArmadaShineThink_Start\n\t#Init Positions\n\t\tmr\tr3,REG_P1GObj\n\t\tmr\tr4,REG_P2GObj\n\t\tbl\tArmadaShine_InitializePositions\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\n\t#Init State\n\t\tli\tr3,EventState_Hitstun\n\t\tstb\tr3,EventState(REG_EventData)\nArmadaShineThink_Start:\n\n#Reset if anyone died\n\tbl\tIsAnyoneDead\n\tcmpwi r3,0\n\tbne ArmadaShineThink_Restore\n\n#DPad left to instant reset\n  lbz\tr3, 0x0618 (REG_P1Data)\n  bl\tGetInputStruct\n\tlwz\tr4,InputStruct_InstantButtons(r3)\n\trlwinm. r0,r4,0,31,31\n\tbne\tArmadaShineThink_Restore\n\nArmadaShineThink_GroundCheck:\n#If P2 is grounded, reset quick\n\tlwz\tr3,0xE0(REG_P2Data)\n\tcmpwi\tr3,0\n\tbeq\tArmadaShineThink_GroundCheck_OnGround\n#If P2 is grabbing a cliff, reset quick\n\tlwz\tr3,0x10(REG_P2Data)\n\tcmpwi\tr3,ASID_CliffCatch\n\tbeq\tArmadaShineThink_GroundCheck_OnGround\n\tb\tArmadaShineThink_GroundCheckSkip\nArmadaShineThink_GroundCheck_OnGround:\n#Check if timer was set\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi\tr3,QuickResetTimer\n\tble\tArmadaShineThink_GroundCheckSkip\n#Set timer\n\tli\tr3,QuickResetTimer\n\tstb r3,Timer(REG_EventData)\n#Change State\n\tli\tr3,EventState_Reset\n\tstb\tr3,EventState(REG_EventData)\nArmadaShineThink_GroundCheckSkip:\n\n#Switch Case\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_Hitstun\n\tbeq ArmadaShineThink_Hitstun\n\tcmpwi r3,EventState_Falling\n\tbeq ArmadaShineThink_Falling\n\tcmpwi r3,EventState_RecoverStart\n\tbeq ArmadaShineThink_RecoverStart\n\tcmpwi r3,EventState_RecoverEnd\n\tbeq ArmadaShineThink_RecoverEnd\n\tcmpwi\tr3,EventState_Reset\n\tbeq\tArmadaShineThink_Reset\n\tb\tArmadaShineThink_Exit\n\n#region ArmadaShineThink_Hitstun\nArmadaShineThink_Hitstun:\n#Check if still in hitstun\n\tlbz\tr3,0x221C(REG_P2Data)\n\trlwinm. r3,r3,0,30,30\n\tbne\tArmadaShineThink_Hitstun_Exit\n#Change Event State\n\tli\tr3,EventState_Falling\n\tstb\tr3,EventState(REG_EventData)\n#Run Next State Code\n\tb\tArmadaShineThink_Falling\n\nArmadaShineThink_Hitstun_Exit:\n#Always L-Cancel\n\tli\tr3,0\n\tstb r3,0x67F(REG_P1Data)\n\tb\tArmadaShineThink_Exit\n#endregion\n\n#region ArmadaShineThink_Falling\nArmadaShineThink_Falling:\n.set FirefoxRadius,80\n.set FirefoxChance,8\n#Get distance from ledge\n\taddi r3,REG_P2Data,0xB0\n\taddi r4,REG_P2Data,0x1ADC\n\tbl\tGetDistance\n\tstfs\tf1,0x80(sp)\n#Fox travels approx 82 Mm during firefox, so ensure he is at least this far\n\tli\tr3,FirefoxRadius\n\tbl\tIntToFloat\n\tlfs f2,0x80(sp)\n\tfcmpo cr0,f2,f1\n\tbge ArmadaShineThink_Falling_EnterFirefox\n#Random chance to firefox\n\tli\tr3,FirefoxChance\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0\n\tbeq ArmadaShineThink_Falling_EnterFirefox\n\tb\tArmadaShineThink_Exit\n\nArmadaShineThink_Falling_EnterFirefox:\n#Enter Firefox\n\tli\tr3,127\n\tstb r3,CPU_AnalogY(REG_P2Data)\n\tli\tr3,PAD_BUTTON_B\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n#Change Event State\n\tli\tr3,EventState_RecoverStart\n\tstb\tr3,EventState(REG_EventData)\n#Exit\n\tb\tArmadaShineThink_Exit\n#endregion\n\n#region ArmadaShineThink_RecoverStart\nArmadaShineThink_RecoverStart:\n.set RestartTimer,30\n.set FirefoxHoldFrames,43\n\nArmadaShineThink_RecoverStart_CheckIfDone:\n#Check if no longer in SpecialHiStart\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,354\n\tbeq ArmadaShineThink_RecoverStart_CheckIfDoneSkip\n#Start restart timer\n\tlwz\tr3,0x4(REG_P1Data)\n\tcmpwi\tr3,Fox.Int\n\tbne\tArmadaShineThink_RecoverStart_NotFox\n\tli\tr3,RestartTimer\n\tb\tArmadaShineThink_RecoverStart_StoreRestartTimer\nArmadaShineThink_RecoverStart_NotFox:\n\tli\tr3,RestartTimer+60\nArmadaShineThink_RecoverStart_StoreRestartTimer:\n\tstb r3,Timer(REG_EventData)\n#Change Event State\n\tli\tr3,EventState_RecoverEnd\n\tstb\tr3,EventState(REG_EventData)\n#Run Next State Code\n\tb\tArmadaShineThink_RecoverEnd\nArmadaShineThink_RecoverStart_CheckIfDoneSkip:\n\n/*\n#Wait until last frame of firefox\n\tlhz\tr3,FramesinCurrentAS(REG_P2Data)\n\tcmpwi\tr3,FirefoxHoldFrames-2\n\tbeq\tArmadaShineThink_RecoverStart_InputAngle\n#Input Up\n\tli\tr3,127\n\tstb\tr3,CPU_AnalogY(REG_P2Data)\n\tb\tArmadaShineThink_RecoverStart_Exit\n*/\n\nArmadaShineThink_RecoverStart_InputAngle:\n#Backup f28-f31\n\tstfs f29,0xB0(sp)\n\tstfs f30,0xB4(sp)\n\tstfs f31,0xB8(sp)\n\tstfs f28,0xBC(sp)\n\tstfs f27,0xC0(sp)\n\n#Hold towards ledge\n#Get Angle Between Fox and Ledge\n\taddi r3,REG_P2Data,0xB0\n\taddi r4,REG_P2Data,0x1ADC\n\tbl\tGetAngleBetweenPoints\n\n#Convert this to an input\n.set REG_arctan,31\n.set REG_XComp,30\n.set REG_YComp,31\n.set REG_127,29\n#Backup arctan\n\tfmr REG_arctan,f1\n#Get 127 as a float\n\tli\tr3,127\n\tbl\tIntToFloat\n\tfmr REG_127,f1\n#Get X Component\n\tfmr f1,REG_arctan\t\t#angle in radians\n\tbranchl r12,cos\n\tfmr REG_XComp,f1\n#Get Y Component\n\tfmr f1,REG_arctan\t\t#angle in radians\n\tbranchl r12,sin\n\tfmr REG_YComp,f1\n#Get X input\n\tfmuls f1,REG_XComp,REG_127\n\tfctiwz f1,f1,\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tstb r3,0x1A8C(REG_P2Data)\n#Get Y input\n\tfmuls f1,REG_YComp,REG_127\n\tfctiwz f1,f1,\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tstb r3,0x1A8D(REG_P2Data)\n\n#region ecb test code\n.set REG_XPerFrame,29\n.set REG_YPerFrame,28\n.set REG_CurrXPos,27\n.set REG_CurrYPos,26\n.set REG_ECBStruct,20\n.set REG_ECBBoneStruct,21\n.set REG_LoopCount,22\n.set FirefoxFrames,30\n.set RandomAngleRange,20\n\n#Get Per Frame Velocity\n\tmr\tr3,REG_P2Data\n\tbranchl\tr12,0x800a17e4\n\tfmr\tREG_XComp,f1\n\tmr\tr3,REG_P2Data\n\tbranchl\tr12,0x800a1874\n\tfmr\tREG_YComp,f1\n#Get atan2\n\tfmr\tf1,REG_YComp\n\tlfs\tf2,0x2C(REG_P2Data)\n\tfmuls\tf2,f2,REG_XComp\n\tbranchl\tr12,0x80022c30\n\tfmr\tREG_arctan,f1\n#Get XComp\n\tfmr\tf1,REG_arctan\n\tbranchl\tr12,0x80326240\n\tfmr\tREG_XComp,f1\n\tfmr\tf1,REG_arctan\n\tbranchl\tr12,0x803263d4\n\tfmr\tREG_YComp,f1\n#Get Firefox distance per frame\n\tlwz\tr3, 0x02D4 (REG_P2Data)\n\tlfs\tf1, 0x0074 (r3)\n\tlfs\tf0, 0x002C (REG_P2Data)\n\tfmuls\tf1,f1,REG_XComp\n\tfmuls\tREG_XPerFrame,f1,f0\n\tlfs\tf1, 0x0074 (r3)\n\tfmuls\tREG_YPerFrame,f1,REG_YComp\n#Create an ECB struct on the stack\n\tsubi\tsp,sp,0x1d0\n\taddi\tREG_ECBBoneStruct,sp,0xC\n\taddi\tREG_ECBStruct,sp,0x24\n\tmr\tr3,REG_ECBStruct\n\tbranchl\tr12,0x80041ee4\n#Create ECB Bone struct\n/*\n0x00 = ECB Current Top Y Offset scale * value\n0x04 = ECB Current Bottom Y Offset neg(scale * vlaue)\n0x08 = ECB Current Left X Offset neg(scale * vlaue)\n0x0C = ECB Current Left Y Offset 0\n0x10 = ECB Current Right X Offset scale * value\n0x14 = ECB Current Right Y Offset 0\n*/\n#Copy Struct\n\tmr\tr3,REG_ECBBoneStruct\n\taddi\tr4,REG_EventConstants,ECB_TopY\n\tli\tr5,0x18\n\tbranchl\tr12,memcpy\n#Place Current XY into struct\n\tlfs\tREG_CurrXPos,0xB0(REG_P2Data)\n\tlfs\tREG_CurrYPos,0xB4(REG_P2Data)\n#Subtract 0.4 to account for the frame of animation left in this state\n\tlfs\tf1,FinalAnimYDifference(REG_EventConstants)\n\tfsubs\tREG_CurrYPos,REG_CurrYPos,f1\n\tlfs\tf1,0xB8(REG_P2Data)\n\tstfs\tf1,0x24(REG_ECBStruct)\n#Init Loop\n\tli\tREG_LoopCount,0\nArmadaShineThink_RecoverStart_CollisionLoop:\n#Store current position\n\tstfs\tREG_CurrXPos,0x1C(REG_ECBStruct)\n\tstfs\tREG_CurrYPos,0x20(REG_ECBStruct)\n#Check if frame X or greater\n  lwz\tr5, 0x02D4 (REG_P2Data)\n  lfs f1,0x70(r5)\n  fctiwz  f1,f1\n  stfd  f1,-0x10(sp)\n  lwz r3,-0x0C(sp)\n\tcmpw\tREG_LoopCount,r3\n\tblt\tArmadaShineThink_RecoverStart_CollisionLoop_SkipDecay\nArmadaShineThink_RecoverStart_CollisionLoop_Decay:\n\tlfs\tf1,0x78(r5)\n\tfmuls\tf1,f1,REG_XComp\n\tlfs\tf2, 0x002C (REG_P2Data)\n\tfmuls\tf1,f1,f2\n\tfsubs\tREG_XPerFrame,REG_XPerFrame,f1\n\tlfs\tf1,0x78(r5)\n\tfmuls\tf1,f1,REG_YComp\n\tfsubs\tREG_YPerFrame,REG_YPerFrame,f1\nArmadaShineThink_RecoverStart_CollisionLoop_SkipDecay:\n#Store next position\n\tfadds\tf1,REG_CurrXPos,REG_XPerFrame\n\tstfs\tf1,0x4(REG_ECBStruct)\n\tfadds\tf1,REG_CurrYPos,REG_YPerFrame\n\tstfs\tf1,0x8(REG_ECBStruct)\n\tlfs\tf1,0x24(REG_ECBStruct)\n\tstfs\tf1,0xC(REG_ECBStruct)\n\tmr\tr3,REG_ECBStruct\n\tmr\tr4,REG_ECBBoneStruct\n\tbranchl\tr12,0x8004730c\n\tlfs\tREG_CurrXPos,0x4(REG_ECBStruct)\n\tlfs\tREG_CurrYPos,0x8(REG_ECBStruct)\n#Inc Loop\n\taddi\tREG_LoopCount,REG_LoopCount,1\n  lwz\tr5, 0x02D4 (REG_P2Data)\n  lfs\tf1, 0x0068 (r5)\n  fctiwz  f1,f1\n  stfd  f1,-0x10(sp)\n  lwz r3,-0x0C(sp)\n\tcmpw\tREG_LoopCount,r3\n\tblt\tArmadaShineThink_RecoverStart_CollisionLoop\n#End Loop\n\taddi\tsp,sp,0x1d0\n#endregion\n\n#Restore f28-f31\n\tlfs f29,0xB0(sp)\n\tlfs f30,0xB4(sp)\n\tlfs f31,0xB8(sp)\n\tlfs f28,0xBC(sp)\n\tlfs f27,0xC0(sp)\n\nArmadaShineThink_RecoverStart_Exit:\n\tb\tArmadaShineThink_Exit\n#endregion\n\n#region ArmadaShineThink_RecoverEnd\nArmadaShineThink_RecoverEnd:\n#If CPU got hit, recover again\n\tlbz\tr3,0x221C(REG_P2Data)\n\trlwinm. r3,r3,0,30,30\n\tbeq\tArmadaShineThink_Reset\n#Enter Hitstun state\n\tli\tr3,EventState_Hitstun\n\tstb\tr3,EventState(REG_EventData)\n\tb\tArmadaShineThink_Exit\n#endregion\n\n#region ArmadaShineThink_Reset\nArmadaShineThink_Reset:\n#Get timer\n\tlbz r3,Timer(REG_EventData)\n\tsubi r3,r3,1\n\tstb r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tble ArmadaShineThink_Restore\n\tb\tArmadaShineThink_Exit\n\n#endregion\n\nArmadaShineThink_Restore:\n#Restore State\n\taddi r3,REG_EventData,EventData_SaveStateStruct\n\tli\tr4,1\n\tbl\tSaveState_Load\n#Init Positions Again\n\tmr\tr3,REG_P1GObj\n\tmr\tr4,REG_P2GObj\n\tbl\tArmadaShine_InitializePositions\n#Reset Variables\n\tli\tr3,0\n\tstb r3,EventState(REG_EventData)\n\tstb r3,Timer(REG_EventData)\n\nArmadaShineThink_Exit:\n\trestore\n\tblr\n\nArmadaShineThink_Constants:\nblrl\n\n.set\tECB_TopY,0x0 #scale * value\n.set\tECB_BottomY,0x4 #neg(scale * vlaue)\n.set\tECB_LeftX,0x8 #neg(scale * vlaue)\n.set\tECB_LeftY,0xC #0\n.set\tECB_RightX,0x10 #scale * value\n.set\tECB_RightY,0x14 #0\n.set\tFinalAnimYDifference,0x18\n.float 9\n.float 2.5\n.float -3.3\n.float 5.7\n.float 3.3\n.float 5.7\n.float 0.4\n\nArmadaShine_InitializePositions:\nbackup\n\n.set LedgeSide,20\n\n#Constants\n.set ArmadaShine_P1X,15\n.set ArmadaShine_P1Y,6\n.set ArmadaShine_P2X,12\n.set ArmadaShine_P2Y,6\n.set HitlagFrames,12\n\n#Get random side\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n#Backup Ledge Side\n\tmr\tLedgeSide,r3\n\n#Change Facing Directions\n  cmpwi LedgeSide,0x0\n  beq\tArmadaShine_InitializePositions_GetLeftLedgeID\nArmadaShine_InitializePositions_GetRightLedgeID:\n #Change Facing Direction\n\tli\tr3,-1\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n  li\tr3,-1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\n\tb\tArmadaShine_InitializePositions_DirectionChangeEnd\nArmadaShine_InitializePositions_GetLeftLedgeID:\n#Change Facing Direction\n\tli\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P1Data)\n  li\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\nArmadaShine_InitializePositions_DirectionChangeEnd:\n\n#Get Ledge Coordinates\n\tmr\tr3,LedgeSide\n\taddi r4,sp,0x80\n\tbl\tGetLedgeCoordinates\n\n#Move P1\n\tli r3,ArmadaShine_P1X\n\tbl\tIntToFloat\n\tlfs f2,0x80(sp)\n\tlfs f3,0x2C(REG_P1Data)\n\tfmadds f1,f1,f3,f2\n\tstfs f1,0xB0(REG_P1Data)\n\tli r3,ArmadaShine_P1Y\n\tbl\tIntToFloat\n\tlfs f2,0x84(sp)\n\tfadds f1,f1,f2\n\tstfs f1,0xB4(REG_P1Data)\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdatePosition\n#Move P2\n\tli r3,ArmadaShine_P2X\n\tbl\tIntToFloat\n\tlfs f2,0x80(sp)\n\tlfs f3,0x2C(REG_P2Data)\n\tfmadds f1,f1,f3,f2\n\tstfs f1,0xB0(REG_P2Data)\n\tli r3,ArmadaShine_P2Y\n\tbl\tIntToFloat\n\tlfs f2,0x84(sp)\n\tfadds f1,f1,f2\n\tstfs f1,0xB4(REG_P2Data)\n\tmr\tr3,REG_P2GObj\n\tbl\tUpdatePosition\n#P1 enters Bair\n\tmr\tr3,REG_P1GObj\n\tli\tr4,ASID_AttackAirB\n\tbranchl r12,0x8008cfac\n#Fastforward to frame 7\n\tli\tr3,7\n\tbl\tIntToFloat\n\tmr\tr3,REG_P1GObj\n\tlfs\tf2, -0x67D8 (rtoc)\n\tlfs\tf3, -0x67E4 (rtoc)\n\tbranchl r12,0x8006ebe8\n\tli\tr3,7\n\tbl\tIntToFloat\n\tstfs f1,0x894(REG_P1Data)\n\tli\tr3,0\n\tstw r3,0x3E4(REG_P1Data)\n\tmr\tr3,REG_P1GObj\n\tbranchl r12,0x80073354\n#Update Animation\n\tmr\tr3,REG_P1GObj\n\tbranchl r12,0x8006e9b4\n#Remove all hitboxes\n\tmr\tr3,REG_P1GObj\n\tbranchl r12,0x8007aff8\n#Stop subaction script from being updated\n\tli\tr3,0\n\tstw r3,0x3EC(REG_P1Data)\n#Update Camera\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdateCameraBox\n\n#P2 enters DamageFlyN\n\tmr\tr3,REG_P2GObj\n\tli\tr4,ASID_DamageFlyN\n\tli\tr5,0x40\n\tli\tr6,0\n\tlfs\tf1, -0x750C (rtoc)\n\tlfs\tf2, -0x7508 (rtoc)\n\tlfs\tf3, -0x750C (rtoc)\n\tbranchl r12,ActionStateChange\n#Update Animation\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,0x8006e9b4\n#Remove Jump\n\tlwz r3,0x168(REG_P2Data)\n\tstb r3,0x1968(REG_P2Data)\n#Update Camera\n\tmr\tr3,REG_P2GObj\n\tbl\tUpdateCameraBox\n\n.set AngleLo,45\n.set AngleHi,60\n.set MagLo,106\n.set MagHi,120\n#Enter into knockback\n\tmr\tr3,REG_P2GObj\n\tli\tr4,AngleLo\n\tli\tr5,AngleHi\n\tli\tr6,MagLo\n\tli\tr7,MagHi\n\tbl\tEnterKnockback\n\n#Give 7 Frames of Hitlag to Each\n\tli\tr3,HitlagFrames\n\tbl\tIntToFloat\n\tstfs f1,0x195C(REG_P1Data)\n\tlbz r0,0x221A(REG_P1Data)\n\tli\tr3,1\n\trlwimi r0,r3,5,26,26\n\tstb r0,0x221A(REG_P1Data)\n\tlbz r0,0x2219(REG_P1Data)\n\tli\tr3,1\n\trlwimi r0,r3,2,29,29\n\tstb r0,0x2219(REG_P1Data)\n\tli\tr3,HitlagFrames\n\tbl\tIntToFloat\n\tstfs f1,0x195C(REG_P2Data)\n\tlbz r0,0x221A(REG_P2Data)\n\tli\tr3,1\n\trlwimi r0,r3,5,26,26\n\tstb r0,0x221A(REG_P2Data)\n\tlbz r0,0x2219(REG_P2Data)\n\tli\tr3,1\n\trlwimi r0,r3,2,29,29\n\tstb r0,0x2219(REG_P2Data)\n\n#Random percent\n\tli\tr3,PercentHi-PercentLo\n\tbranchl r12,HSD_Randi\n\taddi r4,r3,PercentLo\n\tlbz r3,0xC(REG_P2Data)\n\tbranchl r12,PlayerBlock_SetDamage\n\nArmadaShine_InitializePositions_Exit:\n\trestore\n\tblr\n\n#endregion\n\n#region SideB Sweetspot\n###########################\n## SideB Sweetspot HIJACK INFO ##\n###########################\n\nSideBSweetspot:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Marth.Ext\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_SideBSweetspot\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nSideBSweetspotStoreThink:\n\tbl\tSideBSweetspotLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## \t\t\tSideB Sweetspot LOAD FUNCT \t\t##\n##################################\nSideBSweetspotLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tSideBSweetspotThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\tb\tSideBSweetspotThink_Exit\n\n###################################\n## SideB Sweetspot THINK FUNCT ##\n###################################\n\nSideBSweetspotThink:\n\tblrl\n\n#Registers\n\t.set REG_EventConstants,25\n  .set REG_MenuData,26\n  .set REG_EventData,31\n  .set REG_P1Data,27\n  .set REG_P1GObj,28\n\t.set REG_P2Data,29\n\t.set REG_P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set EventState_Endlag,0x0\n\t\t.set EventState_WaitToAttack,0x1\n\t\t.set EventState_AttackThink,0x2\n\t\t.set EventState_Reset,0x3\n\t.set Timer,0x1\n\t.set ThrowTimer,0x2\n\t.set JabFrame,0x4\n\n#Constants\n\t.set ResetTimer,30\n\t.set AngleLo,45\n\t.set AngleHi,60\n\t.set MagLo,106#106\n\t.set MagHi,135#120\n\t.set PercentHi,100\n\t.set PercentLo,50\n\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tlwz\tREG_EventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n#Get Player Pointers\n  bl GetAllPlayerPointers\n  mr REG_P1GObj,r3\n  mr REG_P1Data,r4\n  mr REG_P2GObj,r5\n  mr REG_P2Data,r6\n\n#Get Menu and Constants Pointers\n  lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData)\n\tbl\tSideBSweetspotThink_Constants\n\tmflr REG_EventConstants\n\n\tbl\tStoreCPUTypeAndZeroInputs\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tSideBSweetspotThink_Start\n\t#Init Positions\n\t\tmr\tr3,REG_P1GObj\n\t\tmr\tr4,REG_P2GObj\n\t\tmr\tr5,REG_EventData\n\t\tbl\tSideBSweetspot_InitializePositions\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\nSideBSweetspotThink_Start:\n\n#P2 intangible\n\tmr\tr3,P2GObj\n\tli\tr4,1\n\tbranchl r12,ApplyIntangibility\n\n#Reset if anyone died\n\tbl\tIsAnyoneDead\n\tcmpwi r3,0\n\tbne SideBSweetspotThink_Restore\n\nSideBSweetspotThink_Crouch:\n#Always hold crouch when state is higher than EventState_Endlag\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_Endlag\n\tble SideBSweetspotThink_CrouchSkip\n#Input crouch\n\tli\tr3,-127\n\tstb r3,CPU_AnalogY(REG_P2Data)\nSideBSweetspotThink_CrouchSkip:\n\nSideBSweetspotThink_SwitchCase:\n#Switch Case\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_Endlag\n\tbeq SideBSweetspotThink_Endlag\n\tcmpwi r3,EventState_WaitToAttack\n\tbeq SideBSweetspotThink_WaitToAttack\n\tcmpwi r3,EventState_AttackThink\n\tbeq SideBSweetspotThink_AttackThink\n\tcmpwi r3,EventState_Reset\n\tbeq SideBSweetspotThink_Reset\n\tb\tSideBSweetspotThink_CheckTimer\n\n#region SideBSweetspotThink_Endlag\nSideBSweetspotThink_Endlag:\n#Check if in Wait\n\tlwz r3,0x10(P2Data)\n\tcmpwi r3,ASID_Wait\n\tbne SideBSweetspotThink_CheckTimer\n#Input Crouch\n\tli\tr3,-127\n\tstb r3,CPU_AnalogY(REG_P2Data)\n#Change state to attack\n\tli\tr3,EventState_WaitToAttack\n\tstb\tr3,EventState(EventData)\n\tb\tSideBSweetspotThink_CheckTimer\n\n#endregion\n\n#region SideBSweetspotThink_WaitToAttack\nSideBSweetspotThink_WaitToAttack:\n#Wait for Fox to be in SpecialAirS\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,0x15F\n\tbne SideBSweetspotThink_WaitToAttackSkip\n#Input Dtilt\n\tli\tr3,PAD_BUTTON_A\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n\tli\tr3,-38\n\tstb r3,CPU_AnalogY(REG_P2Data)\n#Advance State\n\tli\tr3,EventState_AttackThink\n\tstb r3,EventState(REG_EventData)\n\tb\tSideBSweetspotThink_CheckTimer\nSideBSweetspotThink_WaitToAttackSkip:\n\n#Check if fox up-b'd\n\tcmpwi r3,0x162\n\tbeq SideBSweetspotThink_WaitToAttack_BlacklistMove\n\tcmpwi r3,ASID_EscapeAir\n\tbeq SideBSweetspotThink_WaitToAttack_BlacklistMove\n\tb\tSideBSweetspotThink_WaitToAttack_CheckForBlacklistMovesSkip\nSideBSweetspotThink_WaitToAttack_BlacklistMove:\n#PLay Error SFX\n  li\tr3,0xAF\n  bl  PlaySFX\n#Start Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n#Advance State\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n\tb\tSideBSweetspotThink_CheckTimer\nSideBSweetspotThink_WaitToAttack_CheckForBlacklistMovesSkip:\n#endregion\n\n#region SideBSweetspotThink_AttackThink\nSideBSweetspotThink_AttackThink:\n#Check if d-tilting\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_AttackLw3\n\tbne SideBSweetspotThink_CheckTimer\n#Check if frame 7\n\tli\tr3,7\n\tbl\tIntToFloat\n\tlfs f2,0x894(REG_P2Data)\n\tfcmpo cr0,f1,f2\n\tbne SideBSweetspotThink_AttackThink_FreezeSkip\n#Check if already frozen\n\tli\tr3,0\n\tbl\tIntToFloat\n\tlfs f2,0x89C(REG_P2Data)\n\tfcmpo cr0,f1,f2\n\tbeq SideBSweetspotThink_AttackThink_FreezeCheckToUnfreeze\n#Freeze\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,FrameSpeedChange\n\tb\tSideBSweetspotThink_AttackThink_FreezeSkip\nSideBSweetspotThink_AttackThink_FreezeCheckToUnfreeze:\n#Check if player was hit\n\tlwz r3,0x2094(REG_P2Data)\n\tcmpwi r3,0\n\tbeq SideBSweetspotThink_AttackThink_FreezeSkip\n#Unfreeze\n\tli\tr3,1\n\tbl\tIntToFloat\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,FrameSpeedChange\n#Start Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n#Advance State\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n\tb\tSideBSweetspotThink_CheckTimer\nSideBSweetspotThink_AttackThink_FreezeSkip:\n\n#Check if P1 grabbed ledge successfully\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_CliffCatch\n\tbne SideBSweetspotThink_AttackThink_CliffCatchSkip\n#Play Success SFX\n\tli\tr3,0xAD\n\tbl\tPlaySFX\n#Unfreeze P2\n\tli\tr3,1\n\tbl\tIntToFloat\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,FrameSpeedChange\n#Start Timer\n\tli\tr3,ResetTimer+30\n\tstb r3,Timer(REG_EventData)\n#Advance State\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n\tb\tSideBSweetspotThink_CheckTimer\nSideBSweetspotThink_AttackThink_CliffCatchSkip:\n\n#endregion\n\n#region SideBSweetspotThink_Reset\nSideBSweetspotThink_Reset:\n\tb\tSideBSweetspotThink_CheckTimer\n#endregion\n\nSideBSweetspotThink_CheckTimer:\n#Check if timer exists\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tble SideBSweetspotThink_Exit\n#Decrement timer\n\tsubi r3,r3,1\n\tstb r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt SideBSweetspotThink_Exit\n\nSideBSweetspotThink_Restore:\n#Restore State\n\taddi r3,REG_EventData,EventData_SaveStateStruct\n\tli\tr4,1\n\tbl\tSaveState_Load\n#Init Positions Again\n\tmr\tr3,REG_P1GObj\n\tmr\tr4,REG_P2GObj\n\tmr\tr5,REG_EventData\n\tbl\tSideBSweetspot_InitializePositions\n\nSideBSweetspotThink_Exit:\n\trestore\n\tblr\n\n################################\n\nSideBSweetspotThink_Constants:\nblrl\n.set P1X,0x0\n.set P1Y,0x4\n.set P2X,0x8\n.set P2Y,0xC\n.set GrabDistance,0x10\n.set HoldShieldVelocity,0x14\n.set RunDistance,0x18\n\n.float -8\t\t#p1 x\n.float  0\t\t#p1 y\n.float  8\t\t#p2 x\n.float  0\t\t#p2 y\n.float 14\t\t#16\n.float 1.1\n.float 23\n###########################################\n\nSideBSweetspot_InitializePositions:\nbackup\n\n.set REG_P1GObj,30\n.set REG_P1Data,29\n.set REG_P2GObj,28\n.set REG_P2Data,27\n.set REG_EventData,26\n.set LedgeSide,20\n\n#Constants\n.set SideBSweet_P1X,-12\n.set SideBSweet_P1Y,6\n.set SideBSweet_P2X,15\n.set SideBSweet_P2Y,0\n.set HitlagFrames,12\n\n#Init Registers\n  mr\tREG_P1GObj,r3\n  lwz REG_P1Data,0x2C(REG_P1GObj)\n  mr\tREG_P2GObj,r4\n  lwz REG_P2Data,0x2C(REG_P2GObj)\n\tmr\tREG_EventData,r5\n\n#Get random side\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n#Backup Ledge Side\n\tmr\tLedgeSide,r3\n\n#Change Facing Directions\n  cmpwi LedgeSide,0x0\n  beq\tSideBSweet_InitializePositions_GetLeftLedgeID\nSideBSweet_InitializePositions_GetRightLedgeID:\n #Change Facing Direction\n\tli\tr3,-1\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n  li\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\n\tb\tSideBSweet_InitializePositions_DirectionChangeEnd\nSideBSweet_InitializePositions_GetLeftLedgeID:\n#Change Facing Direction\n\tli\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P1Data)\n  li\tr3,-1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\nSideBSweet_InitializePositions_DirectionChangeEnd:\n\n#Get Ledge Coordinates\n\tmr\tr3,LedgeSide\n\taddi r4,sp,0x80\n\tbl\tGetLedgeCoordinates\n\n#Move P1\n\tli r3,SideBSweet_P1X\n\tbl\tIntToFloat\n\tlfs f2,0x80(sp)\n\tlfs f3,0x2C(REG_P1Data)\n\tfmadds f1,f1,f3,f2\n\tstfs f1,0xB0(REG_P1Data)\n\tli r3,SideBSweet_P1Y\n\tbl\tIntToFloat\n\tlfs f2,0x84(sp)\n\tfadds f1,f1,f2\n\tstfs f1,0xB4(REG_P1Data)\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdatePosition\n#Move P2\n\tli r3,SideBSweet_P2X\n\tbl\tIntToFloat\n\tlfs f2,0x80(sp)\n\tlfs f3,0x2C(REG_P2Data)\n\tfneg f3,f3\n\tfmadds f1,f1,f3,f2\n\tstfs f1,0xB0(REG_P2Data)\n\tli r3,SideBSweet_P2Y\n\tbl\tIntToFloat\n\tlfs f2,0x84(sp)\n\tfadds f1,f1,f2\n\tstfs f1,0xB4(REG_P2Data)\n\tmr\tr3,REG_P2GObj\n\tbl\tPlacePlayerOnGround\n#Clear P2's GFX Pointer\n\tli\tr3,0\n\tstw r3,0x60C(REG_P2Data)\n#P2 enters FSmash\n\tli\tr3,0\n\tbl\tIntToFloat\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,0x8008c3e0\n#Fastforward to frame 11\n\tli\tr3,11\n\tbl\tIntToFloat\n\tmr\tr3,REG_P2GObj\n\tlfs\tf2, -0x67D8 (rtoc)\n\tlfs\tf3, -0x67E4 (rtoc)\n\tbranchl r12,0x8006ebe8\n\tli\tr3,7\n\tbl\tIntToFloat\n\tstfs f1,0x894(REG_P2Data)\n\tli\tr3,0\n\tstw r3,0x3E4(REG_P2Data)\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,0x80073354\n#Update Animation\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,0x8006e9b4\n#Remove all hitboxes\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,0x8007aff8\n#Stop subaction script from being updated\n\tli\tr3,0\n\tstw r3,0x3EC(REG_P2Data)\n#Update Camera\n\tmr\tr3,REG_P2GObj\n\tbl\tUpdateCameraBox\n\n#P1 enters DamageFlyN\n\tmr\tr3,REG_P1GObj\n\tli\tr4,ASID_DamageFlyN\n\tli\tr5,0x40\n\tli\tr6,0\n\tlfs\tf1, -0x750C (rtoc)\n\tlfs\tf2, -0x7508 (rtoc)\n\tlfs\tf3, -0x750C (rtoc)\n\tbranchl r12,ActionStateChange\n#Update Animation\n\tmr\tr3,REG_P1GObj\n\tbranchl r12,0x8006e9b4\n#Remove Jump\n\t#lwz r3,0x168(REG_P1Data)\n\t#stb r3,0x1968(REG_P1Data)\n#Update Camera\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdateCameraBox\n\n#Enter into knockback\n\tmr\tr3,REG_P1GObj\n\tli\tr4,AngleLo\n\tli\tr5,AngleHi\n\tli\tr6,MagLo\n\tli\tr7,MagHi\n\tbl\tEnterKnockback\n\n#Give 7 Frames of Hitlag to Each\n\tli\tr3,HitlagFrames\n\tbl\tIntToFloat\n\tstfs f1,0x195C(REG_P1Data)\n\tlbz r0,0x221A(REG_P1Data)\n\tli\tr3,1\n\trlwimi r0,r3,5,26,26\n\tstb r0,0x221A(REG_P1Data)\n\tlbz r0,0x2219(REG_P1Data)\n\tli\tr3,1\n\trlwimi r0,r3,2,29,29\n\tstb r0,0x2219(REG_P1Data)\n\tli\tr3,HitlagFrames\n\tbl\tIntToFloat\n\tstfs f1,0x195C(REG_P2Data)\n\tlbz r0,0x221A(REG_P2Data)\n\tli\tr3,1\n\trlwimi r0,r3,5,26,26\n\tstb r0,0x221A(REG_P2Data)\n\tlbz r0,0x2219(REG_P2Data)\n\tli\tr3,1\n\trlwimi r0,r3,2,29,29\n\tstb r0,0x2219(REG_P2Data)\n\n#Random percent\n\tli\tr3,PercentHi-PercentLo\n\tbranchl r12,HSD_Randi\n\taddi r4,r3,PercentLo\n\tlbz r3,0xC(REG_P1Data)\n\tbranchl r12,PlayerBlock_SetDamage\n\n#Reset Variables\n\tli\tr3,EventState_ThrowDelay\n\tstb r3,EventState(REG_EventData)\n\tli\tr3,0\n\tstb r3,Timer(REG_EventData)\nSideBSweetspot_InitializePositions_Exit:\n\trestore\n\tblr\n\n#endregion\n\n#region Escape Sheik\n###########################\n## Escape Sheik HIJACK INFO ##\n###########################\n\nEscapeSheik:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Sheik.Ext\n\tli\tr6,FinalDestination\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_EscapeSheik\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nEscapeSheikStoreThink:\n\tbl\tEscapeSheikLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## \t\t\tEscape Sheik LOAD FUNCT \t\t##\n##################################\nEscapeSheikLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tEscapeSheikThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\tb\tEscapeSheikThink_Exit\n\n###################################\n## Escape Sheik THINK FUNCT ##\n###################################\n\nEscapeSheikThink:\n\tblrl\n\n#Registers\n\t.set REG_EventConstants,25\n  .set REG_MenuData,26\n  .set REG_EventData,31\n  .set REG_P1Data,27\n  .set REG_P1GObj,28\n\t.set REG_P2Data,29\n\t.set REG_P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set EventState_ThrowDelay,0x0\n\t\t.set EventState_ThrowEndlag,0x1\n\t\t.set EventState_Chase,0x2\n\t\t.set EventState_Jab2,0x3\n\t\t.set EventState_Reset,0x4\n\t.set\tTimer,0x1\n\t.set\tThrowTimer,0x2\n\t.set\tJabFrame,0x4\n\t.set\tisJabTwice,0x5\n\t.set\tJab2Frame,0x6\n\t.set\tJab2Timer,0x7\n\t.set\tisDisplayedTiming,0x8\n\n#Constants\n\t.set ResetTimer,40\n\t.set PercentLo,0\n\t.set PercentHi,40\n\t.set ThrowTimerLo,30\n\t.set ThrowTimerHi,60\n\t.set ReactFrame,12\n\t.set JabFrameLo,15\n\t.set JabFrameHi,20\n\t.set Jab2FrameLo,6\n\t.set Jab2FrameHi,18\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tlwz\tREG_EventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n#Get Player Pointers\n  bl GetAllPlayerPointers\n  mr REG_P1GObj,r3\n  mr REG_P1Data,r4\n  mr REG_P2GObj,r5\n  mr REG_P2Data,r6\n\n#Get Menu and Constants Pointers\n  lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData)\n\tbl\tEscapeSheikThink_Constants\n\tmflr REG_EventConstants\n\n\tbl\tStoreCPUTypeAndZeroInputs\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tEscapeSheikThink_Start\n\t#Init Positions\n\t\tmr\tr3,REG_P1GObj\n\t\tmr\tr4,REG_P2GObj\n\t\tmr\tr5,REG_EventData\n\t\tbl\tEscapeSheik_InitializePositions\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\nEscapeSheikThink_Start:\n\n#Reset if anyone died\n\tbl\tIsAnyoneDead\n\tcmpwi r3,0\n\tbne EscapeSheikThink_Restore\n\nEscapeSheikThink_CheckIfFailed:\n#Check if failed the Escape Sheik (grabbed))\n#EventState > EventState_Hitstun\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_Chase\n\tblt EscapeSheikThink_CheckIfFailed_End\n#Check if grabbed\n\tlwz r3,0x10(P1Data)\n\tcmpwi r3,ASID_CapturePulledHi\n\tblt EscapeSheikThink_CheckIfFailed_End\n\tcmpwi r3,ASID_CaptureFoot\n\tbgt EscapeSheikThink_CheckIfFailed_End\n#Check if timer has started\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt EscapeSheikThink_CheckIfFailed_End\n#Start Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\nEscapeSheikThink_CheckIfFailed_End:\n\nEscapeSheikThink_CheckIfCPUDamaged:\n\tlwz\tr3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_DamageHi1\n\tblt\tEscapeSheikThink_CheckIfCPUDamaged_End\n\tcmpwi r3,ASID_DamageFlyRoll\n\tbgt\tEscapeSheikThink_CheckIfCPUDamaged_End\n#Check if timer has started\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt EscapeSheikThink_CheckIfCPUDamaged_End\n#Start Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n#Play Success Sound?\n#Maybe increment a high score or something idk\nEscapeSheikThink_CheckIfCPUDamaged_End:\n\nEscapeSheikThink_CheckForMistimedShine:\n#Check if event state is in chase\n\tlbz\tr3,EventState(REG_EventData)\n\tcmpwi\tr3,EventState_Chase\n\tblt\tEscapeSheikThink_CheckForMistimedShine_End\n#Check if displayed already\n\tlbz\tr3,isDisplayedTiming(REG_EventData)\n\tcmpwi\tr3,0\n\tbne\tEscapeSheikThink_CheckForMistimedShine_End\n#Get this frames inputs\n  lbz\tr4, 0x0618 (REG_P1Data)\n  bl\tGetInputStruct\n\tmr\tr5,r3\n#Check B Button\n\tlwz\tr3,InputStruct_InstantButtons(r5)\n\trlwinm.\tr0,r3,0,22,22\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_End\n#Check if pushing down\n\tlbz\tr3,InputStruct_LeftAnalogY(r5)\n\textsb\tr3,r3\n\tcmpwi\tr3,-44\n\tbgt\tEscapeSheikThink_CheckForMistimedShine_End\n#Check if in any missed tech state\n\tlwz\tr3,0x10(REG_P1Data)\n\tcmpwi\tr3,ASID_Passive\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Early\n\tcmpwi\tr3,ASID_PassiveStandB\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Early\n\tcmpwi\tr3,ASID_PassiveStandF\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Early\n#Check if being grabbed\n\tcmpwi\tr3,ASID_CapturePulledLw\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Late\n\tcmpwi\tr3,ASID_CapturePulledHi\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Late\n\tcmpwi\tr3,ASID_CaptureWaitLw\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Late\n\tcmpwi\tr3,ASID_CaptureWaitHi\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Late\n\tb\tEscapeSheikThink_CheckForMistimedShine_End\n.set\tREG_String,20\n.set\tREG_Frames,21\nEscapeSheikThink_CheckForMistimedShine_Early:\n#Get early string\n\tbl\tEscapeSheikThink_EarlyText\n\tmflr\tREG_String\n#Get frames early\n\tmr\tr3,REG_P1Data\n\tlwz\tr4,0x14(REG_P1Data)\n\tbranchl\tr12,0x80085e50\n\tlfs\tf1,0x8(r3)\n\tfctiwz\tf1,f1\n\tstfd\tf1,0x80(sp)\n\tlwz\tr3,0x84(sp)\n\tlhz\tr4,FramesinCurrentAS(REG_P1Data)\n\tsub\tREG_Frames,r3,r4\n\tb\tEscapeSheikThink_CheckForMistimedShine_Display\nEscapeSheikThink_CheckForMistimedShine_Late:\n#Get late string\n\tbl\tEscapeSheikThink_LateText\n\tmflr\tREG_String\n#Get frames late\nEscapeSheikThink_CheckForMistimedShine_LateSearchInitLoop:\n.set\tREG_Count,22\n\tli\tREG_Count,0\n\tlhz\tREG_Frames,FramesinCurrentAS(REG_P1Data)\nEscapeSheikThink_CheckForMistimedShine_LateSearchLoop:\n#Get previous action state\n\taddi\tr3,REG_P1Data,PrevASStart\n\tmulli\tr4,REG_Count,0x2\n\tadd\tr5,r3,r4\n#Check if wait\n\tlhz\tr3,0x0(r5)\n\tcmpwi\tr3,ASID_Wait\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_LateSearchFoundWait\n#Add frames spent in this state\n\tlhz\tr3,0xC(r5)\n\tadd\tREG_Frames,REG_Frames,r3\nEscapeSheikThink_CheckForMistimedShine_LateSearchIncLoop:\n\taddi\tREG_Count,REG_Count,1\n\tcmpwi\tREG_Count,6\n\tblt\tEscapeSheikThink_CheckForMistimedShine_LateSearchLoop\n\tb\tEscapeSheikThink_CheckForMistimedShine_End\n\nEscapeSheikThink_CheckForMistimedShine_LateSearchFoundWait:\n\nEscapeSheikThink_CheckForMistimedShine_Display:\n#Output reaction time\n\tmr\tr3,REG_P1Data\t\t#p1 (no offsetting window)\n\tli\tr4,120\t\t\t\t\t#text timeout\n\tli\tr5,0\t\t\t\t\t\t#Area to Display (0-2)\n\tli\tr6,OSD.Miscellaneous\t\t\t#Window ID (Unique to This Display)\n\tbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\n\tmr\tr22,r3\t\t\t#backup text pointer\n\n#Create Text 1\n\tmr \tr3,r22\t\t\t#text pointer\n\tbl\tEscapeSheikThink_TopText\n\tmflr\tr4\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tbranchl r12,Text_InitializeSubtext\n#Create Text 2\n\tmr \tr3,r22\t\t\t#text pointer\n\tbl\tEscapeSheikThink_BottomText\n\tmflr\tr4\n\tmr\tr5,REG_Frames\n\tmr\tr6,REG_String\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#default text X/Y\n\tbranchl r12,Text_InitializeSubtext\n#Set as displayed\n\tli\tr3,1\n\tstb\tr3,isDisplayedTiming(REG_EventData)\nEscapeSheikThink_CheckForMistimedShine_End:\n\nEscapeSheikThink_SwitchCase:\n#Switch Case\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_ThrowDelay\n\tbeq EscapeSheikThink_ThrowDelay\n\tcmpwi r3,EventState_ThrowEndlag\n\tbeq EscapeSheikThink_ThrowEndlag\n\tcmpwi r3,EventState_Chase\n\tbeq EscapeSheikThink_Chase\n\tcmpwi r3,EventState_Reset\n\tbeq EscapeSheikThink_Reset\n\tcmpwi\tr3,EventState_Jab2\n\tbeq\tEscapeSheikThink_Jab2\n\tb\tEscapeSheikThink_CheckTimer\n\n#region EscapeSheikThink_ThrowDelay\nEscapeSheikThink_ThrowDelay:\n#Check to throw\n\tlhz r3,ThrowTimer(REG_EventData)\n\tsubi r3,r3,1\n\tsth r3,ThrowTimer(REG_EventData)\n\tcmpwi r3,0\n\tbgt EscapeSheikThink_CheckTimer\n#Input DThrow\n\tli\tr3,-127\n\tstb r3,CPU_AnalogY(REG_P2Data)\n#Change state to attack\n\tli\tr3,EventState_ThrowEndlag\n\tstb\tr3,EventState(EventData)\n\tb\tEscapeSheikThink_CheckTimer\n\n#endregion\n\n#region EscapeSheikThink_ThrowEndlag\nEscapeSheikThink_ThrowEndlag:\n#Wait for Sheik to be out of ThrowLw\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_Wait\n\tbne EscapeSheikThink_CheckTimer\n#Wait for P1 to be in their tech option\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_Passive\n\tblt EscapeSheikThink_ThrowEndlag_CheckMissTech\n\tcmpwi r3,ASID_PassiveStandB\n\tble EscapeSheikThink_ThrowEndlag_End\nEscapeSheikThink_ThrowEndlag_CheckMissTech:\n\tcmpwi r3,ASID_DownBoundD\n\tbeq EscapeSheikThink_ThrowEndlag_End\n\tcmpwi r3,ASID_DownBoundU\n\tbeq EscapeSheikThink_ThrowEndlag_End\n\tb\tEscapeSheikThink_CheckTimer\nEscapeSheikThink_ThrowEndlag_End:\n#Advance State\n\tli\tr3,EventState_Chase\n\tstb r3,EventState(REG_EventData)\n\tb\tEscapeSheikThink_Chase\n\n#endregion\n\n#region EscapeSheikThink_Chase\nEscapeSheikThink_Chase:\n.set Distance,0xB0\n.set REG_Direction,20\n#Get Distance\n\tlfs f1,0xB0(REG_P2Data)\n\tlfs f2,0xB0(REG_P1Data)\n\tfsubs f1,f2,f1\n\tlfs f2,0x2C(REG_P2Data)\n\tfmuls f1,f1,f2\n\tstfs f1,Distance(sp)\n#Get Direction\n\tli\tr3,0\n\tbl\tIntToFloat\n\tlfs f2,Distance(sp)\n\tfcmpo cr0,f2,f1\n\tblt 0xC\n\tli\tREG_Direction,1\n\tb\t0x8\n\tli\tREG_Direction,-1\n\n#Determine Tech Option\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_DownBoundD\n\tbeq EscapeSheikThink_Chase_DownBoundThink\n\tcmpwi r3,ASID_DownBoundU\n\tbeq EscapeSheikThink_Chase_DownBoundThink\n#Now only run these when over frame 12\n\tlhz r4,FramesinCurrentAS(REG_P1Data)\n\tcmpwi r4,ReactFrame\n\tblt EscapeSheikThink_CheckTimer\n\tcmpwi r3,ASID_Passive\n\tbeq EscapeSheikThink_Chase_PassiveThink\n\tcmpwi r3,ASID_PassiveStandB\n\tbeq EscapeSheikThink_Chase_PassiveStandThink\n\tcmpwi r3,ASID_PassiveStandF\n\tbeq EscapeSheikThink_Chase_PassiveStandThink\n\tb\tEscapeSheikThink_CheckTimer\n\nEscapeSheikThink_Chase_PassiveThink:\n#Check if facing P1\n\tcmpwi REG_Direction,0\n\tbgt EscapeSheikThink_Chase_PassiveThink_FacingSkip\n#Input slightly towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,100\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_PassiveThink_FacingSkip:\n#Check distance (if over 16 units, walk towards)\n\tlfs f1,GrabDistance(REG_EventConstants)\n\tlfs f2,Distance(sp)\n\tfabs f2,f2\n\tfcmpo cr0,f2,f1\n\tble EscapeSheikThink_Chase_PassiveThink_RunTowardsSkip\n#If over 24 units, run towards\n\tlfs f1,RunDistance(REG_EventConstants)\n\tfcmpo cr0,f2,f1\n\tbgt\tEscapeSheikThink_Chase_PassiveThink_RunTowards\nEscapeSheikThink_Chase_PassiveThink_WalkTowards:\n#Walk Towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,100\n\tstb r3,CPU_AnalogX(REG_P2Data)\n\tb\tEscapeSheikThink_Chase_PassiveThink_RunTowardsSkip\nEscapeSheikThink_Chase_PassiveThink_RunTowards:\n#Run Towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,127\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_PassiveThink_RunTowardsSkip:\n#Check distance\n\tlfs f1,GrabDistance(REG_EventConstants)\n\tlfs f2,Distance(sp)\n\tfabs f2,f2\n\tfcmpo cr0,f2,f1\n\tbgt EscapeSheikThink_Chase_PassiveThink_HoldShieldSkip\n#Check State\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_Dash\n\tbeq EscapeSheikThink_Chase_PassiveThink_HoldShield\n\tcmpwi r3,ASID_Run\n\tbeq EscapeSheikThink_Chase_PassiveThink_HoldShield\n\tb\tEscapeSheikThink_Chase_PassiveThink_HoldShieldSkip\nEscapeSheikThink_Chase_PassiveThink_HoldShield:\n#Enter shield\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,AS_Guard\n#And hold\n\tli\tr3,PAD_TRIGGER_R\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n\tb\tEscapeSheikThink_Chase_PassiveThink_HoldShieldSkip\nEscapeSheikThink_Chase_PassiveThink_HoldShieldSkip:\n#Now grab when P1 is on frame 20\n\tlhz r3,FramesinCurrentAS(REG_P1Data)\n\tcmpwi r3,20\n\tblt EscapeSheikThink_CheckTimer\n#Enter grab\n\tmr\tr3,REG_P2GObj\n\tli\tr4,0xD4\n\tbranchl r12,AS_Catch\n#Advance state\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n#Start timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n\tb\tEscapeSheikThink_CheckTimer\n\nEscapeSheikThink_Chase_PassiveStandThink:\n#Check if facing P1\n\tcmpwi REG_Direction,0\n\tbgt EscapeSheikThink_Chase_PassiveStandThink_FacingSkip\n#BUT is he coming to me?\n\tlfs f2,0xC8(REG_P1Data)\n\tli\tr3,0\n\tbl\tIntToFloat\n\tli\tr3,1\t\t#Moving Right\n\tfcmpo cr0,f2,f1\n\tbgt 0x8\n\tli\tr3,-1\t\t#Moving Left\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r4,0x84(sp)\n\tmullw r4,r4,REG_Direction\n\tcmpw r3,r4\n\tbne  EscapeSheikThink_Chase_PassiveStandThink_FacingSkip\n#If under frame 20, run instead\n\tli\tr5,127\n\tlhz r3,FramesinCurrentAS(REG_P1Data)\n\tcmpwi r3,20\n\tblt 0x8\n\tli\tr5,100\n#Input slightly towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmullw r3,r3,r5\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_PassiveStandThink_FacingSkip:\n#Check distance (if over 16 units, run towards)\n\tlfs f1,GrabDistance(REG_EventConstants)\n\tlfs f2,Distance(sp)\n\tfabs f2,f2\n\tfcmpo cr0,f2,f1\n\tble EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip\n#Wait until no longer turning\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_Turn\n\tbne  EscapeSheikThink_Chase_PassiveStandThink_RunTowardCheckMovementDirection\n#If turning, wait til frame 2 to make a decision\n\tlhz r3,FramesinCurrentAS(REG_P2Data)\n\tcmpwi r3,2\n\tbge EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip\nEscapeSheikThink_Chase_PassiveStandThink_RunTowardCheckMovementDirection:\n#BUT is he coming to me?\n\tlfs f2,0xC8(REG_P1Data)\n\tli\tr3,0\n\tbl\tIntToFloat\n\tli\tr3,1\t\t#Moving Right\n\tfcmpo cr0,f2,f1\n\tbgt 0x8\n\tli\tr3,-1\t\t#Moving Left\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r4,0x84(sp)\n\tmullw r4,r4,REG_Direction\n\tcmpw r3,r4\n\tbne  EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip\nEscapeSheikThink_Chase_PassiveStandThink_RunTowards:\n#Run Towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,127\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip:\n#If and within range and running, hold shield\n#Check distance\n\tlfs f1,GrabDistance(REG_EventConstants)\n\tlfs f2,Distance(sp)\n\tfabs f2,f2\n\tfcmpo cr0,f2,f1\n\tbgt EscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_Dash\n\tbeq EscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckFrame\n\tcmpwi r3,ASID_Run\n\tbeq EscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckFrame\n\tb\tEscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip\nEscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckFrame:\n\tlhz r3,FramesinCurrentAS(REG_P1Data)\n\tcmpwi r3,28\n\tbge EscapeSheikThink_Chase_PassiveStandThink_HoldShield\nEscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckVelocity:\n#Allow to hold shield earlier than usual if the character isnt moving very far\n\tlfs f1,0xC8(REG_P1Data)\n\tfabs f1,f1,\n\tlfs f2,HoldShieldVelocity(REG_EventConstants)\n\tfcmpo cr0,f1,f2\n\tbgt EscapeSheikThink_Chase_PassiveStandThink_HoldShieldRunInstead\nEscapeSheikThink_Chase_PassiveStandThink_HoldShield:\n#Enter shield\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,AS_Guard\n#And hold\n\tli\tr3,PAD_TRIGGER_R\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n\tb\tEscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip\nEscapeSheikThink_Chase_PassiveStandThink_HoldShieldRunInstead:\n#Run Towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,127\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip:\n#Now grab when P1 is on frame 34\n\tlhz r3,FramesinCurrentAS(REG_P1Data)\n\tcmpwi r3,34\n\tblt EscapeSheikThink_CheckTimer\n#Enter grab\n\tmr\tr3,REG_P2GObj\n\tli\tr4,0xD4\n\tbranchl r12,AS_Catch\n#Advance state\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n#Start timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n\tb\tEscapeSheikThink_CheckTimer\n\n\nEscapeSheikThink_Chase_DownBoundThink:\n#Determine jab frame\n\tlbz r3,JabFrame(REG_EventData)\n\tcmpwi r3,0\n\tbne EscapeSheikThink_Chase_DownBoundThink_JabFrameInitSkip\n#Init Jab Frame\n\tli\tr3,JabFrameHi-JabFrameLo\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,JabFrameLo\n\tstb r3,JabFrame(REG_EventData)\n#Get chance to jab again\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tstb r3,isJabTwice(REG_EventData)\n#Get frame to jab again\n\tli\tr3,Jab2FrameHi-Jab2FrameLo\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,Jab2FrameLo\n\tstb r3,Jab2Frame(REG_EventData)\n#Init Jab 2 Timer\n\tli\tr3,0\n\tstb\tr3,Jab2Timer(REG_EventData)\nEscapeSheikThink_Chase_DownBoundThink_JabFrameInitSkip:\n#Check if facing P1\n\tcmpwi REG_Direction,0\n\tbgt EscapeSheikThink_Chase_DownBoundThink_FacingSkip\n#Input slightly towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,100\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_DownBoundThink_FacingSkip:\n#Check distance (if over 16 units, walk towards)\n\tlfs f1,GrabDistance(REG_EventConstants)\n\tlfs f2,Distance(sp)\n\tfabs f2,f2\n\tfcmpo cr0,f2,f1\n\tble EscapeSheikThink_Chase_DownBoundThink_RunTowardsSkip\nEscapeSheikThink_Chase_DownBoundThink_WalkTowards:\n#Walk Towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,100\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_DownBoundThink_RunTowardsSkip:\n#Check distance\n\tlfs f1,GrabDistance(REG_EventConstants)\n\tlfs f2,Distance(sp)\n\tfabs f2,f2\n\tfcmpo cr0,f2,f1\n\tbgt EscapeSheikThink_Chase_DownBoundThink_HaltSkip\n#Ensure Facing\n\tcmpwi REG_Direction,1\n\tbne EscapeSheikThink_Chase_DownBoundThink_HaltSkip\nEscapeSheikThink_Chase_DownBoundThink_Halt:\n#Stop Moving\n\tli\tr3,0\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_DownBoundThink_HaltSkip:\n#Now jab when P1 is on the jab frame\n\tlhz r3,FramesinCurrentAS(REG_P1Data)\n\tlbz r4,JabFrame(REG_EventData)\n\tcmpw r3,r4\n\tblt EscapeSheikThink_CheckTimer\n#Enter jab\n\tli\tr3,PAD_BUTTON_A\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n\tli\tr3,0\n\tstb r3,CPU_AnalogX(REG_P2Data)\n#Check if sheik will double jab\n\tlbz\tr3,isJabTwice(REG_EventData)\n\tcmpwi\tr3,0\n\tbeq\tEscapeSheikThink_Chase_DownBoundThink_SingleJab\n#Start Double Jab timer\n\tlbz\tr3,Jab2Frame(REG_EventData)\n\tstb\tr3,Jab2Timer(REG_EventData)\n#Change Event State\n\tli\tr3,EventState_Jab2\n\tstb\tr3,EventState(REG_EventData)\n\tb\tEscapeSheikThink_CheckTimer\nEscapeSheikThink_Chase_DownBoundThink_SingleJab:\n#Advance state\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n#Start timer\n\tli\tr3,ResetTimer+30\n\tstb r3,Timer(REG_EventData)\n\tb\tEscapeSheikThink_CheckTimer\n#endregion\n\n#region EscapeSheikThink_Jab2\nEscapeSheikThink_Jab2:\n#Check if waiting on jab 2\n\tlbz\tr3,Jab2Timer(REG_EventData)\n\tcmpwi\tr3,0\n\tbeq\tEscapeSheikThink_Chase_DownBoundThink_Jab2Skip\n#But not during hitlag\n\tlbz\tr3,0x221A(REG_P2Data)\n\trlwinm.\tr3,r3,0,26,26\n\tbne\tEscapeSheikThink_Chase_DownBoundThink_Jab2Skip\n#Decrement timer\n\tlbz\tr3,Jab2Timer(REG_EventData)\n\tsubi\tr3,r3,1\n\tstb\tr3,Jab2Timer(REG_EventData)\n#Check if up\n\tcmpwi\tr3,0\n\tbgt\tEscapeSheikThink_CheckTimer\n#Enter jab\n\tli\tr3,PAD_BUTTON_A\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n\tli\tr3,0\n\tstb r3,CPU_AnalogX(REG_P2Data)\n#Advance state\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n#Start timer\n\tli\tr3,ResetTimer+30\n\tstb r3,Timer(REG_EventData)\n\tb\tEscapeSheikThink_CheckTimer\nEscapeSheikThink_Chase_DownBoundThink_Jab2Skip:\n\tb\tEscapeSheikThink_CheckTimer\n#endregion\n\n#region EscapeSheikThink_Reset\nEscapeSheikThink_Reset:\n#Hold Shield\n\tli\tr3,PAD_TRIGGER_R\n\tstw\tr3,CPU_HeldButtons(REG_P2Data)\n\tb\tEscapeSheikThink_CheckTimer\n#endregion\n\nEscapeSheikThink_CheckTimer:\n#Check if timer exists\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tble EscapeSheikThink_Exit\n#Decrement timer\n\tsubi r3,r3,1\n\tstb r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt EscapeSheikThink_Exit\n\nEscapeSheikThink_Restore:\n#Restore State\n\taddi r3,REG_EventData,EventData_SaveStateStruct\n\tli\tr4,1\n\tbl\tSaveState_Load\n#Init Positions Again\n\tmr\tr3,REG_P1GObj\n\tmr\tr4,REG_P2GObj\n\tmr\tr5,REG_EventData\n\tbl\tEscapeSheik_InitializePositions\n\nEscapeSheikThink_Exit:\n\trestore\n\tblr\n\n################################\n\nEscapeSheikThink_Constants:\nblrl\n.set P1X,0x0\n.set P1Y,0x4\n.set P2X,0x8\n.set P2Y,0xC\n.set GrabDistance,0x10\n.set HoldShieldVelocity,0x14\n.set RunDistance,0x18\n\n.float -8\t\t#p1 x\n.float  0\t\t#p1 y\n.float  8\t\t#p2 x\n.float  0\t\t#p2 y\n.float 14\t\t#16\n.float 1.1\n.float 23\n\n###########################################\n\nEscapeSheikThink_TopText:\nblrl\n.string \"Down B Input\"\n.align 2\n\nEscapeSheikThink_BottomText:\nblrl\n.string \"%df %s\"\n.align 2\n\nEscapeSheikThink_EarlyText:\nblrl\n.string \"Early\"\n.align 2\n\nEscapeSheikThink_LateText:\nblrl\n.string \"Late\"\n.align 2\n\n###########################################\n\nEscapeSheik_InitializePositions:\nbackup\n\n.set REG_FacingDirection,31\t\t#1 = p1 facing right, -1 = p1 facing left\n.set REG_P1GObj,30\n.set REG_P1Data,29\n.set REG_P2GObj,28\n.set REG_P2Data,27\n.set REG_EventData,26\n\n#Init Registers\n  mr\tREG_P1GObj,r3\n  lwz REG_P1Data,0x2C(REG_P1GObj)\n  mr\tREG_P2GObj,r4\n  lwz REG_P2Data,0x2C(REG_P2GObj)\n\tmr\tREG_EventData,r5\n\nEscapeSheik_InitializePositions_DetermineFacingDirection:\n#Determine Facing Direction\n\tli\tREG_FacingDirection,1\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0\n\tbeq EscapeSheik_InitializePositions_DetermineFacingDirection_End\n\tli\tREG_FacingDirection,-1\nEscapeSheik_InitializePositions_DetermineFacingDirection_End:\n\n #Apply Facing Directions\n\tmr\tr3,REG_FacingDirection\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n  mulli\tr3,REG_FacingDirection,-1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\n\n#Get Starting Coordinates\n\tlfs f1,P1X(REG_EventConstants)\n\tlfs f2,P1Y(REG_EventConstants)\n\tcmpwi REG_FacingDirection,0\n\tblt EscapeSheik_InitializePositions_P1FacingLeft\n\tstfs f1,0xB0(REG_P1Data)\n\tstfs f2,0xB4(REG_P1Data)\n\tb\tEscapeSheik_InitializePositions_RightPosition\nEscapeSheik_InitializePositions_P1FacingLeft:\n\tstfs f1,0xB0(REG_P2Data)\n\tstfs f2,0xB4(REG_P2Data)\nEscapeSheik_InitializePositions_RightPosition:\n\tlfs f1,P1X(REG_EventConstants)\n\tlfs f2,P1Y(REG_EventConstants)\n\tcmpwi REG_FacingDirection,0\n\tblt EscapeSheik_InitializePositions_P2FacingRight\n\tstfs f1,0xB0(REG_P2Data)\n\tstfs f2,0xB4(REG_P2Data)\nEscapeSheik_InitializePositions_P2FacingRight:\n\tstfs f1,0xB0(REG_P1Data)\n\tstfs f2,0xB4(REG_P1Data)\n#Update Positions\n\tmr\tr3,REG_P1GObj\n\tbl\tPlacePlayerOnGround\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdateCameraBox\n\tmr\tr3,REG_P2GObj\n\tbl\tPlacePlayerOnGround\n\tmr\tr3,REG_P2GObj\n\tbl\tUpdateCameraBox\n\n#Store P1 into P2 Grab Pointer\n\tstw\tREG_P1GObj,0x1A58(REG_P2Data)\n\tstw\tREG_P1GObj,0x1A5C(REG_P2Data)\n#Clear P1's Grabbed Player Pointer\n\tli\tr3,0\n\tstw\tr3,0x1A58(REG_P1Data)\n\tstw\tr3,0x1A5C(REG_P1Data)\n#Clear P2's GFX Pointer\n\tstw r3,0x60C(REG_P2Data)\n#Enter P2 Into Grab\n\tmr\tr3,REG_P2GObj\t\t\t#P2 Enters Grab\n\tbranchl\tr12,AS_GrabOpponent\n#Enter P1 Into Grabbed\n\tmr\tr3,REG_P1GObj\t\t\t#P1 Grabbed\n\tmr\tr4,REG_P2GObj\t\t\t#P2 = Grabber\n\tbranchl\tr12,AS_Grabbed\n#Enter P2 Into GrabWait\n\tmr\tr3,REG_P2GObj\t\t\t#P2 Enters GrabWait\n\tbranchl\tr12,AS_CatchWait\n#Give a bunch of grabstun\n\tli\tr3,999\n\tbl\tIntToFloat\n\tstfs f1,0x1A4C(REG_P1Data)\n\n#Random percent\n\tli\tr3,PercentHi-PercentLo\n\tbranchl r12,HSD_Randi\n\taddi r4,r3,PercentLo\n\tlbz r3,0xC(REG_P1Data)\n\tbranchl r12,PlayerBlock_SetDamage\n\n#Reset Variables\n\tli\tr3,EventState_ThrowDelay\n\tstb r3,EventState(REG_EventData)\n\tli\tr3,0\n\tstb r3,Timer(REG_EventData)\n\tstb r3,JabFrame(REG_EventData)\n#Init Throw Timer\n\tli\tr3,ThrowTimerHi-ThrowTimerLo\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,ThrowTimerLo\n\tsth r3,ThrowTimer(REG_EventData)\n#Init isDisplayedTiming\n\tli\tr3,0\n\tstb\tr3,isDisplayedTiming(REG_EventData)\n\nEscapeSheik_InitializePositions_Exit:\n\trestore\n\tblr\n\n#endregion\n\n#region Scrapped Edgeguard Event\n/*\n\n#########################\n## Event 16 HIJACK INFO ##\n#########################\n\nEvent16:\n#STORE STAGE\nli\tr3,0x20\nsth\tr3,0xE(r26)\n\nli\tr5,0x2\t\t#Ice Climbers\nli\tr5,0x14\n\n#STORE CPU\nlwz\tr4,0x0(r29)\nbl\tP2Struct\nmflr\tr3\nstw\tr3,0x18(r4)\t\t#p2 pointer\nstb\tr5,0x0(r3)\t\t#make top tier p2\nli\tr5,0x1\t\t#make CPU controlled\nstb\tr5,0x1(r3)\n\n#SPAWN 2 PLAYERS\nli\tr3,0x40\nstb\tr3,0x1(r4)\n\n\n#STORE THINK FUNCTION\nbl\tEvent16Load\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Event 16 LOAD FUNCT ##\n\t########################\n\tEvent16Load:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tEvent16Think\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n\tbl\tCreateEventThinkFunction\n\n\tb\tEvent16LoadExit\n\n\n\t\t#########################\n\t\t## Event 16 THINK FUNCT ##\n\t\t#########################\n\n\n\t\tEvent16Think:\n\t\t\tblrl\n\t\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\t\tlwz\t\tr31,0x2c(r3)\t\t\t#backup data pointer in r31\n\n\t\t#Get P2\n\t\t\tli\t\tr3,0x1\n\t\t\tbranchl\t\tr12,PlayerBlock_LoadMainCharDataOffset\t\t\t#get player block\n\t\t\tmr\t\tr30,r3\t\t\t#player block in r30\n\t\t\tlwz\t\tr29,0x2c(r30)\t\t\t#player data in r29\n\n\t\t#Get P1\n\t\t\tli\t\tr3,0x0\n\t\t\tbranchl\t\tr12,PlayerBlock_LoadMainCharDataOffset\t\t\t#get player block\n\t\t\tmr\t\tr28,r3\t\t\t#player block in r28\n\t\t\tlwz\t\tr27,0x2c(r28)\t\t\t#player data in r27\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\t\tlbz\tr3,0x0(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tEvent16ThinkMain\n\n\t\t\t\tlbz\tr3,0x221D(r29)\n\t\t\t\trlwinm.\tr3,r3,0,28,28\n\t\t\t\tbne\tEvent16ThinkExit\n\n\t\t\t\t#Set Frame 1 As Over\n\t\t\t\t\tli\t\tr3,0x1\n\t\t\t\t\tstb\t\tr3,0x0(r31)\n\t\t\t\t#Initlize Positions\n\t\t\t\t\tbl\tEvent16_Floats\n\t\t\t\t\tmflr\tr3\n\t\t\t\t\t#bl\tInitializePositions\n        #Clear Inputs\n          bl  RemoveFirstFrameInputs\n\t\t\t\t#Save State\n\t\t\t\t\tmr\tr3,r31\n\t\t\t\t\tbl\tSaveState_Save\n\t\t\t\t#Set Timer to -60\n\t\t\t\t\tli\t\tr3,-60\n\t\t\t\t\tstw\t\tr3,0x4(r31)\n\n\n\n\t\tEvent16ThinkMain:\n\t\tEvent16ThinkSequence:\n\t\t#Inc Timer\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tstw\tr3,0x4(r31)\n\n\t\t#Get Floats\n\t\t\tbl\tEvent16_Floats\n\t\t\tmflr\tr21\n\n\t\t#L+DPad Controls CPU Percent\n\t\tbl\tDPadCPUPercent\n\n\t\t#Check If Already in A Recovery Mode\n\t\t\tlbz\tr3,0x8(r31)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbeq\tEvent16CheckRecoveryFlag\n\n\t\t#Check If CPU Is Offstage\n\t\t\tmr\tr3,r29\n\t\t\tbranchl\tr12,0x800a2c80\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tEvent16CheckRecoveryFlag\n\n\t\t\t#Check If Still in Hitstun\n\t\t\t\tlbz\tr3,0x221C(r29)\n\t\t\t\trlwinm.\tr3,r3,0,30,30\n\t\t\t\tbne\tEvent16CheckRecoveryFlag\n\n\t\t\t#Check If Below Ledge\n\t\t\t#Hold Towards Ledge\n\n\t\t\t\t#Get Random Recovery Option\n\t\t\t\tEvent16GetRandomRecovery:\n\t\t\t\t\tli\tr3,3\t\t#Number of Recovery Options (Side B Immediately,Jump Then Side B, ShineStall-Jump-SideB)\n\t\t\t\t\tbranchl\tr12,HSD_Randi\n\t\t\t\t\tcmpwi\tr3,0x0\n\t\t\t\t\tbne\tEvent16StoreRecoveryType\n\t\t\t\t#Check If Can Side B Only\n\t\t\t\t\t#Check If Above Ledge\n\t\t\t\t\t\tlfs\tf1,0xB4(r29)\t#Get Y Coord\n\t\t\t\t\t\t#lfs\tf2,0x10(r21)\n\t\t\t\t\t\t#fcmpo\tcr0,f1,f2\n\t\t\t\t\t\t#bgt\tEvent16GetRandomRecovery\n\t\t\t\t\t\t#lfs\tf2,0x10(r21)\n\t\t\t\t\t#Check If Below Ledge\n\t\t\t\t\t\tlfs\tf2,0x14(r21)\n\t\t\t\t\t\tfcmpo\tcr0,f1,f2\n\t\t\t\t\t\tblt\tEvent16GetRandomRecovery\n\n\t\t\t\tEvent16StoreRecoveryType:\n\t\t\t\t\tstb\tr3,0x9(r31)\n\t\t\t\t#Init Recovery Flag\n\t\t\t\t\tli\tr3,0x1\n\t\t\t\t\tstb\tr3,0x8(r31)\n\n\n\t\tEvent16CheckRecoveryFlag:\n\t\t#Check Recovery Flag\n\t\t\tlbz\tr3,0x8(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tEvent16CheckToReset\n\n#******************************************************************#\n\n#IsRecovering\n\n\t\t#If Timer Is Set, Dont Run Any of This\n\t\tlwz\tr3,0xC(r31)\t\t#get timer\t#Get Timer\n\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\tbgt\tEvent16GetRecoveryID\n\n\t\t#Hold Towards Stage\n\t\tli\tr3,127\n\t\tlfs\tf0,0x00B0 (r29)\t#X Pos\n\t\tlfs\tf1,0x1ADC (r29) #Last Grounded X Pos\n\t\tfcmpo\tcr0,f1,f0\n\t\tbgt\tEvent16HoldTowardsRight\n\t\tneg\tr3,r3\n\t\tEvent16HoldTowardsRight:\n\t\tstb\tr3,0x1A8C(r29)\n\n\t\t\t#Check If Died\n\t\t\tlbz\tr3,0x221F(r29)\n\t\t\trlwinm.\tr3,r3,0,25,25\n\t\t\tbne\tEvent16SideBThink_Reset\n\n\t\t\t#Check If In Hitlag\n\t\t\t#Recover again\n\t\t\tlbz\tr3,0x221A(r29)\n\t\t\trlwinm.\tr3,r3,0,26,26\n\t\t\tbne\tEvent16RecoverAgain\n\n\t\t\t#Check If Made It Back\n\t\t\t#Check Ground Flag\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tEvent16SideBThink_Reset\n\t\t\t#Check CliffCatch\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0xFC\n\t\t\tbeq\tEvent16SideBThink_Reset\n\n\t\t\tb\tEvent16GetRecoveryID\n\n\t\t\tEvent16RecoverAgain:\n\t\t\t#Recover Again\n\t\t\tli\tr3,0x0\n\t\t\tstb\tr3,0x8(r31)\n\t\t\tstb\tr3,0x9(r31)\n\t\t\tb\tEvent16CheckToReset\n\n\t\t\tEvent16SideBThink_Reset:\n\t\t\t#Set Timer\n\t\t\tlwz\tr3,0xC(r31)\t\t#get timer\t#Get Timer\n\t\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\t\tbgt\tEvent16CheckToReset\t#Reset Timer Set\n\t\t\tli\tr3,30\n\t\t\tstw\tr3,0xC(r31)\t\t#Store Reset Timer\n\t\t\tb\tEvent16CheckToReset\n\n\t\t#Run Recovery Think\n\t\t#Get Which Recovery To Perform\n\t\tEvent16GetRecoveryID:\n\t\tlbz\tr3,0x9(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tEvent16SideBOnly\n\t\tcmpwi\tr3,0x1\n\t\tbeq\tEvent16JumpSideB\n\t\tcmpwi\tr3,0x2\n\t\tbeq\tEvent16SSJumpSideB\n\t\tcmpwi\tr3,0x3\n\t\tbeq\tEvent16SideBThink\n\n\t#*************************************************#\n\n\t\tEvent16SideBOnly:\n\t\t#Be in ledge Y range, Check if next frame will be out of Y range\n\t\t\tbl\tEvent16CheckIfLineUpWithLedge\n\t\t\tcmpwi\tr3,-1\t\t\t#Not In Range Yet\n\t\t\tbeq\tEvent16CheckToReset\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tEvent16ChanceToInputSideB\n\n\t\t#If OoRange Next Frame + Descending, Side B Immediately\n\t\t\tlfs\tf0, -0x7208 (rtoc)\n\t\t\tlfs\tf1,0xCC(r29)\n\t\t\tfcmpo\tcr0,f1,f0\n\t\t\tblt\tEvent16InputSideB\n\n\t\t\tEvent16ChanceToInputSideB:\n\t\t\tli\tr3,5\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tEvent16InputSideB\n\t\t\tb\tEvent16CheckToReset\n\n\t\t\tEvent16InputSideB:\n\t\t\t\t#Joystick X = 120 * Facing Direction\n\t\t\t\tlfs\tf1,0x2C(r29)\n\t\t\t\tfctiwz\tf1,f1\n\t\t\t\tstfd\tf1,0xF0(sp)\n\t\t\t\tlwz\tr4,0xF4(sp)\n\t\t\t\tli\tr3,120\t\t#X Stick\n\t\t\t\tmullw\tr3,r3,r4\n\t\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\t\tli\tr3,0x200\n\t\t\t\tstw\tr3,0x1A88(r29)\n\t\t\t\t#li\tr3,0x0\n\t\t\t\t#stb\tr3,0x8(r31)\n\n\t\t\t\t#Change State to Mid-Side B\n\t\t\t\tli\tr3,3\n\t\t\t\tstb\tr3,0x9(r31)\n\t\t\t\tb\tEvent16CheckToReset\n\n\t#*************************************************#\n\n\t\tEvent16JumpSideB:\n\t\t#Be above bottom most coord, Check if next frame will be out of Y range\n\t\t#Be in ledge Y range, Check if next frame will be out of Y range\n\n\t\t#Check If Above Bottom-most\n\t\tlfs\tf1,0xB4(r29)\t#Get Next Frames Y Coord\n\t\tlfs\tf2,0x84(r29)\n\t\tfadds\tf1,f1,f2\n\t\tlfs\tf2,0x18(r21)\t#Get Bottom Y Coord\n\t\tfcmpo\tcr0,f1,f2\n\t\tblt\tEvent16JumpSideB_Jump\n\n\t\tEvent16JumpSideB_ChanceToJump:\n\t\tli\tr3,20\t\t#1 in 4 Chance\n\t\tbranchl\tr12,HSD_Randi\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tEvent16JumpSideB_Jump\n\t\tb\tEvent16CheckToReset\n\n\t\tEvent16JumpSideB_Jump:\n\t\tli\tr3,0x800\n\t\tstw\tr3,0x1A88(r29)\n\t\t#Advance to Next State\n\t\tli\tr3,0x0\n\t\tstb\tr3,0x9(r31)\n\t\tb\tEvent16CheckToReset\n\n\t#*************************************************#\n\n\t\tEvent16SSJumpSideB:\n\t\t#Hold Down B\n\t\t#Be above bottom most coord, Check if next frame will be out of Y range\n\t\t#Be in ledge Y range, Check if next frame will be out of Y range\n\n\t\t#Always Hold Down B\n\t\tli\tr3,-127\n\t\tstb\tr3,0x1A8D(r29)\n\t\tli\tr3,0x200\n\t\tstw\tr3,0x1A88(r29)\n\n\t\t#Wait Until in Shine Loop\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x16E\n\t\tbne\tEvent16CheckToReset\n\n\t\t#Check If Above Bottom-most\n\t\tlfs\tf1,0xB4(r29)\t#Get Next Frames Y Coord\n\t\tlfs\tf2,0x84(r29)\n\t\tfadds\tf1,f1,f2\n\t\tlfs\tf2,0x18(r21)\t#Get Bottom Y Coord\n\t\tfcmpo\tcr0,f1,f2\n\t\tblt\tEvent16SSJumpSideB_Jump\n\n\t\tEvent16SSJumpSideB_ChanceToJump:\n\t\tli\tr3,15\t\t#1 in 6 Chance\n\t\tbranchl\tr12,HSD_Randi\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tEvent16SSJumpSideB_Jump\n\t\tb\tEvent16CheckToReset\n\n\t\tEvent16SSJumpSideB_Jump:\n\t\tli\tr3,0x800\n\t\tstw\tr3,0x1A88(r29)\n\t\t#Advance to Next State\n\t\tli\tr3,0x0\n\t\tstb\tr3,0x9(r31)\n\t\tb\tEvent16CheckToReset\n\n\t#*************************************************#\n\n\t\tEvent16SideBThink:\n\n\t\tb\tEvent16CheckToReset\n\n\t#*************************************************#\n\n\t\t#Check To Reset\n\t\tEvent16CheckToReset:\n\t\t\tlwz\tr3,0xC(r31)\t\t#Get Timer\n\t\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\t\tble\tEvent16ThinkExit\n\t\t#Dec Timer\n\t\t\tsubi\tr3,r3,0x1\n\t\t\tstw\tr3,0xC(r31)\t\t#store timer\n\t\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\t\tbne\tEvent16ThinkExit\t#Exit If Not\n\t\tEvent16RestoreState:\n\t\t#Restore State\n\t\t\tmr\tr3,r31\n\t\t\tbl\tSaveState_Load\n\t\t#Reset Timer\n\t\t\tli\tr3,60\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tli\tr4,0\n\t\t\tsub\tr3,r4,r3\n\t\t\tstw\tr3,0x4(r31)\n\t\t\tli\tr3,0x0\n\t\t\tstb\tr3,0x8(r31)\n\n\t\tEvent16ThinkExit:\n\t\trestore\n\t\tblr\n\n#################################\n\nEvent16_Floats:\nblrl\n.long 0xC28C0000\t\t#P1 X Position\n.long 0xc2982e6c \t#P2 X Position\n.long 0x38d1b717  #P1 Y Position\n.long 0x38d1b717\t\t#FD Floor Y Coord\n.long 0x40A00000\t\t#Top Most Y Value = -5\n.long 0xC1700000\t #Bottom-most Y Value = -15\n.long 0xC25C0000\t\t#Shine Stall Bottom Most Coord\n\n#################################\n\nEvent16CheckIfLineUpWithLedge:\n#-1 = Not In Any Range Yet\n#0 = In Range This And Next Frame\n#1 = In Range This but NOT Next Frame\n\n#Check If In Range This Frame\nlfs\tf1,0xB4(r29)\t#Get Y Coord\nlfs\tf2,0x10(r21)\nfcmpo\tcr0,f1,f2\nbgt\tEvent16CheckIfLineUpWithLedge_NotInRange\nlfs\tf2,0x14(r21)\nfcmpo\tcr0,f1,f2\nblt\tEvent16CheckIfLineUpWithLedge_NotInRange\n\nEvent16CheckIfLineUpWithLedge_CheckNextFrame:\n#Check If Out Of Range Next Range\nlfs\tf1,0xB4(r29)\t#Get Y Coord\nlfs\tf2,0x84(r29)\t#Get Y Vel\nfadds\tf1,f1,f2\t    #Get Next Frames Position\n#Check If Will Be Above Ledge Next Frame\nlfs\tf2,0x10(r21)\nfcmpo\tcr0,f1,f2\nbgt\tEvent16CheckIfLineUpWithLedge_OutOfRangeNextFrame\nlfs\tf2,0x10(r21)\n#Check If Will Be Below Ledge Next Frame\nlfs\tf2,0x14(r21)\nfcmpo\tcr0,f1,f2\nblt\tEvent16CheckIfLineUpWithLedge_OutOfRangeNextFrame\nb\tEvent16CheckIfLineUpWithLedge_InRangeThisAndNextFrame\n\nEvent16CheckIfLineUpWithLedge_NotInRange:\nli\tr3,-1\nb\tEvent16CheckIfLineUpWithLedge_Exit\nEvent16CheckIfLineUpWithLedge_InRangeThisAndNextFrame:\nli\tr3,0x0\nb\tEvent16CheckIfLineUpWithLedge_Exit\nEvent16CheckIfLineUpWithLedge_OutOfRangeNextFrame:\nli\tr3,0x1\n\nEvent16CheckIfLineUpWithLedge_Exit:\nblr\n\n#################################\n\n\nEvent16LoadExit:\nrestore\nblr\n\n\n*/\n#endregion\n\n#region Scrapped Dash Dance Code\n/*\n#########################\n## Shield Drop HIJACK INFO ##\n#########################\n\nShieldDrop:\n#STORE STAGE\nli\tr3,0x20\nsth\tr3,0xE(r26)\n\n#STORE CPU\nlwz\tr4,0x0(r29)\nbl\tP2Struct\nmflr\tr3\nstw\tr3,0x18(r4)\t\t#p2 pointer\nli\tr5,0x2\t\t#fox ext ID\nstb\tr5,0x0(r3)\t\t#make fox p2\nli\tr5,0x1\t\t#make CPU controlled\nstb\tr5,0x1(r3)\n\n#SPAWN 2 PLAYERS\nli\tr3,0x40\nstb\tr3,0x1(r4)\n\n\n#STORE THINK FUNCTION\nbl\tShieldDropLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Shield Drop LOAD FUNCT ##\n\t########################\n\tShieldDropLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tShieldDropThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n\tbl\tCreateEventThinkFunction\n\n\tb\tShieldDropLoadExit\n\n\n\t\t#########################\n\t\t## Shield Drop THINK FUNCT ##\n\t\t#########################\n\n\n\t\tShieldDropThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tr31,0x2c(r3)\t\t\t#backup data pointer in r31\n\n\t\t#Get P2\n\t\tli\t\tr3,0x1\n\t\tbranchl\t\tr12,PlayerBlock_LoadMainCharDataOffset\t\t\t#get player block\n\t\tmr\t\tr30,r3\t\t\t#player block in r30\n\t\tlwz\t\tr29,0x2c(r30)\t\t\t#player data in r29\n\n\t\t#Get P1\n\t\tli\t\tr3,0x0\n\t\tbranchl\t\tr12,PlayerBlock_LoadMainCharDataOffset\t\t\t#get player block\n\t\tmr\t\tr28,r3\t\t\t#player block in r28\n\t\tlwz\t\tr27,0x2c(r28)\t\t\t#player data in r27\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\n\t\t#ON FIRST FRAME\n\t\tlbz\tr3,0x0(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tShieldDropThinkMain\n\n\t\t\tlbz\tr3,0x221D(r29)\n\t\t\trlwinm.\tr3,r3,0,28,28\n\t\t\tbne\tShieldDropThinkExit\n\n\t\t\t#Set Frame 1 As Over\n\t\t\tli\t\tr3,0x1\n\t\t\tstb\t\tr3,0x0(r31)\n\t\t\tbl\t\tShieldDrop_InitializePositions\n\t\t\tmr\t\tr3,r31\n\t\t\tbl\t\tSaveState_Save\n\n\n\n\t\tShieldDropThinkMain:\n\t\tbl\tGiveFullShields\n\n\t\tShieldDropThinkSequence:\n\t\t#Get Floats and Frame Info\n\t\tbl\tShieldDropFloats\n\t\tmflr\tr21\t\t#Get Floats\n\t\tlwz\tr20,0x4(r31)\t\t#Get State\n\t\tlfs\tf1,0x894(r29)\n\t\tfctiwz\tf1,f1\n\t\tstfd\tf1,0xF0(sp)\n\t\tlwz\tr24,0xF4(sp)\t\t#Frame Number in r24\n\n\t\t#Get Distance and Direction\n\t\t#f1 = distance\n\t\t#r22= towards direction\n\t\t#r23= away direction\n\t\tlfs\tf1,0xB0(r27)\n\t\tlfs\tf2,0xB0(r29)\n\t\tfsubs\tf1,f1,f2\n\t\tlfs\tf0, -0x6768 (rtoc)\n\t\tfcmpo\tcr0,f1,f0\n\t\tbgt\tShieldDropRight\n\t\tShieldDropLeft:\n\t\tli\tr22,-127\n\t\tli\tr23,127\n\t\tb\tShieldDropCheckState\n\t\tShieldDropRight:\n\t\tli\tr22,127\n\t\tli\tr23,-127\n\n\t\tShieldDropCheckState:\n\t\t#When DDing, Move In Facing Direction\n\t\tcmpwi\tr20,0x1\n\t\tbne\tShieldDrop_SkipHoldForward\n\t\tlfs\tf2,0x2C(r29)\n\t\tfctiwz\tf2,f2\n\t\tstfd\tf2,0xF0(sp)\n\t\tlwz\tr3,0xF4(sp)\t\t#Facing direction as int\n\t\tmulli\tr3,r3,127\n\t\tstb\tr3,0x1A8C(r29)\t\t#Move Towards\n\n\t\tShieldDrop_SkipHoldForward:\n\t\tfabs\tf1,f1\t\t#abs distance\n\t\tcmpwi\tr20,0x0\n\t\tbeq\tShieldDropDashDanceStart\n\t\tcmpwi\tr20,0x1\n\t\tbeq\tShieldDropDashDanceThink\n\t\tcmpwi\tr20,0x2\n\t\tbeq\tShieldDropJumpThink\n\t\tcmpwi\tr20,0x3\n\t\tbeq\tShieldDropLCancelThink\n\t\tcmpwi\tr20,0x4\n\t\tbeq\tShieldDropInvincibleThink\n\n\n\t\tShieldDropDashDanceStart:\n\t\t\tstb\tr23,0x1A8C(r29)\t\t#Move Away\n\t\t\tli\tr3,0x1\t\t #Enter DDThink\n\t\t\tstw\tr3,0x4(r31)\n\t\t\tb\tShieldDropThinkExit\n\n\t\tShieldDropDashDanceThink:\n\t\t\t#Check If Too Close\n\t\t\tShieldDropDashDanceThink_CheckIfTooClose:\n\t\t\tlfs\tf2,0x0(r21)\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tbgt\tShieldDropDashDanceThink_CheckIfTooFar\n\t\t\tstb\tr23,0x1A8C(r29)\t\t#Move Away\n\t\t\tb\tShieldDropThinkExit\n\t\t\tShieldDropDashDanceThink_CheckIfTooFar:\n\t\t\tlfs\tf2,0x4(r21)\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tblt\tShieldDropDashDanceThink_CheckToAttack\n\t\t\tstb\tr22,0x1A8C(r29)\t\t#Move Towards\n\t\t\tb\tShieldDropThinkExit\n\n\t\t\tShieldDropDashDanceThink_CheckToAttack:\n\t\t\tlfs\tf2,0x8(r21)\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tbgt\tShieldDropDashDanceThink_CheckToChangeDirection\n\t\t\tShieldDropDashDanceThink_CheckIfFacingOpponent:\n\t\t\tlfs\tf2,0x2C(r29)\n\t\t\tfctiwz\tf2,f2\n\t\t\tstfd\tf2,0xF0(sp)\n\t\t\tlwz\tr3,0xF4(sp)\t\t#Facing direction as int\n\t\t\tcmpwi\tr3,0x0\n\t\t\tblt\tShieldDropDashDanceThink_FacingLeft\n\t\t\tShieldDropDashDanceThink_FacingRight:\n\t\t\tcmpwi\tr22,0x0\n\t\t\tbgt\tShieldDropDashDanceThink_FacingOpponent\n\t\t\tb\tShieldDropDashDanceThink_NotFacingOpponent\n\t\t\tShieldDropDashDanceThink_FacingLeft:\n\t\t\tcmpwi\tr22,0x0\n\t\t\tblt\tShieldDropDashDanceThink_FacingOpponent\n\t\t\tb\tShieldDropDashDanceThink_NotFacingOpponent\n\t\t\tShieldDropDashDanceThink_FacingOpponent:\n\t\t\tli\tr3,0x1\n\t\t\tb\t0x8\n\t\t\tShieldDropDashDanceThink_NotFacingOpponent:\n\t\t\tli\tr3,0x0\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tShieldDropDashDanceThink_CheckToChangeDirection\n\t\t\t#RNG Chance To Attack\n\t\t\tli\tr3,20\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tShieldDropDashDanceThink_CheckToChangeDirection\n\t\t\tli\tr3,0x400\t\t#X Button\n\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\tli\tr3,0x2\t\t#JumpThink\n\t\t\tstw\tr3,0x4(r31)\n\t\t\tb\tShieldDropThinkExit\n\n\n\t\tShieldDropDashDanceThink_CheckToChangeDirection:\n\t\t#Move if in Wait\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xE\n\t\tbeq\tShieldDropDashDanceThink_ChangeDirection\n\t\t#At least frame 3 of dash\n\t\tcmpwi\tr24,6\n\t\tblt\tShieldDropThinkExit\n\t\tcmpwi\tr24,11\n\t\tbge\tShieldDropDashDanceThink_ChangeDirection\n\t\t#RNG Chance To ChangeDirection\n\t\tli\tr3,7\n\t\tbranchl\tr12,HSD_Randi\n\t\tcmpwi\tr3,0x0\n\t\tbne\tShieldDropThinkExit\n\t\tShieldDropDashDanceThink_ChangeDirection:\n\t\tlfs\tf2,0x2C(r29)\n\t\tfctiwz\tf2,f2\n\t\tstfd\tf2,0xF0(sp)\n\t\tlwz\tr3,0xF4(sp)\t\t#Facing direction as int\n\t\tmulli\tr3,r3,127\n\t\tmulli\tr3,r3,-1\n\t\tstb\tr3,0x1A8C(r29)\t\t#Move Away\n\t\tb\tShieldDropThinkExit\n\n\t\tShieldDropJumpThink:\n\t\tlwz\tr3,0xE0(r29)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tShieldDropThinkExit\n\t\tli\tr3,0x100\t\t#A Button\n\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\tli\tr3,0x3\t\t#LCancelThink\n\t\tstw\tr3,0x4(r31)\n\t\tb\tShieldDropThinkExit\n\n\t\tShieldDropLCancelThink:\n\t\tShieldDropLCancelInputFF:\n\t\tlfs\tf2,0x84(r29)\n\t\tlfs\tf0, -0x76B0 (rtoc)\n\t\tfcmpo\tcr0,f2,f0\n\t\tbge\tShieldDropThinkExit\n\t\t#Input Down to FF\n\t\tli\tr3,-127\n\t\tstb\tr3,0x1A8D(r29)\t\t#Ananlog Y\n\t\t#Check If Under 5Mm Above Ground\n\t\tlfs\tf2,0xB4(r29)\n\t\tlfs\tf0,0xC(r21)\n\t\tfcmpo\tcr0,f2,f0\n\t\tbgt\tShieldDropThinkExit\n\t\tli\tr3,0xC0\t\t#Hit L\n\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t#Enter InvincibleThink + Init Counter\n\t\tli\tr3,0x4\t\t#State\n\t\tstw\tr3,0x4(r31)\n\t\tli\tr3,60\n\t\tstw\tr3,0x8(r31)\t\t#Counter\n\t\tb\tShieldDropThinkExit\n\n\t\tShieldDropInvincibleThink:\n\t\t#Dec Counter And Check To Restore\n\t\tlwz\tr3,0x8(r31)\n\t\tsubi\tr3,r3,0x1\n\t\tstw\tr3,0x8(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbgt\tShieldDrop_CheckToMakeInvincible\n\t\t#Reset State ID\n\t\tli\tr3,0x0\n\t\tstw\tr3,0x4(r31)\n\t\t#Restore Savestate\n\t\tmr\tr3,r31\n\t\tbl\tSaveState_Load\n\t\tb\tShieldDropThinkExit\n\t\tShieldDrop_CheckToMakeInvincible:\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xE\n\t\t#bne\tShieldDropThinkExit\n\t\t#Make Invincible\n\t\t#mr\tr3,r30\n\t\t#li\tr4,0x2\n\t\t#branchl\tr12,ApplyInvincibility\n\t\t#b\tShieldDropThinkExit\n\n\n\t\t#Multishine\n\t\tmr\tr3,r29\n\t\tbl\tCPUActions_MultiShine\n\t\tb\tShieldDropThinkExit\n\n\t\tShieldDropThinkExit:\n\t\trestore\n\t\tblr\n\n\n##########################\n\nShieldDropFloats:\nblrl\n.long 0x41A00000 #no closer than this\n.long 0x42180000 #no further than this\n.long 0x41C80000 #at least this close to jump\n.long 0x40000000 #below this Y coord to L Cancel\n.long 0xC02CCCCD\t\t#P1 X Position\n.long 0x4144CCCD\t\t#P2 X Position\n\n#################################\n\nShieldDrop_InitializePositions:\nbackup\n\n#P1 @ -2.7\n#P2 @ 12.3\n\n#Get Floats\nbl\tShieldDropFloats\nmflr\tr20\n\n#Move P1\nmr\tr3,r28\nbranchl\tr12,0x8008a2bc\t\t#Enter Wait\nlfs\tf1,0x10(r20)\nstfs\tf1,0xB0(r27)\nmr\tr3,r28\nbl  UpdatePosition\n\n#Move P2\nmr\tr3,r30\nbranchl\tr12,0x8008a2bc\t\t#Enter Wait\nlfs\tf1,0x14(r20)\nstfs\tf1,0xB0(r29)\nmr\tr3,r30\nbl  UpdatePosition\n\nrestore\nblr\n\n###################################\n\nShieldDropLoadExit:\nrestore\nblr\n\n*/\n#endregion\n\n#region Event Template\n/*\n\n#########################\n## Eggs-ercise HIJACK INFO ##\n#########################\n\nEggs:\n#STORE THINK FUNCTION\nbl\tEggsLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Eggs-ercise LOAD FUNCT ##\n\t########################\n\tEggsLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tEggsThink\n\tmflr\tr3\n\tbl\tCreateEventThinkFunction\n\n\tb\tEggsLoadExit\n\n\n\t\t#########################\n\t\t## Eggs-ercise THINK FUNCT ##\n\t\t#########################\n\n\n\t\tEggsThink:\n\t\tblrl\n\t\tbackup\n\n\n\n\t\tEggsThinkExit:\n\t\trestore\n\t\tblr\n\n\nEggsLoadExit:\nrestore\nblr\n\n*/\n####################################################\n#endregion\n\n###############\n## P1 STRUCT ##\n###############\nP1Struct:\nblrl\n\n.long 0x01000200 #external char, player type, stocks, costume\n.long 0xff000400 #spawn point, subcolor,team,voice pitch\n.long 0x00040700 #player flag\n.long 0x00000000 #level and starting %\n.long 0x3f800000 #attk ratio\n.long 0x3f800000 #def ratio\n.long 0x3f800000 #model scale\n\n###############\n## P2 STRUCT ##\n###############\nP2Struct:\nblrl\n\n.long 0x01010200 #external char, player type, stocks, costume\n.long 0xff000400 #spawn point, subcolor,team,voice pitch\n.long 0x00040700 #player flag\n.long 0x00000000 #level and starting %\n.long 0x3f800000 #attk ratio\n.long 0x3f800000 #def ratio\n.long 0x3f800000 #model scale\n\n\n###########################\n## Create Think Function ##\n###########################\nCreateEventThinkFunction:\n\n#Registers\n.set WindowOptionCount,31\n.set ASCIIStruct,30\n.set EventGObj,29\n.set EventData,28\n.set MenuGObj,27\n.set MenuData,26\n.set Priority,25\n.set Function,24\n\nbackup\n\nmr\tFunction,r3\nmr\tPriority,r4\nmr  WindowOptionCount,r5\nmr  ASCIIStruct,r6\n\n########################\n## Create Event Think ##\n########################\n\n#Create GObj\n  li\tr3,6\t\t#GObj Type\n  li\tr4,7\t\t#On-Pause Function\n  li\tr5,80\n  branchl\tr12,GObj_Create\n\n#Backup Allocation\n  mr\tEventGObj,r3\n\n#Schedule Task\n  mr\tr4,Function\n  mr\tr5,Priority\n  branchl\tr12,GObj_AddProc\n\n#Give Task Some Data Space\n  li\tr3,EventData_DataSize\t\t#50 bytes of space\n  branchl\tr12,HSD_MemAlloc\t\t#HSD_MemAlloc\n  mr\tEventData,r3\n\n#Initalize GObj\n  mr\tr6,r3\n  mr\tr3,EventGObj\t\t#task space\n  li\tr4,0x0\t\t#typedef\n  load\tr5,HSD_Free\t\t#destructor (HSD_Free)\n  branchl\tr12,GObj_AddUserData\t\t#Create Data Block\n\n#Zero Dataspace\n  mr\tr3,EventData\n  li\tr4,EventData_DataSize\n  branchl\tr12,ZeroAreaLength\t\t#zero length\n\n##############################\n## Create Option Menu Think ##\n##############################\n\n#Check if Option Menu is enabled for this event\n  cmpwi WindowOptionCount,0\n  beq CreateEventThinkFunction_NoOptionMenu\n\n#Create GObj\n  li\tr3,6\t\t#GObj Type\n  li\tr4,0\t\t#On-Pause Function\n  li\tr5,80\n  branchl\tr12,GObj_Create\n\n#Backup Allocation\n  mr\tMenuGObj,r3\n\n#Schedule Task\n  bl  OptionMenuThink\n  mflr r4\n  li\tr5,22          #Last Function to Run\n  branchl\tr12,GObj_AddProc\n\n#Give Task Some Data Space\n  li\tr3,MenuData_DataSize\t\t#50 bytes of space\n  branchl\tr12,HSD_MemAlloc\t\t#HSD_MemAlloc\n  mr\tMenuData,r3\n\n#Initalize GObj\n  mr\tr6,MenuData\n  mr\tr3,MenuGObj\t\t#task space\n  li\tr4,0x0\t    \t#typedef\n  load\tr5,HSD_Free\t\t#destructor (HSD_Free)\n  branchl\tr12,GObj_AddUserData\t\t#Create Data Block\n\n#Zero Dataspace\n  mr\tr3,MenuData\n  li\tr4,MenuData_DataSize\n  branchl\tr12,ZeroAreaLength\t\t#zero length\n\n#Store Option Menu info to Dataspace\n  stw WindowOptionCount,MenuData_WindowOptionCountPointer(MenuData)\n  stw ASCIIStruct,MenuData_ASCIIStructPointer(MenuData)\n\n#Store Pointers to Each Other\n  stw MenuData,EventData_MenuDataPointer(EventData)\n  stw EventData,MenuData_EventDataPointer(MenuData)\nCreateEventThinkFunction_NoOptionMenu:\n\n#Disable Hazards\n\tbl\tDisableHazards\n\nCreateEventThinkFunction_Exit:\nrestore\nblr\n\n####################################\n## Create Option Menu When Paused ##\n####################################\n\nOptionMenuThink:\nblrl\n\n.set MenuData,31\n\nbackup\n\n#Load Data Pointer\n  lwz MenuData,0x2C(r3)\n\n#Check If Paused\n  li  r3,1\n  branchl r12,DevelopMode_FrameAdvanceCheck\n  cmpwi r3,0x2\n  bne OptionMenuThink_Exit\n\n#Run OptionThink Code\nOptionMenuThink_CheckInputs:\n  addi r3,MenuData,MenuData_OptionMenuMemory\n  lwz r4,MenuData_WindowOptionCountPointer(MenuData)\n  lwz r5,MenuData_ASCIIStructPointer(MenuData)\n  bl\tOptionWindow\n\n#Store Modified Option Bool\n  cmpwi r3,0\n  beq OptionMenuThink_Exit\n  addi r5,MenuData,MenuData_OptionMenuToggled\n  stbx r3,r4,r5\n\nOptionMenuThink_Exit:\nrestore\nblr\n\n##########################\n## Clear Option Toggled ##\n##########################\n\nClearToggledOptions:\n\n#in\n#r3 = Menu Data\n\n#Get Amount of Options\n  lwz r4,MenuData_WindowOptionCountPointer(r3)\n  lbz r4,0x0(r4)\n\n#Loop Through All Data\n  addi r3,r3,MenuData_OptionMenuToggled\n  li  r5,0\n\nClearToggledOptions_Loop:\n  stbx r5,r3,r4     #Zero Byte\n  subi r4,r4,1\n  cmpwi r4,0\n  bge ClearToggledOptions_Loop\n\nClearToggledOptions_Exit:\n  blr\n\n######################\n## Save States Main ##\n######################\n\n\n#0x0 -> 0x23EC = player block\n#0x23EC -> 0x24EC = Static Block\n#0x24EC = Camera Flag\n\n\n\n\n\n\n################################\n## Save State Quick Functions ##\n################################\n\nSaveState_Save:\n.set REG_SaveStruct,31\n.set REG_PlayerTotal,30\n.set REG_LoopCount,29\n.set REG_isSubchar,23\n.set REG_Backup,28\n.set REG_SpawnedOrder,22\n.set REG_PlayerGObj,25\n.set REG_PlayerData,26\n.set REG_PlayerDataSize,24\n.set REG_PlayerData_Backup,27\n\n\tbackup\n\n#Backup Task Data\n\tmr\tREG_SaveStruct,r3\n#Backup \"skip failsafe\" bool\n\tmr\tr20,r4\n\n#Count Players in Match\n\tbranchl\tr3,0x8016b558\n\n#Move Player Number to REG_PlayerTotal\n\tmr\tREG_PlayerTotal,r3\n\n#Check to run failsafe code\n\tcmpwi r20,0x0\n\tbne SaveState_SaveLoopInit\n\nSaveState_OnDeathCheck:\n#Mini loop to make sure no players have on-death functions\n\tli\tREG_LoopCount,0x0\t\t#player ID\n\tli\tREG_isSubchar,0x0\t\t#main/sub char bool\nSaveState_OnDeathCheckLoop:\n#Get Proper Player Data\n\tmr\t\tr3,REG_LoopCount\n\tmr\t\tr4,REG_isSubchar\n\tbl\t\tSaveState_GetPlayerDataPointer  #returns player slot,player pointer and player data\n\tcmpwi\t\tr3,0xFF\t\t\t\t                #check if player didnt exist\n\tbeq\t\tSaveState_OnDeathCheckInc\t\t\t\t#move on with loop\n#Check for on-death function\n\tlwz\t\tr3,0x21E0(r5)\n  cmpwi r3,0x0\n  bne SaveState_OnDeathCheckExit\n\tlwz\t\tr3,0x21E4(r5)\n  cmpwi r3,0x0\n  bne SaveState_OnDeathCheckExit\n\tlwz\t\tr3,0x21E8(r5)\n  cmpwi r3,0x0\n  bne SaveState_OnDeathCheckExit\n#Check if holding an item\n\tlwz\t\tr3,0x1974(r5)\n  cmpwi r3,0x0\n  bne SaveState_OnDeathCheckExit\n\tlwz\t\tr3,0x1978(r5)\n  cmpwi r3,0x0\n  bne SaveState_OnDeathCheckExit\n#Check for fighter accessory\n\tlwz\t\tr3,0x20A0(r5)\n  cmpwi r3,0x0\n  bne SaveState_OnDeathCheckExit\n  b SaveState_OnDeathCheckInc\n\nSaveState_OnDeathCheckExit:\n#PLay Error SFX\n  li\tr3,0xAF\n  bl  PlaySFX\n  li\tr3,0xAF\n  bl  PlaySFX\n  b SaveState_SaveExit\n\nSaveState_OnDeathCheckInc:\n#Check For Subchar Before Looping\n\tcmpwi\t\tREG_isSubchar,0x1\n\tbeq\t\tSaveState_OnDeathCheck_ToggleSubCharOff\n\tli\t\tREG_isSubchar,0x1\n\tb\t\tSaveState_OnDeathCheckLoop\nSaveState_OnDeathCheck_ToggleSubCharOff:\n\tli\t\tREG_isSubchar,0x0\n\taddi\t\tREG_LoopCount,REG_LoopCount,0x1\n\tcmpw\t\tREG_LoopCount,REG_PlayerTotal\n\tblt\t\tSaveState_OnDeathCheckLoop\n\nSaveState_SaveLoopInit:\n\t#Init Save Loop\n\tli\tREG_LoopCount,0x0\t\t#player ID\n\tli\tREG_isSubchar,0x0\t\t#main/sub char bool\n\n\t\tSaveState_SaveLoop:\n\t\t#Get This Player's Backup Pointer in REG_Backup\n\t\tmulli\t\tr4,REG_LoopCount,0x8\t\t#8 bytes per player pointer\n\t\tadd\t\tREG_Backup,r4,REG_SaveStruct\t\t#REG_Backup contains this players block backup\n\n\t\t#Check If Backup Exists\n\t\tcmpwi\t\tREG_isSubchar,0x0\n\t\tbeq\t\tSaveState_Save_MainChar\n\t\tSaveState_Save_SubChar:\n\t\tlwz \t\tr3,0x4(REG_Backup)\t\t#get pointer to backup if it exists\n\t\tb\t\tSaveState_Save_CheckIfExists\n\t\tSaveState_Save_MainChar:\n\t\tlwz \t\tr3,0x0(REG_Backup)\t\t#get pointer to backup if it exists\n\t\tSaveState_Save_CheckIfExists:\n\t\tcmpwi\t\tr3,0x0\n\t\tbeq\t\tSaveState_SaveStart\n\n\t\t#Remove Old Backup (HSD_Free)\n\t\tbranchl\t\tr12,HSD_Free\n\n\n\n\t\tSaveState_SaveStart:\n\n\t\t#Get Proper Player Data\n\t\tmr\t\tr3,REG_LoopCount\n\t\tmr\t\tr4,REG_isSubchar\n\t\tbl\t\tSaveState_GetPlayerDataPointer\t\t#returns player slot,player pointer and player data\n\t\tcmpwi\t\tr3,0xFF\t\t\t\t#check if player didnt exist\n\t\tbeq\t\tSaveState_SaveLoopInc\t\t\t\t#move on with loop\n\t\tmr\t\tREG_SpawnedOrder,r3\t\t\t\t#REG_SpawnedOrder contains actual player slot\n\t\tmr\t\tREG_PlayerData,r5\t\t\t\t#REG_PlayerData contains real player block\n\n\t\t#Get Player Data Length\n\t\tSaveState_Save_GetPlayerBlockLength:\n\t\tload\t\tr3,0x80458fd0\n\t\tlwz    \tREG_PlayerDataSize,0x20(r3)\t\t\t#get player block length in REG_PlayerDataSize\n\t\taddi\t\tr3,REG_PlayerDataSize,0x100\t\t\t#add static block length\n\t\taddi\t\tr3,r3,0x10\t\t\t#add additional storage\n\t\tbranchl\t\tr12,HSD_MemAlloc\t\t\t#HSD_MemAlloc\n\n\t\t#Store Pointer To Task Struct\n\t\tcmpwi\t\tREG_isSubchar,0x0\n\t\tbne\t\tSavestate_Save_StoreBackupSubChar\n\t\tstw\t\tr3,0x0(REG_Backup)\n\t\tb\t\tSavestate_Save_StoreBackupEnd\n\t\tSavestate_Save_StoreBackupSubChar:\n\t\tstw\t\tr3,0x4(REG_Backup)\n\t\tSavestate_Save_StoreBackupEnd:\n\t\tmr\t\tREG_PlayerData_Backup,r3\t\t\t\t#REG_PlayerData_Backup contains playerblock backup\n\n\t\t#Copy Player Block to Backup\n\t\tmr\t\tr3,REG_PlayerData_Backup\t\t\t#r3 = destination to copy to\n\t\tmr\t\tr4,REG_PlayerData\t\t\t#r4 = source\n\t\tmr \t\tr5,REG_PlayerDataSize\t\t\t#r5 = playerblock length\n\t\tbranchl\t\tr12,memcpy\t\t\t#mempcy\n\n\n\t\t#Copy Static Block to Backup\n\t\t\tcmpwi REG_isSubchar,0x0\t\t\t\t\t#unless this is a subcharacter\n\t\t\tbne\tSavestate_Save_SkipStaticBlockBackup\n\t\t\tadd\t\tr3,REG_PlayerDataSize,REG_PlayerData_Backup\t\t\t#get end of playerblock in r4\n\t\t\tload\t\tr4,0x80453080\t\t\t#get static block in r4\n\t\t\tli\t\tr5,0xE90\n\t\t\tmullw\t\tr5,r5,REG_SpawnedOrder\n\t\t\tadd\t\tr4,r4,r5\n\t\t\tli\t\tr5,0x100\t\t\t#only copying the first 100 bytes\n\t\t\tbranchl\t\tr12,memcpy\t\t\t#mempcy\n\t\tSavestate_Save_SkipStaticBlockBackup:\n\n\t\t#Save Camera Flag\n\t\tlwz\t\tr3,0x890(REG_PlayerData)\n\t\tlwz\t\tr3,0x8(r3)\n\t\tadd\t\tr4,REG_PlayerDataSize,REG_PlayerData_Backup\t\t#get end of player block in r4\n\t\taddi\t\tr4,r4,0x100\t\t#get end of static block\n\t\tstw\t\tr3,0x0(r4)\t\t#store to end of block\n\n\t\tSaveState_SaveLoopInc:\n\t\t#Check For Subchar Before Looping\n\t\tcmpwi\t\tREG_isSubchar,0x1\n\t\tbeq\t\tSaveState_SaveLoopInc_ToggleSubCharOff\n\t\tli\t\tREG_isSubchar,0x1\n\t\tb\t\tSaveState_SaveLoop\n\n\t\tSaveState_SaveLoopInc_ToggleSubCharOff:\n\t\tli\t\tREG_isSubchar,0x0\n\t\taddi\t\tREG_LoopCount,REG_LoopCount,0x1\n\t\tcmpw\t\tREG_LoopCount,REG_PlayerTotal\n\t\tblt\t\tSaveState_SaveLoop\n\nSaveState_SaveExit:\n\trestore\n\tblr\n\nSaveState_Load:\n.set REG_SaveStruct,31\n.set REG_PlayerTotal,30\n.set REG_LoopCount,29\n.set REG_isSubchar,23\n.set REG_Backup,28\n.set REG_SpawnedOrder,22\n.set REG_PlayerGObj,25\n.set REG_PlayerData,26\n.set REG_PlayerDataSize,24\n.set REG_PlayerData_Backup,27\n\n\n\tbackup\n\n\tmr\tREG_SaveStruct,r3\n\n\t#Count Players in Match\n\tbranchl\tr3,0x8016b558\n\n\t#Move Player Number to REG_PlayerTotal\n\tmr\tREG_PlayerTotal,r3\n\n\t#Restore Camera Info Here\n\n\n\t#Init Load Loop\n\tli\tREG_LoopCount,0x0\t\t#player count\n\tli\tREG_isSubchar,0x0\t\t#main/subchar bool\n\n\t\tSaveState_LoadLoop:\n\t\t#Get This Player's Backup Pointer in REG_Backup\n\t\tmulli\t\tr4,REG_LoopCount,0x8\t\t#8 bytes per player pointer\n\t\tadd\t\tREG_Backup,r4,REG_SaveStruct\t\t#REG_Backup contains this players block backup\n\n\t\t#Check If Backup Exists\n\t\tcmpwi\t\tREG_isSubchar,0x0\n\t\tbeq\t\tSaveState_Load_MainChar\n\t\tSaveState_Load_SubChar:\n\t\tlwz \t\tr3,0x4(REG_Backup)\t\t#get pointer to backup if it exists\n\t\tb\t\tSaveState_Load_CheckIfExists\n\t\tSaveState_Load_MainChar:\n\t\tlwz \t\tr3,0x0(REG_Backup)\t\t#get pointer to backup if it exists\n\t\tSaveState_Load_CheckIfExists:\n\t\tcmpwi\t\tr3,0x0\n\t\tbeq\t\tSaveState_LoadLoopInc\n\n\n\t\tSaveState_LoadStart:\n\n\t\t#Get Proper Player Data\n\t\tmr\t\tr3,REG_LoopCount\n\t\tmr\t\tr4,REG_isSubchar\n\t\tbl\t\tSaveState_GetPlayerDataPointer\t\t#returns player slot,player pointer and player data\n\t\tcmpwi\t\tr3,0xFF\t\t\t\t#check if player didnt exist\n\t\tbeq\t\tSaveState_LoadLoopInc\t\t\t\t#move on with loop\n\t\tmr\t\tREG_SpawnedOrder,r3\t\t\t\t#REG_SpawnedOrder contains actual player slot\n\t\tmr\t\tREG_PlayerGObj,r4\t\t\t\t#REG_PlayerGObj contains external player\n\t\tmr\t\tREG_PlayerData,r5\t\t\t\t#REG_PlayerData contains real player block\n\n\t\t#Get Player Block Length in REG_PlayerDataSize\n\t\tSaveState_Load_GetPlayerBlockLength:\n\t\tload\t\tREG_PlayerDataSize,0x80458fd0\n\t\tlwz    \t\tREG_PlayerDataSize,0x20(REG_PlayerDataSize)\t\t#REG_PlayerDataSize = length\n\n\t\t#Get Pointer From Task Struct\n\t\tcmpwi\t\tREG_isSubchar,0x0\t\t#check if subcharacter\n\t\tbeq\t\tSavestate_Load_GetBackupMainChar\n\t\tSavestate_Load_GetBackupSubChar:\n\t\tlwz\t\tREG_PlayerData_Backup,0x4(REG_Backup)\t\t#REG_PlayerData_Backup contains playerblock backup\n\t\tb\t\tSavestate_Load_RestoreFacingDirection\n\t\tSavestate_Load_GetBackupMainChar:\n\t\tlwz\t\tREG_PlayerData_Backup,0x0(REG_Backup)\t\t#REG_PlayerData_Backup contains playerblock backup\n\n\t\t#Restore Facing Direction\n\t\tSavestate_Load_RestoreFacingDirection:\n\t\tlwz\t\tr3,0x2C(REG_PlayerData_Backup)\t\t#backed up Facing Direction\n\t\tstw\t\tr3,0x2C(REG_PlayerData)\n\n\t\t#Enter Into Sleep\n\t\tmr\t\tr3,REG_PlayerGObj\n\t\tli\t\tr4,0x0\n\t\tbranchl\t\tr12,AS_Sleep\n\n\t\t#Remove On Death Function Pointer\n\t\tli\t\tr3,0x0\n\t\tstw\t\tr3,0x21E4(REG_PlayerData)\n\t\tstw\t\tr3,0x21E8(REG_PlayerData)\n\n\t\t#Enter Into Backed Up State\n\t\tmr\t\tr3,REG_PlayerGObj\n\t\tlwz\t\tr4,0x10(REG_PlayerData_Backup)\t\t#backed up AS\n\t\tli\t\tr5,0x0\n\t\tli\t\tr6,0x0\n\t\tlfs\t\tf1,0x894(REG_PlayerData_Backup)\t\t#backed up Frame Number\n\t\tlfs\t\tf2,0x89C(REG_PlayerData_Backup)\t\t#backed up Frame Speed\n\t\tlfs\t\tf3,-0x7548 (rtoc)\n\t\t#lfs\t\tf3,0x8A4(REG_PlayerData_Backup)\t\t#backup up Blend Amount\n\t\tbranchl\t\tr12,ActionStateChange\t\t\t\t\t#ASC\n\n\t\t#Keep Previous Frame Buttons From Current Block\n\t\tlwz\t\tr3,0x620(REG_PlayerData)\n\t\tstw\t\tr3,0xD0(sp)\n\t\tlwz\t\tr3,0x624(REG_PlayerData)\n\t\tstw\t\tr3,0xD4(sp)\n\t\tlwz\t\tr3,0x65C(REG_PlayerData)\n\t\tstw\t\tr3,0xD8(sp)\n\n\t\t#Keep Collision Bubble Toggles\n\t\tlwz\t\tr3,0x21FC(REG_PlayerData)\n\t\tstw\t\tr3,0xDC(sp)\n\n\t\t#Copy PlayerBlock Backup to Current\n\t\tmr\t\tr3,REG_PlayerData\n\t\tmr\t\tr4,REG_PlayerData_Backup\n\t\tmr\t\tr5,REG_PlayerDataSize\n\t\tbranchl\t\tr12,memcpy\t#mempcy\n\n\t\t#Zero Blend\n\t\t#lfs\t f1,-0x7548 (rtoc)\n\t\t#stfs f1,0x8A4(REG_PlayerData)\n\n\t\t#Copy Static Block Backup to Current\n\t\t\tcmpwi REG_isSubchar,0\t\t\t\t\t\t\t\t\t#but not if subcharacter\n\t\t\tbne Savestate_Load_SkipStaticBlockRestore\n\t\t\tload\t\tr3,0x80453080\t\t\t#get static block in r3\n\t\t\tli\t\tr4,0xE90\n\t\t\tmullw\t\tr4,r4,REG_SpawnedOrder\n\t\t\tadd\t\tr3,r3,r4\n\t\t\tadd\t\tr4,REG_PlayerDataSize,REG_PlayerData_Backup\t\t\t#get end of block in r4\n\t\t\tli\t\tr5,0x100\t\t\t#length is 0x100\n\t\t\tbranchl\t\tr12,memcpy\t\t\t#mempcy\n\t\t\tSavestate_Load_SkipStaticBlockRestore:\n\n\t\t#Restore Previous Frame Buttons From Current Block\n\t\tlwz\t\tr3,0xD0(sp)\n\t\tstw\t\tr3,0x620(REG_PlayerData)\n\t\tstw\t\tr3,0x628(REG_PlayerData)\n\t\tlwz\t\tr3,0xD4(sp)\n\t\tstw\t\tr3,0x624(REG_PlayerData)\n\t\tstw\t\tr3,0x62C(REG_PlayerData)\n\t\tlwz\t\tr3,0xD8(sp)\n\t\tstw\t\tr3,0x65C(REG_PlayerData)\n\t\tstw\t\tr3,0x660(REG_PlayerData)\n\t\tstw\t\tr3,0x664(REG_PlayerData)\n\n\t\t#Restore Collision Bubble Toggles\n\t\tlwz\t\tr3,0xDC(sp)\n\t\tstw\t\tr3,0x21FC(REG_PlayerData)\n\n\t\t#Remove Cached Animation Pointer (This fixes the Fall Animation Bug)\n\t\tli\tr3,0x0\n\t\tstw\tr3,0x5A8(REG_PlayerData)\n\n    #Remove Respawn Platform JObj Pointer and Think Function\n    stw r3,0x20A0(REG_PlayerData)\n    stw r3,0x21B0(REG_PlayerData)\n\n    #Remove Held Item Pointer\n    stw r3,0x1974(REG_PlayerData)\n\n    #Update ECB Position\n\t\tmr\t\tr3,REG_PlayerGObj\n\t\tbl  UpdatePosition\n\n    #Stop Player's SFX\n    mr  r3,REG_PlayerData\n    branchl r12,SFX_StopAllCharacterSFX\n\n    #Stop Crowd SFX\n    branchl r12,SFXManager_StopSFXIfPlaying\n\n    #Remove GFX\n    mr  r3,REG_PlayerGObj\n    branchl\tr12,GFX_RemoveAll\n\n\t\t/* #Removing this, causes ground issues when restoring. instead im removing the OSReport call for the error\n\t\t#If Grounded, Change Ground Variable Back\n\t\tlwz\t\tr3,0xE0(REG_PlayerData)\n\t\tcmpwi\t\tr3,0x0\n\t\tbne\t\tSavestate_RestoreCameraFlag\n\t\tli\t\tr3,0x1\n\t\tstw\t\tr3,0x83C(REG_PlayerData)\n\t\t*/\n\n\t\t#Restore Camera Flag\n\t\tSavestate_RestoreCameraFlag:\n\t\tadd\t\tr3,REG_PlayerDataSize,REG_PlayerData_Backup\t\t#get end of block in r4\n\t\taddi\t\tr3,r3,0x100\t\t#static block length = 0x100\n\t\tlwz\t\tr3,0x0(r3)\t\t#get flag\n\t\tlwz\t\tr4,0x890(REG_PlayerData)\n\t\tstw\t\tr3,0x8(r4)\n\n    #Update Camera Box Position\n    mr  r3,REG_PlayerGObj\n    bl  UpdateCameraBox\n\n\t\t#Remake HUD For Dead Players (Taken from Achilles' GitHub)\n\t\tcmpwi\t\tREG_isSubchar,0x1\t\t#dont run this on subcharacters\n\t\tbeq\t\tSaveState_HUD_End\n\t\tload\t\tr3,0x804a10c8\t\t#get base HUD info\n\t\tmulli \t\tr4,REG_SpawnedOrder,100\t\t#get offset\n\t\tadd\t\tr20,r4,r3\t\t#get to this player's HUD info\n\t\tbranchl\t\tr12,0x8016b094\t #MatchInfo_StockModeCheck\n\t\tcmpwi \t\tr3,0\t\t#if not stock mode\n\t\tbeq- \t\tSaveState_RELOAD_PERCENT_HUDS_NOT_STOCK\n\n\t\t\tSaveState_RELOAD_PERCENT_HUDS_STOCK:\n\t\t\tmr\t\tr3,REG_SpawnedOrder\t\t#get player number\n\t\t\tbranchl\t\tr12,0x80033bd8\t\t#get stocks left\n\t\t\tcmpwi \t\tr3,0\n\t\t\tbne- \t\tSaveState_RELOAD_PERCENT_HUDS_NOT_STOCK\n\t\t\tli \t\tr5,0x80\t\t#remove percent\n\t\t\tstb \t\tr5,0x10(r20)\n\t\t\tb \t\tSaveState_HUD_End\n\n\t\t\t\tSaveState_RELOAD_PERCENT_HUDS_NOT_STOCK:\n\t\t\t\tlbz\t\tr5,0x10(r20)\n\t\t\t\trlwinm. \t\tr5,r5,0,24,24\t# (00000080), is player HUD percent gone?\n\t\t\t\tbeq- \t\tSaveState_HUD_End\n\n\t\t\t\tSaveState_REMAKE_PERCENT:\n\t\t\t\t.set \t\tHUD_PlayerCreate_Prefunction, 0x802f6e1c\n\t\t\t\tmr \t\tr3,REG_SpawnedOrder\n\t\t\t\tbranchl\t\tr4, HUD_PlayerCreate_Prefunction\n\n\t\tSaveState_HUD_End:\n\n\t\tSaveState_LoadLoopInc:\n\t\t#Check For Subchar Before Looping\n\t\tcmpwi\t\tREG_isSubchar,0x1\n\t\tbeq\t\tSaveState_LoadLoopInc_ToggleSubCharOff\n\t\tli\t\tREG_isSubchar,0x1\n\t\tb\t\tSaveState_LoadLoop\n\t\tSaveState_LoadLoopInc_ToggleSubCharOff:\n\t\tli\t\tREG_isSubchar,0x0\n\t\taddi\t\tREG_LoopCount,REG_LoopCount,0x1\n\t\tcmpw\t\tREG_LoopCount,REG_PlayerTotal\n\t\tblt\t\tSaveState_LoadLoop\n\n    SaveState_LoadEnd:\n\n    /*\n    SaveState_Load_RemoveAllGFX:\n    #Get First GFX\n      lwz  r3,-0x3E74 (r13)\n      lwz  r20,0x30(r3)\n    #Check if exists\n    SaveState_Load_CheckIfGFXExists:\n      cmpwi r20,0\n      beq SaveState_Load_RemoveAllGFXEnd\n    #Check if this is a particle GObj?\n      lbz r3,0x4(r20)\n      cmpwi r3,1\n      beq SaveState_Load_GetNextGFX\n    #Remove this GFX\n      mr  r3,r20\n      branchl r12,0x80390228\n    #Get next GFX\n    SaveState_Load_GetNextGFX:\n      lwz r20,0x8(r20)\n      b SaveState_Load_CheckIfGFXExists\n    SaveState_Load_RemoveAllGFXEnd:\n    */\n\n  SaveState_LoadExit:\n\trestore\n\tblr\n\n#########################################################################\n\n############################\n## Get PlayerData Pointer ##\n############################\n\nSaveState_GetPlayerDataPointer:\n#r3 = player number (regardless of port)\n#r4 = 0x0 for main char // 0x1 for subchar\n\n#returns:\n#r3 = player slot\n#r4 = external player\n#r5 = internal player\nsubi\tsp,sp,0x8\nmr\tr11,r3\t\t\t#move desired player into r11\nmr\tr10,r4\t\t\t#move subchar status into r4\nmr\tr9,sp\t\t\t#move bytefield into r10\nli\tr3,-0x1\t\t\t#zero out new space\nstw\tr3,0x0(r9)\nstw\tr3,0x4(r9)\n\n#Make Bytefield For Player Order\nli\tr7,0x0\t\t\t#init loop\nli\tr6,0x0\t\t\t#init player ID\nload\tr5,0x80453080\t\t\t#first playerblock\n\n\tSaveState_GetPlayerDataPointer_LoopStart:\n\tlwz\tr3,0x0(r5)\t\t\t#an inactive player block will store \"0\" at offset 0x0\n\tcmpwi\tr3,0x0\n\tbeq\tSaveState_GetPlayerDataPointer_Empty\n\n\tSaveState_GetPlayerDataPointer_PlayerPresent:\n\tstbx\tr7,r6,r9\t\t\t#store loop count to player ID offset\n\taddi\tr6,r6,0x1\t\t\t#next player ID\n\n\tSaveState_GetPlayerDataPointer_Empty:\n\taddi\tr5,r5,0xe90\t\t\t#next playerblock\n\taddi\tr7,r7,0x1\t\t\t#inc loop\n\tcmpwi\tr7,6\n\tblt\tSaveState_GetPlayerDataPointer_LoopStart\n\n#Now r9 contains player bytefield\nlbzx\tr3,r11,r9\t\t\t#get the correct player slot for the X player\ncmpwi\tr3,0xFF\t\t\t#check if player exists\nbeq\tSaveState_GetPlayerDataPointer_Exit\t\t\t#if not exit with -1 return\n\nload\tr5,0x80453080\t\t\t#first playerblock\nmulli\tr4,r3,0xe90\t\t\t#get offset\nadd\tr4,r4,r5\t\t\t#get static block in r4\n\ncmpwi\tr10,0x0\nbeq\tSaveState_GetPlayerDataPointer_MainChar\n\nSaveState_GetPlayerDataPointer_SubChar:\nlwz\tr4,0xB4(r4)\nb\tSaveState_GetPlayerDataPointer_LoadInternal\nSaveState_GetPlayerDataPointer_MainChar:\nlwz\tr4,0xB0(r4)\nSaveState_GetPlayerDataPointer_LoadInternal:\n#Check If Player Exists\ncmpwi\tr4,0x0\nbne\tSaveState_GetPlayerDataPointer_LoadInternalContinue\nli\tr3,0xFF\nb\tSaveState_GetPlayerDataPointer_Exit\nSaveState_GetPlayerDataPointer_LoadInternalContinue:\nlwz\tr5,0x2c(r4)\n\nSaveState_GetPlayerDataPointer_Exit:\naddi\tsp,sp,0x8\nblr\n\n#######################################################\n\nCheckForSaveAndLoad:\n\n.set LoopCount,31\n\nbackup\n\nmr\tr29,r3\t\t#Task Data\n\n#Init Loop\n  li  LoopCount,0\n#Loop\nCheckForSaveAndLoad_Loop:\n  mr  r3,LoopCount\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  cmpwi r3,0x0\n  beq CheckForSaveAndLoad_Inc\nCheckForSaveAndLoad_CheckInputs:\n  load r3,0x804c21cc\n  #load r3,0x804c1fac\n  mulli r0,LoopCount,68\n  add r4,r3,r0\n#Make Sure Nothing Else Is Held\n  lhz\tr3,0x2(r4)\n  rlwinm.  r0,r3,0,0,26\n  bne\tCheckForSaveAndLoad_Inc\n  lwz\tr3,0x8(r4)\n  rlwinm.\tr0,r3,0,30,30\n  beq\tCheckForSaveAndLoad_NoSave\n  mr\tr3,r29\n\tli\tr4,0\t\t\t#run failsafe code\n  bl\tSaveState_Save\n  li\tr3,0x0\n  b\tCheckForSaveAndLoad_Exit\nCheckForSaveAndLoad_NoSave:\n  rlwinm.\tr0,r3,0,31,31\n  beq\tCheckForSaveAndLoad_Inc\n  mr\tr3,r29\n  bl\tSaveState_Load\n  mr\tr3,r29\n  bl\tSaveState_Load\n  li\tr3,0x1\n  b\tCheckForSaveAndLoad_Exit\n\nCheckForSaveAndLoad_Inc:\n  addi LoopCount,LoopCount,1\n  cmpwi LoopCount,4\n  blt CheckForSaveAndLoad_Loop\n\nCheckForSaveAndLoad_Exit:\nrestore\nblr\n\n############################################\n\nGiveFullShields:\nbackup\n\nGiveFullShields_GetFirstPlayer:\nlwz\tr3, -0x3E74 (r13)\nlwz\tr20, 0x0020 (r3)\nb\tGiveFullShields_CheckIfPlayerExists\n\nGiveFullShields_GetNextPlayer:\nlwz\tr20,0x8(r20)\n\nGiveFullShields_CheckIfPlayerExists:\ncmpwi\tr20,0x0\nbeq\tGiveFullShields_Exit\nlwz\tr21,0x2C(r20)\n\n#Give Full Shield\nlwz\tr3, -0x514C (r13)\nlfs\tf0, 0x0260 (r3)\nstfs\tf0,0x1998(r21)\nb\tGiveFullShields_GetNextPlayer\n\n\nGiveFullShields_Exit:\n\nrestore\nblr\n\n############################################\n\nUpdateAllGFX:\nbackup\n\nmr\tr3,30\nbranchl\tr12,GFX_UpdatePlayerGFX\n\n#Check For Follower\nmr\tr3,r30\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0x0\nbeq\t\tUpdateAllGFX_Exit\n\n#Apply To Follower Char\nbranchl\tr12,GFX_UpdatePlayerGFX\n\nUpdateAllGFX_Exit:\nrestore\nblr\n\n############################################\n\nGiveInvincibility:\n#r3 = ext pointer\n#r4 = frames\n\nbackup\n\n#Give To Main Char\nmr\tr31,r3\nmr\tr30,r4\nbranchl\tr12,ApplyInvincibility\n\n#Check For Follower\nmr\tr3,r31\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0x0\nbeq\t\tGiveInvincibility_Exit\n\n#Apply To Follower Char\nmr\tr4,r30\nbranchl\tr12,ApplyInvincibility\n\nGiveInvincibility_Exit:\nrestore\nblr\n\n############################################\nStoreCPUTypeAndZeroInputs:\n\n#Set P2 AI Type to None\n#li\tr3,0xF\n#stw\tr3,0x1A94(r29)\n\n#Clear Inputs For P2 CPU\nli\tr3,0x0\nstw\tr3,0x1A88(r29)\nstw\tr3,0x1A8C(r29)\nsth\tr3,0x1A90(r29)\nblr\n\n###########################################\n\nClearNanaInputs:\nbackup\n\n#Clear Inputs if P1 is Ice Climbers\nmr\tr3,28\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0x0\nbeq\tClearNanaInputs_P2\nli\tr3,0x0\nstw\tr3,0x1A88(r4)\nstw\tr3,0x1A8C(r4)\n\n#Clear Inputs if P2 is Ice Climbers\nClearNanaInputs_P2:\nmr\tr3,30\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0x0\nbeq\tClearNanaInputs_Exit\nli\tr3,0x0\nstw\tr3,0x1A88(r4)\nstw\tr3,0x1A8C(r4)\n\nClearNanaInputs_Exit:\nrestore\nblr\n\n###########################################\n\nCheckIfFirstFrame:\nlwz r3,TM_GameFrameCounter(r13)\ncmpwi\tr3,0x1\nbne\tCheckIfFirstFrame_False\nli\tr3,0x1\nb\tCheckIfFirstFrame_Exit\nCheckIfFirstFrame_False:\nli\tr3,0x0\nCheckIfFirstFrame_Exit:\nblr\n\n#############################################\n\nCurrentInputsAsLastFramesInputs:\nload r3,0x804c21cc\nlwz\tr3,0x0(r3)\nstw\tr3,0x65C(r27)\nstw\tr3,0x664(r27)\n\n#Check For Z Press\nrlwinm.\tr0, r3, 0, 27, 27\nbeq\tCurrentInputsAsLastFramesInputs_Exit\noris\tr0, r3, 0x8000\nori\tr0, r0, 0x0100\nstw\tr0,0x65C(r27)\nstw\tr0,0x664(r27)\n\nCurrentInputsAsLastFramesInputs_Exit:\nblr\n\n#############################################\n\n/*\n\nCPUActions_MultiShine:\nbackup\n\nmr\tr29,r3\n\n#Get AS and Frame Number\nlwz\tr4,0x10(r3)\t\t#Get Current AS\n\n#Start - Check to Grounded Shine\ncmpwi\tr4,0xE\t\t#Wait\nbeq\tMultishine_StartShine\ncmpwi\tr4,0x169\t\t#Shine Loop Ground\nbeq\tMultishine_JumpCancelShine\ncmpwi\tr4,0x19\t\t#JumpF\nbeq\tMultishine_StartShine\nb       CPUActions_MultiShine_Exit\n\nMultishine_StartShine:\nli\tr3,-127\t\t#Down\nstb\tr3,0x1A8D(r29)\t\t#Analog Y\nli\tr3,0x200\t\t#B\nstw\tr3,0x1A88(r29)\t #Inputs\nb\tCPUActions_MultiShine_Exit\n\nMultishine_JumpCancelShine:\nli\tr3,0x800\t\t#X\nstw\tr3,0x1A88(r29)\t #Inputs\nb\tCPUActions_MultiShine_Exit\n\nMultishine_ShineAir:\nb\tCPUActions_MultiShine_Exit\n\nCPUActions_MultiShine_Exit:\nrestore\nblr\n\n*/\n\n\n###################################\n\nRAndDPadChangesEventOption:\nOptionWindow:\n#in\n#r3 = pointer to option byte in memory\n#r4 = pointer to Window and Option Count\n#r5 = pointer to ASCII struct\n\n#out\n#r3 =\n\n.set TextCreateFunction,0x80005928\n.set OptionWindowMemory,20\n.set OptionTextInfo,21\n.set OptionASCII,22\n.set text,23\n.set toggledBool,28\n.set toggledOption,29\n\n\nbackup\n\n\n#Backup Parameters\nmr\tOptionWindowMemory,r3\t\t#pointer to option byte in memory\nmr\tOptionTextInfo,r4\t\t#pointer to Window and Option Count\nmr\tOptionASCII,r5\t\t#pointer to ASCII struct\n\n#Initialize Toggled Bools\nli\ttoggledBool,0\nli\ttoggledOption,-1\n\n#Get Number Of Options Onscreen At Once (1,2,or 3)\nlbz\tr24,0x0(OptionTextInfo)\t\t#Get Number of Different Windows\ncmpwi\tr24,2\t\t#Check If Over 3\nble\t0x8\nli\tr24,2\t\t#Make 3\n\n#Get Pausing Player's Inputs\nload r3,0x8046b6a0\nlbz r3,0x1(r3)\nload r4,0x804c1fac\nmulli r3,r3,68\nadd r3,r3,r4\nlwz r3,0x8(r3)\n\n#Check For DPad Up And Down\ncmpwi\tr3,0x04\nbeq\tRAndDPadChangesEventOption_CursorDown\ncmpwi\tr3,0x08\nbeq\tRAndDPadChangesEventOption_CursorUp\nb\tRAndDPadChangesEventOption_CheckDPadLeftAndRight\n\nRAndDPadChangesEventOption_CursorUp:\n#Update Cursor Position\n\tlbz\tr3,0x0(OptionWindowMemory)\t\t#Get Current Cursor Position Byte\n\tsubi\tr3,r3,0x1\t\t#Subtract by 1\n\tstb\tr3,0x0(OptionWindowMemory)\n\tcmpwi\tr3,0x0\n\tbge\tRAndDPadChangesEventOption_PlayScrollSFX\n#Cursor Stays at the top of the screen\n\tli\tr3,0\n\tstb\tr3,0x0(OptionWindowMemory)\n#Check To Scroll Down\n\t#Get Current Window ID (cursor + scroll)\n\t\tlbz\tr3,0x0(OptionWindowMemory)\n\t\tlbz\tr4,0x1(OptionWindowMemory)\n\t\tadd\tr3,r3,r4\n\t#Check If This is the Beginning\n\t\tcmpwi\tr3,0\n\t\tble\tRAndDPadChangesEventOption_DisplayWindow\n\t#Scroll Down\n\t\tlbz\tr4,0x1(OptionWindowMemory)\n\t\tsubi\tr4,r4,1\n\t\tstb\tr4,0x1(OptionWindowMemory)\n    b RAndDPadChangesEventOption_PlayScrollSFX\n\nb\tRAndDPadChangesEventOption_DisplayWindow\n\nRAndDPadChangesEventOption_CursorDown:\n#Update Cursor Position\n\tlbz\tr3,0x0(OptionWindowMemory)\t\t#Get Current Option Byte\n\taddi\tr3,r3,0x1\t\t#Add 1\n\tstb\tr3,0x0(OptionWindowMemory)\n\tcmpw\tr3,r24\n\tble\tRAndDPadChangesEventOption_PlayScrollSFX\n#Cursor Stays at the Bottom of the Screen\n\tstb\tr24,0x0(OptionWindowMemory)\n#Check To Scroll Down\n\t#Get Current Window ID (cursor + scroll)\n\t\tlbz\tr3,0x0(OptionWindowMemory)\n\t\tlbz\tr4,0x1(OptionWindowMemory)\n\t\tadd\tr3,r3,r4\n\t#Get Max Number Of Windows\n\t\tlbz\tr4,0x0(OptionTextInfo)\t\t#Get Number of Different Windows\n\t#Check If This is the End\n\t\tcmpw\tr3,r4\n\t\tbge\tRAndDPadChangesEventOption_DisplayWindow\n\t#Scroll Down\n\t\tlbz\tr4,0x1(OptionWindowMemory)\n\t\taddi\tr4,r4,1\n\t\tstb\tr4,0x1(OptionWindowMemory)\n\nb\tRAndDPadChangesEventOption_PlayScrollSFX\n\n#Check For DPad Left And Right\nRAndDPadChangesEventOption_CheckDPadLeftAndRight:\ncmpwi\tr3,0x02\nbeq\tRAndDPadChangesEventOption_Increment\ncmpwi\tr3,0x01\nbeq\tRAndDPadChangesEventOption_Decrement\nb\tRAndDPadChangesEventOption_DisplayWindow\n\nRAndDPadChangesEventOption_Increment:\n#Get Current Window ID (cursor + scroll)\n\tlbz\tr3,0x0(OptionWindowMemory)\n\tlbz\tr4,0x1(OptionWindowMemory)\n\tadd\tr3,r3,r4\n#Set as Toggled\n\tli toggledBool,1\n\tmr\ttoggledOption,r3\n\naddi\tr5,r3,2\nlbzx\tr3,r5,OptionWindowMemory\t\t#Get Current Option Byte\naddi\tr3,r3,0x1\nstbx\tr3,r5,OptionWindowMemory\t\t#Store New Option Byte Value\nsubi\tr5,r5,1\nlbzx\tr4,r5,OptionTextInfo\t\t#Get Window's Option Byte Max Value\ncmpw\tr3,r4\nble\tRAndDPadChangesEventOption_PlayScrollSFX\nli\tr3,0x0\naddi\tr5,r5,1\nstbx\tr3,r5,OptionWindowMemory\t\t#Get New Option Byte Value\nb\tRAndDPadChangesEventOption_PlayScrollSFX\n\nRAndDPadChangesEventOption_Decrement:\n#Get Current Window ID (cursor + scroll)\n\tlbz\tr3,0x0(OptionWindowMemory)\n\tlbz\tr4,0x1(OptionWindowMemory)\n\tadd\tr3,r3,r4\n#Set as Toggled\n\tli toggledBool,1\n\tmr toggledOption,r3\n\naddi\tr5,r3,0x2\nlbzx\tr3,r5,OptionWindowMemory\t\t#Get Current Option Byte\nsubi\tr3,r3,0x1\nstbx\tr3,r5,OptionWindowMemory\t\t#Store New Option Byte Value\ncmpwi\tr3,0x0\nbge\tRAndDPadChangesEventOption_PlayScrollSFX\nsubi\tr5,r5,1\nlbzx\tr3,r5,OptionTextInfo\t\t#Get Window's Option Byte Max Value\naddi\tr5,r5,1\nstbx\tr3,r5,OptionWindowMemory\t\t#Store New Option Byte Value\nb\tRAndDPadChangesEventOption_PlayScrollSFX\n\nRAndDPadChangesEventOption_PlayScrollSFX:\nli  r3,0x2\nbranchl r12,SFX_MenuCommonSound\n\nRAndDPadChangesEventOption_DisplayWindow:\n#Display Text For The New Option Value\nmr\tr3,r27\t\t\t#p1 (no offsetting window)\nli\tr4,1\t\t\t  #text timeout\nli\tr5,0x2\t\t\t#window instance #3\nli\tr6,0\t\t\t  #window ID #3\nbranchl\tr12,TextCreateFunction\t\t#create text custom function\nmr\ttext,r3\t\t\t#backup text pointer\n\n\n#########################\n## Display Option Menu ##\n#########################\n\n\t\t#Check How Many Options In The Menu\n\t\tcmpwi\tr24,0\n\t\tbeq\tRAndDPadChangesEventOption_DisplayWindow_LoopInit\n\n\t\t#Change Background Size\n\t\tbl\tRAndDPadChangesEventOption_Floats\n\t\tmflr\tr5\n\t\tlfs\tf1,0x0(r5)\t\t#12.5\n\t\taddi\tr5,r5,0x4\t\t#Skip Window X\n\t\tsubi\tr6,r24,1\t\t#Zero Index\n\t\tmulli\tr6,r6,0x4\t\t#Get Y Offset\n\t\tlfsx\tf2,r6,r5\n\t\tli\tr4,0\n\t\tbranchl\tr12,Text_UpdateSubtextSize\n\n\t\t#Move Window\n\t\tbl\tRAndDPadChangesEventOption_Floats\n\t\tmflr\tr5\n\t\tlfs\tf1, -0x37B4 (rtoc)\n\t\taddi\tr5,r5,0xC\t\t#Skip Window X and Window Y's\n\t\tsubi\tr6,r24,1\t\t#Zero Index\n\t\tmulli\tr6,r6,0x4\t\t#Get Y Offset\n\t\tlfsx\tf2,r6,r5\n\t\tmr\tr3,text\n\t\tli\tr4,0\n\t\tbranchl\tr12,Text_UpdateSubtextPosition\n\n############################\n## Display Up/Down Arrows ##\n############################\n\n#Check if at the top of the screen\n  lbz r3,0x1(r20)\n  cmpwi r3,0x0\n  beq RAndDPadChangesEventOption_DisplayDownArrow\n#Create Title Text\n\tli r3,-20        #Y\n  bl  IntToFloat\n  fmr f2,f1\n  li  r3,-210      #X\n  bl  IntToFloat\n\tmr \tr3,text\t\t\t#text pointer\n\tbl  RAndDPadChangesEventOption_UpArrowText\n  mflr r4\n\tbranchl r12,Text_InitializeSubtext\n\nRAndDPadChangesEventOption_DisplayDownArrow:\n#Check if at the bottom of the screen\n  lbz r3,0x0(r21)\n  cmpwi r3,2\n  blt RAndDPadChangesEventOption_DisplayArrowExit\n  lbz r4,0x1(r20)\n  sub r3,r3,r4\n  cmpwi r3,2\n  ble RAndDPadChangesEventOption_DisplayArrowExit\n#Create Title Text\n  li  r3,320      #Y value\n  bl  IntToFloat\n  fmr f2,f1\n  li  r3,-210     #X Value\n  bl  IntToFloat\n\tmr \tr3,text\t\t\t#text pointer\n\tbl  RAndDPadChangesEventOption_DownArrowText\n  mflr r4\n\tbranchl r12,Text_InitializeSubtext\n\nRAndDPadChangesEventOption_DisplayArrowExit:\n\n############################\n## Print Each Option Loop ##\n############################\n\n\tRAndDPadChangesEventOption_DisplayWindow_LoopInit:\n\n\t\tli\tr27,0\t\t\t#Init Loop\n\n\tRAndDPadChangesEventOption_DisplayWindow_Loop:\n\n\t\t#Get Window Title And Option\n\t\t\tmr\tr3,OptionASCII\t\t\t#Option ASCII Start\n\t\t\tlbz\tr4,0x1(OptionWindowMemory)\t\t\t#Get Scroll Position\n\t\t\tadd\tr4,r4,r27\t\t\t#Get Loop Count's Window\n\t\t\taddi\tr5,OptionWindowMemory,0x2\t\t\t#Selection ID's\n\t\t\tlbzx\tr5,r4,r5\t\t\t#Get Current Option This Window is On\n\t\t\tbl\tRAndDPadChangesEventOption_GetOptionASCII\n\t\t\tmr\tr25,r3\n\t\t\tmr\tr26,r4\n\n\t\t#Create Title Text\n\t\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text Y\n\t\t\tli\tr3,120\n\t\t\tmullw\tr3,r3,r27\n\t\t\tbl\tIntToFloat\n\t\t\tfadds\tf2,f1,f2\n\t\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X\n\t\t\tmr \tr3,text\t\t\t#text pointer\n\t\t\tmr\tr4,r25\t\t\t#Title Text Pointer\n\t\t\tbranchl r12,Text_InitializeSubtext\n\t\t#Make Text Grey\n\t\t\tload\tr4,0xdfdfdf00\n\t\t\tstw\tr4,0xF0(sp)\n\t\t\taddi\tr5,sp,0xF0\n\t\t\tmr\tr4,r3\n\t\t\tmr\tr3,text\n\t\t\tbranchl\tr12,Text_ChangeTextColor\n\n\t\t#Create Selection Text\n\t\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\t\t\tli\tr3,120\n\t\t\tmullw\tr3,r3,r27\n\t\t\tbl\tIntToFloat\n\t\t\tfadds\tf2,f1,f2\n\t\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\t\tmr \tr3,text\t\t\t#text pointer\n\t\t\tmr\tr4,r26\t\t\t#Selection Text\n\t\t\tbranchl r12,Text_InitializeSubtext\n\t\t#Check To Outline in Yellow\n\t\t\tlbz\tr4,0x0(OptionWindowMemory)\t\t\t#Get Cursor Position\n\t\t\tcmpw\tr4,r27\t\t\t#Compare With Loop Counter\n\t\t\tbne\tRAndDPadChangesEventOption_DisplayWindow_SkipColor\n\t\t\tload\tr4,0xf7ff2700\n\t\t\tstw\tr4,0xF0(sp)\n\t\t\taddi\tr5,sp,0xF0\n\t\t\tmr\tr4,r3\n\t\t\tmr\tr3,text\n\t\t\tbranchl\tr12,Text_ChangeTextColor\n\n\t\tRAndDPadChangesEventOption_DisplayWindow_SkipColor:\n\t\t\tcmpw\tr27,r24\n\t\t\taddi\tr27,r27,1\n\t\t\tblt\tRAndDPadChangesEventOption_DisplayWindow_Loop\n\n\t\tb RAndDPadChangesEventOption_Exit\n\n\n#########################################\n\nRAndDPadChangesEventOption_GetOptionASCII:\n\nbackup\n\n\tmr\tr31,r3\t\t#Option ASCII Start\n\tmr\tr30,r4\t\t#Option ID We're Looking For\n\tmr\tr29,r5\t\t#Option Selection We're Looking For\n\n#Init Loop\n\tli\tr27,0\n\nRAndDPadChangesEventOption_GetOptionASCII_OptionIDLoop:\n\tcmpw\tr27,r30\t\t#Check If This is the Window We're Looking For\n\tbeq\tRAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection\n\n\n\n\t########################\n\t## Skip Entire Option ##\n\t########################\n\n\t\tRAndDPadChangesEventOption_GetOptionASCII_GetNextOptionID:\n\t\t#Skip Past Window Title\n\t\t\tmr\tr3,r31\n\t\t\tbl\tRAndDPadChangesEventOption_GetNextString\n\t\t\tmr\tr31,r3\t\t#Backup New Pointer\n\n\t\t#Loop Through All The Window's Selections\n\t\t\tli\tr26,0\t\t#Loop Count\n\t\tRAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections:\n\t\t#Get This Options (r27) Total Number of Selections (Pointer in OptionTextInfo)\n\t\t\taddi\tr3,OptionTextInfo,0x1\t\t#Get to Option Selection Counts\n\t\t\tlbzx\tr3,r3,r27\t\t#Get This Windows Total Number of Selections\n\t\t\taddi\tr3,r3,0x1\t\t#Add 1 To Ensure We Are at the Start of the Next Window Title\n\t\t\tcmpw\tr3,r26\t\t#Check If This is the Last Selection\n\t\t\tbne\tRAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections_NextSelection\n\n\t\t#End of Loop, Done With This Option\n\t\t#Increment Loop Count\n\t\t\taddi\tr27,r27,1\t\t#Increment Option Count\n\t\t\tb\tRAndDPadChangesEventOption_GetOptionASCII_OptionIDLoop\n\n\t\tRAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections_NextSelection:\n\t\t#Get Next Selection\n\t\t\tmr\tr3,r31\n\t\t\tbl\tRAndDPadChangesEventOption_GetNextString\n\t\t\tmr\tr31,r3\t\t#Backup New Pointer\n\t\t#Increment Loop Count\n\t\t\taddi\tr26,r26,1\n\t\t\tb\tRAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections\n\n\t###########################\n\t## Find Option Selection ##\n\t###########################\n\n\t\tRAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection:\n\t\t#Init Loop Count + Backup Window Title\n\t\t\tli\tr26,0\t\t#Init Loop Count\n\t\t\tmr\tr25,r31\t\t#r25 = Window Title\n\t\t#Skip Window Title\n\t\t\tmr\tr3,r31\n\t\t\tbl\tRAndDPadChangesEventOption_GetNextString\n\t\t\tmr\tr31,r3\t\t#Backup New Pointer\n\t\tRAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Loop:\n\t\t#Check If This is the Selection We're Looking For\n\t\t\tcmpw\tr26,r29\n\t\t\tbeq\tRAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Done\n\t\t#Get Next Selection\n\t\t#Strlen the entry\n\t\t\tmr\tr3,r31\n\t\t\tbl\tRAndDPadChangesEventOption_GetNextString\n\t\t\tmr\tr31,r3\t\t#Backup New Pointer\n\t\t#Increment Loop Count\n\t\t\taddi\tr26,r26,1\n\t\t\tb\tRAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Loop\n\n\t\tRAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Done:\n\t\t\tmr\tr3,r25\t\t#Return Window Name\n\t\t\tmr\tr4,r31\t\t#Return Selection String\n\n\nRAndDPadChangesEventOption_GetOptionASCII_Exit:\nrestore\nblr\n\n#########################################\n\nRAndDPadChangesEventOption_GetNextString:\nbackup\n\nmr\tr31,r3\t\t\t#Backup String Pointer\nbranchl\tr12,strlen\t\t\t#Get Length\nadd\tr3,r3,r31\t\t\t#Get End of String\n\n#From here, mini loop to find the next non-zero value.\nRAndDPadChangesEventOption_GetNextString_Loop:\nlbzu\tr4,0x1(r3)\ncmpwi\tr4,0x0\nbeq\tRAndDPadChangesEventOption_GetNextString_Loop\n\nrestore\nblr\n\n#########################################\nRAndDPadChangesEventOption_Floats:\nblrl\n\n.float 16 #12.5, X position\n.long 0x427c0000 #63, 2 Window Y Scale\n.long 0x42bc0000 #94, 3 Window Y Scale\n.long 0xc4610000 #-900, 2 Window Y position\n.long 0xc4a8c000 #-1350, 3 Window Y position\n\n#########################################\nRAndDPadChangesEventOption_UpArrowText:\nblrl\n\n.string \"^\"\n.align 2\n\nRAndDPadChangesEventOption_DownArrowText:\nblrl\n\n.string \"v\"\n.align 2\n\n#########################################\n\nRAndDPadChangesEventOption_Exit:\nmr\tr3,toggledBool\nmr\tr4,toggledOption\nrestore\nblr\n\n##################################\n\nDPadCPUPercent:\nbackup\n\n.set REG_SaveStruct,31\n.set REG_PercentInt,30\n.set REG_isSubcharBool,29\n\n#Backup savestate struct\n\tmr\tREG_SaveStruct,r3\n\n#Get P1 Block\n\tli\tr3,0x0\n\tbranchl\tr12,PlayerBlock_LoadMainCharDataOffset\t\t\t#get player block\n\tlwz\tr3,0x2C(r3)\n\n#Get P2 Percent\n\tload\tr6,0x80453F10\n\tlhz\tREG_PercentInt,0x60(r6)\n\n#Get Subchar Bool\n\tlbz REG_isSubcharBool,0xC(r6)\n\n#Get inputs\n  load r4,0x804c21cc\n\tlbz r3,0x618(r3)\n  mulli r0,r3,68\n  add r5,r4,r0\n#Make Sure L Is Held\n\tlwz r3,0x0(r5)\t\t#get held inputs\n\trlwinm. r0,r3,0,25,25\n\tbeq\tDPadCPUPercent_Exit\n#Check DPad\n\tlwz r3,0xC(r5)\t\t#get rapid inputs\n\trlwinm.\tr0,r3,0,30,30\n\tbne\tDPadCPUPercent_IncByOne\n\trlwinm.\tr0,r3,0,31,31\n\tbne\tDPadCPUPercent_DecByOne\n\trlwinm.\tr0,r3,0,28,28\n\tbne\tDPadCPUPercent_IncByTen\n\trlwinm.\tr0,r3,0,29,29\n\tbne\tDPadCPUPercent_DecByTen\n\tb\tDPadCPUPercent_Exit\n\nDPadCPUPercent_IncByOne:\n\tcmpwi\tREG_PercentInt,999\n\tblt\tDPadCPUPercent_IncByOneReal\n\tli\tREG_PercentInt,999\n\tb\tDPadCPUPercent_StorePercent\n\tDPadCPUPercent_IncByOneReal:\n\taddi\tREG_PercentInt,REG_PercentInt,0x1\n\tb\tDPadCPUPercent_StorePercent\n\nDPadCPUPercent_DecByOne:\n\tcmpwi\tREG_PercentInt,0\n\tbgt\tDPadCPUPercent_DecByOneReal\n\tli\tREG_PercentInt,0\n\tb\tDPadCPUPercent_StorePercent\n\tDPadCPUPercent_DecByOneReal:\n\tsubi\tREG_PercentInt,REG_PercentInt,0x1\n\tb\tDPadCPUPercent_StorePercent\n\nDPadCPUPercent_IncByTen:\n\tcmpwi\tREG_PercentInt,989\n\tblt\tDPadCPUPercent_IncByTenReal\n\tli\tREG_PercentInt,999\n\tb\tDPadCPUPercent_StorePercent\n\tDPadCPUPercent_IncByTenReal:\n\taddi\tREG_PercentInt,REG_PercentInt,10\n\tb\tDPadCPUPercent_StorePercent\n\nDPadCPUPercent_DecByTen:\n\tcmpwi\tREG_PercentInt,9\n\tbgt\tDPadCPUPercent_DecByTenReal\n\tli\tREG_PercentInt,0\n\tb\tDPadCPUPercent_StorePercent\n\tDPadCPUPercent_DecByTenReal:\n\tsubi\tREG_PercentInt,REG_PercentInt,10\n\tb\tDPadCPUPercent_StorePercent\n\nDPadCPUPercent_StorePercent:\n#Store to Active Static Playerblock\n\tsth\tREG_PercentInt,0x60(r6)\n#Convert to Float\n\tmr\t\tr3,REG_PercentInt\n\tbl\t\tIntToFloat\n#Active PlayerData\n\tli\tr3,0x1\n\tbranchl\tr12,PlayerBlock_LoadMainCharDataOffset\t\t#get player block\n\tlwz\tr3,0x2C(r3)\n\tstfs\tf1,0x1830(r3)\n\n#Backed Up PlayerData\n\tmulli\tr4,REG_isSubcharBool,0x4\n\tlwzx r3,r4,REG_SaveStruct\n\tstfs\tf1,0x1830(r3)\n#Backed Up Static Playerblock\n\tload\tr4,0x80458fd0\t\t\t\t\t#get player block length\n\tlwz   r4,0x20(r4)\t\t\t\t\t\t#get player block length\n\tlwz r3,0x0(REG_SaveStruct)\t#only the main character has a static block backup\n\tadd\tr3,r3,r4\t\t\t\t\t\t\t\t#static block start\n\tsth\tREG_PercentInt,0x60(r3)\n\tsth\tREG_PercentInt,0x62(r3)\n\n\nDPadCPUPercent_Exit:\n\trestore\n\tblr\n\n##################################\n\nInitializePositions:\nbackup\n\n#Move Float Pointer\nmr\tr20,r3\n\n#P1 Static Block\nload\tr22,0x80453080\n#P2 Static Block\naddi\tr23,r22,0xE90\n\n#Move P1\nmr\tr3,r28\nbranchl\tr12,0x8008a2bc\t\t#Enter Wait\nlfs\tf1,0x0(r20)\nstfs\tf1,0xB0(r27)\nlfs\tf1,0x8(r20)\nstfs\tf1,0xB4(r27)\nmr\tr3,r28\nbl  UpdatePosition\nmr\tr3,r28\nbl\tUpdateCameraBox\nmr\tr3,r28\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0x0\nbeq\tInitializePositions_MoveP2\n#Move This Char Too\nmr\tr24,r3\nmr\tr25,r4\nmr\tr3,r24\nbranchl\tr12,0x8008a2bc\t\t#Enter Wait\nlfs\tf1,0x0(r20)\nstfs\tf1,0xB0(r25)\nlfs\tf1,0x8(r20)\nstfs\tf1,0xB4(r25)\nmr\tr3,r24\nbl  UpdatePosition\nmr\tr3,r24\nbl\tUpdateCameraBox\n\n#Move P2\nInitializePositions_MoveP2:\nmr\tr3,r30\nbranchl\tr12,0x8008a2bc\t\t#Enter Wait\nlfs\tf1,0x4(r20)\nstfs\tf1,0xB0(r29)\nlfs\tf1,0xC(r20)\nstfs\tf1,0xB4(r29)\nmr\tr3,r30\nbl  UpdatePosition\nmr\tr3,r30\nbl\tUpdateCameraBox\nmr\tr3,r30\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0x0\nbeq\tInitializePositions_Exit\n#Move This Char Too\nmr\tr24,r3\nmr\tr25,r4\nmr\tr3,r24\nbranchl\tr12,0x8008a2bc\t\t#Enter Wait\nlfs\tf1,0x4(r20)\nstfs\tf1,0xB0(r25)\nlfs\tf1,0xC(r20)\nstfs\tf1,0xB4(r25)\nmr\tr3,r24\nbl  UpdatePosition\nmr\tr3,r24\nbl\tUpdateCameraBox\n\nInitializePositions_Exit:\nbl\tClearNanaInputs\nbl\tCurrentInputsAsLastFramesInputs\n\nrestore\nblr\n\n#########################################################\n\nCheckIfPlayerHasAFollower:\n#Returns\n#r3 = 0 for no follower // External Pointer\n#r4 = 0 for no follower // Internal Pointer\n\nbackup\n\n#Get Players Data\nlwz\tr31,0x2C(r3)\n\n#Get Player Slot\nlbz\tr3,0xC(r31)\nli\tr4,0x1\nbl\tSaveState_GetPlayerDataPointer\t\t\t\t#returns r3=Slot/-1 if subchar doesnt exist, r4= external, r5=internal\ncmpwi\tr3,0xFF\nbeq\tCheckIfPlayerHasAFollower_NoFollower\n\n#Check If Follower\nmr\tr24,r4\nmr\tr25,r5\nlbz\tr3,0xC(r25)\t\t\t#get slot\nbranchl\tr12,0x80032330\t\t\t#get external character ID\nload\tr4,pdLoadCommonData\t\t\t#pdLoadCommonData table\nmulli\tr0, r3, 3\t\t\t#struct length\nadd\tr3,r4,r0\t\t\t#get characters entry\nlbz\tr0, 0x2 (r3)\t\t\t#get subchar functionality\ncmpwi\tr0,0x0\t\t\t#if not a follower, exit\nbne\tCheckIfPlayerHasAFollower_NoFollower\n\n#Return Follower Pointers\nmr\tr3,r24\t\t\t#External\nmr\tr4,r25\t\t\t#Internal\nb\tCheckIfPlayerHasAFollower_Exit\n\nCheckIfPlayerHasAFollower_NoFollower:\nli\tr3,0x0\nli\tr4,0x0\n\nCheckIfPlayerHasAFollower_Exit:\nrestore\nblr\n\n#########################################################\n\nRandomize_LeftorRightSide:\n#r3 = 0 = Same Side of Stage // 1 = Opposing Sides of Stage\n\nbackup\n\nmr\tr20,r3\t\t#Backup Stage Side Bool\n\n#Get Left or Right Side\nli\tr3,2\nbranchl\tr12,HSD_Randi\n#Check To Negate\ncmpwi\tr3,0x0\t\t#0 = Left, 1 = Right\nbne\tRandomize_RightSide\n\nRandomize_LeftSide:\n#P1 X Position\nlwz\tr3,0x10(r31)\t\t#P1 Backup Start\nlwz\tr4,0x18(r31)\t\t#P2 Backup Start\nlfs\tf1,0xB0(r3)\t\t#P1 Backup X Pos\ncmpwi\tr20,0x0\nbeq\t0xC\nbl\tRandomize_AlwaysNegative\nb\t0x8\nbl\tRandomize_AlwaysNegative\nstfs\tf1,0xB0(r3)\t\t#P1 Backup X Pos\n#P2 X Position\nlfs\tf1,0xB0(r4)\t\t#P2 Backup X Pos\ncmpwi\tr20,0x0\nbeq\t0xC\nbl\tRandomize_AlwaysPositive\nb\t0x8\nbl\tRandomize_AlwaysNegative\nstfs\tf1,0xB0(r4)\t\t#P2 Backup X Pos\n#Facing Directions\nlis\tr5,0x3f80\t\t#P1 Face Right\nlis\tr6,0xbf80\t\t#P2 Face Left\nstw\tr5,0x2C(r3)\t\t#P1 Backup Facing\nstw\tr6,0x2C(r4)\t\t#P2 Facing\nb\tRandomize_LeftorRightSide_CheckForFollowers\n\nRandomize_RightSide:\n#P1 X Position\nlwz\tr3,0x10(r31)\t\t#P1 Backup Start\nlwz\tr4,0x18(r31)\t\t#P2 Backup Start\nlfs\tf1,0xB0(r3)\t\t#P1 Backup X Pos\ncmpwi\tr20,0x0\nbeq\t0xC\nbl\tRandomize_AlwaysPositive\nb\t0x8\nbl\tRandomize_AlwaysPositive\nstfs\tf1,0xB0(r3)\t\t#P1 Backup X Pos\n#P2 X Position\nlfs\tf1,0xB0(r4)\t\t#P2 Backup X Pos\ncmpwi\tr20,0x0\nbeq\t0xC\nbl\tRandomize_AlwaysNegative\nb\t0x8\nbl\tRandomize_AlwaysPositive\nstfs\tf1,0xB0(r4)\t\t#P2 Backup X Pos\n#Facing Directions\nlis\tr5,0xbf80\t\t#P1 Face Left\nlis\tr6,0x3f80\t\t#P2 Face Right\nstw\tr5,0x2C(r3)\t\t#P1 Backup Facing\nstw\tr6,0x2C(r4)\t\t#P2 Facing\n\n\nRandomize_LeftorRightSide_CheckForFollowers:\n\tRandomize_LeftorRightSide_GetFirstPlayer:\n\tlwz\tr3, -0x3E74 (r13)\n\tlwz\tr20, 0x0020 (r3)\n\tb\tRandomize_LeftorRightSide_CheckIfPlayerExists\n\n\tRandomize_LeftorRightSide_GetNextPlayer:\n\tlwz\tr20,0x8(r20)\n\n\tRandomize_LeftorRightSide_CheckIfPlayerExists:\n\tcmpwi\tr20,0x0\n\tbeq\tRandomize_LeftorRightSide_Exit\n\tlwz\tr21,0x2C(r20)\n\n\t#Check If This Fighter is a Main Char\n\tlbz\tr3,0x221F(r21)\n\trlwinm.\tr0, r3, 29, 31, 31\n\tbne\tRandomize_LeftorRightSide_GetNextPlayer\n\n\t#Check For Follower, r20 = External. r21 = Internal\n\t\tmr\tr3,r20\n\t\tbl\tCheckIfPlayerHasAFollower\n\t\tcmpwi\tr3,0x0\t\t\t\t\t#No Follower, Go To Next Player\n\t\tbeq\tRandomize_LeftorRightSide_GetNextPlayer\n\n\t\t#Transfer Info\n\t\t#Get Backups\n\t\taddi\tr3,r31,0x10\t\t#Get Backup Start\n\t\tlbz\tr4,0xC(r21)\t\t#Get Subchars Slot\n\t\tmulli\tr4,r4,0x8\t\t#Each Slot has 2 backups, so get to this slots backup\n\t\tadd\tr3,r3,r4\t\t#Each Slot has 2 backups, so get to this slots backup\n\n\t\t#Copy Main Char's Info Into Subchars\n\t\tlwz\tr4,0x0(r3)\t\t#Main Char Backup\n\t\tlwz\tr5,0x4(r3)\t\t#Follower Backup\n\t\tlwz\tr3,0xB0(r4)\t\t#Main Char X\n\t\tstw\tr3,0xB0(r5)\t\t#Into Subchar X\n\t\tlwz\tr3,0x2C(r4)\t\t#Main Char Facing\n\t\tstw\tr3,0x2C(r5)\t\t#Into Subchar Facing\n\t\tb\tRandomize_LeftorRightSide_GetNextPlayer\n\n\nRandomize_LeftorRightSide_Exit:\nrestore\nblr\n\n#********************************************#\n\nRandomize_AlwaysPositive:\nfabs\tf1,f1\t\t#Always Positive\nblr\n\nRandomize_AlwaysNegative:\nfabs\tf1,f1\nfneg\tf1,f1\t\t#Always Negative\nblr\n\n#********************************************#\n\n############################################\n\nIntToFloat:\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\nstfs  f2,0x38(r1)\n\nlis\tr0, 0x4330\nlfd\tf2, -0x6758 (rtoc)\nxoris\tr3, r3,0x8000\nstw\tr0,0xF0(sp)\nstw\tr3,0xF4(sp)\nlfd\tf1,0xF0(sp)\nfsubs\tf1,f1,f2\t\t#Convert To Float\n\nlfs  f2,0x38(r1)\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\nblr\n\n############################################\n\nGetDirectionInRelationToP1:\n#Get P1 Direction\nlfs\tf1,0xB0(r27)\nlfs\tf2,0xB0(r29)\nfsubs\tf1,f1,f2\nlfs\tf2, -0x6768 (rtoc)\nfcmpo\tcr0,f2,f1\nblt\t0xC\nli\tr3,1\nb\t0x8\nli\tr3,-1\nblr\n\n############################################\n\nIsAnyoneDead:\nbackup\n\nIsAnyoneDead_GetFirstPlayer:\nlwz\tr3, -0x3E74 (r13)\nlwz\tr20, 0x0020 (r3)\nb\tIsAnyoneDead_CheckIfPlayerExists\n\nIsAnyoneDead_GetNextPlayer:\nlwz\tr20,0x8(r20)\n\nIsAnyoneDead_CheckIfPlayerExists:\ncmpwi\tr20,0x0\nbne\tIsAnyoneDead_GetPlayerData\n#Exit If No Other Players\nli\tr3,0x0\nb\tIsAnyoneDead_Exit\n\nIsAnyoneDead_GetPlayerData:\nlwz\tr21,0x2C(r20)\n\n#Check If Follower\nlbz\tr3,0x221F(r21)\nrlwinm.\tr0,r3,0,28,28\nbne\tIsAnyoneDead_GetNextPlayer\n\n#Check If Dead\nlbz\tr3,0x221F(r21)\nrlwinm.\tr0,r3,0,25,25\nbeq\tIsAnyoneDead_GetNextPlayer\nli\tr3,0x1\nb\tIsAnyoneDead_Exit\n\nIsAnyoneDead_Exit:\n\nrestore\nblr\n\n############################################\n\nResetStaleMoves:\nbackup\n\nResetStaleMoves_GetFirstPlayer:\nlwz\tr3, -0x3E74 (r13)\nlwz\tr20, 0x0020 (r3)\nb\tResetStaleMoves_CheckIfPlayerExists\n\nResetStaleMoves_GetNextPlayer:\nlwz\tr20,0x8(r20)\n\nResetStaleMoves_CheckIfPlayerExists:\ncmpwi\tr20,0x0\nbne\tResetStaleMoves_GetPlayerData\n#Exit If No Other Players\nli\tr3,0x0\nb\tResetStaleMoves_Exit\n\nResetStaleMoves_GetPlayerData:\nlwz\tr21,0x2C(r20)\n\n#Reset Stale Moves\n#Get Stale Move Table\nlbz\tr3,0xC(r21)\t\t#Get Slot\nbranchl\tr12,0x80036244\t\t#Get This Players Stale Table\n\n#Fill With 0's\nli\tr4,0x2C\nbranchl\tr12,ZeroAreaLength\nb\tResetStaleMoves_GetNextPlayer\n\n\nResetStaleMoves_Exit:\n\nrestore\nblr\n\n############################################\n\nActOutOfLaserHitDisplay:\nbackup\n\n#Check If In Run\nlwz\tr3,0x10(r27)\ncmpwi\tr3,0x14\nbne\tActOutOfLaserHitDisplayExit\n\n#Check If Frame 2\nli\tr3,2\nbl\tIntToFloat\nlfs\tf2,0x894(r27)\nfcmpo\tcr0,f2,f1\nbne\tActOutOfLaserHitDisplayExit\n\n#Search Prev AS For Laser Hit, returns r3=AS's Since Laser Hit or -1 for didnt happen\nli\tr3,0x0\t\t#Number of AS's ago\naddi\tr4,r27,0x23F0\t\t#First Prev AS\nsubi\tr4,r4,0x2\nActOutOfLaserHitDisplay_SearchLoop:\naddi\tr3,r3,0x1\nlhzu\tr5,0x2(r4)\ncmpwi\tr5,0x4E\t\t#Laser Hit\nbeq\tActOutOfLaserHitDisplay_ExitLoop\ncmpwi\tr5,0x4B\t\t#Laser Hit\nbeq\tActOutOfLaserHitDisplay_ExitLoop\ncmpwi\tr3,0x3\nbeq\tActOutOfLaserHitDisplay_NoLaserHit\nb\tActOutOfLaserHitDisplay_SearchLoop\nActOutOfLaserHitDisplay_NoLaserHit:\nli\tr3,-1\nActOutOfLaserHitDisplay_ExitLoop:\ncmpwi\tr3,-1\nbeq\tActOutOfLaserHitDisplayExit\n\nActOutOfLaserHitDisplay_CountFrameInit:\n#Get Amount Of Frames Since Laser Hit Ended\n\tli\tr5,0x23FC\t\t#As's Frame Count offset\n\tli\tr20,0\t\t#Frames Since Laser Hit\nActOutOfLaserHitDisplay_CountFrameLoop:\n\tcmpwi\tr3,0\t\t#Check If Done Counting\n\tbeq\tActOutOfLaserHitDisplay_CountFrameLoopFinish\n\tmulli\tr4,r3,2\t\t#Frame Count Offset\n\tsubi\tr4,r4,0x2\t\t#1 AS Before\n\tadd\tr4,r4,r5\t\t#Get Offset in Playerblock\n\tlhzx\tr6,r4,r27\t\t#Get Frame Count Value\n\tsubi\tr4,r4,0xC\t\t#Get AS Associated With It\n\tlhzx\tr4,r4,r27\t\t#Get AS ID\n#Check If This AS is Turn\n\tcmpwi\tr4,0x12\n\tbeq\t0x8\n\tadd\tr20,r20,r6\t\t#Add To Toal\n\tcmpwi\tr4,0x4E\n\tbeq\tActOutOfLaserHitDisplay_SubtractHitstun\n\tcmpwi\tr4,0x4B\n\tbeq\tActOutOfLaserHitDisplay_SubtractHitstun\n\tb\tActOutOfLaserHitDisplay_SkipSubtractHitstun\nActOutOfLaserHitDisplay_SubtractHitstun:\n\tsubi\tr20,r20,0x8\nActOutOfLaserHitDisplay_SkipSubtractHitstun:\n\tsubi\tr3,r3,1\n\tb\tActOutOfLaserHitDisplay_CountFrameLoop\n\nActOutOfLaserHitDisplay_CountFrameLoopFinish:\n\nActOutOfLaserHitDisplay_DisplayOSD:\nmr\tr3,r27\t\t\t#p1 (no offsetting window)\nli\tr4,120\t\t\t#text timeout\nli\tr5,0\t\t\t#Area to Display (0-2)\nli\tr6,OSD.Miscellaneous\t\t\t#Window ID (Unique to This Display)\nbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\nmr\ttext,r3\t\t\t#backup text pointer\n\ncmpwi\tr20,0x1\nbeq\tActOutOfLaserHitDisplay_Perfect\nActOutOfLaserHitDisplay_Late:\nload\tr3,0xffa2baff\t\t\t#Red\nb\tActOutOfLaserHitDisplay_StoreTextColor\nActOutOfLaserHitDisplay_Perfect:\nload\tr3,0x8dff6eff\t\t\t#green\nActOutOfLaserHitDisplay_StoreTextColor:\nstw\tr3,0x30(text)\n\n\t#Create Text 1\n\tmr \tr3,text\t\t\t#text pointer\n\tbl\tActOutOfLaserHitDisplay_TopText\n\tmflr\tr4\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tbranchl r12,Text_InitializeSubtext\n\n\t#Create Text 2\n\tmr \tr3,text\t\t\t#text pointer\n\tbl\tActOutOfLaserHitDisplay_BottomText\n\tmflr\tr4\n\tmr\tr5,r20\t\t\t#Frame Count\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#default text X/Y\n\tbranchl r12,Text_InitializeSubtext\n\nActOutOfLaserHitDisplayExit:\nrestore\nblr\n\n#####################\n## Text Properties ##\n#####################\n\nActOutOfLaserHitDisplay_TextProperties:\nblrl\n\n.long 0xC1A80000 #Whether to Use HUD Location, 0 = no\n.long 0x41100000 #Y Value\n.long 0x41600000 #X Difference Between Players\n.long 0x3D23D70A\t#Text Size\n\n.long 0xC3CD0000 #background Y position\n.long 0x4129999A #background X stretch\n.long 0x41E00000 #background Y stretch\n\n##############\n## Top Text ##\n##############\n\nActOutOfLaserHitDisplay_TopText:\nblrl\n.long 0x44617368\n.long 0x204f6f4c\n.long 0x61736572\n.long 0x48697400\n\n\n#################\n## Bottom Text ##\n#################\n\nActOutOfLaserHitDisplay_BottomText:\nblrl\n.long 0x4672616d\n.long 0x65202564\n.long 0x\n\n############################################\n\nMoveCPU:\n#in\n#r3 = P1 GObj\n#r4 = P2 GObj\n#r5 = SaveState Struct\n\n.set P1GObj,31\n.set P1Data,30\n.set P2GObj,29\n.set P2Data,28\n.set SaveStateStruct,27\n.set P2Subchar,26\n.set P2SubcharData,25\n\nbackup\n\n#Get Variables\n  mr  P1GObj,r3\n  lwz P1Data,0x2C(P1GObj)\n  mr  P2GObj,r4\n  lwz P2Data,0x2C(P2GObj)\n  mr  SaveStateStruct,r5\n\n#Get Input\n  lbz\tr4, 0x0618 (P1Data)\n  load r3,InputStructStart\n  mulli\tr0, r4, 68\n  add\tr5, r0, r3\n\n#Check DPad Down\n\tlwz\tr3,0xC(r5)\n\trlwinm.\tr0,r3,0,29,29\n\tbeq\tMoveCPUExit\n#Make Sure Nothing Is Held\n\tlwz\tr3,0x0(r5)\n\tli\tr4,0\n\trlwimi r3,r4,0,29,29\t\t#except dpad down\n\trlwimi r3,r4,0,27,27\t\t#except Z (cause frame advance)\n\tcmpwi r3,0\n\tbne\tMoveCPUExit\n\n#Make Sure Player is Grounded\n  lwz r3,0xE0(P1Data)\n  cmpwi r3,0x0\n  bne MoveCPU_NoGroundFound\n\n#Get Position\n  li  r3,10\n  bl  IntToFloat          #Offset from P1\n  lfs f3,0xB0(P1Data)     #P1 X\n  lfs f2,0xB4(P1Data)     #P1 Y\n  lfs f4,0x2C(P1Data)     #Facing Direction\n  fmuls f1,f1,f4\n  fadds f1,f1,f3\n#Check If P2 Will Be Grounded\n  li  r3,0\n  bl  FindGroundNearPlayer\n  cmpwi r3,0    #Check if ground was found\n  beq MoveCPU_NoGroundFound\n  stfs f1,0xB0(P2Data)\n  stfs f2,0xB4(P2Data)\n  stw r4,0x83C(P2Data)\n  lfs f1,0x2C(P1Data)\n  fneg f1,f1\n  stfs f1,0x2C(P2Data)\n#Enter Wait\n  mr  r3,P2GObj\n  branchl r12,AS_Wait\n#Update Position\n  mr  r3,P2GObj\n  bl  UpdatePosition\n#Update ECB Values for the ground ID\n  mr r3,P2GObj\n  branchl r12,EnvironmentCollision_WaitLanding\n#Set Grounded\n  mr r3,P2Data\n  branchl r12,Air_SetAsGrounded\n\n#Check For Follower\n  mr  r3,P2GObj\n  bl  CheckIfPlayerHasAFollower\n  cmpwi r3,0\n  beq MoveCPU_NoFollower\n  mr P2Subchar,r3\n  mr P2SubcharData,r4\n#Init Player Data Values (So CPU Init is called and nana knows where popp is)\n  mr r3,P2Subchar\n  branchl r12,0x80068354\n#Copy Positions\n  lfs f1,0xB0(P2Data)\n  stfs f1,0xB0(P2SubcharData)\n  lfs f1,0xB4(P2Data)\n  stfs f1,0xB4(P2SubcharData)\n  lwz r3,0x83C(P2Data)\n  stw r3,0x83C(P2SubcharData)\n  lfs f1,0x2C(P2Data)\n  stfs f1,0x2C(P2SubcharData)\n#Enter Wait\n  mr  r3,P2Subchar\n  branchl r12,AS_Wait\n#Update Position\n  mr  r3,P2Subchar\n  bl  UpdatePosition\n#Update ECB Values for the ground ID\n  mr r3,P2Subchar\n  branchl r12,EnvironmentCollision_WaitLanding\n#Set Grounded\n  mr r3,P2SubcharData\n  branchl r12,Air_SetAsGrounded\n\nMoveCPU_NoFollower:\n#Savestate\n  mr  r3,SaveStateStruct\n\tli\tr4,1\t\t\t#Override failsafe code\n  bl  SaveState_Save\n#Play SFX\n  li r3,0xDD\n  bl  PlaySFX\n  b MoveCPUExit\n\nMoveCPU_NoGroundFound:\n#PLay Error SFX\n  li\tr3,0xAF\n  bl  PlaySFX\n\nMoveCPUNoSubchar:\nMoveCPUExit:\nrestore\nblr\n\n############################################\n\nAdjustResetDistance:\n.set SaveStateStruct,25\n.set P2Direction,3\n.set PlayerX,2\n.set P1X,31\n.set P2X,30\n\nbackup\n\nmr  SaveStateStruct,r3\n\n#Make Sure Nothing is Held\n  lhz\tr3,0x662(r27)\n  rlwinm.  r0,r3,0,27,27\n  bne 0xC\n  cmpwi r3,0x0\n  bne\tAdjustResetDistance_NoPress\n\n\n#Check For DPad Right\nAdjustResetDistance_CheckRightDPad:\n  lwz\tr3,0x668(r27)\t\t\t#Get DPad\n  rlwinm.\tr0,r3,0,30,30\n  beq\tAdjustResetDistance_CheckLeftDPad\n#Move Apart\n#Determine if P2 is to the left or right of P1 + Get X Pos Multiplier\n  bl  GetDirectionInRelationToP1\n  bl  IntToFloat\n  fmr P2Direction,f1\n#Load P1 Backup X Location\n  lwz\tr20,0x0(SaveStateStruct)\n  lfs\tPlayerX,0xB0(r20)\n#Add One in the correct direction\n  li\tr3,1\n  bl\tIntToFloat\n  fneg P2Direction,P2Direction\n  fmuls f1,f1,P2Direction\n  fadds\tP1X,f1,PlayerX           #New P1 X\n#Load P2 Backup X Location\n  lwz\tr21,0x8(SaveStateStruct)\n  lfs\tPlayerX,0xB0(r21)\n#Add One in the correct direction\n  li\tr3,1\n  bl\tIntToFloat\n  fneg P2Direction,P2Direction\n  fmuls f1,f1,P2Direction\n  fadds\tP2X,f1,PlayerX            #New P2 X\n#Check if already 30 Mm apart\n  fsubs f2,P1X,P2X\n  fabs f2,f2        #get abs distance from each other in f2\n  li\tr3,30\n  bl\tIntToFloat\n  fcmpo\tcr0,f2,f1\n  bge\tAdjustResetDistance_NoPress\n#Store Back To PlayerBlock\n  stfs\tP1X,0xB0(r20)\n  stfs\tP2X,0xB0(r21)\n  b\tAdjustResetDistance_WasPressed\n\n\n#Check For DPad Left\nAdjustResetDistance_CheckLeftDPad:\n  rlwinm.\tr0,r3,0,31,31\n  beq\tAdjustResetDistance_NoPress\n#Move Together\n#Determine if P2 is to the left or right of P1 + Get X Pos Multiplier\n  bl  GetDirectionInRelationToP1\n  bl  IntToFloat\n  fmr P2Direction,f1\n#Load P1 Backup X Location\n  lwz\tr20,0x0(SaveStateStruct)\n  lfs\tPlayerX,0xB0(r20)\n#Add One in the correct direction\n  li\tr3,1\n  bl\tIntToFloat\n  #fneg P2Direction,P2Direction\n  fmuls f1,f1,P2Direction\n  fadds\tP1X,f1,PlayerX           #New P1 X\n#Load P2 Backup X Location\n  lwz\tr21,0x8(SaveStateStruct)\n  lfs\tPlayerX,0xB0(r21)\n#Add One in the correct direction\n  li\tr3,1\n  bl\tIntToFloat\n  fneg P2Direction,P2Direction\n  fmuls f1,f1,P2Direction\n  fadds\tP2X,f1,PlayerX            #New P2 X\n#Check if already 10 Mm apart\n  fsubs f2,P1X,P2X\n  fabs f2,f2        #get abs distance from each other in f2\n  li\tr3,10\n  bl\tIntToFloat\n  fcmpo\tcr0,f2,f1\n  ble\tAdjustResetDistance_NoPress\n#Store Back To PlayerBlock\n  stfs\tP1X,0xB0(r20)\n  stfs\tP2X,0xB0(r21)\n  b\tAdjustResetDistance_WasPressed\n\n\nAdjustResetDistance_NoPress:\nli\tr3,-1\nb\tAdjustResetDistance_Exit\n\nAdjustResetDistance_WasPressed:\nli\tr3,1\n\nAdjustResetDistance_Exit:\nrestore\nblr\n############################################\n\nCheckForActiveHitboxes:\nbackup\n\nlwz\tr31,0x2C(r3)\n\nCheckForActiveHitboxes_InitLoop:\nli\tr29,0x0\n\nCheckForActiveHitboxes_LoopStart:\nlwz\tr0, 0x0914 (r31)\t\t\t#Check Hitbox Active Bool\ncmpwi\tr0,0x0\nbeq\tCheckForActiveHitboxes_NextHitbox\nli\tr3,0x1\nb\tCheckForActiveHitboxes_Exit\n\nCheckForActiveHitboxes_NextHitbox:\naddi\tr29,r29,1\naddi\tr31,r31,312\t\t\t#Next Hitbox Struct\ncmpwi\tr29,4\nblt\tCheckForActiveHitboxes_LoopStart\n\nCheckForActiveHitboxes_NoHitboxesActive:\nli\tr3,0x0\n\nCheckForActiveHitboxes_Exit:\n\nrestore\nblr\n\n#############################################\n\nEvent_ExitFunction:\nblrl\n\nbackup\n\n#Ensure No Contest/Retry\nlwz\tr3, -0x77C0 (r13)\nlbz\tr3, 0x053B (r3)\nrlwinm.\tr0, r3, 0, 25, 25\nbne\tEvent_ExitFunction_Exit\n\n#Update Event Score\nload\tr20,0x8045abf0\t\t#Current Event Info\n\n#Get High Score\nlbz\tr3,0x5(r20)\t\t#Event ID\nbranchl\tr12,0x8015cf5c\nmr\tr21,r3\t\t#Backup High Score\n\n#Check If Event Was Played Yet\nlbz\tr3,0x5(r20)\t\t#Event ID\nbranchl\tr12,0x8015cefc\ncmpwi\tr3,0x0\nbeq\tEvent_ExitFunction_SaveScore\n\n#Check If Greater\nlhz\tr3,-0x4ea6(r13)\t\t#Current Score\ncmpw\tr3,r21\nble\tEvent_ExitFunction_Exit\n\n#Store As New High Score\nEvent_ExitFunction_SaveScore:\nlbz\tr3,0x5(r20)\t\t#Event ID\nlhz\tr4,-0x4ea6(r13)\nbranchl\tr12,0x8015cf70\n\n#Set Event As Played\nlbz\tr3,0x5(r20)\t\t#Event ID\nbranchl\tr12,0x8015ceb4\n\nEvent_ExitFunction_Exit:\nrestore\nblr\n\n#############################################\n\nInitializeHighScore:\nbackup\n\n\n\t#Create HUD KO Counter\n\tli\tr3,0x0\n\tbranchl\tr12,0x802fa5bc\n\n\t#Init Score Count\n\tli\tr3,0x0\n\tstw\tr3,-0x4ea8(r13)\n\n\t#Store Exit Function\n\tbl\tEvent_ExitFunction\n\tmflr\tr3\n\tload\tr4,0x8046b6a0\n\tstw\tr3,0x2518(r4)\n\n\nrestore\nblr\n\n#############################################\n\nPerformAerialThink:\n#in\n#   r3    CPU Player Pointer\n#   r4    Pointer to dedicated memory to use\n#   r5    Attack to Perform (0 = Random, 1 = Fair, 2 = Nair, 3 = Dair)\n\n.set player,31\n.set playerdata,30\n.set variables,29\n.set frame,28\n.set aerialToPerform,27\n.set performAerial,0x00\n.set aerialAttack,0x01\n.set attackFrame,0x02\n\nbackup\n\n#Get player pointers and frame count\n  mr  player,r3                     #Get Player\n  lwz playerdata,0x2C(player)       #Get Playerdata\n  mr  variables,r4                  #Get Variable Memory\n  lfs\tf1,0x894(playerdata)          #Get Frames as Int\n  fctiwz\tf1,f1\n  stfd\tf1,0xF0(sp)\n  lwz\tframe,0xF4(sp)\n\tmr\taerialToPerform,r5\t\t\t\t\t\t#Aerial to perform\n\n#Check To Aerial\n  lbz r3,performAerial(variables)\n  cmpwi r3,0x0\n  bne PerformAerialThink_Exit\n\n#Check Which Action to Perform\n  lwz r3,0x10(playerdata)   #Get Action State\n\n#Branch To Think Functions\n  #During Wait\n    cmpwi r3,0xE\n    beq PerformAerialThink_DuringWait\n  #During Jump\n    cmpwi r3,0x19\n    beq PerformAerialThink_DuringJump\n    cmpwi r3,0x1A\n    beq PerformAerialThink_DuringJump\n  #During Attack\n    cmpwi r3,0x41\n    blt 0x10\n    cmpwi r3,0x45\n    bgt 0x8\n    b PerformAerialThink_DuringAttack\n  #During Landing\n\t  cmpwi r3,0x2A\n\t\tbeq\tPerformAerialThink_DuringLanding\n    cmpwi r3,0x46\n    blt 0x10\n    cmpwi r3,0x4A\n    bgt 0x8\n    b PerformAerialThink_DuringLanding\n\t#None of The Above\n\t\tb PerformAerialThink_Exit\n\n\n\nPerformAerialThink_DuringWait:\n  #Input Jump\n    li\tr3,0x800\n    stw\tr3,0x1A88(playerdata)\n  #Determine Which Aerial Attack To Do\n\t#Check To Randomize\n\t\tcmpwi aerialToPerform,0x0\n\t\tbeq PerformAerialThink_GetRandomAttack\n\t#Store Attack Chosen\n\t\tsubi\tr3,aerialToPerform,0x1\n\t\tstb r3,aerialAttack(variables)\n\t\tb\tPerformAerialThink_CheckForValidAttack\n\tPerformAerialThink_GetRandomAttack:\n    li\tr3,3\n  \tbranchl\tr12,HSD_Randi\n  \tstb r3,aerialAttack(variables)\n  #Determine Frame to Attack on\n  PerformAerialThink_CheckForValidAttack:\n    lwz r4,0x4(playerdata)      #get char ID\n    bl  PerformAerial_FrameData\n    mflr  r5\n    mulli\tr4,r4,0xC\t\t#Get Characters Offset\n    add\tr4,r4,r5\t\t#Get Characters Table Entry Start\n    mulli\tr3,r3,0x2\t\t#Move Frame Data is 0x2 Long\n    add\tr27,r3,r4\t\t#Get Moves Frame Data\n    lbz\tr4,0x0(r27)\t\t#First Possible Frame\n    lbz\tr5,0x1(r27)\t\t#Last Possible Frame\n    cmpwi\tr4,0x0\n    bne\tPerformAerialThink_GetRandomFrame\n    cmpwi\tr5,0x0\n    bne\tPerformAerialThink_GetRandomFrame\n  #Move Disabled For Char, Get a New One\n    b\tPerformAerialThink_GetRandomAttack\n  PerformAerialThink_GetRandomFrame:\n    sub\tr3,r5,r4\t\t#Get Amount of Possibilities\n    branchl\tr12,HSD_Randi\t\t#Get Random Frame\n    lbz\tr4,0x0(r27)\t\t#First Possible Frame\n    add\tr3,r3,r4\t\t#Adjust for First Possible Frame\n    stb\tr3,attackFrame(variables)\t\t#Store Frame to Attack on\n  b PerformAerialThink_Exit\n\nPerformAerialThink_DuringJump:\n  #Check To Attack\n    lbz r3,attackFrame(variables)\n    cmpw r3,frame\n    bne PerformAerialThink_InputFastfallAndLCancel\n\n  #Perform Attack\n    lbz\tr3,aerialAttack(variables)\t\t#Get Attack ID\n    cmpwi\tr3,0x0\n    beq\tPerformAerialThink_Fair\n    cmpwi\tr3,0x1\n    beq\tPerformAerialThink_Nair\n    cmpwi\tr3,0x2\n    beq\tPerformAerialThink_Dair\n\n    PerformAerialThink_Fair:\n      li\tr3,127\t\t            #Forward\n      lfs\tf1,0x2C(playerdata)\t\t#Facing Direction\n      fctiwz\tf1,f1\n      stfd\tf1,0xF0(sp)\n      lwz\tr4,0xF4(sp)\n      mullw\tr3,r3,r4\t\t         #Forward * facing direction\n      stb\tr3,0x1A8E(playerdata)\n      b\tPerformAerialThink_InputFastfallAndLCancel\n\n    PerformAerialThink_Nair:\n      li\tr3,0x100\n      stw\tr3,0x1A88(playerdata)\n      b\tPerformAerialThink_InputFastfallAndLCancel\n\n    PerformAerialThink_Dair:\n      li\tr3,-127\n      stb\tr3,0x1A8F(playerdata)\n      b\tPerformAerialThink_InputFastfallAndLCancel\n\nb PerformAerialThink_InputFastfallAndLCancel\n\nPerformAerialThink_DuringAttack:\nb PerformAerialThink_InputFastfallAndLCancel\n\nPerformAerialThink_DuringLanding:\n#Set Sequence as Over\n  li  r3,1\n  stb r3,performAerial(variables)\n  b PerformAerialThink_Exit\n\nPerformAerialThink_InputFastfallAndLCancel:\n#Input Fastfall\n\t#Check If Already FastFalling\n\t\tlbz\tr3,0x221A(playerdata)\n\t\trlwinm.\tr3,r3,0,28,28\n\t\tbne\tPerformAerialThink_InputLCancel\n  #Check If Falling\n    lfs\tf2,0x84(playerdata)\n    lfs\tf0, -0x76B0 (rtoc)\n    fcmpo\tcr0,f2,f0\n    bge\tPerformAerialThink_InputLCancel\n  #Check If Inputting A Nair\n    lwz\tr3,0x1A88(playerdata)\n    cmpwi\tr3,0x100\n    beq\tPerformAerialThink_InputLCancel\n  #Input Down to FF\n    li\tr3,-127\n    stb\tr3,0x1A8D(playerdata)\t\t#Analog Y\n\n  PerformAerialThink_InputLCancel:\n  #Spoof Mash L\n   li r3,0x1\n   stb r3,0x67F(playerdata)\n\nb PerformAerialThink_Exit\n\n#################################\n\nPerformAerial_FrameData:\nblrl\n#Mario\n.long 0x00040012\t\t#Fair and Nair\n.long 0x00100005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Fox\n.long 0x0009000A\t\t#Fair and Nair\n.long 0x00080005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Cptn Falcon\n.long 0x0006000E\t\t#Fair and Nair\n.long 0x00040005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#DK\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Kirby\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Bowser\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#link\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Sheik\n.long 0x10140018\t\t#Fair and Nair\n.long 0x00000005\t\t#Dar (was 0-A) and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Ness\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Peach\n.long 0x000D001A\t\t#Fair and Nair\n.long 0x000E0005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Popo\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Nana\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Pikachu\n.long 0x000C000F\t\t#Fair and Nair\n.long 0x00080005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Samus\n.long 0x00200020\t\t#Fair and Nair\n.long 0x080D0005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Yoshi\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Jiggs\n.long 0x00100010\t\t#Fair and Nair\n.long 0x00100005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#mewtwo\n.long 0x00050019\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Luigi\n.long 0x0017001B\t\t#Fair and Nair\n.long 0x00110005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Marth\n.long 0x00160013\t\t#Fair and Nair\n.long 0x00120005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Zelda\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#YLink\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Doc\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Falco\n.long 0x070B000D\t\t#Fair and Nair\n.long 0x000C0005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Pichu\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#GaW\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Ganon\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Roy\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n####################################\n\nPerformAerialThink_Exit:\n  restore\n  blr\n\n#####################################\nRandFloat:\n#in\n#r3 = Rand Float Lower Bound\n#r4 = Rand Float Upper Bound\n\nbackup\nstfs\tf31,0x80(sp)\n\nmr\tr31,r3\n\n#Get Random Upper Bound\n\tsub\tr3,r4,r31\n\tbranchl r12,HSD_Randi\n#Add Lower Bound\n\tadd\tr3,r3,r31\n#Convert to Float\n\tbl\tIntToFloat\n\tfmr\tf31,f1\n#Get Random Float\n\tbranchl r12,HSD_Randf\n\tfadds\tf1,f1,f31\n\nlfs\tf31,0x80(sp)\nrestore\nblr\n\n#####################################\nCustom_InterruptRebirthWait:\nblrl\n.set player,31\n.set playdata,30\n\nbackup\n\n#Get Pointers\n\tmr\tplayer,r3\n\tlwz\tplayerdata,0x2C(player)\n\n#Check For Aerial Jump\n\tmr\tr3,player\n\tbranchl r12,0x800cb870\n\tcmpwi r3,0x0\n\tbne Custom_InterruptRebirthWait_Exit\n\n#Ensure Stick Was Just Moved\n\tlbz\tr3, 0x0670 (playerdata)\n\tcmpwi r3,2\n\tbge\tCustom_InterruptRebirthWait_CheckJoystickDown\n#Check For Any X Joystick Push\n\tlwz\tr3, -0x514C (r13)\n\tlfs\tf0, 0x0024 (r3)\n\tlfs\tf1, 0x0620 (playerdata)\n\tfabs\tf1,f1\n\tfcmpo\tcr0,f1,f0\n\tcror\t2, 1, 2\n\tbeq\tCustom_InterruptRebirthWait_EnterFall\nCustom_InterruptRebirthWait_CheckJoystickDown:\n#Ensure Stick Was Just Moved\n\tlbz\tr3, 0x0671 (playerdata)\n\tcmpwi r3,4\n\tbge\tCustom_InterruptRebirthWait_Exit\n#Check For Down Joystick Push\n\tlwz\tr3, -0x514C (r13)\n\tlfs\tf0, 0x0090 (r3)\n\tfneg f0,f0\n\tlfs\tf1, 0x0624 (playerdata)\n\tfcmpo\tcr0,f1,f0\n\tblt\tCustom_InterruptRebirthWait_EnterFall\n\tb\tCustom_InterruptRebirthWait_Exit\n\nCustom_InterruptRebirthWait_EnterFall:\n#Enter Fall\n\tmr r3,player\n\tbranchl r12,AS_Fall\n\nCustom_InterruptRebirthWait_Exit:\n\trestore\n\tblr\n\n#####################################\nUpdatePosition:\n.set PlayerGObj,31\n.set PlayerData,30\n\nbackup\n\n#Backup Pointer\n  mr  PlayerGObj,r3\n  lwz PlayerData,0x2C(PlayerGObj)\n\n#Update Position (Copy Physics XYZ into all ECB XYZ)\n#X\n  lwz\tr3, 0x00B0 (PlayerData)\n  stw\tr3, 0x06F4 (PlayerData)\n  stw\tr3, 0x0700 (PlayerData)\n\tstw\tr3, 0x070C (PlayerData)\n\tstw\tr3, 0x0718 (PlayerData)\n#Y\n  lwz\tr3, 0x00B4 (PlayerData)\n  stw\tr3, 0x06F8 (PlayerData)\n  stw\tr3, 0x0704 (PlayerData)\n\tstw\tr3, 0x0710 (PlayerData)\n\tstw\tr3, 0x071C (PlayerData)\n#Z\n  lwz\tr3, 0x00B8 (PlayerData)\n  stw\tr3, 0x06FC (PlayerData)\n  stw\tr3, 0x0708 (PlayerData)\n\tstw\tr3, 0x0714 (PlayerData)\n\tstw\tr3, 0x0720 (PlayerData)\n#Update Collision Frame ID\n  lwz\tr3, -0x51F4 (r13)\n  stw r3, 0x728(PlayerData)\n\n  #branchl\tr12,0x80081b38     #Stopped using this because it deletes way too much ECB info\n  #branchl r12,0x80082a68      #Better than the above function, but all i need is to copy current position into the ECB previous values\n\n#Adjust JObj position (code copied from 8006c324)\n\tlwz r3,0x28(PlayerGObj)\t\t\t#get character model JObj\n\tlwz\tr4,0xB0(PlayerData)\t\t\t#get X\n\tstw r4,0x38(r3)\t\t\t\t\t\t\t#store X\n\tlwz\tr4,0xB4(PlayerData)\t\t\t#get Y\n\tstw r4,0x3C(r3)\t\t\t\t\t\t\t#store Y\n\tlwz\tr4,0xB8(PlayerData)\t\t\t#get Z\n\tstw r4,0x40(r3)\t\t\t\t\t\t\t#store Z\n#Dirty Sub\n\t#branchl r12,0x803732e8\n\n#Update Static Player Block Coords\n  lbz r3,0xC(PlayerData)\n  lbz\tr4, 0x221F (PlayerData)\n  rlwinm\tr4, r4, 29, 31, 31\n  addi  r5,PlayerData,176\n  branchl r12,0x80032828\n\nrestore\nblr\n\n#####################################\n\nGetGroundCenter:\n\n#in\n#r3 = Ground ID\n\n#Get Corner IDs from Ground ID\nmulli r0,r3,8\nlwz\tr5, -0x51E4 (r13)\nlwzx r5,r5,r0\nlhz r3,0x0(r5)\nlhz r4,0x2(r5)\n\n#Get Coordinates\nlwz r5, -0x51E8 (r13)\nmulli r3,r3,24\naddi  r3,r3,8\nadd  r3,r3,r5\nlfs f1,0x0(r3)    #Left X\nlfs f2,0x4(r3)    #Left Y\nmulli r4,r4,24\naddi  r4,r4,8\nadd  r4,r4,r5\nlfs f3,0x0(r4)    #Right X\nlfs f4,0x4(r4)    #Right Y\n\n#Get Center Value\nlfs f5,-0x4df0(rtoc)    #2f\nfadds f1,f1,f3\nfdivs f1,f1,f5          #Center X\nfadds f2,f2,f4\nfdivs f2,f2,f5          #Center Y\n\nblr\n\n####################################\n\nPlacePlayersCenterStage:\n\n#in\n#none\n\nbackup\n\n#Loop through players 1 and 2\n  .set count,27\n  .set player,26\n  .set playerdata,25\n  .set subchar,24\n  .set subchardata,23\n\n  li  count,0\n\nPlacePlayersCenterStage_Loop:\n#Get Player GObj\n  mr  r3,r27\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n#Check if exists\n  cmpwi r3,0x0\n  beq PlacePlayersCenterStage_IncLoop\n  mr  player,r3\n  lwz playerdata,0x2C(player)\n#Get Subchar Bool\n  bl CheckIfPlayerHasAFollower\n  mr  subchar,r3\n  mr  subchardata,r4\n#Call function to do heavy lifting\n  mr  r3,player\n  bl  PlacePlayersCenterStage_DoStuff\n#Check if subchar exits\n  cmpwi subchar,0\n  beq PlacePlayersCenterStage_IncLoop\n#Call function for this character\n  mr  r3,subchar\n  bl  PlacePlayersCenterStage_DoStuff\n#Next Player\nPlacePlayersCenterStage_IncLoop:\n  addi count,count,1\n  cmpwi count,6\n  blt PlacePlayersCenterStage_Loop\n  b PlacePlayersCenterStage_Exit\n\n#*****************************#\nPlacePlayersCenterStage_DoStuff:\n#in\n#r3 = player\n\n.set player,31\n.set playerdata,30\n.set constants,29\n\nbackup\n\n#Get Pointers\n  mr  player,r3\n  lwz playerdata,0x2C(r3)\n\n#Get Constants\n  bl  PlacePlayersCenterStage_Constants\n  mflr constants\n  lbz r3,0xC(playerdata)\n  mulli r3,r3,0x2\n  add constants,constants,r3\n\n#Initialize Player Data (Mainly for ICs so Nana knows where Popo is)\n  mr  r3,player\n  branchl r12,0x80068354\n\n#Get Stage's Ground ID\n  lwz\t\tr3,-0x6CB8 (r13)\t\t\t#External Stage ID\n  bl\t\tComboTraining_StartingGroundIDs\n  mflr  r4\n  mulli\tr3,r3,0x2\n  lhzx\tr3,r3,r4\n  bl  GetGroundCenter\n  fmr f30,f1\n  fmr f31,f2\n\n#Facing Directions\n  lbz r3,0x0(constants) #This players facing direction\n  extsb r3,r3\n  bl  IntToFloat\n  stfs f1,0x2C(playerdata)\n\n#Move Players\n  lbz r3,0x1(constants) #This players X offset\n  extsb r3,r3\n  bl  IntToFloat\n  fadds f2,f1,f30   #Player X = X+6\n  stfs f2,0xB0(playerdata)\n  stfs f31,0xB4(playerdata)\n\n#Enter into Wait\n  mr  r3,player\n  branchl r12,AS_Wait\n#Find Ground Below Player\n  mr  r3,player\n  bl  FindGroundNearPlayer\n  cmpwi r3,0    #Check if ground was found\n  beq PlacePlayersCenterStage_DoStuff_SkipGroundCorrection\n  stfs f1,0xB0(playerdata)\n  stfs f2,0xB4(playerdata)\n  stw r4,0x83C(playerdata)\n  PlacePlayersCenterStage_DoStuff_SkipGroundCorrection:\n#Update Position\n  mr  r3,player\n  bl  UpdatePosition\n#Update ECB Values for the ground ID\n  mr r3,player\n  branchl r12,EnvironmentCollision_WaitLanding\n#Set Grounded\n  mr r3,playerdata\n  branchl r12,Air_SetAsGrounded\n#Update Camera\n  mr r3,player\n  bl  UpdateCameraBox\n\nPlacePlayersCenterStage_DoStuff_Exit:\nrestore\nblr\n\n#*********#\n\nPlacePlayersCenterStage_Constants:\nblrl\n.byte 1,-6,-1,6\n.align 2\n#*********#\n\nPlacePlayersCenterStage_Exit:\nrestore\nblr\n\n#####################################\n\nFindGroundNearPlayer:\n#in\n#r3 = player GObj (optional)\n#f1 = X value\n#f2 = Y Value\n\n\n.set player,31\n.set playerdata,30\n\nbackup\nstfs f30,0x38(sp)\nstfs f31,0x3C(sp)\n\n#Check If Given Player GObj\n  cmpwi r3,0x0\n  bne FindGroundNearPlayer_GObjPassedIn\n\nFindGroundNearPlayer_CoordinatesPassedIn:\n#Backup Coords\n  fmr f30,f1\n  fmr f31,f2\n#Get 10f\n  li  r3,10\n  bl  IntToFloat\n#Get Bottom Coord\n  fmr f3,f30       #Bottom X is same as Top X\n  fsubs f4,f31,f1  #Bottom Y is Top Y - 1000\n#Move Top Coords Back\n  fmr f1,f30\n  fmr f2,f31\n  lfs\tf0, -0x7188 (rtoc)\n  fadds f2,f2,f0\n  b FindGroundNearPlayer_Continue\n\n\nFindGroundNearPlayer_GObjPassedIn:\n#Init Variables\n  mr  player,r3\n  lwz playerdata,0x2C(player)\n#Get Players X and Y+10\n  lfs f1,0xB0(playerdata)\n  lfs f2,0xB4(playerdata)\n  lfs\tf0, -0x7188 (rtoc)\n  fadds f2,f2,f0\n#Get Bottom Coord (X and Y-1000)\n  lfs f3,0xB0(playerdata)\n  lfs f4,0xB0(playerdata)\n  lfs\tf0,-0x71A8 (rtoc)\n  fsubs f4,f4,f0\n\nFindGroundNearPlayer_Continue:\n#Get Unk f5 argument\n  lfs\tf5, -0x7208 (rtoc)\n#Setup stack for return values\n  addi r3,sp,0x54   #(Returns Ground Coordinates\n  addi r4,sp,0x44   #(Returns Ground ID)\n  addi r5,sp,0x40   #(Returns Ground Type)\n  addi r6,sp,0x48   #(Returns Unk)\n#Unk arguments\n  li  r7,-1\n  li  r8,-1\n  li  r9,-1\n#Additional function pointer\n  li  r10,0\n#Call function\n  branchl r12,Raycast_GroundLine\n\n#Check if ground exists\n  cmpwi r3,0\n  beq FindGroundNearPlayer_Exit\n\n#Return Coordinates of ground below player\n  lfs f1,0x54(sp)\n  lfs f2,0x58(sp)\n  lwz r4,0x44(sp)\n\nFindGroundNearPlayer_Exit:\nlfs f30,0x38(sp)\nlfs f31,0x3C(sp)\nrestore\nblr\n\n#####################################\n\nFindGroundUnderCoordinate:\n#in\n#f1 = X value\n#f2 = Y Value\n\nbackup\nstfs f30,0x38(sp)\nstfs f31,0x3C(sp)\n\nFindGroundUnderCoordinate_CoordinatesPassedIn:\n#Backup Coords\n  fmr f30,f1\n  fmr f31,f2\n#Get 1000f\n  li  r3,1000\n  bl  IntToFloat\n#Get Bottom Coord\n  fmr f3,f30       #Bottom X is same as Top X\n  fsubs f4,f31,f1  #Bottom Y is Top Y - 1000\n#Move Top Coords Back\n  fmr f1,f30\n  fmr f2,f31\n\nFindGroundUnderCoordinate_Continue:\n#Get Unk f5 argument\n  lfs\tf5, -0x7208 (rtoc)\n#Setup stack for return values\n  addi r3,sp,0x54   #(Returns Ground Coordinates\n  addi r4,sp,0x44   #(Returns Ground ID)\n  addi r5,sp,0x40   #(Returns Ground Type)\n  addi r6,sp,0x48   #(Returns Unk)\n#Unk arguments\n  li  r7,-1\n  li  r8,-1\n  li  r9,-1\n  li  r10,0\n#Call function\n  branchl r12,Raycast_GroundLine\n\n#Check if ground exists\n  cmpwi r3,0\n  beq FindGroundUnderCoordinate_Exit\n\n#Return Coordinates of ground below player\n  lfs f1,0x54(sp)\n  lfs f2,0x58(sp)\n  lwz r4,0x44(sp)\n\nFindGroundUnderCoordinate_Exit:\nlfs f30,0x38(sp)\nlfs f31,0x3C(sp)\nrestore\nblr\n\n#####################################\nPlacePlayerOnGround:\nbackup\n\n.set REG_GObj,31\n.set REG_GObjData,30\n\n#Get Pointers\n\tmr\tREG_GObj,r3\n\tlwz REG_GObjData,0x2C(REG_GObj)\n\n#Find Ground Below Player\n  mr  r3,REG_GObj\n  bl  FindGroundNearPlayer\n  cmpwi r3,0    #Check if ground was found\n  beq PlacePlayerOnGround_SkipGroundCorrection\n  stfs f1,0xB0(REG_GObjData)\n  stfs f2,0xB4(REG_GObjData)\n  stw r4,0x83C(REG_GObjData)\n  PlacePlayerOnGround_SkipGroundCorrection:\n#Update Position\n  mr  r3,REG_GObj\n  bl  UpdatePosition\n#Update ECB Values for the ground ID\n  mr r3,REG_GObj\n  branchl r12,EnvironmentCollision_WaitLanding\n#Set Grounded\n  mr r3,REG_GObjData\n  branchl r12,Air_SetAsGrounded\n\nPlacePlayerOnGround_Exit:\n\trestore\n\tblr\n#####################################\nPlaySFX:\nbackup\n\nbranchl\t\tr12,SFX_PlaySoundAtFullVolume\n\nrestore\nblr\n#####################################\n\nUpdateCameraBox:\n#in\n#r3 = player\n\n.set player,31\n.set playerdata,30\n\nbackup\n\n#Get Pointer\n  mr  player,r3\n  lwz playerdata,0x2C(player)\n\n#Update Camera Box Position\n  mr  r3,player\n  branchl r12,Camera_UpdatePlayerCameraBoxPosition\n\n#Update Camera Box Direction Tween\n#  lwz r3,0x2C(player)\n#  branchl r12,0x80076064\n\n#Update Camera Box Direction Tween\n  lwz r3,0x890(playerdata)\n  lfs f1,0x40(r3)     #Leftmost Bound\n  stfs f1,0x2C(r3)    #Current Left Box Bound\n  lfs f1,0x44(r3)     #Rightmost Bound\n  stfs f1,0x30(r3)    #Current Right Box Bound\n\n#Correct Camera Position\n  branchl r12,Camera_CorrectPosition\n\nrestore\nblr\n\n#####################################\n\nGetAllPlayerPointers:\n\n#in\n#nothing\n\n#out\n#r3 = P1GObj\n#r4 = P1Data\n#r5 = P2GObj\n#r6 = P2Data\n#r7 = P3GObj\n#r8 = P3Data\n#r9 = P4GObj\n#r10 = P4Data\n\nbackup\n\n#Get Space to Store all Pointer to\n  addi r21,sp,0x40\n#Init Loop Count\n  li  r20,0\n\nGetAllPlayerPointers_Loop:\n#Get GObj\n  mr  r3,r20\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n#Check If Exists\n  cmpwi r3,0x0\n  li    r4,0      #Zero Data pointer just in case it doesnt exist\n  beq GetAllPlayerPointers_StoreToStack\n#Get Data\n  lwz r4,0x2C(r3)\n#Store Both to Stack\nGetAllPlayerPointers_StoreToStack:\n  mulli r5,r20,8\n  add r5,r5,r21\n  stw r3,0x0(r5)\n  stw r4,0x4(r5)\n\nGetAllPlayerPointers_IncLoop:\n  addi r20,r20,1\n  cmpwi r20,4\n  blt GetAllPlayerPointers_Loop\n\nGetAllPlayerPointers_LoadPointers:\n  lwz r3,0x00(r21)\n  lwz r4,0x04(r21)\n  lwz r5,0x08(r21)\n  lwz r6,0x0C(r21)\n  lwz r7,0x10(r21)\n  lwz r8,0x14(r21)\n  lwz r9,0x18(r21)\n  lwz r10,0x1C(r21)\n\nGetAllPlayerPointers_Exit:\nrestore\nblr\n\n#####################################\nRemoveFirstFrameInputs:\n\nRemoveFirstFrameInputs_GetFirstPlayer:\n  lwz\tr3, -0x3E74 (r13)\n  lwz\tr12, 0x0020 (r3)\n  b\tRemoveFirstFrameInputs_CheckIfPlayerExists\n\nRemoveFirstFrameInputs_GetNextPlayer:\n  lwz\tr12,0x8(r12)\n\nRemoveFirstFrameInputs_CheckIfPlayerExists:\n  cmpwi\tr12,0x0\n  beq\tRemoveFirstFrameInputs_Exit\n  lwz\tr5,0x2C(r12)\n\n#Remove Input Flag\n  lbz\tr0, 0x221D (r5)\n  li\tr3,0x1\n  rlwimi\tr0,r3,4,27,27\n  stb\tr0,0x221D (r5)\n#Store Current Input\n  lbz\tr4, 0x0618 (r5)\n  load r3,InputStructStart\n  mulli\tr0, r4, 68\n  add\tr3, r0, r3\n  lwz\tr0, 0 (r3)\n  stw\tr0, 0x065C (r5)\n  b\tRemoveFirstFrameInputs_GetNextPlayer\n\nRemoveFirstFrameInputs_Exit:\nblr\n\n#####################################\n\nInitializeMatch:\n\n.set REG_EventStruct,31\n.set REG_MatchStruct,30\n.set REG_CPUChoice,29\n.set REG_StageChoice,28\n.set REG_EventOSDs,27\n.set REG_PlayerStruct,26\n.set REG_UseSopo,25\n\n#Init\n\tbackup\n\tmr REG_EventStruct,r3\n\tmr REG_MatchStruct,r4\n\tmr REG_CPUChoice,r5\n\tmr REG_StageChoice,r6\n\tmr REG_EventOSDs,r7\n\tmr REG_UseSopo,r8\n\n#Check to override OSD Toggles\n\tlwz\tr4,-0x77C0(r13)\n\tlbz\tr3,0x1f2A(r4)\n\tcmpwi r3,1\n\tbeq InitializeMatch_SkipOSDOverride\n#Store Events FDD Toggles\n\tlwz\tr3,0x1F24(r4)\n\tor\tr3,r3,REG_EventOSDs\n\tstw\tr3,0x1F24(r4)\nInitializeMatch_SkipOSDOverride:\n\n#SPAWN 2 PLAYERS\n\tli\tr3,0x40\n\tstb\tr3,0x1(REG_EventStruct)\n\n#Make Copy of Struct\n\tli\tr3,32\n\tbranchl r12,HSD_MemAlloc\n\tmr REG_PlayerStruct,r3\n\tbl\tP2Struct\n\tmflr r4\n\tli\tr5,0x1C\n\tbranchl r12,memcpy\n#Store to P2 pointer in event struct\n\tstw REG_PlayerStruct,0x18(REG_EventStruct)\n\n#Store CPU\n\tcmpwi REG_CPUChoice,-1\n\tbeq InitializeMatch_StoreCSSCPU\n#Store this CPU\n\tstb\tREG_CPUChoice,0x0(REG_PlayerStruct)\n\tb\tInitializeMatch_StoreStage\nInitializeMatch_StoreCSSCPU:\n\tload\tr3,0x8043207c\t\t\t\t\t\t\t#get preload table\n\tlwz\tr4,0x18(r3)\t\t\t\t\t\t\t\t\t#get p2 character ID\n\tcmpwi\tr4,0x12\t\t\t\t\t\t\t\t\t\t#check if zelda\n\tbne\t0x8\n\tli\tr4,0x13\t\t\t\t\t\t\t\t\t\t\t#make zelda sheik\n\tstb\tr4,0x0(REG_PlayerStruct)\t\t#store chosen char\n\tlbz\tr6,0x1C(r3)\t\t\t\t\t\t\t\t\t#get p2 costume ID\n\tstb\tr6,0x3(REG_PlayerStruct)\t\t#store p2 costume ID\n\tli\tr5,0x1\t\t\t\t\t\t\t\t\t\t\t#make CPU controlled\n\tstb\tr5,0x1(REG_PlayerStruct)\n\nInitializeMatch_StoreStage:\n#Store Stage\n\tcmpwi REG_StageChoice,-1\n\tbeq InitializeMatch_StoreSSSStage\n#Store this Stage\n\tsth\tREG_StageChoice,0xE(REG_MatchStruct)\n\tb\tInitializeMatch_StoreStage_End\nInitializeMatch_StoreSSSStage:\n\tload\tr3,0x8043207c\t\t\t\t\t\t\t#get preload table\n\tlwz\tr3, 0x00C (r3)\n\tsth\tr3,0xE(REG_MatchStruct)\t\t\t#store chosen stage\nInitializeMatch_StoreStage_End:\n\nInitializeMatch_SwapInSopo:\n\tcmpwi REG_UseSopo,0\n\tbeq\tInitializeMatch_SwapInSopo_End\n#Swap P1 Character to Sopo\n\tlwz\tr4, -0x77C0 (r13)\n\taddi\tr4, r4, 1328\t\t#event mode match backup struct?\n\tlbz\tr3,0x2(r4)\t\t#P1 External ID\n\tcmpwi\tr3,0xE\n\tbne\tInitializeMatch_SwapInSopo_End\n\tli\tr3,0x20\n\tstb\tr3,0x2(r4)\t\t#Make SoPo\nInitializeMatch_SwapInSopo_End:\n\nInitializeMatch_Exit:\n\trestore\n\tblr\n\n#####################################\n\nGetDistance:\n\tlfs\tf3,0x0(r3)\t#X\n\tlfs\tf4,0x4(r3)  #Y\n\tlfs\tf5,0x0(r4)  #X\n\tlfs\tf6,0x4(r4)  #Y\n\tfsubs\tf1,f5,f3\n\tfsubs\tf2,f4,f6\n\tfmuls\tf1,f1,f1\n\tfmuls\tf2,f2,f2\n\tfadds\tf2,f1,f2\n\tfrsqrte\tf1,f2\n\tfmuls\tf1,f1,f2\n\tblr\n\n#####################################\n\nGetLedgeCoordinates:\n\n.set LedgeSide,20\n.set LedgeID,21\n.set Return,22\n\nbackup\n\n#Backup Ledge Choice (0 = Left, 1 = Right)\n  mr\tLedgeSide,r3\n  mr  Return,r4\n\n#Get Stage's Ledge IDs\n  lwz\t\tr3,-0x6CB8 (r13)\t\t\t#External Stage ID\n  bl\t\tLedgedashCliffIDs\n  mflr  r4\n  mulli\tr3,r3,0x2\n  lhzx\tr3,r3,r4\n#Get Requested Ledge\n\tcmpwi LedgeSide,0x0\n\tbeq\tGetLedgeCoordinates_GetLeftLedgeID\n\nGetLedgeCoordinates_GetRightLedgeID:\n  rlwinm\tLedgeID,r3,0,24,31\n#Get Ledge Coords (0x80 = X, 0x84 = Y)\n  mr  r3,LedgeID\n  mr \tr4,Return\n  branchl\tr12,Stage_GetRightOfLineCoordinates\n  b\tGetLedgeCoordinates_Exit\n\nGetLedgeCoordinates_GetLeftLedgeID:\n\trlwinm\tLedgeID,r3,24,24,31\n#Get Ledge Coords (0x80 = X, 0x84 = Y)\n  mr  r3,LedgeID\n  mr \tr4,Return\n  branchl\tr12,Stage_GetLeftOfLineCoordinates\n\tb\tGetLedgeCoordinates_Exit\n\nGetLedgeCoordinates_Exit:\n  restore\n  blr\n\n##########################################\nGetAngleBetweenPoints:\n.set REG_arctan,2\n.set REG_Constants,31\n\nbackup\n\n#Get Constants\n\tbl\tGetAngleBetweenPoints_Constants\n\tmflr REG_Constants\n\n#Get Values\n\tlfs f1,0x0(r3)\n\tlfs f2,0x4(r3)\n\tlfs f3,0x0(r4)\n\tlfs f4,0x4(r4)\n#Get slope ydelta / xdelta\n\tfsubs f5,f4,f2\n\tfsubs f6,f3,f1\n\tfdivs f1,f5,f6\n#atan\n\tbranchl r12,0x80022e68\n\tfmr REG_arctan,f1\n\n#Ensure above 0 and below 6.28319\nGetAngleBetweenPoints_CheckIfOver0:\n\tlfs f1,0x0(REG_Constants)\n\tfcmpo cr0,REG_arctan,f1\n\tbge GetAngleBetweenPoints_CheckIfUnder360\n#Add 180\n\tlfs f1,0x8(REG_Constants)\n\tfadds REG_arctan,REG_arctan,f1\n\tb\tGetAngleBetweenPoints_CheckIfOver0\nGetAngleBetweenPoints_CheckIfUnder360:\n\tlfs f1,0x4(REG_Constants)\n\tfcmpo cr0,REG_arctan,f1\n\tble GetAngleBetweenPoints_Under360\n#Add 180\n\tlfs f1,0x8(REG_Constants)\n\tfsubs REG_arctan,REG_arctan,f1\n\tb\tGetAngleBetweenPoints_CheckIfUnder360\nGetAngleBetweenPoints_Under360:\n\tfmr\tf1,REG_arctan\n\nGetAngleBetweenPoints_Exit:\nrestore\nblr\n\nGetAngleBetweenPoints_Constants:\nblrl\n.float 0\n.float 6.28319\n.float 3.14159\n\n##########################################\nEnterKnockback:\nbackup\n\n.set REG_GObj,31\n.set REG_GObjData,30\n.set REG_AngleLo,29\n.set REG_AngleHi,28\n.set REG_MagLo,27\n.set REG_MagHi,26\n.set REG_Angle,29\n.set REG_Magnitude,28\n\n#Backup Data\n\tmr\tREG_GObj,r3\n\tlwz REG_GObjData,0x2C(REG_GObj)\n\tmr\tREG_AngleLo,r4\n\tmr\tREG_AngleHi,r5\n\tmr\tREG_MagLo,r6\n\tmr\tREG_MagHi,r7\n\n#Random angle between\n\tsub\tr3,REG_AngleHi,REG_AngleLo\n\tbranchl r12,HSD_Randi\n\tadd REG_Angle,r3,REG_AngleLo\n#Cast to float\n\tmr\tr3,REG_Angle\n\tbl\tIntToFloat\n#Now in radians\n\tlfs\tf2, -0x7510 (rtoc)\n\tfmuls f1,f1,f2\n\tstfs f1,0x80(sp)\n\n#Random magnitude between X and Y\n\tmr\tr3,REG_MagLo\n\tmr\tr4,REG_MagHi\n\tbl\tRandFloat\n\tstfs f1,0x7C(sp)\t\t#will be used later for\n\tlwz\tr3, -0x514C (r13)\n\tlfs\tf0, 0x0100 (r3)\n\tfmuls f1,f1,f0\n\tstfs f1,0x84(sp)\n\n#Get X Component\n\tlfs f1,0x80(sp)\t\t#KB angle in radians\n\tbranchl r12,cos\n\tlfs f2,0x84(sp)\t\t#KB magnitude\n\tfmuls f1,f1,f2\n\tlfs f2,0x2C(REG_GObjData)\n\tfneg f2,f2\n\tfmuls f1,f1,f2\n\tstfs f1,0x8C(REG_GObjData)\n#Get Y Component\n\tlfs f1,0x80(sp)\t\t#KB angle in radians\n\tbranchl r12,sin\n\tlfs f2,0x84(sp)\t\t#KB magnitude\n\tfmuls f1,f1,f2\n\tstfs f1,0x90(REG_GObjData)\n\n#Calculate Hitstun\n\tlwz\tr3, -0x514C (r13)\n\tlfs\tf0, 0x0154 (r3)\n\tlfs f1,0x7C(sp)\n\tfmuls f1,f1,f0\t\t\t#hitstun frames is 0.4 * magnitude\n\tfctiwz f1,f1\t\t\t\t#Round down\n\tstfd f1,0x88(sp)\n\tlwz r3,0x8C(sp)\n\tbl\tIntToFloat\n\tstfs f1,0x2340(REG_GObjData)\n#Enable Hitstun Bit\n\tlbz r0,0x221C(REG_GObjData)\n\tli\tr3,1\n\trlwimi r0,r3,1,30,30\n\tstb r0,0x221C(REG_GObjData)\n\n#Enable ECB Update\n\tmr\tr3,REG_GObjData\n\tbranchl r12,0x8007d5bc\n\nEnterKnockback_Exit:\n\trestore\n\tblr\n\n##########################################\nDisableHazards:\n\n#Get list start\n\tbl\tDisableHazards_SkipList\n########################\nbl\tDisableHazards_Dummy\nbl\tDisableHazards_TEST\nbl\tDisableHazards_Izumi\nbl\tDisableHazards_Pstadium\nbl\tDisableHazards_Castle\nbl\tDisableHazards_Kongo\nbl\tDisableHazards_Zebes\nbl\tDisableHazards_Corneria\nbl\tDisableHazards_Story\nbl\tDisableHazards_Onett\nbl\tDisableHazards_MuteCity\nbl\tDisableHazards_RCruise\nbl\tDisableHazards_Garden\nbl\tDisableHazards_GreatBay\nbl\tDisableHazards_Shrine\nbl\tDisableHazards_Kraid\nbl\tDisableHazards_Yoster\nbl\tDisableHazards_Greens\nbl\tDisableHazards_Fourside\nbl\tDisableHazards_MK1\nbl\tDisableHazards_MK2\nbl\tDisableHazards_Akaneia\nbl\tDisableHazards_Venom\nbl\tDisableHazards_Pura\nbl\tDisableHazards_BigBlue\nbl\tDisableHazards_Icemt\nbl\tDisableHazards_Icetop\nbl\tDisableHazards_FlatZone\nbl\tDisableHazards_OldDL\nbl\tDisableHazards_OldYS\nbl\tDisableHazards_OldKongo\nbl\tDisableHazards_Battlefield\nbl\tDisableHazards_FinalDestination\n########################\nDisableHazards_SkipList:\n\tmflr r3\n\tlwz r4,StageID_External(r13)\n\tmulli\tr4,r4,4\n\tadd r4,r3,r4\n\tlwz r5,0x0(r4)\t\t\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t#Mask Bits 6-29 (the offset)\n\tcmpwi r5,0\t\t\t\t\t\t#If pointer is null, exit\n\tbeq\tDisableHazards_SkipList_Exit\n  add\tr4,r4,r5\t\t\t\t\t#Pointer to code now in r4\n\tmtctr r4\n\tbctr\n\n########################\n\nDisableHazards_Story:\n/*\n#Get randall's line ID\n\tmr\tr3,REG_map_gobj\n\tbranchl r12,0x801c6330\n\tlwz\tr3,0x4(r3)\t\t\t\t\t\t#get map_head\n\tlwz r3,0x8(r3)\t\t\t\t\t\t#get map_gobj info\n\tmulli\tr4,REG_map_gobj,52\t#get randall's info\n\tadd r3,r3,r4\n\tlwz r3,0x20(r3)\t\t\t\t\t\t#pointer to the collision data\n\tlhz r3,0x0(r3)\t\t\t\t\t\t#i believe this is randalls line ID\n#Get randalls corner IDs\n\tmulli r3,r3,8\t\t\t\t\t\t\t#0x8 in length\n\tlwz\tr4, -0x51E4 (r13)\t\t\t#line to corner ID table\n\tlwzx r5,r3,r4\t\t\t\t\t\t\t#now have the corner ID struct\n\tlhz r3,0x0(r5)\t\t\t\t\t\t#left corner id\n\tlhz r4,0x2(r5)\t\t\t\t\t\t#right corner id\n#Get corner IDs info\n\tlwz\tr5, -0x51E8 (r13)\n\tmulli r3,r3,24\n\tmulli r4,r4,24\n\tadd r3,r3,r5\n\tadd r4,r4,r5\n#Zero current X and Y positions, effectively removing these lines\n\tli\tr5,0\n\tstw r5,0x8(r3)\n\tstw r5,0xC(r3)\n\tstw r5,0x8(r4)\n\tstw r5,0xC(r4)\n*/\n\n/*\n#Get randall's map_gobj\n\tli\tr3,2\t\t\t\t#randalls map_gobj is 2\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,Stage_Destroy_map_gobj\n*/\n\n#Get shyguy's map_gobj\n\tli\tr3,3\t\t\t\t#shyguys map_gobj is\n\tbranchl r12,Stage_map_gobj_Load\n#Remove Proc\n\tbranchl r12,GObj_RemoveProc\n\n#Fix ragdoll issue\n\tbl\tDisableHazards_RagdollFix\n\nb\tDisableHazards_SkipList_Exit\n\n########################\n\nDisableHazards_Pstadium:\n#Get transformation's map_gobj\n\tli\tr3,2\t\t\t\t#transformation's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n#Remove Proc\n\tbranchl r12,GObj_RemoveProc\n#Fix ragdoll issue\n\tbl\tDisableHazards_RagdollFix\n\nb\tDisableHazards_SkipList_Exit\n\n########################\n\nDisableHazards_OldDL:\n#Destroy whispy's map_gobj\n\tli\tr3,7\t\t\t\t#transformation's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,Stage_Destroy_map_gobj\n\n#Destroy whispy's blink map_gobj proc\n\tli\tr3,6\t\t\t\t#transformation's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,GObj_RemoveProc\n\n#set wind hazard count to 0\n\tli\tr3,0\n\tstw\tr3,Stage_PositionHazardCount(r13)\n\nb\tDisableHazards_SkipList_Exit\n\n########################\n\nDisableHazards_OldYS:\n#Destroy cloud's map_gobj\n\tli\tr3,2\t\t\t\t#map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,Stage_Destroy_map_gobj\n\nb\tDisableHazards_SkipList_Exit\n\n########################\n\nDisableHazards_OldKongo:\n#Destroy barrel's map_gobj\n\tli\tr3,1\t\t\t\t#map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,Stage_Destroy_map_gobj\n\nb\tDisableHazards_SkipList_Exit\n\n########################\nDisableHazards_RagdollFix:\n#Certain stages have an essential ragdoll function\n#in their map_gobj think function. If the think function is removed,\n#the ragdoll function must be re-scheduled to function properly.\n\nbackup\n\n#Create GObj\n  li\tr3,3\t\t#GObj Type\n  li\tr4,5\t\t#On-Pause Function\n  li\tr5,0\n  branchl\tr12,GObj_Create\n#Schedule Task\n\tbl\tDisableHazards_RagdollFix_Think\n\tmflr r4\n  li\tr5,4\t\t#Priority\n  branchl\tr12,GObj_AddProc\n\tb\tDisableHazards_RagdollFix_Exit\n\n#********************************#\nDisableHazards_RagdollFix_Think:\nblrl\n\nbackup\n\nbranchl r12,Ragdoll_WindDecayThink\n\nrestore\nblr\n#********************************#\n\nDisableHazards_RagdollFix_Exit:\nrestore\nblr\n#########################\n\nDisableHazards_SkipList_Exit:\n\trestore\n\tblr\n###########################################\n\nPlaybackInputSequence:\n.set REG_PlayerData,31\n.set REG_InputSequence,30\n.set REG_AttackTimer,29\n\n#Input Sequence Struct\n.set InputSequence_Length,0x9\n.set InputSequence_Frame,0x0\n.set InputSequence_Buttons,0x1\n.set InputSequence_AnalogX,0x5\n.set InputSequence_AnalogY,0x6\n.set InputSequence_CStickX,0x7\n.set InputSequence_CStickY,0x8\n\nbackup\n\n#Backup args\n\tmr\tREG_PlayerData,r3\n\tmr\tREG_InputSequence,r4\n\tmr\tREG_AttackTimer,r5\n\nPlaybackInputSequence_Loop:\n#Search for this frames input in the sequence\n\tlbz r3,InputSequence_Frame(REG_InputSequence)\n#Check if end of sequence\n\textsb r0,r3\n\tcmpwi r0,-1\n\tbeq PlaybackInputSequenceExit\n#Check if this frame's input\n\tcmpw r5,r3\n\tbeq PlaybackInputSequence_PlayInput\n\tblt PlaybackInputSequenceExit\t\t\t\t\t\t#Check if the current frame is less than the parsed frame\n#If greater, continue parsing\n\taddi REG_InputSequence,REG_InputSequence,InputSequence_Length\n\tb PlaybackInputSequence_Loop\t\t\t\t\t\t#If greater, continue parsing\n\nPlaybackInputSequence_PlayInput:\n\tlwz r3,InputSequence_Buttons(REG_InputSequence)\n\tstw r3,CPU_HeldButtons(REG_PlayerData)\n\tlbz r3,InputSequence_AnalogX(REG_InputSequence)\n\tstb r3,CPU_AnalogX(REG_PlayerData)\n\tlbz r3,InputSequence_AnalogY(REG_InputSequence)\n\tstb r3,CPU_AnalogY(REG_PlayerData)\n\tlbz r3,InputSequence_CStickX(REG_InputSequence)\n\tstb r3,CPU_CStickX(REG_PlayerData)\n\tlbz r3,InputSequence_CStickY(REG_InputSequence)\n\tstb r3,CPU_CStickY(REG_PlayerData)\n\nPlaybackInputSequenceExit:\n\trestore\n\tblr\n\n###########################################\nPlaceOnLedge:\nbackup\n\n.set REG_LedgeID,31\n.set REG_P1GObj,30\n.set REG_P1Data,29\n\n#Backup pointers\nmr\tREG_P1GObj,r3\nlwz REG_P1Data,0x2C(REG_P1GObj)\nmr\tREG_LedgeID,r4\n\n#Get Stage's Ledge IDs\n\tlwz\t\tr3,-0x6CB8 (r13)\t\t\t#External Stage ID\n\tbl\t\tLedgedashCliffIDs\n\tmflr  r4\n\tmulli\tr3,r3,0x2\n\tlhzx\tr3,r3,r4\n#Get Requested Ledge\n\tcmpwi REG_LedgeID,0x0\n\tbeq\tPlaceOnLedge_GetLeftLedgeID\n\nPlaceOnLedge_GetRightLedgeID:\n\trlwinm\tr20,r3,0,24,31\n#Change Facing Direction\n\tli\tr3,-1\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n\tb\tPlaceOnLedge_StoreLedgeIDAndPosition\n\nPlaceOnLedge_GetLeftLedgeID:\n\trlwinm\tr20,r3,24,24,31\n#Change Facing Direction\n\tli\tr3,1\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n\tb\tPlaceOnLedge_StoreLedgeIDAndPosition\n\nPlaceOnLedge_StoreLedgeIDAndPosition:\n#Store Ledge to Player Block\n\tstw r20,0x2340(REG_P1Data)\n#Enter CliffWait\n\tmr\tr3,REG_P1GObj\n\tbranchl r12,AS_CliffWait\n#Init state variable (would be 1 at the start of the next frame if it ocurred naturally)\n\tli\tr3,1\n\tstw\tr3,0x2348(REG_P1Data)\n#Spoof in state for 1 frame\n\tli\tr3,1\n\tsth\tr3,FramesinCurrentAS(REG_P1Data)\n#Get Jump Back\n\tmr r3,REG_P1Data\n\tbranchl r12,Air_StoreBool_LoseGroundJump_NoECBfor10Frames\n#Set ECB Update Flag\n\tmr  r3,REG_P1Data\n\tbranchl r12,DataOffset_ECBBottomUpdateEnable\n#Update ECB Corner Positions\n\taddi\tr3,REG_P1Data,0x6F0\n\tbranchl\tr12,0x80048160\n#Move Player To Ledge\n\tmr\tr3,REG_P1GObj\n\tbranchl r12,MovePlayerToLedge\n#Update Position\n\tmr\tr3,REG_P1GObj\n\tbl UpdatePosition\n#Kill Velocity\n\tli\t\tr3,0x0\n\tstw\t\tr3,0x80(REG_P1Data)\t\t\t#X Velocity\n\tstw\t\tr3,0x84(REG_P1Data)\t\t\t#Y Velocity\n\n#Give Intangibility (30)\n\tmr\tr3,REG_P1GObj\n\tlwz\tr4, -0x514C (r13)\n\tlwz\tr4, 0x049C (r4)\n\tbranchl\tr12,ApplyIntangibility\n\n\trestore\n\tblr\n###########################################\nGetInputStruct:\n  load r4,InputStructStart\n  mulli\tr0, r3, 68\n  add\tr3, r0, r4\n\tblr\n\n###########################################\nexit:\nli\tr0, 3\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Custom Event Code - Rewrite.asm",
    "content": "#To be inserted at 801bb128\n.include \"../Globals.s\"\n.include \"../../m-ex/Header.s\"\n\n# Check if event is legacy (no file)\n  lwz r3,MemcardData(r13)\n  lbz r3,CurrentEventPage(r3)\n  mr\tr4,r25\t\t\t\t\t\t\t\t\t#event\n  mr\tr5,r26\t\t\t\t\t\t\t\t\t#match struct\n  rtocbl\tr12,TM_GetEventFile\n  cmpwi r3,0\n  beq LegacyEvent\n\t\n#Branch to C function to initialize the event\n  lwz r3,MemcardData(r13)\n  lbz r3,CurrentEventPage(r3)\n  mr\tr4,r25\t\t\t\t\t\t\t\t\t#event\n  mr\tr5,r26\t\t\t\t\t\t\t\t\t#match struct\n  rtocbl\tr12,TM_EventInit\n  branch\tr12,0x801bb738\n\nLegacyEvent:\n#r25 = event ID\n#r26 = final match struct\n#r28 = same as r26\n#r29 = event struct index (0x0 of this, then 0x8 of that to get the specifics)\n\n#region Event and Menu GObj Data Structs\n#Event GObj Data Struct\n.set EventData_DataSize,0x50\n.set EventData_MenuDataPointer,(EventData_DataSize-0x4)\n.set EventData_SaveStateStruct,0x10\n\n#Menu GObj Data Struct\n.set MenuData_DataSize,0x50\n.set MenuData_EventDataPointer,(MenuData_DataSize-0x4)\n.set MenuData_WindowOptionCountPointer,0x0\n.set MenuData_ASCIIStructPointer,0x4\n.set MenuData_OptionMenuMemory,0x8\n.set MenuData_OptionMenuToggled,0x28\n#endregion\n\n#region Init Custom Event\n#################\n## Custom Code ##\n#################\n\n#all registers free\n\n\t#1 PLAYER, NO ITEMS, TIME COUNTING UP\n\tlwz\tr9,0x0(r29)\t\t#get event pointers\n\n\t#ZERO OUT p2-p6 STRUCT\n\tli\tr4,0x0\n\tstw\tr4,0x18(r9)\n\tstw\tr4,0x1C(r9)\n\tstw\tr4,0x20(r9)\n\tstw\tr4,0x24(r9)\n\tstw\tr4,0x28(r9)\n\n\t#Disable All-Star Flag\n\tli\tr3,0x0\n\tstb\tr3,0x0(r9)\n\n\t#P1 = Choose Char + Normal Modifiers\n\tbl\tP1Struct\n\tmflr\tr3\n\tstw\tr3,0x14(r9)\n\n\t#STORE MATCH SETTINGS\n\tload\tr3,0x0BB0027C\t\t#HUD and timer behavior\n\tstw\tr3,0x0(r26)\n\tload\tr3,0x90800000\n\tstw\tr3,0x4(r26)\t\t#think functions\n\tli\tr3,0xFF\n\tstb\tr3,0xB(r26)\t\t#items to none\n\tli\tr3,0x0\n\tstw\tr3,0x10(r26)\t\t#time amount\n\n\t#STORE UNLIM STOCKS\n\tli\tr3,0xFF\n\tstb\tr3,0x62(r26)\t\t#p1 stocks\n\n\t#SET FALL FLAG\n\tli\tr3,0x0\n\tstb\tr3,0x6C(r26)\n\n  #SET FFA FLAG\n  li  r3,0\n  stb r3,0x8(r26)\n\n  #Store SSS Stage\n  load\tr3,0x80497758\n  lha\tr4, 0x001E (r3)\n  sth\tr4,0xE(r26)\n\n#Get Event Code\n  bl  SkipPageList\n\n##### Page List #######\n\tEventJumpTable\n#######################\nMinigames:\nbl\tEggs\nbl\tMultishine\nbl\tReaction\nbl\tLedgeStall\n.long -1\n#######################\nGeneralTech:\nbl\tTrainingLab\nbl\tLCancel\nbl\tLedgedash\nbl\t0x0\t# wavedash\nbl\tComboTraining\nbl\tAttackOnShield\nbl\tReversal\nbl\tSDITraining\nbl\tPowershield\nbl\tLedgetech\nbl\tAmsahTech\nbl\tShieldDrop\nbl\tWaveshineSDI\nbl\tSlideOff\nbl\tGrabMashOut\n.long -1\n#######################\nSpacieTech:\nbl  LedgetechCounter\nbl\tArmadaShine\nbl\tSideBSweetspot\nbl\tEscapeSheik\n.long -1\n#######################\n\nSkipPageList:\n#Get Page Jump Table\n  mflr\tr4\t\t#Jump Table Start in r4\n#Get Current Page\n  lwz r3,MemcardData(r13)\n  lbz r3,CurrentEventPage(r3)\n  mulli\tr5,r3,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n  add\tr4,r4,r5\t\t#Gets ASCII Address in r4\n#Get Event Code Pointer\n  mulli\tr5,r25,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n\tcmpwi r5,-1\n\tbeq\tEventNoExist\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n  add\tr4,r4,r5\t\t#Gets ASCII Address in r4\n  mtctr\tr4\n  bctr\n\nEventNoExist:\n\tb\texit\n#endregion\n\n###############\n## Minigames ##\n###############\n\n#region Eggs-ercise\n#########################\n## Eggs-ercise HIJACK INFO ##\n#########################\n\nEggs:\n\n#COUNT DOWN TIME\n\tli\tr3,0x6\n\tstb\tr3,0x0(r26)\n\n#1 Minute On the Clock\n\tli\tr3,60\n\tstw\tr3,0x10(r26)\n\n#Store Match Type to READY, GO!\n\tli\tr3,0x80\n\tstb\tr3,0x1(r26)\n\n#SET EVENT TYPE TO KOs\n\tload\tr5,0x8045abf0\t\t#Static Match Struct\n\tlbz\tr3,0xB(r5)\t\t#Get Event Score Behavior Byte\n\tli\tr4,0x0\n\trlwimi\tr3,r4,1,30,30\t\t#Zero Out Time Bit\n\tstb\tr3,0xB(r5)\t\t#Set Event Score Behavior Byte\n\n#1 Player\n\tlwz r4,0x0(r29)\n\tli\tr3,0x20\n\tstb\tr3,0x1(r4)\n\n#STORE THINK FUNCTION\n\tbl\tEggsLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Eggs-ercise LOAD FUNCT ##\n\t########################\n\tEggsLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n    #r3 = function to run each frame\n    #r4 = priority\n    #r5 = pointer to Window and Option Count\n    #r6 = pointer to ASCII struct\n\tbl\tEggsThink\n\tmflr\tr3\n\tli\tr4,9\t\t#Priority (After Interrupt)\n  bl\tEggsWindowInfo\n  mflr\tr5\n  bl\tEggsWindowText\n  mflr\tr6\n\tbl\tCreateEventThinkFunction\n\n\tbl\tInitializeHighScore\n\n\tb\tEggsLoadExit\n\n\n\t\t#########################\n\t\t## Eggs-ercise THINK FUNCT ##\n\t\t#########################\n\n    #Registers\n    .set EventData,31\n    .set MenuData,26\n    .set P1Data,27\n    .set P1GObj,28\n\n    #Offsets\n\t\t.set\tDamageThreshold,(MenuData_OptionMenuMemory+0x2) +0x0\n\t\t.set\tDamageThresholdToggled,(MenuData_OptionMenuToggled) +0x0\n\n\t\tEggsThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#Get and Backup Event Data\n\t\tmr\tr30,r3\t\t\t#r30 = think entity\n\t\tlwz\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n    lwz MenuData,EventData_MenuDataPointer(EventData)\n\n\t\t#Get Player Data\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n\n\t\t#No Staling\n\t\tbl\tResetStaleMoves\n\n\t\t#Check If Free Practice\n\t\tlbz\tr3,0x5(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tEggsSkipFreePracticeCheck\n\t\t#Check DPad Down\n\t\tlwz\tr0,0x668(r27)\n\t\trlwinm.\tr0,r0,0,29,29\n\t\tbeq\tEggsSkipFreePracticeCheck\n\t\t#Toggle Free Practice On\n\t\tli\tr3,0x1\n\t\tstb\tr3,0x5(r31)\n\t\t#Timer Now Counts Up\n\t\tload\tr3,0x8046b6a0\n\t\tlbz\tr0,0x24C8(r3)\n\t\tli\tr4,1\n\t\trlwimi\tr0,r4,0,31,31\n\t\tstb\tr0,0x24C8(r3)\n\t\t#Play Sound To Indicate\n\t\tli\tr3,0x82\n\t\tbranchl\tr12,SFX_PlaySoundAtFullVolume\n\t\tEggsSkipFreePracticeCheck:\n\n    #Check If Toggled\n      lbz r3,DamageThresholdToggled(MenuData)\n\t\t  cmpwi\tr3,0x0\n\t\t  beq\tEggsSkipToggleCheck\n\t\t#Check If Already Free Practice\n\t\t  lbz\tr3,0x5(r31)\n\t\t  cmpwi\tr3,0x0\n\t\t  bne\tEggsSkipToggleCheck\n\t\t#Make Free Practice\n\t\t  li\tr3,0x1\n\t\t  stb\tr3,0x5(r31)\n\t\t#Timer Now Counts Up\n\t\t  load\tr3,0x8046b6a0\n\t\t  lbz\tr0,0x24C8(r3)\n\t\t  li\tr4,1\n\t\t  rlwimi\tr0,r4,0,31,31\n\t\t  stb\tr0,0x24C8(r3)\n\t\t#Play Sound To Indicate\n\t\t  li\tr3,0x82\n\t\t  branchl\tr12,SFX_PlaySoundAtFullVolume\n    EggsSkipToggleCheck:\n\n\t\t#Check For First Frame\n\t\tlbz\tr3,0x4(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tEggsNotFirstFrame\n\n\t\t\t#Check If Player Can Move\n\t\t\tli\tr3,0x0\n\t\t\tbranchl\tr12,PlayerBlock_LoadMainCharDataOffset\t #get player block\n\t\t\tlwz\tr3,0x2c(r3)\t\t#player data in r29\n\n\t\t\tlbz\tr3,0x221D(r3)\n\t\t\trlwinm.\tr3,r3,0,28,28\n\t\t\tbne\tEggsThinkExit\n\n\t\t\t#Set First Frame Over\n\t\t\tli\tr3,0x1\n\t\t\tstb\tr3,0x4(r31)\n\t\t\tEggsNotFirstFrame:\n\n\t\t#Check If Target is Spawned\n\t\tEggsTargetCheck:\n    #Check If Pointer is Stored\n\t\t  lwz\tr3,0x0(r31)\n\t\t  cmpwi\tr3,0x0\n\t\t  beq\tEggsThinkSpawn\n    #Check if Item GObj is live\n      lwz r3,0x2C(r3)\n      cmpwi r3,0x0\n      beq EggsThinkSpawn\n      b   EggsThinkSkipSpawn\n\n################\n# Spawn Target #\n################\n\n.set LeftCameraBound,20\n.set RightCameraBound,21\n.set TopCameraBound,22\n.set BottomCameraBound,23\n\n    EggsThinkSpawn:\n    .if debug==1\n      li r24,0      #Init loop count\n    .endif\n\n    EggsThinkSpawnLoop:\n\n    .if debug==1\n      addi r24,r24,1  #Inc Loop Count\n    .endif\n\n    #Get OnScreen Boundaries\n    #Left Camera\n      branchl r12,StageInfo_CameraLimitLeft_Load\n      fctiwz f1,f1\n      stfd f1,0x80(sp)\n      lwz LeftCameraBound,0x84(sp)\n    #Right Camera\n      branchl r12,StageInfo_CameraLimitRight_Load\n      fctiwz f1,f1\n      stfd f1,0x80(sp)\n      lwz RightCameraBound,0x84(sp)\n    #Top Camera\n      branchl r12,StageInfo_CameraLimitTop_Load\n      fctiwz f1,f1\n      stfd f1,0x80(sp)\n      lwz TopCameraBound,0x84(sp)\n    #Bottom Camera\n      branchl r12,StageInfo_CameraLimitBottom_Load\n      fctiwz f1,f1\n      stfd f1,0x80(sp)\n      lwz BottomCameraBound,0x84(sp)\n\n    #Get Random Velocity\n\t\t\tbranchl\tr12,HSD_Randf\n      fmr f20,f1\n      li  r3,2\n      bl  IntToFloat\n      fadds f20,f20,f1\n\n    #Get Random X Value Between These\n      mr  r3,LeftCameraBound\n      mr  r4,RightCameraBound\n      bl  RandFloat\n      fmr f21,f1\n\n    #Get Random Y Value Between These\n      mr   r3,BottomCameraBound\n      subi  r4,TopCameraBound,70        #Minus 40 so it doesnt fly up offscreen\n      bl  RandFloat\n      fmr f22,f1\n\n    .set EggSpawnGroundWidth,8\n    #Check If Egg is Above Ground\n      fmr f1,f21\n      fmr f2,f22\n      bl  FindGroundUnderCoordinate\n      cmpwi r3,0x0\n      beq EggsThinkSpawnLoop\n    #Check Left\n      li  r3,EggSpawnGroundWidth\n      bl  IntToFloat\n      fsubs f1,f21,f1\n      fmr f2,f22\n      bl  FindGroundUnderCoordinate\n      cmpwi r3,0x0\n      beq EggsThinkSpawnLoop\n    #Check Right\n      li  r3,EggSpawnGroundWidth\n      bl  IntToFloat\n      fadds f1,f21,f1\n      fmr f2,f22\n      bl  FindGroundUnderCoordinate\n      cmpwi r3,0x0\n      beq EggsThinkSpawnLoop\n\n    .if debug==1\n      #OSReport Loop Count\n        load r3,0x803ead3c\n        mr r4,r24\n        branchl r12,OSReport\n    .endif\n\n\t\t\tSpawnEgg:\n\t\t\taddi\tr3,sp,0x80\n\t\t\tli\tr4,0x0\n\t\t\tstw\tr4,0x0(r3)\t#Player Pointer\n\t\t\tstw\tr4,0x4(r3)\t#Player Pointer\n\t\t\tli\tr4,0x03\n\t\t\tstw\tr4,0x8(r3)\t#Item ID\n\t\t\tlfs\tf0, -0x2858 (rtoc)\n\t\t\tstfs\tf21,0x14(r3)\t#X Coord\n\t\t\tstfs\tf22,0x18(r3)\t#Y Coord\n\t\t\tstfs\tf0,0x1C(r3)\t#Z Coord\n\t\t\tstfs\tf21,0x20(r3)\t#X Coord\n\t\t\tstfs\tf22,0x24(r3)\t#Y Coord\n\t\t\tstfs\tf0,0x28(r3)\t#Z Coord\n\t\t\tstfs\tf0,0x2C(r3)\t#Unk\n\t\t\tstfs\tf0,0x30(r3)\t#Unk\n\t\t\tstfs\tf0,0x34(r3)\t#X Vel\n\t\t\tstfs\tf0,0x38(r3)\t#Y Vel\n\t\t\tli\tr4,0x1\n\t\t\tsth\tr4,0x3C(r3)\n\t\t\tbranchl\tr12,EntityItemSpawn\n\t\t\tmr\tr29,r3\t\t#Backup Entity Pointer\n\n\t\t\tstw\tr29,0x0(r31)\t\t#Store Pointer To Target In Event Think\n\n\t\t\t#Store Pointer To Event Think In Target\n\t\t\tlwz\tr4,0x2C(r29)\n\t\t\tstw\tr31,0xDDC(r4)\n\n\t\t\t#Store Y Velocity\n\t\t\tstfs\tf20,0x44(r4)\n\n\t\t\t#Get OnDestroy\n\t\t\tlwz\tr4,0x2C(r29)\n\t\t\tlwz\tr4,0xB8(r4)\n\n\t\t\t#Store OnCollision\n\t\t\tbl\tEggs_OnCollision\n\t\t\tmflr\tr3\n\t\t\tstw\tr3,0x1C(r4)\n\n\t\t\t#Create Camera Box\n\t\t\tbranchl\tr12,CreateCameraBox\n\t\t\t#Attach to Entity\n\t\t\tlwz\tr4,0x2c(r29)\n\t\t\tstw\tr3, 0x0520 (r4)\n\t\t\t#Enable Camera Box Bit\n\t\t\tlbz\tr0, 0x0DCD (r4)\n\t\t\tli\tr5,0x22\n\t\t\trlwimi\tr0, r5, 5, 24, 25\n\t\t\tstb\tr0, 0x0DCD (r4)\n\t\t\t#Copy Some Stuff To Camera Box\n\t\t\tlwz\tr4, -0x4978 (r13)\n\t\t\tlfs\tf0, 0x014C (r4)\n\t\t\tstfs\tf0, 0x0040 (r3)\n\t\t\tlfs\tf0, 0x0150 (r4)\n\t\t\tstfs\tf0, 0x0044 (r3)\n\t\t\tlfs\tf0, 0x0154 (r4)\n\t\t\tstfs\tf0, 0x0048 (r3)\n\t\t\tlfs\tf0, 0x0158 (r4)\n\t\t\tstfs\tf0, 0x004C (r3)\n\n\t\t\t#Never Timeout\n\t\t\tlwz\tr5, 0x002C (r29)\n\t\t\tlbz\tr3,0xDD0(r5)\n\t\t\tli\tr4,0x1\n\t\t\trlwimi\tr3,r4,4,27,27\n\t\t\tstb\tr3,0xDD0(r5)\n\n\t\t\t#Not Grabbable\n\t\t\tlbz\tr3, 0x0DCA (r5)\n\t\t\tli\tr4,0x0\n\t\t\trlwimi\tr3,r4,2,29,29\n\t\t\tstb\tr3, 0x0DCA (r5)\n\n\t\t\t#Un-Nudgeable?\n\t\t\tlbz\tr3, 0x0DCB (r5)\n\t\t\tli\tr4,0x0\n\t\t\trlwimi\tr3,r4,3,28,28\n\t\t\tstb\tr3, 0x0DCB (r5)\n\n      EggsThinkSkipSpawn:\n      #Not Grabbable Every Frame\n      lwz\tr5,0x0(r31)\n      lwz\tr5,0x2c(r5)\n      lbz\tr3, 0x0DCA (r5)\n      li\tr4,0x0\n      rlwimi\tr3,r4,2,29,29\n      stb\tr3, 0x0DCA (r5)\n\n      #Update HUD Score\n      li\tr3,0\n      li\tr4,5\n      branchl\tr12,Playerblock_LoadTimesR3KilledR4\n      branchl\tr12,HUD_KOCounter_UpdateKOs\n\n      #Check If Free Practice\n        lbz\tr3,0x5(r31)\n        cmpwi\tr3,0x0\n        bne\tEggsThinkExit\n      #Check For TimeUp\n        branchl\tr12,MatchInfo_LoadSeconds\t\t#Seconds Left\n        cmpwi\tr3,0x0\n        bne\tEggsThinkExit\n        branchl\tr12,MatchInfo_LoadSubSeconds\t\t#Sub-Seconds Left\n        cmpwi\tr3,59\n        bne\tEggsThinkExit\n      #On Event End\n        mr\tr3,r30\n        branchl\tr12,EventMatch_OnWinCondition\t\t\t#EventMatch_OnWinCondition\n\nEggsThinkExit:\n  mr  r3,MenuData\n  bl  ClearToggledOptions\n  restore\n  blr\n\n\n\t\t\tEggs_OnCollision:\n\t\t\tblrl\n\n      #First check if this is an event\n        load r4,SceneController\n        lbz r4,Scene.CurrentMajor(r4)\n        cmpwi r4,Scene.EventMode\n        bne Eggs_OnCollisionOriginalFunction\n      #Now check if its eggs-ercise\n        lwz\tr4, -0x77C0 (r13)\n        lbz\tr4, 0x0535 (r4)         #get event ID\n        cmpwi r4,Event_Eggs\n        beq Eggs_OnCollisionStart\n\n      Eggs_OnCollisionOriginalFunction:\n      #Go to the original egg break function\n        branch r12,ItemCollision_Egg\n\n      Eggs_OnCollisionStart:\n  \t\t\tbackup\n  \t\t\tmr\tr30,r3\n  \t\t\tlwz\tr31,0x2C(r3)\t\t\t#Get Data\n\n\t\t\t#Check If Any Attack Should Break\n  \t\t\tlwz\tr3,0xDDC(r31)\t\t\t         #Get Event Data\n        lwz r3,EventData_MenuDataPointer(r3)     #Get Menu Data\n  \t\t\tlbz\tr3,DamageThreshold(r3)\t\t\t#Damage Behavior\n  \t\t\tcmpwi\tr3,0x1\n  \t\t\tbeq\tEggs_OnCollisionBreakEgg\n\t\t\t#Check Damage Dealt Before Exploding\n  \t\t\tlwz\tr3,0xCA0(r31)\n  \t\t\tcmpwi\tr3,11\n  \t\t\tblt\tEgg_OnCollisionExit\n\n\t\t\tEggs_OnCollisionBreakEgg:\n\t\t\t#Increment Score\n  \t\t\tli\tr3,0\n  \t\t\tli\tr4,0\n  \t\t\tli\tr5,5\n  \t\t\tbranchl\tr12,Playerblock_StoreTimesR3KilledR4\n\n\t\t\t#Display Effect\n  \t\t\tli\tr3,1232\n  \t\t\tmr\tr4,r30\n  \t\t\taddi\tr5, r31, 76\n  \t\t\tcrclr\t6\n  \t\t\tbranchl\tr12,Textures_DisplayEffectTextures\n\n\t\t\t#Play Pop Sound\n  \t\t\tmr\tr3,r31\n  \t\t\tli\tr4,244\n  \t\t\tli\tr5,127\n  \t\t\tli\tr6,64\n  \t\t\tbranchl\tr12,0x8026ae84\n\n\t\t\t#Explode\n  \t\t\tmr\tr3,r30\n  \t\t\tbranchl\tr12,0x80289158\n\n\t\t\t#Spawn New Egg\n  \t\t\tlwz\tr3,0xDDC(r31)\t\t\t#Get Event Think\n  \t\t\tli\tr4,0x0\t\t\t#Get 0\n  \t\t\tstw\tr4,0x0(r3)\t\t\t#Zero Pointer\n\n\t\t\tEgg_OnCollisionExit:\n  \t\t\tli\tr3,0x0\n\t\t\tEgg_OnCollisionExitSkip:\n  \t\t\trestore\n  \t\t\tblr\n\nEggsLoadExit:\nrestore\nblr\n\n####################################################\n\nEggsWindowInfo:\nblrl\n#amount of options, amount of options in each window\n\n.long 0x0001FFFF  #1 window, Smash Attack has 2 options\n\n####################################################\n\nEggsWindowText:\nblrl\n\n######################\n## Damage Threshold ##\n######################\n\n#Window Title = Damage Threshold\n.long 0x44616d61\n.long 0x67652054\n.long 0x68726573\n.long 0x686f6c64\n.long 0x\n\n#Option 1 = 12+ Damage\n.long 0x3132817B\n.long 0x2044616d\n.long 0x61676500\n.long 0x\n.long 0x\n\n#Option 2 = Any Damage\n.long 0x416e7920\n.long 0x44616d61\n.long 0x67650000\n.long 0x\n.long 0x\n\n\n################################################################################\n################################################################################\n\n#endregion\n\n#region Multishine\n#########################\n## Multishine HIJACK INFO ##\n#########################\n\nMultishine:\n#COUNT DOWN TIME\n\tli\tr3,0x6\n\tstb\tr3,0x0(r26)\n\n#10 Seconds On the Clock\n\tli\tr3,10\n\tstw\tr3,0x10(r26)\n\n#Store Match Type to READY, GO!\n\tli\tr3,0x80\n\tstb\tr3,0x1(r26)\n\n#SET EVENT TYPE TO KOs\n\tload\tr5,0x8045abf0\t\t#Static Match Struct\n\tlbz\tr3,0xB(r5)\t\t#Get Event Score Behavior Byte\n\tli\tr4,0x0\n\trlwimi\tr3,r4,1,30,30\t\t#Zero Out Time Bit\n\tstb\tr3,0xB(r5)\t\t#Set Event Score Behavior Byte\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,FinalDestination\t\t\t#Use FD\n\tload r7,EventOSD_Multishine\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo Bool\n\tbl\tInitializeMatch\n\n#1 Player\n\tlwz r4,0x0(r29)\n\tli\tr3,0x20\n\tstb\tr3,0x1(r9)\n\n#STORE THINK FUNCTION\n\tbl\tMultishineLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\n\t########################\n\t## Multishine LOAD FUNCT ##\n\t########################\n\tMultishineLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tMultishineThink\n\tmflr\tr3\n\tli\tr4,17\t\t#Priority (After Everything)\n  li  r5,0    #No Option Menu\n\tli\tr6,0\n\tbl\tCreateEventThinkFunction\n\n\tbl\tInitializeHighScore\n\n\tb\tMultishineLoadExit\n\n\t\t#########################\n\t\t## Multishine THINK FUNCT ##\n\t\t#########################\n\n\t\tMultishineThink:\n\t\tblrl\n\n    .set EventData,31\n    .set Event,30\n    .set P1Data,27\n    .set P1GObj,28\n\n\t\tbackup\n\n\t\tmr\tEvent,r3\n\t\tlwz\tEventData,0x2c(Event)\n\n    bl GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n\n\t#First Frame Actions\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tMultishineNotFirstFrame\n  #Init Positions\n    bl  PlacePlayersCenterStage\n\tMultishineNotFirstFrame:\n\n\t#Check for grounded or aerial shine, frame 1\n\t\tlwz r3,0x10(P1Data)\n\t\tcmpwi r3,0x168\n\t\tbeq Multishine_IsShining\n\t\tcmpwi r3,0x16D\n\t\tbeq Multishine_IsShining\n\t\tb\tMultishine_SkipShineCheck\n\tMultishine_IsShining:\n\t#Check for frame 1\n\t\tlhz r3,TM_FramesinCurrentAS(P1Data)\n\t\tcmpwi r3,0\n\t\tbne Multishine_SkipShineCheck\n\t#Increment Score\n  \tli\tr3,0\n  \tli\tr4,0\n  \tli\tr5,5\n  \tbranchl\tr12,Playerblock_StoreTimesR3KilledR4\n\tMultishine_SkipShineCheck:\n\n\t#Check For TimeUp\n  \tbranchl\tr12,MatchInfo_LoadSeconds\t\t#Seconds Left\n    cmpwi\tr3,0x0\n    bne\tMultishineThinkExit\n    branchl\tr12,MatchInfo_LoadSubSeconds\t\t#Sub-Seconds Left\n    cmpwi\tr3,59\n    bne\tMultishineThinkExit\n  #On Event End\n    mr\tr3,Event\n    branchl\tr12,EventMatch_OnWinCondition\t\t\t#EventMatch_OnWinCondition\n\n\tMultishineThinkExit:\n  #Update HUD Score\n  \tli\tr3,0\n  \tli\tr4,5\n    branchl\tr12,Playerblock_LoadTimesR3KilledR4\n    branchl\tr12,HUD_KOCounter_UpdateKOs\n\n\tMultishineLoadExit:\n\trestore\n\tblr\n\n\n\n\n################################################################################\n################################################################################\n#endregion\n\n#region Reaction\n#########################\n## Reaction HIJACK INFO ##\n#########################\n\nReaction:\n#SET EVENT TYPE TO KOs\n\tload\tr5,0x8045abf0\t\t#Static Match Struct\n\tlbz\tr3,0xB(r5)\t\t#Get Event Score Behavior Byte\n\tli\tr4,0x0\n\trlwimi\tr3,r4,1,30,30\t\t#Zero Out Time Bit\n\tstb\tr3,0xB(r5)\t\t#Set Event Score Behavior Byte\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Fox.Ext\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,FinalDestination\t\t\t#Use FD\n\tload r7,EventOSD_Reaction\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo Bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\n\tbl\tReactionLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\n\t########################\n\t## Reaction LOAD FUNCT ##\n\t########################\n\tReactionLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tReactionThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (Interrupt)\n  li  r5,0    #No Option Menu\n\tli\tr6,0\n\tbl\tCreateEventThinkFunction\n\n\tb\tReactionLoadExit\n\n\t\t#########################\n\t\t## Reaction THINK FUNCT ##\n\t\t#########################\n\n\t\tReactionThink:\n\t\tblrl\n\n    .set EventData,31\n    .set Event,30\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n\t\t#Constants\n\t\t.set ShineTimerMax,7*60\n\t\t.set ShineTimerMin,3*60\n\t\t.set ResetTimer,1*60\n\n\t\t#GObj Data Offsets\n\t\t.set OFST_ShineTimer,0x0\n\t\t.set OFST_ResetTimer,0x2\n\t\t.set OFST_ReactionTimer,0x4\n\n\n\t\tbackup\n\n\t\tmr\tEvent,r3\n\t\tlwz\tEventData,0x2c(Event)\n\n    bl\tGetAllPlayerPointers\n    mr\tP1GObj,r3\n    mr\tP1Data,r4\n    mr\tP2GObj,r5\n    mr\tP2Data,r6\n\n\t#First Frame Actions\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tReactionNotFirstFrame\n  #Init Positions\n    bl  PlacePlayersCenterStage\n\t#Savestate\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\n\t\tbl\tSaveState_Save\n\t#Set Initial Timer\n\t\tli\tr3,ShineTimerMax - ShineTimerMin\n\t\tbranchl r12,HSD_Randi\n\t\taddi r3,r3,ShineTimerMin\n\t\tsth r3,OFST_ShineTimer(EventData)\n\t#Initialize Reaction Timer\n\t\tli\tr3,-1\n\t\tsth r3,OFST_ReactionTimer(EventData)\n\t#Stop Music\n\t\tli\tr3,0\n\t\tli\tr4,2\n\t\tbranchl r12,0x80025064\n\tReactionNotFirstFrame:\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t#Give Intangibility to both chars\n\t\tmr\tr3,P1GObj\n\t\tli\tr4,1\n\t\tbranchl r12,ApplyIntangibility\n\t\tmr\tr3,P2GObj\n\t\tli\tr4,1\n\t\tbranchl r12,ApplyIntangibility\n\n\t#Check post countdown timer\n\t\tlhz r3,OFST_ResetTimer(EventData)\n\t\tcmpwi r3,0\n\t\tble Reaction_SkipResetTimer\n\t#Dec timer, if 0 reset\n\t\tsubi r3,r3,1\n\t\tsth r3,OFST_ResetTimer(EventData)\n\t\tcmpwi r3,0\n\t\tbeq Reaction_Reset\n\t\tb\tReactionThinkExit\n\tReaction_SkipResetTimer:\n\n\t#Check shine countdown timer\n\t\tlhz r3,OFST_ShineTimer(EventData)\n\t\tcmpwi r3,0\n\t\tble Reaction_SkipShineTimer\n\t#Dec timer, if 0 perform move\n\t\tsubi r3,r3,1\n\t\tsth r3,OFST_ShineTimer(EventData)\n\t\tcmpwi r3,0\n\t\tbgt ReactionThink_CheckIfActedEarly\n\t#Perform down b\n\t\tmr\tr3,P2GObj\n\t\tbranchl r12,0x800e8560\n\t#Start reaction timer\n\t\tli\tr3,0\n\t\tsth\tr3,OFST_ReactionTimer(EventData)\n\t\tb\tReactionThinkExit\n\nReactionThink_CheckIfActedEarly:\n\t#Check if P1 acted early\n\t\tlwz\tr3,0x10(P1Data)\n\t\tcmpwi r3,ASID_Wait\n\t\tbeq ReactionThinkExit\n\t#Play Error Noise\n\t\tli\tr3,0xAF\n\t\tbl\tPlaySFX\n\t#Set Timer\n\t\tli\tr3,ResetTimer-40\n\t\tsth r3,OFST_ResetTimer(EventData)\n\t\tb\tReactionThinkExit\n\nReaction_SkipShineTimer:\n\n\t#Check reaction timer\n\t\tlhz r3,OFST_ReactionTimer(EventData)\n\t\textsh r3,r3\n\t\tcmpwi r3,0\n\t\tblt Reaction_SkipReactionTimer\n\t#Poll Inputs Again\n\t\t#branchl r12,0x80377ce8\n\t#Check if P1 Reacted\n\t\tlbz r3,0x618(P1Data)\n\t\tload r4,InputStructStart\n\t\tmulli\tr3,r3,68\n\t\tadd\tr3,r3,r4\n\t\tlwz r3,0x8(r3)\n\t\tcmpwi r3,0\n\t\tbeq Reaction_SkipReactionTimer\n\t#Output reaction time\n\t\tmr\tr3,P1Data\t\t\t#p1 (no offsetting window)\n\t\tli\tr4,120\t\t\t#text timeout\n\t\tli\tr5,0\t\t\t#Area to Display (0-2)\n\t\tli\tr6,OSD.Miscellaneous\t\t\t#Window ID (Unique to This Display)\n\t\tbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\n\t\tmr\tr20,r3\t\t\t#backup text pointer\n\t#Decide Color\n\t\tlhz r3,OFST_ReactionTimer(EventData)\n\t\tcmpwi\tr3,15\n\t\tble\tReaction_Good\n\tReaction_Bad:\n\t\tload\tr3,0xffa2baff\t\t\t#Red\n\t\tb\tReaction_StoreTextColor\n\tReaction_Good:\n\t\tload\tr3,0x8dff6eff\t\t\t#green\n\tReaction_StoreTextColor:\n\t\tstw\tr3,0x30(r20)\n\n\t#Create Text 1\n\t\tmr \tr3,r20\t\t\t#text pointer\n\t\tbl\tReaction_TopText\n\t\tmflr\tr4\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,Text_InitializeSubtext\n\n\t#Create Text 2\n\t\tmr \tr3,r20\t\t\t#text pointer\n\t\tbl\tReaction_BottomText\n\t\tmflr\tr4\n\t\tlhz\tr5,OFST_ReactionTimer(EventData)\n\t\taddi r5,r5,1\t\t\t\t\t\t\t\t#0-index is scary\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,Text_InitializeSubtext\n\n\t#Start post countdown timer\n\t\tli\tr3,ResetTimer\n\t\tsth r3,OFST_ResetTimer(EventData)\n\t\tb\tReactionLoadExit\n\tReaction_SkipReactionTimer:\n\t#Inc timer\n\t\tlhz r3,OFST_ReactionTimer(EventData)\n\t\taddi r3,r3,1\n\t\tsth r3,OFST_ReactionTimer(EventData)\n\t\tb\tReactionThinkExit\n\n\tReaction_Reset:\n\t#Load State\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tSaveState_Load\n\t#Reset Variables\n\t#Set Initial Timer\n\t\tli\tr3,ShineTimerMax - ShineTimerMin\n\t\tbranchl r12,HSD_Randi\n\t\taddi r3,r3,ShineTimerMin\n\t\tsth r3,OFST_ShineTimer(EventData)\n\t#Reset Timer\n\t\tli\tr3,0\n\t\tsth\tr3,OFST_ResetTimer(EventData)\n\t#Initialize Reaction Timer\n\t\tli\tr3,-1\n\t\tsth r3,OFST_ReactionTimer(EventData)\n\n\tReactionThinkExit:\n\tReactionLoadExit:\n\trestore\n\tblr\n\nReaction_TopText:\nblrl\n.string \"Reaction Time:\"\n.align 2\n\nReaction_BottomText:\nblrl\n.string \"%d Frames\"\n.align 2\n\n################################################################################\n################################################################################\n#endregion\n\n#region Ledge Stall\n###########################\n## Ledge Stall HIJACK INFO ##\n###########################\n\nLedgeStall:\n#Store Match Type to READY, GO!\n\tli\tr3,0x80\n\tstb\tr3,0x1(r26)\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\n\tli\tr6,Brinstar\t\t\t\t\t\t\t\t\t\t#stage\n\tload r7,EventOSD_LedgeStall\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#1 Player\n\tlwz r4,0x0(r29)\n\tli\tr3,0x20\n\tstb\tr3,0x1(r4)\n\n#STORE THINK FUNCTION\nLedgeStallStoreThink:\n\tbl\tLedgeStallLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## \t\t\tLedge Stall LOAD FUNCT \t\t##\n##################################\nLedgeStallLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tLedgeStallThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\n#Destroy Lava map_gobj proc\n\tli\tr3,8\t\t\t\t#lava's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,GObj_RemoveProc\n/*\n#Make Lava transparent\n\tli\tr3,8\t\t\t\t#lava's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n\tli\tr4,0\n\tbranchl r12,Stage_map_gobj_LoadJObj\n\tli\tr5,1\n\tlwz r4,0x14(r3)\n\trlwimi r4,r5,29,2,2\n\trlwimi r4,r5,28,3,3\n\trlwimi r4,r5,19,12,12\n\tstw r4,0x14(r3)\n\tlwz r3,0x18(r3)\n\tlwz r3,0x8(r3)\n\tlwz r4,0x4(r3)\n\trlwimi r4,r5,29,2,2\n\trlwimi r4,r5,30,1,1\n\tstw r4,0x4(r3)\n\tlwz r3,0xC(r3)\n\tload r4,0x3f000000\n\tstw r4,0xC(r3)\n*/\n#Get map_gobj\n\tli\tr3,6\t\t\t\t#platform's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n#Get platform flesh item pointer\n\tlwz r3,0x2C(r3)\n\tlwz r3,0xE4(r3)\n\tlwz r3,0x2C(r3)\n#Set Hurtbox as intangible\n\tli\tr4,2\n\tstw r4,0xACC(r3)\n\n#Create Camera Box\n\tbranchl\tr12,CreateCameraBox\n\tmr\tr20,r3\n#Get Stage's Ledge IDs\n\tlwz\t\tr3,-0x6CB8 (r13)\t\t\t#External Stage ID\n\tbl\t\tLedgedashCliffIDs\n\tmflr  r4\n\tmulli\tr3,r3,0x2\n\tlhzx\tr3,r3,r4\n#Get Ledge Coordinates\n\trlwinm\tr3,r3,24,24,31\n\taddi\tr4,sp,0xD0\n\tbranchl\tr12,Stage_GetLeftOfLineCoordinates\n#Position Base of CameraBox behind the ledge\n.set CameraBoxXOffset,35\n.set CameraBoxYOffset,20\n\tli\tr3,CameraBoxXOffset\n\tbl\tIntToFloat\n\tlfs f2,0xD0(sp)\t\t#Ledge X\n\tfadds f1,f1,f2\n\tstfs f1,0x10(r20)  #Camera X Position\n\tli\tr3,CameraBoxYOffset\n\tbl\tIntToFloat\n\tlfs f2,0xD4(sp)\t\t#Ledge Y\n\tfadds f1,f1,f2\n\tstfs f1,0x14(r20)  #Camera Y Position\n#Make Boundaries around ledge position\n#Left Bound\n\tli\tr3,-10\n\tbl\tIntToFloat\n\tstfs\tf1,0x40(r20)\n#Right Bound\n\tli\tr3,10\n\tbl\tIntToFloat\n\tstfs\tf1,0x44(r20)\n#Top Bound\n\tli\tr3,10\n\tbl\tIntToFloat\n\tstfs\tf1,0x48(r20)\n#Lower Bound\n\tli\tr3,-10\n\tbl\tIntToFloat\n\tstfs\tf1,0x4C(r20)\n\n#Set Camera To Be Zoomed Out More\n\tload\tr4,0x8049e6c8\n\tload\tr3,0x3FE66666\n\tstw\tr3,0x28(r4)\n\n\tb\tLedgeStallThink_Exit\n\n###########################################\nLedgeStallThink_Constants:\nblrl\n.set LavaRiseRate,0x0\n.set LavaMaxY,0x4\n\n.float 0.4\n.float 10\n###########################################\n\n###################################\n## Ledge Stall THINK FUNCT ##\n###################################\n\nLedgeStallThink:\n\tblrl\n\n#Registers\n\t.set REG_EventConstants,25\n  .set REG_MenuData,26\n  .set REG_EventData,31\n\t.set REG_EventGObj,24\n  .set REG_P1Data,27\n  .set REG_P1GObj,28\n\t.set REG_P2Data,29\n\t.set REG_P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set EventState_LavaDelay,0x0\n\t\t.set EventState_LavaRiseThink,0x1\n\t\t.set EventState_Reset,0x2\n\t.set Timer,0x1\n\t.set LavaTimer,0x2\n\t.set SurvivalTime,0x4\n\t.set LavaPosition,0x8\n\n#Constants\n\t.set ResetTimer,30\n\t.set LavaStartY,-100\n\t.set LavaStartTimer,123\n\t.set SuvivalTime_CountInterval,5\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tmr\tREG_EventGObj,r3\n\tlwz\tREG_EventData,0x2c(REG_EventGObj)\t\t\t#backup data pointer in r31\n\n#Get Player Pointers\n  bl GetAllPlayerPointers\n  mr REG_P1GObj,r3\n  mr REG_P1Data,r4\n  mr REG_P2GObj,r5\n  mr REG_P2Data,r6\n\n#Get Menu and Constants Pointers\n  lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData)\n\tbl\tLedgeStallThink_Constants\n\tmflr REG_EventConstants\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tLedgeStallThink_Start\n\t#Init Positions\n\t\tmr\tr3,REG_P1GObj\n\t\tmr\tr4,REG_EventData\n\t\tbl\tLedgeStall_InitializePositions\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\nLedgeStallThink_Start:\n\n#Check if player was damaged or died\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_DamageHi1\n\tblt LedgeStallThink_DamageCheckSkip\n\tcmpwi r3,ASID_DamageFlyRoll\n\tbgt LedgeStallThink_DamageCheckSkip\n\tb\tLedgeStallThink_TookDamage\nLedgeStallThink_DamageCheckSkip:\n\tlbz r3,0x221F(REG_P1Data)\n\trlwinm. r0,r3,0,25,25\n\tbeq LedgeStallThink_DeadCheckSkip\nLedgeStallThink_TookDamage:\n#Check if took damage already\n\tlbz\tr3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt LedgeStallThink_DeadCheckSkip\n#Set Reset Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n#Play Crowd SFX\n\t#li\tr3,0x13D\n\t#bl\tPlaySFX\n#Advance State\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\nLedgeStallThink_DeadCheckSkip:\n\nLedgeStallThink_SwitchCase:\n#Switch Case\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_LavaDelay\n\tbeq LedgeStallThink_LavaDelay\n\tcmpwi r3,EventState_LavaRiseThink\n\tbeq LedgeStallThink_LavaRiseThink\n\tcmpwi r3,EventState_Reset\n\tbeq LedgeStallThink_Reset\n\tb\tLedgeStallThink_CheckTimer\n\n#region LedgeStallThink_LavaDelay\nLedgeStallThink_LavaDelay:\n#Reset Timer back to 0\n\tli\tr3,0\n\tload r4,0x8046b6a0\n\tstw r3,0x28(r4)\t\t#seconds\n\tsth r3,0x2C(r4)\t\t#subseconds\n\n#Decrement Lava Timer\n\tlhz r3,LavaTimer(REG_EventData)\n\tsubi r3,r3,1\n\tsth r3,LavaTimer(REG_EventData)\n#Check if up\n\tcmpwi r3,0\n\tbgt LedgeStallThink_CheckTimer\n#Advance State\n\tli\tr3,EventState_LavaRiseThink\n\tstb r3,EventState(REG_EventData)\n\tb LedgeStallThink_LavaRiseThink\n#endregion\n\n#region LedgeStallThink_LavaRiseThink\nLedgeStallThink_LavaRiseThink:\n#Ensure player is in the lava before incrementing survival time\n\tlfs f1,LavaPosition(REG_EventData)\n\tlfs f2,0xB4(REG_P1Data)\n\tfcmpo cr0,f2,f1\n\tbge LedgeStallThink_LavaRiseThink_NotInLava\n#Increment Score\n\tlwz r3,SurvivalTime(REG_EventData)\n\taddi r3,r3,1\n\tstw r3,SurvivalTime(REG_EventData)\nLedgeStallThink_LavaRiseThink_SkipScoreIncrement:\n\n#Play HRC SFX every X score\n\tli\tr3,SuvivalTime_CountInterval\n\tbl\tIntToFloat\n\tfmr f2,f1\n\tlwz r3,SurvivalTime(REG_EventData)\n\tsubi r3,r3,1\n\tbl\tIntToFloat\n\tbranchl r12,fmod\n\tfmr f2,f1\n\tli\tr3,0\n\tbl\tIntToFloat\n\tfcmpo cr0,f2,f1\n\tbne LedgeStallThink_LavaRiseThink_SkipSFX\n#Play SFX\n\tli\tr3,0xBB\n\tbl\tPlaySFX\n\tli\tr3,0xBB\n\tbl\tPlaySFX\nLedgeStallThink_LavaRiseThink_SkipSFX:\n\tb\tLedgeStallThink_LavaRiseThink_NotInLavaSkip\n\nLedgeStallThink_LavaRiseThink_NotInLava:\n#Reset Timer back to 0\n\tli\tr3,0\n\tload r4,0x8046b6a0\n\tstw r3,0x28(r4)\t\t#seconds\n\tsth r3,0x2C(r4)\t\t#subseconds\n#Set survival time to 0\n\tstw r3,SurvivalTime(REG_EventData)\nLedgeStallThink_LavaRiseThink_NotInLavaSkip:\n\n#Check if lava is at max height\n\tlfs f1,LavaPosition(REG_EventData)\n\tlfs f2,LavaMaxY(REG_EventConstants)\n\tfcmpo cr0,f1,f2\n\tbge LedgeStallThink_LavaRiseThink_SkipLavaRise\n#Raise Lava\n\tlfs f2,LavaRiseRate(REG_EventConstants)\n\tfadds f1,f1,f2\n\tstfs f1,LavaPosition(REG_EventData)\n\tbl\tLedgestall_UpdateLavaPosition\nLedgeStallThink_LavaRiseThink_SkipLavaRise:\n\n\tb\tLedgeStallThink_CheckTimer\n#endregion\n\n#region LedgeStallThink_Reset\nLedgeStallThink_Reset:\n#Effectively pause timer\n\tload r4,0x8046b6a0\n\tlwz r3,0x28(r4)\t\t#seconds\n\tcmpwi r3,0\n\tbeq LedgeStallThink_NoSecondCarryover\n\tlhz r3,0x2C(r4)\t\t#subseconds\n\tcmpwi r3,0\n\tbne LedgeStallThink_NoSecondCarryover\n\tli\tr3,0x3B\n\tsth r3,0x2C(r4)\t\t#subseconds\n\tlwz r3,0x28(r4)\t\t#seconds\n\tsubi r3,r3,1\n\tstw r3,0x28(r4)\t\t#seconds\n\tb\tLedgeStallThink_CheckTimer\nLedgeStallThink_NoSecondCarryover:\n\tlhz r3,0x2C(r4)\t\t#subseconds\n\tsubi r3,r3,1\n\tsth r3,0x2C(r4)\t\t#subseconds\n\tb\tLedgeStallThink_CheckTimer\n\n#endregion\n\nLedgeStallThink_CheckTimer:\n#Check if timer exists\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tble LedgeStallThink_Exit\n#Decrement timer\n\tsubi r3,r3,1\n\tstb r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt LedgeStallThink_Exit\n\n\n#Pasue game\n\tlfs\tf1, -0x4D68 (rtoc)\n\tbranchl r12,0x8016b274\t\t\t\t#Pause game engine\n#Check if player had any score when taking damage\n\tlwz r3,SurvivalTime(REG_EventData)\n\tcmpwi r3,0\n\tble LedgeStallThink_Failure\nLedgeStallThink_Success:\n#Get current high score\n\tlwz\tr3,-0x77C0 (r13)\n\tlbz r20,0x535(r3)\n\tmr\tr3,r20\n\tbranchl r12,Events_GetEventSavedScore\n\tlwz r4,SurvivalTime(REG_EventData)\n\tcmpw r4,r3\n\tble LedgeStallThink_Success_NoHighScore\nLedgeStallThink_Success_NewHighScore:\n\tli\tr3,2\n\tbranchl r12,0x8016b33c\t\t\t\t#Display Success + SFX\n\tload r3,0x9c40\n\tbranchl r12,0x8016b350\n\tli\tr3,325\n\tbranchl r12,0x8016b364\t\t\t\t#queue crowd cheer after Success\n\tbranchl r12,0x8016b328\t\t\t\t#set game as ended\n\tmr\tr3,r20\t\t\t\t\t\t\t\t\t\t#update score\n\tlwz r4,SurvivalTime(REG_EventData)\n\tbranchl r12,Events_SetEventSavedScore\n\tmr\tr3,r20\t\t\t\t\t\t\t\t\t\t#set event as played\n\tbranchl r12,0x8015ceb4\n\tb\tLedgeStallThink_Success_DestroyGObj\nLedgeStallThink_Success_NoHighScore:\n\tli\tr3,2\n\tbranchl r12,0x8016b33c\t\t\t\t#Display New Record + SFX\n\tli\tr3,324\n\tbranchl r12,0x8016b364\t\t\t\t#queue crowd cheer after New Record\n\tbranchl r12,0x8016b328\t\t\t\t#set game as ended\n\tb\tLedgeStallThink_Success_DestroyGObj\n\nLedgeStallThink_Failure:\n\tli\tr3,6\n\tbranchl r12,0x8016b33c\t\t\t\t#Display Failure + SFX\n\tli\tr3,328\n\tbranchl r12,0x8016b364\t\t\t\t#queue crowd sigh after failure\n\tli\tr3,40\n\tbranchl r12,0x8016b378\t\t\t\t#frames to linger?\n\tbranchl r12,0x8016b328\t\t\t\t#set game as ended\n\tb\tLedgeStallThink_Success_DestroyGObj\n\nLedgeStallThink_Success_DestroyGObj:\n\tmr\tr3,REG_EventGObj\n\tbranchl r12,GObj_Destroy\t\t\t#destroy event gobj\n\tb\tLedgeStallThink_Exit\n\nLedgeStallThink_Restore:\n#Restore State\n\taddi r3,REG_EventData,EventData_SaveStateStruct\n\tli\tr4,1\n\tbl\tSaveState_Load\n#Init Positions Again\n\tmr\tr3,REG_P1GObj\n\tmr\tr4,REG_EventData\n\tbl\tLedgeStall_InitializePositions\n#Enable Inputs\n\tlbz r3,0x221D(REG_P1Data)\n\tli\tr4,0\n\trlwimi r3,r4,3,28,28\n\tstb r3,0x221D(REG_P1Data)\n#Shorten Timer\n\tli\tr3,0\n\tsth r3,LavaTimer(REG_EventData)\nLedgeStallThink_Exit:\n\trestore\n\tblr\n\n################################\n\nLedgeStall_InitializePositions:\nbackup\n\n.set REG_P1GObj,30\n.set REG_P1Data,29\n.set REG_EventData,28\n.set REG_map_gobj,27\n.set REG_map_gobj_JObj,26\n\n#Init Registers\n  mr\tREG_P1GObj,r3\n  lwz REG_P1Data,0x2C(REG_P1GObj)\n\tmr\tREG_EventData,r4\n\n#Place on left ledge\n\tmr\tr3,REG_P1GObj\n\tli\tr4,0\n\tbl\tPlaceOnLedge\n\n#Update Camera\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdateCameraBox\n\n#Init Lava Y\n\tli\tr3,LavaStartY\n\tbl\tIntToFloat\n\tstfs f1,LavaPosition(REG_EventData)\n\tbl\tLedgestall_UpdateLavaPosition\n\n#Reset Variables\n\tli\tr3,EventState_LavaDelay\n\tstb r3,EventState(REG_EventData)\n\tli\tr3,0\n\tstb r3,Timer(REG_EventData)\n\tstw r3,SurvivalTime(REG_EventData)\n\n#Init Lava Start Timer\n\tli\tr3,LavaStartTimer\n\tsth r3,LavaTimer(REG_EventData)\n\nLedgeStall_InitializePositions_Exit:\n\trestore\n\tblr\n\n#####################################\nLedgestall_UpdateLavaPosition:\nbackup\n\n.set REG_LavaY,31\n.set REG_map_gobj_JObj,30\n\n#Backup args\n\tstfs f1,0x80(sp)\n\n#Get Lava map_gobj\n\tli\tr3,8\t\t\t\t#lava's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n#Get JObj\n\tli\tr4,0\n\tbranchl r12,Stage_map_gobj_LoadJObj\n\tmr\tREG_map_gobj_JObj,r3\n\n#Get 55f (jobj doesnt line up with actual position)\n\tli\tr3,55\n\tbl\tIntToFloat\n#Update JObj Y position\n\tlfs f2,0x80(sp)\n\tfadds f1,f1,f2\n\tstfs f1,0x3C(REG_map_gobj_JObj)\n#DirtySub\n\tmr\tr3,REG_map_gobj_JObj\n\tbranchl r12,HSD_JObjSetMtxDirtySub\n\n#Adjust hitbox position\n\tlfs f1,0x80(sp)\n\tbranchl r12,0x801c438c\n\nLedgestall_UpdateLavaPosition_Exit:\nrestore\nblr\n\n#endregion\n\n##################\n## General Tech ##\n##################\n\n#region L-Cancel Training\n#########################\n## L Cancel HIJACK INFO ##\n#########################\n\nLCancel:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t\t#Use SSS Stage\n\tload r7,EventOSD_LCancel\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo Bool\n\tbl\tInitializeMatch\n\n#Make P2 a human\n\tlwz r3,0x0(r29)\n\tlwz r3,0x18(r3)\n\tli\tr4,0\n\tstb r4,0x1(r3)\n\n#STORE THINK FUNCTION\nbl\tLCancelLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\n\t########################\n\t## L Cancel LOAD FUNCT ##\n\t########################\n\tLCancelLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tLCancelThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  li  r5,0    #No Option Menu\n\tbl\tCreateEventThinkFunction\n\n\tb\tLCancelLoadExit\n\n\n\n\t\t#########################\n\t\t## L Cancel THINK FUNCT ##\n\t\t#########################\n\n\t\tLCancelThink:\n\t\tblrl\n\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n\t\tbackup\n\n\t\tlwz\tEventData,0x2c(r3)\n\n    bl GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tLCancelNotFirstFrame\n\n    #Init Positions\n      bl  PlacePlayersCenterStage\n\t\t#Check if P2-P4 Is Using the Event\n\t\t\tli\tr4,0x1\t\t#Make CPU Controlled by P2\n\t\t\tlbz\tr3, -0x5108 (r13)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tLCancelIsP1\n\t\t\tli\tr4,0x0\n    LCancelIsP1:\n\t\t\tstb\tr4,0x618(r29)\n    #Clear Inputs\n      bl  RemoveFirstFrameInputs\n    #Save State\n      addi r3,EventData,EventData_SaveStateStruct\n\t\t\tli\tr4,1\t\t\t\t\t\t\t\t\t#Override failsafe code\n      bl  SaveState_Save\n\t\tLCancelNotFirstFrame:\n\n\t\t#Check For P2 Dpad Down Press\n\t\t\tlwz\tr3,0x668(r29)\t\t\t\t\t#Inputs\n\t\t\trlwinm.\tr0,r3,0,29,29\n\t\t\tbeq\tLCancelThink_CheckForInvinc\n\t\t#Toggle Invinc Bit\n\t\t\tlbz\tr3,0x0(r31)\n\t\t\tnand \t3,3,3\n\t\t\tstb\tr3,0x0(r31)\n\n\n\n\t\tLCancelThink_CheckForInvinc:\n\t\t\tlbz\tr3,0x0(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tLCancelThink_RemoveInvincibility\n\t\t#Give No Knockback To P2\n\t\t\tlbz r3,0x2220(P2Data)\n\t\t\tli\tr4,1\n\t\t\trlwimi r3,r4,4,27,27\n\t\t\tstb r3,0x2220(P2Data)\n\t\t#Ignore Grabs\n\t\t\tli\tr3,0x1FF\n\t\t\tsth r3,0x1A6A(P2Data)\n\t\t#Ignore Percent\n\t\t\tli\tr3,0\n\t\t\tbl\tIntToFloat\n\t\t\tstfs f1,0x1830(P2Data)\n\t\t\tlbz r3,0xC(P2Data)\n\t\t\tli\tr4,0\n\t\t\tli\tr5,0\n\t\t\tbranchl r12,0x80034418\n\t\t#Un-nudgeable\n\t\t\tli\tr3,0x1\n\t\t\tlbz\tr0, 0x221D (P2Data)\n\t\t\trlwimi\tr0,r3,2,29,29\n\t\t\tstb\tr0, 0x221D (P2Data)\n\t\t#Apply Overlay\n\t\t\tmr\tr3,P2Data\n\t\t\tli\tr4,9\n\t\t\tli\tr5,0\n\t\t\tbranchl r12,0x800bffd0\n\t\t\tb\tLCancelThink_SkipInvincibility\n\t\tLCancelThink_RemoveInvincibility:\n\t\t#Give Invincibility To P2\n\t\t\tlbz r3,0x2220(P2Data)\n\t\t\tli\tr4,0\n\t\t\trlwimi r3,r4,4,27,27\n\t\t\tstb r3,0x2220(P2Data)\n\t\t#Allow Grabs\n\t\t\t#li\tr3,0x0\n\t\t\t#sth r3,0x1A6A(P2Data)\n\t\t#Allow Percent\n\t\t\t#li\tr3,1\n\t\t\t#bl\tIntToFloat\n\t\t\t#stfs f1,0x182C(P2Data)\n\t\t#Nudgeable\n\t\t\tli\tr3,0x0\n\t\t\tlbz\tr0, 0x221D (P2Data)\n\t\t\trlwimi\tr0,r3,2,29,29\n\t\t\tstb\tr0, 0x221D (P2Data)\n\t\t#Remove Overlay\n\t\t\tmr\tr3,P2Data\n\t\t\tli\tr4,9\n\t\t\tbranchl r12,0x800c0200\n\t\tLCancelThink_SkipInvincibility:\n\n\t\tLCancelThink_CheckForSaveState:\n\t\t#Check For Savestates\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tCheckForSaveAndLoad\n\n    mr  r3,P1GObj\n    mr  r4,P2GObj\n    addi r5,EventData,EventData_SaveStateStruct\n\t\tbl\tMoveCPU\n\t\tbl\tGiveFullShields\n\t\taddi r3,EventData,EventData_SaveStateStruct+(1*0x8)\n\t\tbl\tDPadCPUPercent\n\t\tbl\tUpdateAllGFX\n\n\tLCancelLoadExit:\n\trestore\n\tblr\n\n\n\n\n################################################################################\n################################################################################\n#endregion\n\n#region Ledgedash Training\n\n###########################\n## Ledgedash HIJACK INFO ##\n###########################\n\nLedgedash:\n\n#SET EVENT TYPE TO KOs\n\tload\tr5,0x8045abf0\t\t#Static Match Struct\n\tlbz\tr3,0xB(r5)\t\t#Get Event Score Behavior Byte\n\tli\tr4,0x0\n\trlwimi\tr3,r4,1,30,30\t\t#Zero Out Time Bit\n\tstb\tr3,0xB(r5)\t\t#Set Event Score Behavior Byte\n\n#Make HUD Centered For 1P and No Timer\n\tli\tr3,0x0430\n\tsth\tr3,0x0(r26)\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t\t#Use SSS Stage\n\tload r7,EventOSD_Ledgedash\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo Bool\n\tbl\tInitializeMatch\n\n#1 Player\n\tlwz r4,0x0(r29)\n\tli\tr3,0x20\n\tstb\tr3,0x1(r9)\n\n#STORE THINK FUNCTION\nLedgedashStoreThink:\nbl\tLedgedashLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Ledgedash LOAD FUNCT ##\n\t########################\n\tLedgedashLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tLedgedashThink\n\tmflr\tr3\n\tli\tr4,9\t\t#Priority (After Interrupt)\n  bl  LedgedashWindowInfo\n  mflr r5\n  bl LedgedashWindowText\n  mflr r6\n\tbl\tCreateEventThinkFunction\n\n\tbl\tInitializeHighScore\n\n#Remove randall\n\tlwz\tr3,StageID_External(r13)\n\tcmpwi\tr3,YoshiStory\n\tbne\tLedgedashLoad_SkipRemoveRandall\n#Get randall's map_gobj\n\tli\tr3,2\t\t\t\t#randalls map_gobj is 2\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,Stage_Destroy_map_gobj\nLedgedashLoad_SkipRemoveRandall:\n\n\tb\tLedgedashLoadExit\n\n\n\t\t#########################\n\t\t## Ledgedash THINK FUNCT ##\n\t\t#########################\n\n    #Registers\n    .set REG_EventData,31\n    .set MenuData,27\n    .set P1GObj,30\n    .set P1Data,29\n\n    #Offsets\n\t\t.set firstFrameFlag,0x0\n\t\t.set eventState,0x1\n\t\t.set hitboxFoundFlag,0x2\n    .set currentLedge,0x3\n\t\t.set timer,0x4\n\t\t.set CameraBox,0x8\n\t\t.set StartingLocation,(MenuData_OptionMenuMemory+0x2+0x0)\n\t\t.set AutoRestore,(MenuData_OptionMenuMemory+0x2+0x1)\n    .set StartingLocationToggled,(MenuData_OptionMenuToggled+0x0)\n\t\t.set AutoRestoreToggled,(MenuData_OptionMenuToggled+0x1)\n\n\t\tLedgedashThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tREG_EventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\t\tlwz   MenuData,EventData_MenuDataPointer(REG_EventData)\n\n    bl    GetAllPlayerPointers\n\t\tmr\t\tP1GObj,r3\t\t\t#player block in r30\n\t\tmr\t\tP1Data,r4\t\t\t#player data in r29\n\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tLedgedashThinkMain\n\n\t\t\t#Create Camera Box\n\t\t\t\tbranchl\tr12,CreateCameraBox\n\t\t\t\tstw r3,CameraBox(r31)\n\t\t\t#Place on Ledge\n\t\t\t\tmr r3,REG_EventData\n\t\t\t\tli\tr4,0\n\t\t\t\tbl\tLedgedash_PlaceOnLedge\n\t\t\t#Set Camera To Be Zoomed Out More\n\t\t\t\tload\tr4,0x8049e6c8\n\t\t\t\tload\tr3,0x3FE66666\n\t\t\t\tstw\tr3,0x28(r4)\n\t\t\t#Set Tangible Frames High So It Doesn't Constantly Show\n\t\t\t\tli\tr3,100\n\t\t\t\tstw\tr3,0x2408(r29)\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n\t\t\t#Save State\n\t\t\t\taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n\t\t\t\tbl\tSaveState_Save\n\n\t\t\t#Set Frame 1 As Over\n\t\t\t\tli\t\tr3,0x1\n\t\t\t\tstb\t\tr3,firstFrameFlag(r31)\n\n\n\t\tLedgedashThinkMain:\n\n\t\t#Update HUD Score\n\t\tlhz\tr3,-0x4ea8(r13)\n\t\tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\n\t\t#Check If Toggled Starting Location\n\t\t\tlbz r3,StartingLocationToggled(MenuData)\n      cmpwi r3,0x0\n\t\t\tbeq\tLedgedash_SkipToggledLoadState\n\t\t\tb\t\tLedgedash_LoadState\n\t\tLedgedash_SkipToggledLoadState:\n\n\t\t#Reset If Anyone Dies\n\t\t\tbl\tIsAnyoneDead\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tLedgedash_LoadState\n\n\t\t#Infinite Time While on Rebirth Platform\n\t\t\tlwz\tr3,0x10(P1Data)\n\t\t\tcmpwi\tr3,0xD\n\t\t\tbne\tLedgedashSkipRebirthTimer\n\t\t\tli\tr3,0x2\n\t\t\tstw\tr3,0x2340(P1Data)\n\t\tLedgedashSkipRebirthTimer:\n\n    #Infinite Time While Holding Ledge\n      lwz\tr3,0x10(P1Data)\n      cmpwi\tr3,0xFD\n      bne\tLedgedashSkipCliffTimer\n      li  r3,2\n      bl  IntToFloat\n      stfs f1,0x2344(P1Data)\n    LedgedashSkipCliffTimer:\n\n\t\t#Make sure nothing else besides Z is held\n\t\t\tlhz\tr3,0x662(P1Data)\n\t\t\trlwinm.  r0,r3,0,27,27\n      bne 0xC\n      cmpwi r3,0x0\n\t\t\tbne GetProgressAndAS\n\t\t#CHECK FOR DPAD TO CHANGE LEDGE\n\t\t\tlwz\tr3,0x668(P1Data)\t\t\t#Get DPad\n\t\t\trlwinm.\tr0,r3,0,30,30\n\t\t\tbeq\tLedgedash_CheckLeft\n\t\t#Load Most Recent State\n\t\t\taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\tbl\t\tSaveState_Load\n\t\t#Place on Right Ledge\n\t\t\tmr r3,REG_EventData\n\t\t\tli\tr4,1\n\t\t\tbl\tLedgedash_PlaceOnLedge\n\t\t#Save State\n\t\t\taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\tli\tr4,1\t\t\t#Override failsafe code\n\t\t\tbl\t\tSaveState_Save\n\t\t\tb\tLedgedash_LoadState\n\t\tLedgedash_CheckLeft:\n\t\t\trlwinm.\tr0,r3,0,31,31\n\t\t\tbeq\tGetProgressAndAS\n\t\t#Load Most Recent State\n\t\t\taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\tbl\t\tSaveState_Load\n\t\t#Place on Left Ledge\n\t\t\tmr r3,REG_EventData\n\t\t\tli\tr4,0\n\t\t\tbl\tLedgedash_PlaceOnLedge\n\t\t#Save State\n\t\t\taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\tli\tr4,1\t\t\t#Override failsafe code\n\t\t\tbl\t\tSaveState_Save\n\t\t\tb\tLedgedash_LoadState\n\n\t\tGetProgressAndAS:\n\t\t#Check If AutoRestore is enabled\n\t\t\tlbz\tr3,AutoRestore(MenuData)\n\t\t\tcmpwi r3,0x1\n\t\t\tbeq\tLedgedashThinkEnd\n\t\t#Check If Timer Is Set\n\t\t\tlbz\tr3,timer(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbgt\tLedgedash_CheckToReset\n\t\t#Get Progress + AS\n\t\t\tlbz\tr3,eventState(r31)\t\t#Progress Byte\n\n\t\tbl\tLedgedashSkipJumpTable\n\t\tbl\tLedgedashProg0\n\t\tbl\tLedgedashProg1\n\t\tbl\tLedgedashProg2\n\t\tbl\tLedgedashProg3\n\t\tbl\tLedgedashProg4\n\n\t\tLedgedashSkipJumpTable:\n\t\tmflr\tr4\t\t#Jump Table Start in r4\n\t\tmulli\tr5,r3,0x4\t\t#Each Pointer is 0x4 Long\n\t\tlwzx\tr3,r4,r5\t\t#Get bl Instruction\n\t\trlwinm\tr3,r3,0,6,29\t\t#Mask Bits 6-29 (the offset)\n\t\tadd\tr3,r4,r3\t\t#Gets Address in r3\n\t\tadd\tr3,r3,r5\t\t#Offset From Start Of Jump Table\n\n\t\t#Init Loop\n\t\tsubi\tr3,r3,0x2\n\t\tlwz\tr6,0x10(r29)\t\t#AS\n\n\t\t#Check For BlackListed AS\n\t\t## Terminator = FFFF\n\t\t## Jump to    = 7FXX\n\t\tLedgedashASCheckLoop:\n\t\t\tlhzu\tr4,0x2(r3)\t\t#Get Next Value\n\t\t\textsb\tr0,r4\n\t\t\tcmpwi\tr0,-1\t\t#Check For Terminator\n\t\t\tbeq\tLedgedash_ResetProg\n\t\t\trlwinm\tr0,r4,0,15,23\t\t#Isolate Left Half\n\t\t\tcmpwi\tr0,0x7F00\t\t#Check If New \"Jump To\"\n\t\t\tbne\tLedgedashCompareAS\n\t\t\trlwinm\tr5,r4,0,24,31\t\t#Isolate Right Half to r5\n\t\t\tb\tLedgedashASCheckLoop\n\t\tLedgedashCompareAS:\n\t\t\tcmpw\tr6,r4\n\t\t\tbne\tLedgedashASCheckLoop\n\t\t\tstb\tr5,0x1(r31)\t\t#Progress Byte\n\t\t\tb\tLedgedashThinkEnd\n\n\n\t\tLedgedashThinkEnd:\n\t    mr  r3,MenuData\n\t    bl  ClearToggledOptions\n\t\t\trestore\n\t\t\tblr\n\n\n\t\t####################\n\t\t## Reset Progress ##\n\t\t####################\n\n\t\tLedgedash_ResetProg:\n\t\t#Check If On Ground\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tLedgedash_Reset\n\t\t#Check If Dead\n\t\t\tlbz\tr3,0x221F(r29)\n\t\t\trlwinm.\tr3,r3,0,25,25\n\t\t\tbne\tLedgedash_Reset\n\t\t#Check If Frame 9 Of Wrong Move\n\t\t\tli\tr3,9\n\t\t\tbl\tIntToFloat\n\t\t\tlfs\tf2,0x894(r29)\t\t#Frames in State\n\t\t\tfcmpo\tcr0,f2,f1\n\t\t\tblt\tLedgedashThinkEnd\n\n\t\tLedgedash_Reset:\n\t\t#Play Success or Failure Noise\n\t\t\tlhz\tr3,TM_OneASAgo(r29)\t\t\t#Check Prev AS\n\t\t\tcmpwi\tr3,ASID_LandingFallSpecial\t\t\t#If Landing, Success\n\t\t\tbeq\tLedgedash_PlaySuccess\n\t\t\tcmpwi\tr3,ASID_Wait\t\t\t#If Wait, Success (Frame Perfect Action)\n\t\t\tbeq\tLedgedash_PlaySuccess\n\n\t\t\tlwz\tr3,CurrentAS(r29)\n\t\t\tcmpwi\tr3,ASID_Landing\t\t\t#If Aerial Interrupt, Check If Can IASA Yet\n\t\t\tbeq\tLedgedash_AerialInterruptCheck\n\t\t\tcmpwi\tr3,ASID_Wait\t\t\t#If No Impact Land, Success\n\t\t\tbeq\tLedgedash_PlaySuccess\n\n\t\tb\tLedgedash_PlayFailure\n\n\t\tLedgedash_AerialInterruptCheck:\n\t\t#Check If Coming From an Aerial Attack\n\t\tlhz\tr3,TM_OneASAgo(r29)\t\t\t#Check Prev AS\n\t\tcmpwi\tr3,ASID_AttackAirN\n\t\tblt\tLedgedash_PlayFailure\n\t\tcmpwi\tr3,ASID_AttackAirLw\n\t\tbgt\tLedgedash_PlayFailure\n\n\t\t#Check If Interruptable Yet\n\t\tlfs\tf2,0x1F4(r29)\t\t\t#Check Which Frame Landing is Interruptable\n\t\tli\tr3,1\n\t\tbl\tIntToFloat\n\t\tfsubs\tf1,f2,f1\t\t\t#Sub 1 Because Order of Operations\n\t\tlfs\tf2,0x894(r29)\t\t\t#Check Current Frame\n\t\tfcmpo\tcr0,f2,f1\n\t\tblt\tLedgedashThinkEnd\n\n\t\tLedgedash_PlaySuccess:\n\t\t#Increment Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\t#Check To Make New High Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tlhz\tr4,-0x4ea6(r13)\n\t\t\tcmpw\tr3,r4\n\t\t\tble\tLedgedash_PlaySuccess_PlaySound\n\t\t#Copy To High Score\n\t\t\tsth\tr3,-0x4ea6(r13)\n\t\tLedgedash_PlaySuccess_PlaySound:\n\t\t#Play Sound\n\t\t\tli\t\tr3,0xAD\n\t\t\tbl PlaySFX\n\t\t#Set Timer\n\t\t\tli\tr3,30\n\t\t\tstb\tr3,timer(r31)\n\t\t\tb\tLedgedashThinkEnd\n\n\t\tLedgedash_PlayFailure:\n\t\t#Reset Score\n\t\t\tli\tr3,0\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\t#Play Sound\n\t\t\tli\tr3,0xAF\n\t\t\tLedgedash_PlaySound:\n\t\t\tbl PlaySFX\n\t\t#Place on Ledge\n\t\t\tmr r3,REG_EventData\n\t\t\tlbz\tr4,currentLedge(REG_EventData)\n      bl Ledgedash_PlaceOnLedge\n\t\t\tb\tLedgedash_LoadState\n\n\n\t\tLedgedash_CheckToReset:\n\t\tlbz\tr3,timer(r31)\t\t\t\t#Check If Timer is Set\n\t\tcmpwi\tr3,0x0\n\t\tble\tLedgedashThinkEnd\n\n\t\tLedgedash_CheckForInvincibleMove:\n\t\tlbz\tr3,hitboxFoundFlag(r31)\t\t\t\t#Check If Hitbox Was Already Found\n\t\tcmpwi\tr3,0x1\n\t\tbeq\tLedgedash_DecrementTimer\n\t\tlwz\tr3,0x1990(r29)\t\t\t\t#Check If Char is Invincible\n\t\tcmpwi\tr3,0x0\n\t\tble\tLedgedash_DecrementTimer\n\t\tmr\tr3,r30\t\t\t\t#Check If a Hitbox is Active\n\t\tbl\tCheckForActiveHitboxes\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tLedgedash_DecrementTimer\n\t\tli\tr3,0xAA\t\t\t\t#Play Sound\n\t\tbranchl\tr12,SFX_PlaySoundAtFullVolume\n\t\tli\tr3,1\t\t\t\t#Mark As Found\n\t\tstb\tr3,hitboxFoundFlag(r31)\n\n\t\tLedgedash_DecrementTimer:\n\t\t\tlbz\tr3,timer(r31)\n\t\t\tsubi\tr3,r3,0x1\t\t\t#Decrement\n\t\t\tstb\tr3,timer(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbgt\tLedgedashThinkEnd\n    #Load State (to cleanup volatile entities)\n      addi r3,REG_EventData,EventData_SaveStateStruct\n      bl\t\tSaveState_Load\n\t\t#Place on Ledge\n\t\t\tmr r3,REG_EventData\n\t\t\tlbz\tr4,currentLedge(REG_EventData)\n      bl\tLedgedash_PlaceOnLedge\n    #Save State\n      addi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\tli\tr4,1\t\t\t\t\t\t\t#Override failsafe code\n      bl\t\tSaveState_Save\n\n\t\tLedgedash_LoadState:\n\t\t#Reset all event variables\n\t\t\tli\t\tr3,0x0\n\t\t\tstb\t\tr3,eventState(r31)\t\t\t\t#Progress Byte\n\t\t\tstb\t\tr3,hitboxFoundFlag(r31)\t\t#Invincible Move Bool\n\t\t\tstb\t\tr3,timer(r31)\t\t\t\t\t\t\t#Timer\n\t\t\taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\t\tbl\t\tSaveState_Load\n\t\t#Create Respawn Platform If Enabled\n\t\t\tlbz\t\tr3,StartingLocation(MenuData)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tLedgedash_LoadState_SkipRespawnPlatform\n\t\t#Remember Facing Direction (Rebirth changes this)\n\t\t\tlfs\tf31,0x2C(r29)\n\t\t#Enter P1 Into Rebirth Again\n\t\t\tmr\tr3,r30\n\t\t\tbranchl\tr12,AS_Rebirth\n\t\t#Restore Facing Direction\n\t\t\tstfs\tf31,0x2C(r29)\n\t\t#Randomize Location\n\t\t#Get Stage's Ledges\n\t\t\tlwz\t\tr3,-0x6CB8 (r13)\t\t\t#External Stage ID\n\t\t\tbl\t\tLedgedashCliffIDs\n\t\t\tmflr  r4\n\t\t\tmulli\tr3,r3,0x2\n\t\t\tlhzx\tr3,r3,r4\n\t\t#Get Correct Ledge From Facing Direction\n\t\t\tlfs\tf1, 0x002C (r29)\n\t\t\tlfs\tf0, -0x7660 (rtoc)\n\t\t\tfcmpo\tcr0,f1,f0\n\t\t\tble\tLedgedash_LoadState_GetRightLedge\n\t\tLedgedash_LoadState_GetLeftLedge:\n\t\t#Get Ledge X and Y Coordinates\n\t\t\trlwinm\tr3,r3,24,24,31\n\t\t\taddi\tr4,sp,0x80\n\t\t\tbranchl\tr12,Stage_GetLeftOfLineCoordinates\n\t\t\tb\tLedgedash_LoadState_RandomizePosition\n\t\tLedgedash_LoadState_GetRightLedge:\n\t\t#Get Ledge X and Y Coordinates\n\t\t\trlwinm\tr3,r3,0,24,31\n\t\t\taddi\tr4,sp,0x80\n\t\t\tbranchl\tr12,Stage_GetRightOfLineCoordinates\n\t\tLedgedash_LoadState_RandomizePosition:\n\t\t#Get Random Distance from this\n\t\t\t.set RandomDistanceMinX,30\n\t\t\t.set RandomDistanceMaxX,55\n\t\t\t.set RandomDistanceMinY,-30\n\t\t\t.set RandomDistanceMaxY,30\n\t\t\tli\tr3,RandomDistanceMinX\n\t\t\tli\tr4,RandomDistanceMaxX\n\t\t\tbl\tRandFloat\n\t\t\tfmr\tf31,f1\n\t\t\tli\tr3,RandomDistanceMinY\n\t\t\tli\tr4,RandomDistanceMaxY\n\t\t\tbl\tRandFloat\n\t\t\tfmr\tf30,f1\n\t\t#Add to Ledge Coordinates\n\t\t\tlfs\tf1,0x2C(r29)\t#Facing Direction\n\t\t\tfneg f1,f1\n\t\t\tfmuls f31,f1,f31\n\t\t\tlfs\tf0,0x80(sp)\t\t#Ledge X\n\t\t\tfadds f31,f0,f31\n\t\t\tlfs\tf1,0x84(sp)\t\t#Ledge Y\n\t\t\tfadds f30,f1,f30\n\t\t#Store to Player Block\n\t\t\tstfs f31,0xB0(r29)\n\t\t\tstfs f30,0xB4(r29)\n\t\t#Enter RebirthWait\n\t\t\tmr\t\tr3,r30\n\t\t\tbranchl\t\tr12,AS_RebirthWait\n\t\t#Store Blr as Physics\n\t\t\tbl\t\tBlrFunctionPointer\n\t\t\tmflr\t\tr3\n\t\t\tstw\t\tr3,0x21A4(r29)\n\t\t#Store Custom RebirthWait Interrupt\n\t\t\tbl\tCustom_InterruptRebirthWait\n\t\t\tmflr\tr3\n\t\t\tstw\t\tr3,0x219C(r29)\n    #Update RebirthPlat Position\n      mr  r3,P1GObj\n      branchl r12,RebirthPlatform_UpdatePosition\n\n\t\tLedgedash_LoadState_SkipRespawnPlatform:\n      mr  r3,r30\n      bl  UpdatePosition\n    #Update Camera Box\n      mr  r3,P1GObj\n      bl  UpdateCameraBox\n\n\t\tb\t\tLedgedashThinkEnd\n\n\n\t\t#####################\n\t\t## PlaceAboveLedge ##\n\t\t#####################\n\t\tLedgedash_PlaceOnLedge:\n    backup\n\n\t\t.set\tREG_EventData,31\n\t\t.set\tREG_P1GObj,30\n\t\t.set\tREG_P1Data,29\n\t\t.set\tREG_LedgeID,28\n\t\t.set\tREG_CameraBox,28\n\n\t\t#Init\n\t\t\tmr\tREG_EventData,r3\n\t\t\tmr\tREG_LedgeID,r4\n\t\t\tstb\tREG_LedgeID,currentLedge(REG_EventData)\n\t\t#Get P1 data\n\t\t\tli\tr3,0\n\t\t\tbranchl\tr12,PlayerBlock_LoadMainCharDataOffset\n\t\t\tmr\tREG_P1GObj,r3\n\t\t\tlwz\tREG_P1Data,0x2C(REG_P1GObj)\n\n\t\t#Place on ledge\n\t\t\tmr\tr3,REG_P1GObj\n\t\t\tmr\tr4,REG_LedgeID\n\t\t\tbl\tPlaceOnLedge\n\n\t\t#RESET PROGRESS\n\t\t\tli\t\tr3,0x0\n\t\t\tstb\t\tr3,eventState(REG_EventData)\n\n\t\t#Get Stage's Ledge IDs\n\t\t\tlwz\t\tr3,-0x6CB8 (r13)\t\t\t#External Stage ID\n\t\t\tbl\t\tLedgedashCliffIDs\n\t\t\tmflr  r4\n\t\t\tmulli\tr3,r3,0x2\n\t\t\tlhzx\tr3,r3,r4\n\t\t#Get Requested Ledge\n\t\t\tcmpwi REG_LedgeID,0x0\n\t\t\tbeq\tLedgedash_PlaceOnLedge_GetLeftLedgeID\n\t\tLedgedash_PlaceOnLedge_GetRightLedgeID:\n\t\t\trlwinm\tr21,r3,0,24,31\n\t\t\tb\tLedgedash_PlaceOnLedge_SkipLedgeID\n\t\tLedgedash_PlaceOnLedge_GetLeftLedgeID:\n\t\t\trlwinm\tr21,r3,24,24,31\n\t\tLedgedash_PlaceOnLedge_SkipLedgeID:\n\n\t\t#Adjust Ledge Camera Box Accordingly\n\t\t#Get Ledge Coordinates\n\t\t\tmr\tr3,r21\n\t\t\taddi\tr4,sp,0xD0\n\t\t\tlfs\tf1, 0x002C (REG_P1Data)\n\t\t\tlfs\tf0, -0x7660 (rtoc)\n\t\t\tfcmpo\tcr0,f1,f0\n\t\t\tble Ledgedash_PlaceOnLedge_CameraBoxRightLedge\n\t\tLedgedash_PlaceOnLedge_CameraBoxLeftLedge:\n\t\t\tbranchl\tr12,Stage_GetLeftOfLineCoordinates\n\t\t\tb\tLedgedash_PlaceOnLedge_UpdateCameraBox\n\t\tLedgedash_PlaceOnLedge_CameraBoxRightLedge:\n\t\t\tbranchl r12,Stage_GetRightOfLineCoordinates\n\t\tLedgedash_PlaceOnLedge_UpdateCameraBox:\n\t\t#Get CameraBox\n\t\t\tlwz REG_CameraBox,CameraBox(REG_EventData)\n\t\t#Position Base of CameraBox behind the ledge\n\t\t.set CameraBoxXOffset,35\n\t\t.set CameraBoxYOffset,20\n\t\t\tli\tr3,CameraBoxXOffset\n\t\t\tbl\tIntToFloat\n\t\t\tlfs f2,0xD0(sp)\t\t#Ledge X\n\t\t\tlfs f3,0x2C(REG_P1Data)\n\t\t\tfmadds f1,f1,f3,f2\n\t\t\tstfs f1,0x10(REG_CameraBox)  #Camera X Position\n\t\t\tli\tr3,CameraBoxYOffset\n\t\t\tbl\tIntToFloat\n\t\t\tlfs f2,0xD4(sp)\t\t#Ledge Y\n\t\t\tfadds f1,f1,f2\n\t\t\tstfs f1,0x14(REG_CameraBox)  #Camera Y Position\n\t\t#Make Boundaries around ledge position\n\t\t#Left Bound\n\t\t\tli\tr3,-10\n\t\t\tbl\tIntToFloat\n\t\t\tstfs\tf1,0x40(REG_CameraBox)\n\t\t#Right Bound\n\t\t\tli\tr3,10\n\t\t\tbl\tIntToFloat\n\t\t\tstfs\tf1,0x44(REG_CameraBox)\n\t\t#Top Bound\n\t\t\tli\tr3,10\n\t\t\tbl\tIntToFloat\n\t\t\tstfs\tf1,0x48(REG_CameraBox)\n\t\t#Lower Bound\n\t\t\tli\tr3,-10\n\t\t\tbl\tIntToFloat\n\t\t\tstfs\tf1,0x4C(REG_CameraBox)\n\n    #Update Camera Box\n      mr  r3,REG_P1GObj\n      bl  UpdateCameraBox\n\n\t\trestore\n\t\tblr\n\n####################################\n\nLedgedashCliffIDs:\nblrl\n.long 0xFFFFFFFF #Dummy, TEST\n.long 0x03073336 #FoD, Pokemon Stadium\n.long 0x030D2945 #Peach's Castle, Kongo Jungle\n.long 0x0511091A #Brinstar, Corneria\n.long 0x02061517 #Yoshi's Story, Onett\n.long 0x0000434C #Mute City, Rainbow Cruise\n.long 0x00000000 #Jungle Japes, Great Bay\n.long 0x0E0D0000 #Hyrule Temple, Brinstar Depths\n.long 0x00051E2E #Yoshi's Island, Green Greens\n.long 0x0C0E0204 #Fourside, MKI\n.long 0x03050000 #MKII, Akaneia\n.long 0x06120000 #Venom, PokeFloats\n.long 0xD7E20000 #Big Blue, Icicle Mountain\n.long 0x00000000 #Icetop, Flatzone\n.long 0x0305030B #Dream Land, Yoshis Island 64\n.long 0x06100005 #Kongo Jungle 64, Battlefield\n.long 0x00020101 #Final Destination\n\n\n\n####################################\n#CliffWait -> Fall\nLedgedashProg0:\n#*********************#\n.hword 0x7F00\n.hword ASID_CliffCatch,ASID_CliffWait\n.hword ASID_RebirthWait\n#*********************#\n.hword 0x7F01\n.hword ASID_Fall\n#*********************#\n.hword 0x7F02\n.hword ASID_JumpAerialF,ASID_JumpAerialB\n#*********************#\n.hword -1\n.align 2\n\n#Fall -> JumpAerial\nLedgedashProg1:\n.hword 0x7F00\n.hword ASID_CliffCatch,ASID_CliffWait\n#*********************#\n.hword 0x7F01\n.hword ASID_Fall,ASID_PassiveWallJump\n#*********************#\n.hword 0x7F02\n.hword ASID_JumpAerialF,ASID_JumpAerialB\n.hword ASID_FallSpecial,ASID_CliffJumpSlow2\n.hword ASID_FallAerial,0x17E\n.hword 0x166,0x167\n.hword 0x170,0x164\n.hword 0x155,0x15e\n.hword 0x15f,0x160\n.hword 0x16B,0x171\n.hword 0x15C,0x16D\n.hword 0x165,0x16E\n.hword 0x168,0x161\n.hword 0x176,0x15D\n.hword 0x169,0x162\n#*********************#\n.hword -1\n.align 2\n\n\n#JumpAerial -> Airdodge\nLedgedashProg2:\n#*********************#\n.hword 0x7F02\n.hword ASID_JumpAerialF,ASID_PassiveWallJump\n.hword ASID_JumpAerialB,ASID_Fall\n.hword ASID_FallSpecial,ASID_CliffJumpSlow2\n.hword ASID_FallAerial,0x17E\n.hword 0x167,0x170\n.hword 0x164,0x162\n.hword 0x15e,0x15f\n.hword 0x160,0x16B\n.hword 0x171,0x15C\n.hword 0x16D,0x16E\n.hword 0x165,0x168\n.hword 0x161,0x176\n.hword 0x15D,0x155\n.hword 0x169,0x166\n#*********************#\n.hword 0x7F03\n.hword ASID_EscapeAir,ASID_AttackAirB\n.hword ASID_AttackAirB,ASID_AttackAirU\n.hword ASID_AttackAirD,ASID_AttackAirF\n.hword ASID_AttackAirN,ASID_LandingFallSpecial\n#*********************#\n.hword 0x7F00\n.hword ASID_CliffCatch\n#*********************#\n.hword -1\n.align 2\n\n#Airdodge -> Landing\nLedgedashProg3:\n#*********************#\n.hword 0x7F03\n.hword 0xAA\t\t#i think this is just a placeholder, could prob remove but w/e\n#*********************#\n.hword 0x7F04\n.hword ASID_LandingFallSpecial,ASID_Landing\n#*********************#\n.hword -1\n.align 2\n\n\n#Landing -> Wait\nLedgedashProg4:\n#*********************#\n.hword 0x7F04\n.hword ASID_LandingFallSpecial\n#*********************#\n.hword 0x7F02\n.hword ASID_Fall\n#*********************#\n.hword -1\n.align 2\n\n\n####################################\n\nLedgedashWindowInfo:\nblrl\n.long 0x010101FF  #1 window, Respawn Platform has 2 options, AutoRestore has 2 options\n\nLedgedashWindowText:\nblrl\n\n#Option Title = Starting Location\n.string \"Starting Location\"\n.align 2\n\n#Option 1 = Ledge\n.string \"Ledge\"\n.align 2\n\n#Option 2 = Respawn Platform\n.string \"Respawn Platform\"\n.align 2\n\n#Option Title = AutoRestore\n.string \"AutoRestore\"\n.align 2\n\n#Option 1 = On\n.string \"On\"\n.align 2\n\n#Option 2 = Off\n.string \"Off\"\n.align 2\n\n\n####################################\n\nLedgedashLoadExit:\nrestore\nblr\n\n#endregion\n\n#region SDI Training\n##############################\n## SDI Training HIJACK INFO ##\n##############################\n\nSDITraining:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Fox.Ext\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,FinalDestination\t\t\t#Use SSS Stage\n\tload r7,EventOSD_SDI\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#Make default color\n\tlwz\tr3,0x0(r29)\n\tlwz\tr3,0x18(r3)\t\t#p2 pointer\n\tli  r4,0x0\n\tstb r4,0x3(r3)    #Default color\n\n#STORE THINK FUNCTION\nSDITrainingStoreThink:\nbl\tSDITrainingLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\n\t########################\n\t## SDI Training LOAD FUNCT ##\n\t########################\n\tSDITrainingLoad:\n\tblrl\n\n\tbackup\n\n\tbl\tInitializeHighScore\n\n\t#Schedule Think\n\tbl\tSDITrainingThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  li  r5,0    #No Option Menu\n\tbl\tCreateEventThinkFunction\n\n\tb\tSDITrainingLoadExit\n\n\n\t\t#########################\n\t\t## SDI Training THINK FUNCT ##\n\t\t#########################\n\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n\t\tSDITrainingThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tli\tr3,0xF\n\t\tstw\tr3,0x1A94(r29)\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tSDITrainingThinkMain\n\n  \t\t\tbl\tSDITrainingFloats\n  \t\t\tmflr\tr3\n  \t\t\tbl\tEvent_EnterGrab\n\t\t\t#Store 999 To Breakout\n  \t\t\tlis\tr3,0x4461\n  \t\t\tstw\tr3,0x1A4C(r27)\n\t\t\t#Give Percent\n  \t\t\tbl\tSDITrainingStartingPercents\n  \t\t\tmflr\tr4\n  \t\t\tlwz\tr3,0x4(r27)\t\t#Get Char ID\n  \t\t\tlbzx\tr3,r3,r4\t\t#Get Percent\n  \t\t\tload\tr4,0x80453080\t\t#P1 Static Block\n  \t\t\tsth\tr3,0x60(r4)\t\t#Store Percent Int To Display Value\n  \t\t\tsth\tr3,0x62(r4)\t\t#Store Percent Int To Display Value (Subchar)\n  \t\t\tbl\tIntToFloat\n  \t\t\tstfs\tf1,0x1830(r27)\t\t#Store to Actual Damage Value\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n\t\t\t#Save State\n  \t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n  \t\t\tbl\tSaveState_Save\n\t\t\t#Random Start Time\n  \t\t\tli\tr3,60\n  \t\t\tbranchl\tr12,HSD_Randi\n  \t\t\tli\tr4,0\n  \t\t\tsub\tr3,r4,r3\n  \t\t\tstw\tr3,0x4(r31)\t\t#Reset Timer\n\n\n\t\tSDITrainingThinkMain:\n\n\t\t#Inc Timer\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tstw\tr3,0x4(r31)\n\n\t\t#Check If SDI'd UpAir (Damage_LightHit + No Hitstun)\n\t\t#Check If Already Incremented\n\t\t\tlbz\tr3,0xA(r31)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbeq\tSDITraining_SkipSDICheck\n\t\t#Check AS\n\t\t\tlwz\tr3,0x10(r27)\n\t\t\tcmpwi\tr3,0x55\n\t\t\tbne\tSDITraining_SkipSDICheck\n\t\t#Check For Hitstun\n\t\t\tlbz\tr3, 0x221C (r27)\n\t\t\trlwinm.\tr0, r3, 31, 31, 31\n\t\t\tbne\tSDITraining_SkipSDICheck\n\t\t#Set Flag\n\t\t\tli\tr3,0x1\n\t\t\tstb\tr3,0xA(r31)\n\t\t#Play Sound\n\t\t\tli\t\tr3,0xAD\n\t\t\tbl PlaySFX\n\t\t#Increment Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\t#Check To Make New High Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tlhz\tr4,-0x4ea6(r13)\n\t\t\tcmpw\tr3,r4\n\t\t\tble\tSDITraining_SkipSDICheck\n\t\t#Copy To High Score\n\t\t\tsth\tr3,-0x4ea6(r13)\n\t\tSDITraining_SkipSDICheck:\n\n\t\t#Check If Missed SDI\t(Fox in UpAir + P1 in Damage Heavy State)\n\t\t#Check If Fox Is Up-Airing\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x44\n\t\t\tbne\tSDITraining_SkipMissedSDICheck\n\t\t#Check If P1 is in Hitlag\n\t\t\tlbz\tr3,0x221A(r27)\t\t\t#Check If in Hitlag\n\t\t\trlwinm.\tr3,r3,0,26,26\n\t\t\tbeq\tSDITraining_SkipMissedSDICheck\n\t\t#Check If Fox is Past Frame 11\n\t\t\tli\tr3,11\n\t\t\tbl\tIntToFloat\n\t\t\tlfs\tf2,0x894(r29)\n\t\t\tfcmpo\tcr0,f2,f1\n\t\t\tblt\tSDITraining_SkipMissedSDICheck\n\t\t#Reset Score\n\t\t\tli\tr3,0\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\tSDITraining_SkipMissedSDICheck:\n\n\t\t#Update Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\n\t\t#Check State\n\t\t\tlbz\tr3,0x8(r31)\n\t\t\tcmpwi\tr3,0\n\t\t\tbeq\tSDITrainingUpThrowThink\n\t\t\tcmpwi\tr3,1\n\t\t\tbeq\tSDITrainingFollowOpponentThink\n\t\t\tcmpwi\tr3,2\n\t\t\tbeq\tSDITrainingJumpThink\n\t\t\tcmpwi\tr3,3\n\t\t\tbeq\tSDITrainingUpAirThink\n\t\t\tcmpwi\tr3,4\n\t\t\tbeq\tSDITrainingCheckForReset\n\n\n#******************************************************#\n\n\t\tSDITrainingUpThrowThink:\n\t\t#Check Timer\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tblt\tSDITrainingThinkExit\n\t\t#Check If In Wait\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0xE\n\t\t\tbne\tSDITrainingUpThrowThink_InputUpThrow\n\n\t\t\t#Advance to Next State\n\t\t\t\tli\tr3,0x1\n\t\t\t\tstb\tr3,0x8(r31)\n\t\t\t\tb\tSDITrainingFollowOpponentThink\n\n\t\tSDITrainingUpThrowThink_InputUpThrow:\n\t\t#UpThrow\n\t\t\tli\tr3,127\n\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\tb\tSDITrainingThinkExit\n\n#******************************************************#\n\n\t\tSDITrainingFollowOpponentThink:\n\n\t\tSDITrainingFollowOpponentThink_CheckIfAirbourne:\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbne\tSDITrainingFollowOpponentThink_CheckDistance\n\t\t\tli\tr3,0x2\n\t\t\tstb\tr3,0x8(r31)\n\t\t\tb\tSDITrainingJumpThink\n\n\t\tSDITrainingFollowOpponentThink_CheckDistance:\n\t\t\t#Determine Which Distance Value\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x14\n\t\t\tbne\t0xC\n\t\t\tli\tr3,15\n\t\t\tb\t0x8\n\t\t\tli\tr3,10\n\t\t\tbl\tSDITrainingInputTowardsOpponent\n\t\t#Check If Already Jumping, If So Follow Through\n\t\t\tlwz\tr4,0x10(r29)\n\t\t\tcmpwi\tr4,0x18\n\t\t\tbeq\tSDITrainingFollowOpponentThink_CheckIfJumping\n\t\t\tcmpwi\tr3,0x1\t\t\t#Checks If In Range of Opponent\n\t\t\tbne\tSDITrainingThinkExit\n\n\t\t#Check If Jumping\n\t\tSDITrainingFollowOpponentThink_CheckIfJumping:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x18\n\t\t\tbne\tSDITrainingFollowOpponentThink_InputJump\n\t\t#If Less than 32 Mm Away, Short Hop\n\t\t\tlfs\tf1,0xB4(r27)\t\t#P1 X Coord\n\t\t\tlfs\tf2,0xB4(r29)\t\t#P2 X Coord\n\t\t\tfsubs\tf3,f2,f1\t\t#Get Difference\n\t\t\tli\tr3,32\n\t\t\tbl\tIntToFloat\n\t\t\tfabs\tf2,f3\n\t\t\tfcmpo\tcr0,f2,f1\n\t\t\tblt\tSDITrainingThinkExit\n\n\t\t#Input Jump\n\t\tSDITrainingFollowOpponentThink_InputJump:\n\t\t\tli\tr3,0x800\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tSDITrainingThinkExit\n\n#******************************************************#\n\n\t\tSDITrainingJumpThink:\n\t\t#Follow Opponent\n\t\t\tli\tr3,5\n\t\t\tbl\tSDITrainingInputTowardsOpponent\n\t\t#When Less Than 35 Mm Away in the Y Direction, Up Air\n\t\t\tlfs\tf1,0xB4(r27)\t\t#P1 X Coord\n\t\t\tlfs\tf2,0xB4(r29)\t\t#P2 X Coord\n\t\t\tfsubs\tf3,f2,f1\t\t#Get Difference\n\t\t\tli\tr3,35\n\t\t\tbl\tIntToFloat\n\t\t\tfabs\tf2,f3\n\t\t\tfcmpo\tcr0,f2,f1\n\t\t\tbgt\tSDITrainingJumpThink_CheckToDJ\n\t\t#Input UpAir\n\t\t\tli\tr3,127\n\t\t\tstb\tr3,0x1A8F(r29)\n\t\t#Set Timer To Reset\n\t\t\tli\tr3,60\n\t\t\tstb\tr3,0x9(r31)\n\t\t#Advance State\n\t\t\tli\tr3,0x3\n\t\t\tstb\tr3,0x8(r31)\n\t\t\tb\tSDITrainingUpAirThink\n\n\t\tSDITrainingJumpThink_CheckToDJ:\n\t\t#If in Frame X Of Jump, DJ\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x19\n\t\t\tbeq\tSDITrainingJumpThink_CheckToDJ_InJump\n\t\t\tcmpwi\tr3,0x1A\n\t\t\tbeq\tSDITrainingJumpThink_CheckToDJ_InJump\n\t\t\tb\tSDITrainingThinkExit\n\t\t\tSDITrainingJumpThink_CheckToDJ_InJump:\n\t\t\tli\tr3,4\n\t\t\tbl\tIntToFloat\n\t\t\tlfs\tf2,0x894(r29)\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tbne\tSDITrainingThinkExit\n\t\t#Enter DJ\n\t\t\tli\tr3,0x800\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tSDITrainingThinkExit\n\n#******************************************************#\n\n\t\tSDITrainingUpAirThink:\n\t\t#Check If UpAir Hitboxes Are Over\n\t\t\tli\tr3,12\n\t\t\tbl\tIntToFloat\n\t\t\tlfs\tf2,0x894(r29)\n\t\t\tfcmpo\tcr0,f2,f1\n\t\t\tbge\tSDITrainingCheckForReset\n\t\t#Follow Opponent\n\t\t\tli\tr3,5\n\t\t\tbl\tSDITrainingInputTowardsOpponent\n\t\t#Check If Back On Ground\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tSDITrainingCheckForReset\n\t\t#Advance State\n\t\t\tli\tr3,0x4\n\t\t\tstb\tr3,0x8(r31)\n\t\t\tb\tSDITrainingCheckForReset\n\n#******************************************************#\n\nSDITrainingInputTowardsOpponent:\n#Returns a bool indicating if the character is within range\n\nbackup\n\nmr\tr31,r3\t\t\t#Backup Distance Threshold\n\n#Get X Distance\n\tlfs\tf1,0xB0(r27)\t\t#P1 X Coord\n\tlfs\tf2,0xB0(r29)\t\t#P2 X Coord\n\tfsubs\tf3,f2,f1\t\t#Get Difference\n#If Within 4 Mm, Jump\n\tmr\tr3,r31\n\tbl\tIntToFloat\n\tfabs\tf2,f3\n\tfcmpo\tcr0,f2,f1\n\tbgt\tSDITrainingFollowOpponentThink_InputTowardsOpponent\n\tli\tr3,0x1\n\tb\tSDITrainingInputTowardsOpponent_Exit\n\nSDITrainingFollowOpponentThink_InputTowardsOpponent:\n#Push Towards Opponent's Direction\n\tbl\tGetDirectionInRelationToP1\n\tmulli\tr3,r3,-1\t\t#Negate This\n\tli\tr4,127\n\tmullw\tr3,r3,r4\n\tstb\tr3,0x1A8C(r29)\n\tli\tr3,0x0\n\nSDITrainingInputTowardsOpponent_Exit:\n\trestore\n\tblr\n\n#******************************************************#\n\n\n\t\tSDITrainingCheckForReset:\n\t\t\tlbz\tr3,0x9(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tSDITrainingThinkExit\n\t\t\tsubi\tr3,r3,0x1\n\t\t\tstb\tr3,0x9(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tSDITrainingThinkExit\n\t\t#Load State\n\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\tbl\tSaveState_Load\n\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\tbl\tSaveState_Load\n\t\t#Random Timer\n\t\t\tli\tr3,60\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tmulli\tr3,r3,-1\n\t\t\tstw\tr3,0x4(r31)\n\t\t#Reset State\n\t\t\tli\tr3,0\n\t\t\tstb\tr3,0x8(r31)\n\t\t#Reset SDI'd Flag\n\t\t\tli\tr3,0x0\n\t\t\tstb\tr3,0xA(r31)\n\n\t\tSDITrainingThinkExit:\n\t\trestore\n\t\tblr\n\n##############\n\nEvent_EnterGrab:\nbackup\n\nmr\tr20,r3\n\n#Move P1\nlfs\tf1,0x0(r20)\nstfs\tf1,0xB0(r27)\nlfs\tf1,0x4(r20)\nstfs\tf1,0xB4(r27)\nmr\tr3,r28\nbl  UpdatePosition\nmr\tr3,r28\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0\nbeq\tEvent_EnterGrab_MoveP2\n#Move Subchar\nlfs\tf1,0x0(r20)\nstfs\tf1,0xB0(r5)\nlfs\tf1,0x4(r20)\nstfs\tf1,0xB4(r5)\nbl  UpdatePosition\n\n\nEvent_EnterGrab_MoveP2:\n#Move P2\nlfs\tf1,0x8(r20)\nstfs\tf1,0xB0(r29)\nlfs\tf1,0xC(r20)\nstfs\tf1,0xB4(r29)\nmr\tr3,r30\nbl  UpdatePosition\nmr\tr3,r30\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0\nbeq\tEvent_EnterGrab_EnterGrabAS\n#Move Subchar\nlfs\tf1,0x8(r20)\nstfs\tf1,0xB0(r5)\nlfs\tf1,0xC(r20)\nstfs\tf1,0xB4(r5)\nbl  UpdatePosition\n\nEvent_EnterGrab_EnterGrabAS:\n#Store P1 into P2 Grab Pointer\nstw\tr28,0x1A58(r29)\n\n#Enter P2 Into Grab\nmr\tr3,r30\t\t\t#P2 Enters Grab\nbranchl\tr12,AS_GrabOpponent\n\n#Enter P1 Into Grabbed\nmr\tr3,r28\t\t\t#P1 Grabbed\nmr\tr4,r30\t\t\t#P2 = Grabber\nbranchl\tr12,AS_Grabbed\n\n#Enter P2 Into GrabWait\nmr\tr3,r30\t\t\t#P2 Enters GrabWait\nbranchl\tr12,AS_CatchWait\n\n#Enter P2 Into Grounded\nmr\tr3,r29\nbranchl\tr12,SetAsGrounded\n\n#Remove P2's GFX Pointer That Is Crashing the Game\nli\tr3,0x0\nstw\tr3,0x60C(r29)\n\nrestore\nblr\n\n##############\n\nSDITrainingStartingPercents:\nblrl\n.long 0x085F8040 # Mario = 8 / Fox = 95 / Falcon = 70 / DK = 25\n.long 0x0030190F # Kirby = 0 / Bowser = 25 / Link = 25 / Sheik = 15\n.long 0x00000000 # Ness = 0 / Peach = 0 / Popo = 0 / Nana = 0\n.long 0x08050F00 # Pikachu = 8 / Samus = 5 / Yoshi = 15 / Jiggs = 0\n.long 0x00001400 # Mewtwo = 0 / Luigi = 0 / Marth = 20 / Zelda = 0\n.long 0x19085F00 # YLink = 25 / Doc = 8 / Falco = 95 / Pichu = 0\n.long 0x002D3A00 # GaW = 0 / Ganon = 45 / Roy = 58\n\nSDITrainingFloats:\nblrl\n.long 0xC02CCCCD\t\t#P1 X Position\n.long 0x00000000\t\t#P1 Y Position\n.long 0x4144CCCD\t\t#P2 X Position\n.long 0x00000000\t\t#P2 Y Position\n\nSDITrainingLoadExit:\nrestore\nblr\n\n\n\n\n################################################################################\n################################################################################\n#endregion\n\n#region Reversal Training\n#########################\n## Reversal HIJACK INFO ##\n#########################\n\nReversal:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t\t#Use SSS Stage\n\tload r7,EventOSD_Reversal\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nbl\tReversalLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Reversal LOAD FUNCT ##\n\t########################\n\tReversalLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tReversalThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  bl\tReversalWindowInfo\n  mflr\tr5\n  bl\tReversalWindowText\n  mflr\tr6\n\tbl\tCreateEventThinkFunction\n\n\tb\tReversalLoadExit\n\n\n\t\t#########################\n\t\t## Reversal THINK FUNCT ##\n\t\t#########################\n\n    .set MenuData,26\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n\t\t.set firstFrameFlag,0x0\n\t\t.set timer,0x4\n\t\t.set CPUAttack,(MenuData_OptionMenuMemory+0x2)+(0x0)\n\t\t.set P1FacingDirection,(MenuData_OptionMenuMemory+0x2)+(0x1)\n\t\t.set CPUFacingDirection,(MenuData_OptionMenuMemory+0x2)+(0x2)\n    .set CPUAttackToggled,MenuData_OptionMenuToggled+(0x0)\n    .set P1FacingDirectionToggled,MenuData_OptionMenuToggled+(0x1)\n    .set CPUFacingDirectionToggled,MenuData_OptionMenuToggled+(0x2)\n\t\t.set AerialThinkStruct,0x20\n\n\t\tReversalThink:\n\t\tblrl\n\n    .set EventData,31\n\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n    lwz MenuData,EventData_MenuDataPointer(EventData)\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tli\tr3,0xF\n\t\tstb\tr3,0x1A94(r29)\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tReversalThinkMain\n\n  \t\t\t#bl\tReversal_Floats\n  \t\t\t#mflr r3\n  \t\t\t#bl\tInitializePositions\n      #Move PLayers Center Stage\n        bl  PlacePlayersCenterStage\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n      #SaveState\n        addi  r3,EventData,0x10       #SaveState start\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n  \t\t\tbl\tSaveState_Save\n\t\t\t#Set Frame 1 As Over\n  \t\t\tli\t\tr3,0x1\n  \t\t\tstb\t\tr3,0x0(r31)\n\t\t\t#Set Timer to -60\n  \t\t\tli\t\tr3,-60\n  \t\t\tstw\t\tr3,0x4(r31)\n\n\n\t\tReversalThinkMain:\n\n\t\tbl\tGiveFullShields\n\n    #Reset when menu is toggled\n      lbz r3,P1FacingDirectionToggled(MenuData)\n  \t\tcmpwi\tr3,0x0\n  \t\tbne\tReversalReset\t\t\t#Only Run When Hovered Over Facing Direction\n      lbz r3,CPUFacingDirectionToggled(MenuData)\n  \t\tcmpwi\tr3,0x0\n  \t\tbne\tReversalReset\t\t\t#Only Run When Hovered Over Facing Direction\n      lbz r3,CPUAttackToggled(MenuData)\n      cmpwi r3,0x0\n      bne ReversalReset\n\t\tReversalSkipFacingReset:\n\n\t\t#Move Players Apart With DPad\n      addi  r3,EventData,0x10       #SaveState start\n  \t\tbl\tAdjustResetDistance\n  \t\tcmpwi\tr3,-1\n  \t\tbne\tReversalReset\n\n\t\tReversalThinkSequence:\n\n\t\t#Increment Timer\n\t\tlwz\tr20,0x4(r31)\t\t#get timer\n\t\taddi\tr20,r20,0x1\n\t\tstw\tr20,0x4(r31)\t\t#store timer\n\n\t\t#Give Invincibility in Wait, Squat Reverse, IASA Flag Flipped\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xE\n\t\tbeq\tReversalGiveInvincibility\n\t\tcmpwi\tr3,0x29\n\t\tbeq\tReversalGiveInvincibility\n\t\tlbz\tr3, 0x2218 (r29)\n\t\trlwinm.\tr3, r3, 25, 31, 31\n\t\tbne\tReversalGiveInvincibility\n\t\tb\tReversalCheckToAttack\n\n\t\tReversalGiveInvincibility:\n\t\tmr\tr3,r30\n\t\tli\tr4,0x2\n\t\tbl\tGiveInvincibility\n\n\t\t#Check To Attack\n\t\tReversalCheckToAttack:\n\t\t#Check Timer\n\t\t\tcmpwi\tr20,45\n\t\t\tblt\tReversalThinkExit\n\t\t#Check If Attack is Over\n\t\t\tlbz r3,AerialThinkStruct(r31)\n\t\t\tcmpwi r3,0x0\n\t\t\tbne ReversalCheckToReset\n\n\n\t\tReversalDecideSmashAttack:\n\t\tlbz\tr3,CPUAttack(MenuData)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tReversalRandomSmashAttack\n\t\tcmpwi\tr3,0x1\n\t\tbeq\tReversalFSmash\n\t\tcmpwi\tr3,0x2\n\t\tbeq\tReversalDSmash\n\t\tcmpwi\tr3,0x3\n\t\tbeq\tReversalUSmash\n\t\tcmpwi r3,0x4\n\t\tbeq\tReversalRandomAerial\n\t\tcmpwi r3,0x5\n\t\tbeq\tReversalNair\n\t\tcmpwi r3,0x6\n\t\tbeq\tReversalFair\n\t\tcmpwi r3,0x7\n\t\tbeq\tReversalDair\n\t\tcmpwi\tr3,0x8\n\t\tbeq\tReversalFTilt\n\t\tcmpwi\tr3,0x9\n\t\tbeq\tReversalDTilt\n\t\tcmpwi\tr3,0xA\n\t\tbeq\tReversalUTilt\n\n\t\tReversalRandomSmashAttack:\n\t\t\tli\tr3,3\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tmr\tr21,r3\n\t\t#Check If Move is Blacklisted\n\t\t\tlwz\tr4,0x4(r29)\t\t#Char ID\n\t\t\tbl\tReversal_Blacklist\n\t\t\tmflr\tr5\t\t#Get Frame Data Table\n\t\t\tmulli\tr4,r4,0x4\t\t#Get Characters Offset\n\t\t\tadd\tr4,r4,r5\t\t#Get Characters Table Entry Start\n\t\t\tlbzx\tr4,r21,r4\t\t#Get Moves Entry\n\t\t\tcmpwi\tr4,0x1\t\t#Is Move BlackListed?\n\t\t\tbeq\tReversalRandomSmashAttack\n\n\t\t#Perform Move\n\t\t\tcmpwi\tr21,0x0\n\t\t\tbeq\tReversalFSmash\n\t\t\tcmpwi\tr21,0x1\n\t\t\tbeq\tReversalUSmash\n\t\t\tcmpwi\tr21,0x2\n\t\t\tbeq\tReversalDSmash\n\t\tReversalFSmash:\n\t\t#Input Atack\n\t\t\tli\tr3,127\t\t#Forward\n\t\t\tlfs\tf1,0x2C(r29)\t\t#Facing Direction\n\t\t\tfctiwz\tf1,f1\n\t\t\tstfd\tf1,0xF0(sp)\n\t\t\tlwz\tr4,0xF4(sp)\n\t\t\tmullw\tr3,r3,r4\t\t#Forward * facing direction\n\t\t\tstb\tr3,0x1A8E(r29)\n\t\t#Set Attack as ended\n\t\t\tli\tr3,0x1\n\t\t\tstb r3,AerialThinkStruct(r31)\n\t\t\tb\tReversalCheckToReset\n\t\tReversalUSmash:\n\t\t\tli\tr3,127\n\t\t\tstb\tr3,0x1A8F(r29)\n\t\t\tb\tReversalCheckToReset\n\t\t#Set Attack as ended\n\t\t\tli\tr3,0x1\n\t\t\tstb r3,AerialThinkStruct(r31)\n\t\tReversalDSmash:\n\t\t\tli\tr3,-127\n\t\t\tstb\tr3,0x1A8F(r29)\n\t\t#Set Attack as ended\n\t\t\tli\tr3,0x1\n\t\t\tstb r3,AerialThinkStruct(r31)\n\t\t\tb\t\tReversalCheckToReset\n\t\tReversalRandomAerial:\n\t\t#Perform Aerial\n\t\t\tmr\t\tr3,r30\n\t\t\taddi\tr4,r31,AerialThinkStruct\n\t\t\tli\t\tr5,0\t\t#Random Aerial\n\t\t\tbl\t\tPerformAerialThink\n\t\t\tb\t\tReversalCheckToReset\n\t\tReversalNair:\n\t\tReversalFair:\n\t\tReversalDair:\n\t\t#Perform Aerial\n\t\t\tsubi\tr5,r3,0x4\n\t\t\tmr\t\tr3,r30\n\t\t\taddi\tr4,r31,AerialThinkStruct\n\t\t\tbl\t\tPerformAerialThink\n\t\t\tb\t\tReversalCheckToReset\n\t\tReversalFTilt:\n\t\t\tli\tr3,45\n\t\t\tlfs\tf1,0x2C(r29)\t\t#Facing Direction\n\t\t\tfctiwz\tf1,f1\n\t\t\tstfd\tf1,0xF0(sp)\n\t\t\tlwz\tr4,0xF4(sp)\n\t\t\tmullw\tr3,r3,r4\t\t#Forward * facing direction\n\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\tli\tr3,0x100\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t#Set Attack as ended\n\t\t\tli\tr3,0x1\n\t\t\tstb r3,AerialThinkStruct(r31)\n\t\t\tb\tReversalCheckToReset\n\t\tReversalUTilt:\n\t\t\tli\tr3,45\n\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\tli\tr3,0x100\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t#Set Attack as ended\n\t\t\tli\tr3,0x1\n\t\t\tstb r3,AerialThinkStruct(r31)\n\t\t\tb\tReversalCheckToReset\n\t\tReversalDTilt:\n\t\t\tli\tr3,-45\n\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\tli\tr3,0x100\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t#Set Attack as ended\n\t\t\tli\tr3,0x1\n\t\t\tstb r3,AerialThinkStruct(r31)\n\t\t\tb\tReversalCheckToReset\n\n\n\t\tReversalCheckToReset:\n\t\t\tcmpwi\tr20,150\t\t#Restore After 120 Frames\n\t\t\tblt\tReversalThinkExit\n\t\tReversalReset:\n    ReversalSwap:\n    #I fucking hate this code, i need to clean this up at some point.\n    #Get leftmost player pointer in r20, rightmost in r21\n      addi r5,EventData,0x10\n      lwz r3,0x0(r5)\n      lfs f1,0xB0(r3)\n      lwz r4,0x8(r5)\n      lfs f2,0xB0(r4)\n      fcmpo cr0,f1,f2\n      bgt 0x10\n      mr r20,r3\n      mr r21,r4\n      b 0xC\n      mr r20,r4\n      mr r21,r3\n    #Get which side to start on\n      li\tr3,2        #0 = p1 on left, 1 = p1 on right\n      branchl r12,HSD_Randi\n      cmpwi r3,0x0\n      bne ReversalReset_RightSide\n    ReversalReset_LeftSide:\n    #Swap Position\n      addi r5,EventData,0x10\n      #Get Leftmost Chars Position\n        li  r3,1\n        bl  IntToFloat\n        fmr f2,f1\n        lfs f3,0xB0(r20)\n        lfs f4,0xB4(r20)\n      #Get Rightmost Chars Position\n        li  r3,-1\n        bl  IntToFloat\n        fmr f5,f1\n        lfs f6,0xB0(r21)\n        lfs f7,0xB4(r21)\n      #Store to P1 Data\n        lwz r3,0x0(r5)\n        stfs f2,0x2C(r3)\n        stfs f3,0xB0(r3)\n        stfs f4,0xB4(r3)\n      #Store to P2 Data\n        lwz r3,0x8(r5)\n        stfs f5,0x2C(r3)\n        stfs f6,0xB0(r3)\n        stfs f7,0xB4(r3)\n        b ReversalReset_SwapEnd\n    ReversalReset_RightSide:\n      addi r5,EventData,0x10\n      #Get Leftmost Chars Position\n        li  r3,1\n        bl  IntToFloat\n        fmr f2,f1\n        lfs f3,0xB0(r20)\n        lfs f4,0xB4(r20)\n      #Get Rightmost Chars Position\n        li  r3,-1\n        bl  IntToFloat\n        fmr f5,f1\n        lfs f6,0xB0(r21)\n        lfs f7,0xB4(r21)\n      #Store to P2 Data\n        lwz r3,0x8(r5)\n        stfs f2,0x2C(r3)\n        stfs f3,0xB0(r3)\n        stfs f4,0xB4(r3)\n      #Store to P1 Data\n        lwz r3,0x0(r5)\n        stfs f5,0x2C(r3)\n        stfs f6,0xB0(r3)\n        stfs f7,0xB4(r3)\n    ReversalReset_SwapEnd:\n    ReversalAdjustP1Direction:\n\t\t#Adjust P1 Facing Direction Based on Preference\n      addi r5,EventData,0x10\n\t\t\tlbz\tr3,P1FacingDirection(MenuData)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbne\tReversalAdjustP1Direction_Skip\n\t\t#Invert P1 Facing Direction\n\t\t\tlwz\tr3,0x0(r5)\n\t\t\tlfs\tf1,0x2C(r3)\n\t\t\tfneg\tf1,f1\n\t\t\tstfs\tf1,0x2C(r3)\n    ReversalAdjustP1Direction_Skip:\n\t\t#Adjust CPU Facing Direction Based on Preference\n\t\tReversalAdjustCPUDirection:\n\t\t\tlbz\tr3,CPUFacingDirection(MenuData)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbne\tReversalAdjustCPUDirection_Skip\n\t\t#Invert P2 Facing Direction\n\t\t\tlwz\tr3,0x8(r5)\n\t\t\tlfs\tf1,0x2C(r3)\n\t\t\tfneg\tf1,f1\n\t\t\tstfs\tf1,0x2C(r3)\n    ReversalAdjustCPUDirection_Skip:\n\t\t#Restore\n\t\tReversalLoadState:\n\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\tbl\tSaveState_Load\n\t\t#Reset Timer\n\t\t\tli\tr3,30\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tli\tr4,0\n\t\t\tsub\tr3,r4,r3\n\t\t\tstw\tr3,0x4(r31)\n\t\t#Reset AerialThinkStruct\n\t\t\tli\tr3,0x0\n\t\t\tstw r3,AerialThinkStruct(r31)\n\n\t\tReversalThinkExit:\n      mr  r3,MenuData\n      bl  ClearToggledOptions\n\t\t\tbl\tUpdateAllGFX\n\t\t\trestore\n\t\t\tblr\n\n\n#################################\n\nReversal_Floats:\nblrl\n.long 0xC0F9999A\t\t#P1 X Position\n.long 0x40F9999A\t\t#P2 X Position\n.long 0x38d1b717\t\t#FD Floor Y Coord\n.long 0x38d1b717\t\t#FD Floor Y Coord\n\n#################################\n\nReversal_Blacklist:\nblrl\n#Mario\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Fox\n.long 0x01000000 \t#FSmash USmash DSmash\n\n#Cptn Falcon\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#DK\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#Kirby\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Bowser\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#link\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Sheik\n.long 0x01000000\t\t#FSmash USmash DSmash\n\n#Ness\n.long 0x00010100\t\t#FSmash USmash DSmash\n\n#Peach\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#Popo\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Nana\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Pikachu\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Samus\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#Yoshi\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#Jiggs\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#mewtwo\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#Luigi\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Marth\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#Zelda\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n#YLink\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Doc\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Falco\n.long 0x01000000\t\t#FSmash USmash DSmash\n\n#Pichu\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#GaW\n.long 0x00000100\t\t#FSmash USmash DSmash\n\n#Ganon\n.long 0x00000000\t\t#FSmash USmash DSmash\n\n#Roy\n.long 0x00010000\t\t#FSmash USmash DSmash\n\n####################################################\n\nReversalWindowInfo:\nblrl\n#amount of options, amount of options in each window\n\n.long 0x020A0101  #3 window, Smash Attack has 11 options, Facing Direction Has 2\n\n####################################################\n\nReversalWindowText:\nblrl\n\n########\n## DI ##\n########\n\n#Window Title = CPU Attack\n.long 0x43505520\n.long 0x41747461\n.long 0x636b0000\n\n#Option 1 = Random Smash Attack\n.long 0x52616e64\n.long 0x6f6d2053\n.long 0x6d617368\n.long 0x20417474\n.long 0x61636b00\n\n#Option 2 = Forward Smash\n.long 0x466f7277\n.long 0x61726420\n.long 0x536d6173\n.long 0x68000000\n\n#Option 3 = Down Smash\n.long 0x446f776e\n.long 0x20536d61\n.long 0x73680000\n\n#Option 4 = Up Smash\n.long 0x55702053\n.long 0x6d617368\n.long 0x\n\n#Option 5 = Random Aerial\n.long 0x52616e64\n.long 0x6f6d2041\n.long 0x65726961\n.long 0x6c000000\n\n#Option 6 = Fair\n.long 0x46616972\n.long 0x\n\n#Option 7 = Nair\n.long 0x4e616972\n.long 0x\n\n#Option 8 = Dair\n.long 0x44616972\n.long 0x\n\n#Option 9 = FTilt\n.long 0x4654696c\n.long 0x74000000\n\n#Option 10 = DTilt\n.long 0x4454696c\n.long 0x74000000\n\n#Option 11 = UTilt\n.long 0x5554696c\n.long 0x74000000\n\n#########$$$#############\n## P1 Facing Direction ##\n##########$$$############\n\n#Window Title = Facing Direction\n.long 0x50312046\n.long 0x6163696e\n.long 0x67204469\n.long 0x72656374\n.long 0x696f6e00\n\n#Option 1 = Towards\n.long 0x546f7761\n.long 0x72647300\n.long 0x\n.long 0x\n.long 0x\n\n#Option 2 = Away\n.long 0x41776179\n.long 0x\n.long 0x\n.long 0x\n.long 0x\n\n#########$$$##############\n## CPU Facing Direction ##\n##########$$$#############\n\n#Window Title = CP Facing Direction\n.long 0x43502046\n.long 0x6163696e\n.long 0x67204469\n.long 0x72656374\n.long 0x696f6e00\n\n\n#Option 1 = Towards\n.long 0x546f7761\n.long 0x72647300\n.long 0x\n.long 0x\n.long 0x\n\n#Option 2 = Away\n.long 0x41776179\n.long 0x\n.long 0x\n.long 0x\n.long 0x\n\n####################################################\n\nReversalLoadExit:\nrestore\nblr\n\n\n\n################################################################################\n################################################################################\n#endregion\n\n#region Powershield Training\n#########################\n## Powershield HIJACK INFO ##\n#########################\n\nPowershield:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Falco.Ext\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,FinalDestination\t\t\t#Use SSS Stage\n\tload r7,EventOSD_Powershield\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nbl\tPowershieldLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Powershield LOAD FUNCT ##\n\t########################\n\tPowershieldLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tPowershieldThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  bl\tPowershieldWindowInfo\n  mflr\tr5\n  bl\tPowershieldWindowText\n  mflr\tr6\n\tbl\tCreateEventThinkFunction\n\n\tbl\tInitializeHighScore\n\n\tb\tPowershieldLoadExit\n\n\n\t\t#########################\n\t\t## Powershield THINK FUNCT ##\n\t\t#########################\n\n    #Registers\n    .set MenuData,26\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n    #Offsets\n\t\t.set FireSpeed,(MenuData_OptionMenuMemory+0x2)+0x0\n\n\t\tPowershieldThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n    lwz   MenuData,EventData_MenuDataPointer(EventData)\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#Make P2 A Follower (No Nudge)\n\t\t#li\tr3,0x8\n\t\t#stb\tr3,0x221F(r29)\n\t\tli\tr3,0x1\n\t\tlbz\tr0, 0x221D (r29)\n\t\trlwimi\tr0,r3,2,29,29\n\t\tstb\tr0, 0x221D (r29)\n\n\t\t#Update GFX\n\t\tmr\tr3,r30\n\t\tbl\tUpdateAllGFX\n\n\t\t#Give Invincibility To P2\n\t\tmr\tr3,r30\n\t\tli\tr4,0x2\n\t\tbl\tGiveInvincibility\n\n\t\t#Reset All Stale Moves\n\t\tbl\tResetStaleMoves\n\n\t\t#DPad Changes Falco's Side\n\t\tlhz\tr3,0x662(r27)\t\t\t#Get Held Buttons\n\t\trlwinm.  r0,r3,0,27,27\n    bne 0xC\n    cmpwi r3,0x0\n\t\tbne\tPowershield_SkipPositionChange\n\t\t#CHECK FOR DPAD TO CHANGE Side\n\t\tlwz\tr3,0x668(r27)\t\t\t#Get DPad\n\t\trlwinm.\tr0,r3,0,30,30\n\t\tbeq\tPowershield_CheckLeft\n\t\tlwz\tr3,0x10(r31)\t\t\t#P1's Backup\n\t\tlfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tfabs\tf1,f1\n\t\tstfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tlfs\tf1,0x2C(r3)\t\t\t#Facing\n\t\tfabs\tf1,f1\n\t\tfneg\tf1,f1\t\t\t#Negate Always\n\t\tstfs\tf1,0x2C(r3)\t\t\t#Facing\n\n\t\tlwz\tr3,0x18(r31)\t\t\t#P2's Backup\n\t\tlfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tfabs\tf1,f1\n\t\tfneg\tf1,f1\t\t\t#Negate Always\n\t\tstfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tlfs\tf1,0x2C(r3)\t\t\t#Facing\n\t\tfabs\tf1,f1\t\t\t#Always Positive\n\t\tstfs\tf1,0x2C(r3)\t\t\t#Facing\n\t\tb\tPowershieldRestore\n\n\t\tPowershield_CheckLeft:\n\t\trlwinm.\tr0,r3,0,31,31\n\t\tbeq\tPowershield_SkipPositionChange\n\t\tlwz\tr3,0x10(r31)\t\t\t#P1's Backup\n\t\tlfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tfabs\tf1,f1\n\t\tfneg\tf1,f1\t\t\t#Negate Always\n\t\tstfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tlfs\tf1,0x2C(r3)\t\t\t#Facing\n\t\tfabs\tf1,f1\t\t\t#Always Positive\n\t\tstfs\tf1,0x2C(r3)\t\t\t#Facing\n\n\t\tlwz\tr3,0x18(r31)\t\t\t#P2's Backup\n\t\tlfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tfabs\tf1,f1\n\t\tstfs\tf1,0xB0(r3)\t\t\t#X Pos\n\t\tlfs\tf1,0x2C(r3)\t\t\t#Facing\n\t\tfabs\tf1,f1\n\t\tfneg\tf1,f1\t\t\t#Negate Always\n\t\tstfs\tf1,0x2C(r3)\t\t\t#Facing\n\t\tb\tPowershieldRestore\n\t\tPowershield_SkipPositionChange:\n\n\t\t#Act Out Of Laser Hit\n\t\tbl\tActOutOfLaserHitDisplay\n\n\t\t#Check For Powershield Reflect\n\t\t#Check For Shield Action State\n\t\t\tlwz\tr3,0x10(r27)\n\t\t\tcmpwi\tr3,0xB6\t\t#Shield Start\n\t\t\tbne\tPowershield_SkipPowershieldCheck\n\t\t#Check For Powershield Bool\n\t\t\tlwz\tr3,0x2368(r27)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tPowershield_SkipPowershieldCheck\n\t\t#Remove Flag\n\t\t\tli\tr3,0x0\n\t\t\tstw\tr3,0x2368(r27)\n\t\t#Increment Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\t#Check To Make New High Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tlhz\tr4,-0x4ea6(r13)\n\t\t\tcmpw\tr3,r4\n\t\t\tble\tPowershield_SkipPowershieldCheck\n\t\t#Copy To High Score\n\t\t\tsth\tr3,-0x4ea6(r13)\n\t\tPowershield_SkipPowershieldCheck:\n\n\t\t#Check For Powershield Miss\n\t\t#Check For Shield Stun\n\t\t\tlwz\tr3,0x10(r27)\n\t\t\tcmpwi\tr3,0xB5\t\t#Shield Stun\n\t\t\tbeq\tPowershield_ResetScore\n\t\t#Check For Hitstun\n\t\t\tlbz\tr3, 0x221C (r27)\n\t\t\trlwinm.\tr0, r3, 31, 31, 31\n\t\t\tbne\tPowershield_ResetScore\n\t\t\tb\tPowershield_SkipMissedPowershieldCheck\n\t\tPowershield_ResetScore:\n\t\t#Reset Score\n\t\t\tli\tr3,0\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\tPowershield_SkipMissedPowershieldCheck:\n\n\t\t#Update HUD Score\n\t\tlhz\tr3,-0x4ea8(r13)\n\t\tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tPowershieldThinkMain\n\n\t\t#Set Timer to -60\n\t\tli\t\tr3,-60\n\t\tstw\t\tr3,0x4(r31)\n\t\t#Fix Inputs\n\t\tbl\tCurrentInputsAsLastFramesInputs\n\t\t#SaveState\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n\t\tbl\tSaveState_Save\n\n\n\t\tPowershieldThinkMain:\n\t\tbl\tGiveFullShields\n\n\t\tPowershieldThinkSequence:\n\t\t#Increment Timer\n\t\tlwz\tr20,0x4(r31)\t\t#get timer\n\t\taddi\tr20,r20,0x1\n\t\tstw\tr20,0x4(r31)\t\t#store timer\n\n\t\t#KneeBend(shorthop)\n\t\tcmpwi\tr20,0\n\t\tblt\tPowershieldThinkExit\n\t\tbne\tPowershieldSkipJump\n\t\tli\tr3,0x800\n\t\tstw\tr3,0x1A88(r29)\n\t\tb\tPowershieldThinkExit\n\n\t\t#Get Random Laser Timing in JumpF\n\t\tPowershieldSkipJump:\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x19\n\t\tbne\tPowershieldSkipLaser\n\t\tli\tr3,4\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x894(r29)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbne\tPowershieldThinkExit\n\t\t#Random Laser Timing\n\t\tli\tr3,2\n\t\tbranchl\tr12,HSD_Randi\n\t\taddi\tr3,r3,5\t\t#Start on Frame 5\n\t\tstw\tr3,0x8(r31)\n\t\t#Input Laser\n\t\tli\tr3,0x200\n\t\tstw\tr3,0x1A88(r29)\n\t\tb\tPowershieldThinkExit\n\n\t\tPowershieldSkipLaser:\n\t\t#Check if in Laser Shoot\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x159\n\t\tbne\tPowershieldCheckForIASA\n\t\t#Check in on the right frame\n\t\tlwz\tr3,0x8(r31)\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x894(r29)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbne\tPowershieldCheckForIASA\n\t\t#Input a FF\n\t\tli\tr3,-127\n\t\tstb\tr3,0x1A8D(r29)\n\t\tb\tPowershieldThinkExit\n\n\n\t\tPowershieldCheckForIASA:\n\t\t#Check if in Landing\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x2A\n\t\tbne\tPowershieldThinkExit\n\t\t#Check If Can Interrupt\n\t\tli\tr3,3\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x894(r29)\n\t\tfcmpo\tcr0,f2,f1\n\t\tblt\tPowershieldThinkExit\n\t\tbne\tPowershieldRandom\n\t\tli\tr3,14\n\t\tbranchl\tr12,HSD_Randi\n\t\taddi\tr3,r3,15\n\t\tstb\tr3,0xF(r31)\n\t\t#Get Interval\n\t\tlbz\tr3,FireSpeed(MenuData)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tPowershieldRandom\n\t\tcmpwi\tr3,0x1\n\t\tbeq\tPowershieldSlow\n\t\tcmpwi\tr3,0x2\n\t\tbeq\tPowershieldMedium\n\t\tcmpwi\tr3,0x3\n\t\tbeq\tPowershieldFast\n\t\tcmpwi\tr3,0x4\n\t\tbeq\tPowershieldVeryFast\n\n\t\tPowershieldRandom:\n\t\tlbz\tr3,0xF(r31)\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x894(r29)\n\t\tfcmpo\tcr0,f2,f1\n\t\tblt\tPowershieldThinkExit\n\t\tli\tr3,-1\n\t\tstw\tr3,0x4(r31)\n\t\tb\tPowershieldThinkExit\n\n\t\tPowershieldSlow:\n\t\t#Reset Timer\n\t\tli\tr3,-30\n\t\tstw\tr3,0x4(r31)\n\t\tb\tPowershieldThinkExit\n\n\t\tPowershieldMedium:\n\t\t#Reset Timer\n\t\tli\tr3,-15\n\t\tstw\tr3,0x4(r31)\n\t\tb\tPowershieldThinkExit\n\n\t\tPowershieldFast:\n\t\t#Reset Timer\n\t\tli\tr3,-8\n\t\tstw\tr3,0x4(r31)\n\t\tb\tPowershieldThinkExit\n\n\t\tPowershieldVeryFast:\n\t\t#Reset Timer\n\t\tli\tr3,-1\n\t\tstw\tr3,0x4(r31)\n\t\tb\tPowershieldThinkExit\n\n\t\tPowershieldThinkExit:\n    mr  r3,MenuData\n    bl  ClearToggledOptions\n\t\trestore\n\t\tblr\n\n\nPowershieldLoadExit:\nrestore\nblr\n\n##################################\n\nPowershieldRestore:\naddi r3,EventData,EventData_SaveStateStruct\nbl\tSaveState_Load\naddi r3,EventData,EventData_SaveStateStruct\nbl\tSaveState_Load\nb\tPowershieldThinkExit\n\n##################################\n\nPowershieldWindowInfo:\nblrl\n.long 0x00040000\t\t#1 window, 5 options\n\nPowershieldWindowText:\nblrl\n\n#Title\n.long 0x46697265\n.long 0x20537065\n.long 0x65640000\n.long 0x00000000\n.long 0x00000000\n\n#Random\n.long 0x52616e64\n.long 0x6f6d0000\n.long 0x\n.long 0x\n.long 0x\n\n#Slow\n.long 0x536c6f77\n.long 0x\n.long 0x\n.long 0x\n.long 0x\n\n#Medium\n.long 0x4d656469\n.long 0x756d0000\n.long 0x\n.long 0x\n.long 0x\n\n#Fast\n.long 0x46617374\n.long 0x\n.long 0x\n.long 0x\n.long 0x\n\n#Very Fast\n.long 0x56657279\n.long 0x20466173\n.long 0x74000000\n.long 0x\n.long 0x\n\n\n\n##################################\n\n\n\n\n################################################################################\n################################################################################\n#endregion\n\n#region Shield Drop Training\n#########################\n## Shield Drop HIJACK INFO ##\n#########################\n\nShieldDrop:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,Battlefield\t\t\t\t#Use SSS Stage\n\tload r7,EventOSD_ShieldDrop\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nbl\tShieldDropLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Shield Drop LOAD FUNCT ##\n\t########################\n\tShieldDropLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tShieldDropThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  bl\tShieldDropWindowInfo\n  mflr\tr5\n  bl\tShieldDropWindowText\n  mflr\tr6\n\tbl\tCreateEventThinkFunction\n\n\tb\tShieldDropLoadExit\n\n\n\t\t##########################\n\t\t## Shield Drop THINK FUNCT ##\n\t\t##########################\n\n    #Registers\n    .set MenuData,26\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n    #Offsets\n\t\t.set FacingDirection,(MenuData_OptionMenuMemory+0x2)+0x0\n    .set FacingDirectionToggled,(MenuData_OptionMenuToggled)+0x0\n\n\t\tShieldDropThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n    lwz   MenuData,EventData_MenuDataPointer(EventData)\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tShieldDropThinkMain\n\n\t\t\t#Set Frame 1 As Over\n  \t\t\tli\tr3,0x1\n  \t\t\tstb\tr3,0x0(r31)\n  \t\t\tbl\tShieldDrop_Floats\n  \t\t\tmflr\tr3\n  \t\t\tbl\tInitializePositions\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n\t\t\t#Store Y Position to Last Known Y Position\n  \t\t\tlfs\tf1,0xB4(r29)\n  \t\t\tstfs\tf1,0x834(r29)\n\t\t\t#Save State\n  \t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n  \t\t\tbl\tSaveState_Save\n\t\t\t#Set Timer to -60\n  \t\t\tli\tr3,-60\n  \t\t\tstw\tr3,0x4(r31)\n\n\n\n\t\tShieldDropThinkMain:\n\t\t.set AerialThinkStruct,0x8\n\n\t\tbl\tGiveFullShields\n\n\t\tlbz r3,FacingDirectionToggled(MenuData)\n\t\tcmpwi\tr3,0\t\t\t#Check If Toggled An Option\n\t\tbne\tShieldDropReset\n    lbz r3,FacingDirectionToggled(MenuData)\n\t\tcmpwi\tr3,0\t\t\t#Check If Toggled An Option\n\t\tbne\tShieldDropReset\n\n\t\t#Move Players Apart With DPad\n    addi  r3,EventData,0x10       #SaveState start\n\t\tbl\tAdjustResetDistance\n\t\tcmpwi\tr3,-1\n\t\tbne\tShieldDropReset\n\n\t\tShieldDropThinkSequence:\n\t\t#Increment Timer\n\t\tlwz\tr20,0x4(r31)\t\t#get timer\n\t\taddi\tr20,r20,0x1\n\t\tstw\tr20,0x4(r31)\t\t#store timer\n\n\t\t#Check if In Wait\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0xE\n\t\t\tbne ShieldDropNoIntangibility\n\t\t#Give Intangibility in Wait\n\t\t\tmr\tr3,r30\n\t\t\tli\tr4,0x2\n\t\t\tbl\tGiveInvincibility\n\t\tShieldDropNoIntangibility:\n\n\t\t#Check To Start Aerial\n\t\tcmpwi\tr20,40\n\t\tblt\tShieldDropThinkExit\n\n\t\t#Perform Aerial\n\t\t\tmr\tr3,r30\n\t\t\taddi\tr4,r31,AerialThinkStruct\n\t\t\tli\t\tr5,0\t\t#Random Attack\n\t\t\tbl\tPerformAerialThink\n\n\t\tShieldDropCheckToShield:\n\t\t#Check If CPU is done with Aerial Sequence\n\t\t\tlbz\tr3,AerialThinkStruct(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tShieldDropCheckToReset\n\t\t#Hold Shield\n\t\t\tli\tr3,0xC0\t\t#Hit L\n\t\t\tstw\tr3,0x1A88(r29)\t\t#Hold Shield\n\n\t\tShieldDropCheckToReset:\n\t\tcmpwi\tr20,140\n\t\tbne\tShieldDropThinkExit\n\t\tShieldDropReset:\n\t\t#Randomize Position\n\t\tli\tr3,0x1\t\t\t#Opposing Sides of Stage\n\t\tbl\tRandomize_LeftorRightSide\n\t\t#Adjust Facing Direction Based on Preference\n\t\tlbz\tr3,FacingDirection(MenuData)\n\t\tcmpwi\tr3,0x1\n\t\tbne\tShieldDropLoadState\n\t\t#Invert P1 Facing Direction\n\t\tlwz\tr3,0x10(r31)\n\t\tlfs\tf1,0x2C(r3)\n\t\tfneg\tf1,f1\n\t\tstfs\tf1,0x2C(r3)\n\t\tShieldDropLoadState:\n\t\t#Backup P1 Analog Timers\n\t\tlwz\tr23,0x620(r27)\n\t\tlwz\tr24,0x624(r27)\n\t\t#Restore\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tSaveState_Load\n\t\t#Restore P1 Analog Timers\n\t\tlwz\tr23,0x620(r27)\n\t\tlwz\tr24,0x624(r27)\n\t\t#Reset Timer\n\t\tli\tr3,50\n\t\tbranchl\tr12,HSD_Randi\n\t\tli\tr4,0\n\t\tsub\tr3,r4,r3\n\t\tstw\tr3,0x4(r31)\n\t\t#Reset Aerial Move Think Struct\n\t\tli\tr3,0\n\t\tstw\tr3,AerialThinkStruct(r31)\n\n\t\tShieldDropThinkExit:\n    mr  r3,MenuData\n    bl  ClearToggledOptions\n\t\tbl\tUpdateAllGFX\n\t\trestore\n\t\tblr\n\n#################################\n\nShieldDrop_Floats:\nblrl\n.long 0xC0F9999A\t\t#P1 X Position\n.long 0x40F9999A\t\t#P2 X Position\n.long 0x425999b4\t\t#Top Plat Y Position\n.long 0x425999b4\t\t#Top Plat Y Position\n.long 0x3E99999A  #Y Vel to Attack\n.long 0x40A00000  #Distance from Ground to L Cancel\n\n#################################\n\nShieldDropWindowInfo:\nblrl\n\n.long 0x0001FFFF  #1 Window, Facing Direction Has 2 Options\n\n################################\n\nShieldDropWindowText:\nblrl\n\n######################\n## Facing Direction ##\n######################\n\n#Window Title = Facing Direction\n.long 0x46616369\n.long 0x6e672044\n.long 0x69726563\n.long 0x74696f6e\n.long 0x\n\n#Option 1 = Towards\n.long 0x546f7761\n.long 0x72647300\n.long 0x\n.long 0x\n.long 0x\n\n#Option 2 = Away\n.long 0x41776179\n.long 0x\n.long 0x\n.long 0x\n.long 0x\n\n\n#################################\n\nShieldDropLoadExit:\nrestore\nblr\n\n################################################################################\n#endregion\n\n#region Attack on Shield\n#########################\n## Attack On Shield HIJACK INFO ##\n#########################\n\nAttackOnShield:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,FinalDestination\t\t#Use SSS Stage\n\tload r7,EventOSD_AttackOnShield\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\n\tbl\tAttackOnShieldLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Attack On Shield LOAD FUNCT ##\n\t########################\n\tAttackOnShieldLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tAttackOnShieldThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  bl\tAttackOnShieldWindowInfo\n  mflr\tr5\n  bl\tAttackOnShieldWindowText\n  mflr\tr6\n\tbl\tCreateEventThinkFunction\n\n\n\tb\tAttackOnShieldLoadExit\n\n\n\t\t#########################\n\t\t## Attack On Shield THINK FUNCT ##\n\t\t#########################\n\n    #Registers\n    .set MenuData,26\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n\t\t.set firstFrameFlag,0x0\n\t\t.set timer,0x4\n\t\t.set OoSOption,MenuData_OptionMenuMemory+0x2 + 0x0\n  \t.set OoSOptionToggled,MenuData_OptionMenuToggled + 0x0\n\n\t\tAttackOnShieldThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n    lwz MenuData,EventData_MenuDataPointer(EventData)\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n  \t\tbl\tCheckIfFirstFrame\n  \t\tcmpwi\tr3,0x0\n  \t\tbeq\tAttackOnShieldThinkMain\n\t\t\t#Set Frame 1 As Over\n  \t\t\tli\t\tr3,0x1\n  \t\t\tstb\t\tr3,0x0(r31)\n  \t\t\tbl\t\tAttackOnShield_Floats\n  \t\t\tmflr\tr3\n  \t\t\tbl\t\tInitializePositions\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n\t\t\t#Save State\n  \t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n  \t\t\tbl\t\tSaveState_Save\n\n\n\n\t\tAttackOnShieldThinkMain:\n\t\tbl\tGiveFullShields\n\n\t\t#Reset If Anyone Dies\n\t\tbl\tIsAnyoneDead\n\t\tcmpwi\tr3,0x0\n\t\tbne\tAttackOnShieldRestoreState\n\n\t\tAttackOnShieldThinkSequence:\n\n      lbz r3,OoSOptionToggled(MenuData)\n\t\t\tcmpwi\tr3,0\n\t\t\tbeq\tAttackOnShieldNoOptionToggled\n\t\t#Clear Last AS So CPU Doesnt Act Immediately\n\t\t\tli\tr3,0\n\t\t\tsth\tr3,TM_OneASAgo(r29)\n\t\tAttackOnShieldNoOptionToggled:\n\n\t\t#Get Floats\n\t\tbl\tAttackOnShield_Floats\n\t\tmflr\tr21\n\t\t#Get Frames as Int\n\t\tlfs\tf1,0x894(r29)\n\t\tfctiwz\tf1,f1\n\t\tstfd\tf1,0xF0(sp)\n\t\tlwz\tr22,0xF4(sp)\n\n\t\t#Check If Perfroming OoS Option\n\t\tlwz\tr3,0x4(r31)\n\t\tcmpwi\tr3,0x0\n\t\tble\tAttackOnShieldShieldWait\n\t\t#Branch To OoSThink\n\t\tlbz\tr3,OoSOption(MenuData)\n\t\tcmpwi\tr3,0x1\n\t\tbeq\tAttackOnShieldNairThink\n\t\tcmpwi\tr3,0x2\n\t\tbeq\tAttackOnShieldUpBThink\n\t\tcmpwi r3,0x3\n\t\tbeq AttackOnShieldUpSmashThink\n\t\tcmpwi\tr3,0x4\n\t\tbeq\tAttackOnShieldShineThink\n    cmpwi\tr3,0x7\n\t\tbeq\tAttackOnShieldWavedashThink\n\t\tb\tAttackOnShieldShieldWait\n\n\t\t\tAttackOnShieldNairThink:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x19\n\t\t\tbne\tAttackOnShieldCheckToReset\n\t\t\t#Input Nair\n\t\t\tli\tr3,0x100\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tAttackOnShieldCheckToReset\n\n\t\t\tAttackOnShieldUpBThink:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x18\n\t\t\tbne\tAttackOnShieldCheckToReset\n\t\t\tli\tr3,127\n\t\t\tstb\tr3,0x1A8D(r29)\t\t\t#Press Up\n\t\t\tli\tr3,0x200\n\t\t\tstw\tr3,0x1A88(r29)\t\t\t#Press B\n\t\t\tb\tAttackOnShieldCheckToReset\n\n\t\t\tAttackOnShieldUpSmashThink:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x18\n\t\t\tbne\tAttackOnShieldCheckToReset\n\t\t\tli\tr3,127\n\t\t\tstb\tr3,0x1A8D(r29)\t\t\t#Press Up\n\t\t\tli\tr3,0x100\n\t\t\tstw\tr3,0x1A88(r29)\t\t\t#Press A\n\t\t\tb\tAttackOnShieldCheckToReset\n\n\t\t\tAttackOnShieldShineThink:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x19\n\t\t\tbne\tAttackOnShieldCheckToReset\n\t\t\t#Input Shine\n\t\t\tli\tr3,-127\n\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\tli\tr3,0x200\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tAttackOnShieldCheckToReset\n\n      AttackOnShieldWavedashThink:\n      lwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x19\n\t\t\tbne\tAttackOnShieldCheckToReset\n      #Get Random Airdodge Angle\n  \t\t\tli\tr3,30\t\t#30 Different Angles\n  \t\t\tbranchl\tr12,HSD_Randi\n  \t\t\taddi\tr3,r3,310\t\t#Start at 310°\n  \t\t\tbl\tComboTrainingDecideStickAngle_ConvertAngle\n        mr  r20,r3\n  \t\t#Joystick X = X Component * (OpponentDirection)\n        bl  GetDirectionInRelationToP1\n  \t\t\tmullw\tr3,r3,r20\n  \t\t\tstb\tr3,0x1A8C(r29)\n  \t\t#Joystick Y = Y Component\n  \t\t\tstb\tr4,0x1A8D(r29)\n  \t\t#Press L To Wavedash\n  \t\t\tli\tr3,0xC0\n  \t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tAttackOnShieldCheckToReset\n\n\t\tAttackOnShieldShieldWait:\n\t\t#Always Hold L\n\t\tli\tr3,0xC0\t\t#Hit L\n\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\n\t\t#Check If Got Shield Poked\n\t\t#Hitlag\n\t\t\tlbz\tr3,0x221A(r29)\t\t\t#Check If in Hitlag\n\t\t\trlwinm.\tr3,r3,0,26,26\n\t\t\tbeq\tAttackOnShieldCheckForShieldHit\n\t\t#Damage State\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x4B\n\t\t\tblt\tAttackOnShieldCheckForShieldHit\n\t\t\tcmpwi\tr3,0x5B\n\t\t\tbgt\tAttackOnShieldCheckForShieldHit\n\t\t#Was Hit, Start Reset Timer\n\t\t\tli\tr3,48\t\t#Init Timer\n\t\t\tstw\tr3,0x4(r31)\n\t\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldCheckForShieldHit:\n\t\t#Check If In ShieldWait (0xb3)\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xB3\n\t\tbne\tAttackOnShieldCheckToReset\n\t\t#Check If Was Just in ShieldStun\n\t\tlhz\tr3,TM_OneASAgo(r29)\n\t\tcmpwi\tr3,0xB5\n\t\tbne\tAttackOnShieldCheckToReset\n\t\t#Input OoS Option\n\t\tlbz\tr3,OoSOption(MenuData)\n\t\tcmpwi \tr3,0x0\n\t\tbeq\tAttackOnShieldInputGrab\n\t\tcmpwi \tr3,0x1\n\t\tbeq\tAttackOnShieldNair\n\t\tcmpwi \tr3,0x2\n\t\tbeq\tAttackOnShieldUpB\n\t\tcmpwi\t\tr3,0x3\n\t\tbeq AttackOnShieldUpSmash\n\t\tcmpwi \tr3,0x4\n\t\tbeq\tAttackOnShieldShine\n\t\tcmpwi \tr3,0x5\n\t\tbeq\tAttackOnShieldSpotdodge\n\t\tcmpwi \tr3,0x6\n\t\tbeq\tAttackOnShieldRoll\n    cmpwi \tr3,0x7\n\t\tbeq\tAttackOnShieldWavedash\n\t\tcmpwi \tr3,0x8\n\t\tbeq\tAttackOnShieldNone\n\n\t\tAttackOnShieldInputGrab:\n\t\tli\tr3,0x1C0\n\t\tstw\tr3,0x1A88(r29)\t\t#Press R+A\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldNair:\n\t\tli\tr3,0xCC0\n\t\tstw\tr3,0x1A88(r29)\t\t#Press X/Y\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldUpB:\n\t\tli\tr3,127\n\t\tstb\tr3,0x1A8D(r29)\t\t#Press Up\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldUpSmash:\n\t\tli\tr3,127\n\t\tstb\tr3,0x1A8D(r29)\t\t#Press Up\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldShine:\n\t\tli\tr3,0xCC0\n\t\tstw\tr3,0x1A88(r29)\t\t#Press X/Y\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldSpotdodge:\n\t\tli\tr3,-127\n\t\tstb\tr3,0x1A8D(r29)\t\t#Press Down\n\t\tli\tr3,0xC0\n\t\tstw\tr3,0x1A88(r29)\t\t#Press R\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldRoll:\n\t\tli\tr3,0xC0\n\t\tstw\tr3,0x1A88(r29)\t\t#Press R\n\t\t#Push Towards Opponent's Direction\n\t\tbl\tGetDirectionInRelationToP1\n\t\tli\tr4,127\n\t\tmullw\tr3,r3,r4\n\t\tstb\tr3,0x1A8C(r29)\t\t#Press Away\n\t\tli\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n    AttackOnShieldWavedash:\n    li\tr3,0xCC0\n\t\tstw\tr3,0x1A88(r29)\t\t#Press X/Y\n    li\tr3,48\t\t#Init Timer\n\t\tstw\tr3,0x4(r31)\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldNone:\n\t\tb\tAttackOnShieldThinkExit\n\n\t\t#Check To Reset\n\t\tAttackOnShieldCheckToReset:\n\t\tlwz\tr3,0x4(r31)\t\t#get timer\t#Get Timer\n\t\tcmpwi\tr3,0x0\t\t#Check if >0\n\t\tble\tAttackOnShieldThinkExit\n\t\t#Dec Timer\n\t\tsubi\tr3,r3,0x1\n\t\tstw\tr3,0x4(r31)\t\t#store timer\n\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\tbne\tAttackOnShieldThinkExit\t#Exit If Not\n\n\t\t#Randomize P1's X Coord\n\t\t#Get Random X Coord\n\t\tlbz\tr23,0x10(r21)\t\t#Starting X Coord\n\t\tlbz\tr24,0x11(r21)\t\t#Furthest X Coord\n\t\tsub\tr3,r24,r23\t\t#Get Range\n\t\tbranchl\tr12,HSD_Randi\t\t#Get Random Number in Between\n\t\tadd\tr3,r3,r23\t\t#Add to Starting Coord\n\t\t#Cast to Float\n\t\tbl  IntToFloat\n\t\tlwz\tr3,0x10(r31)\t\t#P1 Backup\n\t\tstfs\tf1,0xB0(r3)\t\t#P1 Backup X Pos\n\t\tli\tr3,0x1\t\t\t#Opposing Sides of Stage\n\t\tbl\tRandomize_LeftorRightSide\n\n\t\tAttackOnShieldRestoreState:\n\t\t#Restore State\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tSaveState_Load\n\t\tb\tAttackOnShieldThinkExit\n\n\t\tAttackOnShieldThinkExit:\n    mr  r3,MenuData\n    bl  ClearToggledOptions\n\t\trestore\n\t\tblr\n\n\n#################################\n\nAttackOnShield_Floats:\nblrl\n.long 0xC1A00000\t\t#P1 X Position\n.long 0x41A00000\t\t#P2 X Position\n.long 0x38d1b717\t\t#FD Floor Y Coord\n.long 0x38d1b717\t\t#FD Floor Y Coord\n.long 0x14460000    #P1 X Rand Pos Range\n\n#################################\n\nAttackOnShieldWindowInfo:\nblrl\n#amount of options, amount of options in each window\n\n.long 0x0008FFFF  #1 window, OoS Option has 10 options\n\n####################################################\n\nAttackOnShieldWindowText:\nblrl\n\n################\n## OoS Option ##\n################\n\n#Window Title = OoS Option\n.long 0x4f6f5320\n.long 0x4f707469\n.long 0x6f6e0000\n\n#Option 1 = Grab\n.long 0x47726162\n.long 0x00000000\n\n#Option 2 = Nair\n.long 0x4e616972\n.long 0x00000000\n\n#Option 3 = Up B\n.long 0x55702042\n.long 0x00000000\n\n#Option 5 = Up Smash\n.long 0x55702d53\n.long 0x6d617368\n.long 0x\n\n#Option 6 = Shine\n.long 0x5368696e\n.long 0x65000000\n\n#Option 7 = Spotdodge\n.long 0x53706f74\n.long 0x646f6467\n.long 0x65000000\n\n#Option 8 = Roll Away\n.long 0x526f6c6c\n.long 0x20417761\n.long 0x79000000\n\n#Option 9 = Wavedash Away\n.long 0x57617665\n.long 0x64617368\n.long 0x20417761\n.long 0x79000000\n\n#Option 10 = None\n.long 0x4E6F6E65\n.long 0x00000000\n\nAttackOnShieldLoadExit:\nrestore\nblr\n\n\n################################################################################\n#endregion\n\n#region Ledgetech Training\n#########################\n## Ledgetech HIJACK INFO ##\n#########################\n\nLedgetech:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Falco.Ext\t\t\t\t\t#Use chosen CPU\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_LedgeTech\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#BUFF DEFENSE RATIO\nlis\tr3,0x3f00\nstw\tr3,0x14(r20)\n\n#STORE THINK FUNCTION\nLedgetechStoreThink:\nbl\tLedgetechLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Ledgetech LOAD FUNCT ##\n\t########################\n\tLedgetechLoad:\n\tblrl\n\n\tbackup\n\n\tbl\tInitializeHighScore\n\n\t#Schedule Think\n\tbl\tLedgetechThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  li  r5,0    #No Option Menu\n\tbl\tCreateEventThinkFunction\n\n\tb\tLedgetechLoadExit\n\n\n\t\t#########################\n\t\t## Ledgetech THINK FUNCT ##\n\t\t#########################\n\n\n\t\tLedgetechThink:\n\t\tblrl\n\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n    .set EventData,31\n\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tLedgetechThinkMain\n\n    #Clear Inputs\n      bl  RemoveFirstFrameInputs\n    #Random Side of Stage\n      li  r3,2\n      branchl r12,HSD_Randi\n      bl  Ledgetech_InitializePositions\n\t\t#Enter SquatWait\n\t\t  mr r3,P2GObj\n\t\t  branchl r12,AS_SquatWait\n\t\t#P1 Has 90%\n\t\t\tli\tr3,90\n\t\t\tload\tr4,0x80453080\t\t#P1 Static Block\n\t\t\tsth\tr3,0x60(r4)\t\t#Store Percent Int To Display Value\n\t\t\tlis\tr3,0x42B4\n\t\t\tstw\tr3,0x1830(r27)\n    #Always Hold Down (Crouch Cancel)\n      li\tr3,-127\n      stb\tr3,0x1A8D(P2Data)\n\t\t#Save State\n\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\tli\tr4,1\t\t\t#Override failsafe\n\t\t\tbl\t\tSaveState_Save\n\n\n\n\t\tLedgetechThinkMain:\n\t\tbl\tGiveFullShields\n\n\t\tLedgetechThinkSequence:\n\t\t#Get Floats\n\t\tbl\tLedgetech_Floats\n\t\tmflr\tr21\n\n\t\t#Reset if P1 Is In a Dead State\n\t\tlbz\tr3,0x221F(r27)\n\t\trlwinm.\tr3,r3,0,25,25\n\t\tbne\tLedgetechRestoreState\n\n\t\t#D-Pad Left Restores State\n\t\tlwz\tr3,0x668(r27)\n\t\trlwinm.\tr0, r3, 0, 31, 31\n\t\tbne\tLedgetechRestoreState\n\n\t\t#Always Hold Down (Crouch Cancel)\n\t\tli\tr3,-127\n\t\tstb\tr3,0x1A8D(r29)\n\n\t\t#Start Timer When Leaving Rebirth Plat\n\t\tlbz\tr3,0x8(r31)\t\t#Check If Left Plat Already\n\t\tcmpwi\tr3,0x0\n\t\tbne\tLedgetechSkipTimerStart\n\t\tlwz\tr3,0x10(r27)\n\t\tcmpwi\tr3,0xD\n\t\tbeq\tLedgetechIncreaseRespawnPlatTime\n\t\t#Set Flag\n\t\tli\tr3,0x1\n\t\tstb\tr3,0x8(r31)\n\t\t#Remove Invinc\n\t\tli\tr3,0x0\n\t\tstw\tr3,0x198C(r27)\n\t\tstw\tr3,0x1990(r27)\n\t\tstw\tr3,0x1994(r27)\n\t\tmr\tr3,r28\n\t\tbranchl\tr12,GFX_RemoveAll\n\t\t#Set Timer\n\t\tli\tr3,180\n\t\tstw\tr3,0x4(r31)\n\t\tb\tLedgetechSkipTimerStart\n\n\t\tLedgetechIncreaseRespawnPlatTime:\n\t\tli\tr3,0x2\n\t\tstw\tr3,0x2340(r27)\n\t\tLedgetechSkipTimerStart:\n\n\t\t#Freeze Falco On Frame X\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x40\n\t\tbne\tLedgetechSkipFalcoFreze\n\t\tli\tr3,0x6\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x894(r29)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbne\tLedgetechSkipFalcoFreze\n\t\tli\tr3,0\n\t\tbl\tIntToFloat\n\t\tmr\tr3,r30\n\t\tbranchl\tr12,FrameSpeedChange\n\t\tLedgetechSkipFalcoFreze:\n\n\n\t\t#If Player 1 Ledge Tech's, Set Timer to 2 Seconds\n\t\t#Check Gatekeeper Flag\n\t\t\tlbz\tr3,0xA(r31)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbeq\tLedgetech_UpdateLedgetechFlags\n\n\t\t#Check For Tech\n\t\t\tlwz\tr3,0x10(r27)\n\t\t\tcmpwi\tr3,0xCA\n\t\t\tbeq\tLedgetechWallTeched\n\t\t\tcmpwi\tr3,0xCB\n\t\t\tbeq\tLedgetechWallTeched\n\t\t\tb\tLedgetech_UpdateLedgetechFlags\n\t\tLedgetechWallTeched:\n\t\t\t#Extend Timer\n\t\t\t\tli\tr3,180\n\t\t\t\tstw\tr3,0x4(r31)\n\t\t\t#Set Tech Bool\n\t\t\t\tli\tr3,1\n\t\t\t\tstb\tr3,0x9(r31)\n\t\t\t#Set Gatekeeper Flag\n\t\t\t\tli\tr3,1\n\t\t\t\tstb\tr3,0xA(r31)\n\n\t\tLedgetech_UpdateLedgetechFlags:\n\t\t#Check If Still Ledgeteching\n\t\t\tlwz\tr3,0x10(r27)\n\t\t\tcmpwi\tr3,0xCA\n\t\t\tbeq\tLedgetechUpdateScore\n\t\t\tcmpwi\tr3,0xCB\n\t\t\tbeq\tLedgetechUpdateScore\n\t\t#Not Ledgeteching, Remove Gatekeeper Flag\n\t\t\tli\tr3,0\n\t\t\tstb\tr3,0xA(r31)\n\t\t\tb\tLedgetechUpdateScoreHUD\n\n\t\tLedgetechUpdateScore:\n\t\t#Check To Increment Score\n\t\t#Check Ledgetech Bool\n\t\t\tlbz\tr3,0x9(r31)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbne\tLedgetechUpdateScoreHUD\n\t\t#Reset LedgeTech Bool\n\t\t\tli\tr3,0\n\t\t\tstb\tr3,0x9(r31)\n\t\t#Increment Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\t#Check To Make New High Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tlhz\tr4,-0x4ea6(r13)\n\t\t\tcmpw\tr3,r4\n\t\t\tble\tLedgetechUpdateScoreHUD\n\t\t#Copy To High Score\n\t\t\tsth\tr3,-0x4ea6(r13)\n\n\t\tLedgetechUpdateScoreHUD:\n\t\t#Update HUD Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\n\n\t\t#Unfreeze Falco On Hit\n\t\tli\tr3,0x0\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x89C(r29)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbne\tLedgetechSkipFalcoUnfreeze\n\t\tlwz\tr3,0x988(r29)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tLedgetechSkipFalcoUnfreeze\n\t\tli\tr3,1\n\t\tbl\tIntToFloat\n\t\tmr\tr3,r30\n\t\tbranchl\tr12,FrameSpeedChange\n\t\tLedgetechSkipFalcoUnfreeze:\n\n\t\tLedgetechCheckIfCrouching:\n\t\t#Only Attempt to DSmash in Squat and SquatWait\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x27\n\t\tbeq\tLedgetechCheckDistance\n\t\tcmpwi\tr3,0x28\n\t\tbeq\tLedgetechCheckDistance\n\t\tb\tLedgetechCheckToReset\n\t\tLedgetechCheckDistance:\n\t\t#Distance Formula\t(Get Distance in f1)\n\t\taddi r3,r29,0xB0 #P2 Positon\n\t\taddi r4,r27,0xB0 #P1 Position\n\t\tbl\tGetDistance\n\t\tlfs\tf2,0x0(r21)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbgt\tLedgetechCheckToReset\n\t\t#Enter DSmash\n\t\tli\tr3,-127\n\t\tstb\tr3,0x1A8F(r29)\n\t\t#Initiate Reset Timer\n\t\tlwz\tr3,0x4(r31)\t\t#Get Timer\n\t\tcmpwi\tr3,0x0\t\t#If Already Set, Skip\n\t\tbne\tLedgetechCheckToReset\n\t\tli\tr3,60\n\t\tstw\tr3,0x4(r31)\n\n\n\n\t\t#Check To Reset\n\t\tLedgetechCheckToReset:\n\t\tlwz\tr3,0x4(r31)\t\t#get timer\t#Get Timer\n\t\tcmpwi\tr3,0x0\t\t#Check if >0\n\t\tble\tLedgetechThinkExit\n\t\t#Dec Timer\n\t\tsubi\tr3,r3,0x1\n\t\tstw\tr3,0x4(r31)\t\t#store timer\n\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\tbne\tLedgetechThinkExit\t#Exit If Not\n\n\t\tLedgetechRestoreState:\n\t  #Restore State\n    \taddi r3,EventData,EventData_SaveStateStruct\n    \tbl\tSaveState_Load\n    #Random Side of Stage\n      li  r3,2\n      branchl r12,HSD_Randi\n      bl  Ledgetech_InitializePositions\n\t\t#Enter SquatWait\n\t\t  mr r3,P2GObj\n\t\t  branchl r12,AS_SquatWait\n\n\t\t#Set Timer\n\t\tli\tr3,0\n\t\tstw\tr3,0x4(r31)\n\t\t#Reset Rebirth Plat Fall Flag\n\t\tstb\tr3,0x8(r31)\n\t\t#Reset Tech and Gatekeeper Flag\n\t\tstb\tr3,0x9(r31)\n\t\tstb\tr3,0xA(r31)\n\t\t#Reset Score\n\t\tli\tr3,0\n\t\tsth\tr3,-0x4ea8(r13)\n\t\tb\tLedgetechThinkExit\n\n\t\tLedgetechThinkExit:\n\t\trestore\n\t\tblr\n\n#################################\n\nLedgetech_Floats:\nblrl\n.float 35.0\t\t#Distance to Initiate DSmash\n\n#################################\n\nBlrFunctionPointer:\nblrl\nblr\n\n#################################\n\nLedgetech_InitializePositions:\nbackup\n\n.set LedgeSide,20\n\n#Backup Ledge Side\n\tmr\tLedgeSide,r3\n\n#Change Facing Directions\n  cmpwi LedgeSide,0x0\n  beq\tLedgetech_InitializePositions_GetLeftLedgeID\nLedgetech_InitializePositions_GetRightLedgeID:\n #Change Facing Direction\n\tli\tr3,-1\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(P1Data)\n  li\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(P2Data)\n\tb\tLedgetech_InitializePositions_DirectionChangeEnd\nLedgetech_InitializePositions_GetLeftLedgeID:\n#Change Facing Direction\n\tli\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(P1Data)\n  li\tr3,-1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(P2Data)\nLedgetech_InitializePositions_DirectionChangeEnd:\n\n#Get Ledge Coordinates\n\tmr\tr3,LedgeSide\n\taddi r4,sp,0x80\n\tbl\tGetLedgeCoordinates\n\nLedgetech_InitializePositions_StorePosition:\n#Place P2 a few Mm behind it\n  li  r3,10\n  bl  IntToFloat\n  lfs f2,0x2C(P2Data)\n  fmuls f1,f1,f2\n  lfs f2,0x80(sp)\n  fsubs f1,f2,f1\n  stfs f1,0xB0(P2Data)\n  lfs f1,0x84(sp)\n  stfs f1,0xB4(P2Data)\n#Find Ground Below Player\n  mr  r3,P2GObj\n  bl  FindGroundNearPlayer\n  cmpwi r3,0    #Check if ground was found\n  beq Ledgetech_InitializePositions_SkipGroundCorrection\n  stfs f1,0xB0(P2Data)\n  stfs f2,0xB4(P2Data)\n  stw r4,0x83C(P2Data)\n  Ledgetech_InitializePositions_SkipGroundCorrection:\n#Enter into Wait\n  mr  r3,P2GObj\n  branchl r12,AS_Wait\n#Update Position\n  mr  r3,P2GObj\n  bl  UpdatePosition\n#Update ECB Values for the ground ID\n  mr r3,P2GObj\n  branchl r12,EnvironmentCollision_WaitLanding\n#Set Grounded\n  mr r3,P2Data\n  branchl r12,Air_SetAsGrounded\n#Update Camera\n  mr r3,P2GObj\n  bl  UpdateCameraBox\n\n#Enter Rebirth\n  lwz\tr26,0x2C(P1Data)\n  mr\t\tr3,P1GObj\n  branchl\t\tr12,AS_Rebirth\n  stw\tr26,0x2C(P1Data)\n#Place P1 a few Mm in front of it\n  li  r3,60\n  bl  IntToFloat\n  lfs f2,0x2C(P1Data)\n  fmuls f1,f1,f2\n  lfs f2,0x80(sp)\n  fsubs f1,f2,f1\n  stfs f1,0xB0(P1Data)\n  lfs f1,0x84(sp)\n  stfs f1,0xB4(P1Data)\n#Enter RebirthWait\n  mr\t\tr3,P1GObj\n  branchl\t\tr12,AS_RebirthWait\n#Update Position\n  mr  r3,P1GObj\n  bl  UpdatePosition\n#Store Blr as Physics\n\tbl\t\tBlrFunctionPointer\n\tmflr\t\tr3\n\tstw\t\tr3,0x21A4(P1Data)\n#Store Custom RebirthWait Interrupt\n\tbl\tCustom_InterruptRebirthWait\n\tmflr\tr3\n\tstw\t\tr3,0x219C(P1Data)\n#Update RebirthPlat Position\n  mr  r3,P1GObj\n  branchl r12,RebirthPlatform_UpdatePosition\n#Update Camera\n  mr r3,P1GObj\n  bl  UpdateCameraBox\n\nrestore\nblr\n\n#################################\n\nLedgetechLoadExit:\nrestore\nblr\n\n\n\n###################################################\n#endregion\n\n#region Amsah Tech\n#########################\n## Amsah Tech HIJACK INFO ##\n#########################\n\nAmsahTech:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t#Send match struct\n\tli\tr5,9\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,-1\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_AmsahTech\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nbl\tAmsahTechLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Amsah Tech LOAD FUNCT ##\n\t########################\n\tAmsahTechLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tAmsahTechThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  li  r5,0    #No Option Menu\n\tbl\tCreateEventThinkFunction\n\n\tb\tAmsahTechLoadExit\n\n\n\t\t#########################\n\t\t## Amsah Tech THINK FUNCT ##\n\t\t#########################\n\n    .set EventData,31\n    .set P1Gobj,28\n    .set P1Data,27\n    .set P2GObj,30\n    .set P2Data,29\n\n    #Offsets\n    .set Timer,0x8\n\n\t\tAmsahTechThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tAmsahTechThinkMain\n\n      #Move Players\n        bl  PlacePlayersCenterStage\n\t\t\t#P1 Has 120%\n  \t\t\tli\tr3,120\n  \t\t\tload\tr4,0x80453080\t\t#P1 Static Block\n  \t\t\tsth\tr3,0x60(r4)\t\t#Store Percent Int To Display Value\n  \t\t\tbl\tIntToFloat\n  \t\t\tstfs\tf1,0x1830(P1Data)\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n\t\t\t#Save State\n  \t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n  \t\t\tbl\tSaveState_Save\n\n\n\n\t\tAmsahTechThinkMain:\n\n\t\t#Make P2 A Follower (No Nudge)\n\t\t#li\tr3,0x8\n\t\t#stb\tr3,0x221F(r29)\n\t\tli\tr3,0x1\n\t\tlbz\tr0, 0x221D (r29)\n\t\trlwimi\tr0,r3,2,29,29\n\t\tstb\tr0, 0x221D (r29)\n\n\t\t#Give Invincibility To P2\n\t\tmr\tr3,r30\n\t\tli\tr4,0x2\n\t\tbl\tGiveInvincibility\n\n\t\t#Update GFX\n\t\tmr\tr3,r30\n\t\tbl\tUpdateAllGFX\n\n\t\t#Reset If Anyone Dies\n\t\tbl\tIsAnyoneDead\n\t\tcmpwi\tr3,0x0\n\t\tbne\tAmsahTechRestoreState\n\n\t\tAmsahTechThinkSequence:\n\t\t#Get Floats\n\t\tbl\tAmsahTech_Floats\n\t\tmflr\tr21\n\n\t\t#Check If Timer Started Already\n\t\tlwz\tr3,0x4(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tAmsahTechCheckUpBTimer\n\n\t\t#Check For P1 Taunt\n\t\tlwz\tr3,0x10(r27)\n\t\tcmpwi\tr3,0x108\n\t\tbeq\tAmsahTechIsTaunting\n\t\tcmpwi\tr3,0x109\n\t\tbeq\tAmsahTechIsTaunting\n\n\t\t#Check For Doc Taunt\n\t\tlwz\tr3,0x4(r27)\n\t\tcmpwi\tr3,0x15\n\t\tbne\tAmsahTechCheckYLink\n\t\t#Check For AS 155\n\t\tlwz\tr3,0x10(r27)\n\t\tcmpwi\tr3,0x155\n\t\tbeq\tAmsahTechIsTaunting\n\n\t\t#Check For YLink Taunt\n\t\tAmsahTechCheckYLink:\n\t\tlwz\tr3,0x4(r27)\n\t\tcmpwi\tr3,0x14\n\t\tbne\tAmsahTechCheckUpBTimer\n\t\t#Check For AS 156\n\t\tlwz\tr3,0x10(r27)\n\t\tcmpwi\tr3,0x156\n\t\tbeq\tAmsahTechIsTaunting\n\t\tb\tAmsahTechCheckUpBTimer\n\n\t\tAmsahTechIsTaunting:\n  #Check for Frame 1 of Taunt\n    lhz r3,TM_FramesinCurrentAS(P1Data)\n    cmpwi r3,0x1\n    bne AmsahTechCheckUpBTimer\n  #Check If UpB Timer is Set\n\t\tlwz\tr3,0x8(r31)\n\t\tcmpwi\tr3,0x0\t\t#Timer Already Set\n\t\tbne\tAmsahTechCheckUpBTimer\n\t\t#Check If Marth is In Wait\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xE\n\t\tbne\tAmsahTechCheckUpBTimer\n\n  #Move Marth X Mm in front of P1, facing him\n  #Get Position\n    li  r3,10\n    bl  IntToFloat          #Offset from P1\n    lfs f3,0xB0(P1Data)     #P1 X\n    lfs f2,0xB4(P1Data)     #P1 Y\n    lfs f4,0x2C(P1Data)     #Facing Direction\n    fmuls f1,f1,f4\n    fadds f1,f1,f3\n  #Check If P2 Will Be Grounded\n    li  r3,0\n    bl  FindGroundNearPlayer\n    cmpwi r3,0    #Check if ground was found\n    beq AmsahTech_NoGroundFound\n    stfs f1,0xB0(P2Data)\n    stfs f2,0xB4(P2Data)\n    stw r4,0x83C(P2Data)\n    lfs f1,0x2C(P1Data)\n    fneg f1,f1\n    stfs f1,0x2C(P2Data)\n  #Enter Wait\n    mr  r3,P2GObj\n    branchl r12,AS_Wait\n  #Update Position\n    mr  r3,P2GObj\n    bl  UpdatePosition\n  #Update ECB Values for the ground ID\n    mr r3,P2GObj\n    branchl r12,EnvironmentCollision_WaitLanding\n  #Set Grounded\n    mr r3,P2Data\n    branchl r12,Air_SetAsGrounded\n  #Set UpB Timer\n    li\tr3,30\n    stw\tr3,Timer(EventData)\n  #Store To Backups as Well\n    lwz\tr3,0x18(EventData)\t\t#P2 Backup\n    lfs\tf1,0xB0(P2Data)\t     \t#Get P2 X\n    stfs\tf1,0xB0(r3)\t       \t#Store to P2 Backup\n    lfs\tf1,0xB4(P2Data)\t     \t#Get P2 Y\n    stfs\tf1,0xB4(r3)\t       \t#Store to P2 Backup\n    lfs\tf1,0x2C(P2Data)\t     \t#Get P2 Facing\n    stfs\tf1,0x2C(r3)\t       \t#Store to P2 Backup\n    lwz r4,0x83C(P2Data)      #Get P2 Ground ID\n    stw r4,0x83C(r3)          #Store to P2 Backup\n    lwz\tr3,0x10(EventData)\t\t#P1 Backup\n    lfs\tf1,0xB0(P1Data)\t    \t#Get P1 X\n    stfs\tf1,0xB0(r3)\t       \t#Store to P1 Backup\n    lfs\tf1,0xB4(P1Data)\t    \t#Get P1 X\n    stfs\tf1,0xB4(r3)\t       \t#Store to P1 Backup\n    lfs\tf1,0x2C(P1Data)\t     \t#Get P1 Facing\n    stfs\tf1,0x2C(r3)\t\t      #Store to P1 Backup\n    lwz r4,0x83C(P1Data)      #Get P1 Ground ID\n    stw r4,0x83C(r3)          #Store to P1 Backup\n  \tmr\tr3,P1GObj\n  \tbl\tCheckIfPlayerHasAFollower\n  \tcmpwi\tr3,0x0\n  \tbeq\tAmsahTechNoSubchar\n  \tlwz\tr3,0x14(EventData)\t\t#P1 Subchar Backup\n  \tlfs\tf1,0xB0(r4)\t\t#Get P1 Subchar X\n  \tstfs\tf1,0xB0(r3)\t\t#Store to P1 Subchar Backup\n  \tlfs\tf1,0x2C(r4)\t\t#Get P1 Subchar Facing\n  \tstfs\tf1,0x2C(r3)\t\t#Store to P1 Subchar Backup\n\tAmsahTechNoSubchar:\n    b AmsahTechCheckToReset\n\n  AmsahTech_NoGroundFound:\n  #Play Error SFX\n    li\tr3,0xAF\n    bl PlaySFX\n    b AmsahTechCheckToReset\n\n\t\tAmsahTechCheckUpBTimer:\n\t\t#Check For UpBTimer\n\t\tlwz\tr3,0x8(r31)\n\t\tcmpwi\tr3,0x0\t\t#No UpB Timer Set Yet\n\t\tble\tAmsahTechCheckToReset\n\t\t#Dec Timer\n\t\tsubi\tr3,r3,0x1\n\t\tstw\tr3,0x8(r31)\t\t#store timer\n\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\tbne\tAmsahTechCheckToReset\t#Exit If Not\n\t\t#Move Marth in Front of P1 Again (Fox's\n\t\tlfs\tf1,0xB0(r27)\t\t#Get P1 X\n\t\tlfs\tf2,0x2C(r27)\t\t#Get P1 Facing\n\t\tlfs\tf3,0x10(r21)\t\t#Get Marth Distance\n\t\tfmuls\tf2,f2,f3\t\t#Distance * Facing Direction\n\t\tfadds\tf1,f1,f2\t\t#P1.X + (Distance * Facing Direction)\n\t\tstfs\tf1,0xB0(r29)\t\t#Store Position to P2\n\t\t#Enter UpB\n\t\tli\tr3,0x200\n\t\tstw\tr3,0x1A88(r29)\n\t\tli\tr3,127\n\t\tstb\tr3,0x1A8D(r29)\n\t\t#Initiate Reset Timer\n\t\tli\tr3,120\n\t\tstw\tr3,0x4(r31)\n\n\t\t#Check To Reset\n\t\tAmsahTechCheckToReset:\n\t\tlwz\tr3,0x4(r31)\t\t#get timer\t#Get Timer\n\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\tble\tAmsahTechThinkExit\n\t\t#Dec Timer\n\t\tsubi\tr3,r3,0x1\n\t\tstw\tr3,0x4(r31)\t\t#store timer\n\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\tbne\tAmsahTechThinkExit\t#Exit If Not\n\n\t\tAmsahTechRestoreState:\n\t\t#Restore State\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tSaveState_Load\n\t\t#Restore Timers Just In Case\n\t\tli\tr3,0x0\n\t\tstw\tr3,0x4(r31)\n\t\tstw\tr3,0x8(r31)\n\n\t\tAmsahTechThinkExit:\n\t\trestore\n\t\tblr\n\n#################################\n\nAmsahTech_Floats:\nblrl\n.long 0x4308ca0c\t\t#P1 X Position\n.long 0x42942371\t\t#P2 X Position\n.long 0x00000000  #P1 Y Position\n.long 0x38d1b717\t\t#FD Floor Y Coord\n.long 0x41800000 \t#Distance to place Marth from P1\n.long 0x428C0000  #FD Stage Boundary X\n\n#################################\n\nAmsahTechLoadExit:\nrestore\nblr\n\n\n\n###########################################\n#endregion\n\n#region Combo Training\n################################\n## Combo Training HIJACK INFO ##\n################################\n\nComboTraining:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t#Send match struct\n\tli\tr5,-1\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,-1\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_ComboTraining\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nbl\tComboTrainingLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Combo Training LOAD FUNCT ##\n\t########################\n\tComboTrainingLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tComboTrainingThink\n\tmflr\tr3\n\tli\tr4,3\t\t\t\t\t\t\t\t\t\t\t\t#Priority (After Interrupt)\n  bl\tComboTrainingWindowInfo\t\t\t#r4 = pointer to option info\n  mflr\tr5\n  bl\tComboTrainingWindowText\t\t\t#r5 = pointer to ASCII struct\n  mflr\tr6\n\tbl\tCreateEventThinkFunction\n\n\tbl\tInitializeHighScore\n\n\tb\tComboTrainingLoadExit\n\n\n\t\t#########################\n\t\t## Combo Training THINK FUNCT ##\n\t\t#########################\n\n    #Registers\n    .set MenuData,26\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n    #Offsets\n\t\t.set EventState,0x8\n\t\t.set DIBehavior,(MenuData_OptionMenuMemory+0x2)+0x0\n\t\t.set SDIBehavior,(MenuData_OptionMenuMemory+0x2)+0x1\n\t\t.set TechOption,(MenuData_OptionMenuMemory+0x2)+0x2\n\t\t.set PostHitstunAction,(MenuData_OptionMenuMemory+0x2)+0x3\n\t\t.set GrabMashout,(MenuData_OptionMenuMemory+0x2)+0x4\n    .set DIBehaviorToggled,(MenuData_OptionMenuToggled)+0x0\n\t\t.set SDIBehaviorToggled,(MenuData_OptionMenuToggled)+0x1\n\t\t.set TechOptionToggled,(MenuData_OptionMenuToggled)+0x2\n\t\t.set PostHitstunActionToggled,(MenuData_OptionMenuToggled)+0x3\n\t\t.set GrabMashoutToggled,(MenuData_OptionMenuToggled)+0x4\n\n\t\t#Definitions\n\t\t#DIBehavior\n\t\t\t.set DI_Random,0x0\n\t\t\t.set DI_Survival,0x1\n\t\t\t.set DI_ComboDI,0x2\n\t\t\t.set DI_SlightDIRandom,0x3\n\t\t\t.set DI_SlightDIInwards,0x4\n\t\t\t.set DI_DownAndAway,0x5\n\t\t\t.set DI_None,0x6\n\t\t#SDIBehavior\n\t\t\t.set SDI_33Percent,0x0\n\t\t\t.set SDI_66Percent,0x1\n\t\t\t.set SDI_Always,0x2\n\t\t\t.set SDI_None,0x3\n\n\t\tComboTrainingThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tr31,0x2c(r3)\t\t\t#backup data pointer in r31\n\n    bl  GetAllPlayerPointers\n    mr P1GObj,r3\n    mr P1Data,r4\n    mr P2GObj,r5\n    mr P2Data,r6\n\n    lwz MenuData,EventData_MenuDataPointer(EventData)\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tComboTrainingThinkMain\n\n        bl  PlacePlayersCenterStage\n      #Clear Inputs\n        bl  RemoveFirstFrameInputs\n\t\t\t#Save State\n  \t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n  \t\t\tbl\tSaveState_Save\n\t\t\t#Init Score Count\n  \t\t\tlhz\tr3,-0x4ea8(r13)\n  \t\t\tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\n\n\t\tComboTrainingThinkMain:\n\n\t\t#Set Combo As Score\n\t\t\tli\tr3,0x0\n\t\t\tbranchl\tr12,0x8004134c\n\t\t\tsth\tr3,-0x4ea8(r13)\n\t\t#Check To Make New High Score\n\t\t\tlhz\tr3,-0x4ea8(r13)\n\t\t\tlhz\tr4,-0x4ea6(r13)\n\t\t\tcmpw\tr3,r4\n\t\t\tble\tComboTraining_SkipNewHighscore\n\t\t#Copy To High Score\n\t\t\tsth\tr3,-0x4ea6(r13)\n\t\tComboTraining_SkipNewHighscore:\n\n\t\t#Update HUD Score\n\t\tlhz\tr3,-0x4ea8(r13)\n\t\tcmpwi\tr3,0x1\n\t\tblt\tComboTraining_SkipHUDUpdate\n\t\tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\t\tComboTraining_SkipHUDUpdate:\n\n\t\t#DPad Right Makes New Savestate\n\t\t#Check If Trying to SaveState\n\t\tlwz\tr3,0x668(r27)\n\t\trlwinm.\tr0,r3,0,30,30\n\t\tbeq\tComboTraining_CheckForSaveAndLoad\n\t\t#Only Allow a Save If Event State is 0\n\t\tlbz\tr3,EventState(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tComboTraining_SkipCheckForSaveAndLoad\n\t\t#Only Allow a Save If P2 is in Wait\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xE\n\t\tbne\tComboTraining_SkipCheckForSaveAndLoad\n\t\tComboTraining_CheckForSaveAndLoad:\n\t\taddi\tr3,EventData,0x10\n\t\tbl\tCheckForSaveAndLoad\n\t\t#Check If Loaded Successfully\n\t\tcmpwi\tr3,0x1\n\t\tbne\tComboTraining_SkipCheckForSaveAndLoad\n\t\t#Restore Event State And Timer\n\t\tli\tr3,0x0\n\t\tstb\tr3,EventState(r31)\n\t\tstw\tr3,0x4(r31)\n\t\tComboTraining_SkipCheckForSaveAndLoad:\n\n\t\t#DPad Down Moves CPU In Front\n\t\t#Only If Event State = 0\n\t\tlbz\tr3,EventState(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tComboTrainingSkipMoveCPU\n    mr  r3,P1GObj\n    mr  r4,P2GObj\n    addi r5,EventData,0x10\n\t\tbl\tMoveCPU\n\t\tComboTrainingSkipMoveCPU:\n\n\t\t#L+DPad Controls CPU Percent\n\t\taddi r3,EventData,EventData_SaveStateStruct+(1*0x8)\n\t\tbl\tDPadCPUPercent\n\n\t\tbl\tGiveFullShields\n\n\t\t#Reset If Anyone Dies\n\t\tbl\tIsAnyoneDead\n\t\tcmpwi\tr3,0x0\n\t\tbne\tComboTrainingRestoreState\n\n\n\t############################\n\t## Check If Was Hit Again ##\n\t############################\n\n\t#Don't Run If Over 6 Frames in Escape Air\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xEC\n\t\tbne\tComboTrainingCheckIfP2isGrabbed\n\t\tli\tr3,6\n\t\tbl\tIntToFloat\n\t\tlfs\tf2,0x894(r29)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbge\tComboTrainingCheckState\n\t#Check If P2 is Grabbed (Any Grab State)\n\tComboTrainingCheckIfP2isGrabbed:\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xDF\n\t\tblt\tComboTrainingStartCheckIfHit\n\t\tcmpwi\tr3,0xE8\n\t\tbgt\tComboTrainingStartCheckIfHit\n\t\tb\tComboTrainingChangeToRandomDIandTech\n\t#Check If P2 is Hit\n\tComboTrainingStartCheckIfHit:\n\t\tlbz\tr3,0x221A(r29)\t\t\t#Check If in Hitlag\n\t\trlwinm.\tr3,r3,0,26,26\n\t\tbne\tComboTrainingCheckIfBeingHit\n\t\tb\tComboTrainingCheckState\n\t\tComboTrainingCheckIfBeingHit:\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,ASID_DamageHi1\n\t\tblt\tComboTrainingCheckState\n\t\tcmpwi\tr3,ASID_DamageFlyRoll\n\t\tbgt\tComboTrainingCheckState\n\t\tComboTrainingChangeToRandomDIandTech:\n\t#Change To DI and Tech\n\t\tli\tr3,0x1\n\t\tstb\tr3,EventState(r31)\n\t\tb\tComboTrainingInputDIAndTech\n\n#Get Which State\nComboTrainingCheckState:\n\tlbz\tr3,EventState(r31)\n\tcmpwi\tr3,0x0\n\tbeq\tComboTrainingStart\n\tcmpwi\tr3,0x1\n\tbeq\tComboTrainingInputDIAndTech\n\tcmpwi\tr3,0x2\n\tbeq\tComboTrainingPostHitstun\n\n\nComboTrainingStart:\n\tb\tComboTrainingCheckToReset\n\nComboTrainingInputDIAndTech:\n\tbl\tComboTrainingCheckExitStates\n\tcmpwi\tr3,0x0\n\tbeq\tComboTrainingInputDIAndTechNoJiggs\n\tb\tComboTrainingChangeStateToPostHitstun\n\n\nComboTrainingInputDIAndTechNoJiggs:\n\tlwz\tr3,0x10(r29)\n\tcmpwi\tr3,0xB8\t\t#Missed Tech, Needs to Input a Roll or Attack\n\tbeq\tComboTrainingMissedTechThink\n\tcmpwi\tr3,0xC0\t\t#Missed Tech, Needs to Input a Roll or Attack\n\tbeq\tComboTrainingMissedTechThink\n#Check If Still Grabbed\n\tcmpwi r3,ASID_ShoulderedWait\n\tblt ComboTraining_GrabCheckSkipShoulder\n\tcmpwi r3,ASID_ShoulderedTurn\n\tble ComboTrainingMashOutOfGrab\nComboTraining_GrabCheckSkipShoulder:\n\tcmpwi\tr3,ASID_CaptureKoopa\n\tblt\tComboTraining_GrabCheckSkipKoopaLw\n\tcmpwi\tr3,ASID_CaptureWaitKoopa\n\tble\tComboTrainingMashOutOfGrab\nComboTraining_GrabCheckSkipKoopaLw:\n\tcmpwi\tr3,ASID_CaptureKoopaAir\n\tblt\tComboTraining_GrabCheckSkipKoopaAir\n\tcmpwi\tr3,ASID_CaptureWaitKoopaAir\n\tble\tComboTrainingMashOutOfGrab\nComboTraining_GrabCheckSkipKoopaAir:\n\tcmpwi\tr3,ASID_CapturePulledHi\t\t#CapturePulledLow\n\tblt\tComboTraining_GrabCheckSkipGrabbed\n\tcmpwi\tr3,ASID_CaptureFoot \t\t#CapturePulledHi\n\tble\tComboTrainingMashOutOfGrab\nComboTraining_GrabCheckSkipGrabbed:\n\tb\tComboTrainingDecideInputs\n\n#When Grabbed\n#Check Mash Out Behavior\nComboTrainingMashOutOfGrab:\n\tlbz\tr3,GrabMashout(MenuData)\n\tcmpwi\tr3,0x0\n\tbeq\tComboTrainingInputDIAndTech_RandomMash\n\tcmpwi\tr3,0x1\n\tbeq\tComboTrainingInputDIAndTech_RandomMash_AnalogInput\n\tcmpwi\tr3,0x2\t\t\t\t\t\t\t\t#No Mash\n\tbeq\tComboTrainingCheckToReset\n\n\n\t#Random Mash Out\n\tComboTrainingInputDIAndTech_RandomMash:\n\t#Only start randomly mashing after a few frames (to simulate human reaction)\n\t\tlwz r3,0x10(r29)\n\t\tcmpwi\tr3,ASID_CapturePulledHi\t\t#CapturePulledLow\n\t\tblt\tComboTrainingInputDIAndTech_RandomMashStart\n\t\tcmpwi\tr3,ASID_CaptureFoot \t\t#CapturePulledHi\n\t\tbgt\tComboTrainingInputDIAndTech_RandomMashStart\n\t#In a normal grab state, should wait a few frames before starting to mash\n\n\tComboTrainingInputDIAndTech_RandomMashStart:\n\t\tli\tr3,10\t\t\t\t\t\t\t\t\t\t#1- Numbers\n\t\tbranchl\tr12,HSD_Randi\n\t\tcmpwi\tr3,7\t\t\t\t\t\t\t\t\t#7 and below are no input\n\t\tble\tComboTrainingCheckToReset\n\t\tcmpwi\tr3,8\t\t\t\t\t\t\t\t\t#8 = Button Only, 9 = Both Analog and Button\n\t\tbeq\tComboTrainingInputDIAndTech_RandomMash_ButtonPress\n\n\tComboTrainingInputDIAndTech_RandomMash_AnalogInput:\n\t\tli\tr3,127\n\t\tstb\tr3,0x1A8C(r29)\t\t\t#Push Analog Stick Forward\n\t\tli\tr3,-1\n\t\tstb\tr3,0x1A50(r29)\t\t\t#Spoof Analog Stick as First Frame Pushed\n\n\tComboTrainingInputDIAndTech_RandomMash_ButtonPress:\n\t\t#Input Button Press\n\t\tli\tr3,0x100\n\t\tstw\tr3,0x1A88(r29)\t\t\t#Press A\n\t\tli\tr3,0\n\t\tstw\tr3,0x65C(r29)\t\t\t#Spoof Prev Frame Buttons as Nothing Pushed\n\n\t\tb\tComboTrainingCheckToReset\n\n\n\t\tComboTrainingChangeStateToPostHitstun:\n\t\t#Change State\n\t\tli\tr3,0x2\n\t\tstb\tr3,EventState(r31)\n\t\tb\tComboTrainingPostHitstun\n\n\n\n\n\n\t\tComboTrainingDecideInputs:\n\n\n\t\t#CHECK TO DI ATTACK\n\t\tComboTrainingDIThrowsAndHits:\n\t\t#Check If in Hitlag\n\t\t\tlbz\tr3,0x221A(r29)\n\t\t\trlwinm.\tr3,r3,0,26,26\n\t\t\tbeq\tComboTrainingCheckIfBeingThrown\n\t\t#Check If In Last Frame of Hitlag\n\t\t\tlfs\tf1,-0x7418(rtoc)\t\t#1fp\n\t\t\tlfs\tf2,0x195C(r29)\t\t  #hitlag frames left\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tbne\tComboTrainingCheckToReset\n\t\t#Check If Attack Was Strong\n\t\t#DI Attack\n\t\t\tlbz\tr3,DIBehavior(MenuData)\t\t#Get DI Behavior\n\t\t\tcmpwi\tr3,DI_SlightDIInwards\t\t#Check If Slight In\n\t\t\tbne\t0x8\n\t\t\tli\tr3,0x0\t\t#Override To Never Slight DI In Attacks\n\t\t\tb\t0x8\n\t\t\tli\tr3,0x2\n\t\t\tbl\tComboTrainingDecideStickAngle\n\t\t#SDI Attack\n\t\t\tlbz\tr3,SDIBehavior(MenuData)\t\t#Get SDI Behavior\n\t\t\tcmpwi\tr3,SDI_None\t\t#No SDI\n\t\t\tbeq\tComboTrainingNoSDI\n\t\t\tcmpwi\tr3,SDI_Always\t\t#Always SDI\n\t\t\tbeq\tComboTrainingCheckToReset\n\n\t\t\tli\tr3,0x3\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tlbz\tr4,SDIBehavior(MenuData)\t\t#Get SDI Behavior\n\t\t\tcmpwi\tr4,SDI_33Percent\n\t\t\tbeq\tComboTraining33PercentSDI\n\t\t\tcmpwi\tr4,SDI_66Percent\n\t\t\tbeq\tComboTraining66PercentSDI\n\t\t\tComboTraining33PercentSDI:\n\t\t\tli\tr4,0\n\t\t\tb\tComboTrainingCompareSDIChance\n\t\t\tComboTraining66PercentSDI:\n\t\t\tli\tr4,1\n\t\t\tb\tComboTrainingCompareSDIChance\n\n\t\t\tComboTrainingCompareSDIChance:\n\t\t\tcmpw\tr3,r4\n\t\t\tble\tComboTrainingGetChanceToTech\n\t\t#Don't SDI\n\t\tComboTrainingNoSDI:\n\t\t\tmr\tr3,r29\n\t\t\tbranchl\tr12,CPU_JoystickXAxis_Convert\n\t\t\tstfs\tf1,0x620(r29)\n\t\t\tmr\tr3,r29\n\t\t\tbranchl\tr12,CPU_JoystickYAxis_Convert\n\t\t\tstfs\tf1,0x624(r29)\n\t\t\tb\tComboTrainingGetChanceToTech\n\n\n\n\n\n\t\t#CHECK TO DI A THROW\n\t\tComboTrainingCheckIfBeingThrown:\n\t\t#Check If Being Thrown\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0xEF\n\t\t\tblt\tComboTrainingCheckToJumpOutOfHitstun\n\t\t\tcmpwi\tr3,0xF3\n\t\t\tbgt\tComboTrainingCheckToJumpOutOfHitstun\n\t\tComboTrainingInputDI:\n\t\t\tlbz\tr3,DIBehavior(MenuData)\n\t\t\tbl\tComboTrainingDecideStickAngle\n\t\t\tb\tComboTrainingCheckToReset\n\n\n\n\n\n\n\t\t#NOT BEING THROWN OR LAST FRAME OF HITLAG\n\t\t#CHECK TO JUMP OUT OF HITSTUN AND BECOME INVINCIBLE\n\t\tComboTrainingCheckToJumpOutOfHitstun:\n\t\t#Check If in Damage State\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x26\t\t#Tumble\n\t\tbeq\tComboTrainingCheckIfInAir\n\t\tcmpwi\tr3,0x4B\n\t\tblt\tComboTrainingCheckToReset\n\t\tcmpwi\tr3,0x5B\n\t\tbgt\tComboTrainingCheckToReset\n\n\t\t#IN A DAMAGE STATE\n\t\t#Check If In Air\n\t\tComboTrainingCheckIfInAir:\n\t\tlwz\tr3,0xE0(r29)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tComboTrainingDamageGrounded\n\n\t\t#IN THE AIR\n\t\t#Check If Still in Hitstun\n\t\tlbz\tr3,0x221C(r29)\n\t\trlwinm.\tr3,r3,0,30,30\n\t\tbne\tComboTrainingGetChanceToTech\n\n\t\t#NOT IN HITSTUN\n\t\t#Check Post Hitstun Behavior\n\t\tlbz\tr3,PostHitstunAction(MenuData)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tComboTrainingAirdodge\n\t\tcmpwi\tr3,0x1\n\t\tbeq\tComboTrainingJumpAndInvincible\n\t\tcmpwi\tr3,0x2\n\t\tbeq\tComboTrainingAerialAttack\n\n\t\t\tComboTrainingJumpAndInvincible:\n\t\t\t#Always Jump\n\t\t\t#li\tr3,0\n\t\t\t#stw\tr3,0x1A8C(r29)\t\t#Nuetralize Stick Inputs\n\t\t\t#i\tr3,0x400\n\t\t\t#stw\tr3,0x1A88(r29)\t\t#X Button\n\t\t\tb\tComboTrainingChangeStateToPostHitstun\n\n\t\t\tComboTrainingAirdodge:\n\t\t\t#Wiggle Out of Hitstun\n\t\t\tli\tr3,127\n\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\t#Last Frame's Stick Was Centered\n\t\t\tli\tr3,0x0\n\t\t\tstw\tr3,0x628(r29)\n\t\t\tstw\tr3,0x62C(r29)\n\t\t\t#Stick Frame Timer Reset\n\t\t\tli\tr3,255\n\t\t\tstb\tr3,0x670(r29)\n\t\t\t#Change State\n\t\t\tli\tr3,0x2\n\t\t\tstb r3,0x8(r31)\n\t\t\tb\tComboTrainingPostHitstun\n\n\t\t\tComboTrainingAerialAttack:\n\t\t\t#li\tr3,0x100\n\t\t\t#stw\tr3,0x1A88(r29)\t\t#Nair\n\t\t\t#Change State\n\t\t\tli\tr3,0x2\n\t\t\tstb\tr3,EventState(r31)\n\t\t\tb\tComboTrainingPostHitstun\n\n\n\n\t\t#CHECK TO BECOME INVINCIBLE OUT OF GROUNDED LIGHT DAMAGE STATES\n\t\tComboTrainingDamageGrounded:\n\t\t#Check For Hitstun (Can Act Out of Certain Light Damage States)\n\t\tlbz\tr3,0x221C(r29)\n\t\trlwinm.\tr3,r3,0,30,30\n\t\tbne\tComboTrainingCheckToReset\n\t\t#Grounded, No Hitstun Left, Become Invincible and Spotdodge\n\t\t\t#Check Post Hitstun Behavior\n\t\t\tlbz\tr3,PostHitstunAction(MenuData)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingGroundedSpotdodge\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbeq\tComboTrainingGroundedInvincibility\n\t\t\tcmpwi\tr3,0x2\n\t\t\tbeq\tComboTrainingGroundedAttack\n\n\t\t\tComboTrainingGroundedInvincibility:\n\t\t\tb\tComboTrainingChangeStateToPostHitstun\n\n\t\t\tComboTrainingGroundedSpotdodge:\n\t\t\tli\tr3,0xC0\t\t#Hit L\n\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\tli\tr3,-127\t\t#Hold Down\n\t\t\tstb r3,0x1A8D(r29)\t\t#Stick Y\n\t\t\tb\tComboTrainingChangeStateToPostHitstun\n\n\t\t\tComboTrainingGroundedAttack:\n\t\t\t#li\tr3,0x100\t\t#Hit A\n\t\t\t#stw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\tb\tComboTrainingChangeStateToPostHitstun\n\n\n\n\n\tComboTrainingGetChanceToTech:\n\t#INPUT A TECH WHEN IN AERIAL HITSTUN\n\t\tlbz\tr3,TechOption(MenuData)\t\t#Get Tech Behavior\n\t\tcmpwi\tr3,0x0\t\t#Random Tech (Original Behavior)\n\t\tbeq\tComboTrainingRandomTech\n\t\tcmpwi\tr3,0x1\t\t#Miss Tech\n\t\tbeq\tComboTrainingMissTech\n\t\tcmpwi\tr3,0x2\n\t\tbeq\tComboTrainingTechInPlace\n\t\tcmpwi\tr3,0x3\n\t\tbeq\tComboTrainingTechTowards\n\t\tcmpwi\tr3,0x4\n\t\tbeq\tComboTrainingTechAway\n\n\tComboTrainingRandomTech:\n\t#Reset Tech Cooldown Window Constantly\n\t\tli\tr3,0x1\n\t\tstb\tr3,0x680(r29)\t\t#Frames Since Pressed L/R\n\t\tli\tr3,0xFF\n\t\tstb\tr3,0x684(r29)\t\t#L/R Lockout Window\n\t#Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise)\n\t\tlbz\tr3,0x221A(r29)\n\t\trlwinm.\tr3,r3,0,26,26\n\t\tbne\tComboTrainingCheckToReset\n\t#Tech Random Side\n\tComboTrainingRandomTech_GetStickAngle:\n\t\tli\tr3,4\t\t\t\t\t\t\t\t\t#Decide between left right and center and none\n\t\tbranchl\tr12,HSD_Randi\n\t\tcmpwi r3,0x0\n\t\tbeq ComboTrainingRandomTech_TechInPlace\n\t\tcmpwi r3,0x1\n\t\tbeq ComboTrainingRandomTech_TechLeft\n\t\tcmpwi r3,0x2\n\t\tbeq ComboTrainingRandomTech_TechRight\n\t\tcmpwi r3,0x3\n\t\tbeq ComboTrainingMissTech\n\n\tComboTrainingRandomTech_TechInPlace:\n\t\tli\tr3,0\n\t\tstb r3,0x1A8C(r29)\n\t\tstb r3,0x1A8D(r29)\n\t\tb\tComboTrainingCheckToReset\n\tComboTrainingRandomTech_TechLeft:\n\t\tli\tr3,-127\n\t\tstb r3,0x1A8C(r29)\n\t\tb\tComboTrainingCheckToReset\n\tComboTrainingRandomTech_TechRight:\n\t\tli\tr3,127\n\t\tstb r3,0x1A8C(r29)\n\t\tb\tComboTrainingCheckToReset\n\tComboTrainingMissTech:\n\t\tli\tr3,0x0\n\t\tstw\tr3,0x1A88(r29)\n\t#Fail Tech Cooldown\n\t\tli\tr3,0xFF\n\t\tstb\tr3,0x680(r29)\n\t\tli\tr3,0x00\n\t\tstb\tr3,0x684(r29)\n\t\tb\tComboTrainingCheckToReset\n\n\tComboTrainingTechInPlace:\n\t\t#Hold L\n\t\tli\tr3,0xC0\n\t\tstw\tr3,0x1A88(r29)\n\t#Reset Tech Cooldown Window Constantly\n\t\tli\tr3,0x0\n\t\tstb\tr3,0x680(r29)\n\t\tli\tr3,0xFF\n\t\tstb\tr3,0x684(r29)\n\t#Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise)\n\t\tlbz\tr3,0x221A(r29)\n\t\trlwinm.\tr3,r3,0,26,26\n\t\tbne\tComboTrainingCheckToReset\n\t\tli\tr3,0x0\n\t\tstb\tr3,0x1A8C(r29)\n\t\tb\tComboTrainingCheckToReset\n\n\t\tComboTrainingTechTowards:\n\t\t#Hold L\n\t\tli\tr3,0xC0\n\t\tstw\tr3,0x1A88(r29)\n\t\t#Reset Tech Cooldown Window Constantly\n\t\tli\tr3,0x0\n\t\tstb\tr3,0x680(r29)\n\t\tli\tr3,0xFF\n\t\tstb\tr3,0x684(r29)\n\t\t#Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise)\n\t\tlbz\tr3,0x221A(r29)\n\t\trlwinm.\tr3,r3,0,26,26\n\t\tbne\tComboTrainingCheckToReset\n\t\t#Push Towards Opponent's Direction\n\t\tbl\tGetDirectionInRelationToP1\n\t\tmulli\tr3,r3,-1\t\t#Negate This\n\t\tli\tr4,127\n\t\tmullw\tr3,r3,r4\n\t\tstb\tr3,0x1A8C(r29)\n\t\tb\tComboTrainingCheckToReset\n\n\t\tComboTrainingTechAway:\n\t\t#Hold L\n\t\tli\tr3,0xC0\n\t\tstw\tr3,0x1A88(r29)\n\t\t#Reset Tech Cooldown Window Constantly\n\t\tli\tr3,0x0\n\t\tstb\tr3,0x680(r29)\n\t\tli\tr3,0xFF\n\t\tstb\tr3,0x684(r29)\n\t\t#Check If In Hitlag Before Inputting Random Side (Messes Up DI Otherwise)\n\t\tlbz\tr3,0x221A(r29)\n\t\trlwinm.\tr3,r3,0,26,26\n\t\tbne\tComboTrainingCheckToReset\n\t\tbl\tGetDirectionInRelationToP1\n\t\tli\tr4,127\n\t\tmullw\tr3,r3,r4\n\t\tstb\tr3,0x1A8C(r29)\n\t\tb\tComboTrainingCheckToReset\n\n\t\t#INPUT AN ATTACK OR DIRECTION WHEN MISSED A TECH\n\t\tComboTrainingMissedTechThink:\n\t\t\tli\tr3,4\t\t#1/4 chance to getup attack\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingMissedTech_GetupAttack\n\t\t#No Getup Attack, Input Random Direction\n\t\t\tli r3,0\n\t\t\tbl\tComboTrainingDecideStickAngle\n\t\t\tb\t\tComboTrainingCheckToReset\n\t\t#Input Getup Attack\n\t\tComboTrainingMissedTech_GetupAttack:\n\t\t\tli\tr3,0x100\t\t#Press A To Getup Attack\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tComboTrainingCheckToReset\n\n\n\n\t\t########################\n\t\t## Post Hitstun Think ##\n\t\t########################\n\n\n\t\tComboTrainingPostHitstun:\n\n\t\t#Check Post Hitstun Behavior\n\t\tlbz\tr3,PostHitstunAction(MenuData)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\t\tComboTrainingPostHitstun_AirdodgeSpotdodge\n\t\tcmpwi\tr3,0x1\n\t\tbeq\t\tComboTrainingPostHitstun_GiveInvinc\n\t\tcmpwi\tr3,0x2\n\t\tbeq\t\tComboTrainingPostHitstun_Attack\n\n\t\t\tComboTrainingPostHitstun_GiveInvinc:\n\t\t\t#Constantly Press Jump If In The Air\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingPostHitstun_GiveInvinc_ApplyInvinc\n\t\t\tli\tr3,0x800\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\t#Clear Prev Frame Jump Input\n\t\t\tli\tr3,0x0\n\t\t\tstw\tr3,0x668(r29)\n\t\t\t#Apply Invinc\n\t\t\tComboTrainingPostHitstun_GiveInvinc_ApplyInvinc:\n\t\t\tmr\tr3,r30\n\t\t\tli\tr4,30\n\t\t\tbranchl\tr12,ApplyIntangibility\n\t\t\t#UpdateGFX\n\t\t\tmr\tr3,r30\n\t\t\tbranchl\tr12,GFX_UpdatePlayerGFX\n\t\t\t#Set Timer if Not Set\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbgt\tComboTrainingCheckToReset\n\t\t\t#Set Timer\n\t\t\tli\tr3,30\n\t\t\tstw\tr3,0x4(r31)\n\t\t\tb\tComboTrainingCheckToReset\n\n\t\t#****************************************************************#\n\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge:\n\t\t\t#Check If In Airdodge\n\t\t\t#Check If In Gained Invuln From Air/Spotdodge\n\t\t\tlwz\tr3,0x1988(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge\n\t\t\tb\tComboTrainingPostHitstun_EnteredAirdodgeSpotdodge\n\t\t\tComboTrainingPostHitstun_EnteredAirdodgeSpotdodge:\n\t\t\t#Set Timer if Not Set\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbgt\tComboTrainingCheckToReset\n\t\t\t#Set Timer\n\t\t\tli\tr3,30\n\t\t\tstw\tr3,0x4(r31)\n\t\t\t#Give Invince and Exit\n\t\t\tb\tComboTrainingCheckToReset\n\n\t\t#****************************************************************#\n\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge:\n\t\t\t#If in An Exit State, Reset State\n\t\t\tbl\tComboTrainingCheckExitStates\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState\n\t\t\t#Except Fall\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x1D\n\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState\n\t\t\t#Except Landing\n\t\t\tcmpwi\tr3,0x2A\n\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState\n\t\t\t#Except Wait\n\t\t\tcmpwi\tr3,0xE\n\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState\n\t\t\t#Set Timer if Not Set\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbgt\tComboTrainingCheckToReset\n\t\t\t#Set Timer\n\t\t\tli\tr3,30\n\t\t\tstw\tr3,0x4(r31)\n\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState:\n\t\t\t#Check If in Air\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_CheckToSpotdodge\n\t\t\t#Check If In DamageLightHit With No Hitstun Left (Same interrupts as Fall)\n\t\t\t\tlwz\tr3,0x10(r29)\n\t\t\t\tcmpwi\tr3,0x56\n\t\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_InputAirdodge\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckToWiggleOut:\n\t\t\t#Check If In Damage States\n\t\t\t\tlwz\tr3,0x10(r29)\n\t\t\t\tcmpwi\tr3,0x4B\n\t\t\t\tblt\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckForFall\n\t\t\t\tcmpwi\tr3,0x5B\n\t\t\t\tbgt\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckForFall\n\t\t\t#Wiggle Out to Enter Fall\n\t\t\t\tli\tr3,127\n\t\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\t\tb\tComboTrainingCheckToReset\n\t\t\t#Check If In Fall\n\t\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_CheckForFall:\n\t\t\t\tlwz\tr3,0x10(r29)\n\t\t\t\tcmpwi\tr3,0x1D\n\t\t\t\tbne\tComboTrainingCheckToReset\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckAirState_InputAirdodge:\n\t\t\t#Airdodge\n\t\t\t\tli\tr3,0\n\t\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\t\tli\tr3,0xC0\n\t\t\t\tstw\tr3,0x1A88(r29)\n\t\t\t#Clear Buttons From Last Frame\n\t\t\t\tli\tr3,0x0\n\t\t\t\tstw\tr3,0x65C(r29)\n\t\t\t\tb\tComboTrainingCheckToReset\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_CheckToSpotdodge:\n\t\t\t#Check If Grounded and Actionable\n\t\t\t\tlwz\tr3,0x10(r29)\n\t\t\t\tcmpwi\tr3,0xE\t\t#Wait\n\t\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_Spotdodge\n\t\t\t\tcmpwi\tr3,0xB6\t\t#Shielding\n\t\t\t\tbeq\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_Spotdodge\n\t\t\t\tcmpwi\tr3,0x2A\t\t#Land\n\t\t\t\tbne\tComboTrainingCheckToReset\n\t\t\t\t#Check If Can Interrupt Land\n\t\t\t\t\tlfs\tf1,0x894(r29)\n\t\t\t\t\tlfs\tf2,0x1F4(r29)\n\t\t\t\t\tfcmpo\tcr0,f1,f2\n\t\t\t\t\tblt\tComboTrainingCheckToReset\n\t\t\tComboTrainingPostHitstun_AirdodgeSpotdodge_CheckToAirdodge_Spotdodge:\n\t\t\t#Clear Buttons From Last Frame\n\t\t\tli\tr3,0x0\n\t\t\tstw\tr3,0x65C(r29)\n\t\t\t#Input Spotdodge\n\t\t\tli\tr3,0xC0\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tli\tr3,-127\n\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\tb\tComboTrainingCheckToReset\n\n\t\t#****************************************************************#\n\n\t\t\tComboTrainingPostHitstun_Attack:\n\n\t\t\t#Clear Buttons From Last Frame\n\t\t\tli\tr3,0x0\n\t\t\tstw\tr3,0x65C(r29)\n\n\t\t\t#Get Air or Ground\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingPostHitstun_AttackGround\n\n\t\t\tComboTrainingPostHitstun_AttackAir:\n\t\t\tbl\tComboTrainingAttackList\n\t\t\tmflr\tr5\n\t\t\tlwz\tr4,0x4(r29)\n\t\t\tlbzx\tr3,r4,r5\n\t\t\trlwinm\tr3,r3,0,28,31\t\t#Get Right Bits\n\t\t\tb\tComboTrainingPostHitstun_Attack_BranchToAttack\n\n\t\t\tComboTrainingPostHitstun_AttackGround:\n\t\t\tbl\tComboTrainingAttackList\n\t\t\tmflr\tr5\n\t\t\tlwz\tr4,0x4(r29)\n\t\t\tlbzx\tr3,r4,r5\n\t\t\trlwinm\tr3,r3,28,28,31\t\t#Get Left Bits\n\t\t\tb\tComboTrainingPostHitstun_Attack_BranchToAttack\n\n\n\t\t\tComboTrainingPostHitstun_Attack_BranchToAttack:\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_A\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_ForwardA\n\t\t\tcmpwi\tr3,0x2\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_BackA\n\t\t\tcmpwi\tr3,0x3\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_DownA\n\t\t\tcmpwi\tr3,0x4\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_UpA\n\t\t\tcmpwi\tr3,0x5\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_DownSmash\n\t\t\tcmpwi\tr3,0x6\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_UpB\n\t\t\tcmpwi\tr3,0x7\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_DownB\n\n\t\t\t\tComboTrainingPostHitstun_Attack_A:\n\t\t\t\tli\tr3,0x100\t\t#Hit A\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_ForwardA:\n\t\t\t\t#Push Towards Opponent's Direction\n\t\t\t\tbl\tGetDirectionInRelationToP1\n\t\t\t\tmulli\tr3,r3,-1\t\t#Negate This\n\t\t\t\tli\tr4,60\n\t\t\t\tmullw\tr3,r3,r4\n\t\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\t\tli\tr3,0x100\t\t#Hit A\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_BackA:\n\t\t\t\t#Push Away Opponent's Direction\n\t\t\t\tbl\tGetDirectionInRelationToP1\n\t\t\t\tli\tr4,60\n\t\t\t\tmullw\tr3,r3,r4\n\t\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\t\tli\tr3,0x100\t\t#Hit A\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_DownA:\n\t\t\t\tli\tr3,60\n\t\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\t\tli\tr3,0x100\t\t#Hit A\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_UpA:\n\t\t\t\tli\tr3,60\n\t\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\t\tli\tr3,0x100\t\t#Hit A\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_DownSmash:\n\t\t\t\tli\tr3,-127\n\t\t\t\tstb\tr3,0x1A8F(r29)\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_UpB:\n\t\t\t\tli\tr3,127\n\t\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\t\tli\tr3,0x200\t\t#Hit B\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\t\t\t\tComboTrainingPostHitstun_Attack_DownB:\n\t\t\t\tli\tr3,-127\n\t\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\t\tli\tr3,0x200\t\t#Hit B\n\t\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\t\tb\tComboTrainingPostHitstun_Attack_CheckForHitbox\n\n\n\n\t\t\t#Search For Active Hitbox\n\t\t\tComboTrainingPostHitstun_Attack_CheckForHitbox:\n\t\t\tmr\tr3,r30\n\t\t\tbl\tCheckForActiveHitboxes\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tComboTrainingPostHitstun_GiveInvinc_ApplyInvinc\n\t\t\t#Harcoded Fox Grounded Shine Check =(\n\t\t\tlwz\tr3,0x4(r29)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_CheckForGroundShine\n\t\t\tcmpwi\tr3,0x16\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_CheckForGroundShine\n\t\t\t#Hardcoded Puff Rest Check =(\n\t\t\tcmpwi\tr3,0xF\n\t\t\tbeq\tComboTrainingPostHitstun_Attack_CheckForRest\n\t\t\tb\tComboTrainingCheckToReset\n\t\t\tComboTrainingPostHitstun_Attack_CheckForGroundShine:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x168\n\t\t\tbeq\tComboTrainingPostHitstun_GiveInvinc_ApplyInvinc\n\t\t\tb\tComboTrainingCheckToReset\n\t\t\tComboTrainingPostHitstun_Attack_CheckForRest:\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0x171\n\t\t\tbeq\tComboTrainingPostHitstun_GiveInvinc_ApplyInvinc\n\t\t\tb\tComboTrainingCheckToReset\n\n\n\t\t#****************************************************************#\n\n\t\t#Check To Reset\n\t\tComboTrainingCheckToReset:\n\t\tlwz\tr3,0x4(r31)\t\t#get timer\n\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\tble\tComboTrainingThinkExit\n\t\t#Dec Timer\n\t\tsubi\tr3,r3,0x1\n\t\tstw\tr3,0x4(r31)\t\t#store timer\n\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\tbne\tComboTrainingThinkExit\t#Exit If Not\n\n\t\tComboTrainingRestoreState:\n\t\t#Restore State\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tSaveState_Load\n\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\tbl\tSaveState_Load\n\t\t#Reset State ID\n\t\tli\tr3,0x0\n\t\tstb\tr3,EventState(r31)\n\t\tComboTrainingThinkExit:\n    mr  r3,MenuData\n    bl  ClearToggledOptions\n\t\tbl\tUpdateAllGFX\n\t\trestore\n\t\tblr\n\n#################################\n\nComboTraining_StartingGroundIDs:\nblrl\n#Ground IDs to start on\n.long 0xFFFFFFFF #Dummy, TEST\n.long 0x00050022 #FoD, Pokemon Stadium\n.long 0x00050037 #Peach's Castle, Kongo Jungle\n.long 0x000B0012 #Brinstar, Corneria\n.long 0x00030019 #Yoshi's Story, Onett\n.long 0x00000048 #Mute City, Rainbow Cruise\n.long 0x00000024 #Jungle Japes, Great Bay\n.long 0x00190007 #Hyrule Temple, Brinstar Depths\n.long 0x000E0026 #Yoshi's Island, Green Greens\n.long 0x00040003 #Fourside, MKI\n.long 0x00040000 #MKII, Akaneia\n.long 0x00010105 #Venom, PokeFloats\n.long 0x00D9015B #Big Blue, Icicle Mountain\n.long 0x00000064 #Icetop, Flatzone\n.long 0x00040009 #Dream Land, Yoshis Island 64\n.long 0x000b0001 #Kongo Jungle 64, Battlefield\n.long 0x00010000 #Final Destination\n#################################\n\nComboTrainingDecideStickAngle:\n#Decide Stick Angle\nbackup\n\n#Clear Stick Inputs Just in Case\nli\tr4,0x0\nstb\tr4,0x1A8C(r29)\nstb\tr4,0x1A8D(r29)\n\n#Check Which Type Of DI To Perform\ncmpwi\tr3,DI_Random\nbeq\tComboTrainingDecideStickAngle_RandomDI\ncmpwi\tr3,DI_Survival\nbeq\tComboTrainingDecideStickAngle_SurvivalDI\ncmpwi\tr3,DI_ComboDI\nbeq\tComboTrainingDecideStickAngle_ComboDI\ncmpwi\tr3,DI_SlightDIRandom\nbeq\tComboTrainingDecideStickAngle_RandomDI_SlightDI\ncmpwi\tr3,DI_SlightDIInwards\nbeq\tComboTrainingDecideStickAngle_SlightDIInwards\ncmpwi\tr3,DI_DownAndAway\nbeq\tComboTrainingDecideStickAngle_DownAwayDI\ncmpwi\tr3,DI_None\nbeq\tComboTrainingDecideStickAngle_NoDI\n\n###############\n## Random DI ##\n###############\n\n#Roll RNG\nComboTrainingDecideStickAngle_RandomDI:\n\tli\tr3,6\n\tbranchl\tr12,HSD_Randi\n\tcmpwi\tr3,0x0\n\tbeq\tComboTrainingDecideStickAngle_RandomDI_TrulyRandom\n\tcmpwi\tr3,0x1\n\tbeq\tComboTrainingDecideStickAngle_ComboDI\n\tcmpwi\tr3,0x2\n\tbeq\tComboTrainingDecideStickAngle_SurvivalDI\n\tcmpwi r3,0x3\n\tbeq ComboTrainingDecideStickAngle_RandomDI_SlightDI\n\tcmpwi r3,0x4\n\tbeq\tComboTrainingDecideStickAngle_DownAwayDI\n\tcmpwi\tr3,0x5\n\tbeq\tComboTrainingDecideStickAngle_NoDI\n\nComboTrainingDecideStickAngle_RandomDI_TrulyRandom:\n.set Combo_RandomAnalogMin, 36\n.set Combo_RandomAnalogMax, 127\n\n#Get X magnitude\n\tli\tr3,Combo_RandomAnalogMax - Combo_RandomAnalogMin\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,Combo_RandomAnalogMin\n\tstb r3,0x1A8C(r29)\n#Chance to negate\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0x0\n\tbeq 0x10\n\tlbz r3,0x1A8C(r29)\n\tneg r3,r3\n\tstb r3,0x1A8C(r29)\n#Get Y magnitude\n\tli\tr3,Combo_RandomAnalogMax - Combo_RandomAnalogMin\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,Combo_RandomAnalogMin\n\tstb r3,0x1A8D(r29)\n#Chance to negate\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0x0\n\tbeq 0x10\n\tlbz r3,0x1A8D(r29)\n\tneg r3,r3\n\tstb r3,0x1A8D(r29)\n\tb\tComboTrainingDecideStickAngleExit\n\nComboTrainingDecideStickAngle_RandomDI_SlightDI:\n.set Combo_SlightAnalogMin, 36\n.set Combo_SlightAnalogMax, 66\n\n#Get X magnitude\n\tli\tr3,Combo_SlightAnalogMax - Combo_SlightAnalogMin\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,Combo_RandomAnalogMin\n\tstb r3,0x1A8C(r29)\n#Chance to negate\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0x0\n\tbeq 0x10\n\tlbz r3,0x1A8C(r29)\n\tneg r3,r3\n\tstb r3,0x1A8C(r29)\n#Get Y magnitude\n\tli\tr3,Combo_SlightAnalogMax - Combo_SlightAnalogMin\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,Combo_SlightAnalogMin\n\tstb r3,0x1A8D(r29)\n#Chance to negate\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0x0\n\tbeq 0x10\n\tlbz r3,0x1A8D(r29)\n\tneg r3,r3\n\tstb r3,0x1A8D(r29)\n\tb\tComboTrainingDecideStickAngleExit\n\n#######################\n## Slight DI Towards ##\n#######################\n\nComboTrainingDecideStickAngle_SlightDIInwards:\n\n#Get Random Stick X Input 86-105, 86-95 go in front, 96-105 go behind shiek\nli\tr3,19\nbranchl\tr12,HSD_Randi\naddi\tr3,r3,86\t\t#Start at 86\nlfs\tf1,0x2C(r27)\nfneg\tf1,f1\nfctiwz\tf1,f1\nstfd\tf1,0xF0(sp)\nlwz\tr4,0xF4(sp)\t\t#Facing direction as int\nmullw\tr3,r3,r4\nstb\tr3,0x1A8C(r29)\nb\tComboTrainingDecideStickAngleExit\n\n#################\n## Survival DI ##\n#################\n\nComboTrainingDecideStickAngle_SurvivalDI:\n#Check If In Throw\nbl\tComboTrainingCheckForThrowAngle\ncmpwi\tr3,-1\nbne\tComboTrainingDecideStickAngle_SurvivalDI_UsingThrowAngle\n#Get Knockback Angle\nlwz\tr3,0x1848(r29)\nComboTrainingDecideStickAngle_SurvivalDI_UsingThrowAngle:\n\n#Get Perpendicular Angle\n#Get Damage Direction\ncmpwi\tr3,0x169\t\t#Check For Sakurai Angle\nbne\t0xC\nli\tr3,0x2D\nli\tr4,0x2D\ncmpwi\tr3,90\nbge\tComboTrainingDecideStickAngle_SurvivalDI_Above90\nb\tComboTrainingDecideStickAngle_SurvivalDI_RightSide\nComboTrainingDecideStickAngle_SurvivalDI_Above90:\ncmpwi\tr3,269\nblt\tComboTrainingDecideStickAngle_SurvivalDI_LeftSide\nComboTrainingDecideStickAngle_SurvivalDI_RightSide:\naddi\tr3,r3,90\ncmpwi\tr3,360\nblt\t0x8\nsubi\tr3,r3,360\nb\tComboTrainingDecideStickAngle_SurvivalDI_GetXY\nComboTrainingDecideStickAngle_SurvivalDI_LeftSide:\nsubi\tr3,r3,90\ncmpwi\tr3,0\nbgt\t0x8\naddi\tr3,r3,360\nb\tComboTrainingDecideStickAngle_SurvivalDI_GetXY\n\nComboTrainingDecideStickAngle_SurvivalDI_GetXY:\nbl\tComboTrainingDecideStickAngle_ConvertAngle\nstb\tr3,0x1A8C(r29)\nstb\tr4,0x1A8D(r29)\nbl\tGetDirectionInRelationToP1\n#mulli\tr3,r3,-1\t\t#Negate This Value\nlbz\tr4,0x1A8C(r29)\nmullw\tr3,r3,r4\nstb\tr3,0x1A8C(r29)\t\t#Point Towards Opponent\nb\tComboTrainingDecideStickAngleExit\n\n##############\n## Combo DI ##\n##############\n\nComboTrainingDecideStickAngle_ComboDI:\n\n#Check If In Throw\nbl\tComboTrainingCheckForThrowAngle\ncmpwi\tr3,-1\nbne\tComboTrainingDecideStickAngle_ComboDI_UsingThrowAngle\n#Get Knockback Angle\nlwz\tr3,0x1848(r29)\nComboTrainingDecideStickAngle_ComboDI_UsingThrowAngle:\nmr\tr24,r3\t\t#Backup Original Angle We're Using\n\n#Get Perpendicular Angle\n#Get Damage Direction\ncmpwi\tr3,0x169\t\t#Check For Sakurai Angle\nbne\t0xC\nli\tr3,0x2D\nli\tr4,0x2D\ncmpwi\tr3,90\nbge\tComboTrainingDecideStickAngle_ComboDI_Above90\nb\tComboTrainingDecideStickAngle_ComboDI_RightSide\nComboTrainingDecideStickAngle_ComboDI_Above90:\ncmpwi\tr3,269\nblt\tComboTrainingDecideStickAngle_ComboDI_LeftSide\nComboTrainingDecideStickAngle_ComboDI_RightSide:\nsubi\tr3,r3,90\ncmpwi\tr3,0\nbgt\t0x8\naddi\tr3,r3,360\nb\tComboTrainingDecideStickAngle_ComboDI_GetXY\nComboTrainingDecideStickAngle_ComboDI_LeftSide:\naddi\tr3,r3,90\ncmpwi\tr3,360\nblt\t0x8\nsubi\tr3,r3,360\nb\tComboTrainingDecideStickAngle_ComboDI_GetXY\n\nComboTrainingDecideStickAngle_ComboDI_GetXY:\nbl\tComboTrainingDecideStickAngle_ConvertAngle\nstb\tr3,0x1A8C(r29)\nstb\tr4,0x1A8D(r29)\n\n#If In a Throw, Always DI The Direction Of The Angle\nlwz\tr3,0x10(r29)\ncmpwi\tr3,0xEF\nblt\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionNoThrow\ncmpwi\tr3,0xF3\nbgt\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionNoThrow\n\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow:\ncmpwi\tr24,90\nbge\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_Above90\nb\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_Above90:\ncmpwi\tr3,269\nblt\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide\n\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide:\n#Always Facing Direction\n\nli\tr3,0x0\nbl\tIntToFloat\nlfs\tf2,0x2C(r27)\nfcmpo\tcr0,f2,f1\nbgt\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_Abs\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_AbsNeg:\nlbz\tr3,0x1A8C(r29)\nextsb\tr3,r3\nbl\tIntToFloat\nfabs\tf1,f1\nfneg\tf1,f1\nb\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_StoreX\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_Abs:\nlbz\tr3,0x1A8C(r29)\nextsb\tr3,r3\nbl\tIntToFloat\nfabs\tf1,f1\nb\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_StoreX\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_RightSide_StoreX:\nfctiwz\tf1,f1\nstfd\tf1,0xF0(sp)\nlwz\tr3,0xF4(sp)\nstb\tr3,0x1A8C(r29)\nb\tComboTrainingDecideStickAngleExit\n\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide:\n#Always Opposite My Facing Direction\n\nli\tr3,0x0\nbl\tIntToFloat\nlfs\tf2,0x2C(r27)\nfcmpo\tcr0,f2,f1\nbgt\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_AbsNeg\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_Abs:\nlbz\tr3,0x1A8C(r29)\nextsb\tr3,r3\nbl\tIntToFloat\nfabs\tf1,f1\nb\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_StoreX\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_AbsNeg:\nlbz\tr3,0x1A8C(r29)\nextsb\tr3,r3\nbl\tIntToFloat\nfabs\tf1,f1\nfneg\tf1,f1\nb\tComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_StoreX\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionInThrow_LeftSide_StoreX:\nfctiwz\tf1,f1\nstfd\tf1,0xF0(sp)\nlwz\tr3,0xF4(sp)\nstb\tr3,0x1A8C(r29)\nb\tComboTrainingDecideStickAngleExit\n\nComboTrainingDecideStickAngle_ComboDI_AdjustDirectionNoThrow:\nbl\tGetDirectionInRelationToP1\n#mulli\tr3,r3,-1\t\t#Negate This Value\nlbz\tr4,0x1A8C(r29)\nmullw\tr3,r3,r4\nstb\tr3,0x1A8C(r29)\t\t#Point Towards Opponent\nb\tComboTrainingDecideStickAngleExit\n\n######################\n## Down And Away DI ##\n######################\n\nComboTrainingDecideStickAngle_DownAwayDI:\n#Load X Value\n\tbl\tGetDirectionInRelationToP1\n#Point Away From P1\n\tli\tr4,89\n\tmullw\tr3,r3,r4\n\tstb\tr3, 0x1A8C (r29)\n#Load Y Value\n\tli\tr3,-89\n\tstb\tr3, 0x1A8D (r29)\n#C-Stick Down\n\tli\tr3,-127\n\tstb\tr3, 0x1A8F (r29)\n\nb\tComboTrainingDecideStickAngleExit\n\n###########\n## No DI ##\n###########\n\nComboTrainingDecideStickAngle_NoDI:\n\nComboTrainingDecideStickAngleExit:\nrestore\nblr\n\n\n#######################################################\n\nComboTrainingDecideStickAngle_ConvertAngle:\n#Convert New Angle To Float\nbackup\n\nbl\t\tIntToFloat\n\n#Get Pi/180\nlfs\tf2,-0x7510(rtoc)\n\n#Get Angle As Radian\nfmuls\tf31,f1,f2\n\n#Get 127 as Float\nli\tr3,127\nbl\t\tIntToFloat\nfmr\t\tf30,f1\n\n#Convert To X and Y Components\nfmr\tf1,f31\nbranchl\tr12,cos\t\t#load cosine function\nfmuls\tf1,f1,f30\t\t#Get X Component As Float\nfctiwz\tf1,f1\nstfd\tf1,0xF0(sp)\nlwz\tr20,0xF4(sp)\n\nfmr\tf1,f31\nbranchl\tr12,sin\t#load sine function\nfmuls\tf1,f1,f30\t\t#Get X Component As Float\nfctiwz\tf1,f1\nstfd\tf1,0xF0(sp)\nlwz\tr21,0xF4(sp)\n\n#Clamp Deadzones\nComboTrainingDecideStickAngle_ConvertAngle_ClampX:\nmr\tr3,r20\nbl\tIntToFloat\nfabs\tf3,f1\nli\tr3,36\nbl\tIntToFloat\nfcmpo\tcr0,f3,f1\nbge\tComboTrainingDecideStickAngle_ConvertAngle_ClampY\nli\tr20,0x0\n\nComboTrainingDecideStickAngle_ConvertAngle_ClampY:\nmr\tr3,r21\nbl\tIntToFloat\nfabs\tf3,f1\nli\tr3,36\nbl\tIntToFloat\nfcmpo\tcr0,f3,f1\nbge\tComboTrainingDecideStickAngle_ConvertAngle_Exit\nli\tr21,0x0\n\nComboTrainingDecideStickAngle_ConvertAngle_Exit:\n#Return X Y Stick Values\nmr\tr3,r20\nmr\tr4,r21\n\nrestore\nblr\n\n##############################################################\n\nComboTrainingCheckForThrowAngle:\n#Check If In Throw First (Must Retrieve Angle Manually)\nlwz\tr3,0x10(r29)\t\t#CPU AS\ncmpwi\tr3,0xEF\nblt\tComboTrainingCheckForThrowAngle_NoThrow\ncmpwi\tr3,0xF3\nbgt\tComboTrainingCheckForThrowAngle_NoThrow\n\n#Get Throw Angle\naddi\tr4,r27,0xdf4\t\t#P1 Throw Hitbox Info?\nlwz\tr3,0x20(r4)\t\t#Throw Angle\nb\tComboTrainingCheckForThrowAngle_NoThrowExit\n\nComboTrainingCheckForThrowAngle_NoThrow:\nli\tr3,-1\n\nComboTrainingCheckForThrowAngle_NoThrowExit:\nblr\n\n####################################################\n\nComboTrainingCheckExitStates:\n\n#Check For Exit States\n\tlwz\tr3,0x10(r29)\n\tcmpwi\tr3,0xE\t\t#Wait\n\tbeq\tComboTrainingCheckExitStates_ExitState\n\tcmpwi\tr3,0x1D\t\t#Fall\n\tbeq\tComboTrainingCheckExitStates_ExitState\n\tcmpwi\tr3,0x1B\t\t#DJ\n\tbeq\tComboTrainingCheckExitStates_ExitState\n\tcmpwi\tr3,0xFD\t\t#CliffWait\n\tbeq\tComboTrainingCheckExitStates_ExitState\n\tcmpwi\tr3,0xF5\t\t#Teeter\n\tbeq\tComboTrainingCheckExitStates_ExitState\n\tcmpwi\tr3,0x1C\t\t#JumpB Aerial\n\tbeq\tComboTrainingCheckExitStates_ExitState\n\tcmpwi\tr3,0x2A\t\t#Land\n\tbne\tComboTrainingCheckExitStates_CheckJiggsJump\n\t\t#Check If Can Interrupt Land\n\t\tlfs\tf1,0x894(r29)\n\t\tlfs\tf2,0x1F4(r29)\n\t\tfcmpo\tcr0,f1,f2\n\t\tbge\tComboTrainingCheckExitStates_ExitState\n\n\tComboTrainingCheckExitStates_CheckJiggsJump:\n\tlwz\tr4,0x4(r29)\n\tcmpwi\tr4,0xF\t\t#Check If Jiggs\n\tbne\tComboTrainingCheckExitStates_NoExitState\n\t\tcmpwi\tr3,0x155\n\t\tbeq\tComboTrainingCheckExitStates_ExitState\n\nComboTrainingCheckExitStates_NoExitState:\nli\tr3,0x0\nb\tComboTrainingCheckExitStates_Exit\n\nComboTrainingCheckExitStates_ExitState:\nli\tr3,0x1\nb\tComboTrainingCheckExitStates_Exit\n\nComboTrainingCheckExitStates_Exit:\nblr\n\n####################################################\n\nComboTrainingWindowInfo:\nblrl\n#amount of options, amount of options in each window\n\n.long 0x04060304  #5 windows, DI has 7 options, SDI has 4 Options, Tech Has 5 Options\n.long 0x02020000  #PostHitstun has 3 options, Mash has 3 options\n\n####################################################\n\nComboTrainingWindowText:\nblrl\n\n########\n## DI ##\n########\n\n#Window Title = DI Behavior\n.string \"DI Behavior\"\n.align 2\n\n#Option 1 = Random DI\n.string \"Random DI\"\n.align 2\n\n#Option 2 = Survival DI\n.string \"Survival DI\"\n.align 2\n\n#Option 3 = Combo DI\n.string \"Combo DI\"\n.align 2\n\n#Option 4 = Slight DI Random\n.string \"Slight DI Random\"\n.align 2\n\n#Option 5 = Slight DI Towards\n.string \"Slight DI Towards\"\n.align 2\n\n#Option 6 = Down and Away DI\n.string \"Down and Away DI\"\n.align 2\n\n#Option 6 = No DI\n.string \"No DI\"\n.align 2\n\n#########\n## SDI ##\n#########\n\n#SDI Behavior\n.long 0x53444920\n.long 0x42656861\n.long 0x76696f72\n.long 0x00000000\n\n#Option 1 = 33% Chance to SDI\n.long 0x33338193\n.long 0x20436861\n.long 0x6e636520\n.long 0x746f2053\n.long 0x44490000\n\n#Option 2 = 66% Chance to SDI\n.long 0x36368193\n.long 0x20436861\n.long 0x6e636520\n.long 0x746f2053\n.long 0x44490000\n\n#Option 3 = Always SDI\n.long 0x416c7761\n.long 0x79732053\n.long 0x44490000\n\n#Option 4 = No SDI\n.long 0x4e6f2053\n.long 0x44490000\n\n#################\n## Tech Option ##\n#################\n\n#Tech Option\n.long 0x54656368\n.long 0x204f7074\n.long 0x696f6e00\n\n#Option 1 = Random\n.long 0x52616e64\n.long 0x6f6d0000\n\n#Option 2 = Missed Tech\n.long 0x4d697373\n.long 0x65642054\n.long 0x65636800\n\n#Option 3 = Tech In Place\n.long 0x54656368\n.long 0x20496e20\n.long 0x506c6163\n.long 0x65000000\n\n#Option 4 = Tech In\n.long 0x54656368\n.long 0x20496e00\n\n#Option 5 = Tech Away\n.long 0x54656368\n.long 0x20417761\n.long 0x79000000\n\n\n#################\n## Tech Option ##\n#################\n\n#Post Hitstun Action\n.long 0x506f7374\n.long 0x20486974\n.long 0x7374756e\n.long 0x20416374\n.long 0x696f6e00\n\n#Airdodge/Spotdodge\n.long 0x41697264\n.long 0x6f646765\n.long 0x815e5370\n.long 0x6f74646f\n.long 0x64676500\n\n#Invincible\n.long 0x496e7669\n.long 0x6e636962\n.long 0x6c650000\n\n#Attack\n.long 0x41747461\n.long 0x636b0000\n\n\n###################\n## Grab Mash-Out ##\n###################\n\n#Grab Mash-Out\n.long 0x47726162\n.long 0x204d6173\n.long 0x682d4f75\n.long 0x74000000\n.long 0x\n\n#Random Mash\n.long 0x52616e64\n.long 0x6f6d204d\n.long 0x61736800\n.long 0x\n.long 0x\n\n#Frame Perfect\n.long 0x4672616d\n.long 0x65205065\n.long 0x72666563\n.long 0x74000000\n.long 0x\n\n#No Mash-Out\n.long 0x4e6f204d\n.long 0x6173682d\n.long 0x4f757400\n.long 0x\n.long 0x\n\n####################################################\n\nComboTrainingAttackList:\nblrl\n.long 0x00700466\n.long 0x02660000\n.long 0x30000303\n.long 0x04660073\n.long 0x30000152\n.long 0x00007000\n.long 0x660400FF\n\n####################################################\n\n\n\nComboTrainingLoadExit:\nrestore\nblr\n\n##################################################\n#endregion\n\n#region Waveshine SDI\n#########################\n## Waveshine SDI HIJACK INFO ##\n#########################\n\nWaveshineSDI:\n\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Fox.Ext\t\t\t\t\t\t\t\t\t\t#Use chosen CPU\n\tli\tr6,FinalDestination\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_WaveshineSDI\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nWaveshineSDIStoreThink:\n\tbl\tWaveshineSDILoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Waveshine SDI LOAD FUNCT ##\n\t########################\n\tWaveshineSDILoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tWaveshineSDIThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\n/*\n\t#Make Long Destination\n\t#Get Stage DAT Pointer\n\tload\tr3,0x80432290\n\tlwz\tr3,0x10(r3)\n\tlwz\tr6,0x4(r3)\n  lis r3, 0x4040\n  li r5, 0x0\n  ori r4, r5, 0xF488\n  stwx r3, r6, r4\n  ori r4, r5, 0xF4CC\n  stwx r3, r6, r4\n  ori r4, r5, 0xF4D0\n  stwx r3, r6, r4\n  ori r4, r5, 0xF590\n  stwx r3, r6, r4\n  lis r4, 0x1\n  ori r4, r4, 0x88\n  stwx r3, r6, r4\n  lis r4, 0x1\n  ori r4, r4, 0x608\n  stwx r3, r6, r4\n  lis r3, 0x4248\n  ori r4, r5, 0xF4D8\n  stwx r3, r6, r4\n  lis r4, 0x5\n  ori r4, r4, 0x1B90\n  stwx r5, r6, r4\n  lis r5, 0x5\n  lis r3, 0xC3AA\n  ori r3, r3, 0x91EC\n  ori r4, r5, 0x1F20\n  stwx r3, r6, r4\n  lis r3, 0x43AA\n  ori r3, r3, 0x91EC\n  ori r4, r5, 0x1F60\n  stwx r3, r6, r4\n  lis r3, 0xC3D0\n  ori r3, r3, 0x91EC\n  ori r4, r5, 0x1FA0\n  stwx r3, r6, r4\n  lis r3, 0x43D0\n  ori r3, r3, 0x91EC\n  ori r4, r5, 0x1FE0\n  stwx r3, r6, r4\n*/\n\n\tb\tWaveshineSDILoadExit\n\n\n\t\t#########################\n\t\t## Waveshine SDI THINK FUNCT ##\n\t\t#########################\n\n\n\t\tWaveshineSDIThink:\n\t\t\tblrl\n\n      .set EventData,31\n      .set P1Data,27\n      .set P1GObj,28\n      .set P2Data,29\n      .set P2GObj,30\n\n\t\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n      bl  GetAllPlayerPointers\n      mr P1GObj,r3\n      mr P1Data,r4\n      mr P2GObj,r5\n      mr P2Data,r6\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tWaveshineSDIThinkMain\n\n\t\t\t\t#Set Frame 1 As Over\n\t\t\t\t\tli\t\tr3,0x1\n\t\t\t\t\tstb\t\tr3,0x0(r31)\n\t\t\t\t#Set Facing Directions\n\t\t\t\t\tlis\tr3,0x3f80\n\t\t\t\t\tstw\tr3,0x2C(r29)\n\t\t\t\t\tlis\tr3,0xBf80\n\t\t\t\t\tstw\tr3,0x2C(r27)\n\t\t\t\t#Initlize Positions\n\t\t\t\t\tbl\tWaveshineSDI_Floats\n\t\t\t\t\tmflr\tr3\n\t\t\t\t\tbl\tInitializePositions\n        #Clear Inputs\n          bl  RemoveFirstFrameInputs\n\t\t\t\t#Store Ground As Last Known Position\n\t\t\t\t\tlfs\tf1, 0x00B4 (r29)\n\t\t\t\t\tstfs\tf1, 0x0834 (r29)\n\t\t\t\t#Save State\n\t\t\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n\t\t\t\t\tbl\tSaveState_Save\n\t\t\t\t#Set Timer to -60\n\t\t\t\t\tli\t\tr3,-60\n\t\t\t\t\tstw\t\tr3,0x4(r31)\n\n\n\n\t\tWaveshineSDIThinkMain:\n\t\tWaveshineSDIThinkSequence:\n\t\t#Inc Timer\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tstw\tr3,0x4(r31)\n\n\t\t#Get Floats\n\t\t\tbl\tWaveshineSDI_Floats\n\t\t\tmflr\tr21\n\n\t\t#Check Timer\n\t\t\tcmpwi\tr3,0x0\n\t\t\tblt\tWaveshineSDICheckToReset\n\n\t\t#Check If Edge Of Stage\n\t\t\tlfs\tf1,0xB0(r29)\t\t#P1 X Coord\n\t\t\tlfs\tf2,0x18(r21)\t\t#Max X Coord\n\t\t\tfabs\tf1,f1\n\t\t\tfabs\tf2,f2\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tblt\tWaveshineSDISkipBoundaryCheck\n\t\t#Freeze Fox If So\n\t\t\tlbz\tr0,0x2219(r29)\n\t\t\tli\tr3,1\n\t\t\trlwimi\tr0,r3,2,29,29\n\t\t\tstb\tr0,0x2219(r29)\n\t\t\tlwz \tr3,0xC(r31)\n\t\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\t\tbgt\tWaveshineSDICheckToReset\n\t\t\tli\tr3,60\t\t#Set Timer If Not Set Yet\n\t\t\tstw\tr3,0xC(r31)\n\t\t\tb\tWaveshineSDICheckToReset\n\t\tWaveshineSDISkipBoundaryCheck:\n\n\t\t#Check If Fox Grabbed Marth\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0xD8\n\t\t\tbne\tWaveshineSDICheckDrillOrWaveshine\n\t\t\tlwz\tr3,0xC(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbgt\tWaveshineSDICheckDrillOrWaveshine\n\t\t\tli\tr3,60\n\t\t\tstw\tr3,0xC(r31)\n\n\t\t#Check If Drilling or Waveshining\n\t\t\tWaveshineSDICheckDrillOrWaveshine:\n\t\t\tlbz\tr3,0x8(r31)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbge\tWaveshineSDIWaveshineThink\n\n\t\t#Run Drill Code\n\t\t\tWaveshineSDIDrillThink:\n\t\t\tlwz\tr3,0x10(r29)\n\n\t\tWaveshineSDIDrillThink_CheckToJump:\n\t\t\tcmpwi\tr3,0xE\n\t\t\tbne\tWaveshineSDIDrillThink_CheckToDair\n\t\t\tli\tr3,0x400\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tWaveshineSDICheckToReset\n\n\t\tWaveshineSDIDrillThink_CheckToDair:\n\t\t\tcmpwi\tr3,0x19\n\t\t\tbne\tWaveshineSDI_CheckToFF\n\t\t\tli\tr3,-127\n\t\t\tstb\tr3,0x1A8F(r29)\n\t\t\tb\tWaveshineSDICheckToReset\n\n\t\tWaveshineSDI_CheckToFF:\n\t\t#Check If Drilling\n\t\t\tcmpwi\tr3,0x45\n\t\t\tbne\tWaveshineSDICheckToReset\n\t\t#Joystick X = 36 * Facing Direction (Drift Forward during drill\n\t\t\tlfs\tf1,0x2C(r29)\n\t\t\tfctiwz\tf1,f1\n\t\t\tstfd\tf1,0xF0(sp)\n\t\t\tlwz\tr4,0xF4(sp)\n\t\t\tli\tr3,36\t\t#X Stick\n\t\t\tmullw\tr3,r3,r4\n\t\t\tstb\tr3,0x1A8C(r29)\n\t\t#Check If Already FF'ing\n\t\t\tlbz\tr3,0x221A(r29)\n\t\t\trlwinm.\tr3,r3,0,28,28\n\t\t\tbne\tWaveshineSDICheckToLCancel\n\t\t#Check If Falling\n\t\t\tlfs\tf2,0x84(r29)\n\t\t\tlfs\tf0, -0x76B0 (rtoc)\n\t\t\tfcmpo\tcr0,f2,f0\n\t\t\tbge\tWaveshineSDICheckToReset\n\t\t#Input Down to FF\n\t\t\tli\tr3,-127\n\t\t\tstb\tr3,0x1A8D(r29)\t\t#Ananlog Y\n\n\t\tWaveshineSDICheckToLCancel:\n\t\t#Check If Under 5Mm Above Ground\n\t\t\tlfs\tf2,0xB4(r29)\n\t\t\tlfs\tf0,0x834(r29)\t\t#Last Grounded Y Pos\n\t\t\tfsubs\tf2,f2,f0\t\t#Distance from Floor\n\t\t\tlfs\tf0,0x10(r21)\t\t#5 fp\n\t\t\tfcmpo\tcr0,f2,f0\t\t#If less than 5 Mm away, Input L Cancel\n\t\t\tbgt\tWaveshineSDICheckToReset\n\t\t\tli\tr3,0xC0\t\t#Hit L\n\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\tli\tr3,0x1\t\t#Set Start Waveshine Flag\n\t\t\tstb\tr3,0x8(r31)\n\t\t\tb\tWaveshineSDICheckToReset\n\n\n\t\t#Run Waveshine Code\n\t\tWaveshineSDIWaveshineThink:\n\t\t\tlwz\tr3,0x10(r29)\n\n\n\t\t#Shine If In Wait\n\t\t\tcmpwi\tr3,0xE\n\t\t\tbne\tWaveshineSDICheckToJump\n\t\t#Check If First Shine Or FollowUp Shine\n\t\t\tlbz\tr4,0x8(r31)\n\t\t\tcmpwi\tr4,0x2\n\t\t\tbeq\tWaveshineSDIWaveshine_FollowOpponent\n\t\t#Input Shine\n\t\t\tli\tr3,-127\n\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\tli\tr3,0x200\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t#Set Flag as Mid-Waveshine\n\t\t\tli\tr3,0x2\n\t\t\tstb\tr3,0x8(r31)\n\t\t#Get JC Timing\n\t\t\tli\tr3,3\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tstb\tr3,0x9(r31)\n\t\t\tb\tWaveshineSDICheckToReset\n\n\t\t#Jump If In Shine Loop\n\t\tWaveshineSDICheckToJump:\n\t\t#Check\n\t\t\t#Check For Shine Loop\n\t\t\t\tcmpwi\tr3,0x169\n\t\t\t\tbne\tWaveshineSDICheckToAirdodge\n\t\t\t#Check For JC Frame\n\t\t\t\tlbz\tr3,0x9(r31)\t\t#Get JC Timing\n\t\t\t\tbl\tIntToFloat\n\t\t\t\tlfs\tf2,0x894(r29)\n\t\t\t\tfcmpo\tcr0,f1,f2\n\t\t\t\tbne\tWaveshineSDICheckToReset\n\t\t\t#Jump\n\t\t\t\tli\tr3,0x400\n\t\t\t\tstw\tr3,0x1A88(r29)\n\t\t\t\tb\tWaveshineSDICheckToReset\n\n\t\t#Airdodge If In JumpF\n\t\tWaveshineSDICheckToAirdodge:\n\t\t\tcmpwi\tr3,0x19\n\t\t\tbne\tWaveshineSDIWaveshine_CheckIfFollowingOpponent\n\t\t#Get Random Airdodge Angle\n\t\t\tli\tr3,30\t\t#30 Different Angles\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\taddi\tr3,r3,310\t\t#Start at 310°\n\t\t\tbl\tComboTrainingDecideStickAngle_ConvertAngle\n\t\t#Joystick X = X Component * Facing Direction\n\t\t\tlfs\tf1,0x2C(r29)\n\t\t\tfctiwz\tf1,f1\n\t\t\tstfd\tf1,0xF0(sp)\n\t\t\tlwz\tr5,0xF4(sp)\n\t\t\tmullw\tr3,r3,r5\n\t\t\tstb\tr3,0x1A8C(r29)\n\t\t#Joystick Y = Y Component\n\t\t\tstb\tr4,0x1A8D(r29)\n\t\t#Press L To Wavedash\n\t\t\tli\tr3,0xC0\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tWaveshineSDICheckToReset\n\n\t\tWaveshineSDIWaveshine_CheckIfFollowingOpponent:\n\t\t\tcmpwi\tr3,0xf\t\t#Check if Walking\n\t\t\tblt\tWaveshineSDICheckIfInTeeter\n\t\t\tcmpwi\tr3,0x11\t\t#Check if Walking\n\t\t\tbgt\tWaveshineSDICheckIfInTeeter\n\t\t\tb\tWaveshineSDIWaveshine_FollowOpponent\n\n\t\tWaveshineSDICheckIfInTeeter:\n\t\t\tcmpwi\tr3,0xf5\n\t\t\tbne\tWaveshineSDICheckToReset\n\t\t\tb\tWaveshineSDIRestoreState\n\n\t\tWaveshineSDIWaveshine_FollowOpponent:\n\t\t#Determine Distance From Opponent\n\t\t\tlfs\tf1,0xB0(r27)\n\t\t\tlfs\tf2,0xB0(r29)\n\t\t\tfsubs\tf1,f1,f2\n\t\t\tlfs\tf2,-0x7414(rtoc)\t\t#0f\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tbge\tWaveshineSDIWaveshine_FollowOpponent_FacingRight\n\n\t\tWaveshineSDIWaveshine_FollowOpponent_FacingLeft:\n\t\t#Check If Close Enough To Shine\n\t\t\tlfs\tf2,0x14(r21)\n\t\t\tfneg\tf2,f2\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tblt\tWaveshineSDIWaveshine_FollowOpponent_WalkTowards\n\t\t\tb\tWaveshineSDIWaveshine_FollowOpponent_EnterShine\n\t\t\t#b\tWaveshineSDIWaveshine_FollowOpponent_CheckMarth\n\t\tWaveshineSDIWaveshine_FollowOpponent_FacingRight:\n\t\t\tlfs\tf2,0x14(r21)\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tbgt\tWaveshineSDIWaveshine_FollowOpponent_WalkTowards\n\t\t\tb\tWaveshineSDIWaveshine_FollowOpponent_EnterShine\n\t\t#Check Opponent\n\t\tWaveshineSDIWaveshine_FollowOpponent_CheckMarth:\n\t\t\tlwz\tr3,0x4(r27)\n\t\t\tcmpwi\tr3,0x12\t\t#Marth\n\t\t\tbeq\tWaveshineSDIWaveshine_FollowOpponent_EnterGrab\n\t\tWaveshineSDIWaveshine_FollowOpponent_EnterShine:\n\t\t\t#Shine\n\t\t\t\tli\tr3,-127\n\t\t\t\tstb\tr3,0x1A8D(r29)\n\t\t\t\tli\tr3,0x200\n\t\t\t\tstw\tr3,0x1A88(r29)\n\t\t\t#Get JC Timing\n\t\t\t\tli\tr3,3\n\t\t\t\tbranchl\tr12,HSD_Randi\n\t\t\t\tstb\tr3,0x9(r31)\n\t\t\t\tb\tWaveshineSDICheckToReset\n\t\tWaveshineSDIWaveshine_FollowOpponent_EnterGrab:\n\t\t\tli\tr3,0x1C0\n\t\t\tstw\tr3,0x1A88(r29)\n\t\t\tb\tWaveshineSDICheckToReset\n\t\tWaveshineSDIWaveshine_FollowOpponent_WalkTowards:\n\t\t#Walk Towards Opponent\n\t\t#Stick Forward\n\t\t\tlfs\tf1,0x2C(r29)\n\t\t\tfctiwz\tf2,f1\n\t\t\tstfd\tf2,0xF0(sp)\n\t\t\tlwz\tr4,0xF4(sp)\n\t\t\tli\tr3,127\t\t#X Stick\n\t\t\tmullw\tr3,r3,r4\n\t\t\tstb\tr3,0x1A8C(r29)\n\t\t#Override Analog Smash Counter So Always Walking (Set Facing As Prev X Input)\n\t\t\tstfs\tf1,0x620(r29)\n\t\t\tb\tWaveshineSDICheckToReset\n\n\n\t\t#Initiate Reset Timer\n\t\t\tli\tr3,120\n\t\t\tstw\tr3,0xC(r31)\n\n\t\t#Check To Reset\n\t\tWaveshineSDICheckToReset:\n\t\t\tlwz\tr3,0xC(r31)\t\t#get timer\t#Get Timer\n\t\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\t\tble\tWaveshineSDIThinkExit\n\t\t#Dec Timer\n\t\t\tsubi\tr3,r3,0x1\n\t\t\tstw\tr3,0xC(r31)\t\t#store timer\n\t\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\t\tbne\tWaveshineSDIThinkExit\t#Exit If Not\n\t\tWaveshineSDIRestoreState:\n\t\t#Invert Facing Directions\n\t\t\tlwz\tr4,0x10(r31)\n\t\t\tlwz\tr5,0x18(r31)\n\t\t\tlfs\tf1,0x2C(r4)\n\t\t\tfneg\tf1,f1\n\t\t\tstfs\tf1,0x2C(r4)\n\t\t\tlfs\tf1,0x2C(r5)\n\t\t\tfneg\tf1,f1\n\t\t\tstfs\tf1,0x2C(r5)\n\t\t\t#Invert X Positions\n\t\t\tlfs\tf1,0xB0(r4)\n\t\t\tfneg\tf1,f1\n\t\t\tstfs\tf1,0xB0(r4)\n\t\t\tlfs\tf1,0xB0(r5)\n\t\t\tfneg\tf1,f1\n\t\t\tstfs\tf1,0xB0(r5)\n\t\t#Restore State\n\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\tbl\tSaveState_Load\n\t\t#Reset Timer\n\t\t\tli\tr3,60\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tli\tr4,0\n\t\t\tsub\tr3,r4,r3\n\t\t\tstw\tr3,0x4(r31)\n\t\t#Reset Mid-Waveshine Flag\n\t\t\tli\tr3,0x0\n\t\t\tstb\tr3,0x8(r31)\n\n\t\tWaveshineSDIThinkExit:\n\t\trestore\n\t\tblr\n\n#################################\n\nWaveshineSDI_Floats:\nblrl\n.long 0xC28C0000\t\t#P1 X Position\n.long 0xc2982e6c \t#P2 X Position\n.long 0x38d1b717  #P1 Y Position\n.long 0x38d1b717\t\t#FD Floor Y Coord\n.long 0x40A00000  #5fp\n.long 0x40F00000  #Distance From Opponent to Waveshine\n.long 0x42A00000  #X Coord To Stop\n\n#################################\n\nWaveshineSDILoadExit:\nrestore\nblr\n\n##################################################\n#endregion\n\n#region Slide Off\n###########################\n## Slide Off HIJACK INFO ##\n###########################\n\nSlideOff:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Marth.Ext\n\tli\tr6,PokemonStadium\t\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_SlideOff\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nSlideOffStoreThink:\n\tbl\tSlideOffLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## \t\t\tSlide Off LOAD FUNCT \t\t##\n##################################\nSlideOffLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tSlideOffThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\tb\tSlideOffThink_Exit\n\n###################################\n## Slide Off THINK FUNCT ##\n###################################\n\nSlideOffThink:\n\tblrl\n\n#Registers\n\t.set REG_EventConstants,25\n  .set REG_MenuData,26\n  .set REG_EventData,31\n  .set REG_P1Data,27\n  .set REG_P1GObj,28\n\t.set REG_P2Data,29\n\t.set REG_P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set EventState_Hitstun,0x0\n\t\t.set EventState_DetermineAttack,0x1\n\t\t.set EventState_AttackThink,0x2\n\t\t.set EventState_Shield,0x3\n\t.set Timer,0x1\n\t.set P1State,0x2\n\t\t.set P1State_Wait,0x0\n\t\t.set P1State_Attacking,0x1\n\t.set AttackTimer,0x3\n\n#Constants\n\t.set ResetTimer,40\n\t.set AngleLo,83\n\t.set AngleHi,100\n\t.set MagLo,65\n\t.set MagHi,75\n\t.set HitlagFrames,12\n\t.set PercentLo,40\n\t.set PercentHi,40\n\t.set FramesBeforeHitbox,7\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tlwz\tREG_EventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n#Get Player Pointers\n  bl GetAllPlayerPointers\n  mr REG_P1GObj,r3\n  mr REG_P1Data,r4\n  mr REG_P2GObj,r5\n  mr REG_P2Data,r6\n\n#Get Menu and Constants Pointers\n  lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData)\n\tbl\tSlideOffThink_Constants\n\tmflr REG_EventConstants\n\n\tbl\tStoreCPUTypeAndZeroInputs\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tSlideOffThink_Start\n\t#Init Positions\n\t\tmr\tr3,REG_P1GObj\n\t\tmr\tr4,REG_P2GObj\n\t\tbl\tSlideOff_InitializePositions\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\n\t#Init State\n\t\tli\tr3,EventState_Hitstun\n\t\tstb\tr3,EventState(REG_EventData)\nSlideOffThink_Start:\n\n#Reset if anyone died\n\tbl\tIsAnyoneDead\n\tcmpwi r3,0\n\tbne SlideOffThink_Restore\n\nSlideOffThink_CheckIfFailed:\n#Check if failed the slide off (in non-hitlag damage state)\n#EventState > EventState_Hitstun\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_Hitstun\n\tble SlideOffThink_CheckIfFailed_End\n#Check for hitlag\n\tlbz r3,0x221A(REG_P1Data)\n\trlwinm. r3,r3,0,26,26\n\tbne SlideOffThink_CheckIfFailed_End\n#Check if in hitstun\n\tlbz r3,0x221C(REG_P1Data)\n\trlwinm. r3,r3,0,30,30\n\tbeq SlideOffThink_CheckIfFailed_End\n#Check if player has been in this state for over 5 frames\n\tlhz r3,TM_FramesinCurrentAS(REG_P1Data)\n\tcmpwi r3,5\n\tblt SlideOffThink_CheckIfFailed_End\n#Check if timer has started\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt SlideOffThink_CheckTimer\n#Start Timer\n\tli\tr3,10\n\tstb r3,Timer(REG_EventData)\nSlideOffThink_CheckIfFailed_End:\n\nSlideOffThink_CheckIfCPUDamaged:\n\tlwz\tr3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_DamageHi1\n\tblt\tSlideOffThink_CheckIfCPUDamaged_End\n\tcmpwi r3,ASID_DamageFlyRoll\n\tbgt\tSlideOffThink_CheckIfCPUDamaged_End\n#Check if timer has started\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt SlideOffThink_CheckIfCPUDamaged_End\n#Start Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\nSlideOffThink_CheckIfCPUDamaged_End:\n\nSlideOffThink_SwitchCase:\n#Switch Case\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_Hitstun\n\tbeq SlideOffThink_Hitstun\n\tcmpwi r3,EventState_DetermineAttack\n\tbeq SlideOffThink_DetermineAttackorShield\n\tcmpwi r3,EventState_AttackThink\n\tbeq SlideOffThink_AttackThink\n\tcmpwi r3,EventState_Shield\n\tbeq SlideOffThink_Shield\n\tb\tSlideOffThink_CheckTimer\n\n#region SlideOffThink_Hitstun\nSlideOffThink_Hitstun:\n#Check if still in ThrowHi\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_ThrowHi\n\tbeq SlideOffThink_CheckTimer\n\n#Check if P1 is in a tech/mistech state\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_DownBoundU\n\tblt SlideOffThink_CheckTimer\n\tcmpwi r3,ASID_PassiveStandB\n\tbgt SlideOffThink_CheckTimer\n\n#Change state to attack\n\tli\tr3,EventState_DetermineAttack\n\tstb\tr3,EventState(EventData)\n\tb\tSlideOffThink_CheckTimer\n\n#endregion\n\n#region SlideOffThink_DetermineAttackorShield\nSlideOffThink_DetermineAttackorShield:\n/*\n#Ensure facing correct direction\n#Get Values\n\tlfs f1,0xB0(REG_P2Data)\t\t\t\t#p2 position\n\tlfs f2,0x2C(REG_P2Data)\t\t\t\t#p2 direction\n\tlfs f4,TriggerBoxXMin(REG_EventConstants)\n\tlfs f5,TriggerBoxXMax(REG_EventConstants)\n\tlfs f6,0xB0(REG_P1Data)\n#Check X\n\tfmadds f3,f2,f4,f1\t\t\t\t#XMin\n\tfmadds f4,f2,f5,f1\t\t\t\t#XMax\n#Make sure player is not behind marths range\n\tlfs f1,-0x68E0 (rtoc)\t\t\t#fp 0\n\tfcmpo cr0,f2,f1\n\tbge SlideOffThink_Attck_FacingRight\nSlideOffThink_Attck_FacingLeft:\n\tli\tr3,1\n\tfcmpo cr0,f6,f3\n\tbge SlideOffThink_Attck_InputTurn\n\tb\tSlideOffThink_Attck_SkipDirectionChange\nSlideOffThink_Attck_FacingRight:\n\tli\tr3,-1\n\tfcmpo cr0,f6,f3\n\tble SlideOffThink_Attck_InputTurn\n\tb\tSlideOffThink_Attck_SkipDirectionChange\nSlideOffThink_Attck_InputTurn:\n#Check if already turning\n\tlwz r4,0x10(REG_P2Data)\n\tcmpwi r4,ASID_Turn\n\tbeq SlideOffThink_Attck_SkipDirectionChange\n#Input turn\n\tmulli r3,r3,36\n\tstb r3,CPU_AnalogX(REG_P2Data)\nSlideOffThink_Attck_SkipDirectionChange:\n*/\n\nSlideOffThink_DetermineAttackorShield_SkipFailCheck:\n\n#Decide to shield or attack\n\tlfs f1,0xB4(REG_P2Data)\t\t\t\t#p2 position\n\tlfs f2,TriggerBoxYMin(REG_EventConstants)\n\tlfs f3,TriggerBoxYMax(REG_EventConstants)\n\tlfs f4,0xB4(REG_P1Data)\t\t\t\t#p1 position\n\tfadds f2,f1,f2\t\t\t\t\t\t#YMin\n\tfadds f3,f1,f3\t\t\t\t\t\t#YMax\n#Check if P1 is above YMax\n\tfcmpo cr0,f4,f3\n\tbge SlideOffThink_DetermineAttackorShield_AboveTriggerBox\n#Check if P1 is below YMin\n\tfcmpo cr0,f4,f2\n\tbge SlideOffThink_DetermineAttackorShield_CheckToAttack_CanAttack\nSlideOffThink_DetermineAttackorShield_EnterShield:\n#Change Event State\n\tli\tr3,EventState_Shield\n\tstb\tr3,EventState(REG_EventData)\n#Start Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n\tb\tSlideOffThink_Shield\n\nSlideOffThink_DetermineAttackorShield_AboveTriggerBox:\n#Check if timer has started\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt SlideOffThink_CheckTimer\n#Start Timer\n\tli\tr3,10\n\tstb r3,Timer(REG_EventData)\n\tb\tSlideOffThink_CheckTimer\n\nSlideOffThink_DetermineAttackorShield_CheckToAttack_CanAttack:\n#Get P1's State\n\tlwz r3,0x10(REG_P1Data)\n#Ensure we have the frame data for this state\n\tcmpwi r3,ASID_DownBoundU\n\tblt SlideOffThink_DetermineAttackorShield_CheckToAttack_StartAttack\n\tcmpwi r3,ASID_PassiveStandB\n\tbgt SlideOffThink_DetermineAttackorShield_CheckToAttack_StartAttack\n#If DownWait or Bound, dont do anything\n\tcmpwi r3,ASID_DownWaitD\n\tbeq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd\n\tcmpwi r3,ASID_DownWaitU\n\tbeq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd\n\tcmpwi r3,ASID_DownBoundD\n\tbeq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd\n\tcmpwi r3,ASID_DownBoundU\n\tbeq SlideOffThink_DetermineAttackorShield_CheckToAttackEnd\n#Get the frame data to use\n\tsubi r3,r3,ASID_DownBoundU\n\taddi r4,REG_EventConstants,VulnFrameData\n\tlbzx r3,r3,r4\n#Marth takes 8 frames for his utilt hitbox to appear, so subtract 8\n\tsubi r3,r3,FramesBeforeHitbox\n#Use the custom playerblock offset to check P1's frame count\n\tlhz r4,TM_FramesinCurrentAS(REG_P1Data)\n\tcmpw r4,r3\n\tblt SlideOffThink_DetermineAttackorShield_CheckToAttackEnd\n#Time to attack\nSlideOffThink_DetermineAttackorShield_CheckToAttack_StartAttack:\n\tli\tr3,EventState_AttackThink\n\tstb r3,EventState(REG_EventData)\n\tb\tSlideOffThink_DetermineAttackorShield_CheckToAttackEnd\nSlideOffThink_DetermineAttackorShield_CheckToAttackEnd:\n\tb\tSlideOffThink_CheckTimer\n\n#endregion\n\n#region SlideOffThink_AttackThink\nSlideOffThink_AttackThink:\n#Get Inputs for this frame\n\tmr\tr3,REG_P2Data\n\tbl\tSlideOffThink_AttackInputs\n\tmflr r4\n\tlbz r5,AttackTimer(REG_EventData)\n\tbl\tPlaybackInputSequence\n\n#Always succeed LCancel\n\tli\tr3,0\n\tstb r3,0x67F(REG_P2Data)\n\n#Remove Hitbox ID 1,2 and 3 (problematic for getting slideoff)\n\tmr\tr3,REG_P2GObj\n\tli\tr4,1\n\tbranchl r12,0x8007afc8\n\tmr\tr3,REG_P2GObj\n\tli\tr4,2\n\tbranchl r12,0x8007afc8\n\tmr\tr3,REG_P2GObj\n\tli\tr4,3\n\tbranchl r12,0x8007afc8\n\n#Exit AttackThink when returning to Wait\n\tlbz r3,AttackTimer(REG_EventData)\n\tcmpwi r3,0\n\tble SlideOffThink_AttackThink_Exit\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_Wait\n\tbeq SlideOffThink_AttackThink_Reset\n\tcmpwi r3,ASID_Landing\n\tbne SlideOffThink_AttackThink_Exit\n#Now check if interruptable\n\tlwz\tr3, 0x2340 (REG_P2Data)\n\tcmpwi r3,0\n\tbeq SlideOffThink_AttackThink_Exit\n#Check if this frame is interruptable\n\tlfs f1,0x1f4 (REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tlhz r4,TM_FramesinCurrentAS(REG_P2Data)\n\tcmpw r4,r3\n\tblt SlideOffThink_AttackThink_Exit\n\nSlideOffThink_AttackThink_Reset:\n\tli\tr3,EventState_DetermineAttack\t\t\t#event state\n\tstb r3,EventState(REG_EventData)\n\tli\tr3,0\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#reset timer\n\tstb r3,AttackTimer(REG_EventData)\n\tb\tSlideOffThink_CheckTimer\n\nSlideOffThink_AttackThink_Exit:\n#Check if in Hitlag\n\tlbz r3,0x221A(REG_P2Data)\n\trlwinm. r3,r3,0,26,26\n\tbne SlideOffThink_CheckTimer\n#Increment Attack Timer\n\tlbz r3,AttackTimer(REG_EventData)\n\taddi r3,r3,1\n\tstb r3,AttackTimer(REG_EventData)\n\tb\tSlideOffThink_CheckTimer\n#endregion\n\n#region SlideOffThink_Shield\nSlideOffThink_Shield:\n#Hold Shield\n\tli\tr3,PAD_TRIGGER_R\n\tstw\tr3,CPU_HeldButtons(REG_P2Data)\n\tb\tSlideOffThink_CheckTimer\n#endregion\n\nSlideOffThink_CheckTimer:\n#Check if timer exists\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tble SlideOffThink_Exit\n#Decrement timer\n\tsubi r3,r3,1\n\tstb r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt SlideOffThink_Exit\n\nSlideOffThink_Restore:\n#Restore State\n\taddi r3,REG_EventData,EventData_SaveStateStruct\n\tli\tr4,1\n\tbl\tSaveState_Load\n#Init Positions Again\n\tmr\tr3,REG_P1GObj\n\tmr\tr4,REG_P2GObj\n\tbl\tSlideOff_InitializePositions\n#Reset Variables\n\tli\tr3,0\n\tstb r3,EventState(REG_EventData)\n\tstb r3,Timer(REG_EventData)\n\tstb r3,P1State(REG_EventData)\n\tstb r3,AttackTimer(REG_EventData)\n\nSlideOffThink_Exit:\n\trestore\n\tblr\n\n################################\n\nSlideOffThink_Constants:\nblrl\n.set MarthUTiltFrame,8\n.set P1X,0x0\n.set P1Y,0x4\n.set P2X,0x8\n.set P2Y,0xC\n.set UThrowStartFrame,0x10\n.set DamageFlyTopStartFrame,0x14\n.set MagnitudeScalar,0x18\n.set MagnitudeScalar2,0x1C\n.set MagnitudeScalar3,0x20\n.set TriggerBoxXMin,0x24\n.set TriggerBoxXMax,0x28\n.set TriggerBoxYMin,0x2C\n.set TriggerBoxYMax,0x30\n.set VulnFrameData,0x34\n.set Unk,0x48\n\n.float -37.7\t\t#p1 x\n.float 21.2\t\t\t#p1 y\n.float -41.1\t\t#p2 x\n.float 0\t\t\t\t#p2 y\n.float 13\t\t\t\t#marth upthrow starting frame\n.float 2\t\t\t\t#p1 damageflytop starting frame\n.float 0.1\t\t\t#baseline for mag scaling\n.float 1\t\t\t\t#mag scaling constant\n.float 0.4\t\t\t#mag scaling constant\n.float -8\t\t\t\t#xmin\n.float 20\t\t\t\t#xmax\n.float 18\t\t\t\t#ymin\n.float 30\t\t\t\t#ymax\n##########################################\n.set TechVuln,24-4\n.set TechRollVuln,23\n.set KnockdownVuln,23\n.set GetupVuln,23\n.set GetupRollForwardVuln,20-1\n.set GetupRollBackwardVuln,30-3\n.set GetupAttackVuln,27\n\n.byte KnockdownVuln\t\t\t\t\t#DownBoundU\n.byte 0\t\t\t\t\t\t\t\t\t\t\t#DownWaitU\n.byte 0\t\t\t\t\t\t\t\t\t\t\t#DownDamageU\n.byte GetupVuln\t\t\t\t\t\t\t#DownStandU\n.byte GetupAttackVuln\t\t\t\t#DownAttackU\n.byte GetupRollForwardVuln\t#DownForwardU\n.byte GetupRollBackwardVuln\t#DownBackU\n.byte -1\t\t\t\t\t\t\t\t\t\t#DownSpotU (unused state)\n.byte KnockdownVuln\t\t\t\t\t#DownBoundD\n.byte 0\t\t\t\t\t\t\t\t\t\t\t#DownWaitD\n.byte 0\t\t\t\t\t\t\t\t\t\t\t#DownDamageD\n.byte GetupVuln\t\t\t\t\t\t\t#DownStandD\n.byte GetupAttackVuln\t\t\t\t#DownAttackD\n.byte GetupRollForwardVuln\t#DownForwardD\n.byte GetupRollBackwardVuln\t#DownBackD\n.byte -1\t\t\t\t\t\t\t\t\t\t#DownSpotD (unused state)\n.byte TechVuln\t\t\t\t\t\t\t#Passive\n.byte TechRollVuln\t\t\t\t\t#PassiveStandF\n.byte TechRollVuln\t\t\t\t\t#PassiveStandB\n.align 2\n###########################################\nSlideOffThink_AttackInputs:\nblrl\n.byte 0\n.long PAD_BUTTON_X\n.byte 0,0,0,0\n\n.byte 4\n.long 0\n.byte 0,0,0,127\n\n.byte 26\n.long PAD_TRIGGER_L\n.byte 0,-127,0,0\n\n.byte -1\n.align 2\n\n#################################\n\nSlideOff_InitializePositions:\nbackup\n\n #Change Facing Direction\n\tli\tr3,-1\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n  li\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\n\n#Get Starting Coordinates\n\tlfs f1,P1X(REG_EventConstants)\n\tstfs f1,0xB0(REG_P1Data)\n\tlfs f1,P1Y(REG_EventConstants)\n\tstfs f1,0xB4(REG_P1Data)\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdatePosition\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdateCameraBox\n\n\tlfs f1,P2X(REG_EventConstants)\n\tstfs f1,0xB0(REG_P2Data)\n\tlfs f1,P2Y(REG_EventConstants)\n\tstfs f1,0xB4(REG_P2Data)\n\tmr\tr3,REG_P2GObj\n\tbl\tPlacePlayerOnGround\n\tmr\tr3,REG_P2GObj\n\tbl\tUpdateCameraBox\n\n#P2 enters UpThrow\n\tmr\tr3,REG_P2GObj\n\tli\tr4,ASID_ThrowHi\n\tli\tr5,0\n\tli\tr6,0\n\tlwz r7,0x10C(REG_P1Data)\t\t#determine speed from weight\n\tlwz r7,0x0(r7)\n\tlfs f1,0x88(r7)\n\tlfs\tf2, -0x68DC (rtoc)\n\tlwz\tr7, -0x514C (r13)\n\tlfs\tf0, 0x037C (r7)\n\tfmuls\tf0,f1,f0\n\tfdivs\tf2,f2,f0\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#anim speed\n\tlfs\tf3, -0x68E0 (rtoc)\t\t\t\t\t\t\t\t\t\t\t#frame blend\n\tlfs f1,UThrowStartFrame(REG_EventConstants)\t#starting frame\n\tbranchl r12,ActionStateChange\n\n#P1 enters DamageFlyTop\n\tmr\tr3,REG_P1GObj\n\tli\tr4,ASID_DamageFlyTop\n\tli\tr5,0x40\n\tli\tr6,0\n\tlfs\tf1,DamageFlyTopStartFrame (REG_EventConstants)\n\tlfs\tf2, -0x73D0 (rtoc)\n\tlfs\tf3, -0x750C (rtoc)\n\tbranchl r12,ActionStateChange\n\n#Scale KB Magnitude based on characters weight\n\tli\tr3,MagLo\n\tbl\tIntToFloat\n\tlfs f2,MagnitudeScalar(REG_EventConstants)\n\tlfs f3,0x16C(REG_P1Data)\n\tlfs f4,MagnitudeScalar2(REG_EventConstants)\n\tlfs f5,MagnitudeScalar3(REG_EventConstants)\n\tfdivs f2,f3,f2\n\tfsubs f2,f2,f4\n\tfmuls f2,f2,f5\n\tfmuls f2,f2,f1\n\tfadds f1,f1,f2\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r20,0x84(sp)\n\n\tli\tr3,MagHi\n\tbl\tIntToFloat\n\tlfs f2,MagnitudeScalar(REG_EventConstants)\n\tlfs f3,0x16C(REG_P1Data)\n\tlfs f4,MagnitudeScalar2(REG_EventConstants)\n\tlfs f5,MagnitudeScalar3(REG_EventConstants)\n\tfdivs f2,f3,f2\n\tfsubs f2,f2,f4\n\tfmuls f2,f2,f5\n\tfmuls f2,f2,f1\n\tfadds f1,f1,f2\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r21,0x84(sp)\n\n#Enter into knockback\n\tmr\tr3,REG_P1GObj\n\tli\tr4,AngleLo\n\tli\tr5,AngleHi\n\tmr\tr6,r20\n\tmr\tr7,r21\n\tbl\tEnterKnockback\n\n#Override hitstun amount\n\tli\tr3,50\n\tbl\tIntToFloat\n\tstfs f1,0x2340(REG_P1Data)\n\n#Give 7 Frames of Hitlag to Each\n\tli\tr3,HitlagFrames\n\tbl\tIntToFloat\n\tstfs f1,0x195C(REG_P1Data)\n\tlbz r0,0x221A(REG_P1Data)\n\tli\tr3,1\n\trlwimi r0,r3,5,26,26\n\tstb r0,0x221A(REG_P1Data)\n\tlbz r0,0x2219(REG_P1Data)\n\tli\tr3,1\n\trlwimi r0,r3,2,29,29\n\tstb r0,0x2219(REG_P1Data)\n\tli\tr3,HitlagFrames\n\tbl\tIntToFloat\n\tstfs f1,0x195C(REG_P2Data)\n\tlbz r0,0x221A(REG_P2Data)\n\tli\tr3,1\n\trlwimi r0,r3,5,26,26\n\tstb r0,0x221A(REG_P2Data)\n\tlbz r0,0x2219(REG_P2Data)\n\tli\tr3,1\n\trlwimi r0,r3,2,29,29\n\tstb r0,0x2219(REG_P2Data)\n\n#Random percent between 10-25\n\tli\tr3,PercentHi-PercentLo\n\tbranchl r12,HSD_Randi\n\taddi r4,r3,PercentLo\n\tlbz r3,0xC(REG_P1Data)\n\tbranchl r12,PlayerBlock_SetDamage\n\nSlideOff_InitializePositions_Exit:\n\trestore\n\tblr\n\n#endregion\n\n#region Grab Mash Out\n###########################\n## Grab Mash Out HIJACK INFO ##\n###########################\n\nGrabMashOut:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Marth.Ext\n\tli\tr6,FinalDestination\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_GrabMashOut\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nGrabMashOutStoreThink:\n\tbl\tGrabMashOutLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## \t\t\tGrab Mash Out LOAD FUNCT \t\t##\n##################################\nGrabMashOutLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tGrabMashOutThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\tb\tGrabMashOutThink_Exit\n\n###################################\n## Grab Mash Out THINK FUNCT ##\n###################################\n\nGrabMashOutThink:\n\tblrl\n\n#Registers\n\t.set REG_EventConstants,25\n  .set REG_MenuData,26\n  .set REG_EventData,31\n  .set REG_P1Data,27\n  .set REG_P1GObj,28\n\t.set REG_P2Data,29\n\t.set REG_P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set EventState_ThrowDelay,0x0\n\t\t.set EventState_MashOutThink,0x1\n\t\t.set EventState_Reset,0x2\n\t.set Timer,0x1\n\t.set ThrowTimer,0x2\n\t.set GrabBreakout,0x4\n\n#Constants\n\t.set ResetTimer,80\n\t.set PercentLo,0\n\t.set PercentHi,80\n\t.set ThrowTimerLo,40\n\t.set ThrowTimerHi,100\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tlwz\tREG_EventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n#Get Player Pointers\n  bl GetAllPlayerPointers\n  mr REG_P1GObj,r3\n  mr REG_P1Data,r4\n  mr REG_P2GObj,r5\n  mr REG_P2Data,r6\n\n#Get Menu and Constants Pointers\n  lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData)\n\tbl\tGrabMashOutThink_Constants\n\tmflr REG_EventConstants\n\n\tbl\tStoreCPUTypeAndZeroInputs\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tGrabMashOutThink_Start\n\t#Init Positions\n\t\tmr\tr3,REG_P1GObj\n\t\tmr\tr4,REG_P2GObj\n\t\tmr\tr5,REG_EventData\n\t\tbl\tGrabMashOut_InitializePositions\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\nGrabMashOutThink_Start:\n\n#Reset if anyone died\n\tbl\tIsAnyoneDead\n\tcmpwi r3,0\n\tbne GrabMashOutThink_Restore\n\nGrabMashOutThink_SwitchCase:\n#Switch Case\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_ThrowDelay\n\tbeq GrabMashOutThink_ThrowDelay\n\tcmpwi r3,EventState_MashOutThink\n\tbeq GrabMashOutThink_MashOutThink\n\tcmpwi r3,EventState_Reset\n\tbeq GrabMashOutThink_Reset\n\tb\tGrabMashOutThink_CheckTimer\n\n#region GrabMashOutThink_ThrowDelay\nGrabMashOutThink_ThrowDelay:\n#Check to grab\n\tlhz r3,ThrowTimer(REG_EventData)\n\tsubi r3,r3,1\n\tsth r3,ThrowTimer(REG_EventData)\n\tcmpwi r3,0\n\tbne GrabMashOutThink_ThrowDelay_TimerSkip\n#Input grab\n\tli\tr3,PAD_BUTTON_A | PAD_TRIGGER_R\n\tstw r3,CPU_HeldButtons(REG_P2Data)\nGrabMashOutThink_ThrowDelay_TimerSkip:\n\n#Check if P1 was grabbed\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_CaptureWaitLw\n\tbeq GrabMashOutThink_ThrowDelay_Grabbed\n\tcmpwi r3,ASID_CaptureWaitHi\n\tbeq GrabMashOutThink_ThrowDelay_Grabbed\n#If just grabbed, skip\n\tcmpwi r3,ASID_CapturePulledLw\n\tbeq GrabMashOutThink_CheckTimer\n\tcmpwi r3,ASID_CapturePulledHi\n\tbeq GrabMashOutThink_CheckTimer\n#Check if P1 acted early\n\tcmpwi r3,ASID_Wait\n\tbne GrabMashOutThink_ThrowDelay_ActedEarly\n\tb\tGrabMashOutThink_CheckTimer\n\nGrabMashOutThink_ThrowDelay_Grabbed:\n#Get breakout timer\n\tlfs f1,0x2354(REG_P1Data)\n\tstfs f1,GrabBreakout(REG_EventData)\n#Change state to attack\n\tli\tr3,EventState_MashOutThink\n\tstb\tr3,EventState(EventData)\n\tb\tGrabMashOutThink_CheckTimer\nGrabMashOutThink_ThrowDelay_ActedEarly:\n#Play Error Noise\n\tli\tr3,0xAF\n\tbl\tPlaySFX\n#Set Timer\n\tli\tr3,ResetTimer-40\n\tstb r3,Timer(REG_EventData)\n#Change state to reset\n\tli\tr3,EventState_Reset\n\tstb\tr3,EventState(EventData)\n\tb\tGrabMashOutThink_CheckTimer\n\n#endregion\n\n#region GrabMashOutThink_MashOutThink\nGrabMashOutThink_MashOutThink:\n#Wait for P1 to be in CaptureCut\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_CaptureJump\n\tbeq GrabMashOutThink_BrokeOut\n\tcmpwi r3,ASID_CaptureCut\n\tbeq GrabMashOutThink_BrokeOut\n\tb GrabMashOutThink_CheckTimer\n\nGrabMashOutThink_BrokeOut:\n#Set reset timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n#Advance State\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n\tb\tGrabMashOutThink_CheckTimer\n\n#endregion\n\n#region GrabMashOutThink_Reset\nGrabMashOutThink_Reset:\n\tb\tGrabMashOutThink_CheckTimer\n#endregion\n\nGrabMashOutThink_CheckTimer:\n#Check if timer exists\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tble GrabMashOutThink_Exit\n#Decrement timer\n\tsubi r3,r3,1\n\tstb r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt GrabMashOutThink_Exit\n\nGrabMashOutThink_Restore:\n#Restore State\n\taddi r3,REG_EventData,EventData_SaveStateStruct\n\tli\tr4,1\n\tbl\tSaveState_Load\n#Init Positions Again\n\tmr\tr3,REG_P1GObj\n\tmr\tr4,REG_P2GObj\n\tmr\tr5,REG_EventData\n\tbl\tGrabMashOut_InitializePositions\n\nGrabMashOutThink_Exit:\n\trestore\n\tblr\n\n################################\n\nGrabMashOutThink_Constants:\nblrl\n.set P1X,0x0\n.set P1Y,0x4\n.set P2X,0x8\n.set P2Y,0xC\n\n.float -8\t\t#p1 x\n.float  0\t\t#p1 y\n.float  8\t\t#p2 x\n.float  0\t\t#p2 y\n###########################################\n\nGrabMashOut_TopText:\nblrl\n.string \"Escaped Grab\"\n.align 2\n\nGrabMashOut_BottomText:\nblrl\n.string \"Frame %d/%d\"\n.align 2\n###########################################\n\nGrabMashOut_InitializePositions:\nbackup\n\n.set REG_FacingDirection,31\t\t#1 = p1 facing right, -1 = p1 facing left\n.set REG_P1GObj,30\n.set REG_P1Data,29\n.set REG_P2GObj,28\n.set REG_P2Data,27\n.set REG_EventData,26\n\n#Init Registers\n  mr\tREG_P1GObj,r3\n  lwz REG_P1Data,0x2C(REG_P1GObj)\n  mr\tREG_P2GObj,r4\n  lwz REG_P2Data,0x2C(REG_P2GObj)\n\tmr\tREG_EventData,r5\n\nGrabMashOut_InitializePositions_DetermineFacingDirection:\n#Determine Facing Direction\n\tli\tREG_FacingDirection,1\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0\n\tbeq GrabMashOut_InitializePositions_DetermineFacingDirection_End\n\tli\tREG_FacingDirection,-1\nGrabMashOut_InitializePositions_DetermineFacingDirection_End:\n\n #Apply Facing Directions\n\tmr\tr3,REG_FacingDirection\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n  mulli\tr3,REG_FacingDirection,-1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\n\n#Get Starting Coordinates\n\tlfs f1,P1X(REG_EventConstants)\n\tlfs f2,P1Y(REG_EventConstants)\n\tcmpwi REG_FacingDirection,0\n\tblt GrabMashOut_InitializePositions_P1FacingLeft\n\tstfs f1,0xB0(REG_P1Data)\n\tstfs f2,0xB4(REG_P1Data)\n\tb\tGrabMashOut_InitializePositions_RightPosition\nGrabMashOut_InitializePositions_P1FacingLeft:\n\tstfs f1,0xB0(REG_P2Data)\n\tstfs f2,0xB4(REG_P2Data)\nGrabMashOut_InitializePositions_RightPosition:\n\tlfs f1,P2X(REG_EventConstants)\n\tlfs f2,P2Y(REG_EventConstants)\n\tcmpwi REG_FacingDirection,0\n\tblt GrabMashOut_InitializePositions_P2FacingRight\n\tstfs f1,0xB0(REG_P2Data)\n\tstfs f2,0xB4(REG_P2Data)\n\tb\tGrabMashOut_InitializePositions_FacingEnd\nGrabMashOut_InitializePositions_P2FacingRight:\n\tstfs f1,0xB0(REG_P1Data)\n\tstfs f2,0xB4(REG_P1Data)\nGrabMashOut_InitializePositions_FacingEnd:\n\n#Update Positions\n\tmr\tr3,REG_P1GObj\n\tbl\tPlacePlayerOnGround\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdateCameraBox\n\tmr\tr3,REG_P2GObj\n\tbl\tPlacePlayerOnGround\n\tmr\tr3,REG_P2GObj\n\tbl\tUpdateCameraBox\n\n#Enter P1 Into Wait\n\tmr\tr3,REG_P1GObj\n\tbranchl\tr12,AS_Wait\n#Enter P2 Into Wait\n\tmr\tr3,REG_P2GObj\n\tbranchl\tr12,AS_Wait\n\n#Random percent\n\tli\tr3,PercentHi-PercentLo\n\tbranchl r12,HSD_Randi\n\taddi r4,r3,PercentLo\n\tlbz r3,0xC(REG_P1Data)\n\tbranchl r12,PlayerBlock_SetDamage\n\n#Reset Variables\n\tli\tr3,EventState_ThrowDelay\n\tstb r3,EventState(REG_EventData)\n\tli\tr3,0\n\tstb r3,Timer(REG_EventData)\n#Init Throw Timer\n\tli\tr3,ThrowTimerHi-ThrowTimerLo\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,ThrowTimerLo\n\tsth r3,ThrowTimer(REG_EventData)\n\nGrabMashOut_InitializePositions_Exit:\n\trestore\n\tblr\n\n#endregion\n\n#region SDI IC DThrow Dair\n#########################\n## Event 16 HIJACK INFO ##\n#########################\n\nEvent16:\n#STORE STAGE\nli\tr3,0x20\nsth\tr3,0xE(r26)\n\nli\tr5,0xE\t\t#Ice Climbers\n\n#STORE CPU\nbl\tP2Struct\nmflr\tr3\nlwz\tr4,0x0(r29)\nstw\tr3,0x18(r4)\t\t#p2 pointer\nstb\tr5,0x0(r3)\t\t#make top tier p2\nli\tr5,0x1\t\t#make CPU controlled\nstb\tr5,0x1(r3)\n\n#SPAWN 2 PLAYERS\nli\tr3,0x40\nstb\tr3,0x1(r4)\n\n#STORE THINK FUNCTION\nbl\tEvent16Load\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t#########################\n\t## Event 16 LOAD FUNCT ##\n\t#########################\n\tEvent16Load:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tEvent16Think\n\tmflr\tr3\n  li  r4,3\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\n\tb\tEvent16LoadExit\n\n\n\t\t##########################\n\t\t## Event 16 THINK FUNCT ##\n\t\t##########################\n\n\n\t\tEvent16Think:\n\t\tblrl\n\n    .set EventData,31\n    .set P1Data,27\n    .set P1GObj,28\n    .set P2Data,29\n    .set P2GObj,30\n\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\t\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n      bl  GetAllPlayerPointers\n      mr P1GObj,r3\n      mr P1Data,r4\n      mr P2GObj,r5\n      mr P2Data,r6\n\n\t\tli\tr3,0xF\n\t\tstw\tr3,0x1A94(r29)\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\tbl\tCheckIfFirstFrame\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tEvent16ThinkMain\n\n\t\t\t\t#Set Frame 1 As Over\n\t\t\t\t\tli\t\tr3,0x1\n\t\t\t\t\tstb\t\tr3,0x0(r31)\n\t\t\t\t#Set Facing Directions\n\t\t\t\t\tlis\tr3,0x3f80\n\t\t\t\t\tstw\tr3,0x2C(r29)\n\t\t\t\t\tlis\tr3,0xBf80\n\t\t\t\t\tstw\tr3,0x2C(r27)\n\t\t\t\t#Initlize Positions\n\t\t\t\t\tbl\tEvent16_Floats\n\t\t\t\t\tmflr\tr3\n\t\t\t\t\tbl\tEvent_EnterGrab\n        #Clear Inputs\n          bl  RemoveFirstFrameInputs\n\t\t\t\t#Store Ground As Last Known Position\n\t\t\t\t\tlfs\tf1, 0x00B4 (r29)\n\t\t\t\t\tstfs\tf1, 0x0834 (r29)\n\t\t\t\t#Save State\n\t\t\t\t\taddi r3,EventData,EventData_SaveStateStruct\n\t\t\t\t\tli\tr4,1\t\t\t#Override failsafe code\n\t\t\t\t\tbl\tSaveState_Save\n\n\n\t\tEvent16ThinkMain:\n\n\n\n\t\tEvent16ThinkExit:\n\t\trestore\n\t\tblr\n\n#################################################\n\nEvent16_Floats:\nblrl\n.long 0x4144CCCD \t#P1 X Position\n.long 0x00000000\t\t#P1 Y Position\n.long 0xC02CCCCD\t\t#P2 X Position\n.long 0x00000000\t\t#P2 Y Position\n\n#################################################\n\nEvent16LoadExit:\nrestore\nblr\n\n##################################################\n#endregion\n\n##############\n## Fox Tech ##\n##############\n\n#region Ledgetech Counter\n###################################\n## Ledgetech Counter HIJACK INFO ##\n###################################\n\nLedgetechCounter:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Marth.Ext\t\t\t\t\t\t\t\t\t#Use marth\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_LedgetechCounter\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nLedgetechCounterStoreThink:\n\tbl\tLedgetechCounterLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## Ledgetech Counter LOAD FUNCT ##\n##################################\nLedgetechCounterLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tLedgetechCounterThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\tb\tLedgetechCounterThink_Exit\n\n###################################\n## Ledgetech Counter THINK FUNCT ##\n###################################\n\nLedgetechCounterThink:\n\tblrl\n\n#Registers\n\t.set EventConstants,25\n  .set MenuData,26\n  .set EventData,31\n  .set P1Data,27\n  .set P1GObj,28\n\t.set P2Data,29\n\t.set P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set EventState_OnRebirthPlat,0x0\n\t\t.set EventState_Recovering,0x1\n\t.set MarthState,0x1\n\t\t.set MarthState_Wait,0x0\n\t\t.set MarthState_Attacked,0x1\n\t.set Timer,0x2\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tlwz\t\tEventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n  bl  GetAllPlayerPointers\n  mr P1GObj,r3\n  mr P1Data,r4\n  mr P2GObj,r5\n  mr P2Data,r6\n\n  lwz MenuData,EventData_MenuDataPointer(EventData)\n\n\tbl\tLedgetechCounter_Constants\n\tmflr EventConstants\n\n\tbl\tStoreCPUTypeAndZeroInputs\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tLedgetechCounterThink_Start\n\t#Random Side of Stage\n\t\tli  r3,2\n\t\tbranchl r12,HSD_Randi\n\t\tbl  Ledgetech_InitializePositions\n\t#Move Marth forward a bit\n\t\tlfs f1,0x2C(P2Data)\n\t\tlfs f2,0x4(EventConstants)\n\t\tfmuls f1,f1,f2\n\t\tlfs f2,0xB0(P2Data)\n\t\tfadds f1,f1,f2\n\t\tstfs f1,0xB0(P2Data)\n\t#Move Falco down a bit\n\t\tlfs f1,0x8(EventConstants)\n\t\tlfs f2,0xB4(P1Data)\n\t\tfadds f1,f1,f2\n\t\tstfs f1,0xB4(P1Data)\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\n\t#Init Score Count\n  \tlhz\tr3,-0x4ea8(r13)\n  \tbranchl\tr12,HUD_KOCounter_UpdateKOs\n\nLedgetechCounterThink_Start:\n\n#Reset if anyone died\n\tbl\tIsAnyoneDead\n\tcmpwi r3,0\n\tbne LedgetechCounterThink_Restore\n\n#Switch case for state of event\n\tlbz r3,EventState(EventData)\n\tcmpwi r3,EventState_OnRebirthPlat\n\tbeq LedgetechCounterThink_OnRebirthPlat\n\tcmpwi r3,EventState_Recovering\n\tbeq LedgetechCounterThink_Recovering\n\tb\tLedgetechCounterThink_CheckForTimer\n\n###########################################\nLedgetechCounterThink_OnRebirthPlat:\n#Check if exited RebirthWait\n\tlwz r3,0x10(P1Data)\n\tcmpwi r3,ASID_RebirthWait\n\tbeq LedgetechCounterThink_OnRebirthPlat_ExtendTimer\n#Change Event State\n\tli\tr3,EventState_Recovering\n\tstb r3,EventState(EventData)\n\tb\tLedgetechCounterThink_CheckForTimer\nLedgetechCounterThink_OnRebirthPlat_ExtendTimer:\n#Extend RebithWait Timer\n\tli\tr3,2\n\tstw r3,0x2340(P1Data)\n\tb\tLedgetechCounterThink_CheckForTimer\n###########################################\n\n###########################################\nLedgetechCounterThink_Recovering:\n#Check if marth acted already\n\tlbz r3,MarthState(EventData)\n\tcmpwi r3,MarthState_Wait\n\tbne LedgetechCounterThink_CheckForTimer\n\n#Check P1s Distance from Marth\n\taddi r3,P1Data,0xB0\n\taddi r4,P2Data,0xB0\n\tbl\tGetDistance\n\tlfs f2,0x0(EventConstants)\n\tfcmpo cr0,f1,f2\n\tbgt LedgetechCounterThink_CheckForTimer\n#P1 is in range, use down B\n\tli\tr3,0x200\n\tstw r3,CPU_HeldButtons(P2Data)\n\tli\tr3,-127\n\tstb r3,CPU_AnalogY(P2Data)\n#Set as attacking\n\tli\tr3,MarthState_Attacked\n\tstb r3,MarthState(EventData)\n#Start Timer\n\tli\tr3,70\n\tstb r3,Timer(EventData)\n\n\tb\tLedgetechCounterThink_CheckForTimer\n############################################\n\nLedgetechCounterThink_CheckForTimer:\n#Check Timer\n\tlbz r3,Timer(EventData)\n\tcmpwi r3,0\n\tbeq LedgetechCounterThink_Exit\n#Decrement\n\tsubi r3,r3,1\n\tstb r3,Timer(EventData)\n\tcmpwi r3,0\n\tbne LedgetechCounterThink_Exit\n\nLedgetechCounterThink_Restore:\n#Load State\n  addi r3,EventData,EventData_SaveStateStruct\n  bl\tSaveState_Load\n#Random Side of Stage\n\tli  r3,2\n\tbranchl r12,HSD_Randi\n\tbl  Ledgetech_InitializePositions\n#Move Marth forward a bit\n\tlfs f1,0x2C(P2Data)\n\tlfs f2,0x4(EventConstants)\n\tfmuls f1,f1,f2\n\tlfs f2,0xB0(P2Data)\n\tfadds f1,f1,f2\n\tstfs f1,0xB0(P2Data)\n#Move Falco down a bit\n\tlfs f1,0x8(EventConstants)\n\tlfs f2,0xB4(P1Data)\n\tfadds f1,f1,f2\n\tstfs f1,0xB4(P1Data)\n\n#Reset Variables\n\tli\tr3,EventState_OnRebirthPlat\n\tstb r3,EventState(EventData)\n\tli\tr3,MarthState_Wait\n\tstb r3,MarthState(EventData)\n\tli\tr3,0\n\tstb r3,Timer(EventData)\n\nLedgetechCounterThink_Exit:\n\trestore\n\tblr\n\n\n######\nLedgetechCounter_Constants:\nblrl\n.float 33\t\t#Mm away from fox to init counter\n.float 5\t\t#Mm to move marth forward after placing on ledge\n.float -15\t\t#Mm to move spacies down after placing in the air\n######\n\n#endregion\n\n#region Armada Shine\n###################################\n## Armada Shine HIJACK INFO ##\n###################################\n\nArmadaShine:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Fox.Ext\t\t\t\t\t\t\t\t\t\t#Use fox\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_ArmadaShine\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nArmadaShineStoreThink:\n\tbl\tArmadaShineLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## Armada Shine LOAD FUNCT ##\n##################################\nArmadaShineLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tArmadaShineThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\n#Remove randall\n\tlwz\tr3,StageID_External(r13)\n\tcmpwi\tr3,YoshiStory\n\tbne\tLedgedashLoad_SkipRemoveRandall\n#Get randall's map_gobj\n\tli\tr3,2\t\t\t\t#randalls map_gobj is 2\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,Stage_Destroy_map_gobj\n\n\tb\tArmadaShineThink_Exit\n\n###################################\n## Armada Shine THINK FUNCT ##\n###################################\n\nArmadaShineThink:\n\tblrl\n\n#Registers\n\t.set REG_EventConstants,25\n  .set REG_MenuData,26\n  .set REG_EventData,31\n  .set REG_P1Data,27\n  .set REG_P1GObj,28\n\t.set REG_P2Data,29\n\t.set REG_P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set\tEventState_Hitstun,0x0\n\t\t.set\tEventState_Falling,0x1\n\t\t.set\tEventState_RecoverStart,0x2\n\t\t.set\tEventState_RecoverEnd,0x3\n\t\t.set\tEventState_Reset,0x4\n\t.set Timer,0x1\n\n#Constants\n.set ResetTimer,80\n.set\tQuickResetTimer,30\n.set PercentLo,0\n.set PercentHi,60\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tlwz\tREG_EventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n#Get Player Pointers\n  bl GetAllPlayerPointers\n  mr REG_P1GObj,r3\n  mr REG_P1Data,r4\n  mr REG_P2GObj,r5\n  mr REG_P2Data,r6\n\n#Get Menu and Constants Pointers\n  lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData)\n\tbl\tArmadaShineThink_Constants\n\tmflr REG_EventConstants\n\n\tbl\tStoreCPUTypeAndZeroInputs\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tArmadaShineThink_Start\n\t#Init Positions\n\t\tmr\tr3,REG_P1GObj\n\t\tmr\tr4,REG_P2GObj\n\t\tbl\tArmadaShine_InitializePositions\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\n\t#Init State\n\t\tli\tr3,EventState_Hitstun\n\t\tstb\tr3,EventState(REG_EventData)\nArmadaShineThink_Start:\n\n#Reset if anyone died\n\tbl\tIsAnyoneDead\n\tcmpwi r3,0\n\tbne ArmadaShineThink_Restore\n\n#DPad left to instant reset\n  lbz\tr3, 0x0618 (REG_P1Data)\n  bl\tGetInputStruct\n\tlwz\tr4,InputStruct_InstantButtons(r3)\n\trlwinm. r0,r4,0,31,31\n\tbne\tArmadaShineThink_Restore\n\nArmadaShineThink_GroundCheck:\n#If P2 is grounded, reset quick\n\tlwz\tr3,0xE0(REG_P2Data)\n\tcmpwi\tr3,0\n\tbeq\tArmadaShineThink_GroundCheck_OnGround\n#If P2 is grabbing a cliff, reset quick\n\tlwz\tr3,0x10(REG_P2Data)\n\tcmpwi\tr3,ASID_CliffCatch\n\tbeq\tArmadaShineThink_GroundCheck_OnGround\n\tb\tArmadaShineThink_GroundCheckSkip\nArmadaShineThink_GroundCheck_OnGround:\n#Check if timer was set\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi\tr3,QuickResetTimer\n\tble\tArmadaShineThink_GroundCheckSkip\n#Set timer\n\tli\tr3,QuickResetTimer\n\tstb r3,Timer(REG_EventData)\n#Change State\n\tli\tr3,EventState_Reset\n\tstb\tr3,EventState(REG_EventData)\nArmadaShineThink_GroundCheckSkip:\n\n#Switch Case\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_Hitstun\n\tbeq ArmadaShineThink_Hitstun\n\tcmpwi r3,EventState_Falling\n\tbeq ArmadaShineThink_Falling\n\tcmpwi r3,EventState_RecoverStart\n\tbeq ArmadaShineThink_RecoverStart\n\tcmpwi r3,EventState_RecoverEnd\n\tbeq ArmadaShineThink_RecoverEnd\n\tcmpwi\tr3,EventState_Reset\n\tbeq\tArmadaShineThink_Reset\n\tb\tArmadaShineThink_Exit\n\n#region ArmadaShineThink_Hitstun\nArmadaShineThink_Hitstun:\n#Check if still in hitstun\n\tlbz\tr3,0x221C(REG_P2Data)\n\trlwinm. r3,r3,0,30,30\n\tbne\tArmadaShineThink_Hitstun_Exit\n#Change Event State\n\tli\tr3,EventState_Falling\n\tstb\tr3,EventState(REG_EventData)\n#Run Next State Code\n\tb\tArmadaShineThink_Falling\n\nArmadaShineThink_Hitstun_Exit:\n#Always L-Cancel\n\tli\tr3,0\n\tstb r3,0x67F(REG_P1Data)\n\tb\tArmadaShineThink_Exit\n#endregion\n\n#region ArmadaShineThink_Falling\nArmadaShineThink_Falling:\n.set FirefoxRadius,80\n.set FirefoxChance,8\n#Get distance from ledge\n\taddi r3,REG_P2Data,0xB0\n\taddi r4,REG_P2Data,0x1ADC\n\tbl\tGetDistance\n\tstfs\tf1,0x80(sp)\n#Fox travels approx 82 Mm during firefox, so ensure he is at least this far\n\tli\tr3,FirefoxRadius\n\tbl\tIntToFloat\n\tlfs f2,0x80(sp)\n\tfcmpo cr0,f2,f1\n\tbge ArmadaShineThink_Falling_EnterFirefox\n#Random chance to firefox\n\tli\tr3,FirefoxChance\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0\n\tbeq ArmadaShineThink_Falling_EnterFirefox\n\tb\tArmadaShineThink_Exit\n\nArmadaShineThink_Falling_EnterFirefox:\n#Enter Firefox\n\tli\tr3,127\n\tstb r3,CPU_AnalogY(REG_P2Data)\n\tli\tr3,PAD_BUTTON_B\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n#Change Event State\n\tli\tr3,EventState_RecoverStart\n\tstb\tr3,EventState(REG_EventData)\n#Exit\n\tb\tArmadaShineThink_Exit\n#endregion\n\n#region ArmadaShineThink_RecoverStart\nArmadaShineThink_RecoverStart:\n.set RestartTimer,30\n.set FirefoxHoldFrames,43\n\nArmadaShineThink_RecoverStart_CheckIfDone:\n#Check if no longer in SpecialHiStart\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,354\n\tbeq ArmadaShineThink_RecoverStart_CheckIfDoneSkip\n#Start restart timer\n\tlwz\tr3,0x4(REG_P1Data)\n\tcmpwi\tr3,Fox.Int\n\tbne\tArmadaShineThink_RecoverStart_NotFox\n\tli\tr3,RestartTimer\n\tb\tArmadaShineThink_RecoverStart_StoreRestartTimer\nArmadaShineThink_RecoverStart_NotFox:\n\tli\tr3,RestartTimer+60\nArmadaShineThink_RecoverStart_StoreRestartTimer:\n\tstb r3,Timer(REG_EventData)\n#Change Event State\n\tli\tr3,EventState_RecoverEnd\n\tstb\tr3,EventState(REG_EventData)\n#Run Next State Code\n\tb\tArmadaShineThink_RecoverEnd\nArmadaShineThink_RecoverStart_CheckIfDoneSkip:\n\n/*\n#Wait until last frame of firefox\n\tlhz\tr3,TM_FramesinCurrentAS(REG_P2Data)\n\tcmpwi\tr3,FirefoxHoldFrames-2\n\tbeq\tArmadaShineThink_RecoverStart_InputAngle\n#Input Up\n\tli\tr3,127\n\tstb\tr3,CPU_AnalogY(REG_P2Data)\n\tb\tArmadaShineThink_RecoverStart_Exit\n*/\n\nArmadaShineThink_RecoverStart_InputAngle:\n#Backup f28-f31\n\tstfs f29,0xB0(sp)\n\tstfs f30,0xB4(sp)\n\tstfs f31,0xB8(sp)\n\tstfs f28,0xBC(sp)\n\tstfs f27,0xC0(sp)\n\n#Hold towards ledge\n#Get Angle Between Fox and Ledge\n\taddi r3,REG_P2Data,0xB0\n\taddi r4,REG_P2Data,0x1ADC\n\tbl\tGetAngleBetweenPoints\n\n#Convert this to an input\n.set REG_arctan,31\n.set REG_XComp,30\n.set REG_YComp,31\n.set REG_127,29\n#Backup arctan\n\tfmr REG_arctan,f1\n#Get 127 as a float\n\tli\tr3,127\n\tbl\tIntToFloat\n\tfmr REG_127,f1\n#Get X Component\n\tfmr f1,REG_arctan\t\t#angle in radians\n\tbranchl r12,cos\n\tfmr REG_XComp,f1\n#Get Y Component\n\tfmr f1,REG_arctan\t\t#angle in radians\n\tbranchl r12,sin\n\tfmr REG_YComp,f1\n#Get X input\n\tfmuls f1,REG_XComp,REG_127\n\tfctiwz f1,f1,\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tstb r3,0x1A8C(REG_P2Data)\n#Get Y input\n\tfmuls f1,REG_YComp,REG_127\n\tfctiwz f1,f1,\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tstb r3,0x1A8D(REG_P2Data)\n\n#region ecb test code\n.set REG_XPerFrame,29\n.set REG_YPerFrame,28\n.set REG_CurrXPos,27\n.set REG_CurrYPos,26\n.set REG_ECBStruct,20\n.set REG_ECBBoneStruct,21\n.set REG_LoopCount,22\n.set FirefoxFrames,30\n.set RandomAngleRange,20\n\n#Get Per Frame Velocity\n\tmr\tr3,REG_P2Data\n\tbranchl\tr12,0x800a17e4\n\tfmr\tREG_XComp,f1\n\tmr\tr3,REG_P2Data\n\tbranchl\tr12,0x800a1874\n\tfmr\tREG_YComp,f1\n#Get atan2\n\tfmr\tf1,REG_YComp\n\tlfs\tf2,0x2C(REG_P2Data)\n\tfmuls\tf2,f2,REG_XComp\n\tbranchl\tr12,0x80022c30\n\tfmr\tREG_arctan,f1\n#Get XComp\n\tfmr\tf1,REG_arctan\n\tbranchl\tr12,0x80326240\n\tfmr\tREG_XComp,f1\n\tfmr\tf1,REG_arctan\n\tbranchl\tr12,0x803263d4\n\tfmr\tREG_YComp,f1\n#Get Firefox distance per frame\n\tlwz\tr3, 0x02D4 (REG_P2Data)\n\tlfs\tf1, 0x0074 (r3)\n\tlfs\tf0, 0x002C (REG_P2Data)\n\tfmuls\tf1,f1,REG_XComp\n\tfmuls\tREG_XPerFrame,f1,f0\n\tlfs\tf1, 0x0074 (r3)\n\tfmuls\tREG_YPerFrame,f1,REG_YComp\n#Create an ECB struct on the stack\n\tsubi\tsp,sp,0x1d0\n\taddi\tREG_ECBBoneStruct,sp,0xC\n\taddi\tREG_ECBStruct,sp,0x24\n\tmr\tr3,REG_ECBStruct\n\tbranchl\tr12,0x80041ee4\n#Create ECB Bone struct\n/*\n0x00 = ECB Current Top Y Offset scale * value\n0x04 = ECB Current Bottom Y Offset neg(scale * vlaue)\n0x08 = ECB Current Left X Offset neg(scale * vlaue)\n0x0C = ECB Current Left Y Offset 0\n0x10 = ECB Current Right X Offset scale * value\n0x14 = ECB Current Right Y Offset 0\n*/\n#Copy Struct\n\tmr\tr3,REG_ECBBoneStruct\n\taddi\tr4,REG_EventConstants,ECB_TopY\n\tli\tr5,0x18\n\tbranchl\tr12,memcpy\n#Place Current XY into struct\n\tlfs\tREG_CurrXPos,0xB0(REG_P2Data)\n\tlfs\tREG_CurrYPos,0xB4(REG_P2Data)\n#Subtract 0.4 to account for the frame of animation left in this state\n\tlfs\tf1,FinalAnimYDifference(REG_EventConstants)\n\tfsubs\tREG_CurrYPos,REG_CurrYPos,f1\n\tlfs\tf1,0xB8(REG_P2Data)\n\tstfs\tf1,0x24(REG_ECBStruct)\n#Init Loop\n\tli\tREG_LoopCount,0\nArmadaShineThink_RecoverStart_CollisionLoop:\n#Store current position\n\tstfs\tREG_CurrXPos,0x1C(REG_ECBStruct)\n\tstfs\tREG_CurrYPos,0x20(REG_ECBStruct)\n#Check if frame X or greater\n  lwz\tr5, 0x02D4 (REG_P2Data)\n  lfs f1,0x70(r5)\n  fctiwz  f1,f1\n  stfd  f1,-0x10(sp)\n  lwz r3,-0x0C(sp)\n\tcmpw\tREG_LoopCount,r3\n\tblt\tArmadaShineThink_RecoverStart_CollisionLoop_SkipDecay\nArmadaShineThink_RecoverStart_CollisionLoop_Decay:\n\tlfs\tf1,0x78(r5)\n\tfmuls\tf1,f1,REG_XComp\n\tlfs\tf2, 0x002C (REG_P2Data)\n\tfmuls\tf1,f1,f2\n\tfsubs\tREG_XPerFrame,REG_XPerFrame,f1\n\tlfs\tf1,0x78(r5)\n\tfmuls\tf1,f1,REG_YComp\n\tfsubs\tREG_YPerFrame,REG_YPerFrame,f1\nArmadaShineThink_RecoverStart_CollisionLoop_SkipDecay:\n#Store next position\n\tfadds\tf1,REG_CurrXPos,REG_XPerFrame\n\tstfs\tf1,0x4(REG_ECBStruct)\n\tfadds\tf1,REG_CurrYPos,REG_YPerFrame\n\tstfs\tf1,0x8(REG_ECBStruct)\n\tlfs\tf1,0x24(REG_ECBStruct)\n\tstfs\tf1,0xC(REG_ECBStruct)\n\tmr\tr3,REG_ECBStruct\n\tmr\tr4,REG_ECBBoneStruct\n\tbranchl\tr12,0x8004730c\n\tlfs\tREG_CurrXPos,0x4(REG_ECBStruct)\n\tlfs\tREG_CurrYPos,0x8(REG_ECBStruct)\n#Inc Loop\n\taddi\tREG_LoopCount,REG_LoopCount,1\n  lwz\tr5, 0x02D4 (REG_P2Data)\n  lfs\tf1, 0x0068 (r5)\n  fctiwz  f1,f1\n  stfd  f1,-0x10(sp)\n  lwz r3,-0x0C(sp)\n\tcmpw\tREG_LoopCount,r3\n\tblt\tArmadaShineThink_RecoverStart_CollisionLoop\n#End Loop\n\taddi\tsp,sp,0x1d0\n#endregion\n\n#Restore f28-f31\n\tlfs f29,0xB0(sp)\n\tlfs f30,0xB4(sp)\n\tlfs f31,0xB8(sp)\n\tlfs f28,0xBC(sp)\n\tlfs f27,0xC0(sp)\n\nArmadaShineThink_RecoverStart_Exit:\n\tb\tArmadaShineThink_Exit\n#endregion\n\n#region ArmadaShineThink_RecoverEnd\nArmadaShineThink_RecoverEnd:\n#If CPU got hit, recover again\n\tlbz\tr3,0x221C(REG_P2Data)\n\trlwinm. r3,r3,0,30,30\n\tbeq\tArmadaShineThink_Reset\n#Enter Hitstun state\n\tli\tr3,EventState_Hitstun\n\tstb\tr3,EventState(REG_EventData)\n\tb\tArmadaShineThink_Exit\n#endregion\n\n#region ArmadaShineThink_Reset\nArmadaShineThink_Reset:\n#Get timer\n\tlbz r3,Timer(REG_EventData)\n\tsubi r3,r3,1\n\tstb r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tble ArmadaShineThink_Restore\n\tb\tArmadaShineThink_Exit\n\n#endregion\n\nArmadaShineThink_Restore:\n#Restore State\n\taddi r3,REG_EventData,EventData_SaveStateStruct\n\tli\tr4,1\n\tbl\tSaveState_Load\n#Init Positions Again\n\tmr\tr3,REG_P1GObj\n\tmr\tr4,REG_P2GObj\n\tbl\tArmadaShine_InitializePositions\n#Reset Variables\n\tli\tr3,0\n\tstb r3,EventState(REG_EventData)\n\tstb r3,Timer(REG_EventData)\n\nArmadaShineThink_Exit:\n\trestore\n\tblr\n\nArmadaShineThink_Constants:\nblrl\n\n.set\tECB_TopY,0x0 #scale * value\n.set\tECB_BottomY,0x4 #neg(scale * vlaue)\n.set\tECB_LeftX,0x8 #neg(scale * vlaue)\n.set\tECB_LeftY,0xC #0\n.set\tECB_RightX,0x10 #scale * value\n.set\tECB_RightY,0x14 #0\n.set\tFinalAnimYDifference,0x18\n.float 9\n.float 2.5\n.float -3.3\n.float 5.7\n.float 3.3\n.float 5.7\n.float 0.4\n\nArmadaShine_InitializePositions:\nbackup\n\n.set LedgeSide,20\n\n#Constants\n.set ArmadaShine_P1X,15\n.set ArmadaShine_P1Y,6\n.set ArmadaShine_P2X,12\n.set ArmadaShine_P2Y,6\n.set HitlagFrames,12\n\n#Get random side\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n#Backup Ledge Side\n\tmr\tLedgeSide,r3\n\n#Change Facing Directions\n  cmpwi LedgeSide,0x0\n  beq\tArmadaShine_InitializePositions_GetLeftLedgeID\nArmadaShine_InitializePositions_GetRightLedgeID:\n #Change Facing Direction\n\tli\tr3,-1\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n  li\tr3,-1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\n\tb\tArmadaShine_InitializePositions_DirectionChangeEnd\nArmadaShine_InitializePositions_GetLeftLedgeID:\n#Change Facing Direction\n\tli\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P1Data)\n  li\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\nArmadaShine_InitializePositions_DirectionChangeEnd:\n\n#Get Ledge Coordinates\n\tmr\tr3,LedgeSide\n\taddi r4,sp,0x80\n\tbl\tGetLedgeCoordinates\n\n#Move P1\n\tli r3,ArmadaShine_P1X\n\tbl\tIntToFloat\n\tlfs f2,0x80(sp)\n\tlfs f3,0x2C(REG_P1Data)\n\tfmadds f1,f1,f3,f2\n\tstfs f1,0xB0(REG_P1Data)\n\tli r3,ArmadaShine_P1Y\n\tbl\tIntToFloat\n\tlfs f2,0x84(sp)\n\tfadds f1,f1,f2\n\tstfs f1,0xB4(REG_P1Data)\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdatePosition\n#Move P2\n\tli r3,ArmadaShine_P2X\n\tbl\tIntToFloat\n\tlfs f2,0x80(sp)\n\tlfs f3,0x2C(REG_P2Data)\n\tfmadds f1,f1,f3,f2\n\tstfs f1,0xB0(REG_P2Data)\n\tli r3,ArmadaShine_P2Y\n\tbl\tIntToFloat\n\tlfs f2,0x84(sp)\n\tfadds f1,f1,f2\n\tstfs f1,0xB4(REG_P2Data)\n\tmr\tr3,REG_P2GObj\n\tbl\tUpdatePosition\n#P1 enters Bair\n\tmr\tr3,REG_P1GObj\n\tli\tr4,ASID_AttackAirB\n\tbranchl r12,0x8008cfac\n#Fastforward to frame 7\n\tli\tr3,7\n\tbl\tIntToFloat\n\tmr\tr3,REG_P1GObj\n\tlfs\tf2, -0x67D8 (rtoc)\n\tlfs\tf3, -0x67E4 (rtoc)\n\tbranchl r12,0x8006ebe8\n\tli\tr3,7\n\tbl\tIntToFloat\n\tstfs f1,0x894(REG_P1Data)\n\tli\tr3,0\n\tstw r3,0x3E4(REG_P1Data)\n\tmr\tr3,REG_P1GObj\n\tbranchl r12,0x80073354\n#Update Animation\n\tmr\tr3,REG_P1GObj\n\tbranchl r12,0x8006e9b4\n#Remove all hitboxes\n\tmr\tr3,REG_P1GObj\n\tbranchl r12,0x8007aff8\n#Stop subaction script from being updated\n\tli\tr3,0\n\tstw r3,0x3EC(REG_P1Data)\n#Update Camera\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdateCameraBox\n\n#P2 enters DamageFlyN\n\tmr\tr3,REG_P2GObj\n\tli\tr4,ASID_DamageFlyN\n\tli\tr5,0x40\n\tli\tr6,0\n\tlfs\tf1, -0x750C (rtoc)\n\tlfs\tf2, -0x7508 (rtoc)\n\tlfs\tf3, -0x750C (rtoc)\n\tbranchl r12,ActionStateChange\n#Update Animation\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,0x8006e9b4\n#Remove Jump\n\tlwz r3,0x168(REG_P2Data)\n\tstb r3,0x1968(REG_P2Data)\n#Update Camera\n\tmr\tr3,REG_P2GObj\n\tbl\tUpdateCameraBox\n\n.set AngleLo,45\n.set AngleHi,60\n.set MagLo,106\n.set MagHi,120\n#Enter into knockback\n\tmr\tr3,REG_P2GObj\n\tli\tr4,AngleLo\n\tli\tr5,AngleHi\n\tli\tr6,MagLo\n\tli\tr7,MagHi\n\tbl\tEnterKnockback\n\n#Give 7 Frames of Hitlag to Each\n\tli\tr3,HitlagFrames\n\tbl\tIntToFloat\n\tstfs f1,0x195C(REG_P1Data)\n\tlbz r0,0x221A(REG_P1Data)\n\tli\tr3,1\n\trlwimi r0,r3,5,26,26\n\tstb r0,0x221A(REG_P1Data)\n\tlbz r0,0x2219(REG_P1Data)\n\tli\tr3,1\n\trlwimi r0,r3,2,29,29\n\tstb r0,0x2219(REG_P1Data)\n\tli\tr3,HitlagFrames\n\tbl\tIntToFloat\n\tstfs f1,0x195C(REG_P2Data)\n\tlbz r0,0x221A(REG_P2Data)\n\tli\tr3,1\n\trlwimi r0,r3,5,26,26\n\tstb r0,0x221A(REG_P2Data)\n\tlbz r0,0x2219(REG_P2Data)\n\tli\tr3,1\n\trlwimi r0,r3,2,29,29\n\tstb r0,0x2219(REG_P2Data)\n\n#Random percent\n\tli\tr3,PercentHi-PercentLo\n\tbranchl r12,HSD_Randi\n\taddi r4,r3,PercentLo\n\tlbz r3,0xC(REG_P2Data)\n\tbranchl r12,PlayerBlock_SetDamage\n\nArmadaShine_InitializePositions_Exit:\n\trestore\n\tblr\n\n#endregion\n\n#region SideB Sweetspot\n###########################\n## SideB Sweetspot HIJACK INFO ##\n###########################\n\nSideBSweetspot:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Marth.Ext\n\tli\tr6,-1\t\t\t\t\t\t\t\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_SideBSweetspot\n\tli\tr8,0\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nSideBSweetspotStoreThink:\n\tbl\tSideBSweetspotLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## \t\t\tSideB Sweetspot LOAD FUNCT \t\t##\n##################################\nSideBSweetspotLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tSideBSweetspotThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\tb\tSideBSweetspotThink_Exit\n\n###################################\n## SideB Sweetspot THINK FUNCT ##\n###################################\n\nSideBSweetspotThink:\n\tblrl\n\n#Registers\n\t.set REG_EventConstants,25\n  .set REG_MenuData,26\n  .set REG_EventData,31\n  .set REG_P1Data,27\n  .set REG_P1GObj,28\n\t.set REG_P2Data,29\n\t.set REG_P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set EventState_Endlag,0x0\n\t\t.set EventState_WaitToAttack,0x1\n\t\t.set EventState_AttackThink,0x2\n\t\t.set EventState_Reset,0x3\n\t.set Timer,0x1\n\t.set ThrowTimer,0x2\n\t.set JabFrame,0x4\n\n#Constants\n\t.set ResetTimer,30\n\t.set AngleLo,45\n\t.set AngleHi,60\n\t.set MagLo,106#106\n\t.set MagHi,135#120\n\t.set PercentHi,100\n\t.set PercentLo,50\n\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tlwz\tREG_EventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n#Get Player Pointers\n  bl GetAllPlayerPointers\n  mr REG_P1GObj,r3\n  mr REG_P1Data,r4\n  mr REG_P2GObj,r5\n  mr REG_P2Data,r6\n\n#Get Menu and Constants Pointers\n  lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData)\n\tbl\tSideBSweetspotThink_Constants\n\tmflr REG_EventConstants\n\n\tbl\tStoreCPUTypeAndZeroInputs\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tSideBSweetspotThink_Start\n\t#Init Positions\n\t\tmr\tr3,REG_P1GObj\n\t\tmr\tr4,REG_P2GObj\n\t\tmr\tr5,REG_EventData\n\t\tbl\tSideBSweetspot_InitializePositions\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\nSideBSweetspotThink_Start:\n\n#P2 intangible\n\tmr\tr3,P2GObj\n\tli\tr4,1\n\tbranchl r12,ApplyIntangibility\n\n#Reset if anyone died\n\tbl\tIsAnyoneDead\n\tcmpwi r3,0\n\tbne SideBSweetspotThink_Restore\n\nSideBSweetspotThink_Crouch:\n#Always hold crouch when state is higher than EventState_Endlag\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_Endlag\n\tble SideBSweetspotThink_CrouchSkip\n#Input crouch\n\tli\tr3,-127\n\tstb r3,CPU_AnalogY(REG_P2Data)\nSideBSweetspotThink_CrouchSkip:\n\nSideBSweetspotThink_SwitchCase:\n#Switch Case\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_Endlag\n\tbeq SideBSweetspotThink_Endlag\n\tcmpwi r3,EventState_WaitToAttack\n\tbeq SideBSweetspotThink_WaitToAttack\n\tcmpwi r3,EventState_AttackThink\n\tbeq SideBSweetspotThink_AttackThink\n\tcmpwi r3,EventState_Reset\n\tbeq SideBSweetspotThink_Reset\n\tb\tSideBSweetspotThink_CheckTimer\n\n#region SideBSweetspotThink_Endlag\nSideBSweetspotThink_Endlag:\n#Check if in Wait\n\tlwz r3,0x10(P2Data)\n\tcmpwi r3,ASID_Wait\n\tbne SideBSweetspotThink_CheckTimer\n#Input Crouch\n\tli\tr3,-127\n\tstb r3,CPU_AnalogY(REG_P2Data)\n#Change state to attack\n\tli\tr3,EventState_WaitToAttack\n\tstb\tr3,EventState(EventData)\n\tb\tSideBSweetspotThink_CheckTimer\n\n#endregion\n\n#region SideBSweetspotThink_WaitToAttack\nSideBSweetspotThink_WaitToAttack:\n#Wait for Fox to be in SpecialAirS\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,0x15F\n\tbne SideBSweetspotThink_WaitToAttackSkip\n#Input Dtilt\n\tli\tr3,PAD_BUTTON_A\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n\tli\tr3,-38\n\tstb r3,CPU_AnalogY(REG_P2Data)\n#Advance State\n\tli\tr3,EventState_AttackThink\n\tstb r3,EventState(REG_EventData)\n\tb\tSideBSweetspotThink_CheckTimer\nSideBSweetspotThink_WaitToAttackSkip:\n\n#Check if fox up-b'd\n\tcmpwi r3,0x162\n\tbeq SideBSweetspotThink_WaitToAttack_BlacklistMove\n\tcmpwi r3,ASID_EscapeAir\n\tbeq SideBSweetspotThink_WaitToAttack_BlacklistMove\n\tb\tSideBSweetspotThink_WaitToAttack_CheckForBlacklistMovesSkip\nSideBSweetspotThink_WaitToAttack_BlacklistMove:\n#PLay Error SFX\n  li\tr3,0xAF\n  bl  PlaySFX\n#Start Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n#Advance State\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n\tb\tSideBSweetspotThink_CheckTimer\nSideBSweetspotThink_WaitToAttack_CheckForBlacklistMovesSkip:\n#endregion\n\n#region SideBSweetspotThink_AttackThink\nSideBSweetspotThink_AttackThink:\n#Check if d-tilting\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_AttackLw3\n\tbne SideBSweetspotThink_CheckTimer\n#Check if frame 7\n\tli\tr3,7\n\tbl\tIntToFloat\n\tlfs f2,0x894(REG_P2Data)\n\tfcmpo cr0,f1,f2\n\tbne SideBSweetspotThink_AttackThink_FreezeSkip\n#Check if already frozen\n\tli\tr3,0\n\tbl\tIntToFloat\n\tlfs f2,0x89C(REG_P2Data)\n\tfcmpo cr0,f1,f2\n\tbeq SideBSweetspotThink_AttackThink_FreezeCheckToUnfreeze\n#Freeze\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,FrameSpeedChange\n\tb\tSideBSweetspotThink_AttackThink_FreezeSkip\nSideBSweetspotThink_AttackThink_FreezeCheckToUnfreeze:\n#Check if player was hit\n\tlwz r3,0x2094(REG_P2Data)\n\tcmpwi r3,0\n\tbeq SideBSweetspotThink_AttackThink_FreezeSkip\n#Unfreeze\n\tli\tr3,1\n\tbl\tIntToFloat\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,FrameSpeedChange\n#Start Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n#Advance State\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n\tb\tSideBSweetspotThink_CheckTimer\nSideBSweetspotThink_AttackThink_FreezeSkip:\n\n#Check if P1 grabbed ledge successfully\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_CliffCatch\n\tbne SideBSweetspotThink_AttackThink_CliffCatchSkip\n#Play Success SFX\n\tli\tr3,0xAD\n\tbl\tPlaySFX\n#Unfreeze P2\n\tli\tr3,1\n\tbl\tIntToFloat\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,FrameSpeedChange\n#Start Timer\n\tli\tr3,ResetTimer+30\n\tstb r3,Timer(REG_EventData)\n#Advance State\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n\tb\tSideBSweetspotThink_CheckTimer\nSideBSweetspotThink_AttackThink_CliffCatchSkip:\n\n#endregion\n\n#region SideBSweetspotThink_Reset\nSideBSweetspotThink_Reset:\n\tb\tSideBSweetspotThink_CheckTimer\n#endregion\n\nSideBSweetspotThink_CheckTimer:\n#Check if timer exists\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tble SideBSweetspotThink_Exit\n#Decrement timer\n\tsubi r3,r3,1\n\tstb r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt SideBSweetspotThink_Exit\n\nSideBSweetspotThink_Restore:\n#Restore State\n\taddi r3,REG_EventData,EventData_SaveStateStruct\n\tli\tr4,1\n\tbl\tSaveState_Load\n#Init Positions Again\n\tmr\tr3,REG_P1GObj\n\tmr\tr4,REG_P2GObj\n\tmr\tr5,REG_EventData\n\tbl\tSideBSweetspot_InitializePositions\n\nSideBSweetspotThink_Exit:\n\trestore\n\tblr\n\n################################\n\nSideBSweetspotThink_Constants:\nblrl\n.set P1X,0x0\n.set P1Y,0x4\n.set P2X,0x8\n.set P2Y,0xC\n.set GrabDistance,0x10\n.set HoldShieldVelocity,0x14\n.set RunDistance,0x18\n\n.float -8\t\t#p1 x\n.float  0\t\t#p1 y\n.float  8\t\t#p2 x\n.float  0\t\t#p2 y\n.float 14\t\t#16\n.float 1.1\n.float 23\n###########################################\n\nSideBSweetspot_InitializePositions:\nbackup\n\n.set REG_P1GObj,30\n.set REG_P1Data,29\n.set REG_P2GObj,28\n.set REG_P2Data,27\n.set REG_EventData,26\n.set LedgeSide,20\n\n#Constants\n.set SideBSweet_P1X,-12\n.set SideBSweet_P1Y,6\n.set SideBSweet_P2X,15\n.set SideBSweet_P2Y,0\n.set HitlagFrames,12\n\n#Init Registers\n  mr\tREG_P1GObj,r3\n  lwz REG_P1Data,0x2C(REG_P1GObj)\n  mr\tREG_P2GObj,r4\n  lwz REG_P2Data,0x2C(REG_P2GObj)\n\tmr\tREG_EventData,r5\n\n#Get random side\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n#Backup Ledge Side\n\tmr\tLedgeSide,r3\n\n#Change Facing Directions\n  cmpwi LedgeSide,0x0\n  beq\tSideBSweet_InitializePositions_GetLeftLedgeID\nSideBSweet_InitializePositions_GetRightLedgeID:\n #Change Facing Direction\n\tli\tr3,-1\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n  li\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\n\tb\tSideBSweet_InitializePositions_DirectionChangeEnd\nSideBSweet_InitializePositions_GetLeftLedgeID:\n#Change Facing Direction\n\tli\tr3,1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P1Data)\n  li\tr3,-1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\nSideBSweet_InitializePositions_DirectionChangeEnd:\n\n#Get Ledge Coordinates\n\tmr\tr3,LedgeSide\n\taddi r4,sp,0x80\n\tbl\tGetLedgeCoordinates\n\n#Move P1\n\tli r3,SideBSweet_P1X\n\tbl\tIntToFloat\n\tlfs f2,0x80(sp)\n\tlfs f3,0x2C(REG_P1Data)\n\tfmadds f1,f1,f3,f2\n\tstfs f1,0xB0(REG_P1Data)\n\tli r3,SideBSweet_P1Y\n\tbl\tIntToFloat\n\tlfs f2,0x84(sp)\n\tfadds f1,f1,f2\n\tstfs f1,0xB4(REG_P1Data)\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdatePosition\n#Move P2\n\tli r3,SideBSweet_P2X\n\tbl\tIntToFloat\n\tlfs f2,0x80(sp)\n\tlfs f3,0x2C(REG_P2Data)\n\tfneg f3,f3\n\tfmadds f1,f1,f3,f2\n\tstfs f1,0xB0(REG_P2Data)\n\tli r3,SideBSweet_P2Y\n\tbl\tIntToFloat\n\tlfs f2,0x84(sp)\n\tfadds f1,f1,f2\n\tstfs f1,0xB4(REG_P2Data)\n\tmr\tr3,REG_P2GObj\n\tbl\tPlacePlayerOnGround\n#Clear P2's GFX Pointer\n\tli\tr3,0\n\tstw r3,0x60C(REG_P2Data)\n#P2 enters FSmash\n\tli\tr3,0\n\tbl\tIntToFloat\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,0x8008c3e0\n#Fastforward to frame 11\n\tli\tr3,11\n\tbl\tIntToFloat\n\tmr\tr3,REG_P2GObj\n\tlfs\tf2, -0x67D8 (rtoc)\n\tlfs\tf3, -0x67E4 (rtoc)\n\tbranchl r12,0x8006ebe8\n\tli\tr3,7\n\tbl\tIntToFloat\n\tstfs f1,0x894(REG_P2Data)\n\tli\tr3,0\n\tstw r3,0x3E4(REG_P2Data)\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,0x80073354\n#Update Animation\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,0x8006e9b4\n#Remove all hitboxes\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,0x8007aff8\n#Stop subaction script from being updated\n\tli\tr3,0\n\tstw r3,0x3EC(REG_P2Data)\n#Update Camera\n\tmr\tr3,REG_P2GObj\n\tbl\tUpdateCameraBox\n\n#P1 enters DamageFlyN\n\tmr\tr3,REG_P1GObj\n\tli\tr4,ASID_DamageFlyN\n\tli\tr5,0x40\n\tli\tr6,0\n\tlfs\tf1, -0x750C (rtoc)\n\tlfs\tf2, -0x7508 (rtoc)\n\tlfs\tf3, -0x750C (rtoc)\n\tbranchl r12,ActionStateChange\n#Update Animation\n\tmr\tr3,REG_P1GObj\n\tbranchl r12,0x8006e9b4\n#Remove Jump\n\t#lwz r3,0x168(REG_P1Data)\n\t#stb r3,0x1968(REG_P1Data)\n#Update Camera\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdateCameraBox\n\n#Enter into knockback\n\tmr\tr3,REG_P1GObj\n\tli\tr4,AngleLo\n\tli\tr5,AngleHi\n\tli\tr6,MagLo\n\tli\tr7,MagHi\n\tbl\tEnterKnockback\n\n#Give 7 Frames of Hitlag to Each\n\tli\tr3,HitlagFrames\n\tbl\tIntToFloat\n\tstfs f1,0x195C(REG_P1Data)\n\tlbz r0,0x221A(REG_P1Data)\n\tli\tr3,1\n\trlwimi r0,r3,5,26,26\n\tstb r0,0x221A(REG_P1Data)\n\tlbz r0,0x2219(REG_P1Data)\n\tli\tr3,1\n\trlwimi r0,r3,2,29,29\n\tstb r0,0x2219(REG_P1Data)\n\tli\tr3,HitlagFrames\n\tbl\tIntToFloat\n\tstfs f1,0x195C(REG_P2Data)\n\tlbz r0,0x221A(REG_P2Data)\n\tli\tr3,1\n\trlwimi r0,r3,5,26,26\n\tstb r0,0x221A(REG_P2Data)\n\tlbz r0,0x2219(REG_P2Data)\n\tli\tr3,1\n\trlwimi r0,r3,2,29,29\n\tstb r0,0x2219(REG_P2Data)\n\n#Random percent\n\tli\tr3,PercentHi-PercentLo\n\tbranchl r12,HSD_Randi\n\taddi r4,r3,PercentLo\n\tlbz r3,0xC(REG_P1Data)\n\tbranchl r12,PlayerBlock_SetDamage\n\n#Reset Variables\n\tli\tr3,EventState_ThrowDelay\n\tstb r3,EventState(REG_EventData)\n\tli\tr3,0\n\tstb r3,Timer(REG_EventData)\nSideBSweetspot_InitializePositions_Exit:\n\trestore\n\tblr\n\n#endregion\n\n#region Escape Sheik\n###########################\n## Escape Sheik HIJACK INFO ##\n###########################\n\nEscapeSheik:\n#Store Stage, CPU, and FDD Toggles\n\tlwz r3,0x0(r29)\t\t\t\t\t\t\t\t\t\t#Send event struct\n\tmr\tr4,r26\t\t\t\t\t\t\t\t\t\t\t\t#Send match struct\n\tli\tr5,Sheik.Ext\n\tli\tr6,FinalDestination\t\t\t\t\t\t#Use chosen Stage\n\tload r7,EventOSD_EscapeSheik\n\tli\tr8,1\t\t\t\t\t\t\t\t\t\t#Use Sopo bool\n\tbl\tInitializeMatch\n\n#STORE THINK FUNCTION\nEscapeSheikStoreThink:\n\tbl\tEscapeSheikLoad\n\tmflr\tr3\n\tstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n##################################\n## \t\t\tEscape Sheik LOAD FUNCT \t\t##\n##################################\nEscapeSheikLoad:\n\tblrl\n\n\tbackup\n\n#Schedule Think\n\tbl\tEscapeSheikThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After EnvCOllision)\n  li  r5,0\n\tbl\tCreateEventThinkFunction\n\tb\tEscapeSheikThink_Exit\n\n###################################\n## Escape Sheik THINK FUNCT ##\n###################################\n\nEscapeSheikThink:\n\tblrl\n\n#Registers\n\t.set REG_EventConstants,25\n  .set REG_MenuData,26\n  .set REG_EventData,31\n  .set REG_P1Data,27\n  .set REG_P1GObj,28\n\t.set REG_P2Data,29\n\t.set REG_P2GObj,30\n\n#Event Data Offsets\n\t.set EventState,0x0\n\t\t.set EventState_ThrowDelay,0x0\n\t\t.set EventState_ThrowEndlag,0x1\n\t\t.set EventState_Chase,0x2\n\t\t.set EventState_Jab2,0x3\n\t\t.set EventState_Reset,0x4\n\t.set\tTimer,0x1\n\t.set\tThrowTimer,0x2\n\t.set\tJabFrame,0x4\n\t.set\tisJabTwice,0x5\n\t.set\tJab2Frame,0x6\n\t.set\tJab2Timer,0x7\n\t.set\tisDisplayedTiming,0x8\n\n#Constants\n\t.set ResetTimer,40\n\t.set PercentLo,0\n\t.set PercentHi,40\n\t.set ThrowTimerLo,30\n\t.set ThrowTimerHi,60\n\t.set ReactFrame,12\n\t.set JabFrameLo,15\n\t.set JabFrameHi,20\n\t.set Jab2FrameLo,6\n\t.set Jab2FrameHi,18\n\nbackup\n\n#INIT FUNCTION VARIABLES\n\tlwz\tREG_EventData,0x2c(r3)\t\t\t#backup data pointer in r31\n\n#Get Player Pointers\n  bl GetAllPlayerPointers\n  mr REG_P1GObj,r3\n  mr REG_P1Data,r4\n  mr REG_P2GObj,r5\n  mr REG_P2Data,r6\n\n#Get Menu and Constants Pointers\n  lwz REG_MenuData,REG_EventData_REG_MenuDataPointer(REG_EventData)\n\tbl\tEscapeSheikThink_Constants\n\tmflr REG_EventConstants\n\n\tbl\tStoreCPUTypeAndZeroInputs\n\n#ON FIRST FRAME\n\tbl\tCheckIfFirstFrame\n\tcmpwi\tr3,0x0\n\tbeq\tEscapeSheikThink_Start\n\t#Init Positions\n\t\tmr\tr3,REG_P1GObj\n\t\tmr\tr4,REG_P2GObj\n\t\tmr\tr5,REG_EventData\n\t\tbl\tEscapeSheik_InitializePositions\n  #Clear Inputs\n    bl  RemoveFirstFrameInputs\n\t#Save State\n  \taddi r3,REG_EventData,EventData_SaveStateStruct\n\t\tli\tr4,1\t\t\t#Override failsafe code\n  \tbl\tSaveState_Save\nEscapeSheikThink_Start:\n\n#Reset if anyone died\n\tbl\tIsAnyoneDead\n\tcmpwi r3,0\n\tbne EscapeSheikThink_Restore\n\nEscapeSheikThink_CheckIfFailed:\n#Check if failed the Escape Sheik (grabbed))\n#EventState > EventState_Hitstun\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_Chase\n\tblt EscapeSheikThink_CheckIfFailed_End\n#Check if grabbed\n\tlwz r3,0x10(P1Data)\n\tcmpwi r3,ASID_CapturePulledHi\n\tblt EscapeSheikThink_CheckIfFailed_End\n\tcmpwi r3,ASID_CaptureFoot\n\tbgt EscapeSheikThink_CheckIfFailed_End\n#Check if timer has started\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt EscapeSheikThink_CheckIfFailed_End\n#Start Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\nEscapeSheikThink_CheckIfFailed_End:\n\nEscapeSheikThink_CheckIfCPUDamaged:\n\tlwz\tr3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_DamageHi1\n\tblt\tEscapeSheikThink_CheckIfCPUDamaged_End\n\tcmpwi r3,ASID_DamageFlyRoll\n\tbgt\tEscapeSheikThink_CheckIfCPUDamaged_End\n#Check if timer has started\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt EscapeSheikThink_CheckIfCPUDamaged_End\n#Start Timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n#Play Success Sound?\n#Maybe increment a high score or something idk\nEscapeSheikThink_CheckIfCPUDamaged_End:\n\nEscapeSheikThink_CheckForMistimedShine:\n#Check if event state is in chase\n\tlbz\tr3,EventState(REG_EventData)\n\tcmpwi\tr3,EventState_Chase\n\tblt\tEscapeSheikThink_CheckForMistimedShine_End\n#Check if displayed already\n\tlbz\tr3,isDisplayedTiming(REG_EventData)\n\tcmpwi\tr3,0\n\tbne\tEscapeSheikThink_CheckForMistimedShine_End\n#Get this frames inputs\n  lbz\tr4, 0x0618 (REG_P1Data)\n  bl\tGetInputStruct\n\tmr\tr5,r3\n#Check B Button\n\tlwz\tr3,InputStruct_InstantButtons(r5)\n\trlwinm.\tr0,r3,0,22,22\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_End\n#Check if pushing down\n\tlbz\tr3,InputStruct_LeftAnalogY(r5)\n\textsb\tr3,r3\n\tcmpwi\tr3,-44\n\tbgt\tEscapeSheikThink_CheckForMistimedShine_End\n#Check if in any missed tech state\n\tlwz\tr3,0x10(REG_P1Data)\n\tcmpwi\tr3,ASID_Passive\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Early\n\tcmpwi\tr3,ASID_PassiveStandB\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Early\n\tcmpwi\tr3,ASID_PassiveStandF\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Early\n#Check if being grabbed\n\tcmpwi\tr3,ASID_CapturePulledLw\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Late\n\tcmpwi\tr3,ASID_CapturePulledHi\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Late\n\tcmpwi\tr3,ASID_CaptureWaitLw\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Late\n\tcmpwi\tr3,ASID_CaptureWaitHi\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_Late\n\tb\tEscapeSheikThink_CheckForMistimedShine_End\n.set\tREG_String,20\n.set\tREG_Frames,21\nEscapeSheikThink_CheckForMistimedShine_Early:\n#Get early string\n\tbl\tEscapeSheikThink_EarlyText\n\tmflr\tREG_String\n#Get frames early\n\tmr\tr3,REG_P1Data\n\tlwz\tr4,0x14(REG_P1Data)\n\tbranchl\tr12,0x80085e50\n\tlfs\tf1,0x8(r3)\n\tfctiwz\tf1,f1\n\tstfd\tf1,0x80(sp)\n\tlwz\tr3,0x84(sp)\n\tlhz\tr4,TM_FramesinCurrentAS(REG_P1Data)\n\tsub\tREG_Frames,r3,r4\n\tb\tEscapeSheikThink_CheckForMistimedShine_Display\nEscapeSheikThink_CheckForMistimedShine_Late:\n#Get late string\n\tbl\tEscapeSheikThink_LateText\n\tmflr\tREG_String\n#Get frames late\nEscapeSheikThink_CheckForMistimedShine_LateSearchInitLoop:\n.set\tREG_Count,22\n\tli\tREG_Count,0\n\tlhz\tREG_Frames,TM_FramesinCurrentAS(REG_P1Data)\nEscapeSheikThink_CheckForMistimedShine_LateSearchLoop:\n#Get previous action state\n\taddi\tr3,REG_P1Data,TM_PrevASStart\n\tmulli\tr4,REG_Count,0x2\n\tadd\tr5,r3,r4\n#Check if wait\n\tlhz\tr3,0x0(r5)\n\tcmpwi\tr3,ASID_Wait\n\tbeq\tEscapeSheikThink_CheckForMistimedShine_LateSearchFoundWait\n#Add frames spent in this state\n\tlhz\tr3,0xC(r5)\n\tadd\tREG_Frames,REG_Frames,r3\nEscapeSheikThink_CheckForMistimedShine_LateSearchIncLoop:\n\taddi\tREG_Count,REG_Count,1\n\tcmpwi\tREG_Count,6\n\tblt\tEscapeSheikThink_CheckForMistimedShine_LateSearchLoop\n\tb\tEscapeSheikThink_CheckForMistimedShine_End\n\nEscapeSheikThink_CheckForMistimedShine_LateSearchFoundWait:\n\nEscapeSheikThink_CheckForMistimedShine_Display:\n#Output reaction time\n\tmr\tr3,REG_P1Data\t\t#p1 (no offsetting window)\n\tli\tr4,120\t\t\t\t\t#text timeout\n\tli\tr5,0\t\t\t\t\t\t#Area to Display (0-2)\n\tli\tr6,OSD.Miscellaneous\t\t\t#Window ID (Unique to This Display)\n\tbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\n\tmr\tr22,r3\t\t\t#backup text pointer\n\n#Create Text 1\n\tmr \tr3,r22\t\t\t#text pointer\n\tbl\tEscapeSheikThink_TopText\n\tmflr\tr4\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tbranchl r12,Text_InitializeSubtext\n#Create Text 2\n\tmr \tr3,r22\t\t\t#text pointer\n\tbl\tEscapeSheikThink_BottomText\n\tmflr\tr4\n\tmr\tr5,REG_Frames\n\tmr\tr6,REG_String\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#default text X/Y\n\tbranchl r12,Text_InitializeSubtext\n#Set as displayed\n\tli\tr3,1\n\tstb\tr3,isDisplayedTiming(REG_EventData)\nEscapeSheikThink_CheckForMistimedShine_End:\n\nEscapeSheikThink_SwitchCase:\n#Switch Case\n\tlbz r3,EventState(REG_EventData)\n\tcmpwi r3,EventState_ThrowDelay\n\tbeq EscapeSheikThink_ThrowDelay\n\tcmpwi r3,EventState_ThrowEndlag\n\tbeq EscapeSheikThink_ThrowEndlag\n\tcmpwi r3,EventState_Chase\n\tbeq EscapeSheikThink_Chase\n\tcmpwi r3,EventState_Reset\n\tbeq EscapeSheikThink_Reset\n\tcmpwi\tr3,EventState_Jab2\n\tbeq\tEscapeSheikThink_Jab2\n\tb\tEscapeSheikThink_CheckTimer\n\n#region EscapeSheikThink_ThrowDelay\nEscapeSheikThink_ThrowDelay:\n#Check to throw\n\tlhz r3,ThrowTimer(REG_EventData)\n\tsubi r3,r3,1\n\tsth r3,ThrowTimer(REG_EventData)\n\tcmpwi r3,0\n\tbgt EscapeSheikThink_CheckTimer\n#Input DThrow\n\tli\tr3,-127\n\tstb r3,CPU_AnalogY(REG_P2Data)\n#Change state to attack\n\tli\tr3,EventState_ThrowEndlag\n\tstb\tr3,EventState(EventData)\n\tb\tEscapeSheikThink_CheckTimer\n\n#endregion\n\n#region EscapeSheikThink_ThrowEndlag\nEscapeSheikThink_ThrowEndlag:\n#Wait for Sheik to be out of ThrowLw\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_Wait\n\tbne EscapeSheikThink_CheckTimer\n#Wait for P1 to be in their tech option\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_Passive\n\tblt EscapeSheikThink_ThrowEndlag_CheckMissTech\n\tcmpwi r3,ASID_PassiveStandB\n\tble EscapeSheikThink_ThrowEndlag_End\nEscapeSheikThink_ThrowEndlag_CheckMissTech:\n\tcmpwi r3,ASID_DownBoundD\n\tbeq EscapeSheikThink_ThrowEndlag_End\n\tcmpwi r3,ASID_DownBoundU\n\tbeq EscapeSheikThink_ThrowEndlag_End\n\tb\tEscapeSheikThink_CheckTimer\nEscapeSheikThink_ThrowEndlag_End:\n#Advance State\n\tli\tr3,EventState_Chase\n\tstb r3,EventState(REG_EventData)\n\tb\tEscapeSheikThink_Chase\n\n#endregion\n\n#region EscapeSheikThink_Chase\nEscapeSheikThink_Chase:\n.set Distance,0xB0\n.set REG_Direction,20\n#Get Distance\n\tlfs f1,0xB0(REG_P2Data)\n\tlfs f2,0xB0(REG_P1Data)\n\tfsubs f1,f2,f1\n\tlfs f2,0x2C(REG_P2Data)\n\tfmuls f1,f1,f2\n\tstfs f1,Distance(sp)\n#Get Direction\n\tli\tr3,0\n\tbl\tIntToFloat\n\tlfs f2,Distance(sp)\n\tfcmpo cr0,f2,f1\n\tblt 0xC\n\tli\tREG_Direction,1\n\tb\t0x8\n\tli\tREG_Direction,-1\n\n#Determine Tech Option\n\tlwz r3,0x10(REG_P1Data)\n\tcmpwi r3,ASID_DownBoundD\n\tbeq EscapeSheikThink_Chase_DownBoundThink\n\tcmpwi r3,ASID_DownBoundU\n\tbeq EscapeSheikThink_Chase_DownBoundThink\n#Now only run these when over frame 12\n\tlhz r4,TM_FramesinCurrentAS(REG_P1Data)\n\tcmpwi r4,ReactFrame\n\tblt EscapeSheikThink_CheckTimer\n\tcmpwi r3,ASID_Passive\n\tbeq EscapeSheikThink_Chase_PassiveThink\n\tcmpwi r3,ASID_PassiveStandB\n\tbeq EscapeSheikThink_Chase_PassiveStandThink\n\tcmpwi r3,ASID_PassiveStandF\n\tbeq EscapeSheikThink_Chase_PassiveStandThink\n\tb\tEscapeSheikThink_CheckTimer\n\nEscapeSheikThink_Chase_PassiveThink:\n#Check if facing P1\n\tcmpwi REG_Direction,0\n\tbgt EscapeSheikThink_Chase_PassiveThink_FacingSkip\n#Input slightly towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,100\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_PassiveThink_FacingSkip:\n#Check distance (if over 16 units, walk towards)\n\tlfs f1,GrabDistance(REG_EventConstants)\n\tlfs f2,Distance(sp)\n\tfabs f2,f2\n\tfcmpo cr0,f2,f1\n\tble EscapeSheikThink_Chase_PassiveThink_RunTowardsSkip\n#If over 24 units, run towards\n\tlfs f1,RunDistance(REG_EventConstants)\n\tfcmpo cr0,f2,f1\n\tbgt\tEscapeSheikThink_Chase_PassiveThink_RunTowards\nEscapeSheikThink_Chase_PassiveThink_WalkTowards:\n#Walk Towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,100\n\tstb r3,CPU_AnalogX(REG_P2Data)\n\tb\tEscapeSheikThink_Chase_PassiveThink_RunTowardsSkip\nEscapeSheikThink_Chase_PassiveThink_RunTowards:\n#Run Towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,127\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_PassiveThink_RunTowardsSkip:\n#Check distance\n\tlfs f1,GrabDistance(REG_EventConstants)\n\tlfs f2,Distance(sp)\n\tfabs f2,f2\n\tfcmpo cr0,f2,f1\n\tbgt EscapeSheikThink_Chase_PassiveThink_HoldShieldSkip\n#Check State\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_Dash\n\tbeq EscapeSheikThink_Chase_PassiveThink_HoldShield\n\tcmpwi r3,ASID_Run\n\tbeq EscapeSheikThink_Chase_PassiveThink_HoldShield\n\tb\tEscapeSheikThink_Chase_PassiveThink_HoldShieldSkip\nEscapeSheikThink_Chase_PassiveThink_HoldShield:\n#Enter shield\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,AS_Guard\n#And hold\n\tli\tr3,PAD_TRIGGER_R\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n\tb\tEscapeSheikThink_Chase_PassiveThink_HoldShieldSkip\nEscapeSheikThink_Chase_PassiveThink_HoldShieldSkip:\n#Now grab when P1 is on frame 20\n\tlhz r3,TM_FramesinCurrentAS(REG_P1Data)\n\tcmpwi r3,20\n\tblt EscapeSheikThink_CheckTimer\n#Enter grab\n\tmr\tr3,REG_P2GObj\n\tli\tr4,0xD4\n\tbranchl r12,AS_Catch\n#Advance state\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n#Start timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n\tb\tEscapeSheikThink_CheckTimer\n\nEscapeSheikThink_Chase_PassiveStandThink:\n#Check if facing P1\n\tcmpwi REG_Direction,0\n\tbgt EscapeSheikThink_Chase_PassiveStandThink_FacingSkip\n#BUT is he coming to me?\n\tlfs f2,0xC8(REG_P1Data)\n\tli\tr3,0\n\tbl\tIntToFloat\n\tli\tr3,1\t\t#Moving Right\n\tfcmpo cr0,f2,f1\n\tbgt 0x8\n\tli\tr3,-1\t\t#Moving Left\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r4,0x84(sp)\n\tmullw r4,r4,REG_Direction\n\tcmpw r3,r4\n\tbne  EscapeSheikThink_Chase_PassiveStandThink_FacingSkip\n#If under frame 20, run instead\n\tli\tr5,127\n\tlhz r3,TM_FramesinCurrentAS(REG_P1Data)\n\tcmpwi r3,20\n\tblt 0x8\n\tli\tr5,100\n#Input slightly towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmullw r3,r3,r5\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_PassiveStandThink_FacingSkip:\n#Check distance (if over 16 units, run towards)\n\tlfs f1,GrabDistance(REG_EventConstants)\n\tlfs f2,Distance(sp)\n\tfabs f2,f2\n\tfcmpo cr0,f2,f1\n\tble EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip\n#Wait until no longer turning\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_Turn\n\tbne  EscapeSheikThink_Chase_PassiveStandThink_RunTowardCheckMovementDirection\n#If turning, wait til frame 2 to make a decision\n\tlhz r3,TM_FramesinCurrentAS(REG_P2Data)\n\tcmpwi r3,2\n\tbge EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip\nEscapeSheikThink_Chase_PassiveStandThink_RunTowardCheckMovementDirection:\n#BUT is he coming to me?\n\tlfs f2,0xC8(REG_P1Data)\n\tli\tr3,0\n\tbl\tIntToFloat\n\tli\tr3,1\t\t#Moving Right\n\tfcmpo cr0,f2,f1\n\tbgt 0x8\n\tli\tr3,-1\t\t#Moving Left\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r4,0x84(sp)\n\tmullw r4,r4,REG_Direction\n\tcmpw r3,r4\n\tbne  EscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip\nEscapeSheikThink_Chase_PassiveStandThink_RunTowards:\n#Run Towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,127\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_PassiveStandThink_RunTowardsSkip:\n#If and within range and running, hold shield\n#Check distance\n\tlfs f1,GrabDistance(REG_EventConstants)\n\tlfs f2,Distance(sp)\n\tfabs f2,f2\n\tfcmpo cr0,f2,f1\n\tbgt EscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip\n\tlwz r3,0x10(REG_P2Data)\n\tcmpwi r3,ASID_Dash\n\tbeq EscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckFrame\n\tcmpwi r3,ASID_Run\n\tbeq EscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckFrame\n\tb\tEscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip\nEscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckFrame:\n\tlhz r3,TM_FramesinCurrentAS(REG_P1Data)\n\tcmpwi r3,28\n\tbge EscapeSheikThink_Chase_PassiveStandThink_HoldShield\nEscapeSheikThink_Chase_PassiveStandThink_HoldShieldCheckVelocity:\n#Allow to hold shield earlier than usual if the character isnt moving very far\n\tlfs f1,0xC8(REG_P1Data)\n\tfabs f1,f1,\n\tlfs f2,HoldShieldVelocity(REG_EventConstants)\n\tfcmpo cr0,f1,f2\n\tbgt EscapeSheikThink_Chase_PassiveStandThink_HoldShieldRunInstead\nEscapeSheikThink_Chase_PassiveStandThink_HoldShield:\n#Enter shield\n\tmr\tr3,REG_P2GObj\n\tbranchl r12,AS_Guard\n#And hold\n\tli\tr3,PAD_TRIGGER_R\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n\tb\tEscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip\nEscapeSheikThink_Chase_PassiveStandThink_HoldShieldRunInstead:\n#Run Towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,127\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_PassiveStandThink_HoldShieldSkip:\n#Now grab when P1 is on frame 34\n\tlhz r3,TM_FramesinCurrentAS(REG_P1Data)\n\tcmpwi r3,34\n\tblt EscapeSheikThink_CheckTimer\n#Enter grab\n\tmr\tr3,REG_P2GObj\n\tli\tr4,0xD4\n\tbranchl r12,AS_Catch\n#Advance state\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n#Start timer\n\tli\tr3,ResetTimer\n\tstb r3,Timer(REG_EventData)\n\tb\tEscapeSheikThink_CheckTimer\n\n\nEscapeSheikThink_Chase_DownBoundThink:\n#Determine jab frame\n\tlbz r3,JabFrame(REG_EventData)\n\tcmpwi r3,0\n\tbne EscapeSheikThink_Chase_DownBoundThink_JabFrameInitSkip\n#Init Jab Frame\n\tli\tr3,JabFrameHi-JabFrameLo\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,JabFrameLo\n\tstb r3,JabFrame(REG_EventData)\n#Get chance to jab again\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tstb r3,isJabTwice(REG_EventData)\n#Get frame to jab again\n\tli\tr3,Jab2FrameHi-Jab2FrameLo\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,Jab2FrameLo\n\tstb r3,Jab2Frame(REG_EventData)\n#Init Jab 2 Timer\n\tli\tr3,0\n\tstb\tr3,Jab2Timer(REG_EventData)\nEscapeSheikThink_Chase_DownBoundThink_JabFrameInitSkip:\n#Check if facing P1\n\tcmpwi REG_Direction,0\n\tbgt EscapeSheikThink_Chase_DownBoundThink_FacingSkip\n#Input slightly towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,100\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_DownBoundThink_FacingSkip:\n#Check distance (if over 16 units, walk towards)\n\tlfs f1,GrabDistance(REG_EventConstants)\n\tlfs f2,Distance(sp)\n\tfabs f2,f2\n\tfcmpo cr0,f2,f1\n\tble EscapeSheikThink_Chase_DownBoundThink_RunTowardsSkip\nEscapeSheikThink_Chase_DownBoundThink_WalkTowards:\n#Walk Towards\n\tlfs f1,0x2C(REG_P2Data)\n\tfctiwz f1,f1\n\tstfd f1,0x80(sp)\n\tlwz r3,0x84(sp)\n\tmullw r3,r3,REG_Direction\n\tmulli r3,r3,100\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_DownBoundThink_RunTowardsSkip:\n#Check distance\n\tlfs f1,GrabDistance(REG_EventConstants)\n\tlfs f2,Distance(sp)\n\tfabs f2,f2\n\tfcmpo cr0,f2,f1\n\tbgt EscapeSheikThink_Chase_DownBoundThink_HaltSkip\n#Ensure Facing\n\tcmpwi REG_Direction,1\n\tbne EscapeSheikThink_Chase_DownBoundThink_HaltSkip\nEscapeSheikThink_Chase_DownBoundThink_Halt:\n#Stop Moving\n\tli\tr3,0\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n\tstb r3,CPU_AnalogX(REG_P2Data)\nEscapeSheikThink_Chase_DownBoundThink_HaltSkip:\n#Now jab when P1 is on the jab frame\n\tlhz r3,TM_FramesinCurrentAS(REG_P1Data)\n\tlbz r4,JabFrame(REG_EventData)\n\tcmpw r3,r4\n\tblt EscapeSheikThink_CheckTimer\n#Enter jab\n\tli\tr3,PAD_BUTTON_A\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n\tli\tr3,0\n\tstb r3,CPU_AnalogX(REG_P2Data)\n#Check if sheik will double jab\n\tlbz\tr3,isJabTwice(REG_EventData)\n\tcmpwi\tr3,0\n\tbeq\tEscapeSheikThink_Chase_DownBoundThink_SingleJab\n#Start Double Jab timer\n\tlbz\tr3,Jab2Frame(REG_EventData)\n\tstb\tr3,Jab2Timer(REG_EventData)\n#Change Event State\n\tli\tr3,EventState_Jab2\n\tstb\tr3,EventState(REG_EventData)\n\tb\tEscapeSheikThink_CheckTimer\nEscapeSheikThink_Chase_DownBoundThink_SingleJab:\n#Advance state\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n#Start timer\n\tli\tr3,ResetTimer+30\n\tstb r3,Timer(REG_EventData)\n\tb\tEscapeSheikThink_CheckTimer\n#endregion\n\n#region EscapeSheikThink_Jab2\nEscapeSheikThink_Jab2:\n#Check if waiting on jab 2\n\tlbz\tr3,Jab2Timer(REG_EventData)\n\tcmpwi\tr3,0\n\tbeq\tEscapeSheikThink_Chase_DownBoundThink_Jab2Skip\n#But not during hitlag\n\tlbz\tr3,0x221A(REG_P2Data)\n\trlwinm.\tr3,r3,0,26,26\n\tbne\tEscapeSheikThink_Chase_DownBoundThink_Jab2Skip\n#Decrement timer\n\tlbz\tr3,Jab2Timer(REG_EventData)\n\tsubi\tr3,r3,1\n\tstb\tr3,Jab2Timer(REG_EventData)\n#Check if up\n\tcmpwi\tr3,0\n\tbgt\tEscapeSheikThink_CheckTimer\n#Enter jab\n\tli\tr3,PAD_BUTTON_A\n\tstw r3,CPU_HeldButtons(REG_P2Data)\n\tli\tr3,0\n\tstb r3,CPU_AnalogX(REG_P2Data)\n#Advance state\n\tli\tr3,EventState_Reset\n\tstb r3,EventState(REG_EventData)\n#Start timer\n\tli\tr3,ResetTimer+30\n\tstb r3,Timer(REG_EventData)\n\tb\tEscapeSheikThink_CheckTimer\nEscapeSheikThink_Chase_DownBoundThink_Jab2Skip:\n\tb\tEscapeSheikThink_CheckTimer\n#endregion\n\n#region EscapeSheikThink_Reset\nEscapeSheikThink_Reset:\n#Hold Shield\n\tli\tr3,PAD_TRIGGER_R\n\tstw\tr3,CPU_HeldButtons(REG_P2Data)\n\tb\tEscapeSheikThink_CheckTimer\n#endregion\n\nEscapeSheikThink_CheckTimer:\n#Check if timer exists\n\tlbz r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tble EscapeSheikThink_Exit\n#Decrement timer\n\tsubi r3,r3,1\n\tstb r3,Timer(REG_EventData)\n\tcmpwi r3,0\n\tbgt EscapeSheikThink_Exit\n\nEscapeSheikThink_Restore:\n#Restore State\n\taddi r3,REG_EventData,EventData_SaveStateStruct\n\tli\tr4,1\n\tbl\tSaveState_Load\n#Init Positions Again\n\tmr\tr3,REG_P1GObj\n\tmr\tr4,REG_P2GObj\n\tmr\tr5,REG_EventData\n\tbl\tEscapeSheik_InitializePositions\n\nEscapeSheikThink_Exit:\n\trestore\n\tblr\n\n################################\n\nEscapeSheikThink_Constants:\nblrl\n.set P1X,0x0\n.set P1Y,0x4\n.set P2X,0x8\n.set P2Y,0xC\n.set GrabDistance,0x10\n.set HoldShieldVelocity,0x14\n.set RunDistance,0x18\n\n.float -8\t\t#p1 x\n.float  0\t\t#p1 y\n.float  8\t\t#p2 x\n.float  0\t\t#p2 y\n.float 14\t\t#16\n.float 1.1\n.float 23\n\n###########################################\n\nEscapeSheikThink_TopText:\nblrl\n.string \"Down B Input\"\n.align 2\n\nEscapeSheikThink_BottomText:\nblrl\n.string \"%df %s\"\n.align 2\n\nEscapeSheikThink_EarlyText:\nblrl\n.string \"Early\"\n.align 2\n\nEscapeSheikThink_LateText:\nblrl\n.string \"Late\"\n.align 2\n\n###########################################\n\nEscapeSheik_InitializePositions:\nbackup\n\n.set REG_FacingDirection,31\t\t#1 = p1 facing right, -1 = p1 facing left\n.set REG_P1GObj,30\n.set REG_P1Data,29\n.set REG_P2GObj,28\n.set REG_P2Data,27\n.set REG_EventData,26\n\n#Init Registers\n  mr\tREG_P1GObj,r3\n  lwz REG_P1Data,0x2C(REG_P1GObj)\n  mr\tREG_P2GObj,r4\n  lwz REG_P2Data,0x2C(REG_P2GObj)\n\tmr\tREG_EventData,r5\n\nEscapeSheik_InitializePositions_DetermineFacingDirection:\n#Determine Facing Direction\n\tli\tREG_FacingDirection,1\n\tli\tr3,2\n\tbranchl r12,HSD_Randi\n\tcmpwi r3,0\n\tbeq EscapeSheik_InitializePositions_DetermineFacingDirection_End\n\tli\tREG_FacingDirection,-1\nEscapeSheik_InitializePositions_DetermineFacingDirection_End:\n\n #Apply Facing Directions\n\tmr\tr3,REG_FacingDirection\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n  mulli\tr3,REG_FacingDirection,-1\n  bl\tIntToFloat\n  stfs\tf1,0x2C(REG_P2Data)\n\n#Get Starting Coordinates\n\tlfs f1,P1X(REG_EventConstants)\n\tlfs f2,P1Y(REG_EventConstants)\n\tcmpwi REG_FacingDirection,0\n\tblt EscapeSheik_InitializePositions_P1FacingLeft\n\tstfs f1,0xB0(REG_P1Data)\n\tstfs f2,0xB4(REG_P1Data)\n\tb\tEscapeSheik_InitializePositions_RightPosition\nEscapeSheik_InitializePositions_P1FacingLeft:\n\tstfs f1,0xB0(REG_P2Data)\n\tstfs f2,0xB4(REG_P2Data)\nEscapeSheik_InitializePositions_RightPosition:\n\tlfs f1,P1X(REG_EventConstants)\n\tlfs f2,P1Y(REG_EventConstants)\n\tcmpwi REG_FacingDirection,0\n\tblt EscapeSheik_InitializePositions_P2FacingRight\n\tstfs f1,0xB0(REG_P2Data)\n\tstfs f2,0xB4(REG_P2Data)\nEscapeSheik_InitializePositions_P2FacingRight:\n\tstfs f1,0xB0(REG_P1Data)\n\tstfs f2,0xB4(REG_P1Data)\n#Update Positions\n\tmr\tr3,REG_P1GObj\n\tbl\tPlacePlayerOnGround\n\tmr\tr3,REG_P1GObj\n\tbl\tUpdateCameraBox\n\tmr\tr3,REG_P2GObj\n\tbl\tPlacePlayerOnGround\n\tmr\tr3,REG_P2GObj\n\tbl\tUpdateCameraBox\n\n#Store P1 into P2 Grab Pointer\n\tstw\tREG_P1GObj,0x1A58(REG_P2Data)\n\tstw\tREG_P1GObj,0x1A5C(REG_P2Data)\n#Clear P1's Grabbed Player Pointer\n\tli\tr3,0\n\tstw\tr3,0x1A58(REG_P1Data)\n\tstw\tr3,0x1A5C(REG_P1Data)\n#Clear P2's GFX Pointer\n\tstw r3,0x60C(REG_P2Data)\n#Enter P2 Into Grab\n\tmr\tr3,REG_P2GObj\t\t\t#P2 Enters Grab\n\tbranchl\tr12,AS_GrabOpponent\n#Enter P1 Into Grabbed\n\tmr\tr3,REG_P1GObj\t\t\t#P1 Grabbed\n\tmr\tr4,REG_P2GObj\t\t\t#P2 = Grabber\n\tbranchl\tr12,AS_Grabbed\n#Enter P2 Into GrabWait\n\tmr\tr3,REG_P2GObj\t\t\t#P2 Enters GrabWait\n\tbranchl\tr12,AS_CatchWait\n#Give a bunch of grabstun\n\tli\tr3,999\n\tbl\tIntToFloat\n\tstfs f1,0x1A4C(REG_P1Data)\n\n#Random percent\n\tli\tr3,PercentHi-PercentLo\n\tbranchl r12,HSD_Randi\n\taddi r4,r3,PercentLo\n\tlbz r3,0xC(REG_P1Data)\n\tbranchl r12,PlayerBlock_SetDamage\n\n#Reset Variables\n\tli\tr3,EventState_ThrowDelay\n\tstb r3,EventState(REG_EventData)\n\tli\tr3,0\n\tstb r3,Timer(REG_EventData)\n\tstb r3,JabFrame(REG_EventData)\n#Init Throw Timer\n\tli\tr3,ThrowTimerHi-ThrowTimerLo\n\tbranchl r12,HSD_Randi\n\taddi r3,r3,ThrowTimerLo\n\tsth r3,ThrowTimer(REG_EventData)\n#Init isDisplayedTiming\n\tli\tr3,0\n\tstb\tr3,isDisplayedTiming(REG_EventData)\n\nEscapeSheik_InitializePositions_Exit:\n\trestore\n\tblr\n\n#endregion\n\n#region Scrapped Edgeguard Event\n/*\n\n#########################\n## Event 16 HIJACK INFO ##\n#########################\n\nEvent16:\n#STORE STAGE\nli\tr3,0x20\nsth\tr3,0xE(r26)\n\nli\tr5,0x2\t\t#Ice Climbers\nli\tr5,0x14\n\n#STORE CPU\nlwz\tr4,0x0(r29)\nbl\tP2Struct\nmflr\tr3\nstw\tr3,0x18(r4)\t\t#p2 pointer\nstb\tr5,0x0(r3)\t\t#make top tier p2\nli\tr5,0x1\t\t#make CPU controlled\nstb\tr5,0x1(r3)\n\n#SPAWN 2 PLAYERS\nli\tr3,0x40\nstb\tr3,0x1(r4)\n\n\n#STORE THINK FUNCTION\nbl\tEvent16Load\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Event 16 LOAD FUNCT ##\n\t########################\n\tEvent16Load:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tEvent16Think\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n\tbl\tCreateEventThinkFunction\n\n\tb\tEvent16LoadExit\n\n\n\t\t#########################\n\t\t## Event 16 THINK FUNCT ##\n\t\t#########################\n\n\n\t\tEvent16Think:\n\t\t\tblrl\n\t\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\t\tlwz\t\tr31,0x2c(r3)\t\t\t#backup data pointer in r31\n\n\t\t#Get P2\n\t\t\tli\t\tr3,0x1\n\t\t\tbranchl\t\tr12,PlayerBlock_LoadMainCharDataOffset\t\t\t#get player block\n\t\t\tmr\t\tr30,r3\t\t\t#player block in r30\n\t\t\tlwz\t\tr29,0x2c(r30)\t\t\t#player data in r29\n\n\t\t#Get P1\n\t\t\tli\t\tr3,0x0\n\t\t\tbranchl\t\tr12,PlayerBlock_LoadMainCharDataOffset\t\t\t#get player block\n\t\t\tmr\t\tr28,r3\t\t\t#player block in r28\n\t\t\tlwz\t\tr27,0x2c(r28)\t\t\t#player data in r27\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\t\t#ON FIRST FRAME\n\t\t\tlbz\tr3,0x0(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tEvent16ThinkMain\n\n\t\t\t\tlbz\tr3,0x221D(r29)\n\t\t\t\trlwinm.\tr3,r3,0,28,28\n\t\t\t\tbne\tEvent16ThinkExit\n\n\t\t\t\t#Set Frame 1 As Over\n\t\t\t\t\tli\t\tr3,0x1\n\t\t\t\t\tstb\t\tr3,0x0(r31)\n\t\t\t\t#Initlize Positions\n\t\t\t\t\tbl\tEvent16_Floats\n\t\t\t\t\tmflr\tr3\n\t\t\t\t\t#bl\tInitializePositions\n        #Clear Inputs\n          bl  RemoveFirstFrameInputs\n\t\t\t\t#Save State\n\t\t\t\t\tmr\tr3,r31\n\t\t\t\t\tbl\tSaveState_Save\n\t\t\t\t#Set Timer to -60\n\t\t\t\t\tli\t\tr3,-60\n\t\t\t\t\tstw\t\tr3,0x4(r31)\n\n\n\n\t\tEvent16ThinkMain:\n\t\tEvent16ThinkSequence:\n\t\t#Inc Timer\n\t\t\tlwz\tr3,0x4(r31)\n\t\t\taddi\tr3,r3,0x1\n\t\t\tstw\tr3,0x4(r31)\n\n\t\t#Get Floats\n\t\t\tbl\tEvent16_Floats\n\t\t\tmflr\tr21\n\n\t\t#L+DPad Controls CPU Percent\n\t\tbl\tDPadCPUPercent\n\n\t\t#Check If Already in A Recovery Mode\n\t\t\tlbz\tr3,0x8(r31)\n\t\t\tcmpwi\tr3,0x1\n\t\t\tbeq\tEvent16CheckRecoveryFlag\n\n\t\t#Check If CPU Is Offstage\n\t\t\tmr\tr3,r29\n\t\t\tbranchl\tr12,0x800a2c80\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tEvent16CheckRecoveryFlag\n\n\t\t\t#Check If Still in Hitstun\n\t\t\t\tlbz\tr3,0x221C(r29)\n\t\t\t\trlwinm.\tr3,r3,0,30,30\n\t\t\t\tbne\tEvent16CheckRecoveryFlag\n\n\t\t\t#Check If Below Ledge\n\t\t\t#Hold Towards Ledge\n\n\t\t\t\t#Get Random Recovery Option\n\t\t\t\tEvent16GetRandomRecovery:\n\t\t\t\t\tli\tr3,3\t\t#Number of Recovery Options (Side B Immediately,Jump Then Side B, ShineStall-Jump-SideB)\n\t\t\t\t\tbranchl\tr12,HSD_Randi\n\t\t\t\t\tcmpwi\tr3,0x0\n\t\t\t\t\tbne\tEvent16StoreRecoveryType\n\t\t\t\t#Check If Can Side B Only\n\t\t\t\t\t#Check If Above Ledge\n\t\t\t\t\t\tlfs\tf1,0xB4(r29)\t#Get Y Coord\n\t\t\t\t\t\t#lfs\tf2,0x10(r21)\n\t\t\t\t\t\t#fcmpo\tcr0,f1,f2\n\t\t\t\t\t\t#bgt\tEvent16GetRandomRecovery\n\t\t\t\t\t\t#lfs\tf2,0x10(r21)\n\t\t\t\t\t#Check If Below Ledge\n\t\t\t\t\t\tlfs\tf2,0x14(r21)\n\t\t\t\t\t\tfcmpo\tcr0,f1,f2\n\t\t\t\t\t\tblt\tEvent16GetRandomRecovery\n\n\t\t\t\tEvent16StoreRecoveryType:\n\t\t\t\t\tstb\tr3,0x9(r31)\n\t\t\t\t#Init Recovery Flag\n\t\t\t\t\tli\tr3,0x1\n\t\t\t\t\tstb\tr3,0x8(r31)\n\n\n\t\tEvent16CheckRecoveryFlag:\n\t\t#Check Recovery Flag\n\t\t\tlbz\tr3,0x8(r31)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tEvent16CheckToReset\n\n#******************************************************************#\n\n#IsRecovering\n\n\t\t#If Timer Is Set, Dont Run Any of This\n\t\tlwz\tr3,0xC(r31)\t\t#get timer\t#Get Timer\n\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\tbgt\tEvent16GetRecoveryID\n\n\t\t#Hold Towards Stage\n\t\tli\tr3,127\n\t\tlfs\tf0,0x00B0 (r29)\t#X Pos\n\t\tlfs\tf1,0x1ADC (r29) #Last Grounded X Pos\n\t\tfcmpo\tcr0,f1,f0\n\t\tbgt\tEvent16HoldTowardsRight\n\t\tneg\tr3,r3\n\t\tEvent16HoldTowardsRight:\n\t\tstb\tr3,0x1A8C(r29)\n\n\t\t\t#Check If Died\n\t\t\tlbz\tr3,0x221F(r29)\n\t\t\trlwinm.\tr3,r3,0,25,25\n\t\t\tbne\tEvent16SideBThink_Reset\n\n\t\t\t#Check If In Hitlag\n\t\t\t#Recover again\n\t\t\tlbz\tr3,0x221A(r29)\n\t\t\trlwinm.\tr3,r3,0,26,26\n\t\t\tbne\tEvent16RecoverAgain\n\n\t\t\t#Check If Made It Back\n\t\t\t#Check Ground Flag\n\t\t\tlwz\tr3,0xE0(r29)\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tEvent16SideBThink_Reset\n\t\t\t#Check CliffCatch\n\t\t\tlwz\tr3,0x10(r29)\n\t\t\tcmpwi\tr3,0xFC\n\t\t\tbeq\tEvent16SideBThink_Reset\n\n\t\t\tb\tEvent16GetRecoveryID\n\n\t\t\tEvent16RecoverAgain:\n\t\t\t#Recover Again\n\t\t\tli\tr3,0x0\n\t\t\tstb\tr3,0x8(r31)\n\t\t\tstb\tr3,0x9(r31)\n\t\t\tb\tEvent16CheckToReset\n\n\t\t\tEvent16SideBThink_Reset:\n\t\t\t#Set Timer\n\t\t\tlwz\tr3,0xC(r31)\t\t#get timer\t#Get Timer\n\t\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\t\tbgt\tEvent16CheckToReset\t#Reset Timer Set\n\t\t\tli\tr3,30\n\t\t\tstw\tr3,0xC(r31)\t\t#Store Reset Timer\n\t\t\tb\tEvent16CheckToReset\n\n\t\t#Run Recovery Think\n\t\t#Get Which Recovery To Perform\n\t\tEvent16GetRecoveryID:\n\t\tlbz\tr3,0x9(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tEvent16SideBOnly\n\t\tcmpwi\tr3,0x1\n\t\tbeq\tEvent16JumpSideB\n\t\tcmpwi\tr3,0x2\n\t\tbeq\tEvent16SSJumpSideB\n\t\tcmpwi\tr3,0x3\n\t\tbeq\tEvent16SideBThink\n\n\t#*************************************************#\n\n\t\tEvent16SideBOnly:\n\t\t#Be in ledge Y range, Check if next frame will be out of Y range\n\t\t\tbl\tEvent16CheckIfLineUpWithLedge\n\t\t\tcmpwi\tr3,-1\t\t\t#Not In Range Yet\n\t\t\tbeq\tEvent16CheckToReset\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tEvent16ChanceToInputSideB\n\n\t\t#If OoRange Next Frame + Descending, Side B Immediately\n\t\t\tlfs\tf0, -0x7208 (rtoc)\n\t\t\tlfs\tf1,0xCC(r29)\n\t\t\tfcmpo\tcr0,f1,f0\n\t\t\tblt\tEvent16InputSideB\n\n\t\t\tEvent16ChanceToInputSideB:\n\t\t\tli\tr3,5\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tEvent16InputSideB\n\t\t\tb\tEvent16CheckToReset\n\n\t\t\tEvent16InputSideB:\n\t\t\t\t#Joystick X = 120 * Facing Direction\n\t\t\t\tlfs\tf1,0x2C(r29)\n\t\t\t\tfctiwz\tf1,f1\n\t\t\t\tstfd\tf1,0xF0(sp)\n\t\t\t\tlwz\tr4,0xF4(sp)\n\t\t\t\tli\tr3,120\t\t#X Stick\n\t\t\t\tmullw\tr3,r3,r4\n\t\t\t\tstb\tr3,0x1A8C(r29)\n\t\t\t\tli\tr3,0x200\n\t\t\t\tstw\tr3,0x1A88(r29)\n\t\t\t\t#li\tr3,0x0\n\t\t\t\t#stb\tr3,0x8(r31)\n\n\t\t\t\t#Change State to Mid-Side B\n\t\t\t\tli\tr3,3\n\t\t\t\tstb\tr3,0x9(r31)\n\t\t\t\tb\tEvent16CheckToReset\n\n\t#*************************************************#\n\n\t\tEvent16JumpSideB:\n\t\t#Be above bottom most coord, Check if next frame will be out of Y range\n\t\t#Be in ledge Y range, Check if next frame will be out of Y range\n\n\t\t#Check If Above Bottom-most\n\t\tlfs\tf1,0xB4(r29)\t#Get Next Frames Y Coord\n\t\tlfs\tf2,0x84(r29)\n\t\tfadds\tf1,f1,f2\n\t\tlfs\tf2,0x18(r21)\t#Get Bottom Y Coord\n\t\tfcmpo\tcr0,f1,f2\n\t\tblt\tEvent16JumpSideB_Jump\n\n\t\tEvent16JumpSideB_ChanceToJump:\n\t\tli\tr3,20\t\t#1 in 4 Chance\n\t\tbranchl\tr12,HSD_Randi\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tEvent16JumpSideB_Jump\n\t\tb\tEvent16CheckToReset\n\n\t\tEvent16JumpSideB_Jump:\n\t\tli\tr3,0x800\n\t\tstw\tr3,0x1A88(r29)\n\t\t#Advance to Next State\n\t\tli\tr3,0x0\n\t\tstb\tr3,0x9(r31)\n\t\tb\tEvent16CheckToReset\n\n\t#*************************************************#\n\n\t\tEvent16SSJumpSideB:\n\t\t#Hold Down B\n\t\t#Be above bottom most coord, Check if next frame will be out of Y range\n\t\t#Be in ledge Y range, Check if next frame will be out of Y range\n\n\t\t#Always Hold Down B\n\t\tli\tr3,-127\n\t\tstb\tr3,0x1A8D(r29)\n\t\tli\tr3,0x200\n\t\tstw\tr3,0x1A88(r29)\n\n\t\t#Wait Until in Shine Loop\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0x16E\n\t\tbne\tEvent16CheckToReset\n\n\t\t#Check If Above Bottom-most\n\t\tlfs\tf1,0xB4(r29)\t#Get Next Frames Y Coord\n\t\tlfs\tf2,0x84(r29)\n\t\tfadds\tf1,f1,f2\n\t\tlfs\tf2,0x18(r21)\t#Get Bottom Y Coord\n\t\tfcmpo\tcr0,f1,f2\n\t\tblt\tEvent16SSJumpSideB_Jump\n\n\t\tEvent16SSJumpSideB_ChanceToJump:\n\t\tli\tr3,15\t\t#1 in 6 Chance\n\t\tbranchl\tr12,HSD_Randi\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tEvent16SSJumpSideB_Jump\n\t\tb\tEvent16CheckToReset\n\n\t\tEvent16SSJumpSideB_Jump:\n\t\tli\tr3,0x800\n\t\tstw\tr3,0x1A88(r29)\n\t\t#Advance to Next State\n\t\tli\tr3,0x0\n\t\tstb\tr3,0x9(r31)\n\t\tb\tEvent16CheckToReset\n\n\t#*************************************************#\n\n\t\tEvent16SideBThink:\n\n\t\tb\tEvent16CheckToReset\n\n\t#*************************************************#\n\n\t\t#Check To Reset\n\t\tEvent16CheckToReset:\n\t\t\tlwz\tr3,0xC(r31)\t\t#Get Timer\n\t\t\tcmpwi\tr3,0x0\t\t#No Reset Timer Set Yet\n\t\t\tble\tEvent16ThinkExit\n\t\t#Dec Timer\n\t\t\tsubi\tr3,r3,0x1\n\t\t\tstw\tr3,0xC(r31)\t\t#store timer\n\t\t\tcmpwi\tr3,0x0\t\t#Check if 0 now\n\t\t\tbne\tEvent16ThinkExit\t#Exit If Not\n\t\tEvent16RestoreState:\n\t\t#Restore State\n\t\t\tmr\tr3,r31\n\t\t\tbl\tSaveState_Load\n\t\t#Reset Timer\n\t\t\tli\tr3,60\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tli\tr4,0\n\t\t\tsub\tr3,r4,r3\n\t\t\tstw\tr3,0x4(r31)\n\t\t\tli\tr3,0x0\n\t\t\tstb\tr3,0x8(r31)\n\n\t\tEvent16ThinkExit:\n\t\trestore\n\t\tblr\n\n#################################\n\nEvent16_Floats:\nblrl\n.long 0xC28C0000\t\t#P1 X Position\n.long 0xc2982e6c \t#P2 X Position\n.long 0x38d1b717  #P1 Y Position\n.long 0x38d1b717\t\t#FD Floor Y Coord\n.long 0x40A00000\t\t#Top Most Y Value = -5\n.long 0xC1700000\t #Bottom-most Y Value = -15\n.long 0xC25C0000\t\t#Shine Stall Bottom Most Coord\n\n#################################\n\nEvent16CheckIfLineUpWithLedge:\n#-1 = Not In Any Range Yet\n#0 = In Range This And Next Frame\n#1 = In Range This but NOT Next Frame\n\n#Check If In Range This Frame\nlfs\tf1,0xB4(r29)\t#Get Y Coord\nlfs\tf2,0x10(r21)\nfcmpo\tcr0,f1,f2\nbgt\tEvent16CheckIfLineUpWithLedge_NotInRange\nlfs\tf2,0x14(r21)\nfcmpo\tcr0,f1,f2\nblt\tEvent16CheckIfLineUpWithLedge_NotInRange\n\nEvent16CheckIfLineUpWithLedge_CheckNextFrame:\n#Check If Out Of Range Next Range\nlfs\tf1,0xB4(r29)\t#Get Y Coord\nlfs\tf2,0x84(r29)\t#Get Y Vel\nfadds\tf1,f1,f2\t    #Get Next Frames Position\n#Check If Will Be Above Ledge Next Frame\nlfs\tf2,0x10(r21)\nfcmpo\tcr0,f1,f2\nbgt\tEvent16CheckIfLineUpWithLedge_OutOfRangeNextFrame\nlfs\tf2,0x10(r21)\n#Check If Will Be Below Ledge Next Frame\nlfs\tf2,0x14(r21)\nfcmpo\tcr0,f1,f2\nblt\tEvent16CheckIfLineUpWithLedge_OutOfRangeNextFrame\nb\tEvent16CheckIfLineUpWithLedge_InRangeThisAndNextFrame\n\nEvent16CheckIfLineUpWithLedge_NotInRange:\nli\tr3,-1\nb\tEvent16CheckIfLineUpWithLedge_Exit\nEvent16CheckIfLineUpWithLedge_InRangeThisAndNextFrame:\nli\tr3,0x0\nb\tEvent16CheckIfLineUpWithLedge_Exit\nEvent16CheckIfLineUpWithLedge_OutOfRangeNextFrame:\nli\tr3,0x1\n\nEvent16CheckIfLineUpWithLedge_Exit:\nblr\n\n#################################\n\n\nEvent16LoadExit:\nrestore\nblr\n\n\n*/\n#endregion\n\n#region Scrapped Dash Dance Code\n/*\n#########################\n## Shield Drop HIJACK INFO ##\n#########################\n\nShieldDrop:\n#STORE STAGE\nli\tr3,0x20\nsth\tr3,0xE(r26)\n\n#STORE CPU\nlwz\tr4,0x0(r29)\nbl\tP2Struct\nmflr\tr3\nstw\tr3,0x18(r4)\t\t#p2 pointer\nli\tr5,0x2\t\t#fox ext ID\nstb\tr5,0x0(r3)\t\t#make fox p2\nli\tr5,0x1\t\t#make CPU controlled\nstb\tr5,0x1(r3)\n\n#SPAWN 2 PLAYERS\nli\tr3,0x40\nstb\tr3,0x1(r4)\n\n\n#STORE THINK FUNCTION\nbl\tShieldDropLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Shield Drop LOAD FUNCT ##\n\t########################\n\tShieldDropLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tShieldDropThink\n\tmflr\tr3\n\tli\tr4,3\t\t#Priority (After Interrupt)\n\tbl\tCreateEventThinkFunction\n\n\tb\tShieldDropLoadExit\n\n\n\t\t#########################\n\t\t## Shield Drop THINK FUNCT ##\n\t\t#########################\n\n\n\t\tShieldDropThink:\n\t\tblrl\n\t\tbackup\n\n\t\t#INIT FUNCTION VARIABLES\n\t\tlwz\t\tr31,0x2c(r3)\t\t\t#backup data pointer in r31\n\n\t\t#Get P2\n\t\tli\t\tr3,0x1\n\t\tbranchl\t\tr12,PlayerBlock_LoadMainCharDataOffset\t\t\t#get player block\n\t\tmr\t\tr30,r3\t\t\t#player block in r30\n\t\tlwz\t\tr29,0x2c(r30)\t\t\t#player data in r29\n\n\t\t#Get P1\n\t\tli\t\tr3,0x0\n\t\tbranchl\t\tr12,PlayerBlock_LoadMainCharDataOffset\t\t\t#get player block\n\t\tmr\t\tr28,r3\t\t\t#player block in r28\n\t\tlwz\t\tr27,0x2c(r28)\t\t\t#player data in r27\n\n\t\tbl\tStoreCPUTypeAndZeroInputs\n\n\n\t\t#ON FIRST FRAME\n\t\tlbz\tr3,0x0(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tShieldDropThinkMain\n\n\t\t\tlbz\tr3,0x221D(r29)\n\t\t\trlwinm.\tr3,r3,0,28,28\n\t\t\tbne\tShieldDropThinkExit\n\n\t\t\t#Set Frame 1 As Over\n\t\t\tli\t\tr3,0x1\n\t\t\tstb\t\tr3,0x0(r31)\n\t\t\tbl\t\tShieldDrop_InitializePositions\n\t\t\tmr\t\tr3,r31\n\t\t\tbl\t\tSaveState_Save\n\n\n\n\t\tShieldDropThinkMain:\n\t\tbl\tGiveFullShields\n\n\t\tShieldDropThinkSequence:\n\t\t#Get Floats and Frame Info\n\t\tbl\tShieldDropFloats\n\t\tmflr\tr21\t\t#Get Floats\n\t\tlwz\tr20,0x4(r31)\t\t#Get State\n\t\tlfs\tf1,0x894(r29)\n\t\tfctiwz\tf1,f1\n\t\tstfd\tf1,0xF0(sp)\n\t\tlwz\tr24,0xF4(sp)\t\t#Frame Number in r24\n\n\t\t#Get Distance and Direction\n\t\t#f1 = distance\n\t\t#r22= towards direction\n\t\t#r23= away direction\n\t\tlfs\tf1,0xB0(r27)\n\t\tlfs\tf2,0xB0(r29)\n\t\tfsubs\tf1,f1,f2\n\t\tlfs\tf0, -0x6768 (rtoc)\n\t\tfcmpo\tcr0,f1,f0\n\t\tbgt\tShieldDropRight\n\t\tShieldDropLeft:\n\t\tli\tr22,-127\n\t\tli\tr23,127\n\t\tb\tShieldDropCheckState\n\t\tShieldDropRight:\n\t\tli\tr22,127\n\t\tli\tr23,-127\n\n\t\tShieldDropCheckState:\n\t\t#When DDing, Move In Facing Direction\n\t\tcmpwi\tr20,0x1\n\t\tbne\tShieldDrop_SkipHoldForward\n\t\tlfs\tf2,0x2C(r29)\n\t\tfctiwz\tf2,f2\n\t\tstfd\tf2,0xF0(sp)\n\t\tlwz\tr3,0xF4(sp)\t\t#Facing direction as int\n\t\tmulli\tr3,r3,127\n\t\tstb\tr3,0x1A8C(r29)\t\t#Move Towards\n\n\t\tShieldDrop_SkipHoldForward:\n\t\tfabs\tf1,f1\t\t#abs distance\n\t\tcmpwi\tr20,0x0\n\t\tbeq\tShieldDropDashDanceStart\n\t\tcmpwi\tr20,0x1\n\t\tbeq\tShieldDropDashDanceThink\n\t\tcmpwi\tr20,0x2\n\t\tbeq\tShieldDropJumpThink\n\t\tcmpwi\tr20,0x3\n\t\tbeq\tShieldDropLCancelThink\n\t\tcmpwi\tr20,0x4\n\t\tbeq\tShieldDropInvincibleThink\n\n\n\t\tShieldDropDashDanceStart:\n\t\t\tstb\tr23,0x1A8C(r29)\t\t#Move Away\n\t\t\tli\tr3,0x1\t\t #Enter DDThink\n\t\t\tstw\tr3,0x4(r31)\n\t\t\tb\tShieldDropThinkExit\n\n\t\tShieldDropDashDanceThink:\n\t\t\t#Check If Too Close\n\t\t\tShieldDropDashDanceThink_CheckIfTooClose:\n\t\t\tlfs\tf2,0x0(r21)\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tbgt\tShieldDropDashDanceThink_CheckIfTooFar\n\t\t\tstb\tr23,0x1A8C(r29)\t\t#Move Away\n\t\t\tb\tShieldDropThinkExit\n\t\t\tShieldDropDashDanceThink_CheckIfTooFar:\n\t\t\tlfs\tf2,0x4(r21)\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tblt\tShieldDropDashDanceThink_CheckToAttack\n\t\t\tstb\tr22,0x1A8C(r29)\t\t#Move Towards\n\t\t\tb\tShieldDropThinkExit\n\n\t\t\tShieldDropDashDanceThink_CheckToAttack:\n\t\t\tlfs\tf2,0x8(r21)\n\t\t\tfcmpo\tcr0,f1,f2\n\t\t\tbgt\tShieldDropDashDanceThink_CheckToChangeDirection\n\t\t\tShieldDropDashDanceThink_CheckIfFacingOpponent:\n\t\t\tlfs\tf2,0x2C(r29)\n\t\t\tfctiwz\tf2,f2\n\t\t\tstfd\tf2,0xF0(sp)\n\t\t\tlwz\tr3,0xF4(sp)\t\t#Facing direction as int\n\t\t\tcmpwi\tr3,0x0\n\t\t\tblt\tShieldDropDashDanceThink_FacingLeft\n\t\t\tShieldDropDashDanceThink_FacingRight:\n\t\t\tcmpwi\tr22,0x0\n\t\t\tbgt\tShieldDropDashDanceThink_FacingOpponent\n\t\t\tb\tShieldDropDashDanceThink_NotFacingOpponent\n\t\t\tShieldDropDashDanceThink_FacingLeft:\n\t\t\tcmpwi\tr22,0x0\n\t\t\tblt\tShieldDropDashDanceThink_FacingOpponent\n\t\t\tb\tShieldDropDashDanceThink_NotFacingOpponent\n\t\t\tShieldDropDashDanceThink_FacingOpponent:\n\t\t\tli\tr3,0x1\n\t\t\tb\t0x8\n\t\t\tShieldDropDashDanceThink_NotFacingOpponent:\n\t\t\tli\tr3,0x0\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tShieldDropDashDanceThink_CheckToChangeDirection\n\t\t\t#RNG Chance To Attack\n\t\t\tli\tr3,20\n\t\t\tbranchl\tr12,HSD_Randi\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbne\tShieldDropDashDanceThink_CheckToChangeDirection\n\t\t\tli\tr3,0x400\t\t#X Button\n\t\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t\tli\tr3,0x2\t\t#JumpThink\n\t\t\tstw\tr3,0x4(r31)\n\t\t\tb\tShieldDropThinkExit\n\n\n\t\tShieldDropDashDanceThink_CheckToChangeDirection:\n\t\t#Move if in Wait\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xE\n\t\tbeq\tShieldDropDashDanceThink_ChangeDirection\n\t\t#At least frame 3 of dash\n\t\tcmpwi\tr24,6\n\t\tblt\tShieldDropThinkExit\n\t\tcmpwi\tr24,11\n\t\tbge\tShieldDropDashDanceThink_ChangeDirection\n\t\t#RNG Chance To ChangeDirection\n\t\tli\tr3,7\n\t\tbranchl\tr12,HSD_Randi\n\t\tcmpwi\tr3,0x0\n\t\tbne\tShieldDropThinkExit\n\t\tShieldDropDashDanceThink_ChangeDirection:\n\t\tlfs\tf2,0x2C(r29)\n\t\tfctiwz\tf2,f2\n\t\tstfd\tf2,0xF0(sp)\n\t\tlwz\tr3,0xF4(sp)\t\t#Facing direction as int\n\t\tmulli\tr3,r3,127\n\t\tmulli\tr3,r3,-1\n\t\tstb\tr3,0x1A8C(r29)\t\t#Move Away\n\t\tb\tShieldDropThinkExit\n\n\t\tShieldDropJumpThink:\n\t\tlwz\tr3,0xE0(r29)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tShieldDropThinkExit\n\t\tli\tr3,0x100\t\t#A Button\n\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\tli\tr3,0x3\t\t#LCancelThink\n\t\tstw\tr3,0x4(r31)\n\t\tb\tShieldDropThinkExit\n\n\t\tShieldDropLCancelThink:\n\t\tShieldDropLCancelInputFF:\n\t\tlfs\tf2,0x84(r29)\n\t\tlfs\tf0, -0x76B0 (rtoc)\n\t\tfcmpo\tcr0,f2,f0\n\t\tbge\tShieldDropThinkExit\n\t\t#Input Down to FF\n\t\tli\tr3,-127\n\t\tstb\tr3,0x1A8D(r29)\t\t#Ananlog Y\n\t\t#Check If Under 5Mm Above Ground\n\t\tlfs\tf2,0xB4(r29)\n\t\tlfs\tf0,0xC(r21)\n\t\tfcmpo\tcr0,f2,f0\n\t\tbgt\tShieldDropThinkExit\n\t\tli\tr3,0xC0\t\t#Hit L\n\t\tstw\tr3,0x1A88(r29)\t\t#Held Buttons\n\t\t#Enter InvincibleThink + Init Counter\n\t\tli\tr3,0x4\t\t#State\n\t\tstw\tr3,0x4(r31)\n\t\tli\tr3,60\n\t\tstw\tr3,0x8(r31)\t\t#Counter\n\t\tb\tShieldDropThinkExit\n\n\t\tShieldDropInvincibleThink:\n\t\t#Dec Counter And Check To Restore\n\t\tlwz\tr3,0x8(r31)\n\t\tsubi\tr3,r3,0x1\n\t\tstw\tr3,0x8(r31)\n\t\tcmpwi\tr3,0x0\n\t\tbgt\tShieldDrop_CheckToMakeInvincible\n\t\t#Reset State ID\n\t\tli\tr3,0x0\n\t\tstw\tr3,0x4(r31)\n\t\t#Restore Savestate\n\t\tmr\tr3,r31\n\t\tbl\tSaveState_Load\n\t\tb\tShieldDropThinkExit\n\t\tShieldDrop_CheckToMakeInvincible:\n\t\tlwz\tr3,0x10(r29)\n\t\tcmpwi\tr3,0xE\n\t\t#bne\tShieldDropThinkExit\n\t\t#Make Invincible\n\t\t#mr\tr3,r30\n\t\t#li\tr4,0x2\n\t\t#branchl\tr12,ApplyInvincibility\n\t\t#b\tShieldDropThinkExit\n\n\n\t\t#Multishine\n\t\tmr\tr3,r29\n\t\tbl\tCPUActions_MultiShine\n\t\tb\tShieldDropThinkExit\n\n\t\tShieldDropThinkExit:\n\t\trestore\n\t\tblr\n\n\n##########################\n\nShieldDropFloats:\nblrl\n.long 0x41A00000 #no closer than this\n.long 0x42180000 #no further than this\n.long 0x41C80000 #at least this close to jump\n.long 0x40000000 #below this Y coord to L Cancel\n.long 0xC02CCCCD\t\t#P1 X Position\n.long 0x4144CCCD\t\t#P2 X Position\n\n#################################\n\nShieldDrop_InitializePositions:\nbackup\n\n#P1 @ -2.7\n#P2 @ 12.3\n\n#Get Floats\nbl\tShieldDropFloats\nmflr\tr20\n\n#Move P1\nmr\tr3,r28\nbranchl\tr12,0x8008a2bc\t\t#Enter Wait\nlfs\tf1,0x10(r20)\nstfs\tf1,0xB0(r27)\nmr\tr3,r28\nbl  UpdatePosition\n\n#Move P2\nmr\tr3,r30\nbranchl\tr12,0x8008a2bc\t\t#Enter Wait\nlfs\tf1,0x14(r20)\nstfs\tf1,0xB0(r29)\nmr\tr3,r30\nbl  UpdatePosition\n\nrestore\nblr\n\n###################################\n\nShieldDropLoadExit:\nrestore\nblr\n\n*/\n#endregion\n\n#region Event Template\n/*\n\n#########################\n## Eggs-ercise HIJACK INFO ##\n#########################\n\nEggs:\n#STORE THINK FUNCTION\nbl\tEggsLoad\nmflr\tr3\nstw\tr3,0x44(r26)\t\t#on match load\n\nb\texit\n\n\t########################\n\t## Eggs-ercise LOAD FUNCT ##\n\t########################\n\tEggsLoad:\n\tblrl\n\n\tbackup\n\n\t#Schedule Think\n\tbl\tEggsThink\n\tmflr\tr3\n\tbl\tCreateEventThinkFunction\n\n\tb\tEggsLoadExit\n\n\n\t\t#########################\n\t\t## Eggs-ercise THINK FUNCT ##\n\t\t#########################\n\n\n\t\tEggsThink:\n\t\tblrl\n\t\tbackup\n\n\n\n\t\tEggsThinkExit:\n\t\trestore\n\t\tblr\n\n\nEggsLoadExit:\nrestore\nblr\n\n*/\n####################################################\n#endregion\n\n###############\n## P1 STRUCT ##\n###############\nP1Struct:\nblrl\n\n.long 0x01000200 #external char, player type, stocks, costume\n.long 0xff000400 #spawn point, subcolor,team,voice pitch\n.long 0x00040700 #player flag\n.long 0x00000000 #level and starting %\n.long 0x3f800000 #attk ratio\n.long 0x3f800000 #def ratio\n.long 0x3f800000 #model scale\n\n###############\n## P2 STRUCT ##\n###############\nP2Struct:\nblrl\n\n.long 0x01010200 #external char, player type, stocks, costume\n.long 0xff000400 #spawn point, subcolor,team,voice pitch\n.long 0x00040700 #player flag\n.long 0x00000000 #level and starting %\n.long 0x3f800000 #attk ratio\n.long 0x3f800000 #def ratio\n.long 0x3f800000 #model scale\n\n\n###########################\n## Create Think Function ##\n###########################\nCreateEventThinkFunction:\n\n#Registers\n.set WindowOptionCount,31\n.set ASCIIStruct,30\n.set EventGObj,29\n.set EventData,28\n.set MenuGObj,27\n.set MenuData,26\n.set Priority,25\n.set Function,24\n\nbackup\n\nmr\tFunction,r3\nmr\tPriority,r4\nmr  WindowOptionCount,r5\nmr  ASCIIStruct,r6\n\n########################\n## Create Event Think ##\n########################\n\n#Create GObj\n  li\tr3,6\t\t#GObj Type\n  li\tr4,7\t\t#On-Pause Function\n  li\tr5,80\n  branchl\tr12,GObj_Create\n\n#Backup Allocation\n  mr\tEventGObj,r3\n\n#Schedule Task\n  mr\tr4,Function\n  mr\tr5,Priority\n  branchl\tr12,GObj_AddProc\n\n#Give Task Some Data Space\n  li\tr3,EventData_DataSize\t\t#50 bytes of space\n  branchl\tr12,HSD_MemAlloc\t\t#HSD_MemAlloc\n  mr\tEventData,r3\n\n#Initalize GObj\n  mr\tr6,r3\n  mr\tr3,EventGObj\t\t#task space\n  li\tr4,0x0\t\t#typedef\n  load\tr5,HSD_Free\t\t#destructor (HSD_Free)\n  branchl\tr12,GObj_AddUserData\t\t#Create Data Block\n\n#Zero Dataspace\n  mr\tr3,EventData\n  li\tr4,EventData_DataSize\n  branchl\tr12,ZeroAreaLength\t\t#zero length\n\n##############################\n## Create Option Menu Think ##\n##############################\n\n#Check if Option Menu is enabled for this event\n  cmpwi WindowOptionCount,0\n  beq CreateEventThinkFunction_NoOptionMenu\n\n#Create GObj\n  li\tr3,6\t\t#GObj Type\n  li\tr4,0\t\t#On-Pause Function\n  li\tr5,80\n  branchl\tr12,GObj_Create\n\n#Backup Allocation\n  mr\tMenuGObj,r3\n\n#Schedule Task\n  bl  OptionMenuThink\n  mflr r4\n  li\tr5,22          #Last Function to Run\n  branchl\tr12,GObj_AddProc\n\n#Give Task Some Data Space\n  li\tr3,MenuData_DataSize\t\t#50 bytes of space\n  branchl\tr12,HSD_MemAlloc\t\t#HSD_MemAlloc\n  mr\tMenuData,r3\n\n#Initalize GObj\n  mr\tr6,MenuData\n  mr\tr3,MenuGObj\t\t#task space\n  li\tr4,0x0\t    \t#typedef\n  load\tr5,HSD_Free\t\t#destructor (HSD_Free)\n  branchl\tr12,GObj_AddUserData\t\t#Create Data Block\n\n#Zero Dataspace\n  mr\tr3,MenuData\n  li\tr4,MenuData_DataSize\n  branchl\tr12,ZeroAreaLength\t\t#zero length\n\n#Store Option Menu info to Dataspace\n  stw WindowOptionCount,MenuData_WindowOptionCountPointer(MenuData)\n  stw ASCIIStruct,MenuData_ASCIIStructPointer(MenuData)\n\n#Store Pointers to Each Other\n  stw MenuData,EventData_MenuDataPointer(EventData)\n  stw EventData,MenuData_EventDataPointer(MenuData)\nCreateEventThinkFunction_NoOptionMenu:\n\n#Disable Hazards\n\tbl\tDisableHazards\n\nCreateEventThinkFunction_Exit:\nrestore\nblr\n\n####################################\n## Create Option Menu When Paused ##\n####################################\n\nOptionMenuThink:\nblrl\n\n.set MenuData,31\n\nbackup\n\n#Load Data Pointer\n  lwz MenuData,0x2C(r3)\n\n#Check If Paused\n  li  r3,1\n  branchl r12,DevelopMode_FrameAdvanceCheck\n  cmpwi r3,0x2\n  bne OptionMenuThink_Exit\n\n#Run OptionThink Code\nOptionMenuThink_CheckInputs:\n  addi r3,MenuData,MenuData_OptionMenuMemory\n  lwz r4,MenuData_WindowOptionCountPointer(MenuData)\n  lwz r5,MenuData_ASCIIStructPointer(MenuData)\n  bl\tOptionWindow\n\n#Store Modified Option Bool\n  cmpwi r3,0\n  beq OptionMenuThink_Exit\n  addi r5,MenuData,MenuData_OptionMenuToggled\n  stbx r3,r4,r5\n\nOptionMenuThink_Exit:\nrestore\nblr\n\n##########################\n## Clear Option Toggled ##\n##########################\n\nClearToggledOptions:\n\n#in\n#r3 = Menu Data\n\n#Get Amount of Options\n  lwz r4,MenuData_WindowOptionCountPointer(r3)\n  lbz r4,0x0(r4)\n\n#Loop Through All Data\n  addi r3,r3,MenuData_OptionMenuToggled\n  li  r5,0\n\nClearToggledOptions_Loop:\n  stbx r5,r3,r4     #Zero Byte\n  subi r4,r4,1\n  cmpwi r4,0\n  bge ClearToggledOptions_Loop\n\nClearToggledOptions_Exit:\n  blr\n\n######################\n## Save States Main ##\n######################\n\n\n#0x0 -> 0x23EC = player block\n#0x23EC -> 0x24EC = Static Block\n#0x24EC = Camera Flag\n\n\n\n\n\n\n################################\n## Save State Quick Functions ##\n################################\n\nSaveState_Save:\n.set REG_SaveStruct,31\n.set REG_PlayerTotal,30\n.set REG_LoopCount,29\n.set REG_isSubchar,23\n.set REG_Backup,28\n.set REG_SpawnedOrder,22\n.set REG_PlayerGObj,25\n.set REG_PlayerData,26\n.set REG_PlayerDataSize,24\n.set REG_PlayerData_Backup,27\n\n\tbackup\n\n#Backup Task Data\n\tmr\tREG_SaveStruct,r3\n#Backup \"skip failsafe\" bool\n\tmr\tr20,r4\n\n#Count Players in Match\n\tbranchl\tr3,0x8016b558\n\n#Move Player Number to REG_PlayerTotal\n\tmr\tREG_PlayerTotal,r3\n\n#Check to run failsafe code\n\tcmpwi r20,0x0\n\tbne SaveState_SaveLoopInit\n\nSaveState_OnDeathCheck:\n#Mini loop to make sure no players have on-death functions\n\tli\tREG_LoopCount,0x0\t\t#player ID\n\tli\tREG_isSubchar,0x0\t\t#main/sub char bool\nSaveState_OnDeathCheckLoop:\n#Get Proper Player Data\n\tmr\t\tr3,REG_LoopCount\n\tmr\t\tr4,REG_isSubchar\n\tbl\t\tSaveState_GetPlayerDataPointer  #returns player slot,player pointer and player data\n\tcmpwi\t\tr3,0xFF\t\t\t\t                #check if player didnt exist\n\tbeq\t\tSaveState_OnDeathCheckInc\t\t\t\t#move on with loop\n#Check for on-death function\n\tlwz\t\tr3,0x21E0(r5)\n  cmpwi r3,0x0\n  bne SaveState_OnDeathCheckExit\n\tlwz\t\tr3,0x21E4(r5)\n  cmpwi r3,0x0\n  bne SaveState_OnDeathCheckExit\n\tlwz\t\tr3,0x21E8(r5)\n  cmpwi r3,0x0\n  bne SaveState_OnDeathCheckExit\n#Check if holding an item\n\tlwz\t\tr3,0x1974(r5)\n  cmpwi r3,0x0\n  bne SaveState_OnDeathCheckExit\n\tlwz\t\tr3,0x1978(r5)\n  cmpwi r3,0x0\n  bne SaveState_OnDeathCheckExit\n#Check for fighter accessory\n\tlwz\t\tr3,0x20A0(r5)\n  cmpwi r3,0x0\n  bne SaveState_OnDeathCheckExit\n  b SaveState_OnDeathCheckInc\n\nSaveState_OnDeathCheckExit:\n#PLay Error SFX\n  li\tr3,0xAF\n  bl  PlaySFX\n  li\tr3,0xAF\n  bl  PlaySFX\n  b SaveState_SaveExit\n\nSaveState_OnDeathCheckInc:\n#Check For Subchar Before Looping\n\tcmpwi\t\tREG_isSubchar,0x1\n\tbeq\t\tSaveState_OnDeathCheck_ToggleSubCharOff\n\tli\t\tREG_isSubchar,0x1\n\tb\t\tSaveState_OnDeathCheckLoop\nSaveState_OnDeathCheck_ToggleSubCharOff:\n\tli\t\tREG_isSubchar,0x0\n\taddi\t\tREG_LoopCount,REG_LoopCount,0x1\n\tcmpw\t\tREG_LoopCount,REG_PlayerTotal\n\tblt\t\tSaveState_OnDeathCheckLoop\n\nSaveState_SaveLoopInit:\n\t#Init Save Loop\n\tli\tREG_LoopCount,0x0\t\t#player ID\n\tli\tREG_isSubchar,0x0\t\t#main/sub char bool\n\n\t\tSaveState_SaveLoop:\n\t\t#Get This Player's Backup Pointer in REG_Backup\n\t\tmulli\t\tr4,REG_LoopCount,0x8\t\t#8 bytes per player pointer\n\t\tadd\t\tREG_Backup,r4,REG_SaveStruct\t\t#REG_Backup contains this players block backup\n\n\t\t#Check If Backup Exists\n\t\tcmpwi\t\tREG_isSubchar,0x0\n\t\tbeq\t\tSaveState_Save_MainChar\n\t\tSaveState_Save_SubChar:\n\t\tlwz \t\tr3,0x4(REG_Backup)\t\t#get pointer to backup if it exists\n\t\tb\t\tSaveState_Save_CheckIfExists\n\t\tSaveState_Save_MainChar:\n\t\tlwz \t\tr3,0x0(REG_Backup)\t\t#get pointer to backup if it exists\n\t\tSaveState_Save_CheckIfExists:\n\t\tcmpwi\t\tr3,0x0\n\t\tbeq\t\tSaveState_SaveStart\n\n\t\t#Remove Old Backup (HSD_Free)\n\t\tbranchl\t\tr12,HSD_Free\n\n\n\n\t\tSaveState_SaveStart:\n\n\t\t#Get Proper Player Data\n\t\tmr\t\tr3,REG_LoopCount\n\t\tmr\t\tr4,REG_isSubchar\n\t\tbl\t\tSaveState_GetPlayerDataPointer\t\t#returns player slot,player pointer and player data\n\t\tcmpwi\t\tr3,0xFF\t\t\t\t#check if player didnt exist\n\t\tbeq\t\tSaveState_SaveLoopInc\t\t\t\t#move on with loop\n\t\tmr\t\tREG_SpawnedOrder,r3\t\t\t\t#REG_SpawnedOrder contains actual player slot\n\t\tmr\t\tREG_PlayerData,r5\t\t\t\t#REG_PlayerData contains real player block\n\n\t\t#Get Player Data Length\n\t\tSaveState_Save_GetPlayerBlockLength:\n\t\tload\t\tr3,0x80458fd0\n\t\tlwz    \tREG_PlayerDataSize,0x20(r3)\t\t\t#get player block length in REG_PlayerDataSize\n\t\taddi\t\tr3,REG_PlayerDataSize,0x100\t\t\t#add static block length\n\t\taddi\t\tr3,r3,0x10\t\t\t#add additional storage\n\t\tbranchl\t\tr12,HSD_MemAlloc\t\t\t#HSD_MemAlloc\n\n\t\t#Store Pointer To Task Struct\n\t\tcmpwi\t\tREG_isSubchar,0x0\n\t\tbne\t\tSavestate_Save_StoreBackupSubChar\n\t\tstw\t\tr3,0x0(REG_Backup)\n\t\tb\t\tSavestate_Save_StoreBackupEnd\n\t\tSavestate_Save_StoreBackupSubChar:\n\t\tstw\t\tr3,0x4(REG_Backup)\n\t\tSavestate_Save_StoreBackupEnd:\n\t\tmr\t\tREG_PlayerData_Backup,r3\t\t\t\t#REG_PlayerData_Backup contains playerblock backup\n\n\t\t#Copy Player Block to Backup\n\t\tmr\t\tr3,REG_PlayerData_Backup\t\t\t#r3 = destination to copy to\n\t\tmr\t\tr4,REG_PlayerData\t\t\t#r4 = source\n\t\tmr \t\tr5,REG_PlayerDataSize\t\t\t#r5 = playerblock length\n\t\tbranchl\t\tr12,memcpy\t\t\t#mempcy\n\n\n\t\t#Copy Static Block to Backup\n\t\t\tcmpwi REG_isSubchar,0x0\t\t\t\t\t#unless this is a subcharacter\n\t\t\tbne\tSavestate_Save_SkipStaticBlockBackup\n\t\t\tadd\t\tr3,REG_PlayerDataSize,REG_PlayerData_Backup\t\t\t#get end of playerblock in r4\n\t\t\tload\t\tr4,0x80453080\t\t\t#get static block in r4\n\t\t\tli\t\tr5,0xE90\n\t\t\tmullw\t\tr5,r5,REG_SpawnedOrder\n\t\t\tadd\t\tr4,r4,r5\n\t\t\tli\t\tr5,0x100\t\t\t#only copying the first 100 bytes\n\t\t\tbranchl\t\tr12,memcpy\t\t\t#mempcy\n\t\tSavestate_Save_SkipStaticBlockBackup:\n\n\t\t#Save Camera Flag\n\t\tlwz\t\tr3,0x890(REG_PlayerData)\n\t\tlwz\t\tr3,0x8(r3)\n\t\tadd\t\tr4,REG_PlayerDataSize,REG_PlayerData_Backup\t\t#get end of player block in r4\n\t\taddi\t\tr4,r4,0x100\t\t#get end of static block\n\t\tstw\t\tr3,0x0(r4)\t\t#store to end of block\n\n\t\tSaveState_SaveLoopInc:\n\t\t#Check For Subchar Before Looping\n\t\tcmpwi\t\tREG_isSubchar,0x1\n\t\tbeq\t\tSaveState_SaveLoopInc_ToggleSubCharOff\n\t\tli\t\tREG_isSubchar,0x1\n\t\tb\t\tSaveState_SaveLoop\n\n\t\tSaveState_SaveLoopInc_ToggleSubCharOff:\n\t\tli\t\tREG_isSubchar,0x0\n\t\taddi\t\tREG_LoopCount,REG_LoopCount,0x1\n\t\tcmpw\t\tREG_LoopCount,REG_PlayerTotal\n\t\tblt\t\tSaveState_SaveLoop\n\nSaveState_SaveExit:\n\trestore\n\tblr\n\nSaveState_Load:\n.set REG_SaveStruct,31\n.set REG_PlayerTotal,30\n.set REG_LoopCount,29\n.set REG_isSubchar,23\n.set REG_Backup,28\n.set REG_SpawnedOrder,22\n.set REG_PlayerGObj,25\n.set REG_PlayerData,26\n.set REG_PlayerDataSize,24\n.set REG_PlayerData_Backup,27\n\n\n\tbackup\n\n\tmr\tREG_SaveStruct,r3\n\n\t#Count Players in Match\n\tbranchl\tr3,0x8016b558\n\n\t#Move Player Number to REG_PlayerTotal\n\tmr\tREG_PlayerTotal,r3\n\n\t#Restore Camera Info Here\n\n\n\t#Init Load Loop\n\tli\tREG_LoopCount,0x0\t\t#player count\n\tli\tREG_isSubchar,0x0\t\t#main/subchar bool\n\n\t\tSaveState_LoadLoop:\n\t\t#Get This Player's Backup Pointer in REG_Backup\n\t\tmulli\t\tr4,REG_LoopCount,0x8\t\t#8 bytes per player pointer\n\t\tadd\t\tREG_Backup,r4,REG_SaveStruct\t\t#REG_Backup contains this players block backup\n\n\t\t#Check If Backup Exists\n\t\tcmpwi\t\tREG_isSubchar,0x0\n\t\tbeq\t\tSaveState_Load_MainChar\n\t\tSaveState_Load_SubChar:\n\t\tlwz \t\tr3,0x4(REG_Backup)\t\t#get pointer to backup if it exists\n\t\tb\t\tSaveState_Load_CheckIfExists\n\t\tSaveState_Load_MainChar:\n\t\tlwz \t\tr3,0x0(REG_Backup)\t\t#get pointer to backup if it exists\n\t\tSaveState_Load_CheckIfExists:\n\t\tcmpwi\t\tr3,0x0\n\t\tbeq\t\tSaveState_LoadLoopInc\n\n\n\t\tSaveState_LoadStart:\n\n\t\t#Get Proper Player Data\n\t\tmr\t\tr3,REG_LoopCount\n\t\tmr\t\tr4,REG_isSubchar\n\t\tbl\t\tSaveState_GetPlayerDataPointer\t\t#returns player slot,player pointer and player data\n\t\tcmpwi\t\tr3,0xFF\t\t\t\t#check if player didnt exist\n\t\tbeq\t\tSaveState_LoadLoopInc\t\t\t\t#move on with loop\n\t\tmr\t\tREG_SpawnedOrder,r3\t\t\t\t#REG_SpawnedOrder contains actual player slot\n\t\tmr\t\tREG_PlayerGObj,r4\t\t\t\t#REG_PlayerGObj contains external player\n\t\tmr\t\tREG_PlayerData,r5\t\t\t\t#REG_PlayerData contains real player block\n\n\t\t#Get Player Block Length in REG_PlayerDataSize\n\t\tSaveState_Load_GetPlayerBlockLength:\n\t\tload\t\tREG_PlayerDataSize,0x80458fd0\n\t\tlwz    \t\tREG_PlayerDataSize,0x20(REG_PlayerDataSize)\t\t#REG_PlayerDataSize = length\n\n\t\t#Get Pointer From Task Struct\n\t\tcmpwi\t\tREG_isSubchar,0x0\t\t#check if subcharacter\n\t\tbeq\t\tSavestate_Load_GetBackupMainChar\n\t\tSavestate_Load_GetBackupSubChar:\n\t\tlwz\t\tREG_PlayerData_Backup,0x4(REG_Backup)\t\t#REG_PlayerData_Backup contains playerblock backup\n\t\tb\t\tSavestate_Load_RestoreFacingDirection\n\t\tSavestate_Load_GetBackupMainChar:\n\t\tlwz\t\tREG_PlayerData_Backup,0x0(REG_Backup)\t\t#REG_PlayerData_Backup contains playerblock backup\n\n\t\t#Restore Facing Direction\n\t\tSavestate_Load_RestoreFacingDirection:\n\t\tlwz\t\tr3,0x2C(REG_PlayerData_Backup)\t\t#backed up Facing Direction\n\t\tstw\t\tr3,0x2C(REG_PlayerData)\n\n\t\t#Enter Into Sleep\n\t\tmr\t\tr3,REG_PlayerGObj\n\t\tli\t\tr4,0x0\n\t\tbranchl\t\tr12,AS_Sleep\n\n\t\t#Remove On Death Function Pointer\n\t\tli\t\tr3,0x0\n\t\tstw\t\tr3,0x21E4(REG_PlayerData)\n\t\tstw\t\tr3,0x21E8(REG_PlayerData)\n\n\t\t#Enter Into Backed Up State\n\t\tmr\t\tr3,REG_PlayerGObj\n\t\tlwz\t\tr4,0x10(REG_PlayerData_Backup)\t\t#backed up AS\n\t\tli\t\tr5,0x0\n\t\tli\t\tr6,0x0\n\t\tlfs\t\tf1,0x894(REG_PlayerData_Backup)\t\t#backed up Frame Number\n\t\tlfs\t\tf2,0x89C(REG_PlayerData_Backup)\t\t#backed up Frame Speed\n\t\tlfs\t\tf3,-0x7548 (rtoc)\n\t\t#lfs\t\tf3,0x8A4(REG_PlayerData_Backup)\t\t#backup up Blend Amount\n\t\tbranchl\t\tr12,ActionStateChange\t\t\t\t\t#ASC\n\n\t\t#Keep Previous Frame Buttons From Current Block\n\t\tlwz\t\tr3,0x620(REG_PlayerData)\n\t\tstw\t\tr3,0xD0(sp)\n\t\tlwz\t\tr3,0x624(REG_PlayerData)\n\t\tstw\t\tr3,0xD4(sp)\n\t\tlwz\t\tr3,0x65C(REG_PlayerData)\n\t\tstw\t\tr3,0xD8(sp)\n\n\t\t#Keep Collision Bubble Toggles\n\t\tlwz\t\tr3,0x21FC(REG_PlayerData)\n\t\tstw\t\tr3,0xDC(sp)\n\n\t\t#Copy PlayerBlock Backup to Current\n\t\tmr\t\tr3,REG_PlayerData\n\t\tmr\t\tr4,REG_PlayerData_Backup\n\t\tmr\t\tr5,REG_PlayerDataSize\n\t\tbranchl\t\tr12,memcpy\t#mempcy\n\n\t\t#Zero Blend\n\t\t#lfs\t f1,-0x7548 (rtoc)\n\t\t#stfs f1,0x8A4(REG_PlayerData)\n\n\t\t#Copy Static Block Backup to Current\n\t\t\tcmpwi REG_isSubchar,0\t\t\t\t\t\t\t\t\t#but not if subcharacter\n\t\t\tbne Savestate_Load_SkipStaticBlockRestore\n\t\t\tload\t\tr3,0x80453080\t\t\t#get static block in r3\n\t\t\tli\t\tr4,0xE90\n\t\t\tmullw\t\tr4,r4,REG_SpawnedOrder\n\t\t\tadd\t\tr3,r3,r4\n\t\t\tadd\t\tr4,REG_PlayerDataSize,REG_PlayerData_Backup\t\t\t#get end of block in r4\n\t\t\tli\t\tr5,0x100\t\t\t#length is 0x100\n\t\t\tbranchl\t\tr12,memcpy\t\t\t#mempcy\n\t\t\tSavestate_Load_SkipStaticBlockRestore:\n\n\t\t#Restore Previous Frame Buttons From Current Block\n\t\tlwz\t\tr3,0xD0(sp)\n\t\tstw\t\tr3,0x620(REG_PlayerData)\n\t\tstw\t\tr3,0x628(REG_PlayerData)\n\t\tlwz\t\tr3,0xD4(sp)\n\t\tstw\t\tr3,0x624(REG_PlayerData)\n\t\tstw\t\tr3,0x62C(REG_PlayerData)\n\t\tlwz\t\tr3,0xD8(sp)\n\t\tstw\t\tr3,0x65C(REG_PlayerData)\n\t\tstw\t\tr3,0x660(REG_PlayerData)\n\t\tstw\t\tr3,0x664(REG_PlayerData)\n\n\t\t#Restore Collision Bubble Toggles\n\t\tlwz\t\tr3,0xDC(sp)\n\t\tstw\t\tr3,0x21FC(REG_PlayerData)\n\n\t\t#Remove Cached Animation Pointer (This fixes the Fall Animation Bug)\n\t\tli\tr3,0x0\n\t\tstw\tr3,0x5A8(REG_PlayerData)\n\n    #Remove Respawn Platform JObj Pointer and Think Function\n    stw r3,0x20A0(REG_PlayerData)\n    stw r3,0x21B0(REG_PlayerData)\n\n    #Remove Held Item Pointer\n    stw r3,0x1974(REG_PlayerData)\n\n    #Update ECB Position\n\t\tmr\t\tr3,REG_PlayerGObj\n\t\tbl  UpdatePosition\n\n    #Stop Player's SFX\n    mr  r3,REG_PlayerData\n    branchl r12,SFX_StopAllCharacterSFX\n\n    #Stop Crowd SFX\n    branchl r12,SFXManager_StopSFXIfPlaying\n\n    #Remove GFX\n    mr  r3,REG_PlayerGObj\n    branchl\tr12,GFX_RemoveAll\n\n\t\t/* #Removing this, causes ground issues when restoring. instead im removing the OSReport call for the error\n\t\t#If Grounded, Change Ground Variable Back\n\t\tlwz\t\tr3,0xE0(REG_PlayerData)\n\t\tcmpwi\t\tr3,0x0\n\t\tbne\t\tSavestate_RestoreCameraFlag\n\t\tli\t\tr3,0x1\n\t\tstw\t\tr3,0x83C(REG_PlayerData)\n\t\t*/\n\n\t\t#Restore Camera Flag\n\t\tSavestate_RestoreCameraFlag:\n\t\tadd\t\tr3,REG_PlayerDataSize,REG_PlayerData_Backup\t\t#get end of block in r4\n\t\taddi\t\tr3,r3,0x100\t\t#static block length = 0x100\n\t\tlwz\t\tr3,0x0(r3)\t\t#get flag\n\t\tlwz\t\tr4,0x890(REG_PlayerData)\n\t\tstw\t\tr3,0x8(r4)\n\n    #Update Camera Box Position\n    mr  r3,REG_PlayerGObj\n    bl  UpdateCameraBox\n\n\t\t#Remake HUD For Dead Players (Taken from Achilles' GitHub)\n\t\tcmpwi\t\tREG_isSubchar,0x1\t\t#dont run this on subcharacters\n\t\tbeq\t\tSaveState_HUD_End\n\t\tload\t\tr3,0x804a10c8\t\t#get base HUD info\n\t\tmulli \t\tr4,REG_SpawnedOrder,100\t\t#get offset\n\t\tadd\t\tr20,r4,r3\t\t#get to this player's HUD info\n\t\tbranchl\t\tr12,0x8016b094\t #MatchInfo_StockModeCheck\n\t\tcmpwi \t\tr3,0\t\t#if not stock mode\n\t\tbeq- \t\tSaveState_RELOAD_PERCENT_HUDS_NOT_STOCK\n\n\t\t\tSaveState_RELOAD_PERCENT_HUDS_STOCK:\n\t\t\tmr\t\tr3,REG_SpawnedOrder\t\t#get player number\n\t\t\tbranchl\t\tr12,0x80033bd8\t\t#get stocks left\n\t\t\tcmpwi \t\tr3,0\n\t\t\tbne- \t\tSaveState_RELOAD_PERCENT_HUDS_NOT_STOCK\n\t\t\tli \t\tr5,0x80\t\t#remove percent\n\t\t\tstb \t\tr5,0x10(r20)\n\t\t\tb \t\tSaveState_HUD_End\n\n\t\t\t\tSaveState_RELOAD_PERCENT_HUDS_NOT_STOCK:\n\t\t\t\tlbz\t\tr5,0x10(r20)\n\t\t\t\trlwinm. \t\tr5,r5,0,24,24\t# (00000080), is player HUD percent gone?\n\t\t\t\tbeq- \t\tSaveState_HUD_End\n\n\t\t\t\tSaveState_REMAKE_PERCENT:\n\t\t\t\t.set \t\tHUD_PlayerCreate_Prefunction, 0x802f6e1c\n\t\t\t\tmr \t\tr3,REG_SpawnedOrder\n\t\t\t\tbranchl\t\tr4, HUD_PlayerCreate_Prefunction\n\n\t\tSaveState_HUD_End:\n\n\t\tSaveState_LoadLoopInc:\n\t\t#Check For Subchar Before Looping\n\t\tcmpwi\t\tREG_isSubchar,0x1\n\t\tbeq\t\tSaveState_LoadLoopInc_ToggleSubCharOff\n\t\tli\t\tREG_isSubchar,0x1\n\t\tb\t\tSaveState_LoadLoop\n\t\tSaveState_LoadLoopInc_ToggleSubCharOff:\n\t\tli\t\tREG_isSubchar,0x0\n\t\taddi\t\tREG_LoopCount,REG_LoopCount,0x1\n\t\tcmpw\t\tREG_LoopCount,REG_PlayerTotal\n\t\tblt\t\tSaveState_LoadLoop\n\n    SaveState_LoadEnd:\n\n    /*\n    SaveState_Load_RemoveAllGFX:\n    #Get First GFX\n      lwz  r3,-0x3E74 (r13)\n      lwz  r20,0x30(r3)\n    #Check if exists\n    SaveState_Load_CheckIfGFXExists:\n      cmpwi r20,0\n      beq SaveState_Load_RemoveAllGFXEnd\n    #Check if this is a particle GObj?\n      lbz r3,0x4(r20)\n      cmpwi r3,1\n      beq SaveState_Load_GetNextGFX\n    #Remove this GFX\n      mr  r3,r20\n      branchl r12,0x80390228\n    #Get next GFX\n    SaveState_Load_GetNextGFX:\n      lwz r20,0x8(r20)\n      b SaveState_Load_CheckIfGFXExists\n    SaveState_Load_RemoveAllGFXEnd:\n    */\n\n  SaveState_LoadExit:\n\trestore\n\tblr\n\n#########################################################################\n\n############################\n## Get PlayerData Pointer ##\n############################\n\nSaveState_GetPlayerDataPointer:\n#r3 = player number (regardless of port)\n#r4 = 0x0 for main char // 0x1 for subchar\n\n#returns:\n#r3 = player slot\n#r4 = external player\n#r5 = internal player\nsubi\tsp,sp,0x8\nmr\tr11,r3\t\t\t#move desired player into r11\nmr\tr10,r4\t\t\t#move subchar status into r4\nmr\tr9,sp\t\t\t#move bytefield into r10\nli\tr3,-0x1\t\t\t#zero out new space\nstw\tr3,0x0(r9)\nstw\tr3,0x4(r9)\n\n#Make Bytefield For Player Order\nli\tr7,0x0\t\t\t#init loop\nli\tr6,0x0\t\t\t#init player ID\nload\tr5,0x80453080\t\t\t#first playerblock\n\n\tSaveState_GetPlayerDataPointer_LoopStart:\n\tlwz\tr3,0x0(r5)\t\t\t#an inactive player block will store \"0\" at offset 0x0\n\tcmpwi\tr3,0x0\n\tbeq\tSaveState_GetPlayerDataPointer_Empty\n\n\tSaveState_GetPlayerDataPointer_PlayerPresent:\n\tstbx\tr7,r6,r9\t\t\t#store loop count to player ID offset\n\taddi\tr6,r6,0x1\t\t\t#next player ID\n\n\tSaveState_GetPlayerDataPointer_Empty:\n\taddi\tr5,r5,0xe90\t\t\t#next playerblock\n\taddi\tr7,r7,0x1\t\t\t#inc loop\n\tcmpwi\tr7,6\n\tblt\tSaveState_GetPlayerDataPointer_LoopStart\n\n#Now r9 contains player bytefield\nlbzx\tr3,r11,r9\t\t\t#get the correct player slot for the X player\ncmpwi\tr3,0xFF\t\t\t#check if player exists\nbeq\tSaveState_GetPlayerDataPointer_Exit\t\t\t#if not exit with -1 return\n\nload\tr5,0x80453080\t\t\t#first playerblock\nmulli\tr4,r3,0xe90\t\t\t#get offset\nadd\tr4,r4,r5\t\t\t#get static block in r4\n\ncmpwi\tr10,0x0\nbeq\tSaveState_GetPlayerDataPointer_MainChar\n\nSaveState_GetPlayerDataPointer_SubChar:\nlwz\tr4,0xB4(r4)\nb\tSaveState_GetPlayerDataPointer_LoadInternal\nSaveState_GetPlayerDataPointer_MainChar:\nlwz\tr4,0xB0(r4)\nSaveState_GetPlayerDataPointer_LoadInternal:\n#Check If Player Exists\ncmpwi\tr4,0x0\nbne\tSaveState_GetPlayerDataPointer_LoadInternalContinue\nli\tr3,0xFF\nb\tSaveState_GetPlayerDataPointer_Exit\nSaveState_GetPlayerDataPointer_LoadInternalContinue:\nlwz\tr5,0x2c(r4)\n\nSaveState_GetPlayerDataPointer_Exit:\naddi\tsp,sp,0x8\nblr\n\n#######################################################\n\nCheckForSaveAndLoad:\n\n.set LoopCount,31\n\nbackup\n\nmr\tr29,r3\t\t#Task Data\n\n#Init Loop\n  li  LoopCount,0\n#Loop\nCheckForSaveAndLoad_Loop:\n  mr  r3,LoopCount\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n  cmpwi r3,0x0\n  beq CheckForSaveAndLoad_Inc\nCheckForSaveAndLoad_CheckInputs:\n  load r3,0x804c21cc\n  #load r3,0x804c1fac\n  mulli r0,LoopCount,68\n  add r4,r3,r0\n#Make Sure Nothing Else Is Held\n  lhz\tr3,0x2(r4)\n  rlwinm.  r0,r3,0,0,26\n  bne\tCheckForSaveAndLoad_Inc\n  lwz\tr3,0x8(r4)\n  rlwinm.\tr0,r3,0,30,30\n  beq\tCheckForSaveAndLoad_NoSave\n  mr\tr3,r29\n\tli\tr4,0\t\t\t#run failsafe code\n  bl\tSaveState_Save\n  li\tr3,0x0\n  b\tCheckForSaveAndLoad_Exit\nCheckForSaveAndLoad_NoSave:\n  rlwinm.\tr0,r3,0,31,31\n  beq\tCheckForSaveAndLoad_Inc\n  mr\tr3,r29\n  bl\tSaveState_Load\n  mr\tr3,r29\n  bl\tSaveState_Load\n  li\tr3,0x1\n  b\tCheckForSaveAndLoad_Exit\n\nCheckForSaveAndLoad_Inc:\n  addi LoopCount,LoopCount,1\n  cmpwi LoopCount,4\n  blt CheckForSaveAndLoad_Loop\n\nCheckForSaveAndLoad_Exit:\nrestore\nblr\n\n############################################\n\nGiveFullShields:\nbackup\n\nGiveFullShields_GetFirstPlayer:\nlwz\tr3, -0x3E74 (r13)\nlwz\tr20, 0x0020 (r3)\nb\tGiveFullShields_CheckIfPlayerExists\n\nGiveFullShields_GetNextPlayer:\nlwz\tr20,0x8(r20)\n\nGiveFullShields_CheckIfPlayerExists:\ncmpwi\tr20,0x0\nbeq\tGiveFullShields_Exit\nlwz\tr21,0x2C(r20)\n\n#Give Full Shield\nlwz\tr3, -0x514C (r13)\nlfs\tf0, 0x0260 (r3)\nstfs\tf0,0x1998(r21)\nb\tGiveFullShields_GetNextPlayer\n\n\nGiveFullShields_Exit:\n\nrestore\nblr\n\n############################################\n\nUpdateAllGFX:\nbackup\n\nmr\tr3,30\nbranchl\tr12,GFX_UpdatePlayerGFX\n\n#Check For Follower\nmr\tr3,r30\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0x0\nbeq\t\tUpdateAllGFX_Exit\n\n#Apply To Follower Char\nbranchl\tr12,GFX_UpdatePlayerGFX\n\nUpdateAllGFX_Exit:\nrestore\nblr\n\n############################################\n\nGiveInvincibility:\n#r3 = ext pointer\n#r4 = frames\n\nbackup\n\n#Give To Main Char\nmr\tr31,r3\nmr\tr30,r4\nbranchl\tr12,ApplyInvincibility\n\n#Check For Follower\nmr\tr3,r31\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0x0\nbeq\t\tGiveInvincibility_Exit\n\n#Apply To Follower Char\nmr\tr4,r30\nbranchl\tr12,ApplyInvincibility\n\nGiveInvincibility_Exit:\nrestore\nblr\n\n############################################\nStoreCPUTypeAndZeroInputs:\n\n#Set P2 AI Type to None\n#li\tr3,0xF\n#stw\tr3,0x1A94(r29)\n\n#Clear Inputs For P2 CPU\nli\tr3,0x0\nstw\tr3,0x1A88(r29)\nstw\tr3,0x1A8C(r29)\nsth\tr3,0x1A90(r29)\nblr\n\n###########################################\n\nClearNanaInputs:\nbackup\n\n#Clear Inputs if P1 is Ice Climbers\nmr\tr3,28\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0x0\nbeq\tClearNanaInputs_P2\nli\tr3,0x0\nstw\tr3,0x1A88(r4)\nstw\tr3,0x1A8C(r4)\n\n#Clear Inputs if P2 is Ice Climbers\nClearNanaInputs_P2:\nmr\tr3,30\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0x0\nbeq\tClearNanaInputs_Exit\nli\tr3,0x0\nstw\tr3,0x1A88(r4)\nstw\tr3,0x1A8C(r4)\n\nClearNanaInputs_Exit:\nrestore\nblr\n\n###########################################\n\nCheckIfFirstFrame:\nlwz r3,TM_GameFrameCounter(r13)\ncmpwi\tr3,0x1\nbne\tCheckIfFirstFrame_False\nli\tr3,0x1\nb\tCheckIfFirstFrame_Exit\nCheckIfFirstFrame_False:\nli\tr3,0x0\nCheckIfFirstFrame_Exit:\nblr\n\n#############################################\n\nCurrentInputsAsLastFramesInputs:\nload r3,0x804c21cc\nlwz\tr3,0x0(r3)\nstw\tr3,0x65C(r27)\nstw\tr3,0x664(r27)\n\n#Check For Z Press\nrlwinm.\tr0, r3, 0, 27, 27\nbeq\tCurrentInputsAsLastFramesInputs_Exit\noris\tr0, r3, 0x8000\nori\tr0, r0, 0x0100\nstw\tr0,0x65C(r27)\nstw\tr0,0x664(r27)\n\nCurrentInputsAsLastFramesInputs_Exit:\nblr\n\n#############################################\n\n/*\n\nCPUActions_MultiShine:\nbackup\n\nmr\tr29,r3\n\n#Get AS and Frame Number\nlwz\tr4,0x10(r3)\t\t#Get Current AS\n\n#Start - Check to Grounded Shine\ncmpwi\tr4,0xE\t\t#Wait\nbeq\tMultishine_StartShine\ncmpwi\tr4,0x169\t\t#Shine Loop Ground\nbeq\tMultishine_JumpCancelShine\ncmpwi\tr4,0x19\t\t#JumpF\nbeq\tMultishine_StartShine\nb       CPUActions_MultiShine_Exit\n\nMultishine_StartShine:\nli\tr3,-127\t\t#Down\nstb\tr3,0x1A8D(r29)\t\t#Analog Y\nli\tr3,0x200\t\t#B\nstw\tr3,0x1A88(r29)\t #Inputs\nb\tCPUActions_MultiShine_Exit\n\nMultishine_JumpCancelShine:\nli\tr3,0x800\t\t#X\nstw\tr3,0x1A88(r29)\t #Inputs\nb\tCPUActions_MultiShine_Exit\n\nMultishine_ShineAir:\nb\tCPUActions_MultiShine_Exit\n\nCPUActions_MultiShine_Exit:\nrestore\nblr\n\n*/\n\n\n###################################\n\nRAndDPadChangesEventOption:\nOptionWindow:\n#in\n#r3 = pointer to option byte in memory\n#r4 = pointer to Window and Option Count\n#r5 = pointer to ASCII struct\n\n#out\n#r3 =\n\n.set TextCreateFunction,0x80005928\n.set OptionWindowMemory,20\n.set OptionTextInfo,21\n.set OptionASCII,22\n.set text,23\n.set toggledBool,28\n.set toggledOption,29\n\n\nbackup\n\n\n#Backup Parameters\nmr\tOptionWindowMemory,r3\t\t#pointer to option byte in memory\nmr\tOptionTextInfo,r4\t\t#pointer to Window and Option Count\nmr\tOptionASCII,r5\t\t#pointer to ASCII struct\n\n#Initialize Toggled Bools\nli\ttoggledBool,0\nli\ttoggledOption,-1\n\n#Get Number Of Options Onscreen At Once (1,2,or 3)\nlbz\tr24,0x0(OptionTextInfo)\t\t#Get Number of Different Windows\ncmpwi\tr24,2\t\t#Check If Over 3\nble\t0x8\nli\tr24,2\t\t#Make 3\n\n#Get Pausing Player's Inputs\nload r3,0x8046b6a0\nlbz r3,0x1(r3)\nload r4,0x804c1fac\nmulli r3,r3,68\nadd r3,r3,r4\nlwz r3,0x8(r3)\n\n#Check For DPad Up And Down\ncmpwi\tr3,0x04\nbeq\tRAndDPadChangesEventOption_CursorDown\ncmpwi\tr3,0x08\nbeq\tRAndDPadChangesEventOption_CursorUp\nb\tRAndDPadChangesEventOption_CheckDPadLeftAndRight\n\nRAndDPadChangesEventOption_CursorUp:\n#Update Cursor Position\n\tlbz\tr3,0x0(OptionWindowMemory)\t\t#Get Current Cursor Position Byte\n\tsubi\tr3,r3,0x1\t\t#Subtract by 1\n\tstb\tr3,0x0(OptionWindowMemory)\n\tcmpwi\tr3,0x0\n\tbge\tRAndDPadChangesEventOption_PlayScrollSFX\n#Cursor Stays at the top of the screen\n\tli\tr3,0\n\tstb\tr3,0x0(OptionWindowMemory)\n#Check To Scroll Down\n\t#Get Current Window ID (cursor + scroll)\n\t\tlbz\tr3,0x0(OptionWindowMemory)\n\t\tlbz\tr4,0x1(OptionWindowMemory)\n\t\tadd\tr3,r3,r4\n\t#Check If This is the Beginning\n\t\tcmpwi\tr3,0\n\t\tble\tRAndDPadChangesEventOption_DisplayWindow\n\t#Scroll Down\n\t\tlbz\tr4,0x1(OptionWindowMemory)\n\t\tsubi\tr4,r4,1\n\t\tstb\tr4,0x1(OptionWindowMemory)\n    b RAndDPadChangesEventOption_PlayScrollSFX\n\nb\tRAndDPadChangesEventOption_DisplayWindow\n\nRAndDPadChangesEventOption_CursorDown:\n#Update Cursor Position\n\tlbz\tr3,0x0(OptionWindowMemory)\t\t#Get Current Option Byte\n\taddi\tr3,r3,0x1\t\t#Add 1\n\tstb\tr3,0x0(OptionWindowMemory)\n\tcmpw\tr3,r24\n\tble\tRAndDPadChangesEventOption_PlayScrollSFX\n#Cursor Stays at the Bottom of the Screen\n\tstb\tr24,0x0(OptionWindowMemory)\n#Check To Scroll Down\n\t#Get Current Window ID (cursor + scroll)\n\t\tlbz\tr3,0x0(OptionWindowMemory)\n\t\tlbz\tr4,0x1(OptionWindowMemory)\n\t\tadd\tr3,r3,r4\n\t#Get Max Number Of Windows\n\t\tlbz\tr4,0x0(OptionTextInfo)\t\t#Get Number of Different Windows\n\t#Check If This is the End\n\t\tcmpw\tr3,r4\n\t\tbge\tRAndDPadChangesEventOption_DisplayWindow\n\t#Scroll Down\n\t\tlbz\tr4,0x1(OptionWindowMemory)\n\t\taddi\tr4,r4,1\n\t\tstb\tr4,0x1(OptionWindowMemory)\n\nb\tRAndDPadChangesEventOption_PlayScrollSFX\n\n#Check For DPad Left And Right\nRAndDPadChangesEventOption_CheckDPadLeftAndRight:\ncmpwi\tr3,0x02\nbeq\tRAndDPadChangesEventOption_Increment\ncmpwi\tr3,0x01\nbeq\tRAndDPadChangesEventOption_Decrement\nb\tRAndDPadChangesEventOption_DisplayWindow\n\nRAndDPadChangesEventOption_Increment:\n#Get Current Window ID (cursor + scroll)\n\tlbz\tr3,0x0(OptionWindowMemory)\n\tlbz\tr4,0x1(OptionWindowMemory)\n\tadd\tr3,r3,r4\n#Set as Toggled\n\tli toggledBool,1\n\tmr\ttoggledOption,r3\n\naddi\tr5,r3,2\nlbzx\tr3,r5,OptionWindowMemory\t\t#Get Current Option Byte\naddi\tr3,r3,0x1\nstbx\tr3,r5,OptionWindowMemory\t\t#Store New Option Byte Value\nsubi\tr5,r5,1\nlbzx\tr4,r5,OptionTextInfo\t\t#Get Window's Option Byte Max Value\ncmpw\tr3,r4\nble\tRAndDPadChangesEventOption_PlayScrollSFX\nli\tr3,0x0\naddi\tr5,r5,1\nstbx\tr3,r5,OptionWindowMemory\t\t#Get New Option Byte Value\nb\tRAndDPadChangesEventOption_PlayScrollSFX\n\nRAndDPadChangesEventOption_Decrement:\n#Get Current Window ID (cursor + scroll)\n\tlbz\tr3,0x0(OptionWindowMemory)\n\tlbz\tr4,0x1(OptionWindowMemory)\n\tadd\tr3,r3,r4\n#Set as Toggled\n\tli toggledBool,1\n\tmr toggledOption,r3\n\naddi\tr5,r3,0x2\nlbzx\tr3,r5,OptionWindowMemory\t\t#Get Current Option Byte\nsubi\tr3,r3,0x1\nstbx\tr3,r5,OptionWindowMemory\t\t#Store New Option Byte Value\ncmpwi\tr3,0x0\nbge\tRAndDPadChangesEventOption_PlayScrollSFX\nsubi\tr5,r5,1\nlbzx\tr3,r5,OptionTextInfo\t\t#Get Window's Option Byte Max Value\naddi\tr5,r5,1\nstbx\tr3,r5,OptionWindowMemory\t\t#Store New Option Byte Value\nb\tRAndDPadChangesEventOption_PlayScrollSFX\n\nRAndDPadChangesEventOption_PlayScrollSFX:\nli  r3,0x2\nbranchl r12,SFX_MenuCommonSound\n\nRAndDPadChangesEventOption_DisplayWindow:\n#Display Text For The New Option Value\nmr\tr3,r27\t\t\t#p1 (no offsetting window)\nli\tr4,1\t\t\t  #text timeout\nli\tr5,0x2\t\t\t#window instance #3\nli\tr6,0\t\t\t  #window ID #3\nbranchl\tr12,TextCreateFunction\t\t#create text custom function\nmr\ttext,r3\t\t\t#backup text pointer\n\n\n#########################\n## Display Option Menu ##\n#########################\n\n\t\t#Check How Many Options In The Menu\n\t\tcmpwi\tr24,0\n\t\tbeq\tRAndDPadChangesEventOption_DisplayWindow_LoopInit\n\n\t\t#Change Background Size\n\t\tbl\tRAndDPadChangesEventOption_Floats\n\t\tmflr\tr5\n\t\tlfs\tf1,0x0(r5)\t\t#12.5\n\t\taddi\tr5,r5,0x4\t\t#Skip Window X\n\t\tsubi\tr6,r24,1\t\t#Zero Index\n\t\tmulli\tr6,r6,0x4\t\t#Get Y Offset\n\t\tlfsx\tf2,r6,r5\n\t\tli\tr4,0\n\t\tbranchl\tr12,Text_UpdateSubtextSize\n\n\t\t#Move Window\n\t\tbl\tRAndDPadChangesEventOption_Floats\n\t\tmflr\tr5\n\t\tlfs\tf1, -0x37B4 (rtoc)\n\t\taddi\tr5,r5,0xC\t\t#Skip Window X and Window Y's\n\t\tsubi\tr6,r24,1\t\t#Zero Index\n\t\tmulli\tr6,r6,0x4\t\t#Get Y Offset\n\t\tlfsx\tf2,r6,r5\n\t\tmr\tr3,text\n\t\tli\tr4,0\n\t\tbranchl\tr12,Text_UpdateSubtextPosition\n\n############################\n## Display Up/Down Arrows ##\n############################\n\n#Check if at the top of the screen\n  lbz r3,0x1(r20)\n  cmpwi r3,0x0\n  beq RAndDPadChangesEventOption_DisplayDownArrow\n#Create Title Text\n\tli r3,-20        #Y\n  bl  IntToFloat\n  fmr f2,f1\n  li  r3,-210      #X\n  bl  IntToFloat\n\tmr \tr3,text\t\t\t#text pointer\n\tbl  RAndDPadChangesEventOption_UpArrowText\n  mflr r4\n\tbranchl r12,Text_InitializeSubtext\n\nRAndDPadChangesEventOption_DisplayDownArrow:\n#Check if at the bottom of the screen\n  lbz r3,0x0(r21)\n  cmpwi r3,2\n  blt RAndDPadChangesEventOption_DisplayArrowExit\n  lbz r4,0x1(r20)\n  sub r3,r3,r4\n  cmpwi r3,2\n  ble RAndDPadChangesEventOption_DisplayArrowExit\n#Create Title Text\n  li  r3,320      #Y value\n  bl  IntToFloat\n  fmr f2,f1\n  li  r3,-210     #X Value\n  bl  IntToFloat\n\tmr \tr3,text\t\t\t#text pointer\n\tbl  RAndDPadChangesEventOption_DownArrowText\n  mflr r4\n\tbranchl r12,Text_InitializeSubtext\n\nRAndDPadChangesEventOption_DisplayArrowExit:\n\n############################\n## Print Each Option Loop ##\n############################\n\n\tRAndDPadChangesEventOption_DisplayWindow_LoopInit:\n\n\t\tli\tr27,0\t\t\t#Init Loop\n\n\tRAndDPadChangesEventOption_DisplayWindow_Loop:\n\n\t\t#Get Window Title And Option\n\t\t\tmr\tr3,OptionASCII\t\t\t#Option ASCII Start\n\t\t\tlbz\tr4,0x1(OptionWindowMemory)\t\t\t#Get Scroll Position\n\t\t\tadd\tr4,r4,r27\t\t\t#Get Loop Count's Window\n\t\t\taddi\tr5,OptionWindowMemory,0x2\t\t\t#Selection ID's\n\t\t\tlbzx\tr5,r4,r5\t\t\t#Get Current Option This Window is On\n\t\t\tbl\tRAndDPadChangesEventOption_GetOptionASCII\n\t\t\tmr\tr25,r3\n\t\t\tmr\tr26,r4\n\n\t\t#Create Title Text\n\t\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text Y\n\t\t\tli\tr3,120\n\t\t\tmullw\tr3,r3,r27\n\t\t\tbl\tIntToFloat\n\t\t\tfadds\tf2,f1,f2\n\t\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X\n\t\t\tmr \tr3,text\t\t\t#text pointer\n\t\t\tmr\tr4,r25\t\t\t#Title Text Pointer\n\t\t\tbranchl r12,Text_InitializeSubtext\n\t\t#Make Text Grey\n\t\t\tload\tr4,0xdfdfdf00\n\t\t\tstw\tr4,0xF0(sp)\n\t\t\taddi\tr5,sp,0xF0\n\t\t\tmr\tr4,r3\n\t\t\tmr\tr3,text\n\t\t\tbranchl\tr12,Text_ChangeTextColor\n\n\t\t#Create Selection Text\n\t\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\t\t\tli\tr3,120\n\t\t\tmullw\tr3,r3,r27\n\t\t\tbl\tIntToFloat\n\t\t\tfadds\tf2,f1,f2\n\t\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\t\tmr \tr3,text\t\t\t#text pointer\n\t\t\tmr\tr4,r26\t\t\t#Selection Text\n\t\t\tbranchl r12,Text_InitializeSubtext\n\t\t#Check To Outline in Yellow\n\t\t\tlbz\tr4,0x0(OptionWindowMemory)\t\t\t#Get Cursor Position\n\t\t\tcmpw\tr4,r27\t\t\t#Compare With Loop Counter\n\t\t\tbne\tRAndDPadChangesEventOption_DisplayWindow_SkipColor\n\t\t\tload\tr4,0xf7ff2700\n\t\t\tstw\tr4,0xF0(sp)\n\t\t\taddi\tr5,sp,0xF0\n\t\t\tmr\tr4,r3\n\t\t\tmr\tr3,text\n\t\t\tbranchl\tr12,Text_ChangeTextColor\n\n\t\tRAndDPadChangesEventOption_DisplayWindow_SkipColor:\n\t\t\tcmpw\tr27,r24\n\t\t\taddi\tr27,r27,1\n\t\t\tblt\tRAndDPadChangesEventOption_DisplayWindow_Loop\n\n\t\tb RAndDPadChangesEventOption_Exit\n\n\n#########################################\n\nRAndDPadChangesEventOption_GetOptionASCII:\n\nbackup\n\n\tmr\tr31,r3\t\t#Option ASCII Start\n\tmr\tr30,r4\t\t#Option ID We're Looking For\n\tmr\tr29,r5\t\t#Option Selection We're Looking For\n\n#Init Loop\n\tli\tr27,0\n\nRAndDPadChangesEventOption_GetOptionASCII_OptionIDLoop:\n\tcmpw\tr27,r30\t\t#Check If This is the Window We're Looking For\n\tbeq\tRAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection\n\n\n\n\t########################\n\t## Skip Entire Option ##\n\t########################\n\n\t\tRAndDPadChangesEventOption_GetOptionASCII_GetNextOptionID:\n\t\t#Skip Past Window Title\n\t\t\tmr\tr3,r31\n\t\t\tbl\tRAndDPadChangesEventOption_GetNextString\n\t\t\tmr\tr31,r3\t\t#Backup New Pointer\n\n\t\t#Loop Through All The Window's Selections\n\t\t\tli\tr26,0\t\t#Loop Count\n\t\tRAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections:\n\t\t#Get This Options (r27) Total Number of Selections (Pointer in OptionTextInfo)\n\t\t\taddi\tr3,OptionTextInfo,0x1\t\t#Get to Option Selection Counts\n\t\t\tlbzx\tr3,r3,r27\t\t#Get This Windows Total Number of Selections\n\t\t\taddi\tr3,r3,0x1\t\t#Add 1 To Ensure We Are at the Start of the Next Window Title\n\t\t\tcmpw\tr3,r26\t\t#Check If This is the Last Selection\n\t\t\tbne\tRAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections_NextSelection\n\n\t\t#End of Loop, Done With This Option\n\t\t#Increment Loop Count\n\t\t\taddi\tr27,r27,1\t\t#Increment Option Count\n\t\t\tb\tRAndDPadChangesEventOption_GetOptionASCII_OptionIDLoop\n\n\t\tRAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections_NextSelection:\n\t\t#Get Next Selection\n\t\t\tmr\tr3,r31\n\t\t\tbl\tRAndDPadChangesEventOption_GetNextString\n\t\t\tmr\tr31,r3\t\t#Backup New Pointer\n\t\t#Increment Loop Count\n\t\t\taddi\tr26,r26,1\n\t\t\tb\tRAndDPadChangesEventOption_GetOptionASCII_LoopThroughSelections\n\n\t###########################\n\t## Find Option Selection ##\n\t###########################\n\n\t\tRAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection:\n\t\t#Init Loop Count + Backup Window Title\n\t\t\tli\tr26,0\t\t#Init Loop Count\n\t\t\tmr\tr25,r31\t\t#r25 = Window Title\n\t\t#Skip Window Title\n\t\t\tmr\tr3,r31\n\t\t\tbl\tRAndDPadChangesEventOption_GetNextString\n\t\t\tmr\tr31,r3\t\t#Backup New Pointer\n\t\tRAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Loop:\n\t\t#Check If This is the Selection We're Looking For\n\t\t\tcmpw\tr26,r29\n\t\t\tbeq\tRAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Done\n\t\t#Get Next Selection\n\t\t#Strlen the entry\n\t\t\tmr\tr3,r31\n\t\t\tbl\tRAndDPadChangesEventOption_GetNextString\n\t\t\tmr\tr31,r3\t\t#Backup New Pointer\n\t\t#Increment Loop Count\n\t\t\taddi\tr26,r26,1\n\t\t\tb\tRAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Loop\n\n\t\tRAndDPadChangesEventOption_GetOptionASCII_GetOptionSelection_Done:\n\t\t\tmr\tr3,r25\t\t#Return Window Name\n\t\t\tmr\tr4,r31\t\t#Return Selection String\n\n\nRAndDPadChangesEventOption_GetOptionASCII_Exit:\nrestore\nblr\n\n#########################################\n\nRAndDPadChangesEventOption_GetNextString:\nbackup\n\nmr\tr31,r3\t\t\t#Backup String Pointer\nbranchl\tr12,strlen\t\t\t#Get Length\nadd\tr3,r3,r31\t\t\t#Get End of String\n\n#From here, mini loop to find the next non-zero value.\nRAndDPadChangesEventOption_GetNextString_Loop:\nlbzu\tr4,0x1(r3)\ncmpwi\tr4,0x0\nbeq\tRAndDPadChangesEventOption_GetNextString_Loop\n\nrestore\nblr\n\n#########################################\nRAndDPadChangesEventOption_Floats:\nblrl\n\n.float 16 #12.5, X position\n.long 0x427c0000 #63, 2 Window Y Scale\n.long 0x42bc0000 #94, 3 Window Y Scale\n.long 0xc4610000 #-900, 2 Window Y position\n.long 0xc4a8c000 #-1350, 3 Window Y position\n\n#########################################\nRAndDPadChangesEventOption_UpArrowText:\nblrl\n\n.string \"^\"\n.align 2\n\nRAndDPadChangesEventOption_DownArrowText:\nblrl\n\n.string \"v\"\n.align 2\n\n#########################################\n\nRAndDPadChangesEventOption_Exit:\nmr\tr3,toggledBool\nmr\tr4,toggledOption\nrestore\nblr\n\n##################################\n\nDPadCPUPercent:\nbackup\n\n.set REG_SaveStruct,31\n.set REG_PercentInt,30\n.set REG_isSubcharBool,29\n\n#Backup savestate struct\n\tmr\tREG_SaveStruct,r3\n\n#Get P1 Block\n\tli\tr3,0x0\n\tbranchl\tr12,PlayerBlock_LoadMainCharDataOffset\t\t\t#get player block\n\tlwz\tr3,0x2C(r3)\n\n#Get P2 Percent\n\tload\tr6,0x80453F10\n\tlhz\tREG_PercentInt,0x60(r6)\n\n#Get Subchar Bool\n\tlbz REG_isSubcharBool,0xC(r6)\n\n#Get inputs\n  load r4,0x804c21cc\n\tlbz r3,0x618(r3)\n  mulli r0,r3,68\n  add r5,r4,r0\n#Make Sure L Is Held\n\tlwz r3,0x0(r5)\t\t#get held inputs\n\trlwinm. r0,r3,0,25,25\n\tbeq\tDPadCPUPercent_Exit\n#Check DPad\n\tlwz r3,0xC(r5)\t\t#get rapid inputs\n\trlwinm.\tr0,r3,0,30,30\n\tbne\tDPadCPUPercent_IncByOne\n\trlwinm.\tr0,r3,0,31,31\n\tbne\tDPadCPUPercent_DecByOne\n\trlwinm.\tr0,r3,0,28,28\n\tbne\tDPadCPUPercent_IncByTen\n\trlwinm.\tr0,r3,0,29,29\n\tbne\tDPadCPUPercent_DecByTen\n\tb\tDPadCPUPercent_Exit\n\nDPadCPUPercent_IncByOne:\n\tcmpwi\tREG_PercentInt,999\n\tblt\tDPadCPUPercent_IncByOneReal\n\tli\tREG_PercentInt,999\n\tb\tDPadCPUPercent_StorePercent\n\tDPadCPUPercent_IncByOneReal:\n\taddi\tREG_PercentInt,REG_PercentInt,0x1\n\tb\tDPadCPUPercent_StorePercent\n\nDPadCPUPercent_DecByOne:\n\tcmpwi\tREG_PercentInt,0\n\tbgt\tDPadCPUPercent_DecByOneReal\n\tli\tREG_PercentInt,0\n\tb\tDPadCPUPercent_StorePercent\n\tDPadCPUPercent_DecByOneReal:\n\tsubi\tREG_PercentInt,REG_PercentInt,0x1\n\tb\tDPadCPUPercent_StorePercent\n\nDPadCPUPercent_IncByTen:\n\tcmpwi\tREG_PercentInt,989\n\tblt\tDPadCPUPercent_IncByTenReal\n\tli\tREG_PercentInt,999\n\tb\tDPadCPUPercent_StorePercent\n\tDPadCPUPercent_IncByTenReal:\n\taddi\tREG_PercentInt,REG_PercentInt,10\n\tb\tDPadCPUPercent_StorePercent\n\nDPadCPUPercent_DecByTen:\n\tcmpwi\tREG_PercentInt,9\n\tbgt\tDPadCPUPercent_DecByTenReal\n\tli\tREG_PercentInt,0\n\tb\tDPadCPUPercent_StorePercent\n\tDPadCPUPercent_DecByTenReal:\n\tsubi\tREG_PercentInt,REG_PercentInt,10\n\tb\tDPadCPUPercent_StorePercent\n\nDPadCPUPercent_StorePercent:\n#Store to Active Static Playerblock\n\tsth\tREG_PercentInt,0x60(r6)\n#Convert to Float\n\tmr\t\tr3,REG_PercentInt\n\tbl\t\tIntToFloat\n#Active PlayerData\n\tli\tr3,0x1\n\tbranchl\tr12,PlayerBlock_LoadMainCharDataOffset\t\t#get player block\n\tlwz\tr3,0x2C(r3)\n\tstfs\tf1,0x1830(r3)\n\n#Backed Up PlayerData\n\tmulli\tr4,REG_isSubcharBool,0x4\n\tlwzx r3,r4,REG_SaveStruct\n\tstfs\tf1,0x1830(r3)\n#Backed Up Static Playerblock\n\tload\tr4,0x80458fd0\t\t\t\t\t#get player block length\n\tlwz   r4,0x20(r4)\t\t\t\t\t\t#get player block length\n\tlwz r3,0x0(REG_SaveStruct)\t#only the main character has a static block backup\n\tadd\tr3,r3,r4\t\t\t\t\t\t\t\t#static block start\n\tsth\tREG_PercentInt,0x60(r3)\n\tsth\tREG_PercentInt,0x62(r3)\n\n\nDPadCPUPercent_Exit:\n\trestore\n\tblr\n\n##################################\n\nInitializePositions:\nbackup\n\n#Move Float Pointer\nmr\tr20,r3\n\n#P1 Static Block\nload\tr22,0x80453080\n#P2 Static Block\naddi\tr23,r22,0xE90\n\n#Move P1\nmr\tr3,r28\nbranchl\tr12,0x8008a2bc\t\t#Enter Wait\nlfs\tf1,0x0(r20)\nstfs\tf1,0xB0(r27)\nlfs\tf1,0x8(r20)\nstfs\tf1,0xB4(r27)\nmr\tr3,r28\nbl  UpdatePosition\nmr\tr3,r28\nbl\tUpdateCameraBox\nmr\tr3,r28\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0x0\nbeq\tInitializePositions_MoveP2\n#Move This Char Too\nmr\tr24,r3\nmr\tr25,r4\nmr\tr3,r24\nbranchl\tr12,0x8008a2bc\t\t#Enter Wait\nlfs\tf1,0x0(r20)\nstfs\tf1,0xB0(r25)\nlfs\tf1,0x8(r20)\nstfs\tf1,0xB4(r25)\nmr\tr3,r24\nbl  UpdatePosition\nmr\tr3,r24\nbl\tUpdateCameraBox\n\n#Move P2\nInitializePositions_MoveP2:\nmr\tr3,r30\nbranchl\tr12,0x8008a2bc\t\t#Enter Wait\nlfs\tf1,0x4(r20)\nstfs\tf1,0xB0(r29)\nlfs\tf1,0xC(r20)\nstfs\tf1,0xB4(r29)\nmr\tr3,r30\nbl  UpdatePosition\nmr\tr3,r30\nbl\tUpdateCameraBox\nmr\tr3,r30\nbl\tCheckIfPlayerHasAFollower\ncmpwi\tr3,0x0\nbeq\tInitializePositions_Exit\n#Move This Char Too\nmr\tr24,r3\nmr\tr25,r4\nmr\tr3,r24\nbranchl\tr12,0x8008a2bc\t\t#Enter Wait\nlfs\tf1,0x4(r20)\nstfs\tf1,0xB0(r25)\nlfs\tf1,0xC(r20)\nstfs\tf1,0xB4(r25)\nmr\tr3,r24\nbl  UpdatePosition\nmr\tr3,r24\nbl\tUpdateCameraBox\n\nInitializePositions_Exit:\nbl\tClearNanaInputs\nbl\tCurrentInputsAsLastFramesInputs\n\nrestore\nblr\n\n#########################################################\n\nCheckIfPlayerHasAFollower:\n#Returns\n#r3 = 0 for no follower // External Pointer\n#r4 = 0 for no follower // Internal Pointer\n\nbackup\n\n#Get Players Data\nlwz\tr31,0x2C(r3)\n\n#Get Player Slot\nlbz\tr3,0xC(r31)\nli\tr4,0x1\nbl\tSaveState_GetPlayerDataPointer\t\t\t\t#returns r3=Slot/-1 if subchar doesnt exist, r4= external, r5=internal\ncmpwi\tr3,0xFF\nbeq\tCheckIfPlayerHasAFollower_NoFollower\n\n#Check If Follower\nmr\tr24,r4\nmr\tr25,r5\nlbz\tr3,0xC(r25)\t\t\t#get slot\nbranchl\tr12,0x80032330\t\t\t#get external character ID\nload\tr4,pdLoadCommonData\t\t\t#pdLoadCommonData table\nmulli\tr0, r3, 3\t\t\t#struct length\nadd\tr3,r4,r0\t\t\t#get characters entry\nlbz\tr0, 0x2 (r3)\t\t\t#get subchar functionality\ncmpwi\tr0,0x0\t\t\t#if not a follower, exit\nbne\tCheckIfPlayerHasAFollower_NoFollower\n\n#Return Follower Pointers\nmr\tr3,r24\t\t\t#External\nmr\tr4,r25\t\t\t#Internal\nb\tCheckIfPlayerHasAFollower_Exit\n\nCheckIfPlayerHasAFollower_NoFollower:\nli\tr3,0x0\nli\tr4,0x0\n\nCheckIfPlayerHasAFollower_Exit:\nrestore\nblr\n\n#########################################################\n\nRandomize_LeftorRightSide:\n#r3 = 0 = Same Side of Stage // 1 = Opposing Sides of Stage\n\nbackup\n\nmr\tr20,r3\t\t#Backup Stage Side Bool\n\n#Get Left or Right Side\nli\tr3,2\nbranchl\tr12,HSD_Randi\n#Check To Negate\ncmpwi\tr3,0x0\t\t#0 = Left, 1 = Right\nbne\tRandomize_RightSide\n\nRandomize_LeftSide:\n#P1 X Position\nlwz\tr3,0x10(r31)\t\t#P1 Backup Start\nlwz\tr4,0x18(r31)\t\t#P2 Backup Start\nlfs\tf1,0xB0(r3)\t\t#P1 Backup X Pos\ncmpwi\tr20,0x0\nbeq\t0xC\nbl\tRandomize_AlwaysNegative\nb\t0x8\nbl\tRandomize_AlwaysNegative\nstfs\tf1,0xB0(r3)\t\t#P1 Backup X Pos\n#P2 X Position\nlfs\tf1,0xB0(r4)\t\t#P2 Backup X Pos\ncmpwi\tr20,0x0\nbeq\t0xC\nbl\tRandomize_AlwaysPositive\nb\t0x8\nbl\tRandomize_AlwaysNegative\nstfs\tf1,0xB0(r4)\t\t#P2 Backup X Pos\n#Facing Directions\nlis\tr5,0x3f80\t\t#P1 Face Right\nlis\tr6,0xbf80\t\t#P2 Face Left\nstw\tr5,0x2C(r3)\t\t#P1 Backup Facing\nstw\tr6,0x2C(r4)\t\t#P2 Facing\nb\tRandomize_LeftorRightSide_CheckForFollowers\n\nRandomize_RightSide:\n#P1 X Position\nlwz\tr3,0x10(r31)\t\t#P1 Backup Start\nlwz\tr4,0x18(r31)\t\t#P2 Backup Start\nlfs\tf1,0xB0(r3)\t\t#P1 Backup X Pos\ncmpwi\tr20,0x0\nbeq\t0xC\nbl\tRandomize_AlwaysPositive\nb\t0x8\nbl\tRandomize_AlwaysPositive\nstfs\tf1,0xB0(r3)\t\t#P1 Backup X Pos\n#P2 X Position\nlfs\tf1,0xB0(r4)\t\t#P2 Backup X Pos\ncmpwi\tr20,0x0\nbeq\t0xC\nbl\tRandomize_AlwaysNegative\nb\t0x8\nbl\tRandomize_AlwaysPositive\nstfs\tf1,0xB0(r4)\t\t#P2 Backup X Pos\n#Facing Directions\nlis\tr5,0xbf80\t\t#P1 Face Left\nlis\tr6,0x3f80\t\t#P2 Face Right\nstw\tr5,0x2C(r3)\t\t#P1 Backup Facing\nstw\tr6,0x2C(r4)\t\t#P2 Facing\n\n\nRandomize_LeftorRightSide_CheckForFollowers:\n\tRandomize_LeftorRightSide_GetFirstPlayer:\n\tlwz\tr3, -0x3E74 (r13)\n\tlwz\tr20, 0x0020 (r3)\n\tb\tRandomize_LeftorRightSide_CheckIfPlayerExists\n\n\tRandomize_LeftorRightSide_GetNextPlayer:\n\tlwz\tr20,0x8(r20)\n\n\tRandomize_LeftorRightSide_CheckIfPlayerExists:\n\tcmpwi\tr20,0x0\n\tbeq\tRandomize_LeftorRightSide_Exit\n\tlwz\tr21,0x2C(r20)\n\n\t#Check If This Fighter is a Main Char\n\tlbz\tr3,0x221F(r21)\n\trlwinm.\tr0, r3, 29, 31, 31\n\tbne\tRandomize_LeftorRightSide_GetNextPlayer\n\n\t#Check For Follower, r20 = External. r21 = Internal\n\t\tmr\tr3,r20\n\t\tbl\tCheckIfPlayerHasAFollower\n\t\tcmpwi\tr3,0x0\t\t\t\t\t#No Follower, Go To Next Player\n\t\tbeq\tRandomize_LeftorRightSide_GetNextPlayer\n\n\t\t#Transfer Info\n\t\t#Get Backups\n\t\taddi\tr3,r31,0x10\t\t#Get Backup Start\n\t\tlbz\tr4,0xC(r21)\t\t#Get Subchars Slot\n\t\tmulli\tr4,r4,0x8\t\t#Each Slot has 2 backups, so get to this slots backup\n\t\tadd\tr3,r3,r4\t\t#Each Slot has 2 backups, so get to this slots backup\n\n\t\t#Copy Main Char's Info Into Subchars\n\t\tlwz\tr4,0x0(r3)\t\t#Main Char Backup\n\t\tlwz\tr5,0x4(r3)\t\t#Follower Backup\n\t\tlwz\tr3,0xB0(r4)\t\t#Main Char X\n\t\tstw\tr3,0xB0(r5)\t\t#Into Subchar X\n\t\tlwz\tr3,0x2C(r4)\t\t#Main Char Facing\n\t\tstw\tr3,0x2C(r5)\t\t#Into Subchar Facing\n\t\tb\tRandomize_LeftorRightSide_GetNextPlayer\n\n\nRandomize_LeftorRightSide_Exit:\nrestore\nblr\n\n#********************************************#\n\nRandomize_AlwaysPositive:\nfabs\tf1,f1\t\t#Always Positive\nblr\n\nRandomize_AlwaysNegative:\nfabs\tf1,f1\nfneg\tf1,f1\t\t#Always Negative\nblr\n\n#********************************************#\n\n############################################\n\nIntToFloat:\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\nstfs  f2,0x38(r1)\n\nlis\tr0, 0x4330\nlfd\tf2, -0x6758 (rtoc)\nxoris\tr3, r3,0x8000\nstw\tr0,0xF0(sp)\nstw\tr3,0xF4(sp)\nlfd\tf1,0xF0(sp)\nfsubs\tf1,f1,f2\t\t#Convert To Float\n\nlfs  f2,0x38(r1)\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\nblr\n\n############################################\n\nGetDirectionInRelationToP1:\n#Get P1 Direction\nlfs\tf1,0xB0(r27)\nlfs\tf2,0xB0(r29)\nfsubs\tf1,f1,f2\nlfs\tf2, -0x6768 (rtoc)\nfcmpo\tcr0,f2,f1\nblt\t0xC\nli\tr3,1\nb\t0x8\nli\tr3,-1\nblr\n\n############################################\n\nIsAnyoneDead:\nbackup\n\nIsAnyoneDead_GetFirstPlayer:\nlwz\tr3, -0x3E74 (r13)\nlwz\tr20, 0x0020 (r3)\nb\tIsAnyoneDead_CheckIfPlayerExists\n\nIsAnyoneDead_GetNextPlayer:\nlwz\tr20,0x8(r20)\n\nIsAnyoneDead_CheckIfPlayerExists:\ncmpwi\tr20,0x0\nbne\tIsAnyoneDead_GetPlayerData\n#Exit If No Other Players\nli\tr3,0x0\nb\tIsAnyoneDead_Exit\n\nIsAnyoneDead_GetPlayerData:\nlwz\tr21,0x2C(r20)\n\n#Check If Follower\nlbz\tr3,0x221F(r21)\nrlwinm.\tr0,r3,0,28,28\nbne\tIsAnyoneDead_GetNextPlayer\n\n#Check If Dead\nlbz\tr3,0x221F(r21)\nrlwinm.\tr0,r3,0,25,25\nbeq\tIsAnyoneDead_GetNextPlayer\nli\tr3,0x1\nb\tIsAnyoneDead_Exit\n\nIsAnyoneDead_Exit:\n\nrestore\nblr\n\n############################################\n\nResetStaleMoves:\nbackup\n\nResetStaleMoves_GetFirstPlayer:\nlwz\tr3, -0x3E74 (r13)\nlwz\tr20, 0x0020 (r3)\nb\tResetStaleMoves_CheckIfPlayerExists\n\nResetStaleMoves_GetNextPlayer:\nlwz\tr20,0x8(r20)\n\nResetStaleMoves_CheckIfPlayerExists:\ncmpwi\tr20,0x0\nbne\tResetStaleMoves_GetPlayerData\n#Exit If No Other Players\nli\tr3,0x0\nb\tResetStaleMoves_Exit\n\nResetStaleMoves_GetPlayerData:\nlwz\tr21,0x2C(r20)\n\n#Reset Stale Moves\n#Get Stale Move Table\nlbz\tr3,0xC(r21)\t\t#Get Slot\nbranchl\tr12,0x80036244\t\t#Get This Players Stale Table\n\n#Fill With 0's\nli\tr4,0x2C\nbranchl\tr12,ZeroAreaLength\nb\tResetStaleMoves_GetNextPlayer\n\n\nResetStaleMoves_Exit:\n\nrestore\nblr\n\n############################################\n\nActOutOfLaserHitDisplay:\nbackup\n\n#Check If In Run\nlwz\tr3,0x10(r27)\ncmpwi\tr3,0x14\nbne\tActOutOfLaserHitDisplayExit\n\n#Check If Frame 2\nli\tr3,2\nbl\tIntToFloat\nlfs\tf2,0x894(r27)\nfcmpo\tcr0,f2,f1\nbne\tActOutOfLaserHitDisplayExit\n\n#Search Prev AS For Laser Hit, returns r3=AS's Since Laser Hit or -1 for didnt happen\nli\tr3,0x0\t\t#Number of AS's ago\naddi\tr4,r27,0x23F0\t\t#First Prev AS\nsubi\tr4,r4,0x2\nActOutOfLaserHitDisplay_SearchLoop:\naddi\tr3,r3,0x1\nlhzu\tr5,0x2(r4)\ncmpwi\tr5,0x4E\t\t#Laser Hit\nbeq\tActOutOfLaserHitDisplay_ExitLoop\ncmpwi\tr5,0x4B\t\t#Laser Hit\nbeq\tActOutOfLaserHitDisplay_ExitLoop\ncmpwi\tr3,0x3\nbeq\tActOutOfLaserHitDisplay_NoLaserHit\nb\tActOutOfLaserHitDisplay_SearchLoop\nActOutOfLaserHitDisplay_NoLaserHit:\nli\tr3,-1\nActOutOfLaserHitDisplay_ExitLoop:\ncmpwi\tr3,-1\nbeq\tActOutOfLaserHitDisplayExit\n\nActOutOfLaserHitDisplay_CountFrameInit:\n#Get Amount Of Frames Since Laser Hit Ended\n\tli\tr5,0x23FC\t\t#As's Frame Count offset\n\tli\tr20,0\t\t#Frames Since Laser Hit\nActOutOfLaserHitDisplay_CountFrameLoop:\n\tcmpwi\tr3,0\t\t#Check If Done Counting\n\tbeq\tActOutOfLaserHitDisplay_CountFrameLoopFinish\n\tmulli\tr4,r3,2\t\t#Frame Count Offset\n\tsubi\tr4,r4,0x2\t\t#1 AS Before\n\tadd\tr4,r4,r5\t\t#Get Offset in Playerblock\n\tlhzx\tr6,r4,r27\t\t#Get Frame Count Value\n\tsubi\tr4,r4,0xC\t\t#Get AS Associated With It\n\tlhzx\tr4,r4,r27\t\t#Get AS ID\n#Check If This AS is Turn\n\tcmpwi\tr4,0x12\n\tbeq\t0x8\n\tadd\tr20,r20,r6\t\t#Add To Toal\n\tcmpwi\tr4,0x4E\n\tbeq\tActOutOfLaserHitDisplay_SubtractHitstun\n\tcmpwi\tr4,0x4B\n\tbeq\tActOutOfLaserHitDisplay_SubtractHitstun\n\tb\tActOutOfLaserHitDisplay_SkipSubtractHitstun\nActOutOfLaserHitDisplay_SubtractHitstun:\n\tsubi\tr20,r20,0x8\nActOutOfLaserHitDisplay_SkipSubtractHitstun:\n\tsubi\tr3,r3,1\n\tb\tActOutOfLaserHitDisplay_CountFrameLoop\n\nActOutOfLaserHitDisplay_CountFrameLoopFinish:\n\nActOutOfLaserHitDisplay_DisplayOSD:\nmr\tr3,r27\t\t\t#p1 (no offsetting window)\nli\tr4,120\t\t\t#text timeout\nli\tr5,0\t\t\t#Area to Display (0-2)\nli\tr6,OSD.Miscellaneous\t\t\t#Window ID (Unique to This Display)\nbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\nmr\ttext,r3\t\t\t#backup text pointer\n\ncmpwi\tr20,0x1\nbeq\tActOutOfLaserHitDisplay_Perfect\nActOutOfLaserHitDisplay_Late:\nload\tr3,0xffa2baff\t\t\t#Red\nb\tActOutOfLaserHitDisplay_StoreTextColor\nActOutOfLaserHitDisplay_Perfect:\nload\tr3,0x8dff6eff\t\t\t#green\nActOutOfLaserHitDisplay_StoreTextColor:\nstw\tr3,0x30(text)\n\n\t#Create Text 1\n\tmr \tr3,text\t\t\t#text pointer\n\tbl\tActOutOfLaserHitDisplay_TopText\n\tmflr\tr4\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tbranchl r12,Text_InitializeSubtext\n\n\t#Create Text 2\n\tmr \tr3,text\t\t\t#text pointer\n\tbl\tActOutOfLaserHitDisplay_BottomText\n\tmflr\tr4\n\tmr\tr5,r20\t\t\t#Frame Count\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#default text X/Y\n\tbranchl r12,Text_InitializeSubtext\n\nActOutOfLaserHitDisplayExit:\nrestore\nblr\n\n#####################\n## Text Properties ##\n#####################\n\nActOutOfLaserHitDisplay_TextProperties:\nblrl\n\n.long 0xC1A80000 #Whether to Use HUD Location, 0 = no\n.long 0x41100000 #Y Value\n.long 0x41600000 #X Difference Between Players\n.long 0x3D23D70A\t#Text Size\n\n.long 0xC3CD0000 #background Y position\n.long 0x4129999A #background X stretch\n.long 0x41E00000 #background Y stretch\n\n##############\n## Top Text ##\n##############\n\nActOutOfLaserHitDisplay_TopText:\nblrl\n.long 0x44617368\n.long 0x204f6f4c\n.long 0x61736572\n.long 0x48697400\n\n\n#################\n## Bottom Text ##\n#################\n\nActOutOfLaserHitDisplay_BottomText:\nblrl\n.long 0x4672616d\n.long 0x65202564\n.long 0x\n\n############################################\n\nMoveCPU:\n#in\n#r3 = P1 GObj\n#r4 = P2 GObj\n#r5 = SaveState Struct\n\n.set P1GObj,31\n.set P1Data,30\n.set P2GObj,29\n.set P2Data,28\n.set SaveStateStruct,27\n.set P2Subchar,26\n.set P2SubcharData,25\n\nbackup\n\n#Get Variables\n  mr  P1GObj,r3\n  lwz P1Data,0x2C(P1GObj)\n  mr  P2GObj,r4\n  lwz P2Data,0x2C(P2GObj)\n  mr  SaveStateStruct,r5\n\n#Get Input\n  lbz\tr4, 0x0618 (P1Data)\n  load r3,InputStructStart\n  mulli\tr0, r4, 68\n  add\tr5, r0, r3\n\n#Check DPad Down\n\tlwz\tr3,0xC(r5)\n\trlwinm.\tr0,r3,0,29,29\n\tbeq\tMoveCPUExit\n#Make Sure Nothing Is Held\n\tlwz\tr3,0x0(r5)\n\tli\tr4,0\n\trlwimi r3,r4,0,29,29\t\t#except dpad down\n\trlwimi r3,r4,0,27,27\t\t#except Z (cause frame advance)\n\tcmpwi r3,0\n\tbne\tMoveCPUExit\n\n#Make Sure Player is Grounded\n  lwz r3,0xE0(P1Data)\n  cmpwi r3,0x0\n  bne MoveCPU_NoGroundFound\n\n#Get Position\n  li  r3,10\n  bl  IntToFloat          #Offset from P1\n  lfs f3,0xB0(P1Data)     #P1 X\n  lfs f2,0xB4(P1Data)     #P1 Y\n  lfs f4,0x2C(P1Data)     #Facing Direction\n  fmuls f1,f1,f4\n  fadds f1,f1,f3\n#Check If P2 Will Be Grounded\n  li  r3,0\n  bl  FindGroundNearPlayer\n  cmpwi r3,0    #Check if ground was found\n  beq MoveCPU_NoGroundFound\n  stfs f1,0xB0(P2Data)\n  stfs f2,0xB4(P2Data)\n  stw r4,0x83C(P2Data)\n  lfs f1,0x2C(P1Data)\n  fneg f1,f1\n  stfs f1,0x2C(P2Data)\n#Enter Wait\n  mr  r3,P2GObj\n  branchl r12,AS_Wait\n#Update Position\n  mr  r3,P2GObj\n  bl  UpdatePosition\n#Update ECB Values for the ground ID\n  mr r3,P2GObj\n  branchl r12,EnvironmentCollision_WaitLanding\n#Set Grounded\n  mr r3,P2Data\n  branchl r12,Air_SetAsGrounded\n\n#Check For Follower\n  mr  r3,P2GObj\n  bl  CheckIfPlayerHasAFollower\n  cmpwi r3,0\n  beq MoveCPU_NoFollower\n  mr P2Subchar,r3\n  mr P2SubcharData,r4\n#Init Player Data Values (So CPU Init is called and nana knows where popp is)\n  mr r3,P2Subchar\n  branchl r12,0x80068354\n#Copy Positions\n  lfs f1,0xB0(P2Data)\n  stfs f1,0xB0(P2SubcharData)\n  lfs f1,0xB4(P2Data)\n  stfs f1,0xB4(P2SubcharData)\n  lwz r3,0x83C(P2Data)\n  stw r3,0x83C(P2SubcharData)\n  lfs f1,0x2C(P2Data)\n  stfs f1,0x2C(P2SubcharData)\n#Enter Wait\n  mr  r3,P2Subchar\n  branchl r12,AS_Wait\n#Update Position\n  mr  r3,P2Subchar\n  bl  UpdatePosition\n#Update ECB Values for the ground ID\n  mr r3,P2Subchar\n  branchl r12,EnvironmentCollision_WaitLanding\n#Set Grounded\n  mr r3,P2SubcharData\n  branchl r12,Air_SetAsGrounded\n\nMoveCPU_NoFollower:\n#Savestate\n  mr  r3,SaveStateStruct\n\tli\tr4,1\t\t\t#Override failsafe code\n  bl  SaveState_Save\n#Play SFX\n  li r3,0xDD\n  bl  PlaySFX\n  b MoveCPUExit\n\nMoveCPU_NoGroundFound:\n#PLay Error SFX\n  li\tr3,0xAF\n  bl  PlaySFX\n\nMoveCPUNoSubchar:\nMoveCPUExit:\nrestore\nblr\n\n############################################\n\nAdjustResetDistance:\n.set SaveStateStruct,25\n.set P2Direction,3\n.set PlayerX,2\n.set P1X,31\n.set P2X,30\n\nbackup\n\nmr  SaveStateStruct,r3\n\n#Make Sure Nothing is Held\n  lhz\tr3,0x662(r27)\n  rlwinm.  r0,r3,0,27,27\n  bne 0xC\n  cmpwi r3,0x0\n  bne\tAdjustResetDistance_NoPress\n\n\n#Check For DPad Right\nAdjustResetDistance_CheckRightDPad:\n  lwz\tr3,0x668(r27)\t\t\t#Get DPad\n  rlwinm.\tr0,r3,0,30,30\n  beq\tAdjustResetDistance_CheckLeftDPad\n#Move Apart\n#Determine if P2 is to the left or right of P1 + Get X Pos Multiplier\n  bl  GetDirectionInRelationToP1\n  bl  IntToFloat\n  fmr P2Direction,f1\n#Load P1 Backup X Location\n  lwz\tr20,0x0(SaveStateStruct)\n  lfs\tPlayerX,0xB0(r20)\n#Add One in the correct direction\n  li\tr3,1\n  bl\tIntToFloat\n  fneg P2Direction,P2Direction\n  fmuls f1,f1,P2Direction\n  fadds\tP1X,f1,PlayerX           #New P1 X\n#Load P2 Backup X Location\n  lwz\tr21,0x8(SaveStateStruct)\n  lfs\tPlayerX,0xB0(r21)\n#Add One in the correct direction\n  li\tr3,1\n  bl\tIntToFloat\n  fneg P2Direction,P2Direction\n  fmuls f1,f1,P2Direction\n  fadds\tP2X,f1,PlayerX            #New P2 X\n#Check if already 30 Mm apart\n  fsubs f2,P1X,P2X\n  fabs f2,f2        #get abs distance from each other in f2\n  li\tr3,30\n  bl\tIntToFloat\n  fcmpo\tcr0,f2,f1\n  bge\tAdjustResetDistance_NoPress\n#Store Back To PlayerBlock\n  stfs\tP1X,0xB0(r20)\n  stfs\tP2X,0xB0(r21)\n  b\tAdjustResetDistance_WasPressed\n\n\n#Check For DPad Left\nAdjustResetDistance_CheckLeftDPad:\n  rlwinm.\tr0,r3,0,31,31\n  beq\tAdjustResetDistance_NoPress\n#Move Together\n#Determine if P2 is to the left or right of P1 + Get X Pos Multiplier\n  bl  GetDirectionInRelationToP1\n  bl  IntToFloat\n  fmr P2Direction,f1\n#Load P1 Backup X Location\n  lwz\tr20,0x0(SaveStateStruct)\n  lfs\tPlayerX,0xB0(r20)\n#Add One in the correct direction\n  li\tr3,1\n  bl\tIntToFloat\n  #fneg P2Direction,P2Direction\n  fmuls f1,f1,P2Direction\n  fadds\tP1X,f1,PlayerX           #New P1 X\n#Load P2 Backup X Location\n  lwz\tr21,0x8(SaveStateStruct)\n  lfs\tPlayerX,0xB0(r21)\n#Add One in the correct direction\n  li\tr3,1\n  bl\tIntToFloat\n  fneg P2Direction,P2Direction\n  fmuls f1,f1,P2Direction\n  fadds\tP2X,f1,PlayerX            #New P2 X\n#Check if already 10 Mm apart\n  fsubs f2,P1X,P2X\n  fabs f2,f2        #get abs distance from each other in f2\n  li\tr3,10\n  bl\tIntToFloat\n  fcmpo\tcr0,f2,f1\n  ble\tAdjustResetDistance_NoPress\n#Store Back To PlayerBlock\n  stfs\tP1X,0xB0(r20)\n  stfs\tP2X,0xB0(r21)\n  b\tAdjustResetDistance_WasPressed\n\n\nAdjustResetDistance_NoPress:\nli\tr3,-1\nb\tAdjustResetDistance_Exit\n\nAdjustResetDistance_WasPressed:\nli\tr3,1\n\nAdjustResetDistance_Exit:\nrestore\nblr\n############################################\n\nCheckForActiveHitboxes:\nbackup\n\nlwz\tr31,0x2C(r3)\n\nCheckForActiveHitboxes_InitLoop:\nli\tr29,0x0\n\nCheckForActiveHitboxes_LoopStart:\nlwz\tr0, 0x0914 (r31)\t\t\t#Check Hitbox Active Bool\ncmpwi\tr0,0x0\nbeq\tCheckForActiveHitboxes_NextHitbox\nli\tr3,0x1\nb\tCheckForActiveHitboxes_Exit\n\nCheckForActiveHitboxes_NextHitbox:\naddi\tr29,r29,1\naddi\tr31,r31,312\t\t\t#Next Hitbox Struct\ncmpwi\tr29,4\nblt\tCheckForActiveHitboxes_LoopStart\n\nCheckForActiveHitboxes_NoHitboxesActive:\nli\tr3,0x0\n\nCheckForActiveHitboxes_Exit:\n\nrestore\nblr\n\n#############################################\n\nEvent_ExitFunction:\nblrl\n\nbackup\n\n#Ensure No Contest/Retry\nlwz\tr3, -0x77C0 (r13)\nlbz\tr3, 0x053B (r3)\nrlwinm.\tr0, r3, 0, 25, 25\nbne\tEvent_ExitFunction_Exit\n\n#Update Event Score\nload\tr20,0x8045abf0\t\t#Current Event Info\n\n#Get High Score\nlbz\tr3,0x5(r20)\t\t#Event ID\nbranchl\tr12,0x8015cf5c\nmr\tr21,r3\t\t#Backup High Score\n\n#Check If Event Was Played Yet\nlbz\tr3,0x5(r20)\t\t#Event ID\nbranchl\tr12,0x8015cefc\ncmpwi\tr3,0x0\nbeq\tEvent_ExitFunction_SaveScore\n\n#Check If Greater\nlhz\tr3,-0x4ea6(r13)\t\t#Current Score\ncmpw\tr3,r21\nble\tEvent_ExitFunction_Exit\n\n#Store As New High Score\nEvent_ExitFunction_SaveScore:\nlbz\tr3,0x5(r20)\t\t#Event ID\nlhz\tr4,-0x4ea6(r13)\nbranchl\tr12,0x8015cf70\n\n#Set Event As Played\nlbz\tr3,0x5(r20)\t\t#Event ID\nbranchl\tr12,0x8015ceb4\n\nEvent_ExitFunction_Exit:\nrestore\nblr\n\n#############################################\n\nInitializeHighScore:\nbackup\n\n\n\t#Create HUD KO Counter\n\tli\tr3,0x0\n\tbranchl\tr12,0x802fa5bc\n\n\t#Init Score Count\n\tli\tr3,0x0\n\tstw\tr3,-0x4ea8(r13)\n\n\t#Store Exit Function\n\tbl\tEvent_ExitFunction\n\tmflr\tr3\n\tload\tr4,0x8046b6a0\n\tstw\tr3,0x2518(r4)\n\n\nrestore\nblr\n\n#############################################\n\nPerformAerialThink:\n#in\n#   r3    CPU Player Pointer\n#   r4    Pointer to dedicated memory to use\n#   r5    Attack to Perform (0 = Random, 1 = Fair, 2 = Nair, 3 = Dair)\n\n.set player,31\n.set playerdata,30\n.set variables,29\n.set frame,28\n.set aerialToPerform,27\n.set performAerial,0x00\n.set aerialAttack,0x01\n.set attackFrame,0x02\n\nbackup\n\n#Get player pointers and frame count\n  mr  player,r3                     #Get Player\n  lwz playerdata,0x2C(player)       #Get Playerdata\n  mr  variables,r4                  #Get Variable Memory\n  lfs\tf1,0x894(playerdata)          #Get Frames as Int\n  fctiwz\tf1,f1\n  stfd\tf1,0xF0(sp)\n  lwz\tframe,0xF4(sp)\n\tmr\taerialToPerform,r5\t\t\t\t\t\t#Aerial to perform\n\n#Check To Aerial\n  lbz r3,performAerial(variables)\n  cmpwi r3,0x0\n  bne PerformAerialThink_Exit\n\n#Check Which Action to Perform\n  lwz r3,0x10(playerdata)   #Get Action State\n\n#Branch To Think Functions\n  #During Wait\n    cmpwi r3,0xE\n    beq PerformAerialThink_DuringWait\n  #During Jump\n    cmpwi r3,0x19\n    beq PerformAerialThink_DuringJump\n    cmpwi r3,0x1A\n    beq PerformAerialThink_DuringJump\n  #During Attack\n    cmpwi r3,0x41\n    blt 0x10\n    cmpwi r3,0x45\n    bgt 0x8\n    b PerformAerialThink_DuringAttack\n  #During Landing\n\t  cmpwi r3,0x2A\n\t\tbeq\tPerformAerialThink_DuringLanding\n    cmpwi r3,0x46\n    blt 0x10\n    cmpwi r3,0x4A\n    bgt 0x8\n    b PerformAerialThink_DuringLanding\n\t#None of The Above\n\t\tb PerformAerialThink_Exit\n\n\n\nPerformAerialThink_DuringWait:\n  #Input Jump\n    li\tr3,0x800\n    stw\tr3,0x1A88(playerdata)\n  #Determine Which Aerial Attack To Do\n\t#Check To Randomize\n\t\tcmpwi aerialToPerform,0x0\n\t\tbeq PerformAerialThink_GetRandomAttack\n\t#Store Attack Chosen\n\t\tsubi\tr3,aerialToPerform,0x1\n\t\tstb r3,aerialAttack(variables)\n\t\tb\tPerformAerialThink_CheckForValidAttack\n\tPerformAerialThink_GetRandomAttack:\n    li\tr3,3\n  \tbranchl\tr12,HSD_Randi\n  \tstb r3,aerialAttack(variables)\n  #Determine Frame to Attack on\n  PerformAerialThink_CheckForValidAttack:\n    lwz r4,0x4(playerdata)      #get char ID\n    bl  PerformAerial_FrameData\n    mflr  r5\n    mulli\tr4,r4,0xC\t\t#Get Characters Offset\n    add\tr4,r4,r5\t\t#Get Characters Table Entry Start\n    mulli\tr3,r3,0x2\t\t#Move Frame Data is 0x2 Long\n    add\tr27,r3,r4\t\t#Get Moves Frame Data\n    lbz\tr4,0x0(r27)\t\t#First Possible Frame\n    lbz\tr5,0x1(r27)\t\t#Last Possible Frame\n    cmpwi\tr4,0x0\n    bne\tPerformAerialThink_GetRandomFrame\n    cmpwi\tr5,0x0\n    bne\tPerformAerialThink_GetRandomFrame\n  #Move Disabled For Char, Get a New One\n    b\tPerformAerialThink_GetRandomAttack\n  PerformAerialThink_GetRandomFrame:\n    sub\tr3,r5,r4\t\t#Get Amount of Possibilities\n    branchl\tr12,HSD_Randi\t\t#Get Random Frame\n    lbz\tr4,0x0(r27)\t\t#First Possible Frame\n    add\tr3,r3,r4\t\t#Adjust for First Possible Frame\n    stb\tr3,attackFrame(variables)\t\t#Store Frame to Attack on\n  b PerformAerialThink_Exit\n\nPerformAerialThink_DuringJump:\n  #Check To Attack\n    lbz r3,attackFrame(variables)\n    cmpw r3,frame\n    bne PerformAerialThink_InputFastfallAndLCancel\n\n  #Perform Attack\n    lbz\tr3,aerialAttack(variables)\t\t#Get Attack ID\n    cmpwi\tr3,0x0\n    beq\tPerformAerialThink_Fair\n    cmpwi\tr3,0x1\n    beq\tPerformAerialThink_Nair\n    cmpwi\tr3,0x2\n    beq\tPerformAerialThink_Dair\n\n    PerformAerialThink_Fair:\n      li\tr3,127\t\t            #Forward\n      lfs\tf1,0x2C(playerdata)\t\t#Facing Direction\n      fctiwz\tf1,f1\n      stfd\tf1,0xF0(sp)\n      lwz\tr4,0xF4(sp)\n      mullw\tr3,r3,r4\t\t         #Forward * facing direction\n      stb\tr3,0x1A8E(playerdata)\n      b\tPerformAerialThink_InputFastfallAndLCancel\n\n    PerformAerialThink_Nair:\n      li\tr3,0x100\n      stw\tr3,0x1A88(playerdata)\n      b\tPerformAerialThink_InputFastfallAndLCancel\n\n    PerformAerialThink_Dair:\n      li\tr3,-127\n      stb\tr3,0x1A8F(playerdata)\n      b\tPerformAerialThink_InputFastfallAndLCancel\n\nb PerformAerialThink_InputFastfallAndLCancel\n\nPerformAerialThink_DuringAttack:\nb PerformAerialThink_InputFastfallAndLCancel\n\nPerformAerialThink_DuringLanding:\n#Set Sequence as Over\n  li  r3,1\n  stb r3,performAerial(variables)\n  b PerformAerialThink_Exit\n\nPerformAerialThink_InputFastfallAndLCancel:\n#Input Fastfall\n\t#Check If Already FastFalling\n\t\tlbz\tr3,0x221A(playerdata)\n\t\trlwinm.\tr3,r3,0,28,28\n\t\tbne\tPerformAerialThink_InputLCancel\n  #Check If Falling\n    lfs\tf2,0x84(playerdata)\n    lfs\tf0, -0x76B0 (rtoc)\n    fcmpo\tcr0,f2,f0\n    bge\tPerformAerialThink_InputLCancel\n  #Check If Inputting A Nair\n    lwz\tr3,0x1A88(playerdata)\n    cmpwi\tr3,0x100\n    beq\tPerformAerialThink_InputLCancel\n  #Input Down to FF\n    li\tr3,-127\n    stb\tr3,0x1A8D(playerdata)\t\t#Analog Y\n\n  PerformAerialThink_InputLCancel:\n  #Spoof Mash L\n   li r3,0x1\n   stb r3,0x67F(playerdata)\n\nb PerformAerialThink_Exit\n\n#################################\n\nPerformAerial_FrameData:\nblrl\n#Mario\n.long 0x00040012\t\t#Fair and Nair\n.long 0x00100005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Fox\n.long 0x0009000A\t\t#Fair and Nair\n.long 0x00080005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Cptn Falcon\n.long 0x0006000E\t\t#Fair and Nair\n.long 0x00040005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#DK\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Kirby\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Bowser\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#link\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Sheik\n.long 0x10140018\t\t#Fair and Nair\n.long 0x00000005\t\t#Dar (was 0-A) and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Ness\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Peach\n.long 0x000D001A\t\t#Fair and Nair\n.long 0x000E0005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Popo\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Nana\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Pikachu\n.long 0x000C000F\t\t#Fair and Nair\n.long 0x00080005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Samus\n.long 0x00200020\t\t#Fair and Nair\n.long 0x080D0005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Yoshi\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Jiggs\n.long 0x00100010\t\t#Fair and Nair\n.long 0x00100005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#mewtwo\n.long 0x00050019\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Luigi\n.long 0x0017001B\t\t#Fair and Nair\n.long 0x00110005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Marth\n.long 0x00160013\t\t#Fair and Nair\n.long 0x00120005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Zelda\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#YLink\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Doc\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Falco\n.long 0x070B000D\t\t#Fair and Nair\n.long 0x000C0005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Pichu\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#GaW\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Ganon\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n#Roy\n.long 0x00050005\t\t#Fair and Nair\n.long 0x00050005\t\t#Dar and UAir\n.long 0x0005FFFF    #Bair and Nothing\n\n####################################\n\nPerformAerialThink_Exit:\n  restore\n  blr\n\n#####################################\nRandFloat:\n#in\n#r3 = Rand Float Lower Bound\n#r4 = Rand Float Upper Bound\n\nbackup\nstfs\tf31,0x80(sp)\n\nmr\tr31,r3\n\n#Get Random Upper Bound\n\tsub\tr3,r4,r31\n\tbranchl r12,HSD_Randi\n#Add Lower Bound\n\tadd\tr3,r3,r31\n#Convert to Float\n\tbl\tIntToFloat\n\tfmr\tf31,f1\n#Get Random Float\n\tbranchl r12,HSD_Randf\n\tfadds\tf1,f1,f31\n\nlfs\tf31,0x80(sp)\nrestore\nblr\n\n#####################################\nCustom_InterruptRebirthWait:\nblrl\n.set player,31\n.set playdata,30\n\nbackup\n\n#Get Pointers\n\tmr\tplayer,r3\n\tlwz\tplayerdata,0x2C(player)\n\n#Check For Aerial Jump\n\tmr\tr3,player\n\tbranchl r12,0x800cb870\n\tcmpwi r3,0x0\n\tbne Custom_InterruptRebirthWait_Exit\n\n#Ensure Stick Was Just Moved\n\tlbz\tr3, 0x0670 (playerdata)\n\tcmpwi r3,2\n\tbge\tCustom_InterruptRebirthWait_CheckJoystickDown\n#Check For Any X Joystick Push\n\tlwz\tr3, -0x514C (r13)\n\tlfs\tf0, 0x0024 (r3)\n\tlfs\tf1, 0x0620 (playerdata)\n\tfabs\tf1,f1\n\tfcmpo\tcr0,f1,f0\n\tcror\t2, 1, 2\n\tbeq\tCustom_InterruptRebirthWait_EnterFall\nCustom_InterruptRebirthWait_CheckJoystickDown:\n#Ensure Stick Was Just Moved\n\tlbz\tr3, 0x0671 (playerdata)\n\tcmpwi r3,4\n\tbge\tCustom_InterruptRebirthWait_Exit\n#Check For Down Joystick Push\n\tlwz\tr3, -0x514C (r13)\n\tlfs\tf0, 0x0090 (r3)\n\tfneg f0,f0\n\tlfs\tf1, 0x0624 (playerdata)\n\tfcmpo\tcr0,f1,f0\n\tblt\tCustom_InterruptRebirthWait_EnterFall\n\tb\tCustom_InterruptRebirthWait_Exit\n\nCustom_InterruptRebirthWait_EnterFall:\n#Enter Fall\n\tmr r3,player\n\tbranchl r12,AS_Fall\n\nCustom_InterruptRebirthWait_Exit:\n\trestore\n\tblr\n\n#####################################\nUpdatePosition:\n.set PlayerGObj,31\n.set PlayerData,30\n\nbackup\n\n#Backup Pointer\n  mr  PlayerGObj,r3\n  lwz PlayerData,0x2C(PlayerGObj)\n\n#Update Position (Copy Physics XYZ into all ECB XYZ)\n#X\n  lwz\tr3, 0x00B0 (PlayerData)\n  stw\tr3, 0x06F4 (PlayerData)\n  stw\tr3, 0x0700 (PlayerData)\n\tstw\tr3, 0x070C (PlayerData)\n\tstw\tr3, 0x0718 (PlayerData)\n#Y\n  lwz\tr3, 0x00B4 (PlayerData)\n  stw\tr3, 0x06F8 (PlayerData)\n  stw\tr3, 0x0704 (PlayerData)\n\tstw\tr3, 0x0710 (PlayerData)\n\tstw\tr3, 0x071C (PlayerData)\n#Z\n  lwz\tr3, 0x00B8 (PlayerData)\n  stw\tr3, 0x06FC (PlayerData)\n  stw\tr3, 0x0708 (PlayerData)\n\tstw\tr3, 0x0714 (PlayerData)\n\tstw\tr3, 0x0720 (PlayerData)\n#Update Collision Frame ID\n  lwz\tr3, -0x51F4 (r13)\n  stw r3, 0x728(PlayerData)\n\n  #branchl\tr12,0x80081b38     #Stopped using this because it deletes way too much ECB info\n  #branchl r12,0x80082a68      #Better than the above function, but all i need is to copy current position into the ECB previous values\n\n#Adjust JObj position (code copied from 8006c324)\n\tlwz r3,0x28(PlayerGObj)\t\t\t#get character model JObj\n\tlwz\tr4,0xB0(PlayerData)\t\t\t#get X\n\tstw r4,0x38(r3)\t\t\t\t\t\t\t#store X\n\tlwz\tr4,0xB4(PlayerData)\t\t\t#get Y\n\tstw r4,0x3C(r3)\t\t\t\t\t\t\t#store Y\n\tlwz\tr4,0xB8(PlayerData)\t\t\t#get Z\n\tstw r4,0x40(r3)\t\t\t\t\t\t\t#store Z\n#Dirty Sub\n\t#branchl r12,0x803732e8\n\n#Update Static Player Block Coords\n  lbz r3,0xC(PlayerData)\n  lbz\tr4, 0x221F (PlayerData)\n  rlwinm\tr4, r4, 29, 31, 31\n  addi  r5,PlayerData,176\n  branchl r12,0x80032828\n\nrestore\nblr\n\n#####################################\n\nGetGroundCenter:\n\n#in\n#r3 = Ground ID\n\n#Get Corner IDs from Ground ID\nmulli r0,r3,8\nlwz\tr5, -0x51E4 (r13)\nlwzx r5,r5,r0\nlhz r3,0x0(r5)\nlhz r4,0x2(r5)\n\n#Get Coordinates\nlwz r5, -0x51E8 (r13)\nmulli r3,r3,24\naddi  r3,r3,8\nadd  r3,r3,r5\nlfs f1,0x0(r3)    #Left X\nlfs f2,0x4(r3)    #Left Y\nmulli r4,r4,24\naddi  r4,r4,8\nadd  r4,r4,r5\nlfs f3,0x0(r4)    #Right X\nlfs f4,0x4(r4)    #Right Y\n\n#Get Center Value\nlfs f5,-0x4df0(rtoc)    #2f\nfadds f1,f1,f3\nfdivs f1,f1,f5          #Center X\nfadds f2,f2,f4\nfdivs f2,f2,f5          #Center Y\n\nblr\n\n####################################\n\nPlacePlayersCenterStage:\n\n#in\n#none\n\nbackup\n\n#Loop through players 1 and 2\n  .set count,27\n  .set player,26\n  .set playerdata,25\n  .set subchar,24\n  .set subchardata,23\n\n  li  count,0\n\nPlacePlayersCenterStage_Loop:\n#Get Player GObj\n  mr  r3,r27\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n#Check if exists\n  cmpwi r3,0x0\n  beq PlacePlayersCenterStage_IncLoop\n  mr  player,r3\n  lwz playerdata,0x2C(player)\n#Get Subchar Bool\n  bl CheckIfPlayerHasAFollower\n  mr  subchar,r3\n  mr  subchardata,r4\n#Call function to do heavy lifting\n  mr  r3,player\n  bl  PlacePlayersCenterStage_DoStuff\n#Check if subchar exits\n  cmpwi subchar,0\n  beq PlacePlayersCenterStage_IncLoop\n#Call function for this character\n  mr  r3,subchar\n  bl  PlacePlayersCenterStage_DoStuff\n#Next Player\nPlacePlayersCenterStage_IncLoop:\n  addi count,count,1\n  cmpwi count,6\n  blt PlacePlayersCenterStage_Loop\n  b PlacePlayersCenterStage_Exit\n\n#*****************************#\nPlacePlayersCenterStage_DoStuff:\n#in\n#r3 = player\n\n.set player,31\n.set playerdata,30\n.set constants,29\n\nbackup\n\n#Get Pointers\n  mr  player,r3\n  lwz playerdata,0x2C(r3)\n\n#Get Constants\n  bl  PlacePlayersCenterStage_Constants\n  mflr constants\n  lbz r3,0xC(playerdata)\n  mulli r3,r3,0x2\n  add constants,constants,r3\n\n#Initialize Player Data (Mainly for ICs so Nana knows where Popo is)\n  mr  r3,player\n  branchl r12,0x80068354\n\n#Get Stage's Ground ID\n  lwz\t\tr3,-0x6CB8 (r13)\t\t\t#External Stage ID\n  bl\t\tComboTraining_StartingGroundIDs\n  mflr  r4\n  mulli\tr3,r3,0x2\n  lhzx\tr3,r3,r4\n  bl  GetGroundCenter\n  fmr f30,f1\n  fmr f31,f2\n\n#Facing Directions\n  lbz r3,0x0(constants) #This players facing direction\n  extsb r3,r3\n  bl  IntToFloat\n  stfs f1,0x2C(playerdata)\n\n#Move Players\n  lbz r3,0x1(constants) #This players X offset\n  extsb r3,r3\n  bl  IntToFloat\n  fadds f2,f1,f30   #Player X = X+6\n  stfs f2,0xB0(playerdata)\n  stfs f31,0xB4(playerdata)\n\n#Enter into Wait\n  mr  r3,player\n  branchl r12,AS_Wait\n#Find Ground Below Player\n  mr  r3,player\n  bl  FindGroundNearPlayer\n  cmpwi r3,0    #Check if ground was found\n  beq PlacePlayersCenterStage_DoStuff_SkipGroundCorrection\n  stfs f1,0xB0(playerdata)\n  stfs f2,0xB4(playerdata)\n  stw r4,0x83C(playerdata)\n  PlacePlayersCenterStage_DoStuff_SkipGroundCorrection:\n#Update Position\n  mr  r3,player\n  bl  UpdatePosition\n#Update ECB Values for the ground ID\n  mr r3,player\n  branchl r12,EnvironmentCollision_WaitLanding\n#Set Grounded\n  mr r3,playerdata\n  branchl r12,Air_SetAsGrounded\n#Update Camera\n  mr r3,player\n  bl  UpdateCameraBox\n\nPlacePlayersCenterStage_DoStuff_Exit:\nrestore\nblr\n\n#*********#\n\nPlacePlayersCenterStage_Constants:\nblrl\n.byte 1,-6,-1,6\n.align 2\n#*********#\n\nPlacePlayersCenterStage_Exit:\nrestore\nblr\n\n#####################################\n\nFindGroundNearPlayer:\n#in\n#r3 = player GObj (optional)\n#f1 = X value\n#f2 = Y Value\n\n\n.set player,31\n.set playerdata,30\n\nbackup\nstfs f30,0x38(sp)\nstfs f31,0x3C(sp)\n\n#Check If Given Player GObj\n  cmpwi r3,0x0\n  bne FindGroundNearPlayer_GObjPassedIn\n\nFindGroundNearPlayer_CoordinatesPassedIn:\n#Backup Coords\n  fmr f30,f1\n  fmr f31,f2\n#Get 10f\n  li  r3,10\n  bl  IntToFloat\n#Get Bottom Coord\n  fmr f3,f30       #Bottom X is same as Top X\n  fsubs f4,f31,f1  #Bottom Y is Top Y - 1000\n#Move Top Coords Back\n  fmr f1,f30\n  fmr f2,f31\n  lfs\tf0, -0x7188 (rtoc)\n  fadds f2,f2,f0\n  b FindGroundNearPlayer_Continue\n\n\nFindGroundNearPlayer_GObjPassedIn:\n#Init Variables\n  mr  player,r3\n  lwz playerdata,0x2C(player)\n#Get Players X and Y+10\n  lfs f1,0xB0(playerdata)\n  lfs f2,0xB4(playerdata)\n  lfs\tf0, -0x7188 (rtoc)\n  fadds f2,f2,f0\n#Get Bottom Coord (X and Y-1000)\n  lfs f3,0xB0(playerdata)\n  lfs f4,0xB0(playerdata)\n  lfs\tf0,-0x71A8 (rtoc)\n  fsubs f4,f4,f0\n\nFindGroundNearPlayer_Continue:\n#Get Unk f5 argument\n  lfs\tf5, -0x7208 (rtoc)\n#Setup stack for return values\n  addi r3,sp,0x54   #(Returns Ground Coordinates\n  addi r4,sp,0x44   #(Returns Ground ID)\n  addi r5,sp,0x40   #(Returns Ground Type)\n  addi r6,sp,0x48   #(Returns Unk)\n#Unk arguments\n  li  r7,-1\n  li  r8,-1\n  li  r9,-1\n#Additional function pointer\n  li  r10,0\n#Call function\n  branchl r12,Raycast_GroundLine\n\n#Check if ground exists\n  cmpwi r3,0\n  beq FindGroundNearPlayer_Exit\n\n#Return Coordinates of ground below player\n  lfs f1,0x54(sp)\n  lfs f2,0x58(sp)\n  lwz r4,0x44(sp)\n\nFindGroundNearPlayer_Exit:\nlfs f30,0x38(sp)\nlfs f31,0x3C(sp)\nrestore\nblr\n\n#####################################\n\nFindGroundUnderCoordinate:\n#in\n#f1 = X value\n#f2 = Y Value\n\nbackup\nstfs f30,0x38(sp)\nstfs f31,0x3C(sp)\n\nFindGroundUnderCoordinate_CoordinatesPassedIn:\n#Backup Coords\n  fmr f30,f1\n  fmr f31,f2\n#Get 1000f\n  li  r3,1000\n  bl  IntToFloat\n#Get Bottom Coord\n  fmr f3,f30       #Bottom X is same as Top X\n  fsubs f4,f31,f1  #Bottom Y is Top Y - 1000\n#Move Top Coords Back\n  fmr f1,f30\n  fmr f2,f31\n\nFindGroundUnderCoordinate_Continue:\n#Get Unk f5 argument\n  lfs\tf5, -0x7208 (rtoc)\n#Setup stack for return values\n  addi r3,sp,0x54   #(Returns Ground Coordinates\n  addi r4,sp,0x44   #(Returns Ground ID)\n  addi r5,sp,0x40   #(Returns Ground Type)\n  addi r6,sp,0x48   #(Returns Unk)\n#Unk arguments\n  li  r7,-1\n  li  r8,-1\n  li  r9,-1\n  li  r10,0\n#Call function\n  branchl r12,Raycast_GroundLine\n\n#Check if ground exists\n  cmpwi r3,0\n  beq FindGroundUnderCoordinate_Exit\n\n#Return Coordinates of ground below player\n  lfs f1,0x54(sp)\n  lfs f2,0x58(sp)\n  lwz r4,0x44(sp)\n\nFindGroundUnderCoordinate_Exit:\nlfs f30,0x38(sp)\nlfs f31,0x3C(sp)\nrestore\nblr\n\n#####################################\nPlacePlayerOnGround:\nbackup\n\n.set REG_GObj,31\n.set REG_GObjData,30\n\n#Get Pointers\n\tmr\tREG_GObj,r3\n\tlwz REG_GObjData,0x2C(REG_GObj)\n\n#Find Ground Below Player\n  mr  r3,REG_GObj\n  bl  FindGroundNearPlayer\n  cmpwi r3,0    #Check if ground was found\n  beq PlacePlayerOnGround_SkipGroundCorrection\n  stfs f1,0xB0(REG_GObjData)\n  stfs f2,0xB4(REG_GObjData)\n  stw r4,0x83C(REG_GObjData)\n  PlacePlayerOnGround_SkipGroundCorrection:\n#Update Position\n  mr  r3,REG_GObj\n  bl  UpdatePosition\n#Update ECB Values for the ground ID\n  mr r3,REG_GObj\n  branchl r12,EnvironmentCollision_WaitLanding\n#Set Grounded\n  mr r3,REG_GObjData\n  branchl r12,Air_SetAsGrounded\n\nPlacePlayerOnGround_Exit:\n\trestore\n\tblr\n#####################################\nPlaySFX:\nbackup\n\nbranchl\t\tr12,SFX_PlaySoundAtFullVolume\n\nrestore\nblr\n#####################################\n\nUpdateCameraBox:\n#in\n#r3 = player\n\n.set player,31\n.set playerdata,30\n\nbackup\n\n#Get Pointer\n  mr  player,r3\n  lwz playerdata,0x2C(player)\n\n#Update Camera Box Position\n  mr  r3,player\n  branchl r12,Camera_UpdatePlayerCameraBoxPosition\n\n#Update Camera Box Direction Tween\n#  lwz r3,0x2C(player)\n#  branchl r12,0x80076064\n\n#Update Camera Box Direction Tween\n  lwz r3,0x890(playerdata)\n  lfs f1,0x40(r3)     #Leftmost Bound\n  stfs f1,0x2C(r3)    #Current Left Box Bound\n  lfs f1,0x44(r3)     #Rightmost Bound\n  stfs f1,0x30(r3)    #Current Right Box Bound\n\n#Correct Camera Position\n  branchl r12,Camera_CorrectPosition\n\nrestore\nblr\n\n#####################################\n\nGetAllPlayerPointers:\n\n#in\n#nothing\n\n#out\n#r3 = P1GObj\n#r4 = P1Data\n#r5 = P2GObj\n#r6 = P2Data\n#r7 = P3GObj\n#r8 = P3Data\n#r9 = P4GObj\n#r10 = P4Data\n\nbackup\n\n#Get Space to Store all Pointer to\n  addi r21,sp,0x40\n#Init Loop Count\n  li  r20,0\n\nGetAllPlayerPointers_Loop:\n#Get GObj\n  mr  r3,r20\n  branchl r12,PlayerBlock_LoadMainCharDataOffset\n#Check If Exists\n  cmpwi r3,0x0\n  li    r4,0      #Zero Data pointer just in case it doesnt exist\n  beq GetAllPlayerPointers_StoreToStack\n#Get Data\n  lwz r4,0x2C(r3)\n#Store Both to Stack\nGetAllPlayerPointers_StoreToStack:\n  mulli r5,r20,8\n  add r5,r5,r21\n  stw r3,0x0(r5)\n  stw r4,0x4(r5)\n\nGetAllPlayerPointers_IncLoop:\n  addi r20,r20,1\n  cmpwi r20,4\n  blt GetAllPlayerPointers_Loop\n\nGetAllPlayerPointers_LoadPointers:\n  lwz r3,0x00(r21)\n  lwz r4,0x04(r21)\n  lwz r5,0x08(r21)\n  lwz r6,0x0C(r21)\n  lwz r7,0x10(r21)\n  lwz r8,0x14(r21)\n  lwz r9,0x18(r21)\n  lwz r10,0x1C(r21)\n\nGetAllPlayerPointers_Exit:\nrestore\nblr\n\n#####################################\nRemoveFirstFrameInputs:\n\nRemoveFirstFrameInputs_GetFirstPlayer:\n  lwz\tr3, -0x3E74 (r13)\n  lwz\tr12, 0x0020 (r3)\n  b\tRemoveFirstFrameInputs_CheckIfPlayerExists\n\nRemoveFirstFrameInputs_GetNextPlayer:\n  lwz\tr12,0x8(r12)\n\nRemoveFirstFrameInputs_CheckIfPlayerExists:\n  cmpwi\tr12,0x0\n  beq\tRemoveFirstFrameInputs_Exit\n  lwz\tr5,0x2C(r12)\n\n#Remove Input Flag\n  lbz\tr0, 0x221D (r5)\n  li\tr3,0x1\n  rlwimi\tr0,r3,4,27,27\n  stb\tr0,0x221D (r5)\n#Store Current Input\n  lbz\tr4, 0x0618 (r5)\n  load r3,InputStructStart\n  mulli\tr0, r4, 68\n  add\tr3, r0, r3\n  lwz\tr0, 0 (r3)\n  stw\tr0, 0x065C (r5)\n  b\tRemoveFirstFrameInputs_GetNextPlayer\n\nRemoveFirstFrameInputs_Exit:\nblr\n\n#####################################\n\nInitializeMatch:\n\n.set REG_EventStruct,31\n.set REG_MatchStruct,30\n.set REG_CPUChoice,29\n.set REG_StageChoice,28\n.set REG_EventOSDs,27\n.set REG_PlayerStruct,26\n.set REG_UseSopo,25\n\n#Init\n\tbackup\n\tmr REG_EventStruct,r3\n\tmr REG_MatchStruct,r4\n\tmr REG_CPUChoice,r5\n\tmr REG_StageChoice,r6\n\tmr REG_EventOSDs,r7\n\tmr REG_UseSopo,r8\n\n#Check to override OSD Toggles\n\tlwz\tr4,-0x77C0(r13)\n\tlbz\tr3,0x1f2A(r4)\n\tcmpwi r3,1\n\tbeq InitializeMatch_SkipOSDOverride\n#Store Events FDD Toggles\n\tlwz\tr3,0x1F24(r4)\n\tor\tr3,r3,REG_EventOSDs\n\tstw\tr3,0x1F24(r4)\nInitializeMatch_SkipOSDOverride:\n\n#SPAWN 2 PLAYERS\n\tli\tr3,0x40\n\tstb\tr3,0x1(REG_EventStruct)\n\n#Make Copy of Struct\n\tli\tr3,32\n\tbranchl r12,HSD_MemAlloc\n\tmr REG_PlayerStruct,r3\n\tbl\tP2Struct\n\tmflr r4\n\tli\tr5,0x1C\n\tbranchl r12,memcpy\n#Store to P2 pointer in event struct\n\tstw REG_PlayerStruct,0x18(REG_EventStruct)\n\n#Store CPU\n\tcmpwi REG_CPUChoice,-1\n\tbeq InitializeMatch_StoreCSSCPU\n#Store this CPU\n\tstb\tREG_CPUChoice,0x0(REG_PlayerStruct)\n\tb\tInitializeMatch_StoreStage\nInitializeMatch_StoreCSSCPU:\n\tload\tr3,0x8043207c\t\t\t\t\t\t\t#get preload table\n\tlwz\tr4,0x18(r3)\t\t\t\t\t\t\t\t\t#get p2 character ID\n\tcmpwi\tr4,0x12\t\t\t\t\t\t\t\t\t\t#check if zelda\n\tbne\t0x8\n\tli\tr4,0x13\t\t\t\t\t\t\t\t\t\t\t#make zelda sheik\n\tstb\tr4,0x0(REG_PlayerStruct)\t\t#store chosen char\n\tlbz\tr6,0x1C(r3)\t\t\t\t\t\t\t\t\t#get p2 costume ID\n\tstb\tr6,0x3(REG_PlayerStruct)\t\t#store p2 costume ID\n\tli\tr5,0x1\t\t\t\t\t\t\t\t\t\t\t#make CPU controlled\n\tstb\tr5,0x1(REG_PlayerStruct)\n\nInitializeMatch_StoreStage:\n#Store Stage\n\tcmpwi REG_StageChoice,-1\n\tbeq InitializeMatch_StoreSSSStage\n#Store this Stage\n\tsth\tREG_StageChoice,0xE(REG_MatchStruct)\n\tb\tInitializeMatch_StoreStage_End\nInitializeMatch_StoreSSSStage:\n\tload\tr3,0x8043207c\t\t\t\t\t\t\t#get preload table\n\tlwz\tr3, 0x00C (r3)\n\tsth\tr3,0xE(REG_MatchStruct)\t\t\t#store chosen stage\nInitializeMatch_StoreStage_End:\n\nInitializeMatch_SwapInSopo:\n\tcmpwi REG_UseSopo,0\n\tbeq\tInitializeMatch_SwapInSopo_End\n#Swap P1 Character to Sopo\n\tlwz\tr4, -0x77C0 (r13)\n\taddi\tr4, r4, 1328\t\t#event mode match backup struct?\n\tlbz\tr3,0x2(r4)\t\t#P1 External ID\n\tcmpwi\tr3,0xE\n\tbne\tInitializeMatch_SwapInSopo_End\n\tli\tr3,0x20\n\tstb\tr3,0x2(r4)\t\t#Make SoPo\nInitializeMatch_SwapInSopo_End:\n\nInitializeMatch_Exit:\n\trestore\n\tblr\n\n#####################################\n\nGetDistance:\n\tlfs\tf3,0x0(r3)\t#X\n\tlfs\tf4,0x4(r3)  #Y\n\tlfs\tf5,0x0(r4)  #X\n\tlfs\tf6,0x4(r4)  #Y\n\tfsubs\tf1,f5,f3\n\tfsubs\tf2,f4,f6\n\tfmuls\tf1,f1,f1\n\tfmuls\tf2,f2,f2\n\tfadds\tf2,f1,f2\n\tfrsqrte\tf1,f2\n\tfmuls\tf1,f1,f2\n\tblr\n\n#####################################\n\nGetLedgeCoordinates:\n\n.set LedgeSide,20\n.set LedgeID,21\n.set Return,22\n\nbackup\n\n#Backup Ledge Choice (0 = Left, 1 = Right)\n  mr\tLedgeSide,r3\n  mr  Return,r4\n\n#Get Stage's Ledge IDs\n  lwz\t\tr3,-0x6CB8 (r13)\t\t\t#External Stage ID\n  bl\t\tLedgedashCliffIDs\n  mflr  r4\n  mulli\tr3,r3,0x2\n  lhzx\tr3,r3,r4\n#Get Requested Ledge\n\tcmpwi LedgeSide,0x0\n\tbeq\tGetLedgeCoordinates_GetLeftLedgeID\n\nGetLedgeCoordinates_GetRightLedgeID:\n  rlwinm\tLedgeID,r3,0,24,31\n#Get Ledge Coords (0x80 = X, 0x84 = Y)\n  mr  r3,LedgeID\n  mr \tr4,Return\n  branchl\tr12,Stage_GetRightOfLineCoordinates\n  b\tGetLedgeCoordinates_Exit\n\nGetLedgeCoordinates_GetLeftLedgeID:\n\trlwinm\tLedgeID,r3,24,24,31\n#Get Ledge Coords (0x80 = X, 0x84 = Y)\n  mr  r3,LedgeID\n  mr \tr4,Return\n  branchl\tr12,Stage_GetLeftOfLineCoordinates\n\tb\tGetLedgeCoordinates_Exit\n\nGetLedgeCoordinates_Exit:\n  restore\n  blr\n\n##########################################\nGetAngleBetweenPoints:\n.set REG_arctan,2\n.set REG_Constants,31\n\nbackup\n\n#Get Constants\n\tbl\tGetAngleBetweenPoints_Constants\n\tmflr REG_Constants\n\n#Get Values\n\tlfs f1,0x0(r3)\n\tlfs f2,0x4(r3)\n\tlfs f3,0x0(r4)\n\tlfs f4,0x4(r4)\n#Get slope ydelta / xdelta\n\tfsubs f5,f4,f2\n\tfsubs f6,f3,f1\n\tfdivs f1,f5,f6\n#atan\n\tbranchl r12,0x80022e68\n\tfmr REG_arctan,f1\n\n#Ensure above 0 and below 6.28319\nGetAngleBetweenPoints_CheckIfOver0:\n\tlfs f1,0x0(REG_Constants)\n\tfcmpo cr0,REG_arctan,f1\n\tbge GetAngleBetweenPoints_CheckIfUnder360\n#Add 180\n\tlfs f1,0x8(REG_Constants)\n\tfadds REG_arctan,REG_arctan,f1\n\tb\tGetAngleBetweenPoints_CheckIfOver0\nGetAngleBetweenPoints_CheckIfUnder360:\n\tlfs f1,0x4(REG_Constants)\n\tfcmpo cr0,REG_arctan,f1\n\tble GetAngleBetweenPoints_Under360\n#Add 180\n\tlfs f1,0x8(REG_Constants)\n\tfsubs REG_arctan,REG_arctan,f1\n\tb\tGetAngleBetweenPoints_CheckIfUnder360\nGetAngleBetweenPoints_Under360:\n\tfmr\tf1,REG_arctan\n\nGetAngleBetweenPoints_Exit:\nrestore\nblr\n\nGetAngleBetweenPoints_Constants:\nblrl\n.float 0\n.float 6.28319\n.float 3.14159\n\n##########################################\nEnterKnockback:\nbackup\n\n.set REG_GObj,31\n.set REG_GObjData,30\n.set REG_AngleLo,29\n.set REG_AngleHi,28\n.set REG_MagLo,27\n.set REG_MagHi,26\n.set REG_Angle,29\n.set REG_Magnitude,28\n\n#Backup Data\n\tmr\tREG_GObj,r3\n\tlwz REG_GObjData,0x2C(REG_GObj)\n\tmr\tREG_AngleLo,r4\n\tmr\tREG_AngleHi,r5\n\tmr\tREG_MagLo,r6\n\tmr\tREG_MagHi,r7\n\n#Random angle between\n\tsub\tr3,REG_AngleHi,REG_AngleLo\n\tbranchl r12,HSD_Randi\n\tadd REG_Angle,r3,REG_AngleLo\n#Cast to float\n\tmr\tr3,REG_Angle\n\tbl\tIntToFloat\n#Now in radians\n\tlfs\tf2, -0x7510 (rtoc)\n\tfmuls f1,f1,f2\n\tstfs f1,0x80(sp)\n\n#Random magnitude between X and Y\n\tmr\tr3,REG_MagLo\n\tmr\tr4,REG_MagHi\n\tbl\tRandFloat\n\tstfs f1,0x7C(sp)\t\t#will be used later for\n\tlwz\tr3, -0x514C (r13)\n\tlfs\tf0, 0x0100 (r3)\n\tfmuls f1,f1,f0\n\tstfs f1,0x84(sp)\n\n#Get X Component\n\tlfs f1,0x80(sp)\t\t#KB angle in radians\n\tbranchl r12,cos\n\tlfs f2,0x84(sp)\t\t#KB magnitude\n\tfmuls f1,f1,f2\n\tlfs f2,0x2C(REG_GObjData)\n\tfneg f2,f2\n\tfmuls f1,f1,f2\n\tstfs f1,0x8C(REG_GObjData)\n#Get Y Component\n\tlfs f1,0x80(sp)\t\t#KB angle in radians\n\tbranchl r12,sin\n\tlfs f2,0x84(sp)\t\t#KB magnitude\n\tfmuls f1,f1,f2\n\tstfs f1,0x90(REG_GObjData)\n\n#Calculate Hitstun\n\tlwz\tr3, -0x514C (r13)\n\tlfs\tf0, 0x0154 (r3)\n\tlfs f1,0x7C(sp)\n\tfmuls f1,f1,f0\t\t\t#hitstun frames is 0.4 * magnitude\n\tfctiwz f1,f1\t\t\t\t#Round down\n\tstfd f1,0x88(sp)\n\tlwz r3,0x8C(sp)\n\tbl\tIntToFloat\n\tstfs f1,0x2340(REG_GObjData)\n#Enable Hitstun Bit\n\tlbz r0,0x221C(REG_GObjData)\n\tli\tr3,1\n\trlwimi r0,r3,1,30,30\n\tstb r0,0x221C(REG_GObjData)\n\n#Enable ECB Update\n\tmr\tr3,REG_GObjData\n\tbranchl r12,0x8007d5bc\n\nEnterKnockback_Exit:\n\trestore\n\tblr\n\n##########################################\nDisableHazards:\n\n#Get list start\n\tbl\tDisableHazards_SkipList\n########################\nbl\tDisableHazards_Dummy\nbl\tDisableHazards_TEST\nbl\tDisableHazards_Izumi\nbl\tDisableHazards_Pstadium\nbl\tDisableHazards_Castle\nbl\tDisableHazards_Kongo\nbl\tDisableHazards_Zebes\nbl\tDisableHazards_Corneria\nbl\tDisableHazards_Story\nbl\tDisableHazards_Onett\nbl\tDisableHazards_MuteCity\nbl\tDisableHazards_RCruise\nbl\tDisableHazards_Garden\nbl\tDisableHazards_GreatBay\nbl\tDisableHazards_Shrine\nbl\tDisableHazards_Kraid\nbl\tDisableHazards_Yoster\nbl\tDisableHazards_Greens\nbl\tDisableHazards_Fourside\nbl\tDisableHazards_MK1\nbl\tDisableHazards_MK2\nbl\tDisableHazards_Akaneia\nbl\tDisableHazards_Venom\nbl\tDisableHazards_Pura\nbl\tDisableHazards_BigBlue\nbl\tDisableHazards_Icemt\nbl\tDisableHazards_Icetop\nbl\tDisableHazards_FlatZone\nbl\tDisableHazards_OldDL\nbl\tDisableHazards_OldYS\nbl\tDisableHazards_OldKongo\nbl\tDisableHazards_Battlefield\nbl\tDisableHazards_FinalDestination\n########################\nDisableHazards_SkipList:\n\tmflr r3\n\tlwz r4,StageID_External(r13)\n\tmulli\tr4,r4,4\n\tadd r4,r3,r4\n\tlwz r5,0x0(r4)\t\t\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t#Mask Bits 6-29 (the offset)\n\tcmpwi r5,0\t\t\t\t\t\t#If pointer is null, exit\n\tbeq\tDisableHazards_SkipList_Exit\n  add\tr4,r4,r5\t\t\t\t\t#Pointer to code now in r4\n\tmtctr r4\n\tbctr\n\n########################\n\nDisableHazards_Story:\n/*\n#Get randall's line ID\n\tmr\tr3,REG_map_gobj\n\tbranchl r12,0x801c6330\n\tlwz\tr3,0x4(r3)\t\t\t\t\t\t#get map_head\n\tlwz r3,0x8(r3)\t\t\t\t\t\t#get map_gobj info\n\tmulli\tr4,REG_map_gobj,52\t#get randall's info\n\tadd r3,r3,r4\n\tlwz r3,0x20(r3)\t\t\t\t\t\t#pointer to the collision data\n\tlhz r3,0x0(r3)\t\t\t\t\t\t#i believe this is randalls line ID\n#Get randalls corner IDs\n\tmulli r3,r3,8\t\t\t\t\t\t\t#0x8 in length\n\tlwz\tr4, -0x51E4 (r13)\t\t\t#line to corner ID table\n\tlwzx r5,r3,r4\t\t\t\t\t\t\t#now have the corner ID struct\n\tlhz r3,0x0(r5)\t\t\t\t\t\t#left corner id\n\tlhz r4,0x2(r5)\t\t\t\t\t\t#right corner id\n#Get corner IDs info\n\tlwz\tr5, -0x51E8 (r13)\n\tmulli r3,r3,24\n\tmulli r4,r4,24\n\tadd r3,r3,r5\n\tadd r4,r4,r5\n#Zero current X and Y positions, effectively removing these lines\n\tli\tr5,0\n\tstw r5,0x8(r3)\n\tstw r5,0xC(r3)\n\tstw r5,0x8(r4)\n\tstw r5,0xC(r4)\n*/\n\n/*\n#Get randall's map_gobj\n\tli\tr3,2\t\t\t\t#randalls map_gobj is 2\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,Stage_Destroy_map_gobj\n*/\n\n#Get shyguy's map_gobj\n\tli\tr3,3\t\t\t\t#shyguys map_gobj is\n\tbranchl r12,Stage_map_gobj_Load\n#Remove Proc\n\tbranchl r12,GObj_RemoveProc\n\n#Fix ragdoll issue\n\tbl\tDisableHazards_RagdollFix\n\nb\tDisableHazards_SkipList_Exit\n\n########################\n\nDisableHazards_Pstadium:\n#Get transformation's map_gobj\n\tli\tr3,2\t\t\t\t#transformation's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n#Remove Proc\n\tbranchl r12,GObj_RemoveProc\n#Fix ragdoll issue\n\tbl\tDisableHazards_RagdollFix\n\nb\tDisableHazards_SkipList_Exit\n\n########################\n\nDisableHazards_OldDL:\n#Destroy whispy's map_gobj\n\tli\tr3,7\t\t\t\t#transformation's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,Stage_Destroy_map_gobj\n\n#Destroy whispy's blink map_gobj proc\n\tli\tr3,6\t\t\t\t#transformation's map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,GObj_RemoveProc\n\n#set wind hazard count to 0\n\tli\tr3,0\n\tstw\tr3,Stage_PositionHazardCount(r13)\n\nb\tDisableHazards_SkipList_Exit\n\n########################\n\nDisableHazards_OldYS:\n#Destroy cloud's map_gobj\n\tli\tr3,2\t\t\t\t#map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,Stage_Destroy_map_gobj\n\nb\tDisableHazards_SkipList_Exit\n\n########################\n\nDisableHazards_OldKongo:\n#Destroy barrel's map_gobj\n\tli\tr3,1\t\t\t\t#map_gobj ID\n\tbranchl r12,Stage_map_gobj_Load\n\tbranchl r12,Stage_Destroy_map_gobj\n\nb\tDisableHazards_SkipList_Exit\n\n########################\nDisableHazards_RagdollFix:\n#Certain stages have an essential ragdoll function\n#in their map_gobj think function. If the think function is removed,\n#the ragdoll function must be re-scheduled to function properly.\n\nbackup\n\n#Create GObj\n  li\tr3,3\t\t#GObj Type\n  li\tr4,5\t\t#On-Pause Function\n  li\tr5,0\n  branchl\tr12,GObj_Create\n#Schedule Task\n\tbl\tDisableHazards_RagdollFix_Think\n\tmflr r4\n  li\tr5,4\t\t#Priority\n  branchl\tr12,GObj_AddProc\n\tb\tDisableHazards_RagdollFix_Exit\n\n#********************************#\nDisableHazards_RagdollFix_Think:\nblrl\n\nbackup\n\nbranchl r12,Ragdoll_WindDecayThink\n\nrestore\nblr\n#********************************#\n\nDisableHazards_RagdollFix_Exit:\nrestore\nblr\n#########################\n\nDisableHazards_SkipList_Exit:\n\trestore\n\tblr\n###########################################\n\nPlaybackInputSequence:\n.set REG_PlayerData,31\n.set REG_InputSequence,30\n.set REG_AttackTimer,29\n\n#Input Sequence Struct\n.set InputSequence_Length,0x9\n.set InputSequence_Frame,0x0\n.set InputSequence_Buttons,0x1\n.set InputSequence_AnalogX,0x5\n.set InputSequence_AnalogY,0x6\n.set InputSequence_CStickX,0x7\n.set InputSequence_CStickY,0x8\n\nbackup\n\n#Backup args\n\tmr\tREG_PlayerData,r3\n\tmr\tREG_InputSequence,r4\n\tmr\tREG_AttackTimer,r5\n\nPlaybackInputSequence_Loop:\n#Search for this frames input in the sequence\n\tlbz r3,InputSequence_Frame(REG_InputSequence)\n#Check if end of sequence\n\textsb r0,r3\n\tcmpwi r0,-1\n\tbeq PlaybackInputSequenceExit\n#Check if this frame's input\n\tcmpw r5,r3\n\tbeq PlaybackInputSequence_PlayInput\n\tblt PlaybackInputSequenceExit\t\t\t\t\t\t#Check if the current frame is less than the parsed frame\n#If greater, continue parsing\n\taddi REG_InputSequence,REG_InputSequence,InputSequence_Length\n\tb PlaybackInputSequence_Loop\t\t\t\t\t\t#If greater, continue parsing\n\nPlaybackInputSequence_PlayInput:\n\tlwz r3,InputSequence_Buttons(REG_InputSequence)\n\tstw r3,CPU_HeldButtons(REG_PlayerData)\n\tlbz r3,InputSequence_AnalogX(REG_InputSequence)\n\tstb r3,CPU_AnalogX(REG_PlayerData)\n\tlbz r3,InputSequence_AnalogY(REG_InputSequence)\n\tstb r3,CPU_AnalogY(REG_PlayerData)\n\tlbz r3,InputSequence_CStickX(REG_InputSequence)\n\tstb r3,CPU_CStickX(REG_PlayerData)\n\tlbz r3,InputSequence_CStickY(REG_InputSequence)\n\tstb r3,CPU_CStickY(REG_PlayerData)\n\nPlaybackInputSequenceExit:\n\trestore\n\tblr\n\n###########################################\nPlaceOnLedge:\nbackup\n\n.set REG_LedgeID,31\n.set REG_P1GObj,30\n.set REG_P1Data,29\n\n#Backup pointers\nmr\tREG_P1GObj,r3\nlwz REG_P1Data,0x2C(REG_P1GObj)\nmr\tREG_LedgeID,r4\n\n#Get Stage's Ledge IDs\n\tlwz\t\tr3,-0x6CB8 (r13)\t\t\t#External Stage ID\n\tbl\t\tLedgedashCliffIDs\n\tmflr  r4\n\tmulli\tr3,r3,0x2\n\tlhzx\tr3,r3,r4\n#Get Requested Ledge\n\tcmpwi REG_LedgeID,0x0\n\tbeq\tPlaceOnLedge_GetLeftLedgeID\n\nPlaceOnLedge_GetRightLedgeID:\n\trlwinm\tr20,r3,0,24,31\n#Change Facing Direction\n\tli\tr3,-1\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n\tb\tPlaceOnLedge_StoreLedgeIDAndPosition\n\nPlaceOnLedge_GetLeftLedgeID:\n\trlwinm\tr20,r3,24,24,31\n#Change Facing Direction\n\tli\tr3,1\n\tbl\tIntToFloat\n\tstfs\tf1,0x2C(REG_P1Data)\n\tb\tPlaceOnLedge_StoreLedgeIDAndPosition\n\nPlaceOnLedge_StoreLedgeIDAndPosition:\n#Store Ledge to Player Block\n\tstw r20,0x2340(REG_P1Data)\n#Enter CliffWait\n\tmr\tr3,REG_P1GObj\n\tbranchl r12,AS_CliffWait\n#Init state variable (would be 1 at the start of the next frame if it ocurred naturally)\n\tli\tr3,1\n\tstw\tr3,0x2348(REG_P1Data)\n#Spoof in state for 1 frame\n\tli\tr3,1\n\tsth\tr3,TM_FramesinCurrentAS(REG_P1Data)\n#Get Jump Back\n\tmr r3,REG_P1Data\n\tbranchl r12,Air_StoreBool_LoseGroundJump_NoECBfor10Frames\n#Set ECB Update Flag\n\tmr  r3,REG_P1Data\n\tbranchl r12,DataOffset_ECBBottomUpdateEnable\n#Update ECB Corner Positions\n\taddi\tr3,REG_P1Data,0x6F0\n\tbranchl\tr12,0x80048160\n#Move Player To Ledge\n\tmr\tr3,REG_P1GObj\n\tbranchl r12,MovePlayerToLedge\n#Update Position\n\tmr\tr3,REG_P1GObj\n\tbl UpdatePosition\n#Kill Velocity\n\tli\t\tr3,0x0\n\tstw\t\tr3,0x80(REG_P1Data)\t\t\t#X Velocity\n\tstw\t\tr3,0x84(REG_P1Data)\t\t\t#Y Velocity\n\n#Give Intangibility (30)\n\tmr\tr3,REG_P1GObj\n\tlwz\tr4, -0x514C (r13)\n\tlwz\tr4, 0x049C (r4)\n\tbranchl\tr12,ApplyIntangibility\n\n\trestore\n\tblr\n###########################################\nGetInputStruct:\n  load r4,InputStructStart\n  mulli\tr0, r3, 68\n  add\tr3, r0, r4\n\tblr\n\n###########################################\nexit:\nli\tr0, 3\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Custom Event Preload Behavior/Disable Event Preload - CSS Enter.asm",
    "content": "#To be inserted at 801baaa8\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n .macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n.set playerdata,31\n\nCustomEvent:\n  branch r12,0x801baabc\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Custom Event Preload Behavior/Disable Event Preload - Match Enter.asm",
    "content": "#To be inserted at 801bb648\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n .macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n.set playerdata,31\n\n  li r0,-1        #Load -1, which doesnt attempt to hijack any preload table values\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Custom Event Preload Behavior/Disable Event Preload.asm",
    "content": "#To be inserted at 803db000\n.long 0x012b0000\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Custom Event Preload Behavior/Dont Adjust CPU Color in Event Mode When Its Already in Use.asm",
    "content": "#To be inserted at 801bb294\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nb 0x30\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Custom Event Preload Behavior/Load Character ssm Files.asm",
    "content": "#To be inserted at 801bab04\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n .macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n.set playerdata,31\n\nbackup\n\nmr r31,r3\n\n#Loop through selected characters and load .ssm files\n  mr r27,r31\n  li  r28,0\n  mulli r0,r28,36\n  li  r29,0\n  li  r30,0\nLoop:\n  lbz r3,0x70(r27)\n  extsb r3,r3\n  branchl r12,0x80026e84\n  addi r28,r28,1\n  cmpwi r28,6\n  or r29,r29,r4\n  or r30,r30,r3\n  addi r27,r27,36\n  blt Loop\n\n#Clear Audio Cache?\n  li r3,20\n  branchl r12,0x80026f2c\n#Request All ssm Files\n  li  r3,4\n  mr r5,r30\n  mr r6,r29\n  branchl r12,0x8002702c\n#Load Preload Cache\n  branchl r12,0x80027168\n\nexit:\nmr r3,r31\nrestore\naddi\tr4, r31, 2\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Backup FDD Backup on Event Choose.asm",
    "content": "#To be inserted at 8024d95c\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n .macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n.set playerdata,31\n\n\n#Backup\nlwz\tr6,-0x77C0(r13)\nlwz\tr5,0x1F24(r6)\nstw\tr5,-0xDA8(rtoc)\n\nExit:\nlwz\tr3, 0x0004 (r28)\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Better X and Y Event Jump/Jump Down - Update Cursor.asm",
    "content": "#To be inserted at 8024da98\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n#Update cursor position\n#Get Texture Data\n\tlwz\tr3, -0x4A40 (r13)\n\tlwz\tr3, 0x0028 (r3)\n\taddi r4,sp,0x40\n\tli\tr5,11\n\tli\tr6,-1\n\tcrclr\t6\n\tbranchl r12,0x80011e24\n#Get New Y Offset\n\tlis\tr0,0x4330\n\tstw r0,0xA8(sp)\n\tlwz\tr3, -0x4A40 (r13)\n\tlwz\tr3, 0x002C (r3)\n\tlbz\tr3,0x0(r3)\t\t\t#event selection ID\n\tstw r3,0xAC(sp)\n\tlfd f1,0xA8(sp)\n\tlfd\tf2, -0x3888 (rtoc)\n\tfsubs f1,f1,f2\n\tbl\tFloat\n\tmflr r3\n\tlfs f2,0x0(r3)\n\tfmuls f1,f1,f2\n#Change Y offset\n\tlwz r3,0x40(sp)\n\tstfs f1,0x3C(r3)\n#DirtySub\n\tlwz r3,0x40(sp)\n\tbranchl r12,0x803732e8\n\tb\tOriginal\n\nFloat:\nblrl\n.float -1.32\n\nOriginal:\n\tmr\tr3,r28\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Better X and Y Event Jump/Jump Down.asm",
    "content": "#To be inserted at 8024d998\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set EventID,31\n.set PageID,30\n.set NumOfEvents,30\n\nbackup\n\n#Get Current Event\n\tlbz\tr3,0x0(r28)\n\tlwz\tr4,0x4(r28)\n\tadd\tEventID,r3,r4\n\n#Get Current Page\n  lwz r3,MemcardData(r13)\n  lbz PageID,CurrentEventPage(r3)\n#Get pointer page's string array\n\tbl\tSkipJumpTable\n\n##### Page List #######\n\tEventJumpTable\n#######################\n\nSkipJumpTable:\n#Get number of events on this page\n  mflr\tr4\t\t#Jump Table Start in r4\n  mulli\tr5,PageID,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n  add\tr5,r4,r5\t\t#Gets Address in r4\n  lwz NumOfEvents,0x0(r5)\n\n#Check if already on last event\n  cmpw EventID,NumOfEvents\n  bge exit\n\n#Jump 9 events\n  addi  r3,EventID,9\n#Check if exceeded NumOfEvents\n  cmpw r3,NumOfEvents\n  bge LastEvent\n\nJumpEvent:\n#add 9 to event ID\n  lbz\tr3,0x0(r28)\n  addi r3,r3,9\n  stb r3,0x0(r28)\n  b UpdateText\n\nLastEvent:\n#if NumOfEvents >= 9, event ID = 9, scroll ID = NumOfEvents-8\n  cmpwi NumOfEvents,9\n  blt LessThan9Events\nGreaterThan9Events:\n  li  r3,8\n  stb\tr3,0x0(r28)\n  subi r3,NumOfEvents,8\n  stw r3,0x4(r28)\n  b UpdateText\nLessThan9Events:\n#if NumOfEvents < 9, event ID = NumOfEvents, scroll ID = 0\n  stb\tNumOfEvents,0x0(r28)\n  li  r3,0\n  stw r3,0x4(r28)\n  b UpdateText\n\n#############################\nEventAmountPerPage\n##############################\n\nUpdateText:\n#overflow event ID to scroll ID\n  lbz r3,0x0(r28)\n  cmpwi r3,8\n  ble 0x1C\n#get overflow and add to scroll\n  subi r3,r3,8\n  lwz r4,0x4(r28)\n  add r3,r3,r4\n  stw r3,0x4(r28)     #add to scroll\n  li  r3,8\n  stb r3,0x0(r28)\n#now Correct Scroll\n  lwz r3,0x4(r28)\n  subi r4,NumOfEvents,8\n  cmpw r3,r4\n  ble UpdateText1\n#Highlight last entry\n  cmpwi NumOfEvents,8\n  bgt 0x10\n  mr  r3,NumOfEvents\n  li  r4,0\n  b 0x8\n  li  r3,8          #highlight last entry\n  stb\tr3,0x0(r28)\n  stw r4,0x4(r28)   #last scroll\n\nUpdateText1:\n#Play SFX and Update Text\n  li  r3,2\n  branchl r12,0x80024030\n  restore\n  branch r12,0x8024d9dc\n\nexit:\n  restore\n  branch r12,0x8024e198\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Better X and Y Event Jump/Jump Up - Update Cursor.asm",
    "content": "#To be inserted at 8024dbb4\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n#Update cursor position\n#Get Texture Data\n\tlwz\tr3, -0x4A40 (r13)\n\tlwz\tr3, 0x0028 (r3)\n\taddi r4,sp,0x40\n\tli\tr5,11\n\tli\tr6,-1\n\tcrclr\t6\n\tbranchl r12,0x80011e24\n#Get New Y Offset\n\tlis\tr0,0x4330\n\tstw r0,0xA8(sp)\n\tlwz\tr3, -0x4A40 (r13)\n\tlwz\tr3, 0x002C (r3)\n\tlbz\tr3,0x0(r3)\t\t\t#event selection ID\n\tstw r3,0xAC(sp)\n\tlfd f1,0xA8(sp)\n\tlfd\tf2, -0x3888 (rtoc)\n\tfsubs f1,f1,f2\n\tbl\tFloat\n\tmflr r3\n\tlfs f2,0x0(r3)\n\tfmuls f1,f1,f2\n#Change Y offset\n\tlwz r3,0x40(sp)\n\tstfs f1,0x3C(r3)\n#DirtySub\n\tlwz r3,0x40(sp)\n\tbranchl r12,0x803732e8\n\tb\tOriginal\n\nFloat:\nblrl\n.float -1.32\n\nOriginal:\n\tmr\tr3,r28\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Better X and Y Event Jump/Jump Up.asm",
    "content": "#To be inserted at 8024dabc\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set EventID,31\n.set PageID,30\n.set NumOfEvents,30\n\nbackup\n\n#Get Current Event\n\tlbz\tr3,0x0(r28)\n\tlwz\tr4,0x4(r28)\n\tadd\tEventID,r3,r4\n\n#Check if already on first event\n  cmpwi EventID,0\n  ble exit\n\n#Jump 9 events\n  subi  r3,EventID,9\n#Check if exceeded 0\n  cmpwi r3,0\n  ble FirstEvent\n\nJumpEvent:\n#sub 9 from event ID\n  lbz\tr3,0x0(r28)\n  subi r3,r3,9\n  stb r3,0x0(r28)\n  b UpdateText\n\nFirstEvent:\n\tli\tr3,0\n\tstb r3,0x0(r28)\n\tstw r3,0x4(r28)\n  b UpdateText\n\nUpdateText:\n#overflow event ID to scroll ID\n  lbz r3,0x0(r28)\n\textsb r3,r3\n  cmpwi r3,0\n  bge UpdateText1\n#get overflow and add to scroll\n  lwz r4,0x4(r28)\n  add r3,r3,r4\n  stw r3,0x4(r28)     #add to scroll\n  li  r3,0\n  stb r3,0x0(r28)\n\nUpdateText1:\n#Play SFX and Update Text\n  li  r3,2\n  branchl r12,0x80024030\n  restore\n  branch r12,0x8024daf8\n\nexit:\n  restore\n  branch r12,0x8024e198\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Change ESS Proc To Pri 1.asm",
    "content": "#To be inserted at 8024e910\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nli\tr5,1\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Choose Any Character for Events/Always Copy CSS Character Info.asm",
    "content": "#To be inserted at 801bb1b0\nnop"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Choose Any Character for Events/Always Show Select Character Texture.asm",
    "content": "#To be inserted at 8024d0e8\nnop"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Choose Any Character for Events/Always Spoof AnyCharacter.asm",
    "content": "#To be inserted at 801bbfb0\nli\tr0, 33"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Custom ESS Button Actions.asm",
    "content": "#To be inserted at 8024d92c\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nbackup\n\n#Check For L\n\tli\tr3,4\n\tbranchl\tr12,Inputs_GetPlayerInstantInputs\n\trlwinm.\tr0, r4, 0, 25, 25\t\t\t#CHECK FOR L\n\tbne\tOpenFDD\n\n/*\n\trlwinm.\tr0, r4, 0, 27, 27\t\t\t#CHECK FOR Z\n\tbne\tOpenOptions\n\n\n#Check for Tutotial (R)\n#Check For Training Mode ISO Game ID First\n\tlis\tr5,0x8000\n\tlwz\tr5,0x0(r5)\n\tload\tr6,0x47544d45\t\t\t#GTME\n\tcmpw\tr5,r6\n\tbne\tCheckToSwitchPage\n#Check for R\n\trlwinm.\tr0, r4, 0, 26, 26\t\t\t#CHECK FOR R\n\tbne\tPlayMovie\n*/\n\nCheckToSwitchPage:\n\tli\tr3,4\n\tbranchl\tr12,Inputs_GetPlayerRapidInputs\n#Check For Left\n\tli\tr5,-1\n\trlwinm. r0,r3,0,25,25\n\tbne\tSwitchPage\n#Check For Right\n\tli\tr5,1\n\trlwinm. r0,r3,0,24,24\n\tbne\tSwitchPage\n\tb\texit\n\nOpenFDD:\n\n\t#PLAY SFX\n\tli\tr3, 1\n\tbranchl\tr4,0x80024030\n\n\t#SET FLAG IN RULES STRUCT\n\tli\tr0,3\t\t\t\t\t\t\t\t#3 = frame data from event toggle\n\tload\tr3,0x804a04f0\n\tstb\tr0, 0x0011 (r3)\n\n\t#SET SOMETHING\n\tli\tr0, 5\n\tsth\tr0, -0x4AD8 (r13)\n\n\t#BACKUP CURRENT EVENT ID\n\tlwz\tr3, -0x4A40 (r13)\n\tlwz\tr5, 0x002C (r3)\n\tlbz\tr3,0x0(r5)\n\tlwz\tr4,0x4(r5)\n\tadd\tr3,r3,r4\n\tlwz\tr4, -0x77C0 (r13)\n\tstb\tr3, 0x0535 (r4)\n\n\t#LOAD RSS\n\tbranchl\tr3,0x80237410\n\n\t#REMOVE EVENT THINK FUNCTION\n\tlwz\tr3, -0x3E84 (r13)\n\tbranchl\tr12,0x80390228\n\n\tb\texit\n\n/*\nOpenOptions:\n\n#Create Background + GObj\n\tbl\tOptionMenu_CreateBackground\n#Display Menus Text\n\tbl\tMenuData_MainMenuBlrl\n\tmflr r4\n\tbl\tOptionMenu_CreateText\n#Play SFX\n\tli\tr3,1\n\tbranchl r12,0x80024030\n\tb\texit\n\n#region OptionMenu_CreateBackground\nBG_Constants:\nblrl\n.set BG_Transparency,0x0\n.set BG_ScaleX,0x4\n.set BG_ScaleY,0x8\n.set BG_TransformX,0xC\n.set BG_TransformY,0x10\n.set BG_TransformZ,0x14\n.set BG_Color,0x18\n.float 0.85\t\t\t\t\t\t\t#transparency\n.float 0.1\t\t\t\t\t\t\t#scale X\n.float 0.15\t\t\t\t\t\t\t#scale Y\n.float 8\t\t\t\t\t\t\t\t#X Position\n.float 3\t\t\t\t\t\t\t\t#Y position\n.float 20\t\t\t\t\t\t\t\t#Z Position\n.byte 13, 13, 46, 255\t\t#Color\n\nOptionMenu_CreateBackground:\n.set\tREG_GObj,20\n.set\tREG_GObjData,21\n\nbackup\n\n#Create Background GObj\n  li  r3,6\n  li  r4,7\n  li  r5,0x80\n  branchl r12,GObj_Create\n  mr  REG_GObj,r3\n#Allocate Space\n\tli\tr3,64\n\tbranchl r12,HSD_MemAlloc\n\tmr\tREG_GObjData,r3\n#Zero\n\tli\tr4,64\n\tbranchl r12,ZeroAreaLength\n#Initialize\n\tmr\tr6,REG_GObjData\n\tmr\tr3,REG_GObj\n\tli\tr4,4\n\tload\tr5,0x8037f1b0\n\tbranchl r12,GObj_AddUserData\n#Add Process\n\tmr\tr3,REG_GObj\n\tbl\tOptionMenu_Think\n\tmflr r4\n\tli\tr5,0\n\tbranchl r12,GObj_AddProc\n#Get JObj from archive\n  lwz\tr3, -0x4AE8 (r13)\n  load r4,0x803efa0c\n  branchl r12,0x80380358\n#Load JObj\n  branchl r12,HSD_JObjLoadJoint\n#Get child JObj (the black background)\n\tmr\tr22,r3\n\tlwz r3,0x10(r3)\n\n#Remove parent and child (the message box)\n\tli\tr4,0\n\tstw r4,0x0c(r3)\n\tstw r4,0x10(r3)\n#Adjust transparency\n\tlwz r4,0x18(r3)\n\tlwz r4,0x8(r4)\n\tlwz r4,0xC(r4)\n\tbl\tBG_Constants\n\tmflr r5\n\tlfs f1,BG_Transparency(r5)\n\tstfs f1,0xC(r4)\n#Adjust color\n\tlwz r6,BG_Color(r5)\n\tstw r6,0x4(r4)\n#Adjust Scale\n\tlfs f1,BG_ScaleX(r5)\n\tstfs f1,0x2C(r3)\n\tlfs f1,BG_ScaleY(r5)\n\tstfs f1,0x30(r3)\n#Adjust Position\n\tlfs f1,BG_TransformX(r5)\n\tstfs f1,0x38(r3)\n\tlfs f1,BG_TransformY(r5)\n\tstfs f1,0x3C(r3)\n\tlfs f1,BG_TransformZ(r5)\n\tstfs f1,0x40(r3)\n#Store JObj to GObj\n  mr  r5,r22\n  mr  r3,REG_GObj\n  lbz\tr4, -0x3E57 (r13)\n  branchl r12,GObj_StorePointerToJObj\n#Add GX Link\n  mr  r3,REG_GObj\n  load r4,0x80391070\n  li  r5,7                    #layer id? higher = drawn later\n  li  r6,127                  #priority, higher = drawn later\n  branchl r12,GObj_AddGXLink\n\n#Return the GObj\n\tmr\tr3,REG_GObj\n\n#Exit\n\trestore\n\tblr\n#endregion\n\n#region OptionMenu_Think\nOptionMenu_Think:\nblrl\n.set REG_GObj,31\nbackup\n\n#Backup\n\tmr\tREG_GObj,r3\n\tlwz\tREG_GObjData,0x2C(REG_GObj)\n\n#Disable Event Menu\n\tli\tr3,1\n\tsth\tr3, -0x4AD8 (r13)\n\n#Check for Z and close menu\n\tli\tr3,4\n\tbranchl r12,Inputs_GetPlayerInstantInputs\n\trlwinm.\tr0, r4, 0, 27, 27\t\t\t#CHECK FOR Z\n\tbne\tOptionMenu_ThinkDestroy\n\trlwinm.\tr0, r3, 0, 26, 26\t\t\t#CHECK FOR Down\n\tbne OptionMenu_ThinkDown\n\trlwinm.\tr0, r3, 0, 27, 27\t\t\t#CHECK FOR Up\n\tbne OptionMenu_ThinkUp\n\trlwinm.\tr0, r3, 0, 31, 31\t\t\t#CHECK FOR A\n\tbne OptionMenu_ThinkSelect\n\trlwinm.\tr0, r3, 0, 30, 30\t\t\t#CHECK FOR B\n\tbne OptionMenu_ThinkBack\n\tb\tOptionMenu_ThinkExit\n\nOptionMenu_ThinkDown:\n#Down one cursor position\n\tlwz\tr3,Cursor(REG_GObjData)\n\taddi r4,r3,1\n#Highlight current cursor\n\tmr\tr3,REG_GObjData\n\tbl\tOptionMenu_AdjustCursor\n#Play SFX\n\tli\tr3,2\n\tbranchl r12,0x80024030\n\tb\tOptionMenu_ThinkExit\n\nOptionMenu_ThinkUp:\n#Up one cursor position\n\tlwz\tr3,Cursor(REG_GObjData)\n\tsubi r4,r3,1\n#Highlight current cursor\n\tmr\tr3,REG_GObjData\n\tbl\tOptionMenu_AdjustCursor\n#Play SFX\n\tli\tr3,2\n\tbranchl r12,0x80024030\n\tb\tOptionMenu_ThinkExit\n\nOptionMenu_ThinkSelect:\n#Loop through current menu\n.set REG_Count,20\n.set REG_OptionData,22\n.set REG_OptionCount,23\n.set REG_MenuData,24\n.set REG_Cursor,25\n#Init\n\tli\tREG_Count,0\t\t\t\t\t\t\t\t\t\t\t\t\t\t#loop count\n\tli\tREG_OptionCount,0\t\t\t\t\t\t\t\t\t\t\t#Only incremented when an option is found\n\tlwz\tREG_MenuData,MenuData(REG_GObjData)\n\tlwz\tREG_Cursor,Cursor(REG_GObjData)\n\nOptionMenu_ThinkSelect_SearchOptionsLoop:\n#Get this option's text\n\taddi r3,REG_MenuData,MenuData_OptionsStart\n\tmulli\tr4,REG_Count,MenuData_OptionDataLength\n\tadd\tREG_OptionData,r3,r4\n#Get OnSelectType\n\tlwz \tr3,MenuData_OnSelectType(REG_OptionData)\n\tcmpwi\tr3,OnSelect_None\n\tbeq\tOptionMenu_ThinkSelect_SearchOptionsIncLoop\n#Check if this is the desired option\n\tcmpw REG_OptionCount,REG_Cursor\n\tbeq OptionMenu_ThinkSelect_SelectOption\n#Increment Option Count\n\taddi\tREG_OptionCount,REG_OptionCount,1\n\tb\tOptionMenu_ThinkSelect_SearchOptionsIncLoop\n\nOptionMenu_ThinkSelect_SelectOption:\n#Play SFX\n\tli\tr3,1\n\tbranchl r12,0x80024030\n#Decide Selection Type\n\tlwz\tr3,MenuData_OnSelectType(REG_OptionData)\n\tcmpwi\tr3,OnSelect_Menu\n\tbeq\tOptionMenu_ThinkSelect_GetNextMenu\n\tcmpwi\tr3,OnSelect_Function\n\tbeq\tOptionMenu_ThinkSelect_GetFunction\n\tb\tOptionMenu_ThinkSelect_SearchOptionsEnd\n\nOptionMenu_ThinkSelect_GetNextMenu:\n#Convert bl instruction to mem address\n\taddi\tr4,REG_OptionData,MenuData_OnSelectData\n\tlwz\tr5,0x0(r4)\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n\textsh\tr5,r5\n  add\tr4,r4,r5\t\t\t\t\t\t#Gets Address in r3\n#Create Text\n\tmr\tr3,REG_GObj\n\tbl\tOptionMenu_CreateText\n\tb\tOptionMenu_ThinkSelect_SearchOptionsEnd\n\nOptionMenu_ThinkSelect_GetFunction:\n#Convert bl instruction to mem address\n\taddi\tr4,REG_OptionData,MenuData_OnSelectData\n\tlwz\tr5,0x0(r4)\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n\textsh\tr5,r5\n\tcmpwi\tr5,0\n\tbeq\tOptionMenu_ThinkSelect_NoFunction\n  add\tr4,r4,r5\t\t\t\t\t\t#Gets Address in r3\n\tmtctr\tr4\n\tmr\tr3,REG_GObj\n\tbctrl\n\tb\tOptionMenu_ThinkSelect_SearchOptionsEnd\nOptionMenu_ThinkSelect_NoFunction:\n#Play Error Sound\n  li\tr3, 3\n  branchl\tr12,0x80024030\n  li\tr3, 3\n  branchl\tr12,0x80024030\n\tb\tOptionMenu_ThinkSelect_SearchOptionsEnd\n\nOptionMenu_ThinkSelect_SearchOptionsIncLoop:\n\taddi REG_Count,REG_Count,1\n\tb\tOptionMenu_ThinkSelect_SearchOptionsLoop\n\nOptionMenu_ThinkSelect_SearchOptionsEnd:\n\tb\tOptionMenu_ThinkExit\n\nOptionMenu_ThinkBack:\n.set REG_MenuData,24\n\tlwz\tr4,MenuData(REG_GObjData)\n#Convert bl instruction to mem address\n\taddi\tr4,r4,MenuData_ReturnMenu\n\tlwz\tr5,0x0(r4)\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n\textsh\tr5,r5\n\tcmpwi\tr5,0\n\tbeq OptionMenu_ThinkDestroy\n  add\tr4,r4,r5\t\t\t\t\t\t#Gets Address in r4\n#Load Prev Menu\n\tmr\tr3,REG_GObj\n\tbl\tOptionMenu_CreateText\n#Play SFX\n\tli\tr3,0\n\tbranchl r12,0x80024030\n\tb\tOptionMenu_ThinkExit\n\nOptionMenu_ThinkDestroy:\n#Remove text\n\tlwz\tr3,0x2C(REG_GObj)\n\tlwz\tr3,TextGObj(r3)\n\tbranchl r12,Text_RemoveText\n#Remove GObj\n\tmr\tr3,REG_GObj\n\tbranchl r12,GObj_Destroy\n#Play SFX\n\tli\tr3,0\n\tbranchl r12,0x80024030\n\nOptionMenu_ThinkExit:\n\trestore\n\tblr\n#endregion\n\n#region OptionMenu_CreateText\nTextProperties:\nblrl\n.set VersionX,0x0\n.set VersionY,0x4\n.set ZOffset,0x8\n.set CanvasScaling,0xC\n.set Scale,0x10\n.set YOffset,0x14\n.set YOffsetAddAfterTitle,0x18\n.set HighlightColor,0x1C\n.set NonHighlightColor,0x20\n.float 120      \t\t\t#REG_TextGObj X pos\n.float -250  \t\t\t\t\t#REG_TextGObj Y pos\n.float 21.9     \t\t\t#Z offset\n.float 0.035   \t\t\t\t#Canvas Scaling\n.float 0.65\t\t\t\t\t\t#Text scale\n.float 30\t\t\t\t\t\t\t#Y offset difference\n.float 20\t\t\t\t\t\t\t#Y Offset to Add After Title\n.byte 251,199,57,255\t\t#highlighted color\n.byte 170,170,170,255\t#nonhighlighted color\n\nOptionMenu_CreateText:\n.set REG_MenuData,28\n.set REG_GObjData,29\n.set REG_TextProp,30\n.set REG_TextGObj,31\n\n#GObj Data Struct\n.set Cursor,0x0\n.set TextGObj,0x4\n.set MenuData,0x8\n\nbackup\n\n#Backup GObj and MenuData\n\tlwz\tREG_GObjData,0x2C(r3)\n\tmr\tREG_MenuData,r4\n\n#Check if a text gobj already\n\tlwz r3,TextGObj(REG_GObjData)\n\tcmpwi r3,0\n\tbeq OptionMenu_CreateText_SkipDestroyOldText\n#Destroy\n\tbranchl r12,Text_RemoveText\n\tli\tr3,0\n\tstw r3,TextGObj(REG_GObjData)\nOptionMenu_CreateText_SkipDestroyOldText:\n\n#Store new menudata\n\tstw\tREG_MenuData,MenuData(REG_GObjData)\n\n#GET PROPERTIES TABLE\n\tbl TextProperties\n\tmflr REG_TextProp\n\n########################\n## Create Text Object ##\n########################\n\n#CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3\n\tli r3,0\n\tli r4,1\n\tbranchl r12,Text_CreateTextStruct\n\tstw r3,TextGObj(REG_GObjData)\n#BACKUP STRUCT POINTER\n\tmr REG_TextGObj,r3\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x1\n\tstb r4,0x49(REG_TextGObj)\n#SET TEXT TO CENTER AROUND X LOCATION\n\tli r4,0x0\n\tstb r4,0x4A(REG_TextGObj)\n#Store Base Z Offset\n\tlfs f1,ZOffset(REG_TextProp) #Z offset\n\tstfs f1,0x8(REG_TextGObj)\n#Scale Canvas Down\n  lfs f1,CanvasScaling(REG_TextProp)\n  stfs f1,0x24(REG_TextGObj)\n  stfs f1,0x28(REG_TextGObj)\n\nOptionMenu_CreateText_PrintOptions:\n.set REG_Count,20\n.set REG_ASCII,21\n.set REG_OptionData,22\n.set OFST_LastYPos,0x80\n#Init\n\tli\tREG_Count,0\t\t\t\t\t\t\t\t\t#loop count\n\tlfs\tf1,VersionY(REG_TextProp)\t\t#Last text's Y position\n\tstfs\tf1,OFST_LastYPos(sp)\n\nOptionMenu_CreateText_PrintOptionsLoop:\n#Get this option's text\n\taddi r3,REG_MenuData,MenuData_OptionsStart\n\tmulli\tr4,REG_Count,MenuData_OptionDataLength\n\tadd\tREG_OptionData,r3,r4\n#Convert bl instruction to mem address\n  lwz\tr4,0x0(REG_OptionData)\t\t#Get bl Instruction\n\textsb\tr5,r4\t\t\t\t\t\t\t\t\t\t#Check if none left\n\tcmpwi\tr5,-1\n\tbeq OptionMenu_CreateText_PrintOptionsEnd\n  rlwinm\tr4,r4,0,6,29\t\t\t\t\t\t\t#Mask Bits 6-29 (the offset)\n\textsh\tr4,r4\n  add\tREG_ASCII,REG_OptionData,r4\t\t#Gets ASCII Address in r3\n\n#Get Y offset\n\tlfs\tf2,OFST_LastYPos(sp)\t\t \t#Y base offset of REG_TextGObj\n\tlfs\tf3,YOffset(REG_TextProp)\t\t\t#Y offset difference\n\tfadds\tf2,f2,f3\n#Check if this is the first option\n\tcmpwi REG_Count,0\n\tbeq OptionMenu_CreateText_PrintOptions_SkipTitleAdjust\n#Check if last option was a title\n\tlwz\tr3,-MenuData_OptionDataLength + MenuData_OnSelectType(REG_OptionData)\n\tcmpwi\tr3,OnSelect_None\n\tbne\tOptionMenu_CreateText_PrintOptions_SkipTitleAdjust\n#Move down further\n\tlfs\tf1,YOffsetAddAfterTitle(REG_TextProp)\n\tfadds\tf2,f1,f2\n\nOptionMenu_CreateText_PrintOptions_SkipTitleAdjust:\n#Store as last Y position\n\tstfs\tf2,OFST_LastYPos(sp)\n#Initialize Subtext\n\tmr \tr3,REG_TextGObj\t\t#struct pointer\n\tmr\tr4,REG_ASCII\t\t\t#text\n\tlfs\tf1,VersionX(REG_TextProp) \t\t#X offset of REG_TextGObj\n\tbranchl r12,0x803a6b98\n\n#Change Text Scale\n\tmr \tr3,REG_TextGObj\t\t#struct pointer\n\tmr\tr4,REG_Count\n\tlfs \tf1,Scale(REG_TextProp) \t\t#X offset of REG_TextGObj\n\tlfs \tf2,Scale(REG_TextProp)\t  \t#Y offset of REG_TextGObj\n\tbranchl r12,Text_UpdateSubtextSize\n\nOptionMenu_CreateText_PrintOptionsIncLoop:\n\taddi REG_Count,REG_Count,1\n\tb\tOptionMenu_CreateText_PrintOptionsLoop\n\nOptionMenu_CreateText_PrintOptionsEnd:\n\n#Reset cursor position\n\tli\tr3,0\n#Highlight current cursor\n\tmr\tr4,r3\n\tmr\tr3,REG_GObjData\n\tbl\tOptionMenu_AdjustCursor\n\n\n\n#Exit\n\trestore\n\tblr\n#endregion\n\n#region OptionMenu_AdjustCursor\nOptionMenu_AdjustCursor:\n.set REG_GObjData,31\n.set REG_TextGObj,30\n.set REG_Cursor,29\n.set REG_TextProp,28\n\nbackup\n\n#Backup\n\tmr\tREG_GObjData,r3\n\tlwz\tREG_TextGObj,TextGObj(REG_GObjData)\n\tmr\tREG_Cursor,r4\n\tbl\tTextProperties\n\tmflr\tREG_TextProp\n\n#Change all options to white\nOptionMenu_AdjustCursor_ResetColors:\n.set REG_Count,20\n#Init\n\tli\tREG_Count,0\t\t\t\t\t\t\t\t\t#loop count\nOptionMenu_AdjustCursor_ResetColorsLoop:\n#Adjust Subtext\n\tmr \tr3,REG_TextGObj\t\t#struct pointer\n\tmr\tr4,REG_Count\t\t\t#subtext text\n\taddi\tr5,REG_TextProp,NonHighlightColor\n\tbranchl r12,Text_ChangeTextColor\n\nOptionMenu_AdjustCursor_ResetColorsIncLoop:\n\taddi\tREG_Count,REG_Count,1\n#Get number of subtexts\n\tlwz\tr3,0x64(REG_TextGObj)\n\tlwz\tr3,0xC(r3)\n\tcmpw REG_Count,r3\n\tblt OptionMenu_AdjustCursor_ResetColorsLoop\n\n#Ensure this isnt below 0\n\tcmpwi REG_Cursor,0\n\tbge OptionMenu_AdjustCursor_SearchOptions\n#Adjust to be 0\n\tli\tREG_Cursor,0\n\n#Loop through current menu\nOptionMenu_AdjustCursor_SearchOptions:\n.set REG_Count,20\n.set REG_ASCII,21\n.set REG_OptionData,22\n.set REG_OptionCount,23\n.set REG_MenuData,24\n#Init\n\tli\tREG_Count,0\t\t\t\t\t\t\t\t\t#loop count\n\tli\tREG_OptionCount,0\t\t\t\t\t\t#Only incremented when an option is found\n\tlwz\tREG_MenuData,MenuData(REG_GObjData)\n\nOptionMenu_AdjustCursor_SearchOptionsLoop:\n#Get this option's text\n\taddi r3,REG_MenuData,MenuData_OptionsStart\n\tmulli\tr4,REG_Count,MenuData_OptionDataLength\n\tadd\tREG_OptionData,r3,r4\n#Convert bl instruction to mem address\n  lwz\tr4,0x0(REG_OptionData)\t\t#Get bl Instruction\n\textsb\tr5,r4\t\t\t\t\t\t\t\t\t\t#Check if none left\n\tcmpwi\tr5,-1\n\tbne\tOptionMenu_AdjustCursor_SearchOptionsNotLast\n\tsubi REG_OptionCount,REG_OptionCount,1\nOptionMenu_AdjustCursor_SearchOptionsGetLastValidOption:\n\tsubi REG_Count,REG_Count,1\n\taddi r3,REG_MenuData,MenuData_OptionsStart\n\tmulli\tr4,REG_Count,MenuData_OptionDataLength\n\tadd\tREG_OptionData,r3,r4\n\tlwz\tr3,MenuData_OnSelectType(REG_OptionData)\n\tcmpwi\tr3,OnSelect_None\n\tbeq\tOptionMenu_AdjustCursor_SearchOptionsGetLastValidOption\n\tb\tOptionMenu_AdjustCursor_SearchOptionsChangeColor\n#Get OnSelectType\nOptionMenu_AdjustCursor_SearchOptionsNotLast:\n\tlwz \tr3,MenuData_OnSelectType(REG_OptionData)\n\tcmpwi\tr3,OnSelect_None\n\tbeq\tOptionMenu_AdjustCursor_SearchOptionsIncLoop\n#Check if this is the desired option\n\tcmpw REG_OptionCount,REG_Cursor\n\tbeq OptionMenu_AdjustCursor_SearchOptionsChangeColor\n#Increment Option Count\n\taddi\tREG_OptionCount,REG_OptionCount,1\n\tb\tOptionMenu_AdjustCursor_SearchOptionsIncLoop\n\nOptionMenu_AdjustCursor_SearchOptionsChangeColor:\n#Adjust Subtext\n\tmr \tr3,REG_TextGObj\t\t#struct pointer\n\tmr\tr4,REG_Count\t\t\t#subtext text\n\taddi\tr5,REG_TextProp,HighlightColor\n\tbranchl r12,Text_ChangeTextColor\n\n#Update Cursor Position\n\tstw\tREG_OptionCount,Cursor(REG_GObjData)\n\tb\tOptionMenu_AdjustCursor_SearchOptionsEnd\n\nOptionMenu_AdjustCursor_SearchOptionsIncLoop:\n\taddi REG_Count,REG_Count,1\n\tb\tOptionMenu_AdjustCursor_SearchOptionsLoop\n\nOptionMenu_AdjustCursor_SearchOptionsEnd:\n#Exit\n\trestore\n\tblr\n#endregion\n\n#region MenuData\n\n#MenuData Structure\n.set MenuData_ReturnMenu,0x0\n.set MenuData_OptionsStart,0x4\n\t.set MenuData_OptionName,0x0\n\t.set MenuData_OnSelectType,0x4\n\t.set MenuData_OnSelectData,0x8\n.set MenuData_OptionDataLength,0xC\n\n#OnSelect Definitions\n.set OnSelect_None,0\n.set OnSelect_Menu,1\n.set OnSelect_Function,2\n\n#region Options\nMenuData_MainMenuBlrl:\nblrl\nMenuData_MainMenu:\n#Return menu\n\t.long 0\n#Options\n\tbl\tMenuData_MainMenu_OptionsTitleName\n\t.long\tOnSelect_None\n\t.long 0\n#Create Save File\n\tbl\tMenuData_MainMenu_CreateSaveName\n\t.long\tOnSelect_Menu\n\tbl\tMenuData_CreateSave\n#Play\n\tbl\tMenuData_MainMenu_PlayCreditsName\n\t.long\tOnSelect_Function\n\tbl\tLoadCredits\n\t.long -1\n.align 2\n\nMenuData_MainMenu_OptionsTitleName:\n.string \"<Options>\"\n.align 2\nMenuData_MainMenu_PlayCreditsName:\n.string \"Show Credits\"\n.align 2\nMenuData_MainMenu_CreateSaveName:\n.string \"Create Save\"\n.align 2\n#endregion\n#region Create Save\nMenuData_CreateSave:\n#Return menu\n\tbl\tMenuData_MainMenu\n#Create Save\n\tbl\tMenuData_MainMenu_CreateSaveTitleName\n\t.long\tOnSelect_None\n\t.long 0\n#Play\n\tbl\tMenuData_CreateSave_SlotA\n\t.long\tOnSelect_Function\n\t.long 0#bl\tCreateSave_SlotA\n#Create Save File\n\tbl\tMenuData_CreateSave_SlotB\n\t.long\tOnSelect_Function\n\t.long 0#bl\tCreateSave_SlotB\n\n#Space\n\tbl\tMenuData_CreateSave_Empty\n\t.long\tOnSelect_None\n\t.long 0\n#Disabled\n\tbl\tMenuData_MainMenu_Disabled\n\t.long\tOnSelect_None\n\t.long 0\n\n.long -1\n.align 2\n\nMenuData_MainMenu_CreateSaveTitleName:\n.string \"<Create Save>\"\n.align 2\nMenuData_CreateSave_SlotA:\n.string \"Save to Slot A\"\n.align 2\nMenuData_CreateSave_SlotB:\n.string \"Save to Slot B\"\n.align 2\nMenuData_CreateSave_Empty:\n.string \"\"\n.align 2\nMenuData_MainMenu_Disabled:\n.string \"(Temp Disabled)\"\n.align 2\n\nCreateSave_SlotA:\n\tli\tr3,0\n\tb\tCreateSave\n\nCreateSave_SlotB:\n\tli\tr3,1\n\tb\tCreateSave\n#endregion\n\n#endregion\n\n#region CreateSave\nCreateSave:\n.set MemcardFileList,0x804333c8\n.set REG_MemcardSlot,20\nbackup\n\n#Backup slot\n\tmr\tREG_MemcardSlot,r3\n\n#Backup current Game ID\n  addi r3,sp,0xB0\n  lis r4,0x8000\n  branchl r12,strcpy\n#Change Game ID to Melee's\n  lis r3,0x8000\n  bl  MeleeGameID\n  mflr r4\n  branchl r12,strcpy\n\n#Get memcard pointer\n.set REG_Memcard,30\n  lwz\tREG_Memcard, -0x77C0 (r13)\n\n###########################\n## Create Main Save File ##\n###########################\n\n#Check if save file already exists\n\tmr\tr3,REG_MemcardSlot\n\tload\tr6,0x803bab60\n\taddi\tr4, r6, 252\n\taddi\tr5, r6, 20\n\tload r7,0x8043331C\n  branchl r12,0x8001b7e0\n  cmpwi r3,0x1\n  bne CreateMainSave\n\nDeleteMainSave:\n\tmr\tr3,REG_MemcardSlot\n\tload\tr4,0x803bac5c\n\tload\tr5,0x8043331c\n  branchl r12,0x8001ba44\n  cmpwi r3,0\n  bne SaveError\n\nCreateMainSave:\n.set REG_OldSaveBackup,31\n#Allocate mem to backup current save data to\n  load  r3,68144\n  branchl r12,HSD_MemAlloc\n  mr  REG_OldSaveBackup,r3\n#Copy old data here\n  mr\tr4, REG_Memcard\n  load  r5,68144\n  branchl r12,memcpy\n#Start building exploit\n  addi r3,REG_Memcard,0x3190    #destination\n  load r4,0xdd064bdd            #data to write\n  li  r5,0xD4                   #length to write\n  subi r3,r3,4\nExploitFillLoop:\n  stwu r4,0x4(r3)\n  subi r5,r5,0x4\n  cmpwi r5,0\n  bgt ExploitFillLoop\n#Place LR hijacks\n  mr\tr3, REG_Memcard\n  load  r4,0x804eeac8\n  stw r4,0x3230(r3)\n  load  r4,0x8045d930\n  stw r4,0x3234(r3)\n  load  r4,0x804ee8f8\n  stw r4,0x3264(r3)\n  load  r4,0x8045d930\n  stw r4,0x3268(r3)\n#Place exploit code for 1.02\n  addi r3,REG_Memcard,0x3270             #exploit code destination\n  bl  ExploitCode102\n  mflr r4\n  li  r5,0xD30                  #length of code\n  branchl r12,memcpy\n#Place exploit code for 1.00\n  addi r3,REG_Memcard,0x5238             #exploit code destination\n  bl  ExploitCode100\n  mflr r4\n  li  r5,0x80                  #length of code\n  branchl r12,memcpy\n#Place exploit code for 1.01\n  addi r3,REG_Memcard,0x3f50            #exploit code destination\n  bl  ExploitCode101\n  mflr r4\n  li  r5,0x80                  #length of code\n  branchl r12,memcpy\n\n#Run onSaveCreate functions (enable UCF and unlock trophies)\n  OnSaveCreate\n\n#Unlock All Messages\n  addi r3,REG_Memcard,0x1B4C\n  li  r4,0xFF\n  li  r5,0x34\n  branchl r12,0x80003100\n\n#Only Mewtwo Unlocked\n  li  r3,0x8\n  stb r3,6249(REG_Memcard)\n\n#Wipe High Scores\n  addi r3,REG_Memcard,0x1A70\n  li  r4,0\n  li  r5,0xCC\n  branchl r12,0x80003100\n#Set as unplayed\n  li  r3,0\n  stw r3,0x1A68(REG_Memcard)\n  stw r3,0x1A6C(REG_Memcard)\n\n#Create Save\n\tmr\tr3,REG_MemcardSlot\n\tload\tr6,0x803bab60\n\taddi\tr5,r6,20\n\taddi\tr4,r6,252\n\tbl\tMainSaveName\n\tmflr r7\n\tload\tr10,0x80433318\n\tlwz\tr9,0x5C(r10)\n\tlwz r8,0x8(r9)\t\t\t\t\t#banner data with flames\n\tlwz r9,0xC(r9)\t\t\t\t\t#icon data\n\taddi\tr10,r10,4\n  branchl r12,0x8001bc18\n  cmpwi r3,0\n  bne SaveError\n#Copy original save data back\n  mr\tr3, REG_Memcard\n  mr  r4,REG_OldSaveBackup\n  load  r5,68144\n  branchl r12,memcpy\n#Free allocation\n  mr  r3,REG_OldSaveBackup\n  branchl r12,HSD_Free\n\n##########################\n## Create Snapshot File ##\n##########################\n\n#Update list of present memcard snapshots\n  mr\tr3,REG_MemcardSlot\n  branchl r12,0x80253e90\n\n.set REG_Count,31\n.set REG_Index,30\n.set REG_SnapshotStruct,29\n.set REG_SnapshotID,28\n#Check if file exists on card\n  load  r3,MemcardFileList                            #go to pointer location\n  lwz REG_SnapshotStruct,0x0(r3)                      #access pointer to snapshot file list\n\tmulli\tr3,REG_MemcardSlot,1032\n\tadd\tREG_SnapshotStruct,REG_SnapshotStruct,r3\n  lwz REG_Index,0x4(REG_SnapshotStruct)               #get number of snapshots present\n  addi REG_SnapshotStruct,REG_SnapshotStruct,0x10     #get to snapshot info\n  bl  SnapshotID                                      #get ID we are looking for\n  mflr r3\n  lwz REG_SnapshotID,0x0(r3)\n  li  REG_Count,0                                     #init count\nSnapshotSearchLoop:\n  cmpw REG_Count,REG_Index\n  bge SnapshotSearchLoop_NotFound\n#Get the next snapshots ID\n  mulli r3,REG_Count,0x8          #each snapshots data is 0x8 long\n  add r3,r3,REG_SnapshotStruct\n  lwz r4,0x0(r3)                  #get the snaps ID\n  cmpw r4,REG_SnapshotID\n  bne SnapshotSearchLoop_IncLoop\n  b SnapshotSearchLoop_Found\nSnapshotSearchLoop_IncLoop:\n  addi REG_Count,REG_Count,1\n  b SnapshotSearchLoop\n\nSnapshotSearchLoop_NotFound:\n  b CreateSnapshot\n\nSnapshotSearchLoop_Found:\n#Delete Snapshot\n  mr\tr3,REG_MemcardSlot\n  mr  r4,REG_Count\n  branchl r12,0x8001d5fc\nWaitToDeleteLoop:\n  branchl\tr12,0x8001b6f8\n  cmpwi\tr3,0xB\n  beq\tWaitToDeleteLoop\n#If Exists\n  cmpwi\tr3,0x0\n  beq\tCreateSnapshot\n  cmpwi\tr3,0x9\n  bne\tSaveError\n\nCreateSnapshot:\n.set REG_Codeset,31\n\n#Get codeset pointer and length\n  lwz REG_Codeset,CodesetPointer(rtoc)\n  bl  SnapshotSaveStruct\n  mflr r4\n  stw REG_Codeset,0x8(r4)\n#Store file size\n  lwz r3,0x0(REG_Codeset)\n  stw r3,0x0(r4)\n#Load banner and image\n#Convert ID to string\n  addi r3,sp,0x80\n  bl  SnapshotString\n  mflr r4\n  bl  SnapshotID\n  mflr r5\n  lwz r5,0x0(r5)\n  branchl r12,0x80323cf4\n#Create File\n  mr\tr3,REG_MemcardSlot\n  addi r4,sp,0x80       #Snapshot ID\n  bl  SnapshotSaveStruct\n  mflr r5\n  load r6,0x803bacc8\n  bl  SnapshotSaveName\n  mflr r7\n\n\tbl\tSnapshotBanner\n\tmflr r8\n\tbl\tSnapshotIcon\n\tmflr r9\n  li  r10,0\n  branchl r12,0x8001bb48\n\nWaitToLoadLoop:\n  branchl\tr12,0x8001b6f8\n  cmpwi\tr3,0xB\n  beq\tWaitToLoadLoop\n#If Exists\n  cmpwi\tr3,0x0\n  beq\tSuccess\n  cmpwi\tr3,0x9\n  beq\tSuccess\n  b\tFailure\n\nSuccess:\n  li\tr3,0xAA\n  branchl\tr12,0x801c53ec\n  b CreateSnapshot_End\n\nFailure:\n#Play Error Sound\n  li\tr3, 3\n  branchl\tr12,0x80024030\n  li\tr3, 3\n  branchl\tr12,0x80024030\n  b CreateSnapshot_End\n\nCreateSnapshot_End:\n#Change Game ID back\n  lis r3,0x8000\n  addi r4,sp,0xB0\n  branchl r12,strcpy\n  b ExitInjection\n\nSaveError:\n#Play Error Sound\n  li\tr3, 3\n  branchl\tr12,0x80024030\n  li\tr3, 3\n  branchl\tr12,0x80024030\n#Change Game ID back\n  lis r3,0x8000\n  addi r4,sp,0xB0\n  branchl r12,strcpy\n  b ExitInjection\n\n###################\nMainSaveName:\nblrl\n.ascii \"Super Smash Bros. Melee         \"\n.ascii \"Mod Launcher (1 of 2)           \"\n###################\nSnapshotID:\nblrl\n.long 0x00D0C0DE\n.align 2\n###################\nSnapshotString:\nblrl\n.string \"%u\"\n.align 2\n###################\nSnapshotSaveStruct:\nblrl\n.long 0         #File size, will dynamically change based on gct size\n.long 3         #Unknown\n.long 0         #Pointer to snapshot data, will be stored to during runtime\n.long -1        #end of structure\n.align 2\n###################\nSnapshotSaveName:\nblrl\n.ascii \"Training Mode v2.0              \"\n.ascii \"Mod Data (2 of 2)               \"\n###################\nCodeFileName:\nblrl\n.string \"codes.gct\"\n.align 2\n###################\nTMGameID:\nblrl\n.string \"GTME01\"\n.align 2\n###################\nMeleeGameID:\nblrl\n.string \"GALE01\"\n.align 2\n###################\n\n#region ExploitCode102\nExploitCode102:\nblrl\n.set InjectionPoint,0x80375510 #0x803754e4\n.set InjectionReturn,0x803754dc #0x803754e8\n\n\n##################################\n## PLACE AT 0xb6f3d0 IN state FILE ##\n##################################\n\n\n#*** Possibly inject into 801a4000, memcard stuff has already been reset, this might be the\n#neatest place to do this. destroy the heap, make a new one, load the snapshot and rerun this\n#function\n\n\n##################\n## Change Major ##\n##################\n\n#request to change screen\n branchl r3,0x801A4B60\n\n#Set Next Scene Byte (Main Menu) for sceneDecide_Menu\n#Check For X Button Held\nli\tr3,4\nbranchl\tr12,0x801a3680\nrlwinm.\tr4,r4,0,21,21\nbeq\tExploitCode102_GoToEventSS\n\nExploitCode102_GoToCSS:\nli\tr3,2\nb\tExploitCode102_StoreNewScene\n\n#Spoof current (soon to be previous) screen\nExploitCode102_GoToEventSS:\n li\tr3,0x2b\n load\tr4,0x80479d30\n stb\tr3,0x0(r4)\n li r3,0x1\n\nExploitCode102_StoreNewScene:\n lis r4,0x804d\n stb r3,0x68bC(r4)\n\n################################\n## Disable memory card saving ##\n################################\n\n#lis \tr5,0x8043\t\t#v1.0=80431360\n#li\tr6,4\n#stw\tr6,0x3320(r5)\t# store 4 to disable memory card saving henceforth\n\n#########################\n## Tournament Settings ##\n#########################\n\nlwz\tr4, -0x77C0 (r13)\nload r3,0x00340102\nstw r3,0x1850(r4)\t\t\t#store stock mode\nload r3,0x04000A00\nstw r3,0x1854(r4)\t\t\t#store 4 stocks\nload r3,0x08010100\nstw r3,0x1858(r4)\t\t\t#store 8 minutes\n\nload r3,0xFF000000\nstw r3,0x1CB0(r4)\t\t\t#store items off\nload r3,0xE70000B0\nstw r3,0x1CC8(r4)\t\t\t#store stages\n\n#################################\n## Place Branch To Heap Hijack ##\n#################################\n\n#Get Function To Branch To\n  bl\tExploitCode102_HeapHijack\n  mflr\tr3\n#Get Where to Place Branch\n  load\tr4,InjectionPoint\n#Make a Branch Instruction out of This (FunctionAddress - BranchPoint)\n  sub\tr3,r3,r4\t\t#r3 contains difference between\n  rlwinm\tr3,r3,0,6,29\t\t#Mask Out bits 6 through 29\n  oris\tr3,r3,0x4800\t\t#Place 0x48 at the start (opcode)\n  stw\tr3,0x0(r4)\n\n#####################\n## TRK_flush_cache ##\n#####################\n\nload r3,InjectionPoint\nlis\tr4,0x4\nbranchl\tr12,0x80328F50\n\n##########\n## Exit ##\n##########\n\nlis r12,0x8023\nori r12,r12,0x9e9c\nmtctr r12\nbctr\n\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n\n\n######################\n## Heap Hijack Code ##\n######################\nExploitCode102_HeapHijack:\nblrl\n\nbackup\n\n###################\n## Load Snapshot ##\n###################\n\n#Update list of present memcard snapshots\n  li  r3,0\n  branchl r12,0x80253e90\n\n.set MemcardFileList,0x804333c8\n.set REG_Count,31\n.set REG_Index,30\n.set REG_SnapshotStruct,29\n.set REG_SnapshotID,28\n#Check if file exists on card\n  load  r3,MemcardFileList                            #go to pointer location\n  lwz REG_SnapshotStruct,0x0(r3)                      #access pointer to snapshot file list\n  lwz REG_Index,0x4(REG_SnapshotStruct)               #get number of snapshots present\n  addi REG_SnapshotStruct,REG_SnapshotStruct,0x10     #get to snapshot info\n  bl  ExploitCode102_HeapHijack_SnapshotIDInt                                      #get ID we are looking for\n  mflr r3\n  lwz REG_SnapshotID,0x0(r3)\n  li  REG_Count,0                                     #init count\nExploitCode102_HeapHijack_SnapshotSearchLoop:\n  cmpw REG_Count,REG_Index\n  bge ExploitCode102_HeapHijack_SnapshotSearchLoop_NotFound\n#Get the next snapshots ID\n  mulli r3,REG_Count,0x8          #each snapshots data is 0x8 long\n  add r3,r3,REG_SnapshotStruct\n  lwz r4,0x0(r3)                  #get the snaps ID\n  cmpw r4,REG_SnapshotID\n  bne ExploitCode102_HeapHijack_SnapshotSearchLoop_IncLoop\n  b ExploitCode102_HeapHijack_SnapshotSearchLoop_Found\nExploitCode102_HeapHijack_SnapshotSearchLoop_IncLoop:\n  addi REG_Count,REG_Count,1\n  b ExploitCode102_HeapHijack_SnapshotSearchLoop\n\nExploitCode102_HeapHijack_SnapshotSearchLoop_NotFound:\n#Play Error Sound\n  li\tr3, 3\n  branchl\tr12,0x80024030\n  li\tr3, 3\n  branchl\tr12,0x80024030\n#Disable Saving\n  lis     r4,0x8043\n  li     r3,4\n  stw    r3,0x3320(r4)    # store 4 to disable memory card saving\n  b ExploitCode102_HeapHijack_CleanUpHijack\n\nExploitCode102_HeapHijack_SnapshotSearchLoop_Found:\n.set REG_CodesetSize,31\n.set REG_CodesetPointer,30\n#Convert blocks to bytes\n  lhz r3,0x6(r3)\n  mulli REG_CodesetSize,r3,0x2000\n#Alloc Space For Snapshot File\n  mr  r3,REG_CodesetSize\n  branchl\tr12,0x8037f1e4\t\t\t       #HSD_Alloc\n  mr  REG_CodesetPointer,r3\n  load\tr5,0x803bacdc\t\t\t           #Snapshot Data Struct\n  stw\tREG_CodesetPointer,0x8(r5)     #Store Pointer to this area\n\n#Remove Pointer To Current Memcard Stuff\n  branchl\tr12,0x8001c5a4\n#Alloc Space For Memcard Stuff\n  branchl\tr12,0x8001c550\n\n#Load File\n  li\tr3,0x0\t\t#Slot A?\n  bl\tExploitCode102_HeapHijack_SnapshotID\n  mflr\tr4\n  load\tr5,0x803bacdc\t\t#Snapshot Data Struct\n  load\tr6,0x80433384\t\t#String Space?\n  load\tr9,0x80433380\n  lwz\tr9,0x44(r9)\n  lwz\tr7,0x0(r9)\t\t#Weird Char Pointer, Maybe Icon Image\n  lwz\tr8,0x4(r9)\t\t#Banner Image\n  li\tr9,0\t\t#Unk\n  branchl\tr12,0x8001bf04\n#Store Result\n  load\tr4,0x804A0B6C\n  stw\tr3,0x0(r4)\n\nExploitCode102_HeapHijack_WaitToLoadLoop:\n  branchl\tr12,0x8001b6f8\n  cmpwi\tr3,0xB\n  beq\tExploitCode102_HeapHijack_WaitToLoadLoop\n#If Exists\n  cmpwi\tr3,0x0\n  beq\tExploitCode102_HeapHijack_Success\n  cmpwi\tr3,0x9\n  beq\tExploitCode102_HeapHijack_Success\n  b\tExploitCode102_HeapHijack_Failure\n\nExploitCode102_HeapHijack_SnapshotIDInt:\nblrl\n.long 0x00D0C0DE\n.align 2\nExploitCode102_HeapHijack_SnapshotID:\nblrl\n.string \"13680862\"\n.align 2\n\n#############\n## Failure ##\n#############\n\nExploitCode102_HeapHijack_Failure:\n#Play Error Sound\n  li\tr3, 3\n  branchl\tr12,0x80024030\n  li\tr3, 3\n  branchl\tr12,0x80024030\n#Disable Saving\n  lis     r4,0x8043\n  li     r3,4\n  stw    r3,0x3320(r4)    # store 4 to disable memory card saving\n\nb\tExploitCode102_Exit\n\n\n#############\n## Success ##\n#############\nExploitCode102_HeapHijack_Success:\n#Store codeset pointer and length\n  stw REG_CodesetPointer,CodesetPointer(rtoc)\n\n#Play SFX\n  li\tr3,0xAA\n  branchl\tr12,0x801c53ec\n\n#Boot up tasks\n  OnBootup\n\n#####################\n## Run Codehandler ##\n#####################\n\nExploitCode102_HeapHijack_RunCodehandler:\n  addi r4,REG_CodesetPointer,32\n  bl\tGeckoCodehandler\n\n###################################\n## Change Start Of Original Heap ##\n###################################\n\n  load\tr3,0x8043200c\t\t\t#Heap Start\n  mr\tr4,REG_CodesetSize\t\t\t#Space to Add\n  lwz\tr5,0x4(r3)\t\t\t#Get Heap Start\n  add\tr4,r4,r5\t\t\t#Add\n  stw\tr4,0x4(r3)\t\t\t#Store New Heap Start\n\n##################\n## Destroy Heap ##\n##################\n\n  lwz\tr3, -0x58A0 (r13)\n  branchl\tr12,0x80344154\n\n#####################\n## Exit HeapHijack ##\n#####################\n\n#Adjust Heap Start\n  lwz\tr3, -0x3FE8 (r13)\n  mr\tr4,REG_CodesetSize\n  add\tr3,r3,r4\n  stw\tr3,-0x3FE8 (r13)\n\n\nExploitCode102_HeapHijack_CleanUpHijack:\n\n################################\n## Remove Branch To This Code ##\n################################\n\nload\tr3,0x806da760\nload\tr4,InjectionPoint\nstw\tr3,0x0(r4)\n\n#############################\n## Flush Instruction Cache ##\n#############################\nExploitCode102_Exit:\n#Now flush the instruction cache\n  lis r3,0x8000\n  load r4,0x3b722c    #might be overkill but flush the entire dol file\n  branchl r12,0x80328f50\n\n###################################\n## Zero fill entire nametag area ##\n###################################\n\nrestore\n\nload\tr3,InjectionReturn\nmtlr\tr3\n\nlis r3,0x8045\nori r3,r3,0xd850\t\t\t#v1.0 = 8045b888\nli r4,0\nli r5,0\nori r5,r5,0xc344\nlis r12,0x8000\nori r12,r12,0x3130\t\t\t#v1.0 = 8045b888\nmtctr r12\nbctr\n\n\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n#########################################################\n\n\n#######################\n## Gecko Codehandler ##\n#######################\n\n.text\n\n.set r0,0;   .set r1,1;   .set r2,2; .set r3,3;   .set r4,4\n.set r5,5;   .set r6,6;   .set r7,7;   .set r8,8;   .set r9,9\n.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14\n.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19\n.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24\n.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29\n.set r30,30; .set r31,31; .set f0,0; .set f2,2; .set f3,3\n\n.globl _start\n\ncheatdata:\n.long\tfrozenvalue\n.space 39*4\n\nGeckoCodehandler:\n_start:\n\tstwu\tr1,-168(r1)\t\t# stores sp\n\tstw\tr0,8(r1)\t\t# stores r0\n\n\tmflr\tr0\n\tstw\tr0,172(r1)\t\t# stores lr\n\n\tmfcr\tr0\n\tstw\tr0,12(r1)\t\t# stores cr\n\n\tmfctr\tr0\n\tstw\tr0,16(r1)\t\t# stores ctr\n\n\tmfxer\tr0\n\tstw\tr0,20(r1)\t\t# stores xer\n\n\tstmw\tr3,24(r1)\t\t# saves r3-r31\n\n\tmfmsr\tr20\n\tori\tr26,r20,0x2000\t\t#enable floating point ?\n\tandi.\tr26,r26,0xF9FF\n\tmtmsr\tr26\n\n\tstfd\tf2,152(r1)\t\t# stores f2\n\tstfd\tf3,160(r1)\t\t# stores f3\n\n    lis\tr31,0x8000\n\n    lis r3, 0xCC00\n    lhz r28, 0x4010(r3)\n    ori r21, r28, 0xFF\n    sth r21, 0x4010(r3) # disable MP3 memory protection\n\n\tmflr\tr29\n\tmr\tr15,r4\n\n\tori\tr7, r31, cheatdata@l\t# set pointer for storing data (before the codelist)\n\n\tlis\tr6,0x8000\t\t# default base address = 0x80000000 (code handler)\n\n\tmr\tr16,r6\t\t\t# default pointer =0x80000000 (code handler)\n\n\tli\tr8,0\t\t\t# code execution status set to true (code handler)\n\n\tlis\tr3,0x00D0\n    ori\tr3,r3,0xC0DE\n\n\tlwz\tr4,0(r15)\n\tcmpw\tr3,r4\n\tbne-\t_exitcodehandler\n\tlwz\tr4,4(r15)\n\tcmpw\tr3,r4\n    bne-\t_exitcodehandler\t# lf no code list skip code handler\n    addi\tr15,r15,8\n\tb\t_readcodes\n\n_exitcodehandler:\n\tmtlr\tr29\n\nresumegame:\n    lis r3, 0xCC00\n    sth r28,0x4010(r3)  # restore memory protection value\n\n\tlfd\tf2,152(r1)\t\t# loads f2\n\tlfd\tf3,160(r1)\t\t# loads f3\n\n\tmtmsr\tr20         # restore msr\n\n\tlwz\tr0,172(r1)\n\tmtlr\tr0\t\t\t# restores lr\n\n\tlwz\tr0,12(r1)\n\tmtcr\tr0\t\t\t# restores cr\n\n\tlwz\tr0,16(r1)\n\tmtctr\tr0\t\t\t# restores ctr\n\n\tlwz\tr0,20(r1)\n\tmtxer\tr0\t\t\t# restores xer\n\n\tlmw\tr3,24(r1)\t\t# restores r3-r31\n\n\tlwz\tr0,8(r1)\t\t# loads r0\n\n\taddi\tr1,r1,168\n\n\tisync\n\n    blr\t\t\t\t# return back to game\n\n_readcodes:\n\tlwz\tr3,0(r15)\t\t#load code address\n\tlwz\tr4,4(r15)\t\t#load code value\n\n\taddi\tr15,r15,8\t\t#r15 points to next code\n\n\tandi.\tr9,r8,1\n\tcmpwi\tcr7,r9,0\t\t#check code execution status in cr7. eq = true, ne = false\n\n\tli\tr9,0\t\t\t#Clears r9\n\n\trlwinm\tr10,r3,3,29,31\t\t#r10 = extract code type, 3 bits\n\trlwinm \tr5,r3,7,29,31\t\t#r5  = extract sub code type 3 bits\n\n\tandis.\tr11,r3,0x1000\t\t#test pointer\n\trlwinm\tr3,r3,0,7,31\t\t#r3  = extract address in r3 (code type 0/1/2) #0x01FFFFFF\n\n\tbne\t+12\t\t\t#jump lf the pointer is used\n\n\trlwinm\tr12,r6,0,0,6\t\t#lf pointer is not used, address = base address\n\tb\t+8\n\n\tmr\tr12,r16\t\t\t#lf pointer is used, address = pointer\n\n\tcmpwi\tcr4,r5,0\t\t#compares sub code type with 0 in cr4\n\n\tcmpwi\tr10,1\n\tblt+\t_write\t\t\t#code type 0 : write\n\tbeq+\t_conditional\t\t#code type 1 : conditional\n\n\tcmpwi\tr10,3\n\tblt+\t_ba_pointer\t\t#Code type 2 : base address operation\n\n\tbeq-\t_repeat_goto\t\t#Code type 3 : Repeat & goto\n\n\tcmpwi\tr10,5\n\tblt-\t_operation_rN\t\t#Code type 4 : rN Operation\n\tbeq+\t_compare16_NM_counter\t#Code type 5 : compare [rN] with [rM]\n\n\tcmpwi\tr10,7\n\tblt+\t_hook_execute\t\t#Code type 6 : hook, execute code\n\n\tb\t_terminator_onoff_\t#code type 7 : End of code list\n\n#CT0=============================================================================\n#write  8bits (0): 00XXXXXX YYYY00ZZ\n#write 16bits (1): 02XXXXXX YYYYZZZZ\n#write 32bits (2): 04XXXXXX ZZZZZZZZ\n#string code  (3): 06XXXXXX YYYYYYYY, d1d1d1d1 d2d2d2d2, d3d3d3d3 ....\n#Serial Code  (4): 08XXXXXX YYYYYYYY TNNNZZZZ VVVVVVVV\n\n_write:\n\tadd\tr12,r12,r3\t\t#address = (ba/po)+(XXXXXX)\n\tcmpwi\tr5,3\n\tbeq-\t_write_string\t\t#r5  == 3, goto string code\n\tbgt-\t_write_serial\t\t#r5  >= 4, goto serial code\n\n\tbne-\tcr7,_readcodes\t\t#lf code execution set to false skip code\n\n\tcmpwi\tcr4,r5,1\t\t#compares sub code type and 1 in cr4\n\n\tbgt-\tcr4,_write32\t\t#lf sub code type == 2, goto write32\n\n\t#lf sub code type = 0 or 1 (8/16bits)\n\trlwinm\tr10,r4,16,16,31\t\t#r10 = extract number of times to write (16bits value)\n\n_write816:\n\tbeq\tcr4,+16\t\t\t#lf r5 = 1 then 16 bits write\n\tstbx\tr4,r9,r12\t\t#write byte\n\taddi\tr9,r9,1\n\tb\t+12\n\tsthx\tr4,r9,r12\t\t#write halfword\n\taddi\tr9,r9,2\n\tsubic.\tr10,r10,1\t\t#number of times to write -1\n\tbge-\t_write816\n\tb\t_readcodes\n\n_write32:\n\trlwinm\tr12,r12,0,0,29\t\t#32bits align adress\n    stw\tr4,0(r12)\t\t#write word to address\n    b\t_readcodes\n\n_write_string:\t\t\t\t#endianess ?\n\tmr\tr9,r4\n\tbne-\tcr7,_skip_and_align\t#lf code execution is false, skip string code data\n\n\t_stb:\n\tsubic.\tr9,r9,1\t\t\t#r9 -= 1 (and compares r9 with 0)\n\tblt-\t_skip_and_align\t\t#lf r9 < 0 then ExploitCode102_Exit\n\tlbzx\tr5,r9,r15\n\tstbx\tr5,r9,r12\t\t#loop until all the data has been written\n\tb\t_stb\n\n_write_serial:\n\taddi\tr15,r15,8\t\t#r15 points to the code after the serial code\n\tbne-\tcr7,_readcodes\t\t#lf code execution is false, skip serial code\n\n\tlwz\tr5,-8(r15)\t\t#load TNNNZZZZ\n\tlwz\tr11,-4(r15)\t\t#r11 = load VVVVVVVV\n\n\trlwinm\tr17,r5,0,16,31\t\t#r17 = ZZZZ\n\trlwinm\tr10,r5,16,20,31\t\t#r10 = NNN (# of times to write -1)\n\trlwinm\tr5,r5,4,28,31\t\t#r5  = T (0:8bits/1:16bits/2:32bits)\n\n_loop_serial:\n\tcmpwi\tcr5,r5,1\n\tbeq-\tcr5,+16\t\t\t#lf 16bits\n\tbgt+\tcr5,+20\t\t\t#lf 32bits\n\n\tstbx\tr4,r9,r12\t\t#write serial byte (CT04,T=0)\n\tb\t+16\n\n\tsthx\tr4,r9,r12\t\t#write serial halfword (CT04,T=1)\n\tb\t+8\n\n\tstwx\tr4,r9,r12\t\t#write serial word (CT04,T>=2)\n\n\tadd\tr4,r4,r11\t\t#value +=VVVVVVVV\n\tadd\tr9,r9,r17\t\t#address +=ZZZZ\n\tsubic.\tr10,r10,1\n\tbge+\t_loop_serial\t\t#loop until all the data has been written\n\n\tb\t_readcodes\n\n#CT1=============================================================================\n#32bits conditional (0,1,2,3): 20XXXXXX YYYYYYYY\n#16bits conditional (4,5,6,7): 28XXXXXX ZZZZYYYY\n\n#PS : 31 bit of address = endlf.\n\n_conditional:\n\trlwinm.\tr9,r3,0,31,31\t\t#r10 = (bit31 & 1) (endlf enabled?)\n\n\tbeq\t+16\t\t\t#jump lf endlf is not enabled\n\n\trlwinm\tr8,r8,31,1,31\t\t#Endlf (r8>>1)\n\tandi.\tr9,r8,1\t\t\t#r9=code execution status\n\tcmpwi\tcr7,r9,0\t\t#check code execution status in cr7\n\tcmpwi\tcr5,r5,4\t\t#compares sub code type and 4 in cr5\n\tcmpwi\tcr3,r10,5\t\t#compares code type and 5 in cr3\n\n\trlwimi\tr8,r8,1,0,30\t\t#r8<<1 and current execution status = old execution status\n\tbne-\tcr7,_true_end\t\t#lf code execution is set to false -> ExploitCode102_Exit\n\n\tbgt\tcr3,_addresscheck2\t#lf code type==6 -> address check\n\tadd\tr12,r12,r3\t\t#address = (ba/po)+(XXXXXX)\n\n\tblt\tcr3,+12\t\t\t#jump lf code type <5 (==1)\n\tblt\tcr5,_condition_sub\t#compare [rN][rM]\n\tb\t_conditional16_2\t#counter compare\n\tbge\tcr5,_conditional16\t#lf sub code type>=4 -> 16 bits conditional\n\n_conditional32:\n\trlwinm\tr12,r12,0,0,29\t\t#32bits align\n\tlwz\tr11,0(r12)\n\tb\t_condition_sub\n\n_conditional16:\n\trlwinm\tr12,r12,0,0,30\t\t#16bits align\n\tlhz\tr11,0(r12)\n_conditional16_2:\n\tnor\tr9,r4,r4\n\trlwinm\tr9,r9,16,16,31\t\t#r9  = extract mask\n\tand\tr11,r11,r9\t\t#r11 &= r9\n\trlwinm\tr4,r4,0,16,31\t\t#r4  = extract data to check against\n\n_condition_sub:\n\tcmpl\tcr6,r11,r4\t\t#Unsigned compare. r11=data at address, r4=YYYYYYYY\n\tandi.\tr9,r5,3\n\tbeq\t_skip_NE\t\t#lf sub code (type & 3) == 0\n\tcmpwi\tr9,2\n\tbeq\t_skip_LE\t\t#lf sub code (type & 3) == 2\n\tbgt\t_skip_GE\t\t#lf sub code (type & 3) == 3\n\n_skip_EQ:#1\n\tbne-\tcr6,_true_end\t\t#CT21, CT25, CT29 or CT2D (lf !=)\n\tb\t_skip\n\n_skip_NE:#0\n\tbeq-\tcr6,_true_end\t\t#CT20, CT24, CT28 or CT2C (lf==)\n\tb\t_skip\n\n_skip_LE:#2\n\tbgt-\tcr6,_true_end\t\t#CT22, CT26, CT2A or CT2E (lf r4>[])\n\tb\t_skip\n\n_skip_GE:#3\n\tblt-\tcr6,_true_end\t\t#CT23, CT27, CT2B or CT2F (lf r4<r4)\n\n_skip:\n\tori\tr8,r8,1\t\t\t#r8|=1 (execution status set to false)\n_true_end:\n\tbne+\tcr3,_readcodes\t\t#lf code type <> 5\n\tblt\tcr5,_readcodes\n\tlwz\tr11,-8(r15)\t\t#load counter\n\tbne\tcr7,_clearcounter\t#lf previous code execution false clear counter\n\tandi.\tr12,r3,0x8\t\t#else lf clear counter bit not set increase counter\n\tbeq\t_increase_counter\n\tandi.\tr12,r8,0x1\t\t#else lf.. code result true clear counter\n\tbeq\t_clearcounter\n\n_increase_counter:\n\taddi\tr12,r11,0x10\t\t#else increase the counter\n\trlwimi\tr11,r12,0,12,27\t\t#update counter\n\tb\t_savecounter\n\n_clearcounter:\n\trlwinm\tr11,r11,0,28,11\t\t#clear the counter\n_savecounter:\n\tstw\tr11,-8(r15)\t\t#save counter\n\tb _readcodes\n\n\n#CT2============================================================================\n\n#load base adress    (0): 40TYZ00N XXXXXXXX = (load/add:T) ba from [(ba/po:Y)+XXXXXXXX(+rN:Z)]\n\n#set base address    (1): 42TYZ00N XXXXXXXX = (set/add:T) ba to (ba/po:Y)+XXXXXXXX(+rN:Z)\n\n#store base address  (2): 440Y0000 XXXXXXXX = store base address to [(ba/po)+XXXXXXXX]\n#set base address to (3): 4600XXXX 00000000 = set base address to code address+XXXXXXXX\n#load pointer        (4): 48TYZ00N XXXXXXXX = (load/add:T) po from [(ba/po:Y)+XXXXXXXX(+rN:Z)]\n\n#set pointer         (5): 4ATYZ00N XXXXXXXX = (set/add:T) po to (ba/po:Y)+XXXXXXXX(+rN:Y)\n\n#store pointer       (6): 4C0Y0000 XXXXXXXX = store pointer to [(ba/po)+XXXXXXXX]\n#set pointer to      (7): 4E00XXXX 00000000 = set pointer to code address+XXXXXXXX\n\n_ba_pointer:\n\tbne-\tcr7,_readcodes\n\n\trlwinm\tr9,r3,2,26,29\t\t#r9  = extract N, makes N*4\n\n\trlwinm\tr14,r3,16,31,31\t\t#r3 = add ba/po flag bit (Y)\n\tcmpwi\tcr3,r14,0\n\n\tcmpwi\tcr4,r5,4\t\t#cr4 = compare sub code type with 4 (ba/po)\n\tandi.\tr14,r5,3\t\t#r14 = sub code type and 3\n\n\tcmpwi\tcr5,r14,2\t\t#compares sub code type and 2\n\n\tblt-\tcr5,_p01\n\tbeq-\tcr5,_p2\t\t\t#sub code type 2\n\n_p3:\n\textsh\tr4,r3\n\tadd\tr4,r4,r15\t\t#r4=XXXXXXXX+r15 (code location in memory)\n\tb\t_pend\n\n_p01:\n\trlwinm.\tr5,r3,20,31,31\t\t#r3 = rN use bit (Z)\n\tbeq\t+12\t\t\t#flag is not set(=0), address = XXXXXXXX\n\n\tlwzx\tr9,r7,r9\t\t#r9 = load register N\n\tadd\tr4,r4,r9\t\t#flag is set (=1), address = XXXXXXXX+rN\n\n\tbeq\tcr3,+8\t\t\t#(Y) flag is not set(=0), address = XXXXXXXX (+rN)\n\n  \tadd\tr4,r12,r4\t\t#address = XXXXXXXX (+rN) + (ba/po)\n\n\tcmpwi\tcr5,r14,1\n\tbeq\tcr5,+8\t\t\t#address = (ba/po)+XXXXXXXX(+rN)\n\tlwz\tr4,0(r4)\t\t#address = [(ba/po)+XXXXXXXX(+rN)]\n\n\trlwinm.\tr3,r3,12,31,31\t\t#r5 = add/replace flag (T)\n\tbeq\t_pend\t\t\t#flag is not set (=0), (ba/po)= XXXXXXXX (+rN) + (ba/po)\n\tbge\tcr4,+12\n\tadd\tr4,r4,r6\t\t#ba += XXXXXXXX (+rN) + (ba/po)\n\tb\t_pend\n\tadd\tr4,r4,r16\t\t#po += XXXXXXXX (+rN) + (ba/po)\n\tb\t_pend\n\n_p2:\n\trlwinm.\tr5,r3,20,31,31\t\t#r3 = rN use bit (Z)\n\tbeq\t+12\t\t\t#flag is not set(=0), address = XXXXXXXX\n\n\tlwzx\tr9,r7,r9\t\t#r9 = load register N\n\tadd\tr4,r4,r9\t\t#flag is set (=1), address = XXXXXXXX+rN\n\n\tbge\tcr4,+12\n\tstwx\tr6,r12,r4\t\t#[(ba/po)+XXXXXXXX] = base address\n\tb\t_readcodes\n\tstwx\tr16,r12,r4\t\t#[(ba/po)+XXXXXXXX] = pointer\n\tb\t_readcodes\n\n_pend:\n\tbge\tcr4,+12\n\tmr\tr6,r4\t\t\t#store result to base address\n\tb\t_readcodes\n\tmr\tr16,r4\t\t\t#store result to pointer\n\tb\t_readcodes\n\n\n#CT3============================================================================\n#set repeat     (0): 6000ZZZZ 0000000P = set repeat\n#execute repeat (1): 62000000 0000000P = execute repeat\n#return\t\t(2): 64S00000 0000000P = return (lf true/false/always)\n#goto\t\t(3): 66S0XXXX 00000000 = goto (lf true/false/always)\n#gosub\t\t(4): 68S0XXXX 0000000P = gosub (lf true/false/always)\n\n_repeat_goto:\n\trlwinm\tr9,r4,3,25,28\t\t#r9  = extract P, makes P*8\n\taddi\tr9,r9,0x40\t\t#offset that points to block P's\n\tcmpwi\tr5,2\t\t\t#compares sub code type with 2\n\tblt-\t_repeat\n\n\trlwinm.\tr11,r3,10,0,1\t\t#extract (S&3)\n\tbeq\t+20\t\t\t#S=0, skip lf true, don't skip lf false\n\tbgt\t+8\n\tb\t_b_bl_blr_nocheck\t#S=2/3, always skip (code exec status turned to true)\n\tbeq-\tcr7,_readcodes\t\t#S=1, skip lf false, don't skip lf true\n\tb\t_b_bl_blr_nocheck\n\n_b_bl_blr:\n\tbne-\tcr7,_readcodes\t\t#lf code execution set to false skip code\n\n_b_bl_blr_nocheck:\n\tcmpwi\tr5,3\n\n\tbgt-\t_bl\t\t\t#sub code type >=4, bl\n\tbeq+\t_b\t\t\t#sub code type ==3, b\n\n_blr:\n\tlwzx\tr15,r7,r9\t\t#loads the next code address\n\tb\t_readcodes\n\n_bl:\n\tstwx\tr15,r7,r9\t\t#stores the next code address in block P's address\n_b:\n\textsh\tr4,r3\t\t\t#XXXX becomes signed\n\trlwinm\tr4,r4,3,9,28\n\n\tadd\tr15,r15,r4\t\t#next code address +/-=line XXXX\n\tb\t_readcodes\n\n_repeat:\n\tbne-\tcr7,_readcodes\t\t#lf code execution set to false skip code\n\n\tadd\tr5,r7,r9\t\t#r5 points to P address\n\tbne-\tcr4,_execute_repeat\t#branch lf sub code type == 1\n\n_set_repeat:\n\trlwinm\tr4,r3,0,16,31\t\t#r4  = extract NNNNN\n\tstw\tr15,0(r5)\t\t#store current code address to [bP's address]\n\tstw\tr4,4(r5)\t\t#store NNNN to [bP's address+4]\n\n\tb\t_readcodes\n\n_execute_repeat:\n\tlwz\tr9,4(r5)\t\t#load NNNN from [M+4]\n\tcmpwi\tr9,0\n\tbeq-\t_readcodes\n\tsubi\tr9,r9,1\n\tstw\tr9,4(r5)\t\t#saves (NNNN-1) to [bP's address+4]\n\tlwz\tr15,0(r5)\t\t#load next code address from [bP's address]\n\tb\t_readcodes\n\n#CT4============================================================================\n#set/add to rN(0) : 80SY000N XXXXXXXX = rN = (ba/po) + XXXXXXXX\n#load rN      (1) : 82UY000N XXXXXXXX = rN = [XXXXXXXX] (offset support) (U:8/16/32)\n#store rN     (2) : 84UYZZZN XXXXXXXX = store rN in [XXXXXXXX] (offset support) (8/16/32)\n\n#operation 1  (3) : 86TY000N XXXXXXXX = operation rN?XXXXXXXX ([rN]?XXXXXXXX)\n#operation 2  (4) : 88TY000N 0000000M = operation rN?rM ([rN]?rM, rN?[rM], [rN]?[rM])\n\n#copy1        (5) : 8AYYYYNM XXXXXXXX = copy YYYY bytes from [rN] to ([rM]+)XXXXXXXX\n#copy2        (6) : 8CYYYYNM XXXXXXXX = copy YYYY bytes from ([rN]+)XXXXXX to [rM]\n\n\n#for copy1/copy2, lf register == 0xF, base address is used.\n\n#of course, sub codes types 0/1, 2/3 and 4/5 can be put together lf we need more subtypes.\n\n\n_operation_rN:\n\tbne-\tcr7,_readcodes\n\n\trlwinm\tr11,r3,2,26,29\t\t#r11  = extract N, makes N*4\n\tadd\tr26,r7,r11\t\t#1st value address = rN's address\n\tlwz\tr9,0(r26)\t\t#r9 = rN\n\n\trlwinm\tr14,r3,12,30,31\t\t#extracts S, U, T (3bits)\n\n\tbeq-\tcr4,_op0\t\t#lf sub code type = 0\n\n\tcmpwi\tcr4,r5,5\n\tbge-\tcr4,_op56\t\t\t#lf sub code type = 5/6\n\n\tcmpwi\tcr4,r5,3\n\tbge-\tcr4,_op34\t\t\t#lf sub code type = 3/4\n\n\tcmpwi\tcr4,r5,1\n\n_op12:\t#load/store\n\trlwinm.\tr5,r3,16,31,31\t\t#+(ba/po) flag : Y\n\tbeq\t+8\t\t\t#address = XXXXXXXX\n\tadd\tr4,r12,r4\n\n\tcmpwi\tcr6,r14,1\n\tbne-\tcr4,_store\n\n_load:\n\tbgt+\tcr6,+24\n\tbeq-\tcr6,+12\n\n\tlbz\tr4,0(r4)\t\t#load byte at address\n\tb\t_store_reg\n\n\tlhz\tr4,0(r4)\t\t#load halfword at address\n\tb\t_store_reg\n\n\tlwz\tr4,0(r4)\t\t#load word at address\n\tb\t_store_reg\n\n_store:\n\trlwinm\tr19,r3,28,20,31\t\t#r9=r3 ror 12 (N84UYZZZ)\n\n_storeloop:\n\tbgt+\tcr6,+32\n\tbeq-\tcr6,+16\n\n\tstb\tr9,0(r4)\t\t#store byte at address\n\taddi\tr4,r4,1\n\tb\t_storeloopend\n\n\tsth\tr9,0(r4)\t\t#store byte at address\n\taddi\tr4,r4,2\n\tb\t_storeloopend\n\n\tstw\tr9,0(r4)\t\t#store byte at address\n\taddi\tr4,r4,4\n_storeloopend:\n\tsubic.\tr19,r19,1\n\tbge \t_storeloop\n\tb\t_readcodes\n\n_op0:\n\trlwinm.\tr5,r3,16,31,31\t\t#+(ba/po) flag : Y\n\tbeq\t+8\t\t\t#value = XXXXXXXX\n\tadd\tr4,r4,r12\t\t#value = XXXXXXXX+(ba/po)\n\n\tandi.\tr5,r14,1\t\t#add flag : S\n\tbeq\t_store_reg\t\t#add flag not set (=0), rN=value\n\tadd\tr4,r4,r9\t\t#add flag set (=1), rN=rN+value\n\tb\t_store_reg\n\n_op34:\t#operation 1 & 2\n\trlwinm\tr10,r3,16,30,31\t\t#extracts Y\n\n\trlwinm\tr14,r4,2,26,29\t\t#r14  = extract M (in r4), makes M*=4\n\n\tadd\tr19,r7,r14\t\t#2nd value address = rM's address\n\tbne\tcr4,+8\n\tsubi\tr19,r15,4\t\t#lf CT3, 2nd value address = XXXXXXXX's address\n\n\tlwz\tr4,0(r26)\t\t#1st value = rN\n\tlwz\tr9,0(r19)\t\t#2nd value = rM/XXXXXXXX\n\n\tandi.\tr11,r10,1\t\t#lf [] for 1st value\n\tbeq\t+8\n\tmr\tr26,r4\n\n\tandi.\tr11,r10,2\t\t#lf [] for 2nd value\n\tbeq\t+16\n\tmr\tr19,r9\n\tbne+\tcr4,+8\n\tadd\tr19,r12,r19\t\t#lf CT3, 2nd value address = XXXXXXXX+(ba/op)\n\n\trlwinm.\tr5,r3,12,28,31\t\t#operation # flag : T\n\n\tcmpwi\tr5,9\n\tbge\t_op_float\n\n_operation_bl:\n\tbl\t_operation_bl_return\n\n_op450:\n\tadd\tr4,r9,r4\t\t#N + M\n\tb\t_store_reg\n\n_op451:\n\tmullw\tr4,r9,r4\t\t#N * M\n\tb\t_store_reg\n\n_op452:\n\tor\tr4,r9,r4\t\t#N | M\n\tb\t_store_reg\n\n_op453:\n\tand\tr4,r9,r4\t\t#N & M\n\tb\t_store_reg\n\n_op454:\n\txor\tr4,r9,r4\t\t#N ^ M\n\tb\t_store_reg\n\n_op455:\n\tslw\tr4,r9,r4\t\t#N << M\n\tb\t_store_reg\n\n_op456:\n\tsrw\tr4,r9,r4\t\t#N >> M\n\tb\t_store_reg\n\n_op457:\n\trlwnm\tr4,r9,r4,0,31\t\t#N rol M\n\tb\t_store_reg\n\n_op458:\n\tsraw\tr4,r9,r4\t\t#N asr M\n\n_store_reg:\n\tstw\tr4,0(r26)\t\t#Store result in rN/[rN]\n\tb\t_readcodes\n\n_op_float:\n\tcmpwi\tr5,0xA\n\tbgt\t_readcodes\n\n\tlfs\tf2,0(r26)\t\t#f2 = load 1st value\n\tlfs\tf3,0(r19)\t\t#f3 = load 2nd value\n\tbeq-\t_op45A\n\n_op459:\n\tfadds\tf2,f3,f2\t\t#N = N + M (float)\n\tb\t_store_float\n\n_op45A:\n\tfmuls\tf2,f3,f2\t\t#N = N * M (float)\n\n_store_float:\n\tstfs\tf2,0(r26)\t\t#Store result in rN/[rN]\n\tb\t_readcodes\n\n_operation_bl_return:\n\tmflr\tr10\n\trlwinm\tr5,r5,3,25,28\t\t#r5 = T*8\n\tadd\tr10,r10,r5\t\t#jumps to _op5: + r5\n\n\tlwz\tr4,0(r26)\t\t#load [rN]\n\tlwz\tr9,0(r19)\t\t#2nd value address = rM/XXXXXXXX\n\n\tmtlr\tr10\n\tblr\n\n#copy1        (5) : 8AYYYYNM XXXXXXXX = copy YYYY bytes from [rN] to ([rM]+)XXXXXXXX\n#copy2        (6) : 8CYYYYNM XXXXXXXX = copy YYYY bytes from ([rN]+)XXXXXX to [rM]\n\n_op56:\n\tbne-\tcr7,_readcodes\t\t#lf code execution set to false skip code\n\n\trlwinm\tr9,r3,24,0,31\t\t#r9=r3 ror 8 (NM8AYYYY, NM8CYYYY)\n\tmr\tr14,r12\t\t\t#r14=(ba/po)\n\tbl\t_load_NM\n\n\tbeq-\tcr4,+12\n\tadd\tr17,r17,r4\t\t#lf sub code type==0 then source+=XXXXXXXX\n\tb\t+8\n\tadd\tr9,r9,r4\t\t#lf sub code type==1 then destination+=XXXXXXXX\n\n\trlwinm.\tr4,r3,24,16,31\t\t#Extracts YYYY, compares it with 0\n\tli\tr5,0\n\n\t_copy_loop:\n\tbeq \t_readcodes\t\t#Loop until all bytes have been copied.\n\tlbzx \tr10,r5,r17\n\tstbx \tr10,r5,r9\n\taddi\tr5,r5,1\n\tcmpw\tr5,r4\n\tb \t_copy_loop\n\n\n#===============================================================================\n#This is a routine called by _memory_copy and _compare_NM_16\n\n_load_NM:\n\tcmpwi\tcr5,r10,4\t\t#compare code type and 4(rn Operations) in cr5\n\n\trlwinm \tr17,r9,6,26,29\t\t#Extracts N*4\n\tcmpwi \tr17,0x3C\n\tlwzx\tr17,r7,r17\t\t#Loads rN value in r17\n\tbne \t+8\n\tmr\tr17,r14\t\t\t#lf N==0xF then source address=(ba/po)(+XXXXXXXX, CT5)\n\n\tbeq\tcr5,+8\n\tlhz\tr17,0(r17)\t\t#...and lf CT5 then N = 16 bits at [XXXXXX+base address]\n\n\trlwinm \tr9,r9,10,26,29\t\t#Extracts M*4\n\tcmpwi \tr9,0x3C\n\tlwzx\tr9,r7,r9\t\t#Loads rM value in r9\n\tbne \t+8\n\tmr\tr9,r14\t\t\t#lf M==0xF then dest address=(ba/po)(+XXXXXXXX, CT5)\n\n\tbeq\tcr5,+8\n\tlhz\tr9,0(r9)\t\t#...and lf CT5 then M = 16 bits at [XXXXXX+base address]\n\n\tblr\n\n#CT5============================================================================\n#16bits conditional (0,1,2,3): A0XXXXXX NM00YYYY (unknown values)\n#16bits conditional (4,5,6,7): A8XXXXXX ZZZZYYYY (counter)\n\n#sub codes types 0,1,2,3 compare [rN] with [rM] (both 16bits values)\n#lf register == 0xF, the value at [base address+XXXXXXXX] is used.\n\n_compare16_NM_counter:\n\tcmpwi \tr5,4\n\tbge\t_compare16_counter\n\n_compare16_NM:\n\tmr\tr9,r4\t\t\t#r9=NM00YYYY\n\n\tadd\tr14,r3,r12\t\t#r14 = XXXXXXXX+(ba/po)\n\n\trlwinm\tr14,r14,0,0,30\t\t#16bits align (base address+XXXXXXXX)\n\n\tbl\t_load_NM\t\t#r17 = N's value, r9 = M's value\n\n\tnor\tr4,r4,r4\t\t#r4=!r4\n\trlwinm\tr4,r4,0,16,31\t\t#Extracts !YYYY\n\n\tand\tr11,r9,r4\t\t#r3 = (M AND !YYYY)\n\tand\tr4,r17,r4\t\t#r4 = (N AND !YYYY)\n\n\tb _conditional\n\n_compare16_counter:\n\trlwinm\tr11,r3,28,16,31\t\t#extract counter value from r3 in r11\n\tb _conditional\n\n#===============================================================================\n#execute     (0) : C0000000 NNNNNNNN = execute\n#hook1       (2) : C4XXXXXX NNNNNNNN = insert instructions at XXXXXX\n#hook2       (3) : C6XXXXXX YYYYYYYY = branch from XXXXXX to YYYYYY\n#on/off      (6) : CC000000 00000000 = on/off switch\n#range check (7) : CE000000 XXXXYYYY = is ba/po in XXXX0000-YYYY0000\n\n_hook_execute:\n\tmr\tr26,r4\t\t\t#r18 = 0YYYYYYY\n\trlwinm\tr4,r4,3,0,28\t\t#r4  = NNNNNNNN*8 = number of lines (and not number of bytes)\n\tbne-\tcr4,_hook_addresscheck\t#lf sub code type != 0\n\tbne-\tcr7,_skip_and_align\n\n_execute:\n\tmtlr\tr15\n\tblrl\n\n_skip_and_align:\n\tadd\tr15,r4,r15\n\taddi\tr15,r15,7\n\trlwinm\tr15,r15,0,0,28\t\t#align 64-bit\n\tb\t_readcodes\n\n_hook_addresscheck:\n\n\tcmpwi\tcr4,r5,3\n\tbgt-\tcr4,_addresscheck1\t#lf sub code type ==6 or 7\n\tlis\tr5,0x4800\n\tadd\tr12,r3,r12\n\trlwinm\tr12,r12,0,0,29\t\t#align address\n\n\tbne-\tcr4,_hook1\t\t#lf sub code type ==2\n\n_hook2:\n\tbne-\tcr7,_readcodes\n\n\trlwinm\tr4,r26,0,0,29\t\t#address &=0x01FFFFFC\n\n\tsub\tr4,r4,r12\t\t#r4 = to-from\n\trlwimi\tr5,r4,0,6,29\t\t#r5  = (r4 AND 0x03FFFFFC) OR 0x48000000\n\trlwimi\tr5,r3,0,31,31\t\t#restore lr bit\n\tstw\tr5,0(r12)\t\t#store opcode\n\tb\t_readcodes\n\n_hook1:\n\tbne-\tcr7,_skip_and_align\n\n\tsub\tr9,r15,r12\t\t#r9 = to-from\n\trlwimi\tr5,r9,0,6,29\t\t#r5  = (r9 AND 0x03FFFFFC) OR 0x48000000\n\tstw\tr5,0(r12)\t\t#stores b at the hook place (over original instruction)\n\taddi\tr12,r12,4\n\tadd\tr11,r15,r4\n\tsubi\tr11,r11,4\t\t#r11 = address of the last work of the hook1 code\n\tsub\tr9,r12,r11\n\trlwimi\tr5,r9,0,6,29\t\t#r5  = (r9 AND 0x03FFFFFC) OR 0x48000000\n\tstw\tr5,0(r11)\t\t#stores b at the last word of the hook1 code\n\tb\t_skip_and_align\n\n_addresscheck1:\n\tcmpwi\tcr4,r5,6\n\tbeq\tcr4,_onoff\n\tb\t_conditional\n_addresscheck2:\n\trlwinm\tr12,r12,16,16,31\n\trlwinm\tr4,r26,16,16,31\n\trlwinm\tr26,r26,0,16,31\n\tcmpw\tr12,r4\n\tblt\t_skip\n\tcmpw\tr12,r26\n\tbge\t_skip\n\tb\t_readcodes\n\n_onoff:\n\trlwinm\tr5,r26,31,31,31\t\t#extracts old exec status (x b a)\n\txori\tr5,r5,1\n\tandi.\tr3,r8,1\t\t\t#extracts current exec status\n\tcmpw\tr5,r3\n\tbeq\t_onoff_end\n\trlwimi\tr26,r8,1,30,30\n\txori\tr26,r26,2\n\n\trlwinm.\tr5,r26,31,31,31\t\t#extracts b\n\tbeq\t+8\n\n\txori\tr26,r26,1\n\n\tstw\tr26,-4(r15)\t\t#updates the code value in the code list\n\n_onoff_end:\n\trlwimi\tr8,r26,0,31,31\t\t#current execution status = a\n\n\tb _readcodes\n\n#===============================================================================\n#Full terminator  (0) = E0000000 XXXXXXXX = full terminator\n#Endlfs/Else      (1) = E2T000VV XXXXXXXX = endlfs (+else)\n#End code handler     = F0000000 00000000\n\n_terminator_onoff_:\n\tcmpwi\tr11,0\t\t\t#lf code type = 0xF\n    beq _notTerminator\n    cmpwi r5,1\n    beq _asmTypeba\n    cmpwi r5,2\n    beq _asmTypepo\n    cmpwi r5,3\n    beq _patchType\n    b _exitcodehandler\n_asmTypeba:\n    rlwinm r12,r6,0,0,6 # use base address\n_asmTypepo:\n    rlwinm r23,r4,8,24,31 # extract number of half words to XOR\n    rlwinm r24,r4,24,16,31 # extract XOR checksum\n    rlwinm r4,r4,0,24,31 # set code value to number of ASM lines only\n    bne cr7,_goBackToHandler #skip code if code execution is set to false\n    rlwinm. r25,r23,0,24,24 # check for negative number of half words\n    mr r26,r12 # copy ba/po address\n    add r26,r3,r26 # add code offset to ba/po code address\n    rlwinm r26,r26,0,0,29 # clear last two bits to align address to 32-bit\n    beq _positiveOffset # if number of half words is negative, extra setup needs to be done\n    extsb r23,r23\n    neg r23,r23\n    mulli r25,r23,2\n    addi r25,r25,4\n    subf r26,r25,r26\n_positiveOffset:\n    cmpwi r23,0\n    beq _endXORLoop\n    li r25,0\n    mtctr r23\n_XORLoop:\n    lhz r27,4(r26)\n    xor r25,r27,r25\n    addi r26,r26,2\n    bdnz _XORLoop\n_endXORLoop:\n    cmpw r24,r25\n    bne _goBackToHandler\n    b _hook_execute\n_patchType:\n    rlwimi\tr8,r8,1,0,30\t\t#r8<<1 and current execution status = old execution status\n    bne\tcr7,_exitpatch\t\t#lf code execution is set to false -> ExploitCode102_Exit\n    rlwinm. r23,r3,22,0,1\n    bgt _patchfail\n    blt _copytopo\n_runpatch:\n    rlwinm r30,r3,0,24,31\n    mulli r30,r30,2\n    rlwinm r23,r4,0,0,15\n    xoris r24,r23,0x8000\n    cmpwi r24,0\n    bne- _notincodehandler\n    ori r23,r23,0x3000\n_notincodehandler:\n    rlwinm r24,r4,16,0,15\n    mulli r25,r30,4\n    subf r24,r25,r24\n_patchloop:\n    li r25,0\n_patchloopnext:\n    mulli r26,r25,4\n    lwzx r27,r15,r26\n    lwzx r26,r23,r26\n    addi r25,r25,1\n    cmplw r23,r24\n    bgt _failpatchloop\n    cmpw r25,r30\n    bgt _foundaddress\n    cmpw r26,r27\n    beq _patchloopnext\n    addi r23,r23,4\n    b _patchloop\n_foundaddress:\n    lwz r3,-8(r15)\n    ori r3,r3,0x300\n    stw r3,-8(r15)\n    stw r23,-4(r15)\n    mr r16,r23\n    b _exitpatch\n_failpatchloop:\n    lwz r3,-8(r15)\n    ori r3,r3,0x100\n    stw r3,-8(r15)\n_patchfail:\n    ori\tr8,r8,1\t\t\t#r8|=1 (execution status set to false)\n    b _exitpatch\n_copytopo:\n    mr r16,r4\n_exitpatch:\n    rlwinm r4,r3,0,24,31 # set code to number of lines only\n_goBackToHandler:\n    mulli r4,r4,8\n    add r15,r4,r15 # skip the lines of the code\n    b _readcodes\n\n_notTerminator:\n\n_terminator:\n\tbne\tcr4,+12\t\t\t#check lf sub code type == 0\n\tli\tr8,0\t\t\t#clear whole code execution status lf T=0\n\tb\t+20\n\n\trlwinm.\tr9,r3,0,27,31\t\t#extract VV\n#\tbne \t+8\t\t\t#lf VV!=0\n#\tbne-\tcr7,+16\n\n\trlwinm\tr5,r3,12,31,31\t\t#extract \"else\" bit\n\n\tsrw\tr8,r8,r9\t\t#r8>>VV, meaning endlf VV lfs\n\n    rlwinm. r23,r8,31,31,31\n    bne +8 # execution is false if code execution >>, so don't invert code status\n\txor\tr8,r8,r5\t\t#lf 'else' is set then invert current code status\n\n_load_baseaddress:\n\trlwinm.\tr5,r4,0,0,15\n\tbeq\t+8\n\tmr\tr6,r5\t\t\t#base address = r4\n\trlwinm.\tr5,r4,16,0,15\n\tbeq\t+8\n\tmr\tr16,r5\t\t\t#pointer = r4\n\tb\t_readcodes\n\n#===============================================================================\n\nfrozenvalue:\t#frozen value, then LR\n.long        0,0\ndwordbuffer:\n.long        0,0\nrem:\n.long        0\nbpbuffer:\n.long 0\t\t#int address to bp on\n.long 0\t\t#data address to bp on\n.long 0\t\t#alignement check\n.long 0\t\t#counter for alignement\n\nregbuffer:\n#.space 72*4\n\n#.align 3\n\n#codelist:\n#.space 2*4\n#.end\n#endregion\n#region ExploitCode101\nExploitCode101:\nblrl\n#Scene Change\n  branchl r12,0x801a4518\n#Start Menu\n  li\tr3, 0\n  lis\tr4, 0x804D\n  stb\tr3, 0x5B9C (r4)\n#Disable Saving\n  lis r5,0x8043\n  li\tr6, 4\n  stw\tr6, 0x2640 (r5)\n#Error SFX\n  li  r3,3\n  branchl r12,0x80024030\n#Error SFX\n  li  r3,3\n  branchl r12,0x80024030\n#Zero Nametag and exit\n  load r3,0x80239700\n  mtlr r3\n  load r3,0x8045cb70\n  li  r4,0\n  load  r5,0xC344\n  branch r12,0x80003130\n#endregion\n#region ExploitCode100\nExploitCode100:\nblrl\n#Scene Change\n  branchl r12,0x801a3e18\n#Start Menu\n  li\tr3, 0\n  lis\tr4, 0x804D\n  stb\tr3, 0x473c (r4)\n#Disable Saving\n  lis r5,0x8043\n  li\tr6,4\n  stw\tr6,0x1360 (r5)\n#Error SFX\n  li  r3,3\n  branchl r12,0x80023fb0\n#Error SFX\n  li  r3,3\n  branchl r12,0x80023fb0\n#Zero Nametag and exit\n  load r3,0x80238b90\n  mtlr r3\n  load r3,0x8045b888\n  li  r4,0\n  load  r5,0xC344\n  branch r12,0x80003130\n\n#endregion\n\nExitInjection:\n#Exit\n  restore\n  blr\n\n#region SnapshotBanner:\nSnapshotBanner:\nblrl\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x26,0x98,0xa6\n.byte 0x84,0x25,0x84,0x46,0x88,0x46,0xc5,0xc6,0x84,0x25,0x84,0x25,0x9c,0xc6,0xb1,0x26\n.byte 0x88,0x45,0xa0,0xe6,0xa5,0x06,0xa4,0xe6,0xc5,0xa6,0xb1,0x46,0xad,0x26,0xad,0x26\n.byte 0x9c,0xc6,0x9c,0xc6,0x9c,0xc6,0x9c,0xc6,0xad,0x26,0xff,0x67,0xff,0x47,0xff,0x27\n.byte 0xa4,0xe6,0xa9,0x06,0xa9,0x06,0xa9,0x06,0xad,0x26,0xad,0x26,0xad,0x26,0xad,0x26\n.byte 0x9c,0xc6,0x9c,0xc6,0x9c,0xc6,0x90,0x85,0xff,0x27,0xff,0x47,0xff,0x67,0xd6,0x26\n.byte 0xa5,0x06,0xa9,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xb1,0x46\n.byte 0x80,0x05,0x80,0x06,0x80,0x05,0x80,0x05,0x80,0x05,0x88,0x46,0x84,0x25,0x80,0x25\n.byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xad,0x26,0xad,0x26,0xad,0x26\n.byte 0x84,0x25,0x9c,0xc6,0x9c,0xc6,0x9c,0xc6,0x94,0x85,0xff,0x07,0xff,0x47,0xff,0x47\n.byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xad,0x26,0xad,0x26,0xb1,0x26,0xb1,0x46\n.byte 0x9c,0xc6,0x9c,0xc6,0x88,0x45,0x80,0x05,0xff,0x47,0xff,0x47,0xf6,0xe7,0xa9,0x06\n.byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46\n.byte 0x80,0x05,0x80,0x26,0x80,0x05,0x80,0x05,0x80,0x05,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46\n.byte 0x80,0x05,0x80,0x26,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x26,0x8c,0x66\n.byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xad,0x26,0xad,0x26,0xb1,0x26,0xb1,0x46\n.byte 0x94,0x85,0xa0,0xe6,0x8c,0x45,0x80,0x05,0xf2,0xc7,0xff,0x67,0xd6,0x06,0x80,0x05\n.byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46\n.byte 0x80,0x05,0x80,0x26,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x88,0x46,0x88,0x46\n.byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xad,0x26\n.byte 0x80,0x05,0x80,0x06,0x88,0x45,0x9c,0xc6,0x84,0x25,0x80,0x26,0xb1,0x46,0xff,0x87\n.byte 0xa4,0xe6,0xa5,0x06,0xa5,0x06,0xa4,0xe6,0xb1,0x26,0xb5,0x46,0xb1,0x46,0xb1,0x46\n.byte 0x8c,0x65,0x80,0x06,0x80,0x05,0x80,0x05,0xbd,0x86,0x80,0x06,0x88,0x46,0x88,0x46\n.byte 0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xa4,0xe6,0xb1,0x46,0xb5,0x46,0xad,0x26,0xad,0x26\n.byte 0x80,0x05,0x80,0x06,0x98,0xa6,0x9c,0xc6,0x84,0x26,0x88,0x46,0xea,0x87,0xff,0x67\n.byte 0xa4,0xe6,0xa5,0x06,0xa5,0x06,0xa4,0xe6,0xb1,0x46,0xb5,0x46,0xb5,0x46,0xb1,0x26\n.byte 0x84,0x25,0x80,0x05,0x80,0x05,0x8c,0x65,0xc1,0xa6,0x80,0x06,0x80,0x06,0xc1,0xa6\n.byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xad,0x26,0xb1,0x46,0xb5,0x46,0xb1,0x46\n.byte 0x9c,0xc6,0x88,0x46,0x80,0x05,0x80,0x05,0xff,0x67,0xa4,0xe6,0x84,0x26,0x88,0x46\n.byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xad,0x26\n.byte 0x80,0x05,0x80,0x05,0x80,0x26,0x98,0xa6,0x84,0x26,0x84,0x26,0x8c,0x66,0xf6,0xe7\n.byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xad,0x26,0xb1,0x46,0xb5,0x46,0xb1,0x46\n.byte 0x98,0xa6,0x80,0x05,0x80,0x06,0x80,0x05,0xee,0xc6,0x88,0x46,0x88,0x46,0x84,0x26\n.byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xad,0x26\n.byte 0x80,0x05,0x80,0x05,0x8c,0x66,0x9c,0xc6,0x84,0x25,0x80,0x05,0xbd,0x86,0xff,0x67\n.byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xad,0x26,0xb1,0x46,0xb5,0x46,0xb1,0x46\n.byte 0x90,0x65,0x80,0x05,0x80,0x06,0x84,0x25,0xee,0xa7,0x88,0x45,0x80,0x26,0x94,0x85\n.byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xad,0x26,0xad,0x26,0xb5,0x46,0xb1,0x46\n.byte 0x9c,0xc6,0x90,0x85,0x80,0x06,0x80,0x05,0xff,0x47,0xd2,0x06,0x80,0x06,0x84,0x25\n.byte 0xa4,0xe6,0xa4,0xe6,0xa5,0x06,0xa4,0xe6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xb1,0x46\n.byte 0x80,0x05,0x80,0x05,0x80,0x26,0x80,0x05,0x84,0x25,0x84,0x25,0x88,0x46,0x80,0x05\n.byte 0xa4,0xe6,0xa4,0xe6,0xa9,0x06,0xa9,0x06,0xb1,0x46,0xad,0x26,0xad,0x26,0xa9,0x06\n.byte 0x80,0x05,0x8c,0x65,0xb1,0x46,0xbd,0x86,0xb1,0x46,0xfb,0x07,0xff,0x47,0xfb,0x07\n.byte 0xa9,0x06,0xa9,0x06,0xa5,0x06,0x90,0x66,0xad,0x26,0xb1,0x26,0xb5,0x46,0xc5,0xc6\n.byte 0xad,0x26,0x88,0x45,0x80,0x05,0x84,0x25,0xff,0x47,0xf2,0xe7,0xa0,0xe6,0x80,0x05\n.byte 0x80,0x05,0x84,0x26,0x88,0x46,0x84,0x25,0xa4,0xe6,0x80,0x26,0x88,0x46,0x88,0x46\n.byte 0xc5,0xc6,0x94,0x86,0x84,0x25,0x84,0x25,0xa4,0xe6,0xb1,0x46,0x80,0x05,0x84,0x25\n.byte 0x84,0x25,0x84,0x26,0xa0,0xe6,0xb1,0x26,0x84,0x25,0x84,0x26,0xa0,0xc6,0xb1,0x46\n.byte 0x84,0x25,0x84,0x26,0xa0,0xe6,0xb1,0x46,0x84,0x25,0x84,0x26,0xa0,0xe6,0xb1,0x46\n.byte 0x88,0x45,0xa0,0xe6,0xa0,0xc6,0xea,0x86,0x80,0x05,0x80,0x26,0x80,0x05,0xe2,0x66\n.byte 0x80,0x05,0x88,0x46,0x84,0x26,0xe2,0x66,0x80,0x05,0x84,0x26,0x80,0x25,0xe2,0x66\n.byte 0xff,0x07,0xa9,0x06,0xa0,0xc6,0x98,0xa6,0xff,0x07,0x90,0x66,0x80,0x06,0x84,0x26\n.byte 0xff,0x07,0x90,0x86,0x84,0x25,0x84,0x25,0xff,0x07,0x90,0x86,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46,0x88,0x46,0x84,0x26\n.byte 0x84,0x25,0x84,0x26,0x84,0x25,0x80,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x80,0x25\n.byte 0x94,0x86,0xff,0x27,0xe6,0x87,0x9c,0xc6,0x94,0x86,0xff,0x27,0xda,0x26,0x80,0x05\n.byte 0x94,0x85,0xff,0x27,0xea,0xa6,0xb1,0x46,0x94,0x85,0xfb,0x07,0xff,0x27,0xff,0x27\n.byte 0x9c,0xc6,0xb5,0x66,0xff,0x27,0xee,0xc7,0x80,0x05,0x80,0x05,0xee,0xa7,0xfb,0x07\n.byte 0xb1,0x46,0xc5,0xc6,0xfb,0x27,0xcd,0xe6,0xff,0x27,0xff,0x47,0xf7,0x07,0x9c,0xc6\n.byte 0x88,0x46,0x88,0x46,0x88,0x46,0x88,0x46,0x8c,0x65,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0x80,0x05,0x84,0x26,0x84,0x25,0x84,0x25,0x80,0x05,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x88,0x46,0x80,0x06,0xad,0x26,0x84,0x25,0x84,0x26,0x80,0x05,0xda,0x26\n.byte 0x84,0x25,0x84,0x26,0x90,0x65,0xfb,0x07,0x84,0x25,0x80,0x06,0xb5,0x46,0xff,0x67\n.byte 0xff,0x47,0xff,0x27,0xf6,0xe7,0x90,0x66,0xf6,0xe7,0xcd,0xe6,0xff,0x47,0xb1,0x26\n.byte 0xda,0x26,0x94,0x86,0xff,0x27,0xda,0x46,0xb5,0x66,0x84,0x26,0xea,0x86,0xfb,0x07\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x80,0x05,0x84,0x26,0x84,0x25,0x84,0x25\n.byte 0x80,0x05,0x84,0x26,0x84,0x25,0x84,0x25,0x94,0x85,0x84,0x26,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x80,0x05,0xb1,0x26,0xff,0x67,0x84,0x25,0x80,0x05,0xad,0x26,0xff,0x67\n.byte 0x84,0x25,0x80,0x06,0xb1,0x26,0xff,0x67,0x84,0x25,0x80,0x06,0xb1,0x26,0xff,0x67\n.byte 0xbd,0x86,0x80,0x05,0x84,0x25,0x84,0x25,0xbd,0x86,0x80,0x05,0x84,0x25,0x84,0x25\n.byte 0xbd,0x86,0x80,0x06,0x84,0x25,0x84,0x25,0xbd,0x86,0x80,0x06,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0xe6,0x86,0xff,0x47,0x84,0x25,0x84,0x25,0xe6,0x87,0xf6,0xe7\n.byte 0x84,0x25,0x84,0x26,0xea,0x87,0xea,0xa6,0x84,0x25,0x84,0x26,0xea,0x87,0xee,0xc7\n.byte 0xfb,0x07,0x94,0x86,0x80,0x05,0xbd,0x86,0xfb,0x07,0xd6,0x26,0x80,0x05,0xbd,0x86\n.byte 0xbd,0x86,0xff,0x47,0x9c,0xa6,0xb9,0x66,0x88,0x45,0xea,0xa6,0xe2,0x66,0xbd,0x86\n.byte 0xff,0x47,0xa0,0xe6,0x80,0x05,0x84,0x25,0xff,0x47,0xa0,0xe6,0x80,0x05,0x84,0x25\n.byte 0xff,0x47,0xa0,0xe6,0x80,0x25,0x84,0x25,0xff,0x47,0xa0,0xe6,0x80,0x26,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x8c,0x66,0xf6,0xe7,0x84,0x25,0x84,0x25,0x8c,0x46,0xf2,0xc7\n.byte 0x84,0x25,0x84,0x25,0x8c,0x46,0xf2,0xc7,0x84,0x25,0x84,0x25,0x8c,0x66,0xf2,0xc7\n.byte 0xee,0xa6,0x88,0x46,0x84,0x26,0x84,0x26,0xea,0xa6,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0xea,0xa6,0x84,0x25,0x84,0x26,0x84,0x25,0xea,0xa6,0x88,0x25,0x84,0x26,0x84,0x25\n.byte 0x84,0x26,0x80,0x05,0xb9,0x66,0xff,0x47,0x84,0x25,0x80,0x05,0xb9,0x66,0xff,0x27\n.byte 0x84,0x25,0x80,0x05,0xb9,0x66,0xff,0x47,0x84,0x25,0x80,0x05,0xb9,0x66,0xff,0x67\n.byte 0xff,0x47,0xc1,0xa6,0x80,0x06,0x94,0x86,0xee,0xc7,0xfb,0x07,0x90,0x66,0x90,0x65\n.byte 0xb5,0x46,0xf6,0xe7,0xd2,0x06,0x8c,0x65,0xa0,0xe6,0xb5,0x46,0xff,0x47,0xb1,0x26\n.byte 0xff,0x27,0xd2,0x06,0x80,0x26,0x88,0x46,0xff,0x27,0xd2,0x06,0x80,0x05,0x84,0x25\n.byte 0xff,0x27,0xd2,0x06,0x80,0x05,0x84,0x25,0xfb,0x07,0xd2,0x06,0x80,0x06,0x84,0x25\n.byte 0x88,0x46,0x84,0x26,0x84,0x26,0x9c,0xc6,0x84,0x25,0x84,0x25,0x80,0x06,0xcd,0xe6\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0xe6,0x66,0x84,0x25,0x84,0x25,0x84,0x26,0xe6,0x86\n.byte 0xff,0x27,0xee,0xc7,0xa0,0xc6,0x88,0x45,0xff,0x67,0xad,0x06,0x80,0x06,0x84,0x26\n.byte 0xff,0x07,0x90,0x85,0x80,0x25,0x8c,0x65,0xfb,0x07,0x90,0x65,0x80,0x05,0xb5,0x66\n.byte 0xa9,0x06,0xff,0x27,0xf6,0xe7,0x88,0x45,0x80,0x05,0xa4,0xe6,0xb9,0x66,0x8c,0x46\n.byte 0x98,0xa6,0x94,0x86,0x94,0x86,0x84,0x26,0xff,0x67,0xff,0x27,0xff,0x27,0x9c,0xa6\n.byte 0x9c,0xc6,0xb1,0x46,0x80,0x26,0x84,0x25,0xa0,0xc6,0xb1,0x46,0x80,0x26,0x84,0x25\n.byte 0xa0,0xc6,0xb1,0x46,0x84,0x26,0x88,0x46,0x9c,0xa6,0xb1,0x46,0x80,0x05,0x84,0x25\n.byte 0x84,0x25,0x80,0x25,0xa0,0xc6,0xb1,0x46,0x84,0x25,0x84,0x26,0xa0,0xc6,0xb1,0x46\n.byte 0x84,0x25,0x84,0x26,0xa0,0xc6,0xb1,0x46,0x84,0x25,0x84,0x26,0xa0,0xe6,0xb1,0x46\n.byte 0x80,0x05,0x84,0x26,0x84,0x25,0xe2,0x66,0x80,0x05,0x88,0x46,0x84,0x25,0xe2,0x66\n.byte 0x80,0x05,0x88,0x46,0x84,0x26,0xea,0x86,0x80,0x05,0x84,0x26,0x84,0x26,0xad,0x26\n.byte 0xff,0x07,0x90,0x86,0x84,0x25,0x84,0x25,0xff,0x07,0x90,0x86,0x84,0x25,0x84,0x25\n.byte 0xff,0x47,0x94,0x86,0x84,0x26,0x84,0x26,0xb9,0x66,0x8c,0x66,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x25\n.byte 0x84,0x26,0x88,0x46,0x88,0x46,0x84,0x26,0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25\n.byte 0x94,0x85,0xff,0x27,0xde,0x66,0x8c,0x65,0x94,0x85,0xff,0x27,0xda,0x46,0x80,0x05\n.byte 0x94,0x86,0xff,0x47,0xe2,0x66,0x80,0x26,0x8c,0x45,0xb9,0x86,0xa9,0x06,0x80,0x05\n.byte 0x8c,0x65,0xb9,0x66,0xff,0x47,0xd6,0x26,0x80,0x05,0x94,0xa6,0xff,0x27,0xe2,0x66\n.byte 0x80,0x25,0x94,0xa6,0xff,0x47,0xee,0xa7,0x80,0x05,0x84,0x26,0xb5,0x46,0xb9,0x66\n.byte 0x80,0x05,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x26\n.byte 0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25,0x8c,0x45,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x84,0x26,0xde,0x46,0xff,0x47,0x80,0x25,0x98,0xa6,0xfb,0x27,0xea,0xa7\n.byte 0x80,0x05,0xc5,0xa6,0xff,0xa7,0xb5,0x66,0x84,0x25,0xa9,0x06,0xb9,0x86,0x8c,0x65\n.byte 0xfb,0x07,0xf6,0xe7,0xff,0x27,0xff,0x47,0xc1,0xa6,0xc5,0xc6,0xcd,0xe6,0xff,0x27\n.byte 0x80,0x05,0x80,0x05,0x80,0x05,0xee,0xc7,0x80,0x25,0x84,0x26,0x80,0x25,0xa4,0xe6\n.byte 0xb5,0x66,0x80,0x06,0x84,0x25,0x84,0x25,0xe2,0x66,0x84,0x26,0x88,0x46,0x88,0x46\n.byte 0xff,0x47,0x9c,0xc6,0x80,0x05,0x84,0x25,0xb9,0x86,0x98,0xa6,0x80,0x25,0x84,0x25\n.byte 0x84,0x25,0x80,0x06,0xb1,0x26,0xff,0x67,0x84,0x26,0x80,0x26,0xb1,0x46,0xff,0x67\n.byte 0x84,0x25,0x80,0x05,0xb1,0x46,0xff,0x87,0x84,0x25,0x80,0x25,0x94,0x86,0xb9,0x86\n.byte 0xbd,0x86,0x80,0x06,0x84,0x25,0x84,0x25,0xbd,0x86,0x80,0x06,0x88,0x46,0x88,0x46\n.byte 0xc1,0x86,0x80,0x05,0x84,0x25,0x84,0x25,0x9c,0xc6,0x80,0x25,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x84,0x26,0xea,0x87,0xf2,0xc7,0x84,0x25,0x88,0x46,0xea,0xa7,0xf2,0xc7\n.byte 0x84,0x25,0x84,0x25,0xee,0xc7,0xf6,0xe7,0x84,0x25,0x84,0x25,0xa9,0x06,0xb1,0x26\n.byte 0x80,0x25,0xa5,0x06,0xff,0x27,0xea,0xa6,0x88,0x46,0x80,0x06,0xda,0x26,0xff,0x47\n.byte 0x88,0x45,0x80,0x05,0x98,0xa6,0xff,0x27,0x84,0x25,0x84,0x25,0x80,0x05,0xa9,0x06\n.byte 0xff,0x27,0xa0,0xe6,0x80,0x26,0x84,0x25,0xff,0x27,0xa0,0xe6,0x84,0x26,0x88,0x46\n.byte 0xff,0x67,0xa0,0xe6,0x80,0x05,0x84,0x25,0xb9,0x66,0x90,0x66,0x80,0x25,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x8c,0x66,0xf2,0xc7,0x84,0x26,0x84,0x26,0x8c,0x66,0xf6,0xe7\n.byte 0x84,0x25,0x84,0x25,0x8c,0x66,0xfb,0x07,0x84,0x25,0x80,0x25,0x84,0x25,0xb1,0x46\n.byte 0xea,0xa6,0x88,0x25,0x84,0x26,0x84,0x25,0xea,0xa6,0x88,0x46,0x88,0x46,0x88,0x46\n.byte 0xf2,0xc7,0x84,0x25,0x84,0x25,0x84,0x25,0xad,0x26,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x80,0x05,0xb9,0x66,0xff,0x67,0x88,0x46,0x80,0x06,0xb9,0x86,0xff,0x67\n.byte 0x84,0x25,0x80,0x05,0xbd,0x86,0xff,0x87,0x84,0x25,0x80,0x05,0x98,0xa6,0xb9,0x86\n.byte 0xa9,0x06,0x80,0x05,0xee,0xa7,0xf2,0xc7,0xad,0x26,0x80,0x05,0xad,0x26,0xff,0x47\n.byte 0xad,0x26,0x80,0x05,0x80,0x26,0xda,0x46,0x90,0x85,0x80,0x05,0x80,0x05,0x90,0x85\n.byte 0xff,0x27,0xcd,0xe6,0x80,0x06,0x84,0x25,0xff,0x47,0xcd,0xe6,0x80,0x06,0x84,0x26\n.byte 0xff,0x87,0xd2,0x06,0x80,0x06,0x88,0x46,0xb9,0x86,0xa0,0xe6,0x80,0x05,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x80,0x26,0xda,0x26,0x84,0x25,0x84,0x25,0x80,0x26,0xad,0x26\n.byte 0x84,0x26,0x84,0x25,0x88,0x46,0x84,0x26,0x84,0x25,0x84,0x25,0x84,0x26,0x80,0x05\n.byte 0xff,0x47,0x9c,0xc6,0x80,0x06,0x94,0x85,0xff,0x67,0xde,0x46,0x8c,0x66,0x80,0x05\n.byte 0xcd,0xe6,0xff,0x67,0xfb,0x07,0xe6,0x86,0x80,0x05,0xa9,0x06,0xd2,0x06,0xda,0x26\n.byte 0xa4,0xe6,0xd6,0x06,0xff,0x47,0x9c,0xa6,0x90,0x65,0xee,0xa7,0xff,0x27,0x98,0xa6\n.byte 0xff,0x07,0xe6,0x87,0xff,0x27,0x98,0xa6,0xb5,0x46,0x88,0x45,0xb1,0x46,0xb1,0x46\n.byte 0x98,0xa6,0xb1,0x46,0x80,0x05,0x84,0x25,0x9c,0xc6,0xb1,0x46,0x80,0x26,0x84,0x25\n.byte 0xb5,0x46,0xa0,0xe6,0x84,0x26,0x84,0x25,0xc1,0xa6,0x84,0x25,0x88,0x46,0x88,0x46\n.byte 0x84,0x25,0x80,0x25,0xa0,0xc6,0xb1,0x46,0x84,0x25,0x80,0x25,0xa0,0xc6,0xad,0x26\n.byte 0x84,0x25,0x84,0x26,0xa0,0xc6,0xad,0x26,0x84,0x25,0x84,0x26,0xa0,0xc6,0xad,0x26\n.byte 0x80,0x05,0x88,0x46,0x84,0x25,0x80,0x05,0xc1,0x86,0xee,0xc7,0xea,0x86,0x94,0x85\n.byte 0xcd,0xe6,0xff,0x47,0xff,0x47,0xa9,0x06,0xcd,0xe6,0xfb,0x07,0xf2,0xc7,0xc9,0xc6\n.byte 0x80,0x05,0x84,0x26,0x84,0x25,0x88,0x45,0x80,0x05,0x8c,0x66,0xe2,0x66,0xee,0xe7\n.byte 0x80,0x05,0xa0,0xe6,0xff,0x27,0xff,0x47,0x80,0x05,0xbd,0x86,0xf6,0xe7,0xf6,0xe7\n.byte 0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25,0xcd,0xe6,0x84,0x26,0x84,0x25,0x84,0x25\n.byte 0xda,0x46,0x84,0x26,0x84,0x25,0x84,0x25,0xda,0x46,0x84,0x26,0x84,0x26,0x80,0x05\n.byte 0x84,0x25,0x80,0x05,0x80,0x05,0x90,0x85,0x80,0x05,0x94,0x86,0xda,0x46,0xff,0x27\n.byte 0x8c,0x45,0xea,0xa6,0xff,0x47,0xc9,0xc6,0xb5,0x66,0xff,0x67,0xc9,0xc6,0x80,0x05\n.byte 0x98,0xa6,0x90,0x86,0x80,0x05,0x80,0x05,0xff,0x47,0xff,0x27,0xd6,0x26,0x8c,0x65\n.byte 0xa9,0x06,0xd2,0x06,0xff,0x67,0xe2,0x66,0x80,0x05,0x80,0x06,0xd6,0x06,0xff,0x67\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x80,0x25,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25,0xad,0x06,0x80,0x26,0x88,0x46,0x88,0x46\n.byte 0x84,0x25,0x84,0x26,0x80,0x05,0x84,0x25,0x80,0x05,0xc9,0xc6,0xee,0xc7,0xf2,0xc7\n.byte 0x80,0x05,0xda,0x26,0xff,0x47,0xd6,0x06,0x80,0x05,0xd6,0x26,0xff,0x27,0x90,0x86\n.byte 0x88,0x45,0x88,0x46,0x80,0x05,0x80,0x05,0xf6,0xe7,0xf2,0xc7,0xd6,0x26,0x94,0x86\n.byte 0xc9,0xc6,0xda,0x26,0xff,0x47,0xee,0xa6,0x80,0x05,0x80,0x06,0xc5,0xa6,0xff,0x67\n.byte 0x80,0x05,0x84,0x26,0x84,0x25,0x84,0x25,0x80,0x05,0x88,0x46,0x84,0x25,0x80,0x05\n.byte 0x8c,0x45,0x84,0x26,0x84,0x25,0x80,0x05,0xb9,0x66,0x80,0x06,0x88,0x46,0x80,0x06\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x05,0xa5,0x06,0xee,0xc7,0xf2,0xc7,0xf6,0xe7\n.byte 0xad,0x26,0xff,0x67,0xe6,0x86,0xc9,0xc6,0xad,0x26,0xff,0x67,0xb5,0x46,0x80,0x05\n.byte 0x84,0x25,0x88,0x46,0x88,0x45,0x84,0x25,0xf2,0xc7,0xf6,0xe7,0xea,0xa6,0x8c,0x65\n.byte 0xcd,0xe6,0xcd,0xe6,0xc9,0xc6,0x88,0x45,0x80,0x05,0x80,0x06,0x80,0x06,0x80,0x26\n.byte 0x84,0x25,0x88,0x46,0xad,0x26,0xb9,0x66,0x84,0x25,0xc1,0xa6,0xa9,0x06,0x8c,0x65\n.byte 0x9c,0xa6,0xb9,0x86,0x80,0x06,0x84,0x25,0xa0,0xe6,0xb5,0x46,0x80,0x26,0x88,0x46\n.byte 0xbd,0x86,0xc1,0x86,0xc1,0x86,0xb9,0x66,0x8c,0x65,0x8c,0x66,0x8c,0x66,0x8c,0x65\n.byte 0x84,0x25,0x84,0x26,0x84,0x26,0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46,0x88,0x46\n.byte 0xb9,0x66,0xbd,0x86,0xc1,0xa6,0xbd,0x86,0x8c,0x65,0x8c,0x66,0x8c,0x66,0x8c,0x65\n.byte 0x84,0x25,0x84,0x25,0x84,0x46,0x84,0x25,0x88,0x46,0x88,0x46,0x88,0x46,0x88,0x46\n.byte 0xbd,0x86,0xc1,0x86,0xc1,0x86,0xb9,0x66,0x8c,0x65,0x8c,0x66,0x8c,0x66,0x8c,0x65\n.byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x8c,0x67,0x88,0x46,0x88,0x46,0x88,0x46\n.byte 0xb9,0x66,0xbd,0x86,0xc1,0x86,0xbd,0x86,0x8c,0x65,0x8c,0x66,0x8c,0x66,0x8c,0x65\n.byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x88,0x46,0x88,0x46,0x88,0x46,0x88,0x46\n.byte 0xbd,0x86,0xc1,0x86,0xbd,0x86,0xb9,0x66,0x8c,0x65,0x8c,0x66,0x90,0x66,0x8c,0x65\n.byte 0x84,0x25,0x84,0x25,0x84,0x46,0x84,0x25,0x88,0x46,0x84,0x26,0x88,0x46,0x8c,0x66\n.byte 0xbd,0x86,0xc1,0x86,0xc1,0xa6,0xbd,0x86,0x8c,0x65,0x8c,0x65,0x90,0x66,0x8c,0x65\n.byte 0x84,0x25,0x84,0x25,0x84,0x46,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x88,0x46\n.byte 0xb9,0x66,0xb9,0x66,0xc1,0xa6,0xbd,0x86,0x8c,0x65,0x8c,0x65,0x90,0x66,0x8c,0x65\n.byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x88,0x46\n.byte 0xbd,0x86,0xbd,0x86,0xc1,0x86,0xbd,0x86,0x8c,0x65,0x8c,0x65,0x90,0x66,0x8c,0x65\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x8c,0x67,0x8c,0x67\n.byte 0xbd,0x86,0xb9,0x66,0xb9,0x66,0xb9,0x66,0x8c,0x65,0x8c,0x65,0x8c,0x66,0x8c,0x65\n.byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x8c,0x67,0x88,0x46,0x88,0x46,0x88,0x46\n.byte 0xb9,0x66,0xbd,0x86,0xb9,0x86,0xbd,0x86,0x8c,0x65,0x8c,0x65,0x8c,0x66,0x80,0x05\n.byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x26,0x84,0x25,0x88,0x46,0x88,0x46\n.byte 0x88,0x45,0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x26,0x88,0x46,0x84,0x25\n.byte 0x84,0x26,0x84,0x26,0xa0,0xe6,0xad,0x26,0x84,0x25,0x84,0x25,0xa0,0xc6,0xad,0x26\n.byte 0x84,0x25,0x84,0x26,0xa0,0xc6,0xad,0x26,0x84,0x25,0x84,0x26,0xa0,0xc6,0xa9,0x06\n.byte 0xcd,0xe6,0xf6,0xe7,0xd6,0x26,0xe6,0x86,0xcd,0xe6,0xf6,0xe7,0xb9,0x66,0xf6,0xe7\n.byte 0xcd,0xe6,0xfb,0x07,0xa0,0xe6,0xf6,0xe7,0xcd,0xe6,0xfb,0x07,0x90,0x65,0xe6,0x86\n.byte 0x80,0x05,0xda,0x26,0xda,0x46,0xee,0xc7,0x90,0x65,0xee,0xa6,0xbd,0x86,0xee,0xc7\n.byte 0xb9,0x66,0xf6,0xe7,0xa0,0xe6,0xf2,0xc7,0xee,0xc7,0xea,0xa6,0x90,0x65,0xf6,0xe7\n.byte 0xda,0x46,0x80,0x26,0x84,0x25,0x80,0x05,0xda,0x46,0x80,0x25,0x84,0x25,0x80,0x05\n.byte 0xda,0x46,0x80,0x26,0x84,0x25,0x80,0x05,0xda,0x46,0x84,0x26,0x84,0x25,0x80,0x05\n.byte 0xd2,0x06,0xff,0x47,0x9c,0xc6,0x80,0x05,0xda,0x26,0xff,0x27,0x94,0x86,0x80,0x05\n.byte 0xd2,0x06,0xff,0x47,0xa0,0xc6,0x80,0x05,0xb1,0x26,0xff,0x67,0xcd,0xe6,0x80,0x05\n.byte 0x84,0x25,0x80,0x05,0xa9,0x06,0xff,0x67,0x84,0x25,0x80,0x05,0xa0,0xe6,0xff,0x47\n.byte 0x84,0x25,0x80,0x06,0xad,0x26,0xff,0x67,0x80,0x05,0x80,0x26,0xda,0x46,0xff,0x67\n.byte 0xc5,0xc6,0x80,0x05,0x84,0x25,0x84,0x25,0xcd,0xe6,0x80,0x05,0x84,0x25,0x84,0x25\n.byte 0xc5,0xa6,0x80,0x06,0x84,0x25,0x84,0x25,0xa4,0xe6,0x80,0x26,0x84,0x25,0x84,0x25\n.byte 0x80,0x05,0xd6,0x26,0xff,0x27,0x98,0xa6,0x80,0x05,0xd6,0x26,0xff,0x27,0x98,0xa6\n.byte 0x80,0x05,0xd6,0x26,0xff,0x27,0x98,0xa6,0x80,0x05,0xd6,0x26,0xff,0x27,0x90,0x86\n.byte 0x80,0x05,0x80,0x05,0xa0,0xc6,0xff,0x47,0x80,0x05,0x80,0x25,0x9c,0xc6,0xff,0x47\n.byte 0x80,0x05,0x80,0x06,0xa9,0x06,0xff,0x67,0x80,0x05,0x84,0x26,0xda,0x46,0xff,0x67\n.byte 0xd2,0x06,0x80,0x05,0x84,0x25,0x80,0x05,0xd6,0x26,0x80,0x05,0x84,0x25,0x80,0x05\n.byte 0xc9,0xc6,0x80,0x06,0x84,0x25,0x80,0x05,0xa5,0x06,0x80,0x26,0x84,0x25,0x80,0x05\n.byte 0xad,0x26,0xff,0x47,0xe2,0x66,0xc5,0xa6,0xad,0x26,0xff,0x47,0xfb,0x07,0xf6,0xe7\n.byte 0xad,0x26,0xff,0x67,0xbd,0x86,0x84,0x25,0xad,0x26,0xff,0x67,0xb9,0x66,0x80,0x05\n.byte 0xc5,0xc6,0xc9,0xe6,0xb1,0x26,0x80,0x05,0xf6,0xe7,0xfb,0x07,0xcd,0xe6,0x80,0x05\n.byte 0x88,0x45,0x88,0x46,0x88,0x45,0x80,0x05,0x80,0x05,0x80,0x05,0x80,0x05,0x80,0x05\n.byte 0xa0,0xc6,0xb5,0x46,0x80,0x05,0x84,0x25,0xa0,0xc6,0xb5,0x46,0x80,0x05,0x84,0x25\n.byte 0xa0,0xc6,0xb5,0x46,0x80,0x05,0x84,0x25,0xa0,0xc6,0xb5,0x66,0x80,0x05,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x90,0x88,0x84,0x25,0x84,0x25,0x80,0x05,0x9c,0xea\n.byte 0x84,0x25,0x84,0x26,0x84,0x25,0xa9,0x4d,0x84,0x25,0x84,0x25,0x84,0x25,0xb5,0xaf\n.byte 0xc2,0x11,0xa9,0x4d,0x80,0x04,0xa1,0x0b,0xc2,0x11,0xad,0x6d,0x88,0x46,0xb5,0xaf\n.byte 0xb5,0xae,0xa9,0x4c,0x9c,0xea,0xb1,0x8e,0xa5,0x2c,0xad,0x6d,0xad,0x6d,0xa9,0x4c\n.byte 0xc2,0x11,0x98,0xc9,0x84,0x25,0x80,0x05,0xbd,0xf1,0x90,0x87,0x84,0x25,0x98,0xc9\n.byte 0xb5,0xaf,0x84,0x25,0x94,0xa8,0xb1,0x8e,0xb1,0x8e,0x80,0x05,0x98,0xc9,0xa9,0x4c\n.byte 0x80,0x05,0x84,0x25,0x84,0x25,0x84,0x25,0xad,0x6d,0x9c,0xea,0x88,0x46,0x80,0x05\n.byte 0xa9,0x4c,0xc2,0x11,0x90,0x87,0x90,0x88,0xa9,0x4c,0xbd,0xf0,0x88,0x46,0xb1,0x8e\n.byte 0x84,0x25,0x80,0x04,0x8c,0x67,0xb9,0xcf,0x94,0xa8,0xa9,0x4c,0xa5,0x2b,0xb9,0xcf\n.byte 0xc2,0x11,0xb1,0x8e,0xc2,0x11,0xad,0x6d,0xa5,0x2c,0x80,0x03,0xb1,0x8e,0xa1,0x0a\n.byte 0x8c,0x67,0x84,0x25,0x84,0x25,0x80,0x05,0x84,0x25,0x88,0x46,0xa5,0x2b,0xa9,0x4c\n.byte 0x80,0x05,0xb1,0x8e,0xb1,0x8e,0xb5,0xaf,0x90,0x88,0xbd,0xf0,0x9c,0xea,0x9c,0xea\n.byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x90,0x87,0x84,0x25,0x84,0x26,0x84,0x25\n.byte 0xb5,0xaf,0x84,0x25,0x88,0x46,0x84,0x25,0xa1,0x0b,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0x84,0x25,0x88,0x46,0xb9,0xcf,0xc2,0x11,0x84,0x25,0x94,0xa8,0xbd,0xf0,0x90,0x88\n.byte 0x80,0x05,0x9c,0xea,0xc2,0x11,0xa9,0x4c,0x80,0x05,0xad,0x6d,0xb9,0xcf,0xa5,0x2c\n.byte 0xc2,0x11,0xb9,0xcf,0x90,0x88,0x84,0x25,0x90,0x88,0xc2,0x11,0x98,0xc9,0x8c,0x66\n.byte 0xad,0x6d,0xb5,0xae,0x88,0x46,0x90,0x87,0xb5,0xae,0xb9,0xcf,0x88,0x46,0x88,0x46\n.byte 0x80,0x05,0x84,0x25,0x84,0x25,0x84,0x25,0xa5,0x2b,0x84,0x25,0x94,0xa8,0xa1,0x0b\n.byte 0xc2,0x11,0x8c,0x66,0xb5,0xae,0xa1,0x0b,0xb9,0xcf,0xa1,0x0b,0xb5,0xae,0x84,0x25\n.byte 0x88,0x46,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25\n.byte 0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0x84,0x25,0x84,0x26,0xa0,0xc6,0xad,0x26,0x84,0x25,0x84,0x26,0x8c,0x66,0xc1,0xa6\n.byte 0x84,0x25,0x84,0x26,0x80,0x05,0xa4,0xe6,0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x05\n.byte 0xcd,0xe6,0xff,0x27,0x8c,0x66,0xd2,0x06,0xc1,0xa6,0xda,0x46,0x84,0x25,0xa9,0x06\n.byte 0xc5,0xa6,0xa0,0xe6,0xa0,0xc6,0x9c,0xc6,0x94,0x86,0xb1,0x26,0xb5,0x46,0xb1,0x46\n.byte 0xff,0x87,0xda,0x26,0x88,0x46,0xfb,0x07,0xde,0x86,0xad,0x26,0x80,0x25,0xda,0x26\n.byte 0x9c,0xc6,0x9c,0xc6,0xa0,0xc6,0x9c,0xc6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xb1,0x46\n.byte 0xde,0x66,0x84,0x26,0x84,0x26,0x84,0x25,0xc1,0xa6,0x80,0x06,0x80,0x25,0x80,0x25\n.byte 0x9c,0xc6,0xa0,0xe6,0xa0,0xc6,0xa0,0xe6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46\n.byte 0x88,0x25,0xe2,0x67,0xff,0x67,0xd6,0x26,0x80,0x05,0x8c,0x46,0xc9,0xe6,0xf2,0xc7\n.byte 0xa0,0xe6,0xa0,0xc6,0x9c,0xa6,0xa5,0x06,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46\n.byte 0xb9,0x66,0xde,0x46,0xff,0x67,0xda,0x26,0xfb,0x07,0xf2,0xc7,0xc5,0xa6,0x84,0x25\n.byte 0xa9,0x26,0xa5,0x06,0x9c,0xa6,0xa0,0xc6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xb1,0x46\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x80,0x05,0x84,0x26,0x84,0x26,0x80,0x25\n.byte 0xa0,0xe6,0xa0,0xe6,0xa0,0xc6,0xa0,0xc6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46\n.byte 0x80,0x05,0xda,0x26,0xff,0x67,0xe2,0x66,0x80,0x05,0xbd,0x86,0xde,0x66,0xe2,0x66\n.byte 0xa0,0xe6,0xa0,0xc6,0x9c,0xc6,0x9c,0xc6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46\n.byte 0xda,0x26,0xea,0xa7,0xff,0x67,0xda,0x26,0xe6,0x86,0xe2,0x66,0xbd,0x86,0x84,0x26\n.byte 0x9c,0xc6,0x9c,0xc6,0x98,0xa5,0xa0,0xc6,0xb1,0x46,0xb1,0x46,0xb1,0x46,0xb1,0x46\n.byte 0x84,0x25,0x88,0x46,0x84,0x26,0x80,0x05,0x80,0x05,0x84,0x26,0x84,0x26,0x80,0x05\n.byte 0xa0,0xe6,0xa0,0xe6,0xa0,0xc6,0xa0,0xe6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46\n.byte 0xad,0x26,0xff,0x67,0xee,0xa7,0xda,0x26,0xa0,0xc6,0xde,0x66,0xe2,0x66,0xe6,0x86\n.byte 0xa0,0xc6,0x9c,0xc6,0x9c,0xc6,0x9c,0xc6,0xb1,0x46,0xb5,0x46,0xb1,0x46,0xb1,0x46\n.byte 0xda,0x46,0xde,0x46,0xde,0x46,0x94,0x86,0xe6,0x66,0xe6,0x86,0xe6,0x86,0x94,0xa6\n.byte 0x9c,0xc6,0x9c,0xc6,0x9c,0xc6,0xbd,0x86,0xb1,0x46,0xb5,0x46,0xb1,0x46,0x9c,0xc6\n.byte 0x9c,0xc6,0xb5,0x46,0x80,0x06,0x84,0x25,0xbd,0x86,0xa0,0xc6,0x84,0x26,0x88,0x46\n.byte 0xb5,0x66,0x80,0x25,0x84,0x25,0x84,0x25,0x80,0x05,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x8c,0x67,0xbd,0xf0,0x84,0x26,0x84,0x25,0x94,0xa8,0xad,0x6d\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0x98,0xc9,0xc2,0x11,0xa5,0x2c,0xad,0x6d,0x8c,0x67,0xb1,0x8e,0x90,0x88,0xa9,0x4c\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0xa5,0x2c,0x84,0x25,0xbd,0xf0,0x9c,0xea,0x94,0xa8,0x84,0x25,0xa9,0x4c,0xa9,0x4c\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0xa9,0x4c,0xb5,0xaf,0x84,0x25,0xb5,0xaf,0xa9,0x4c,0xa5,0x2c,0x84,0x25,0x98,0xc9\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0xa9,0x4d,0x98,0xc9,0xc2,0x11,0x90,0x88,0xb5,0xaf,0xa9,0x4c,0xad,0x6d,0x88,0x46\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25\n.byte 0x98,0xc9,0xbd,0xf0,0x94,0xa9,0x9c,0xea,0x88,0x46,0xa9,0x4c,0xb5,0xaf,0xa5,0x2c\n.byte 0x84,0x25,0x80,0x05,0x84,0x25,0x80,0x05,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25\n.byte 0x8c,0x67,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0x84,0x25,0xb9,0xd0,0xb1,0x8e,0x98,0xc9,0x88,0x46,0xb1,0x8e,0xb5,0xaf,0xb9,0xcf\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25\n.byte 0xb1,0x8e,0xb9,0xcf,0x88,0x46,0x88,0x46,0xad,0x6d,0x8c,0x67,0x84,0x25,0x80,0x05\n.byte 0x80,0x05,0x84,0x25,0x84,0x25,0x9c,0xea,0x84,0x25,0x84,0x25,0x88,0x46,0xa1,0x0a\n.byte 0xb5,0xaf,0xc2,0x11,0x98,0xc9,0x84,0x25,0xb1,0x8e,0xb1,0x8e,0x84,0x25,0x84,0x25\n.byte 0xb9,0xcf,0x90,0x87,0x84,0x25,0x84,0x25,0x94,0xa8,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0x84,0x26,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x26\n.byte 0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x26,0x88,0x46,0x88,0x46,0x84,0x25\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x80,0x04\n.byte 0x80,0x05,0xb5,0xaf,0xa9,0x6e,0x80,0x04,0x88,0x46,0xd2,0x95,0xad,0x6d,0x80,0x04\n.byte 0x98,0xc9,0xd6,0xb5,0x98,0xc9,0x80,0x04,0xa9,0x4c,0xd2,0x94,0x88,0x46,0x80,0x04\n.byte 0x80,0x05,0xb9,0xd1,0xa1,0x2c,0x80,0x05,0x90,0x87,0xda,0xd6,0xa1,0x0b,0x80,0x05\n.byte 0xa1,0x0b,0xd6,0xb5,0x90,0x88,0x84,0x25,0xb1,0x8e,0xce,0x73,0x84,0x25,0x84,0x25\n.byte 0x80,0x05,0x80,0x26,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x8c,0x67\n.byte 0x88,0x46,0x88,0x46,0x84,0x25,0xbd,0xf0,0x84,0x25,0x84,0x25,0x88,0x46,0xce,0x74\n.byte 0x80,0x05,0x80,0x05,0x80,0x05,0x80,0x05,0x8c,0x67,0x90,0x88,0x90,0x88,0x84,0x25\n.byte 0xce,0x73,0xc2,0x11,0xd6,0xb5,0xa5,0x2c,0xb1,0x8e,0x84,0x25,0xce,0x74,0xb1,0x8e\n.byte 0x80,0x05,0x80,0x26,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x25,0x80,0x04,0x84,0x26,0x84,0x25,0x84,0x25\n.byte 0x80,0x05,0x80,0x06,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x90,0x88,0x8c,0x67\n.byte 0x90,0x87,0xc6,0x32,0xd6,0xb5,0xd6,0xb5,0xc2,0x11,0xc6,0x31,0x8c,0x67,0xb5,0xaf\n.byte 0x80,0x05,0x80,0x26,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0xa5,0x2b,0x84,0x25,0x88,0x46,0x88,0x46,0xad,0x6d,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0x80,0x05,0x80,0x05,0xb5,0xb0,0xa1,0x0c,0x84,0x25,0x8c,0x67,0xd6,0xb5,0xa1,0x0a\n.byte 0x84,0x25,0x98,0xca,0xd2,0x95,0x90,0x87,0x80,0x04,0xa9,0x4c,0xca,0x53,0x84,0x26\n.byte 0x80,0x04,0x80,0x26,0x80,0x05,0x80,0x05,0x80,0x04,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x98,0xca\n.byte 0x80,0x05,0x80,0x05,0x80,0x05,0x80,0x05,0x80,0x05,0x8c,0x67,0x94,0xa8,0x84,0x26\n.byte 0xa9,0x4c,0xce,0x73,0xd2,0x94,0xc2,0x11,0xda,0xd6,0xb1,0x8e,0xb1,0x8e,0xde,0xf6\n.byte 0x80,0x05,0x80,0x05,0x80,0x05,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0x88,0x46,0x84,0x26,0x88,0x46,0x84,0x25,0x94,0xa9,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0x80,0x05,0x98,0xc9,0xca,0x53,0xca,0x53,0x80,0x04,0xb1,0x8e,0xd2,0x94,0xa5,0x2b\n.byte 0x84,0x25,0xc6,0x32,0xb9,0xcf,0x80,0x03,0x88,0x46,0xce,0x74,0xce,0x74,0xc2,0x11\n.byte 0xca,0x53,0xb9,0xcf,0x8c,0x67,0x84,0x25,0xad,0x6d,0xda,0xd6,0xa5,0x2c,0x80,0x04\n.byte 0x8c,0x67,0xd6,0xb5,0xa1,0x0b,0x84,0x25,0xd2,0x94,0xc6,0x32,0x88,0x46,0x84,0x25\n.byte 0x84,0x25,0x84,0x26,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x8c,0x67\n.byte 0x84,0x25,0x84,0x26,0x88,0x46,0xca,0x53,0x84,0x25,0x84,0x25,0x90,0x87,0xd2,0x95\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x8c,0x67,0x84,0x25,0x90,0x87,0x90,0x87\n.byte 0xad,0x6d,0x80,0x04,0xc6,0x32,0xb5,0xaf,0x98,0xc9,0x88,0x46,0xd2,0x94,0xa5,0x2b\n.byte 0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0x80,0x05,0x88,0x46,0x88,0x46,0x84,0x25,0x80,0x05,0x84,0x25,0x88,0x46,0x80,0x04\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x26,0x90,0x88,0x8c,0x67,0x94,0xa8\n.byte 0x94,0xa9,0xd6,0xb5,0xbd,0xf1,0xce,0x73,0xa9,0x4c,0xd2,0x94,0x8c,0x67,0xa1,0x0b\n.byte 0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0xca,0x52,0x88,0x46,0x88,0x46,0x88,0x46,0xd6,0xb5,0x8c,0x67,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x8c,0x67\n.byte 0x84,0x26,0x84,0x25,0xa9,0x4d,0xd2,0x94,0x80,0x05,0x98,0xc9,0xd6,0xb5,0xa1,0x0b\n.byte 0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x94,0xa8,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0xd6,0xb5,0xc6,0x32,0x8c,0x67,0x84,0x26,0x98,0xc9,0xc2,0x11,0x90,0x88,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x98,0xc9,0x84,0x25,0x84,0x25,0x84,0x25,0xb1,0x8e\n.byte 0x88,0x46,0x84,0x25,0x84,0x25,0xbd,0xf1,0x84,0x25,0x84,0x25,0x88,0x46,0xce,0x74\n.byte 0xc2,0x11,0x88,0x46,0x84,0x25,0x84,0x25,0xca,0x52,0x8c,0x67,0x90,0x88,0x84,0x25\n.byte 0xce,0x74,0xca,0x53,0xd6,0xb5,0xa5,0x2b,0xb9,0xd0,0x90,0x87,0xd2,0x94,0xad,0x6d\n.byte 0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46\n.byte 0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x26,0x80,0x04,0x84,0x25,0x84,0x26,0x84,0x25\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x04,0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x04\n.byte 0x84,0x26,0x88,0x46,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25,0x84,0x25\n.byte 0xb9,0xd0,0xca,0x52,0x80,0x04,0x80,0x05,0xb5,0xae,0xda,0xd6,0xb5,0xaf,0xc2,0x11\n.byte 0x8c,0x67,0xb1,0x8e,0xc2,0x11,0xb9,0xcf,0x84,0x25,0x80,0x05,0x80,0x05,0x80,0x05\n.byte 0xca,0x53,0xb9,0xd0,0x80,0x04,0x84,0x25,0xd6,0xb5,0x94,0xa9,0x80,0x05,0x84,0x25\n.byte 0x94,0xa8,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x26\n.byte 0x84,0x25,0x84,0x25,0x94,0xa8,0xd6,0xb5,0x84,0x25,0x80,0x05,0xa5,0x2c,0xd2,0x94\n.byte 0x84,0x25,0x84,0x25,0xa5,0x2b,0xb1,0x8d,0x88,0x46,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0x90,0x88,0x8c,0x66,0xd2,0x94,0x9c,0xea,0x84,0x25,0xa1,0x0a,0xd6,0xb5,0x8c,0x67\n.byte 0x80,0x04,0xa1,0x0b,0xb5,0xae,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0x80,0x05,0x84,0x26,0x84,0x25,0x90,0x87,0x84,0x25,0x88,0x46,0x84,0x25,0x8c,0x67\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x25\n.byte 0xd6,0xb5,0x98,0xc9,0x80,0x04,0x98,0xc9,0xd6,0xb5,0xc2,0x11,0xc2,0x11,0xca,0x53\n.byte 0xa1,0x0b,0xc2,0x11,0xb5,0xaf,0x8c,0x67,0x80,0x05,0x84,0x25,0x80,0x04,0x84,0x25\n.byte 0x8c,0x66,0x84,0x25,0x84,0x25,0x84,0x25,0x8c,0x66,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0x80,0x04,0xbd,0xf0,0xbd,0xf0,0x80,0x04,0x84,0x26,0xce,0x74,0xa9,0x4d,0x80,0x04\n.byte 0x8c,0x66,0xb9,0xd0,0x94,0xa8,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x80,0x04,0xb5,0xaf,0x84,0x25,0x88,0x46,0x80,0x05,0xb1,0x8e\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0xce,0x73,0xa5,0x2c,0xad,0x6d,0xad,0x6d,0xd6,0xb5,0xb1,0x8e,0xbd,0xf0,0xa1,0x0b\n.byte 0xb1,0x8e,0xc2,0x11,0xa9,0x4d,0x88,0x46,0x80,0x04,0x84,0x25,0x80,0x05,0x84,0x25\n.byte 0x88,0x46,0x84,0x25,0x84,0x25,0x80,0x05,0x80,0x05,0x84,0x26,0x84,0x25,0x80,0x04\n.byte 0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25\n.byte 0x94,0xa8,0xd6,0xb5,0xb9,0xcf,0xb1,0x8e,0xa9,0x4c,0xd6,0xb5,0x88,0x46,0x80,0x04\n.byte 0xa5,0x2c,0xb5,0xae,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x25\n.byte 0xa9,0x4c,0x88,0x46,0x84,0x25,0x84,0x25,0x80,0x04,0x84,0x25,0x84,0x26,0x84,0x25\n.byte 0x84,0x25,0x84,0x26,0x84,0x26,0x84,0x25,0x84,0x25,0x84,0x26,0x84,0x26,0x84,0x25\n.byte 0x84,0x25,0x80,0x05,0x9c,0xea,0xd2,0x94,0x84,0x25,0x80,0x05,0xa9,0x4c,0xda,0xd6\n.byte 0x84,0x25,0x84,0x25,0x90,0x87,0xb9,0xcf,0x84,0x25,0x84,0x26,0x84,0x25,0x80,0x04\n.byte 0x84,0x25,0x98,0xc9,0xd6,0xb5,0x90,0x88,0xb5,0xaf,0xce,0x73,0xce,0x74,0x88,0x46\n.byte 0xb5,0xaf,0xad,0x6d,0xad,0x6d,0x84,0x25,0x80,0x04,0x80,0x05,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x80,0x04,0x84,0x25,0x84,0x25,0x84,0x25,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0xb9,0xd0,0xbd,0xf0,0x80,0x03,0xb1,0x8e,0xce,0x74,0xad,0x6d,0x80,0x04,0xca,0x52\n.byte 0xb9,0xcf,0x94,0xa8,0x88,0x46,0xb5,0xaf,0x80,0x05,0x84,0x25,0x88,0x46,0x80,0x05\n.byte 0xca,0x52,0x84,0x25,0x84,0x25,0x84,0x25,0xb9,0xcf,0x80,0x04,0x88,0x46,0x84,0x25\n.byte 0x9c,0xea,0x80,0x05,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0x80,0x04,0xb5,0xaf,0xca,0x52,0x80,0x03,0x80,0x04,0xb1,0x8e,0xd6,0xb5,0xb5,0xaf\n.byte 0x84,0x25,0x8c,0x67,0xb5,0xaf,0xc2,0x11,0x84,0x25,0x84,0x25,0x84,0x25,0x80,0x05\n.byte 0x8c,0x67,0x94,0xa9,0x84,0x25,0x84,0x25,0xd2,0x94,0xad,0x6d,0x84,0x25,0x84,0x25\n.byte 0xa1,0x0b,0x84,0x25,0x88,0x46,0x84,0x25,0x80,0x05,0x84,0x25,0x88,0x46,0x88,0x46\n.byte 0x84,0x25,0x84,0x25,0x94,0xa8,0xd6,0xb5,0x84,0x25,0x80,0x04,0xa9,0x4c,0xd2,0x94\n.byte 0x84,0x25,0x80,0x05,0xa5,0x2b,0xb1,0x8e,0x88,0x46,0x84,0x26,0x84,0x26,0x84,0x25\n.byte 0x90,0x88,0x84,0x26,0xd2,0x94,0x9c,0xea,0x84,0x25,0x9c,0xea,0xd6,0xb5,0x8c,0x67\n.byte 0x80,0x04,0x9c,0xea,0xb5,0xaf,0x84,0x26,0x88,0x46,0x84,0x25,0x84,0x25,0x88,0x46\n.byte 0x80,0x05,0x84,0x25,0x88,0x46,0x84,0x25,0x84,0x25,0x84,0x25,0x88,0x46,0x84,0x25\n.byte 0x84,0x25,0x84,0x25,0x88,0x46,0x88,0x46,0x84,0x26,0x84,0x25,0x88,0x46,0x84,0x25\n#endregion\n\n#region SnapshotIcon\nSnapshotIcon:\nblrl\n.byte 0x00,0x00,0x0c,0x1c,0x13,0x17,0x06,0x06,0x00,0x06,0x54,0xbe,0x52,0x54,0x0f,0x0f\n.byte 0x00,0x0e,0x4c,0x53,0xc4,0x1a,0x4a,0x35,0x00,0x17,0x49,0xc1,0x09,0x09,0x6a,0xc5\n.byte 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0e,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x49\n.byte 0x4a,0x1a,0x1a,0x1a,0x35,0x35,0x1a,0x4e,0x6a,0x09,0x09,0x09,0x1a,0x4e,0x09,0x09\n.byte 0x1c,0x25,0x0c,0x00,0x00,0x00,0x00,0x00,0x6e,0x30,0x06,0x00,0x00,0x00,0x00,0x00\n.byte 0xc9,0x52,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x4f,0x38,0x0c,0x00,0x00,0x00,0x00\n.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\n.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\n.byte 0x00,0x17,0xbc,0xc3,0x09,0xc2,0x30,0x67,0x00,0x06,0x30,0x7a,0x4e,0x32,0x1e,0x44\n.byte 0x00,0x12,0x1b,0x47,0x6b,0x13,0x17,0x23,0x00,0x00,0xa5,0x45,0x19,0x05,0x06,0x23\n.byte 0x4a,0x09,0x09,0x6c,0x80,0x88,0x6b,0x6c,0x73,0x09,0x27,0x4d,0x32,0x1e,0x0f,0x82\n.byte 0x63,0x27,0x1f,0x4d,0x1b,0x14,0x05,0x68,0x63,0x1f,0x4b,0x47,0x1b,0x06,0x12,0x1c\n.byte 0x09,0x4f,0x1c,0x01,0x00,0x00,0x00,0x00,0x27,0x78,0x7f,0x12,0x00,0x00,0x00,0x00\n.byte 0xb3,0xad,0x34,0x14,0x00,0x00,0x00,0x00,0xa5,0x71,0x44,0x06,0x00,0x00,0x00,0x00\n.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\n.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\n.byte 0x0c,0x12,0x32,0x48,0x1c,0x12,0x06,0x23,0x00,0x00,0x12,0x38,0x0c,0x00,0x06,0x23\n.byte 0x00,0x00,0x0c,0x01,0x00,0x00,0x06,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x43\n.byte 0x45,0x4b,0x76,0x47,0x1b,0x06,0x00,0x17,0x45,0x39,0x39,0xab,0x1b,0x06,0x00,0x0c\n.byte 0xa6,0x3a,0x3a,0xae,0x1b,0x1e,0x17,0x17,0xa9,0x3b,0x3b,0x81,0x6e,0x51,0x69,0x19\n.byte 0x30,0x48,0xa2,0x14,0x00,0x00,0x00,0x00,0x25,0x25,0x12,0x00,0x00,0x00,0x00,0x00\n.byte 0x05,0x05,0x05,0x14,0x13,0x00,0x00,0x0e,0x19,0x4c,0x49,0x34,0x14,0x0c,0x13,0x51\n.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\n.byte 0x17,0x17,0x17,0x17,0x17,0x0e,0x00,0x00,0xbb,0x4c,0x19,0x19,0x69,0xa3,0x00,0x00\n.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x43\n.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0xb1,0x00,0x00,0x00,0x00,0x0c,0x14,0x1e,0x68\n.byte 0xac,0x65,0x65,0xc8,0xcd,0x84,0x73,0x53,0xb0,0x55,0x55,0xce,0x56,0x34,0xd7,0xdb\n.byte 0x5b,0x9a,0x70,0xd4,0x56,0x1d,0x51,0x58,0xc0,0xcc,0xd1,0x8c,0x87,0x28,0x72,0xdc\n.byte 0x75,0x53,0xc6,0x67,0x05,0x0c,0x25,0xca,0x09,0x09,0x50,0x19,0x17,0x0c,0x25,0x4f\n.byte 0x7d,0x09,0x4d,0x32,0x0e,0xd3,0x34,0x58,0x48,0x09,0x1f,0x58,0x38,0xd8,0xe2,0x79\n.byte 0x7d,0x50,0x75,0x50,0x79,0xa7,0x13,0x04,0x09,0x09,0x09,0x35,0xbd,0x1c,0x0a,0x00\n.byte 0x1a,0x09,0x09,0xcf,0x0b,0x2f,0x42,0x10,0x84,0x27,0x27,0x7e,0x5a,0x0d,0x0d,0x2d\n.byte 0x00,0x00,0x00,0x00,0x00,0x83,0xb7,0xb9,0x00,0x00,0x00,0x17,0x19,0xb5,0xb8,0xb6\n.byte 0x00,0x00,0x00,0x0e,0x72,0xb4,0x29,0x36,0x00,0x00,0x00,0x13,0x14,0x28,0x28,0x28\n.byte 0xbf,0x74,0x74,0xd6,0xda,0x52,0x7b,0x5d,0x37,0x37,0x37,0x37,0xd9,0xde,0x8f,0x78\n.byte 0x86,0xba,0x3c,0x89,0x3c,0x36,0x6d,0x95,0x85,0x6f,0xc7,0x6f,0xdd,0x28,0x7c,0x5f\n.byte 0xe0,0x7a,0x27,0x71,0xe1,0xe3,0x5e,0x82,0x80,0xe6,0x1f,0xe7,0x96,0x8b,0x5d,0x3f\n.byte 0x88,0x95,0x39,0x98,0x5e,0xa0,0xf6,0x9f,0xef,0x3f,0x9c,0x3a,0x5f,0x94,0x86,0x97\n.byte 0x94,0x1f,0x1f,0x7e,0xd2,0x02,0x0b,0x22,0x3f,0x76,0x4b,0x56,0x8b,0x02,0x0b,0xa8\n.byte 0x9b,0x98,0x39,0x8d,0x59,0x26,0x2e,0x15,0x5e,0x9c,0x3a,0x8d,0x59,0x0d,0x16,0x61\n.byte 0x00,0x00,0x00,0x00,0x00,0x0c,0x2d,0x2b,0x00,0x00,0x00,0x00,0x04,0x21,0x31,0x24\n.byte 0x00,0x00,0x0c,0x01,0x0c,0x0c,0x04,0x10,0x00,0x0c,0x0c,0x33,0x2b,0x2f,0x16,0x01\n.byte 0x41,0x0b,0x24,0x15,0x0a,0x38,0x5f,0x60,0x24,0x42,0x10,0x01,0x10,0x7f,0x60,0x60\n.byte 0x0a,0x10,0x04,0x10,0x1e,0x8e,0x5b,0x91,0x00,0x00,0x0a,0x64,0x33,0x3f,0xe9,0xec\n.byte 0x57,0x9f,0xfb,0x3b,0xfc,0xfe,0xf5,0x5a,0xa1,0xa1,0x99,0x9e,0x55,0xf9,0x9b,0x33\n.byte 0x83,0x1e,0xfd,0xfa,0x9a,0x5b,0x54,0x1d,0xee,0x85,0xf8,0x90,0x93,0x9d,0x31,0xf2\n.byte 0xf0,0x81,0x3b,0x29,0x57,0x22,0x2a,0x11,0xf4,0xf1,0x9e,0x99,0xe4,0x46,0x03,0x11\n.byte 0x5d,0xeb,0x9a,0x91,0x8e,0x1e,0x03,0x03,0x9d,0x8c,0x93,0x90,0x52,0xb2,0x46,0x03\n.byte 0x00,0x01,0x33,0x41,0x2c,0x16,0x04,0x00,0x0a,0x42,0x41,0x3e,0x21,0x0a,0x00,0x01\n.byte 0x21,0x2b,0x22,0x01,0x01,0x00,0x0a,0x15,0x2d,0x2d,0x0a,0x04,0x00,0x0a,0x64,0x2b\n.byte 0x04,0x0a,0xaf,0xcb,0xd0,0x77,0x92,0x92,0x01,0x31,0x26,0x57,0x5c,0x8a,0x3c,0x3c\n.byte 0x3e,0x0b,0x02,0x02,0x20,0x20,0x20,0x20,0x0b,0x02,0x02,0x02,0x02,0x02,0x02,0x02\n.byte 0xed,0x5c,0xf3,0xf7,0x3d,0x96,0xa0,0xea,0x8a,0x5c,0x59,0x89,0x8f,0x97,0xe5,0x87\n.byte 0x20,0x20,0x26,0x5a,0xdf,0x16,0xd5,0x18,0x0b,0x0d,0x2f,0x16,0x03,0x66,0x07,0x07\n.byte 0xe8,0x3d,0x3d,0x3d,0x77,0xaa,0xa4,0x1e,0x29,0x36,0x36,0x36,0x29,0x6d,0xa4,0x1e\n.byte 0x18,0x18,0x18,0x18,0x18,0x18,0x46,0x08,0x07,0x07,0x07,0x07,0x07,0x07,0x08,0x08\n.byte 0x04,0x01,0x00,0x04,0x0a,0x42,0x02,0x0b,0x00,0x00,0x04,0x13,0x31,0x0b,0x0d,0x0d\n.byte 0x00,0x00,0x04,0x22,0x2c,0x2c,0x2e,0x2e,0x00,0x00,0x00,0x13,0x15,0x21,0x21,0x15\n.byte 0x02,0x02,0x02,0x02,0x0d,0x0b,0x0b,0x2c,0x0d,0x0b,0x0b,0x0d,0x2e,0x3e,0x42,0x15\n.byte 0x2f,0x24,0x22,0x62,0x15,0x2a,0x40,0x08,0x01,0x11,0x61,0x2a,0x03,0x11,0x11,0x03\n.byte 0x24,0x62,0x03,0x40,0x07,0x08,0x07,0x07,0x40,0x40,0x07,0x08,0x08,0x07,0x07,0x07\n.byte 0x03,0x08,0x08,0x08,0x07,0x07,0x07,0x07,0x08,0x08,0x08,0x08,0x07,0x07,0x07,0x07\n.byte 0x07,0x07,0x07,0x07,0x07,0x08,0x08,0x08,0x07,0x07,0x07,0x07,0x08,0x08,0x08,0x03\n.byte 0x07,0x07,0x07,0x07,0x08,0x08,0x03,0x11,0x07,0x08,0x08,0x08,0x03,0x03,0x11,0x11\n.byte 0x84,0x25,0x84,0x25,0xa8,0x0f,0x84,0x24,0x84,0x25,0x80,0x04,0x80,0x05,0x84,0x24\n.byte 0x84,0x24,0x80,0x00,0x84,0x24,0xa8,0x30,0x84,0x25,0xa8,0x10,0x80,0x04,0x98,0xca\n.byte 0x84,0x25,0x84,0x24,0x84,0x25,0x84,0x25,0x80,0x05,0x88,0x26,0x90,0x28,0x80,0x04\n.byte 0x80,0x04,0xad,0x6e,0xb1,0x8c,0xbd,0xd0,0x8c,0x67,0x80,0x03,0x80,0x03,0x84,0x00\n.byte 0xa4,0x10,0x88,0x26,0x94,0x2a,0xa1,0x0c,0x9c,0x2c,0x88,0x46,0xa8,0x10,0x80,0x00\n.byte 0x80,0x05,0xcd,0xcf,0x84,0x24,0xa0,0x2e,0xa4,0x2f,0x8c,0x28,0xa4,0x2e,0xa0,0x0d\n.byte 0xb9,0xd0,0x98,0x2b,0xb9,0xd0,0x98,0x0c,0x98,0xc9,0xa9,0x4a,0xd1,0xd0,0xf4,0x41\n.byte 0x88,0x46,0x90,0x00,0x98,0x00,0xa4,0x00,0xd9,0xd4,0xec,0x21,0x9c,0x2c,0xc9,0xf3\n.byte 0x80,0x24,0xac,0x11,0x90,0x29,0xa1,0x0c,0xa1,0x0b,0xb9,0x6a,0x80,0x04,0x98,0x63\n.byte 0xd2,0x74,0xb1,0x8e,0xad,0x6b,0x88,0x00,0xad,0x6e,0x90,0x63,0xa5,0x29,0xbd,0xf0\n.byte 0x9c,0xe7,0xa5,0x4c,0xbd,0xf1,0x9c,0xe7,0x9c,0xea,0xb4,0x00,0xc5,0xf1,0xb4,0x92\n.byte 0xc1,0xf0,0xb0,0x72,0xac,0x31,0xd9,0x4a,0xe2,0x36,0xc5,0xf0,0xc9,0xd3,0xc5,0xae\n.byte 0xcd,0x8d,0x80,0x24,0x8c,0x27,0xb1,0x4a,0x8c,0x27,0xac,0x00,0x80,0x23,0xb5,0xaf\n.byte 0xb1,0x8f,0xa9,0x4d,0x94,0x84,0xc6,0x31,0x8c,0x42,0xda,0x32,0xca,0x53,0xa0,0x0e\n.byte 0xc4,0x00,0xb5,0x8c,0xa5,0x2c,0xad,0x6a,0xe0,0x00,0xa1,0x07,0x90,0x00,0xf5,0x4a\n.byte 0xb9,0xce,0xc2,0x0f,0x8c,0x41,0xbd,0xf1,0xbd,0xcf,0xa1,0x08,0xc5,0xf2,0x90,0x88\n.byte 0xc6,0x33,0xac,0x41,0xc6,0x11,0x8c,0xa8,0xd6,0xb5,0x8c,0x09,0xcd,0xef,0xd6,0x11\n.byte 0xa9,0x4d,0xdd,0xf5,0xdd,0xd2,0xac,0x51,0xd4,0x00,0xc9,0xd0,0x98,0xea,0xf2,0x53\n.byte 0xe0,0xc6,0xd5,0x8c,0xe8,0x20,0xd4,0x00,0xd6,0x76,0xc1,0xad,0xcd,0xb5,0xb8,0xd3\n.byte 0x98,0x20,0xd1,0xae,0xc0,0x00,0xc5,0xb3,0xa4,0x21,0xdd,0xf1,0xb0,0x00,0xc5,0x75\n.byte 0xc1,0x35,0xa8,0xaf,0x94,0xa9,0xa5,0x2c,0x9d,0x0a,0xbd,0xf0,0xbd,0x4a,0xd2,0x95\n.byte 0x94,0x29,0xc5,0x4a,0xea,0x73,0xa0,0x62,0xc9,0x4a,0xb1,0x6c,0xa8,0x63,0x90,0x08\n.byte 0xd1,0x4a,0xa1,0x2c,0x80,0x25,0xa5,0x07,0xd6,0x11,0xfa,0x72,0xf8,0x42,0xad,0x8f\n.byte 0xfd,0x6a,0xe1,0xf0,0xd1,0xf1,0xad,0x6e,0xb5,0xaf,0xb9,0xb1,0xca,0x53,0xe0,0x00\n.byte 0xdc,0xe7,0x9c,0xc6,0xb1,0x8c,0x94,0xa4,0x94,0xa5,0xb5,0xad,0xbd,0xee,0xa4,0x10\n.byte 0xb4,0x21,0x84,0x21,0xce,0x74,0xb0,0xb1,0xd0,0x00,0xe2,0xf7,0xc0,0x42,0xc5,0xf2\n.byte 0xea,0x77,0xd0,0x00,0xac,0x51,0x80,0x04,0xcc,0x42,0x84,0x04,0xdc,0x00,0xc2,0x11\n.byte 0x84,0x06,0xf4,0x20,0xe9,0x29,0x88,0x42,0xce,0x52,0x88,0x08,0xfc,0xe7,0xa4,0x70\n.byte 0xda,0xd7,0xa8,0xee,0xbd,0x52,0xa0,0x0e,0xa0,0xad,0xb9,0x31,0xad,0x08,0xa4,0xc5\n.byte 0xf0,0xa5,0xdc,0x83,0xf6,0x74,0xc8,0x21,0xe1,0x28,0xf5,0xce,0xb5,0x92,0x9c,0xcc\n.byte 0xd1,0xd4,0xbc,0x21,0x98,0xad,0xb9,0x35,0xcd,0xd3,0xd1,0xd2,0xca,0x0f,0xed,0x8c\n.byte 0xc1,0x92,0xc9,0x07,0xc8,0x21,0xc1,0x07,0xbd,0x08,0xce,0x10,0xe2,0xb4,0xcd,0xae\n#endregion\n\n#endregion\n\n#region LoadCredits\nLoadCredits:\nbackup\n\n#Load Minor Scene 0x1\n\tload\tr4,SceneController\n\tli\tr3,0x1\n\tstb\tr3,0x4(r4)\n\n#Change Screen\n\tli\tr3,0x1\n\tstw\tr3,0x34(r4)\n\n#Make Previous Major Event CSS So It Returns to Event SS\n\tload\tr4,SceneController\n\tli\tr3,0x2B\n\tstb\tr3,0x2(r4)\n\n#BACKUP CURRENT EVENT ID\n\tlwz\tr3, -0x4A40 (r13)\n\tlwz\tr5, 0x002C (r3)\n\tlbz\tr3,0x0(r5)\n\tlwz\tr4,0x4(r5)\n\tadd\tr3,r3,r4\n\tlwz\tr4, -0x77C0 (r13)\n\tstb\tr3, 0x0535 (r4)\n\n#Return To Event SS\n\t#load\tr4,0x804d68b8\n\t#li\tr3,0x7\n\t#stb\tr3,0x0(r4)\n\t#li\tr3,0x2B\n\t#stb\tr3,0x4(r4)\n\n#Overwrite SceneDecide Function So It Doesn't Change Majors\n\tbl\tTempSceneDecide\n\tmflr\tr3\n\tload\tr4,0x803dae44\t\t#Main Menu's Minor Table Pointer\n\tlwz\tr4,0x0(r4)\n\tstw\tr3,0x8(r4)\t\t#Overwrite MainMenu's SceneDecide Temporarily\n\n#Init Name Count Variable\n\tli\tr3,0x0\n\tstw\tr3, -0x4eac (r13)\n\n#Exit\n\trestore\n\tblr\n#endregion\n\n#region PlayMovie\nPlayMovie:\n\t\t#Get Events Tutorial\n\t\t\tlwz r3,MemcardData(r13)\n\t\t\tlbz r3,CurrentEventPage(r3)\n\t\t\tlwz\tr4, -0x77C0 (r13)\n\t\t\tlbz\tr4, 0x0535 (r4)\n\t\t\trtocbl r12,TM_GetEventTut\n\t\t\tmr\tr20,r3\t\t\t\t\t#Get Event's Tutorial File Name in r20\n\n\t\t\t#Get Extension Pointer in r21\n\t\t\tbl\tFileSuffixes\n\t\t\tmflr\tr21\n\n\t\t##############################\n\t\t## Play Movie's Audio Track ##\n\t\t##############################\n\n\t\t\t#Copy To Temp Audio String Space\n\t\t\tload\tr22,0x803bb380\t\t#Temp Audio String Space\n\t\t\taddi\tr3,r22,0x7\t\t#After the /audio/\n\t\t\tmr\tr4,r20\t\t#Movie FileName\n\t\t\tbranchl\tr12,0x80325a50\t\t#strcpy\n\n\t\t\t#Get Length of This String Now\n\t\t\tmr\tr3,r22\n\t\t\tbranchl\tr12,0x80325b04\n\n\t\t\t#Copy .hps to the end of it\n\t\t\tadd\tr3,r3,r22\t\t#Dest\n\t\t\tmr\tr4,r21\t\t#.hps string\n\t\t\tbranchl\tr12,0x80325a50\n\n\t\t\t#Check If File Exists\n\t\t\tmr\tr3,r22\n\t\t\tbranchl\tr12,0x8033796c\n\t\t\tcmpwi\tr3,-1\n\t\t\tbeq\tFileNotFound\n\n\t\t\t#Load Song File\n\t\t\tLoadSongFile:\n\t\t\tmr\tr3,r22\t\t#Full Song File Name\n\t\t\tli\tr4,127\t\t#Volume?\n\t\t\tli\tr5,1\t\t#Unk\n\t\t\tbranchl\tr12,0x80023ed4\n\n\n\t\t#####################\n\t\t## Load Movie File ##\n\t\t#####################\n\n\t\tStartLoadMovieFile:\n\n\t\t\t#Copy File Name To Temp Space\n\t\t\tload\tr22,0x80432058\t\t#Temp File Name Space\n\t\t\tmr\tr3,r22\t\t#Destination\n\t\t\tmr\tr4,r20\t\t#Movie FileName\n\t\t\tbranchl\tr12,0x80325a50\t\t#strcpy\n\n\t\t\t#Get Length of This String Now\n\t\t\tmr\tr3,r22\t\t#Destination\n\t\t\tbranchl\tr12,0x80325b04\n\n\t\t\t#Copy .mth Suffix\n\t\t\tadd\tr3,r3,r22\t\t#Dest\n\t\t\taddi\tr4,r21,0x8\t\t#.mth string\n\t\t\tbranchl\tr12,0x80325a50\n\n\t\t\t#Check If File Exists\n\t\t\tmr\tr3,r22\n\t\t\tbranchl\tr12,0x8033796c\n\t\t\tcmpwi\tr3,-1\n\t\t\tbeq\tFileNotFound\n\n\t\t\t#PLAY SFX\n\t\t\tli\tr3, 1\n\t\t\tbranchl\tr4,0x80024030\n\n\t\t\t#Unk Set\n\t\t\tli\tr3,0x1\n\t\t\tbranchl\tr12,0x80024e50\n\n\t\t\t#Load Movie File\n\t\t\tmr\tr3,r22\t\t\t\t\t\t\t\t#File Name\n\t\t\tbl\tFramerateDefinition\n\t\t\tmflr r4\t\t\t\t\t\t\t\t\t\t#0x803dbfb4 = opening movie fps define\n\t\t\tli\tr5,0\t\t\t\t\t\t\t\t\t#lwz\tr5, -0x4A14 (r13)\n\t\t\tload\tr6,0x00271000\t\t\t\t#li\tr6,0\t\t#Frame Buffer Heap Size?\n\t\t\tli\tr7,0\n\t\t\tbranchl\tr12,0x8001f410\n\n\t\t#Set Framerate\n\t\t\tload r3,0x804333e0\n\t\t\tlwz r3,0x18(r3)\t\t\t\t\t\t#get framerate from mth header\n\t\t\tli\tr4,60\n\t\t\tdivw r3,r4,r3\t\t\t\t\t\t\t#decide how many in game frames per movie frame\n\t\t\tbl\tFramerateDefinition\n\t\t\tmflr r4\n\t\t\tstw r3,0x4(r4)\t\t\t\t\t\t#update fps\n\n\t\t\t#Unk Unset\n\t\t\tli\tr3,0x0\n\t\t\tbranchl\tr12,0x80024e50\n\n\n\n\t#Create And Schedule Custom Movie Think Functions\n\n\t\t#Create Camera Think Entity\n\t\t\tli\tr3, 13\n\t\t\tli\tr4,14\n\t\t\tli\tr5,0\n\t\t\tbranchl\tr12,0x803901f0\n\t\t#Attach Camera Think\n\t\t\tmr\tr31,r3\n\t\t\tli\tr4,640\n\t\t\tli\tr5,480\n\t\t\tli\tr6,8\n\t\t\tli\tr7,0\n\t\t\tbranchl\tr12,0x801a9dd0\n\t\t\tli\tr0,0x800\n\t\t\tstw\tr0,0x24(r31)\n\t\t\tli\tr0,0x0\n\t\t\tstw\tr0,0x20(r31)\n\n\t\t#Create Movie Display Entity\n\t\t\tli\tr3, 14\n\t\t\tli\tr4,15\n\t\t\tli\tr5,0\n\t\t\tbranchl\tr12,0x803901f0\n\t\t\tmr\tr30,r3\n\t\t\tstw\tr3, -0x4E48 (r13)\n\t\t\tlbz\tr4, -0x3D40 (r13)\n\t\t\tli\tr5, 0\n\t\t\tbranchl\tr12,0x80390a70\n\t\t#Attach Display Process\n\t\t\tmr\tr3,r30\n\t\t\tload\tr4,0x8001f67c\n\t\t\tli\tr5,11\n\t\t\tli\tr6,0\n\t\t\tbranchl\tr12,0x8039069c\n\n\t\t#Change Screen Size to Fullscreen\n\t\t\tmr\tr3,r30\n\t\t\tli\tr4,640\n\t\t\tli\tr5,480\n\t\t\tbranchl\tr12,0x8001f624\n\t\t\tlfs\tf0, -0x3680 (rtoc)\n\t\t\tstfs\tf0, 0x0010 (r3)\n\t\t\tstfs\tf0, 0x0014 (r3)\n\n\n\n\t\t#Create Movie Think Entity\n\t\t\tli\tr3, 6\n\t\t\tli\tr4,7\n\t\t\tli\tr5,128\n\t\t\tbranchl\tr12,0x803901f0\n\t\t\tmr\tr29,r3\n\t\t#Alloc 10 Bytes\n\t\t\tli\tr3,10\n\t\t\tbranchl\tr12,0x8037f1e4\n\t\t#Initliaze Entity\n\t\t\tmr\tr6,r3\n\t\t\tmr\tr3,r29\n\t\t\tli\tr4,0x0\n\t\t\tload\tr5,0x8037f1b0\n\t\t\tbranchl\tr12,0x80390b68\n\t\t#Schedule Think\n\t\t\tmr\tr3,r29\n\t\t\tbl\tMovieThink\n\t\t\tmflr\tr4\n\t\t\tli\tr5,0x0\n\t\t\tbranchl\tr12,0x8038fd54\n\t\t#Store Display Entity and Camera Entity to the Think Entity\n\t\t\tlwz\tr3,0x2C(r29)\t\t#Think's Data\n\t\t\tstw\tr31,0x0(r3)\t\t#Camera Entity\n\t\t\tstw\tr30,0x4(r3)\t\t#Display Entity\n\n\t\t#REMOVE EVENT THINK FUNCTION\n\t\t\tlwz\tr3, -0x3E84 (r13)\n\t\t\tbranchl\tr12,0x80390228\n\n\tb\texit\n#endregion\n#######################################\nFramerateDefinition:\nblrl\n#This structure is passed through via r4 to the MTH play function\n#It contains variable framerate information\n\n#Structure is\n# 0x0 = number of frames to use the following fps for\n# 0x4 = in game frames per movie frame\n.long 1048576\n.long 2\n#######################################\n\nFileNotFound:\n\n\t#PLAY SFX\n\tli\tr3, 3\n\tbranchl\tr4,0x80024030\n\n\tb\texit\n\n#######################################\n\nTempSceneDecide:\nblrl\n\n#Store Back\nload\tr3,0x801b138c\t\t#Function Address\nload\tr4,0x803dae44\t\t#Main Menu's Minor Table Pointer\nlwz\tr4,0x0(r4)\nstw\tr3,0x8(r4)\t\t#Overwrite MainMenu's SceneDecide\n\nblr\n\n#######################################\n\nMovieThink:\nblrl\n\nbackup\n\n#Backup Entity Pointer\n\tmr\tr31,r3\n\tlwz\tr30,0x2C(r3)\n\n#Advance Frame\n\tbranchl\tr12,0x8001f578\n\n#Check If Movie Is Over\n\tbranchl\tr12,0x8001f604\n\tcmpwi\tr3,0x0\n\tbne\tEndMovie\n\n#Check For Button Press\n\tli\tr3, 4\n\tbranchl\tr12,0x801a36a0\t\t#All Players Inputs\n\tandi.\tr4,r4,0x1100\n\tbeq\tExit\n#PLAY SFX\n\tli\tr3, 1\n\tbranchl\tr4,0x80024030\n\tb\tEndMovie\n\nrestore\nblr\n\n\nEndMovie:\n#Stop Music\n\tbranchl\tr12,0x800236dc\n#Remove Camera Think Function\n\tlwz\tr3,0x0(r30)\t\t#Camera Entity\n\tbranchl\tr12,0x80390228\n#Remove Display Process Function\n\tlwz\tr3,0x4(r30)\t\t#Display Entity\n\tbranchl\tr12,0x80390228\n#Remove This Think Function\n\tmr\tr3,r31\n\tbranchl\tr12,0x80390228\n#Unload Movie\n\tbranchl\tr12,0x8001f800\n#Play Menu Music\n\tlwz\tr3, -0x77C0 (r13)\n\tlbz\tr3, 0x1851 (r3)\n\tbranchl\tr12,0x80023f28\n#Reload Event Match Think\n\tli\tr3, 0\n\tli\tr4, 1\n\tli\tr5, 128\n\tbranchl\tr12,0x803901f0\n\tload\tr4,0x8024d864\n\tli\tr5,0\n\tbranchl\tr12,0x8038fd54\n\nExit:\nrestore\nblr\n\nFileSuffixes:\nblrl\n\n#.hps\n.string \".hps\"\n.align 2\n\n#.mth\n.string \".mth\"\n.align 2\n\n#######################################\n*/\n\nSwitchPage:\n#Get number of pages\n\trtocbl\tr12,TM_GetPageNum\n\tmr\tr6,r3\n#Change page\n\tlwz r4,MemcardData(r13)\n\tlbz r3,CurrentEventPage(r4)\n\tadd\tr3,r3,r5\n\tstb r3,CurrentEventPage(r4)\n#Check if within page bounds\nSwitchPage_CheckHigh:\n\tcmpw r3,r6\n\tble SwitchPage_CheckLow\n#Stay on current page\n\tsubi r3,r3,1\n\tstb r3,CurrentEventPage(r4)\n\tb\texit\nSwitchPage_CheckLow:\n\tcmpwi r3,0\n\tbge SwitchPage_ChangePage\n#Stay on current page\n\tli\tr3,0\n\tstb r3,CurrentEventPage(r4)\n\tb\texit\n\nSwitchPage_ChangePage:\n#Get Page Name string\n\tlwz r3,MemcardData(r13)\n\tlbz r3,CurrentEventPage(r3)\n\trtocbl r12,TM_GetPageName\n#Update Page Name\n\tmr\tr5,r3\n\tlwz r3,-0x4EB4(r13)\n\tli\tr4,0\n\tbranchl r12,Text_UpdateSubtextContents\n\n#Reset cursor to 0,0\n\tlwz\tr5, -0x4A40 (r13)\n\tlwz\tr5, 0x002C (r5)\n\tli\tr3,0\n\tstw\tr3, 0x0004 (r5)\t\t #Selection Number\n\tstb\tr3, 0 (r5)\t\t  \t #Page Number\n\n#Redraw Event Text\nSwitchPage_DrawEventTextInit:\n\tli\tr29,0\t\t\t\t\t\t\t#loop count\n\tlwz\tr3, 0x0004 (r5)\t\t #Selection Number\n\tlbz\tr4, 0 (r5)\t\t  \t #Page Number\n\tadd r28,r3,r4\nSwitchPage_DrawEventTextLoop:\n\tmr\tr3,r29\n\tadd\tr4,r29,r28\n\tbranchl r12,0x8024d15c\n\taddi r29,r29,1\n\tcmpwi r29,9\n\tblt SwitchPage_DrawEventTextLoop\n\n#Redraw Event Description\n\tlwz\tr3, -0x4A40 (r13)\n\tmr\tr4,r28\n\tbranchl r12,0x8024d7e0\n\n#Update High Score\n\tlwz\tr3, -0x4A40 (r13)\n\tli\tr4,0\n\tbranchl r12,0x8024d5b0\n\n#Update cursor position\n#Get Texture Data\n\tlwz\tr3, -0x4A40 (r13)\n\tlwz\tr3, 0x0028 (r3)\n\taddi r4,sp,0x40\n\tli\tr5,11\n\tli\tr6,-1\n\tcrclr\t6\n\tbranchl r12,0x80011e24\n\tlwz r3,0x40(sp)\n#Change Y offset?\n\tli\tr0,0\n\tstw r0,0x3C(r3)\n#DirtySub\n\tbranchl r12,0x803732e8\n\n#Play SFX\n\tli\tr3,2\n\tbranchl r12,SFX_MenuCommonSound\n\n#######################################\n\nexit:\nrestore\nli\tr0, 16\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event High Scores/Load Event High Scores.asm",
    "content": "#To be inserted at 8015cf60\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n#r3 = event\n#r4 = event score pointer\n\n.set REG_EventID,3\n.set REG_EventScorePointer,4\n.set REG_PageID,5\n.set REG_HighScoreTable,6\n\nbackup\n\n#Get page ID\n  lbz REG_PageID,CurrentEventPage(REG_EventScorePointer)\n#Get event's score offset using table\n  bl  EventHighScores\n  mflr REG_HighScoreTable\n  lbzx REG_PageID,REG_PageID,REG_HighScoreTable\n#Multiply and add to score pointer\n  mulli REG_PageID,REG_PageID,4\n  add REG_EventScorePointer,REG_PageID,REG_EventScorePointer\n#Now this events offset\n  mulli REG_EventID,REG_EventID,4\n  add REG_EventScorePointer,REG_EventID,REG_EventScorePointer\n#Load score\n  lwz\tr3, 0x1A70 (REG_EventScorePointer)\n  b Exit\n\nEventHighScores\n\nExit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event High Scores/Save Event High Scores.asm",
    "content": "#To be inserted at 8015cf74\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n#r3 = event\n#r4 = score\n#r5 = event score pointer\n\n.set REG_EventID,3\n.set REG_EventScore,4\n.set REG_EventScorePointer,5\n.set REG_PageID,6\n.set REG_HighScoreTable,7\n\nbackup\n\n#Get page ID\n  lbz REG_PageID,CurrentEventPage(REG_EventScorePointer)\n#Get event's score offset using table\n  bl  EventHighScores\n  mflr REG_HighScoreTable\n  lbzx REG_PageID,REG_PageID,REG_HighScoreTable\n#Multiply and add to score pointer\n  mulli REG_PageID,REG_PageID,4\n  add REG_EventScorePointer,REG_PageID,REG_EventScorePointer\n#Now this events offset\n  mulli REG_EventID,REG_EventID,4\n  add REG_EventScorePointer,REG_EventID,REG_EventScorePointer\n#Save score\n  stw\tREG_EventScore, 0x1A70 (REG_EventScorePointer)\n  b Exit\n\nEventHighScores\n\nExit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/CannotScrollPastEventsOnPage.asm",
    "content": "#To be inserted at 8024dec8\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set PageID,31\n\n#Get number of events on this page\n\tlwz r3,MemcardData(r13)\n\tlbz r3,CurrentEventPage(r3)\n  rtocbl r12,TM_GetPageEventNum\n\n#Get current event\n  lbz\tr4, 0 (r28)\n\n#If on the last event, dont scroll down\n  cmpw r4,r3\n  blt Exit\n\n#Exit EventThink\n  branch r12,0x8024e198\n\nExit:\n  lbz\tr0, 0 (r28)\n  cmplwi\tr0, 8\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/Custom Event Highscore Types.asm",
    "content": "#To be inserted at 801beb8c\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set EventID,31\n.set PageID,30\n\n.set KO,0x0\n.set Time,0x1\n\nbackup\n\n#Backup Requested Event\n  mr EventID,r3\n\n#Get Current Page\n  lwz r3,MemcardData(r13)\n  lbz PageID,CurrentEventPage(r3)\n  bl  SkipPageList\n\n##### Page List #######\n  EventJumpTable\n#######################\n\nMinigames:\n.byte KO\n.byte KO\n.byte KO\n.byte Time\n.align 2\n\nGeneralTech:\n.byte KO\n.byte KO\n.byte KO\n.byte KO\n.byte KO\n.byte KO\n.byte KO\n.byte KO\n.byte KO\n.byte KO\n.byte KO\n.byte KO\n.byte KO\n.align 2\n\nSpacieTech:\n.byte KO\n.byte KO\n.byte KO\n.byte KO\n.align 2\n##########################\n\nSkipPageList:\n  mflr\tr4\t\t#Jump Table Start in r4\n  mulli\tr5,PageID,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n  add\tr4,r4,r5\t\t#Gets ASCII Address in r4\n#Get Byte\n  lbzx\tr3,EventID,r4\n\nexit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/Display Custom Event Descriptions.asm",
    "content": "#To be inserted at 8024d80c\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set HeaderLength,0xB\n\n.set EventID,30\n\n#Get Event ID\n  lbz\tr3,0x0(r31)\n  lwz\tr4,0x4(r31)\n  add\tr4,r3,r4\n#Get page number\n  lwz r3,MemcardData(r13)\n  lbz r3,CurrentEventPage(r3)\n#Get Event Description ASCII\n  rtocbl r12,TM_GetEventDesc\n\nCustomEvent:\n.set text,24\n.set ascii,23\n\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x200(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n\n#Backup ASCII\n  mr  ascii,r3\n\n#Create Text\n  li  r3,0\n  li  r4,0\n  branchl r12,0x803a6754\n  mr  text,r3\n#Store pointer to text so it can be removed by the game\n  stw text,0x78(r31)\n#Set Text Values\n  lfs\tf1, -0x384C (rtoc)\n  lfs\tf2, -0x3848 (rtoc)\n  lfs\tf3, -0x3874 (rtoc)\n  lfs\tf4, -0x386C (rtoc)\n  lfs\tf5, -0x3868 (rtoc)\n  stfs f1,0x00(text)\n  stfs f2,0x04(text)\n  stfs f3,0x08(text)\n  stfs f4,0x0C(text)\n  stfs f5,0x10(text)\n  lfs\t  f0, -0x3844 (rtoc)\n  stfs\tf0, 0x0024 (text)\n  stfs\tf0, 0x0028 (text)\n\n#Convert To Menu Text\n  mr  r4,ascii               #ASCII To Store\n  addi r3,sp,0x40\n  branchl r12,0x803a67ec\n#Backup Length\n  mr r20,r3\n\n#Get Allocation Info Pointer\n  lwz r21,0x64(text)\n#Check To Adjust Allocation\n  lwz\tr22, 0x0004 (r21)     #Get old menu text allocation\n  lwz\tr0, 0 (r21)\n  lwz\tr4, 0x0008 (r21)      #Get size of allocation\n  sub\tr3, r0, r22\n  addi\tr0, r3, 17\n  add\tr0, r20, r0\n  cmplw\tr4, r0\n  bge-\t NoAdjustAllocation\n  sub\tr0, r0, r4\n  rlwinm\tr3, r0, 25, 7, 31\n  addi\tr0, r3, 1\n  rlwinm\tr0, r0, 7, 0, 24\n  add\tr0, r4, r0\n  stw\tr0, 0x0008 (r21)\n  lwz\tr3, 0x0008 (r21)\n  branchl r12,0x803A5798\n  addi\tr5, r22, 0\n  addi\tr4, r3, 0\n  li\tr7, 0\n  b\t\tReAllocateLoop_Inc\nReAllocateLoop:\n  lbz\tr0, 0 (r5)\n  addi\tr7, r7, 1\n  addi\tr5, r5, 1\n  stb\tr0, 0 (r4)\n  addi\tr4, r4, 1\nReAllocateLoop_Inc:\n  lwz\tr6, 0x0004 (r21)\n  lwz\tr0, 0 (r21)\n  sub\tr6, r0, r6\n  addi\tr0, r6, 1\n  cmpw\tr7, r0\n  blt+\tReAllocateLoop\n  stw\tr3, 0x0004 (r21)\n  stw\tr3, 0x005C (text)\n  lwz\tr0, 0 (r21)\n  sub\tr0, r0, r22\n  add\tr0, r3, r0\n  stw\tr0, 0 (r21)\n  mr\tr3, r22\n  branchl r12,0x803A594C\nNoAdjustAllocation:\n\n#Copy Header to Text Allocation\n  lwz r3,0x5C(text)       #Get Pointer to Next Available Menu Text Location\n  bl  DescriptionHeader\n  mflr  r4\n  li  r5,HeaderLength\n  branchl r12,0x800031f4\n\n#Copy Text to Text Allocation\n  mr  r5,r20               #Length\n  lwz r3,0x5C(text)       #Get Pointer to Next Available Menu Text Location\n  addi r3,r3,HeaderLength         #Skip Past Header\n  addi r4,sp,0x40\n  branchl r12,0x800031f4\n\n#Add Terminator\n  li  r3,0x1900\n  lwz r4,0x5C(text)\n  addi r4,r4,HeaderLength   #Skip Header Length\n  add r4,r4,r20             #Skip Text Length\n  sth r3,0x0(r4)\n\nExit:\n  lmw  r20,0x8(r1)\n  lwz r0, 0x204(r1)\n  addi\tr1,r1,0x200\t# release the space\n  mtlr r0\n  branch\tr12,0x8024d84c\n\nDescriptionHeader:\nblrl\n.long 0x160caaaa\n.long 0xaa0e00b3\n.long 0x00b31800\n\nVanillaEvent:\n  rlwinm\tr3, r30, 1, 0, 30\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/Display Custom Event Names on ESS.asm",
    "content": "#To be inserted at 8024d470\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n#r24 = text struct\n#r27 = Event ID\n\nCustomEvent:\n.set text,24\n\n#Create Text\n  li  r3,0\n  li  r4,0\n  branchl r12,0x803a6754\n  mr  text,r3\n\n#Store pointer to text so it can be removed by the game\n  stw text,0x0(r23)\n\n#Set Text Values\n  lfs\tf1, 0x0030 (r31)\n  lfs\tf4, 0x007C (sp)\n  fadds\tf1,f4,f1\n  lfs\tf0, 0x0034 (r31)\n  fadds\tf2,f31,f0\n  lfs\tf3, -0x3874 (rtoc)\n  lfs\tf4, -0x386C (rtoc)\n  lfs\tf5, -0x3868 (rtoc)\n  stfs f1,0x00(text)\n  stfs f2,0x04(text)\n  stfs f3,0x08(text)\n  stfs f4,0x0C(text)\n  stfs f5,0x10(text)\n  lfs\tf0, -0x3878 (rtoc)\n  stfs\tf0, 0x0024 (text)\n  stfs\tf0, 0x0028 (text)\n  li r3,1\n  stb r3,0x48(text)\n  li r3,1\n  stb r3,0x49(text)\n\nbackup\n\n#Get Event Name\n  lwz r3,MemcardData(r13)\n  lbz r3,CurrentEventPage(r3)\n  mr r4,r27\n  rtocbl r12,TM_GetEventName\n\n# Add subtext\n  mr r4,r3\n  mr r3,text\n  lfs\tf1, -0x3870 (rtoc)\n  lfs\tf2, -0x3870 (rtoc)\n  branchl r12,0x803a6b98\n\n# Get event file\n  lwz r3,MemcardData(r13)\n  lbz r3,CurrentEventPage(r3)\n  mr r4,r27\n  rtocbl r12,TM_GetEventFile\n  cmpwi r3,0\n  bne HasFile\nNoFile:\n# Change color\n  mr r3,text\n  li r4,0\n  bl Color\n  mflr r5\n  branchl r12,0x803a74f0\n\nHasFile:\n\n#Exit\n  restore\n  branch r12,0x8024d4c8\n\nColor:\nblrl\n.byte 180, 180, 180, 255\n\n\nVanillaEvent:\nOriginal:\n  lfs\tf0, 0x0034 (r31)\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/Get Custom Event Description.asm",
    "content": "#To be inserted at 80005528\n.include \"../../../Globals.s\"\n\n.set EventID,31\n.set PageID,30\n\nbackup\n\n#Backup Requested Event\n  mr EventID,r3\n\n#Get Current Page\n  lwz r3,MemcardData(r13)\n  lbz PageID,CurrentEventPage(r3)\n  bl  SkipPageList\n\n##### Page List #######\n\tEventJumpTable\n#######################\n  EventDescriptionStrings\n#######################\n\nSkipPageList:\n  mflr\tr4\t\t#Jump Table Start in r4\n  mulli\tr5,PageID,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n#Get String\n  mr  r3,EventID\n  add\tr4,r4,r5\t\t#Gets ASCII Address in r4\n  branchl r12,SearchStringTable\n\nExit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/Get Custom Event Description.s",
    "content": "#To be inserted at 80005528\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set EventID,31\n.set PageID,30\n\nbackup\n\n#Backup Requested Event\n  mr EventID,r3\n\n#Get Current Page\n  lwz r3,MemcardData(r13)\n  lbz PageID,CurrentEventPage(r3)\n  bl  SkipPageList\n\n##### Page List #######\n\tEventJumpTable\n#######################\n  EventDescriptionStrings\n#######################\n\nSkipPageList:\n  mflr\tr4\t\t#Jump Table Start in r4\n  mulli\tr5,PageID,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n#Get String\n  mr  r3,EventID\n  add\tr4,r4,r5\t\t#Gets ASCII Address in r4\n  branchl r12,SearchStringTable\n\nExit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/Get Custom Event Name.asm",
    "content": "#To be inserted at 80005524\n.include \"../../../Globals.s\"\n\n.set EventID,31\n.set PageID,30\n\nbackup\n\n#Backup Requested Event\n  mr EventID,r3\n\n#Get Current Page\n  lwz r3,MemcardData(r13)\n  lbz PageID,CurrentEventPage(r3)\n  bl  SkipPageList\n\n##### Page List #######\n\tEventJumpTable\n#######################\n  EventNameStrings\n#######################\nSkipPageList:\n  mflr\tr4\t\t#Jump Table Start in r4\n  mulli\tr5,PageID,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n#Get String\n  mr  r3,EventID\n  add\tr4,r4,r5\t\t#Gets ASCII Address in r4\n  branchl r12,SearchStringTable\n\n\n#######################\n\nExit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/Get Custom Event Name.s",
    "content": "#To be inserted at 80005524\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set EventID,31\n.set PageID,30\n\nbackup\n\n#Backup Requested Event\n  mr EventID,r3\n\n#Get Current Page\n  lwz r3,MemcardData(r13)\n  lbz PageID,CurrentEventPage(r3)\n  bl  SkipPageList\n\n##### Page List #######\n\tEventJumpTable\n#######################\n  EventNameStrings\n#######################\nSkipPageList:\n  mflr\tr4\t\t#Jump Table Start in r4\n  mulli\tr5,PageID,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n#Get String\n  mr  r3,EventID\n  add\tr4,r4,r5\t\t#Gets ASCII Address in r4\n  branchl r12,SearchStringTable\n\n\n#######################\n\nExit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/Get Custom Event Page Name.asm",
    "content": "#To be inserted at 8000552c\n.include \"../../../Globals.s\"\n\n.set PageID,31\n\nbackup\n\nmr PageID,r3\n\n#Get Events Text\n  bl\tSkipJumpTable\n\n##### Page List #######\n  EventJumpTable\n#######################\n\nSkipJumpTable:\n  mflr\tr4\t\t#Jump Table Start in r4\n  mulli\tr5,PageID,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n  add\tr3,r4,r5\t\t#Gets ASCII Address in r4\n  b Exit\n\nMinigames:\n.string \"Minigames\"\n.align 2\n\nGeneralTech:\n.string \"Universal Tech\"\n.align 2\n\nSpacieTech:\n.string \"Spacie Tech\"\n.align 2\n\nExit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/Get Custom Event Page Name.s",
    "content": "#To be inserted at 8000552c\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set PageID,31\n\nbackup\n\nmr PageID,r3\n\n#Get Events Text\n  bl\tSkipJumpTable\n\n##### Page List #######\n  EventJumpTable\n#######################\n\nSkipJumpTable:\n  mflr\tr4\t\t#Jump Table Start in r4\n  mulli\tr5,PageID,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n  add\tr3,r4,r5\t\t#Gets ASCII Address in r4\n  b Exit\n\nMinigames:\n.string \"Minigames\"\n.align 2\n\nGeneralTech:\n.string \"Universal Tech\"\n.align 2\n\nSpacieTech:\n.string \"Spacie Tech\"\n.align 2\n\nExit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/GetNumOfEventsOnCurrentPage.asm",
    "content": "#To be inserted at 80005534\n.include \"../../../Globals.s\"\n\n.set EventID,31\n.set PageID,30\n\nbackup\n\n#Backup Requested Event\n  mr EventID,r3\n\n#Get Current Page\n  lwz r3,MemcardData(r13)\n  lbz PageID,CurrentEventPage(r3)\n#Get pointer page's string array\n\tbl\tSkipJumpTable\n\n##### Page List #######\n\tEventJumpTable\n#######################\n\nSkipJumpTable:\n  mflr\tr4\t\t#Jump Table Start in r4\n  mulli\tr5,PageID,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n  add\tr5,r4,r5\t\t#Gets Address in r4\n  lwz r3,0x0(r5)\nb exit\n\nMinigames:\n.long Minigames.NumOfEvents\n.align 2\nGeneralTech:\n.long GeneralTech.NumOfEvents\n.align 2\nSpacieTech:\n.long SpacieTech.NumOfEvents\n.align 2\n\nexit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/GetNumOfEventsOnCurrentPage.s",
    "content": "#To be inserted at 80005534\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set EventID,31\n.set PageID,30\n\nbackup\n\n#Backup Requested Event\n  mr EventID,r3\n\n#Get Current Page\n  lwz r3,MemcardData(r13)\n  lbz PageID,CurrentEventPage(r3)\n#Get pointer page's string array\n\tbl\tSkipJumpTable\n\n##### Page List #######\n\tEventJumpTable\n#######################\n\nSkipJumpTable:\n  mflr\tr4\t\t#Jump Table Start in r4\n  mulli\tr5,PageID,0x4\t\t#Each Pointer is 0x4 Long\n  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n  add\tr5,r4,r5\t\t#Gets Address in r4\n  lwz r3,0x0(r5)\nb exit\n\nMinigames:\n.long Minigames.NumOfEvents\n.align 2\nGeneralTech:\n.long GeneralTech.NumOfEvents\n.align 2\nSpacieTech:\n.long SpacieTech.NumOfEvents\n.align 2\n\nexit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/Never Scroll If Less than 9 Events on Page.asm",
    "content": "#To be inserted at 8024e438\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n#Original Codeline\n  addi\tr30, r3, 0\n\n#First check if page has 9 events\n\tlwz r3,MemcardData(r13)\n\tlbz r3,CurrentEventPage(r3)\n  rtocbl r12,TM_GetPageEventNum\n  cmpwi r3,9\n  bge Original\n#Set no scroll\n  li  r0,0\n  stw r0,0x4(r30)\n#Set selection\n  stb r31,0x0(r30)\n#Exit\n  branch r12,0x8024e464\nOriginal:\n  addi\tr3, r30, 0\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/OnlyDisplayEventsOnPage.asm",
    "content": "#To be inserted at 8024cffc\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set PageID,31\n\n#Get number of events on this page\n\tlwz r3,MemcardData(r13)\n\tlbz r3,CurrentEventPage(r3)\n  rtocbl r12,TM_GetPageEventNum\n  cmpwi r3,8\n  blt Exit\n  subi r3,r3,8\n\nExit:\n  lwz\tr0, 0x001C (sp)\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Event Text/SkipDisplayingEventNames.asm",
    "content": "#To be inserted at 8024d3e8\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set PageID,31\n\n#Get number of events on this page\n\tlwz r3,MemcardData(r13)\n\tlbz r3,CurrentEventPage(r3)\n  rtocbl r12,TM_GetPageEventNum\n\n#Check if event exists on this page\n  cmpw r27,r3\n  ble Exit\n\n#Zero out Lv X text\n  li  r3,0\n  stw\tr3, 0 (r23)\n#Remove Text\n  lwz r3,0x24(r23)\n  branchl r12,Text_RemoveText\n  li  r3,0\n  stw r3,0x24(r23)\n#Skip displaying this event\n  branch r12,0x8024d4c8\n\nExit:\n  li\tr3, 0\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/GetEventTutorialFileName.asm",
    "content": "#To be inserted at 80005538\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nbackup\n\n\t\t################################################\n\t\t## Get Movie's FileName and Extension Pointer ##\n\t\t################################################\n\n\t\t.set EventID,23\n\t\t.set PageID,24\n\t\t.set ReturnString,25\n\n\t\t#Backup return string\n\t\t\tmr\tReturnString,r3\n\n\t\t#Get Hovered Over Event ID in r23\n\t\t\tlwz\tr5, -0x4A40 (r13)\n\t\t\tlwz\tr5, 0x002C (r5)\n\t\t\tlwz\tr3, 0x0004 (r5)\t\t #Selection Number\n\t\t\tlbz\tr0, 0 (r5)\t\t  #Page Number\n\t\t\tadd\tEventID,r3,r0\n\n\t\t#Get Current Page in\n\t\t  lwz r3,MemcardData(r13)\n\t\t  lbz PageID,CurrentEventPage(r3)\n\n\t\t#Get pointer page's string array\n\t\t\tbl\tSkipJumpTable\n\n\t\t##### Page List #######\n\t\t\tEventJumpTable\n\t\t#######################\n\n\t\tSkipJumpTable:\n\t\t  mflr\tr4\t\t#Jump Table Start in r4\n\t\t  mulli\tr5,PageID,0x4\t\t#Each Pointer is 0x4 Long\n\t\t  add\tr4,r4,r5\t\t#Get Event's Pointer Address\n\t\t  lwz\tr5,0x0(r4)\t\t#Get bl Instruction\n\t\t  rlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\n\t\t#Get Movie File String\n\t\t\tmr\tr3,EventID\n\t\t\tadd\tr4,r4,r5\t\t#Gets ASCII Address in r4\n\t\t\tbranchl r12,SearchStringTable\n\n\t\t\trestore\n\t\t\tblr\n\n#######################################\n\nEventTutorials\n\n#######################################\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Restore FDD Backup on Main Menu Load.asm",
    "content": "#To be inserted at 8022e630\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n#Check If First Boot\nCheckIfFirstBoot:\n  lbz\tr5,FirstBootFlag(rtoc)\n  cmpwi\tr5,0x0\n  beq\tRestoreBackup\n#On First Boot\n#Backup Instead of Restoring\n  lwz\tr6,-0x77C0(r13)\n  lwz\tr5,0x1F24(r6)\n  stw\tr5,-0xDA8(rtoc)\n#Remove Boot Flag\n  li\tr5,0x0\n  stb\tr5,FirstBootFlag(rtoc)\n\nb\tExit\n\nRestoreBackup:\n  lwz\tr5,-0xDA8(rtoc)\n  lwz\tr6,-0x77C0(r13)\n  stw\tr5,0x1F24(r6)\n\nExit:\n#Original Line\n  li\tr3, 3\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Spoof All Events as Not Played.asm",
    "content": "#To be inserted at 8024d288\n\nli  r3,0\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Version Indicator/Event Code Version Indicator.asm",
    "content": "#To be inserted at 8024e568\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set text,31\n.set textproperties,30\n\n.set VersionString,0x8040a58c\n\n.set MainTextOffset,-0x4EB4\n.set LeftArrowTextOffset,-0x4EB0\n.set RightArrowTextOffset,-0x4EAC\n.set TutTextOffset,-0x4EA8\n.set MenuBackgroundPointer,-0x4EA4\n.set MenuTextPointer,-0x4EA0\n\nbackup\n\n#GET PROPERTIES TABLE\n\tbl TEXTPROPERTIES\n\tmflr textproperties\n\n#Init background pointer\n\tli\tr3,0\n\tstw r3,MenuBackgroundPointer(r13)\n\n########################\n## Create Text Object ##\n########################\n\n#CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3\n\tli r3,0\n\tli r4,0\n\tbranchl r12,0x803a6754\n#BACKUP STRUCT POINTER\n\tmr text,r3\n#STORE POINTER\n\tstw\ttext,MainTextOffset(r13)\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x1\n\tstb r4,0x49(text)\n#SET TEXT TO CENTER AROUND X LOCATION\n\tli r4,0x1\n\tstb r4,0x4A(text)\n#Store Base Z Offset\n\tlfs f1,ZOffset(textproperties) #Z offset\n\tstfs f1,0x8(text)\n#Scale Canvas Down\n  lfs f1,CanvasScaling(textproperties)\n  stfs f1,0x24(text)\n  stfs f1,0x28(text)\n\n###############\n## Page Name ##\n###############\n\n#Get Current Page\n\tlwz r3,MemcardData(r13)\n\tlbz r3,CurrentEventPage(r3)\n\trtocbl r12,TM_GetPageName\n#Initialize Subtext\n\tmr\tr4,r3\n\tlfs \tf1,PageX(textproperties) \t\t#X offset of text\n\tlfs \tf2,PageY(textproperties)\t  \t#Y offset of text\n\tmr \tr3,text\t\t#struct pointer\n\tbranchl r12,0x803a6b98\n\n#############\n## L = OSD ##\n#############\n\n#Initialize Subtext\n\tlfs \tf1,LX(textproperties) #X offset of text\n\tlfs \tf2,LY(textproperties) #Y offset of text\n\tmr \tr3,text       #struct pointer\n\tbl \tLText\n\tmflr \tr4\t\t#pointer to ASCII\n\tbranchl r12,0x803a6b98\n#Change scale\n\tmr\tr4,r3\n\tmr\tr3,text\n\tlfs\tf1,RScale(textproperties)\n\tlfs\tf2,RScale(textproperties)\n\tbranchl r12,Text_UpdateSubtextSize\n\n##################\n## Version Text ##\n##################\n\n#Get version string\n\trtocbl r12,TM_GetTMVersLong\n\tmr\tr4,r3\n#Initialize Subtext\n\tlfs \tf1,VersionX(textproperties) #X offset of text\n\tlfs \tf2,VersionY(textproperties) #Y offset of text\n\tmr \tr3,text       #struct pointer\n\tbranchl r12,0x803a6b98\n#Temp remember subtext ID\n\tmr\tr20,r3\n#Change scale\n\tmr\tr4,r20\n\tmr\tr3,text\n\tlfs\tf1,VersionScale(textproperties)\n\tlfs\tf2,VersionScale(textproperties)\n\tbranchl r12,Text_UpdateSubtextSize\n\n#Change Color\n\tmr\tr4,r20\t\t\t#subtext id\n\tmr \tr3,text\t\t\t#text pointer\n\tload\tr5,0x8dff6eff\n\tstw\tr5,0xF0(sp)\n\taddi r5,sp,0xF0\n\tbranchl r12,Text_ChangeTextColor\n\n/*\n#################\n## Z = Options ##\n#################\n\n#Initialize Subtext\n\tlfs \tf1,OptionsX(textproperties) #X offset of text\n\tlfs \tf2,OptionsY(textproperties) #Y offset of text\n\tmr \tr3,text       #struct pointer\n\tbl \tOptionsText\n\tmflr \tr4\t\t#pointer to ASCII\n\tbranchl r12,0x803a6b98\n#Change scale\n\tmr\tr4,r3\n\tmr\tr3,text\n\tlfs\tf1,OptionsScale(textproperties)\n\tlfs\tf2,OptionsScale(textproperties)\n\tbranchl r12,Text_UpdateSubtextSize\n*/\n\n###############################\n## Left Page Arrow Indicator ##\n###############################\n\n#CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3\n\tli r3,0\n\tli r4,0\n\tbranchl r12,0x803a6754\n#BACKUP STRUCT POINTER\n\tmr text,r3\n#STORE POINTER\n\tstw\ttext,LeftArrowTextOffset(r13)\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x1\n\tstb r4,0x49(text)\n#SET TEXT TO CENTER AROUND X LOCATION\n\tli r4,0x1\n\tstb r4,0x4A(text)\n#Store Base Z Offset\n\tlfs f1,ZOffset(textproperties) #Z offset\n\tstfs f1,0x8(text)\n#Scale Canvas Down\n  lfs f1,CanvasScaling(textproperties)\n  stfs f1,0x24(text)\n  stfs f1,0x28(text)\n\n#Initialize Subtext\n\tlfs \tf1,LeftArrowX(textproperties) \t\t#X offset of text\n\tlfs \tf2,ArrowY(textproperties)\t  \t\t\t#Y offset of text\n\tmr \tr3,text\t\t#struct pointer\n\tbl\tPageArrowLeft\n\tmflr r4\n\tbranchl r12,0x803a6b98\n#Change scale\n\tmr\tr4,r3\n\tmr\tr3,text\n\tlfs\tf1,ArrowScale(textproperties)\n\tlfs\tf2,ArrowScale(textproperties)\n\tbranchl r12,Text_UpdateSubtextSize\n\n###############################\n## Right Page Arrow Indicator ##\n###############################\n\n#CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3\n\tli r3,0\n\tli r4,0\n\tbranchl r12,0x803a6754\n#BACKUP STRUCT POINTER\n\tmr text,r3\n#STORE POINTER\n\tstw\ttext,RightArrowTextOffset(r13)\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x1\n\tstb r4,0x49(text)\n#SET TEXT TO CENTER AROUND X LOCATION\n\tli r4,0x1\n\tstb r4,0x4A(text)\n#Store Base Z Offset\n\tlfs f1,ZOffset(textproperties) #Z offset\n\tstfs f1,0x8(text)\n#Scale Canvas Down\n  lfs f1,CanvasScaling(textproperties)\n  stfs f1,0x24(text)\n  stfs f1,0x28(text)\n\n#Initialize Subtext\n\tlfs \tf1,RightArrowX(textproperties) \t\t#X offset of text\n\tlfs \tf2,ArrowY(textproperties)\t  \t\t\t#Y offset of text\n\tmr \tr3,text\t\t#struct pointer\n\tbl\tPageArrowRight\n\tmflr r4\n\tbranchl r12,0x803a6b98\n\n#Change scale\n\tmr\tr4,r3\n\tmr\tr3,text\n\tlfs\tf1,ArrowScale(textproperties)\n\tlfs\tf2,ArrowScale(textproperties)\n\tbranchl r12,Text_UpdateSubtextSize\n\n##################\n## R = Tutorial ##\n##################\n\n#Check For Training Mode ISO Game ID\n\tlis\tr5,0x8000\n\tlwz\tr5,0x0(r5)\n\tload\tr6,0x47544d45\t\t\t#GTME\n\tcmpw\tr5,r6\n\tbne\tIsMemcard\n\n#CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3\n\tli r3,0\n\tli r4,0\n\tbranchl r12,0x803a6754\n#BACKUP STRUCT POINTER\n\tmr text,r3\n#STORE POINTER\n\tstw\ttext,TutTextOffset(r13)\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x1\n\tstb r4,0x49(text)\n#SET TEXT TO CENTER AROUND X LOCATION\n\tli r4,0x1\n\tstb r4,0x4A(text)\n#Store Base Z Offset\n\tlfs f1,ZOffset(textproperties) #Z offset\n\tstfs f1,0x8(text)\n#Scale Canvas Down\n  lfs f1,CanvasScaling(textproperties)\n  stfs f1,0x24(text)\n  stfs f1,0x28(text)\n\n#Initialize Subtext\n\tlfs \tf1,RX(textproperties) #X offset of text\n\tlfs \tf2,RY(textproperties) #Y offset of text\n\tmr \tr3,text       #struct pointer\n\tbl \tRText\n\tmflr \tr4\t\t#pointer to ASCII\n\tbranchl r12,0x803a6b98\n\n#Change scale\n\tmr\tr4,r3\n\tmr\tr3,text\n\tlfs\tf1,RScale(textproperties)\n\tlfs\tf2,RScale(textproperties)\n\tbranchl r12,Text_UpdateSubtextSize\n\n\tb\tTutorialSkip\n\nIsMemcard:\n\tli\tr3,0\n\tstw\tr3,TutTextOffset(r13)\n\nTutorialSkip:\n\n\nb end\n\n\n\n#**************************************************#\nTEXTPROPERTIES:\nblrl\n.set PageX,0x0\n.set PageY,0x4\n.set ZOffset,0x8\n.set RX,0xC\n.set RY,0x10\n.set RScale,0x14\n.set LX,0x18\n.set LY,0x1C\n.set VersionX,0x20\n.set VersionY,0x24\n.set VersionScale,0x28\n.set CanvasScaling,0x2C\n.set ArrowY,0x30\n.set LeftArrowX,0x34\n.set RightArrowX,0x38\n.set ArrowScale,0x3C\n.set OptionsX,0x40\n.set OptionsY,0x44\n.set OptionsScale,0x48\n\n#Page\n.float 0      #text X pos\n.float -240   #text Y pos\n.float 17     #Z offset\n\n#Press R\n.float 310    #text X pos\n.float -230   #text Y pos\n.float 0.8\t\t#scale\n\n#Press L\n.float -310   #text X pos\n.float -230   #text Y pos\n\n#Version\n.float 0    #text X pos\n.float -212   #text Y pos\n.float 0.6\t\t#text scale\n\n.float 0.035   #Canvas Scaling\n\n#Arrows\n.float\t-215\t\t#Y coordinate\n.float\t-210\t\t#left X\n.float   210    #Right X\n.float\t 0.7\t\t#Scale\n\n#Options\n.float 299    #text X pos\n.float -282   #text Y pos\n.float 0.8\t\t#text scale\n\nNullString:\nblrl\n.string \"Null\"\n.align 2\n\nPageArrowLeft:\nblrl\n.string \"<\"\n.align 2\n\nPageArrowRight:\nblrl\n.string \">\"\n.align 2\n\nRText:\nblrl\n.string \"R = Tut\"\n.align 2\n\nLText:\nblrl\n.string \"L = OSD\"\n.align 2\n\nVersionText:\nblrl\n.string \"Training Mode %s\"\n.align 2\n\nOptionsText:\nblrl\n.string \"Z = Options\"\n.align 2\n\n#**************************************************#\nend:\n\nrestore\nlwz\tr3, 0 (r30)\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Version Indicator/Remove Event Texture.asm",
    "content": "#To be inserted at 8022e5e4\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n .macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n\n#Original Codeline\nstw\tr3, -0x4AE8 (r13)\n\n#GET START OF DAT\nlwz \tr5,0x0(r3) #get dat length\nsubi \tr3,r3,0x31 #get to the end of the dat in memory\nsub \tr5,r3,r5\t\t#get start of dat\n\n#Zero\nli\tr3,0\n\n#Make Background Texture Transparent\nload\tr4,0x1e754\nadd\tr4,r4,r5\nstw\tr3,0xC(r4)\n\n#Make Subject Table Texture Transparent\nload\tr4,0x1ec88\nadd\tr4,r4,r5\nstw\tr3,0xC(r4)\n\nexit:\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Version Indicator/Remove Version Indicator 1.asm",
    "content": "#To be inserted at 8024e304\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set MainTextOffset,-0x4EB4\n.set LeftArrowTextOffset,-0x4EB0\n.set RightArrowTextOffset,-0x4EAC\n.set TutTextOffset,-0x4EA8\n\n#Remove All Text\n\tlwz\tr3, MainTextOffset (r13)\n\tbranchl\tr12,0x803a5cc4\n\tlwz\tr3, LeftArrowTextOffset (r13)\n\tbranchl\tr12,0x803a5cc4\n\tlwz\tr3, RightArrowTextOffset (r13)\n\tbranchl\tr12,0x803a5cc4\n\tlwz\tr3, TutTextOffset (r13)\n  cmpwi r3,0\n  beq SkipTutorial\n\tbranchl\tr12,0x803a5cc4\nSkipTutorial:\n\n#Original Line\nlwz\tr3, 0x0074 (r31)\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Version Indicator/Remove Version Indicator 2.asm",
    "content": "#To be inserted at 8024e3b0\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set MainTextOffset,-0x4EB4\n.set LeftArrowTextOffset,-0x4EB0\n.set RightArrowTextOffset,-0x4EAC\n.set TutTextOffset,-0x4EA8\n\n#Remove All Text\n\tlwz\tr3, MainTextOffset (r13)\n\tbranchl\tr12,0x803a5cc4\n\tlwz\tr3, LeftArrowTextOffset (r13)\n\tbranchl\tr12,0x803a5cc4\n\tlwz\tr3, RightArrowTextOffset (r13)\n\tbranchl\tr12,0x803a5cc4\n\tlwz\tr3, TutTextOffset (r13)\n  cmpwi r3,0\n  beq SkipTutorial\n\tbranchl\tr12,0x803a5cc4\nSkipTutorial:\n\n#Original Line\nlwz\tr3, 0x0074 (r31)\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Event Select Screen/Version Indicator/Toggle Tutorial Text.asm",
    "content": "#To be inserted at 8024d84c\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set MainTextOffset,-0x4EB4\n.set LeftArrowTextOffset,-0x4EB0\n.set RightArrowTextOffset,-0x4EAC\n.set TutTextOffset,-0x4EA8\n\nbackup\n\n.set  REG_PageNum,22\n.set  EventID,23\n.set  PageID,24\n\n#Get number of pages\n  rtocbl\tr12,TM_GetPageNum\n  mr  REG_PageNum,r3\n#Get Event ID\n  lbz\tr3,0x0(r31)\n  lwz\tr4,0x4(r31)\n  add\tEventID,r3,r4\n#Check if first page\n  lwz r3,MemcardData(r13)\n  lbz PageID,CurrentEventPage(r3)\n\tcmpwi PageID,0\n\tbne ShowFirstPage\n#Hide left arrow\n\tli\tr4,1\n\tb\tFirstPageVisibility\nShowFirstPage:\n#Show left arrow\n\tli\tr4,0\n\tb\tFirstPageVisibility\nFirstPageVisibility:\n\tlwz\tr3, LeftArrowTextOffset (r13)\n\tstb r4,0x4D(r3)\n\n#Check if last page\n\tcmpw PageID,REG_PageNum\n\tbne ShowLastPage\n#Hide right arrow\n\tli\tr4,1\n\tb\tLastPageVisibility\nShowLastPage:\n#Show right arrow\n\tli\tr4,0\n\tb\tLastPageVisibility\nLastPageVisibility:\n\tlwz\tr3, RightArrowTextOffset (r13)\n\tstb r4,0x4D(r3)\n\n\n#Check For Training Mode ISO Game ID\n\tlis\tr5,0x8000\n\tlwz\tr5,0x0(r5)\n\tload\tr6,0x47544d45\t\t\t#GTME\n\tcmpw\tr5,r6\n\tbne\tend\n#Get Events Tutorial\n\tlwz r3,MemcardData(r13)\n\tlbz r3,CurrentEventPage(r3)\n  mr  r4,EventID\n\trtocbl r12,TM_GetEventTut\n\tmr\tr20,r3\n#Copy File Name To Temp Space\n\taddi\tr21,sp,0x80\n\tmr\tr3,r21\t\t\t\t\t\t\t\t#Destination\n\tmr\tr4,r20\t\t\t\t\t\t\t\t#Movie FileName\n\tbranchl\tr12,0x80325a50\t\t#strcpy\n#Get Length of This String Now\n\tmr\tr3,r21\t\t\t\t\t\t\t\t#Destination\n\tbranchl\tr12,0x80325b04\n#Copy .mth Suffix\n\tadd\tr3,r3,r21\t\t\t\t\t\t\t#Dest\n\tbl\tFileSuffix\n\tmflr r4\n\tbranchl\tr12,0x80325a50\n\n#Check if exists\n\tmr\tr3,r21\t\t\t\t\t\t\t\t#Destination\n\tbranchl r12,0x8033796c\n\tcmpwi r3,-1\n\tbeq HideTutorial\nShowTutorial:\n\tli\tr4,0\n\tb\tDisplayTutorial\nHideTutorial:\n\tli\tr4,1\nDisplayTutorial:\n\tlwz\tr3, TutTextOffset (r13)\n\tstb r4,0x4D(r3)\n\n\tb\tend\n\nFileSuffix:\nblrl\n.string \".mth\"\n.align 2\n\n\nend:\nrestore\nlwz\tr0, 0x0024 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Custom Events/Unlock All Events/Unlock Event 1.asm",
    "content": "#To be inserted at 8024CEC4\nb\t0x58"
  },
  {
    "path": "ASM/training-mode/Custom Events/Unlock All Events/Unlock Event 2.asm",
    "content": "#To be inserted at 80162EE8\nbeq-\t 0xC"
  },
  {
    "path": "ASM/training-mode/Globals.s",
    "content": "#Debug Flag\n.set debug,0\n\n#PAL Flag, compiles with PAL codes when enabled\n.set PAL,0\n\n#######################\n## Codeset Variables ##\n#######################\n#Number of Pages\n.set NumOfPages,3 -1\n\n#Score Types\n.set KO,0x0\n.set Time,0x1\n\n##################################\n#region Minigame Page Data\n#Number of Events\n.set Minigames.NumOfEvents,4 -1\n\n#region Eggs-ercise\n  .set Event_Eggs,0\n  #Event Name\n    .macro Event_Eggs_Name\n      .string \"Eggs-ercise\"\n    .endm\n\n    .macro Event_Eggs_Description\n      .string \"Break the eggs! Only strong hits will\nbreak them. DPad down = free practice.\"\n    .endm\n\n    .macro Event_Eggs_Tutorial\n      .string \"TvEgg\"\n    .endm\n\n    .macro Event_Eggs_ChooseCPU\n    .endm\n\n    .macro Event_Eggs_PreloadData\n    .endm\n\n    .macro Event_Eggs_LoadSSS\n      .byte Event_Eggs\n    .endm\n\n    .macro Event_Eggs_PlayableCharacters\n    .endm\n\n    .macro Event_Eggs_AvailableCPUs\n    .endm\n\n    .macro Event_Eggs_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region Multishine\n  .set Event_Multishine,1\n  #Event Name\n    .macro Event_Multishine_Name\n      .string \"Shined Blind\"\n    .endm\n\n    .macro Event_Multishine_Description\n      .string \"How many shines can you\nperform in 10 seconds?\"\n    .endm\n\n    .macro Event_Multishine_Tutorial\n      .string \"TvMulShine\"\n    .endm\n\n    .macro Event_Multishine_ChooseCPU\n    .endm\n\n    .macro Event_Multishine_PreloadData\n    .byte Event_Multishine, -1, FinalDestination\n    .endm\n\n    .macro Event_Multishine_LoadSSS\n    .endm\n\n    .macro Event_Multishine_PlayableCharacters\n      .byte Event_Multishine\n      .long Falco_CSSID | Fox_CSSID\n      .long -1\n    .endm\n\n    .macro Event_Multishine_AvailableCPUs\n    .endm\n\n    .macro Event_Multishine_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region Reaction\n  .set Event_Reaction,2\n  #Event Name\n    .macro Event_Reaction_Name\n      .string \"Reaction Test\"\n    .endm\n\n    .macro Event_Reaction_Description\n      .string \"Test your reaction time by pressing\nany button when you see/hear Fox shine!\"\n    .endm\n\n    .macro Event_Reaction_Tutorial\n      .string \"TvReaction\"\n    .endm\n\n    .macro Event_Reaction_ChooseCPU\n    .endm\n\n    .macro Event_Reaction_PreloadData\n      .byte Event_Reaction, Fox.Ext, FinalDestination\n    .endm\n\n    .macro Event_Reaction_LoadSSS\n    .endm\n\n    .macro Event_Reaction_PlayableCharacters\n    .endm\n\n    .macro Event_Reaction_AvailableCPUs\n    .endm\n\n    .macro Event_Reaction_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region Ledgestall\n  .set Event_Ledgestall,3\n  #Event Name\n    .macro Event_Ledgestall_Name\n      .string \"Under Fire\"\n    .endm\n\n    .macro Event_Ledgestall_Description\n      .string \"Use ledgestalling to remain\ninvincible while the lava rises!\"\n    .endm\n\n    .macro Event_Ledgestall_Tutorial\n      .string \"TvMulShine\"\n    .endm\n\n    .macro Event_Ledgestall_ChooseCPU\n    .endm\n\n    .macro Event_Ledgestall_PreloadData\n    .byte Event_Ledgestall, -1, Brinstar\n    .endm\n\n    .macro Event_Ledgestall_LoadSSS\n    .endm\n\n    .macro Event_Ledgestall_PlayableCharacters\n      .byte #Event_Ledgestall\n      .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\n      .long #-1\n    .endm\n\n    .macro Event_Ledgestall_AvailableCPUs\n    .endm\n\n    .macro Event_Ledgestall_ScoreType\n      .byte Time\n    .endm\n\n    .set EventOSD_LedgeStall,0x00000000\n\n#endregion\n\n#endregion\n#region Universal Tech Page Data\n#Number of Events\n  .set GeneralTech.NumOfEvents, 13 -1\n\n#Event List\n#region LCancel\n  .set Event_LCancel,0\n  #Event Name\n    .macro Event_LCancel_Name\n      .string \"L-Cancel Training\"\n    .endm\n\n    .macro Event_LCancel_Description\n      .string \"Practice L-Cancelling on\na stationary CPU.\"\n    .endm\n\n    .macro Event_LCancel_Tutorial\n      .string \"TvLC\"\n    .endm\n\n    .macro Event_LCancel_ChooseCPU\n      .byte Event_LCancel\n    .endm\n\n    .macro Event_LCancel_PreloadData\n    .endm\n\n    .macro Event_LCancel_LoadSSS\n      .byte Event_LCancel\n    .endm\n\n    .macro Event_LCancel_PlayableCharacters\n    .endm\n\n    .macro Event_LCancel_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region Ledgedash\n  .set Event_Ledgedash,1\n  #Event Name\n    .macro Event_Ledgedash_Name\n      .string \"Ledgedash Training\"\n    .endm\n\n    .macro Event_Ledgedash_Description\n      .string \"Practice Ledgedashes!\nUse D-Pad to change ledge.\"\n    .endm\n\n    .macro Event_Ledgedash_Tutorial\n      .string \"TvLedDa\"\n    .endm\n\n    .macro Event_Ledgedash_ChooseCPU\n    .endm\n\n    .macro Event_Ledgedash_PreloadData\n    .endm\n\n    .macro Event_Ledgedash_LoadSSS\n      .byte Event_Ledgedash\n    .endm\n\n    .macro Event_Ledgedash_PlayableCharacters\n    .endm\n\n    .macro Event_Ledgedash_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region Combo\n  .set Event_Combo,2\n  #Event Name\n    .macro Event_Combo_Name\n      .string \"Combo Training\"\n    .endm\n\n    .macro Event_Combo_Description\n      .string \"L+DPad adjusts percent | DPadDown moves CPU\nDPad right/left saves and loads positions.\"\n    .endm\n\n    .macro Event_Combo_Tutorial\n      .string \"TvCombo\"\n    .endm\n\n    .macro Event_Combo_ChooseCPU\n      .byte Event_Combo\n    .endm\n\n    .macro Event_Combo_PreloadData\n    .endm\n\n    .macro Event_Combo_LoadSSS\n      .byte Event_Combo\n    .endm\n\n    .macro Event_Combo_PlayableCharacters\n    .endm\n\n    .macro Event_Combo_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region AttackOnShield\n  .set Event_AttackOnShield,3\n  #Event Name\n    .macro Event_AttackOnShield_Name\n      .string \"Attack On Shield\"\n    .endm\n\n    .macro Event_AttackOnShield_Description\n      .string \"Practice attacks on a shielding opponent!\nPause to change their OoS option.\"\n    .endm\n\n    .macro Event_AttackOnShield_Tutorial\n      .string \"TvAttOnSh\"\n    .endm\n\n    .macro Event_AttackOnShield_ChooseCPU\n      .byte Event_AttackOnShield\n    .endm\n\n    .macro Event_AttackOnShield_PreloadData\n      .byte Event_AttackOnShield,-1,FinalDestination\n    .endm\n\n    .macro Event_AttackOnShield_LoadSSS\n    .endm\n\n    .macro Event_AttackOnShield_PlayableCharacters\n    .endm\n\n    .macro Event_AttackOnShield_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region Reversal\n  .set Event_Reversal,4\n  #Event Name\n    .macro Event_Reversal_Name\n      .string \"Reversal Training\"\n    .endm\n\n    .macro Event_Reversal_Description\n      .string \"Practice OoS punishes! DPad left/right\nmoves characters closer and further apart.\"\n    .endm\n\n    .macro Event_Reversal_Tutorial\n      .string \"TvRvrsl\"\n    .endm\n\n    .macro Event_Reversal_ChooseCPU\n      .byte Event_Reversal\n    .endm\n\n    .macro Event_Reversal_PreloadData\n    .endm\n\n    .macro Event_Reversal_LoadSSS\n      .byte Event_Reversal\n    .endm\n\n    .macro Event_Reversal_PlayableCharacters\n    .endm\n\n    .macro Event_Reversal_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region SDI\n  .set Event_SDI,5\n  #Event Name\n    .macro Event_SDI_Name\n      .string \"SDI Training\"\n    .endm\n\n    .macro Event_SDI_Description\n      .string \"Practice Smash DI'ing\nFox's up-air!\"\n    .endm\n\n    .macro Event_SDI_Tutorial\n      .string \"TvSDI\"\n    .endm\n\n    .macro Event_SDI_ChooseCPU\n    .endm\n\n    .macro Event_SDI_PreloadData\n      .byte Event_SDI, Fox.Ext, FinalDestination\n    .endm\n\n    .macro Event_SDI_LoadSSS\n    .endm\n\n    .macro Event_SDI_PlayableCharacters\n    .endm\n\n    .macro Event_SDI_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region Powershield\n  .set Event_Powershield,6\n  #Event Name\n    .macro Event_Powershield_Name\n      .string \"Powershield Training\"\n    .endm\n\n    .macro Event_Powershield_Description\n      .string \"Powershield Falco's laser!\nPause to change fire-rate.\"\n    .endm\n\n    .macro Event_Powershield_Tutorial\n      .string \"TvPowSh\"\n    .endm\n\n    .macro Event_Powershield_ChooseCPU\n    .endm\n\n    .macro Event_Powershield_PreloadData\n      .byte Event_Powershield, Falco.Ext, FinalDestination\n    .endm\n\n    .macro Event_Powershield_LoadSSS\n    .endm\n\n    .macro Event_Powershield_PlayableCharacters\n    .endm\n\n    .macro Event_Powershield_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region LedgeTech\n  .set Event_LedgeTech,7\n  #Event Name\n    .macro Event_LedgeTech_Name\n      .string \"Ledge-Tech Training\"\n    .endm\n\n    .macro Event_LedgeTech_Description\n      #Ledge-Tech Training\n      .string \"Practice ledge-teching\nFalco's down-smash!\"\n    .endm\n\n    .macro Event_LedgeTech_Tutorial\n      .string \"TvLedTc\"\n    .endm\n\n    .macro Event_LedgeTech_ChooseCPU\n    .endm\n\n    .macro Event_LedgeTech_PreloadData\n      .byte Event_LedgeTech, Falco.Ext, -1\n    .endm\n\n    .macro Event_LedgeTech_LoadSSS\n      .byte Event_LedgeTech\n    .endm\n\n    .macro Event_LedgeTech_PlayableCharacters\n    .endm\n\n    .macro Event_LedgeTech_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region AmsahTech\n  .set Event_AmsahTech,8\n  #Event Name\n    .macro Event_AmsahTech_Name\n      .string \"Amsah-Tech Training\"\n    .endm\n\n    .macro Event_AmsahTech_Description\n      .string \"Taunt to have Marth Up-B,\nthen ASDI down and tech!\"\n    .endm\n\n    .macro Event_AmsahTech_Tutorial\n      .string \"TvAmsTc\"\n    .endm\n\n    .macro Event_AmsahTech_ChooseCPU\n    .endm\n\n    .macro Event_AmsahTech_PreloadData\n      .byte Event_AmsahTech, Marth.Ext, -1\n    .endm\n\n    .macro Event_AmsahTech_LoadSSS\n      .byte Event_AmsahTech\n    .endm\n\n    .macro Event_AmsahTech_PlayableCharacters\n    .endm\n\n    .macro Event_AmsahTech_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region ShieldDrop\n  .set Event_ShieldDrop,9\n  #Event Name\n    .macro Event_ShieldDrop_Name\n      .string \"Shield Drop Training\"\n    .endm\n\n    .macro Event_ShieldDrop_Description\n      .string \"Counter with a shield-drop aerial!\nDPad left/right moves players apart.\"\n    .endm\n\n    .macro Event_ShieldDrop_Tutorial\n      .string \"TvShDrp\"\n    .endm\n\n    .macro Event_ShieldDrop_ChooseCPU\n      .byte Event_ShieldDrop\n    .endm\n\n    .macro Event_ShieldDrop_PreloadData\n      .byte Event_ShieldDrop, -1, Battlefield\n    .endm\n\n    .macro Event_ShieldDrop_LoadSSS\n    .endm\n\n    .macro Event_ShieldDrop_PlayableCharacters\n    .endm\n\n    .macro Event_ShieldDrop_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region WaveshineSDI\n  .set Event_WaveshineSDI,10\n  #Event Name\n    .macro Event_WaveshineSDI_Name\n      .string \"Waveshine SDI\"\n    .endm\n\n    .macro Event_WaveshineSDI_Description\n      .string \"Use Smash DI to get out\nof Fox's waveshine!\"\n    .endm\n\n    .macro Event_WaveshineSDI_Tutorial\n      .string \"TvWvSDI\"\n    .endm\n\n    .macro Event_WaveshineSDI_ChooseCPU\n    .endm\n\n    .macro Event_WaveshineSDI_PreloadData\n      .byte Event_WaveshineSDI, Fox.Ext, FinalDestination\n    .endm\n\n    .macro Event_WaveshineSDI_LoadSSS\n    .endm\n\n    .macro Event_WaveshineSDI_PlayableCharacters\n    .byte Event_WaveshineSDI\n    .if PAL==0\n      .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\n    .endif\n    .if PAL==1\n      .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\n    .endif\n    .long -1\n    .endm\n\n    .macro Event_WaveshineSDI_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region SlideOff\n  .set Event_SlideOff,11\n  #Event Name\n    .macro Event_SlideOff_Name\n      .string \"Slide-Off Training\"\n    .endm\n\n    .macro Event_SlideOff_Description\n      .string \"Use Slide-Off DI to slide off\nthe platform and counter attack!\"\n    .endm\n\n    .macro Event_SlideOff_Tutorial\n      .string \"TvSlOff\"\n    .endm\n\n    .macro Event_SlideOff_ChooseCPU\n    .endm\n\n    .macro Event_SlideOff_PreloadData\n      .byte Event_SlideOff, Marth.Ext, PokemonStadium\n    .endm\n\n    .macro Event_SlideOff_LoadSSS\n    .endm\n\n    .macro Event_SlideOff_PlayableCharacters\n    .endm\n\n    .macro Event_SlideOff_ScoreType\n    .endm\n\n    .set EventOSD_SlideOff,0x00000000\n\n#endregion\n#region GrabMashOut\n  .set Event_GrabMashOut,12\n  #Event Name\n    .macro Event_GrabMashOut_Name\n      .string \"Grab Mash Training\"\n    .endm\n\n    .macro Event_GrabMashOut_Description\n      .string \"Mash buttons to escape the grab\nas quickly as possible!\"\n    .endm\n\n    .macro Event_GrabMashOut_Tutorial\n      .string \"TvGrabMash\"\n    .endm\n\n    .macro Event_GrabMashOut_ChooseCPU\n    .endm\n\n    .macro Event_GrabMashOut_PreloadData\n      .byte Event_GrabMashOut, Marth.Ext, FinalDestination\n    .endm\n\n    .macro Event_GrabMashOut_LoadSSS\n    .endm\n\n    .macro Event_GrabMashOut_PlayableCharacters\n    .endm\n\n    .macro Event_GrabMashOut_ScoreType\n      .byte KO\n    .endm\n\n    .set EventOSD_GrabMashOut,0x01000000\n\n#endregion\n\n#endregion\n#region Spacie Tech Page Data\n#Number of Events\n  .set SpacieTech.NumOfEvents,4 -1\n\n#Event List\n#region LedgetechCounter\n  .set Event_LedgetechCounter,0\n  #Event Name\n    .macro Event_LedgetechCounter_Name\n      .string \"Ledgetech Marth Counter\"\n    .endm\n\n    .macro Event_LedgetechCounter_Description\n      .string \"Practice ledge-teching\nMarth's counter!\"\n    .endm\n\n    .macro Event_LedgetechCounter_Tutorial\n      .string \"TvLdTcCntr\"\n    .endm\n\n    .macro Event_LedgetechCounter_ChooseCPU\n    .endm\n\n    .macro Event_LedgetechCounter_PreloadData\n      .byte Event_LedgetechCounter, Marth.Ext, -1\n    .endm\n\n    .macro Event_LedgetechCounter_LoadSSS\n      .byte Event_LedgetechCounter\n    .endm\n\n    .macro Event_LedgetechCounter_PlayableCharacters\n      .byte Event_LedgetechCounter\n      .long Fox_CSSID | Falco_CSSID      #Player Characters\n\t\t\t.long -1\n    .endm\n\n    .macro Event_LedgetechCounter_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region ArmadaShine\n  .set Event_ArmadaShine,1\n  #Event Name\n    .macro Event_ArmadaShine_Name\n      .string \"Armada-Shine Training\"\n    .endm\n\n    .macro Event_ArmadaShine_Description\n      .string \"Finish off the enemy Fox\nwith an Armada-Shine!\"\n    .endm\n\n    .macro Event_ArmadaShine_Tutorial\n      .string \"TvArmShine\"\n    .endm\n\n    .macro Event_ArmadaShine_ChooseCPU\n    .endm\n\n    .macro Event_ArmadaShine_PreloadData\n      .byte Event_ArmadaShine, Fox.Ext, -1\n    .endm\n\n    .macro Event_ArmadaShine_LoadSSS\n      .byte Event_ArmadaShine\n    .endm\n\n    .macro Event_ArmadaShine_PlayableCharacters\n      .byte Event_ArmadaShine\n      .long -1  #Fox_CSSID         #Player Characters\n\t\t\t.long -1\n    .endm\n\n    .macro Event_ArmadaShine_ScoreType\n      .byte KO\n    .endm\n\n  .set EventOSD_ArmadaShine,0x00000000\n\n#endregion\n#region SideBSweetspot\n  .set Event_SideBSweetspot,2\n  #Event Name\n    .macro Event_SideBSweetspot_Name\n      .string \"Side-B Sweetspot\"\n    .endm\n\n    .macro Event_SideBSweetspot_Description\n      .string \"Use a sweetspot side-B to avoid Marth's\ndown-tilt and grab the ledge!\"\n    .endm\n\n    .macro Event_SideBSweetspot_Tutorial\n      .string \"TvSideBSweet\"\n    .endm\n\n    .macro Event_SideBSweetspot_ChooseCPU\n    .endm\n\n    .macro Event_SideBSweetspot_PreloadData\n      .byte Event_SideBSweetspot, Marth.Ext, -1\n    .endm\n\n    .macro Event_SideBSweetspot_LoadSSS\n      .byte Event_SideBSweetspot\n    .endm\n\n    .macro Event_SideBSweetspot_PlayableCharacters\n      .byte Event_SideBSweetspot\n      .long Fox_CSSID | Falco_CSSID         #Player Characters\n\t\t\t.long -1\n    .endm\n\n    .macro Event_SideBSweetspot_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n#region EscapeSheik\n  .set Event_EscapeSheik,3\n  #Event Name\n    .macro Event_EscapeSheik_Name\n      .string \"Escape Sheik Techchase\"\n    .endm\n\n    .macro Event_EscapeSheik_Description\n      .string \"Practice escaping the techchase with a\nframe perfect shine or jab SDI!\"\n    .endm\n\n    .macro Event_EscapeSheik_Tutorial\n      .string \"TvEscSheik\"\n    .endm\n\n    .macro Event_EscapeSheik_ChooseCPU\n    .endm\n\n    .macro Event_EscapeSheik_PreloadData\n      .byte Event_EscapeSheik, Sheik.Ext, FinalDestination\n    .endm\n\n    .macro Event_EscapeSheik_LoadSSS\n    .endm\n\n    .macro Event_EscapeSheik_PlayableCharacters\n      .byte Event_EscapeSheik\n      .long Fox_CSSID | Falco_CSSID | CaptainFalcon_CSSID         #Player Characters\n\t\t\t.long -1\n    .endm\n\n    .macro Event_EscapeSheik_ScoreType\n      .byte KO\n    .endm\n\n#endregion\n\n#endregion\n##################################\n\n#region Event Table Macros\n\n#region Event Page Order\n#This macro will change the order of the pages\n#Only thing this macro doesn't affect is Load CSS + Preload CPU + high scores. Must change this manually.\n.macro EventJumpTable\n\tbl\tMinigames\n  bl  GeneralTech\n  bl  SpacieTech\n.endm\n#endregion\n#region EventAmountPerPage\n.macro EventAmountPerPage\n\nMinigames:\n.long Minigames.NumOfEvents\n.align 2\nGeneralTech:\n.long GeneralTech.NumOfEvents\n.align 2\nSpacieTech:\n.long SpacieTech.NumOfEvents\n.align 2\n\n.endm\n#endregion\n\n#region EventNameStrings\n.macro EventNameStrings\nMinigames:\n  Event_Eggs_Name\n  Event_Multishine_Name\n  Event_Reaction_Name\n  Event_Ledgestall_Name\n.align 2\n\nGeneralTech:\n  Event_LCancel_Name\n  Event_Ledgedash_Name\n  Event_Combo_Name\n  Event_AttackOnShield_Name\n  Event_Reversal_Name\n  Event_SDI_Name\n  Event_Powershield_Name\n  Event_LedgeTech_Name\n  Event_AmsahTech_Name\n  Event_ShieldDrop_Name\n  Event_WaveshineSDI_Name\n  Event_SlideOff_Name\n  Event_GrabMashOut_Name\n.align 2\n\n#######################\n\nSpacieTech:\n#Ledgetech Marth Counter\n  Event_LedgetechCounter_Name\n#Armada-Shine Practice\n  Event_ArmadaShine_Name\n  Event_SideBSweetspot_Name\n  Event_EscapeSheik_Name\n.align 2\n.endm\n#endregion\n#region EventDescriptionStrings\n.macro EventDescriptionStrings\n\n################\nMinigames:\n  Event_Eggs_Description\n  Event_Multishine_Description\n  Event_Reaction_Description\n  Event_Ledgestall_Description\n.align 2\n################\nGeneralTech:\n  Event_LCancel_Description\n  Event_Ledgedash_Description\n  Event_Combo_Description\n  Event_AttackOnShield_Description\n  Event_Reversal_Description\n  Event_SDI_Description\n  Event_Powershield_Description\n  Event_LedgeTech_Description\n  Event_AmsahTech_Description\n  Event_ShieldDrop_Description\n  Event_WaveshineSDI_Description\n  Event_SlideOff_Description\n  Event_GrabMashOut_Description\n.align 2\n#######################\nSpacieTech:\n#Ledgetech Marths Counter\n  Event_LedgetechCounter_Description\n#Armada-Shine Practice\n  Event_ArmadaShine_Description\n  Event_SideBSweetspot_Description\n  Event_EscapeSheik_Description\n.align 2\n########################\n.endm\n#endregion\n#region EventChooseCPU\n.macro EventChooseCPU\n\n############################\nChooseCPU_Minigames:\n  Event_Eggs_ChooseCPU\n  Event_Multishine_ChooseCPU\n  Event_Reaction_ChooseCPU\n  Event_Ledgestall_ChooseCPU\n  .byte -1\n.align 2\n############################\nChooseCPU_GeneralTech:\n  Event_LCancel_ChooseCPU\n  Event_Ledgedash_ChooseCPU\n  Event_SDI_ChooseCPU\n  Event_Reversal_ChooseCPU\n  Event_Powershield_ChooseCPU\n  Event_ShieldDrop_ChooseCPU\n  Event_AttackOnShield_ChooseCPU\n  Event_LedgeTech_ChooseCPU\n  Event_AmsahTech_ChooseCPU\n  Event_Combo_ChooseCPU\n  Event_WaveshineSDI_ChooseCPU\n  Event_SlideOff_ChooseCPU\n  Event_GrabMashOut_ChooseCPU\n  .byte -1\n.align 2\n############################\nChooseCPU_SpacieTech:\n  Event_LedgetechCounter_ChooseCPU\n  Event_ArmadaShine_ChooseCPU\n  Event_SideBSweetspot_ChooseCPU\n  Event_EscapeSheik_ChooseCPU\n  .byte -1\n.align 2\n############################\n\n.endm\n#endregion\n#region EventPreloadData\n.macro EventPreloadData\n\n############################\nPreloadEvents_Minigames:\n  Event_Eggs_PreloadData\n  Event_Multishine_PreloadData\n  Event_Reaction_PreloadData\n  Event_Ledgestall_PreloadData\n  .byte -1\n.align 2\n############################\nPreloadEvents_GeneralTech:\n  Event_LCancel_PreloadData\n  Event_Ledgedash_PreloadData\n  Event_SDI_PreloadData\n  Event_Reversal_PreloadData\n  Event_Powershield_PreloadData\n  Event_ShieldDrop_PreloadData\n  Event_AttackOnShield_PreloadData\n  Event_LedgeTech_PreloadData\n  Event_AmsahTech_PreloadData\n  Event_Combo_PreloadData\n  Event_WaveshineSDI_PreloadData\n  Event_SlideOff_PreloadData\n  Event_GrabMashOut_PreloadData\n  .byte -1\n.align 2\n############################\nPreloadEvents_SpacieTech:\n  Event_LedgetechCounter_PreloadData\n  Event_ArmadaShine_PreloadData\n  Event_SideBSweetspot_PreloadData\n  Event_EscapeSheik_PreloadData\n  .byte -1\n.align 2\n############################\n\n.endm\n#endregion\n#region EventLoadSSS\n.macro EventLoadSSS\n\n############################\nMinigames:\n  Event_Eggs_LoadSSS\n  Event_Multishine_LoadSSS\n  Event_Reaction_LoadSSS\n  Event_Ledgestall_LoadSSS\n  .byte -1\n.align 2\n############################\nGeneralTech:\n  Event_LCancel_LoadSSS\n  Event_Ledgedash_LoadSSS\n  Event_SDI_LoadSSS\n  Event_Reversal_LoadSSS\n  Event_Powershield_LoadSSS\n  Event_ShieldDrop_LoadSSS\n  Event_AttackOnShield_LoadSSS\n  Event_LedgeTech_LoadSSS\n  Event_AmsahTech_LoadSSS\n  Event_Combo_LoadSSS\n  Event_WaveshineSDI_LoadSSS\n  Event_SlideOff_LoadSSS\n  Event_GrabMashOut_LoadSSS\n  .byte -1\n.align 2\n############################\nSpacieTech:\n  Event_LedgetechCounter_LoadSSS\n  Event_ArmadaShine_LoadSSS\n  Event_SideBSweetspot_LoadSSS\n  Event_EscapeSheik_LoadSSS\n  .byte -1\n.align 2\n############################\n\n.endm\n#endregion\n#region EventPlayableCharacters\n.macro EventPlayableCharacters\n\n############################\nMinigames:\n  Event_Eggs_PlayableCharacters\n  Event_Multishine_PlayableCharacters\n  Event_Reaction_PlayableCharacters\n  Event_Ledgestall_PlayableCharacters\n  .byte -1\n.align 2\n############################\nGeneralTech:\n  Event_LCancel_PlayableCharacters\n  Event_Ledgedash_PlayableCharacters\n  Event_SDI_PlayableCharacters\n  Event_Reversal_PlayableCharacters\n  Event_Powershield_PlayableCharacters\n  Event_ShieldDrop_PlayableCharacters\n  Event_AttackOnShield_PlayableCharacters\n  Event_LedgeTech_PlayableCharacters\n  Event_AmsahTech_PlayableCharacters\n  Event_Combo_PlayableCharacters\n  Event_WaveshineSDI_PlayableCharacters\n  Event_SlideOff_PlayableCharacters\n  Event_GrabMashOut_PlayableCharacters\n  .byte -1\n.align 2\n############################\nSpacieTech:\n  Event_LedgetechCounter_PlayableCharacters\n  Event_ArmadaShine_PlayableCharacters\n  Event_SideBSweetspot_PlayableCharacters\n  Event_EscapeSheik_PlayableCharacters\n  .byte -1\n.align 2\n############################\n\n.endm\n#endregion\n#region EventHighScores\n.macro EventHighScores\n\nEventHighScores:\nblrl\n.byte 0\n.byte Minigames.NumOfEvents +1\n.byte Minigames.NumOfEvents + GeneralTech.NumOfEvents +1\n.align 2\n\n.endm\n#endregion\n#region EventTutorials\n\n.macro EventTutorials\n\nMinigames:\nEvent_Eggs_Tutorial\nEvent_Multishine_Tutorial\nEvent_Reaction_Tutorial\nEvent_Ledgestall_Tutorial\n.align 2\n\nGeneralTech:\nEvent_LCancel_Tutorial\nEvent_Ledgedash_Tutorial\nEvent_Combo_Tutorial\nEvent_AttackOnShield_Tutorial\nEvent_Reversal_Tutorial\nEvent_SDI_Tutorial\nEvent_Powershield_Tutorial\nEvent_LedgeTech_Tutorial\nEvent_AmsahTech_Tutorial\nEvent_ShieldDrop_Tutorial\nEvent_WaveshineSDI_Tutorial\nEvent_SlideOff_Tutorial\nEvent_GrabMashOut_Tutorial\n.align 2\n\nSpacieTech:\nEvent_LedgetechCounter_Tutorial\nEvent_ArmadaShine_Tutorial\nEvent_SideBSweetspot_Tutorial\nEvent_EscapeSheik_Tutorial\n.align 2\n\n.endm\n\n#endregion\n\n#endregion\n\n#region OnSaveCreate\n.macro OnSaveCreate\n#Get trophy data\n  lwz\tr3, -0x77C0 (r13)\n  addi\tr3, r3, 7376\n#Set trophy count\n  li  r4,293\n  sth r4,0x0(r3)\n#Set individual trophies as unlocked\n  addi r3,r3,4\n  li  r4,99\n  li  r5,0x24f\n  branchl r12,memset\n\nInitSettings:\n#Set Max OSD on No Memcard\n  li\tr3,1\n  lwz\tr4, -0x77C0 (r13)\n  stb\tr3,0x1F28(r4)\n#Set Initial Page Number\n  li  r3,0x1\n  stb r3,CurrentEventPage(r4)\n#Enable Recommended OSDs\n  li  r3,0\n  stb r3,OSDRecommended(r4)\n#Enable UCF by default\n  load r3,0x08000000\n  stw r3,OSDBitfield(r4)\n.endm\n#endregion\n#region OnBootup\n.macro OnBootup\n#Set First Boot Flag (used for OSD backup/restore)\n  li\tr3,0x1\n  stb\tr3,FirstBootFlag(rtoc)\n#Set CPU Info\n  li  r3,0x21\n  stb r3,EventCPUBackup_CharID(rtoc)   #Set CPU Character ID\n.endm\n#endregion\n\n#Custom Memcard Data Bitfield\n.set OSDBitfield,0x1F24\n.set OSDMaxWindows,0x1F28\n.set CurrentEventPage,0x1F29\n.set OSDRecommended,0x1F2A\n\n#Custom rtoc offsets\n.set EventCPUBackup_CharID,-0xDA5     #byte\n.set FirstBootFlag,-0xDA4 \t\t\t\t\t\t#byte\n.set CodesetPointer,-0xDA0            #word\n.set CodesetLength,-0xD9C            \t#word\n\n#OSD IDs\n.set OSD.Wavedash,0\n.set OSD.LCancel,1\n.set OSD.MissedTech,2\n.set OSD.ActOoS,3\n.set OSD.MeteorCancel,4\n.set OSD.Dashback,5\n.set OSD.ShieldDrop,6\n.set OSD.APM,7\n.set OSD.SpacieTech,8\n.set OSD.SDI,10\n.set OSD.Powershield,9\n.set OSD.ShieldPoke,11\n.set OSD.HitstunLeft,12\n.set OSD.ShieldStun,13\n.set OSD.ASFramesLeft,14\n.set OSD.Miscellaneous,15\n.set OSD.ActOoWait,16\n.set OSD.CrouchCancel,17\n.set OSD.ActOoJump,18\n.set OSD.ActOoJumpSquat,19\n.set OSD.Fastfall,20\n.set OSD.FrameAdvantage,21\n.set OSD.ComboCounter,22\n.set OSD_23,23\n.set OSD.GrabBreakout,24\n.set OSD_25,25\n.set OSD.Ledge,26\n.set OSD.UCF,27\n.set OSD.ActOoHitstun,28\n.set OSD.DIDraw,0x800000\n\n#Event OSDs\n.set EventOSD_Eggs,0x00000000\n.set EventOSD_Multishine,0x00000000\n.set EventOSD_Reaction,0x00000000\n\n.set EventOSD_LCancel,0x00000003\n.set EventOSD_Ledgedash,0x04000000\n.set EventOSD_Eggs,0x00000000\n.set EventOSD_SDI,0x10000400\n.set EventOSD_Reversal,0x002C0009\n.set EventOSD_Powershield,0x00000200\n.set EventOSD_ShieldDrop,0x00200048\n.set EventOSD_AttackOnShield,0x00210000\n.set EventOSD_LedgeTech,0x00000404\n.set EventOSD_AmsahTech,0x00000004\n.set EventOSD_ComboTraining,0x01010020\n.set EventOSD_WaveshineSDI,0x10000400\n\n.set EventOSD_LedgetechCounter,0x00000604\n.set EventOSD_EscapeSheik,0x00000400\n\n#####################\n## Melee Variables ##\n#####################\n#Static Memory Locations\n.set pdLoadCommonData,0x803bcde0\n.set InputStructStart,0x804c21cc\n  .set InputStruct_HeldButtons,0x0\n  .set InputStruct_HeldButtonsPrevFrame,0x4\n  .set InputStruct_InstantButtons,0x8\n  .set InputStruct_RapidFireButtons,0xC\n  .set InputStruct_InstantReleasedButtons,0x10\n  .set InputStruct_RapidFireCounter,0x14\n  .set InputStruct_LeftAnalogX,0x18\n  .set InputStruct_LeftAnalogY,0x19\n  .set InputStruct_RightAnalogX,0x1A\n  .set InputStruct_RightAnalogY,0x1B\n  .set InputStruct_LeftTrigger,0x1C\n  .set InputStruct_RightTrigger,0x1D\n  .set InputStruct_LeftAnalogXFloat,0x20\n  .set InputStruct_LeftAnalogYFloat,0x24\n  .set InputStruct_RightAnalogXFloat,0x28\n  .set InputStruct_RightAnalogYFloat,0x2C\n  .set InputStruct_IsPlugged,0x41\n  .set InputStruct_Length,68\n.set HSD_InputStructStart,0x804c1fac\n.set PreloadTable,0x80432078\n  .set Preload_Stage,0x10\n.set CSS_CursorPointers,0x804a0bc0\n.set HSD_Pad,0x804c1f78\n.set CSS_DoorStructs,0x803f0dfc\n  .set  CSSDoor_State,0xB\n\n#r13 Offsets\n.set MemcardData,-0x77C0\n.set DEBUGLV,-0x6C98\n.set CSS_Data,-0x49F0\n.set CSS_UnkGObj,-0x49E4\n.set CSS_UnkJObj,-0x49E0\n.set CSS_PointerToDatNodes,-0x49C8    #these are initialized to at 80266970\n.set CSS_MainPlayerPort,-0x49B0\n.set CSS_CPUPlayerPort,-0x49AF\n.set CSS_StartCountdown,-0x49AE\n.set CSS_Unk,-0x49AC\n.set CSS_MaxPlayers,-0x49AB\n.set CSS_Unk,-0x49AA\n.set CSS_SinglePlayerPortNumber,-0x4DE0\n.set HPS_Unk,-0x3F44\n.set HPS_CurrentSongEntryNum,-0x3F3C\n.set HPS_Unk,-0x3F14\n.set GObj_CurrentProc,-0x3E68\n.set HSDPerf_,0x0\n.set Hitbox_DamageLog,-0x5148     #Num of solid hits dealt by the player this check\n.set Hitbox_TipLog,-0x5144        #Num of phantom hits dealt by the player this check\n.set StageID_External,-0x6CB8\n.set Stage_LedgeInfo,-0x51E8\n.set Stage_LineInfo,-0x51EC       #ctrl f \"stage line counts\" in melee notes.txt for detailed info\n.set Stage_PositionHazardCount,-0x5128\n.set Stage_GrabHazardCount,-0x512C\n.set Stage_DamageHazardCount,-0x5130\n.set Audio_NextAreaInSSMHeap,-0x5258\n.set Audio_UnkConstant,-0x5250\n.set Audio_TotalSSMMemory,-0x5268\n.set GObj_Lists,-0x3E74\n\n.set TM_FrozenToggle,-0x4F8C\n.set TM_GameFrameCounter,-0x49a8\n\n#TM Function\n.set TM_tmFunction,-(50*4)         #offset of rtoc where function pointers are kept, probably temp solution\n.set TM_EventPages, TM_tmFunction + 0x0\n.set TM_GetEventName, TM_EventPages + 0x4\n.set TM_GetEventDesc, TM_GetEventName + 0x4\n.set TM_GetEventTut, TM_GetEventDesc + 0x4\n.set TM_GetPageName, TM_GetEventTut + 0x4\n.set TM_GetPageEventNum, TM_GetPageName + 0x4\n.set TM_GetTMVersShort, TM_GetPageEventNum + 0x4\n.set TM_GetTMVersLong, TM_GetTMVersShort + 0x4\n.set TM_GetTMCompile, TM_GetTMVersLong + 0x4\n.set TM_GetPageNum, TM_GetTMCompile + 0x4\n.set TM_GetIsChooseCPU, TM_GetPageNum + 0x4\n.set TM_GetIsSelectStage, TM_GetIsChooseCPU + 0x4\n.set TM_GetFighter, TM_GetIsSelectStage + 0x4\n.set TM_GetCPUFighter, TM_GetFighter + 0x4\n.set TM_GetStage, TM_GetCPUFighter + 0x4\n.set TM_GetEventFile, TM_GetStage + 0x4\n.set TM_GetCSSFile, TM_GetEventFile + 0x4\n.set TM_EventInit, TM_GetCSSFile + 0x4\n.set TM_OnSceneChange, TM_EventInit + 0x4 \n.set TM_OnBoot, TM_OnSceneChange + 0x4 \n.set TM_OnStartMelee, TM_OnBoot + 0x4  \n.set TM_OnFileLoad, TM_OnStartMelee + 0x4 \n.set TM_MessageDisplay, TM_OnFileLoad + 0x4\n\n#TmDt Data Pointers\n.set TM_Data,TM_tmFunction - 0x4\n\n#Scene Struct\n.set SceneController,0x80479D30\n  .set Scene.CurrentMajor,0x0\n  .set Scene.PendingMajor,0x1\n  .set Scene.PreviousMajor,0x2\n  .set Scene.CurrentMinor,0x3\n  .set Scene.PendingMinor,0x4\n  .set Scene.PreviousMinor,0x5\n#Scene ID's\n.set Scene.TitleScreen,0x00\n.set Scene.MainMenu,0x01\n.set Scene.VSMode,0x02\n.set Scene.ClassicMode,0x03\n.set Scene.AdventureMode,0x04\n.set Scene.AllStarMode,0x05\n.set Scene.MainDebugMenu,0x06\n.set Scene.SoundTestDebugMenu,0x07\n.set Scene.HanyuTestCSS,0x08\n.set Scene.HanyuTestSSS,0x09\n.set Scene.CameraModeMemcardPrompt,0x0A\n.set Scene.TrophyGallery,0x0B\n.set Scene.TrophyLottery,0x0C\n.set Scene.TrophyCollection,0x0D\n.set Scene.DebugDiarantou,0x0E\n.set Scene.TargetTest,0x0F\n.set Scene.SuperSuddenDeath,0x10\n.set Scene.InvisibleMelee,0x11\n.set Scene.SloMoMelee,0x12\n.set Scene.LightningMelee,0x13\n.set Scene.ChallengerApproaching,0x14\n.set Scene.ClassicModeEnding,0x15\n.set Scene.AdventureModeEnding,0x16\n.set Scene.AllStarModeEnding,0x17\n.set Scene.OpeningMovie,0x18\n.set Scene.VisualSceneDebug,0x19\n.set Scene.1PEndingDebug,0x1A\n.set Scene.TournamentMode,0x1B\n.set Scene.TrainingMode,0x1C\n.set Scene.TinyMelee,0x1D\n.set Scene.GiantMelee,0x1E\n.set Scene.StaminaMode,0x1F\n.set Scene.HomeRunContest,0x20\n.set Scene.10ManMelee,0x21\n.set Scene.100ManMelee,0x22\n.set Scene.3MinuteMelee,0x23\n.set Scene.15MinuteMelee,0x24\n.set Scene.EndlessMelee,0x25\n.set Scene.CruelMelee,0x26\n.set Scene.ProgressiveScanPrompt,0x27\n.set Scene.BootUp,0x28\n.set Scene.MemcardPropmt,0x29\n.set Scene.FixedCamera,0x2A\n.set Scene.EventMode,0x2B\n.set Scene.SingleButton,0x2C\n\n####################\n## Function Names ##\n####################\n\n.set ActionStateChange,0x800693ac\n.set OSReport,0x803456a8\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set AS_Wait,0x8008a2bc\n.set AS_Fall,0x800cc730\n.set AS_Catch,0x800d8c54\n.set AS_Guard,0x800939b4\n.set HSD_MemAlloc,0x8037f1e4\n.set HSD_JObjLoadJoint,0x80370e44\n.set memcpy,0x800031f4\n.set strcpy,0x80325a50\n.set ZeroAreaLength,0x8000c160\n.set CreateCameraBox,0x80029020\n.set FrameSpeedChange,0x8006f190\n.set HUD_KOCounter_UpdateKOs,0x802fa2d0\n.set Playerblock_StoreTimesR3KilledR4,0x80034fa8\n.set Playerblock_LoadTimesR3KilledR4,0x80034f24\n.set SFX_PlaySoundAtFullVolume,0x801c53ec\n.set SFX_MenuCommonSound,0x80024030\n.set AS_Rebirth,0x800d4ff4\n.set Stage_GetLeftOfLineCoordinates,0x80053ecc\n.set Stage_GetRightOfLineCoordinates,0x80053da4\n.set AS_RebirthWait,0x800d5600\n.set RebirthPlatform_UpdatePosition,0x800d54a4\n.set AS_CliffWait,0x8009a804\n.set Air_StoreBool_LoseGroundJump_NoECBfor10Frames,0x8007d5d4\n.set DataOffset_ECBBottomUpdateEnable,0x8007d5bc\n.set MovePlayerToLedge,0x80081544\n.set ApplyIntangibility,0x8007b760\n.set ApplyInvincibility,0x8007b7a4\n.set GFX_RemoveAll,0x8007db24\n.set PlayerBlock_LoadMainCharDataOffset,0x80034110\n.set PlayerBlock_SetDamage,0x80034330\n.set PlayerBlock_LoadDamage,0x800342b4\n.set StageInfo_CameraLimitLeft_Load,0x80224a54\n.set StageInfo_CameraLimitRight_Load,0x80224a68\n.set StageInfo_CameraLimitTop_Load,0x80224a80\n.set StageInfo_CameraLimitBottom_Load,0x80224a98\n.set Stage_map_gobj_Load,0x801c2ba4\n.set Stage_map_gobj_LoadJObj,0x801c3fa4\n.set Stage_Destroy_map_gobj,0x801c4a08\n.set EntityItemSpawn,0x80268b18\n.set MatchInfo_LoadSeconds,0x8016aeec\n.set MatchInfo_LoadSubSeconds,0x8016aefc\n.set EventMatch_OnWinCondition,0x801bc4f4\n.set Events_GetEventSavedScore,0x8015cf5c\n.set Events_SetEventSavedScore,0x8015cf70\n.set Textures_DisplayEffectTextures,0x8005fddc\n.set AS_GrabOpponent,0x800d9ce8\n.set AS_Grabbed,0x800daadc\n.set AS_CatchWait,0x800da1d8\n.set AS_SquatWait,0x800d62c4\n.set AS_Sleep,0x800d4f24\n.set SetAsGrounded,0x8007d7fc\n.set FrameSpeedChange,0x8006f190\n.set EnvironmentCollision_WaitLanding,0x80084280\n.set Air_SetAsGrounded,0x8007d6a4\n.set CPU_JoystickXAxis_Convert,0x800a17e4\n.set CPU_JoystickYAxis_Convert,0x800a1874\n.set Joystick_Angle_Retrieve,0x8007d9d4\n.set GFX_UpdatePlayerGFX,0x800c0408\n.set cos,0x80326240\n.set sin,0x803263d4\n.set fmod,0x80364340\n.set sqrt,0x8000d5bc\n.set HSD_Free,0x8037f1b0\n.set GObj_Create,0x803901f0\n.set GObj_AddUserData,0x80390b68\n.set GObj_Destroy,0x80390228\n.set GObj_AddProc,0x8038fd54\n.set GObj_RemoveProc,0x8038fed4\n.set GObj_StorePointerToJObj,0x80390a70\n.set GObj_AddGXLink,0x8039069c\n.set HSD_JObjSetMtxDirtySub,0x803732e8\n.set DevelopMode_FrameAdvanceCheck,0x801a45e8\n.set MatchInfo_StockModeCheck,0x8016b094\n.set PlayerBlock_LoadStocksLeft,0x80033bd8\n.set PlayerBlock_LoadSlotType,0x8003241c\n.set Playerblock_LoadStaticBlock,0x80031724\n.set Text_CreateTextStruct,0x803a6754\n.set Text_InitializeSubtext,0x803a6b98\n.set Text_UpdateSubtextSize,0x803a7548\n.set Text_UpdateSubtextPosition,0x803a746c\n.set Text_UpdateSubtextContents,0x803a70a0\n.set Text_ChangeTextColor,0x803a74f0\n.set Text_RemoveText,0x803a5cc4\n.set strlen,0x80325b04\n.set PlayerBlock_LoadExternalCharID,0x80032330\n.set PlayerBlock_GotoStaleMoveEntry_0xBC,0x80036244\n.set InitializePlayerDataValues,0x80068354\n.set Event_GetEventSavedScore,0x8015cf5c\n.set Events_CheckIfEventWasPlayedYet,0x8015cefc\n.set Events_SetEventAsPlayed,0x8015ceb4\n.set Events_StoreEventScore,0x8015cf70\n.set Interrupt_AerialJumpGoTo,0x800cb870\n.set PlayerBlock_UpdateXYCoords,0x80032828\n.set Raycast_GroundLine,0x8004f008\n.set Camera_UpdatePlayerCameraBoxPosition,0x800761c8\n.set Camera_CorrectPosition,0x8002f3ac\n.set ItemCollision_Egg,0x802895a8\n.set SFX_StopAllCharacterSFX,0x80088a50\n.set SFXManager_StopSFXIfPlaying,0x80321ce8\n.set memset,0x80003100\n.set Ragdoll_WindDecayThink,0x800115f4\n.set Inputs_GetPlayerHeldInputs,0x801a3680\n.set Inputs_GetPlayerInstantInputs,0x801a36a0\n.set Inputs_GetPlayerRapidInputs,0x801a36c0\n.set DevelopText_CreateDataTable,0x80302834\n.set DevelopText_Activate,0x80302810\n.set DevelopText_AddString,0x80302be4\n.set DevelopText_EraseAllText,0x80302bb0\n.set DevelopMode_Text_ResetCursorXY,0x80302a3c\n.set DevelopText_StoreBGColor,0x80302b90\n.set DevelopText_HideBG,0x80302ae0\n.set DevelopText_ShowBG,0x80302ad0\n.set cvt_sll_flt,0x80322da0\n.set cvt_fp2unsigned,0x803228c0\n.set sprintf,0x80323cf4\n.set PlayerBlock_LoadNameTagSlot,0x8003556c\n.set Nametag_LoadNametagSlotText,0x8023754c\n.set LoadRulesSettingsPointer1,0x8015cc34\n.set CSS_UpdateCSPInfo,0x8025db34\n.set Rumble_StoreRumbleFlag,0x8015ed4c\n\n#Custom Functions\n.set TextCreateFunction,0x80005928\n.set GetCustomEventPageName,0x8000552c\n.set SearchStringTable,0x80005530\n.set GetNumOfEventsOnCurrentPage,0x80005534\n.set GetEventTutorialFileName,0x80005538\n.set prim.new,0x804DD84C\n.set prim.close,0x804DD848\n\n#Character External IDs\n.set CaptainFalcon.Ext,0x0\n.set DK.Ext,0x1\n.set Fox.Ext,0x2\n.set GaW.Ext,0x3\n.set Kirby.Ext,0x4\n.set Bowser.Ext,0x5\n.set Link.Ext,0x6\n.set Luigi.Ext,0x7\n.set Mario.Ext,0x8\n.set Marth.Ext,0x9\n.set Mewtwo.Ext,0xA\n.set Ness.Ext,0xB\n.set Peach.Ext,0xC\n.set Pikachu.Ext,0xD\n.set IceClimbers.Ext,0xE\n.set Jigglypuff.Ext,0xF\n.set Samus.Ext,0x10\n.set Yoshi.Ext,0x11\n.set Zelda.Ext,0x12\n.set Sheik.Ext,0x13\n.set Falco.Ext,0x14\n.set YLink.Ext,0x15\n.set Doc.Ext,0x16\n.set Roy.Ext,0x17\n.set Pichu.Ext,0x18\n.set Ganondorf.Ext,0x19\n\n#Character Internal IDs\n.set Mario.Int,0x0\n.set Fox.Int,0x1\n.set CaptainFalcon.Int,0x2\n.set DK.Int,0x3\n.set Kirby.Int,0x4\n.set Bowser.Int,0x5\n.set Link.Int,0x6\n.set Sheik.Int,0x7\n.set Ness.Int,0x8\n.set Peach.Int,0x9\n.set Popo.Int,0xA\n.set Nana.Int,0xB\n.set Pikachu.Int,0xC\n.set Samus.Int,0xD\n.set Yoshi.Int,0xE\n.set Jigglypuff.Int,0xF\n.set Mewtwo.Int,0x10\n.set Luigi.Int,0x11\n.set Marth.Int,0x12\n.set Zelda.Int,0x13\n.set YLink.Int,0x14\n.set Doc.Int,0x15\n.set Falco.Int,0x16\n.set Pichu.Int,0x17\n.set GaW.Int,0x18\n.set Ganondorf.Int,0x19\n.set Roy.Int,0x1A\n\n/*\n#Character CSS ID\n.set Doc_CSSID,0x0\n.set Mario_CSSID,0x1\n.set Luigi_CSSID,0x2\n.set Bowser_CSSID,0x3\n.set Peach_CSSID,0x4\n.set Yoshi_CSSID,0x5\n.set DK_CSSID,0x6\n.set CaptainFalcon_CSSID,0x7\n.set Ganondorf_CSSID,0x8\n.set Falco_CSSID,0x9\n.set Fox_CSSID,0xA\n.set Ness_CSSID,0xB\n.set IceClimbers_CSSID,0xC\n.set Kirby_CSSID,0xD\n.set Samus_CSSID,0xE\n.set Zelda_CSSID,0xF\n.set Link_CSSID,0x10\n.set YLink_CSSID,0x11\n.set Pichu_CSSID,0x12\n.set Pikachu_CSSID,0x13\n.set Jigglypuff_CSSID,0x14\n.set Mewtwo_CSSID,0x15\n.set GaW_CSSID,0x16\n.set Marth_CSSID,0x17\n.set Roy_CSSID,0x18\n*/\n\n#Character CSS Bitflag IDs\n#(used for TM's lookup tables for displaying CSS icons)\n.set Doc_CSSID,0x1\n.set Mario_CSSID,0x2\n.set Luigi_CSSID,0x4\n.set Bowser_CSSID,0x8\n.set Peach_CSSID,0x10\n.set Yoshi_CSSID,0x20\n.set DK_CSSID,0x40\n.set CaptainFalcon_CSSID,0x80\n.set Ganondorf_CSSID,0x100\n.set Falco_CSSID,0x200\n.set Fox_CSSID,0x400\n.set Ness_CSSID,0x800\n.set IceClimbers_CSSID,0x1000\n.set Kirby_CSSID,0x2000\n.set Samus_CSSID,0x4000\n.set Zelda_CSSID,0x8000\n.set Link_CSSID,0x10000\n.set YLink_CSSID,0x20000\n.set Pichu_CSSID,0x40000\n.set Pikachu_CSSID,0x80000\n.set Jigglypuff_CSSID,0x100000\n.set Mewtwo_CSSID,0x200000\n.set GaW_CSSID,0x400000\n.set Marth_CSSID,0x800000\n.set Roy_CSSID,0x1000000\n\n#Stage External IDs\n.set FoD,0x2\n.set PokemonStadium,0x3\n.set PeachsCastle,0x4\n.set KongoJungle,0x5\n.set Brinstar,0x6\n.set Corneria,0x7\n.set YoshiStory,0x8\n.set Onett,0x9\n.set MuteCity,0xA\n.set RainbowCruise,0xB\n.set JungleJapes,0xC\n.set GreatBay,0xD\n.set HyruleTemple,0xE\n.set BrinstarDepths,0xF\n.set YoshiIsland,0x10\n.set GreenGreens,0x11\n.set Fourside,0x12\n.set MushroomKingdomI,0x13\n.set MushroomKingdomII,0x14\n.set Akaneia,0x15\n.set Venom,0x16\n.set PokeFloats,0x17\n.set BigBlue,0x18\n.set IcicleMountain,0x19\n.set IceTop,0x1A\n.set FlatZone,0x1B\n.set DreamLand,0x1C\n.set YoshiIsland64,0x1D\n.set KongoJungle64,0x1E\n.set Battlefield,0x1F\n.set FinalDestination,0x20\n\n#Button Definitions\n.set PAD_BUTTON_LEFT,0x40000\n.set PAD_BUTTON_RIGHT,0x80000\n.set PAD_BUTTON_DOWN,0x20000\n.set PAD_BUTTON_UP,0x10000\n.set PAD_BUTTON_DPAD_LEFT,0x0001\n.set PAD_BUTTON_DPAD_RIGHT,0x0002\n.set PAD_BUTTON_DPAD_DOWN,0x0004\n.set PAD_BUTTON_DPAD_UP,0x0008\n.set PAD_TRIGGER_Z,0x0010\n.set PAD_TRIGGER_R,0x0020\n.set PAD_TRIGGER_L,0x0040\n.set PAD_BUTTON_A,0x0100\n.set PAD_BUTTON_B,0x0200\n.set PAD_BUTTON_X,0x0400\n.set PAD_BUTTON_Y,0x0800\n.set PAD_BUTTON_START,0x1000\n\n#SFX Definitions\n.set SFX_cs_cancel,0xac\n.set SFX_cs_decide,0xad\n.set SFX_cs_mv,0xae\n.set SFX_cs_beep1,0xaf\n\n#########################\n## Playerblock Offsets ##\n#########################\n\n#Misc\n  .set ControllerPort,0x618\n  .set CostumeID,0x619\n#Input Data\n  .set HeldButtons,0x65C\n  .set InstantButtons,0x668\n  .set AnalogX,0x620\n  .set AnalogY,0x624\n#Animation Data\n  .set CurrentFrame,0x894\n#CPU AI Data\n  .set CPU_HeldButtons,0x1A88\n  .set CPU_AnalogX,0x1A8C\n  .set CPU_AnalogY,0x1A8D\n  .set CPU_CStickX,0x1A8E\n  .set CPU_CStickY,0x1A8F\n  .set CPU_LAnalog,0x1A90\n  .set CPU_RAnalog,0x1A91\n\n#############################\n## Player Action State IDs ##\n#############################\n.set ASID_DeadDown, 0x00\n.set ASID_DeadLeft, 0x01\n.set ASID_DeadRight, 0x02\n.set ASID_DeadUp, 0x03\n.set ASID_DeadUpStar, 0x04\n.set ASID_DeadUpStarIce, 0x05\n.set ASID_DeadUpFall, 0x06\n.set ASID_DeadUpFallHitCamera, 0x07\n.set ASID_DeadUpFallHitCameraFlat, 0x08\n.set ASID_DeadUpFallIce, 0x09\n.set ASID_DeadUpFallHitCameraIce, 0x0A\n.set ASID_Sleep, 0x0B\n.set ASID_Rebirth, 0x0C\n.set ASID_RebirthWait, 0x0D\n.set ASID_Wait, 0x0E\n.set ASID_WalkSlow, 0x0F\n.set ASID_WalkMiddle, 0x10\n.set ASID_WalkFast, 0x11\n.set ASID_Turn, 0x12\n.set ASID_TurnRun, 0x13\n.set ASID_Dash, 0x14\n.set ASID_Run, 0x15\n.set ASID_RunDirect, 0x16\n.set ASID_RunBrake, 0x17\n.set ASID_KneeBend, 0x18\n.set ASID_JumpF, 0x19\n.set ASID_JumpB, 0x1A\n.set ASID_JumpAerialF, 0x1B\n.set ASID_JumpAerialB, 0x1C\n.set ASID_Fall, 0x1D\n.set ASID_FallF, 0x1E\n.set ASID_FallB, 0x1F\n.set ASID_FallAerial, 0x20\n.set ASID_FallAerialF, 0x21\n.set ASID_FallAerialB, 0x22\n.set ASID_FallSpecial, 0x23\n.set ASID_FallSpecialF, 0x24\n.set ASID_FallSpecialB, 0x25\n.set ASID_DamageFall, 0x26\n.set ASID_Squat, 0x27\n.set ASID_SquatWait, 0x28\n.set ASID_SquatRv, 0x29\n.set ASID_Landing, 0x2A\n.set ASID_LandingFallSpecial, 0x2B\n.set ASID_Attack11, 0x2C\n.set ASID_Attack12, 0x2D\n.set ASID_Attack13, 0x2E\n.set ASID_Attack100Start, 0x2F\n.set ASID_Attack100Loop, 0x30\n.set ASID_Attack100End, 0x31\n.set ASID_AttackDash, 0x32\n.set ASID_AttackS3Hi, 0x33\n.set ASID_AttackS3HiS, 0x34\n.set ASID_AttackS3S, 0x35\n.set ASID_AttackS3LwS, 0x36\n.set ASID_AttackS3Lw, 0x37\n.set ASID_AttackHi3, 0x38\n.set ASID_AttackLw3, 0x39\n.set ASID_AttackS4Hi, 0x3A\n.set ASID_AttackS4HiS, 0x3B\n.set ASID_AttackS4S, 0x3C\n.set ASID_AttackS4LwS, 0x3D\n.set ASID_AttackS4Lw, 0x3E\n.set ASID_AttackHi4, 0x3F\n.set ASID_AttackLw4, 0x40\n.set ASID_AttackAirN, 0x41\n.set ASID_AttackAirF, 0x42\n.set ASID_AttackAirB, 0x43\n.set ASID_AttackAirHi, 0x44\n.set ASID_AttackAirLw, 0x45\n.set ASID_LandingAirN, 0x46\n.set ASID_LandingAirF, 0x47\n.set ASID_LandingAirB, 0x48\n.set ASID_LandingAirHi, 0x49\n.set ASID_LandingAirLw, 0x4A\n.set ASID_DamageHi1, 0x4B\n.set ASID_DamageHi2, 0x4C\n.set ASID_DamageHi3, 0x4D\n.set ASID_DamageN1, 0x4E\n.set ASID_DamageN2, 0x4F\n.set ASID_DamageN3, 0x50\n.set ASID_DamageLw1, 0x51\n.set ASID_DamageLw2, 0x52\n.set ASID_DamageLw3, 0x53\n.set ASID_DamageAir1, 0x54\n.set ASID_DamageAir2, 0x55\n.set ASID_DamageAir3, 0x56\n.set ASID_DamageFlyHi, 0x57\n.set ASID_DamageFlyN, 0x58\n.set ASID_DamageFlyLw, 0x59\n.set ASID_DamageFlyTop, 0x5A\n.set ASID_DamageFlyRoll, 0x5B\n.set ASID_LightGet, 0x5C\n.set ASID_HeavyGet, 0x5D\n.set ASID_LightThrowF, 0x5E\n.set ASID_LightThrowB, 0x5F\n.set ASID_LightThrowHi, 0x60\n.set ASID_LightThrowLw, 0x61\n.set ASID_LightThrowDash, 0x62\n.set ASID_LightThrowDrop, 0x63\n.set ASID_LightThrowAirF, 0x64\n.set ASID_LightThrowAirB, 0x65\n.set ASID_LightThrowAirHi, 0x66\n.set ASID_LightThrowAirLw, 0x67\n.set ASID_HeavyThrowF, 0x68\n.set ASID_HeavyThrowB, 0x69\n.set ASID_HeavyThrowHi, 0x6A\n.set ASID_HeavyThrowLw, 0x6B\n.set ASID_LightThrowF4, 0x6C\n.set ASID_LightThrowB4, 0x6D\n.set ASID_LightThrowHi4, 0x6E\n.set ASID_LightThrowLw4, 0x6F\n.set ASID_LightThrowAirF4, 0x70\n.set ASID_LightThrowAirB4, 0x71\n.set ASID_LightThrowAirHi4, 0x72\n.set ASID_LightThrowAirLw4, 0x73\n.set ASID_HeavyThrowF4, 0x74\n.set ASID_HeavyThrowB4, 0x75\n.set ASID_HeavyThrowHi4, 0x76\n.set ASID_HeavyThrowLw4, 0x77\n.set ASID_SwordSwing1, 0x78\n.set ASID_SwordSwing3, 0x79\n.set ASID_SwordSwing4, 0x7A\n.set ASID_SwordSwingDash, 0x7B\n.set ASID_BatSwing1, 0x7C\n.set ASID_BatSwing3, 0x7D\n.set ASID_BatSwing4, 0x7E\n.set ASID_BatSwingDash, 0x7F\n.set ASID_ParasolSwing1, 0x80\n.set ASID_ParasolSwing3, 0x81\n.set ASID_ParasolSwing4, 0x82\n.set ASID_ParasolSwingDash, 0x83\n.set ASID_HarisenSwing1, 0x84\n.set ASID_HarisenSwing3, 0x85\n.set ASID_HarisenSwing4, 0x86\n.set ASID_HarisenSwingDash, 0x87\n.set ASID_StarRodSwing1, 0x88\n.set ASID_StarRodSwing3, 0x89\n.set ASID_StarRodSwing4, 0x8A\n.set ASID_StarRodSwingDash, 0x8B\n.set ASID_LipStickSwing1, 0x8C\n.set ASID_LipStickSwing3, 0x8D\n.set ASID_LipStickSwing4, 0x8E\n.set ASID_LipStickSwingDash, 0x8F\n.set ASID_ItemParasolOpen, 0x90\n.set ASID_ItemParasolFall, 0x91\n.set ASID_ItemParasolFallSpecial, 0x92\n.set ASID_ItemParasolDamageFall, 0x93\n.set ASID_LGunShoot, 0x94\n.set ASID_LGunShootAir, 0x95\n.set ASID_LGunShootEmpty, 0x96\n.set ASID_LGunShootAirEmpty, 0x97\n.set ASID_FireFlowerShoot, 0x98\n.set ASID_FireFlowerShootAir, 0x99\n.set ASID_ItemScrew, 0x9A\n.set ASID_ItemScrewAir, 0x9B\n.set ASID_DamageScrew, 0x9C\n.set ASID_DamageScrewAir, 0x9D\n.set ASID_ItemScopeStart, 0x9E\n.set ASID_ItemScopeRapid, 0x9F\n.set ASID_ItemScopeFire, 0xA0\n.set ASID_ItemScopeEnd, 0xA1\n.set ASID_ItemScopeAirStart, 0xA2\n.set ASID_ItemScopeAirRapid, 0xA3\n.set ASID_ItemScopeAirFire, 0xA4\n.set ASID_ItemScopeAirEnd, 0xA5\n.set ASID_ItemScopeStartEmpty, 0xA6\n.set ASID_ItemScopeRapidEmpty, 0xA7\n.set ASID_ItemScopeFireEmpty, 0xA8\n.set ASID_ItemScopeEndEmpty, 0xA9\n.set ASID_ItemScopeAirStartEmpty, 0xAA\n.set ASID_ItemScopeAirRapidEmpty, 0xAB\n.set ASID_ItemScopeAirFireEmpty, 0xAC\n.set ASID_ItemScopeAirEndEmpty, 0xAD\n.set ASID_LiftWait, 0xAE\n.set ASID_LiftWalk1, 0xAF\n.set ASID_LiftWalk2, 0xB0\n.set ASID_LiftTurn, 0xB1\n.set ASID_GuardOn, 0xB2\n.set ASID_Guard, 0xB3\n.set ASID_GuardOff, 0xB4\n.set ASID_GuardSetOff, 0xB5\n.set ASID_GuardReflect, 0xB6\n.set ASID_DownBoundU, 0xB7\n.set ASID_DownWaitU, 0xB8\n.set ASID_DownDamageU, 0xB9\n.set ASID_DownStandU, 0xBA\n.set ASID_DownAttackU, 0xBB\n.set ASID_DownFowardU, 0xBC\n.set ASID_DownBackU, 0xBD\n.set ASID_DownSpotU, 0xBE\n.set ASID_DownBoundD, 0xBF\n.set ASID_DownWaitD, 0xC0\n.set ASID_DownDamageD, 0xC1\n.set ASID_DownStandD, 0xC2\n.set ASID_DownAttackD, 0xC3\n.set ASID_DownFowardD, 0xC4\n.set ASID_DownBackD, 0xC5\n.set ASID_DownSpotD, 0xC6\n.set ASID_Passive, 0xC7\n.set ASID_PassiveStandF, 0xC8\n.set ASID_PassiveStandB, 0xC9\n.set ASID_PassiveWall, 0xCA\n.set ASID_PassiveWallJump, 0xCB\n.set ASID_PassiveCeil, 0xCC\n.set ASID_ShieldBreakFly, 0xCD\n.set ASID_ShieldBreakFall, 0xCE\n.set ASID_ShieldBreakDownU, 0xCF\n.set ASID_ShieldBreakDownD, 0xD0\n.set ASID_ShieldBreakStandU, 0xD1\n.set ASID_ShieldBreakStandD, 0xD2\n.set ASID_FuraFura, 0xD3\n.set ASID_Catch, 0xD4\n.set ASID_CatchPull, 0xD5\n.set ASID_CatchDash, 0xD6\n.set ASID_CatchDashPull, 0xD7\n.set ASID_CatchWait, 0xD8\n.set ASID_CatchAttack, 0xD9\n.set ASID_CatchCut, 0xDA\n.set ASID_ThrowF, 0xDB\n.set ASID_ThrowB, 0xDC\n.set ASID_ThrowHi, 0xDD\n.set ASID_ThrowLw, 0xDE\n.set ASID_CapturePulledHi, 0xDF\n.set ASID_CaptureWaitHi, 0xE0\n.set ASID_CaptureDamageHi, 0xE1\n.set ASID_CapturePulledLw, 0xE2\n.set ASID_CaptureWaitLw, 0xE3\n.set ASID_CaptureDamageLw, 0xE4\n.set ASID_CaptureCut, 0xE5\n.set ASID_CaptureJump, 0xE6\n.set ASID_CaptureNeck, 0xE7\n.set ASID_CaptureFoot, 0xE8\n.set ASID_EscapeF, 0xE9\n.set ASID_EscapeB, 0xEA\n.set ASID_Escape, 0xEB\n.set ASID_EscapeAir, 0xEC\n.set ASID_ReboundStop, 0xED\n.set ASID_Rebound, 0xEE\n.set ASID_ThrownF, 0xEF\n.set ASID_ThrownB, 0xF0\n.set ASID_ThrownHi, 0xF1\n.set ASID_ThrownLw, 0xF2\n.set ASID_ThrownLwWomen, 0xF3\n.set ASID_Pass, 0xF4\n.set ASID_Ottotto, 0xF5\n.set ASID_OttottoWait, 0xF6\n.set ASID_FlyReflectWall, 0xF7\n.set ASID_FlyReflectCeil, 0xF8\n.set ASID_StopWall, 0xF9\n.set ASID_StopCeil, 0xFA\n.set ASID_MissFoot, 0xFB\n.set ASID_CliffCatch, 0xFC\n.set ASID_CliffWait, 0xFD\n.set ASID_CliffClimbSlow, 0xFE\n.set ASID_CliffClimbQuick, 0xFF\n.set ASID_CliffAttackSlow, 0x100\n.set ASID_CliffAttackQuick, 0x101\n.set ASID_CliffEscapeSlow, 0x102\n.set ASID_CliffEscapeQuick, 0x103\n.set ASID_CliffJumpSlow1, 0x104\n.set ASID_CliffJumpSlow2, 0x105\n.set ASID_CliffJumpQuick1, 0x106\n.set ASID_CliffJumpQuick2, 0x107\n.set ASID_AppealR, 0x108\n.set ASID_AppealL, 0x109\n.set ASID_ShoulderedWait, 0x10A\n.set ASID_ShoulderedWalkSlow, 0x10B\n.set ASID_ShoulderedWalkMiddle, 0x10C\n.set ASID_ShoulderedWalkFast, 0x10D\n.set ASID_ShoulderedTurn, 0x10E\n.set ASID_ThrownFF, 0x10F\n.set ASID_ThrownFB, 0x110\n.set ASID_ThrownFHi, 0x111\n.set ASID_ThrownFLw, 0x112\n.set ASID_CaptureCaptain, 0x113\n.set ASID_CaptureYoshi, 0x114\n.set ASID_YoshiEgg, 0x115\n.set ASID_CaptureKoopa, 0x116\n.set ASID_CaptureDamageKoopa, 0x117\n.set ASID_CaptureWaitKoopa, 0x118\n.set ASID_ThrownKoopaF, 0x119\n.set ASID_ThrownKoopaB, 0x11A\n.set ASID_CaptureKoopaAir, 0x11B\n.set ASID_CaptureDamageKoopaAir, 0x11C\n.set ASID_CaptureWaitKoopaAir, 0x11D\n.set ASID_ThrownKoopaAirF, 0x11E\n.set ASID_ThrownKoopaAirB, 0x11F\n.set ASID_CaptureKirby, 0x120\n.set ASID_CaptureWaitKirby, 0x121\n.set ASID_ThrownKirbyStar, 0x122\n.set ASID_ThrownCopyStar, 0x123\n.set ASID_ThrownKirby, 0x124\n.set ASID_BarrelWait, 0x125\n.set ASID_Bury, 0x126\n.set ASID_BuryWait, 0x127\n.set ASID_BuryJump, 0x128\n.set ASID_DamageSong, 0x129\n.set ASID_DamageSongWait, 0x12A\n.set ASID_DamageSongRv, 0x12B\n.set ASID_DamageBind, 0x12C\n.set ASID_CaptureMewtwo, 0x12D\n.set ASID_CaptureMewtwoAir, 0x12E\n.set ASID_ThrownMewtwo, 0x12F\n.set ASID_ThrownMewtwoAir, 0x130\n.set ASID_WarpStarJump, 0x131\n.set ASID_WarpStarFall, 0x132\n.set ASID_HammerWait, 0x133\n.set ASID_HammerWalk, 0x134\n.set ASID_HammerTurn, 0x135\n.set ASID_HammerKneeBend, 0x136\n.set ASID_HammerFall, 0x137\n.set ASID_HammerJump, 0x138\n.set ASID_HammerLanding, 0x139\n.set ASID_KinokoGiantStart, 0x13A\n.set ASID_KinokoGiantStartAir, 0x13B\n.set ASID_KinokoGiantEnd, 0x13C\n.set ASID_KinokoGiantEndAir, 0x13D\n.set ASID_KinokoSmallStart, 0x13E\n.set ASID_KinokoSmallStartAir, 0x13F\n.set ASID_KinokoSmallEnd, 0x140\n.set ASID_KinokoSmallEndAir, 0x141\n.set ASID_Entry, 0x142\n.set ASID_EntryStart, 0x143\n.set ASID_EntryEnd, 0x144\n.set ASID_DamageIce, 0x145\n.set ASID_DamageIceJump, 0x146\n.set ASID_CaptureMasterhand, 0x147\n.set ASID_CapturedamageMasterhand, 0x148\n.set ASID_CapturewaitMasterhand, 0x149\n.set ASID_ThrownMasterhand, 0x14A\n.set ASID_CaptureKirbyYoshi, 0x14B\n.set ASID_KirbyYoshiEgg, 0x14C\n.set ASID_CaptureLeadead, 0x14D\n.set ASID_CaptureLikelike, 0x14E\n.set ASID_DownReflect, 0x14F\n.set ASID_CaptureCrazyhand, 0x150\n.set ASID_CapturedamageCrazyhand, 0x151\n.set ASID_CapturewaitCrazyhand, 0x152\n.set ASID_ThrownCrazyhand, 0x153\n.set ASID_BarrelCannonWait, 0x154\n\n\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro rtocbl reg, offset\nlwz \\reg,\\offset(rtoc)\nmtctr \\reg\nbctrl\n.endm\n\n/*\n.macro branchl reg, address\n.long \\address ^ 0x80<<24 | 0xC8<<24\n.endm\n*/\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n .macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro backupall\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r3,0x8(r1)\n.endm\n\n.macro restoreall\nlmw  r3,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.set R13_EventVars, -0x4A0C\n.set EventVars_MessageDisplay, (8 * 4)\n\n#Message Display\n.macro Message_Display\ncrset 6\nrtocbl r12,TM_MessageDisplay\n.endm\n\n.set MsgData_Text,0x0\n\n.set MSGCOLOR_WHITE, 0\n.set MSGCOLOR_GREEN, 1\n.set MSGCOLOR_RED, 2\n.set MSGCOLOR_YELLOW, 3\n"
  },
  {
    "path": "ASM/training-mode/Hooks/OnBoot.asm",
    "content": "#To be inserted at 801bfa28\n.include \"../Globals.s\"\n.include \"../../m-ex/Header.s\"\n\n#Call function in TmDt\n  rtocbl  r12,TM_OnBoot\n\n#Original Line\n  lwz\tr0, 0x001C (sp)\n  "
  },
  {
    "path": "ASM/training-mode/Hooks/OnCSSLoad.asm",
    "content": "#To be inserted at 80266810\n.include \"../Globals.s\"\n.include \"../../m-ex/Header.s\"\n\nbackup\n\n# Check if event scene\n  load r3,SceneController\n  lbz r3,Scene.CurrentMajor(r3)\n  cmpwi r3,Scene.EventMode\n  bne Exit\n\n\n# Init pointer as 0\n  li  r3,0\n  stw  r3,0x80(sp)\n\n# Get file string \n  lwz r3,MemcardData(r13)\n  lbz r3,CurrentEventPage(r3)\n\tlwz\tr4, -0x77C0 (r13)\n\tlbz\tr4, 0x0535 (r4)\n  rtocbl r12,TM_GetCSSFile\n  cmpwi r3,0\n  beq Exit\n\n# Load this file\n  addi  r4,sp,0x80\n  bl  SymbolName\n  mflr  r5\n  branchl r12,0x803d7080\n\n# Execute the function\n  lwz  r12,0x80(sp)\n  cmpwi r12,0\n  beq Exit\n  mtctr r12\n  bctrl  \n  \n  b Exit\n\nSymbolName:\nblrl\n.string \"cssFunction\"\n.align 2\n\nExit:\n# Original Line\n  restore\n  lwz\tr3, -0x49F0 (r13)\n  "
  },
  {
    "path": "ASM/training-mode/Hooks/OnSceneChange.asm",
    "content": "#To be inserted at 801a4c94\n.include \"../Globals.s\"\n.include \"../../m-ex/Header.s\"\n\n#Original Line\n  stw\tr3, -0x4F74 (r13)\n\n#Call function in TmDt\n  rtocbl  r12,TM_OnSceneChange\n"
  },
  {
    "path": "ASM/training-mode/Hooks/OnStartMelee.asm",
    "content": "#To be inserted at 8016e8c8\n.include \"../Globals.s\"\n.include \"../../m-ex/Header.s\"\n\n#Call function in TmDt\n  rtocbl  r12,TM_OnStartMelee\n\n#Original Line\n  lwz\tr12, 0x0044 (r31)"
  },
  {
    "path": "ASM/training-mode/Misc/Adjust Pad Params/Adjust Menu Navigation Deadzone Boot.asm",
    "content": "#To be inserted at 80406dc0\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set Deadzone,40\n\n.byte 00\n.byte Deadzone\n.byte 00\n.byte 00\n"
  },
  {
    "path": "ASM/training-mode/Misc/Adjust Pad Params/Adjust Menu Navigation Deadzone.asm",
    "content": "#To be inserted at 804c1f8c\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set Deadzone,40\n\n.byte 00\n.byte Deadzone\n.byte 00\n.byte 00\n"
  },
  {
    "path": "ASM/training-mode/Misc/Adjust Pad Params/Increase Rapid Fire Timer.s",
    "content": "#To be inserted at 8037797c\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set AltTimer,3\n\n# Check if R is held\n    lwz r0,0x0(r26)\n    rlwinm. r0,r0,0,0x20\n    beq Original\n# Use new timer\n    li  r0,AltTimer\n    b   Exit\n\nOriginal:\n# Original timer\nlwz\tr0, 0x0010 (r30)\n\nExit:"
  },
  {
    "path": "ASM/training-mode/Misc/Better VS Mode Frame Counter/Inc Counter.asm",
    "content": "#To be inserted at 8016d310\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nlwz r3,TM_GameFrameCounter(r13)\naddi r3,r3,1\nstw r3,TM_GameFrameCounter(r13)\n\nExit:\n  lwz\tr31, 0x0034 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Misc/Better VS Mode Frame Counter/Init Counter.asm",
    "content": "#To be inserted at 8016e744\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nli  r3,0\nstw r3,TM_GameFrameCounter(r13)\n\nExit:\n  stw\tr30, 0x0018 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Misc/Boot Up Tasks.asm",
    "content": "#To be inserted at 801b02ec\n.include \"../Globals.s\"\n.include \"../../m-ex/Header.s\"\n\n.set entity,31\n.set player,31\n.set playerdata,31\n\nOnBootup\n\nOriginal:\n  lwz\tr0, 0x001C (sp)\n"
  },
  {
    "path": "ASM/training-mode/Misc/CSS - Increase SIS Text Heap.asm",
    "content": "#To be inserted at 801a3f9c\n.include \"../Globals.s\"\n.include \"../../m-ex/Header.s\"\n\nli  r3, 18432"
  },
  {
    "path": "ASM/training-mode/Misc/Corneria - Move Ship on Stage Init.asm",
    "content": "#To be inserted at 801dd980\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n .macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n/*\nI honestly cant believe this code is needed. Melee spawns the players at Y coordinate 300,\nbut the stage starts at Y coordinate 0. Because of this, when i get the coordinate of the\nground ID i want to spawn the players over, corneria is technically IN THE BLASTZONE.\nTherefore, i spawn the players in the blastzone and it loads state on death, so it infinitely\nkills the players and eventually crashes.\n\nThis code changes corneria's initialization code to move the ship, instead of waiting for the\nper frame think function to do it. This way the stage is in the right position when i\nrequest the coordinates.\n*/\n\n#Move Corneria\n  mr r3,r30\n  branchl r12,0x801c2fe0\n\n#Original Codeline\nlwz\tr0, 0x0034 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Misc/Count NonExistant Player Kills.asm",
    "content": "#To be inserted at 801bc59c\nnop"
  },
  {
    "path": "ASM/training-mode/Misc/Disable Calls to ScoreDisplay_Remove.asm",
    "content": "#To be inserted at 802ff4fc\nblr\n"
  },
  {
    "path": "ASM/training-mode/Misc/Disable USB Screenshot.asm",
    "content": "#To be inserted at 801a5070\n.include \"../Globals.s\"\n.include \"../../m-ex/Header.s\"\n\nnop\n"
  },
  {
    "path": "ASM/training-mode/Misc/Display Stick Info When Paused/Create Text on Pause.asm",
    "content": "#To be inserted at 801a10e8\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set text,31\n.set textproperties,30\n.set staticTextData,29\n.set inputStruct,28\n.set GObj,31\n\nbackup\n\n#Only in Event Mode\n  load r3,SceneController\n  lbz r3,Scene.CurrentMajor(r3)\n  cmpwi r3,Scene.EventMode\n  bne Exit\n\nload staticTextData,0x804a1f58\n\n#CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3\n\tli r3,2\n  lwz  r4,0x0(staticTextData)\n\tbranchl r12,0x803a6754\n  mr  text,r3\n\n#Store pointer to text\n  stw  r3,0x8(staticTextData)\n\n#Get Properties\n\tbl Text_Properties\n\tmflr textproperties\n\n#Check Who Paused\n  load r3,0x8046b69c\n  lbz  r3,0x5(r3)\n#Get Inputs\n  mulli r3,r3,68\n  load r4,0x804c21cc\n  add  inputStruct,r3,r4\n\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x0\n\tstb r4,0x49(text)\n\n#SET TEXT TO NOT CENTER AROUND X LOCATION\n\tli r4,0x0\n\tstb r4,0x4A(text)\n\n#Change Background Text Color\n  li  r3,0x0\n  stw r3,0x30(text)\n#Init Background Text\n  mr \t  r3,text\t\t#struct pointer\n  lfs \tf1,0x10(textproperties)\t\t#X offset of text\n  lfs \tf2,0x14(textproperties) \t\t#Y offset of text\n  bl    TextBackground\n  mflr  r4\n  branchl r12,0x803a6b98\n#set size/scaling\n  mr  r4,r3\n  mr\tr3,text\n  lfs\tf1,0x18(textproperties) #get text scaling value from table\n  lfs\tf2,0x1C(textproperties) #get text scaling value from table\n  branchl\tr12,0x803a7548\n\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x1\n\tstb r4,0x49(text)\n\n#Init Textline X\n\tmr \t  r3,text\t\t#struct pointer\n\tlfs \tf1,0x0(textproperties)\t\t#X offset of text\n\tlfs \tf2,0x4(textproperties) \t\t#Y offset of text\n\tbl    TextX\n  mflr  r4\n  lbz r5,0x18(inputStruct)\n  lfs\tf3,0x20(inputStruct)\n  crset\t6\n\tbranchl r12,0x803a6b98\n#set size/scaling\n  mr  r4,r3\n\tmr\tr3,text\n\tlfs\tf1,0x8(textproperties) #get text scaling value from table\n\tlfs\tf2,0x8(textproperties) #get text scaling value from table\n\tbranchl\tr12,0x803a7548\n\n#Init Textline Y\n  mr \t  r3,text\t\t#struct pointer\n  lfs \tf1,0x0(textproperties)\t\t#X offset of text\n  lfs \tf2,0xC(textproperties) \t\t#Y offset of text\n  bl    TextY\n  mflr  r4\n  lbz r5,0x19(inputStruct)\n  lfs\tf3,0x24(inputStruct)\n  crset\t6\n  branchl r12,0x803a6b98\n#set size/scaling\n  mr  r4,r3\n\tmr\tr3,text\n\tlfs\tf1,0x8(textproperties) #get text scaling value from table\n\tlfs\tf2,0x8(textproperties) #get text scaling value from table\n\tbranchl\tr12,0x803a7548\n\n###############################\n## Schedule Updater Function ##\n###############################\n\n#Create GObj\n\tli\tr3, 6\n\tli\tr4, 0\n\tli\tr5, 128\n\tbranchl\tr12,0x803901f0\n\tmr\tGObj,r3\n\n#Store Pointer\n  stw GObj,0xC(staticTextData)\n\n#Attach Per Frame Process\n\tmr\tr3,GObj\n\tbl\tTextUpdateFunction\n\tmflr\tr4\n\tli\tr5,10\n\tbranchl\tr12,0x8038fd54\n\n\nb Exit\n\n#**************************************************#\n\nTextBackground:\nblrl\n.long 0x815B0000\n\nTextX:\nblrl\n.long 0x583a2025\n.long 0x342e3466\n.long 0x20815e20\n.long 0x25640000\n\nTextY:\nblrl\n.long 0x593a2025\n.long 0x342e3466\n.long 0x20815e20\n.long 0x25640000\n\n#**************************************************#\n\nText_Properties:\nblrl\n.long 0xC1D80000 #X VALUE x offset (-27)\n.long 0xC1B80000 #X VALUE y offset (-23)\n.long 0x3D4CCCCD #XANDY text scaling\n.long 0xC1A80000 #Y VALUE y offset (-21)\n.long 0xC1E80000 #background x offset (-29)\n.long 0xC1000000 #background y offset (-8)\n.float 0.50      #background X text scaling #0.56\n.float 1.08      #background Y text scaling #1.08\n\n#***************************************************#\n\nTextUpdateFunction:\n  blrl\n  backup\n\n#Get Text Info\n  load staticTextData,0x804a1f58\n  lwz text,0x8(staticTextData)\n\n#Check Who Paused\n  load r3,0x8046b69c\n  lbz  r3,0x5(r3)\n#Get Inputs\n  mulli r3,r3,68\n  load r4,0x804c21cc\n  add  inputStruct,r3,r4\n\n#Update X Color\n  lbz r6,0x18(inputStruct)\n  extsb r6,r6\n  cmpwi r6,0x0\n  blt XNeg\n  XPos:\n\tload\tr3,0x8dff6eff\n  b XUpdateColor\n  XNeg:\n\tload\tr3,0xffa2baff\n  b XUpdateColor\nXUpdateColor:\n  stw r3,0xF8(sp)\n  mr  r3,text\n  li  r4,1\n  addi  r5,sp,0xF8\n  branchl r12,0x803a74f0\n\n#Update Textline X\n\tmr \t  r3,text\t\t#struct pointer\n  li    r4,1\n\tbl    TextX\n  mflr  r5\n  lbz r6,0x18(inputStruct)\n  extsb r6,r6\n  cmpwi r6,0\n  bge 0x8\n  neg r6,r6\n  lfs\tf1,0x20(inputStruct)\n  fabs  f1,f1\n  crset\t6\n\tbranchl r12,0x803a70a0\n\n#Update Y Color\n  lbz r6,0x19(inputStruct)\n  extsb r6,r6\n  cmpwi r6,0x0\n  blt YNeg\n  YPos:\n\tload\tr3,0x8dff6eff\n  b YUpdateColor\n  YNeg:\n\tload\tr3,0xffa2baff\n  b YUpdateColor\nYUpdateColor:\n  stw r3,0xF8(sp)\n  mr  r3,text\n  li  r4,2\n  addi  r5,sp,0xF8\n  branchl r12,0x803a74f0\n\n#Update Textline Y\n  mr \t  r3,text\t\t#struct pointer\n  li    r4,2\n  bl    TextY\n  mflr  r5\n  lbz r6,0x19(inputStruct)\n  extsb r6,r6\n  cmpwi r6,0\n  bge 0x8\n  neg r6,r6\n  lfs\tf1,0x24(inputStruct)\n  fabs  f1,f1\n  crset\t6\n  branchl r12,0x803a70a0\n\n  restore\n  blr\n\n  #***************************************************#\n\nExit:\nrestore\nlmw\tr26, 0x0018 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Misc/Display Stick Info When Paused/Remove Text on UnPause.asm",
    "content": "#To be inserted at 801a1124\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set FFVar,0x240C\n\n#Only in Event Mode\n  load r3,SceneController\n  lbz r3,Scene.CurrentMajor(r3)\n  cmpwi r3,Scene.EventMode\n  bne Exit\n\n#Get Text Struct\n  load r3,0x804a1f58\n  lwz r3,0x8(r3)\n#Remove Text Struct\n  branchl r12,0x803a5cc4\n\n#Get GObj\n  load r5,0x804a1f58\n  lwz r3,0xC(r5)\n#Zero Out Data\n  li  r4,0\n  stw r4,0x8(r5)\n  stw r4,0xC(r5)\n#Remove GObj\n  branchl r12,0x80390228\n\nExit:\n#Original Codeline\n  lwz\tr0, 0x000C (sp)\n"
  },
  {
    "path": "ASM/training-mode/Misc/Display Tweet Message And Version Number.asm",
    "content": "#To be inserted at 80394a6c\n.include \"../Globals.s\"\n\n.set VersionString,0x8040a58c\n\n# Remove all previous OSReports\n  #load r3,0x804cf7e8\n  #li  r4,0\n  #stw r4,0xC(r3)\n\n# Play SFX?\n  li r3, 317 #188 = warning #317 = gasp\n  branchl r12,0x801c53ec\n\n#############################\n## OS Report Tweet Message ##\n#############################\n\nload\tr20,0x803456a8\t\t\t#OSReport\n\n#OSReport Blank Line\n  bl\tNewLine\n  mflr\tr3\n  mtctr\tr20\n  bctrl\n\n#OSReport # Line\n  bl\tPoundLine\n  mflr\tr3\n  mtctr\tr20\n  bctrl\n\n#OSReport Error Message\n  bl\tResetCombo    #StackDumpMessage1\n  mflr\tr3\n  mtctr\tr20\n  bctrl\n\n#OSReport # Line\n  bl\tPoundLine\n  mflr\tr3\n  mtctr\tr20\n  bctrl\n\n#OSReport Blank Line\n  bl\tNewLine\n  mflr\tr3\n  mtctr\tr20\n  bctrl\n\n#OSReport Mod Version\n\trtocbl r12,TM_GetTMVersLong\n\tmr\tr4,r3\n  bl\tVersion\n  mflr\tr3\n  mtctr\tr20\n  bctrl\n\n#OSReport Compile Date\n  rtocbl r12,TM_GetTMCompile\n  mtctr\tr20\n  bctrl\n\n#OSReport Blank Line\n  bl\tNewLine\n  mflr\tr3\n  mtctr\tr20\n  bctrl\n\nb\tExit\n\n#########################################################\n\nPoundLine:\nblrl\n.long 0x23232323\n.long 0x23232323\n.long 0x23232323\n.long 0x23232323\n.long 0x23232323\n.long 0x23232323\n.long 0x23232323\n.long 0x23232323\n.long 0x23232323\n.long 0x23232323\n.long 0x23232323\n.long 0x23232323\n.long 0x23232323\n.long 0x230A0000\n\nNewLine:\nblrl\n.long 0x0A000000\n\nVersion:\nblrl\n.string \"%s\\n\"\n.align 2\n\nResetCombo:\nblrl\n.string \"## TWEET A PICTURE OF THIS MESSAGE TO @UnclePunch_ ##\\n##   After submitting, PRESS LRA-START to reboot   ##\\n\"\n.align 2\n\n#########################################################\n\nExit:\naddi\tr3, r30, 2252\n"
  },
  {
    "path": "ASM/training-mode/Misc/Do Not Save Nametag Region to Memcard for GALE01.asm",
    "content": "#To be inserted at 8001ae8c\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw\tr3,8(r1)\t# push r20-r31 onto the stack\nmflr r0\nstw r0,0xFC(sp)\n.endm\n\n.macro restore\nlwz r0,0xFC(sp)\nmtlr r0\nlmw\tr3,8(r1)\t# pop r20-r31 off the stack\naddi\tr1,r1,0x100\t# release the space\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n.set TextCreateFunction,0x80005928\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n#Check If Save Chunk #2 and #3\ncmpwi\tr25,0x2\nbeq\tSkipSave\ncmpwi\tr25,0x3\nbeq\tSkipSave\nb\toriginal\n\n#Check For Game ID GALE01 (Memcard Only)\nSkipSave:\nlis\tr3,0x8000\nlwz\tr3,0x0(r3)\nload\tr4,0x47414c45\t\t#GALE\ncmpw\tr3,r4\nbne\toriginal\nli\tr0,0\nb\texit\n\noriginal:\nlwz\tr0, 0x00F4 (r31)\nexit:\n\n\n\n\n"
  },
  {
    "path": "ASM/training-mode/Misc/Edit Carrot Texture.s",
    "content": "#To be inserted at 8042a760\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00144444\n.long 0x008FFFFF\n.long 0x008FFFFF\n.long 0x00EFFFFD\n.long 0x02FFFFF8\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x44441000\n.long 0xFFFF8000\n.long 0xFFFF8000\n.long 0xFFFFE000\n.long 0xFFFFF200\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000002\n.long 0x00000008\n.long 0x08FFFFD1\n.long 0x0BFFFFB0\n.long 0x1EFFFF80\n.long 0x4FFFFF40\n.long 0x8FFFFF10\n.long 0xDFFFFD00\n.long 0xFFFFF800\n.long 0xFFFFF800\n.long 0xDFFFF800\n.long 0xBFFFFB00\n.long 0x8FFFFE10\n.long 0x4FFFFF40\n.long 0x1FFFFF80\n.long 0x0DFFFFD0\n.long 0x08FFFFF2\n.long 0x08FFFFF8\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000008\n.long 0x0000000D\n.long 0x0000002F\n.long 0x0000008F\n.long 0x000000BF\n.long 0x00000088\n.long 0x00000000\n.long 0x00000000\n.long 0xFFFFF200\n.long 0xFFFFD000\n.long 0xFFFFB000\n.long 0xFFFF8000\n.long 0xFFFF4000\n.long 0x88880000\n.long 0x00000000\n.long 0x00000000\n.long 0x02FFFFF8\n.long 0x00DFFFFD\n.long 0x00BFFFFF\n.long 0x008FFFFF\n.long 0x004FFFFF\n.long 0x00088888\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x20000000\n.long 0x80000000\n"
  },
  {
    "path": "ASM/training-mode/Misc/Edit Hyphen Texture.s",
    "content": "#To be inserted at 8042ABD8\n.long 0x00888888\n.long 0x00888888\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x88888888\n.long 0x88888888\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x88888888\n.long 0x88888888\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x88888880\n.long 0x88888880\n.long 0x00888888\n.long 0x00888888\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x88888888\n.long 0x88888888\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x88888888\n.long 0x88888888\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x00000000\n.long 0x88888880\n.long 0x88888880\n"
  },
  {
    "path": "ASM/training-mode/Misc/Frame Advance Rewrite.asm",
    "content": "#To be inserted at 8016bbb4\n.include \"../Globals.s\"\n.include \"../../m-ex/Header.s\"\n\n.set REG_Timer, 10\n.set REG_Inputs, 11\n.set REG_Count, 12\n\nbackup\n\nbl Timer\nmflr REG_Timer\nload REG_Inputs,0x804c1fac\nli REG_Count,0\n\nLoop:\n.set REG_ThisInputs, 9\n  mulli r3,REG_Count,68\n  add REG_ThisInputs,r3,REG_Inputs\n\n# Check for Z\n  lwz r0,0x0(REG_ThisInputs)\n  rlwinm. r0,r0,0,0x10\n  beq LoopInc\n\n# increment timer\n  lwz r3,0x0(REG_Timer)\n  addi r3,r3,1\n  stw r3,0x0(REG_Timer)\n# Check if held for 30 frames\n  lwz r3,0x0(REG_Timer)\n  cmpwi r3,1\n  beq Success \n  cmpwi r3,30\n  bge Success\n  b Failure\n\nSuccess:\n# Inputted, now remove input\n  li r4,0\n  lwz r0,0x0(REG_ThisInputs)\n  rlwimi r0,r4,4,0x10\n  stw r0,0x0(REG_ThisInputs)\n  lwz r0,0x8(REG_ThisInputs)\n  rlwimi r0,r4,4,0x10\n  stw r0,0x8(REG_ThisInputs)\n# Exit with success\n  li r3,1\n  b Exit\n\nLoopInc:\n  addi REG_Count,REG_Count,1\n  cmpwi REG_Count,4\n  blt Loop\n\n# Reset timer\n  li r3,0\n  stw r3,0x0(REG_Timer)\n# Set advance to 0\n  load r3,0x80479d48\n  li r4,0\n  lbz r0,0x22(r3)\n  rlwimi r0,r4,31,0x1\n  stb r0,0x22(r3)\n\nFailure:\n  li r3,0\n  b Exit\n\nTimer:\nblrl\n.long 0\n\n\nExit:\nrestore\nblr"
  },
  {
    "path": "ASM/training-mode/Misc/GObj_Destory Exits When Input = 0.asm",
    "content": "#To be inserted at 80390240\nb\t0xD8"
  },
  {
    "path": "ASM/training-mode/Misc/HSD_Update Tweak/Allow Z in VS While Paused.asm",
    "content": "#To be inserted at 8006b0b4\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nnop"
  },
  {
    "path": "ASM/training-mode/Misc/HSD_Update Tweak/Always Run Debug Update.asm",
    "content": "#To be inserted at 801a4df4\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nnop"
  },
  {
    "path": "ASM/training-mode/Misc/HSD_Update Tweak/Check for DBLevel.asm",
    "content": "#To be inserted at 801a49a8\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nlwz\tr0, -0x6C98 (r13)\ncmpwi r0,3\nbge isDebug\n\nNoDebug:\n#Run just HSDUpdate\nbranch r12,0x801a4a78\n\nisDebug:\n#Run as normal"
  },
  {
    "path": "ASM/training-mode/Misc/HSD_Update Tweak/Clear HSDUpdate for no Debug Melee.asm",
    "content": "#To be inserted at 801a4b14\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n# Finish storing function\n    stw\tr4, 0x0018 (r5)\n\n# Check if DBLevel\n    lwz\tr0, -0x6C98 (r13)\n    cmpwi r0,3\n    bge isDebug\n\nNoDebug:\n# Clear these functions\n    li  r0,0\n    stw\tr0, 0x0014 (r5)\n    stw\tr0, 0x0018 (r5)\n\nisDebug:\n#Run as normal\n"
  },
  {
    "path": "ASM/training-mode/Misc/HSD_Update Tweak/Clear HSDUpdate for no Debug.asm",
    "content": "#To be inserted at 801a4c08\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n# Finish storing function\n    stw\tr0, 0x0028 (r31)\n\n# Check if DBLevel\n    lwz\tr0, -0x6C98 (r13)\n    cmpwi r0,3\n    bge isDebug\n\nNoDebug:\n# Clear these functions\n    li  r0,0\n    stw r0,0x24(r31)\n    stw r0,0x28(r31)\n\nisDebug:\n#Run as normal\n"
  },
  {
    "path": "ASM/training-mode/Misc/Load .gct on Boot.s",
    "content": "#To be inserted at 80375384\n.include \"../Globals.s\"\n\n.set GeckoCodehandler,0x8040a5e4\n.set HeaderSize,32\n\n\n#########################\n## LOAD FILE FROM DISC ##\n#########################\n\tbackup\n\n#Backup ArenaLo to r25\n\tmr\tr25,r31\n\n#Get File Name\n\tbl fileName\n\tmflr r3\n\n#Get File Length For Heap Creation\n\tmr\tr29, r3\n\tbranchl r12,0x800163D8\n\n#Check If File Exists\n\tcmpwi\tr3,-1\n\tbne\tCreateHeapBoundaries\n\tmr\tr3,r25\n\tb\texit\n\n#Create Heap Boundaries\n.set REG_FileSize,28\n\tCreateHeapBoundaries:\n\taddi r3,r3,HeaderSize\t\t\t\t#add some extra space for the header\n\taddi\tr0, r3, 31\t\t\t\t\t\t#allign to something\n\trlwinm\tREG_FileSize, r0, 0, 0, 26\t\t\t#allign to something\n\tmr\tr3,r25\t\t\t#r3 = start of heap\n\tadd\tr25,r3,REG_FileSize\t\t\t#ArenaHi = ArenaLo+ .gct size\n\taddi\tr25,r25,0x500\t\t\t#ArenaHi = ArenaHi+ 0x500 (misc space for file loading)\n\tmr\tr4,r25\t\t\t#r4= end of heap\n\tbranchl\tr12,0x803440e8\t\t\t#Create Heap\n\tstw\tr3, -0x5688 (r13)\t\t\t#Store Active Heap\n\n#Allocate persistent file space\n.set REG_Codeset,27\n\tli\tr3, 0\n\tmr\tr4,REG_FileSize\n\tbranchl\tr12,0x80015BD0\n#Load File\n\taddi\tREG_Codeset, r3, 0\n\taddi\tr3, r29, 0\n\taddi\tr4, REG_Codeset, HeaderSize\n\taddi\tr5, sp, 12\n\tbranchl\tr12,0x8001668C\n\n#Store codeset pointer and length\n  stw REG_Codeset,CodesetPointer(rtoc)\n  stw REG_FileSize,0x0(REG_Codeset)\n\n#Run Codehandler\n\taddi\tr4,REG_Codeset,HeaderSize\n\tbranchl\tr12,GeckoCodehandler\n\n#Now flush the instruction cache\n  lis r3,0x8000\n  load r4,0x3b722c    #might be overkill but flush the entire dol file\n  branchl r12,0x80328f50\n\n#Return End of Heap\n\tmr\tr3,r25\n\n\tb exit\n\nfileName:\nblrl\n\n.string \"codes.gct\"\n.align 2\n\n#EXIT\nexit:\nrestore\nmr\tr31,r3\t\t#r31 = start of next heap\naddi\tr3, r31, 31\t\t#original codeline\n"
  },
  {
    "path": "ASM/training-mode/Misc/Load TmDt.asm",
    "content": "#To be inserted at 803753b0\n.include \"../Globals.s\"\n.include \"../../m-ex/Header.s\"\n.include \"../../m-ex/Header.s\"\n\n#ftX struct\n  .set  ftX_Code,0x0\n  .set  ftX_InstructionRelocTable,0x4\n  .set  ftX_InstructionRelocTableCount,0x8\n  .set  ftX_FunctionRelocTable,0xC\n    .set  FunctionRelocTable_ReplaceThis,0x0\n    .set  FunctionRelocTable_ReplaceWith,0x4\n  .set  ftX_FunctionRelocTableCount,0x10\n\n.set  REG_HeapLo,31\n.set  REG_FileSize,28\n.set  REG_File,27\n.set  REG_HeapID,26\n.set  REG_Header,25\n.set  REG_mexData,24\n\nstw\tr31, -0x3FE8 (r13)\n\nbackup\n\n#Check if file exists\n  bl  FileName\n  mflr  r3\n  branchl r12,0x8033796c\n  cmpwi r3,-1\n  beq Exit\n#Get size of TmDt.dat\n  bl  FileName\n  mflr  r3\n  branchl r12,0x800163d8\n  addi  REG_FileSize,r3,0\n#ALlign\n  addi  REG_FileSize,REG_FileSize,31\n  rlwinm\tREG_FileSize, REG_FileSize, 0, 0, 26\n#Create heap of this size\n  add r4,REG_HeapLo,REG_FileSize     #heap hi = start + filesize\n  addi  r4,r4,32*5              #plus 96 for header\n  mr  r3,REG_HeapLo                  #heap lo = start\n  mr  REG_HeapLo,r4             #new start = heap hi\n  branchl r12,0x803440e8\n  mr  REG_HeapID,r3\n#Alloc header\n  li  r4,68\n  branchl r12,0x80343ef0\n  mr  REG_Header,r3\n#Alloc from this heap\n  mr  r3,REG_HeapID\n  mr  r4,REG_FileSize\n  branchl r12,0x80343ef0\n  mr  REG_File,r3\n#Load file here\n  bl  FileName\n  mflr  r3\n\tmr r4, REG_File\n\taddi\tr5, sp, 0x80\n\tbranchl\tr12,0x8001668C\n#Init Archive\n  lwz r5,0x80(sp)\n  mr  r3,REG_Header   #store header\n  mr  r4,REG_File      #file\n  branchl r12,0x80016a54\n#Get symbol offset\n  mr  r3,REG_Header\n  bl  SymbolName\n  mflr  r4\n  branchl r12,0x80380358\n  mr.  REG_mexData,r3\n  beq mexPatch_Skip\n#Reloc\n  lwz r3,ftX_InstructionRelocTableCount(REG_mexData)  #count\n  lwz r4,ftX_Code(REG_mexData)                        #code\n  lwz r5,ftX_InstructionRelocTable(REG_mexData)       #reloc table\n  branchl r12,Reloc\n#Overload\n  mr  r3,REG_mexData\n  addi  r4,rtoc,TM_tmFunction\n  bl  Overload\nmexPatch_Skip:\n\n#Flush instruction cache so code can be run from this file\n  mr  r3,REG_File\n  mr  r4,REG_FileSize\n  branchl r12,0x80328f50\n\n#Run TM_OnFileLoad\n  lwz r12,TM_OnFileLoad(rtoc)\n  cmpwi r12,0\n  beq Skip_OnFileLoad\n  mr  r3,REG_Header\n  mtctr r12\n  bctrl\n  Skip_OnFileLoad:\n\n  b Exit\n\n###########################################\n\nOverload:\n# r3 = ftX\n# r4 = table\n#Copy function pointers - init\n.set  REG_ftX,12\n.set  REG_ThisElement,11\n.set  REG_Code,10\n.set  REG_OverloadTable,9\n.set  REG_Count,8\n.set  REG_RelocTable,7\n  mr  REG_ftX,r3\n  mr  REG_OverloadTable,r4\n  lwz REG_RelocTable,ftX_FunctionRelocTable(REG_ftX)\n  lwz REG_Code,0x0(REG_ftX)\n  li  REG_Count,0\n  b Overload_CheckLoop\nOverload_Loop:\n#Get this element\n  mulli r3,REG_Count,8\n  add REG_ThisElement,r3,REG_RelocTable\n\nOverload_TableIndex:\n#Get ram offset for this function\n  lwz r3,FunctionRelocTable_ReplaceWith(REG_ThisElement)\n  add r3,r3,REG_Code\n#Update table\n  mulli r4,REG_Count,4\n  stwx  r3,r4,REG_OverloadTable\n  b Overload_IncLoop\n\nOverload_IncLoop:\n  addi  REG_Count,REG_Count,1\nOverload_CheckLoop:\n  lwz r3,ftX_FunctionRelocTableCount(REG_ftX)\n  cmpw  REG_Count,r3\n  blt Overload_Loop\nOverload_Exit:\n  blr\n############################################\n\nFileName:\nblrl\n.string \"TM/TmDt.dat\"\n.align 2\nSymbolName:\nblrl\n.string \"tmFunction\"\n.align 2\n\nExit:\n  mr  r3,REG_HeapLo\n  restore\n  mr  r31,r3\n  stw\tr31, -0x3FE8 (r13)\n  mr\tr3, r31\n  mr\tr4, r29\n"
  },
  {
    "path": "ASM/training-mode/Misc/Never Play Movies in Archives.asm",
    "content": "#To be inserted at 80259090\nb\t0x18"
  },
  {
    "path": "ASM/training-mode/Misc/OSReport Match Load Time/Output Time Since Last Tick.asm",
    "content": "#To be inserted at 8016e91c\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n#*************************************************\n.if debug==1\n#Get Prev Tick\n\tlwz\tr3,-0x49b4(r13)\n#Get Current Tick\n\tmftbl\tr4\n#Find Difference\n\tsub\tr3,r4,r3\n\n#Convert to ms\n#Get Clock Bus\n\tload \tr4,0x800000f8\n\tlwz \tr4,0x0(r4)\n#Clock Bus / 4\n\tli\tr5,4\n\tdivw \tr4,r4,r5\n#Divided by 1000\n\tli\tr5,1000\n\tdivw\tr4,r4,r5\n#divided by ticks\n\tdivw\tr4,r3,r4\n\n#OSReport Difference\n\tbl\tOSReportString\n\tmflr\tr3\n\tbranchl r12,0x803456a8\n\tb\tExit\n\nOSReportString:\nblrl\n.string \"Match loaded in: %dms\n\"\n.align 2\n.endif\n#*************************************************\n\nExit:\nlwz\tr0, 0x0024 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Misc/OSReport Match Load Time/Store Starting Tick.asm",
    "content": "#To be inserted at 8016e740\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nmr\tr31, r3\n\n.if debug==1\n#Store Current tick\nmftbl\tr3\nstw\tr3,-0x49b4(r13)\n.endif\n"
  },
  {
    "path": "ASM/training-mode/Misc/On No Save.asm",
    "content": "#To be inserted at 801af6f4\n.include \"../Globals.s\"\n\n.set MEMCARD_HASSAVE,0x0\n.set MEMCARD_NOSAVE,0x4\n.set MEMCARD_NONE,0xF\n.set MEMCARD_NONE2,0xD\n\n#Check if no memcard inserted\n  cmpwi r29,MEMCARD_HASSAVE\n  beq Original\n  cmpwi r29,MEMCARD_NOSAVE\n  beq NoSave  \n  cmpwi r29,MEMCARD_NONE\n  beq NoMemcard\n  cmpwi r29,MEMCARD_NONE2\n  beq NoMemcard\n\n  b NoSave\n\nNoSave:\nbl InitSave\nb Original\n\nNoMemcard:\nbl InitSave\n\n#Exit memcard think and disable saving\n  branch r12,0x801b01ac\n\nInitSave:\nbackup\n\n  OnSaveCreate\n\nrestore\nblr\n\nOriginal:\n  cmpwi r29,0\n"
  },
  {
    "path": "ASM/training-mode/Misc/Overwrite Compile Date.s",
    "content": "#To be inserted at 803ea6c8\n.string \"DATE 08.22.2019 TIME 10.47 PM\"\n.align 2\n"
  },
  {
    "path": "ASM/training-mode/Misc/PAL Changes/Character DAT Patcher.asm",
    "content": "#To be inserted at 80068f30\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set player,31\n\n.if PAL==1\n\nbackup\n\nlwz r31,0x10C(r30)\nlwz r31,0x8(r31)\nsubi r31,r31,0x20\nlwz r3,0x0(r29)\t\t\t#get character internal ID\ncmpwi r3,0x1b\t\t\t#check if master hand, crazy hand, wireframes, giga or sandbag\nbge exit\t\t\t#exit if so\n\nbl SkipTable\nbl diffMario\nbl diffFox\nbl diffCaptain\nbl diffDK\nbl diffKirby\nbl diffBowser\nbl diffLink\nbl diffSheik\nbl diffNess\nbl diffPeach\nbl diffPopo\nbl diffNana\nbl diffPikachu\nbl diffSamus\nbl diffYoshi\nbl diffJigglypuff\nbl diffMewtwo\nbl diffLuigi\nbl diffMarth\nbl diffZelda\nbl diffYLink\nbl diffDoc\nbl diffFalco\nbl diffPichu\nbl diffGaW\nbl diffGanon\nbl diffRoy\n\nSkipTable:\nmflr\tr4\t\t#Jump Table Start in r4\nmulli\tr3,r3,0x4\t\t#Each Pointer is 0x4 Long\nadd\tr4,r4,r3\t\t#Get Event's Pointer Address\nlwz\tr5,0x0(r4)\t\t#Get bl Instruction\nrlwinm\tr5,r5,0,6,29\t\t#Mask Bits 6-29 (the offset)\nadd\tr5,r4,r5\t\t#Gets Address in r4\n\n################\n## Patch Loop ##\n################\n\ncontinue:\npatchLoop:\nlwz r3,0x0(r5)\nlwz r4,0x4(r5)\n\ncmpwi r3,0xFF\nbeq endPatchLoop\n\nadd r3,r3,r31\nstw r4,0x0(r3)\naddi r5,r5,0x8\nb patchLoop\n\nendPatchLoop:\nb exit\n\n\n#################\n## DIFF TABLES ##\n#################\ndiffMario:\n\n.long 0x00003344\n.long 0x3f547ae1\n.long 0x00003360\n.long 0x42c40000\n.long 0x000000FF\n\ndiffFox:\n\n.long 0x0000379c\n.long 0x42920000\n.long 0x00003908\n.long 0x40000000\n.long 0x0000390c\n.long 0x40866666\n.long 0x00003910\n.long 0x3dea0ea1\n.long 0x00003928\n.long 0x41a00000\n.long 0x00003c04\n.long 0x2c01480c\n.long 0x00004720\n.long 0x1b968013\n.long 0x00004734\n.long 0x1b968013\n.long 0x0000473C\n.long 0x04000009\n.long 0x00004A40\n.long 0x2C006811\n.long 0x00004A4C\n.long 0x281B0013\n.long 0x00004A50\n.long 0x0D00010B\n.long 0x00004A54\n.long 0x2C806811\n.long 0x00004A60\n.long 0x281B0013\n.long 0x00004A64\n.long 0x0D00010B\n.long 0x00004B24\n.long 0x2C00680D\n.long 0x00004B30\n.long 0x0F104013\n.long 0x00004B38\n.long 0x2C80380D\n.long 0x00004B44\n.long 0x0F104013\n.long 0x000000FF\n\ndiffCaptain:\n\n.long 0x0000380c\n.long 0x00000007\n.long 0x00004ef8\n.long 0x2c003803\n.long 0x00004f08\n.long 0x0f80000b\n.long 0x00004f0c\n.long 0x2c802003\n.long 0x00004f1C\n.long 0x0f80000b\n.long 0x000000FF\n\ndiffDK:\n\n.long 0x000000FF\n\ndiffKirby:\n\n.long 0x00004d10\n.long 0x3fc00000\n.long 0x00004d70\n.long 0x42940000\n.long 0x00004dd4\n.long 0x41900000\n.long 0x00004de0\n.long 0x41900000\n.long 0x000083ac\n.long 0x2c000009\n.long 0x000083b8\n.long 0x348c8011\n.long 0x00008400\n.long 0x348C8011\n.long 0x00008430\n.long 0x0500008b\n.long 0x00008438\n.long 0x041a0500\n.long 0x00008444\n.long 0x0500008b\n.long 0x000084dc\n.long 0x05780578\n.long 0x000085b8\n.long 0x1000010b\n.long 0x000085c0\n.long 0x03e801f4\n.long 0x000085cc\n.long 0x1000010b\n.long 0x000085d4\n.long 0x038403e8\n.long 0x000085e0\n.long 0x1000010b\n.long 0x00008818\n.long 0x0b00010b\n.long 0x0000882c\n.long 0x0b00010b\n.long 0x000088f8\n.long 0x041a0bb8\n.long 0x0000893c\n.long 0x041a0bb8\n.long 0x00008980\n.long 0x041a0bb8\n.long 0x000089E0\n.long 0x04fef704\n.long 0x000000FF\n\ndiffBowser:\n\n.long 0x000036cc\n.long 0x42EC0000\n.long 0x000037c4\n.long 0x0C000000\n.long 0x000000FF\n\ndiffLink:\n\n.long 0x00003468\n.long 0x3f666666\n.long 0x000039d8\n.long 0x440C0000\n.long 0x00003a44\n.long 0xb4990011\n.long 0x00003a48\n.long 0x1b8c008f\n.long 0x00003a58\n.long 0xb4990011\n.long 0x00003a5c\n.long 0x1b8c008f\n.long 0x00003a6c\n.long 0xb4990011\n.long 0x00003a70\n.long 0x1b8c008f\n.long 0x00003b30\n.long 0x440C0000\n.long 0x000000FF\n\ndiffSheik:\n\n.long 0x000045c8\n.long 0x2c015010\n.long 0x000045d4\n.long 0x2d198013\n.long 0x000045dc\n.long 0x2c80b010\n.long 0x000045e8\n.long 0x2d198013\n.long 0x000049c4\n.long 0x2c00680a\n.long 0x000049d0\n.long 0x281b8013\n.long 0x000049d8\n.long 0x2c80780a\n.long 0x000049e4\n.long 0x281b8013\n.long 0x000049f0\n.long 0x2c006808\n.long 0x000049fc\n.long 0x231b8013\n.long 0x00004a04\n.long 0x2c807808\n.long 0x00004a10\n.long 0x231b8013\n.long 0x00005c98\n.long 0x1e0c8080\n.long 0x00005cf4\n.long 0xb4800c90\n.long 0x00005d08\n.long 0xb4800c90\n.long 0x000000FF\n\ndiffNess:\n\n.long 0x00003a1c\n.long 0xb4940013\n.long 0x00003a64\n.long 0x2c000015\n.long 0x00003a70\n.long 0xb4928013\n.long 0x000000FF\n\ndiffPeach:\n\n.long 0x000000FF\n\ndiffPopo:\n\n.long 0x000000FF\n\ndiffNana:\n\n.long 0x000000FF\n\n\ndiffPikachu:\n\n.long 0x0000647C\n.long 0xb49a4017\n.long 0x00006480\n.long 0x64001097\n.long 0x000000FF\n\ndiffSamus:\n\n.long 0x000000FF\n\ndiffYoshi:\n\n.long 0x000033e4\n.long 0x42de0000\n.long 0x00004528\n.long 0x2c013011\n.long 0x00004534\n.long 0xb4988013\n.long 0x0000453c\n.long 0x2c813011\n.long 0x00004548\n.long 0xb4988013\n.long 0x00004550\n.long 0x2d002011\n.long 0x0000455c\n.long 0xb4988013\n.long 0x000045f8\n.long 0x2c01300f\n.long 0x00004608\n.long 0x0f00010b\n.long 0x0000460c\n.long 0x2c81280f\n.long 0x0000461c\n.long 0x0f00010b\n.long 0x00004aec\n.long 0x2c007003\n.long 0x00004b00\n.long 0x2c803803\n.long 0x000000FF\n\ndiffJigglypuff:\n\n.long 0x000000FF\n\ndiffMewtwo:\n\n.long 0x0000485c\n.long 0x2c00000f\n.long 0x000000FF\n\ndiffLuigi:\n\n.long 0x000000FF\n\ndiffMarth:\n\n.long 0x000037b0\n.long 0x3f59999a\n.long 0x000037cc\n.long 0x42aa0000\n.long 0x00005520\n.long 0x87118013\n.long 0x000000FF\n\ndiffZelda:\n\n.long 0x000000FF\n\ndiffYLink:\n\n.long 0x00003b8c\n.long 0x440c0000\n.long 0x00003d0c\n.long 0x440c0000\n.long 0x000000FF\n\ndiffDoc:\n\n.long 0x000000FF\n\ndiffFalco:\n\n.long 0x000050e4\n.long 0xb4990013\n.long 0x000050f8\n.long 0xb4990013\n.long 0x000000FF\n\ndiffPichu:\n\n.long 0x000000FF\n\ndiffGaW:\n\n.long 0x000000FF\n\ndiffGanon:\n\n.long 0x00004eb0\n.long 0x02bcff38\n.long 0x00004ebc\n.long 0x14000123\n.long 0x00004ec4\n.long 0x038401f4\n.long 0x00004ed0\n.long 0x14000123\n.long 0x00004ed8\n.long 0x044c04b0\n.long 0x00004ee4\n.long 0x14000123\n.long 0x0000505c\n.long 0x2c006815\n.long 0x0000506c\n.long 0x14080123\n.long 0x00005070\n.long 0x2c806015\n.long 0x00005080\n.long 0x14080123\n.long 0x00005084\n.long 0x2d002015\n.long 0x00005094\n.long 0x14080123\n.long 0x000000FF\n\ndiffRoy:\n\n.long 0x000000FF\n\nexit:\nrestore\n.endif\n\nlis\tr3, 0x803C\n"
  },
  {
    "path": "ASM/training-mode/Misc/PAL Changes/DK - Keep Up B Charge After Getting Hit out of Up B/Keep Charge Aerial Up B.asm",
    "content": "#To be inserted at 8010fc48\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.if PAL==1\nnop\n.endif\n\n.if PAL==0\nstw\tr0, 0x21DC (r5)\n.endif\n"
  },
  {
    "path": "ASM/training-mode/Misc/PAL Changes/DK - Keep Up B Charge After Getting Hit out of Up B/Keep Charge Grounded Up B.asm",
    "content": "#To be inserted at 8010fb68\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.if PAL==1\nnop\n.endif\n\n.if PAL==0\nstw\tr0, 0x21DC (r5)\n.endif\n"
  },
  {
    "path": "ASM/training-mode/Misc/PAL Changes/Detection Hitboxes Does Not Skip Hurtbox Collision Check.asm",
    "content": "#To be inserted at 800796e0\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.if PAL==1\nnop\n.endif\n\n.if PAL==0\nli\tr18, 1\n.endif\n"
  },
  {
    "path": "ASM/training-mode/Misc/PAL Changes/Fix Freeze Glitch.asm",
    "content": "#To be inserted at 801239a8\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.if PAL==1\nnop\n.endif\n\n.if PAL==0\nstw\tr0, 0x1A5C (r31)\n.endif\n"
  },
  {
    "path": "ASM/training-mode/Misc/PAL Changes/PAL CSS Indicator.asm",
    "content": "#To be inserted at 80266978\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.if PAL==1\nloc_0x0:\n  mflr r14\n  bl loc_0x34\n  mflr r4\n  mtlr r14\n  lis r14, 0x35\n  ori r14, r14, 0x6A60\n  sub r3, r3, r14\n  li r5, 0x238\n  lis r14, 0x8000\n  ori r14, r14, 0x31F4\n  mtctr r14\n  bctrl\n  b loc_0x274\n\nloc_0x34:\n  blrl\n  .long 0x00000000\n  .long 0x00006fff\n  .long 0x00007ff1\n  .long 0x00007ff0\n  .long 0x00007ff0\n  .long 0x00007ff0\n  .long 0x00007fff\n  .long 0x00007ff1\n  .long 0x00000000\n  .long 0xffc40002\n  .long 0x17ff3006\n  .long 0x00ef800b\n  .long 0x00ef801f\n  .long 0x04ff404f\n  .long 0xfff7009f\n  .long 0x110000ef\n  .long 0x00000000\n  .long 0xfff8000d\n  .long 0xfefd000f\n  .long 0xfbff300f\n  .long 0xF6DF700F\n  .long 0xF3BFC00F\n  .long 0xE07FF10F\n  .long 0xB14FF60F\n  .long 0x00000000\n  .long 0xF6000000\n  .long 0xF7000000\n  .long 0xF7000000\n  .long 0xF7000000\n  .long 0xF7000000\n  .long 0xF7000000\n  .long 0xF7000000\n  .long 0x04ff9888\n  .long 0x00cfb888\n  .long 0x009fc888\n  .long 0x006fd888\n  .long 0x004fe888\n  .long 0x002ff888\n  .long 0x000ff888\n  .long 0x002ff888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x8888888E\n  .long 0x888888DF\n  .long 0x88888CFF\n  .long 0x8888AFF7\n  .long 0x8889FFA0\n  .long 0x888FFC00\n  .long 0x8DFFB100\n  .long 0xeff60000\n  .long 0xff400000\n  .long 0xF3000000\n  .long 0x40000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x88888888\n  .long 0x8888EF40\n  .long 0x8888DF60\n  .long 0x8888CF90\n  .long 0x8888BFC0\n  .long 0x88889FF4\n  .long 0x88888DF9\n  .long 0x88888BFE\n  .long 0x888888EF\n  .long 0x00007ff0\n  .long 0x00007ff0\n  .long 0x00006fd0\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x30000000\n  .long 0x90000000\n  .long 0x000003ff\n  .long 0x000008ff\n  .long 0x00000bfb\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0xeffffb0f\n  .long 0x200AFF1F\n  .long 0x0004ff4d\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0xF7000000\n  .long 0xF7111100\n  .long 0xfffffb00\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x00000000\n  .long 0x004fe888\n  .long 0x006fd888\n  .long 0x009fc888\n  .long 0x00cfb888\n  .long 0x04ff9888\n  .long 0x09fd8888\n  .long 0x3EFB8888\n\n.endif\n\nloc_0x274:\n  addi r3, r31, 0x718\n"
  },
  {
    "path": "ASM/training-mode/Misc/PAL Changes/PAL Stock Icons.asm",
    "content": "#To be inserted at 802f9a3c\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.if PAL==1\n#Get Flaots\n  bl  Floats\n  mflr r4\n#Store X Scale\n  lwz r3,0x0(r4)\n  stw r3,0x2c(r29)\n#Store Y Scale\n  stw r3,0x30(r29)\n#Load Y Offset\n  lwz r3,0x4(r4)\n  stw r3,0x3C(r29)\n  b original\n\n######################################\nFloats:\nblrl\n.float 0.85     #x and y scale\n.float -21      #y offset\n######################################\n\noriginal:\nlwz\tr0, 0x0014 (r29)\n\n.endif\n\n.if PAL==0\nlwz\tr0, 0x0014 (r29)\n.endif\n"
  },
  {
    "path": "ASM/training-mode/Misc/PAL Changes/Samus - Disable Extender/Disable Initial Extender Polling.asm",
    "content": "#To be inserted at 802b7e54\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.if PAL==1\nb 0x88\n.endif\n\n.if PAL==0\nlbz\tr3, 0x2240 (r31)\n.endif\n"
  },
  {
    "path": "ASM/training-mode/Misc/PAL Changes/Samus - Disable Extender/Disable Secondary Extender Polling.asm",
    "content": "#To be inserted at 802b808c\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.if PAL==1\nb 0x84\n.endif\n\n.if PAL==0\ncmpwi\tr3, 2\n.endif\n"
  },
  {
    "path": "ASM/training-mode/Misc/PAL Changes/Samus Cant Bomb Jump Out of Grapple.asm",
    "content": "#To be inserted at 803ce4d4\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.if PAL==1\n.long 0x00240464\n.endif\n\n.if PAL==0\n.long 0x00200000\n.endif\n"
  },
  {
    "path": "ASM/training-mode/Misc/Save File Renaming.asm",
    "content": "#To be inserted at 8001c800\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n .macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n.set TextCreateFunction,0x80005928\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n\n#Check For Game ID GTME (ISO)\nlis\tr11,0x8000\nlwz\tr11,0x0(r11)\nload\tr12,0x47544d45\t\t#GTME\ncmpw\tr11,r12\nbeq\tISO\nb\tMemcard\n\nISO:\nbl\tISOSaveName\nmflr\tr5\nb\texit\n\nMemcard:\nbl\tMemcardSaveName\nmflr\tr5\nbl\tMemcardStringFormat\nmflr\tr4\nb\texit\n\nISOSaveName:\nblrl\n.long 0x54726169\n.long 0x6e696e67\n.long 0x204d6f64\n.long 0x65206279\n.long 0x20556e63\n.long 0x6c655075\n.long 0x6e636820\n.long 0x20202020\n\nISOSaveDesc:\n#blrl\n.long 0x47616D65\n.long 0x20446174\n.long 0x61000000\n\nMemcardSaveName:\nblrl\n.long 0x53757065\n.long 0x7220536D\n.long 0x61736820\n.long 0x42726F73\n.long 0x2E204D65\n.long 0x6C656520\n.long 0x20202020\n.long 0x20202020\n\nMemcardSaveDesc:\n#blrl\n.long 0x4d6f6420\n.long 0x4c61756e\n.long 0x63686572\n.long 0x20283120\n.long 0x6f662032\n.long 0x29000000\n\nMemcardStringFormat:\nblrl\n.long 0x25730000\n\nexit:\nbranchl\tr12,0x80323cf4\n"
  },
  {
    "path": "ASM/training-mode/Misc/ScoreDisplay - Change GXLink Pri.asm",
    "content": "#To be inserted at 802ff4d8\nli r9,1"
  },
  {
    "path": "ASM/training-mode/Misc/SearchStringTable.asm",
    "content": "#To be inserted at 0x80005530\n.include \"../Globals.s\"\n.include \"../../m-ex/Header.s\"\n\n#############################################\n.set ID,31\n.set LoopCount,30\n.set Name,29\n\nbackup\n\n#Get ID\n  mr  ID,r3\n#Get Names\n  mr  Name,r4\n#Init Loop Count\n  li  LoopCount,0\n\nSearchStringTable_Loop:\n#Check if we are up to the correct name\n  cmpw ID,LoopCount\n  beq SearchStringTable_Exit\n#Get string length\n  mr  r3,Name\n  branchl r12,0x80325b04\n#Add to current name pointer\n  add Name,Name,r3\n  addi Name,Name,1\n#Inc Loop Count\n  addi LoopCount,LoopCount,1\n  b SearchStringTable_Loop\n\nSearchStringTable_Exit:\nmr  r3,Name\nrestore\nblr\n\n###################################\n"
  },
  {
    "path": "ASM/training-mode/Misc/Skip Assert for Respawn Platform.asm",
    "content": "#To be inserted at 800d5524\nb 0x7C\n"
  },
  {
    "path": "ASM/training-mode/Misc/Skip Assert for no_reaction_always.asm",
    "content": "#To be inserted at 8006d494\nb 0x20C\n"
  },
  {
    "path": "ASM/training-mode/Misc/Skip SetGroundStateAssert For Restore States.asm",
    "content": "#To be inserted at 8007d8e8\nb\t0x30"
  },
  {
    "path": "ASM/training-mode/Misc/Store Version Number.s",
    "content": "#To be inserted at 8040a58c\n.string \"v2.0 Beta 3\"\n.align 2\n"
  },
  {
    "path": "ASM/training-mode/Misc/Text - Increment Max Size.asm.asm",
    "content": "#To be inserted at 803a6b7c\nb -0x360"
  },
  {
    "path": "ASM/training-mode/Misc/Text Modifications/Add Symbols to ASCII-Menu Text Lookup Table.asm",
    "content": "#To be inserted at 803a684c\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n .macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n.set TextCreateFunction,0x80005928\n\n.set LoopCount,31\n.set Dictionary,30\n.set CurrentDictOffset,12\n\n\n#Runs When the ASCII Value is 0x85 or Greater\n#Katagana Starts at Dictionary Offset 0xB0\n\nbackup\n\n#Search custom symbol table\n  bl  CustomSymbolDictionary\n  mflr Dictionary\n  li LoopCount,0\n\nLoop:\n  mulli CurrentDictOffset,LoopCount,0x3\n  add CurrentDictOffset,CurrentDictOffset,Dictionary\n  lbz r11,0x0(CurrentDictOffset)\n  cmpwi r11,0xFF\n  beq Exit\n  cmpw r10,r11\n  beq CharacterFound\nIncLoop:\n  addi LoopCount,LoopCount,1\n  b Loop\n\nCharacterFound:\n#If overriding 0xA\n  lbz r10,0x0(CurrentDictOffset)    #Check Matched Character\n  cmpwi r10,0x0A\n  bne CharacterFound_Resume\n#Store 0x3 to the menu text string\n  li  r10,0x03\n  stbx r10,r3,r9\n#increment r9 by 1 to get next offset in menu text string\n  addi r9,r9,1\n#branch to 803a6b70, will increment r5 and r6 by 1 to get next offset in ASCII string and loop\n  restore\n  branch r12,0x803a6b70\nCharacterFound_Resume:\n  lbz r10,0x1(CurrentDictOffset)    #Load Override Character\n  lbz r12,0x2(CurrentDictOffset)    #Load Override Character\n  restore\n  mr  r31,r12\n  load r0,0x8040c8c0\n  branch\tr12,0x803a6b08\n\nCustomSymbolDictionary:\nblrl\n.byte 0x21,0x81,0x49   #Exclamation Point\n.byte 0x2f,0x81,0x5E   #Slash\n.byte 0x2e,0x81,0x44   #Period\n.byte 0x3d,0x81,0x81   #Equals Sign\n.byte 0x2b,0x81,0x7B   #Plus Sign\n.byte 0x25,0x81,0x93   #Percent Sign\n.byte 0x0A,0x03,0x00   #New Line\n.byte 0x27,0x81,0x66   #Apostrophe\n.byte 0x3e,0x81,0x84   #Greater than\n.byte 0x3c,0x81,0x83   #Less than\n.byte 0x5F,0x81,0x51   #Underscore\n.byte 0x5E,0x81,0x4F   #Carrot\n.byte 0x3F,0x81,0x48   #Question mark\n.byte 0x7c,0x81,0x62   # | symbol\n.byte 0x28,0x81,0x69   #Open Parenthesis\n.byte 0x29,0x81,0x6A   #Close Parenthesis\n.byte 0xFF\n.align 2\n\n\nExit:\nrestore\nload r0,0x8040c8c0\ncmplwi\tr10, 32\n\n/*\n#Katagana code\ncmpwi\tr10,0x85\nblt\toriginal\n\naddi\tr31,r10,0x2b\nbranch\tr12,0x803a6b38\n\noriginal:\nlbzu\tr31, 0x0001 (r6)\n*/\n"
  },
  {
    "path": "ASM/training-mode/Misc/Text Modifications/Make Spaces Not Store 00s.asm",
    "content": "#To be inserted at 803a6868\nb 0x34\n"
  },
  {
    "path": "ASM/training-mode/Misc/Text Modifications/Make Spaces Store 0x1A.asm",
    "content": "#To be inserted at 803a6860\nli\tr8, 26\n"
  },
  {
    "path": "ASM/training-mode/Misc/Text Modifications/Parse Numbers Correctly.asm",
    "content": "#To be inserted at 803a69c0\nb 0x3C\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOS Frame Display/Count During GuardOff.asm",
    "content": "#To be inserted at 80092ce8\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,4\n.set player,30\n.set text,29\n.set textprop,28\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\n\nlwz\tplayerdata, 0x002C (r31)\n\nlhz\tr5,TM_ShieldFrames(playerdata)\n\ncmpwi\tr5,0xFF\nbeq\tskipInc\naddi\tr5,r5,0x1\nsth\tr5,TM_ShieldFrames(playerdata)\n\nskipInc:\nlwz\tr0, 0x0024 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOS Frame Display/Count During ShieldWait.asm",
    "content": "#To be inserted at 80092a38\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,4\n.set player,30\n.set text,29\n.set textprop,28\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\n\nlwz\tr4, 0x002C (r3)\n\nlhz\tr5,TM_ShieldFrames(playerdata)\n\ncmpwi\tr5,0xFF\nbeq\tskipInc\naddi\tr5,r5,0x1\nsth\tr5,TM_ShieldFrames(playerdata)\n\nskipInc:\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOS Frame Display/Display OOS Frame Count Standalone.asm",
    "content": "#To be inserted at 80005508\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set REG_FighterData,31\n.set player,30\n.set REG_TextColor, 29\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\nmr\tplayer,r4\nlwz\tREG_FighterData,0x2C(player)\n\n\t#####################\n\t## CHECK IF IASA'd ##\n\t#####################\n\n\t#CHECK IF ENABLED\n\tli\tr0,OSD.ActOoS\t\t\t#wavedash ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr5, 1\n\tslw\tr0, r5, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\tCheckForIASA:\n\tcmpwi\tr3,0x1\n\tbne \tMoonwalk_Exit\n\n\tCheckForFollower:\n\tmr\tr3,REG_FighterData\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n\tCheckForGuardOff:\n\tlwz\tr3,0x10(REG_FighterData)\n\tcmpwi\tr3,0xB4\n\tbeq\tMoonwalk_Exit\n\n\tShieldWaitCheck:\n\t#CHECK IF 3RD MOST RECENT AS WAS SHIELD STUN\n\tlhz\tr3,TM_TwoASAgo(REG_FighterData)\n\tcmpwi\tr3,0xB5\n\tbeq\tCreateText\n\n\tGuardOffCheck:\n\t#CHECK IF 4TH MOST RECENT AS WAS SHIELD STUN\n\tlhz\tr3,TM_ThreeASAgo(REG_FighterData)\n\tcmpwi\tr3,0xB5\n\tbeq \tCreateText\n\tb\tMoonwalk_Exit\n\n\tCreateText:\n\t#Change color to Green if frame perfect act oos\n\t\tlhz\tr3,TM_ShieldFrames(REG_FighterData)\t\t\t#get shield stun frames left\n\t\tcmpwi\tr3,0x0\n\t\tbgt\tWhiteText\n\t\tli\tREG_TextColor,MSGCOLOR_GREEN\n\t\tb\tPrintMessage\n\t\tWhiteText:\n\t\tli\tREG_TextColor,MSGCOLOR_WHITE\n\t\tb\tPrintMessage\n\n\t\tPrintMessage:\n\t\tli\tr3,3\t\t\t#Message Kind\n\t\tlbz\tr4,0xC(REG_FighterData)\t#Message Queue\n\t\tmr\tr5,REG_TextColor\n\t\tbl\tOoS_String\n\t\tmflr r6\n\t\tlhz\tr7,TM_ShieldFrames(REG_FighterData)\t\t\t#get shield stun frames left\n\t\taddi r7,r7,1\n\t\tMessage_Display\n\n\t\tb\tMoonwalk_Exit\n\n\n\n\n\n\n/*\n\tmr\tr3,REG_FighterData\t\t\t#backup REG_FighterData pointer\n\tli\tr4,60\t\t\t#display for 60 frames\n\tli\tr5,0\t\t\t#Area to Display (0-2)\n\tli\tr6,3\t\t\t#Window ID (Unique to This Display)\n\tbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\n\n\n\tmr\ttext,r3\t\t\t#backup text pointer\n\n\n\t#CHECK IF FRAME PERFECT\n\tlhz\tr3,0x23EE(REG_FighterData)\t\t\t#get shield stun frames left\n\tcmpwi\tr3,0x0\n\tbgt\tNotFramePerfect\n\n\t\t#SET TEXT COLOR TO GREEN\n\t\tload\tr3,0x8dff6eff\n\t\tstw\tr3, 0x0030 (text)\n\n\n\t\tNotFramePerfect:\n\t\t#INITALIZE TEXT 1\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tbl\tDuringSSASCII\n\t\tmflr \tr4\t\t\t#get ASCII to print\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,0x803a6b98\n\n\n\t\t#INITALIZE TEXT 2\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tbl\tDuringSSASCII2\n\t\tmflr \tr4\t\t\t#get ASCII to print\n\n\t\tlhz\tr5,0x23EE(REG_FighterData)\t\t\t#get shield stun frames left\n\t\taddi\tr5,r5,0x1\n\n\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\t\tbranchl r12,0x803a6b98\n\n\t\tb Moonwalk_Exit\n*/\n\n###################\n## TEXT CONTENTS ##\n###################\n\nOoS_String:\nblrl\n.string \"Act OoShield\\nFrame %d\"\n.align 2\n\n##############################\n\nMoonwalk_Exit:\nrestoreall\nblr\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOS Frame Display/GuardOff - Display OOS Frame Count.asm",
    "content": "#To be inserted at 80092dfc\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set TextCreateFunction,0x80005928\n\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nmr\tr4,r30\nbranchl\tr12,0x80005508\n\nlwz\tr0, 0x0024 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOS Frame Display/GuardWait - Display OOS Frame Count.asm",
    "content": "#To be inserted at 80092b58\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set TextCreateFunction,0x80005928\n\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nmr\tr4,r30\nbranchl\tr12,0x80005508\n\nlwz\tr0, 0x001C (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOS Frame Display/Init Frame Count.asm",
    "content": "#To be inserted at 80093388\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\n\n#init count\nli\tr0,0\nsth\tr0,TM_ShieldFrames(r29)\n\nlwz\tr0, 0x234C (r29)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/DamageFall - Check For Interrupt.asm",
    "content": "#To be inserted at 80090924\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n\n#Check If Entered Fall\nlwz\tr4,0x10(r31)\ncmpwi\tr4,0x1D\nbne\tCheckToDisplay\n\nli\tr3,1\n\nCheckToDisplay:\n#Branch to Interrupt Check With Interrupt Bool in r3 and player in r4\nmr\tr4,r30\nbranchl\tr12,0x80005504\n\nlwz\tr0, 0x001C (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/DamageFlyTop - CheckForInterrupt.asm",
    "content": "#To be inserted at 8008ff14\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n#Branch to Interrupt Check With Interrupt Bool in r3 and player in r4\nmr\tr4,r31\nbranchl\tr12,0x80005504\n\nbranch\tr12,0x8008ff1c\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/DamageLightHit - Check For Animation Interrupt.asm",
    "content": "#To be inserted at 8008f914\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n#Branch to Interrupt Check With Interrupt Bool in r3 and player in r4\nmr\tr4,r31\nbranchl\tr12,0x80005504\n\nbranch\tr12,0x8008f920\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/DamageLightHit - Check For Interrupt - Aerial Jump.asm",
    "content": "#To be inserted at 8008f8fc\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n#Branch to Interrupt Check With Interrupt Bool in r3 and player in r4\nmr\tr4,r31\nbranchl\tr12,0x80005504\n\nbranch\tr12,0x8008f904\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/DamageLightHit - Check ForInterrupt.asm",
    "content": "#To be inserted at 8008fae4\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n#Branch to Interrupt Check With Interrupt Bool in r3 and player in r4\nmr\tr4,r30\nbranchl\tr12,0x80005504\n\nbranch\tr12,0x8008fb00\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/Increment Post Hitstun Count.asm",
    "content": "#To be inserted at 8006ab60\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set player,31\n.set Text,30\n.set TextProp,29\n\n###################################\n## Increment Post-Hitstun Frames ##\n###################################\n\n#Check If In Hitstun\nlbz\tr3, 0x221C (r31)\nrlwinm.\tr0, r3, 31, 31, 31\nbeq\tNoHitstun\n\nInHitstun:\nli\tr3,0\nsth\tr3,TM_PostHitstunFrameCount(r31)\nb\tHitstun_End\n\nNoHitstun:\nlhz\tr3,TM_PostHitstunFrameCount(r31)\naddi\tr3,r3,1\nsth\tr3,TM_PostHitstunFrameCount(r31)\nb\tHitstun_End\n\nHitstun_End:\n\nexit:\nlwz\tr12, 0x21A0 (r31)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageFall - Increment Counter.asm",
    "content": "#To be inserted at 80090824\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,4\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\nlwz\tplayerdata,0x2c(r3)\n\n#Increment PostHitstun Counter\nlhz\tr3,TM_PostHitstunFrameCount(playerdata)\naddi\tr3,r3,0x1\nsth\tr3,TM_PostHitstunFrameCount(playerdata)\n\nExit:\nblr\n\n\n\n\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageFlyRoll - Increment Counter.asm",
    "content": "#To be inserted at 8009029c\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,29\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n#Check If Not In Hitstun\nlbz\tr3, 0x221C (r29)\nrlwinm.\tr0, r3, 31, 31, 31\nbne\tExit\n\n#Increment PostHitstun Counter\nlhz\tr3,TM_PostHitstunFrameCount(playerdata)\naddi\tr3,r3,0x1\nsth\tr3,TM_PostHitstunFrameCount(playerdata)\n\nExit:\nlbz\tr3, 0x221C (r29)\n\n\n\n\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageFlyRoll - Init DamageFallCounter.asm",
    "content": "#To be inserted at 800902c4\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,29\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\nstb\tr3, 0x221C (r29)\n\n#Initialize Counter at 0x2354\nsth\tr0,TM_PostHitstunFrameCount(playerdata)\n\n\n\n\n\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageFlyTop - Increment Counter.asm",
    "content": "#To be inserted at 8008fe64\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,29\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n#Check If Not In Hitstun\nlbz\tr3, 0x221C (r29)\nrlwinm.\tr0, r3, 31, 31, 31\nbne\tExit\n\n#Increment PostHitstun Counter\nlhz\tr3,TM_PostHitstunFrameCount(playerdata)\naddi\tr3,r3,0x1\nsth\tr3,TM_PostHitstunFrameCount(playerdata)\n\nExit:\nlbz\tr3, 0x221C (r29)\n\n\n\n\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageFlyTop - Init DamageFallCounter.asm",
    "content": "#To be inserted at 8008fe8c\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,29\n.set player,30\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nstb\tr3, 0x221C (r29)\n\n#Initialize Counter at 0x2354\nsth\tr0, TM_PostHitstunFrameCount(playerdata)\n\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageLightHit - Increment Counter.asm",
    "content": "#To be inserted at 8008f828\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set playerdata,30\n.set player,30\n\n#Check If Not In Hitstun\nlbz\tr3, 0x221C (playerdata)\nrlwinm.\tr0, r3, 31, 31, 31\nbne\tExit\n\n#Increment PostHitstun Counter\nlhz\tr3,TM_PostHitstunFrameCount(playerdata)\naddi\tr3,r3,0x1\nsth\tr3,TM_PostHitstunFrameCount(playerdata)\n\nExit:\nlbz\tr3, 0x221C (playerdata)\n\n\n\n\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/DamageLightHit - Init DamageFallCounter.asm",
    "content": "#To be inserted at 8008f850\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,30\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nstb\tr3, 0x221C (r30)\n\n#Initialize Counter at 0x2340\nsth\tr0,TM_PostHitstunFrameCount(playerdata)\n\n\n\n\n\n\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/Original Counters and Variable Initializers/MissFoot - Init Counter.asm",
    "content": "#To be inserted at 8009f3ec\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\n#Initialize Counter at 0x2354\nli\tr0,0\nsth\tr0,TM_PostHitstunFrameCount(playerdata)\n\nlwz\tr0, 0x001C (sp)\n\n\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OOTumble/Static Function - Display Frames Spent Post Hitstun.asm",
    "content": "#To be inserted at 80005504\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set REG_FighterData,31\n.set player,30\n\n.set REG_TextColor,29\n.set REG_Text,28\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackup\n\nmr\tplayer,r4\nlwz\tREG_FighterData,0x2c(player)\n\n#Check For Interrupt\ncmpwi\tr3,0x1\nbne\tMoonwalk_Exit\n\n\n\n\t#CHECK IF ENABLED\n\tli\tr0,OSD.ActOoHitstun\t\t\t#PowerShield ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\tCheckForFollower:\n\tmr\tr3,REG_FighterData\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n\t#Check if frame 1\n\tlhz\tr3,TM_PostHitstunFrameCount(REG_FighterData)\n\tcmpwi\tr3,0\n\tbgt\tWhiteText\n\tGreenText:\n\tli\tREG_TextColor,MSGCOLOR_GREEN\n\tb\tPrintMessage\t\n\n\tWhiteText:\n\tli\tREG_TextColor,MSGCOLOR_WHITE\n\tb\tPrintMessage\n\n\tPrintMessage:\n\tli\tr3,5\t\t\t\t\t\t#Message Kind\n\tlbz\tr4,0xC(REG_FighterData)\t\t#Message Queue\n\tmr\tr5,REG_TextColor\n\tbl\tActOoHitstun_String\n\tmflr r6\n\tlhz\tr7,TM_PostHitstunFrameCount(REG_FighterData)\n\taddi r7,r7,1\n\tMessage_Display\n\n\tb Moonwalk_Exit\n\n\n\n/*\n\t\tbl\tCreateText\n\n\t\t#Change Text Color\n\t\tlhz\tr3,TM_PostHitstunFrameCount(REG_FighterData)\n\t\tcmpwi\tr3,0x0\n\t\tbne\tRedText\n\n\t\tGreenText:\n\t\tload\tr3,0x8dff6eff\t\t\t#green\n\t\tb\tStoreTextColor\n\n\t\tRedText:\n\t\tload\tr3,0xffa2baff\n\n\t\tStoreTextColor:\n\t\tstw\tr3,0x30(text)\n\n\t\t#Create Text\n\t\tbl\tTopText\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,0x803a6b98\n\n\t\t#Create Text2\n\t\tbl\tBottomText\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tlhz\tr5,TM_PostHitstunFrameCount(REG_FighterData)\n\t\taddi\tr5,r5,1\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\t\tbranchl r12,0x803a6b98\n\n\n\n\tCreateText:\n  mflr\tr0\n\tstw\tr0, 0x0004 (sp)\n\tstwu\tsp, -0x0008 (sp)\n\tmr\tr3,REG_FighterData\t\t\t#backup REG_FighterData pointer\n\tli\tr4,60\t\t\t#display for 60 frames\n\tli\tr5,0\t\t\t#Area to Display (0-2)\n\tli\tr6,15\t\t\t#Window ID (Unique to This Display)\n\tbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\n\tmr\ttext,r3\t\t\t#backup text pointer\n  lwz\tr0, 0x000C (sp)\n\taddi\tsp, sp, 8\n\tmtlr r0\n\tblr\n*/\n\n\n###################\n## TEXT CONTENTS ##\n###################\n\nActOoHitstun_String:\nblrl\n.string \"Act OoHitstun\\nFrame %d\"\n.align 2\n\n##############################\n\n\nMoonwalk_Exit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OoWait/Act OOWait- Standalone.asm",
    "content": "#To be inserted at 8000551c\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set FramesSince,28\n.set ASBeforeWait,27\n.set REG_Color,26\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\n#Get Player Pointers\n\tmr\tplayer,r3\n\tlwz\tplayerdata,0x2c(player)\n\n\t#CHECK IF ENABLED\n\tli\tr0,OSD.ActOoWait\t\t\t#PowerShield ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\tCheckForFollower:\n\tmr\tr3,playerdata\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n#Calculate Frames Since Wait and Get AS Before Wait\n\tli\tr5,0\t\t#Loop Count\n\tli\tr4,TM_PrevASStart\nWaitSearchLoop:\n\tmulli\tr3,r5,0x2\n\tadd\tr3,r3,r4\n\tlhzx\tr3,r3,playerdata\n\tcmpwi\tr3,0xE\n\tbeq\tWaitSearchExit\n\taddi\tr5,r5,1\n\tcmpwi\tr5,6\n\tbge\tMoonwalk_Exit\n\tb\tWaitSearchLoop\nWaitSearchExit:\n#Get AS Before Wait\n\taddi\tr3,r5,1\n\tmulli\tr3,r3,0x2\n\tadd\tr3,r3,r4\n\tlhzx\tASBeforeWait,r3,playerdata\n#Get Frames In Wait\n\tli\tr4,TM_FramesInPrevASStart\t\t#Frame Count Start\n\tli\tFramesSince,0\t\t#Init Frame Count\nFrameCountLoop:\n\tcmpwi\tr5,0\n\tbeq\tFrameCountLoopFinish\n\tmulli\tr3,r5,0x2\n\tadd\tr3,r3,r4\n\tlhzx\tr3,r3,playerdata\n\tadd\tFramesSince,r3,FramesSince\n\tsubi\tr5,r5,1\n\tb\tFrameCountLoop\nFrameCountLoopFinish:\n\tlhz\tr3,TM_FramesInPrevASStart(playerdata)\t\t\t#Frames spent in Wait\n\tadd\tFramesSince,r3,FramesSince\t\t\t#Get Total Frames Since\n\n\n#Check If Under 13 Frames\n\tcmpwi\tFramesSince,13\n\tbgt\tMoonwalk_Exit\n\n#Only Coming from Throws, Aerial Landing, and Teching/Getups\n#Aerial Landing\n\tcmpwi\tASBeforeWait,0x46\n\tblt\tNotThrow\n\tcmpwi\tASBeforeWait,0x4A\n\tbgt\tNotThrow\n\tb\tComingFromWhitelist\n\tNotThrow:\n#Throws\n\tcmpwi\tASBeforeWait,0xDB\n\tblt\tNotAerialLanding\n\tcmpwi\tASBeforeWait,0xDE\n\tbgt\tNotAerialLanding\n\tb\tComingFromWhitelist\n\tNotAerialLanding:\n#Teching/Getups\n#Aerial Landing\n\tcmpwi\tASBeforeWait,0xB7\n\tblt\tNotTeching\n\tcmpwi\tASBeforeWait,0xC9\n\tbgt\tNotTeching\n\tb\tComingFromWhitelist\n\tNotTeching:\n#Wavedash\n\tcmpwi\tASBeforeWait,ASID_LandingFallSpecial\n\tbne\tNotWavedash \n\tb\tComingFromWhitelist\nNotWavedash:\n\tb\tMoonwalk_Exit\nComingFromWhitelist:\n\n\t\tSpawnText:\n\t\t#Change Text Color\n\t\tcmpwi\tFramesSince,0x1\n\t\tbne\tRedText\n\t\tGreenText:\n\t\tload\tr3,0x8dff6eff\t\t\t#green\n\t\tb\tStoreTextColor\n\t\tRedText:\n\t\tload\tr3,0xffa2baff\n\t\tStoreTextColor:\n\t\tstw r3,0x80(sp)\n\n\t\t#Create Text\n\t\tli\tr3,5\t\t\t\t\t#Message Kind\n\t\tlbz\tr4,0xC(playerdata)\t#Message Queue\n\t\tli\tr5,MSGCOLOR_WHITE\n\t\tbl\tTechText\n\t\tmflr  r6\n\t\tmr\tr7,FramesSince\n\t\tMessage_Display\n\t\t\n\t\tChangeColor:\n\t\tlwz\tr3,0x2C(r3)\n\t\tlwz\tr3,MsgData_Text(r3)\n\t\tli\tr4,1\n\t\taddi r5,sp,0x80\n\t\tbranchl r12,Text_ChangeTextColor\n\n\t\tb Moonwalk_Exit\n\n\n###################\n## TEXT CONTENTS ##\n###################\n\nTechText:\nblrl\n.string \"Act OoWait\\nFrame: %d\"\n.align 2\n\n##############################\n\n\nMoonwalk_Exit:\nrestoreall\nblr\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OoWait/Act OoWait - From Crouch.asm",
    "content": "#To be inserted at 800d6228\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,30\n.set player,31\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\n#Get Playerdata\n\tlwz\tplayerdata,0x2C(player)\n\n#Check If Interrupted\n\tlwz\tr3,0x10(playerdata)\n\tcmpwi\tr3,0x27\n\tbeq\tMoonwalk_Exit\n\n#Make Sure Player Didn't Buffer Shield\n\tlwz\tr3,0x10(playerdata)\n\tcmpwi\tr3,0xB2\n\tbeq\tMoonwalk_Exit\n\n#Ensure I'm Actually Coming from Wait\n\tlhz\tr3,TM_TwoASAgo(playerdata)\n\tcmpwi\tr3,0xE\n\tbne\tMoonwalk_Exit\n\n#Check To Display OSD\n\tmr\tr3,r31\n\tbranchl\tr12,0x8000551c\n\nMoonwalk_Exit:\nrestoreall\nlwz\tr0, 0x0024 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OoWait/Act OoWait - From Landing.asm",
    "content": "#To be inserted at 800d5efc\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,30\n.set player,29\n.set text,29\n.set FramesSince,28\n.set ASBeforeLanding,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\n#Check if Interrupted\n\tcmpwi r3,0x1\n\tbne\tMoonwalk_Exit\n\n\t#CHECK IF ENABLED\n\tli\tr0,0x10\t\t\t#PowerShield ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\tCheckForFollower:\n\tmr\tr3,playerdata\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n#Ensure I'm Actually Coming from Landing (Wait interrupt is used for certain IASA)\n\tlhz\tr3,TM_OneASAgo(playerdata)\n\tcmpwi\tr3,ASID_Landing\n\tbne\tMoonwalk_Exit\n\n#Make Sure Player Didn't Buffer Crouch, Shield, or Walk\n\tlwz\tr3,0x10(playerdata)\n\tcmpwi\tr3,0xF\n\tbeq\tMoonwalk_Exit\n\tcmpwi\tr3,0x10\n\tbeq\tMoonwalk_Exit\n\tcmpwi\tr3,0x11\n\tbeq\tMoonwalk_Exit\n\tcmpwi\tr3,0x27\n\tbeq\tMoonwalk_Exit\n\tcmpwi\tr3,0xB2\n\tbeq\tMoonwalk_Exit\n\tcmpwi r3,ASID_SquatWait\n\tbeq\tMoonwalk_Exit\n\n#Ensure player came from aerial attack landing or special move\nCheckForAerial:\n\tlhz r3,TM_TwoASAgo(playerdata)\n\tcmpwi r3,ASID_AttackAirN\n\tblt\tCheckForSpecialMove\n\tcmpwi r3,ASID_AttackAirLw\n\tbgt CheckForSpecialMove\n\tb\tLandingSearch\nCheckForSpecialMove:\n\tcmpwi r3,ASID_BarrelCannonWait\n\tble\tMoonwalk_Exit\n\nLandingSearch:\n#Calculate Frames Since Wait and Get AS Before Wait\n\tli\tr5,0\t\t#Loop Count\n\tli\tr4,TM_PrevASStart\nLandingSearchLoop:\n\tmulli\tr3,r5,0x2\n\tadd\tr3,r3,r4\n\tlhzx\tr3,r3,playerdata\n\tcmpwi\tr3,ASID_Landing\n\tbeq\tLandingSearchExit\n\taddi\tr5,r5,1\n\tcmpwi\tr5,6\n\tbge\tMoonwalk_Exit\n\tb\tLandingSearchLoop\nLandingSearchExit:\n#Get AS Before Wait\n\taddi\tr3,r5,1\n\tmulli\tr3,r3,0x2\n\tadd\tr3,r3,r4\n\tlhzx\tASBeforeLanding,r3,playerdata\n#Get Frames In Wait\n\tli\tr4,TM_FramesInPrevASStart\t\t#Frame Count Start\n\tli\tFramesSince,0\t\t#Init Frame Count\nFrameCountLoop:\n\tcmpwi\tr5,0\n\tbeq\tFrameCountLoopFinish\n\tmulli\tr3,r5,0x2\n\tadd\tr3,r3,r4\n\tlhzx\tr3,r3,playerdata\n\tadd\tFramesSince,r3,FramesSince\n\tsubi\tr5,r5,1\n\tb\tFrameCountLoop\nFrameCountLoopFinish:\n\tlhz\tr3,TM_FramesInPrevASStart(playerdata)\t\t\t#Frames spent in Wait\n\tadd\tFramesSince,r3,FramesSince\t\t\t#Get Total Frames Since\n#Minus in-actionable frames\n\tlfs\tf1, 0x01F4 (playerdata)\n\tfctiwz f1,f1\n\tstfd f1,0xB0(sp)\n\tlwz r3,0xB4(sp)\n\tsub\tFramesSince,FramesSince,r3\n\n#Change Text Color\n\tcmpwi\tFramesSince,0x0\n\tbne\tRedText\nGreenText:\n\tload\tr3,0x8dff6eff\t\t\t#green\n\tb\tStoreTextColor\nRedText:\n\tload\tr3,0xffa2baff\n\tStoreTextColor:\n\tstw\tr3,0x80(sp)\n\n\n\t\t#Create Text\n\t\tli\tr3,5\t\t\t\t\t#Message Kind\n\t\tlbz\tr4,0xC(playerdata)\t#Message Queue\n\t\tli\tr5,MSGCOLOR_WHITE\n\t\tbl\tText\n\t\tmflr  r6\n\t\taddi\tr7,FramesSince,1\n\t\tMessage_Display\n\t\t\n\t\tChangeColor:\n\t\tlwz\tr3,0x2C(r3)\n\t\tlwz\tr3,MsgData_Text(r3)\n\t\tli\tr4,1\n\t\taddi r5,sp,0x80\n\t\tbranchl r12,Text_ChangeTextColor\n\n\n\n\tb Moonwalk_Exit\n\n###################\n## TEXT CONTENTS ##\n###################\n\nText:\nblrl\n.string \"Act OoAutoCancel\\nFrame: %d\"\n.align 2\n\n##############################\n\n\nMoonwalk_Exit:\nrestoreall\nlwz\tr0, 0x002C (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Act OoWait/Act OoWait - From Wait.asm",
    "content": "#To be inserted at 8008A630\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,30\n.set player,31\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\n#Check If Interrupted\n\tcmpwi\tr3,0x0\n\tbeq\tMoonwalk_Exit\n\n#Get Playerdata\n\tlwz\tplayerdata,0x2C(player)\n\n#Ensure I'm Actually Coming from Wait (Wait interrupt is used for certain IASA)\n\tlhz\tr3,TM_OneASAgo(playerdata)\n\tcmpwi\tr3,0xE\n\tbne\tMoonwalk_Exit\n\n#Make Sure Player Didn't Buffer Crouch, Shield, or Walk\n\tlwz\tr3,0x10(playerdata)\n\tcmpwi\tr3,0xF\n\tbeq\tMoonwalk_Exit\n\tcmpwi\tr3,0x10\n\tbeq\tMoonwalk_Exit\n\tcmpwi\tr3,0x11\n\tbeq\tMoonwalk_Exit\n\tcmpwi\tr3,0x27\n\tbeq\tMoonwalk_Exit\n\tcmpwi\tr3,0xB2\n\tbeq\tMoonwalk_Exit\n\tcmpwi r3,ASID_SquatWait\n\tbeq\tMoonwalk_Exit\n\n#Check To Display OSD\n\tmr\tr3,r31\n\tbranchl\tr12,0x8000551c\n\nMoonwalk_Exit:\nrestoreall\nlwz\tr0, 0x001C (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Additional Playerblock Variables/Fastfall Timer/Display FF Timing.asm",
    "content": "#To be inserted at 8007d57c\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set REG_FighterData,31\n.set player,30\n.set REG_TextColor,29\n.set REG_Text,28\n\t\t\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\nmr\tREG_FighterData,r3\n\n\n\t#CHECK IF ENABLED\n\tli\tr0,OSD.Fastfall\t\t\t#PowerShield ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\tCheckForFollower:\n\tmr\tr3,REG_FighterData\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n\t#Check If Falling Off Ledge and Respawn Platform\n\tlhz\tr3,TM_OneASAgo(REG_FighterData)\n#\tcmpwi\tr3,0xFD\t\t\t#CliffWait\n#\tbeq\tMoonwalk_Exit\n\tcmpwi\tr3,0xD\t\t\t#RebirthWait\n\tbeq\tMoonwalk_Exit\n\n\tPrintMessage:\n\tli\tr3,7\t\t\t\t\t\t#Message Kind\n\tlbz\tr4,0xC(REG_FighterData)\t\t#Message Queue\n\tli\tr5,MSGCOLOR_WHITE\n\tbl\tFastfall_String\n\tmflr r6\n\tlhz\tr7,TM_CanFastfallFrameCount(REG_FighterData)\n\tMessage_Display\n\tlwz\tr3,0x2C(r3)\n\tlwz\tREG_Text,MsgData_Text(r3)\n\n\t#Check if frame 1\n\tlhz\tr3,TM_CanFastfallFrameCount(REG_FighterData)\n\tcmpwi\tr3,1\n\tbne\tMoonwalk_Exit\n\tmr\tr3,REG_Text\n\tli\tr4,1\n\tbl\tColors\n\tmflr\tr5\n\tbranchl r12,Text_ChangeTextColor\n\n\tb Moonwalk_Exit\n\n###################\n## TEXT CONTENTS ##\n###################\n\nFastfall_String:\nblrl\n.string \"Fastfall\\nFrame %d\"\n.align 2\n\nColors:\nblrl\n.long 0x8dff6eff\t#green\n\n##############################\n\n\nMoonwalk_Exit:\nrestoreall\nli\tr0, 1\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Additional Playerblock Variables/Fastfall Timer/Increment Fastfall Variable.asm",
    "content": "#To be inserted at 8007d550\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set player,31\n.set Text,30\n.set TextProp,29\n\n#Increment FastFall Variable\nlhz\tr6,TM_CanFastfallFrameCount(r3)\naddi\tr6,r6,0x1\nsth\tr6,TM_CanFastfallFrameCount(r3)\n\n#Original Codeline\nlwz\tr6, -0x514C (r13)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Additional Playerblock Variables/Fastfall Timer/Initialize Fastfall Variable.asm",
    "content": "#To be inserted at 800698c8\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set player,31\n.set Text,30\n.set TextProp,29\n\n#Store IsFastFalling Bit (Original Line)\nstb\tr0, 0x221A (r26)\n\n#Initialize FastFall Variable\nli\tr0,0\nsth\tr0,TM_CanFastfallFrameCount(r26)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Additional Playerblock Variables/Frame Advantage/Initialize Frame Advantage Think.asm",
    "content": "#To be inserted at 80092e68\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set REG_FighterData,30\n.set player,31\n.set text,29\n.set actionableFlag,28\n.set hitbool,27\n.set REG_FrameAdvantage,26\n.set REG_TextColor,25\n\n##############################\n## Init FrameAdvantageThink ##\n##############################\n\n#CHECK IF ENABLED\n\tli\tr0,OSD.FrameAdvantage\t\t\t#PowerShield ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4, 0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tInjectionExit\n\n\t\t#Check If Entity That Hit Shield Was a Player\n\t\t\tlwz\tr3, 0x002C (r30)\n\t\t\tlwz\tr3, 0x19A8 (r3)\n\t\t\tbranchl\tr12,0x80086960\n\t\t\tcmpwi\tr3,0x0\n\t\t\tbeq\tInjectionExit\n\n\t\t#Store Pointer to Frame Advantage Think\n\t\t\tbl\tFrameAdvantageThink\n\t\t\tmflr\tr3\n\t\t\tlwz\tr4, 0x002C (r30)\n\t\t\tlwz\tr4, 0x19A8 (r4)\n\t\t\tlwz\tr4, 0x002C (r4)\n\t\t\tstw\tr3, TM_AnimCallback (r4)\n\nb\tInjectionExit\n\n\n###########################\n## Frame Advantage Think ##\n###########################\n\nFrameAdvantageThink:\nblrl\n\n.set REG_VictimData, 20\n\nbackup\n\n\n\nmr\tplayer,r3\nlwz\tREG_FighterData,0x2c(player)\n\n\t#Get Entity Who Shielded Attack\n\t\tlwz\tREG_VictimData,TM_PlayerWhoShieldedAttack(REG_FighterData)\n\n\t#Self Destruct If Player was Hit or Grabbed\n\t#Check Hitstun\n\t\tlbz\tr3, 0x221C (REG_FighterData)\n\t\trlwinm.\tr0, r3, 31, 31, 31\n\t\tbne\tSelfDestruct\n\t#Check Grabbed AS's\n\t\tlwz\tr3,0x10(REG_FighterData)\n\t\tcmpwi\tr3,0xDF\n\t\tblt\tSkipGrabCheck\n\t\tcmpwi\tr3,0xE8\n\t\tbgt\tSkipGrabCheck\n\t\tb\tSelfDestruct\n\t\tSkipGrabCheck:\n\n\t#Check If ShieldStun Ended\n\t\t#lwz\tr3,0x10(REG_VictimData)\n\t\t#cmpwi\tr3,0xB5\n\t\t#beq\tMoonwalk_Exit\n\n\t#########################\n\t## Check If Actionable ##\n\t#########################\n\n\t#Am I in Non-IASA Landing?\n\t\tlwz\tr3,0x10 (REG_FighterData)\n\t\tcmpwi\tr3,0x2A\n\t\tbne\tSkipIASALandingCheck\n\t\tlfs\tf1, 0x0894 (REG_FighterData)\n\t\tlfs\tf0, 0x01F4 (REG_FighterData)\n\t\tfcmpo\tcr0,f1,f0\n\t\tbge\tActionable\n\t\tSkipIASALandingCheck:\n\t#Check For Any Form of Jumping/Falling\n\t\tcmpwi\tr3,0x19\n\t\tblt\tSkipJumpFallCheck\n\t\tcmpwi\tr3,0x22\n\t\tbgt\tSkipJumpFallCheck\n\t\tb\tActionable\n\t\tSkipJumpFallCheck:\n\t#Check For AS Wait\n\t\tcmpwi\tr3,0xE\n\t\tbeq\tActionable\n\t#Check For AS CrouchWait\n\t\tcmpwi\tr3,0x28\n\t\tbeq\tActionable\n\t#Check For Peach Float\n\t\tlwz\tr4,0x4(REG_FighterData)\n\t\tcmpwi\tr4,0x9\n\t\tbne\tSkipPeachFloat\n\t\tcmpwi\tr3,0x155\n\t\tbeq\tActionable\n\t\tSkipPeachFloat:\n\n\t###########################\n\t## Check For IASA States ##\n\t###########################\n\n\t#Check Jabs Tilts Aerials Smash Attacks\n\t\tcmpwi\tr3,0x2C\n\t\tblt\tSkipAttackCheck\n\t\tcmpwi\tr3,0x45\n\t\tbgt\tSkipAttackCheck\n\t\tb\tCheckIASA\n\t\tSkipAttackCheck:\n\t#Check Throws\n\t\tcmpwi\tr3,0xDB\n\t\tblt\tSkipThrowCheck\n\t\tcmpwi\tr3,0xDE\n\t\tbgt\tSkipThrowCheck\n\t\tb\tCheckIASA\n\t\tSkipThrowCheck:\n\n\tb\tMoonwalk_Exit\n\n\n\t#########################\n\t## Check for IASA Flag ##\n\t#########################\n\n\tCheckIASA:\n\t\tlbz\tr3,0x2218(REG_FighterData)\n\t\trlwinm.\tr3,r3,0,24,24\n\t\tbeq\tMoonwalk_Exit\n\n\n\t##########################\n\t## Get Frame Advantages ##\n\t##########################\n\n\n\tActionable:\n\t#Check If Still in ShieldStun\n\t\tlwz\tr3,0x10(REG_VictimData)\n\t\tcmpwi\tr3,0xB5\n\t\tbne\tCheckFramesPassed\n\n\n\t####################################\n\t## Get Frames of Shield Stun Left ##\n\t####################################\n\n\t#Check Frames Left of Shield Stun\n\t\tlwz \tr3,0x590(REG_VictimData)\t\t\t#get anim data\n\t\tlfs\tf1,0x008(r3)\t\t\t#get anim length (float)\n\t\tlfs\tf2,0x89C(REG_VictimData)\t\t\t#get anim speed\n\t\tlfs\tf3,0x894(REG_VictimData)\t\t\t#get current AS\n\t\tfdivs\tf4,f1,f2\t\t\t#get calculated AS length in f4\n\t\tfdivs\tf1,f3,f1\t\t\t#yields percentage of animation finished\n\t\tfmuls\tf1,f4,f1\t\t\t#(DEFINED_LENGTH)*(PERCENTAGE)\n\t\tfsubs\tf3,f4,f1\t\t\t#SUBTRACT FROM DEFINED\n\n\t\t\t\tConvertASFrameToInt:\n\t\t\t\t#ROUND APPROX FRAMES LEFT UP\n\t\t\t\t#GET FRAME NUMBER IN F1 WITHOUT DECIMAL POINT\n\t\t\t\tfctiwz\tf1,f3\n\t\t\t\tstfd\tf1,0xF0(sp)\n\t\t\t\tlwz\tr3,0xF4(sp)\n\t\t\t\txoris    r4,r3,0x8000\n\t\t\t\tlis   \t r5,0x4330\n\t\t\t\tstw   \t r5,0xF0(sp)\n\t\t\t\tstw   \t r4,0xF4(sp)\n\t\t\t\tlfd   \t f1,0xF0(sp)\n\t\t\t\tlfd\t f2,-0x7470(rtoc)    \t\t\t#load magic number\n\t\t\t\tfsubs    f1,f1,f2\n\n\t\t\t\t#SUBTRACT ROUNDED DOWN NUMBER FROM ORIGINAL TO GET DECIMAL POINT\n\t\t\t\tfsubs\tf1,f3,f1\n\t\t\t\tlfs\tf2, -0x6B00 (rtoc)\t\t\t#get 0 float\n\n\t\t\t\t#CHECK IF GREATER THAN 0.0\n\t\t\t\tfcmpo\tcr0,f1,f2\n\t\t\t\tbeq\tRoundDown\n\n\t\t\t\tRoundUp:\n\t\t\t\taddi\tr5,r3,0x1\n\t\t\t\tb\tSubFrameCount\n\n\t\t\t\tRoundDown:\n\t\t\t\tmr\tr5,r3\n\n\t\t\t\tSubFrameCount:\n\t\t\t\tsubi\tREG_FrameAdvantage,r5,0x1\t\t\t#backup frame number\n\n\n\tb\tCreateTextGObj\n\n\n\t########################################\n\t## Get Frames Since Shield Stun Ended ##\n\t########################################\n\n\tCheckFramesPassed:\n\t#Check How Long Since Opponent's Shield Stun Ended\n\t#Search For Shield Stun In Opponent's Previous Actions\n\t\tli\tr5,0\t\t#loop count init\n\t\taddi\tr4,REG_VictimData,TM_PrevASStart\t\t#Beginning of Prev Actions\n\t\tsubi\tr4,r4,0x2\t\t#Adjust for lhzu instruction\n\tShieldStunSearchLoop:\n\t\tlhzu\tr3,0x2(r4)\t\t#Get AS\n\t\tcmpwi\tr3,0xB5\t\t#Is this shield stun?\n\t\tbeq\tShieldStunFound\n\t\taddi\tr5,r5,1\n\t\tcmpwi\tr5,6\t\t#6 Total Prev Actions\n\t\tbgt\tSelfDestruct\t\t#Self Destruct if not Found\n\t\tb\tShieldStunSearchLoop\n\n\tShieldStunFound:\n\t\tli\tREG_FrameAdvantage,0\t\t#total frame count init\n\t\taddi\tr4,REG_VictimData,TM_FramesInPrevASStart\t\t#Beginning of Prev AS Frames\n\t\tsubi\tr4,r4,0x2\t\t#Adjust for lhzu instruction\n\tShieldStunFrameCountLoop:\n\t\tcmpwi\tr5,0\t\t#Check If Done\n\t\tble\tShieldStunAddCurrentAS\n\t\tlhzu\tr3,0x2(r4)\t\t#Get Frame Count\n\t\tsub\tREG_FrameAdvantage,REG_FrameAdvantage,r3\t\t#Add to Total\n\t\tsubi\tr5,r5,1\n\t\tb\tShieldStunFrameCountLoop\n\tShieldStunAddCurrentAS:\n\t\tlhz\tr3,TM_FramesinCurrentAS(REG_VictimData)\t\t#Add Current AS's Frame Count as Well\n\t\tsub\tREG_FrameAdvantage,REG_FrameAdvantage,r3\n\n\tCreateTextGObj:\n\n\t#Check if frame 1\n\tcmpwi\tREG_FrameAdvantage,-6\n\tblt\tWhiteText\n\tGreenText:\n\tli\tREG_TextColor,MSGCOLOR_GREEN\n\tb\tPrintMessage\t\n\n\tWhiteText:\n\tli\tREG_TextColor,MSGCOLOR_WHITE\n\tb\tPrintMessage\n\n\tPrintMessage:\n\tli\tr3,6\t\t\t\t\t\t#Message Kind\n\tlbz\tr4,0xC(REG_FighterData)\t\t#Message Queue\n\tmr\tr5,REG_TextColor\n\tbl\tFrameAdvantage_String\n\tmflr r6\n\tmr\tr7,REG_FrameAdvantage\n\n\tMessage_Display\n\n\t#Self Destruct\n\tSelfDestruct:\n\t\tli\tr3,0\n\t\tstw\tr3,TM_AnimCallback(REG_FighterData)\n\n\t#Exit\n\t\tb Moonwalk_Exit\n\n###################\n## TEXT CONTENTS ##\n###################\n\nFrameAdvantage_String:\nblrl\n.string \"Frame Advantage\\n%d Frames\"\n.align 2\n\n##############################\n\n\nMoonwalk_Exit:\nrestore\nblr\n\n\n############################################################################\n\n\nInjectionExit:\nlwz\tr3, 0x002C (r30)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Additional Playerblock Variables/Frame Advantage/Save Pointer to Shield Owner On Hit.asm",
    "content": "#To be inserted at 80076eac\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n#################################\n## On Hitbox->Shield Collision ##\n#################################\n\n#Store Pointer to Player Whose Shield Was Hit\nstw\tr31,TM_PlayerWhoShieldedAttack(r29)\n\nInjectionExit:\nlfs\tf1, 0x19B4 (r31)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Additional Playerblock Variables/Previous Move Instance Hit By/Backup Previous Move Instance Player was Hit By.asm",
    "content": "#To be inserted at 8003820c\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n#Backup Previous Move Instance ID\n  lhz r3,0x18EC(r25)\n  sth r3,0x2418(r25)\n\n#Original Line\n  rlwinm.\tr3, r27, 0, 16, 31\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Additional Playerblock Variables/StatesAndTimers/IncFrameCounts.asm",
    "content": "#To be inserted at 8006ab78\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n# Inc Frame Count + Frames Tangible + Hitstun\n\n#Don't Run During Hitlag\nlbz\tr0, 0x2219 (r31)\nrlwinm.\tr0, r0, 30, 31, 31\nbne\texit\n\n########################\n## Increment AS Frame ##\n########################\n\nlhz\tr3,TM_FramesinCurrentAS(r31)\naddi\tr3,r3,0x1\nsth\tr3,TM_FramesinCurrentAS(r31)\n\n##################################\n## Increment Tangibility Frames ##\n##################################\n\n#Check Timer Intangible Count\nlwz\tr3,0x1990(r31)\ncmpwi\tr3,0x0\nbgt\tIsIntangible\n\n#Ensure Player Had Ledge Intang FIRST\nlhz\tr3,TM_TangibleFrameCount(r31)\ncmpwi\tr3,0x0\nbne\tIncTangibleFrames\n#Check For Subaction Intang\nlwz\tr3,0x1988(r31)\ncmpwi\tr3,0x2\nbne\tIncTangibleFrames\n\n#Set Tangible Frames to 0 When Player Has Intangibility\nIsIntangible:\nli\tr3,0x0\nsth\tr3,TM_TangibleFrameCount(r31)\t\t\t#Store Tangible Frame Count\nb\tTangible_End\n\nIncTangibleFrames:\nlhz\tr3,TM_TangibleFrameCount(r31)\naddi\tr3,r3,0x1\nsth\tr3,TM_TangibleFrameCount(r31)\n\nTangible_End:\n\nexit:\nmr\tr3, r30\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Additional Playerblock Variables/StatesAndTimers/ShiftStates.asm",
    "content": "#To be inserted at 800693ec\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n\n# Store Previous AS + Reset AS Frame Count Timer\n\n###################\n## Shift AS ID's ##\n###################\n\n#SHIFT AS ID's\nli\tr12,TM_PrevASSlots-2\t\t\t#Loop Count\n\nASLoop:\naddi\tr3,r26,TM_PrevASStart\t\t\t#Get Start of AS List\nmulli\tr4,r12,2\t\t\t#Current AS ID * Length\nadd\tr4,r3,r4\t\t\t#Get AS Offset in Playerblock\nlhz\tr3,0x0(r4)\t\t\t#Load Previous AS\nsth\tr3,0x2(r4)\t\t\t#Push Back\n\nASIncLoop:\nsubi\tr12,r12,1\ncmpwi\tr12,0x0\nbge\tASLoop\n\n#Move Current AS To Last AS\nlwz\tr3,0x10(r26)\t\t#get action state that we just left\nsth\tr3,TM_PrevASStart(r26)\t\t#store as last action state\n\n#########################\n## SHIFT FRAME NUMBERS ##\n#########################\n\n#SHIFT AS Frame #'s\nli\tr12,TM_PrevASSlots-2\t\t\t#Loop Count\n\nFrameCountLoop:\naddi\tr3,r26,TM_FramesInPrevASStart\t\t\t#Get to the Start of the Frame Counts\nmulli\tr4,r12,2\t\t\t#Current AS ID * Length\nadd\tr4,r3,r4\t\t\t#Get AS Offset in Playerblock\nlhz\tr3,0x0(r4)\t\t\t#Load Previous AS\nsth\tr3,0x2(r4)\t\t\t#Push up\n\nFrameCountIncLoop:\nsubi\tr12,r12,1\ncmpwi\tr12,0x0\nbge\tFrameCountLoop\n\n#Move Current AS Frame To Last AS Frame\naddi\tr3,r26,TM_FramesInPrevASStart\t\t\t#Get to the Start of the Frame Counts\nlhz\tr4,TM_FramesinCurrentAS(r26)\t\t\t#Get AS Frame Number we Just Left\nsth\tr4,0x0(r3)\n\n###########################################\n## Init Current AS Frame To Int Variable ##\n###########################################\n\n\n\n#lfs\tf1,0x894(r26)\n#fctiwz\tf1,f1\n#stfd\tf1,0x8(sp)\n#lwz\tr3,0xC(sp)\nli\tr3,0x0\nsth\tr3,TM_FramesinCurrentAS(r26)\n\nexit:\ncmplwi\tr27, 0\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Check For IC's Static Function.asm",
    "content": "#To be inserted at 80005510\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n.macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n.set TextCreateFunction,0x80005928\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\nbackup\n\nmr\tr31,r3\n\n#Get Byte\nlbz\tr3, 0x221F (playerdata)\n\n#Check If Subchar\nrlwinm.\tr0, r3, 29, 31, 31\nbeq\tNoFollower\n\n#Check If Follower\nlbz\tr3,0xC(playerdata)\t\t\t#get slot\nbranchl\tr12,0x80032330\t\t\t#get external character ID\nload\tr4,0x803bcde0\t\t\t#pdLoadCommonData table\nmulli\tr0, r3, 3\t\t\t#struct length\nadd\tr3,r4,r0\t\t\t#get characters entry\nlbz\tr0, 0x2 (r3)\t\t\t#get subchar functionality\ncmpwi\tr0,0x0\t\t\t#if not a follower, exit\nbne\tNoFollower\n\nFollower:\nli\tr3,0x1\nb\t0x8\n\nNoFollower:\nli\tr3,0x0\n\nMoonwalk_Exit:\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Custom Function Blrl + Keep Combo Counter Going For Missed Techs+Getups.asm",
    "content": "#To be inserted at 8006ab88\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set actionableFlag,28\n.set hitbool,27\n\n#Check For Function Pointer\nlwz\tr12,TM_AnimCallback(r31)\ncmpwi\tr12,0x0\nbeq\tSkipFunctionBlrl\nmtlr\tr12\naddi\tr3, r30, 0\nblrl\nSkipFunctionBlrl:\n\n#################################\n## Check To End Combo Progress ##\n#################################\n\n#Check Hitstun\n\tlbz\tr0, 0x221C (r31)\n\trlwinm.\tr0, r0, 31, 31, 31\n\tbne\tInjectionExit\n#Am I in Missfoot?\n\tlwz\tr3,0x10(playerdata)\n\tcmpwi\tr3,0xFB\n\tbeq\tInjectionExit\n#Am I in Non-IASA Landing?\n\tcmpwi\tr3,0x2A\n\tbne\tSkipIASALandingCheck\n\tlfs\tf1, 0x0894 (playerdata)\n\tlfs\tf0, 0x01F4 (playerdata)\n\tfcmpo\tcr0,f1,f0\n\tblt\tInjectionExit\n\tSkipIASALandingCheck:\n#Am I in Missed Tech, Tech Roll, Slow Getup, Or Getup Attack\n\tlwz\tr0,0x10(playerdata)\n\tcmpwi\tr0,0xB7\n\tblt\tEndCombo\n\tcmpwi\tr0,0xC9\n\tbgt\tCheckGrab\n\tb\tInjectionExit\nCheckGrab:\n\tcmpwi\tr0,0xDF\n\tblt\tEndCombo\n\tcmpwi\tr0,0xE8\n\tbgt\tCheckThrow\n\tb\tInjectionExit\nCheckThrow:\n\tcmpwi\tr0,0xEF\n\tblt\tEndCombo\n\tcmpwi\tr0,0xF3\n\tbgt\tCheckSpecialThrows\n\tb\tInjectionExit\nCheckSpecialThrows:\n\tcmpwi\tr0,0x10A\n\tblt\tEndCombo\n\tcmpwi\tr0,0x130\n\tbgt\tEndCombo\n\tb\tInjectionExit\n\nEndCombo:\n\tlbz\tr3, 0x000C (r31)\n\tlbz\tr4, 0x221F (r31)\n\trlwinm\tr4, r4, 29, 31, 31\n\tbranchl\tr12,0x800411c4\n\n\nInjectionExit:\nlwz\tr0, 0x0034 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Disregard Projectile Hitboxes w Same Move ID.asm",
    "content": "#To be inserted at 800789e0\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n#r31 = Projectile Data\n#r30 = Victim GObj\n\n#Check If Same Move ID as Last Hit\nlwz\tr3,0x2C(r30)\nlhz\tr3,0x18EC(r3)\t\t#Last Move Instance Victim Was Hit By\nlhz\tr4,0xDA8(r31)\t\t#Attacking Player's Current Move Instance\ncmpw\tr3,r4\nbeq\tSkipComboIncrement\n\nb\tExit\n\nSkipComboIncrement:\nbranch\tr12,0x80078a10\n\nExit:\nlwz\tr3, 0x0518 (r31)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Disregard Throw Hitboxes.asm.bak",
    "content": "#To be inserted at 80078950\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n#Original Line\nlwz\tr7, 0x002C (r30)\n\n#Check if this is a Pummel\nlwz\tr3,0x10(r7)\ncmpwi\tr3,0xD9\nbeq\tExit\n\n#Allow for Cliff Attacks\ncmpwi\tr3,0x100\nbeq\tExit\ncmpwi\tr3,0x101\nbeq\tExit\n\n#Check If Attacker Is Grabbable (Attacker is Set Grabbable When the Throw Releases the Victim)\nlhz\tr3,0x1A6A(r7)\t\t#Grabbable Flag\ncmpwi\tr3,0x0\nbne\tSkipComboIncrement\n\n#Check If Attacker Is Throwing, Allow Combo Inc\nlwz\tr3,0x10(r7)\ncmpwi\tr3,0xDB\nblt\tSkipThrowCheck\ncmpwi\tr3,0xDE\nbgt\tSkipThrowCheck\nb\tExit\nSkipThrowCheck:\n\n#Check If Same Move ID as Last Hit\n#lwz\tr3,0x2C(r31)\n#lhz\tr3,0x18EC(r3)\t\t#Last Move Instance Victim Was Hit By\n#lhz\tr4,0x2088(r7)\t\t#Attacking Player's Current Move Instance\n#cmpw\tr3,r4\n#beq\tSkipComboIncrement\n\nb\tExit\n\nSkipComboIncrement:\nbranch\tr12,0x8007897c\n\nExit:\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Interrupting Move with Same Move Gives a Unique ID.asm",
    "content": "#To be inserted at 80089610\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n#Check If Move Was Interrupted With the Same Move\n  lwz r3,0x10(r26)  #New Move\n  lhz r4,TM_OneASAgo(r26)  #Previous Moe\n  cmpw  r3,r4\n  bne Original\n\n#Interrupted move with same move, assign unique move ID\n  branch r12,0x8008961c\n\nOriginal:\n  lbz\tr0, 0x2073 (r31)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Keep Combo Counter Going For Missed Techs+Getups.asm",
    "content": "#To be inserted at 8006ab48\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set player,31\n.set playerdata,31\n\n#Am I in Hitstun? (Ran prior to the injection)\n\n#Am I in Missfoot?\nlwz\tr3,0x10(playerdata)\ncmpwi\tr3,0xFB\nbeq\tContinueCombo\n\n#Am I in Non-IASA Landing?\ncmpwi\tr3,0x2A\nbne\tSkipIASALandingCheck\nlfs\tf1, 0x0894 (playerdata)\nlfs\tf0, 0x01F4 (playerdata)\nfcmpo\tcr0,f1,f0\nblt\tContinueCombo\nSkipIASALandingCheck:\n\n#Am I in Missed Tech, Tech Roll, Slow Getup, Or Getup Attack\nlwz\tr0,0x10(playerdata)\ncmpwi\tr0,0xB7\nblt\tEndCombo\ncmpwi\tr0,0xC9\nbgt\tCheckGrab\nb\tContinueCombo\n\nCheckGrab:\ncmpwi\tr0,0xDF\nblt\tEndCombo\ncmpwi\tr0,0xE8\nbgt\tCheckThrow\nb\tContinueCombo\n\nCheckThrow:\ncmpwi\tr0,0xEF\nblt\tEndCombo\ncmpwi\tr0,0xF3\nbgt\tCheckSpecialThrows\nb\tContinueCombo\n\nCheckSpecialThrows:\ncmpwi\tr0,0x10A\nblt\tEndCombo\ncmpwi\tr0,0x130\nbgt\tEndCombo\nb\tContinueCombo\n\nContinueCombo:\nbranch\tr12,0x8006ab58\n\nEndCombo:\nlbz\tr4, 0x221F (r31)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Pummels and Multi-Hits Increment Total Damage But Not Combo Counter.asm",
    "content": "#To be inserted at 80040f04\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set player,31\n.set playerdata,31\n\n#r27 = Attacker Slot\n#r28 = Victim Slot\n\n#r5 = Attacker\n#r6 = Victim\n\n#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.\n\n\n\n\n#Get Attacker Pointer\n\tmr\tr3,r27\n\tbranchl\tr12,0x80034110\n\tlwz\tr5,0x2C(r3)\n#Get Victim Pointer\n\tmr\tr3,r28\n\tbranchl\tr12,0x80034110\n\tlwz\tr6,0x2C(r3)\n\n\n\n######################\n## Check For Pummel ##\n######################\n\n\tcmpwi\tr30,0x34\n\tbeq\tNoComboInc\n\n#################################\n## Check For Same Move as Last ##\n#################################\n\nSameMoveCheck:\n\tlhz\tr3,0x18EC(r6)\t\t#Last Move Instance Victim Was Hit By\n\tlhz\tr4,0x2088(r5)\t\t#Attacking Player's Current Move Instance\n\tcmpw\tr3,r4\n\tbne\tSkipSameMoveCheck\n#Check If Its a Throw\n\tcmpwi\tr30,0x35\n\tblt\tNoComboInc\n\tcmpwi\tr30,0x38\n\tbgt\tNoComboInc\n#Check If Attacker Is Grabbable (Attacker is Set Grabbable When the Throw Releases the Victim)\n\tlhz\tr3,0x1A6A(r5)\t\t#Grabbable Flag\n\tcmpwi\tr3,0x0\n\tbne\tNoComboInc\n\tb\tOriginal\n\tSkipSameMoveCheck:\n\n################################\n## Check For MidGrab Hitboxes ##\n################################\n\n#Allow Cliff Attacks\n\tcmpwi\tr30,0x3F\n\tbeq\tOriginal\n\tcmpwi\tr30,0x3E\n\tbeq\tOriginal\n\n#Check If Attacker Is Grabbable (Attacker is Set Grabbable When the Throw Releases the Victim)\n\tlhz\tr3,0x1A6A(r5)\t\t#Grabbable Flag\n\tcmpwi\tr3,0x0\n\tbne\tNoComboInc\n\n\tb\tOriginal\n\n\n\nNoComboInc:\n#Spoof Pummel as Some Other Move that Triggers the Check\n\tli\tr30,76\n\nOriginal:\naddi\tr3, r28, 0\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Skip Original Combo End Check.asm",
    "content": "#To be inserted at 8006ab44\nb 0x14"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Combo Counter/Better Combo Counter/Throw Hitboxes Update (Last Damage Source) Variable in Playerblock.asm",
    "content": "#To be inserted at 800dde68\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set player,31\n.set playerdata,31\n\n#Store/Update Last Damage Source For Victim\nstw\tr24,0x1868(r30)\n\nExit:\n#Original Line\nlwz\tr0, 0x1988 (r30)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Combo Counter/Combo Counter - On Combo Increment.asm",
    "content": "#To be inserted at 80040fa4\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set ComboCount,28\n.set hitbool,27\n\n.set MessageAreaLength,0x100\n.set PerPlayerMessageStructLength,0x28\n\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackup\n\n\t#Backup Combo Count\n\tlhz\tComboCount,0x14(r3)\n\n\t#CHECK IF ENABLED\n\tli\tr0,OSD.ComboCounter\t\t\t#PowerShield ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\t#Get Playerdata\n\tmr\tr3,r27\n\tbranchl\tr12,0x80034110\n\tmr\tplayer,r3\n\tlwz\tplayerdata,0x2C(player)\n\n\tCheckForFollower:\n\tmr\tr3,playerdata\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n\t#Check If Combo Count is 2 Hits or Higher\n\tcmpwi\tComboCount,2\n\tblt\tMoonwalk_Exit\n\n\t\tbl\tCreateText\n\n\t#Create Text\n\t\tbl\tTopText\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,0x803a6b98\n\n\t#Get Damage as Int\n\t\tlbz\tr3,0xC(playerdata)\n\t\tbranchl\tr12,0x80041300\n\t\tmr\tr6,r3\n\n\t#Create Text2\n\t\tbl\tBottomText\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tmr\tr5,ComboCount\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\t\tbranchl r12,0x803a6b98\n\n\t#Store Per Frame Function to Monitor When Hitstun Runs Out\n\t\tlwz\tr3,0x2094(playerdata)\n\t#Check If Valid Player GObj\n\t\tbranchl\tr12,0x80086960\n\t\tcmpwi\tr3,0\n\t\tbeq\tMoonwalk_Exit\n\t#Store Function\n\t\tbl\tHitstunMonitor\n\t\tmflr\tr3\n\t\tlwz\tr4,0x2094(playerdata)\n\t\tlwz\tr4,0x2C(r4)\n\t\tstw\tr3,TM_AnimCallback(r4)\n\n\t\tb Moonwalk_Exit\n\n\n\tCreateText:\n\tmflr\tr0\n\tstw\tr0, 0x0004 (sp)\n\tstwu\tsp, -0x0008 (sp)\n\tmr\tr3,playerdata\t\t\t#backup playerdata pointer\n\tli\tr4,120\t\t\t#display until terminated\n\tli\tr5,0\t\t\t#Area to Display (0-2)\n\tli\tr6,13\t\t\t#Window ID (Unique to This Display)\n\tbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\n\n\tmr\ttext,r3\t\t\t#backup text pointer\n\tlwz\tr0, 0x000C (sp)\n\taddi\tsp, sp, 8\n\tmtlr r0\n\tblr\n\n\n###################\n## TEXT CONTENTS ##\n###################\n\nTopText:\nblrl\n.string \"Combo Count\"\n.align 2\n\nBottomText:\nblrl\n.string \"%d Hits / %d%\"\n.align 2\n/*\n.long 0x25642048\n.long 0x69747320\n.long 0x815e2025\n.long 0x64819300\n*/\n\n##############################\n\nHitstunMonitor:\nblrl\n\nbackup\n\n#Get Pointers\n\tmr\tplayer,r3\n\tlwz\tplayerdata,0x2C(player)\n\n#Get Damage Source (Person Combo'ing Me)\n\tlwz\tr3,0x1868(playerdata)\n#Ensure It's a Player\n\tbranchl\tr12,0x80086960\n\tcmpwi\tr3,0x0\n\tbeq\tHitstunMonitor_SelfDestruct\n\tlwz\tr28,0x1868(playerdata)\n\tlwz\tr28,0x2C(r28)\t\t\t#Save For Later\n\n#Check If Combo Has Ended\n#Am I in Hitstun?\n\tlbz\tr0, 0x221C (playerdata)\n\trlwinm.\tr0, r0, 31, 31, 31\n\tbne\tHitstunMonitor_ContinueCombo\n#Am I in Missfoot?\n\tlwz\tr3,0x10(playerdata)\n\tcmpwi\tr3,0xFB\n\tbeq\tHitstunMonitor_ContinueCombo\n#Am I in Non-IASA Landing?\n\tcmpwi\tr3,0x2A\n\tbne\tHitstunMonitor_SkipIASALandingCheck\n\tlfs\tf1, 0x0894 (playerdata)\n\tlfs\tf0, 0x01F4 (playerdata)\n\tfcmpo\tcr0,f1,f0\n\tblt\tHitstunMonitor_ContinueCombo\nHitstunMonitor_SkipIASALandingCheck:\n#Am I in Missed Tech, Tech Roll, Slow Getup, Or Getup Attack\n\tlwz\tr0,0x10(playerdata)\n\tcmpwi\tr0,0xB7\n\tblt\tHitstunMonitor_EndCombo\n\tcmpwi\tr0,0xC9\n\tbgt\tHitstunMonitor_CheckGrab\n\tb\tHitstunMonitor_ContinueCombo\nHitstunMonitor_CheckGrab:\n\tcmpwi\tr0,0xDF\n\tblt\tHitstunMonitor_EndCombo\n\tcmpwi\tr0,0xE8\n\tbgt\tHitstunMonitor_CheckThrow\n\tb\tHitstunMonitor_ContinueCombo\nHitstunMonitor_CheckThrow:\n\tcmpwi\tr0,0xEF\n\tblt\tHitstunMonitor_EndCombo\n\tcmpwi\tr0,0xF3\n\tbgt\tHitstunMonitor_CheckSpecialThrows\n\tb\tHitstunMonitor_ContinueCombo\nHitstunMonitor_CheckSpecialThrows:\n\tcmpwi\tr0,0x10A\n\tblt\tHitstunMonitor_EndCombo\n\tcmpwi\tr0,0x130\n\tbgt\tHitstunMonitor_EndCombo\n\tb\tHitstunMonitor_ContinueCombo\n\n\nHitstunMonitor_EndCombo:\n#Find MessageBox Pointer\n#Get Player's Message Struct in r29\n\tload\tr3,0x804a1f58\n\tlwz\tr29,0x4(r3)\n\tlbz\tr3,0xC(r28)\n\tmulli\tr4,r3,PerPlayerMessageStructLength\n\tadd\tr29,r29,r4\n#Init Search Loop\n\tli\tr27,0\nHitstunMonitor_SearchLoop:\n\tmulli\tr3,r27,8\n\tadd\tr3,r3,r29\n\tlhz\tr4,0x6(r3)\t\t#Get OSD ID\n\tcmpwi\tr4,13\n\tbeq\tHitstunMonitor_EditOSD\n\taddi\tr27,r27,1\n\tcmpwi\tr27,4\n\tble\tHitstunMonitor_SearchLoop\n\n#OSD Not Found, Self Destruct\n\tb\tHitstunMonitor_SelfDestruct\n\nHitstunMonitor_EditOSD:\n\tmr\tr26,r3\t\t\t#Backup OSD Info\n#Set Time To Expire\n\tli\tr3,60\n\tsth\tr3,0x4(r26)\n#Get Green On Stack\n\tload\tr3,0x8dff6eff\n\tstw\tr3,0xF0(sp)\n#Change Subtext's Colors\n\tlwz\tr3,0x0(r26)\n\tli\tr4,1\n\taddi\tr5,sp,0xF0\n\tbranchl\tr12,0x803a74f0\n\tlwz\tr3,0x0(r26)\n\tli\tr4,2\n\taddi\tr5,sp,0xF0\n\tbranchl\tr12,0x803a74f0\n\nHitstunMonitor_SelfDestruct:\n\tli\tr3,0\n\tstw\tr3,TM_AnimCallback(playerdata)\n\nHitstunMonitor_ContinueCombo:\nHitstunMonitor_Exit:\nrestore\nblr\n\n##############################\n\n\n\nMoonwalk_Exit:\nrestore\nlmw\tr27, 0x0024 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Dashback/Dashback Display - Static Function.asm",
    "content": "#To be inserted at 80005518\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set REG_FighterData,31\n.set player,30\n.set REG_DBBool, 29\n.set REG_String, 28\n.set REG_DBRate,27\n.set REG_TextColor,26\n.set REG_Text,25\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\nmr\tplayer,r3\nlwz\tREG_FighterData,0x2C(player)\nmr\tREG_DBBool,r4\t\t\t\t#Dashback Bool\n\n\t#CHECK IF ENABLED\n\tli\tr0,OSD.Dashback\t\t\t#wavedash ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\tCheckForFollower:\n\tmr\tr3,REG_FighterData\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n\t#Change color to Green if frame perfect act oos\n\t\tcmpwi\tREG_DBBool,0x0\n\t\tbeq\tFailedDB\n\t#Check If UCF DB or Vanilla DB\n\t\tlwz\tr3,0x2350(REG_FighterData)\t\t #get turn flag\n\t\tcmpwi\tr3,0x0\t\t\t#if 0, was a smash turn\n\t\tbne\tUCFDB\n\t\tVanillaDB:\n\t\tmr\tr3,REG_FighterData\n\t\tbl\tIncDBRate\n\t\tmr\tREG_DBRate,r3\n\t\tbl\tDBVanilla_String\n\t\tmflr REG_String\n\t\tli\tREG_TextColor,MSGCOLOR_GREEN\n\t\tb\tPrintMessage\t\n\t\tUCFDB:\n\t\tmr\tr3,REG_FighterData\n\t\tbl\tIncDBRate\n\t\tmr\tREG_DBRate,r3\n\t\tbl\tDBUCF_String\n\t\tmflr REG_String\n\t\tli\tREG_TextColor,MSGCOLOR_YELLOW\n\t\tb\tPrintMessage\n\t\tFailedDB:\n\t\tmr\tr3,REG_FighterData\n\t\tbl\tDecDBRate\n\t\tmr\tREG_DBRate,r3\n\t\tbl\tDBFailed_String\n\t\tmflr REG_String\n\t\tli\tREG_TextColor,MSGCOLOR_RED\n\t\tb\tPrintMessage\n\n\t\tPrintMessage:\n\t\tli\tr3,4\t\t\t#Message Kind\n\t\tlbz\tr4,0xC(REG_FighterData)\t#Message Queue\n\t\tli\tr5,MSGCOLOR_WHITE\n\t\tmr\tr6,REG_String\n\t\tmr\tr7,REG_DBRate\n\t\tMessage_Display\n\t\tlwz\tr3,0x2C(r3)\n\t\tlwz\tREG_Text,MsgData_Text(r3)\n\n\t\t# adjust top line color\n\t\tbl\tColors\n\t\tmflr\tr3\n\t\tcmpwi\tREG_TextColor,MSGCOLOR_GREEN\n\t\tbeq\tGreenText\n\t\tcmpwi\tREG_TextColor,MSGCOLOR_RED\n\t\tbeq\tRedText\t\n\t\tYellowText:\n\t\taddi r5,r3,0x4\n\t\tb\tChangeColor\n\t\tGreenText:\n\t\taddi r5,r3,0x0\n\t\tb\tChangeColor\n\t\tRedText:\n\t\taddi r5,r3,0x8\n\t\tb\tChangeColor\n\n\t\tChangeColor:\n\t\tmr\tr3,REG_Text\n\t\tli\tr4,0\n\t\tbranchl r12,Text_ChangeTextColor\n\n\t\tb Moonwalk_Exit\n\n#########################\n### DB Rate Functions ###\n#########################\n\nIncDBRate:\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nmflr r0\nstw r0,0xFC(sp)\nlbz\tr3,0xC(r3)\t\t#get player slot\nload\tr4,0x804a1fc8\t\t#get DB rate mem location\nmulli\tr3,r3,0x4\t\t#length of players DB info\nadd\tr8,r3,r4\t\t#players DB info in r8\nlhz\tr3,0x0(r8)\t\t#successful DBs\naddi\tr3,r3,0x1\nsth\tr3,0x0(r8)\t\t#successful DBs\nlhz\tr3,0x2(r8)\t\t#total DBs\naddi\tr3,r3,0x1\nsth\tr3,0x2(r8)\t\t#total DBs\nmr\tr3,r8\nbl\tGetDBRate\nlwz r0,0xFC(sp)\nmtlr r0\naddi\tr1,r1,0x100\t# release the space\nblr\n\nDecDBRate:\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nmflr r0\nstw r0,0xFC(sp)\nlbz\tr3,0xC(r3)\t\t#get player slot\nload\tr4,0x804a1fc8\t\t#get DB rate mem location\nmulli\tr3,r3,0x4\t\t#length of players DB info\nadd\tr8,r3,r4\t\t#players DB info in r8\nlhz\tr3,0x2(r8)\t\t#total DBs\naddi\tr3,r3,0x1\nsth\tr3,0x2(r8)\t\t#total DBs\nmr\tr3,r8\nbl\tGetDBRate\nlwz r0,0xFC(sp)\nmtlr r0\naddi\tr1,r1,0x100\t# release the space\nblr\n\n\nGetDBRate:\n#Get Values\nlhz\tr4,0x0(r3)\t\t#successful DBs\nlhz\tr5,0x2(r3)\t\t#total DBs\n#Get as Floats (f1 = successful, f2 = total\nlis\tr0, 0x4330\nlfd\tf5, -0x6758 (rtoc)\nxoris\tr6, r4, 0x8000\nxoris\tr7, r5, 0x8000\nstw\tr0,0xF0(sp)\n#Successful DB\nstw\tr6,0xF4(sp)\nlfd\tf1,0xF0(sp)\nfsubs\tf1,f1,f5\n#Total DB\nstw\tr7,0xF4(sp)\nlfd\tf2,0xF0(sp)\nfsubs\tf2,f2,f5\n#100f\nli\tr4,100\nxoris\tr4,r4,0x8000\nstw\tr4,0xF4(sp)\nlfd\tf3,0xF0(sp)\nfsubs\tf3,f3,f5\nfdivs\tf1,f1,f2\t\t#successful DB / total DB\nfmuls\tf1,f1,f3\t\t#times 100\n#Back to Int\nfctiwz\tf1,f1\nstfd\tf1,0xF0(sp)\nlwz\tr3,0xF4(sp)\nblr\n\n\n###################\n## TEXT CONTENTS ##\n###################\n\nDBVanilla_String:\nblrl\n.string \"Vanilla Dashback\\nSuccession: %d%\"\n.align 2\n\nDBUCF_String:\nblrl\n.string \"UCF Dashback\\nSuccession: %d%\"\n.align 2\n\nDBFailed_String:\nblrl\n.string \"Failed Dashback\\nSuccession: %d%\"\n.align 2\n\nColors:\nblrl\n.long 0x8dff6eff\t#green\n.long 0xfff000ff \t#yellow\n.byte 255, 162, 186, 255 \t#red\n##############################\n\n\nMoonwalk_Exit:\nrestoreall\nblr\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Dashback/Grab Out of Tilt Turn.asm.bak",
    "content": "#To be inserted at 800c9b38\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\n\t#Check If Jumped\n\tcmpwi\tr3,0x0\n\tbeq\tMoonwalk_Exit\n\n\t#Check If Dashed Back (Flag at 0x2340)\n\tmr\tr3,player\n\tmr\tr4,r20\n\tbranchl\tr12,0x80005518\n\nMoonwalk_Exit:\nrestoreall\ncmpwi\tr3,0x0\n\ncmpwi\tr20, 0\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Dashback/Run Out of Tilt Turn.asm",
    "content": "#To be inserted at 800c9b88\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\n\t#Ensure NOT Coming From Dash or Crouch\n\tlhz\tr3,TM_OneASAgo(playerdata)\t\t\t#load last AS\n\tcmpwi\tr3,0x14\n\tbeq\tMoonwalk_Exit\n\tcmpwi\tr3,0x28\n\tbeq\tMoonwalk_Exit\n\n\t#Check If Dashed Back (Flag at 0x2340)\n\tmr\tr3,player\n\tlhz\tr4,0x894(playerdata)\n\tcmpwi\tr4,0x4000\n\tbeq\t0xC\n\tli\tr4,0x0\n\tb\t0x8\n\tli\tr4,0x1\n\tbranchl\tr12,0x80005518\n\nMoonwalk_Exit:\nrestoreall\nmr\tr3,r30\nli\tr4,0x0\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Fox Training Codes/Side B Shorten Display.asm",
    "content": "#To be inserted at 8006b7f4\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\n\t#General AS's\n\n\n\t#Check If Fox or Falco\n\tlwz\tr3,0x4(playerdata)\n\tcmpwi\tr3,0x1\n\tbeq\tFoxFalco\n\tcmpwi\tr3,0x16\n\tbeq\tFoxFalco\n\n\t#Check If Anyone Else\n\tb\tMoonwalk_Exit\n\n#/////////////////////////////////////////////////////////////////////////////\n\n\tFoxFalco:\n\t#CHECK IF ENABLED\n\tli\tr0,OSD.SpacieTech\t\t\t#Fox Training Codes ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\t#Branch to AS Functions\n\tlwz\tr3,0x10(playerdata)\n\tcmpwi\tr3,0x15B\t\t\t#Ground Side B Start\n\tbeq\tFox_SideBStart\n\tcmpwi\tr3,0x15E\t\t\t#Air Side B Start\n\tbeq\tFox_SideBStart\n\n\tcmpwi\tr3,0x15C\t\t\t#Ground Side B\n\tbeq\tFox_SideB\n\tcmpwi\tr3,0x15F\t\t\t#Air Side B\n\tbeq\tFox_SideB\n\n\tcmpwi\tr3,0x15D\t\t\t#Ground Side B End\n\tbeq\tFox_SideBEnd\n\tcmpwi\tr3,0x160\t\t\t#Air Side B End\n\tbeq\tFox_SideBEnd\n\n\tcmpwi\tr3,0x169\n\tbeq\tFox_ShineGroundLoop\n\tcmpwi\tr3,0x16E\n\tbeq\tFox_ShineAirLoop\n\n\n\tb\tMoonwalk_Exit\n\n#/////////////////////////////////////////////////////////////////////////////\n\n\tFox_SideBStart:\n\t#Check If Pressed B\n\tlwz\tr3,0x668(playerdata)\n\trlwinm.\tr3,r3,0,22,22\n\tbeq\tFox_SideBStart_NoPress\n\n\t#Create Text\n\tbl\tCreateText\n\tmr\ttext,r3\t\t\t#backup text pointer\n\n\t#Change Text Color\n\tload\tr3,0xffa2baff\n\tstw\tr3,0x30(text)\n\n\t#Create Top Line\n\tbl\tShortenPress\n\n\t#Create Bottom Line\n\t#Get Current Frame\n\t#lfs\tf1,0x894(playerdata)\n\t#fctiwz\tf1,f1\n\t#stfd\tf1,0xF0(sp)\n\t#lwz\tr3,0xF4(sp)\n\tlhz\tr3,0x23EC(playerdata)\n\t#Get Frames Early\n\tlwz \tr5,0x590(playerdata)\t\t\t#get anim data\n\tlfs\tf1,0x008(r5)\t\t\t#get anim length (float)\n\tfctiwz\tf1,f1\n\tstfd\tf1,0xF0(sp)\n\tlwz\tr4,0xF4(sp)\n\tsub\tr5,r4,r3\n\tsubi\tr5,r5,0x1\n\n\tbl\tEarlyPressText\n\tmflr\tr4\n\tmr\tr3,text\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\tbranchl r12,0x803a6b98\n\n\n\tFox_SideBStart_NoPress:\n\tb\tMoonwalk_Exit\n\n#/////////////////////////////////////////////////////////////////////////////\n\n\tFox_SideB:\n\t#Check If Pressed B\n\tlwz\tr3,0x668(playerdata)\n\trlwinm.\tr3,r3,0,22,22\n\tbeq\tFox_SideB_NoPress\n\n\t#Create Text\n\tbl\tCreateText\n\tmr\ttext,r3\t\t\t#backup text pointer\n\n\t#Change Text Color\n\tload\tr3,0x8dff6eff\n\tstw\tr3,0x30(text)\n\n\t#Create Top Line\n\tbl\tShortenPress\n\n\t#Create Bottom Line\n\t#Get Current Frame\n\tlfs\tf1,0x894(playerdata)\n\tfctiwz\tf1,f1\n\tstfd\tf1,0xF0(sp)\n\tlwz\tr3,0xF4(sp)\n\t#Get Frames Early\n\taddi\tr5,r3,0x1\n\n\tbl\tShortenTypeText\n\tmflr\tr4\n\tmr\tr3,text\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\tbranchl r12,0x803a6b98\n\n\tFox_SideB_NoPress:\n\tb\tMoonwalk_Exit\n\n#/////////////////////////////////////////////////////////////////////////////\n\n\tFox_SideBEnd:\n\t#Check If Pressed B\n\tlwz\tr3,0x668(playerdata)\n\trlwinm.\tr3,r3,0,22,22\n\tbeq\tFox_SideBEnd_NoPress\n\n\t#Create Text\n\tbl\tCreateText\n\tmr\ttext,r3\t\t\t#backup text pointer\n\n\t#Change Text Color\n\tload\tr3,0xffa2baff\n\tstw\tr3,0x30(text)\n\n\t#Create Top Line\n\tbl\tShortenPress\n\n\t#Create Bottom Line\n\t#Get Current Frame\n\t#lfs\tf1,0x894(playerdata)\n\t#fctiwz\tf1,f1\n\t#stfd\tf1,0xF0(sp)\n\t#lwz\tr3,0xF4(sp)\n\tlhz\tr5,0x23EC(playerdata)\n\t#addi\tr5,r3,0x1\n\n\tbl\tLatePressText\n\tmflr\tr4\n\tmr\tr3,text\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\tbranchl r12,0x803a6b98\n\n\tFox_SideBEnd_NoPress:\n\tb\tMoonwalk_Exit\n\n#/////////////////////////////////////////////////////////////////////////////\n\n\nFox_ShineGroundLoop:\n\t#Check For JC\n\tbl\tCheckForJumpCancel\n\tcmpwi\tr3,0x0\n\tbeq\tMoonwalk_Exit\n\n\tFox_ShineGroundLoop_Interrupted:\n\t#Create Text\n\tbl\tCreateText\n\tmr\ttext,r3\t\t\t#backup text pointer\n\n\n\t\t#Check If Frame Perfect\n\t\t#Get Current Frame\n\t\t#lfs\tf1,0x894(playerdata)\n\t\t#fctiwz\tf1,f1\n\t\t#stfd\tf1,0xF0(sp)\n\t\t#lwz\tr3,0xF4(sp)\n\t\tlhz\tr3,0x23EC(playerdata)\n\t\tcmpwi\tr3,0x1\n\t\tbne\tFox_ShineGroundLoop_RedText\n\n\t\t#Frame Perfect\n\t\tload\tr3,0x8dff6eff\t\t\t#green\n\t\tb\tFox_ShineGroundLoop_StoreColor\n\n\t\tFox_ShineGroundLoop_RedText:\n\t\tload\tr3,0xffa2baff\n\n\t\tFox_ShineGroundLoop_StoreColor:\n\t\tstw\tr3,0x30(text)\n\n\t\tFox_ShineGroundLoop_TopLine:\n\t\t#Create Text\n\t\tbl\tActOOShineTop\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,0x803a6b98\n\n\n\t\tFox_ShineGroundLoop_BottomLine:\n\t\t#Create Text2\n\t\tbl\tActOOShineBottom\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\t#Get Current Frame\n\t\t#lfs\tf1,0x894(playerdata)\n\t\t#fctiwz\tf1,f1\n\t\t#stfd\tf1,0xF0(sp)\n\t\t#lwz\tr3,0xF4(sp)\n\t\tlhz\tr5,0x23EC(playerdata)\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\t\tbranchl r12,0x803a6b98\n\n\t\tb Moonwalk_Exit\n\n\n#/////////////////////////////////////////////////////////////////////////////\n\nFox_ShineAirLoop:\n\t#Check For Remaining Jump\n\tlbz\tr3, 0x1968 (playerdata)\t\t\t#Jumps Used\n\tlwz\tr0, 0x0168 (playerdata)\t\t\t#Total Jumps\n\tcmpw\tr3,r0\n\tbge\tMoonwalk_Exit\n\n\t#Check For JC\n\tbl\tCheckForJumpCancel\n\tcmpwi\tr3,0x0\n\tbeq\tMoonwalk_Exit\n\n\tFox_ShineAirLoop_Interrupted:\n\t#Create Text\n\tbl\tCreateText\n\tmr\ttext,r3\t\t\t#backup text pointer\n\n\n\t\t#Check If Frame Perfect\n\t\t#Get Current Frame\n\t\t#lfs\tf1,0x894(playerdata)\n\t\t#fctiwz\tf1,f1\n\t\t#stfd\tf1,0xF0(sp)\n\t\t#lwz\tr3,0xF4(sp)\n\t\tlhz\tr3,0x23EC(playerdata)\n\t\tcmpwi\tr3,0x1\n\t\tbne\tFox_ShineAirLoop_RedText\n\n\t\t#Frame Perfect\n\t\tload\tr3,0x8dff6eff\t\t\t#green\n\t\tb\tFox_ShineAirLoop_StoreColor\n\n\t\tFox_ShineAirLoop_RedText:\n\t\tload\tr3,0xffa2baff\n\n\t\tFox_ShineAirLoop_StoreColor:\n\t\tstw\tr3,0x30(text)\n\n\t\tFox_ShineAirLoop_TopLine:\n\t\t#Create Text\n\t\tbl\tActOOShineTop\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,0x803a6b98\n\n\n\t\tFox_ShineAirLoop_BottomLine:\n\t\t#Create Text2\n\t\tbl\tActOOShineBottom\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\t#Get Current Frame\n\t\t#lfs\tf1,0x894(playerdata)\n\t\t#fctiwz\tf1,f1\n\t\t#stfd\tf1,0xF0(sp)\n\t\t#lwz\tr3,0xF4(sp)\n\t\tlhz\tr5,0x23EC(playerdata)\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\t\tbranchl r12,0x803a6b98\n\n\t\tb Moonwalk_Exit\n\n#/////////////////////////////////////////////////////////////////////////////\n\nCheckForJumpCancel:\nmflr\tr0\nstw\tr0, 0x0004 (sp)\nstwu\tsp, -0x0038 (sp)\n\t#Check For JC\n\tlwz\tr5, -0x514C (r13)\n\tlfs\tf0, 0x0070 (r5)\n\tlfs\tf1, 0x0624 (playerdata)\n\tfcmpo\tcr0,f1,f0\n\tblt\tCheckForJumpCancel_CheckButtons\n\tlbz\tr3, 0x0671 (playerdata)\n\tlwz\tr0, 0x0074 (r5)\n\tcmpw\tr3,r0\n\tbge\tCheckForJumpCancel_CheckButtons\n\tli\tr3,0x1\n\tb\tCheckForJumpCancel_Exit\n\tCheckForJumpCancel_CheckButtons:\n\tlwz\tr0, 0x0668 (playerdata)\n\trlwinm.\tr0, r0, 0, 20, 21\n\tbeq\tCheckForJumpCancel_NoButtons\n\tli\tr3,0x1\n\tb\tCheckForJumpCancel_Exit\nCheckForJumpCancel_NoButtons:\nli\tr3,0x0\nCheckForJumpCancel_Exit:\nlwz\tr0, 0x003C (sp)\naddi\tsp, sp, 56\nmtlr\tr0\nblr\n\nShortenPress:\nmflr\tr0\nstw\tr0, 0x0004 (sp)\nstwu\tsp, -0x0038 (sp)\nbl\tShortenPressText\nmr \tr3,r29\t\t\t#text pointer\nmflr\tr4\nlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\nlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\nbranchl r12,0x803a6b98\nlwz\tr0, 0x003C (sp)\naddi\tsp, sp, 56\nmtlr\tr0\nblr\n\n\nCreateText:\nmflr\tr0\nstw\tr0, 0x0004 (sp)\nstwu\tsp, -0x0008 (sp)\nmr\tr3,playerdata\t\t\t#backup playerdata pointer\nli\tr4,60\t\t\t#display for 60 frames\nli\tr5,0\t\t\t#Area to Display (0-2)\nli\tr6,8\t\t\t#Window ID (Unique to This Display)\nbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\nlwz\tr0, 0x000C (sp)\naddi\tsp, sp, 8\nmtlr r0\nblr\n\n\n###################\n## TEXT CONTENTS ##\n###################\nShortenPressText:\nblrl\n.string \"Shorten Press\"\n.align 2\n\nEarlyPressText:\nblrl\n.string \"%df Early\"\n.align 2\n\nShortenTypeText:\nblrl\n.string \"Frame %d/4\"\n.align 2\n\nLatePressText:\nblrl\n.string \"%df Late\"\n.align 2\n\nActOOShineTop:\nblrl\n.string \"Act OOShine\"\n.align 2\n\nActOOShineBottom:\nblrl\n.string \"Frame %d\"\n.align 2\n\n##############################\n\n\nMoonwalk_Exit:\nrestoreall\nlwz\tr12, 0x219C (r31)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/L Cancel Display NEW.asm",
    "content": "#To be inserted at 8008d770\n.include \"../Globals.s\"\n.include \"../../m-ex/Header.s\"\n\n.set entity,31\n.set REG_FighterData,31\n.set player,30\n.set text,29\n.set textprop,28\n.set\tREG_TextColor,27\n.set\tREG_String,26\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\tlwz\tREG_FighterData,0x2c(player)\n\n\t#CHECK IF ENABLED\n\tli\tr0,OSD.LCancel\t\t\t#wavedash ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\tCheckForFollower:\n\tmr\tr3,REG_FighterData\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n\t# Check if succeeded\n\tlbz\tr5,0x67F(REG_FighterData)\t\t\t#get decimal to print\n\tcmpwi\tr5,0x7\n\tblt\tSuccessLCancel\n\tFailedLCancel:\n\tli\tREG_TextColor,MSGCOLOR_RED\n\tmr\tr3,REG_FighterData\n\tbl\tDecLCRate \n\tb\tDetermineString\n\tSuccessLCancel:\n\tli\tREG_TextColor,MSGCOLOR_GREEN\n\tmr\tr3,REG_FighterData\n\tbl\tIncLCRate\n\tb\tDetermineString\n\n\tDetermineString:\n\t# If under 40 frames, qualify as an attempt\n\tlbz\tr8,0x67F(REG_FighterData)\t\t\t#get decimal to print\n\tcmpwi\tr8,40\n\tbgt\tDetermineString_NoPress\n\tbl\tLCancel_Press\n\tmflr\tREG_String\n\tb\tPrintMessage\n\t\n\tDetermineString_NoPress:\n\tbl\tLCancel_NoPress\n\tmflr\tREG_String\n\tb\tPrintMessage\n\n\tPrintMessage:\n\tmr\tr7,r3\t\t#LCancel Percent\n\tli\tr3,1\t\t\t#Message Kind\n\tlbz\tr4,0xC(REG_FighterData)\t#Message Queue\n\tmr\tr5,REG_TextColor\n\tmr\tr6,REG_String\n\tlbz\tr8,0x67F(REG_FighterData)\t\t\t#get decimal to print\n\taddi\tr8,r8,1\n\tMessage_Display\n\n\t\n\t# Make Top Line White\n\tlwz\tr3,0x2C(r3)\n\tlwz\tr3,MsgData_Text(r3)\n\tli\tr4,0\n\tbl\tColor_White\n\tmflr r5\n\tbranchl\tr12,Text_ChangeTextColor\n\t\n\nb Moonwalk_Exit\n\n#########################\n### LC Rate Functions ###\n#########################\n\nIncLCRate:\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nmflr r0\nstw r0,0xFC(sp)\nlbz\tr3,0xC(r3)\t\t#get player slot\nload\tr4,0x804a1fa8\t\t#get LC rate mem location\nmulli\tr3,r3,0x4\t\t#length of players DB info\nadd\tr8,r3,r4\t\t#players LC info in r8\nlhz\tr3,0x0(r8)\t\t#successful LCs\naddi\tr3,r3,0x1\nsth\tr3,0x0(r8)\t\t#successful LCs\nlhz\tr3,0x2(r8)\t\t#total LCs\naddi\tr3,r3,0x1\nsth\tr3,0x2(r8)\t\t#total LCs\nmr\tr3,r8\nbl\tGetLCRate\nlwz r0,0xFC(sp)\nmtlr r0\naddi\tr1,r1,0x100\t# release the space\nblr\n\nDecLCRate:\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nmflr r0\nstw r0,0xFC(sp)\nlbz\tr3,0xC(r3)\t\t#get player slot\nload\tr4,0x804a1fa8\t\t#get DB rate mem location\nmulli\tr3,r3,0x4\t\t#length of players DB info\nadd\tr8,r3,r4\t\t#players DB info in r8\nlhz\tr3,0x2(r8)\t\t#total DBs\naddi\tr3,r3,0x1\nsth\tr3,0x2(r8)\t\t#total DBs\nmr\tr3,r8\nbl\tGetLCRate\nlwz r0,0xFC(sp)\nmtlr r0\naddi\tr1,r1,0x100\t# release the space\nblr\n\n\nGetLCRate:\n#Get Values\nlhz\tr4,0x0(r3)\t\t#successful LCs\nlhz\tr5,0x2(r3)\t\t#total LCs\n#Get as Floats (f1 = successful, f2 = total\nlis\tr0, 0x4330\nlfd\tf5, -0x6758 (rtoc)\nxoris\tr6, r4, 0x8000\nxoris\tr7, r5, 0x8000\nstw\tr0,0xF0(sp)\n#Successful DB\nstw\tr6,0xF4(sp)\nlfd\tf1,0xF0(sp)\nfsubs\tf1,f1,f5\n#Total DB\nstw\tr7,0xF4(sp)\nlfd\tf2,0xF0(sp)\nfsubs\tf2,f2,f5\n#100f\nli\tr4,100\nxoris\tr4,r4,0x8000\nstw\tr4,0xF4(sp)\nlfd\tf3,0xF0(sp)\nfsubs\tf3,f3,f5\nfdivs\tf1,f1,f2\t\t#successful LC / total LC\nfmuls\tf1,f1,f3\t\t#times 100\n#Back to Int\nfctiwz\tf1,f1\nstfd\tf1,0xF0(sp)\nlwz\tr3,0xF4(sp)\nblr\n\n\nLCancel_Press:\nblrl\n.string \"L-Cancel %d%%\\nFrame %d/7\"\n.align 2\n\nLCancel_NoPress:\nblrl\n.string \"L-Cancel %d%%\\nNo Press\"\n.align 2\n\nColor_White:\nblrl\n.long 0xFFFFFFFF\n\n##############################\n\nMoonwalk_Exit:\nrestoreall\n\nlwz\tr0, 0x0034 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Ledge Codes/Frames Spent in CliffWait.asm",
    "content": "#To be inserted at 8009ab78\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nstw\tr0, 0x2064 (r6)\n\nbackupall\n\nmr\tplayerdata,r6\n\n\n\t#CHECK IF ENABLED\n\tli\tr0,OSD.Ledge\t\t\t#PowerShield ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\tCheckForFollower:\n\tmr\tr3,playerdata\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n\t#Check if Over 20 Frames\n\t\tlhz\tr3,0x23EC(playerdata)\n\t\tcmpwi r3,20\n\t\tbgt Moonwalk_Exit\n\n\t\tbl\tCreateText\n\n\t\t#Change Text Color\n\t\tlhz\tr3,0x23EC(playerdata)\n\t\tsubi r3,r3,1\n\t\tcmpwi\tr3,0x1\n\t\tbne\tRedText\n\n\t\tGreenText:\n\t\tload\tr3,0x8dff6eff\t\t\t#green\n\t\tb\tStoreTextColor\n\n\t\tRedText:\n\t\tload\tr3,0xffa2baff\n\n\t\tStoreTextColor:\n\t\tstw\tr3,0x30(text)\n\n\t\t#Create Text\n\t\tbl\tTopText\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,0x803a6b98\n\n\t\t#Create Text2\n\t\tbl\tBottomText\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tlhz\tr5,0x23EC(playerdata)\n\t\tsubi r5,r5,1\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\t\tbranchl r12,0x803a6b98\n\n\t\tb Moonwalk_Exit\n\n\n\tCreateText:\n\tmflr\tr0\n\tstw\tr0, 0x0004 (sp)\n\tstwu\tsp, -0x0008 (sp)\n\tmr\tr3,playerdata\t\t\t#backup playerdata pointer\n\tli\tr4,60\t\t\t#display for 60 frames\n\n\t#Display Up Top For Event\n\tload\tr5,SceneController\n\tlbz\tr5,0x0(r5)\n\tcmpwi\tr5,0x2B\n\tbne\t0xC\n\tli\tr5,1\n\tb\t0x8\n\tli\tr5,0\t\t\t#Area to Display (0-2)\n\tli\tr6,13\t\t\t#Window ID (Unique to This Display)\n\tbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\n\n\tmr\ttext,r3\t\t\t#backup text pointer\n\tlwz\tr0, 0x000C (sp)\n\taddi\tsp, sp, 8\n\tmtlr r0\n\tblr\n\n\n###################\n## TEXT CONTENTS ##\n###################\n\nTopText:\nblrl\n.string \"Frames in\"\n.align 2\n\nBottomText:\nblrl\n.string \"Cliffwait: %d\"\n.align 2\n\n##############################\n\n\nMoonwalk_Exit:\nrestoreall\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Ledge Codes/GALINT/GALINT Aerail Interrupt.asm",
    "content": "#To be inserted at 8008d6f4\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\n\n#Check For CliffWait\nlhz\tr4, TM_ThreeASAgo (r5)\ncmpwi\tr4,0xFD\nbne\tMoonwalk_Exit\n\nli  r4,1\nbranchl\tr12,0x80005514\n\n\n\n\n\nMoonwalk_Exit:\nrestoreall\nbranchl\tr12,0x800d5bf8\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Ledge Codes/GALINT/GALINT Laser Land.asm",
    "content": "#To be inserted at 80082c40\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\n#Search last 5 AS's for CliffWait\n  li  r5,0x0\n  lwz r6,0x2C(28)\nCliffWaitSearch:\n  mulli r3,r5,0x2\n  addi  r3,r3,TM_PrevASStart\n  lhzx r3,r3,r6\n  cmpwi\tr3,0xFD\n  beq\tDisplayGALINT\n  addi r5,r5,1\n  cmpwi r5,5\n  ble CliffWaitSearch\n  b Moonwalk_Exit\n\n#Display GALINT\nDisplayGALINT:\n  mr  r3,r28\n  li  r4,0\n  branchl\tr12,0x80005514\n\nMoonwalk_Exit:\nrestoreall\nmr\tr3, r28\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Ledge Codes/GALINT/GALINT Ledgedash.asm",
    "content": "#To be inserted at 800d5d5c\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\nlwz\tr5,0x2C(r31)\n\n#Check If Coming From Airdodge\nlhz\tr3, TM_OneASAgo (r5)\ncmpwi\tr3,0xEC\nbne\tMoonwalk_Exit\n#Check For CliffWait\nlhz\tr3, TM_FourASAgo (r5)\ncmpwi\tr3,0xFD\nbne\tMoonwalk_Exit\n\nmr\tr3,r31\nli  r4,0\nbranchl\tr12,0x80005514\n\n\n\n\n\nMoonwalk_Exit:\nrestoreall\nmr\tr3, r31\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Ledge Codes/GALINT/GALINT No Impact Land.asm",
    "content": "#To be inserted at 80082b4c\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\nlwz\tr5,0x2C(r30)\n\n#Check For CliffWait\nlhz\tr3, TM_TwoASAgo (r5)\ncmpwi\tr3,0xFD\nbne\tMoonwalk_Exit\n\nmr\tr3,r30\nli  r4,0\nbranchl\tr12,0x80005514\n\n\n\n\n\nMoonwalk_Exit:\nrestoreall\nmr\tr3, r30\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Ledge Codes/GALINT/Standalaone - GALINT Display.asm",
    "content": "#To be inserted at 80005514\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set REG_isAerialInterrupt,28\n.set REG_GALINT,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\nmr\tplayer,r3\nlwz\tplayerdata,0x2c(player)\nmr\tREG_isAerialInterrupt,r4\n\n\t#CHECK IF ENABLED\n\tli\tr0,OSD.Ledge\t\t\t#PowerShield ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\tCheckForFollower:\n\tmr\tr3,playerdata\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n\t#Check if Over 20 Frames past GALINT\n\t\tlhz\tr3,TM_TangibleFrameCount(playerdata)\n\t\tcmpwi r3,20\n\t\tbgt Moonwalk_Exit\n\n\t\t#Get GALINT Frames (Ledge Intang - Landing Lag)\n\t\tlwz\tREG_GALINT,0x1990 (playerdata)\n\t\tcmpwi REG_isAerialInterrupt,0\n\t\tbeq\tSkipAI\n\t\tlfs\tf1,0x1F4 (playerdata)\n\t\tfctiwz f1,f1\n\t\tstfd f1,0x80(sp)\n\t\tlwz r3,0x84(sp)\n\t\tsub REG_GALINT,REG_GALINT,r3\n\t\tSkipAI:\n\n\t\tbl\tCreateText\n\n\t\t#Change Text Color\n\t\tcmpwi\tREG_GALINT,0x0\n\t\tble\tRedText\n\n\t\tGreenText:\n\t\tload\tr3,0x8dff6eff\t\t\t#green\n\t\tb\tStoreTextColor\n\n\t\tRedText:\n\t\tload\tr3,0xffa2baff\n\n\t\tStoreTextColor:\n\t\tstw\tr3,0x30(text)\n\n\t\t#Create Text\n\t\tbl\tTopText\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,0x803a6b98\n\n\t\t#Create Text2\n\t\tbl\tBottomText\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tmr\tr5,REG_GALINT\n\t\tcmpwi\tr5,0x0\n\t\tbgt\tSkipShowingTangibleFrames\n\n\t\t#Show Tangible Frames\n\t\tlwz\tr5,0x2408(playerdata)\n\t\taddi\tr5,r5,0x1\n\t\tneg\tr5,r5\n\n\t\tSkipShowingTangibleFrames:\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\t\tbranchl r12,0x803a6b98\n\n\t\tb Moonwalk_Exit\n\n\n\tCreateText:\n\tmflr\tr0\n\tstw\tr0, 0x0004 (sp)\n\tstwu\tsp, -0x0008 (sp)\n\tmr\tr3,playerdata\t\t\t#backup playerdata pointer\n\tli\tr4,60\t\t\t#display for 60 frames\n\tli\tr5,0\t\t\t#Area to Display (0-2)\n\tli\tr6,14\t\t\t#Window ID (Unique to This Display)\n\tbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\n\tmr\ttext,r3\t\t\t#backup text pointer\n\tlwz\tr0, 0x000C (sp)\n\taddi\tsp, sp, 8\n\tmtlr r0\n\tblr\n\n###################\n## TEXT CONTENTS ##\n###################\n\nTopText:\nblrl\n.string \"Ledgedash GALINT\"\n.align 2\n\nBottomText:\nblrl\n.string \"Frames: %d\"\n.align 2\n\n##############################\n\n\nMoonwalk_Exit:\nrestoreall\nblr\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Ledge Codes/Ledgestall/Ledgestall Display.asm",
    "content": "#To be inserted at 800814ec\n.include \"../../../Globals.s\"\n.include \"../../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\n\nlwz\tplayerdata,0x2c(player)\n\n\n\t#CHECK IF ENABLED\n\tli\tr0,OSD.Ledge\t\t\t#Ledge Codes ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\tCheckForFollower:\n\tmr\tr3,playerdata\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n\t#Check If Under 15 Frames\n\tlwz\tr3, 0x2408 (playerdata)\n\tsubi\tr3,r3,1\n\tcmpwi\tr3,15\n\tbgt\tMoonwalk_Exit\n\n\t\tbl\tCreateText\n\n\t\t#Change Text Color\n\t\tlwz\tr3, 0x2408 (playerdata)\n\t\tsubi\tr3,r3,1\n\t\tcmpwi\tr3,0\n\t\tbgt\tRedText\n\n\t\tGreenText:\n\t\tload\tr3,0x8dff6eff\t\t\t#green\n\t\tb\tStoreTextColor\n\n\t\tRedText:\n\t\tload\tr3,0xffa2baff\n\n\t\tStoreTextColor:\n\t\tstw\tr3,0x30(text)\n\n\t\t#Create Text\n\t\tbl\tTopText\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,0x803a6b98\n\n\t\t#Create Text2\n\t\tbl\tBottomText_FramesLate\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tlwz\tr5, 0x2408 (playerdata)\n\t\tsubi\tr5,r5,1\n\t\tcmpwi\tr5,0x0\n\t\tneg\tr5,r5\n\t\tbgt\tLateLedgestall\n\n\t\t#Show Perfect Ledgestall Text\n\t\tbl\tBottomText_PerfectStall\n\t\tmflr\tr4\n\n\t\tLateLedgestall:\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\t\tbranchl r12,0x803a6b98\n\n\t\tb Moonwalk_Exit\n\n\n\tCreateText:\n\tmflr\tr0\n\tstw\tr0, 0x0004 (sp)\n\tstwu\tsp, -0x0008 (sp)\n\tmr\tr3,playerdata\t\t\t#backup playerdata pointer\n\tli\tr4,60\t\t\t#display for 60 frames\n\tli\tr5,0\t\t\t#Area to Display (0-2)\n\tli\tr6,14\t\t\t#Window ID (Unique to This Display)\n\tbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\n\tmr\ttext,r3\t\t\t#backup text pointer\n\tlwz\tr0, 0x000C (sp)\n\taddi\tsp, sp, 8\n\tmtlr r0\n\tblr\n\n\n###################\n## TEXT CONTENTS ##\n###################\n\nTopText:\nblrl\n.string \"Ledgestall\"\n.align 2\n\nBottomText_FramesLate:\nblrl\n.string \"Frames Late: %d\"\n.align 2\n\nBottomText_PerfectStall:\nblrl\n.string \"Perfect\"\n.align 2\n\n##############################\n\n\nMoonwalk_Exit:\nrestoreall\nlwz\tr0, 0x0034 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Message Display System/Create Message Struct.asm",
    "content": "#To be inserted at 802ff4e8\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n.macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set MessageStructTotalSize,0x300\n.set MessageAreaLength,0x100\n.set PerPlayerMessageStructLength,0x28\n\n########################################################\n## Allocate 0x300 Bytes and Store Pointer at 804a1f5c ##\n########################################################\n\n li\tr3,MessageStructTotalSize\n branchl\tr12,0x8037f1e4\n stw\tr3,0x4(r31)\n\n#Zero Space\nli\tr4,MessageStructTotalSize\nbranchl\tr12,0x8000c160\n\n##############################################\n## Create Message Management Think Function ##\n##############################################\n\n#Create GObj\n li\tr3,0xE\n li\tr4,0x7\n li\tr5,0x0\n branchl r12,0x803901f0\n\n#Attach Think Function\n bl \tMessageThink\n mflr \tr4\t\t\t#Get Function Address\n li \tr5,0x0\n branchl r12,0x8038fd54\n\nb\texit\n\n#################################################################\n\n################\n## MessageThink ##\n################\n\nMessageThink:\nblrl\n\nbackup\n\n###############################################\n## Update Message Area 1 (Above Player HUDs) ##\n###############################################\n\n#Init Loop\n li\tr31,0x0 \t\t#Loop Count\n\nMessageThink_UpdateArea1Loop:\n\n li\tr3,0x0\t\t\t\t#Area 1\n mr\tr4,r31\t\t\t\t#Player\n bl\tMessageThink_Updater\n\nMessageThink_UpdateArea1IncLoop:\n addi\tr31,r31,0x1\n cmpwi\tr31,0x4\n blt\tMessageThink_UpdateArea1Loop\n\n###########################################\n## Update Message Area 2 (Top of Screen) ##\n###########################################\n\n#Init Loop\n li\tr31,0x0 \t\t#Loop Count\n\nMessageThink_UpdateArea2Loop:\n\n li\tr3,1\t\t\t\t#Area 2\n mr\tr4,r31\t\t\t\t#Player\n bl\tMessageThink_Updater\n\nMessageThink_UpdateArea2IncLoop:\n addi\tr31,r31,0x1\n cmpwi\tr31,0x4\n blt\tMessageThink_UpdateArea2Loop\n\n#################################################\n## Update Message Area 3 (Right Side of Screen ##\n#################################################\n\n li\tr3,2\t\t\t\t#Area 3\n bl\tMessageThink_Updater\n\nMessageThink_Exit:\nrestore\nblr\n\n##################################################################\n\n##########################\n## MessageThink_Updater ##\n##########################\n\nMessageThink_Updater:\n\n backup\n\n mr\tr31,r3\t\t#Area ID\n mr\tr30,r4\t\t#Player ID\n\n#Get Area's Message Struct in r29\n load\tr3,0x804a1f58\n lwz\tr3,0x4(r3)\n mulli\tr4,r31,MessageAreaLength\n add\tr29,r3,r4\n\n#Check For Area 3, No Player Dependent Stuff If So\n cmpwi\tr31,0x2\n bge\tMessageThink_Updater_NonPlayerArea\n\n######################################################################################\n\nMessageThink_Updater_PlayerAreaLoopInit:\n mulli\tr4,r30,PerPlayerMessageStructLength\n add\tr29,r29,r4\n li\tr28,0x0\t\t\t#Offset In Player's Area\n\nMessageThink_Updater_PlayerAreaLoop:\n add\tr27,r28,r29\n lwz\tr3,0x0(r27)\t\t\t\t#Get Text Pointer\n cmpwi\tr3,0\t\t\t\t#If There's No Text Here, Skip\n beq\tMessageThink_Updater_PlayerAreaIncLoop\n\n#Check If No Timer (-1)\n lhz\tr3,0x4(r27)\t\t\t\t#Get Timer\n cmpwi\tr3,-1\n beq\tMessageThink_Updater_PlayerAreaIncLoop\n\n#Decrement Timer\n #lhz\tr3,0x4(r27)\t\t\t\t#Get Timer\n subi\tr3,r3,0x1\n sth\tr3,0x4(r27)\n\n#Check If Expired\n cmpwi\tr3,0x0\n bgt\tMessageThink_Updater_PlayerAreaIncLoop\n\n#Remove Text\n lwz\tr3,0x0(r27)\t\t\t\t#Get Text Pointer\n branchl\tr12,0x803a5cc4\n\n#Zero Out Entry\n li\tr3,0x0\n stw\tr3,0x0(r27)\n stw\tr3,0x4(r27)\n\n#Check To Shift Upwards\n addi\tr26,r28,0x8\t\t\t\t\t\t\t\t#Next Offset\n cmpwi\tr26,PerPlayerMessageStructLength\t\t\t\t\t\t\t\t#Check If There's Nothing Left to Shift\n bge\tMessageThink_Updater_PlayerAreaIncLoop\t\t\t\t\t\t\t\t#Skip Shift Code\n\n#Shift Everything Below it Upwards\nMessageThink_Updater_PlayerAreaShiftMessagesLoop:\n add\tr5,r26,r29\t\t\t\t#Get Next Individual Message Struct\n lwz\tr3,0x0(r5)\t\t\t\t#Get Messages Text Pointer\n lwz\tr4,0x4(r5)\t\t\t\t#Get Messages Timer and ID\n stw\tr3,-0x8(r5)\t\t\t\t#Push Up\n stw\tr4,-0x4(r5)\t\t\t\t#Push Up\n\n#Check If This Entry Is Live\n cmpwi\tr3,0x0\n beq\tMessageThink_Updater_PlayerAreaShiftMessagesIncLoop\n\n#Move Message Downwards/Upwards Depending On The Area\n bl\tMessageThink_Floats\n mflr\tr4\n mulli\tr5,r31,0x4\t\t\t\t#Area ID into offset\n lfsx\tf1,r4,r5\n lfs\tf2,0x4(r3)\t\t\t\t#Get Text's Y Value\n fadds\tf1,f1,f2\n stfs\tf1,0x4(r3)\t\t\t\t#Store Text's Y Value\n\n#Go To Next Message's Offset\nMessageThink_Updater_PlayerAreaShiftMessagesIncLoop:\n addi\tr26,r26,0x8\t\t\t\t\t\t\t\t\t\t\t#Next Offset\n cmpwi\tr26,PerPlayerMessageStructLength\t\t\t\t\t#Check If There's Nothing Left to Shift\n blt\tMessageThink_Updater_PlayerAreaShiftMessagesLoop\t#Run Code if There Is\n\n\nMessageThink_Updater_PlayerAreaIncLoop:\n addi\tr28,r28,0x8\t\t\t#Length of Each Message Data\n cmpwi\tr28,PerPlayerMessageStructLength\n blt\tMessageThink_Updater_PlayerAreaLoop\n\n b\tMessageThink_Updater_Exit\n\n######################################################################################\n\nMessageThink_Updater_NonPlayerArea:\n lwz\tr3,0x0(r29)\t\t\t\t#Get Text Pointer\n cmpwi\tr3,0\t\t\t\t#If There's No Text Here, Skip\n beq\tMessageThink_Updater_Exit\n\n#Check If No Timer (-1)\n lhz\tr3,0x4(r29)\t\t\t\t#Get Timer\n cmpwi\tr3,-1\n beq\tMessageThink_Updater_Exit\n\n#Decrement Timer\n #lhz\tr3,0x4(r29)\t\t\t\t#Get Timer\n subi\tr3,r3,0x1\n sth\tr3,0x4(r29)\n\n#Check If Expired\n cmpwi\tr3,0x0\n bgt\tMessageThink_Updater_Exit\n\n#Remove Text\n lwz\tr3,0x0(r29)\t\t\t\t#Get Text Pointer\n branchl\tr12,0x803a5cc4\n\n#Zero Out Entry\n li\tr3,0x0\n stw\tr3,0x0(r29)\n stw\tr3,0x4(r29)\n\n b\tMessageThink_Updater_Exit\n\n\n######################################################################################\n\n#******************#\nMessageThink_Floats:\nblrl\n.long 0x40900000\t\t\t#Area 1\n.long 0xC0900000\t\t\t#Area 2\n#******************#\n\nMessageThink_Updater_Exit:\nrestore\nblr\n\n#################################################################\n\n\nexit:\nlwz\tr0, 0x001C (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Message Display System/Disable Hiding Score on Pause.asm",
    "content": "#To be inserted at 802f33b8\nnop"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Message Display System/Disable Showing Score on Unpause.asm",
    "content": "#To be inserted at 802f33f0\nnop"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Message Display System/Display Message 2.0.asm",
    "content": "#To be inserted at 80005928\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n.macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set playerdata,31\n.set messageStruct,30\n.set text,29\n.set textprop,28\n.set texttimer,27\n.set AreaID,26\n.set overlayID,25\n.set MaxWindows,24\n\n.set messageAreaStructLength,0x100\n.set messageStructLength,0x28\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                    ##\n## Store Text Info here                                 ##\n##########################################################\n\n#Message Area Struct Layout\n##0x00 = P1 Area\n##0x28 = P2 Area\n##0x50 = P3 Area\n##0x78 = P4 Area\n\n\t#PX Area\n\t\t#0x0 = 32-bit int, number of active windows in this area\n\t\t#0x4 = Start Individual Message Struct\n\t\t\t#0x0 = Text Pointer\n\t\t\t#0x4 = Countdown Until Expiration\n\t\t\t#0x6 = Unique Message ID (which text prompt this is)\n\n\nbackup\n\n\tmr\tplayerdata,r3\n\tmr\ttexttimer,r4\n\tmr\tAreaID,r5\t\t\t#custom window struct in the stock text match struct\n\tmr\toverlayID,r6\n\tmr\ttextprop,r7\n\n\t#Load Max Number of Windows Variable From OSD Menu\n  \tlwz\tr3,-0x77C0(r13)\t\t\t#Get Memcard Data\n\t  lbz\tMaxWindows,0x1f28(r3)\n\n\t#Get Window's Area in the Message Struct in r3\n\t  load\tr3,0x804a1f58\n\t  lwz\tr3,0x4(r3)\n\t  mulli\tr4,AreaID,messageAreaStructLength\n\t  add\tr3,r3,r4\n\n\t#Check If Area 3 (No Shift or anything Special)\n\t cmpwi\tAreaID,0x2\n\t blt\tGetPlayersArea\n\t mr\tmessageStruct,r3\n\n\t#Remove Old Area 3 Window\n\t lwz\tr3,0x0(messageStruct)\n\t branchl\tr12,0x803a5cc4\n\t b\tCreateText\n\n\tGetPlayersArea:\n\t#Get to the player's area\n\t  lbz\tr4,0xC(playerdata)\n\t  mulli\tr4,r4,messageStructLength\n\t  add\tmessageStruct,r3,r4\n\n\t#Search Queue For This Text ID (Loop)\n\t  mr\tr3,overlayID\n\t  mr\tr4,MaxWindows\n\t  mr\tr5,messageStruct\n\t  bl\tCheckForDuplicates\n\n\t#Shift Queue To Make Room For New Message\n\tCallShiftFunction:\n\t  mr\tr3,MaxWindows\n\t  bl\tShiftQueue\n\n\tCreateText:\n\t#CREATE TEXT ABOVE PLAYERS HUD ELEMENT\n \t li \tr3,0x2\n\t load \tr4,0x804a1f58\t\t\t#get text objects ID?\n\t lwz \tr4,0x0(r4)\n\t branchl r12,0x803a6754\n\n\t#STORE PLAYERS TEXT POINTER\n\t mr\tr29,r3\t\t\t\t\t#backup text pointer\n\t stw\tr3,0x0(messageStruct)\n\n\t#STORE PLAYERS TEXT TIMEOUT\n\t sth\ttexttimer,0x4(messageStruct)\n\n\t#STORE OVERLAY ID\n\tsth\toverlayID,0x6(messageStruct)\n\n\t#SET TEXT TO CENTER AROUND X LOCATION AND BE CLOSE\n\tli\tr3,0x1\n\tstb \tr3,0x4A(r29)\n\tstb \tr3,0x49(r29)\n\n\t#SET X AND Y VALUES\n\t#Get Area's Text Properties\n\tbl\tTextProperties\n\tmflr\ttextprop\n\tmulli\tr3,AreaID,0x1C\n\tadd\ttextprop,textprop,r3\n\n\t#Check To Override HUD Location\n\tlwz\tr3,0x0(textprop)\t\t\t#base X value\n\tcmpwi\tr3,0x0\n\tbne\tGetHUDLocation\n\tlfs\tf1,0x8(textprop)\t\t\t#base X value\n\tb\tGetYLocation\n\n\t#Get HUD Location\n\tGetHUDLocation:\n\tlbz\tr3,0xC(playerdata)\n\tload\tr4,0x804a0ff0\n\tmulli\tr3,r3,0xC\t\t\t#HUD Info is 0xC Long Per Player\n\tlfsx\tf1,r3,r4\t\t\t#Get This Players HUD Info\n\n\tGetYLocation:\n\tlfs \t f2,0x4(textprop)\t\t\t#players Y value\n\tstfs\tf1,0x0(text)\t\t\t#store X value to struct\n\tstfs\tf2,0x4(text)\t\t\t#store Y value to struct\n\n\n\t#SET TEXT SIZE\n\tlfs\t\tf1,0xC(textprop)\n\tstfs\tf1,0x24(text)\t\t\t#X stretch\n\tstfs\tf1,0x28(text)\t\t\t#Y stretch\n\n\n\t#INIT BACKGROUND (HYPHEN)\n\tmr \tr3,r29\t\t\t#text pointer\n\tbl\tTextASCII3\n\tmflr \tr4\t\t\t#get ASCII to print\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2,  0x10   (textprop)\t\t#background Y\n\tbranchl r12,0x803a6b98\n\n\t\t#CHANGE TEXT COLOR TO BLACK\n\t\tmr\tr3,text\n\t\tli\tr4,0x0\n\t\tli\tr5,0x0\n\t\tstw\tr5,0xF0(sp)\n\t\taddi\tr5,sp,0xF0\n\t\tbranchl r12,0x803a74f0\n\n\t\t#CHANGE TEXT SIZE\n\t\tmr\tr3,text\n\t\tli\tr4,0x0\n\t\tlfs\tf1, 0x14 (textprop)\t\t\t#stretch X (12)\n\t\tlfs\tf2, 0x18 (textprop)\t\t\t#stretch Y (30)\n\t\tbranchl r12,0x803a7548\n\n\n\nb Moonwalk_Exit\n\n#######################################################################\n\n####################\n## Shift Messages ##\n####################\n\nShiftQueue:\n\n backup\n\n mr\tr31,r3\t\t#Max Windows\n\n#Remove Last Message if Exists\n mulli\tr3,r31,0x8\n lwzx\tr3,r3,messageStruct\n cmpwi\tr3,0x0\n beq\tShiftQueue_CheckForOneWindowOnly\n\n#Remove Message\n branchl\tr12,0x803a5cc4\n\n#Zero Out Entry\n mulli\tr4,r31,0x8\n add\tr4,r4,messageStruct\n li\tr3,0\n stw\tr3,0x0(r4)\n stw\tr3,0x4(r4)\n\nShiftQueue_CheckForOneWindowOnly:\n\n#Check If Only 1 Message\n cmpwi\tr31,0\n beq\tShiftQueue_Exit\n\nShiftQueue_Loop:\n\n#Shift This Message Upwards in the Queue\n mulli\tr3,r31,0x8\n add\tr3,r3,messageStruct\t\t#Get to the nth Message\n lwz\tr4,0x0(r3)\t\t\t\t#Load Text Pointer into r4\n lwz\tr5,0x4(r3)\t\t\t\t#Load Timer and ID into r5\n stw\tr4,0x8(r3)\t\t\t\t#Push up\n stw\tr5,0xC(r3)\t\t\t\t#Push up\n li\tr4,0x0\n stw\tr4,0x0(r3)\t\t\t\t#Zero Out\n stw\tr4,0x4(r3)\t \t\t\t#Zero Out\n\n#Move This Message Upwards Onscreen\n lwz\tr4,0x8(r3)\t\t\t\t#Text Pointer\n cmpwi\tr4,0x0\n beq\tShiftQueue_IncLoop\n\n#Move Message Downwards/Upwards Depending On The Area\n bl\tShiftQueue_Floats\n mflr\tr3\n mulli\tr5,AreaID,0x4\t\t\t\t#Area ID into offset\n lfsx\tf1,r3,r5\n lfs\tf2,0x4(r4)\t\t\t\t#Get Text's Y Value\n fadds\tf1,f1,f2\n stfs\tf1,0x4(r4)\t\t\t\t#Store Text's Y Value\n\n#Next Message\nShiftQueue_IncLoop:\n subi\tr31,r31,0x1\n cmpwi\tr31,0x0\n bge\tShiftQueue_Loop\n\nShiftQueue_Exit:\n restore\n blr\n\n\n################################################\n\n\n#####################\n## Check For Dupes ##\n#####################\n\n#Inputs:\n#r3 = OverlayID\n#r4 = Max Window Count\n#r5 = Message Queue Start\n\nCheckForDuplicates:\n\nbackup\n\nmr\tr31,r3\nmr\tr30,r4\nmr\tr29,r5\n\n#Search Loop For Matching Window\n#Init Loop\n li\tr28,0x0\t\t#Matching Window Loop Count\n\nCheckForDuplicates_MatchingWindowLoop:\n mulli\tr5,r28,0x8\t\t\t#Get Message's Offset\n add\tr4,r5,r29\t\t\t#Get Message's Location in Memory\n lwz\tr3,0x0(r4)\t\t\t#Get Text Pointer\n cmpwi\tr3,0x0\t\t\t\t#Check If This Entry Exists\n beq\tCheckForDuplicates_MatchingWindowIncLoop\n lhz\tr3,0x6(r4)\t\t\t#Get Window ID\n cmpw\tr3,r31\t\t\t\t#Check If They Match\n bne\tCheckForDuplicates_MatchingWindowIncLoop\n\n\t#Upon Finding a Match\n\t#Remove This Window\n\t lwz\tr3,0x0(r4)\n\t branchl\tr12,0x803a5cc4\n\n\t#Zero Out Entry\n\t mulli\tr5,r28,0x8\t\t\t#Get Message's Offset\n\t add\tr4,r5,r29\t\t\t#Get Message's Location in Memory\n\t li\tr3,0x0\n\t stw\tr3,0x0(r4)\n\t stw\tr3,0x4(r4)\n\n\t#Init Shift Loop Count\n\t addi\tr27,r28,0x1\t\t\t#Window After Matching Window ID = Shift Loop Count Starting Value\n\n\t#Loop - Move All Windows After This Down\n\tCheckForDuplicates_MatchingWindowShiftLoop:\n\t  mulli\tr5,r27,0x8\t\t#Get Message's Offset\n\t  add\tr4,r5,r29\t\t#Get Message's Location in Memory\n\t  lwz\tr5,0x0(r4)\t\t#Load Text Pointer\n\t  lwz\tr6,0x4(r4)\t\t#Load Text Timer and ID\n\t  stw\tr5,-0x8(r4)\t\t#Store Text Pointer\n\t  stw\tr6,-0x4(r4)\t\t#Store Text Timer and ID\n\t  li\tr3,0x0\n\t  stw\tr3,0x0(r4)\t\t#Zero Out\n\t  stw\tr3,0x4(r4)\t \t#Zero Out\n\n\t#Move Message Downwards/Upwards Depending On The Area\n\t  lwz\tr3,-0x8(r4)\t\t#Get Text Pointer\n\t  cmpwi\tr3,0x0\t\t\t#Check If This Entry Is Active\n\t  beq\tCheckForDuplicates_MatchingWindowShiftIncLoop\n\t  bl\tCheckForDuplicates_Floats\n\t  mflr\tr4\n\t  mulli\tr5,AreaID,0x4\t\t\t\t#Area ID into offset\n\t  lfsx\tf1,r4,r5\n\t  lfs\tf2,0x4(r3)\t\t\t\t#Get Text's Y Value\n\t  fadds\tf1,f1,f2\n\t  stfs\tf1,0x4(r3)\t\t\t\t#Store Text's Y Value\n\n\t  CheckForDuplicates_MatchingWindowShiftIncLoop:\n\t  addi\tr27,r27,0x1\n\t  cmpw\tr27,r30\n\t  blt\tCheckForDuplicates_MatchingWindowShiftLoop\n\n  \t  b\tCheckForDuplicates_Exit\n\nCheckForDuplicates_MatchingWindowIncLoop:\naddi\tr28,r28,0x1\ncmpw\tr28,r30\nblt\tCheckForDuplicates_MatchingWindowLoop\n\nCheckForDuplicates_Exit:\nrestore\nblr\n\n##############################\n\nTextProperties:\nblrl\n\n#Area 1 (Above HUD)\n.long 0xC1A80000 #X Base\n.long 0x41300000 #Y Value\n.long 0x41600000 #X Difference Between Players\n.long 0x3D23D70A\t#Text Size\n.long 0xC3CD0000 #background Y position\n.long 0x41400000 #background X stretch\n.long 0x41E00000 #background Y stretch\n\n#Area 2 (top of screen)\n.long 0xC1A80000 #X Base\n.long 0xC1A00000 #Y Value\n.long 0x41600000 #X Difference Between Players\n.long 0x3D23D70A\t#Text Size\n.long 0xC3CD0000 #background Y position\n.long 0x41180000 #background X stretch\n.long 0x41E00000 #background Y stretch\n\n#Area 3 (Event Popup)\n.long 0x00000000 #Whether to Use HUD Location, 0 = no\n.float -15 #Y Value\n.float 19 #X Value\n.float 0.04\t#Canvas Size\n.float -410 #background Y position\n.float 13.5 #background X stretch\n.float 28 #background Y stretch\n\n\n##############################\n\n#******************#\nShiftQueue_Floats:\nblrl\n.long 0xC0900000\t\t\t#Area 1\n.long 0x40900000\t\t\t#Area 2\n#******************#\n\n#******************#\nCheckForDuplicates_Floats:\nblrl\n.long 0x40900000\t\t\t#Area 1\n.long 0xC0900000\t\t\t#Area 2\n#******************#\n\nTextASCII3:\nblrl\n.long 0x815B0000\n\n\n\nMoonwalk_Exit:\nmr\tr3,text\t\t#return text pointer\nrestore\nblr\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/SDI Display/Initialize Total SDI Inputs Variable.asm",
    "content": "#To be inserted at 8008f71c\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\n#Get Victims Data\n  lwz r6,0x2C(r31)\n#Get Attacker GObj\n  lwz r5,0x1868(r6)\n#If Pointer doesn't exist, its most likely environmental damage (break the targets walls)\n  cmpwi r5,0x0\n  beq ResetSDICount\n#Check if Player\n  lhz r0,0(r5)        #Entity Type\n  lwz r5,0x2C(r5)     #Get Attacker Data\n  cmpwi r0,4          #Player\n  beq LastPlayerMove\n  cmpwi r0,6          #Item\n  beq LastItemMove\n  b  exit             #If neither, exit\n\nLastPlayerMove:\n#Get current Move Instance from attacker\n  lhz r4,0x2088(r5)\n  b   GetLastMoveVictimHitBy\nLastItemMove:\n#Get current Move Instance from attacker\n  lhz r4,0xDA8(r5)\n\nGetLastMoveVictimHitBy:\n#Get last Move Instance Victim was hit by\n  lhz r3,TM_PreviousMoveInstanceHitBy(r6)\n\n#If the move instance is 0, was most likely a stage element (corneria lasers)\n  cmpwi r4,0\n  beq ResetSDICount\n\n#Check If New Hit\n  cmpw\tr3,r4\n  beq\texit\n\n#Reset SDI Counter\nResetSDICount:\n  li\tr0, 0x0\n  sth\tr0, TM_SuccessfulSDIInputs (r6)\n  sth\tr0, TM_TotalSDIInputs (r6)\n\nexit:\ncmpwi\tr30, 0\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/SDI Display/SDI Display Main.asm",
    "content": "#To be inserted at 8008e52c\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set REG_FighterData,31\n.set player,30\n.set REG_TextColor,29\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\nbackupall\nstfs\tf0,0x80(sp)\nstfs\tf1,0x84(sp)\nstfs\tf2,0x8C(sp)\nstfs\tf3,0x88(sp)\n\nmr\tREG_FighterData,r3\n\n\t#CHECK IF ENABLED\n\tli\tr0,OSD.SDI\t\t\t#PowerShield ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\tCheckForFollower:\n\tmr\tr3,REG_FighterData\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n\tSDICheck:\n\t#Check For SDI\n\tfcmpo\tcr0,f1,f0\n\tcror\t2, 1, 2\n\tbne\tNoSDI\n\n\t#Check For SDI Cont.\n\tlbz\tr0, 0x0670 (REG_FighterData)\n\tlwz\tr4, -0x514C (r13)\n\tlwz\tr5, 0x04B4 (r4)\n\tcmpw\tr0, r5\n\tblt\tSuccessfulSDI\n\n\t#Check For SDI Cont..\n\tlbz\tr0, 0x0671 (REG_FighterData)\n\tcmpw\tr0, r5\n\tbge\tNoSDI\n\n\tSuccessfulSDI:\n\t#Increment Successful SDI\n\tlhz\tr3,TM_SuccessfulSDIInputs(REG_FighterData)\n\taddi\tr3,r3,0x1\n\tsth\tr3,TM_SuccessfulSDIInputs(REG_FighterData)\n\n\tNoSDI:\n\t#Increment Total SDI\n\tlhz\tr3,TM_TotalSDIInputs(REG_FighterData)\n\taddi\tr3,r3,0x1\n\tsth\tr3,TM_TotalSDIInputs(REG_FighterData)\n\n\n\n\n\t#Change color to Green if SDI'd once\n\t\tlhz\tr3,TM_SuccessfulSDIInputs(REG_FighterData)\n\t\tcmpwi\tr3,0x0\n\t\tbeq\tRedText\n\t\tli\tREG_TextColor,MSGCOLOR_GREEN\n\t\tb\tPrintMessage\n\t\tRedText:\n\t\tli\tREG_TextColor,MSGCOLOR_RED\n\t\tb\tPrintMessage\n\n\t\tPrintMessage:\n\t\tli\tr3,2\t\t\t#Message Kind\n\t\tlbz\tr4,0xC(REG_FighterData)\t#Message Queue\n\t\tmr\tr5,REG_TextColor\n\t\tbl\tSDI_String\n\t\tmflr r6\n\t\tlhz\tr7,TM_SuccessfulSDIInputs(REG_FighterData)\n\t\tlhz\tr8,TM_TotalSDIInputs(REG_FighterData)\n\t\tMessage_Display\n\n\t\tb Moonwalk_Exit\n\n###################\n## TEXT CONTENTS ##\n###################\n\nSDI_String:\nblrl\n.string \"SDI Inputs\\n%d/%d\"\n.align 2\n\n############\n## Floats ##\n############\nFloats:\nblrl\n.long 0x41300000\n##############################\n\nMoonwalk_Exit:\nlfs\tf0,0x80(sp)\nlfs\tf1,0x84(sp)\nlfs\tf2,0x8C(sp)\nlfs\tf3,0x88(sp)\nrestoreall\nfcmpo\tcr0,f1,f0\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Template.s",
    "content": "#To be inserted at 804df470\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n.macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n.set TextCreateFunction,0x80005928\n\n.set entity,31\n.set playerdata,31\n.set player,30\n.set text,29\n.set textprop,28\n.set hitbool,27\n\n##########################################################\n## 804a1f5c -> 804a1fd4 = Static Stock Icon Text Struct ##\n## Is 0x80 long and is zero'd at the start              ##\n##  of every VS Match\t\t\t\t                        ##\n## Store Text Info here                                 ##\n##########################################################\n\n\n/*\nbackup\n\nmr\tplayerdata,r3\n\n\n\t#CHECK IF ENABLED\n\tli\tr0,0x14\t\t\t#PowerShield ID\n\t#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tMoonwalk_Exit\n\n\tCheckForFollower:\n\tmr\tr3,playerdata\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tMoonwalk_Exit\n\n\t\tbl\tCreateText\n\n\t\t#Change Text Color\n\n\t\tcmpwi\tr3,0x1\n\t\tbgt\tRedText\n\n\t\tGreenText:\n\t\tload\tr3,0x8dff6eff\t\t\t#green\n\t\tb\tStoreTextColor\n\n\t\tRedText:\n\t\tload\tr3,0xffa2baff\n\n\t\tStoreTextColor:\n\t\tstw\tr3,0x30(text)\n\n\t\t#Create Text\n\t\tbl\tTopText\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tbranchl r12,0x803a6b98\n\n\t\t#Create Text2\n\t\tbl\tBottomText\n\t\tmr \tr3,r29\t\t\t#text pointer\n\t\tmflr\tr4\n\t\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\t\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\t\tbranchl r12,0x803a6b98\n\n\t\tb Moonwalk_Exit\n\n\n\tCreateText:\n\tstwu\tr1,-0x100(r1)\t# make space for 12 registers\n\tmflr r0\n\tstw r0,0xFC(sp)\n\tmr\tr3,playerdata\t\t\t#backup playerdata pointer\n\tli\tr4,60\t\t\t#display for 60 frames\n\tli\tr5,0\t\t\t#Area to Display (0-2)\n\tli\tr6,13\t\t\t#Window ID (Unique to This Display)\n\tbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\n\n\tmr\ttext,r3\t\t\t#backup text pointer\n\tlwz r0,0xFC(sp)\n\tmtlr r0\n\taddi\tr1,r1,0x100\t# release the space\n\tblr\n\n\n###################\n## TEXT CONTENTS ##\n###################\n\nTopText:\nblrl\n.long 0x46617374\n.long 0x66616c6c\n.long 0x\n\n\nBottomText:\nblrl\n.long 0x4672616d\n.long 0x65202564\n.long 0x\n\n\n##############################\n\n\nMoonwalk_Exit:\nrestore\nli\tr0, 1\n\n*/\nblr\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/Can Disable All Toggles in Custom RSS.asm",
    "content": "#To be inserted at 80236064\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n#CHECK FLAG IN RULES STRUCT\nload\tr3,0x804a04f0\nlbz\tr0, 0x0011 (r3)\ncmpwi\tr0,0x2\nblt\toriginal\n\n\n#REMOVE CUSTOM TEXT\nli\tr0, 0\nb\texit\n\noriginal:\nli\tr0, 1\nexit:\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/Disable Save to Bitfield Every Change.asm",
    "content": "#To be inserted at 802360e0\nnop"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/Load Alt Text When Loaded With L.asm",
    "content": "#To be inserted at 80236b40\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set Text,30\n.set TextProp,28\n\n\n#CHECK FLAG IN RULES STRUCT\nload\tr4,0x804a04f0\nlbz\tr0, 0x0011 (r4)\ncmpwi\tr0,0x2\nblt original\n\nbackup\n\n#SPAWN TEXT\n\nbl\tTextProperties\nmflr\tTextProp\n\n\n\n##########################\n## Write Left Side Text ##\n##########################\n\nCreateText:\n\t#CREATE TEXT ABOVE PLAYERS HUD ELEMENT\n\tli \tr3,0x0\n\tlbz\tr4, -0x4AEB (r13)\n\tbranchl r12,0x803a6754\n\n\t#BACKUP TEXT POINTER\n\tmr\tr30,r3\n\tstw\tr3,0x40(r31)\n\n\t#INITALIZE TEXT ATTRIBUTES\n\tlfs\tf1,0x0(TextProp)\n\tlfs\tf2,0x4(TextProp)\t\t#Y Base\n\tlfs\tf3, -0x3B30 (rtoc)\n\n\tstfs\tf1,0x0(Text)\n\tstfs\tf2,0x4(Text)\n\tstfs\tf3,0x8(Text)\n\n\tli \tr3,0x2\n\tli \tr4,0x1\n\tstb\tr3,0x4A(r30)\n\tstb\tr4,0x48(r30)\n\tstb\tr4,0x49(Text)\n\tlfs\tf2,0x8(TextProp)\n\tstfs\tf2,0x24(Text)\n\tstfs\tf2,0x28(Text)\n\n\n\n#Write Text to the Left Side of the Screen\nInitLoopLeft:\nli\tr29,0\nLoopStartLeft:\nmr\tr3,Text\t\t#text struct to write to\nbl\tTextASCIILeft\nmflr\tr4\t\t#text ascii\nmr\tr5,r29\t\t#text ID\nlfs\tf1, -0x35FC (rtoc)\t#X offset\nbl\tWriteText\nIncLoopLeft:\naddi\tr29,r29,0x1\ncmpwi\tr29,16\nblt\tLoopStartLeft\n\n\n\n#####################\n## Write FDD Title ##\n#####################\n\n#Create Text\nmr\tr3,r30\nbl\tFDDTitleText\nmflr\tr4\nlfs\tf1,0x14(TextProp)\nlfs\tf2,0x18(TextProp)\nbranchl r12,0x803a6b98\n\n#Change Color\nmr\tr4,r3\nmr\tr3,r30\naddi\tr5,sp,0xF0\nload\tr6,0xff7575FF\nstw\tr6,0x0(r5)\nbranchl\tr12,0x803a74f0\n\n#####################\n## Recommended OSD ##\n#####################\n\n#Get Options String\n\tlwz\tr3,-0x77C0(r13)\t\t\t#Get Memcard Data\n  lbz\tr3,OSDRecommended(r3)\n  bl  FDDRecommendedOptions\n  mflr  r4\n  branchl r12,SearchStringTable\n\n#Create Text\n\tmr\tr5,r3\n\tmr\tr3,r30\n\tbl\tFDDRecommended\n\tmflr\tr4\n\tlfs\tf1,RecommendedX(TextProp)\n\tlfs\tf2,RecommendedY(TextProp)\n\tbranchl r12,Text_InitializeSubtext\n\tstb\tr3,0x49(r31)\t\t\t#Store Subtext ID\n\n#Change Color\n\tmr\tr4,r3\n\tmr\tr3,r30\n\taddi\tr5,TextProp,RecommendedColor\n\tbranchl\tr12,Text_ChangeTextColor\n\n#Create Z Text\n\tmr\tr3,r30\n\tbl\tFDDRecommendedZ\n\tmflr\tr4\n\tlfs\tf1,RecommendedZX(TextProp)\n\tlfs\tf2,0x28(TextProp)\n\tbranchl r12,Text_InitializeSubtext\n\n#Change Color\n\tmr\tr4,r3\n\tmr\tr3,r30\n\taddi\tr5,TextProp,RecommendedColor\n\tbranchl\tr12,Text_ChangeTextColor\n\n#########################\n## Write Max OSD Count ##\n#########################\n\n#Create Text\nmr\tr3,r30\nbl\tMaxOSDText\nmflr\tr4\nlwz\tr5, -0x77C0 (r13)\nlbz\tr5, 0x1F28 (r5)\naddi\tr5,r5,1\nlfs\tf1,0x1C(TextProp)\nlfs\tf2,0x20(TextProp)\nbranchl r12,0x803a6b98\nstb\tr3,0x48(r31)\n\n#Change Color\nmr\tr4,r3\nmr\tr3,r30\naddi\tr5,sp,0xF0\nload\tr6,0x8dff6eff\nstw\tr6,0x0(r5)\nbranchl\tr12,0x803a74f0\n\n#Create XY Text\nmr\tr3,r30\nbl\tXYText\nmflr\tr4\nlfs\tf1,0x24(TextProp)\nlfs\tf2,0x28(TextProp)\nbranchl r12,0x803a6b98\n\n#Change Color\nmr\tr4,r3\nmr\tr3,r30\naddi\tr5,sp,0xF0\nbranchl\tr12,0x803a74f0\n\n###########################\n## Write Right Side Text ##\n###########################\n\n\t#CREATE TEXT ABOVE PLAYERS HUD ELEMENT\n\tli \tr3,0x0\n\tlbz\tr4, -0x4AEB (r13)\n\tbranchl r12,0x803a6754\n\n\t#BACKUP TEXT POINTER\n\tmr\tr30,r3\n\tstw\tr3,0x44(r31)\n\n\t#INITALIZE TEXT ATTRIBUTES\n\tlfs\tf1,0x0(TextProp)\n\tlfs\tf2,0x4(TextProp)\t\t#Y Base\n\tlfs\tf3, -0x3B30 (rtoc)\n\n\tstfs\tf1,0x0(Text)\n\tstfs\tf2,0x4(Text)\n\tstfs\tf3,0x8(Text)\n\n\tli \tr3,0x2\n\tli \tr4,0x1\n\tstb\tr3,0x4A(r30)\n\tstb\tr4,0x48(r30)\n\tstb\tr4,0x49(Text)\n\tlfs\tf2,0x8(TextProp)\n\tstfs\tf2,0x24(Text)\n\tstfs\tf2,0x28(Text)\n\n#Write Text to the Right Side of the Screen\nInitLoopRight:\nli\tr29,0\nLoopStartRight:\nmr\tr3,Text\t\t#text struct to write to\nbl\tTextASCIIRight\nmflr\tr4\t\t#text ascii\nmr\tr5,r29\t\t#text ID\nlfs\tf1,0x10(TextProp)\nbl\tWriteText\nIncLoopRight:\naddi\tr29,r29,0x1\ncmpwi\tr29,15\nblt\tLoopStartRight\n\n\nrestore\nb exit\n\n\n\n\n\n\n\n###############\n## WriteText ##\n###############\n#r3= TextStruct\n#r4= TextASCIIPointer\n#r5= Text ID\n#f1= X Offset\n\nWriteText:\n.set REG_TextGObj,31\n.set REG_StringArray,30\n.set REG_StringID,29\n.set TextProp,28\n\n#Backup args\n\tbackup\n\tmr\tREG_TextGObj,r3\n\tmr\tREG_StringArray,r4\n\tmr\tREG_StringID,r5\n\tbl\tTextProperties\n\tmflr\tTextProp\n\tstfs\tf1,0xB0(sp)\n\n\n\tmr\tr3,REG_StringID\n\tmr\tr4,REG_StringArray\n\tbranchl\tr12,SearchStringTable\n\n#GET Y VALUE\n\txoris\tr0, REG_StringID, 0x8000\n\tstw\tr0, 0xF4 (sp)\n\tlis\tr0, 0x4330\n\tstw\tr0, 0xF0 (sp)\n\tlfd\tf0, 0xF0 (sp)\n\tlfd\tf3, -0x3B20 (rtoc)\n\tfsubs\tf0,f3,f0\n\tlfs\tf2,0x4(TextProp)\t\t#Y Base\n\tlfs\tf3,0xC(TextProp)\t\t#Y DIff\n\tfmuls\tf0,f0,f3\n\tfsubs\tf2,f2,f0\n\n\tmr\tr4,r3\n\tmr\tr3,REG_TextGObj\n\tlfs\tf1,0xB0(sp)\n\tbranchl r12,Text_InitializeSubtext\n\trestore\n\tblr\n\n\nTextProperties:\nblrl\n.set RecommendedX,0x2C\n.set RecommendedY,0x30\n.set RecommendedColor,0x34\n.set RecommendedZX,0x38\n.long 0xC0900000\t#Text X Location\n.long 0xC0E80000 #Text Y Base\n.long 0x3CB43958 #Text Scaling\n.long 0x42480000 #Text Y Difference\n.long 0x4423C000 #Right Text X Offset\n.long 0x43960000 #Center Title X\n.long 0xC22C0000 #Center Title Y\n.long 0xC3200000 #Max Windows X\n.long 0xC22C0000 #Max Windows Y\n.long 0xC3700000 #XYText X\n.long 0xC0E80000 #XYText Y\n.float 800\n.float -43.0\n.long 0x8dff6eff\n.float 630\n\nFDDRecommended:\nblrl\n.string \"Suggested OSDs: %s\"\n.align 2\n\nFDDRecommendedOptions:\nblrl\n.string \"On\"\n.string \"Off\"\n.align 2\n\nFDDRecommendedZ:\nblrl\n.string \"(Z)\"\n.align 2\n\nTextASCIILeft:\nblrl\n.string \"\"\n.string \"Wavedash Info\"\n.string \"L-Cancel\"\n.string \"Missed Tech\"\n.string \"Act OoS Frame\"\n.string \"Meteor Cancel\"\n.string \"Dashback\"\n.string \"Shield Drop\"\n.string \"Inputs Per Minute\"\n.string \"Spacie Tech\"\n.string \"Powershield Frame\"\n.string \"Shield Poke + ADT\"\n.string \"SDI Inputs\"\n.string \"Grab Breakout\"\n.string \"Ledgedash Info\"\n.string \"Act OoHitstun\"\n.align 2\n\nTextASCIIRight:\nblrl\n\n.string \"\"\n.string \"Hitstun/Hitlag\"\n.string \"Shield Stun\"\n.string \"State Frames Left\"\n.string \"\"\n.string \"Act OoLag\"\n.string \"Crouch Cancel\"\n.string \"Act OoJump\"\n.string \"Act OoJumpSquat\"\n.string \"Fastfall Timing\"\n.string \"Frame Advantage\"\n.string \"Combo Counter\"\n.string \"DI Draw\"\n.string \"\"\n.string \"UniversalControllerFix\"\n.align 2\n\nFDDTitleText:\nblrl\n.long 0x4f534420\n.long 0x4d656e75\n.long 0x00000000\n\nMaxOSDText:\nblrl\n.long 0x4d617820\n.long 0x4f534427\n.long 0x733a2025\n.long 0x64000000\n\nXYText:\nblrl\n.long 0x81695881\n.long 0x5e59816A\n.long 0x00000000\n\noriginal:\nbranchl\tr4,0x802359c8\nexit:\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/Load Random Stage Select On L Press.asm",
    "content": "#To be inserted at 8022f578\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\nrlwinm.\tr0, r3, 0, 25, 25\t\t\t#CHECK FOR L\nbeq\texit\n\n#PLAY SFX\nli\tr3, 1\nbranchl\tr4,0x80024030\n\n#SET FLAG IN RULES STRUCT\nli\tr0,2\t\t#2 = frame data toggle\nload\tr3,0x804a04f0\nstb\tr0, 0x0011 (r3)\n\n#SET SOMETHING\nli\tr0, 5\nsth\tr0, -0x4AD8 (r13)\n\n#LOAD RSS\nbranchl\tr3,0x80237410\n\n#REMOVE CURRENT THINK FUNCTION\nmr\tr3,r29\nbranchl\tr4,0x80390228\n\nbranch\tr3,0x8022fb68\n#branch\tr3,0x8022f5f4\n\nexit:\nrlwinm.\tr0, r3, 0, 22, 22\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/Load Toggles When Loaded With L .asm",
    "content": "#To be inserted at 80236e00\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n#CHECK FLAG IN RULES STRUCT\nload\tr4,0x804a04f0\nlbz\tr0, 0x0011 (r4)\ncmpwi\tr0,0x2\nblt original\n\n#CUSTOM CODE\nrlwinm\tr0, r3, 0, 16, 31\n#lwz\tr4,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\nlwz\tr4,-0x77C0(r13)\nlwz\tr4,0x1F24(r4)\n\nli\tr3, 1\nslw\tr0, r3, r0\nand.\tr0, r0, r4\nbeq\tOff\n\nOn:\nli\tr3,0x1\nb\texit\nOff:\nli\tr3,0x0\nb\texit\n\noriginal:\nbranchl\tr4,0x80164250\nexit:\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/Press L for OSD Indicator.asm",
    "content": "#To be inserted at 80231618\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set text,31\n.set textproperties,30\n.set originalRegister,29\n\n.set VersionString,0x8040a58c\n\nbackup\n\n########################\n## Create Text Object ##\n########################\n\n#Backup r3\n\tmr\toriginalRegister,r3\n\n#CREATE TEXT OBJECT, RETURN POINTER TO STRUCT IN r3\n\tli r3,0\n\tli r4,1\n\tbranchl r12,0x803a6754\n\n#BACKUP STRUCT POINTER\n\tmr text,r3\n\n#STORE POINTER\n\tstw\ttext,-0x4EB4(r13)\n\n#SET TEXT SPACING TO TIGHT\n\tli r4,0x1\n\tstb r4,0x49(text)\n\n#SET TEXT TO CENTER AROUND X LOCATION\n\tli r4,0x1\n\tstb r4,0x4A(text)\n\n#GET PROPERTIES TABLE\n\tbl TEXTPROPERTIES\n\tmflr textproperties\n\n#Store Base Z Offset\n\tlfs f1,ZPos(textproperties) #Z offset\n\tstfs f1,0x8(text)\n\n#Scale Canvas Down\n  lfs f1,CanvasScaling(textproperties)\n  stfs f1,0x24(text)\n  stfs f1,0x28(text)\n\n#######################\n## Version Indicator ##\n#######################\n\n#Initialize Subtext\n\tlfs \tf1,XPos(textproperties) \t\t#X offset of text\n\tlfs \tf2,YPos(textproperties)\t  \t#Y offset of text\n\tmr \tr3,text\t\t#struct pointer\n\tbl\tText\n\tmflr r4\n\tbranchl r12,0x803a6b98\n#Change scale\n\tmr\tr4,r3\n\tmr\tr3,text\n\tlfs\tf1,TextScale(textproperties)\n\tlfs\tf2,TextScale(textproperties)\n\tbranchl r12,Text_UpdateSubtextSize\n\nb end\n\n\n\n#**************************************************#\nTEXTPROPERTIES:\nblrl\n.set XPos,0x0\n.set YPos,0x4\n.set ZPos,0x8\n.set TextScale,0xC\n.set CanvasScaling,0x10\n\n#Version\n.float -250    #text X pos\n.float -241   #text Y pos\n.float 17     #Z offset\n.float 0.8\t\t#text scale\n\n.float 0.035   #Canvas Scaling\n\nText:\nblrl\n.string \"L = OSD\"\n.align 2\n\n#**************************************************#\nend:\n\nmr\tr3,originalRegister\nrestore\nlmw\tr14, 0x00E0 (sp)\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/Remove Press L for OSD Indicator.asm",
    "content": "#To be inserted at 80230974\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set text,31\n.set textproperties,30\n\nOriginal:\n\tstw\tr0, 0x0130 (r31)\n\n#Get Pointer\n\tlwz r3,-0x4EB4(r13)\n\tcmpwi r3,0\n\tbeq\tExit\n#Remove Text\n\tbranchl r12,Text_RemoveText\n\nExit:\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/Remove Text When Leaving Custom RSS.asm",
    "content": "#To be inserted at 80236bbc\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n.macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n\n#CHECK FLAG IN RULES STRUCT\nload\tr3,0x804a04f0\nlbz\tr0, 0x0011 (r3)\ncmpwi\tr0,0x2\nblt\toriginal\n\n\n#REMOVE CUSTOM TEXT\nlwz\tr3,0x40(r31)\t\t\t#GET TEXT POINTER\nbranchl\tr12,0x803a5cc4\t\t\t#REMOVE TEXT\n\nlwz\tr3,0x44(r31)\t\t\t#GET TEXT POINTER\nbranchl\tr12,0x803a5cc4\t\t\t#REMOVE TEXT\n\nbranch r12,0x80236be0\t\t\t\t#EXIT\n\noriginal:\nli\tr25, 0\nexit:\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/Return to Event Screen When Pressing Start.asm",
    "content": "#To be inserted at 80236128\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n.macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n\n#CHECK FLAG IN RULES STRUCT\nlbz\tr3, 0x0011 (r31)\ncmpwi\tr3,0x3\nbne\toriginal\n\nLoadEvents:\nmr\tr3, r27\nbranchl\tr12,0x80390228\nlwz\tr3, -0x77C0 (r13)\nlbz\tr3, 0x0535 (r3)\t\t\t#Get Last Event Match\nli\tr4,1\t\t\t#No Delay On Text Loading\nbranchl\tr12,0x8024e838\nbranch\tr12,0x80236164\n\noriginal:\nli\tr3, 2\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/Return to First Page When Loaded With L.asm",
    "content": "#To be inserted at 80235fe4\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n.macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n\n#CHECK FLAG IN RULES STRUCT\nload\tr3,0x804a04f0\nlbz\tr0, 0x0011 (r3)\ncmpwi\tr0,0x2\nblt\toriginal\n\n#DETERMINE WHERE TO RETURN\ncmpwi\tr0,0x2\nbeq\tLoadRulesFirstPage\ncmpwi\tr0,0x3\nbeq\tLoadEvents\n\nLoadRulesFirstPage:\nbranchl\tr12,0x8023164c\nb\texit\n\nLoadEvents:\nlwz\tr3, -0x77C0 (r13)\nlbz\tr3, 0x0535 (r3)\t\t\t#Get Last Event Match\nli\tr4,1\t\t\t#No Delay On Text Loading\nbranchl\tr12,0x8024e838\nb\texit\n\noriginal:\nbranchl\tr12,0x802339fc\nexit:\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/Save Toggles When Loaded With L.asm",
    "content": "#To be inserted at 80235994\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n.macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n\n#CHECK FLAG IN RULES STRUCT\nload\tr5,0x804a04f0\nlbz\tr0, 0x0011 (r5)\ncmpwi\tr0,0x2\nblt original\n\n#CUSTOM CODE\nrlwinm\tr0, r3, 0, 24, 31\t\t\t#put menu selection in r0\n#lwz\tr5,-0xdbc(rtoc)\t\t\t#get frame data toggle bits\nlwz\tr6,-0x77C0(r13)\nlwz\tr5,0x1F24(r6)\nrlwinm.\tr4, r4, 0, 24, 31\t\t\t#check if turning on or off\n\nbeq\tturnOff\n\nturnOn:\nli\tr4, 1\nslw\tr0, r4, r0\nor\tr0, r5, r0\nstw\tr0,0x1F24(r6)\n#stw\tr0,-0xdbc(rtoc)\t\t\t#store frame data toggle bits\nb exit\n\nturnOff:\nli\tr4, 1\nslw\tr0, r4, r0\nandc\tr0, r5, r0\nstw\tr0,0x1F24(r6)\n#stw\tr0,-0xdbc(rtoc)\t\t\t#store frame data toggle bits\nb exit\n\n\noriginal:\nbranchl\tr5,0x801641e4\nexit:\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/Set Flag on Leaving Custom RSS.asm",
    "content": "#To be inserted at 80235fcc\n.macro branchl reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctrl\n.endm\n\n.macro branch reg, address\nlis \\reg, \\address @h\nori \\reg,\\reg,\\address @l\nmtctr \\reg\nbctr\n.endm\n\n.macro load reg, address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\n.endm\n\n.macro loadf regf,reg,address\nlis \\reg, \\address @h\nori \\reg, \\reg, \\address @l\nstw \\reg,-0x4(sp)\nlfs \\regf,-0x4(sp)\n.endm\n\n.macro backup\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\n.endm\n\n.macro restore\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\n.endm\n\n.macro intToFloat reg,reg2\nxoris    \\reg,\\reg,0x8000\nlis    r18,0x4330\nlfd    f16,-0x7470(rtoc)    # load magic number\nstw    r18,0(r2)\nstw    \\reg,4(r2)\nlfd    \\reg2,0(r2)\nfsubs    \\reg2,\\reg2,f16\n.endm\n\n.set ActionStateChange,0x800693ac\n.set HSD_Randi,0x80380580\n.set HSD_Randf,0x80380528\n.set Wait,0x8008a348\n.set Fall,0x800cc730\n\n.set entity,31\n.set player,31\n\n#CHECK FLAG IN RULES STRUCT\nlbz\tr0, 0x0011 (r31)\ncmpwi\tr0,0x2\nbge\texit\n\n\noriginal:\nstb\tr30, 0x0011 (r31)\nexit:\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Toggle UI/XY To Adjust Max OSD.asm",
    "content": "#To be inserted at 802360f8\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set Text,30\n.set TextProp,28\n\n.set MaxWindows,4-1\n\n#Injected into CursorMovement Check\n\nbackup\n\n#CHECK FLAG IN RULES STRUCT\nload\tr4,0x804a04f0\nlbz\tr0, 0x0011 (r4)\ncmpwi\tr0,0x2\nblt exit\n\nli  r3,4\nbranchl r12,Inputs_GetPlayerInstantInputs\n\nlwz\tr20,-0x77C0(r13)\t\t\t#Get Memcard Data\n\n#############################################\nCheckY:\nrlwinm.\tr0, r4, 0, 20, 20 \t\t#Check For Y\nbeq\tCheckX\n\n#Increase Number\nlbz\tr3,0x1f28(r20)\naddi\tr3,r3,0x1\n#Check If Over Max\ncmpwi\tr3,MaxWindows\nble\tCheckY_Store\n#Loop Back to 0\nli\tr3,0x0\nCheckY_Store:\nstb\tr3,0x1f28(r20)\n\nb\tUpdateText\n#############################################\n\nCheckX:\nrlwinm.\tr0, r4, 0, 21, 21 \t\t#Check For X\nbeq\tCheckZ\n\n#Decrease Number\nlbz\tr3,0x1f28(r20)\nsubi\tr3,r3,0x1\n#Check If Over Max\ncmpwi\tr3,0\nbge\tCheckX_Store\n#Loop Back to MaxWindows\nli\tr3,MaxWindows\nCheckX_Store:\nstb\tr3,0x1f28(r20)\n\nb\tUpdateText\n#############################################\n\nCheckZ:\nrlwinm.\tr0, r4, 0, 27, 27 \t\t#Check For Z\nbeq\texit\n\n#Toggle option\n  lbz\tr3,OSDRecommended(r20)\n  xori r3,r3,1\n  stb\tr3,OSDRecommended(r20)\n#Get Options String\n  bl  FDDRecommendedOptions\n  mflr  r4\n  branchl r12,SearchStringTable\n#Update Text\n  mr  r6,r3\n  lwz\tr3,0x40(r29)\t\t\t#Get Text Structure\n  lbz\tr4,0x49(r29)\t\t\t#Get Subtext ID\n  bl\tFDDRecommended\n  mflr\tr5\n  crclr 6\n  branchl r12,Text_UpdateSubtextContents\n\nb PlaySFX\n#############################################\n\nUpdateText:\nlwz\tr3,0x40(r29)\t\t\t#Get Text Structure\nlbz\tr4,0x48(r29)\t\t\t#Get Subtext ID\nbl\tUpdateText_Text\nmflr\tr5\nlbz\tr6,0x1f28(r20)\naddi\tr6,r6,0x1\nbranchl\tr12,0x803a70a0\n\nb\tPlaySFX\n#############################################\n\nUpdateText_Text:\nblrl\n.string \"Max OSD's: %d\"\n.align 2\n\nFDDRecommended:\nblrl\n.string \"Suggested OSDs: %s\"\n.align 2\n\nFDDRecommendedOptions:\nblrl\n.string \"On\"\n.string \"Off\"\n.align 2\n########################################\n\nPlaySFX:\n  li  r3,2\n  branchl r12,0x80024030\n\nexit:\nrestore\nrlwinm.\tr0, r28, 0, 23, 23\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Wavedash Display/Save Airdodge Y Angle.asm",
    "content": "#To be inserted at 80099b74\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n#Get Airdodge Angle\n\tmr\tr3,r31\n\tbranchl r12,Joystick_Angle_Retrieve\n#Save angle\n\tstfs f1,TM_AirdodgeAngle(r31)\n\nExit:\naddi\tr3, r29, 0\n"
  },
  {
    "path": "ASM/training-mode/Onscreen Display/Wavedash Display/Wavedash Timing Display.asm",
    "content": "#To be inserted at 80099d7c\n.include \"../../Globals.s\"\n.include \"../../../m-ex/Header.s\"\n\n.set REG_FighterData,29\n.set REG_FighterGObj,27\n.set text,28\n.set REG_Text,30\n\nbackup\n\n#Get Pointers\n\tmr\tREG_FighterGObj,r3\n\tlwz REG_FighterData,0x2C(REG_FighterGObj)\n\n\n#CHECK IF OSD IS ENABLED\n\tli\tr0,OSD.Wavedash\t\t\t#wavedash ID\n\tlwz\tr4,-0x77C0(r13)\n\tlwz\tr4,0x1F24(r4)\n\tli\tr3, 1\n\tslw\tr0, r3, r0\n\tand.\tr0, r0, r4\n\tbeq\tInjection_Exit\n\n#Check if fighter is a subcharacter\n\tmr\tr3,REG_FighterData\n\tbranchl\tr12,0x80005510\n\tcmpwi\tr3,0x1\n\tbeq\tInjection_Exit\n\n#CHECK IF IT WAS A WAVEDASH (landed within 20 frames)\n\tlhz\tr3,TM_FramesinCurrentAS(REG_FighterData)\n\tcmpwi r3,20\n\tbgt\tInjection_Exit\n\n\t#Get wavedash angle\n\tlfs\tf1,TM_AirdodgeAngle(REG_FighterData)\n\tbl\tGetWavedashAngle\n\tstfs f1,0x80(sp)\n\n\tPrintMessage:\n\tli\tr3,0\t\t\t#Message Kind\n\tlbz\tr4,0xC(REG_FighterData)\t#Message Queue\n\tli\tr5,MSGCOLOR_WHITE\n\tbl\tWavedash_String\n\tmflr r6\n\tlhz\tr7,TM_FramesinCurrentAS(REG_FighterData)\n\taddi r7,r7,1\t\t\t\t\t\t\t\t#1-index number\n\tMessage_Display\n\tlwz\tr3,0x2C(r3)\n\tlwz\tREG_Text,MsgData_Text(r3)\n\n\t# Adjust Timing color\n\t\tlhz\tr3,TM_FramesinCurrentAS(REG_FighterData)\n\t\tcmpwi\tr3,0\n\t\tbne AdjustAngleColor\n\t\tbl\tFloats\n\t\tmflr r4\n\t\taddi r5,r4,0xC\n\t#Change Color\n\t\tmr \tr3,REG_Text\t\t\t#text pointer\n\t\tli\tr4,0\n\t\tbranchl\tr12,Text_ChangeTextColor\n\n\tAdjustAngleColor:\n\t# Adjust Angle color\n\t#Get Angle and Float Pointer\n\t\tbl\tFloats\n\t\tmflr r4\n\t\tlfs f1,\t0x80(sp)\n\t#Check For Perfect Angle\n\t\tlfs f2,0x0(r4)\n\t\tfcmpo cr0,f1,f2\n\t\tblt Injection_Exit\n\t\tlfs f2,0x4(r4)\n\t\tfcmpo cr0,f1,f2\n\t\tblt PerfectAngle\n\t\tlfs f2,0x8(r4)\n\t\tfcmpo cr0,f1,f2\n\t\tbgt Injection_Exit\n\tOKAngle:\n\t\taddi r5,r4,0x10\n\t\tb ChangeAngleColor\n\tPerfectAngle:\n\t\taddi r5,r4,0xC\n\t\tb ChangeAngleColor\n\tChangeAngleColor:\n\t#Change Color\n\t\tmr \tr3,REG_Text\t\t\t#text pointer\n\t\tli\tr4,1\n\t\tbranchl\tr12,Text_ChangeTextColor\n\n\n\nb Injection_Exit\n\n\n\n/*\n\n#Create OSD Popup\n\tmr\tr3,REG_FighterData\t\t\t#backup REG_FighterData pointer\n\tli\tr4,60\t\t\t#display for 60 frames\n\tli\tr5,0\t\t\t#Area to Display (0-2)\n\tli\tr6,0\t\t\t#Window ID (Unique to This Display)\n\tbranchl\tr12,TextCreateFunction\t\t\t#create text custom function\n\n\tmr\ttext,r3\t\t\t#backup text pointer\n\n###########################\n## Print Wavedash Timing ##\n###########################\n\n#Write out top line\n\tmr \tr3,text\t\t\t#text pointer\n\tbl\tTextASCII\n\tmflr \tr4\t\t\t#get ASCII to print\n\tlhz\tr5,TM_FramesinCurrentAS(REG_FighterData)\n\taddi r5,r5,1\t\t\t\t\t\t\t\t#1-index number\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tcrset 6\n\tbranchl r12,0x803a6b98\n\n#Check if frame perfect\n\tlbz\tr4,0x680(REG_FighterData)\n\tcmpwi\tr4,0x0\n\tbne DisplayWavedashAngle\n#Change Color\n\tmr\tr4,r3\t\t\t\t#subtext id\n\tmr \tr3,text\t\t\t#text pointer\n\tload\tr5,0x8dff6eff\n\tstw\tr5,0xF0(sp)\n\taddi r5,sp,0xF0\n\tbranchl r12,0x803a74f0\n*/\n#########################\n## Get Wavedash Angle  ##\n#########################\n\nGetWavedashAngle:\nbackup\n\n#Convert angle to degrees\n\tlfs\tf2, -0x3D10 (rtoc)\t\t\t#0.017453\n\tfdivs f2,f1,f2\n#Multiply by 10 to preserve 1 decimal point\n\tli\tr3,10\n\tbl\tIntToFloat\n\tfmuls f2,f1,f2\n#Cast to int to floor\n\tfctiwz f1,f2\n\tstfd f1,-0x4(sp)\n\tlwz r3,0x0(sp)\n#Cast back to float\n\tbl\tIntToFloat\n#Divide by 10 to get decimal point back\n\tfmr f2,f1\n\tli\tr3,10\n\tbl\tIntToFloat\n\tfdivs f2,f2,f1\n#Normalize to 0-90, definitely could have handled this better but its w/e\n\tli\tr3,0\n\tbl\tIntToFloat\n\tfcmpo cr0,f2,f1\n\tbge TopQuadrant\nBottomQuadrant:\n\tli\tr3,-90\n\tbl\tIntToFloat\n\tfcmpo cr0,f2,f1\n\tbgt Quadrant4\nQuadrant3:\n\tli\tr3,180\n\tbl\tIntToFloat\n\tfadds f2,f1,f2\n\tb\tSaveAngle\nQuadrant4:\n\tfneg f2,f2\n\tb\tSaveAngle\nTopQuadrant:\n\tli\tr3,90\n\tbl\tIntToFloat\n\tfcmpo cr0,f2,f1\n\tbgt Quadrant2\nQuadrant1:\n\tb\tSaveAngle\nQuadrant2:\n\tfneg f2,f2\n\tli\tr3,180\n\tbl\tIntToFloat\n\tfadds f2,f1,f2\n\tb\tSaveAngle\n\nSaveAngle:\n\tfmr\tf1,f2\n\trestore\n\tblr\n\n/*\n#Display Wavedash Angle\n\tmr \tr3,text\t\t\t#text pointer\n\tbl\tTextASCII2\n\tmflr \tr4\t\t\t#get ASCII to print\n\tlfs\tf1, -0x37B4 (rtoc)\t\t\t#default text X/Y\n\tlfs\tf2, -0x37B0 (rtoc)\t\t\t#shift down on Y axis\n\tlfs f3,\t0x80(sp)\n\tcrset 6\n\tbranchl r12,0x803a6b98\n\n#Get Angle and Float Pointer\n\tbl\tFloats\n\tmflr r4\n\tlfs f1,\t0x80(sp)\n#Check For Perfect Angle\n\tlfs f2,0x0(r4)\n\tfcmpo cr0,f1,f2\n\tblt Injection_Exit\n\tlfs f2,0x4(r4)\n\tfcmpo cr0,f1,f2\n\tblt PerfectAngle\n\tlfs f2,0x8(r4)\n\tfcmpo cr0,f1,f2\n\tbgt Injection_Exit\nOKAngle:\n\tload\tr5,0xfff000ff\n\tstw\tr5,0xF0(sp)\n\tb ChangeAngleColor\nPerfectAngle:\n\tload\tr5,0x8dff6eff\n\tstw\tr5,0xF0(sp)\n\tb ChangeAngleColor\nChangeAngleColor:\n#Change Color\n\tmr\tr4,r3\t\t\t\t#subtext id\n\tmr \tr3,text\t\t\t#text pointer\n\taddi r5,sp,0xF0\n\tbranchl r12,0x803a74f0\n*/\n\n\n#########################\n\nWavedash_String:\nblrl\n.string \"Wavedash Frame: %d\\nAngle: %2.1f\"\n.align 2\n\nTextASCII:\nblrl\n.string \"Wavedash Frame: %d\"\n.align 2\n\nTextASCII2:\nblrl\n.string \"Angle: %2.1f\"\n.align 2\n\nFloats:\nblrl\n.float 16.8\t\t#Great Angle Min\n.float 23.7\t\t#Great Angle Max\n.float 30.5\t\t#Good Angle Max\n.long 0x8dff6eff\t#Perfect Angle\n.long 0xfff000ff \t#Great Angle\n\n##############################\n\nIntToFloat:\nmflr r0\nstw r0, 0x4(r1)\nstwu\tr1,-0x100(r1)\t# make space for 12 registers\nstmw  r20,0x8(r1)\nstfs  f2,0x38(r1)\n\nlis\tr0, 0x4330\nlfd\tf2, -0x6758 (rtoc)\nxoris\tr3, r3,0x8000\nstw\tr0,0xF0(sp)\nstw\tr3,0xF4(sp)\nlfd\tf1,0xF0(sp)\nfsubs\tf1,f1,f2\t\t#Convert To Float\n\nlfs  f2,0x38(r1)\nlmw  r20,0x8(r1)\nlwz r0, 0x104(r1)\naddi\tr1,r1,0x100\t# release the space\nmtlr r0\nblr\n\n##############################\n\nInjection_Exit:\nmr\tr3,REG_FighterGObj\nrestore\n\nlwz\tr4, -0x514C (r13)\n"
  },
  {
    "path": "Build TM Codeset/Build Training Mode Codeset.bat",
    "content": "gecko build\n\npause"
  },
  {
    "path": "Build TM Codeset/codes.json",
    "content": "{\n  \"settings\": {\n    \"areIncludesRelativeFromFile\": true\n  },\n    \"outputFiles\":\n    [\n      {\n        \"file\": \"..\\\\Additional ISO Files\\\\codes.gct\"\n      }\n    ],\n  \"codes\": [\n    {\n      \"name\": \"Training Mode Codset\",\n      \"authors\": [\n        \"UnclePunch\"\n      ],\n      \"description\": [\n        \"Complete TM Codeset\"\n      ],\n      \"build\": [\n        {\n          \"type\": \"injectFolder\",\n          \"sourceFolder\": \"..\\\\ASM\",\n          \"isRecursive\": true\n        },\n        {\n          \"type\": \"replaceCodeBlock\",\n          \"address\": \"8042ABD8\",\n          \"sourceFile\": \"..\\\\ASM\\\\training-mode\\\\Misc\\\\Edit Hyphen Texture.s\",\n          \"annotation\": \"Edit Hyphen Texture\"\n        },\n        {\n          \"type\": \"replaceCodeBlock\",\n          \"address\": \"8042a760\",\n          \"sourceFile\": \"..\\\\ASM\\\\training-mode\\\\Misc\\\\Edit Carrot Texture.s\",\n          \"annotation\": \"Edit Carrot Texture\"\n        },\n        {\n          \"type\": \"replaceCodeBlock\",\n          \"address\": \"8040a58c\",\n          \"sourceFile\": \"..\\\\ASM\\\\training-mode\\\\Misc\\\\Store Version Number.s\",\n          \"annotation\": \"Version Number\"\n        },\n        {\n          \"type\": \"replaceCodeBlock\",\n          \"address\": \"803ea6c8\",\n          \"sourceFile\": \"..\\\\ASM\\\\training-mode\\\\Misc\\\\Overwrite Compile Date.s\",\n          \"annotation\": \"Overwrite Compile Date\"\n        },\n        {\n          \"type\": \"replaceCodeBlock\",\n          \"address\": \"803edc1c\",\n          \"sourceFile\": \"..\\\\ASM\\\\Additional Codes\\\\QWERTY Keyboard.s\",\n          \"annotation\": \"QWERTY Keyboard\"\n        }\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "Build TM Codeset/mac/codes.json",
    "content": "{\n  \"settings\": {\n    \"areIncludesRelativeFromFile\": true\n  },\n    \"outputFiles\":\n    [\n      {\n        \"file\": \"../../Additional ISO Files//codes.gct\"\n      }\n    ],\n  \"codes\": [\n    {\n      \"name\": \"Training Mode Codset\",\n      \"authors\": [\n        \"UnclePunch\"\n      ],\n      \"description\": [\n        \"Complete TM Codeset\"\n      ],\n      \"build\": [\n        {\n          \"type\": \"injectFolder\",\n          \"sourceFolder\": \"../../ASM\",\n          \"isRecursive\": true\n        },\n        {\n          \"type\": \"replaceCodeBlock\",\n          \"address\": \"8042ABD8\",\n          \"sourceFile\": \"../../ASM/Misc/Edit Hyphen Texture.s\",\n          \"annotation\": \"Edit Hyphen Texture\"\n        },\n        {\n          \"type\": \"replaceCodeBlock\",\n          \"address\": \"8040a58c\",\n          \"sourceFile\": \"../../ASM/Misc/Store Version Number.s\",\n          \"annotation\": \"Version Number\"\n        },\n        {\n          \"type\": \"replaceCodeBlock\",\n          \"address\": \"803ea6c8\",\n          \"sourceFile\": \"../../ASM/Misc/Overwrite Compile Date.s\",\n          \"annotation\": \"Overwrite Compile Date\"\n        },\n        {\n          \"type\": \"replaceCodeBlock\",\n          \"address\": \"803edc1c\",\n          \"sourceFile\": \"../../ASM/Additional Codes/QWERTY Keyboard.s\",\n          \"annotation\": \"QWERTY Keyboard\"\n        }\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "Build TM Codeset/mac/modifyStartDol.sh",
    "content": "output_dir=../../Additional\\ ISO\\ Files/Start.dol\nxdelta_patch_path=../../Build\\ TM\\ Start.dol/StartDolTMPatch.xdelta\n\necho Creating Training Mode Start.dol...\n\necho Mofifying Start.dol located at $1\n\nxdelta3 -d -f -s $1 \"${xdelta_patch_path}\" \"${output_dir}\"\n\n\necho Done!\necho The file is located at ../../Additional ISO Files/Start.dol"
  },
  {
    "path": "Build TM Start.dol/Drag Melee v1.02 Start.dol Here.bat",
    "content": "@echo off\t\n\necho #####################################\necho ##                                 ##\necho ##                                 ##\necho ## Training Mode Start.dol Creator ##\necho ##                                 ##\necho ##                                 ##\necho #####################################\necho.\n\necho Creating Training Mode Start.dol...\necho.\n\ncd /d %~dp0\n\nxdelta.exe -d -f -s %1 \"patch.xdelta\" \"..\\Additional ISO Files\\Start.dol\"\n\necho.\necho Done!\necho The file is located in the \"Additional ISO Files\" folder!\n\npause"
  },
  {
    "path": "MexTK/MexTK.exe.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.7.2\"/>\n    </startup>\n</configuration>\n"
  },
  {
    "path": "MexTK/cssFunction.txt",
    "content": "OnCSSLoad"
  },
  {
    "path": "MexTK/evFunction.txt",
    "content": "Event_Init\nEvent_Update\nEvent_Think\nEvent_Menu"
  },
  {
    "path": "MexTK/ftFunction.txt",
    "content": "onload\nondeath\nonunknown\nmove_logic\nspecialn\nspecialairn\nspecials\nspecialairs\nspecialhi\nspecialairhi\nspeciallw\nspecialairlw\nonabsorb\nonitempickup\nonmakeiteminvisible\nonmakeitemvisible\nonitemdrop\nonitemcatch\nonunknownitemrelated\nonunknowncharactermodelflags1\nonunknowncharactermodelflags2\nonhit\nonunknowneyetexturerelated\nonframe\nonactionstatechange\nonrespawn\nonmodelrender\nonshadowrender\nonunknownmultijump\nonactionstatechangewhileeyetextureischanged\nontwoentrytable\nenterfloat\nenterdoublejump\nentertether\nonlanding\nonsmashf\nonsmashhi\nonsmashlw"
  },
  {
    "path": "MexTK/grFunction.txt",
    "content": "null_1\nmap_gobjs\nnull_2\noninit\nonunk1\nonload\nongo\nonunk2\nonTouchLine\nonunk4\n"
  },
  {
    "path": "MexTK/include/archive.h",
    "content": "#ifndef MEX_H_ARCHIVE\n#define MEX_H_ARCHIVE\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n\nstruct ArchiveInfo\n{\n    int file_size;       // size of file\n    int *reloc_offset;   // pointer to relocation table offset?\n    int reloc_num;       // number of entries on the rleoc table\n    int symbol_num;      // total number of symbols\n    int refsymbol_num;   // number of reference symbols\n    int archive_vers;    // idk for sure sometimes 001B\n    int unk1;            //\n    int unk2;            //\n    int *general_points; //0x20 = pointer to the \"general points\"\n    int *reloc_table;    //pointer to relocation table in memory\n    int *symbols1;       //pointer to symbol pointers and name offsets\n    int *refsymmbols;    //pointer to reference symbol info in memory\n    int *symbols2;       //pointer to symbol list in memory\n    int *file_start;     //pointer to the header of the dat\n};\n\nArchiveInfo *File_Load(char *filename);\nvoid File_LoadInitReturnSymbol(char *filename, void *ptr, ...); // input each symbol name pointer sequentially and terminate with 0;\nvoid *File_GetSymbol(void *archive, char *symbol);\n\n#endif\n"
  },
  {
    "path": "MexTK/include/audio.h",
    "content": "#ifndef MEX_H_AUDIO\n#define MEX_H_AUDIO\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n\nchar *Nametag_GetText(int tag_index);\nvoid Audio_ResetCache(int group_index);\nvoid Audio_QueueFileLoad(int group_index, u64 ssm_index);\nvoid Audio_UpdateCache();\nvoid Audio_SyncLoadAll();\nint BGM_GetMenuBGM();\nvoid BGM_Play(int hpsID);\n\n#endif\n"
  },
  {
    "path": "MexTK/include/boneset.h",
    "content": "#ifndef MEX_H_BONESET\n#define MEX_H_BONESET\n\n#include \"structs.h\"\n\n/*** Structs ***/\n\n#endif\n"
  },
  {
    "path": "MexTK/include/collision.h",
    "content": "#ifndef MEX_H_COLLISION\n#define MEX_H_COLLISION\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"obj.h\"\n\n// ECB Flags\n#define ECB_GROUND 0x8000\n#define ECB_CEIL 0x4000\n#define ECB_WALLLEFT 0x800\n#define ECB_WALLRIGHT 0x20\n\n// Line Directions\n#define LINE_GROUND 1\n#define LINE_CEIL 2\n#define LINE_WALLRIGHT 4\n#define LINE_WALLLEFT 8\n\n/*** Structs ***/\n\nstruct ECBBones\n{\n    float topY;\n    float botY;\n    Vec2 left;\n    Vec2 right;\n};\n\nstruct DmgHazard\n{\n    int x0;\n    int dmg;\n    int angle;\n    int kb_growth;\n    int x10;\n    int kb_base;\n    int element;\n    int x1c;\n    int sfx;\n};\n\nstruct CollData\n{\n    GOBJ *gobj;                // 0x0\n    Vec3 topN_Curr;            // 0x4\n    Vec3 topN_CurrCorrect;     // 0x10\n    Vec3 topN_Prev;            // 0x1c\n    Vec3 topN_Proj;            // 0x28\n    int flags1;                // 0x34\n    int coll_test;             // 0x38, is the ID of the most recent collision test for this object\n    int ignore_line;           // 0x3c, ignores this line ID during collision\n    int ledge_left;            // 0x40, ledge ID in contact with\n    int ledge_right;           // 0x44, ledge ID in contact with\n    int ignore_group;          // 0x48  ignores this line group during collision\n    int check_group;           // 0x4c  checks only this line group during collision\n    int x50;                   // 0x50\n    int x54;                   // 0x54\n    int x58;                   // 0x58\n    int x5c;                   // 0x5c\n    int x60;                   // 0x60\n    int x64;                   // 0x64\n    int x68;                   // 0x68\n    int x6c;                   // 0x6c\n    int x70;                   // 0x70\n    int x74;                   // 0x74\n    int x78;                   // 0x78\n    int x7c;                   // 0x7c\n    int x80;                   // 0x80\n    Vec2 ecbCurr_top;          // 0x84\n    Vec2 ecbCurr_bot;          // 0x8C\n    Vec2 ecbCurr_right;        // 0x94\n    Vec2 ecbCurr_left;         // 0x9C\n    Vec2 ecbCurrCorrect_top;   // 0xA4\n    Vec2 ecbCurrCorrect_bot;   // 0xAC\n    Vec2 ecbCurrCorrect_right; // 0xB4\n    Vec2 ecbCurrCorrect_left;  // 0xBC\n    Vec2 ecbPrev_top;          // 0xC4\n    Vec2 ecbPrev_bot;          // 0xCC\n    Vec2 ecbPrev_right;        // 0xD4\n    Vec2 ecbPrev_left;         // 0xDC\n    Vec2 ecbProj_top;          // 0xE4\n    Vec2 ecbProj_bot;          // 0xEC\n    Vec2 ecbProj_right;        // 0xF4\n    Vec2 ecbProj_left;         // 0xFC\n    int x104;                  // 0x104\n    JOBJ *joint_1;             // 0x108\n    JOBJ *joint_2;             // 0x10c\n    JOBJ *joint_3;             // 0x110\n    JOBJ *joint_4;             // 0x114\n    JOBJ *joint_5;             // 0x118\n    JOBJ *joint_6;             // 0x11c\n    JOBJ *joint_7;             // 0x120\n    int x124;                  // 0x124\n    int x128;                  // 0x128\n    int x12c;                  // 0x12c\n    int flags;                 // 0x130\n    int envFlags;              // 0x134\n    int envFlags_prev;         // 0x138\n    int x13c;                  // 0x13c\n    int x140;                  // 0x140\n    int x144;                  // 0x144\n    int x148;                  // 0x148\n    int ground_index;          // 0x14c, ground\n    u8 ground_info;            // 0x150\n    u8 ground_unk;             // 0x151\n    u8 ground_type;            // 0x152, platform/ledgegrab\n    u8 ground_mat;             // 0x153, grass/ice etc\n    Vec3 ground_slope;         // 0x154\n    int rightwall_index;       // 0x160\n    u8 rightwall_info;         // 0x164\n    u8 rightwall_unk;          // 0x165\n    u8 rightwall_type;         // 0x166, platform/ledgegrab\n    u8 rightwall_mat;          // 0x167, grass/ice etc\n    Vec3 rightwall_slope;      // 0x168\n    int leftwall_index;        // 0x174\n    u8 leftwall_info;          // 0x178\n    u8 leftwall_unk;           // 0x179\n    u8 leftwall_type;          // 0x17A, platform/ledgegrab\n    u8 leftwall_mat;           // 0x17B, grass/ice etc\n    Vec3 leftwall_slope;       // 0x17C\n    int ceil_index;            // 0x188\n    u8 ceil_info;              // 0x18C\n    u8 ceil_unk;               // 0x18D\n    u8 ceil_type;              // 0x18E, platform/ledgegrab\n    u8 ceil_mat;               // 0x18F, grass/ice etc\n    Vec3 ceil_slope;           // 0x190\n    int ecb_lock;              // 0x19c\n};\n\nstruct CollGroupDesc // exists in stage file\n{\n    u16 floor_start;\n    u16 floor_num;\n    u16 ceil_start;\n    u16 ceil_num;\n    u16 rwall_start;\n    u16 rwall_num;\n    u16 lwall_start;\n    u16 lwall_num;\n    u16 dyn_start;\n    u16 dyn_num;\n    Vec2 area_min; // 0x10\n    Vec2 area_max; // 0x18\n    u16 vert_start;\n    u16 vert_num;\n};\n\nstruct CollGroup // exists in heap\n{\n    CollGroup *next;\n    CollGroupDesc *desc;\n    int x8;               // flags\n    u16 ray_id;           // id of the last raycast\n    u16 xe;               // flags\n    Vec2 area_min;        // 0x10\n    Vec2 area_max;        // 0x18\n    JOBJ *jobj;           // 0x20\n    void *cb_floor;       // 0x24\n    void *map_data_floor; // 0x28\n    void *cb_ceil;        // 0x2C\n    void *map_data_ceil;  // 0x30\n    int x34;              // 0x34\n};\n\nstruct CollLineInfo\n{\n    s16 vert_prev;          // 0x0\n    s16 vert_next;          // 0x2\n    s16 line_prev;          // 0x4\n    s16 line_next;          // 0x6\n    s16 line_prev_altgroup; // 0x8\n    s16 line_next_altgroup; // 0xA\n    u8 xc;\n    u8 xd_1 : 1;     // 0xD, 0x8000\n    u8 xd_2 : 1;     // 0xD, 0x8000\n    u8 xd_3 : 1;     // 0xD, 0x8000\n    u8 disabled : 1; // 0xD, 0x8000\n    u8 is_left : 1;  // 0xD, 0x8000\n    u8 is_right : 1; // 0xD, 0x8000\n    u8 is_ceil : 1;  // 0xD, 0x0200\n    u8 is_floor : 1; // 0xD, 0x8000\n    u8 xe_1 : 1;     // 0xE, 0x8000\n    u8 xe_2 : 1;     // 0xE, 0x8000\n    u8 xe_3 : 1;     // 0xE, 0x8000\n    u8 xe_4 : 1;     // 0xE, 0x8000\n    u8 xe_5 : 1;     // 0xE, 0x8000\n    u8 is_drop : 1;  // 0xE, 0x8000\n    u8 is_ledge : 1; // 0xE, 0x0200\n    u8 is_unk : 1;   // 0xE, 0x8000\n    u8 material;\n};\n\nstruct CollLine\n{\n    CollLineInfo *info;\n    u8 x4;             // 0x4\n    u8 x5_1 : 1;       // 0x5\n    u8 x5_2 : 1;       // 0x5\n    u8 x5_3 : 1;       // 0x5\n    u8 x5_4 : 1;       // 0x5\n    u8 x5_5 : 1;       // 0x5\n    u8 x5_6 : 1;       // 0x5\n    u8 x5_7 : 1;       // 0x5\n    u8 is_enabled : 1; // 0x5\n    u8 x6;             // 0x6\n    u8 x7 : 4;         // 0x7\n    u8 is_rwall : 1;   // 0x7, 0x8\n    u8 is_lwall : 1;   // 0x7, 0x4\n    u8 is_ceil : 1;    // 0x7, 0x2\n    u8 is_floor : 1;   // 0x7, 0x1\n};\n\nstruct CollVert\n{\n    Vec2 pos_orig;\n    Vec2 pos_curr;\n    Vec2 pos_prev;\n};\n\nstruct CollDataStage\n{\n    void *verts;\n    int vert_num;\n    void *lines;\n    int line_num;\n    u16 floor_start;\n    u16 floor_num;\n    u16 ceil_start;\n    u16 ceil_num;\n    u16 rwall_start;\n    u16 rwall_num;\n    u16 lwall_start;\n    u16 lwall_num;\n    u16 dyn_start;\n    u16 dyn_num;\n    void *groups;\n    int group_num;\n};\n\n/*** Functions ***/\nvoid Coll_ECBCurrToPrev(CollData *coll_data);\nvoid Coll_InitECB(CollData *coll_data);\nint ECB_CollGround_PassLedge(CollData *ecb, ECBBones *bones); // returns is touching ground bool\nvoid ECB_CollAir(CollData *ecb, ECBBones *bones);\nvoid GrColl_GetLedgeLeft(int floor_index, Vec3 *pos);                                                                                                                                            // this functon will crawl along the entire line sequence and find the end of the ledge\nvoid GrColl_GetLedgeRight(int floor_index, Vec3 *pos);                                                                                                                                           // this functon will crawl along the entire line sequence and find the end of the ledge\nvoid GrColl_GetLedgeLeft2(int floor_index, Vec3 *pos);                                                                                                                                           // this functon will crawl along the entire line sequence and find the end of the ledge\nvoid GrColl_GetLedgeRight2(int floor_index, Vec3 *pos);                                                                                                                                          // this functon will crawl along the entire line sequence and find the end of the ledge\nint 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\nint 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\nint GrColl_GetPosDifference(int line_index, Vec3 *pos, Vec3 *return_pos);\nint GrColl_GetLineInfo(int line_index, Vec3 *r4, void *r5, int *flags, Vec3 *return_slope);\nvoid GrColl_GetLineSlope(int line_index, Vec3 *return_slope);\nint GrColl_CheckIfLineEnabled(int line_index);\n\nstatic int *stc_colltest = R13 + (COLL_TEST);\nstatic CollGroup **stc_firstcollgroup = R13 + (-0x51DC);\nstatic CollGroup **stc_collgroup = R13 + (-0x51E0);\nstatic CollLine **stc_collline = R13 + (-0x51E4);\nstatic CollVert **stc_collvert = R13 + (-0x51E8);\nstatic CollDataStage **stc_colldata = R13 + (-0x51EC);\n\n#endif\n"
  },
  {
    "path": "MexTK/include/color.h",
    "content": "#ifndef MEX_H_COLOR\n#define MEX_H_COLOR\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n\n/*** Structs ***/\n\nstruct GXColor\n{\n    u8 r;\n    u8 g;\n    u8 b;\n    u8 a;\n};\n\nstruct ColorOverlay\n{\n    int timer;                      // 0x0\n    int pri;                        // 0x4  this colanims priority, lower = will persist\n    int *ptr1;                      // 0x8\n    int loop;                       // 0xc\n    int *ptr2;                      // 0x10\n    int x14;                        // 0x14\n    int *alloc;                     // 0x18\n    int x1c;                        // 0x1c\n    int x20;                        // 0x20\n    int x24;                        // 0x24\n    int colanim;                    // 0x28, id for the color animation in effect\n    GXColor hex;                    // 0x2C\n    float color_red;                // 0x30\n    float color_green;              // 0x34\n    float color_blue;               // 0x38\n    float color_alpha;              // 0x3C\n    float colorblend_red;           // 0x40\n    float colorblend_green;         // 0x44\n    float colorblend_blue;          // 0x48\n    float colorblend_alpha;         // 0x4C\n    GXColor light_color;            //0x50\n    float light_red;                // 0x54\n    float light_green;              // 0x58\n    float light_blue;               // 0x5C\n    float light_alpha;              // 0x60\n    float lightblend_red;           // 0x64\n    float lightblend_green;         // 0x68\n    float lightblend_blue;          // 0x6c\n    float lightblend_alpha;         // 0x70\n    float light_angle;              // 0x74\n    float light_unk;                // 0x78\n    unsigned char color_enable : 1; // 0x7c\n    unsigned char flag2 : 1;        // 0x7c\n    unsigned char light_enable : 1; // 0x7c\n    unsigned char flag4 : 1;        // 0x7c\n    unsigned char flag5 : 1;        // 0x7c\n    unsigned char flag6 : 1;        // 0x7c\n    unsigned char flag7 : 1;        // 0x7c\n    unsigned char flag8 : 1;        // 0x7c\n};\n\n#endif\n"
  },
  {
    "path": "MexTK/include/css.h",
    "content": "#ifndef MEX_H_CSS\n#define MEX_H_CSS\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"fighter.h\"\n#include \"scene.h\"\n\n/*** Structs ***/\nstruct CSSBackup\n{\n    u8 fighter_prev; //0x0\n    u8 x1;           //0x1\n    u8 fighter;      //0x2\n    u8 costume;      //0x3\n    u8 nametag;      //0x4\n    u8 event;        //0x5\n    u8 port;         //0x6\n    u8 x7;           //0x7\n    u8 x8;           //0x8\n    u8 x9;           //0x9\n    u8 xA;           //0xA\n};\n\nstruct MnSelectChrDataTable\n{\n    COBJDesc *cobj;\n    void *lobj1;\n    void *lobj2;\n    void *fog;\n    JOBJAnimSet bg;\n    JOBJAnimSet cursor;\n    JOBJAnimSet puck;\n    JOBJAnimSet vsmenu;\n    JOBJAnimSet start;\n    JOBJAnimSet camdoor;\n    JOBJAnimSet solomenu;\n    JOBJAnimSet solooption;\n    JOBJAnimSet cpudoor;\n};\n\nenum CSSCursorState\n{\n    SLCHRCUR_POINT,\n    SLCHRCUR_HOLD,\n    SLCHRCUR_OPEN,\n    SLCHRCUR_HIDDEN,\n};\nstruct CSSCursor\n{\n    GOBJ *gobj;\n    u8 port;\n    u8 state; // 0x5, 0x0 = Pointing / 0x1 = Holding Puck / 0x2 = Open Hand / 0x3 = Hidden/Unplugged\n    u8 puck;  // 0x6, puck index being held\n    u8 x7;    // 0x7,\n    u16 x8;\n    u16 exit_timer; // 0xa, frames held B\n    Vec2 pos;       // 0xc-0x10\n};\n\nstruct CSSPuck\n{\n    GOBJ *gobj;       // 0x0,\n    u8 port;          // 0x4, port this puck belongs to\n    u8 state;         // 0x5, 0x0 = Pointing / 0x1 = Holding Puck / 0x2 = Open Hand / 0x3 = Hidden/Unplugged\n    u8 held;          // 0x6, port that this puck is being held by\n    u8 anim_timer;    // 0x7, Animation Timer. resets animation when this hits 39, checked for @ 80262790\n    Vec2 pos_proj;    // 0x8, where the puck should be\n    Vec2 pos_correct; // 0x10, where the puck is corrected to\n};\n\nstruct MnSlChrIcon\n{\n    u8 ft_hudindex; // used for getting combo count @ 8025c0c4\n    u8 ft_kind;     // icons external ID\n    u8 state;       // Dictates whether icon can be chosen. 0x0 = Not Unlocked, 0x1 = Unlocked (temp value), 0x2 = Unlocked and Displayed\n    u8 anim_timer;  // is made to be 0xC when the character is chosen.\n    u8 joint_id;    // icon background jobj ID\n    u8 joint2_id;   // used to icons JObj pointer\n    int sfx;        // 0x8,\n    float bound_l;  // 0xC\n    float bound_r;  // 0x10\n    float bound_u;  // 0x14\n    float bound_d;  // 0x18\n};\n\nenum DoorState\n{\n    DOOR_HMN,\n    DOOR_CPU,\n    DOOR_UNK,\n    DOOR_CLOSED,\n};\nstruct MnSlChrDoor\n{\n    u8 x0;\n    u8 csp_joint;\n    u8 x2;\n    u8 joint_id; // 0x3\n    u8 x4;\n    u8 x5; // nametag window joint id\n    u8 x6;\n    u8 cpuslider_joint; // 0x7\n    u8 slider2_joint;   //0x8\n    u8 x9;\n    u8 dooranim_timer; // 0xa\n    u8 state;          // 0x0 = HMN, 0x1 = CPU, 0x3 = Closed\n    u8 xc;\n    u8 costume;  // 0xd\n    u8 sel_icon; // 0xe, icon this player has selected\n    u8 xf;\n    u8 x10;\n    u8 slideranim_timer;\n    u8 x12;\n    u8 x13;\n    float button_l; // HMN button bound\n    float button_t; // HMN button bound\n    float button_u; // HMN button bound\n    float button_d; // HMN button bound\n};\n\nstruct MnSlChrTagData\n{\n    Text *name;\n    Text *namelist;     // 0x4, used when opening the tag window\n    float x8;           // 0x8\n    float scroll_amt;   // xC, Text Y Offset to scroll up each frame\n    float scroll_force; //x10\n    int timer;          // x14, state timer\n    u8 next_tag;        // 0x18, index of next empty tag\n    u8 port;\n    u8 state;   // 0x1a, is nametag window open bool\n    u8 use_tag; // 0x1b, is using a nametag bool\n};\n\nstruct MnSlChrTag\n{\n    MnSlChrTagData *tag_data;\n    u8 x4;\n    u8 list_joint;\n    u8 name_joint;\n    u8 x7;\n    u8 kostartext_joint;\n    u8 x9;\n    u8 xa;\n    u8 xb;\n};\n\nstruct MnSlChrKOStar\n{\n    Text *text;\n    float x4;\n    u8 joint;\n    int xc;\n    int x10;\n    int x14;\n    int x18;\n    int x1c;\n};\n\nstruct MnSlChrData\n{\n    u8 GaWName[0x1C];          // 0x0\n    u8 x1C[0xC0];              // 0x1c\n    MnSlChrIcon icons[25 + 1]; // 0xDC\n    MnSlChrDoor doors[4];      // 0x3b4\n    MnSlChrTag tags[4];        // 0x444\n    u8 x474;                   // 0x474\n    u8 x475;                   // 0x475\n    u8 x476;                   // 0x476\n    u8 x477;                   // 0x477\n    u8 x478;                   // 0x478\n    u8 x479;                   // 0x479\n    u8 x47a;                   // 0x47a\n    u8 x47b;                   // 0x47b\n    u8 x47c;                   // 0x47c\n    u8 x47d;                   // 0x47d\n    u8 x47e;                   // 0x47e\n    u8 x47f;                   // 0x47f\n    u8 x480;                   // 0x480\n    u8 x481;                   // 0x481\n    u8 x482;                   // 0x482\n    u8 x483;                   // 0x483\n    u8 x484[0x40];             // 0x484\n    MnSlChrKOStar ko_stars[4]; // 0x4c4\n};\n\nstruct VSMinorData\n{\n    u16 x0;\n    u8 css_kind;   // 0 = VS\n    u8 exit_kind;  // 1 = advance, 2 = leave\n    void *ko_data; // used for displaying KO stars on CSS\n    ScDataVS vs_data;\n};\n\n/*** Variables ***/\nstatic MnSlChrData *stc_css_data = 0x803f0a48;\nstatic VSMinorData **stc_css_minorscene = R13 + (-0x49F0);\nstatic u8 *stc_css_regtagnum = R13 + (-0x49A8); // number of registered tags\nstatic u8 *stc_css_49b0 = R13 + (-0x49B0);\nstatic u8 *stc_css_49a7 = R13 + (-0x49A7);\nstatic u8 *stc_css_49a8 = R13 + (-0x49A8);\nstatic ArchiveInfo **stc_css_archive = R13 + (-0x49D0);\nstatic ArchiveInfo **stc_css_menuarchive = R13 + (-0x49CC);\nstatic u8 *stc_css_49ac = R13 + (-0x49AC);\nstatic GOBJ **stc_css_menugobj = R13 + (-0x49E4);\nstatic JOBJ **stc_css_menumodel = R13 + (-0x49E0);\nstatic CSSCursor **stc_css_cursors = 0x804a0bc0;\nstatic CSSPuck **stc_css_pucks = 0x804a0bd0;\n\nstatic u8 *stc_css_hmnport = R13 + (-0x49B0);\nstatic u8 *stc_css_cpuport = R13 + (-0x49AF);\nstatic u8 *stc_css_delay = R13 + (-0x49AE);\nstatic u8 *stc_css_maxply = R13 + (-0x49AB);\nstatic u8 *stc_css_singeplyport = R13 + (-0x4DE0);\nstatic u8 *stc_css_49f0 = R13 + (-0x49f0);\nstatic int *stc_css_49c0 = R13 + (-0x49c0);\nstatic int *stc_css_49c4 = R13 + (-0x49c4);\nstatic int *stc_css_49b8 = R13 + (-0x49b8);\nstatic int *stc_css_49bc = R13 + (-0x49bc);\nstatic int *stc_css_bgtimer = R13 + (-0x49b4);\nstatic u8 *stc_css_hasreleasedb = R13 + (-0x49ad);\nstatic u8 *stc_css_exitkind = R13 + (-0x49aa);\nstatic u8 *stc_css_49a9 = R13 + (-0x49a9);\nstatic MnSelectChrDataTable **stc_css_datatable = R13 + (-0x49EC);\nstatic COBJDesc **stc_css_cobjdesc = R13 + (-0x4ADC);\nstatic GOBJ **stc_css_camgobj = R13 + (-0x49E8);\nstatic HSD_Pad *stc_css_pad = 0x804c20bc;\nstatic u8 *stc_css_unkarr = 0x804d50c8;\n\n/*** Functions ***/\nvoid MainMenu_CamRotateThink(GOBJ *gobj);\nint CSS_GetNametagRumble(int player, u8 tag);\nvoid CSS_InitPlayerData(PlayerData *player);\nvoid CSS_CameraRotateThink(GOBJ *gobj);\nvoid CSS_MenuModelThink(GOBJ *gobj);\nvoid CSS_CursorThink(GOBJ *gobj);\nvoid CSS_PuckThink(GOBJ *gobj);\nvoid CSS_TagThink(GOBJ *gobj);\nvoid CSS_UpdateRulesText();\nvoid CSS_UpdateKOStars(int ply, int unk);\nvoid CSS_StartThink(GOBJ *gobj);\nint CSS_GetHandicapValue(int ply, int nametag_id);\nvoid CSS_SetModeTexture(int css_kind);\nint CSS_ReturnPuck(int ply);\nint CSS_SetRandomFighter(int ply, int unk);\nvoid CSS_UpdateCSP(int ply);\nint CSS_GetCostumeNum(int ext_id);\nvoid CSS_PlayFighterName(int ext_id);\nvoid CSS_CostumeChange(int port, int button_down);\nvoid CSS_UpdateCSPTexture(int port, int costume, int is_none);\n#endif\n"
  },
  {
    "path": "MexTK/include/datatypes.h",
    "content": "#ifndef MEX_H_DATATYPES\n#define MEX_H_DATATYPES\n\n#include \"structs.h\"\n#include \"offsets.h\"\n\n// Data types\ntypedef signed char s8;\ntypedef signed short s16;\ntypedef signed int s32;\ntypedef signed long long s64;\ntypedef unsigned char u8;\ntypedef unsigned short u16;\ntypedef unsigned int u32;\ntypedef unsigned long long u64;\ntypedef float f32;\ntypedef double f64;\n\n// PadGet Types\n#define PADGET_MASTER 0\n#define PADGET_ENGINE 1\n\n// Matrix definition\ntypedef float Mtx[3][4];\ntypedef float (*MtxPtr)[4];\n\n// Ghidrish\n#define undefined8 long\n#define undefined4 int\n#define byte char\n#define uint unsigned int\n\n// bool lingo\n#define true 1\n#define false 0\n\n// Other Macros\n#define RTOC_PTR(offset) *(void **)(0x804df9e0 + offset)\n#define R13_PTR(offset) *(void **)(R13 + offset)\n#define R13_INT(offset) *(int *)(R13 + offset)\n#define R13_U8(offset) *(u8 *)(R13 + offset)\n#define R13_FLOAT(offset) *(float *)(R13 + offset)\n#define AS_FLOAT(num) *(float *)&num\n#define AS_INT(num) *(int *)&num\n#define ACCESS_INT(addr) *(int *)(addr)\n#define ACCESS_U8(addr) *(u8 *)(addr)\n#define ACCESS_PTR(addr) *(void **)(addr)\n\n/*** Structs ***/\n\nstruct Vec2\n{\n    float X;\n    float Y;\n};\n\nstruct Vec3\n{\n    float X;\n    float Y;\n    float Z;\n};\n\nstruct Vec4\n{\n    float X;\n    float Y;\n    float Z;\n    float W;\n};\n\n#endif\n"
  },
  {
    "path": "MexTK/include/devtext.h",
    "content": "#ifndef MEX_H_DEVTEXT\n#define MEX_H_DEVTEXT\n\n#include \"structs.h\"\n#include \"color.h\"\n\n/*** Structs ***/\n\nstruct DevText\n{\n    int x0;                   // 0x0\n    int x4;                   // 0x4\n    int x8;                   // 0x8\n    int xc;                   // 0xc\n    GXColor bg_color;         // 0x10\n    int x14;                  // 0x14\n    int x18;                  // 0x18\n    int x1c;                  // 0x1c\n    int x20;                  // 0x20\n    char x24;                 // 0x24\n    char x25;                 // 0x25\n    char show_text : 1;       // 0x26\n    char show_background : 1; // 0x26\n    char show_cursor : 1;     // 0x26\n    char x27;                 // 0x27\n    int x28;                  // 0x28\n    int x2c;                  // 0x2c\n    DevText *next;            // 0x30\n    int x34;                  // 0x34\n    int x38;                  // 0x38\n    int x3c;                  // 0x3c\n    int x40;                  // 0x40\n    int x44;                  // 0x44\n    int x48;                  // 0x48\n    int x4c;                  // 0x4c\n    int x50;                  // 0x50\n    int x54;                  // 0x54\n    int x58;                  // 0x58\n    int x5c;                  // 0x5c\n};\n\n/*** Functions ***/\n\nDevText *DevelopText_CreateDataTable(int unk1, int x, int y, int width, int height, void *alloc);\nvoid DevelopText_Activate(void *unk, DevText *text);\nvoid DevelopText_AddString(DevText *text, ...);\nvoid DevelopText_EraseAllText(DevText *text);\nvoid DevelopText_StoreBGColor(DevText *text, u8 *RGBA);\nvoid DevelopText_HideText(DevText *text);\nvoid DevelopText_HideBG(DevText *text);\nvoid DevelopText_StoreTextScale(DevText *text, float x, float y);\nvoid Develop_DrawSphere(float size, Vec3 *pos1, Vec2 *pos2, GXColor *diffuse, GXColor *ambient);\n\nint *stc_dblevel = R13 + (-0x6C98);\n\n#endif\n"
  },
  {
    "path": "MexTK/include/effects.h",
    "content": "#ifndef MEX_H_EFFECTS\n#define MEX_H_EFFECTS\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"obj.h\"\n\n#define PTCL_LINKMAX 16\n\n/*** Structs ***/\n\nstruct Effect\n{\n    GOBJ *child;\n    GOBJ *gobj;\n    int x8;\n    int xc;\n    void *callback;\n    int x14;\n    int x18;\n    int x1c;\n    float x20;\n    short lifetime;\n    char x26;\n    char x27;\n    char x28;\n    char x29;\n};\n\nstruct Particle\n{\n    int x0;\n    int x4;\n    int x8;\n    int xc;\n    int x10;\n    int x14;\n    int x18;\n    int x1c;\n    int x20;\n    int x24;\n    int x28;\n    int x2c;\n    int x30;\n    int x34;\n    int x38;\n    int x3c;\n    int x40;\n    int x44;\n    int x48;\n    int x4c;\n    int x50;\n    GeneratorAppSRT *param;\n};\n\nstruct ptclGen // allocated at 8039d9c8\n{\n    struct ptclGen *next; // 0x0\n    int kind;             // x4\n    float random;         // x8\n    float xc;             // xc\n    JOBJ *joint;          // x10\n    u16 genlife;          // x14\n    u16 type;             // x16\n    u8 ef_file;           // x18\n    u8 link_no;           // x19, r3 for 8039f05c\n    u8 tex_group;         // x1a\n    u8 x1b;               // x1b\n    u16 instance;         // x1c\n    u16 life;             // x1e\n    void *track;          // x20, pointer to track data\n    Vec3 pos;             // x24\n    Vec3 vel;             // x30\n    float gravity;        // x3c\n    float friction;       // x40\n    float size;           // x44\n    float radius;         // x48\n    float angle;          // x4c\n    int timer;            // x50\n    void *mtx;            // x54, points to an SRT mtx used for transforming the generator while attached to a joint\n};\n\nstruct GeneratorAppSRT // allocated at 803a42b0\n{\n    int x0;     //x0\n    int x4;     //x4\n    int x8;     //x8\n    int xc;     //xc\n    int x10;    //x10\n    int x14;    //x14\n    int x18;    //x18\n    int x1c;    //x1c\n    int x20;    //x20\n    Vec3 scale; //x24\n    int x30;    //x30\n    int x34;    //x34\n    int x38;    //x38\n    int x3c;    //x3c\n    int x40;    //x40\n    int x44;    //x44\n    int x48;    //x48\n    int x4c;    //x4c\n    int x50;    //x50\n    int x54;    //x54\n    int x58;    //x58\n    int x5c;    //x5c\n    int x60;    //x60\n    int x64;    //x64\n    int x68;    //x68\n    int x6c;    //x6c\n    int x70;    //x70\n    int x74;    //x74\n    int x78;    //x78\n    int x7c;    //x7c\n    int x80;    //x80\n    int x84;    //x84\n    int x88;    //x88\n    int x8c;    //x8c\n    int x90;    //x90\n    int x94;    //x94\n    int x98;    //x98\n    int x9c;    //x9c\n    int xa0;    //xa0\n    u16 xa2;\n};\n\nstruct Particle2 // created at 80398c90. dont feel like labelling this, offsets are @ 80398de4\n{\n    struct Particle2 *next; // 0x0\n    u32 kind;               // 0x4\n    u8 bank;                // 0x8\n    u8 texGroup;            // 0x9\n    u8 poseNum;             // 0xa\n    u8 palNum;              // 0xb\n    u16 sizeCount;          // 0xc\n    u16 primColCount;       // 0xe\n    u16 envColCount;        // 0x10\n    u8 primCol[4];          // 0x12\n    u8 envCol[4];           // 0x16\n    u16 cmdWait;            // 0x1a\n    u8 loopCount;           // 0x1c\n    u8 linkNo;              // 0x1d\n    u16 idnum;              // 0x1e\n    void *cmdList;          // 0x20\n    u16 cmdPtr;             // 0x24\n    u16 cmdMarkPtr;         // 0x26\n    u16 cmdLoopPtr;         // 0x28\n    u16 life;               // 0x2a\n    Vec3 v;                 // 0x2C\n    float grav;             // 0x38\n    float fric;             // 0x3C\n    Vec3 pos;               // 0x40\n    float size;             // 0x4C\n    float rotate;           // 0x50\n    u16 aCmpCount;          // 0x54\n    u8 aCmpMode;            // 0x56\n    u8 aCmpParam1;          // 0x57\n    u8 aCmpParam2;          // 0x58\n    void *x5c;\n    void *x60;\n    void *x64;\n    void *x68;\n    void *x6c;\n    void *x70;\n    void *x74;\n    void *x78;\n    void *x7c;\n    void *x80;\n    void *x84;\n    void *x88;\n    void *gen;\n    void *x90;\n    // theres more but i got bored, rest are here courtesy of psilupan: https://pastebin.com/raw/yQdjypW0\n};\n\n/*** Functions ***/\n\nEffect *Effect_SpawnSync(int gfx_id, ...);\nvoid Effect_SpawnAsync(GOBJ *fighter, Effect *ptr, int type, int gfx_id, ...);\nvoid Effect_SpawnFtEffectLookup(GOBJ *gobj, int gfx_id, int bone, int unk, int destroy_on_leave, ...);\nvoid Effect_SpawnItEffectLookup(GOBJ *gobj, int gfx_id, int bone, Vec3 *offset, Vec3 *scatter, int unk3);\nvoid Effect_SpawnItEffect(GOBJ *gobj, int gfx_id);\nvoid Effect_DestroyAll(GOBJ *fighter);\nvoid Particle_DestroyAll(JOBJ *jobj);\nvoid Effect_PauseAll(GOBJ *fighter);\nvoid Effect_ResumeAll(GOBJ *fighter);\nint psRemoveParticleAppSRT(Particle2 *ptcl);\nvoid psDeletePntJObjwithParticle(Particle2 *ptcl);\nptclGen *psKillGenerator(ptclGen *gen, ptclGen *unk);\n\nu16 *stc_ptclnum = R13 + (-0x3DBE);      // number of pctls alive\nParticle2 **stc_ptcl = 0x804d0908;       // last created ptcl\nptclGen **stc_ptclgen = R13 + (-0x3DA4); // last created gen\nptclGen **stc_ptclgencurr = R13 + (-0x3DA8);\nu16 *stc_ptclgennum = R13 + (-0x3DC0);\n\n#endif\n"
  },
  {
    "path": "MexTK/include/fighter.h",
    "content": "#ifndef MEX_H_FIGHTER\n#define MEX_H_FIGHTER\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"obj.h\"\n#include \"color.h\"\n#include \"effects.h\"\n#include \"match.h\"\n#include \"collision.h\"\n\n// action state flags\n#define ASC_PRESERVE_FASTFALL 0x1\n#define ASC_PRESERVE_GFX 0x2\n#define ASC_PRESERVE_EYE 0x80\n#define ASC_1000 0x1000\n#define ASC_SKIP_SCRIPT 0x4000\n#define ASC_PRESERVE_VISIBILITY 0x40000\n#define ASC_80000 0x80000\n#define ASC_400000 0x400000\n#define ASC_4000000 0x4000000\n#define ASC_8000000 0x8000000\n#define ASC_NOANIM 0x20000000\n\nenum FtCommonBone\n{\n    TopN,\n    TransN,\n    XRotN,\n    YRotN,\n    HipN,\n    WaistN,\n    LLegJA,\n    LLegJ,\n    LKneeJ,\n    LFootJA,\n    LFootJ,\n    RLegJA,\n    RLegJ,\n    RKneeJ,\n    RFootJA,\n    RFootJ,\n    WaistN2,\n    BustN,\n    LShoulderN,\n    LShoulderJA,\n    LShoulderJ,\n    LArmJ,\n    LHandN,\n    L1stNa,\n    L1stNb,\n    L2ndNa,\n    L2ndNb,\n    L3rdNa,\n    L3rdNb,\n    L4thNa,\n    L4thNb,\n    LHaveN,\n    LThumbNa,\n    LThumbNb,\n    NeckN,\n    HeadN,\n    RShoulderN,\n    RShoulderJA,\n    RShoulderJ,\n    RArmJ,\n    RHandN,\n    R1stNa,\n    R1stNb,\n    R2ndNa,\n    R2ndNb,\n    R3rdNa,\n    R3rdNb,\n    R4thNa,\n    R4thNb,\n    RHaveN,\n    RThumbNa,\n    RThumbNb,\n    ThrowN,\n    Extra\n};\n\n// Fighter States *to-do, make this an enum\n#define ASID_DEADDOWN 0X00\n#define ASID_DEADLEFT 0X01\n#define ASID_DEADRIGHT 0X02\n#define ASID_DEADUP 0X03\n#define ASID_DEADUPSTAR 0X04\n#define ASID_DEADUPSTARICE 0X05\n#define ASID_DEADUPFALL 0X06\n#define ASID_DEADUPFALLHITCAMERA 0X07\n#define ASID_DEADUPFALLHITCAMERAFLAT 0X08\n#define ASID_DEADUPFALLICE 0X09\n#define ASID_DEADUPFALLHITCAMERAICE 0X0A\n#define ASID_SLEEP 0X0B\n#define ASID_REBIRTH 0X0C\n#define ASID_REBIRTHWAIT 0X0D\n#define ASID_WAIT 0X0E\n#define ASID_WALKSLOW 0X0F\n#define ASID_WALKMIDDLE 0X10\n#define ASID_WALKFAST 0X11\n#define ASID_TURN 0X12\n#define ASID_TURNRUN 0X13\n#define ASID_DASH 0X14\n#define ASID_RUN 0X15\n#define ASID_RUNDIRECT 0X16\n#define ASID_RUNBRAKE 0X17\n#define ASID_KNEEBEND 0X18\n#define ASID_JUMPF 0X19\n#define ASID_JUMPB 0X1A\n#define ASID_JUMPAERIALF 0X1B\n#define ASID_JUMPAERIALB 0X1C\n#define ASID_FALL 0X1D\n#define ASID_FALLF 0X1E\n#define ASID_FALLB 0X1F\n#define ASID_FALLAERIAL 0X20\n#define ASID_FALLAERIALF 0X21\n#define ASID_FALLAERIALB 0X22\n#define ASID_FALLSPECIAL 0X23\n#define ASID_FALLSPECIALF 0X24\n#define ASID_FALLSPECIALB 0X25\n#define ASID_DAMAGEFALL 0X26\n#define ASID_SQUAT 0X27\n#define ASID_SQUATWAIT 0X28\n#define ASID_SQUATRV 0X29\n#define ASID_LANDING 0X2A\n#define ASID_LANDINGFALLSPECIAL 0X2B\n#define ASID_ATTACK11 0X2C\n#define ASID_ATTACK12 0X2D\n#define ASID_ATTACK13 0X2E\n#define ASID_ATTACK100START 0X2F\n#define ASID_ATTACK100LOOP 0X30\n#define ASID_ATTACK100END 0X31\n#define ASID_ATTACKDASH 0X32\n#define ASID_ATTACKS3HI 0X33\n#define ASID_ATTACKS3HIS 0X34\n#define ASID_ATTACKS3S 0X35\n#define ASID_ATTACKS3LWS 0X36\n#define ASID_ATTACKS3LW 0X37\n#define ASID_ATTACKHI3 0X38\n#define ASID_ATTACKLW3 0X39\n#define ASID_ATTACKS4HI 0X3A\n#define ASID_ATTACKS4HIS 0X3B\n#define ASID_ATTACKS4S 0X3C\n#define ASID_ATTACKS4LWS 0X3D\n#define ASID_ATTACKS4LW 0X3E\n#define ASID_ATTACKHI4 0X3F\n#define ASID_ATTACKLW4 0X40\n#define ASID_ATTACKAIRN 0X41\n#define ASID_ATTACKAIRF 0X42\n#define ASID_ATTACKAIRB 0X43\n#define ASID_ATTACKAIRHI 0X44\n#define ASID_ATTACKAIRLW 0X45\n#define ASID_LANDINGAIRN 0X46\n#define ASID_LANDINGAIRF 0X47\n#define ASID_LANDINGAIRB 0X48\n#define ASID_LANDINGAIRHI 0X49\n#define ASID_LANDINGAIRLW 0X4A\n#define ASID_DAMAGEHI1 0X4B\n#define ASID_DAMAGEHI2 0X4C\n#define ASID_DAMAGEHI3 0X4D\n#define ASID_DAMAGEN1 0X4E\n#define ASID_DAMAGEN2 0X4F\n#define ASID_DAMAGEN3 0X50\n#define ASID_DAMAGELW1 0X51\n#define ASID_DAMAGELW2 0X52\n#define ASID_DAMAGELW3 0X53\n#define ASID_DAMAGEAIR1 0X54\n#define ASID_DAMAGEAIR2 0X55\n#define ASID_DAMAGEAIR3 0X56\n#define ASID_DAMAGEFLYHI 0X57\n#define ASID_DAMAGEFLYN 0X58\n#define ASID_DAMAGEFLYLW 0X59\n#define ASID_DAMAGEFLYTOP 0X5A\n#define ASID_DAMAGEFLYROLL 0X5B\n#define ASID_LIGHTGET 0X5C\n#define ASID_HEAVYGET 0X5D\n#define ASID_LIGHTTHROWF 0X5E\n#define ASID_LIGHTTHROWB 0X5F\n#define ASID_LIGHTTHROWHI 0X60\n#define ASID_LIGHTTHROWLW 0X61\n#define ASID_LIGHTTHROWDASH 0X62\n#define ASID_LIGHTTHROWDROP 0X63\n#define ASID_LIGHTTHROWAIRF 0X64\n#define ASID_LIGHTTHROWAIRB 0X65\n#define ASID_LIGHTTHROWAIRHI 0X66\n#define ASID_LIGHTTHROWAIRLW 0X67\n#define ASID_HEAVYTHROWF 0X68\n#define ASID_HEAVYTHROWB 0X69\n#define ASID_HEAVYTHROWHI 0X6A\n#define ASID_HEAVYTHROWLW 0X6B\n#define ASID_LIGHTTHROWF4 0X6C\n#define ASID_LIGHTTHROWB4 0X6D\n#define ASID_LIGHTTHROWHI4 0X6E\n#define ASID_LIGHTTHROWLW4 0X6F\n#define ASID_LIGHTTHROWAIRF4 0X70\n#define ASID_LIGHTTHROWAIRB4 0X71\n#define ASID_LIGHTTHROWAIRHI4 0X72\n#define ASID_LIGHTTHROWAIRLW4 0X73\n#define ASID_HEAVYTHROWF4 0X74\n#define ASID_HEAVYTHROWB4 0X75\n#define ASID_HEAVYTHROWHI4 0X76\n#define ASID_HEAVYTHROWLW4 0X77\n#define ASID_SWORDSWING1 0X78\n#define ASID_SWORDSWING3 0X79\n#define ASID_SWORDSWING4 0X7A\n#define ASID_SWORDSWINGDASH 0X7B\n#define ASID_BATSWING1 0X7C\n#define ASID_BATSWING3 0X7D\n#define ASID_BATSWING4 0X7E\n#define ASID_BATSWINGDASH 0X7F\n#define ASID_PARASOLSWING1 0X80\n#define ASID_PARASOLSWING3 0X81\n#define ASID_PARASOLSWING4 0X82\n#define ASID_PARASOLSWINGDASH 0X83\n#define ASID_HARISENSWING1 0X84\n#define ASID_HARISENSWING3 0X85\n#define ASID_HARISENSWING4 0X86\n#define ASID_HARISENSWINGDASH 0X87\n#define ASID_STARRODSWING1 0X88\n#define ASID_STARRODSWING3 0X89\n#define ASID_STARRODSWING4 0X8A\n#define ASID_STARRODSWINGDASH 0X8B\n#define ASID_LIPSTICKSWING1 0X8C\n#define ASID_LIPSTICKSWING3 0X8D\n#define ASID_LIPSTICKSWING4 0X8E\n#define ASID_LIPSTICKSWINGDASH 0X8F\n#define ASID_ITEMPARASOLOPEN 0X90\n#define ASID_ITEMPARASOLFALL 0X91\n#define ASID_ITEMPARASOLFALLSPECIAL 0X92\n#define ASID_ITEMPARASOLDAMAGEFALL 0X93\n#define ASID_LGUNSHOOT 0X94\n#define ASID_LGUNSHOOTAIR 0X95\n#define ASID_LGUNSHOOTEMPTY 0X96\n#define ASID_LGUNSHOOTAIREMPTY 0X97\n#define ASID_FIREFLOWERSHOOT 0X98\n#define ASID_FIREFLOWERSHOOTAIR 0X99\n#define ASID_ITEMSCREW 0X9A\n#define ASID_ITEMSCREWAIR 0X9B\n#define ASID_DAMAGESCREW 0X9C\n#define ASID_DAMAGESCREWAIR 0X9D\n#define ASID_ITEMSCOPESTART 0X9E\n#define ASID_ITEMSCOPERAPID 0X9F\n#define ASID_ITEMSCOPEFIRE 0XA0\n#define ASID_ITEMSCOPEEND 0XA1\n#define ASID_ITEMSCOPEAIRSTART 0XA2\n#define ASID_ITEMSCOPEAIRRAPID 0XA3\n#define ASID_ITEMSCOPEAIRFIRE 0XA4\n#define ASID_ITEMSCOPEAIREND 0XA5\n#define ASID_ITEMSCOPESTARTEMPTY 0XA6\n#define ASID_ITEMSCOPERAPIDEMPTY 0XA7\n#define ASID_ITEMSCOPEFIREEMPTY 0XA8\n#define ASID_ITEMSCOPEENDEMPTY 0XA9\n#define ASID_ITEMSCOPEAIRSTARTEMPTY 0XAA\n#define ASID_ITEMSCOPEAIRRAPIDEMPTY 0XAB\n#define ASID_ITEMSCOPEAIRFIREEMPTY 0XAC\n#define ASID_ITEMSCOPEAIRENDEMPTY 0XAD\n#define ASID_LIFTWAIT 0XAE\n#define ASID_LIFTWALK1 0XAF\n#define ASID_LIFTWALK2 0XB0\n#define ASID_LIFTTURN 0XB1\n#define ASID_GUARDON 0XB2\n#define ASID_GUARD 0XB3\n#define ASID_GUARDOFF 0XB4\n#define ASID_GUARDSETOFF 0XB5\n#define ASID_GUARDREFLECT 0XB6\n#define ASID_DOWNBOUNDU 0XB7\n#define ASID_DOWNWAITU 0XB8\n#define ASID_DOWNDAMAGEU 0XB9\n#define ASID_DOWNSTANDU 0XBA\n#define ASID_DOWNATTACKU 0XBB\n#define ASID_DOWNFOWARDU 0XBC\n#define ASID_DOWNBACKU 0XBD\n#define ASID_DOWNSPOTU 0XBE\n#define ASID_DOWNBOUNDD 0XBF\n#define ASID_DOWNWAITD 0XC0\n#define ASID_DOWNDAMAGED 0XC1\n#define ASID_DOWNSTANDD 0XC2\n#define ASID_DOWNATTACKD 0XC3\n#define ASID_DOWNFOWARDD 0XC4\n#define ASID_DOWNBACKD 0XC5\n#define ASID_DOWNSPOTD 0XC6\n#define ASID_PASSIVE 0XC7\n#define ASID_PASSIVESTANDF 0XC8\n#define ASID_PASSIVESTANDB 0XC9\n#define ASID_PASSIVEWALL 0XCA\n#define ASID_PASSIVEWALLJUMP 0XCB\n#define ASID_PASSIVECEIL 0XCC\n#define ASID_SHIELDBREAKFLY 0XCD\n#define ASID_SHIELDBREAKFALL 0XCE\n#define ASID_SHIELDBREAKDOWNU 0XCF\n#define ASID_SHIELDBREAKDOWND 0XD0\n#define ASID_SHIELDBREAKSTANDU 0XD1\n#define ASID_SHIELDBREAKSTANDD 0XD2\n#define ASID_FURAFURA 0XD3\n#define ASID_CATCH 0XD4\n#define ASID_CATCHPULL 0XD5\n#define ASID_CATCHDASH 0XD6\n#define ASID_CATCHDASHPULL 0XD7\n#define ASID_CATCHWAIT 0XD8\n#define ASID_CATCHATTACK 0XD9\n#define ASID_CATCHCUT 0XDA\n#define ASID_THROWF 0XDB\n#define ASID_THROWB 0XDC\n#define ASID_THROWHI 0XDD\n#define ASID_THROWLW 0XDE\n#define ASID_CAPTUREPULLEDHI 0XDF\n#define ASID_CAPTUREWAITHI 0XE0\n#define ASID_CAPTUREDAMAGEHI 0XE1\n#define ASID_CAPTUREPULLEDLW 0XE2\n#define ASID_CAPTUREWAITLW 0XE3\n#define ASID_CAPTUREDAMAGELW 0XE4\n#define ASID_CAPTURECUT 0XE5\n#define ASID_CAPTUREJUMP 0XE6\n#define ASID_CAPTURENECK 0XE7\n#define ASID_CAPTUREFOOT 0XE8\n#define ASID_ESCAPEF 0XE9\n#define ASID_ESCAPEB 0XEA\n#define ASID_ESCAPE 0XEB\n#define ASID_ESCAPEAIR 0XEC\n#define ASID_REBOUNDSTOP 0XED\n#define ASID_REBOUND 0XEE\n#define ASID_THROWNF 0XEF\n#define ASID_THROWNB 0XF0\n#define ASID_THROWNHI 0XF1\n#define ASID_THROWNLW 0XF2\n#define ASID_THROWNLWWOMEN 0XF3\n#define ASID_PASS 0XF4\n#define ASID_OTTOTTO 0XF5\n#define ASID_OTTOTTOWAIT 0XF6\n#define ASID_FLYREFLECTWALL 0XF7\n#define ASID_FLYREFLECTCEIL 0XF8\n#define ASID_STOPWALL 0XF9\n#define ASID_STOPCEIL 0XFA\n#define ASID_MISSFOOT 0XFB\n#define ASID_CLIFFCATCH 0XFC\n#define ASID_CLIFFWAIT 0XFD\n#define ASID_CLIFFCLIMBSLOW 0XFE\n#define ASID_CLIFFCLIMBQUICK 0XFF\n#define ASID_CLIFFATTACKSLOW 0X100\n#define ASID_CLIFFATTACKQUICK 0X101\n#define ASID_CLIFFESCAPESLOW 0X102\n#define ASID_CLIFFESCAPEQUICK 0X103\n#define ASID_CLIFFJUMPSLOW1 0X104\n#define ASID_CLIFFJUMPSLOW2 0X105\n#define ASID_CLIFFJUMPQUICK1 0X106\n#define ASID_CLIFFJUMPQUICK2 0X107\n#define ASID_APPEALR 0X108\n#define ASID_APPEALL 0X109\n#define ASID_SHOULDEREDWAIT 0X10A\n#define ASID_SHOULDEREDWALKSLOW 0X10B\n#define ASID_SHOULDEREDWALKMIDDLE 0X10C\n#define ASID_SHOULDEREDWALKFAST 0X10D\n#define ASID_SHOULDEREDTURN 0X10E\n#define ASID_THROWNFF 0X10F\n#define ASID_THROWNFB 0X110\n#define ASID_THROWNFHI 0X111\n#define ASID_THROWNFLW 0X112\n#define ASID_CAPTURECAPTAIN 0X113\n#define ASID_CAPTUREYOSHI 0X114\n#define ASID_YOSHIEGG 0X115\n#define ASID_CAPTUREKOOPA 0X116\n#define ASID_CAPTUREDAMAGEKOOPA 0X117\n#define ASID_CAPTUREWAITKOOPA 0X118\n#define ASID_THROWNKOOPAF 0X119\n#define ASID_THROWNKOOPAB 0X11A\n#define ASID_CAPTUREKOOPAAIR 0X11B\n#define ASID_CAPTUREDAMAGEKOOPAAIR 0X11C\n#define ASID_CAPTUREWAITKOOPAAIR 0X11D\n#define ASID_THROWNKOOPAAIRF 0X11E\n#define ASID_THROWNKOOPAAIRB 0X11F\n#define ASID_CAPTUREKIRBY 0X120\n#define ASID_CAPTUREWAITKIRBY 0X121\n#define ASID_THROWNKIRBYSTAR 0X122\n#define ASID_THROWNCOPYSTAR 0X123\n#define ASID_THROWNKIRBY 0X124\n#define ASID_BARRELWAIT 0X125\n#define ASID_BURY 0X126\n#define ASID_BURYWAIT 0X127\n#define ASID_BURYJUMP 0X128\n#define ASID_DAMAGESONG 0X129\n#define ASID_DAMAGESONGWAIT 0X12A\n#define ASID_DAMAGESONGRV 0X12B\n#define ASID_DAMAGEBIND 0X12C\n#define ASID_CAPTUREMEWTWO 0X12D\n#define ASID_CAPTUREMEWTWOAIR 0X12E\n#define ASID_THROWNMEWTWO 0X12F\n#define ASID_THROWNMEWTWOAIR 0X130\n#define ASID_WARPSTARJUMP 0X131\n#define ASID_WARPSTARFALL 0X132\n#define ASID_HAMMERWAIT 0X133\n#define ASID_HAMMERWALK 0X134\n#define ASID_HAMMERTURN 0X135\n#define ASID_HAMMERKNEEBEND 0X136\n#define ASID_HAMMERFALL 0X137\n#define ASID_HAMMERJUMP 0X138\n#define ASID_HAMMERLANDING 0X139\n#define ASID_KINOKOGIANTSTART 0X13A\n#define ASID_KINOKOGIANTSTARTAIR 0X13B\n#define ASID_KINOKOGIANTEND 0X13C\n#define ASID_KINOKOGIANTENDAIR 0X13D\n#define ASID_KINOKOSMALLSTART 0X13E\n#define ASID_KINOKOSMALLSTARTAIR 0X13F\n#define ASID_KINOKOSMALLEND 0X140\n#define ASID_KINOKOSMALLENDAIR 0X141\n#define ASID_ENTRY 0X142\n#define ASID_ENTRYSTART 0X143\n#define ASID_ENTRYEND 0X144\n#define ASID_DAMAGEICE 0X145\n#define ASID_DAMAGEICEJUMP 0X146\n#define ASID_CAPTUREMASTERHAND 0X147\n#define ASID_CAPTUREDAMAGEMASTERHAND 0X148\n#define ASID_CAPTUREWAITMASTERHAND 0X149\n#define ASID_THROWNMASTERHAND 0X14A\n#define ASID_CAPTUREKIRBYYOSHI 0X14B\n#define ASID_KIRBYYOSHIEGG 0X14C\n#define ASID_CAPTURELEADEAD 0X14D\n#define ASID_CAPTURELIKELIKE 0X14E\n#define ASID_DOWNREFLECT 0X14F\n#define ASID_CAPTURECRAZYHAND 0X150\n#define ASID_CAPTUREDAMAGECRAZYHAND 0X151\n#define ASID_CAPTUREWAITCRAZYHAND 0X152\n#define ASID_THROWNCRAZYHAND 0X153\n#define ASID_BARRELCANNONWAIT 0X154\n#define ASID_ACTIONABLE 1000\n#define ASID_ACTIONABLEGROUND 1001\n#define ASID_ACTIONABLEAIR 1002\n#define ASID_DAMAGEAIR 1003\n#define ASID_JUMPS 1004\n#define ASID_FALLS 1005\n\nenum Ft_AttackKind\n{\n    ATKKIND_0,\n    ATKKIND_NONE,\n    ATKKIND_JAB1,\n    ATKKIND_JAB2,\n    ATKKIND_JAB3,\n    ATKKIND_JAB4,\n    ATKKIND_DASH,\n    ATKKIND_FTILT,\n    ATKKIND_UTILT,\n    ATKKIND_DTILT,\n    ATKKIND_FSMASH,\n    ATKKIND_USMASH,\n    ATKKIND_DSMASH,\n    ATKKIND_NAIR,\n    ATKKIND_FAIR,\n    ATKKIND_BAIR,\n    ATKKIND_UAIR,\n    ATKKIND_DAIR,\n    ATKKIND_SPECIALN,\n    ATKKIND_SPECIALS,\n    ATKKIND_SPECIALHI,\n    ATKKIND_SPECIALLW,\n};\n\n/*** Structs ***/\n\nstruct Playerblock\n{\n    int state;           // 0x00 = not present, 0x02 = HMN, 0x03 = CPU\n    int ft_kind;         // external ID\n    int type;            // (0x00 is HMN, 0x01 is CPU, 0x02 is Demo, 0x03 n/a)\n    u8 isTransformed[2]; // 0xC, 1 indicates the fighter that is active\n    Vec3 tagPos;         // 0x10\n    Vec3 spawnPos;       // 0x1C\n    Vec3 respawnPos;     // 0x28\n    int x34;\n    int x38;\n    int x3C;\n    float initialFacing; // 0x40\n    u8 costume;          // 0x44\n    u8 x45;              // 0x45\n    u8 tint;             // 0x46\n    u8 team;             // 0x47\n    u8 controller;       // 0x48\n    u8 cpuLv;\n    u8 cpuKind;\n    u8 handicap;\n    float x50;\n    float attack;\n    float defense;\n    float scale;\n    u16 damage;\n    u16 initialDamage;\n    u16 stamina;\n    int falls[2];\n    int ko[6];\n    int x88;\n    u16 selfDestructs;\n    u8 stocks;\n    int coins_curr;\n    int coins_total;\n    int x98;\n    int x9c;\n    int stickSmashes[2];\n    int tag;\n    u8 flags2;\n    u8 flags3;\n    GOBJ *fighterData;\n    GOBJ *fighterDataSub;\n};\n\nstruct PlayerData\n{\n    // byte 0x0\n    u8 kind;\n    u8 status;\n    u8 stocks;\n    u8 costume;\n    // 0x4\n    u8 portNumberOverride;\n    u8 spawnPointOverride;\n    u8 facingDirection;\n    u8 subcolor;\n    // 0x8\n    u8 handicap;\n    u8 team;\n    u8 nametag;\n    u8 xb;\n    // 0xC\n    unsigned char isRumble : 1;\n    unsigned char isEntry : 1;\n    unsigned char unk2 : 6;\n    unsigned char unk3 : 8;\n    u8 cpuKind;\n    u8 cpuLevel; // 0xf\n    // 0x10\n    u16 damageStart;\n    u16 damageSpawn;\n    u16 staminaStart; // 0x14\n    float attack;     // 0x18\n    float defense;    // 0x1C\n    float scale;      // 0x20\n};\n\nstruct FighterBone\n{\n    JOBJ *joint;\n    JOBJ *joint2; // used for interpolation\n    int flags;\n    int flags2;\n};\n\nstruct DynamicsDesc\n{\n    int root_bone; // bone index;\n    void *params;  // dynamics params;\n    int num;       // number of children bones to make dynamic\n    float xc;\n    float x10;\n    float x14;\n};\n\nstruct DynamicsHitDesc\n{\n    int bone; // bone index\n    int x4;   // unk\n    Vec3 x8;  // unk\n};\n\nstruct DynamicsBehave\n{\n    int num; // number of dynamic bones to animate in the boneset\n};\n\nstruct ftDynamics\n{\n    int dynamics_num;                   // number of dynamic bonesets for this fighter\n    DynamicsDesc *dynamics_desc;        // boneset data array (one for each boneset)\n    int dynamics_hit_num;               // (no collide bubbles), max is 11\n    DynamicsHitDesc *dynamics_hit_desc; // dynamic hit data array (one for each dynamic hit)\n    DynamicsBehave **dynamics_behave;   // pointer to an array of dynamics behavior pointers.\n};\n\nstruct ftData\n{\n    char footBoneL;\n    char footBoneR;\n    int *charAttributes; // 0x4\n    u8 *modelLookup;     // 0x8\n    int animFlags;       // 0xC\n    int animDynamics;    // 0x10\n    int x14;\n    int x18;\n    int x1C;\n    int x20;\n    int x24;\n    int x28;\n    ftDynamics *dynamics; // 0x2C\n    int hurtbox;\n    int *center_bubble;\n    int x38;\n    int x3C;\n    int x40;\n    int coll;\n    void *items;\n    int *x4C;\n    int x50;\n    int x54;\n    int *boneLookup;\n};\n\nstruct ftChkDevice // 80459a68\n{\n    int x0;\n    int x4;\n    int x8;\n    int xc;\n    int x10;\n    int x14;\n    int x18;\n    int x1c;\n    int x20;\n    GOBJ *gobj;\n    int hazard_kind;\n    void *check;\n};\n\nstruct SubactionHeader\n{\n    char *symbol;\n    int animOffset;\n    int animSize;\n    int *subactionData;\n    int flags;\n};\n\nstruct MoveLogic\n{\n    int animation_id;\n    int flags;\n    char move_id;\n    char bitflags1;\n    void *animation_callback;\n    void *iasa_callback;\n    void *physics_callback;\n    void *collision_callback;\n    void *camera_callback;\n};\n\nstruct ReflectDesc\n{\n    int bone;\n    int max_damage;\n    Vec3 pos;\n    float radius;\n    float damage_mult;\n    float velocity_mult;\n    int flags;\n};\n\nstruct ShieldDesc\n{\n    int bone;\n    int max_damage;\n    Vec3 pos;\n    float radius;\n    float damage_mult;\n    float velocity_mult;\n    int flags;\n};\n\nstruct AbsorbDesc\n{\n    int bone;\n    int max_damage;\n    Vec3 pos;\n    float radius;\n    float damage_mult;\n    float velocity_mult;\n    int flags;\n};\n\nstruct HitVictim\n{\n    void *victim_data; // the gobj that was hit\n    int unk;           // not sure, is set to 0 when hitting them\n};\n\nstruct ftHit\n{\n    int active;                   // 0x0\n    int x4;                       // 0x4\n    int dmg;                      // 0x8\n    float dmg_f;                  // 0xc\n    Vec3 offset;                  // 0x10\n    float size;                   // 0x1c\n    int angle;                    // 0x20\n    int kb_growth;                // 0x24\n    int wdsk;                     // 0x28\n    int kb;                       // 0x2c\n    int attribute;                // 0x30\n    int shield_dmg;               // 0x34\n    int hitsound_severity;        // 0x38. hurtbox interaction. 0 = none, 1 = grounded, 2 = aerial, 3 = both\n    int hitsound_kind;            // 0x3c\n    char x40;                     // 0x40\n    char x41;                     // 0x41\n    unsigned char x421 : 1;       // 0x42 0x80\n    unsigned char x422 : 1;       // 0x42 0x40\n    unsigned char x423 : 1;       // 0x42 0x20\n    unsigned char x424 : 1;       // 0x42 0x10\n    unsigned char no_hurt : 1;    // 0x42 0x08      ignore hurtbox\n    unsigned char no_reflect : 1; // 0x42 0x04      ignore reflect?\n    unsigned char x427 : 1;       // 0x42 0x02\n    unsigned char x428 : 1;       // 0x42 0x01\n    unsigned char x431 : 1;       // 0x43 0x80\n    unsigned char x432 : 1;       // 0x43 0x40\n    unsigned char hit_all : 1;    // 0x43 0x20\n    unsigned char x434 : 1;       // 0x43 0x10\n    unsigned char x435 : 1;       // 0x43 0x08\n    unsigned char x436 : 1;       // 0x43 0x04\n    unsigned char x437 : 1;       // 0x43 0x02\n    unsigned char x438 : 1;       // 0x43 0x01\n    int x44;                      // 0x44\n    JOBJ *bone;                   // 0x48\n    Vec3 pos;                     // 0x4c\n    Vec3 pos_prev;                // 0x58\n    Vec3 pos_coll;                // 0x64   position of hurt collision\n    float coll_distance;          // 0x70   Distance From Collding FtHurt (Used for phantom hit collision calculation)\n    HitVictim victims[24];        // 0x74\n    int x134;                     // 0x134, flags of some sort\n};\n\nstruct FtHurt\n{\n    int x0;                       // 0x0\n    Vec3 hurt1_offset;            // 0x4\n    Vec3 hurt2_offset;            // 0x10\n    float scale;                  // 0x1c\n    JOBJ *jobj;                   // 0x20\n    unsigned char is_updated : 1; // 0x24, if enabled, wont update position\n    unsigned char x24_2 : 1;      // 0x24 0x40\n    unsigned char x24_3 : 1;      // 0x24 0x20\n    unsigned char x24_4 : 1;      // 0x24 0x10\n    unsigned char x24_5 : 1;      // 0x24 0x08\n    unsigned char x24_6 : 1;      // 0x24 0x04\n    unsigned char x24_7 : 1;      // 0x24 0x02\n    unsigned char x24_8 : 1;      // 0x24 0x01\n    Vec3 hurt1_pos;               // 0x28\n    Vec3 hurt2_pos;               // 0x34\n    int bone_index;               // 0x40\n    int hurt_kind;                // 0x44. 0 = low, 1 = mid, 2 = high\n    int is_grabbable;             // 0x48\n};\n\nstruct FtDynamicBoneset\n{\n    int apply_phys_num; // if this is 256, dyanmics are not processed\n    void *unk_ptr;      // is stored @ 8000fdd4, comes from a nonstandard heap @ -0x52fc(r13)\n    int bone_num;       // number of bones in this boneset\n    float xc;           // stored @ 80011718, 0x8 of dynamicdesc\n    float x10;          // stored @ 80011720, 0xC of dynamicdesc\n    float x14;          // stored @ 80011728, 0x10 of dynamicdesc\n};\n\nstruct FtDynamicRoot\n{\n    JOBJ *jobj;          // 0x0\n    Vec4 rot;            // 0x4 quaternion\n    Vec3 trans;          // 0x14\n    Vec3 scale;          // 0x20\n    Vec3 rot_global;     // 0x2C, copied from 0x50, 0x60, 0x70 of jobj\n    float x38;           // 0x38, initialized to 1 @ 8000ff30\n    float x3c;           // 0x3c, initialized to 0 @ 8000ff34\n    float x40;           // 0x40, initialized to 0 @ 8000ff38\n    float x44;           // 0x44, initialized to 0 @ 8000ff3c\n    float x48;           // x48, initialized to 0 @ 8000ff44\n    float x4c;           // x4c, THIS IS THE START OF A STRUCTURE, bunch of floats from the dynamicdesc. stored @ 80011744\n    float x50;           // 0x3c\n    float x54;           // 0x40\n    float x58;           // 0x44\n    float x5c;           // x048\n    float x60;           // 0x38\n    float x64;           // 0x3c\n    float x68;           // 0x40\n    float x6c;           // 0x44\n    float x70;           // x048\n    float x74;           // 0x38\n    float x78;           // 0x3c\n    float x7c;           // 0x40\n    float x80;           // 0x44\n    float x84;           // x048\n    float x88;           // 0x38\n    float x8c;           // 0x3c\n    FtDynamicRoot *next; // 0x90\n    float x94;           // 0x44\n};\n\nstruct FtDynamicHit\n{\n    int x0;         // 0x1670\n    Vec3 x4;        // 0x1674\n    JOBJ *bone;     // 0x1680\n    int x14;        // 0x1684\n    Vec3 pos;       // 0x1688\n    int bone_index; // 0x1694\n};\n\nstruct FtAfterImageKey\n{\n    Vec3 pos;\n    Vec3 rot;\n} FtAfterImageKey;\n\nstruct CPU\n{\n    int held;       // 0x0\n    s8 lstickX;     // 0x4\n    s8 lstickY;     // 0x5\n    s8 cstickX;     // 0x6\n    s8 cstickY;     // 0x7\n    int x8;         // 0x8\n    int ai;         // 0xc\n    int level;      // 0x10\n    int x14;        // 0x14\n    int x18;        // 0x18\n    int x1c;        // 0x1c\n    int x20;        // 0x20\n    int x24;        // 0x24\n    int x28;        // 0x28\n    int x2c;        // 0x2c\n    int x30;        // 0x30\n    int x34;        // 0x34\n    int x38;        // 0x38\n    int x3c;        // 0x3c\n    int x40;        // 0x40\n    int x44;        // 0x44\n    int x48;        // 0x48\n    int x4c;        // 0x4c\n    int x50;        // 0x50\n    int x54;        // 0x54\n    int x58;        // 0x58\n    int x5c;        // 0x5c\n    int x60;        // 0x60\n    int x64;        // 0x64\n    int x68;        // 0x68\n    int x6c;        // 0x6c\n    int x70;        // 0x70\n    int x74;        // 0x74\n    int x78;        // 0x78\n    int x7c;        // 0x7c\n    int x80;        // 0x80\n    int x84;        // 0x84\n    int x88;        // 0x88\n    int x8c;        // 0x8c\n    int x90;        // 0x90\n    int x94;        // 0x94\n    int x98;        // 0x98\n    int x9c;        // 0x9c\n    int xa0;        // 0xa0\n    int xa4;        // 0xa4\n    int xa8;        // 0xa8\n    int xac;        // 0xac\n    int xb0;        // 0xb0\n    int xb4;        // 0xb4\n    int xb8;        // 0xb8\n    int xbc;        // 0xbc\n    int xc0;        // 0xc0\n    int xc4;        // 0xc4\n    int xc8;        // 0xc8\n    int xcc;        // 0xcc\n    int xd0;        // 0xd0\n    int xd4;        // 0xd4\n    int xd8;        // 0xd8\n    int xdc;        // 0xdc\n    int xe0;        // 0xe0\n    int xe4;        // 0xe4\n    int xe8;        // 0xe8\n    int xec;        // 0xec\n    int xf0;        // 0xf0\n    int xf4;        // 0xf4\n    int xf8;        // 0xf8\n    int xfc;        // 0xfc\n    int x100;       // 0x100\n    int x104;       // 0x104\n    int x108;       // 0x108\n    int x10c;       // 0x10c\n    int x110;       // 0x110\n    int x114;       // 0x114\n    int x118;       // 0x118\n    int x11c;       // 0x11c\n    int x120;       // 0x120\n    int x124;       // 0x124\n    int x128;       // 0x128\n    int x12c;       // 0x12c\n    int x130;       // 0x130\n    int x134;       // 0x134\n    int x138;       // 0x138\n    int x13c;       // 0x13c\n    int x140;       // 0x140\n    int x144;       // 0x144\n    int x148;       // 0x148\n    int x14c;       // 0x14c\n    int x150;       // 0x150\n    int x154;       // 0x154\n    int x158;       // 0x158\n    int x15c;       // 0x15c\n    int x160;       // 0x160\n    int x164;       // 0x164\n    int x168;       // 0x168\n    int x16c;       // 0x16c\n    int x170;       // 0x170\n    int x174;       // 0x174\n    int x178;       // 0x178\n    int x17c;       // 0x17c\n    int x180;       // 0x180\n    int x184;       // 0x184\n    int x188;       // 0x188\n    int x18c;       // 0x18c\n    int x190;       // 0x190\n    int x194;       // 0x194\n    int x198;       // 0x198\n    int x19c;       // 0x19c\n    int x1a0;       // 0x1a0\n    int x1a4;       // 0x1a4\n    int x1a8;       // 0x1a8\n    int x1ac;       // 0x1ac\n    int x1b0;       // 0x1b0\n    int x1b4;       // 0x1b4\n    int x1b8;       // 0x1b8\n    int x1bc;       // 0x1bc\n    int x1c0;       // 0x1c0\n    int x1c4;       // 0x1c4\n    int x1c8;       // 0x1c8\n    int x1cc;       // 0x1cc\n    int x1d0;       // 0x1d0\n    int x1d4;       // 0x1d4\n    int x1d8;       // 0x1d8\n    int x1dc;       // 0x1dc\n    int x1e0;       // 0x1e0\n    int x1e4;       // 0x1e4\n    int x1e8;       // 0x1e8\n    int x1ec;       // 0x1ec\n    int x1f0;       // 0x1f0\n    int x1f4;       // 0x1f4\n    int x1f8;       // 0x1f8\n    int x1fc;       // 0x1fc\n    int x200;       // 0x200\n    int x204;       // 0x204\n    int x208;       // 0x208\n    int x20c;       // 0x20c\n    int x210;       // 0x210\n    int x214;       // 0x214\n    int x218;       // 0x218\n    int x21c;       // 0x21c\n    int x220;       // 0x220\n    int x224;       // 0x224\n    int x228;       // 0x228\n    int x22c;       // 0x22c\n    int x230;       // 0x230\n    int x234;       // 0x234\n    int x238;       // 0x238\n    int x23c;       // 0x23c\n    int x240;       // 0x240\n    int x244;       // 0x244\n    int x248;       // 0x248\n    int x24c;       // 0x24c\n    int x250;       // 0x250\n    int x254;       // 0x254\n    int x258;       // 0x258\n    int x25c;       // 0x25c\n    int x260;       // 0x260\n    int x264;       // 0x264\n    int x268;       // 0x268\n    int x26c;       // 0x26c\n    int x270;       // 0x270\n    int x274;       // 0x274\n    int x278;       // 0x278\n    int x27c;       // 0x27c\n    int x280;       // 0x280\n    int x284;       // 0x284\n    int x288;       // 0x288\n    int x28c;       // 0x28c\n    int x290;       // 0x290\n    int x294;       // 0x294\n    int x298;       // 0x298\n    int x29c;       // 0x29c\n    int x2a0;       // 0x2a0\n    int x2a4;       // 0x2a4\n    int x2a8;       // 0x2a8\n    int x2ac;       // 0x2ac\n    int x2b0;       // 0x2b0\n    int x2b4;       // 0x2b4\n    int x2b8;       // 0x2b8\n    int x2bc;       // 0x2bc\n    int x2c0;       // 0x2c0\n    int x2c4;       // 0x2c4\n    int x2c8;       // 0x2c8\n    int x2cc;       // 0x2cc\n    int x2d0;       // 0x2d0\n    int x2d4;       // 0x2d4\n    int x2d8;       // 0x2d8\n    int x2dc;       // 0x2dc\n    int x2e0;       // 0x2e0\n    int x2e4;       // 0x2e4\n    int x2e8;       // 0x2e8\n    int x2ec;       // 0x2ec\n    int x2f0;       // 0x2f0\n    int x2f4;       // 0x2f4\n    int x2f8;       // 0x2f8\n    int x2fc;       // 0x2fc\n    int x300;       // 0x300\n    int x304;       // 0x304\n    int x308;       // 0x308\n    int x30c;       // 0x30c\n    int x310;       // 0x310\n    int x314;       // 0x314\n    int x318;       // 0x318\n    int x31c;       // 0x31c\n    int x320;       // 0x320\n    int x324;       // 0x324\n    int x328;       // 0x328\n    int x32c;       // 0x32c\n    int x330;       // 0x330\n    int x334;       // 0x334\n    int x338;       // 0x338\n    int x33c;       // 0x33c\n    int x340;       // 0x340\n    int x344;       // 0x344\n    int x348;       // 0x348\n    int x34c;       // 0x34c\n    int x350;       // 0x350\n    int x354;       // 0x354\n    int x358;       // 0x358\n    int x35c;       // 0x35c\n    int x360;       // 0x360\n    int x364;       // 0x364\n    int x368;       // 0x368\n    int x36c;       // 0x36c\n    int x370;       // 0x370\n    int x374;       // 0x374\n    int x378;       // 0x378\n    int x37c;       // 0x37c\n    int x380;       // 0x380\n    int x384;       // 0x384\n    int x388;       // 0x388\n    int x38c;       // 0x38c\n    int x390;       // 0x390\n    int x394;       // 0x394\n    int x398;       // 0x398\n    int x39c;       // 0x39c\n    int x3a0;       // 0x3a0\n    int x3a4;       // 0x3a4\n    int x3a8;       // 0x3a8\n    int x3ac;       // 0x3ac\n    int x3b0;       // 0x3b0\n    int x3b4;       // 0x3b4\n    int x3b8;       // 0x3b8\n    int x3bc;       // 0x3bc\n    int x3c0;       // 0x3c0\n    int x3c4;       // 0x3c4\n    int x3c8;       // 0x3c8\n    int x3cc;       // 0x3cc\n    int x3d0;       // 0x3d0\n    int x3d4;       // 0x3d4\n    int x3d8;       // 0x3d8\n    int x3dc;       // 0x3dc\n    int x3e0;       // 0x3e0\n    int x3e4;       // 0x3e4\n    int x3e8;       // 0x3e8\n    int x3ec;       // 0x3ec\n    int x3f0;       // 0x3f0\n    int x3f4;       // 0x3f4\n    int x3f8;       // 0x3f8\n    int x3fc;       // 0x3fc\n    int x400;       // 0x400\n    int x404;       // 0x404\n    int x408;       // 0x408\n    int x40c;       // 0x40c\n    int x410;       // 0x410\n    int x414;       // 0x414\n    int x418;       // 0x418\n    int x41c;       // 0x41c\n    int x420;       // 0x420\n    int x424;       // 0x424\n    int x428;       // 0x428\n    int x42c;       // 0x42c\n    int x430;       // 0x430\n    int x434;       // 0x434\n    int x438;       // 0x438\n    int x43c;       // 0x43c\n    int x440;       // 0x440\n    int *curr_unk;  // 0x444\n    int *curr_unk2; // 0x448\n    int x44c;       // 0x44c\n    int x450;       // 0x450\n    int x454;       // 0x454\n    int x458;       // 0x458\n    int x45c;       // 0x45c\n    int x460;       // 0x460\n    int x464;       // 0x464\n    int x468;       // 0x468\n    int x46c;       // 0x46c\n    int x470;       // 0x470\n    int x474;       // 0x474\n    int x478;       // 0x478\n    int x47c;       // 0x47c\n    int x480;       // 0x480\n    int x484;       // 0x484\n    int x488;       // 0x488\n    int x48c;       // 0x48c\n    int x490;       // 0x490\n    int x494;       // 0x494\n    int x498;       // 0x498\n    int x49c;       // 0x49c\n    int x4a0;       // 0x4a0\n    int x4a4;       // 0x4a4\n    int x4a8;       // 0x4a8\n    int x4ac;       // 0x4ac\n    int x4b0;       // 0x4b0\n    int x4b4;       // 0x4b4\n    int x4b8;       // 0x4b8\n    int x4bc;       // 0x4bc\n    int x4c0;       // 0x4c0\n    int x4c4;       // 0x4c4\n    int x4c8;       // 0x4c8\n    int x4cc;       // 0x4cc\n    int x4d0;       // 0x4d0\n    int x4d4;       // 0x4d4\n    int x4d8;       // 0x4d8\n    int x4dc;       // 0x4dc\n    int x4e0;       // 0x4e0\n    int x4e4;       // 0x4e4\n    int x4e8;       // 0x4e8\n    int x4ec;       // 0x4ec\n    int x4f0;       // 0x4f0\n    int x4f4;       // 0x4f4\n    int x4f8;       // 0x4f8\n    int x4fc;       // 0x4fc\n    int x500;       // 0x500\n    int x504;       // 0x504\n    int x508;       // 0x508\n    int x50c;       // 0x50c\n    int x510;       // 0x510\n    int x514;       // 0x514\n    int x518;       // 0x518\n    int x51c;       // 0x51c\n    int x520;       // 0x520\n    int x524;       // 0x524\n    int x528;       // 0x528\n    int x52c;       // 0x52c\n    int x530;       // 0x530\n    int x534;       // 0x534\n    int x538;       // 0x538\n    int x53c;       // 0x53c\n    int x540;       // 0x540\n    int x544;       // 0x544\n    int x548;       // 0x548\n    int x54c;       // 0x54c\n    int x550;       // 0x550\n    int x554;       // 0x554\n};\n\nstruct ftCommonData\n{\n    float x0;                     // 0x0\n    float x4;                     // 0x4\n    float x8;                     // 0x8\n    float xc;                     // 0xc\n    float x10;                    // 0x10\n    float x14;                    // 0x14\n    float x18;                    // 0x18\n    float x1c;                    // 0x1c\n    float lstick_tilt;            // 0x20\n    float x24;                    // 0x24\n    float x28;                    // 0x28\n    float x2c;                    // 0x2c\n    float x30;                    // 0x30\n    float x34;                    // 0x34\n    float x38;                    // 0x38\n    float x3c;                    // 0x3c\n    float x40;                    // 0x40\n    float x44;                    // 0x44\n    float x48;                    // 0x48\n    float x4c;                    // 0x4c\n    float x50;                    // 0x50\n    float x54;                    // 0x54\n    float x58;                    // 0x58\n    float x5c;                    // 0x5c\n    float x60;                    // 0x60\n    float x64;                    // 0x64\n    float x68;                    // 0x68\n    float friction_mult;          // 0x6c\n    float jumpaerial_lsticky;     // 0x70\n    float jumpaerial_lsticktimer; // 0x74\n    float x78;                    // 0x78\n    float x7c;                    // 0x7c\n    float x80;                    // 0x80\n    float x84;                    // 0x84\n    float x88;                    // 0x88\n    float x8c;                    // 0x8c\n    float lstick_rebirthfall;     // 0x90\n    float x94;                    // 0x94\n    float x98;                    // 0x98\n    float x9c;                    // 0x9c\n    float xa0;                    // 0xa0\n    float xa4;                    // 0xa4\n    float xa8;                    // 0xa8\n    float xac;                    // 0xac\n    float xb0;                    // 0xb0\n    float xb4;                    // 0xb4\n    float xb8;                    // 0xb8\n    float xbc;                    // 0xbc\n    float xc0;                    // 0xc0\n    float xc4;                    // 0xc4\n    float xc8;                    // 0xc8\n    float xcc;                    // 0xcc\n    float xd0;                    // 0xd0\n    float xd4;                    // 0xd4\n    float xd8;                    // 0xd8\n    float xdc;                    // 0xdc\n    float xe0;                    // 0xe0\n    float xe4;                    // 0xe4\n    float xe8;                    // 0xe8\n    float xec;                    // 0xec\n    float xf0;                    // 0xf0\n    float xf4;                    // 0xf4\n    float xf8;                    // 0xf8\n    float xfc;                    // 0xfc\n    float kb_mult;                // 0x100\n    float x104;                   // 0x104\n    float x108;                   // 0x108\n    float x10c;                   // 0x10c\n    float x110;                   // 0x110\n    float x114;                   // 0x114\n    float x118;                   // 0x118\n    float x11c;                   // 0x11c\n    float x120;                   // 0x120\n    float x124;                   // 0x124\n    float x128;                   // 0x128\n    float x12c;                   // 0x12c\n    float x130;                   // 0x130\n    float x134;                   // 0x134\n    float x138;                   // 0x138\n    float x13c;                   // 0x13c\n    float x140;                   // 0x140\n    float x144;                   // 0x144\n    float x148;                   // 0x148\n    float x14c;                   // 0x14c\n    float x150;                   // 0x150\n    float x154;                   // 0x154\n    float x158;                   // 0x158\n    float x15c;                   // 0x15c\n    float x160;                   // 0x160\n    float x164;                   // 0x164\n    float x168;                   // 0x168\n    float kb_maxVelX;             // 0x16c\n    float x170;                   // 0x170\n    float x174;                   // 0x174\n    float x178;                   // 0x178\n    float x17c;                   // 0x17c\n    float x180;                   // 0x180\n    float x184;                   // 0x184\n    float x188;                   // 0x188\n    float x18c;                   // 0x18c\n    float x190;                   // 0x190\n    float x194;                   // 0x194\n    float x198;                   // 0x198\n    float x19c;                   // 0x19c\n    float x1a0;                   // 0x1a0\n    float x1a4;                   // 0x1a4\n    float tdi_maxAngle;           // 0x1a8\n    float x1ac;                   // 0x1ac\n    float x1b0;                   // 0x1b0\n    float x1b4;                   // 0x1b4\n    float x1b8;                   // 0x1b8\n    float kb_bounceDecay;         // 0x1bc\n    float x1c0;                   // 0x1c0\n    float x1c4;                   // 0x1c4\n    float x1c8;                   // 0x1c8\n    float x1cc;                   // 0x1cc\n    float x1d0;                   // 0x1d0\n    float x1d4;                   // 0x1d4\n    float x1d8;                   // 0x1d8\n    float x1dc;                   // 0x1dc\n    float x1e0;                   // 0x1e0\n    float x1e4;                   // 0x1e4\n    float x1e8;                   // 0x1e8\n    float x1ec;                   // 0x1ec\n    float x1f0;                   // 0x1f0\n    float x1f4;                   // 0x1f4\n    float x1f8;                   // 0x1f8\n    float x1fc;                   // 0x1fc\n    float x200;                   // 0x200\n    float kb_frameDecay;          // 0x204\n    float x208;                   // 0x208\n    float x20c;                   // 0x20c\n    float x210;                   // 0x210\n    float x214;                   // 0x214\n    float x218;                   // 0x218\n    float x21c;                   // 0x21c\n    float x220;                   // 0x220\n    float x224;                   // 0x224\n    float x228;                   // 0x228\n    float x22c;                   // 0x22c\n    float x230;                   // 0x230\n    float x234;                   // 0x234\n    float x238;                   // 0x238\n    float x23c;                   // 0x23c\n    float x240;                   // 0x240\n    float x244;                   // 0x244\n    float x248;                   // 0x248\n    float x24c;                   // 0x24c\n    float x250;                   // 0x250\n    float x254;                   // 0x254\n    float x258;                   // 0x258\n    float x25c;                   // 0x25c\n    float x260;                   // 0x260\n    float x264;                   // 0x264\n    float x268;                   // 0x268\n    float x26c;                   // 0x26c\n    float x270;                   // 0x270\n    float x274;                   // 0x274\n    float x278;                   // 0x278\n    float x27c;                   // 0x27c\n    float x280;                   // 0x280\n    float x284;                   // 0x284\n    float x288;                   // 0x288\n    float x28c;                   // 0x28c\n    float x290;                   // 0x290\n    float x294;                   // 0x294\n    float x298;                   // 0x298\n    float x29c;                   // 0x29c\n    float x2a0;                   // 0x2a0\n    float x2a4;                   // 0x2a4\n    float x2a8;                   // 0x2a8\n    float x2ac;                   // 0x2ac\n    float x2b0;                   // 0x2b0\n    float x2b4;                   // 0x2b4\n    float x2b8;                   // 0x2b8\n    float x2bc;                   // 0x2bc\n    float x2c0;                   // 0x2c0\n    float x2c4;                   // 0x2c4\n    float x2c8;                   // 0x2c8\n    float x2cc;                   // 0x2cc\n    float x2d0;                   // 0x2d0\n    float x2d4;                   // 0x2d4\n    float x2d8;                   // 0x2d8\n    float x2dc;                   // 0x2dc\n    float x2e0;                   // 0x2e0\n    float x2e4;                   // 0x2e4\n    float x2e8;                   // 0x2e8\n    float x2ec;                   // 0x2ec\n    float x2f0;                   // 0x2f0\n    float x2f4;                   // 0x2f4\n    float x2f8;                   // 0x2f8\n    float x2fc;                   // 0x2fc\n    float x300;                   // 0x300\n    float x304;                   // 0x304\n    float x308;                   // 0x308\n    float x30c;                   // 0x30c\n    float x310;                   // 0x310\n    float x314;                   // 0x314\n    float x318;                   // 0x318\n    float x31c;                   // 0x31c\n    float x320;                   // 0x320\n    float x324;                   // 0x324\n    float x328;                   // 0x328\n    float x32c;                   // 0x32c\n    float x330;                   // 0x330\n    float x334;                   // 0x334\n    float escapeair_vel;          // 0x338\n    float escapeair_veldecaymult; // 0x33c\n    float x340;                   // 0x340\n    float x344;                   // 0x344\n    float x348;                   // 0x348\n    float x34c;                   // 0x34c\n    float x350;                   // 0x350\n    float x354;                   // 0x354\n    float x358;                   // 0x358\n    float x35c;                   // 0x35c\n    float x360;                   // 0x360\n    float x364;                   // 0x364\n    float x368;                   // 0x368\n    float x36c;                   // 0x36c\n    float x370;                   // 0x370\n    float x374;                   // 0x374\n    float x378;                   // 0x378\n    float x37c;                   // 0x37c\n    float x380;                   // 0x380\n    float x384;                   // 0x384\n    float x388;                   // 0x388\n    float x38c;                   // 0x38c\n    float x390;                   // 0x390\n    float x394;                   // 0x394\n    float x398;                   // 0x398\n    float x39c;                   // 0x39c\n    float x3a0;                   // 0x3a0\n    float x3a4;                   // 0x3a4\n    float x3a8;                   // 0x3a8\n    float x3ac;                   // 0x3ac\n    float x3b0;                   // 0x3b0\n    float x3b4;                   // 0x3b4\n    float x3b8;                   // 0x3b8\n    float x3bc;                   // 0x3bc\n    float x3c0;                   // 0x3c0\n    float x3c4;                   // 0x3c4\n    float x3c8;                   // 0x3c8\n    float x3cc;                   // 0x3cc\n    float x3d0;                   // 0x3d0\n    float x3d4;                   // 0x3d4\n    float x3d8;                   // 0x3d8\n    float x3dc;                   // 0x3dc\n    float x3e0;                   // 0x3e0\n    float x3e4;                   // 0x3e4\n    float x3e8;                   // 0x3e8\n    float x3ec;                   // 0x3ec\n    float x3f0;                   // 0x3f0\n    float x3f4;                   // 0x3f4\n    float x3f8;                   // 0x3f8\n    float x3fc;                   // 0x3fc\n    float x400;                   // 0x400\n    float x404;                   // 0x404\n    float x408;                   // 0x408\n    float x40c;                   // 0x40c\n    float x410;                   // 0x410\n    float x414;                   // 0x414\n    float x418;                   // 0x418\n    float x41c;                   // 0x41c\n    float x420;                   // 0x420\n    float x424;                   // 0x424\n    float x428;                   // 0x428\n    float x42c;                   // 0x42c\n    float x430;                   // 0x430\n    float x434;                   // 0x434\n    float x438;                   // 0x438\n    float x43c;                   // 0x43c\n    float x440;                   // 0x440\n    float x444;                   // 0x444\n    float x448;                   // 0x448\n    float x44c;                   // 0x44c\n    float x450;                   // 0x450\n    float zjostle_frame;          // 0x45c\n    float zjostle_max;            // 0x460\n    float ms_zjostle_frame;       // 0x45c\n    float ms_zjostle_max;         // 0x460\n    float x464;                   // 0x464\n    float x468;                   // 0x468\n    float x46c;                   // 0x46c\n    float x470;                   // 0x470\n    float x474;                   // 0x474\n    float x478;                   // 0x478\n    float x47c;                   // 0x47c\n    float x480;                   // 0x480\n    float x484;                   // 0x484\n    float x488;                   // 0x488\n    float x48c;                   // 0x48c\n    float x490;                   // 0x490\n    float x494;                   // 0x494\n    float x498;                   // 0x498\n    int cliff_invuln_time;        // 0x49c\n    float x4a0;                   // 0x4a0\n    float x4a4;                   // 0x4a4\n    float x4a8;                   // 0x4a8\n    float x4ac;                   // 0x4ac\n    float asdi_mag;               // 0x4b0\n    float x4b4;                   // 0x4b4\n    float x4b8;                   // 0x4b8\n    float asdi_units;             // 0x4bc\n    float x4c0;                   // 0x4c0\n    float x4c4;                   // 0x4c4\n    float x4c8;                   // 0x4c8\n    float x4cc;                   // 0x4cc\n    float x4d0;                   // 0x4d0\n    float x4d4;                   // 0x4d4\n    float x4d8;                   // 0x4d8\n    float x4dc;                   // 0x4dc\n    float x4e0;                   // 0x4e0\n    float x4e4;                   // 0x4e4\n    float x4e8;                   // 0x4e8\n    float x4ec;                   // 0x4ec\n    float x4f0;                   // 0x4f0\n    float x4f4;                   // 0x4f4\n    float x4f8;                   // 0x4f8\n    float x4fc;                   // 0x4fc\n    float x500;                   // 0x500\n    float x504;                   // 0x504\n    float x508;                   // 0x508\n    float x50c;                   // 0x50c\n    float x510;                   // 0x510\n    float x514;                   // 0x514\n    float x518;                   // 0x518\n    float x51c;                   // 0x51c\n    float x520;                   // 0x520\n    float x524;                   // 0x524\n    float x528;                   // 0x528\n    float x52c;                   // 0x52c\n    float x530;                   // 0x530\n    float x534;                   // 0x534\n    float x538;                   // 0x538\n    float x53c;                   // 0x53c\n    float x540;                   // 0x540\n    float x544;                   // 0x544\n    float x548;                   // 0x548\n    float x54c;                   // 0x54c\n    float x550;                   // 0x550\n    float x554;                   // 0x554\n    float x558;                   // 0x558\n    float x55c;                   // 0x55c\n    float x560;                   // 0x560\n    float x564;                   // 0x564\n    float x568;                   // 0x568\n    float x56c;                   // 0x56c\n    float x570;                   // 0x570\n    float x574;                   // 0x574\n    float x578;                   // 0x578\n    float x57c;                   // 0x57c\n    float x580;                   // 0x580\n    float x584;                   // 0x584\n    float x588;                   // 0x588\n    float x58c;                   // 0x58c\n    float x590;                   // 0x590\n    float x594;                   // 0x594\n    float x598;                   // 0x598\n    float x59c;                   // 0x59c\n    float x5a0;                   // 0x5a0\n    float x5a4;                   // 0x5a4\n    float x5a8;                   // 0x5a8\n    float x5ac;                   // 0x5ac\n    float x5b0;                   // 0x5b0\n    float x5b4;                   // 0x5b4\n    float x5b8;                   // 0x5b8\n    float x5bc;                   // 0x5bc\n    float x5c0;                   // 0x5c0\n    float x5c4;                   // 0x5c4\n    float x5c8;                   // 0x5c8\n    float x5cc;                   // 0x5cc\n    float x5d0;                   // 0x5d0\n    float x5d4;                   // 0x5d4\n    float x5d8;                   // 0x5d8\n    float x5dc;                   // 0x5dc\n    float x5e0;                   // 0x5e0\n    float x5e4;                   // 0x5e4\n    float x5e8;                   // 0x5e8\n    float x5ec;                   // 0x5ec\n    float x5f0;                   // 0x5f0\n    float x5f4;                   // 0x5f4\n    float x5f8;                   // 0x5f8\n    float x5fc;                   // 0x5fc\n    float x600;                   // 0x600\n    float x604;                   // 0x604\n    float x608;                   // 0x608\n    float x60c;                   // 0x60c\n    float x610;                   // 0x610\n    float x614;                   // 0x614\n    float x618;                   // 0x618\n    float x61c;                   // 0x61c\n    float x620;                   // 0x620\n    float x624;                   // 0x624\n    float x628;                   // 0x628\n    float x62c;                   // 0x62c\n    float x630;                   // 0x630\n    float x634;                   // 0x634\n    float x638;                   // 0x638\n    float x63c;                   // 0x63c\n    float x640;                   // 0x640\n    float x644;                   // 0x644\n    float x648;                   // 0x648\n    float x64c;                   // 0x64c\n    float x650;                   // 0x650\n    float x654;                   // 0x654\n    float x658;                   // 0x658\n    float x65c;                   // 0x65c\n    float x660;                   // 0x660\n    float x664;                   // 0x664\n    float x668;                   // 0x668\n    float x66c;                   // 0x66c\n    float x670;                   // 0x670\n    float x674;                   // 0x674\n    float x678;                   // 0x678\n    float x67c;                   // 0x67c\n    float x680;                   // 0x680\n    float x684;                   // 0x684\n    float x688;                   // 0x688\n    float x68c;                   // 0x68c\n    float x690;                   // 0x690\n    float x694;                   // 0x694\n    float x698;                   // 0x698\n    float x69c;                   // 0x69c\n    float x6a0;                   // 0x6a0\n    float x6a4;                   // 0x6a4\n    float x6a8;                   // 0x6a8\n    float x6ac;                   // 0x6ac\n    float x6b0;                   // 0x6b0\n    float x6b4;                   // 0x6b4\n    float x6b8;                   // 0x6b8\n    float x6bc;                   // 0x6bc\n    float x6c0;                   // 0x6c0\n    float x6c4;                   // 0x6c4\n    float x6c8;                   // 0x6c8\n    float x6cc;                   // 0x6cc\n    float x6d0;                   // 0x6d0\n    float x6d4;                   // 0x6d4\n    float x6d8;                   // 0x6d8\n    float x6dc;                   // 0x6dc\n    float x6e0;                   // 0x6e0\n    float x6e4;                   // 0x6e4\n    float x6e8;                   // 0x6e8\n    float x6ec;                   // 0x6ec\n    float x6f0;                   // 0x6f0\n    float x6f4;                   // 0x6f4\n    float x6f8;                   // 0x6f8\n    float x6fc;                   // 0x6fc\n    float x700;                   // 0x700\n    float x704;                   // 0x704\n    float x708;                   // 0x708\n    float x70c;                   // 0x70c\n    float x710;                   // 0x710\n    float x714;                   // 0x714\n    float x718;                   // 0x718\n    float x71c;                   // 0x71c\n    float x720;                   // 0x720\n    float x724;                   // 0x724\n    float x728;                   // 0x728\n    float x72c;                   // 0x72c\n    float x730;                   // 0x730\n    float x734;                   // 0x734\n    float x738;                   // 0x738\n    float x73c;                   // 0x73c\n    float x740;                   // 0x740\n    float x744;                   // 0x744\n    float x748;                   // 0x748\n    float x74c;                   // 0x74c\n    float x750;                   // 0x750\n    float x754;                   // 0x754\n    float x758;                   // 0x758\n    float x75c;                   // 0x75c\n    float x760;                   // 0x760\n    float x764;                   // 0x764\n    float x768;                   // 0x768\n    float x76c;                   // 0x76c\n    float x770;                   // 0x770\n    float x774;                   // 0x774\n    float x778;                   // 0x778\n    float x77c;                   // 0x77c\n    float x780;                   // 0x780\n    float x784;                   // 0x784\n    float x788;                   // 0x788\n    float x78c;                   // 0x78c\n    float x790;                   // 0x790\n    float x794;                   // 0x794\n    float x798;                   // 0x798\n    float x79c;                   // 0x79c\n    float x7a0;                   // 0x7a0\n    float x7a4;                   // 0x7a4\n    float x7a8;                   // 0x7a8\n    float x7ac;                   // 0x7ac\n    float x7b0;                   // 0x7b0\n    float x7b4;                   // 0x7b4\n    float x7b8;                   // 0x7b8\n    float x7bc;                   // 0x7bc\n    float x7c0;                   // 0x7c0\n    float x7c4;                   // 0x7c4\n    float x7c8;                   // 0x7c8\n    float x7cc;                   // 0x7cc\n    float x7d0;                   // 0x7d0\n    float x7d4;                   // 0x7d4\n    float x7d8;                   // 0x7d8\n    float x7dc;                   // 0x7dc\n    float x7e0;                   // 0x7e0\n    float x7e4;                   // 0x7e4\n    float x7e8;                   // 0x7e8\n    float x7ec;                   // 0x7ec\n    float x7f0;                   // 0x7f0\n    float x7f4;                   // 0x7f4\n    float x7f8;                   // 0x7f8\n    float x7fc;                   // 0x7fc\n    float x800;                   // 0x800\n    float x804;                   // 0x804\n    float x808;                   // 0x808\n    float x80c;                   // 0x80c\n    float x810;                   // 0x810\n};\n\nstruct FighterData\n{\n    GOBJ *fighter;                                             // 0x0\n    int kind;                                                  // 0x4\n    int spawn_num;                                             // 0x8\n    char ply;                                                  // 0xC\n    char unknown;                                              // 0xD\n    char unknownE;                                             // 0xE\n    char unknownF;                                             // 0xF\n    int state;                                                 // 0x10\n    int anim_id;                                               // 0x14\n    int state_num;                                             // 0x18\n    MoveLogic *common_states;                                  // 0x1C\n    MoveLogic *special_states;                                 // 0x20\n    int *anim_flags;                                           // 0x24\n    u16 *dynamics_data;                                        // 0x28\n    float facing_direction;                                    // 0x2C\n    float facing_direction_repeated;                           // 0x30\n    float scale1;                                              // 0x34\n    float scale2;                                              // 0x38\n    float scale3;                                              // 0x3C\n    int pointer_to_next_linked_list;                           // 0x40\n    int pointer_to_0x40__pointer_to_prev_linked_list;          // 0x44\n    int length_of_linked_list;                                 // 0x48\n    int unknown4C;                                             // 0x4C\n    int unknown50;                                             // 0x50\n    int unknown54;                                             // 0x54\n    int unknown58;                                             // 0x58\n    int unknown5C;                                             // 0x5C\n    int unknown60;                                             // 0x60\n    int unknown64;                                             // 0x64\n    int unknown68;                                             // 0x68\n    int unknown6C;                                             // 0x6C\n    int unknown70;                                             // 0x70\n    struct phys                                                // 0x74\n    {                                                          //\n        Vec3 anim_vel;                                         // 0x74\n        Vec3 self_vel;                                         // 0x80\n        Vec3 kb_vel;                                           // 0x8C\n        int x98;                                               // 0x98\n        int x9c;                                               // 0x9C\n        int xa0;                                               // 0xA0\n        int xa4;                                               // 0xA4\n        int xa8;                                               // 0xA8\n        int xac;                                               // 0xAC\n        Vec3 pos;                                              // 0xb0\n        Vec3 pos_prev;                                         // 0xBC\n        Vec3 pos_delta;                                        // 0xC8\n        Vec3 unknownD4;                                        // 0xD4\n        int air_state;                                         // 0xE0\n        float horzitonal_velocity_queue_will_be_added_to_0xec; // 0xE4\n        float vertical_velocity_queue_will_be_added_to_0xec;   // 0xE8\n        Vec3 selfVelGround;                                    // 0xEC\n        int unknownF8;                                         // 0xF8\n        int unknownFC;                                         // 0xFC\n        int unknown100;                                        // 0x100\n    } phys;                                                    //\n    int *costume_JObjDesc;                                     // 0x104\n    int *costume_archive;                                      // 0x108\n    ftData *ftData;                                            // 0x10C\n    struct attr                                                // 0x110\n    {                                                          //\n        float walk_initial_velocity;                           // 0x110\n        float walk_acceleration;                               // 0x114\n        float walk_maximum_velocity;                           // 0x118\n        float slow_walk_max;                                   // 0x11C\n        float mid_walk_point;                                  // 0x120\n        float fast_walk_min;                                   // 0x124\n        float ground_friction;                                 // 0x128\n        float dash_initial_velocity;                           // 0x12C\n        float dashrun_acceleration_a;                          // 0x130\n        float dashrun_acceleration_b;                          // 0x134\n        float dashrun_terminal_velocity;                       // 0x138\n        float run_animation_scaling;                           // 0x13C\n        float max_runbrake_frames;                             // 0x140\n        float grounded_max_horizontal_velocity;                // 0x144\n        float jump_startup_time;                               // 0x148\n        float jump_h_initial_velocity;                         // 0x14C\n        float jump_v_initial_velocity;                         // 0x150\n        float ground_to_air_jump_momentum_multiplier;          // 0x154\n        float jump_h_max_velocity;                             // 0x158\n        float hop_v_initial_velocity;                          // 0x15C\n        float air_jump_v_multiplier;                           // 0x160\n        float air_jump_h_multiplier;                           // 0x164\n        int max_jumps;                                         // 0x168\n        float gravity;                                         // 0x16C\n        float terminal_velocity;                               // 0x170\n        float aerialDriftStickMult;                            // 0x174\n        float aerialDriftBase;                                 // 0x178\n        float aerialDriftMax;                                  // 0x17C\n        float aerialFriction;                                  // 0x180\n        float fastfall_velocity;                               // 0x184\n        float horizontal_air_mobility_constant;                // 0x188\n        int jab_2_input_window;                                // 0x18C\n        int jab_3_input_window;                                // 0x190\n        int frames_to_change_direction_on_standing_turn;       // 0x194\n        float weight;                                          // 0x198\n        float model_scaling;                                   // 0x19C\n        float initial_shield_size;                             // 0x1A0\n        float shield_break_initial_velocity;                   // 0x1A4\n        int rapid_jab_window;                                  // 0x1A8\n        int unknown1AC;                                        // 0x1AC\n        int unknown1B0;                                        // 0x1B0\n        int unknown1B4;                                        // 0x1B4\n        float ledge_jump_horizontal_velocity;                  // 0x1B8\n        float ledge_jump_vertical_velocity;                    // 0x1BC\n        float item_throw_velocity_multiplier;                  // 0x1C0\n        int unknown1C4;                                        // 0x1C4\n        int unknown1C8;                                        // 0x1C8\n        int unknown1CC;                                        // 0x1CC\n        int unknown1D0;                                        // 0x1D0\n        int unknown1D4;                                        // 0x1D4\n        int unknown1D8;                                        // 0x1D8\n        int unknown1DC;                                        // 0x1DC\n        int unknown1E0;                                        // 0x1E0\n        int unknown1E4;                                        // 0x1E4\n        int unknown1E8;                                        // 0x1E8\n        int unknown1EC;                                        // 0x1EC\n        float kirby_b_star_damage;                             // 0x1F0\n        float normal_landing_lag;                              // 0x1F4\n        float n_air_landing_lag;                               // 0x1F8\n        float f_air_landing_lag;                               // 0x1FC\n        float b_air_landing_lag;                               // 0x200\n        float u_air_landing_lag;                               // 0x204\n        float d_air_landing_lag;                               // 0x208\n        float nametag_height;                                  // 0x20C\n        int unknown210;                                        // 0x210\n        float wall_jump_horizontal_velocity;                   // 0x214\n        float wall_jump_vertical_velocity;                     // 0x218\n        int unknown21C;                                        // 0x21C\n        float trophy_scale;                                    // 0x220\n        int unknown224;                                        // 0x224\n        int unknown228;                                        // 0x228\n        int unknown22C;                                        // 0x22C\n        int unknown230;                                        // 0x230\n        int unknown234;                                        // 0x234\n        int unknown238;                                        // 0x238\n        int unknown23C;                                        // 0x23C\n        int unknown240;                                        // 0x240\n        int unknown244;                                        // 0x244\n        int unknown248;                                        // 0x248\n        int unknown24C;                                        // 0x24C\n        int unknown250;                                        // 0x250\n        int unknown254;                                        // 0x254\n        int unknown258;                                        // 0x258\n        float bubble_ratio;                                    // 0x25C\n        int unknown260;                                        // 0x260\n        int unknown264;                                        // 0x264\n        int unknown268;                                        // 0x268\n        int unknown26C;                                        // 0x26C\n        float respawn_platform_scale;                          // 0x270\n        int unknown274;                                        // 0x274\n        int unknown278;                                        // 0x278\n        int camera_zoom_target_bone;                           // 0x27C\n        int unknown280;                                        // 0x280\n        int unknown284;                                        // 0x284\n        int unknown288;                                        // 0x288\n        int special_jump_action___1;                           // 0x28C\n        int weight_dependent_throw_speed_flags;                // 0x290\n    } attr;                                                    //\n    int unknown294;                                            // 0x294\n    int unknown298;                                            // 0x298\n    int unknown29C;                                            // 0x29C\n    int unknown2A0;                                            // 0x2A0\n    int unknown2A4;                                            // 0x2A4\n    int unknown2A8;                                            // 0x2A8\n    int unknown2AC;                                            // 0x2AC\n    int unknown2B0;                                            // 0x2B0\n    int unknown2B4;                                            // 0x2B4\n    int unknown2B8;                                            // 0x2B8\n    int unknown2BC;                                            // 0x2BC\n    int unknown2C0;                                            // 0x2C0\n    int unknown2C4;                                            // 0x2C4\n    int unknown2C8;                                            // 0x2C8\n    int unknown2CC;                                            // 0x2CC\n    int unknown2D0;                                            // 0x2D0\n    int *special_attributes;                                   // 0x2D4\n    int *special_attributes2;                                  // 0x2D8\n    int unknown2DC;                                            // 0x2DC\n    int unknown2E0;                                            // 0x2E0\n    int unknown2E4;                                            // 0x2E4\n    int unknown2E8;                                            // 0x2E8\n    int unknown2EC;                                            // 0x2EC\n    FtDynamicBoneset dynamics_boneset[10];                     // 0x2f0\n    int dynamics_num;                                          // 0x3E0\n    struct script                                              //  0x3E4\n    {                                                          //\n        float script_event_timer;                              // 0x3E4\n        float script_frame_timer;                              // 0x3E8\n        int *script_current;                                   // 0x3EC\n        int script_loop_num;                                   // 0x3F0\n        int *script_return;                                    // 0x3F4\n    } script;                                                  //\n    int unk;                                                   // 0x3F8\n    int unk3FC;                                                // 0x3FC\n    int pointer_to_0x460;                                      // 0x400\n    int pointer_to_0x3c0;                                      // 0x404\n    ColorOverlay color[3];                                     // 0x408\n    int *LObj;                                                 // 0x588\n    int anim_num;                                              // 0x58C\n    int *anim_curr_flags_ptr;                                  // 0x590\n    int anim_curr_flags;                                       // 0x594\n    int *anim_requested;                                       // 0x598\n    int *anim_cache_curr;                                      // 0x59C\n    int *anim_cache_persist;                                   // 0x5A0\n    int *anim_curr_ARAM;                                       // 0x5A4\n    int *anim_persist_ARAM;                                    // 0x5A8\n    int dobj_toggle_num;                                       // 0x5AC\n    int unknown5B0;                                            // 0x5B0\n    int unknown5B4;                                            // 0x5B4\n    int unknown5B8;                                            // 0x5B8\n    int unknown5BC;                                            // 0x5BC\n    int unknown5C0;                                            // 0x5C0\n    int unknown5C4;                                            // 0x5C4\n    int unknown5C8;                                            // 0x5C8\n    int unknown5CC;                                            // 0x5CC\n    int unknown5D0;                                            // 0x5D0\n    int unknown5D4;                                            // 0x5D4\n    int unknown5D8;                                            // 0x5D8\n    int unknown5DC;                                            // 0x5DC\n    int unknown5E0;                                            // 0x5E0\n    int unknown5E4;                                            // 0x5E4\n    FighterBone *bones;                                        // 0x5E8\n    int bone_num;                                              // 0x5EC\n    int bone_arr;                                              // 0x5F0\n    u16 dobj_toggle[12];                                       // 0x5f4\n    Effect *gfx;                                               // 0x60C\n    int unknown610;                                            // 0x610\n    int unknown614;                                            // 0x614\n    char player_controller_number;                             // 0x618\n    char costume_id;                                           // 0x619\n    char color_overlay_id;                                     // 0x61A\n    u8 team;                                                   // 0x61B\n    char unknown61E;                                           // 0x61E\n    char unknown61F;                                           // 0x61F\n    struct input                                               // input data\n    {                                                          //\n        float lstick_x;                                        // 0x620\n        float lstick_y;                                        // 0x624\n        float lstick_prev_x;                                   // 0x628\n        float lstick_prev_y;                                   // 0x62C\n        int unknown630;                                        // 0x630\n        int unknown634;                                        // 0x634\n        float cstick_x;                                        // 0x638\n        float cstick_y;                                        // 0x63C\n        int x640;                                              // 0x640\n        int unknown644;                                        // 0x644\n        int unknown648;                                        // 0x648\n        int unknown64C;                                        // 0x64C\n        float trigger;                                         // 0x650\n        int unknown654;                                        // 0x654\n        int unknown658;                                        // 0x658\n        int held;                                              // 0x65C\n        int held_prev;                                         // 0x660\n        int unknown664;                                        // 0x664\n        int down;                                              // 0x668\n        int unknown66C;                                        // 0x66C\n        char timer_lstick_tilt_x;                              // 0x670\n        char timer_lstick_tilt_y;                              // 0x671\n        char timer_trigger_analog;                             // 0x672\n        char timer_lstick_smash_x;                             // 0x673\n        char timer_lstick_smash_y;                             // 0x674\n        char timer_trigger_digital;                            // 0x675\n        char timer_lstick_any_x;                               // 0x676\n        char timer_lstick_any_y;                               // 0x677\n        char timer_trigger_any;                                // 0x678\n        char x679;                                             // 0x679\n        char x67A;                                             // 0x67A\n        char x67B;                                             // 0x67B\n        char timer_a;                                          // 0x67C\n        char timer_b;                                          // 0x67D\n        char timer_xy;                                         // 0x67E\n        char timer_trigger_any_ignore_hitlag;                  // 0x67F\n        char timer_LR;                                         // 0x680\n        char timer_padup;                                      // 0x681\n        char timer_paddown;                                    // 0x682\n        char timer_item_release;                               // 0x683\n        char sinceRapidLR;                                     // 0x684\n        char timer_unk2;                                       // 0x685\n        char timer_unk3;                                       // 0x686\n        char timer_unk4;                                       // 0x687\n        char timer_sideb;                                      // 0x688\n        char timer_neutralb;                                   // 0x689\n        char timer_unk5;                                       // 0x68A\n        char timer_unk6;                                       // 0x68B\n    } input;                                                   //\n    Vec3 transN_pos;                                           // x68c\n    Vec3 transN_pos_prev;                                      // 0x698\n    Vec3 transN_offset;                                        // 0x6A4\n    Vec3 transN_offset_prev;                                   // 0x6B0\n    float input_stickangle;                                    // 0x6BC\n    int unknown6C0;                                            // 0x6C0\n    int unknown6C4;                                            // 0x6C4\n    int unknown6C8;                                            // 0x6C8\n    int unknown6CC;                                            // 0x6CC\n    int unknown6D0;                                            // 0x6D0\n    int unknown6D4;                                            // 0x6D4\n    int unknown6D8;                                            // 0x6D8\n    int unknown6DC;                                            // 0x6DC\n    int unknown6E0;                                            // 0x6E0\n    int unknown6E4;                                            // 0x6E4\n    int unknown6E8;                                            // 0x6E8\n    int unknown6EC;                                            // 0x6EC\n    CollData coll_data;                                        // 0x6F0 -> 0x88C\n    CameraBox *cameraBox;                                      // 0x890\n    float stateFrame;                                          // 0x894\n    int unknown898;                                            // 0x898\n    float stateSpeed;                                          // 0x89C\n    int x8a0;                                                  // 0x8a0\n    float stateBlend;                                          // 0x8a4\n    int x8a8;                                                  // 0x8a8\n    JOBJ *animSkeleton;                                        // 0x8ac\n    int x8b0;                                                  // 0x8b0\n    int x8b4;                                                  // 0x8b4\n    int x8b8;                                                  // 0x8b8\n    int x8bc;                                                  // 0x8bc\n    int x8c0;                                                  // 0x8c0\n    int x8c4;                                                  // 0x8c4\n    int x8c8;                                                  // 0x8c8\n    int x8cc;                                                  // 0x8cc\n    int x8d0;                                                  // 0x8d0\n    int x8d4;                                                  // 0x8d4\n    int x8d8;                                                  // 0x8d8\n    int x8dc;                                                  // 0x8dc\n    int x8e0;                                                  // 0x8e0\n    int x8e4;                                                  // 0x8e4\n    int x8e8;                                                  // 0x8e8\n    int x8ec;                                                  // 0x8ec\n    int x8f0;                                                  // 0x8f0\n    int x8f4;                                                  // 0x8f4\n    int x8f8;                                                  // 0x8f8\n    int x8fc;                                                  // 0x8fc\n    int x900;                                                  // 0x900\n    int x904;                                                  // 0x904\n    int x908;                                                  // 0x908\n    int x90c;                                                  // 0x90c\n    int x910;                                                  // 0x910\n    ftHit hitbox[4];                                           // 0x914\n    ftHit throw_hitbox[2];                                     // 0xdf4\n    ftHit unk_hitbox;                                          // 0x1064\n    u8 teamID;                                                 // 0x119c, friendly fire related\n    u8 grabbersID;                                             // 0x119D, slot ID of the person grabbing this fighter\n    u8 hurtboxNum;                                             // 0x119E, number of hurtboxesz\n    FtHurt hurtbox[15];                                        // 0x11A0\n    int x1614;                                                 // 0x1614\n    int x1618;                                                 // 0x1618\n    int x161c;                                                 // 0x161c\n    int x1620;                                                 // 0x1620\n    int x1624;                                                 // 0x1624\n    int x1628;                                                 // 0x1628\n    int x162c;                                                 // 0x162c\n    int x1630;                                                 // 0x1630\n    int x1634;                                                 // 0x1634\n    int x1638;                                                 // 0x1638\n    int x163c;                                                 // 0x163c\n    int x1640;                                                 // 0x1640\n    int x1644;                                                 // 0x1644\n    int x1648;                                                 // 0x1648\n    int x164c;                                                 // 0x164c\n    int x1650;                                                 // 0x1650\n    int x1654;                                                 // 0x1654\n    int x1658;                                                 // 0x1658\n    int x165c;                                                 // 0x165c\n    int x1660;                                                 // 0x1660\n    int x1664;                                                 // 0x1664\n    int x1668;                                                 // 0x1668\n    int dynamics_hit_num;                                      // 0x166c\n    FtDynamicHit dynamics_hit[11];                             // 0x1670\n    int x1828;                                                 // 0x1828\n    struct dmg                                                 // 0x182c\n    {                                                          //\n        int behavior;                                          // 0x182c\n        float percent;                                         // 0x1830\n        int x1834;                                             // 0x1834\n        float percent_temp;                                    // 0x1838\n        float applied;                                         // 0x183c\n        int x1840;                                             // 0x1840\n        float direction;                                       // 0x1844\n        int kb_angle;                                          // 0x1848\n        int damaged_hurtbox;                                   // 0x184c\n        float force_applied;                                   // 0x1850\n        Vec3 collpos;                                          // 0x1854\n        int dealt;                                             // 0x1860\n        int x1864;                                             // 0x1864\n        GOBJ *source;                                          // 0x1868\n        int x186c;                                             // 0x186c\n        int x1870;                                             // 0x1870\n        int x1874;                                             // 0x1874\n        int x1878;                                             // 0x1878\n        int x187c;                                             // 0x187c\n        int x1880;                                             // 0x1880\n        int x1884;                                             // 0x1884\n        int x1888;                                             // 0x1888\n        int x188c;                                             // 0x188c\n        int x1890;                                             // 0x1890\n        int x1894;                                             // 0x1894\n        int x1898;                                             // 0x1898\n        int x189c;                                             // 0x189c\n        int x18a0;                                             // 0x18a0\n        float kb_mag;                                          // 0x18a4  kb magnitude\n        int x18a8;                                             // 0x18a8\n        int time_since_hit;                                    // 0x18ac   in frames\n        int x18b0;                                             // 0x18b0\n        float armor;                                           // 0x18b4\n        int x18b8;                                             // 0x18b8\n        int x18bc;                                             // 0x18bc\n        int x18c0;                                             // 0x18c0\n        int source_ply;                                        // 0x18c4   damage source ply number\n        int x18c8;                                             // 0x18c8\n        int x18cc;                                             // 0x18cc\n        int x18d0;                                             // 0x18d0\n        int x18d4;                                             // 0x18d4\n        int x18d8;                                             // 0x18d8\n        int x18dc;                                             // 0x18dc\n        int x18e0;                                             // 0x18e0\n        int x18e4;                                             // 0x18e4\n        int x18e8;                                             // 0x18e8\n        u16 instancehitby;                                     // 0x18ec. Last Move Instance This Player Was Hit by\n        int x18f0;                                             // 0x18f0\n        int x18f4;                                             // 0x18f4\n        u8 x18f8;                                              // 0x18f8\n        u8 x18f9;                                              // 0x18f8\n        u16 model_shift_frames;                                // 0x18f8\n        u8 x18fc;                                              // 0x18fc\n        u8 x18fd;                                              // 0x18fd\n        int x1900;                                             // 0x1900\n        int x1904;                                             // 0x1904\n        int x1908;                                             // 0x1908\n        int x190c;                                             // 0x190c\n        int x1910;                                             // 0x1910\n        int x1914;                                             // 0x1914\n        int x1918;                                             // 0x1918\n        int x191c;                                             // 0x191c\n        int x1920;                                             // 0x1920\n        int x1924;                                             // 0x1924\n        int x1928;                                             // 0x1928\n        int x192c;                                             // 0x192c\n        int x1930;                                             // 0x1930\n        int x1934;                                             // 0x1934\n        int x1938;                                             // 0x1938\n        int x193c;                                             // 0x193c\n        int x1940;                                             // 0x1940\n        int x1944;                                             // 0x1944\n        int x1948;                                             // 0x1948\n        int x194c;                                             // 0x194c\n        int x1950;                                             // 0x1950\n        int x1954;                                             // 0x1954\n        int x1958;                                             // 0x1958\n        float hitlag_frames;                                   // 0x195c\n    } dmg;                                                     //\n    int x1960;                                                 // 0x1960\n    float x1964;                                               // 0x1964\n    struct jump                                                // 0x1968\n    {                                                          //\n        char jumps_used;                                       // 0x1968\n        char walljumps_used;                                   // 0x1969\n    } jump;                                                    //\n    int x196c;                                                 // 0x196c\n    int x1970;                                                 // 0x1970\n    GOBJ *heldItem;                                            // 0x1974\n    GOBJ *x1978;                                               // 0x1978\n    int x197c;                                                 // 0x197c\n    GOBJ *headItem;                                            // 0x1980\n    GOBJ *heldItemSpecial;                                     // 0x1984\n    struct hurtstatus                                          // 0x1988\n    {                                                          //\n        int script;                                            // 0x1988\n        int game;                                              // 0x198c\n        int ledge_intang_left;                                 // 0x1990\n        int respawn_intang_left;                               // 0x1994\n    } hurtstatus;                                              //\n    struct shield\n    {\n        float health;          // 0x1998\n        float lightshield_amt; // 0x199c\n        int dmg_taken;         // 0x19a0, seems to be all damage taken during the frame, is reset at the end of the frame\n        int dmg_taken2;        // 0x19a4, idk there so many of these\n        GOBJ *dmg_source;      // 0x19a8, points to the entity that hit the shield\n        float hit_direction;   // 0x19ac\n        int hit_attr;          // 0x19b0, attribute of the hitbox that collided\n        float x19b4;           // 0x19b4\n        float x19b8;           // 0x19b8\n        int dmg_taken3;        // 0x19bc, seems to be the most recent amount of damage taken\n    } shield;\n    struct shield_update // 0x19c0\n    {\n        JOBJ *bone;                   // 0x19c0\n        unsigned char is_checked : 1; // 0x19d0 0x80. is checked for collision when 0\n        Vec3 pos;                     // 19d4\n        Vec3 offset;                  // 0x19d4\n        float size_mult;              // 0x19e0\n    } shield_bubble;\n    struct reflect_update // 0x19e4\n    {\n        JOBJ *bone;                   // 0x19e4\n        unsigned char is_checked : 1; // 0x19d0 0x80. is checked for collision when 0\n        Vec3 pos;                     // 0x19d4\n        Vec3 offset;                  // 0x19f8\n        float size_mult;              // 0x1a04\n    } reflect_bubble;\n    struct absorb_update // 0x1a08\n    {\n        JOBJ *bone;                   // 0x1a08\n        unsigned char is_checked : 1; // 0x1a0c 0x80. is checked for collision when 0\n        Vec3 pos;                     // 0x1a10\n        Vec3 offset;                  // 0x1a1c\n        float size_mult;              // 0x1a28\n    } absorb_bubble;\n    struct reflect_hit                        // 0x1a2c\n    {                                         //\n        float hit_direction;                  // 0x1a2c\n        int max_dmg;                          // 0x1a30\n        float dmg_mult;                       // 0x1a34\n        int is_break;                         // 0x1a38\n    } reflect_hit;                            //\n    struct absorb_hit                         // 0x1a40\n    {                                         //\n        int x1a3c;                            // 0x1a3c\n        float hit_direction;                  // 0x1a40\n        int dmg_taken;                        // 0x1a44\n        int hits_taken;                       // 0x1a48\n    } absorb_hit;                             //\n    struct grab                               // 0x1a4c\n    {                                         //\n        float grab_timer;                     // 0x1a4c\n        int x1a50;                            // 0x1a50\n        int x1a54;                            // 0x1a54\n        GOBJ *grab_attacker;                  // 0x1a58\n        GOBJ *grab_victim;                    // 0x1a5c\n        int x1a60;                            // 0x1a60\n        int x1a64;                            // 0x1a64\n        u16 x1a68;                            // 0x1a68\n        u16 vuln;                             // 0x1a6a\n        int x1a6c;                            // 0x1a6c\n        int x1a70;                            // 0x1a70\n        int x1a74;                            // 0x1a74\n        int x1a78;                            // 0x1a78\n        int x1a7c;                            // 0x1a7c\n        int x1a80;                            // 0x1a80\n        int x1a84;                            // 0x1a84\n    } grab;                                   //\n    CPU cpu;                                  // 0x1a88\n    int x1fe0;                                // 0x1fe0\n    int x1fe4;                                // 0x1fe4\n    int x1fe8;                                // 0x1fe8\n    int x1fec;                                // 0x1fec\n    int x1ff0;                                // 0x1ff0\n    int x1ff4;                                // 0x1ff4\n    int x1ff8;                                // 0x1ff8\n    int x1ffc;                                // 0x1ffc\n    int x2000;                                // 0x2000\n    int x2004;                                // 0x2004\n    int x2008;                                // 0x2008\n    int x200c;                                // 0x200c\n    int x2010;                                // 0x2010\n    int x2014;                                // 0x2014\n    int x2018;                                // 0x2018\n    int x201c;                                // 0x201c\n    int x2020;                                // 0x2020\n    int x2024;                                // 0x2024\n    int x2028;                                // 0x2028\n    int x202c;                                // 0x202c\n    int x2030;                                // 0x2030\n    int x2034;                                // 0x2034\n    int x2038;                                // 0x2038\n    int x203c;                                // 0x203c\n    int x2040;                                // 0x2040\n    int x2044;                                // 0x2044\n    int x2048;                                // 0x2048\n    int x204c;                                // 0x204c\n    int x2050;                                // 0x2050\n    int x2054;                                // 0x2054\n    int x2058;                                // 0x2058\n    int x205c;                                // 0x205c\n    int x2060;                                // 0x2060\n    int ledge_cooldown;                       // 0x2064\n    int attack_kind;                          // 0x2068, non attacks have id 1\n    int x206c;                                // 0x206c\n    u8 x2070;                                 // 0x2070\n    u8 x2071;                                 // 0x2071\n    u8 x2072;                                 // 0x2072\n    u8 x2073;                                 // 0x2073\n    int x2074;                                // 0x2074\n    int x2078;                                // 0x2078\n    int x207c;                                // 0x207c\n    int x2080;                                // 0x2080\n    int x2084;                                // 0x2084\n    u16 moveID;                               // 0x2088\n    int x208c;                                // 0x208c\n    int x2090;                                // 0x2090\n    int x2094;                                // 0x2094\n    int x2098;                                // 0x2098\n    int x209c;                                // 0x209c\n    JOBJ *accessory;                          // 0x20a0\n    int x20a4;                                // 0x20a4\n    void *shadow;                             // 0x20a8, ASSERTS @ 8037f7b8, describes multiple struct members\n    int x20ac;                                // 0x20ac\n    struct afterimage                         //\n    {                                         //\n        struct FtAfterImageKey afterimage[3]; // 0x20b0\n        float afterimage_bottom;              // 0x20f8\n        float afterimage_top;                 // 0x20fc\n        u8 afterimage_state;                  // 0x2100\n        unsigned char afterimage_num : 7;     // 0x2101\n    } afterimage;                             //\n    int x2104;                                // 0x2104\n    int x2108;                                // 0x2108\n    int x210c;                                // 0x210c\n    int x2110;                                // 0x2110\n    struct smash                              // 0x2114\n    {                                         //\n        int state;                            // 0x2114 0 = none, 1 = pre-charge, 2 = charging, 3 = release\n        int frame;                            // 0x2118 number of frames fighter has charged for\n        float hold_frame;                     // 0x211c frame that charge begins/ends\n        float dmg_mult;                       // 0x2120 damage multiplier\n        float speed_mult;                     // 0x2124 speed multiplier?\n        int x2128;                            // 0x2128\n        int x212c;                            // 0x212c\n        int is_sfx_played;                    // 0x2130 bool for smash sfx?\n        u8 vibrate_frame;                     // 0x2134\n        u8 x22135;                            // 0x2135\n        float since_hitbox;                   // 0x2138\n    } smash;                                  //\n    int x213c;                                // 0x213c\n    int x2140;                                // 0x2140\n    int x2144;                                // 0x2144\n    int x2148;                                // 0x2148\n    int x214c;                                // 0x214c\n    int x2150;                                // 0x2150\n    int x2154;                                // 0x2154\n    int x2158;                                // 0x2158\n    int x215c;                                // 0x215c\n    int x2160;                                // 0x2160\n    int x2164;                                // 0x2164\n    int x2168;                                // 0x2168\n    int x216c;                                // 0x216c\n    int x2170;                                // 0x2170\n    int x2174;                                // 0x2174\n    int x2178;                                // 0x2178\n    int x217c;                                // 0x217c\n    int x2180;                                // 0x2180\n    int x2184;                                // 0x2184\n    int x2188;                                // 0x2188\n    int x218c;                                // 0x218c\n    struct cb\n    {\n        void (*OnGrabFighter_Self)(GOBJ *fighter);   // 0x2190\n        void (*x2194)(GOBJ *fighter);                // 0x2194\n        void (*OnGrabFighter_Victim)(GOBJ *fighter); // 0x2198\n        void (*IASA)(GOBJ *fighter);                 // 0x219C\n        void (*Anim)(GOBJ *fighter);                 // 0x21A0\n        void (*Phys)(GOBJ *fighter);                 // 0x21a4\n        void (*Coll)(GOBJ *fighter);                 // 0x21a8\n        void (*Cam)(GOBJ *fighter);                  // 0x21ac\n        void (*Accessory1)(GOBJ *fighter);           // 0x21b0\n        void (*Accessory2)(GOBJ *fighter);           // 0x21b4\n        void (*Accessory3)(GOBJ *fighter);           // 0x21b8\n        void (*Accessory4)(GOBJ *fighter);           // 0x21bc\n        void (*OnGiveDamage)(GOBJ *fighter);         // 0x21c0\n        void (*OnShieldHit)(GOBJ *fighter);          // 0x21c4\n        void (*OnReflectHit)(GOBJ *fighter);         // 0x21c8\n        void (*x21cc)(GOBJ *fighter);                // 0x21cc\n        void (*EveryHitlag)(GOBJ *fighter);          // 0x21d0\n        void (*EnterHitlag)(GOBJ *fighter);          // 0x21d4\n        void (*ExitHitlag)(GOBJ *fighter);           // 0x21d8\n        void (*OnTakeDamage)(GOBJ *fighter);         // 0x21dc\n        void (*OnDeath)(GOBJ *fighter);              // 0x21e0\n        void (*OnDeath2)(GOBJ *fighter);             // 0x21e4, internally Dead_Proc as evidenced by 800f5430\n        void (*OnDeath3)(GOBJ *fighter);             // 0x21e8\n        void (*OnActionStateChange)(GOBJ *fighter);  // 0x21ec\n        void (*OnTakeDamage2)(GOBJ *fighter);        // 0x21f0\n        void (*OnHurtboxDetect)(GOBJ *fighter);      // 0x21f4\n        void (*OnSpin)(GOBJ *fighter);               // 0x21f8\n    } cb;\n    unsigned char x21fc_1 : 1;                   // 0x80 - x21fc_\n    unsigned char show_center_sphere : 1;        // 0x40 - x21fc_\n    unsigned char show_item_pickup : 1;          // 0x20 - x21fc_\n    unsigned char show_cpu_ai : 1;               // 0x10 - x21fc_\n    unsigned char show_footstool : 1;            // 0x8 - x21fc_\n    unsigned char show_dynamics : 1;             // 0x4 - x21fc_\n    unsigned char show_hit : 1;                  // 0x2 - x21fc_\n    unsigned char show_model : 1;                // 0x1 - x21fc_\n    struct ftcmd_var                             // 0x2200\n    {                                            //\n        int subactionFlag0;                      // 0x2200\n        int subactionFlag1;                      // 0x2204\n        int subactionFlag2;                      // 0x2208\n        int subactionFlag3;                      // 0x220C\n    } ftcmd_var;                                 //\n    struct flags                                 // 0x2210\n    {                                            //\n        unsigned char throw_1 : 1;               // 0x80 - x2210\n        unsigned char throw_2 : 1;               // 0x40 - x2210\n        unsigned char throw_3 : 1;               // 0x20 - x2210\n        unsigned char throw_release : 1;         // 0x10 - x2210. also used to change users direction during aerial attacks\n        unsigned char throw_turn : 1;            // 0x8 - x2210\n        unsigned char throw_6 : 1;               // 0x4 - x2210\n        unsigned char throw_7 : 1;               // 0x2 - x2210\n        unsigned char throw_8 : 1;               // 0x1 - x2210\n        float throw_timerval;                    // equal to script_event_timer of the attacker\n        unsigned char x2218_1 : 1;               // 0x80 - x2218\n        unsigned char x2218_2 : 1;               // 0x40 - x2218\n        unsigned char x2218_3 : 1;               // 0x20 - x2218\n        unsigned char reflect_enable : 1;        // 0x10 - x2218\n        unsigned char reflect_nochangeowner : 1; // 0x8 - x2218\n        unsigned char x2218_6 : 1;               // 0x4 - x2218\n        unsigned char absorb_enable : 1;         // 0x2 - x2218\n        unsigned char absorb_unk : 1;            // 0x1 - x2218\n        unsigned char persistent_gfx : 1;        // is shielding bool. 0x80 - 0x2219\n        unsigned char immune : 1;                // 0x40 - 0x2219\n        unsigned char x2219_3 : 1;               // 0x20 - 0x2219\n        unsigned char hitbox_active : 1;         // 0x10 - 0x2219\n        unsigned char x2219_5 : 1;               // 0x8 - 0x2219\n        unsigned char freeze : 1;                // 0x4 - 0x2219\n        unsigned char hitlag_unk : 1;            // 0x2 - 0x2219\n        unsigned char hitlag_unk2 : 1;           // 0x1 - 0x2219\n        unsigned char x221a_1 : 1;               // 0x80 - 0x221a\n        unsigned char x221a_2 : 1;               // 0x40 - 0x221a\n        unsigned char hitlag : 1;                // 0x20 - 0x221a\n        unsigned char x221a_4 : 1;               // 0x10 - 0x221a\n        unsigned char is_fastfall : 1;           // 0x8 - 0x221a\n        unsigned char no_hurt_script : 1;        // 0x4 - 0x221a\n        unsigned char x221a_7 : 1;               // 0x2 - 0x221a\n        unsigned char gfx_persist : 1;           // 0x1 - 0x221a\n        unsigned char shield_enable : 1;         // 0x80 - 0x221b\n        unsigned char shield_x40 : 1;            // 0x40 - 0x221b\n        unsigned char shield_x20 : 1;            // 0x20 - 0x221b\n        unsigned char shield_x10 : 1;            // 0x10 - 0x221b\n        unsigned char shield_x8 : 1;             //  0x8 - 0x221b\n        unsigned char x221b_6 : 1;               // 0x4 - 0x221b\n        unsigned char x221b_7 : 1;               // 0x2 - 0x221b\n        unsigned char x221b_8 : 1;               // 0x1 - 0x221b\n        unsigned char x221c_1 : 1;               // 0x80 - 0x221c\n        unsigned char x221c_2 : 1;               // 0x40 - 0x221c\n        unsigned char x221c_3 : 1;               // 0x20 - 0x221c\n        unsigned char x221c_4 : 1;               // 0x10 - 0x221c\n        unsigned char x221c_5 : 1;               // 0x8 - 0x221c\n        unsigned char x221c_6 : 1;               // 0x4 - 0x221c\n        unsigned char hitstun : 1;               // 0x2 - 0x221c\n        unsigned char x221c_8 : 1;               // 0x1 = 0x221c\n        unsigned char x221d_1 : 1;               // 0x80 - 0x221d\n        unsigned char x221d_2 : 1;               // 0x40 - 0x221d\n        unsigned char x221d_3 : 1;               // 0x20 - 0x221d\n        unsigned char input_enable : 1;          // 0x10 - 0x221d\n        unsigned char x221d_5 : 1;               // 0x8 - 0x221d\n        unsigned char nudge_disable : 1;         // 0x4 - 0x221d\n        unsigned char ground_ignore : 1;         // 0x2 - 0x221d\n        unsigned char x221d_8 : 1;               // 0x1 - 0x221d\n        unsigned char invisible : 1;             // 0x80 - 0x221e\n        unsigned char x221e_2 : 1;               // 0x40 - 0x221e\n        unsigned char x221e_3 : 1;               // 0x20 - 0x221e\n        unsigned char isItemVisible : 1;         // 0x10 - 0x221e\n        unsigned char x221e_5 : 1;               // 0x8 - 0x221e\n        unsigned char x221e_6 : 1;               // 0x4 - 0x221e\n        unsigned char x221e_7 : 1;               // 0x2 - 0x221e\n        unsigned char x221e_8 : 1;               // 0x1 - 0x221e\n        unsigned char is_offscreen : 1;          // 0x80 - 0x221f\n        unsigned char dead : 1;                  // 0x40 - 0x221f\n        unsigned char x221f_3 : 1;               // 0x20 - 0x221f\n        unsigned char sleep : 1;                 // 0x10\n        unsigned char ms : 1;                    // ms = master/slave. is 1 when the player is a slave\n        unsigned char x221f_6 : 1;\n        unsigned char x221f_7 : 1;\n        unsigned char x221f_8 : 1;\n        char flags_2220;                      // 0x2220\n        char flags_2221;                      // 0x2221\n        unsigned char x2222_1 : 1;            // 0x80 - 0x2222\n        unsigned char is_multijump : 1;       // 0x40 - 0x2222\n        unsigned char x2222_3 : 1;            // 0x20 - 0x2222\n        unsigned char ceilko_nokb : 1;        // 0x10 - 0x2222, allow death off top without any Y KB\n        unsigned char x2222_5 : 1;            // 0x08 - 0x2222\n        unsigned char has_follower : 1;       // 0x04 - 0x2222, this makes the subcharacter enter sleep when the main char dies\n        unsigned char x2222_7 : 1;            // 0x02 - 0x2222\n        unsigned char x2222_8 : 1;            // 0x01 - 0x2222\n        char flags_2223;                      // 0x2223\n        unsigned char x2224_1 : 1;            // 0x80 - 0x2224\n        unsigned char x2224_2 : 1;            // 0x40 - 0x2224\n        unsigned char stamina_dead : 1;       // 0x20 - 0x2224\n        unsigned char x2224_4 : 1;            // 0x10 - 0x2224\n        unsigned char x2224_5 : 1;            // 0x8 - 0x2224\n        unsigned char x2224_6 : 1;            // 0x4 - 0x2224\n        unsigned char x2224_7 : 1;            // 0x2 - 0x2224\n        unsigned char x2224_8 : 1;            // 0x1 - 0x2224\n        unsigned char x2225_1 : 1;            // 0x80 - 0x2225\n        unsigned char x2225_2 : 1;            // 0x40 - 0x2225\n        unsigned char has_model_addition : 1; // 0x20 - 0x2225  bool for if fighter has a model addition, like kirby copy ability and puff hat\n        unsigned char x2225_4 : 1;            // 0x10 - 0x2225\n        unsigned char x2225_5 : 1;            // 0x8 - 0x2225\n        unsigned char x2225_6 : 1;            // 0x4 - 0x2225\n        unsigned char x2225_7 : 1;            // 0x2 - 0x2225\n        unsigned char x2225_8 : 1;            // 0x1 - 0x2225        unsigned char x2226_1 : 1;            // 0x80 - 0x2226\n        unsigned char x2226_2 : 1;            // 0x40 - 0x2226\n        unsigned char is_thrown : 1;          // 0x20 - 0x2226, might actually be for skipping grab collision\n        unsigned char x2226_4 : 1;            // 0x10 - 0x2226\n        unsigned char x2226_5 : 1;            // 0x8 - 0x2226\n        unsigned char x2226_6 : 1;            // 0x4 - 0x2226\n        unsigned char x2226_7 : 1;            // 0x2 - 0x2226\n        unsigned char x2226_8 : 1;            // 0x1 - 0x2226\n        char flags_2227;                      // 0x2227\n        char x2228_1 : 1;                     // 0x80 - 0x2228\n        char x2228_2 : 1;                     // 0x40 - 0x2228\n        char x2228_3 : 1;                     // 0x20 - 0x2228\n        char x2228_4 : 1;                     // 0x10 - 0x2228\n        char x2228_5 : 1;                     // 0x08 - 0x2228\n        char x2228_6 : 1;                     // 0x04 - 0x2228\n        char used_tether : 1;                 // 0x02 - 0x2228\n        char x2228_8 : 1;                     // 0x01 - 0x2228\n        unsigned char x2229_1 : 1;            // 0x80 - 0x2229\n        unsigned char x2229_2 : 1;            // 0x40 - 0x2229\n        unsigned char x2229_3 : 1;            // 0x20 - 0x2229\n        unsigned char x2229_4 : 1;            // 0x10 - 0x2229\n        unsigned char x2229_5 : 1;            // 0x8 - 0x2229\n        unsigned char x2229_6 : 1;            // 0x4 - 0x2229\n        unsigned char x2229_7 : 1;            // 0x2 - 0x2229\n        unsigned char no_reaction_always : 1; // 0x1 - 0x2229\n        char flags_222A;                      // 0x222A\n        char flags_222B;                      // 0x222B\n    } flags;                                  //\n    struct fighter_var                        // 0x222c\n    {                                         //\n        int charVar1;                         // 0x222c\n        int charVar2;                         // 0x2230\n        int charVar3;                         // 0x2234\n        int charVar4;                         // 0x2238\n        int charVar5;                         // 0x223c\n        int charVar6;                         // 0x2240\n        int charVar7;                         // 0x2244\n        int charVar8;                         // 0x2248\n        int charVar9;                         // 0x224c\n        int charVar10;                        // 0x2250\n        int charVar11;                        // 0x2254\n        int charVar12;                        // 0x2258\n        int charVar13;                        // 0x225c\n        int charVar14;                        // 0x2260\n        int charVar15;                        // 0x2264\n        int charVar16;                        // 0x2268\n        int charVar17;                        // 0x226c\n        int charVar18;                        // 0x2270\n        int charVar19;                        // 0x2274\n        int charVar20;                        // 0x2278\n        int charVar21;                        // 0x227c\n        int charVar22;                        // 0x2280\n        int charVar23;                        // 0x2284\n        int charVar24;                        // 0x2288\n        int charVar25;                        // 0x228c\n        int charVar26;                        // 0x2290\n        int charVar27;                        // 0x2294\n        int charVar28;                        // 0x2298\n        int charVar29;                        // 0x229c\n        int charVar30;                        // 0x22a0\n        int charVar31;                        // 0x22a4\n        int charVar32;                        // 0x22a8\n        int charVar33;                        // 0x22ac\n        int charVar34;                        // 0x22b0\n        int charVar35;                        // 0x22b4\n        int charVar36;                        // 0x22b8\n        int charVar37;                        // 0x22bc\n        int charVar38;                        // 0x22c0\n        int charVar39;                        // 0x22c4\n        int charVar40;                        // 0x22c8\n        int charVar41;                        // 0x22cc\n        int charVar42;                        // 0x22d0\n        int charVar43;                        // 0x22d4\n        int charVar44;                        // 0x22d8\n        int charVar45;                        // 0x22dc\n        int charVar46;                        // 0x22e0\n        int charVar47;                        // 0x22e4\n        int charVar48;                        // 0x22e8\n        int charVar49;                        // 0x22ec\n        int charVar50;                        // 0x22f0\n        int charVar51;                        // 0x22f4\n        int charVar52;                        // 0x22f8\n    } fighter_var;\n    int x22fc;          // 0x22fc\n    int x2300;          // 0x2300\n    int x2304;          // 0x2304\n    int x2308;          // 0x2308\n    int x230c;          // 0x230c\n    int x2310;          // 0x2310\n    int x2314;          // 0x2314\n    int x2318;          // 0x2318\n    int x231c;          // 0x231c\n    int x2320;          // 0x2320\n    int stage_internal; // 0x2324 so stupid, used for decrementing hazard immunity\n    int x2328;          // 0x2328\n    int x232c;          // 0x232c\n    int x2330;          // 0x2330\n    int x2334;          // 0x2334\n    int x2338;          // 0x2338\n    int x233c;          // 0x233c\n    struct state_var    // 0x2340\n    {                   //\n        int stateVar1;  // 0x2340\n        int stateVar2;  // 0x2344\n        int stateVar3;  // 0x2348\n        int stateVar4;  // 0x234c\n        int stateVar5;  // 0x2350\n        int stateVar6;  // 0x2354\n        int stateVar7;  // 0x2358\n        int stateVar8;  // 0x235c\n        int stateVar9;  // 0x2360\n        int stateVar10; // 0x2364\n        int stateVar11; // 0x2368\n        int stateVar12; // 0x236c\n        int stateVar13; // 0x2370\n        int stateVar14; // 0x2374\n        int stateVar15; // 0x2378\n        int stateVar16; // 0x237c\n        int stateVar17; // 0x2380\n        int stateVar18; // 0x2384\n    } state_var;        //\n    int x2388;          // 0x2388\n    int x238c;          // 0x238c\n    int x2390;          // 0x2390\n    int x2394;          // 0x2394\n    int x2398;          // 0x2398\n    int x239c;          // 0x239c\n    int x23a0;          // 0x23a0\n    int x23a4;          // 0x23a4\n    int x23a8;          // 0x23a8\n    int x23ac;          // 0x23ac\n    int x23b0;          // 0x23b0\n    int x23b4;          // 0x23b4\n    int x23b8;          // 0x23b8\n    int x23bc;          // 0x23bc\n    int x23c0;          // 0x23c0\n    int x23c4;          // 0x23c4\n    int x23c8;          // 0x23c8\n    int x23cc;          // 0x23cc\n    int x23d0;          // 0x23d0\n    int x23d4;          // 0x23d4\n    int x23d8;          // 0x23d8\n    int x23dc;          // 0x23dc\n    int x23e0;          // 0x23e0\n    int x23e4;          // 0x23e4\n    int x23e8;          // 0x23e8\n    struct MEX\n    {\n        int anim_owner;\n        GOBJ *kb_abilitysource;\n        u8 ucf_stickX[3];\n    } MEX;\n    struct TM\n    {\n        s16 state_frame;  // how many frames the player has been in this state\n        s16 shield_frame; // how many frames the player has been shielding\n        u16 state_prev[6];\n        u16 state_prev_frames[6];\n        u16 last_move_hurt;        // Previous Move Instance Hit By\n        u16 vuln_frames;           // how many frames the fighter has been vulnerable\n        u16 can_fastfall_frames;   // how many frames the fighter has been able to fast fall\n        int post_hitstun_frames;   // frames fighter has been out of hitstun\n        GOBJ *fighter_hurt_shield; // pointer to the fighter who's shield this fighter hit\n        void *cb_anim;             // additional animation callback\n    } TM;\n};\n\nstruct FtParts // is in the fighter data\n{\n    int num;     // 0x2240\n    DOBJ **dobj; // 0x2244   array of dobjs for the ftpar\n    void *x8;    // 0x2248\n    void *xc;    // 0x224C\n};\n\nstruct FtPartsDesc\n{\n    int model_num; // 0x2250\n    FtPartsLookup *lookups;\n};\n\nstruct FtDOBJUnk3\n{\n    int num;\n    FtDOBJUnk2 *x4; // pointer to u8 array\n};\n\nstruct FtDOBJUnk2\n{\n    int num;\n    u8 *id; // pointer to u8 array\n};\n\nstruct FtPartsLookup\n{\n    FtDOBJUnk3 *x0;\n    void *x4;\n    void *x8;\n    void *xc;\n    void *x10;\n};\n\nstruct FtDOBJUnk // is in the fighter data\n{\n    int num;  // 0x2250\n    u8 x4[5]; // array of bools?\n    FtDOBJUnk3 *xc;\n    void *x10;\n    void *x14;\n    void *x18;\n    void *x1c;\n};\n\n/** State Structs **/\nstruct FtCliffCatch\n{\n    int ledge_index;\n    float fall_timer;\n    int timer;\n};\n\n/** Static Variables **/\n\nstatic ftCommonData **stc_ftcommon = (R13 + -0x514C);\nstatic GXColor **stc_shieldcolors = (R13 + -0x5194);\n\n/*** Functions ***/\nvoid ActionStateChange(float startFrame, float animSpeed, float animBlend, GOBJ *fighter, int stateID, int flags1, int flags2);\nvoid Subaction_Update(GOBJ *fighter);\nvoid Fighter_UpdateBonePos(FighterData *fighter_data, int unk);\nvoid *Animation_GetAddress(FighterData *fighter, int animID);\nSubactionHeader *Fighter_GetSubactionHeader(FighterData *fighter, int animID);\nfloat Animation_GetLength(int animAddress);\nvoid Fighter_EnterLightThrow(GOBJ *fighter, int stateID);\nvoid Fighter_EnterDamageFall(GOBJ *fighter);\nvoid Fighter_EnterWait(GOBJ *fighter);\nvoid Fighter_EnterFall(GOBJ *fighter);\nvoid Fighter_EnterSpecialFall(GOBJ *fighter, int can_fastfall, int can_not_noimpactland, int can_not_interrupt, float aerialDriftMultipler, float landing_frames);\nvoid Fighter_EnterLanding(GOBJ *fighter);\nvoid Fighter_EnterSpecialLanding(GOBJ *fighter, int unk, float state_length);\nvoid Fighter_EnterSleep(GOBJ *fighter, int ms);\nvoid Fighter_EnterCliffWait(GOBJ *fighter);\nvoid Fighter_EnterRebirth(GOBJ *fighter);\nvoid Fighter_EnterRebirthWait(GOBJ *fighter);\nvoid Fighter_UpdateRebirthPlatformPos(GOBJ *fighter);\nvoid Fighter_MoveToCliff(GOBJ *fighter);\nGOBJ *Fighter_GetGObj(int ply);\nGOBJ *Fighter_GetSubcharGObj(int ply, int ms);\nPlayerblock *Fighter_GetPlayerblock(int ply);\nvoid Fighter_SetSlotType(int ply, int slot);\nint Fighter_GetControllerPort(int ply);\nint *Fighter_GetStaleMoveTable(int ply);\nvoid Fighter_SetPosition(int ply, int ms, Vec3 *pos);\nvoid Fighter_ApplyIntang(GOBJ *fighter, int duration);\nint Fighter_GetSlotType(int index); // returns 0x0 for HMN, 0x1 for CPU, 0x2 for Demo, 0x3 for not present\nint Fighter_GetStocks(int ply);\nvoid Fighter_SetFallNum(int index, int ms, int falls);\nvoid Fighter_EnableECBBottomUpdate(FighterData *fighter);\nvoid Fighter_EnterDamageState(GOBJ *fighter, int stateID, float frame);\nint Fighter_BoneLookup(FighterData *fighter, int boneID);\nvoid Fighter_GiveDamage(FighterData *fighter, float damage);\nvoid Fighter_GiveHeal(FighterData *fighter, int heal);\nvoid Fighter_SetHUDDamage(int player, u16 damage);\nvoid Fighter_RunOnHitCallbacks(GOBJ *fighter);\nvoid Fighter_SetStocks(int ply, int stocks);\nint FrameTimerCheck(GOBJ *fighter);\nvoid Fighter_EnterMiscPassState(float start_frame, GOBJ *fighter, int state, int flags);\nint Fighter_CollGround_PassLedge(GOBJ *fighter);\nvoid Fighter_CollGround_StopLedge(GOBJ *fighter);\nint Fighter_CollAir_GrabLedgeWalljump(GOBJ *fighter, void *perFrame, void *onLand);\nint Fighter_CollAir_GrabLedge(GOBJ *fighter, int grab_direction);\nvoid Fighter_CollAir_IgnoreLedge(GOBJ *fighter, void *callback);\nint Fighter_CollAir_IgnoreLedge_NoCB(GOBJ *fighter);\nint Fighter_IASACheck_CliffCatch(GOBJ *fighter);\nint Fighter_IASACheck_JumpAerial(GOBJ *fighter);\nint Fighter_IASACheck_JumpF(GOBJ *fighter);\nint Fighter_IASACheck_PassConditions(GOBJ *fighter);\nint Fighter_IASACheck_Turn(GOBJ *fighter);\nvoid Fighter_PhysGround_ApplyFriction(GOBJ *fighter);\nvoid Fighter_PhysAir_ApplyGravity(FighterData *fighter, float gravity, float limit);\nvoid Fighter_PhysAir_LimitVelocity(FighterData *fighter);\nvoid Fighter_Phys_UseAnimPos(FighterData *fighter);\nvoid Fighter_Phys_UseAnimPosAndStick(FighterData *fighter);\nvoid Fighter_SetGrounded(FighterData *fighter);\nvoid Fighter_SetGrounded2(FighterData *fighter);\nvoid Fighter_SetAirborne(FighterData *fighter);\nvoid Fighter_LoseGroundJump(FighterData *fighter_data);\nvoid Fighter_EnableCollUpdate(FighterData *fighter_data);\nvoid Fighter_KillAllVelocity(GOBJ *fighter);\nvoid Fighter_AdvanceScript(GOBJ *fighter);\nvoid Fighter_GFXRemoveAll(GOBJ *fighter);\nvoid Fighter_EnableReflectUpdate(GOBJ *fighter);\nvoid Fighter_CreateReflect(GOBJ *fighter, ReflectDesc *reflect, void *cb_OnReflectHit);\nfloat Fighter_GetBoneRotation(FighterData *fighter, int bone);\nfloat Fighter_RotateBone_Pitch(FighterData *fighter, int bone, float angle);\nfloat Fighter_RotateBone_Yaw(FighterData *fighter, int bone, float angle);\nfloat Fighter_RotateBone_Roll(FighterData *fighter, int bone, float angle);\nvoid Fighter_PlayVoiceSFX(FighterData *fighter, int sfxID, int volume, int balance);\nvoid Fighter_ApplyOverlay(FighterData *fighter_data, int overlay, int unk);\nvoid Fighter_UpdateOverlay(GOBJ *fighter);\nvoid Fighter_DisableBlend(GOBJ *fighter, int animd_id);\nvoid Fighter_UpdateDynamics(GOBJ *fighter, u16 *dynamic_struct);\nvoid Fighter_ZeroCPUInputs(FighterData *fighter_data);\nvoid Fighter_CreateShieldGFX(GOBJ *fighter);\nvoid Fighter_UpdateShieldGFX(GOBJ *fighter, float size);\nint Fighter_GetShieldColorIndex(int ply);\nint Fighter_GetExternalID(int ply);\nint Fighter_GetCostumeID(int ply);\nfloat Fighter_GetBaseScale(FighterData *fighter);\nvoid Fighter_SetScale(GOBJ *fighter, float scale);\nvoid Fighter_InitDynamics(FighterData *fighter_data);\nvoid Fighter_ProcDynamics(GOBJ *fighter);\nfloat Fighter_GetKnockbackAngle(FighterData *fighter_data);\nvoid Fighter_UpdateCameraBox(GOBJ *fighter);\nvoid Fighter_SetAllHurtboxesNotUpdated(GOBJ *fighter);\nvoid Fighter_UpdateHurtboxes(FighterData *fighter_data);\nvoid Fighter_UpdateIK(GOBJ *fighter);\nvoid Fighter_ColorRemove(FighterData *fighter_data, int color_kind);\nvoid Fighter_CPUInitialize(FighterData *fighter_data, int cpu_kind, int cpu_level, int unk);\nint Fighter_GetCPUKind(int ply);\nint Fighter_GetCPULevel(int ply);\nchar *Fighter_GetName(int external_id);\nvoid Fighter_InitPObj();\nvoid Fighter_InitPObj2();\nvoid Fighter_IndexFtPartsDObjs(GOBJ *fighter, JOBJ *copy_model, FtParts *ftparts); // inits the dobj array in ftpartsmodel\nvoid Fighter_InitFtPartsModel(FtPartsDesc *ftpartsdesc, FtDOBJUnk *unk, int index, FtParts *ftparts, FtParts *ftparts2);\nint Fighter_CheckUnlocked(int ext_id);\nvoid Fighter_UpdateOnscreenBool(GOBJ *fighter);\n\n#endif\n"
  },
  {
    "path": "MexTK/include/hsd.h",
    "content": "#ifndef MEX_H_HSD\n#define MEX_H_HSD\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"obj.h\"\n#include \"color.h\"\n\n// button bits\n#define PAD_BUTTON_DPAD_LEFT 0x1\n#define PAD_BUTTON_DPAD_RIGHT 0x2\n#define PAD_BUTTON_DPAD_DOWN 0x4\n#define PAD_BUTTON_DPAD_UP 0x8\n#define PAD_TRIGGER_Z 0x10\n#define PAD_TRIGGER_R 0x20\n#define PAD_TRIGGER_L 0x40\n#define PAD_BUTTON_A 0x100\n#define PAD_BUTTON_B 0x200\n#define PAD_BUTTON_X 0x400\n#define PAD_BUTTON_Y 0x800\n#define PAD_BUTTON_START 0x1000\n#define PAD_BUTTON_UP 0x10000\n#define PAD_BUTTON_DOWN 0x20000\n#define PAD_BUTTON_LEFT 0x40000\n#define PAD_BUTTON_RIGHT 0x80000\n\n#define HSD_BUTTON_DPAD_LEFT 0x0001\n#define HSD_BUTTON_DPAD_RIGHT 0x0002\n#define HSD_BUTTON_DPAD_DOWN 0x0004\n#define HSD_BUTTON_DPAD_UP 0x0008\n#define HSD_TRIGGER_Z 0x0010\n#define HSD_TRIGGER_R 0x0020\n#define HSD_TRIGGER_L 0x0040\n#define HSD_BUTTON_A 0x0100\n#define HSD_BUTTON_B 0x0200\n#define HSD_BUTTON_X 0x0400\n#define HSD_BUTTON_Y 0x0800\n#define HSD_BUTTON_START 0x1000\n#define HSD_BUTTON_UP 0x10000\n#define HSD_BUTTON_DOWN 0x20000\n#define HSD_BUTTON_LEFT 0x40000\n#define HSD_BUTTON_RIGHT 0x80000\n\n/*** Structs ***/\n\nstruct HSD_ObjAllocData\n{\n    u32 flags;                     //0x00 - Technically 2 diff flags\n    void *freehead;                //0x04\n    u32 used;                      //0x08\n    u32 free;                      //0x0C\n    u32 peak;                      //0x10\n    u32 num_limit;                 //0x14\n    u32 heap_limit_size;           //0x18\n    u32 heap_limit_num;            //0x1C\n    u32 size;                      //0x20\n    u32 align;                     //0x24\n    struct HSD_ObjAllocData *next; //0x28\n};\n\nstruct HSD_Material\n{\n    GXColor ambient;\n    GXColor diffuse;\n    GXColor specular;\n    float alpha;\n    float shininess;\n};\n\nstruct HSD_Pad\n{\n    int held;            // 0x0\n    int heldPrev;        // 0x4\n    int down;            // 0x8\n    int rapidFire;       // 0xc\n    int up;              // 0x10\n    int rapidTimer;      // 0x14\n    s8 stickX;           // 0x18\n    s8 stickY;           // 0x19\n    s8 substickX;        // 0x1a\n    s8 substickY;        // 0x1b\n    u8 triggerLeft;      // 0x1c\n    u8 triggerRight;     // 0x1d\n    float fstickX;       // 0x20\n    float fstickY;       // 0x24\n    float fsubstickX;    // 0x28\n    float fsubstickY;    // 0x2c\n    float ftriggerLeft;  // 0x30\n    float ftriggerRight; // 0x34\n    float x38;           // 0x38\n    float x3c;           // 0x3c\n    u8 x40;              // 0x40\n    u8 status;           // 0x41   0 = plugged, -1 = unplugged\n};\n\nstruct HSD_Pads\n{\n    HSD_Pad pad[4];\n};\n\nstruct HSD_Update\n{\n    // 0x80479d58\n    u32 sys_frames_pre;                   //0x0\n    u32 sys_frames_post;                  //0x4\n    u32 engine_frames;                    //0x8\n    u32 change_scene;                     //0xC\n    unsigned char flag1 : 1;              //0x10 - 0x80\n    unsigned char flag2 : 1;              //0x10 - 0x40\n    unsigned char flag3 : 1;              //0x10 - 0x20\n    unsigned char flag4 : 1;              //0x10 - 0x10\n    unsigned char flag5 : 1;              //0x10 - 0x08\n    unsigned char flag6 : 1;              //0x10 - 0x04\n    unsigned char pause_game : 1;         //0x10 - 0x02\n    unsigned char pause_develop : 1;      //0x10 - 0x01\n    unsigned char flag9 : 1;              //0x11 - 0x80\n    unsigned char flag10 : 1;             //0x11 - 0x40\n    unsigned char flag11 : 1;             //0x11 - 0x20\n    unsigned char flag12 : 1;             //0x11 - 0x10\n    unsigned char flag13 : 1;             //0x11 - 0x08\n    unsigned char flag14 : 1;             //0x11 - 0x04\n    unsigned char pause_game_prev : 1;    //0x11 - 0x02\n    unsigned char pause_develop_prev : 1; //0x11 - 0x01\n    unsigned char flag17 : 1;             //0x12 - 0x80\n    unsigned char flag18 : 1;             //0x12 - 0x40\n    unsigned char flag19 : 1;             //0x12 - 0x20\n    unsigned char flag20 : 1;             //0x12 - 0x10\n    unsigned char flag21 : 1;             //0x12 - 0x08\n    unsigned char flag22 : 1;             //0x12 - 0x04\n    unsigned char flag23 : 1;             //0x12 - 0x02\n    unsigned char advance : 1;            //0x12 - 0x01\n    unsigned char flag24 : 1;             //0x12 - 0x80\n    unsigned char flag25 : 1;             //0x12 - 0x40\n    unsigned char flag26 : 1;             //0x12 - 0x20\n    unsigned char flag27 : 1;             //0x12 - 0x10\n    unsigned char flag28 : 1;             //0x12 - 0x08\n    unsigned char flag29 : 1;             //0x12 - 0x04\n    unsigned char flag30 : 1;             //0x12 - 0x02\n    unsigned char advance_prev : 1;       //0x12 - 0x01\n    int (*checkPause)();                  //0x14 returns 1 when toggling pause\n    int (*checkAdvance)();                //0x18 returns 1 when advancing frame\n    u32 x1c;                              //0x1C\n    u32 x20;\n    u32 x24;\n    u32 x28;\n    u32 x2c;\n    void (*onFrame)(); //0x30\n};\n\nstruct HSD_VI\n{\n    int x0;\n    int x4;\n    int is_prog;\n};\n\n/*** Static Variables ***/\nstatic HSD_VI *stc_HSD_VI = 0x8046b0f0;\n\n/*** Functions ***/\n\nint HSD_Randi(int max);\nfloat HSD_Randf();\nvoid *HSD_MemAlloc(int size);\nvoid HSD_Free(void *ptr);\nvoid *HSD_ObjAlloc(HSD_ObjAllocData *obj_def);\nvoid HSD_ObjFree(HSD_ObjAllocData *obj_def, void *obj);\nvoid HSD_ImageDescCopyFromEFB(_HSD_ImageDesc *image_desc, int left, int top, int z_flag);     // must be called from a cobj callback!\nvoid GX_AllocImageData(_HSD_ImageDesc *image_desc, int width, int height, int fmt, int size); // image data buffer is stored to the image_desc\nvoid GXTexModeSync();\nvoid GXPixModeSync();\nvoid GXInvalidateTexAll();\nu64 Pad_GetRapidHeld(int pad);\n#endif\n"
  },
  {
    "path": "MexTK/include/inline.h",
    "content": "#ifndef MEX_H_INLINE\n#define MEX_H_INLINE\n\n#include \"structs.h\"\n#include \"fighter.h\"\n#include \"obj.h\"\n#include \"mex.h\"\n#include \"datatypes.h\"\n#include \"hsd.h\"\n#include \"math.h\"\n#include \"useful.h\"\n\n/*** Functions ***/\n\nstatic float fabs(float x)\n{\n    if (x < 0)\n    {\n        return -x;\n    }\n    return x;\n}\n\nstatic int abs(int x)\n{\n    if (x < 0)\n    {\n        return -x;\n    }\n    return x;\n}\n\nstatic void enterKnockback(GOBJ *fighter, int angle, float mag)\n{\n    FighterData *fighter_data = ((FighterData *)fighter->userdata);\n\n    // store damage variables\n    fighter_data->dmg.force_applied = mag;\n    fighter_data->dmg.kb_angle = angle;\n    fighter_data->dmg.direction = fighter_data->facing_direction;\n    fighter_data->dmg.damaged_hurtbox = 0;\n    fighter_data->dmg.dealt = 0;\n    fighter_data->dmg.collpos.X = fighter_data->phys.pos.X;\n    fighter_data->dmg.collpos.Y = fighter_data->phys.pos.Y;\n    fighter_data->dmg.collpos.Z = fighter_data->phys.pos.Z;\n\n    Fighter_EnterDamageState(fighter, -1, 0);\n\n    return;\n}\n\nstatic void null()\n{\n    return;\n}\n\nstatic void __attribute__((optimize(\"O0\"))) PRIM_DRAW(PRIM *gx, float x, float y, float z, int color)\n{\n    AS_FLOAT(gx->data) = x;\n    AS_FLOAT(gx->data) = y;\n    AS_FLOAT(gx->data) = z;\n    gx->data = color;\n    return;\n}\n\nstatic void C_QUATMtx(Vec4 *r, Mtx m)\n{\n    /*---------------------------------------------------------------------------*\n   Name:         QUATMtx\n\n   Description:  Converts a matrix to a unit quaternion.\n\n   Arguments:    r   - result quaternion\n                m   - the matrix\n\n   Returns:      NONE\n    *---------------------------------------------------------------------------*/\n\n    float tr, s;\n    int i, j, k;\n    int nxt[3] = {1, 2, 0};\n    float q[3];\n\n    tr = m[0][0] + m[1][1] + m[2][2];\n    if (tr > 0.0f)\n    {\n        s = (float)sqrtf(tr + 1.0f);\n        r->W = s * 0.5f;\n        s = 0.5f / s;\n        r->X = (m[1][2] - m[2][1]) * s;\n        r->Y = (m[2][0] - m[0][2]) * s;\n        r->Z = (m[0][1] - m[1][0]) * s;\n    }\n    else\n    {\n        i = 0;\n        if (m[1][1] > m[0][0])\n            i = 1;\n        if (m[2][2] > m[i][i])\n            i = 2;\n        j = nxt[i];\n        k = nxt[j];\n        s = (float)sqrtf((m[i][i] - (m[j][j] + m[k][k])) + 1.0f);\n        q[i] = s * 0.5f;\n\n        if (s != 0.0f)\n            s = 0.5f / s;\n\n        r->W = (m[j][k] - m[k][j]) * s;\n        q[j] = (m[i][j] + m[j][i]) * s;\n        q[k] = (m[i][k] + m[k][i]) * s;\n\n        r->X = q[0];\n        r->Y = q[1];\n        r->Z = q[2];\n    }\n}\n\nstatic HSD_Pad *PadGet(int playerIndex, int padType)\n{\n    HSD_Pads *pads;\n\n    // get the correct pad\n    if (padType == PADGET_MASTER)\n        pads = 0x804c1fac;\n    else if (padType == PADGET_ENGINE)\n        pads = 0x804c21cc;\n\n    return (&pads->pad[playerIndex]);\n}\n\nstatic float lerp(Translation *anim, float currFrame)\n{\n    float prevFrame, prevPos, nextFrame, nextPos, amt;\n\n    // get previous threshold\n    int i = 0;\n    prevFrame = anim[i].frame;\n    prevPos = anim[i].value;\n    nextFrame = anim[i + 1].frame;\n    nextPos = anim[i + 1].value;\n    while ((currFrame < prevFrame) | (currFrame > nextFrame))\n    {\n        i++;\n        prevFrame = anim[i].frame;\n        prevPos = anim[i].value;\n        nextFrame = anim[i + 1].frame;\n        nextPos = anim[i + 1].value;\n    }\n\n    // get amt\n    amt = (currFrame - prevFrame) / (nextFrame - prevFrame);\n\n    return amt * (nextPos - prevPos) + prevPos;\n}\n\nstatic float JOBJ_GetAnimFrame(JOBJ *joint)\n{\n    // check for AOBJ in jobj\n    JOBJ *jobj;\n    jobj = joint;\n    while (jobj != 0)\n    {\n        if (jobj->aobj != 0)\n        {\n            return jobj->aobj->curr_frame;\n        }\n\n        // check for AOBJ in dobj\n        DOBJ *dobj;\n        dobj = jobj->dobj;\n        while (dobj != 0)\n        {\n            if (dobj->aobj != 0)\n            {\n                return dobj->aobj->curr_frame;\n            }\n\n            // check for AOBJ in mobj\n            MOBJ *mobj;\n            mobj = dobj->mobj;\n            if (mobj->aobj != 0)\n            {\n                return mobj->aobj->curr_frame;\n            }\n\n            // check for AOBJ in tobj\n            TOBJ *tobj;\n            tobj = mobj->tobj;\n            while (tobj != 0)\n            {\n                if (tobj->aobj != 0)\n                {\n                    return tobj->aobj->curr_frame;\n                }\n                tobj = tobj->next;\n            }\n\n            dobj = dobj->next;\n        }\n\n        jobj = jobj->child;\n    }\n\n    // no aobj found, return -1\n    return -1;\n}\n\nstatic AOBJ *JOBJ_GetFirstAOBJ(JOBJ *jobj)\n{\n    // check for AOBJ in this jobj\n\n    if (jobj->aobj != 0)\n    {\n        return jobj->aobj;\n    }\n    // check for AOBJ in dobj\n    DOBJ *dobj;\n    dobj = jobj->dobj;\n    while (dobj != 0)\n    {\n        if (dobj->aobj != 0)\n        {\n            return dobj->aobj;\n        }\n\n        // check for AOBJ in mobj\n        MOBJ *mobj;\n        mobj = dobj->mobj;\n        if (mobj->aobj != 0)\n        {\n            return mobj->aobj;\n        }\n\n        // check for AOBJ in tobj\n        TOBJ *tobj;\n        tobj = mobj->tobj;\n        while (tobj != 0)\n        {\n            if (tobj->aobj != 0)\n            {\n                return tobj->aobj;\n            }\n            tobj = tobj->next;\n        }\n\n        dobj = dobj->next;\n    }\n\n    // this jobj doesnt have an aobj, check the child\n    if (jobj->child != 0)\n    {\n        AOBJ *aobj = JOBJ_GetFirstAOBJ(jobj->child);\n        if (aobj != 0)\n            return aobj;\n    }\n\n    // child did not have an aobj, check the sibling\n    if (jobj->sibling != 0)\n    {\n        AOBJ *aobj = JOBJ_GetFirstAOBJ(jobj->sibling);\n        if (aobj != 0)\n            return aobj;\n    }\n\n    // no aobj found, return 0\n    return 0;\n}\n\nstatic AOBJ *JOBJ_GetJointAOBJ(JOBJ *jobj)\n{\n    // check for AOBJ in this jobj\n\n    if (jobj->aobj != 0)\n    {\n        return jobj->aobj;\n    }\n\n    // this jobj doesnt have an aobj, check the child\n    if (jobj->child != 0)\n    {\n        AOBJ *aobj = JOBJ_GetJointAOBJ(jobj->child);\n        if (aobj != 0)\n            return aobj;\n    }\n\n    // child did not have an aobj, check the sibling\n    if (jobj->sibling != 0)\n    {\n        AOBJ *aobj = JOBJ_GetJointAOBJ(jobj->sibling);\n        if (aobj != 0)\n            return aobj;\n    }\n\n    // no aobj found, return 0\n    return 0;\n}\n\nstatic DOBJ *JOBJ_GetDObjChild(JOBJ *joint, int dobj_index)\n{\n\n    int count = 0;\n    DOBJ *dobj = joint->dobj;\n\n    while (count < dobj_index)\n    {\n        if (dobj->next == 0)\n            assert(\"dobj not found!\");\n\n        else\n            dobj = dobj->next;\n\n        count++;\n    }\n\n    return dobj;\n}\n\nstatic float Math_Vec2Angle(Vec2 *a, Vec2 *b)\n{\n    // get angle\n    // float angle = atan((b->Y - a->Y) / (b->X - a->X));\n    float angle = atan2((b->Y - a->Y), (b->X - a->X));\n\n    /*\n    //Ensure above 0 and below 6.28319\n    while (angle < 0)\n    {\n        angle += M_PI;\n    }\n    while (angle > M_PI * 2)\n    {\n        angle -= M_PI;\n    }\n    */\n\n    return angle;\n}\n\nstatic float Math_Vec2Distance(Vec2 *a, Vec2 *b)\n{\n    return sqrtf(pow((a->X - b->X), 2) + pow((a->Y - b->Y), 2));\n}\n\nstatic float Math_Vec3Distance(Vec3 *a, Vec3 *b)\n{\n    return sqrtf(pow((a->X - b->X), 2) + pow((a->Y - b->Y), 2));\n}\n\n#endif\n"
  },
  {
    "path": "MexTK/include/item.h",
    "content": "#ifndef MEX_H_ITEM\n#define MEX_H_ITEM\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"obj.h\"\n#include \"color.h\"\n\n// Item IDs\n#define ITEM_CAPSULE 0\n#define ITEM_BOX 1\n#define ITEM_BARREL 2\n#define ITEM_EGG 3\n#define ITEM_PARTYBALL 4\n#define ITEM_BARRELCANNON 5\n#define ITEM_BOBOMB 6\n#define ITEM_MRSATURN 7\n#define ITEM_HEARTCONTAINER 8\n#define ITEM_MAXIMTOMATO 9\n#define ITEM_STARMAN 10\n#define ITEM_HOMERUNBAT 11\n#define ITEM_BEAMSWORD 12\n#define ITEM_PARASOL 13\n#define ITEM_GREENSHELL 14\n#define ITEM_REDSHELL 15\n#define ITEM_RAYGUN 16\n#define ITEM_FREEZIE 17\n#define ITEM_FOOD 18\n#define ITEM_MOTIONSENSORBOMB 19\n#define ITEM_FLIPPER 20\n#define ITEM_SUPERSCOPE 21\n#define ITEM_STARROD 22\n#define ITEM_LIPSSTICK 23\n#define ITEM_FAN 24\n#define ITEM_FIREFLOWER 25\n#define ITEM_SUPERMUSHROOM 26\n#define ITEM_POISONMUSHROOM 27\n#define ITEM_HAMMER 28\n#define ITEM_WARPSTAR 29\n#define ITEM_SCREWATTACK 30\n#define ITEM_BUNNYHOOD 31\n#define ITEM_METALBOX 32\n#define ITEM_CLOAKINGDEVICE 33\n#define ITEM_POKEBALL 34\n#define ITEM_RAYGUNUNK 35\n#define ITEM_STARRODSTAR 36\n#define ITEM_LIPSSTICKDUST 37\n#define ITEM_SUPERSCOPEBEAM 38\n#define ITEM_RAYGUNBEAM 39\n#define ITEM_HAMMERHEAD 40\n#define ITEM_FLOWER 41\n#define ITEM_YOSHISEGG 42\n#define ITEM_GOOMBA 43\n#define ITEM_REDEAD 44\n#define ITEM_OCTAROK 45\n#define ITEM_OTTOSEA 46\n#define ITEM_STONE 47\n#define ITEM_MARIOFIRE 48\n#define ITEM_DRMARIOPILL 49\n#define ITEM_KIRBYCUTTER 50\n#define ITEM_KIRBYHAMMER 51\n#define ITEM_KIRBYABILITYSTAR 52\n/*\n #define ITEM_ 53\n #define ITEM_ 54\n #define ITEM_ 55\n #define ITEM_ 56\n #define ITEM_ 57\n #define ITEM_ 58\n #define ITEM_ 59\n #define ITEM_ 60\n #define ITEM_ 61\n #define ITEM_ 62\n #define ITEM_ 63\n #define ITEM_ 64\n #define ITEM_ 65\n #define ITEM_ 66\n #define ITEM_ 67\n #define ITEM_ 68\n #define ITEM_ 69\n #define ITEM_ 70\n #define ITEM_ 71\n #define ITEM_ 72\n #define ITEM_ 73\n #define ITEM_ 74\n #define ITEM_ 75\n #define ITEM_ 76\n #define ITEM_ 77\n #define ITEM_ 78\n #define ITEM_ 79\n #define ITEM_ 80\n #define ITEM_ 81\n #define ITEM_ 82\n #define ITEM_ 83\n #define ITEM_ 84\n #define ITEM_ 85\n #define ITEM_ 86\n #define ITEM_ 87\n #define ITEM_ 88\n #define ITEM_ 89\n #define ITEM_ 90\n #define ITEM_ 91\n #define ITEM_ 92\n #define ITEM_ 93\n #define ITEM_ 94\n #define ITEM_ 95\n #define ITEM_ 96\n #define ITEM_ 97\n #define ITEM_ 98\n #define ITEM_ 99\n #define ITEM_ 100\n #define ITEM_ 101\n #define ITEM_ 102\n #define ITEM_ 103\n #define ITEM_ 104\n #define ITEM_ 105\n #define ITEM_ 106\n #define ITEM_ 107\n #define ITEM_ 108\n #define ITEM_ 109\n #define ITEM_ 110\n #define ITEM_ 111\n #define ITEM_ 112\n #define ITEM_ 113\n #define ITEM_ 114\n #define ITEM_ 115\n #define ITEM_ 116\n #define ITEM_ 117\n #define ITEM_ 118\n #define ITEM_ 119\n #define ITEM_ 120\n #define ITEM_ 121\n #define ITEM_ 122\n #define ITEM_ 123\n #define ITEM_ 124\n #define ITEM_ 125\n #define ITEM_ 126\n #define ITEM_ 127\n #define ITEM_ 128\n #define ITEM_ 129\n #define ITEM_ 130\n #define ITEM_ 131\n #define ITEM_ 132\n #define ITEM_ 133\n #define ITEM_ 134\n #define ITEM_ 135\n #define ITEM_ 136\n #define ITEM_ 137\n #define ITEM_ 138\n #define ITEM_ 139\n #define ITEM_ 140\n #define ITEM_ 141\n #define ITEM_ 142\n #define ITEM_ 143\n #define ITEM_ 144\n #define ITEM_ 145\n #define ITEM_ 146\n #define ITEM_ 147\n #define ITEM_ 148\n #define ITEM_ 149\n #define ITEM_ 150\n #define ITEM_ 151\n #define ITEM_ 152\n #define ITEM_ 153\n #define ITEM_ 154\n #define ITEM_ 155\n #define ITEM_ 156\n #define ITEM_ 157\n #define ITEM_ 158\n #define ITEM_ 159\n */\n#define ITEM_POKERANDOM 160\n#define ITEM_GOLDEEN 161\n#define ITEM_CHICORITA 162\n#define ITEM_SNORLAX 163\n#define ITEM_BLASTOISE 164\n#define ITEM_WEEZING 165\n#define ITEM_CHARIZARD 166\n#define ITEM_MOLTRES 167\n#define ITEM_ZAPDOS 168\n#define ITEM_ARCTICUNO 169\n#define ITEM_WOBBUFFET 170\n#define ITEM_SCIZOR 171\n#define ITEM_UNOWN 172\n#define ITEM_ENTEI 173\n#define ITEM_RAIKOU 174\n#define ITEM_SUICUNE 175\n#define ITEM_BELLOSSOM 176\n#define ITEM_ELECTRODE 177\n#define ITEM_LUGIA 178\n#define ITEM_HOOH 179\n#define ITEM_DITTO 180\n#define ITEM_CLEFAIRY 181\n#define ITEM_TOGEPI 182\n#define ITEM_MEW 183\n#define ITEM_CELEBI 184\n#define ITEM_STARYU 185\n#define ITEM_CHANSEY 186\n#define ITEM_PORYGON2 187\n#define ITEM_CYNDAQUIL 188\n#define ITEM_MARILL 189\n#define ITEM_VENUSAUR 190\n/*\n #define ITEM_ 191\n #define ITEM_ 192\n #define ITEM_ 193\n #define ITEM_ 194\n #define ITEM_ 195\n #define ITEM_ 196\n #define ITEM_ 197\n #define ITEM_ 198\n #define ITEM_ 199\n #define ITEM_ 200\n #define ITEM_ 201\n #define ITEM_ 202\n #define ITEM_ 203\n #define ITEM_ 204\n #define ITEM_ 205\n #define ITEM_ 206\n #define ITEM_ 207\n #define ITEM_ 208\n */\n#define ITEM_TARGET 209\n/*\n #define ITEM_ 210\n #define ITEM_ 211\n #define ITEM_ 212\n #define ITEM_ 213\n #define ITEM_ 214\n #define ITEM_ 215\n #define ITEM_ 216\n #define ITEM_ 217\n #define ITEM_ 218\n #define ITEM_ 219\n #define ITEM_ 220\n #define ITEM_ 221\n #define ITEM_ 222\n #define ITEM_ 223\n #define ITEM_ 224\n #define ITEM_ 225\n #define ITEM_ 226\n #define ITEM_ 227\n #define ITEM_ 228\n #define ITEM_ 229\n #define ITEM_ 230\n #define ITEM_ 231\n #define ITEM_ 232\n #define ITEM_ 233\n #define ITEM_ 234\n #define ITEM_ 235\n */\n\n// ItemStateChange Flags\n#define ITEMSTATE_UPDATEANIM 0x2\n#define ITEMSTATE_GRAB 0x4\n#define ITEMSTATE_KEEPHIT 0x10 // dont remove hitboxes on state change\n\n// Item hold_kind definitions\n#define ITHOLD_HAND 0  // held item, like a capsule\n#define ITHOLD_HEAVY 1 // overhead item, like a crate\n#define ITHOLD_NONE 8  // unable to be held\n\n/*** Structs ***/\n\nstruct itData\n{\n    int x0;\n    float *param_ext;\n    void *archive;\n    void *animFlags;\n    void *animDynamics;\n    int x14;\n    int x18;\n    int x1C;\n    int x20;\n    int x24;\n    int x28;\n    int dynamics;\n    int hurtbox;\n    int x34;\n    int x38;\n    int x3C;\n    int x40;\n    int coll;\n    int *items;\n    int x4C;\n    int x50;\n    int x54;\n    int boneLookup;\n};\n\nstruct itCommonAttr\n{\n    char flags1;                //0x0, bit 0x80 = is heavy item (crate)\n    unsigned char x1_1 : 1;     // 0x1 0x80\n    unsigned char x1_2 : 1;     // 0x1 0x40\n    unsigned char x1_3 : 1;     // 0x1 0x20\n    unsigned char x1_4 : 1;     // 0x1 0x10\n    unsigned char x1_5 : 1;     // 0x1 0x08\n    unsigned char cam_kind : 2; // 0x1 0x06, is stored to 0xdcd\n    unsigned char x1_8 : 1;     // 0x1 0x01    char flags3; //0x2\n    char flags4;                //0x3\n    int x4;\n    int x8;\n    float spinVelocity;\n    float fallSpeed;\n    float maxFallSpeed;\n    float x18;\n    float x1C;       //collision related\n    int x20;         // 0x20\n    int x24;         // 0x24\n    int x28;         // 0x28\n    int x2c;         // 0x2c\n    int x30;         // 0x30\n    int x34;         // 0x34\n    int x38;         // 0x38\n    int x3c;         // 0x3c\n    float ecb_top;   // 0x40\n    float ecb_bot;   // 0x44\n    float ecb_right; // 0x48\n    float ecb_left;  // 0x4c\n    int x50;         // 0x50\n    int x54;         // 0x54\n    int x58;         // 0x58\n    int x5c;         // 0x5c\n    int x60;         // 0x60\n    int x64;         // 0x64\n    int x68;         // 0x68\n    int x6c;         // 0x6c\n    int x70;         // 0x70\n    int x74;         // 0x74\n    int x78;         // 0x78\n    int x7c;         // 0x7c\n    int x80;         // 0x80\n    int x84;         // 0x84\n    int x88;         // 0x88\n    int x8c;         // 0x8c\n    int x90;         // 0x90\n    int x94;         // 0x94\n    int x98;         // 0x98\n    int x9c;         // 0x9c\n};\n\nstruct ItemState\n{\n    int state;\n    void *animCallback;\n    void *physCallback;\n    void *collCallback;\n};\n\nstruct SpawnItem\n{\n    GOBJ *parent_gobj;      // 0x0\n    GOBJ *parent_gobj2;     // 0x4\n    int it_kind;            // 0x8, id of the item to spawn\n    int hold_kind;          // 0xC, defines the behavior of the item, such as thrown and pickup. 0 = capsule\n    int unk2;               // 0x10\n    Vec3 pos;               // 0x14\n    Vec3 pos2;              // 0x20\n    Vec3 vel;               // 0x2C\n    float facing_direction; // 0x38\n    short damage;           // 0x3C\n    short unk5;             // 0x3E\n    int unk6;               // 0x40, 1 = correct initial position\n    char unk7;              // 0x44, 0x80 = perform initial collision check\n    int is_spin;            // 0x48, enables item spinning\n};\n\nstruct itHit\n{\n    int active;                   // 0x0\n    int x4;                       // 0x4, depends on\n    int dmg;                      // 0x8\n    float dmg_f;                  // 0xc\n    Vec3 offset;                  // 0x10\n    float size;                   // 0x1c\n    int angle;                    // 0x20\n    int kb_growth;                // 0x24\n    int wdsk;                     // 0x28\n    int kb;                       // 0x2c\n    int attribute;                // 0x30\n    int shield_dmg;               // 0x34\n    int hitsound_severity;        // 0x38. hurtbox interaction. 0 = none, 1 = grounded, 2 = aerial, 3 = both\n    int hitsound_kind;            // 0x3c\n    unsigned char x401 : 1;       // 0x40 0x80\n    unsigned char x402 : 1;       // 0x40 0x40\n    unsigned char hit_air : 1;    // 0x40 0x20. bool to check against aerial fighters\n    unsigned char hit_ground : 1; // 0x40 0x10. bool to check against grounded fighters\n    unsigned char x405 : 1;       // 0x40 0x08\n    unsigned char x406 : 1;       // 0x40 0x04\n    unsigned char x407 : 1;       // 0x40 0x02\n    unsigned char x408 : 1;       // 0x40 0x01\n    char x41;                     // 0x41\n    unsigned char x421 : 1;       // 0x42 0x80\n    unsigned char x422 : 1;       // 0x42 0x40\n    unsigned char hit_facing : 1; // 0x42 0x20. bool to only hit fighters facing the item\n    unsigned char x424 : 1;       // 0x42 0x10\n    unsigned char no_hurt : 1;    // 0x42 0x08      ignore hurtbox\n    unsigned char no_reflect : 1; // 0x42 0x04      ignore reflect?\n    unsigned char x427 : 1;       // 0x42 0x02\n    unsigned char x428 : 1;       // 0x42 0x01\n    unsigned char x431 : 1;       // 0x43 0x80\n    unsigned char x432 : 1;       // 0x43 0x40\n    unsigned char hit_all : 1;    // 0x43 0x20\n    unsigned char x434 : 1;       // 0x43 0x10\n    unsigned char x435 : 1;       // 0x43 0x08\n    unsigned char x436 : 1;       // 0x43 0x04\n    unsigned char x437 : 1;       // 0x43 0x02\n    unsigned char x438 : 1;       // 0x43 0x01\n    int x44;                      // 0x44\n    JOBJ *bone;                   // 0x48\n    Vec3 pos;                     // 0x4c\n    Vec3 pos_prev;                // 0x58\n    Vec3 pos_coll;                // 0x64   position of hurt collision\n    float coll_distance;          // 0x70   Distance From Collding Hurtbox (Used for phantom hit collision calculation)\n    GOBJ *victim;                 // 0x74\n    int x78;                      // 0x78\n    int x7c;                      // 0x7c\n    int x80;                      // 0x80\n    int x84;                      // 0x84\n    int x88;                      // 0x88\n    int x8c;                      // 0x8c\n    int x90;                      // 0x90\n    int x94;                      // 0x94\n    int x98;                      // 0x98\n    int x9c;                      // 0x9c\n    int xa0;                      // 0xa0\n    int xa4;                      // 0xa4\n    int xa8;                      // 0xa8\n    int xac;                      // 0xac\n    int xb0;                      // 0xb0\n    int xb4;                      // 0xb4\n    int xb8;                      // 0xb8\n    int xbc;                      // 0xbc\n    int xc0;                      // 0xc0\n    int xc4;                      // 0xc4\n    int xc8;                      // 0xc8\n    int xcc;                      // 0xcc\n    int xd0;                      // 0xd0\n    int xd4;                      // 0xd4\n    int xd8;                      // 0xd8\n    int xdc;                      // 0xdc\n    int xe0;                      // 0xe0\n    int xe4;                      // 0xe4\n    int xe8;                      // 0xe8\n    int xec;                      // 0xec\n    int xf0;                      // 0xf0\n    int xf4;                      // 0xf4\n    int xf8;                      // 0xf8\n    int xfc;                      // 0xfc\n    int x100;                     // 0x100\n    int x104;                     // 0x104\n    int x108;                     // 0x108\n    int x10c;                     // 0x10c\n    int x110;                     // 0x110\n    int x114;                     // 0x114\n    int x118;                     // 0x118\n    int x11c;                     // 0x11c\n    int x120;                     // 0x120\n    int x124;                     // 0x124\n    int x128;                     // 0x128\n    int x12c;                     // 0x12c\n    int x130;                     // 0x130\n    int x134;                     // 0x134\n    int x138;                     // 0x138\n};\n\nstruct ItemData\n{\n    int x0;                                  // 0x0\n    GOBJ *item;                              // 0x0\n    int x8;                                  // 0x8\n    int spawnType;                           // 0xC\n    int itemID;                              // 0x10\n    int x14;                                 // 0x14\n    int x18;                                 // 0x18\n    int x1c;                                 // 0x1c\n    int x20;                                 // 0x20\n    int stateID;                             // 0x24\n    int x28;                                 // 0x28\n    float facing_direction;                  // 0x2c\n    int x30;                                 // 0x30\n    float spinUnk;                           // 0x34\n    float scale;                             // 0x38\n    int x3c;                                 // 0x3c\n    Vec3 self_vel;                           // 0x40\n    Vec3 pos;                                // 0x4C\n    Vec3 unkVel;                             // 0x58-0x64\n    int x64;                                 // 0x64\n    int x68;                                 // 0x68\n    int x6c;                                 // 0x6c\n    Vec3 nudgeVel;                           // 0x70 - 0x7C\n    int x7c;                                 // 0x7c\n    int x80;                                 // 0x80\n    int x84;                                 // 0x84\n    int x88;                                 // 0x88\n    int x8c;                                 // 0x8c\n    int x90;                                 // 0x90\n    int x94;                                 // 0x94\n    int x98;                                 // 0x98\n    int x9c;                                 // 0x9c\n    int xa0;                                 // 0xa0\n    int xa4;                                 // 0xa4\n    int xa8;                                 // 0xa8\n    int xac;                                 // 0xac\n    int xb0;                                 // 0xb0\n    int xb4;                                 // 0xb4\n    void *it_cb;                             // 0xb8, global item callbacks\n    ItemState *itemStates;                   // 0xbc\n    int isRotate;                            // 0xc0\n    itData *itData;                          // 0xc4\n    JOBJ *joint;                             // 0xc8\n    itCommonAttr *itemAttributes;            // 0xcc\n    int xd0;                                 // 0xd0\n    int xd4;                                 // 0xd4\n    int xd8;                                 // 0xd8\n    int xdc;                                 // 0xdc\n    int xe0;                                 // 0xe0\n    int xe4;                                 // 0xe4\n    int xe8;                                 // 0xe8\n    int xec;                                 // 0xec\n    int xf0;                                 // 0xf0\n    int xf4;                                 // 0xf4\n    int xf8;                                 // 0xf8\n    int xfc;                                 // 0xfc\n    int x100;                                // 0x100\n    int x104;                                // 0x104\n    int x108;                                // 0x108\n    int x10c;                                // 0x10c\n    int x110;                                // 0x110\n    int x114;                                // 0x114\n    int x118;                                // 0x118\n    int x11c;                                // 0x11c\n    int x120;                                // 0x120\n    int x124;                                // 0x124\n    int x128;                                // 0x128\n    int x12c;                                // 0x12c\n    int x130;                                // 0x130\n    int x134;                                // 0x134\n    int x138;                                // 0x138\n    int x13c;                                // 0x13c\n    int x140;                                // 0x140\n    int x144;                                // 0x144\n    int x148;                                // 0x148\n    int x14c;                                // 0x14c\n    int x150;                                // 0x150\n    int x154;                                // 0x154\n    int x158;                                // 0x158\n    int x15c;                                // 0x15c\n    int x160;                                // 0x160\n    int x164;                                // 0x164\n    int x168;                                // 0x168\n    int x16c;                                // 0x16c\n    int x170;                                // 0x170\n    int x174;                                // 0x174\n    int x178;                                // 0x178\n    int x17c;                                // 0x17c\n    int x180;                                // 0x180\n    int x184;                                // 0x184\n    int x188;                                // 0x188\n    int x18c;                                // 0x18c\n    int x190;                                // 0x190\n    int x194;                                // 0x194\n    int x198;                                // 0x198\n    int x19c;                                // 0x19c\n    int x1a0;                                // 0x1a0\n    int x1a4;                                // 0x1a4\n    int x1a8;                                // 0x1a8\n    int x1ac;                                // 0x1ac\n    int x1b0;                                // 0x1b0\n    int x1b4;                                // 0x1b4\n    int x1b8;                                // 0x1b8\n    int x1bc;                                // 0x1bc\n    int x1c0;                                // 0x1c0\n    int x1c4;                                // 0x1c4\n    int x1c8;                                // 0x1c8\n    int x1cc;                                // 0x1cc\n    int x1d0;                                // 0x1d0\n    int x1d4;                                // 0x1d4\n    int x1d8;                                // 0x1d8\n    int x1dc;                                // 0x1dc\n    int x1e0;                                // 0x1e0\n    int x1e4;                                // 0x1e4\n    int x1e8;                                // 0x1e8\n    int x1ec;                                // 0x1ec\n    int x1f0;                                // 0x1f0\n    int x1f4;                                // 0x1f4\n    int x1f8;                                // 0x1f8\n    int x1fc;                                // 0x1fc\n    int x200;                                // 0x200\n    int x204;                                // 0x204\n    int x208;                                // 0x208\n    int x20c;                                // 0x20c\n    int x210;                                // 0x210\n    int x214;                                // 0x214\n    int x218;                                // 0x218\n    int x21c;                                // 0x21c\n    int x220;                                // 0x220\n    int x224;                                // 0x224\n    int x228;                                // 0x228\n    int x22c;                                // 0x22c\n    int x230;                                // 0x230\n    int x234;                                // 0x234\n    int x238;                                // 0x238\n    int x23c;                                // 0x23c\n    int x240;                                // 0x240\n    int x244;                                // 0x244\n    int x248;                                // 0x248\n    int x24c;                                // 0x24c\n    int x250;                                // 0x250\n    int x254;                                // 0x254\n    int x258;                                // 0x258\n    int x25c;                                // 0x25c\n    int x260;                                // 0x260\n    int x264;                                // 0x264\n    int x268;                                // 0x268\n    int x26c;                                // 0x26c\n    int x270;                                // 0x270\n    int x274;                                // 0x274\n    int x278;                                // 0x278\n    int x27c;                                // 0x27c\n    int x280;                                // 0x280\n    int x284;                                // 0x284\n    int x288;                                // 0x288\n    int x28c;                                // 0x28c\n    int x290;                                // 0x290\n    int x294;                                // 0x294\n    int x298;                                // 0x298\n    int x29c;                                // 0x29c\n    int x2a0;                                // 0x2a0\n    int x2a4;                                // 0x2a4\n    int x2a8;                                // 0x2a8\n    int x2ac;                                // 0x2ac\n    int x2b0;                                // 0x2b0\n    int x2b4;                                // 0x2b4\n    int x2b8;                                // 0x2b8\n    int x2bc;                                // 0x2bc\n    int x2c0;                                // 0x2c0\n    int x2c4;                                // 0x2c4\n    int x2c8;                                // 0x2c8\n    int x2cc;                                // 0x2cc\n    int x2d0;                                // 0x2d0\n    int x2d4;                                // 0x2d4\n    int x2d8;                                // 0x2d8\n    int x2dc;                                // 0x2dc\n    int x2e0;                                // 0x2e0\n    int x2e4;                                // 0x2e4\n    int x2e8;                                // 0x2e8\n    int x2ec;                                // 0x2ec\n    int x2f0;                                // 0x2f0\n    int x2f4;                                // 0x2f4\n    int x2f8;                                // 0x2f8\n    int x2fc;                                // 0x2fc\n    int x300;                                // 0x300\n    int x304;                                // 0x304\n    int x308;                                // 0x308\n    int x30c;                                // 0x30c\n    int x310;                                // 0x310\n    int x314;                                // 0x314\n    int x318;                                // 0x318\n    int x31c;                                // 0x31c\n    int x320;                                // 0x320\n    int x324;                                // 0x324\n    int x328;                                // 0x328\n    int x32c;                                // 0x32c\n    int x330;                                // 0x330\n    int x334;                                // 0x334\n    int x338;                                // 0x338\n    int x33c;                                // 0x33c\n    int x340;                                // 0x340\n    int x344;                                // 0x344\n    int x348;                                // 0x348\n    int x34c;                                // 0x34c\n    int x350;                                // 0x350\n    int x354;                                // 0x354\n    int x358;                                // 0x358\n    int x35c;                                // 0x35c\n    int x360;                                // 0x360\n    int x364;                                // 0x364\n    int x368;                                // 0x368\n    int x36c;                                // 0x36c\n    int x370;                                // 0x370\n    int x374;                                // 0x374\n    CollData coll_data;                      // 0x378 -> 0x518\n    FighterData *fighter;                    // 0x518\n    int x51c;                                // 0x51c\n    CameraBox *camerabox;                    // 0x520\n    int x524;                                // 0x524\n    int x528;                                // 0x528\n    int *script_parse;                       // 0x52c\n    int x530;                                // 0x530\n    int x534;                                // 0x534\n    int x538;                                // 0x538\n    int x53c;                                // 0x53c\n    int x540;                                // 0x540\n    int x544;                                // 0x544\n    ColorOverlay color;                      // 0x548\n    int x5c8;                                // 0x5c8\n    int x5cc;                                // 0x5cc\n    int x5d0;                                // 0x5d0\n    itHit hitbox[4];                         // 0x5d4\n    int xac4;                                // 0xac4\n    int xac8;                                // 0xac8\n    int hurt_status;                         // 0xacc\n    int xad0;                                // 0xad0\n    int xad4;                                // 0xad4\n    int xad8;                                // 0xad8\n    int xadc;                                // 0xadc\n    int xae0;                                // 0xae0\n    int xae4;                                // 0xae4\n    int xae8;                                // 0xae8\n    int xaec;                                // 0xaec\n    int xaf0;                                // 0xaf0\n    int xaf4;                                // 0xaf4\n    int xaf8;                                // 0xaf8\n    int xafc;                                // 0xafc\n    int xb00;                                // 0xb00\n    int xb04;                                // 0xb04\n    int xb08;                                // 0xb08\n    int xb0c;                                // 0xb0c\n    int xb10;                                // 0xb10\n    int xb14;                                // 0xb14\n    int xb18;                                // 0xb18\n    int xb1c;                                // 0xb1c\n    int xb20;                                // 0xb20\n    int xb24;                                // 0xb24\n    int xb28;                                // 0xb28\n    int xb2c;                                // 0xb2c\n    int xb30;                                // 0xb30\n    int xb34;                                // 0xb34\n    int xb38;                                // 0xb38\n    int xb3c;                                // 0xb3c\n    int xb40;                                // 0xb40\n    int xb44;                                // 0xb44\n    int xb48;                                // 0xb48\n    int xb4c;                                // 0xb4c\n    int xb50;                                // 0xb50\n    int xb54;                                // 0xb54\n    int xb58;                                // 0xb58\n    int xb5c;                                // 0xb5c\n    int xb60;                                // 0xb60\n    int xb64;                                // 0xb64\n    int xb68;                                // 0xb68\n    int xb6c;                                // 0xb6c\n    int xb70;                                // 0xb70\n    int xb74;                                // 0xb74\n    int xb78;                                // 0xb78\n    int xb7c;                                // 0xb7c\n    int xb80;                                // 0xb80\n    int xb84;                                // 0xb84\n    int xb88;                                // 0xb88\n    int xb8c;                                // 0xb8c\n    int xb90;                                // 0xb90\n    int xb94;                                // 0xb94\n    int xb98;                                // 0xb98\n    int xb9c;                                // 0xb9c\n    int xba0;                                // 0xba0\n    int xba4;                                // 0xba4\n    int xba8;                                // 0xba8\n    int xbac;                                // 0xbac\n    int xbb0;                                // 0xbb0\n    int xbb4;                                // 0xbb4\n    int xbb8;                                // 0xbb8\n    int xbbc;                                // 0xbbc\n    int xbc0;                                // 0xbc0\n    int xbc4;                                // 0xbc4\n    int xbc8;                                // 0xbc8\n    int xbcc;                                // 0xbcc\n    int xbd0;                                // 0xbd0\n    int xbd4;                                // 0xbd4\n    int xbd8;                                // 0xbd8\n    int xbdc;                                // 0xbdc\n    int xbe0;                                // 0xbe0\n    int xbe4;                                // 0xbe4\n    int xbe8;                                // 0xbe8\n    int xbec;                                // 0xbec\n    int xbf0;                                // 0xbf0\n    int xbf4;                                // 0xbf4\n    int xbf8;                                // 0xbf8\n    int xbfc;                                // 0xbfc\n    int xc00;                                // 0xc00\n    int xc04;                                // 0xc04\n    int xc08;                                // 0xc08\n    int xc0c;                                // 0xc0c\n    int xc10;                                // 0xc10\n    int xc14;                                // 0xc14\n    int xc18;                                // 0xc18\n    float ecb_top;                           // 0xc1c\n    float ecb_bottom;                        // 0xc20\n    float ecb_right;                         // 0xc24\n    float ecb_left;                          // 0xc28\n    int xc2c;                                // 0xc2c\n    int xc30;                                // 0xc30\n    int xc34;                                // 0xc34\n    int xc38;                                // 0xc38\n    int xc3c;                                // 0xc3c\n    int xc40;                                // 0xc40\n    int xc44;                                // 0xc44\n    int xc48;                                // 0xc48\n    int xc4c;                                // 0xc4c\n    int xc50;                                // 0xc50\n    int xc54;                                // 0xc54\n    int xc58;                                // 0xc58\n    int xc5c;                                // 0xc5c\n    int xc60;                                // 0xc60\n    int xc64;                                // 0xc64\n    int xc68;                                // 0xc68\n    int xc6c;                                // 0xc6c\n    int xc70;                                // 0xc70\n    int xc74;                                // 0xc74\n    int xc78;                                // 0xc78\n    int xc7c;                                // 0xc7c\n    int xc80;                                // 0xc80\n    int xc84;                                // 0xc84\n    int xc88;                                // 0xc88\n    int xc8c;                                // 0xc8c\n    int xc90;                                // 0xc90\n    int xc94;                                // 0xc94\n    int xc98;                                // 0xc98\n    int dmg_total;                           // 0xc9c\n    int dmg_recent;                          // 0xca0\n    int xca4;                                // 0xca4\n    int xca8;                                // 0xca8\n    int dmg_angle;                           // 0xcac\n    int xcb0;                                // 0xcb0\n    int xcb4;                                // 0xcb4\n    int xcb8;                                // 0xcb8\n    int xcbc;                                // 0xcbc\n    int xcc0;                                // 0xcc0\n    int xcc4;                                // 0xcc4\n    float dmg_kb;                            // 0xcc8\n    float dmg_direction;                     // 0xccc\n    int xcd0;                                // 0xcd0\n    int xcd4;                                // 0xcd4\n    int xcd8;                                // 0xcd8\n    int xcdc;                                // 0xcdc\n    int xce0;                                // 0xce0\n    int xce4;                                // 0xce4\n    int xce8;                                // 0xce8\n    GOBJ *dmgsource_fighter;                 // 0xcec\n    GOBJ *dmgsource_item;                    // 0xcf0\n    int xcf4;                                // 0xcf4\n    int xcf8;                                // 0xcf8\n    int xcfc;                                // 0xcfc\n    GOBJ *grabbedFighter;                    // 0xd00\n    int xd04;                                // 0xd04\n    int xd08;                                // 0xd08\n    int xd0c;                                // 0xd0c\n    int xd10;                                // 0xd10\n    struct                                   // cb\n    {                                        //\n        void (*anim)(GOBJ *item);            // 0xd14\n        void (*phys)(GOBJ *item);            // 0xd18\n        void (*coll)(GOBJ *item);            // 0xd1c\n        void (*accessory)(GOBJ *item);       // 0xd20\n        void *xd24;                          // 0xd24\n        void *xd28;                          // 0xd28\n        void *xd2c;                          // 0xd2c\n        void *jumped_on;                     // 0xd30, runs when the item is \"jumped on\", 80269bac\n        void *grabFt_onIt;                   // 0xd34, when grabbing a fighter, run this function on self\n        void *grabFt_onFt;                   // 0xd38, when grabbing a fighter, run this function on fighter\n    } cb;                                    //\n    float rotateSpeed;                       // 0xd3c\n    int xd40;                                // 0xd40\n    float lifetime;                          // 0xd44\n    int xd48;                                // 0xd48\n    int xd4c;                                // 0xd4c\n    int xd50;                                // 0xd50\n    int xd54;                                // 0xd54\n    int xd58;                                // 0xd58\n    int xd5c;                                // 0xd5c\n    int xd60;                                // 0xd60\n    int xd64;                                // 0xd64\n    int xd68;                                // 0xd68\n    int xd6c;                                // 0xd6c\n    int xd70;                                // 0xd70\n    int xd74;                                // 0xd74\n    int xd78;                                // 0xd78\n    int xd7c;                                // 0xd7c\n    int xd80;                                // 0xd80\n    int xd84;                                // 0xd84\n    int xd88;                                // 0xd88\n    int xd8c;                                // 0xd8c\n    int xd90;                                // 0xd90\n    int xd94;                                // 0xd94\n    int xd98;                                // 0xd98\n    int xd9c;                                // 0xd9c\n    int xda0;                                // 0xda0\n    int xda4;                                // 0xda4\n    char xda8;                               // 0xda8\n    char xda9;                               // 0xda8\n    unsigned char xdaa1 : 1;                 // 0xda8 0x80\n    unsigned char xdaa2 : 1;                 // 0xda8 0x40\n    unsigned char xdaa3 : 1;                 // 0xda8 0x20\n    unsigned char xdaa4 : 1;                 // 0xda8 0x10\n    unsigned char xdaa5 : 1;                 // 0xda8 0x08\n    unsigned char xdaa6 : 1;                 // 0xda8 0x04\n    unsigned char xdaa7 : 1;                 // 0xda8 0x02\n    unsigned char visible : 1;               // 0xda8 0x01\n    char xdab;                               // 0xda8\n    int scriptFlag1;                         // 0xdac\n    int scriptFlag2;                         // 0xdb0\n    int scriptFlag3;                         // 0xdb4\n    int xdb8;                                // 0xdb8\n    int scriptFlag4;                         // 0xdbc\n    int xdc0;                                // 0xdc0\n    int xdc4;                                // 0xdc4\n    u16 flags1 : 16;                         // 0xdc8\n    u16 xdca1 : 1;                           // 0xdca 0x80\n    u16 xdca2 : 1;                           // 0xdca 0x40\n    u16 xdca3 : 1;                           // 0xdca 0x20\n    u16 xdca4 : 1;                           // 0xdca 0x10\n    u16 xdca5 : 1;                           // 0xdca 0x08\n    u16 can_hold : 1;                        // 0xdca 0x04\n    u16 xdca7 : 1;                           // 0xdca 0x02\n    u16 rotateAxis : 3;                      // 0xdcb,\n    u16 flags4 : 2;                          // 0xdcb, 0x30\n    u16 can_nudge : 1;                       // 0xdcb, 0x08\n    u16 xdcb_7 : 3;                          // 0xdcb, 0x07\n    unsigned char xdcc1 : 1;                 // 0xdcc, 0x80\n    unsigned char xdcc2 : 1;                 // 0xdcc, 0x40\n    unsigned char xdcc3 : 1;                 // 0xdcc, 0x20\n    unsigned char isCheckBlastzone : 1;      // 0xdcc, 0x10\n    unsigned char isCheckRightBlastzone : 1; // 0xdcc, 0x08\n    unsigned char isCheckLeftBlastzone : 1;  // 0xdcc, 0x04\n    unsigned char isCheckUpBlastzone : 1;    // 0xdcc, 0x02\n    unsigned char isCheckDownBlastzone : 1;  // 0xdcc, 0x01\n    unsigned char cam_kind : 2;              // 0xdcd, 0xc0. indicates this item has a camera box\n    unsigned char xdcd3 : 1;                 // 0xdcd, 0x20\n    unsigned char xdcd4 : 1;                 // 0xdcd, 0x10\n    unsigned char xdcd5 : 1;                 // 0xdcd, 0x08\n    unsigned char xdcd6 : 1;                 // 0xdcd, 0x04\n    unsigned char xdcd7 : 1;                 // 0xdcd, 0x02\n    unsigned char xdcd8 : 1;                 // 0xdcd, 0x01\n    unsigned char xdce1 : 1;                 // 0xdce, 0x80\n    unsigned char xdce2 : 1;                 // 0xdce, 0x40\n    unsigned char xdce3 : 1;                 // 0xdce, 0x20\n    unsigned char xdce4 : 1;                 // 0xdce, 0x10\n    unsigned char xdce5 : 1;                 // 0xdce, 0x08\n    unsigned char xdce6 : 1;                 // 0xdce, 0x04\n    unsigned char xdce7 : 1;                 // 0xdce, 0x02\n    unsigned char xdce8 : 1;                 // 0xdce, 0x01\n    unsigned char xdcf1 : 1;                 // 0xdcf, 0x80\n    unsigned char xdcf2 : 1;                 // 0xdcf, 0x40\n    unsigned char xdcf3 : 1;                 // 0xdcf, 0x20\n    unsigned char xdcf4 : 1;                 // 0xdcf, 0x10\n    unsigned char xdcf5 : 1;                 // 0xdcf, 0x08\n    unsigned char xdcf6 : 1;                 // 0xdcf, 0x04\n    unsigned char xdcf7 : 1;                 // 0xdcf, 0x02\n    unsigned char xdcf8 : 1;                 // 0xdcf, 0x01\n    int xdd0;                                // 0xdd0\n    int itemVar1;                            // 0xdd4\n    int itemVar2;                            // 0xdd8\n    int itemVar3;                            // 0xddc\n    int itemVar4;                            // 0xde0\n    int itemVar5;                            // 0xde4\n    int itemVar6;                            // 0xde8\n    int itemVar7;                            // 0xdec\n    int itemVar8;                            // 0xdf0\n    int itemVar9;                            // 0xdf4\n    int itemVar10;                           // 0xdf8\n    int itemVar11;                           // 0xdfc\n    int itemVar12;                           // 0xe00\n    int xe04;                                // 0xe04\n    int xe08;                                // 0xe08\n    int xe0c;                                // 0xe0c\n    int xe10;                                // 0xe10\n    int xe14;                                // 0xe14\n    int xe18;                                // 0xe18\n    int xe1c;                                // 0xe1c\n    int xe20;                                // 0xe20\n    int xe24;                                // 0xe24\n    int xe28;                                // 0xe28\n    int xe2c;                                // 0xe2c\n    int xe30;                                // 0xe30\n    int xe34;                                // 0xe34\n    int xe38;                                // 0xe38\n    int xe3c;                                // 0xe3c\n};\n\n/*** Functions ***/\n\nvoid Item_Hold(GOBJ *item, GOBJ *fighter, int boneID);\nvoid Item_Catch(GOBJ *fighter, int unk);\nvoid Items_StoreItemDataToCharItemTable(undefined4, int);\nvoid Items_StoreItemDataToCharItemTable2(int articleData, int articleID);\nvoid Items_StoreTimeout(GOBJ *item, float timeout);\nGOBJ *Item_CreateItem(SpawnItem *item_spawn); // sorry for confusion, use this one for best results\nGOBJ *Item_CreateItem1(SpawnItem *item_spawn);\nGOBJ *Item_CreateItem2(SpawnItem *item_spawn);\nGOBJ *Item_CreateItem3(SpawnItem *item_spawn);\nvoid Item_Destroy(GOBJ *item);\nint Item_CollGround_PassLedge(GOBJ *item, void *callback);\nint Item_CollGround_StopLedge(GOBJ *item, void *callback);\nint Item_CollAir(GOBJ *item, void *callback);\nvoid ItemStateChange(GOBJ *item, int stateID, int flags);\nint ItemFrameTimer(GOBJ *item);\nvoid Item_PlaceOnGroundBelow(GOBJ *item);\nint Item_CheckIfTouchingWall(GOBJ *item, float *unk[]);\nvoid Item_InitGrab(ItemData *item, int unk, void *OnItem, void *OnFighter);\nvoid Item_ResetAllHitPlayers(ItemData *item);\nint Item_CountActiveItems(int itemID);\nvoid Item_CopyDevelopState(GOBJ *item, GOBJ *fighter);\nint Items_DecLife(GOBJ *item);\nvoid GXLink_Item(GOBJ *gobj, int pass);\nvoid Item_UpdateSpin(GOBJ *item, float unk);\nvoid Item_EnableSpin(GOBJ *item);\nvoid Item_DisableSpin(GOBJ *item);\nvoid Item_SetLifeTimer(GOBJ *item, float lifetime); // sets frames until item is destroyed\nint Item_DecLifeTimer(GOBJ *item);                  // returns isEnd bool\nJOBJ *Item_GetBoneJOBJ(GOBJ *item, int bone_index);\nint Item_CheckIfEnabled(); // returns bool regarding if items are enabled for this match\nvoid Barrel_EnterBreak(GOBJ *item);\n\n#endif\n"
  },
  {
    "path": "MexTK/include/kirby.h",
    "content": "#ifndef MEX_H_KIRBY\n#define MEX_H_KIRBY\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"obj.h\"\n#include \"color.h\"\n#include \"effects.h\"\n#include \"match.h\"\n#include \"collision.h\"\n\nstruct FtVarKirby\n{\n    int charVar1;          // 0x222c\n    int charVar2;          // 0x2230\n    int charVar3;          // 0x2234\n    int copy_index;        // 0x2238\n    JOBJ *copy_jobj;       // 0x223c\n    FtParts ftparts_model; // 0x2240\n    FtDOBJUnk ftdobj_unk;  // 0x2250\n};\n\n#endif\n"
  },
  {
    "path": "MexTK/include/match.h",
    "content": "#ifndef MEX_H_MATCH\n#define MEX_H_MATCH\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"obj.h\"\n#include \"fighter.h\"\n\n// Match Data definitions\n#define MATCH_TIMER_FROZEN 0\n#define MATCH_TIMER_HIDE 1\n#define MATCH_TIMER_COUNTDOWN 2\n#define MATCH_TIMER_COUNTUP 3\n#define MATCH_MATCHTYPE_TIME 0\n#define MATCH_MATCHTYPE_STOCK 1\n#define MATCH_MATCHTYPE_COIN 2\n#define MATCH_HUDPOS_NONE 0\n#define MATCH_HUDPOS_ONE 1\n#define MATCH_HUDPOS_TWO 2\n#define MATCH_HUDPOS_THREE 3\n#define MATCH_HUDPOS_FOUR 4\n#define MATCH_HUDPOS_SIX 5\n#define MATCH_HUDPOS_UNK 6\n#define MATCH_HUDPOS_FOURCOMPACT 7\n#define MATCH_PAUSEHUD_HIDE 1\n#define MATCH_MATCHTYPE_STOCK 1\n#define MATCH_MATCHTYPE_COIN 2\n#define MATCH_ITEMFREQ_OFF -1\n#define MATCH_ITEMFREQ_VERYLOW 0\n#define MATCH_ITEMFREQ_LOW 1\n#define MATCH_ITEMFREQ_MEDIUM 2\n#define MATCH_ITEMFREQ_HIGH 3\n#define MATCH_ITEMFREQ_VERYHIGH 4\n\n/*** Structs ***/\n\nstruct MatchInit\n{\n    // byte 0x0\n    unsigned char matchType : 3;\n    unsigned char hudPos : 3;\n    unsigned char timer : 2;\n    // byte 0x1\n    unsigned char timer_unk2 : 1;\n    unsigned char unk4 : 1;\n    unsigned char hideReady : 1;\n    unsigned char hideGo : 1;\n    unsigned char isDisableMusic : 1;\n    unsigned char unk3 : 1;\n    unsigned char timer_unk : 1;\n    unsigned char unk2 : 1;\n    // byte 0x2\n    unsigned char unk9 : 1;\n    unsigned char disableOffscreenDamage : 1;\n    unsigned char unk8 : 1;\n    unsigned char isSingleButtonMode : 1;\n    unsigned char isDisablePause : 1;\n    unsigned char unk7 : 1;\n    unsigned char isCreateHUD : 1;\n    unsigned char unk5 : 1;\n    // byte 0x3\n    unsigned char isShowScore : 1;        // 0x80\n    unsigned char isShowAnalogStick : 1;  // 0x40\n    unsigned char isCheckForZRetry : 1;   // 0x20\n    unsigned char isShowZRetry : 1;       // 0x10\n    unsigned char isCheckForLRAStart : 1; // 0x08\n    unsigned char isShowLRAStart : 1;     // 0x04\n    unsigned char isHidePauseHUD : 1;     // 0x02\n    unsigned char timerRunOnPause : 1;    // 0x01\n    //byte 0x4\n    unsigned char unk11 : 1;             // 0x80\n    unsigned char isCheckStockSteal : 1; // 0x40\n    unsigned char isRunStockLogic : 1;   // 0x20\n    unsigned char unk10 : 5;             // 0x01\n    //byte 0x5\n    unsigned char isSkipEndCheck : 1;      // 0x80\n    unsigned char isSkipUnkStockCheck : 1; // 0x40\n    unsigned char isDisableHit : 1;        // 0x20\n    unsigned char unk12 : 5;               // 0x01\n    // byte 0x6\n    u8 bombRain; // 0xFF\n    //byte 0x7\n    u8 unk13; // 0xFF\n    //byte 0x8\n    u8 isTeams; // 0xFF\n    //byte 0x9\n    u8 isKOCounterActive; // 0xFF\n    //byte 0xA\n    u8 unk14; // 0xFF\n    //byte 0xB\n    u8 itemFreq; // 0xFF\n    //byte 0xC\n    u8 unk15; // 0xFF\n    //byte 0xD\n    u8 unk16; // 0xFF\n    //byte 0xE\n    u16 stage; // 0xFFFF\n    //byte 0x10\n    int timerSeconds : 32; // 0xFFFFFFFF\n    //byte 0x14\n    u8 timerSubSeconds; // 0xFF\n    //0x18\n    int unk17; // 0xFFFFFFFF\n    //0x1C\n    unsigned long long itemSwitch : 64; // 0xFFFFFFFF FFFFFFFF\n    //byte 0x24\n    int unk18; // 0xFFFFFFFF\n    //0x28\n    float cameraShakeMult;\n    //0x2C\n    float unk19;\n    //0x30\n    float unk20;\n    //0x34\n    int x34;\n    //0x38\n    int x38;\n    //0x3C\n    int x3c;\n    //0x40\n    void *onStartMelee;\n    //0x44\n    int unk21;\n    //0x48\n    void *onCheckPause;\n    //0x4C\n    int unk22;\n    //0x50\n    void *onMatchFrame1;\n    //0x54\n    void *onMatchFrame2;\n    //0x58\n    void *onMatchEnd;\n    /*\n    //0x5C\n    int x5c;\n\n    //0x60\n    int x60;\n    //0x64\n    int x64;\n*/\n    // player data\n    PlayerData playerData[6];\n};\n\nstruct MatchHUD\n{\n    GOBJ *percent;\n    GOBJ *insignia;\n    u8 x8;\n    u8 x9;\n    u16 xa;\n    u16 xc;\n    u8 xe;\n    u8 xf;\n    unsigned char is_removed : 1; // 0x80 - 0x10\n    unsigned char x10_2 : 1;      // 0x40 - 0x10\n    unsigned char x10_3 : 1;      // 0x20 - 0x10\n    unsigned char x10_4 : 1;      // 0x10 - 0x10\n    unsigned char x10_5 : 1;      // 0x08 - 0x10\n    unsigned char x10_6 : 1;      // 0x04 - 0x10\n    unsigned char x10_7 : 1;      // 0x02 - 0x10\n    unsigned char x10_8 : 1;      // 0x01 - 0x10\n    u8 x11;\n    u8 x12;\n    u8 x13;\n    float x14[3];\n    float percent_digitpos[4]; // 3 digits and the percent sign\n    int x34[8];\n    JOBJ *x54[5];\n};\n\nstruct CameraBox\n{\n    void *alloc;            // 0x0\n    CameraBox *next;        // 0x4\n    int kind;               // 0x8 2 = only focus if close to center\n    int flags;              // 0xC\n    Vec3 cam_pos;           // 0x10\n    Vec3 bone_pos;          // 0x1c\n    float direction;        // 0x28\n    float boundleft_curr;   // 0x2C\n    float boundright_curr;  // 0x30\n    float boundtop_curr;    // 0x34\n    float boundbottom_curr; // 0x38\n    float x3c;              // 0x3c\n    float boundleft_proj;   // 0x40\n    float boundright_proj;  // 0x44\n    float boundtop_proj;    // 0x48\n    float boundbottom_proj; // 0x4c\n};\n\nstruct MatchCamera\n{\n    int x0;                      // 0x0\n    int cam_kind;                // 0x4\n    int x8;                      // 0x8\n    int xc;                      // 0xc\n    int x10;                     // 0x10\n    int x14;                     // 0x14\n    int x18;                     // 0x18\n    int x1c;                     // 0x1c\n    int x20;                     // 0x20\n    int x24;                     // 0x24\n    int x28;                     // 0x28\n    int x2c;                     // 0x2c\n    int x30;                     // 0x30\n    int x34;                     // 0x34\n    int x38;                     // 0x38\n    int x3c;                     // 0x3c\n    int x40;                     // 0x40\n    int x44;                     // 0x44\n    int x48;                     // 0x48\n    int x4c;                     // 0x4c\n    int x50;                     // 0x50\n    int x54;                     // 0x54\n    int x58;                     // 0x58\n    int x5c;                     // 0x5c\n    int x60;                     // 0x60\n    int x64;                     // 0x64\n    int x68;                     // 0x68\n    int x6c;                     // 0x6c\n    int x70;                     // 0x70\n    int x74;                     // 0x74\n    int x78;                     // 0x78\n    int x7c;                     // 0x7c\n    int x80;                     // 0x80\n    int x84;                     // 0x84\n    int x88;                     // 0x88\n    int x8c;                     // 0x8c\n    int x90;                     // 0x90\n    int x94;                     // 0x94\n    int x98;                     // 0x98\n    int x9c;                     // 0x9c\n    int xa0;                     // 0xa0\n    int xa4;                     // 0xa4\n    int xa8;                     // 0xa8\n    int xac;                     // 0xac\n    int xb0;                     // 0xb0\n    int xb4;                     // 0xb4\n    int xb8;                     // 0xb8\n    int xbc;                     // 0xbc\n    int xc0;                     // 0xc0\n    int xc4;                     // 0xc4\n    int xc8;                     // 0xc8\n    int xcc;                     // 0xcc\n    int xd0;                     // 0xd0\n    int xd4;                     // 0xd4\n    int xd8;                     // 0xd8\n    int xdc;                     // 0xdc\n    int xe0;                     // 0xe0\n    int xe4;                     // 0xe4\n    int xe8;                     // 0xe8\n    int xec;                     // 0xec\n    int xf0;                     // 0xf0\n    int xf4;                     // 0xf4\n    int xf8;                     // 0xf8\n    int xfc;                     // 0xfc\n    int x100;                    // 0x100\n    int x104;                    // 0x104\n    int x108;                    // 0x108\n    int x10c;                    // 0x10c\n    int x110;                    // 0x110\n    int x114;                    // 0x114\n    int x118;                    // 0x118\n    int x11c;                    // 0x11c\n    int x120;                    // 0x120\n    int x124;                    // 0x124\n    int x128;                    // 0x128\n    int x12c;                    // 0x12c\n    int x130;                    // 0x130\n    int x134;                    // 0x134\n    int x138;                    // 0x138\n    int x13c;                    // 0x13c\n    int x140;                    // 0x140\n    int x144;                    // 0x144\n    int x148;                    // 0x148\n    int x14c;                    // 0x14c\n    int x150;                    // 0x150\n    int x154;                    // 0x154\n    int x158;                    // 0x158\n    int x15c;                    // 0x15c\n    int x160;                    // 0x160\n    int x164;                    // 0x164\n    int x168;                    // 0x168\n    int x16c;                    // 0x16c\n    int x170;                    // 0x170\n    int x174;                    // 0x174\n    int x178;                    // 0x178\n    int x17c;                    // 0x17c\n    int x180;                    // 0x180\n    int x184;                    // 0x184\n    int x188;                    // 0x188\n    int x18c;                    // 0x18c\n    int x190;                    // 0x190\n    int x194;                    // 0x194\n    int x198;                    // 0x198\n    int x19c;                    // 0x19c\n    int x1a0;                    // 0x1a0\n    int x1a4;                    // 0x1a4\n    int x1a8;                    // 0x1a8\n    int x1ac;                    // 0x1ac\n    int x1b0;                    // 0x1b0\n    int x1b4;                    // 0x1b4\n    int x1b8;                    // 0x1b8\n    int x1bc;                    // 0x1bc\n    int x1c0;                    // 0x1c0\n    int x1c4;                    // 0x1c4\n    int x1c8;                    // 0x1c8\n    int x1cc;                    // 0x1cc\n    int x1d0;                    // 0x1d0\n    int x1d4;                    // 0x1d4\n    int x1d8;                    // 0x1d8\n    int x1dc;                    // 0x1dc\n    int x1e0;                    // 0x1e0\n    int x1e4;                    // 0x1e4\n    int x1e8;                    // 0x1e8\n    int x1ec;                    // 0x1ec\n    int x1f0;                    // 0x1f0\n    int x1f4;                    // 0x1f4\n    int x1f8;                    // 0x1f8\n    int x1fc;                    // 0x1fc\n    int x200;                    // 0x200\n    int x204;                    // 0x204\n    int x208;                    // 0x208\n    int x20c;                    // 0x20c\n    int x210;                    // 0x210\n    int x214;                    // 0x214\n    int x218;                    // 0x218\n    int x21c;                    // 0x21c\n    int x220;                    // 0x220\n    int x224;                    // 0x224\n    int x228;                    // 0x228\n    int x22c;                    // 0x22c\n    int x230;                    // 0x230\n    int x234;                    // 0x234\n    int x238;                    // 0x238\n    int x23c;                    // 0x23c\n    int x240;                    // 0x240\n    int x244;                    // 0x244\n    int x248;                    // 0x248\n    int x24c;                    // 0x24c\n    int x250;                    // 0x250\n    int x254;                    // 0x254\n    int x258;                    // 0x258\n    int x25c;                    // 0x25c\n    int x260;                    // 0x260\n    int x264;                    // 0x264\n    int x268;                    // 0x268\n    int x26c;                    // 0x26c\n    int x270;                    // 0x270\n    int x274;                    // 0x274\n    int x278;                    // 0x278\n    int x27c;                    // 0x27c\n    int x280;                    // 0x280\n    int x284;                    // 0x284\n    int x288;                    // 0x288\n    int x28c;                    // 0x28c\n    int x290;                    // 0x290\n    int x294;                    // 0x294\n    int x298;                    // 0x298\n    int x29c;                    // 0x29c\n    int x2a0;                    // 0x2a0\n    int x2a4;                    // 0x2a4\n    int x2a8;                    // 0x2a8\n    int x2ac;                    // 0x2ac\n    int x2b0;                    // 0x2b0\n    int x2b4;                    // 0x2b4\n    int x2b8;                    // 0x2b8\n    int x2bc;                    // 0x2bc\n    int x2c0;                    // 0x2c0\n    int x2c4;                    // 0x2c4\n    int x2c8;                    // 0x2c8\n    int x2cc;                    // 0x2cc\n    int x2d0;                    // 0x2d0\n    int x2d4;                    // 0x2d4\n    int x2d8;                    // 0x2d8\n    int x2dc;                    // 0x2dc\n    int x2e0;                    // 0x2e0\n    int x2e4;                    // 0x2e4\n    int x2e8;                    // 0x2e8\n    float freecam_tilt_vertical; // 0x2ec, uses radians\n    int x2f0;                    // 0x2f0\n    int x2f4;                    // 0x2f4\n    float freecam_zoommax;       // 0x2f8\n    float freecam_zoommin;       // 0x2fc\n    int x300;                    // 0x300\n    int x304;                    // 0x304\n    Vec3 freecam_pos;            // 0x308\n    Vec3 freecam_offset;         // 0x314                // 0x314\n    Vec2 freecam_rotate;         // 0x320\n    Vec3 freecam_fov;            // 0x328\n    int x334;                    // 0x334\n    int x338;                    // 0x338\n    int x33c;                    // 0x33c\n    int x340;                    // 0x340\n    int x344;                    // 0x344\n    int x348;                    // 0x348\n    int x34c;                    // 0x34c\n    int x350;                    // 0x350\n    int x354;                    // 0x354\n    int x358;                    // 0x358\n    int x35c;                    // 0x35c\n    int x360;                    // 0x360\n    int x364;                    // 0x364\n    int x368;                    // 0x368\n    int x36c;                    // 0x36c\n    int x370;                    // 0x370\n    int x374;                    // 0x374\n    int x378;                    // 0x378\n    int x37c;                    // 0x37c\n    int x380;                    // 0x380\n    int x384;                    // 0x384\n    int x388;                    // 0x388\n    int x38c;                    // 0x38c\n    int x390;                    // 0x390\n    int x394;                    // 0x394\n    char x398;                   // 0x398\n    unsigned char x399x80 : 1;\n    unsigned char x399x40 : 1;\n    unsigned char x399x20 : 1;\n    unsigned char show_coll : 1;\n    unsigned char x399x08 : 1;\n    unsigned char x399x04 : 1;\n    unsigned char x399x02 : 1;\n    unsigned char x399x01 : 1;\n    char x39a;        // 0x39a\n    char x39b;        // 0x39b\n    int x39c;         // 0x39c\n    int x3a0;         // 0x3a0\n    int x3a4;         // 0x3a4\n    int x3a8;         // 0x3a8\n    int x3ac;         // 0x3ac\n    int x3b0;         // 0x3b0\n    int x3b4;         // 0x3b4\n    int x3b8;         // 0x3b8\n    int x3bc;         // 0x3bc\n    int x3c0;         // 0x3c0\n    int x3c4;         // 0x3c4\n    int x3c8;         // 0x3c8\n    int x3cc;         // 0x3cc\n    int x3d0;         // 0x3d0\n    int x3d4;         // 0x3d4\n    Vec3 devcam_pos;  // 0x3d8\n    Vec3 devcam_rot;  // 0x3e4\n    float devcam_fov; // 0x3f0\n    int x3f4;         // 0x3f4\n    int x3f8;         // 0x3f8\n    int x3fc;         // 0x3fc\n};\n\nstruct MatchOffscreen\n{\n    void *x0;\n    void *x4;\n    void *x8;\n    unsigned char is_offscreen : 1;     // 0xC, 0x80\n    unsigned char ignore_offscreen : 1; // 0xC, 0x40\n    unsigned char x3f : 6;              // 0xC, 0x3f\n    void *x10;\n};\n\nstruct Match // static match struct @ 8046b6a0\n{\n    u8 state;         // 0x0\n    u8 pauser;        // 0x1\n    int x4;           // 0x4\n    int x8;           // 0x8\n    int xc;           // 0xc\n    int x10;          // 0x10\n    int x14;          // 0x14\n    int x18;          // 0x18\n    int x1c;          // 0x1c\n    int x20;          // 0x20\n    int time_frames;  // 0x24\n    int time_seconds; // 0x28\n    u16 time_ms;      // 0x2c, counts frame 0-59\n    int x30;          // 0x30\n    int x34;          // 0x34\n    int x38;          // 0x38\n    int x3c;          // 0x3c\n    int x40;          // 0x40\n    int x44;          // 0x44\n    int x48;          // 0x48\n    int x4c;          // 0x4c\n    int x50;          // 0x50\n    int x54;          // 0x54\n    int x58;          // 0x58\n    int x5c;          // 0x5c\n    int x60;          // 0x60\n    int x64;          // 0x64\n    int x68;          // 0x68\n    int x6c;          // 0x6c\n    int x70;          // 0x70\n    int x74;          // 0x74\n    int x78;          // 0x78\n    int x7c;          // 0x7c\n    int x80;          // 0x80\n    int x84;          // 0x84\n    int x88;          // 0x88\n    int x8c;          // 0x8c\n    int x90;          // 0x90\n    int x94;          // 0x94\n    int x98;          // 0x98\n    int x9c;          // 0x9c\n    int xa0;          // 0xa0\n    int xa4;          // 0xa4\n    int xa8;          // 0xa8\n    int xac;          // 0xac\n    int xb0;          // 0xb0\n    int xb4;          // 0xb4\n    int xb8;          // 0xb8\n    int xbc;          // 0xbc\n    int xc0;          // 0xc0\n    int xc4;          // 0xc4\n    int xc8;          // 0xc8\n    int xcc;          // 0xcc\n    int xd0;          // 0xd0\n    int xd4;          // 0xd4\n    int xd8;          // 0xd8\n    int xdc;          // 0xdc\n    int xe0;          // 0xe0\n    int xe4;          // 0xe4\n    int xe8;          // 0xe8\n    int xec;          // 0xec\n    int xf0;          // 0xf0\n    int xf4;          // 0xf4\n    int xf8;          // 0xf8\n    int xfc;          // 0xfc\n    int x100;         // 0x100\n    int x104;         // 0x104\n    int x108;         // 0x108\n    int x10c;         // 0x10c\n    int x110;         // 0x110\n    int x114;         // 0x114\n    int x118;         // 0x118\n    int x11c;         // 0x11c\n    int x120;         // 0x120\n    int x124;         // 0x124\n    int x128;         // 0x128\n    int x12c;         // 0x12c\n    int x130;         // 0x130\n    int x134;         // 0x134\n    int x138;         // 0x138\n    int x13c;         // 0x13c\n    int x140;         // 0x140\n    int x144;         // 0x144\n    int x148;         // 0x148\n    int x14c;         // 0x14c\n    int x150;         // 0x150\n    int x154;         // 0x154\n    int x158;         // 0x158\n    int x15c;         // 0x15c\n    int x160;         // 0x160\n    int x164;         // 0x164\n    int x168;         // 0x168\n    int x16c;         // 0x16c\n    int x170;         // 0x170\n    int x174;         // 0x174\n    int x178;         // 0x178\n    int x17c;         // 0x17c\n    int x180;         // 0x180\n    int x184;         // 0x184\n    int x188;         // 0x188\n    int x18c;         // 0x18c\n    int x190;         // 0x190\n    int x194;         // 0x194\n    int x198;         // 0x198\n    int x19c;         // 0x19c\n    int x1a0;         // 0x1a0\n    int x1a4;         // 0x1a4\n    int x1a8;         // 0x1a8\n    int x1ac;         // 0x1ac\n    int x1b0;         // 0x1b0\n    int x1b4;         // 0x1b4\n    int x1b8;         // 0x1b8\n    int x1bc;         // 0x1bc\n    int x1c0;         // 0x1c0\n    int x1c4;         // 0x1c4\n    int x1c8;         // 0x1c8\n    int x1cc;         // 0x1cc\n    int x1d0;         // 0x1d0\n    int x1d4;         // 0x1d4\n    int x1d8;         // 0x1d8\n    int x1dc;         // 0x1dc\n    int x1e0;         // 0x1e0\n    int x1e4;         // 0x1e4\n    int x1e8;         // 0x1e8\n    int x1ec;         // 0x1ec\n    int x1f0;         // 0x1f0\n    int x1f4;         // 0x1f4\n    int x1f8;         // 0x1f8\n    int x1fc;         // 0x1fc\n    int x200;         // 0x200\n    int x204;         // 0x204\n    int x208;         // 0x208\n    int x20c;         // 0x20c\n    int x210;         // 0x210\n    int x214;         // 0x214\n    int x218;         // 0x218\n    int x21c;         // 0x21c\n    int x220;         // 0x220\n    int x224;         // 0x224\n    int x228;         // 0x228\n    int x22c;         // 0x22c\n    int x230;         // 0x230\n    int x234;         // 0x234\n    int x238;         // 0x238\n    int x23c;         // 0x23c\n    int x240;         // 0x240\n    int x244;         // 0x244\n    int x248;         // 0x248\n    int x24c;         // 0x24c\n    int x250;         // 0x250\n    int x254;         // 0x254\n    int x258;         // 0x258\n    int x25c;         // 0x25c\n    int x260;         // 0x260\n    int x264;         // 0x264\n    int x268;         // 0x268\n    int x26c;         // 0x26c\n    int x270;         // 0x270\n    int x274;         // 0x274\n    int x278;         // 0x278\n    int x27c;         // 0x27c\n    int x280;         // 0x280\n    int x284;         // 0x284\n    int x288;         // 0x288\n    int x28c;         // 0x28c\n    int x290;         // 0x290\n    int x294;         // 0x294\n    int x298;         // 0x298\n    int x29c;         // 0x29c\n    int x2a0;         // 0x2a0\n    int x2a4;         // 0x2a4\n    int x2a8;         // 0x2a8\n    int x2ac;         // 0x2ac\n    int x2b0;         // 0x2b0\n    int x2b4;         // 0x2b4\n    int x2b8;         // 0x2b8\n    int x2bc;         // 0x2bc\n    int x2c0;         // 0x2c0\n    int x2c4;         // 0x2c4\n    int x2c8;         // 0x2c8\n    int x2cc;         // 0x2cc\n    int x2d0;         // 0x2d0\n    int x2d4;         // 0x2d4\n    int x2d8;         // 0x2d8\n    int x2dc;         // 0x2dc\n    int x2e0;         // 0x2e0\n    int x2e4;         // 0x2e4\n    int x2e8;         // 0x2e8\n    int x2ec;         // 0x2ec\n    int x2f0;         // 0x2f0\n    int x2f4;         // 0x2f4\n    int x2f8;         // 0x2f8\n    int x2fc;         // 0x2fc\n    int x300;         // 0x300\n    int x304;         // 0x304\n    int x308;         // 0x308\n    int x30c;         // 0x30c\n    int x310;         // 0x310\n    int x314;         // 0x314\n    int x318;         // 0x318\n    int x31c;         // 0x31c\n    int x320;         // 0x320\n    int x324;         // 0x324\n    int x328;         // 0x328\n    int x32c;         // 0x32c\n    int x330;         // 0x330\n    int x334;         // 0x334\n    int x338;         // 0x338\n    int x33c;         // 0x33c\n    int x340;         // 0x340\n    int x344;         // 0x344\n    int x348;         // 0x348\n    int x34c;         // 0x34c\n    int x350;         // 0x350\n    int x354;         // 0x354\n    int x358;         // 0x358\n    int x35c;         // 0x35c\n    int x360;         // 0x360\n    int x364;         // 0x364\n    int x368;         // 0x368\n    int x36c;         // 0x36c\n    int x370;         // 0x370\n    int x374;         // 0x374\n    int x378;         // 0x378\n    int x37c;         // 0x37c\n    int x380;         // 0x380\n    int x384;         // 0x384\n    int x388;         // 0x388\n    int x38c;         // 0x38c\n    int x390;         // 0x390\n    int x394;         // 0x394\n    int x398;         // 0x398\n    int x39c;         // 0x39c\n    int x3a0;         // 0x3a0\n    int x3a4;         // 0x3a4\n    int x3a8;         // 0x3a8\n    int x3ac;         // 0x3ac\n    int x3b0;         // 0x3b0\n    int x3b4;         // 0x3b4\n    int x3b8;         // 0x3b8\n    int x3bc;         // 0x3bc\n    int x3c0;         // 0x3c0\n    int x3c4;         // 0x3c4\n    int x3c8;         // 0x3c8\n    int x3cc;         // 0x3cc\n    int x3d0;         // 0x3d0\n    int x3d4;         // 0x3d4\n    int x3d8;         // 0x3d8\n    int x3dc;         // 0x3dc\n    int x3e0;         // 0x3e0\n    int x3e4;         // 0x3e4\n    int x3e8;         // 0x3e8\n    int x3ec;         // 0x3ec\n    int x3f0;         // 0x3f0\n    int x3f4;         // 0x3f4\n    int x3f8;         // 0x3f8\n    int x3fc;         // 0x3fc\n    int x400;         // 0x400\n    int x404;         // 0x404\n    int x408;         // 0x408\n    int x40c;         // 0x40c\n    int x410;         // 0x410\n    int x414;         // 0x414\n    int x418;         // 0x418\n    int x41c;         // 0x41c\n    int x420;         // 0x420\n    int x424;         // 0x424\n    int x428;         // 0x428\n    int x42c;         // 0x42c\n    int x430;         // 0x430\n    int x434;         // 0x434\n    int x438;         // 0x438\n    int x43c;         // 0x43c\n    int x440;         // 0x440\n    int x444;         // 0x444\n    int x448;         // 0x448\n    int x44c;         // 0x44c\n    int x450;         // 0x450\n    int x454;         // 0x454\n    int x458;         // 0x458\n    int x45c;         // 0x45c\n    int x460;         // 0x460\n    int x464;         // 0x464\n    int x468;         // 0x468\n    int x46c;         // 0x46c\n    int x470;         // 0x470\n    int x474;         // 0x474\n    int x478;         // 0x478\n    int x47c;         // 0x47c\n    int x480;         // 0x480\n    int x484;         // 0x484\n    int x488;         // 0x488\n    int x48c;         // 0x48c\n    int x490;         // 0x490\n    int x494;         // 0x494\n    int x498;         // 0x498\n    int x49c;         // 0x49c\n    int x4a0;         // 0x4a0\n    int x4a4;         // 0x4a4\n    int x4a8;         // 0x4a8\n    int x4ac;         // 0x4ac\n    int x4b0;         // 0x4b0\n    int x4b4;         // 0x4b4\n    int x4b8;         // 0x4b8\n    int x4bc;         // 0x4bc\n    int x4c0;         // 0x4c0\n    int x4c4;         // 0x4c4\n    int x4c8;         // 0x4c8\n    int x4cc;         // 0x4cc\n    int x4d0;         // 0x4d0\n    int x4d4;         // 0x4d4\n    int x4d8;         // 0x4d8\n    int x4dc;         // 0x4dc\n    int x4e0;         // 0x4e0\n    int x4e4;         // 0x4e4\n    int x4e8;         // 0x4e8\n    int x4ec;         // 0x4ec\n    int x4f0;         // 0x4f0\n    int x4f4;         // 0x4f4\n    int x4f8;         // 0x4f8\n    int x4fc;         // 0x4fc\n    int x500;         // 0x500\n    int x504;         // 0x504\n    int x508;         // 0x508\n    int x50c;         // 0x50c\n    int x510;         // 0x510\n    int x514;         // 0x514\n    int x518;         // 0x518\n    int x51c;         // 0x51c\n    int x520;         // 0x520\n    int x524;         // 0x524\n    int x528;         // 0x528\n    int x52c;         // 0x52c\n    int x530;         // 0x530\n    int x534;         // 0x534\n    int x538;         // 0x538\n    int x53c;         // 0x53c\n    int x540;         // 0x540\n    int x544;         // 0x544\n    int x548;         // 0x548\n    int x54c;         // 0x54c\n    int x550;         // 0x550\n    int x554;         // 0x554\n    int x558;         // 0x558\n    int x55c;         // 0x55c\n    int x560;         // 0x560\n    int x564;         // 0x564\n    int x568;         // 0x568\n    int x56c;         // 0x56c\n    int x570;         // 0x570\n    int x574;         // 0x574\n    int x578;         // 0x578\n    int x57c;         // 0x57c\n    int x580;         // 0x580\n    int x584;         // 0x584\n    int x588;         // 0x588\n    int x58c;         // 0x58c\n    int x590;         // 0x590\n    int x594;         // 0x594\n    int x598;         // 0x598\n    int x59c;         // 0x59c\n    int x5a0;         // 0x5a0\n    int x5a4;         // 0x5a4\n    int x5a8;         // 0x5a8\n    int x5ac;         // 0x5ac\n    int x5b0;         // 0x5b0\n    int x5b4;         // 0x5b4\n    int x5b8;         // 0x5b8\n    int x5bc;         // 0x5bc\n    int x5c0;         // 0x5c0\n    int x5c4;         // 0x5c4\n    int x5c8;         // 0x5c8\n    int x5cc;         // 0x5cc\n    int x5d0;         // 0x5d0\n    int x5d4;         // 0x5d4\n    int x5d8;         // 0x5d8\n    int x5dc;         // 0x5dc\n    int x5e0;         // 0x5e0\n    int x5e4;         // 0x5e4\n    int x5e8;         // 0x5e8\n    int x5ec;         // 0x5ec\n    int x5f0;         // 0x5f0\n    int x5f4;         // 0x5f4\n    int x5f8;         // 0x5f8\n    int x5fc;         // 0x5fc\n    int x600;         // 0x600\n    int x604;         // 0x604\n    int x608;         // 0x608\n    int x60c;         // 0x60c\n    int x610;         // 0x610\n    int x614;         // 0x614\n    int x618;         // 0x618\n    int x61c;         // 0x61c\n    int x620;         // 0x620\n    int x624;         // 0x624\n    int x628;         // 0x628\n    int x62c;         // 0x62c\n    int x630;         // 0x630\n    int x634;         // 0x634\n    int x638;         // 0x638\n    int x63c;         // 0x63c\n    int x640;         // 0x640\n    int x644;         // 0x644\n    int x648;         // 0x648\n    int x64c;         // 0x64c\n    int x650;         // 0x650\n    int x654;         // 0x654\n    int x658;         // 0x658\n    int x65c;         // 0x65c\n    int x660;         // 0x660\n    int x664;         // 0x664\n    int x668;         // 0x668\n    int x66c;         // 0x66c\n    int x670;         // 0x670\n    int x674;         // 0x674\n    int x678;         // 0x678\n    int x67c;         // 0x67c\n    int x680;         // 0x680\n    int x684;         // 0x684\n    int x688;         // 0x688\n    int x68c;         // 0x68c\n    int x690;         // 0x690\n    int x694;         // 0x694\n    int x698;         // 0x698\n    int x69c;         // 0x69c\n    int x6a0;         // 0x6a0\n    int x6a4;         // 0x6a4\n    int x6a8;         // 0x6a8\n    int x6ac;         // 0x6ac\n    int x6b0;         // 0x6b0\n    int x6b4;         // 0x6b4\n    int x6b8;         // 0x6b8\n    int x6bc;         // 0x6bc\n    int x6c0;         // 0x6c0\n    int x6c4;         // 0x6c4\n    int x6c8;         // 0x6c8\n    int x6cc;         // 0x6cc\n    int x6d0;         // 0x6d0\n    int x6d4;         // 0x6d4\n    int x6d8;         // 0x6d8\n    int x6dc;         // 0x6dc\n    int x6e0;         // 0x6e0\n    int x6e4;         // 0x6e4\n    int x6e8;         // 0x6e8\n    int x6ec;         // 0x6ec\n    int x6f0;         // 0x6f0\n    int x6f4;         // 0x6f4\n    int x6f8;         // 0x6f8\n    int x6fc;         // 0x6fc\n    int x700;         // 0x700\n    int x704;         // 0x704\n    int x708;         // 0x708\n    int x70c;         // 0x70c\n    int x710;         // 0x710\n    int x714;         // 0x714\n    int x718;         // 0x718\n    int x71c;         // 0x71c\n    int x720;         // 0x720\n    int x724;         // 0x724\n    int x728;         // 0x728\n    int x72c;         // 0x72c\n    int x730;         // 0x730\n    int x734;         // 0x734\n    int x738;         // 0x738\n    int x73c;         // 0x73c\n    int x740;         // 0x740\n    int x744;         // 0x744\n    int x748;         // 0x748\n    int x74c;         // 0x74c\n    int x750;         // 0x750\n    int x754;         // 0x754\n    int x758;         // 0x758\n    int x75c;         // 0x75c\n    int x760;         // 0x760\n    int x764;         // 0x764\n    int x768;         // 0x768\n    int x76c;         // 0x76c\n    int x770;         // 0x770\n    int x774;         // 0x774\n    int x778;         // 0x778\n    int x77c;         // 0x77c\n    int x780;         // 0x780\n    int x784;         // 0x784\n    int x788;         // 0x788\n    int x78c;         // 0x78c\n    int x790;         // 0x790\n    int x794;         // 0x794\n    int x798;         // 0x798\n    int x79c;         // 0x79c\n    int x7a0;         // 0x7a0\n    int x7a4;         // 0x7a4\n    int x7a8;         // 0x7a8\n    int x7ac;         // 0x7ac\n    int x7b0;         // 0x7b0\n    int x7b4;         // 0x7b4\n    int x7b8;         // 0x7b8\n    int x7bc;         // 0x7bc\n    int x7c0;         // 0x7c0\n    int x7c4;         // 0x7c4\n    int x7c8;         // 0x7c8\n    int x7cc;         // 0x7cc\n    int x7d0;         // 0x7d0\n    int x7d4;         // 0x7d4\n    int x7d8;         // 0x7d8\n    int x7dc;         // 0x7dc\n    int x7e0;         // 0x7e0\n    int x7e4;         // 0x7e4\n    int x7e8;         // 0x7e8\n    int x7ec;         // 0x7ec\n    int x7f0;         // 0x7f0\n    int x7f4;         // 0x7f4\n    int x7f8;         // 0x7f8\n    int x7fc;         // 0x7fc\n    int x800;         // 0x800\n    int x804;         // 0x804\n    int x808;         // 0x808\n    int x80c;         // 0x80c\n    int x810;         // 0x810\n    int x814;         // 0x814\n    int x818;         // 0x818\n    int x81c;         // 0x81c\n    int x820;         // 0x820\n    int x824;         // 0x824\n    int x828;         // 0x828\n    int x82c;         // 0x82c\n    int x830;         // 0x830\n    int x834;         // 0x834\n    int x838;         // 0x838\n    int x83c;         // 0x83c\n    int x840;         // 0x840\n    int x844;         // 0x844\n    int x848;         // 0x848\n    int x84c;         // 0x84c\n    int x850;         // 0x850\n    int x854;         // 0x854\n    int x858;         // 0x858\n    int x85c;         // 0x85c\n    int x860;         // 0x860\n    int x864;         // 0x864\n    int x868;         // 0x868\n    int x86c;         // 0x86c\n    int x870;         // 0x870\n    int x874;         // 0x874\n    int x878;         // 0x878\n    int x87c;         // 0x87c\n    int x880;         // 0x880\n    int x884;         // 0x884\n    int x888;         // 0x888\n    int x88c;         // 0x88c\n    int x890;         // 0x890\n    int x894;         // 0x894\n    int x898;         // 0x898\n    int x89c;         // 0x89c\n    int x8a0;         // 0x8a0\n    int x8a4;         // 0x8a4\n    int x8a8;         // 0x8a8\n    int x8ac;         // 0x8ac\n    int x8b0;         // 0x8b0\n    int x8b4;         // 0x8b4\n    int x8b8;         // 0x8b8\n    int x8bc;         // 0x8bc\n    int x8c0;         // 0x8c0\n    int x8c4;         // 0x8c4\n    int x8c8;         // 0x8c8\n    int x8cc;         // 0x8cc\n    int x8d0;         // 0x8d0\n    int x8d4;         // 0x8d4\n    int x8d8;         // 0x8d8\n    int x8dc;         // 0x8dc\n    int x8e0;         // 0x8e0\n    int x8e4;         // 0x8e4\n    int x8e8;         // 0x8e8\n    int x8ec;         // 0x8ec\n    int x8f0;         // 0x8f0\n    int x8f4;         // 0x8f4\n    int x8f8;         // 0x8f8\n    int x8fc;         // 0x8fc\n    int x900;         // 0x900\n    int x904;         // 0x904\n    int x908;         // 0x908\n    int x90c;         // 0x90c\n    int x910;         // 0x910\n    int x914;         // 0x914\n    int x918;         // 0x918\n    int x91c;         // 0x91c\n    int x920;         // 0x920\n    int x924;         // 0x924\n    int x928;         // 0x928\n    int x92c;         // 0x92c\n    int x930;         // 0x930\n    int x934;         // 0x934\n    int x938;         // 0x938\n    int x93c;         // 0x93c\n    int x940;         // 0x940\n    int x944;         // 0x944\n    int x948;         // 0x948\n    int x94c;         // 0x94c\n    int x950;         // 0x950\n    int x954;         // 0x954\n    int x958;         // 0x958\n    int x95c;         // 0x95c\n    int x960;         // 0x960\n    int x964;         // 0x964\n    int x968;         // 0x968\n    int x96c;         // 0x96c\n    int x970;         // 0x970\n    int x974;         // 0x974\n    int x978;         // 0x978\n    int x97c;         // 0x97c\n    int x980;         // 0x980\n    int x984;         // 0x984\n    int x988;         // 0x988\n    int x98c;         // 0x98c\n    int x990;         // 0x990\n    int x994;         // 0x994\n    int x998;         // 0x998\n    int x99c;         // 0x99c\n    int x9a0;         // 0x9a0\n    int x9a4;         // 0x9a4\n    int x9a8;         // 0x9a8\n    int x9ac;         // 0x9ac\n    int x9b0;         // 0x9b0\n    int x9b4;         // 0x9b4\n    int x9b8;         // 0x9b8\n    int x9bc;         // 0x9bc\n    int x9c0;         // 0x9c0\n    int x9c4;         // 0x9c4\n    int x9c8;         // 0x9c8\n    int x9cc;         // 0x9cc\n    int x9d0;         // 0x9d0\n    int x9d4;         // 0x9d4\n    int x9d8;         // 0x9d8\n    int x9dc;         // 0x9dc\n    int x9e0;         // 0x9e0\n    int x9e4;         // 0x9e4\n    int x9e8;         // 0x9e8\n    int x9ec;         // 0x9ec\n    int x9f0;         // 0x9f0\n    int x9f4;         // 0x9f4\n    int x9f8;         // 0x9f8\n    int x9fc;         // 0x9fc\n    int xa00;         // 0xa00\n    int xa04;         // 0xa04\n    int xa08;         // 0xa08\n    int xa0c;         // 0xa0c\n    int xa10;         // 0xa10\n    int xa14;         // 0xa14\n    int xa18;         // 0xa18\n    int xa1c;         // 0xa1c\n    int xa20;         // 0xa20\n    int xa24;         // 0xa24\n    int xa28;         // 0xa28\n    int xa2c;         // 0xa2c\n    int xa30;         // 0xa30\n    int xa34;         // 0xa34\n    int xa38;         // 0xa38\n    int xa3c;         // 0xa3c\n    int xa40;         // 0xa40\n    int xa44;         // 0xa44\n    int xa48;         // 0xa48\n    int xa4c;         // 0xa4c\n    int xa50;         // 0xa50\n    int xa54;         // 0xa54\n    int xa58;         // 0xa58\n    int xa5c;         // 0xa5c\n    int xa60;         // 0xa60\n    int xa64;         // 0xa64\n    int xa68;         // 0xa68\n    int xa6c;         // 0xa6c\n    int xa70;         // 0xa70\n    int xa74;         // 0xa74\n    int xa78;         // 0xa78\n    int xa7c;         // 0xa7c\n    int xa80;         // 0xa80\n    int xa84;         // 0xa84\n    int xa88;         // 0xa88\n    int xa8c;         // 0xa8c\n    int xa90;         // 0xa90\n    int xa94;         // 0xa94\n    int xa98;         // 0xa98\n    int xa9c;         // 0xa9c\n    int xaa0;         // 0xaa0\n    int xaa4;         // 0xaa4\n    int xaa8;         // 0xaa8\n    int xaac;         // 0xaac\n    int xab0;         // 0xab0\n    int xab4;         // 0xab4\n    int xab8;         // 0xab8\n    int xabc;         // 0xabc\n    int xac0;         // 0xac0\n    int xac4;         // 0xac4\n    int xac8;         // 0xac8\n    int xacc;         // 0xacc\n    int xad0;         // 0xad0\n    int xad4;         // 0xad4\n    int xad8;         // 0xad8\n    int xadc;         // 0xadc\n    int xae0;         // 0xae0\n    int xae4;         // 0xae4\n    int xae8;         // 0xae8\n    int xaec;         // 0xaec\n    int xaf0;         // 0xaf0\n    int xaf4;         // 0xaf4\n    int xaf8;         // 0xaf8\n    int xafc;         // 0xafc\n    int xb00;         // 0xb00\n    int xb04;         // 0xb04\n    int xb08;         // 0xb08\n    int xb0c;         // 0xb0c\n    int xb10;         // 0xb10\n    int xb14;         // 0xb14\n    int xb18;         // 0xb18\n    int xb1c;         // 0xb1c\n    int xb20;         // 0xb20\n    int xb24;         // 0xb24\n    int xb28;         // 0xb28\n    int xb2c;         // 0xb2c\n    int xb30;         // 0xb30\n    int xb34;         // 0xb34\n    int xb38;         // 0xb38\n    int xb3c;         // 0xb3c\n    int xb40;         // 0xb40\n    int xb44;         // 0xb44\n    int xb48;         // 0xb48\n    int xb4c;         // 0xb4c\n    int xb50;         // 0xb50\n    int xb54;         // 0xb54\n    int xb58;         // 0xb58\n    int xb5c;         // 0xb5c\n    int xb60;         // 0xb60\n    int xb64;         // 0xb64\n    int xb68;         // 0xb68\n    int xb6c;         // 0xb6c\n    int xb70;         // 0xb70\n    int xb74;         // 0xb74\n    int xb78;         // 0xb78\n    int xb7c;         // 0xb7c\n    int xb80;         // 0xb80\n    int xb84;         // 0xb84\n    int xb88;         // 0xb88\n    int xb8c;         // 0xb8c\n    int xb90;         // 0xb90\n    int xb94;         // 0xb94\n    int xb98;         // 0xb98\n    int xb9c;         // 0xb9c\n    int xba0;         // 0xba0\n    int xba4;         // 0xba4\n    int xba8;         // 0xba8\n    int xbac;         // 0xbac\n    int xbb0;         // 0xbb0\n    int xbb4;         // 0xbb4\n    int xbb8;         // 0xbb8\n    int xbbc;         // 0xbbc\n    int xbc0;         // 0xbc0\n    int xbc4;         // 0xbc4\n    int xbc8;         // 0xbc8\n    int xbcc;         // 0xbcc\n    int xbd0;         // 0xbd0\n    int xbd4;         // 0xbd4\n    int xbd8;         // 0xbd8\n    int xbdc;         // 0xbdc\n    int xbe0;         // 0xbe0\n    int xbe4;         // 0xbe4\n    int xbe8;         // 0xbe8\n    int xbec;         // 0xbec\n    int xbf0;         // 0xbf0\n    int xbf4;         // 0xbf4\n    int xbf8;         // 0xbf8\n    int xbfc;         // 0xbfc\n    int xc00;         // 0xc00\n    int xc04;         // 0xc04\n    int xc08;         // 0xc08\n    int xc0c;         // 0xc0c\n    int xc10;         // 0xc10\n    int xc14;         // 0xc14\n    int xc18;         // 0xc18\n    int xc1c;         // 0xc1c\n    int xc20;         // 0xc20\n    int xc24;         // 0xc24\n    int xc28;         // 0xc28\n    int xc2c;         // 0xc2c\n    int xc30;         // 0xc30\n    int xc34;         // 0xc34\n    int xc38;         // 0xc38\n    int xc3c;         // 0xc3c\n    int xc40;         // 0xc40\n    int xc44;         // 0xc44\n    int xc48;         // 0xc48\n    int xc4c;         // 0xc4c\n    int xc50;         // 0xc50\n    int xc54;         // 0xc54\n    int xc58;         // 0xc58\n    int xc5c;         // 0xc5c\n    int xc60;         // 0xc60\n    int xc64;         // 0xc64\n    int xc68;         // 0xc68\n    int xc6c;         // 0xc6c\n    int xc70;         // 0xc70\n    int xc74;         // 0xc74\n    int xc78;         // 0xc78\n    int xc7c;         // 0xc7c\n    int xc80;         // 0xc80\n    int xc84;         // 0xc84\n    int xc88;         // 0xc88\n    int xc8c;         // 0xc8c\n    int xc90;         // 0xc90\n    int xc94;         // 0xc94\n    int xc98;         // 0xc98\n    int xc9c;         // 0xc9c\n    int xca0;         // 0xca0\n    int xca4;         // 0xca4\n    int xca8;         // 0xca8\n    int xcac;         // 0xcac\n    int xcb0;         // 0xcb0\n    int xcb4;         // 0xcb4\n    int xcb8;         // 0xcb8\n    int xcbc;         // 0xcbc\n    int xcc0;         // 0xcc0\n    int xcc4;         // 0xcc4\n    int xcc8;         // 0xcc8\n    int xccc;         // 0xccc\n    int xcd0;         // 0xcd0\n    int xcd4;         // 0xcd4\n    int xcd8;         // 0xcd8\n    int xcdc;         // 0xcdc\n    int xce0;         // 0xce0\n    int xce4;         // 0xce4\n    int xce8;         // 0xce8\n    int xcec;         // 0xcec\n    int xcf0;         // 0xcf0\n    int xcf4;         // 0xcf4\n    int xcf8;         // 0xcf8\n    int xcfc;         // 0xcfc\n    int xd00;         // 0xd00\n    int xd04;         // 0xd04\n    int xd08;         // 0xd08\n    int xd0c;         // 0xd0c\n    int xd10;         // 0xd10\n    int xd14;         // 0xd14\n    int xd18;         // 0xd18\n    int xd1c;         // 0xd1c\n    int xd20;         // 0xd20\n    int xd24;         // 0xd24\n    int xd28;         // 0xd28\n    int xd2c;         // 0xd2c\n    int xd30;         // 0xd30\n    int xd34;         // 0xd34\n    int xd38;         // 0xd38\n    int xd3c;         // 0xd3c\n    int xd40;         // 0xd40\n    int xd44;         // 0xd44\n    int xd48;         // 0xd48\n    int xd4c;         // 0xd4c\n    int xd50;         // 0xd50\n    int xd54;         // 0xd54\n    int xd58;         // 0xd58\n    int xd5c;         // 0xd5c\n    int xd60;         // 0xd60\n    int xd64;         // 0xd64\n    int xd68;         // 0xd68\n    int xd6c;         // 0xd6c\n    int xd70;         // 0xd70\n    int xd74;         // 0xd74\n    int xd78;         // 0xd78\n    int xd7c;         // 0xd7c\n    int xd80;         // 0xd80\n    int xd84;         // 0xd84\n    int xd88;         // 0xd88\n    int xd8c;         // 0xd8c\n    int xd90;         // 0xd90\n    int xd94;         // 0xd94\n    int xd98;         // 0xd98\n    int xd9c;         // 0xd9c\n    int xda0;         // 0xda0\n    int xda4;         // 0xda4\n    int xda8;         // 0xda8\n    int xdac;         // 0xdac\n    int xdb0;         // 0xdb0\n    int xdb4;         // 0xdb4\n    int xdb8;         // 0xdb8\n    int xdbc;         // 0xdbc\n    int xdc0;         // 0xdc0\n    int xdc4;         // 0xdc4\n    int xdc8;         // 0xdc8\n    int xdcc;         // 0xdcc\n    int xdd0;         // 0xdd0\n    int xdd4;         // 0xdd4\n    int xdd8;         // 0xdd8\n    int xddc;         // 0xddc\n    int xde0;         // 0xde0\n    int xde4;         // 0xde4\n    int xde8;         // 0xde8\n    int xdec;         // 0xdec\n    int xdf0;         // 0xdf0\n    int xdf4;         // 0xdf4\n    int xdf8;         // 0xdf8\n    int xdfc;         // 0xdfc\n    int xe00;         // 0xe00\n    int xe04;         // 0xe04\n    int xe08;         // 0xe08\n    int xe0c;         // 0xe0c\n    int xe10;         // 0xe10\n    int xe14;         // 0xe14\n    int xe18;         // 0xe18\n    int xe1c;         // 0xe1c\n    int xe20;         // 0xe20\n    int xe24;         // 0xe24\n    int xe28;         // 0xe28\n    int xe2c;         // 0xe2c\n    int xe30;         // 0xe30\n    int xe34;         // 0xe34\n    int xe38;         // 0xe38\n    int xe3c;         // 0xe3c\n    int xe40;         // 0xe40\n    int xe44;         // 0xe44\n    int xe48;         // 0xe48\n    int xe4c;         // 0xe4c\n    int xe50;         // 0xe50\n    int xe54;         // 0xe54\n    int xe58;         // 0xe58\n    int xe5c;         // 0xe5c\n    int xe60;         // 0xe60\n    int xe64;         // 0xe64\n    int xe68;         // 0xe68\n    int xe6c;         // 0xe6c\n    int xe70;         // 0xe70\n    int xe74;         // 0xe74\n    int xe78;         // 0xe78\n    int xe7c;         // 0xe7c\n    int xe80;         // 0xe80\n    int xe84;         // 0xe84\n    int xe88;         // 0xe88\n    int xe8c;         // 0xe8c\n    int xe90;         // 0xe90\n    int xe94;         // 0xe94\n    int xe98;         // 0xe98\n    int xe9c;         // 0xe9c\n    int xea0;         // 0xea0\n    int xea4;         // 0xea4\n    int xea8;         // 0xea8\n    int xeac;         // 0xeac\n    int xeb0;         // 0xeb0\n    int xeb4;         // 0xeb4\n    int xeb8;         // 0xeb8\n    int xebc;         // 0xebc\n    int xec0;         // 0xec0\n    int xec4;         // 0xec4\n    int xec8;         // 0xec8\n    int xecc;         // 0xecc\n    int xed0;         // 0xed0\n    int xed4;         // 0xed4\n    int xed8;         // 0xed8\n    int xedc;         // 0xedc\n    int xee0;         // 0xee0\n    int xee4;         // 0xee4\n    int xee8;         // 0xee8\n    int xeec;         // 0xeec\n    int xef0;         // 0xef0\n    int xef4;         // 0xef4\n    int xef8;         // 0xef8\n    int xefc;         // 0xefc\n    int xf00;         // 0xf00\n    int xf04;         // 0xf04\n    int xf08;         // 0xf08\n    int xf0c;         // 0xf0c\n    int xf10;         // 0xf10\n    int xf14;         // 0xf14\n    int xf18;         // 0xf18\n    int xf1c;         // 0xf1c\n    int xf20;         // 0xf20\n    int xf24;         // 0xf24\n    int xf28;         // 0xf28\n    int xf2c;         // 0xf2c\n    int xf30;         // 0xf30\n    int xf34;         // 0xf34\n    int xf38;         // 0xf38\n    int xf3c;         // 0xf3c\n    int xf40;         // 0xf40\n    int xf44;         // 0xf44\n    int xf48;         // 0xf48\n    int xf4c;         // 0xf4c\n    int xf50;         // 0xf50\n    int xf54;         // 0xf54\n    int xf58;         // 0xf58\n    int xf5c;         // 0xf5c\n    int xf60;         // 0xf60\n    int xf64;         // 0xf64\n    int xf68;         // 0xf68\n    int xf6c;         // 0xf6c\n    int xf70;         // 0xf70\n    int xf74;         // 0xf74\n    int xf78;         // 0xf78\n    int xf7c;         // 0xf7c\n    int xf80;         // 0xf80\n    int xf84;         // 0xf84\n    int xf88;         // 0xf88\n    int xf8c;         // 0xf8c\n    int xf90;         // 0xf90\n    int xf94;         // 0xf94\n    int xf98;         // 0xf98\n    int xf9c;         // 0xf9c\n    int xfa0;         // 0xfa0\n    int xfa4;         // 0xfa4\n    int xfa8;         // 0xfa8\n    int xfac;         // 0xfac\n    int xfb0;         // 0xfb0\n    int xfb4;         // 0xfb4\n    int xfb8;         // 0xfb8\n    int xfbc;         // 0xfbc\n    int xfc0;         // 0xfc0\n    int xfc4;         // 0xfc4\n    int xfc8;         // 0xfc8\n    int xfcc;         // 0xfcc\n    int xfd0;         // 0xfd0\n    int xfd4;         // 0xfd4\n    int xfd8;         // 0xfd8\n    int xfdc;         // 0xfdc\n    int xfe0;         // 0xfe0\n    int xfe4;         // 0xfe4\n    int xfe8;         // 0xfe8\n    int xfec;         // 0xfec\n    int xff0;         // 0xff0\n    int xff4;         // 0xff4\n    int xff8;         // 0xff8\n    int xffc;         // 0xffc\n    int x1000;        // 0x1000\n    int x1004;        // 0x1004\n    int x1008;        // 0x1008\n    int x100c;        // 0x100c\n    int x1010;        // 0x1010\n    int x1014;        // 0x1014\n    int x1018;        // 0x1018\n    int x101c;        // 0x101c\n    int x1020;        // 0x1020\n    int x1024;        // 0x1024\n    int x1028;        // 0x1028\n    int x102c;        // 0x102c\n    int x1030;        // 0x1030\n    int x1034;        // 0x1034\n    int x1038;        // 0x1038\n    int x103c;        // 0x103c\n    int x1040;        // 0x1040\n    int x1044;        // 0x1044\n    int x1048;        // 0x1048\n    int x104c;        // 0x104c\n    int x1050;        // 0x1050\n    int x1054;        // 0x1054\n    int x1058;        // 0x1058\n    int x105c;        // 0x105c\n    int x1060;        // 0x1060\n    int x1064;        // 0x1064\n    int x1068;        // 0x1068\n    int x106c;        // 0x106c\n    int x1070;        // 0x1070\n    int x1074;        // 0x1074\n    int x1078;        // 0x1078\n    int x107c;        // 0x107c\n    int x1080;        // 0x1080\n    int x1084;        // 0x1084\n    int x1088;        // 0x1088\n    int x108c;        // 0x108c\n    int x1090;        // 0x1090\n    int x1094;        // 0x1094\n    int x1098;        // 0x1098\n    int x109c;        // 0x109c\n    int x10a0;        // 0x10a0\n    int x10a4;        // 0x10a4\n    int x10a8;        // 0x10a8\n    int x10ac;        // 0x10ac\n    int x10b0;        // 0x10b0\n    int x10b4;        // 0x10b4\n    int x10b8;        // 0x10b8\n    int x10bc;        // 0x10bc\n    int x10c0;        // 0x10c0\n    int x10c4;        // 0x10c4\n    int x10c8;        // 0x10c8\n    int x10cc;        // 0x10cc\n    int x10d0;        // 0x10d0\n    int x10d4;        // 0x10d4\n    int x10d8;        // 0x10d8\n    int x10dc;        // 0x10dc\n    int x10e0;        // 0x10e0\n    int x10e4;        // 0x10e4\n    int x10e8;        // 0x10e8\n    int x10ec;        // 0x10ec\n    int x10f0;        // 0x10f0\n    int x10f4;        // 0x10f4\n    int x10f8;        // 0x10f8\n    int x10fc;        // 0x10fc\n    int x1100;        // 0x1100\n    int x1104;        // 0x1104\n    int x1108;        // 0x1108\n    int x110c;        // 0x110c\n    int x1110;        // 0x1110\n    int x1114;        // 0x1114\n    int x1118;        // 0x1118\n    int x111c;        // 0x111c\n    int x1120;        // 0x1120\n    int x1124;        // 0x1124\n    int x1128;        // 0x1128\n    int x112c;        // 0x112c\n    int x1130;        // 0x1130\n    int x1134;        // 0x1134\n    int x1138;        // 0x1138\n    int x113c;        // 0x113c\n    int x1140;        // 0x1140\n    int x1144;        // 0x1144\n    int x1148;        // 0x1148\n    int x114c;        // 0x114c\n    int x1150;        // 0x1150\n    int x1154;        // 0x1154\n    int x1158;        // 0x1158\n    int x115c;        // 0x115c\n    int x1160;        // 0x1160\n    int x1164;        // 0x1164\n    int x1168;        // 0x1168\n    int x116c;        // 0x116c\n    int x1170;        // 0x1170\n    int x1174;        // 0x1174\n    int x1178;        // 0x1178\n    int x117c;        // 0x117c\n    int x1180;        // 0x1180\n    int x1184;        // 0x1184\n    int x1188;        // 0x1188\n    int x118c;        // 0x118c\n    int x1190;        // 0x1190\n    int x1194;        // 0x1194\n    int x1198;        // 0x1198\n    int x119c;        // 0x119c\n    int x11a0;        // 0x11a0\n    int x11a4;        // 0x11a4\n    int x11a8;        // 0x11a8\n    int x11ac;        // 0x11ac\n    int x11b0;        // 0x11b0\n    int x11b4;        // 0x11b4\n    int x11b8;        // 0x11b8\n    int x11bc;        // 0x11bc\n    int x11c0;        // 0x11c0\n    int x11c4;        // 0x11c4\n    int x11c8;        // 0x11c8\n    int x11cc;        // 0x11cc\n    int x11d0;        // 0x11d0\n    int x11d4;        // 0x11d4\n    int x11d8;        // 0x11d8\n    int x11dc;        // 0x11dc\n    int x11e0;        // 0x11e0\n    int x11e4;        // 0x11e4\n    int x11e8;        // 0x11e8\n    int x11ec;        // 0x11ec\n    int x11f0;        // 0x11f0\n    int x11f4;        // 0x11f4\n    int x11f8;        // 0x11f8\n    int x11fc;        // 0x11fc\n    int x1200;        // 0x1200\n    int x1204;        // 0x1204\n    int x1208;        // 0x1208\n    int x120c;        // 0x120c\n    int x1210;        // 0x1210\n    int x1214;        // 0x1214\n    int x1218;        // 0x1218\n    int x121c;        // 0x121c\n    int x1220;        // 0x1220\n    int x1224;        // 0x1224\n    int x1228;        // 0x1228\n    int x122c;        // 0x122c\n    int x1230;        // 0x1230\n    int x1234;        // 0x1234\n    int x1238;        // 0x1238\n    int x123c;        // 0x123c\n    int x1240;        // 0x1240\n    int x1244;        // 0x1244\n    int x1248;        // 0x1248\n    int x124c;        // 0x124c\n    int x1250;        // 0x1250\n    int x1254;        // 0x1254\n    int x1258;        // 0x1258\n    int x125c;        // 0x125c\n    int x1260;        // 0x1260\n    int x1264;        // 0x1264\n    int x1268;        // 0x1268\n    int x126c;        // 0x126c\n    int x1270;        // 0x1270\n    int x1274;        // 0x1274\n    int x1278;        // 0x1278\n    int x127c;        // 0x127c\n    int x1280;        // 0x1280\n    int x1284;        // 0x1284\n    int x1288;        // 0x1288\n    int x128c;        // 0x128c\n    int x1290;        // 0x1290\n    int x1294;        // 0x1294\n    int x1298;        // 0x1298\n    int x129c;        // 0x129c\n    int x12a0;        // 0x12a0\n    int x12a4;        // 0x12a4\n    int x12a8;        // 0x12a8\n    int x12ac;        // 0x12ac\n    int x12b0;        // 0x12b0\n    int x12b4;        // 0x12b4\n    int x12b8;        // 0x12b8\n    int x12bc;        // 0x12bc\n    int x12c0;        // 0x12c0\n    int x12c4;        // 0x12c4\n    int x12c8;        // 0x12c8\n    int x12cc;        // 0x12cc\n    int x12d0;        // 0x12d0\n    int x12d4;        // 0x12d4\n    int x12d8;        // 0x12d8\n    int x12dc;        // 0x12dc\n    int x12e0;        // 0x12e0\n    int x12e4;        // 0x12e4\n    int x12e8;        // 0x12e8\n    int x12ec;        // 0x12ec\n    int x12f0;        // 0x12f0\n    int x12f4;        // 0x12f4\n    int x12f8;        // 0x12f8\n    int x12fc;        // 0x12fc\n    int x1300;        // 0x1300\n    int x1304;        // 0x1304\n    int x1308;        // 0x1308\n    int x130c;        // 0x130c\n    int x1310;        // 0x1310\n    int x1314;        // 0x1314\n    int x1318;        // 0x1318\n    int x131c;        // 0x131c\n    int x1320;        // 0x1320\n    int x1324;        // 0x1324\n    int x1328;        // 0x1328\n    int x132c;        // 0x132c\n    int x1330;        // 0x1330\n    int x1334;        // 0x1334\n    int x1338;        // 0x1338\n    int x133c;        // 0x133c\n    int x1340;        // 0x1340\n    int x1344;        // 0x1344\n    int x1348;        // 0x1348\n    int x134c;        // 0x134c\n    int x1350;        // 0x1350\n    int x1354;        // 0x1354\n    int x1358;        // 0x1358\n    int x135c;        // 0x135c\n    int x1360;        // 0x1360\n    int x1364;        // 0x1364\n    int x1368;        // 0x1368\n    int x136c;        // 0x136c\n    int x1370;        // 0x1370\n    int x1374;        // 0x1374\n    int x1378;        // 0x1378\n    int x137c;        // 0x137c\n    int x1380;        // 0x1380\n    int x1384;        // 0x1384\n    int x1388;        // 0x1388\n    int x138c;        // 0x138c\n    int x1390;        // 0x1390\n    int x1394;        // 0x1394\n    int x1398;        // 0x1398\n    int x139c;        // 0x139c\n    int x13a0;        // 0x13a0\n    int x13a4;        // 0x13a4\n    int x13a8;        // 0x13a8\n    int x13ac;        // 0x13ac\n    int x13b0;        // 0x13b0\n    int x13b4;        // 0x13b4\n    int x13b8;        // 0x13b8\n    int x13bc;        // 0x13bc\n    int x13c0;        // 0x13c0\n    int x13c4;        // 0x13c4\n    int x13c8;        // 0x13c8\n    int x13cc;        // 0x13cc\n    int x13d0;        // 0x13d0\n    int x13d4;        // 0x13d4\n    int x13d8;        // 0x13d8\n    int x13dc;        // 0x13dc\n    int x13e0;        // 0x13e0\n    int x13e4;        // 0x13e4\n    int x13e8;        // 0x13e8\n    int x13ec;        // 0x13ec\n    int x13f0;        // 0x13f0\n    int x13f4;        // 0x13f4\n    int x13f8;        // 0x13f8\n    int x13fc;        // 0x13fc\n    int x1400;        // 0x1400\n    int x1404;        // 0x1404\n    int x1408;        // 0x1408\n    int x140c;        // 0x140c\n    int x1410;        // 0x1410\n    int x1414;        // 0x1414\n    int x1418;        // 0x1418\n    int x141c;        // 0x141c\n    int x1420;        // 0x1420\n    int x1424;        // 0x1424\n    int x1428;        // 0x1428\n    int x142c;        // 0x142c\n    int x1430;        // 0x1430\n    int x1434;        // 0x1434\n    int x1438;        // 0x1438\n    int x143c;        // 0x143c\n    int x1440;        // 0x1440\n    int x1444;        // 0x1444\n    int x1448;        // 0x1448\n    int x144c;        // 0x144c\n    int x1450;        // 0x1450\n    int x1454;        // 0x1454\n    int x1458;        // 0x1458\n    int x145c;        // 0x145c\n    int x1460;        // 0x1460\n    int x1464;        // 0x1464\n    int x1468;        // 0x1468\n    int x146c;        // 0x146c\n    int x1470;        // 0x1470\n    int x1474;        // 0x1474\n    int x1478;        // 0x1478\n    int x147c;        // 0x147c\n    int x1480;        // 0x1480\n    int x1484;        // 0x1484\n    int x1488;        // 0x1488\n    int x148c;        // 0x148c\n    int x1490;        // 0x1490\n    int x1494;        // 0x1494\n    int x1498;        // 0x1498\n    int x149c;        // 0x149c\n    int x14a0;        // 0x14a0\n    int x14a4;        // 0x14a4\n    int x14a8;        // 0x14a8\n    int x14ac;        // 0x14ac\n    int x14b0;        // 0x14b0\n    int x14b4;        // 0x14b4\n    int x14b8;        // 0x14b8\n    int x14bc;        // 0x14bc\n    int x14c0;        // 0x14c0\n    int x14c4;        // 0x14c4\n    int x14c8;        // 0x14c8\n    int x14cc;        // 0x14cc\n    int x14d0;        // 0x14d0\n    int x14d4;        // 0x14d4\n    int x14d8;        // 0x14d8\n    int x14dc;        // 0x14dc\n    int x14e0;        // 0x14e0\n    int x14e4;        // 0x14e4\n    int x14e8;        // 0x14e8\n    int x14ec;        // 0x14ec\n    int x14f0;        // 0x14f0\n    int x14f4;        // 0x14f4\n    int x14f8;        // 0x14f8\n    int x14fc;        // 0x14fc\n    int x1500;        // 0x1500\n    int x1504;        // 0x1504\n    int x1508;        // 0x1508\n    int x150c;        // 0x150c\n    int x1510;        // 0x1510\n    int x1514;        // 0x1514\n    int x1518;        // 0x1518\n    int x151c;        // 0x151c\n    int x1520;        // 0x1520\n    int x1524;        // 0x1524\n    int x1528;        // 0x1528\n    int x152c;        // 0x152c\n    int x1530;        // 0x1530\n    int x1534;        // 0x1534\n    int x1538;        // 0x1538\n    int x153c;        // 0x153c\n    int x1540;        // 0x1540\n    int x1544;        // 0x1544\n    int x1548;        // 0x1548\n    int x154c;        // 0x154c\n    int x1550;        // 0x1550\n    int x1554;        // 0x1554\n    int x1558;        // 0x1558\n    int x155c;        // 0x155c\n    int x1560;        // 0x1560\n    int x1564;        // 0x1564\n    int x1568;        // 0x1568\n    int x156c;        // 0x156c\n    int x1570;        // 0x1570\n    int x1574;        // 0x1574\n    int x1578;        // 0x1578\n    int x157c;        // 0x157c\n    int x1580;        // 0x1580\n    int x1584;        // 0x1584\n    int x1588;        // 0x1588\n    int x158c;        // 0x158c\n    int x1590;        // 0x1590\n    int x1594;        // 0x1594\n    int x1598;        // 0x1598\n    int x159c;        // 0x159c\n    int x15a0;        // 0x15a0\n    int x15a4;        // 0x15a4\n    int x15a8;        // 0x15a8\n    int x15ac;        // 0x15ac\n    int x15b0;        // 0x15b0\n    int x15b4;        // 0x15b4\n    int x15b8;        // 0x15b8\n    int x15bc;        // 0x15bc\n    int x15c0;        // 0x15c0\n    int x15c4;        // 0x15c4\n    int x15c8;        // 0x15c8\n    int x15cc;        // 0x15cc\n    int x15d0;        // 0x15d0\n    int x15d4;        // 0x15d4\n    int x15d8;        // 0x15d8\n    int x15dc;        // 0x15dc\n    int x15e0;        // 0x15e0\n    int x15e4;        // 0x15e4\n    int x15e8;        // 0x15e8\n    int x15ec;        // 0x15ec\n    int x15f0;        // 0x15f0\n    int x15f4;        // 0x15f4\n    int x15f8;        // 0x15f8\n    int x15fc;        // 0x15fc\n    int x1600;        // 0x1600\n    int x1604;        // 0x1604\n    int x1608;        // 0x1608\n    int x160c;        // 0x160c\n    int x1610;        // 0x1610\n    int x1614;        // 0x1614\n    int x1618;        // 0x1618\n    int x161c;        // 0x161c\n    int x1620;        // 0x1620\n    int x1624;        // 0x1624\n    int x1628;        // 0x1628\n    int x162c;        // 0x162c\n    int x1630;        // 0x1630\n    int x1634;        // 0x1634\n    int x1638;        // 0x1638\n    int x163c;        // 0x163c\n    int x1640;        // 0x1640\n    int x1644;        // 0x1644\n    int x1648;        // 0x1648\n    int x164c;        // 0x164c\n    int x1650;        // 0x1650\n    int x1654;        // 0x1654\n    int x1658;        // 0x1658\n    int x165c;        // 0x165c\n    int x1660;        // 0x1660\n    int x1664;        // 0x1664\n    int x1668;        // 0x1668\n    int x166c;        // 0x166c\n    int x1670;        // 0x1670\n    int x1674;        // 0x1674\n    int x1678;        // 0x1678\n    int x167c;        // 0x167c\n    int x1680;        // 0x1680\n    int x1684;        // 0x1684\n    int x1688;        // 0x1688\n    int x168c;        // 0x168c\n    int x1690;        // 0x1690\n    int x1694;        // 0x1694\n    int x1698;        // 0x1698\n    int x169c;        // 0x169c\n    int x16a0;        // 0x16a0\n    int x16a4;        // 0x16a4\n    int x16a8;        // 0x16a8\n    int x16ac;        // 0x16ac\n    int x16b0;        // 0x16b0\n    int x16b4;        // 0x16b4\n    int x16b8;        // 0x16b8\n    int x16bc;        // 0x16bc\n    int x16c0;        // 0x16c0\n    int x16c4;        // 0x16c4\n    int x16c8;        // 0x16c8\n    int x16cc;        // 0x16cc\n    int x16d0;        // 0x16d0\n    int x16d4;        // 0x16d4\n    int x16d8;        // 0x16d8\n    int x16dc;        // 0x16dc\n    int x16e0;        // 0x16e0\n    int x16e4;        // 0x16e4\n    int x16e8;        // 0x16e8\n    int x16ec;        // 0x16ec\n    int x16f0;        // 0x16f0\n    int x16f4;        // 0x16f4\n    int x16f8;        // 0x16f8\n    int x16fc;        // 0x16fc\n    int x1700;        // 0x1700\n    int x1704;        // 0x1704\n    int x1708;        // 0x1708\n    int x170c;        // 0x170c\n    int x1710;        // 0x1710\n    int x1714;        // 0x1714\n    int x1718;        // 0x1718\n    int x171c;        // 0x171c\n    int x1720;        // 0x1720\n    int x1724;        // 0x1724\n    int x1728;        // 0x1728\n    int x172c;        // 0x172c\n    int x1730;        // 0x1730\n    int x1734;        // 0x1734\n    int x1738;        // 0x1738\n    int x173c;        // 0x173c\n    int x1740;        // 0x1740\n    int x1744;        // 0x1744\n    int x1748;        // 0x1748\n    int x174c;        // 0x174c\n    int x1750;        // 0x1750\n    int x1754;        // 0x1754\n    int x1758;        // 0x1758\n    int x175c;        // 0x175c\n    int x1760;        // 0x1760\n    int x1764;        // 0x1764\n    int x1768;        // 0x1768\n    int x176c;        // 0x176c\n    int x1770;        // 0x1770\n    int x1774;        // 0x1774\n    int x1778;        // 0x1778\n    int x177c;        // 0x177c\n    int x1780;        // 0x1780\n    int x1784;        // 0x1784\n    int x1788;        // 0x1788\n    int x178c;        // 0x178c\n    int x1790;        // 0x1790\n    int x1794;        // 0x1794\n    int x1798;        // 0x1798\n    int x179c;        // 0x179c\n    int x17a0;        // 0x17a0\n    int x17a4;        // 0x17a4\n    int x17a8;        // 0x17a8\n    int x17ac;        // 0x17ac\n    int x17b0;        // 0x17b0\n    int x17b4;        // 0x17b4\n    int x17b8;        // 0x17b8\n    int x17bc;        // 0x17bc\n    int x17c0;        // 0x17c0\n    int x17c4;        // 0x17c4\n    int x17c8;        // 0x17c8\n    int x17cc;        // 0x17cc\n    int x17d0;        // 0x17d0\n    int x17d4;        // 0x17d4\n    int x17d8;        // 0x17d8\n    int x17dc;        // 0x17dc\n    int x17e0;        // 0x17e0\n    int x17e4;        // 0x17e4\n    int x17e8;        // 0x17e8\n    int x17ec;        // 0x17ec\n    int x17f0;        // 0x17f0\n    int x17f4;        // 0x17f4\n    int x17f8;        // 0x17f8\n    int x17fc;        // 0x17fc\n    int x1800;        // 0x1800\n    int x1804;        // 0x1804\n    int x1808;        // 0x1808\n    int x180c;        // 0x180c\n    int x1810;        // 0x1810\n    int x1814;        // 0x1814\n    int x1818;        // 0x1818\n    int x181c;        // 0x181c\n    int x1820;        // 0x1820\n    int x1824;        // 0x1824\n    int x1828;        // 0x1828\n    int x182c;        // 0x182c\n    int x1830;        // 0x1830\n    int x1834;        // 0x1834\n    int x1838;        // 0x1838\n    int x183c;        // 0x183c\n    int x1840;        // 0x1840\n    int x1844;        // 0x1844\n    int x1848;        // 0x1848\n    int x184c;        // 0x184c\n    int x1850;        // 0x1850\n    int x1854;        // 0x1854\n    int x1858;        // 0x1858\n    int x185c;        // 0x185c\n    int x1860;        // 0x1860\n    int x1864;        // 0x1864\n    int x1868;        // 0x1868\n    int x186c;        // 0x186c\n    int x1870;        // 0x1870\n    int x1874;        // 0x1874\n    int x1878;        // 0x1878\n    int x187c;        // 0x187c\n    int x1880;        // 0x1880\n    int x1884;        // 0x1884\n    int x1888;        // 0x1888\n    int x188c;        // 0x188c\n    int x1890;        // 0x1890\n    int x1894;        // 0x1894\n    int x1898;        // 0x1898\n    int x189c;        // 0x189c\n    int x18a0;        // 0x18a0\n    int x18a4;        // 0x18a4\n    int x18a8;        // 0x18a8\n    int x18ac;        // 0x18ac\n    int x18b0;        // 0x18b0\n    int x18b4;        // 0x18b4\n    int x18b8;        // 0x18b8\n    int x18bc;        // 0x18bc\n    int x18c0;        // 0x18c0\n    int x18c4;        // 0x18c4\n    int x18c8;        // 0x18c8\n    int x18cc;        // 0x18cc\n    int x18d0;        // 0x18d0\n    int x18d4;        // 0x18d4\n    int x18d8;        // 0x18d8\n    int x18dc;        // 0x18dc\n    int x18e0;        // 0x18e0\n    int x18e4;        // 0x18e4\n    int x18e8;        // 0x18e8\n    int x18ec;        // 0x18ec\n    int x18f0;        // 0x18f0\n    int x18f4;        // 0x18f4\n    int x18f8;        // 0x18f8\n    int x18fc;        // 0x18fc\n    int x1900;        // 0x1900\n    int x1904;        // 0x1904\n    int x1908;        // 0x1908\n    int x190c;        // 0x190c\n    int x1910;        // 0x1910\n    int x1914;        // 0x1914\n    int x1918;        // 0x1918\n    int x191c;        // 0x191c\n    int x1920;        // 0x1920\n    int x1924;        // 0x1924\n    int x1928;        // 0x1928\n    int x192c;        // 0x192c\n    int x1930;        // 0x1930\n    int x1934;        // 0x1934\n    int x1938;        // 0x1938\n    int x193c;        // 0x193c\n    int x1940;        // 0x1940\n    int x1944;        // 0x1944\n    int x1948;        // 0x1948\n    int x194c;        // 0x194c\n    int x1950;        // 0x1950\n    int x1954;        // 0x1954\n    int x1958;        // 0x1958\n    int x195c;        // 0x195c\n    int x1960;        // 0x1960\n    int x1964;        // 0x1964\n    int x1968;        // 0x1968\n    int x196c;        // 0x196c\n    int x1970;        // 0x1970\n    int x1974;        // 0x1974\n    int x1978;        // 0x1978\n    int x197c;        // 0x197c\n    int x1980;        // 0x1980\n    int x1984;        // 0x1984\n    int x1988;        // 0x1988\n    int x198c;        // 0x198c\n    int x1990;        // 0x1990\n    int x1994;        // 0x1994\n    int x1998;        // 0x1998\n    int x199c;        // 0x199c\n    int x19a0;        // 0x19a0\n    int x19a4;        // 0x19a4\n    int x19a8;        // 0x19a8\n    int x19ac;        // 0x19ac\n    int x19b0;        // 0x19b0\n    int x19b4;        // 0x19b4\n    int x19b8;        // 0x19b8\n    int x19bc;        // 0x19bc\n    int x19c0;        // 0x19c0\n    int x19c4;        // 0x19c4\n    int x19c8;        // 0x19c8\n    int x19cc;        // 0x19cc\n    int x19d0;        // 0x19d0\n    int x19d4;        // 0x19d4\n    int x19d8;        // 0x19d8\n    int x19dc;        // 0x19dc\n    int x19e0;        // 0x19e0\n    int x19e4;        // 0x19e4\n    int x19e8;        // 0x19e8\n    int x19ec;        // 0x19ec\n    int x19f0;        // 0x19f0\n    int x19f4;        // 0x19f4\n    int x19f8;        // 0x19f8\n    int x19fc;        // 0x19fc\n    int x1a00;        // 0x1a00\n    int x1a04;        // 0x1a04\n    int x1a08;        // 0x1a08\n    int x1a0c;        // 0x1a0c\n    int x1a10;        // 0x1a10\n    int x1a14;        // 0x1a14\n    int x1a18;        // 0x1a18\n    int x1a1c;        // 0x1a1c\n    int x1a20;        // 0x1a20\n    int x1a24;        // 0x1a24\n    int x1a28;        // 0x1a28\n    int x1a2c;        // 0x1a2c\n    int x1a30;        // 0x1a30\n    int x1a34;        // 0x1a34\n    int x1a38;        // 0x1a38\n    int x1a3c;        // 0x1a3c\n    int x1a40;        // 0x1a40\n    int x1a44;        // 0x1a44\n    int x1a48;        // 0x1a48\n    int x1a4c;        // 0x1a4c\n    int x1a50;        // 0x1a50\n    int x1a54;        // 0x1a54\n    int x1a58;        // 0x1a58\n    int x1a5c;        // 0x1a5c\n    int x1a60;        // 0x1a60\n    int x1a64;        // 0x1a64\n    int x1a68;        // 0x1a68\n    int x1a6c;        // 0x1a6c\n    int x1a70;        // 0x1a70\n    int x1a74;        // 0x1a74\n    int x1a78;        // 0x1a78\n    int x1a7c;        // 0x1a7c\n    int x1a80;        // 0x1a80\n    int x1a84;        // 0x1a84\n    int x1a88;        // 0x1a88\n    int x1a8c;        // 0x1a8c\n    int x1a90;        // 0x1a90\n    int x1a94;        // 0x1a94\n    int x1a98;        // 0x1a98\n    int x1a9c;        // 0x1a9c\n    int x1aa0;        // 0x1aa0\n    int x1aa4;        // 0x1aa4\n    int x1aa8;        // 0x1aa8\n    int x1aac;        // 0x1aac\n    int x1ab0;        // 0x1ab0\n    int x1ab4;        // 0x1ab4\n    int x1ab8;        // 0x1ab8\n    int x1abc;        // 0x1abc\n    int x1ac0;        // 0x1ac0\n    int x1ac4;        // 0x1ac4\n    int x1ac8;        // 0x1ac8\n    int x1acc;        // 0x1acc\n    int x1ad0;        // 0x1ad0\n    int x1ad4;        // 0x1ad4\n    int x1ad8;        // 0x1ad8\n    int x1adc;        // 0x1adc\n    int x1ae0;        // 0x1ae0\n    int x1ae4;        // 0x1ae4\n    int x1ae8;        // 0x1ae8\n    int x1aec;        // 0x1aec\n    int x1af0;        // 0x1af0\n    int x1af4;        // 0x1af4\n    int x1af8;        // 0x1af8\n    int x1afc;        // 0x1afc\n    int x1b00;        // 0x1b00\n    int x1b04;        // 0x1b04\n    int x1b08;        // 0x1b08\n    int x1b0c;        // 0x1b0c\n    int x1b10;        // 0x1b10\n    int x1b14;        // 0x1b14\n    int x1b18;        // 0x1b18\n    int x1b1c;        // 0x1b1c\n    int x1b20;        // 0x1b20\n    int x1b24;        // 0x1b24\n    int x1b28;        // 0x1b28\n    int x1b2c;        // 0x1b2c\n    int x1b30;        // 0x1b30\n    int x1b34;        // 0x1b34\n    int x1b38;        // 0x1b38\n    int x1b3c;        // 0x1b3c\n    int x1b40;        // 0x1b40\n    int x1b44;        // 0x1b44\n    int x1b48;        // 0x1b48\n    int x1b4c;        // 0x1b4c\n    int x1b50;        // 0x1b50\n    int x1b54;        // 0x1b54\n    int x1b58;        // 0x1b58\n    int x1b5c;        // 0x1b5c\n    int x1b60;        // 0x1b60\n    int x1b64;        // 0x1b64\n    int x1b68;        // 0x1b68\n    int x1b6c;        // 0x1b6c\n    int x1b70;        // 0x1b70\n    int x1b74;        // 0x1b74\n    int x1b78;        // 0x1b78\n    int x1b7c;        // 0x1b7c\n    int x1b80;        // 0x1b80\n    int x1b84;        // 0x1b84\n    int x1b88;        // 0x1b88\n    int x1b8c;        // 0x1b8c\n    int x1b90;        // 0x1b90\n    int x1b94;        // 0x1b94\n    int x1b98;        // 0x1b98\n    int x1b9c;        // 0x1b9c\n    int x1ba0;        // 0x1ba0\n    int x1ba4;        // 0x1ba4\n    int x1ba8;        // 0x1ba8\n    int x1bac;        // 0x1bac\n    int x1bb0;        // 0x1bb0\n    int x1bb4;        // 0x1bb4\n    int x1bb8;        // 0x1bb8\n    int x1bbc;        // 0x1bbc\n    int x1bc0;        // 0x1bc0\n    int x1bc4;        // 0x1bc4\n    int x1bc8;        // 0x1bc8\n    int x1bcc;        // 0x1bcc\n    int x1bd0;        // 0x1bd0\n    int x1bd4;        // 0x1bd4\n    int x1bd8;        // 0x1bd8\n    int x1bdc;        // 0x1bdc\n    int x1be0;        // 0x1be0\n    int x1be4;        // 0x1be4\n    int x1be8;        // 0x1be8\n    int x1bec;        // 0x1bec\n    int x1bf0;        // 0x1bf0\n    int x1bf4;        // 0x1bf4\n    int x1bf8;        // 0x1bf8\n    int x1bfc;        // 0x1bfc\n    int x1c00;        // 0x1c00\n    int x1c04;        // 0x1c04\n    int x1c08;        // 0x1c08\n    int x1c0c;        // 0x1c0c\n    int x1c10;        // 0x1c10\n    int x1c14;        // 0x1c14\n    int x1c18;        // 0x1c18\n    int x1c1c;        // 0x1c1c\n    int x1c20;        // 0x1c20\n    int x1c24;        // 0x1c24\n    int x1c28;        // 0x1c28\n    int x1c2c;        // 0x1c2c\n    int x1c30;        // 0x1c30\n    int x1c34;        // 0x1c34\n    int x1c38;        // 0x1c38\n    int x1c3c;        // 0x1c3c\n    int x1c40;        // 0x1c40\n    int x1c44;        // 0x1c44\n    int x1c48;        // 0x1c48\n    int x1c4c;        // 0x1c4c\n    int x1c50;        // 0x1c50\n    int x1c54;        // 0x1c54\n    int x1c58;        // 0x1c58\n    int x1c5c;        // 0x1c5c\n    int x1c60;        // 0x1c60\n    int x1c64;        // 0x1c64\n    int x1c68;        // 0x1c68\n    int x1c6c;        // 0x1c6c\n    int x1c70;        // 0x1c70\n    int x1c74;        // 0x1c74\n    int x1c78;        // 0x1c78\n    int x1c7c;        // 0x1c7c\n    int x1c80;        // 0x1c80\n    int x1c84;        // 0x1c84\n    int x1c88;        // 0x1c88\n    int x1c8c;        // 0x1c8c\n    int x1c90;        // 0x1c90\n    int x1c94;        // 0x1c94\n    int x1c98;        // 0x1c98\n    int x1c9c;        // 0x1c9c\n    int x1ca0;        // 0x1ca0\n    int x1ca4;        // 0x1ca4\n    int x1ca8;        // 0x1ca8\n    int x1cac;        // 0x1cac\n    int x1cb0;        // 0x1cb0\n    int x1cb4;        // 0x1cb4\n    int x1cb8;        // 0x1cb8\n    int x1cbc;        // 0x1cbc\n    int x1cc0;        // 0x1cc0\n    int x1cc4;        // 0x1cc4\n    int x1cc8;        // 0x1cc8\n    int x1ccc;        // 0x1ccc\n    int x1cd0;        // 0x1cd0\n    int x1cd4;        // 0x1cd4\n    int x1cd8;        // 0x1cd8\n    int x1cdc;        // 0x1cdc\n    int x1ce0;        // 0x1ce0\n    int x1ce4;        // 0x1ce4\n    int x1ce8;        // 0x1ce8\n    int x1cec;        // 0x1cec\n    int x1cf0;        // 0x1cf0\n    int x1cf4;        // 0x1cf4\n    int x1cf8;        // 0x1cf8\n    int x1cfc;        // 0x1cfc\n    int x1d00;        // 0x1d00\n    int x1d04;        // 0x1d04\n    int x1d08;        // 0x1d08\n    int x1d0c;        // 0x1d0c\n    int x1d10;        // 0x1d10\n    int x1d14;        // 0x1d14\n    int x1d18;        // 0x1d18\n    int x1d1c;        // 0x1d1c\n    int x1d20;        // 0x1d20\n    int x1d24;        // 0x1d24\n    int x1d28;        // 0x1d28\n    int x1d2c;        // 0x1d2c\n    int x1d30;        // 0x1d30\n    int x1d34;        // 0x1d34\n    int x1d38;        // 0x1d38\n    int x1d3c;        // 0x1d3c\n    int x1d40;        // 0x1d40\n    int x1d44;        // 0x1d44\n    int x1d48;        // 0x1d48\n    int x1d4c;        // 0x1d4c\n    int x1d50;        // 0x1d50\n    int x1d54;        // 0x1d54\n    int x1d58;        // 0x1d58\n    int x1d5c;        // 0x1d5c\n    int x1d60;        // 0x1d60\n    int x1d64;        // 0x1d64\n    int x1d68;        // 0x1d68\n    int x1d6c;        // 0x1d6c\n    int x1d70;        // 0x1d70\n    int x1d74;        // 0x1d74\n    int x1d78;        // 0x1d78\n    int x1d7c;        // 0x1d7c\n    int x1d80;        // 0x1d80\n    int x1d84;        // 0x1d84\n    int x1d88;        // 0x1d88\n    int x1d8c;        // 0x1d8c\n    int x1d90;        // 0x1d90\n    int x1d94;        // 0x1d94\n    int x1d98;        // 0x1d98\n    int x1d9c;        // 0x1d9c\n    int x1da0;        // 0x1da0\n    int x1da4;        // 0x1da4\n    int x1da8;        // 0x1da8\n    int x1dac;        // 0x1dac\n    int x1db0;        // 0x1db0\n    int x1db4;        // 0x1db4\n    int x1db8;        // 0x1db8\n    int x1dbc;        // 0x1dbc\n    int x1dc0;        // 0x1dc0\n    int x1dc4;        // 0x1dc4\n    int x1dc8;        // 0x1dc8\n    int x1dcc;        // 0x1dcc\n    int x1dd0;        // 0x1dd0\n    int x1dd4;        // 0x1dd4\n    int x1dd8;        // 0x1dd8\n    int x1ddc;        // 0x1ddc\n    int x1de0;        // 0x1de0\n    int x1de4;        // 0x1de4\n    int x1de8;        // 0x1de8\n    int x1dec;        // 0x1dec\n    int x1df0;        // 0x1df0\n    int x1df4;        // 0x1df4\n    int x1df8;        // 0x1df8\n    int x1dfc;        // 0x1dfc\n    int x1e00;        // 0x1e00\n    int x1e04;        // 0x1e04\n    int x1e08;        // 0x1e08\n    int x1e0c;        // 0x1e0c\n    int x1e10;        // 0x1e10\n    int x1e14;        // 0x1e14\n    int x1e18;        // 0x1e18\n    int x1e1c;        // 0x1e1c\n    int x1e20;        // 0x1e20\n    int x1e24;        // 0x1e24\n    int x1e28;        // 0x1e28\n    int x1e2c;        // 0x1e2c\n    int x1e30;        // 0x1e30\n    int x1e34;        // 0x1e34\n    int x1e38;        // 0x1e38\n    int x1e3c;        // 0x1e3c\n    int x1e40;        // 0x1e40\n    int x1e44;        // 0x1e44\n    int x1e48;        // 0x1e48\n    int x1e4c;        // 0x1e4c\n    int x1e50;        // 0x1e50\n    int x1e54;        // 0x1e54\n    int x1e58;        // 0x1e58\n    int x1e5c;        // 0x1e5c\n    int x1e60;        // 0x1e60\n    int x1e64;        // 0x1e64\n    int x1e68;        // 0x1e68\n    int x1e6c;        // 0x1e6c\n    int x1e70;        // 0x1e70\n    int x1e74;        // 0x1e74\n    int x1e78;        // 0x1e78\n    int x1e7c;        // 0x1e7c\n    int x1e80;        // 0x1e80\n    int x1e84;        // 0x1e84\n    int x1e88;        // 0x1e88\n    int x1e8c;        // 0x1e8c\n    int x1e90;        // 0x1e90\n    int x1e94;        // 0x1e94\n    int x1e98;        // 0x1e98\n    int x1e9c;        // 0x1e9c\n    int x1ea0;        // 0x1ea0\n    int x1ea4;        // 0x1ea4\n    int x1ea8;        // 0x1ea8\n    int x1eac;        // 0x1eac\n    int x1eb0;        // 0x1eb0\n    int x1eb4;        // 0x1eb4\n    int x1eb8;        // 0x1eb8\n    int x1ebc;        // 0x1ebc\n    int x1ec0;        // 0x1ec0\n    int x1ec4;        // 0x1ec4\n    int x1ec8;        // 0x1ec8\n    int x1ecc;        // 0x1ecc\n    int x1ed0;        // 0x1ed0\n    int x1ed4;        // 0x1ed4\n    int x1ed8;        // 0x1ed8\n    int x1edc;        // 0x1edc\n    int x1ee0;        // 0x1ee0\n    int x1ee4;        // 0x1ee4\n    int x1ee8;        // 0x1ee8\n    int x1eec;        // 0x1eec\n    int x1ef0;        // 0x1ef0\n    int x1ef4;        // 0x1ef4\n    int x1ef8;        // 0x1ef8\n    int x1efc;        // 0x1efc\n    int x1f00;        // 0x1f00\n    int x1f04;        // 0x1f04\n    int x1f08;        // 0x1f08\n    int x1f0c;        // 0x1f0c\n    int x1f10;        // 0x1f10\n    int x1f14;        // 0x1f14\n    int x1f18;        // 0x1f18\n    int x1f1c;        // 0x1f1c\n    int x1f20;        // 0x1f20\n    int x1f24;        // 0x1f24\n    int x1f28;        // 0x1f28\n    int x1f2c;        // 0x1f2c\n    int x1f30;        // 0x1f30\n    int x1f34;        // 0x1f34\n    int x1f38;        // 0x1f38\n    int x1f3c;        // 0x1f3c\n    int x1f40;        // 0x1f40\n    int x1f44;        // 0x1f44\n    int x1f48;        // 0x1f48\n    int x1f4c;        // 0x1f4c\n    int x1f50;        // 0x1f50\n    int x1f54;        // 0x1f54\n    int x1f58;        // 0x1f58\n    int x1f5c;        // 0x1f5c\n    int x1f60;        // 0x1f60\n    int x1f64;        // 0x1f64\n    int x1f68;        // 0x1f68\n    int x1f6c;        // 0x1f6c\n    int x1f70;        // 0x1f70\n    int x1f74;        // 0x1f74\n    int x1f78;        // 0x1f78\n    int x1f7c;        // 0x1f7c\n    int x1f80;        // 0x1f80\n    int x1f84;        // 0x1f84\n    int x1f88;        // 0x1f88\n    int x1f8c;        // 0x1f8c\n    int x1f90;        // 0x1f90\n    int x1f94;        // 0x1f94\n    int x1f98;        // 0x1f98\n    int x1f9c;        // 0x1f9c\n    int x1fa0;        // 0x1fa0\n    int x1fa4;        // 0x1fa4\n    int x1fa8;        // 0x1fa8\n    int x1fac;        // 0x1fac\n    int x1fb0;        // 0x1fb0\n    int x1fb4;        // 0x1fb4\n    int x1fb8;        // 0x1fb8\n    int x1fbc;        // 0x1fbc\n    int x1fc0;        // 0x1fc0\n    int x1fc4;        // 0x1fc4\n    int x1fc8;        // 0x1fc8\n    int x1fcc;        // 0x1fcc\n    int x1fd0;        // 0x1fd0\n    int x1fd4;        // 0x1fd4\n    int x1fd8;        // 0x1fd8\n    int x1fdc;        // 0x1fdc\n    int x1fe0;        // 0x1fe0\n    int x1fe4;        // 0x1fe4\n    int x1fe8;        // 0x1fe8\n    int x1fec;        // 0x1fec\n    int x1ff0;        // 0x1ff0\n    int x1ff4;        // 0x1ff4\n    int x1ff8;        // 0x1ff8\n    int x1ffc;        // 0x1ffc\n    int x2000;        // 0x2000\n    int x2004;        // 0x2004\n    int x2008;        // 0x2008\n    int x200c;        // 0x200c\n    int x2010;        // 0x2010\n    int x2014;        // 0x2014\n    int x2018;        // 0x2018\n    int x201c;        // 0x201c\n    int x2020;        // 0x2020\n    int x2024;        // 0x2024\n    int x2028;        // 0x2028\n    int x202c;        // 0x202c\n    int x2030;        // 0x2030\n    int x2034;        // 0x2034\n    int x2038;        // 0x2038\n    int x203c;        // 0x203c\n    int x2040;        // 0x2040\n    int x2044;        // 0x2044\n    int x2048;        // 0x2048\n    int x204c;        // 0x204c\n    int x2050;        // 0x2050\n    int x2054;        // 0x2054\n    int x2058;        // 0x2058\n    int x205c;        // 0x205c\n    int x2060;        // 0x2060\n    int x2064;        // 0x2064\n    int x2068;        // 0x2068\n    int x206c;        // 0x206c\n    int x2070;        // 0x2070\n    int x2074;        // 0x2074\n    int x2078;        // 0x2078\n    int x207c;        // 0x207c\n    int x2080;        // 0x2080\n    int x2084;        // 0x2084\n    int x2088;        // 0x2088\n    int x208c;        // 0x208c\n    int x2090;        // 0x2090\n    int x2094;        // 0x2094\n    int x2098;        // 0x2098\n    int x209c;        // 0x209c\n    int x20a0;        // 0x20a0\n    int x20a4;        // 0x20a4\n    int x20a8;        // 0x20a8\n    int x20ac;        // 0x20ac\n    int x20b0;        // 0x20b0\n    int x20b4;        // 0x20b4\n    int x20b8;        // 0x20b8\n    int x20bc;        // 0x20bc\n    int x20c0;        // 0x20c0\n    int x20c4;        // 0x20c4\n    int x20c8;        // 0x20c8\n    int x20cc;        // 0x20cc\n    int x20d0;        // 0x20d0\n    int x20d4;        // 0x20d4\n    int x20d8;        // 0x20d8\n    int x20dc;        // 0x20dc\n    int x20e0;        // 0x20e0\n    int x20e4;        // 0x20e4\n    int x20e8;        // 0x20e8\n    int x20ec;        // 0x20ec\n    int x20f0;        // 0x20f0\n    int x20f4;        // 0x20f4\n    int x20f8;        // 0x20f8\n    int x20fc;        // 0x20fc\n    int x2100;        // 0x2100\n    int x2104;        // 0x2104\n    int x2108;        // 0x2108\n    int x210c;        // 0x210c\n    int x2110;        // 0x2110\n    int x2114;        // 0x2114\n    int x2118;        // 0x2118\n    int x211c;        // 0x211c\n    int x2120;        // 0x2120\n    int x2124;        // 0x2124\n    int x2128;        // 0x2128\n    int x212c;        // 0x212c\n    int x2130;        // 0x2130\n    int x2134;        // 0x2134\n    int x2138;        // 0x2138\n    int x213c;        // 0x213c\n    int x2140;        // 0x2140\n    int x2144;        // 0x2144\n    int x2148;        // 0x2148\n    int x214c;        // 0x214c\n    int x2150;        // 0x2150\n    int x2154;        // 0x2154\n    int x2158;        // 0x2158\n    int x215c;        // 0x215c\n    int x2160;        // 0x2160\n    int x2164;        // 0x2164\n    int x2168;        // 0x2168\n    int x216c;        // 0x216c\n    int x2170;        // 0x2170\n    int x2174;        // 0x2174\n    int x2178;        // 0x2178\n    int x217c;        // 0x217c\n    int x2180;        // 0x2180\n    int x2184;        // 0x2184\n    int x2188;        // 0x2188\n    int x218c;        // 0x218c\n    int x2190;        // 0x2190\n    int x2194;        // 0x2194\n    int x2198;        // 0x2198\n    int x219c;        // 0x219c\n    int x21a0;        // 0x21a0\n    int x21a4;        // 0x21a4\n    int x21a8;        // 0x21a8\n    int x21ac;        // 0x21ac\n    int x21b0;        // 0x21b0\n    int x21b4;        // 0x21b4\n    int x21b8;        // 0x21b8\n    int x21bc;        // 0x21bc\n    int x21c0;        // 0x21c0\n    int x21c4;        // 0x21c4\n    int x21c8;        // 0x21c8\n    int x21cc;        // 0x21cc\n    int x21d0;        // 0x21d0\n    int x21d4;        // 0x21d4\n    int x21d8;        // 0x21d8\n    int x21dc;        // 0x21dc\n    int x21e0;        // 0x21e0\n    int x21e4;        // 0x21e4\n    int x21e8;        // 0x21e8\n    int x21ec;        // 0x21ec\n    int x21f0;        // 0x21f0\n    int x21f4;        // 0x21f4\n    int x21f8;        // 0x21f8\n    int x21fc;        // 0x21fc\n    int x2200;        // 0x2200\n    int x2204;        // 0x2204\n    int x2208;        // 0x2208\n    int x220c;        // 0x220c\n    int x2210;        // 0x2210\n    int x2214;        // 0x2214\n    int x2218;        // 0x2218\n    int x221c;        // 0x221c\n    int x2220;        // 0x2220\n    int x2224;        // 0x2224\n    int x2228;        // 0x2228\n    int x222c;        // 0x222c\n    int x2230;        // 0x2230\n    int x2234;        // 0x2234\n    int x2238;        // 0x2238\n    int x223c;        // 0x223c\n    int x2240;        // 0x2240\n    int x2244;        // 0x2244\n    int x2248;        // 0x2248\n    int x224c;        // 0x224c\n    int x2250;        // 0x2250\n    int x2254;        // 0x2254\n    int x2258;        // 0x2258\n    int x225c;        // 0x225c\n    int x2260;        // 0x2260\n    int x2264;        // 0x2264\n    int x2268;        // 0x2268\n    int x226c;        // 0x226c\n    int x2270;        // 0x2270\n    int x2274;        // 0x2274\n    int x2278;        // 0x2278\n    int x227c;        // 0x227c\n    int x2280;        // 0x2280\n    int x2284;        // 0x2284\n    int x2288;        // 0x2288\n    int x228c;        // 0x228c\n    int x2290;        // 0x2290\n    int x2294;        // 0x2294\n    int x2298;        // 0x2298\n    int x229c;        // 0x229c\n    int x22a0;        // 0x22a0\n    int x22a4;        // 0x22a4\n    int x22a8;        // 0x22a8\n    int x22ac;        // 0x22ac\n    int x22b0;        // 0x22b0\n    int x22b4;        // 0x22b4\n    int x22b8;        // 0x22b8\n    int x22bc;        // 0x22bc\n    int x22c0;        // 0x22c0\n    int x22c4;        // 0x22c4\n    int x22c8;        // 0x22c8\n    int x22cc;        // 0x22cc\n    int x22d0;        // 0x22d0\n    int x22d4;        // 0x22d4\n    int x22d8;        // 0x22d8\n    int x22dc;        // 0x22dc\n    int x22e0;        // 0x22e0\n    int x22e4;        // 0x22e4\n    int x22e8;        // 0x22e8\n    int x22ec;        // 0x22ec\n    int x22f0;        // 0x22f0\n    int x22f4;        // 0x22f4\n    int x22f8;        // 0x22f8\n    int x22fc;        // 0x22fc\n    int x2300;        // 0x2300\n    int x2304;        // 0x2304\n    int x2308;        // 0x2308\n    int x230c;        // 0x230c\n    int x2310;        // 0x2310\n    int x2314;        // 0x2314\n    int x2318;        // 0x2318\n    int x231c;        // 0x231c\n    int x2320;        // 0x2320\n    int x2324;        // 0x2324\n    int x2328;        // 0x2328\n    int x232c;        // 0x232c\n    int x2330;        // 0x2330\n    int x2334;        // 0x2334\n    int x2338;        // 0x2338\n    int x233c;        // 0x233c\n    int x2340;        // 0x2340\n    int x2344;        // 0x2344\n    int x2348;        // 0x2348\n    int x234c;        // 0x234c\n    int x2350;        // 0x2350\n    int x2354;        // 0x2354\n    int x2358;        // 0x2358\n    int x235c;        // 0x235c\n    int x2360;        // 0x2360\n    int x2364;        // 0x2364\n    int x2368;        // 0x2368\n    int x236c;        // 0x236c\n    int x2370;        // 0x2370\n    int x2374;        // 0x2374\n    int x2378;        // 0x2378\n    int x237c;        // 0x237c\n    int x2380;        // 0x2380\n    int x2384;        // 0x2384\n    int x2388;        // 0x2388\n    int x238c;        // 0x238c\n    int x2390;        // 0x2390\n    int x2394;        // 0x2394\n    int x2398;        // 0x2398\n    int x239c;        // 0x239c\n    int x23a0;        // 0x23a0\n    int x23a4;        // 0x23a4\n    int x23a8;        // 0x23a8\n    int x23ac;        // 0x23ac\n    int x23b0;        // 0x23b0\n    int x23b4;        // 0x23b4\n    int x23b8;        // 0x23b8\n    int x23bc;        // 0x23bc\n    int x23c0;        // 0x23c0\n    int x23c4;        // 0x23c4\n    int x23c8;        // 0x23c8\n    int x23cc;        // 0x23cc\n    int x23d0;        // 0x23d0\n    int x23d4;        // 0x23d4\n    int x23d8;        // 0x23d8\n    int x23dc;        // 0x23dc\n    int x23e0;        // 0x23e0\n    int x23e4;        // 0x23e4\n    int x23e8;        // 0x23e8\n    int x23ec;        // 0x23ec\n    int x23f0;        // 0x23f0\n    int x23f4;        // 0x23f4\n    int x23f8;        // 0x23f8\n    int x23fc;        // 0x23fc\n    int x2400;        // 0x2400\n    int x2404;        // 0x2404\n    int x2408;        // 0x2408\n    int x240c;        // 0x240c\n    int x2410;        // 0x2410\n    int x2414;        // 0x2414\n    int x2418;        // 0x2418\n    int x241c;        // 0x241c\n    int x2420;        // 0x2420\n    int x2424;        // 0x2424\n    int x2428;        // 0x2428\n    int x242c;        // 0x242c\n    int x2430;        // 0x2430\n    int x2434;        // 0x2434\n    int x2438;        // 0x2438\n    int x243c;        // 0x243c\n    int x2440;        // 0x2440\n    int x2444;        // 0x2444\n    int x2448;        // 0x2448\n    int x244c;        // 0x244c\n    int x2450;        // 0x2450\n    int x2454;        // 0x2454\n    int x2458;        // 0x2458\n    int x245c;        // 0x245c\n    int x2460;        // 0x2460\n    int x2464;        // 0x2464\n    int x2468;        // 0x2468\n    int x246c;        // 0x246c\n    int x2470;        // 0x2470\n    int x2474;        // 0x2474\n    int x2478;        // 0x2478\n    int x247c;        // 0x247c\n    int x2480;        // 0x2480\n    int x2484;        // 0x2484\n    int x2488;        // 0x2488\n    int x248c;        // 0x248c\n    int x2490;        // 0x2490\n    int x2494;        // 0x2494\n    int x2498;        // 0x2498\n    int x249c;        // 0x249c\n    int x24a0;        // 0x24a0\n    int x24a4;        // 0x24a4\n    int x24a8;        // 0x24a8\n    int x24ac;        // 0x24ac\n    int x24b0;        // 0x24b0\n    int x24b4;        // 0x24b4\n    int x24b8;        // 0x24b8\n    int x24bc;        // 0x24bc\n    int x24c0;        // 0x24c0\n    int x24c4;        // 0x24c4\n    MatchInit match;  // 0x24c8\n};\n\nstatic Match *stc_match = 0x8046b6a0;\nstatic MatchCamera *stc_matchcam = 0x80452c68;\nstatic MatchHUD *stc_matchhud = 0x804a10c8;\nMatchOffscreen *stc_match_offscreen = 0x804a1df0;\n\n/*** Functions ***/\n\nCameraBox *CameraBox_Alloc();\nvoid CameraBox_Destroy(CameraBox *cam);\nvoid KOCount_Init(int updateCallback);\nvoid KOCount_Update(int KOs);\nvoid Stage_CameraLimitInitialization();\nvoid Stage_BlastzoneInitialization();\nvoid Match_SetEndGraphic(int graphic);\nvoid Match_EndImmediate();\nvoid Match_EndVS();\nvoid Match_FadeScreen(int time);\nint Match_CheckIfTeams();\nint Match_CheckIfStock();\nvoid Match_SetPostMatchSFX(int sfx);\nvoid Match_FreezeGame(int freeze_kind);\nvoid Match_UnfreezeGame(int freeze_kind);\nvoid Match_CreateHUD(int ply);\nvoid Match_HideHUD();\nvoid Match_ShowHUD();\nvoid Match_ShowTimer();\nvoid Match_HideTimer();\nvoid Match_CorrectCamera();\nvoid Match_SetNormalCamera();\nvoid Match_SetFreeCamera(int unk, int unk2);\nvoid Match_SetZoomCamera(int unk, int unk2);\nvoid Match_SetFixedCamera();\nvoid Match_SetDevelopCamera();\nvoid DevCam_AdjustRotate(COBJ *cobj, Vec3 *wobjpos, Vec3 *rotate, float stickX, float stickY);\nvoid DevCam_AdjustPan(COBJ *cobj, float stickX, float stickY);\nvoid DevCam_AdjustZoom(COBJ *cobj, float stickY);\nvoid ScreenFlash_Create(int kind, int unk);\nvoid ScreenRumble_Execute(int kind, Vec3 *pos);\nvoid Match_StoreGoCallback(GOBJ *gobj, void *cb);\nvoid Match_AdjustSoundOnPause(int is_pause);\nVec3 *Match_GetPlayerHUDPos(int ply);\nCOBJ *Match_GetCObj();\n#endif\n"
  },
  {
    "path": "MexTK/include/math.h",
    "content": "#ifndef MEX_H_MATH\n#define MEX_H_MATH\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n\n#define M_PI 3.14159265358979323846\n#define M_1DEGREE 0.0174533\n\n/*** Functions ***/\n\nfloat atan(float in);\nfloat atan2(float y, float x);\nfloat sin(float x);\nfloat cos(float x);\nvoid MTXLookAt(Mtx *dest, Vec3 *eye, Vec3 *up, Vec3 *target);\nvoid VECNormalize(Vec3 *src, Vec3 *dest);\nvoid VECAdd(Vec3 *a, Vec3 *b, Vec3 *ab);\nvoid VECSubtract(Vec3 *a, Vec3 *b, Vec3 *a_b);\nvoid VECMultAndAdd(Vec3 *a, Vec3 *b);\nfloat VECDotProduct(Vec3 *a, Vec3 *b);\nvoid VECCrossProduct(Vec3 *a, Vec3 *b, Vec3 *axb);\nvoid MTXQuat(Vec4 *dest, Mtx *m);\nvoid HSD_MtxGetRotation(Mtx *m, Vec3 *dest);\nvoid MatToQuat(Mtx *m, Vec3 *dest);\nfloat sqrtf(float num);\nvoid MTXRotRad(Mtx m, char axis, f32 rad);\n\n#endif\n"
  },
  {
    "path": "MexTK/include/memcard.h",
    "content": "#ifndef MEX_H_MEMCARD\n#define MEX_H_MEMCARD\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"css.h\"\n\n#define MEMCARD_BANNER_SIZE 0x1800\n#define MEMCARD_ICON_SIZE 0x400\n\n/*** Memcard Library ***/\nvoid Memcard_InitWorkArea();\nvoid Memcard_LoadAssets(int unk);\nRules1 *Memcard_GetRules1();\nvoid Memcard_InitSnapshotList(void *snap_data, void *snap_list);\nvoid Memcard_UpdateSnapshotList(int slot);\nvoid Memcard_CreateSnapshot(int slot, char *save_id, MemcardSave *memcard_save, MemcardUnk *memcard_unk, char *file_name, _HSD_ImageDesc *banner, _HSD_ImageDesc *icon, int unk);\nvoid Memcard_DeleteSnapshot(int slot, int index);\nvoid Memcard_LoadSnapshot(int slot, char *save_id, MemcardSave *memcard_save, char *file_name, _HSD_ImageDesc *banner, _HSD_ImageDesc *icon, int unk);\nint Memcard_CheckStatus(); // returns 11 when operation in effect\nvoid Memcard_RemovedCallback();\nvoid Memcard_Deobfuscate(void *data, int size);\n\n/*** Structs ***/\nstruct Memcard\n{\n    int unk0;              //0x0\n    int unk1;              //0x4\n    int unk2;              //0x8\n    int unk3;              //0xC\n    int unk4;              //0x10\n    int unk5;              //0x14\n    int unk6;              //0x18\n    int unk7;              //0x1C\n    int unk8;              //0x20\n    int unk9;              //0x24\n    int unk10;             //0x28\n    int unk11;             //0x2C\n    int unk12;             //0x30\n    int unk13;             //0x34\n    int unk14;             //0x38\n    int unk15;             //0x3C\n    int unk16;             //0x40\n    int unk17;             //0x44\n    int unk18;             //0x48\n    int unk19;             //0x4C\n    int unk20;             //0x50\n    int unk21;             //0x54\n    int unk22;             //0x58\n    int unk23;             //0x5C\n    int unk24;             //0x60\n    int unk25;             //0x64\n    int unk26;             //0x68\n    int unk27;             //0x6C\n    int unk28;             //0x70\n    int unk29;             //0x74\n    int unk30;             //0x78\n    int unk31;             //0x7C\n    int unk32;             //0x80\n    int unk33;             //0x84\n    int unk34;             //0x88\n    int unk35;             //0x8C\n    int unk36;             //0x90\n    int unk37;             //0x94\n    int unk38;             //0x98\n    int unk39;             //0x9C\n    int unk40;             //0xA0\n    int unk41;             //0xA4\n    int unk42;             //0xA8\n    int unk43;             //0xAC\n    int unk44;             //0xB0\n    int unk45;             //0xB4\n    int unk46;             //0xB8\n    int unk47;             //0xBC\n    int unk48;             //0xC0\n    int unk49;             //0xC4\n    int unk50;             //0xC8\n    int unk51;             //0xCC\n    int unk52;             //0xD0\n    int unk53;             //0xD4\n    int unk54;             //0xD8\n    int unk55;             //0xDC\n    int unk56;             //0xE0\n    int unk57;             //0xE4\n    int unk58;             //0xE8\n    int unk59;             //0xEC\n    int unk60;             //0xF0\n    int unk61;             //0xF4\n    int unk62;             //0xF8\n    int unk63;             //0xFC\n    int unk64;             //0x100\n    int unk65;             //0x104\n    int unk66;             //0x108\n    int unk67;             //0x10C\n    int unk68;             //0x110\n    int unk69;             //0x114\n    int unk70;             //0x118\n    int unk71;             //0x11C\n    int unk72;             //0x120\n    int unk73;             //0x124\n    int unk74;             //0x128\n    int unk75;             //0x12C\n    int unk76;             //0x130\n    int unk77;             //0x134\n    int unk78;             //0x138\n    int unk79;             //0x13C\n    int unk80;             //0x140\n    int unk81;             //0x144\n    int unk82;             //0x148\n    int unk83;             //0x14C\n    int unk84;             //0x150\n    int unk85;             //0x154\n    int unk86;             //0x158\n    int unk87;             //0x15C\n    int unk88;             //0x160\n    int unk89;             //0x164\n    int unk90;             //0x168\n    int unk91;             //0x16C\n    int unk92;             //0x170\n    int unk93;             //0x174\n    int unk94;             //0x178\n    int unk95;             //0x17C\n    int unk96;             //0x180\n    int unk97;             //0x184\n    int unk98;             //0x188\n    int unk99;             //0x18C\n    int unk100;            //0x190\n    int unk101;            //0x194\n    int unk102;            //0x198\n    int unk103;            //0x19C\n    int unk104;            //0x1A0\n    int unk105;            //0x1A4\n    int unk106;            //0x1A8\n    int unk107;            //0x1AC\n    int unk108;            //0x1B0\n    int unk109;            //0x1B4\n    int unk110;            //0x1B8\n    int unk111;            //0x1BC\n    int unk112;            //0x1C0\n    int unk113;            //0x1C4\n    int unk114;            //0x1C8\n    int unk115;            //0x1CC\n    int unk116;            //0x1D0\n    int unk117;            //0x1D4\n    int unk118;            //0x1D8\n    int unk119;            //0x1DC\n    int unk120;            //0x1E0\n    int unk121;            //0x1E4\n    int unk122;            //0x1E8\n    int unk123;            //0x1EC\n    int unk124;            //0x1F0\n    int unk125;            //0x1F4\n    int unk126;            //0x1F8\n    int unk127;            //0x1FC\n    int unk128;            //0x200\n    int unk129;            //0x204\n    int unk130;            //0x208\n    int unk131;            //0x20C\n    int unk132;            //0x210\n    int unk133;            //0x214\n    int unk134;            //0x218\n    int unk135;            //0x21C\n    int unk136;            //0x220\n    int unk137;            //0x224\n    int unk138;            //0x228\n    int unk139;            //0x22C\n    int unk140;            //0x230\n    int unk141;            //0x234\n    int unk142;            //0x238\n    int unk143;            //0x23C\n    int unk144;            //0x240\n    int unk145;            //0x244\n    int unk146;            //0x248\n    int unk147;            //0x24C\n    int unk148;            //0x250\n    int unk149;            //0x254\n    int unk150;            //0x258\n    int unk151;            //0x25C\n    int unk152;            //0x260\n    int unk153;            //0x264\n    int unk154;            //0x268\n    int unk155;            //0x26C\n    int unk156;            //0x270\n    int unk157;            //0x274\n    int unk158;            //0x278\n    int unk159;            //0x27C\n    int unk160;            //0x280\n    int unk161;            //0x284\n    int unk162;            //0x288\n    int unk163;            //0x28C\n    int unk164;            //0x290\n    int unk165;            //0x294\n    int unk166;            //0x298\n    int unk167;            //0x29C\n    int unk168;            //0x2A0\n    int unk169;            //0x2A4\n    int unk170;            //0x2A8\n    int unk171;            //0x2AC\n    int unk172;            //0x2B0\n    int unk173;            //0x2B4\n    int unk174;            //0x2B8\n    int unk175;            //0x2BC\n    int unk176;            //0x2C0\n    int unk177;            //0x2C4\n    int unk178;            //0x2C8\n    int unk179;            //0x2CC\n    int unk180;            //0x2D0\n    int unk181;            //0x2D4\n    int unk182;            //0x2D8\n    int unk183;            //0x2DC\n    int unk184;            //0x2E0\n    int unk185;            //0x2E4\n    int unk186;            //0x2E8\n    int unk187;            //0x2EC\n    int unk188;            //0x2F0\n    int unk189;            //0x2F4\n    int unk190;            //0x2F8\n    int unk191;            //0x2FC\n    int unk192;            //0x300\n    int unk193;            //0x304\n    int unk194;            //0x308\n    int unk195;            //0x30C\n    int unk196;            //0x310\n    int unk197;            //0x314\n    int unk198;            //0x318\n    int unk199;            //0x31C\n    int unk200;            //0x320\n    int unk201;            //0x324\n    int unk202;            //0x328\n    int unk203;            //0x32C\n    int unk204;            //0x330\n    int unk205;            //0x334\n    int unk206;            //0x338\n    int unk207;            //0x33C\n    int unk208;            //0x340\n    int unk209;            //0x344\n    int unk210;            //0x348\n    int unk211;            //0x34C\n    int unk212;            //0x350\n    int unk213;            //0x354\n    int unk214;            //0x358\n    int unk215;            //0x35C\n    int unk216;            //0x360\n    int unk217;            //0x364\n    int unk218;            //0x368\n    int unk219;            //0x36C\n    int unk220;            //0x370\n    int unk221;            //0x374\n    int unk222;            //0x378\n    int unk223;            //0x37C\n    int unk224;            //0x380\n    int unk225;            //0x384\n    int unk226;            //0x388\n    int unk227;            //0x38C\n    int unk228;            //0x390\n    int unk229;            //0x394\n    int unk230;            //0x398\n    int unk231;            //0x39C\n    int unk232;            //0x3A0\n    int unk233;            //0x3A4\n    int unk234;            //0x3A8\n    int unk235;            //0x3AC\n    int unk236;            //0x3B0\n    int unk237;            //0x3B4\n    int unk238;            //0x3B8\n    int unk239;            //0x3BC\n    int unk240;            //0x3C0\n    int unk241;            //0x3C4\n    int unk242;            //0x3C8\n    int unk243;            //0x3CC\n    int unk244;            //0x3D0\n    int unk245;            //0x3D4\n    int unk246;            //0x3D8\n    int unk247;            //0x3DC\n    int unk248;            //0x3E0\n    int unk249;            //0x3E4\n    int unk250;            //0x3E8\n    int unk251;            //0x3EC\n    int unk252;            //0x3F0\n    int unk253;            //0x3F4\n    int unk254;            //0x3F8\n    int unk255;            //0x3FC\n    int unk256;            //0x400\n    int unk257;            //0x404\n    int unk258;            //0x408\n    int unk259;            //0x40C\n    int unk260;            //0x410\n    int unk261;            //0x414\n    int unk262;            //0x418\n    int unk263;            //0x41C\n    int unk264;            //0x420\n    int unk265;            //0x424\n    int unk266;            //0x428\n    int unk267;            //0x42C\n    int unk268;            //0x430\n    int unk269;            //0x434\n    int unk270;            //0x438\n    int unk271;            //0x43C\n    int unk272;            //0x440\n    int unk273;            //0x444\n    int unk274;            //0x448\n    int unk275;            //0x44C\n    int unk276;            //0x450\n    int unk277;            //0x454\n    int unk278;            //0x458\n    int unk279;            //0x45C\n    int unk280;            //0x460\n    int unk281;            //0x464\n    int unk282;            //0x468\n    int unk283;            //0x46C\n    int unk284;            //0x470\n    int unk285;            //0x474\n    int unk286;            //0x478\n    int unk287;            //0x47C\n    int unk288;            //0x480\n    int unk289;            //0x484\n    int unk290;            //0x488\n    int unk291;            //0x48C\n    int unk292;            //0x490\n    int unk293;            //0x494\n    int unk294;            //0x498\n    int unk295;            //0x49C\n    int unk296;            //0x4A0\n    int unk297;            //0x4A4\n    int unk298;            //0x4A8\n    int unk299;            //0x4AC\n    int unk300;            //0x4B0\n    int unk301;            //0x4B4\n    int unk302;            //0x4B8\n    int unk303;            //0x4BC\n    int unk304;            //0x4C0\n    int unk305;            //0x4C4\n    int unk306;            //0x4C8\n    int unk307;            //0x4CC\n    int unk308;            //0x4D0\n    int unk309;            //0x4D4\n    int unk310;            //0x4D8\n    int unk311;            //0x4DC\n    int unk312;            //0x4E0\n    int unk313;            //0x4E4\n    int unk314;            //0x4E8\n    int unk315;            //0x4EC\n    int unk316;            //0x4F0\n    int unk317;            //0x4F4\n    int unk318;            //0x4F8\n    int unk319;            //0x4FC\n    int unk320;            //0x500\n    int unk321;            //0x504\n    int unk322;            //0x508\n    int unk323;            //0x50C\n    int unk324;            //0x510\n    int unk325;            //0x514\n    int unk326;            //0x518\n    int unk327;            //0x51C\n    int unk328;            //0x520\n    int unk329;            //0x524\n    int unk330;            //0x528\n    int unk331;            //0x52C\n    CSSBackup EventBackup; //0x530\n    int unk335;            //0x53C\n    int unk336;            //0x540\n    int unk337;            //0x544\n    int unk338;            //0x548\n    int unk339;            //0x54C\n    int unk340;            //0x550\n    int unk341;            //0x554\n    int unk342;            //0x558\n    int unk343;            //0x55C\n    int unk344;            //0x560\n    int unk345;            //0x564\n    int unk346;            //0x568\n    int unk347;            //0x56C\n    int unk348;            //0x570\n    int unk349;            //0x574\n    int unk350;            //0x578\n    int unk351;            //0x57C\n    int unk352;            //0x580\n    int unk353;            //0x584\n    int unk354;            //0x588\n    int unk355;            //0x58C\n    int unk356;            //0x590\n    int unk357;            //0x594\n    int unk358;            //0x598\n    int unk359;            //0x59C\n    int unk360;            //0x5A0\n    int unk361;            //0x5A4\n    int unk362;            //0x5A8\n    int unk363;            //0x5AC\n    int unk364;            //0x5B0\n    int unk365;            //0x5B4\n    int unk366;            //0x5B8\n    int unk367;            //0x5BC\n    int unk368;            //0x5C0\n    int unk369;            //0x5C4\n    int unk370;            //0x5C8\n    int unk371;            //0x5CC\n    int unk372;            //0x5D0\n    int unk373;            //0x5D4\n    int unk374;            //0x5D8\n    int unk375;            //0x5DC\n    int unk376;            //0x5E0\n    int unk377;            //0x5E4\n    int unk378;            //0x5E8\n    int unk379;            //0x5EC\n    int unk380;            //0x5F0\n    int unk381;            //0x5F4\n    int unk382;            //0x5F8\n    int unk383;            //0x5FC\n    int unk384;            //0x600\n    int unk385;            //0x604\n    int unk386;            //0x608\n    int unk387;            //0x60C\n    int unk388;            //0x610\n    int unk389;            //0x614\n    int unk390;            //0x618\n    int unk391;            //0x61C\n    int unk392;            //0x620\n    int unk393;            //0x624\n    int unk394;            //0x628\n    int unk395;            //0x62C\n    int unk396;            //0x630\n    int unk397;            //0x634\n    int unk398;            //0x638\n    int unk399;            //0x63C\n    int unk400;            //0x640\n    int unk401;            //0x644\n    int unk402;            //0x648\n    int unk403;            //0x64C\n    int unk404;            //0x650\n    int unk405;            //0x654\n    int unk406;            //0x658\n    int unk407;            //0x65C\n    int unk408;            //0x660\n    int unk409;            //0x664\n    int unk410;            //0x668\n    int unk411;            //0x66C\n    int unk412;            //0x670\n    int unk413;            //0x674\n    int unk414;            //0x678\n    int unk415;            //0x67C\n    int unk416;            //0x680\n    int unk417;            //0x684\n    int unk418;            //0x688\n    int unk419;            //0x68C\n    int unk420;            //0x690\n    int unk421;            //0x694\n    int unk422;            //0x698\n    int unk423;            //0x69C\n    int unk424;            //0x6A0\n    int unk425;            //0x6A4\n    int unk426;            //0x6A8\n    int unk427;            //0x6AC\n    int unk428;            //0x6B0\n    int unk429;            //0x6B4\n    int unk430;            //0x6B8\n    int unk431;            //0x6BC\n    int unk432;            //0x6C0\n    int unk433;            //0x6C4\n    int unk434;            //0x6C8\n    int unk435;            //0x6CC\n    int unk436;            //0x6D0\n    int unk437;            //0x6D4\n    int unk438;            //0x6D8\n    int unk439;            //0x6DC\n    int unk440;            //0x6E0\n    int unk441;            //0x6E4\n    int unk442;            //0x6E8\n    int unk443;            //0x6EC\n    int unk444;            //0x6F0\n    int unk445;            //0x6F4\n    int unk446;            //0x6F8\n    int unk447;            //0x6FC\n    int unk448;            //0x700\n    int unk449;            //0x704\n    int unk450;            //0x708\n    int unk451;            //0x70C\n    int unk452;            //0x710\n    int unk453;            //0x714\n    int unk454;            //0x718\n    int unk455;            //0x71C\n    int unk456;            //0x720\n    int unk457;            //0x724\n    int unk458;            //0x728\n    int unk459;            //0x72C\n    int unk460;            //0x730\n    int unk461;            //0x734\n    int unk462;            //0x738\n    int unk463;            //0x73C\n    int unk464;            //0x740\n    int unk465;            //0x744\n    int unk466;            //0x748\n    int unk467;            //0x74C\n    int unk468;            //0x750\n    int unk469;            //0x754\n    int unk470;            //0x758\n    int unk471;            //0x75C\n    int unk472;            //0x760\n    int unk473;            //0x764\n    int unk474;            //0x768\n    int unk475;            //0x76C\n    int unk476;            //0x770\n    int unk477;            //0x774\n    int unk478;            //0x778\n    int unk479;            //0x77C\n    int unk480;            //0x780\n    int unk481;            //0x784\n    int unk482;            //0x788\n    int unk483;            //0x78C\n    int unk484;            //0x790\n    int unk485;            //0x794\n    int unk486;            //0x798\n    int unk487;            //0x79C\n    int unk488;            //0x7A0\n    int unk489;            //0x7A4\n    int unk490;            //0x7A8\n    int unk491;            //0x7AC\n    int unk492;            //0x7B0\n    int unk493;            //0x7B4\n    int unk494;            //0x7B8\n    int unk495;            //0x7BC\n    int unk496;            //0x7C0\n    int unk497;            //0x7C4\n    int unk498;            //0x7C8\n    int unk499;            //0x7CC\n    int unk500;            //0x7D0\n    int unk501;            //0x7D4\n    int unk502;            //0x7D8\n    int unk503;            //0x7DC\n    int unk504;            //0x7E0\n    int unk505;            //0x7E4\n    int unk506;            //0x7E8\n    int unk507;            //0x7EC\n    int unk508;            //0x7F0\n    int unk509;            //0x7F4\n    int unk510;            //0x7F8\n    int unk511;            //0x7FC\n    int unk512;            //0x800\n    int unk513;            //0x804\n    int unk514;            //0x808\n    int unk515;            //0x80C\n    int unk516;            //0x810\n    int unk517;            //0x814\n    int unk518;            //0x818\n    int unk519;            //0x81C\n    int unk520;            //0x820\n    int unk521;            //0x824\n    int unk522;            //0x828\n    int unk523;            //0x82C\n    int unk524;            //0x830\n    int unk525;            //0x834\n    int unk526;            //0x838\n    int unk527;            //0x83C\n    int unk528;            //0x840\n    int unk529;            //0x844\n    int unk530;            //0x848\n    int unk531;            //0x84C\n    int unk532;            //0x850\n    int unk533;            //0x854\n    int unk534;            //0x858\n    int unk535;            //0x85C\n    int unk536;            //0x860\n    int unk537;            //0x864\n    int unk538;            //0x868\n    int unk539;            //0x86C\n    int unk540;            //0x870\n    int unk541;            //0x874\n    int unk542;            //0x878\n    int unk543;            //0x87C\n    int unk544;            //0x880\n    int unk545;            //0x884\n    int unk546;            //0x888\n    int unk547;            //0x88C\n    int unk548;            //0x890\n    int unk549;            //0x894\n    int unk550;            //0x898\n    int unk551;            //0x89C\n    int unk552;            //0x8A0\n    int unk553;            //0x8A4\n    int unk554;            //0x8A8\n    int unk555;            //0x8AC\n    int unk556;            //0x8B0\n    int unk557;            //0x8B4\n    int unk558;            //0x8B8\n    int unk559;            //0x8BC\n    int unk560;            //0x8C0\n    int unk561;            //0x8C4\n    int unk562;            //0x8C8\n    int unk563;            //0x8CC\n    int unk564;            //0x8D0\n    int unk565;            //0x8D4\n    int unk566;            //0x8D8\n    int unk567;            //0x8DC\n    int unk568;            //0x8E0\n    int unk569;            //0x8E4\n    int unk570;            //0x8E8\n    int unk571;            //0x8EC\n    int unk572;            //0x8F0\n    int unk573;            //0x8F4\n    int unk574;            //0x8F8\n    int unk575;            //0x8FC\n    int unk576;            //0x900\n    int unk577;            //0x904\n    int unk578;            //0x908\n    int unk579;            //0x90C\n    int unk580;            //0x910\n    int unk581;            //0x914\n    int unk582;            //0x918\n    int unk583;            //0x91C\n    int unk584;            //0x920\n    int unk585;            //0x924\n    int unk586;            //0x928\n    int unk587;            //0x92C\n    int unk588;            //0x930\n    int unk589;            //0x934\n    int unk590;            //0x938\n    int unk591;            //0x93C\n    int unk592;            //0x940\n    int unk593;            //0x944\n    int unk594;            //0x948\n    int unk595;            //0x94C\n    int unk596;            //0x950\n    int unk597;            //0x954\n    int unk598;            //0x958\n    int unk599;            //0x95C\n    int unk600;            //0x960\n    int unk601;            //0x964\n    int unk602;            //0x968\n    int unk603;            //0x96C\n    int unk604;            //0x970\n    int unk605;            //0x974\n    int unk606;            //0x978\n    int unk607;            //0x97C\n    int unk608;            //0x980\n    int unk609;            //0x984\n    int unk610;            //0x988\n    int unk611;            //0x98C\n    int unk612;            //0x990\n    int unk613;            //0x994\n    int unk614;            //0x998\n    int unk615;            //0x99C\n    int unk616;            //0x9A0\n    int unk617;            //0x9A4\n    int unk618;            //0x9A8\n    int unk619;            //0x9AC\n    int unk620;            //0x9B0\n    int unk621;            //0x9B4\n    int unk622;            //0x9B8\n    int unk623;            //0x9BC\n    int unk624;            //0x9C0\n    int unk625;            //0x9C4\n    int unk626;            //0x9C8\n    int unk627;            //0x9CC\n    int unk628;            //0x9D0\n    int unk629;            //0x9D4\n    int unk630;            //0x9D8\n    int unk631;            //0x9DC\n    int unk632;            //0x9E0\n    int unk633;            //0x9E4\n    int unk634;            //0x9E8\n    int unk635;            //0x9EC\n    int unk636;            //0x9F0\n    int unk637;            //0x9F4\n    int unk638;            //0x9F8\n    int unk639;            //0x9FC\n    int unk640;            //0xA00\n    int unk641;            //0xA04\n    int unk642;            //0xA08\n    int unk643;            //0xA0C\n    int unk644;            //0xA10\n    int unk645;            //0xA14\n    int unk646;            //0xA18\n    int unk647;            //0xA1C\n    int unk648;            //0xA20\n    int unk649;            //0xA24\n    int unk650;            //0xA28\n    int unk651;            //0xA2C\n    int unk652;            //0xA30\n    int unk653;            //0xA34\n    int unk654;            //0xA38\n    int unk655;            //0xA3C\n    int unk656;            //0xA40\n    int unk657;            //0xA44\n    int unk658;            //0xA48\n    int unk659;            //0xA4C\n    int unk660;            //0xA50\n    int unk661;            //0xA54\n    int unk662;            //0xA58\n    int unk663;            //0xA5C\n    int unk664;            //0xA60\n    int unk665;            //0xA64\n    int unk666;            //0xA68\n    int unk667;            //0xA6C\n    int unk668;            //0xA70\n    int unk669;            //0xA74\n    int unk670;            //0xA78\n    int unk671;            //0xA7C\n    int unk672;            //0xA80\n    int unk673;            //0xA84\n    int unk674;            //0xA88\n    int unk675;            //0xA8C\n    int unk676;            //0xA90\n    int unk677;            //0xA94\n    int unk678;            //0xA98\n    int unk679;            //0xA9C\n    int unk680;            //0xAA0\n    int unk681;            //0xAA4\n    int unk682;            //0xAA8\n    int unk683;            //0xAAC\n    int unk684;            //0xAB0\n    int unk685;            //0xAB4\n    int unk686;            //0xAB8\n    int unk687;            //0xABC\n    int unk688;            //0xAC0\n    int unk689;            //0xAC4\n    int unk690;            //0xAC8\n    int unk691;            //0xACC\n    int unk692;            //0xAD0\n    int unk693;            //0xAD4\n    int unk694;            //0xAD8\n    int unk695;            //0xADC\n    int unk696;            //0xAE0\n    int unk697;            //0xAE4\n    int unk698;            //0xAE8\n    int unk699;            //0xAEC\n    int unk700;            //0xAF0\n    int unk701;            //0xAF4\n    int unk702;            //0xAF8\n    int unk703;            //0xAFC\n    int unk704;            //0xB00\n    int unk705;            //0xB04\n    int unk706;            //0xB08\n    int unk707;            //0xB0C\n    int unk708;            //0xB10\n    int unk709;            //0xB14\n    int unk710;            //0xB18\n    int unk711;            //0xB1C\n    int unk712;            //0xB20\n    int unk713;            //0xB24\n    int unk714;            //0xB28\n    int unk715;            //0xB2C\n    int unk716;            //0xB30\n    int unk717;            //0xB34\n    int unk718;            //0xB38\n    int unk719;            //0xB3C\n    int unk720;            //0xB40\n    int unk721;            //0xB44\n    int unk722;            //0xB48\n    int unk723;            //0xB4C\n    int unk724;            //0xB50\n    int unk725;            //0xB54\n    int unk726;            //0xB58\n    int unk727;            //0xB5C\n    int unk728;            //0xB60\n    int unk729;            //0xB64\n    int unk730;            //0xB68\n    int unk731;            //0xB6C\n    int unk732;            //0xB70\n    int unk733;            //0xB74\n    int unk734;            //0xB78\n    int unk735;            //0xB7C\n    int unk736;            //0xB80\n    int unk737;            //0xB84\n    int unk738;            //0xB88\n    int unk739;            //0xB8C\n    int unk740;            //0xB90\n    int unk741;            //0xB94\n    int unk742;            //0xB98\n    int unk743;            //0xB9C\n    int unk744;            //0xBA0\n    int unk745;            //0xBA4\n    int unk746;            //0xBA8\n    int unk747;            //0xBAC\n    int unk748;            //0xBB0\n    int unk749;            //0xBB4\n    int unk750;            //0xBB8\n    int unk751;            //0xBBC\n    int unk752;            //0xBC0\n    int unk753;            //0xBC4\n    int unk754;            //0xBC8\n    int unk755;            //0xBCC\n    int unk756;            //0xBD0\n    int unk757;            //0xBD4\n    int unk758;            //0xBD8\n    int unk759;            //0xBDC\n    int unk760;            //0xBE0\n    int unk761;            //0xBE4\n    int unk762;            //0xBE8\n    int unk763;            //0xBEC\n    int unk764;            //0xBF0\n    int unk765;            //0xBF4\n    int unk766;            //0xBF8\n    int unk767;            //0xBFC\n    int unk768;            //0xC00\n    int unk769;            //0xC04\n    int unk770;            //0xC08\n    int unk771;            //0xC0C\n    int unk772;            //0xC10\n    int unk773;            //0xC14\n    int unk774;            //0xC18\n    int unk775;            //0xC1C\n    int unk776;            //0xC20\n    int unk777;            //0xC24\n    int unk778;            //0xC28\n    int unk779;            //0xC2C\n    int unk780;            //0xC30\n    int unk781;            //0xC34\n    int unk782;            //0xC38\n    int unk783;            //0xC3C\n    int unk784;            //0xC40\n    int unk785;            //0xC44\n    int unk786;            //0xC48\n    int unk787;            //0xC4C\n    int unk788;            //0xC50\n    int unk789;            //0xC54\n    int unk790;            //0xC58\n    int unk791;            //0xC5C\n    int unk792;            //0xC60\n    int unk793;            //0xC64\n    int unk794;            //0xC68\n    int unk795;            //0xC6C\n    int unk796;            //0xC70\n    int unk797;            //0xC74\n    int unk798;            //0xC78\n    int unk799;            //0xC7C\n    int unk800;            //0xC80\n    int unk801;            //0xC84\n    int unk802;            //0xC88\n    int unk803;            //0xC8C\n    int unk804;            //0xC90\n    int unk805;            //0xC94\n    int unk806;            //0xC98\n    int unk807;            //0xC9C\n    int unk808;            //0xCA0\n    int unk809;            //0xCA4\n    int unk810;            //0xCA8\n    int unk811;            //0xCAC\n    int unk812;            //0xCB0\n    int unk813;            //0xCB4\n    int unk814;            //0xCB8\n    int unk815;            //0xCBC\n    int unk816;            //0xCC0\n    int unk817;            //0xCC4\n    int unk818;            //0xCC8\n    int unk819;            //0xCCC\n    int unk820;            //0xCD0\n    int unk821;            //0xCD4\n    int unk822;            //0xCD8\n    int unk823;            //0xCDC\n    int unk824;            //0xCE0\n    int unk825;            //0xCE4\n    int unk826;            //0xCE8\n    int unk827;            //0xCEC\n    int unk828;            //0xCF0\n    int unk829;            //0xCF4\n    int unk830;            //0xCF8\n    int unk831;            //0xCFC\n    int unk832;            //0xD00\n    int unk833;            //0xD04\n    int unk834;            //0xD08\n    int unk835;            //0xD0C\n    int unk836;            //0xD10\n    int unk837;            //0xD14\n    int unk838;            //0xD18\n    int unk839;            //0xD1C\n    int unk840;            //0xD20\n    int unk841;            //0xD24\n    int unk842;            //0xD28\n    int unk843;            //0xD2C\n    int unk844;            //0xD30\n    int unk845;            //0xD34\n    int unk846;            //0xD38\n    int unk847;            //0xD3C\n    int unk848;            //0xD40\n    int unk849;            //0xD44\n    int unk850;            //0xD48\n    int unk851;            //0xD4C\n    int unk852;            //0xD50\n    int unk853;            //0xD54\n    int unk854;            //0xD58\n    int unk855;            //0xD5C\n    int unk856;            //0xD60\n    int unk857;            //0xD64\n    int unk858;            //0xD68\n    int unk859;            //0xD6C\n    int unk860;            //0xD70\n    int unk861;            //0xD74\n    int unk862;            //0xD78\n    int unk863;            //0xD7C\n    int unk864;            //0xD80\n    int unk865;            //0xD84\n    int unk866;            //0xD88\n    int unk867;            //0xD8C\n    int unk868;            //0xD90\n    int unk869;            //0xD94\n    int unk870;            //0xD98\n    int unk871;            //0xD9C\n    int unk872;            //0xDA0\n    int unk873;            //0xDA4\n    int unk874;            //0xDA8\n    int unk875;            //0xDAC\n    int unk876;            //0xDB0\n    int unk877;            //0xDB4\n    int unk878;            //0xDB8\n    int unk879;            //0xDBC\n    int unk880;            //0xDC0\n    int unk881;            //0xDC4\n    int unk882;            //0xDC8\n    int unk883;            //0xDCC\n    int unk884;            //0xDD0\n    int unk885;            //0xDD4\n    int unk886;            //0xDD8\n    int unk887;            //0xDDC\n    int unk888;            //0xDE0\n    int unk889;            //0xDE4\n    int unk890;            //0xDE8\n    int unk891;            //0xDEC\n    int unk892;            //0xDF0\n    int unk893;            //0xDF4\n    int unk894;            //0xDF8\n    int unk895;            //0xDFC\n    int unk896;            //0xE00\n    int unk897;            //0xE04\n    int unk898;            //0xE08\n    int unk899;            //0xE0C\n    int unk900;            //0xE10\n    int unk901;            //0xE14\n    int unk902;            //0xE18\n    int unk903;            //0xE1C\n    int unk904;            //0xE20\n    int unk905;            //0xE24\n    int unk906;            //0xE28\n    int unk907;            //0xE2C\n    int unk908;            //0xE30\n    int unk909;            //0xE34\n    int unk910;            //0xE38\n    int unk911;            //0xE3C\n    int unk912;            //0xE40\n    int unk913;            //0xE44\n    int unk914;            //0xE48\n    int unk915;            //0xE4C\n    int unk916;            //0xE50\n    int unk917;            //0xE54\n    int unk918;            //0xE58\n    int unk919;            //0xE5C\n    int unk920;            //0xE60\n    int unk921;            //0xE64\n    int unk922;            //0xE68\n    int unk923;            //0xE6C\n    int unk924;            //0xE70\n    int unk925;            //0xE74\n    int unk926;            //0xE78\n    int unk927;            //0xE7C\n    int unk928;            //0xE80\n    int unk929;            //0xE84\n    int unk930;            //0xE88\n    int unk931;            //0xE8C\n    int unk932;            //0xE90\n    int unk933;            //0xE94\n    int unk934;            //0xE98\n    int unk935;            //0xE9C\n    int unk936;            //0xEA0\n    int unk937;            //0xEA4\n    int unk938;            //0xEA8\n    int unk939;            //0xEAC\n    int unk940;            //0xEB0\n    int unk941;            //0xEB4\n    int unk942;            //0xEB8\n    int unk943;            //0xEBC\n    int unk944;            //0xEC0\n    int unk945;            //0xEC4\n    int unk946;            //0xEC8\n    int unk947;            //0xECC\n    int unk948;            //0xED0\n    int unk949;            //0xED4\n    int unk950;            //0xED8\n    int unk951;            //0xEDC\n    int unk952;            //0xEE0\n    int unk953;            //0xEE4\n    int unk954;            //0xEE8\n    int unk955;            //0xEEC\n    int unk956;            //0xEF0\n    int unk957;            //0xEF4\n    int unk958;            //0xEF8\n    int unk959;            //0xEFC\n    int unk960;            //0xF00\n    int unk961;            //0xF04\n    int unk962;            //0xF08\n    int unk963;            //0xF0C\n    int unk964;            //0xF10\n    int unk965;            //0xF14\n    int unk966;            //0xF18\n    int unk967;            //0xF1C\n    int unk968;            //0xF20\n    int unk969;            //0xF24\n    int unk970;            //0xF28\n    int unk971;            //0xF2C\n    int unk972;            //0xF30\n    int unk973;            //0xF34\n    int unk974;            //0xF38\n    int unk975;            //0xF3C\n    int unk976;            //0xF40\n    int unk977;            //0xF44\n    int unk978;            //0xF48\n    int unk979;            //0xF4C\n    int unk980;            //0xF50\n    int unk981;            //0xF54\n    int unk982;            //0xF58\n    int unk983;            //0xF5C\n    int unk984;            //0xF60\n    int unk985;            //0xF64\n    int unk986;            //0xF68\n    int unk987;            //0xF6C\n    int unk988;            //0xF70\n    int unk989;            //0xF74\n    int unk990;            //0xF78\n    int unk991;            //0xF7C\n    int unk992;            //0xF80\n    int unk993;            //0xF84\n    int unk994;            //0xF88\n    int unk995;            //0xF8C\n    int unk996;            //0xF90\n    int unk997;            //0xF94\n    int unk998;            //0xF98\n    int unk999;            //0xF9C\n    int unk1000;           //0xFA0\n    int unk1001;           //0xFA4\n    int unk1002;           //0xFA8\n    int unk1003;           //0xFAC\n    int unk1004;           //0xFB0\n    int unk1005;           //0xFB4\n    int unk1006;           //0xFB8\n    int unk1007;           //0xFBC\n    int unk1008;           //0xFC0\n    int unk1009;           //0xFC4\n    int unk1010;           //0xFC8\n    int unk1011;           //0xFCC\n    int unk1012;           //0xFD0\n    int unk1013;           //0xFD4\n    int unk1014;           //0xFD8\n    int unk1015;           //0xFDC\n    int unk1016;           //0xFE0\n    int unk1017;           //0xFE4\n    int unk1018;           //0xFE8\n    int unk1019;           //0xFEC\n    int unk1020;           //0xFF0\n    int unk1021;           //0xFF4\n    int unk1022;           //0xFF8\n    int unk1023;           //0xFFC\n    int unk1024;           //0x1000\n    int unk1025;           //0x1004\n    int unk1026;           //0x1008\n    int unk1027;           //0x100C\n    int unk1028;           //0x1010\n    int unk1029;           //0x1014\n    int unk1030;           //0x1018\n    int unk1031;           //0x101C\n    int unk1032;           //0x1020\n    int unk1033;           //0x1024\n    int unk1034;           //0x1028\n    int unk1035;           //0x102C\n    int unk1036;           //0x1030\n    int unk1037;           //0x1034\n    int unk1038;           //0x1038\n    int unk1039;           //0x103C\n    int unk1040;           //0x1040\n    int unk1041;           //0x1044\n    int unk1042;           //0x1048\n    int unk1043;           //0x104C\n    int unk1044;           //0x1050\n    int unk1045;           //0x1054\n    int unk1046;           //0x1058\n    int unk1047;           //0x105C\n    int unk1048;           //0x1060\n    int unk1049;           //0x1064\n    int unk1050;           //0x1068\n    int unk1051;           //0x106C\n    int unk1052;           //0x1070\n    int unk1053;           //0x1074\n    int unk1054;           //0x1078\n    int unk1055;           //0x107C\n    int unk1056;           //0x1080\n    int unk1057;           //0x1084\n    int unk1058;           //0x1088\n    int unk1059;           //0x108C\n    int unk1060;           //0x1090\n    int unk1061;           //0x1094\n    int unk1062;           //0x1098\n    int unk1063;           //0x109C\n    int unk1064;           //0x10A0\n    int unk1065;           //0x10A4\n    int unk1066;           //0x10A8\n    int unk1067;           //0x10AC\n    int unk1068;           //0x10B0\n    int unk1069;           //0x10B4\n    int unk1070;           //0x10B8\n    int unk1071;           //0x10BC\n    int unk1072;           //0x10C0\n    int unk1073;           //0x10C4\n    int unk1074;           //0x10C8\n    int unk1075;           //0x10CC\n    int unk1076;           //0x10D0\n    int unk1077;           //0x10D4\n    int unk1078;           //0x10D8\n    int unk1079;           //0x10DC\n    int unk1080;           //0x10E0\n    int unk1081;           //0x10E4\n    int unk1082;           //0x10E8\n    int unk1083;           //0x10EC\n    int unk1084;           //0x10F0\n    int unk1085;           //0x10F4\n    int unk1086;           //0x10F8\n    int unk1087;           //0x10FC\n    int unk1088;           //0x1100\n    int unk1089;           //0x1104\n    int unk1090;           //0x1108\n    int unk1091;           //0x110C\n    int unk1092;           //0x1110\n    int unk1093;           //0x1114\n    int unk1094;           //0x1118\n    int unk1095;           //0x111C\n    int unk1096;           //0x1120\n    int unk1097;           //0x1124\n    int unk1098;           //0x1128\n    int unk1099;           //0x112C\n    int unk1100;           //0x1130\n    int unk1101;           //0x1134\n    int unk1102;           //0x1138\n    int unk1103;           //0x113C\n    int unk1104;           //0x1140\n    int unk1105;           //0x1144\n    int unk1106;           //0x1148\n    int unk1107;           //0x114C\n    int unk1108;           //0x1150\n    int unk1109;           //0x1154\n    int unk1110;           //0x1158\n    int unk1111;           //0x115C\n    int unk1112;           //0x1160\n    int unk1113;           //0x1164\n    int unk1114;           //0x1168\n    int unk1115;           //0x116C\n    int unk1116;           //0x1170\n    int unk1117;           //0x1174\n    int unk1118;           //0x1178\n    int unk1119;           //0x117C\n    int unk1120;           //0x1180\n    int unk1121;           //0x1184\n    int unk1122;           //0x1188\n    int unk1123;           //0x118C\n    int unk1124;           //0x1190\n    int unk1125;           //0x1194\n    int unk1126;           //0x1198\n    int unk1127;           //0x119C\n    int unk1128;           //0x11A0\n    int unk1129;           //0x11A4\n    int unk1130;           //0x11A8\n    int unk1131;           //0x11AC\n    int unk1132;           //0x11B0\n    int unk1133;           //0x11B4\n    int unk1134;           //0x11B8\n    int unk1135;           //0x11BC\n    int unk1136;           //0x11C0\n    int unk1137;           //0x11C4\n    int unk1138;           //0x11C8\n    int unk1139;           //0x11CC\n    int unk1140;           //0x11D0\n    int unk1141;           //0x11D4\n    int unk1142;           //0x11D8\n    int unk1143;           //0x11DC\n    int unk1144;           //0x11E0\n    int unk1145;           //0x11E4\n    int unk1146;           //0x11E8\n    int unk1147;           //0x11EC\n    int unk1148;           //0x11F0\n    int unk1149;           //0x11F4\n    int unk1150;           //0x11F8\n    int unk1151;           //0x11FC\n    int unk1152;           //0x1200\n    int unk1153;           //0x1204\n    int unk1154;           //0x1208\n    int unk1155;           //0x120C\n    int unk1156;           //0x1210\n    int unk1157;           //0x1214\n    int unk1158;           //0x1218\n    int unk1159;           //0x121C\n    int unk1160;           //0x1220\n    int unk1161;           //0x1224\n    int unk1162;           //0x1228\n    int unk1163;           //0x122C\n    int unk1164;           //0x1230\n    int unk1165;           //0x1234\n    int unk1166;           //0x1238\n    int unk1167;           //0x123C\n    int unk1168;           //0x1240\n    int unk1169;           //0x1244\n    int unk1170;           //0x1248\n    int unk1171;           //0x124C\n    int unk1172;           //0x1250\n    int unk1173;           //0x1254\n    int unk1174;           //0x1258\n    int unk1175;           //0x125C\n    int unk1176;           //0x1260\n    int unk1177;           //0x1264\n    int unk1178;           //0x1268\n    int unk1179;           //0x126C\n    int unk1180;           //0x1270\n    int unk1181;           //0x1274\n    int unk1182;           //0x1278\n    int unk1183;           //0x127C\n    int unk1184;           //0x1280\n    int unk1185;           //0x1284\n    int unk1186;           //0x1288\n    int unk1187;           //0x128C\n    int unk1188;           //0x1290\n    int unk1189;           //0x1294\n    int unk1190;           //0x1298\n    int unk1191;           //0x129C\n    int unk1192;           //0x12A0\n    int unk1193;           //0x12A4\n    int unk1194;           //0x12A8\n    int unk1195;           //0x12AC\n    int unk1196;           //0x12B0\n    int unk1197;           //0x12B4\n    int unk1198;           //0x12B8\n    int unk1199;           //0x12BC\n    int unk1200;           //0x12C0\n    int unk1201;           //0x12C4\n    int unk1202;           //0x12C8\n    int unk1203;           //0x12CC\n    int unk1204;           //0x12D0\n    int unk1205;           //0x12D4\n    int unk1206;           //0x12D8\n    int unk1207;           //0x12DC\n    int unk1208;           //0x12E0\n    int unk1209;           //0x12E4\n    int unk1210;           //0x12E8\n    int unk1211;           //0x12EC\n    int unk1212;           //0x12F0\n    int unk1213;           //0x12F4\n    int unk1214;           //0x12F8\n    int unk1215;           //0x12FC\n    int unk1216;           //0x1300\n    int unk1217;           //0x1304\n    int unk1218;           //0x1308\n    int unk1219;           //0x130C\n    int unk1220;           //0x1310\n    int unk1221;           //0x1314\n    int unk1222;           //0x1318\n    int unk1223;           //0x131C\n    int unk1224;           //0x1320\n    int unk1225;           //0x1324\n    int unk1226;           //0x1328\n    int unk1227;           //0x132C\n    int unk1228;           //0x1330\n    int unk1229;           //0x1334\n    int unk1230;           //0x1338\n    int unk1231;           //0x133C\n    int unk1232;           //0x1340\n    int unk1233;           //0x1344\n    int unk1234;           //0x1348\n    int unk1235;           //0x134C\n    int unk1236;           //0x1350\n    int unk1237;           //0x1354\n    int unk1238;           //0x1358\n    int unk1239;           //0x135C\n    int unk1240;           //0x1360\n    int unk1241;           //0x1364\n    int unk1242;           //0x1368\n    int unk1243;           //0x136C\n    int unk1244;           //0x1370\n    int unk1245;           //0x1374\n    int unk1246;           //0x1378\n    int unk1247;           //0x137C\n    int unk1248;           //0x1380\n    int unk1249;           //0x1384\n    int unk1250;           //0x1388\n    int unk1251;           //0x138C\n    int unk1252;           //0x1390\n    int unk1253;           //0x1394\n    int unk1254;           //0x1398\n    int unk1255;           //0x139C\n    int unk1256;           //0x13A0\n    int unk1257;           //0x13A4\n    int unk1258;           //0x13A8\n    int unk1259;           //0x13AC\n    int unk1260;           //0x13B0\n    int unk1261;           //0x13B4\n    int unk1262;           //0x13B8\n    int unk1263;           //0x13BC\n    int unk1264;           //0x13C0\n    int unk1265;           //0x13C4\n    int unk1266;           //0x13C8\n    int unk1267;           //0x13CC\n    int unk1268;           //0x13D0\n    int unk1269;           //0x13D4\n    int unk1270;           //0x13D8\n    int unk1271;           //0x13DC\n    int unk1272;           //0x13E0\n    int unk1273;           //0x13E4\n    int unk1274;           //0x13E8\n    int unk1275;           //0x13EC\n    int unk1276;           //0x13F0\n    int unk1277;           //0x13F4\n    int unk1278;           //0x13F8\n    int unk1279;           //0x13FC\n    int unk1280;           //0x1400\n    int unk1281;           //0x1404\n    int unk1282;           //0x1408\n    int unk1283;           //0x140C\n    int unk1284;           //0x1410\n    int unk1285;           //0x1414\n    int unk1286;           //0x1418\n    int unk1287;           //0x141C\n    int unk1288;           //0x1420\n    int unk1289;           //0x1424\n    int unk1290;           //0x1428\n    int unk1291;           //0x142C\n    int unk1292;           //0x1430\n    int unk1293;           //0x1434\n    int unk1294;           //0x1438\n    int unk1295;           //0x143C\n    int unk1296;           //0x1440\n    int unk1297;           //0x1444\n    int unk1298;           //0x1448\n    int unk1299;           //0x144C\n    int unk1300;           //0x1450\n    int unk1301;           //0x1454\n    int unk1302;           //0x1458\n    int unk1303;           //0x145C\n    int unk1304;           //0x1460\n    int unk1305;           //0x1464\n    int unk1306;           //0x1468\n    int unk1307;           //0x146C\n    int unk1308;           //0x1470\n    int unk1309;           //0x1474\n    int unk1310;           //0x1478\n    int unk1311;           //0x147C\n    int unk1312;           //0x1480\n    int unk1313;           //0x1484\n    int unk1314;           //0x1488\n    int unk1315;           //0x148C\n    int unk1316;           //0x1490\n    int unk1317;           //0x1494\n    int unk1318;           //0x1498\n    int unk1319;           //0x149C\n    int unk1320;           //0x14A0\n    int unk1321;           //0x14A4\n    int unk1322;           //0x14A8\n    int unk1323;           //0x14AC\n    int unk1324;           //0x14B0\n    int unk1325;           //0x14B4\n    int unk1326;           //0x14B8\n    int unk1327;           //0x14BC\n    int unk1328;           //0x14C0\n    int unk1329;           //0x14C4\n    int unk1330;           //0x14C8\n    int unk1331;           //0x14CC\n    int unk1332;           //0x14D0\n    int unk1333;           //0x14D4\n    int unk1334;           //0x14D8\n    int unk1335;           //0x14DC\n    int unk1336;           //0x14E0\n    int unk1337;           //0x14E4\n    int unk1338;           //0x14E8\n    int unk1339;           //0x14EC\n    int unk1340;           //0x14F0\n    int unk1341;           //0x14F4\n    int unk1342;           //0x14F8\n    int unk1343;           //0x14FC\n    int unk1344;           //0x1500\n    int unk1345;           //0x1504\n    int unk1346;           //0x1508\n    int unk1347;           //0x150C\n    int unk1348;           //0x1510\n    int unk1349;           //0x1514\n    int unk1350;           //0x1518\n    int unk1351;           //0x151C\n    int unk1352;           //0x1520\n    int unk1353;           //0x1524\n    int unk1354;           //0x1528\n    int unk1355;           //0x152C\n    int unk1356;           //0x1530\n    int unk1357;           //0x1534\n    int unk1358;           //0x1538\n    int unk1359;           //0x153C\n    int unk1360;           //0x1540\n    int unk1361;           //0x1544\n    int unk1362;           //0x1548\n    int unk1363;           //0x154C\n    int unk1364;           //0x1550\n    int unk1365;           //0x1554\n    int unk1366;           //0x1558\n    int unk1367;           //0x155C\n    int unk1368;           //0x1560\n    int unk1369;           //0x1564\n    int unk1370;           //0x1568\n    int unk1371;           //0x156C\n    int unk1372;           //0x1570\n    int unk1373;           //0x1574\n    int unk1374;           //0x1578\n    int unk1375;           //0x157C\n    int unk1376;           //0x1580\n    int unk1377;           //0x1584\n    int unk1378;           //0x1588\n    int unk1379;           //0x158C\n    int unk1380;           //0x1590\n    int unk1381;           //0x1594\n    int unk1382;           //0x1598\n    int unk1383;           //0x159C\n    int unk1384;           //0x15A0\n    int unk1385;           //0x15A4\n    int unk1386;           //0x15A8\n    int unk1387;           //0x15AC\n    int unk1388;           //0x15B0\n    int unk1389;           //0x15B4\n    int unk1390;           //0x15B8\n    int unk1391;           //0x15BC\n    int unk1392;           //0x15C0\n    int unk1393;           //0x15C4\n    int unk1394;           //0x15C8\n    int unk1395;           //0x15CC\n    int unk1396;           //0x15D0\n    int unk1397;           //0x15D4\n    int unk1398;           //0x15D8\n    int unk1399;           //0x15DC\n    int unk1400;           //0x15E0\n    int unk1401;           //0x15E4\n    int unk1402;           //0x15E8\n    int unk1403;           //0x15EC\n    int unk1404;           //0x15F0\n    int unk1405;           //0x15F4\n    int unk1406;           //0x15F8\n    int unk1407;           //0x15FC\n    int unk1408;           //0x1600\n    int unk1409;           //0x1604\n    int unk1410;           //0x1608\n    int unk1411;           //0x160C\n    int unk1412;           //0x1610\n    int unk1413;           //0x1614\n    int unk1414;           //0x1618\n    int unk1415;           //0x161C\n    int unk1416;           //0x1620\n    int unk1417;           //0x1624\n    int unk1418;           //0x1628\n    int unk1419;           //0x162C\n    int unk1420;           //0x1630\n    int unk1421;           //0x1634\n    int unk1422;           //0x1638\n    int unk1423;           //0x163C\n    int unk1424;           //0x1640\n    int unk1425;           //0x1644\n    int unk1426;           //0x1648\n    int unk1427;           //0x164C\n    int unk1428;           //0x1650\n    int unk1429;           //0x1654\n    int unk1430;           //0x1658\n    int unk1431;           //0x165C\n    int unk1432;           //0x1660\n    int unk1433;           //0x1664\n    int unk1434;           //0x1668\n    int unk1435;           //0x166C\n    int unk1436;           //0x1670\n    int unk1437;           //0x1674\n    int unk1438;           //0x1678\n    int unk1439;           //0x167C\n    int unk1440;           //0x1680\n    int unk1441;           //0x1684\n    int unk1442;           //0x1688\n    int unk1443;           //0x168C\n    int unk1444;           //0x1690\n    int unk1445;           //0x1694\n    int unk1446;           //0x1698\n    int unk1447;           //0x169C\n    int unk1448;           //0x16A0\n    int unk1449;           //0x16A4\n    int unk1450;           //0x16A8\n    int unk1451;           //0x16AC\n    int unk1452;           //0x16B0\n    int unk1453;           //0x16B4\n    int unk1454;           //0x16B8\n    int unk1455;           //0x16BC\n    int unk1456;           //0x16C0\n    int unk1457;           //0x16C4\n    int unk1458;           //0x16C8\n    int unk1459;           //0x16CC\n    int unk1460;           //0x16D0\n    int unk1461;           //0x16D4\n    int unk1462;           //0x16D8\n    int unk1463;           //0x16DC\n    int unk1464;           //0x16E0\n    int unk1465;           //0x16E4\n    int unk1466;           //0x16E8\n    int unk1467;           //0x16EC\n    int unk1468;           //0x16F0\n    int unk1469;           //0x16F4\n    int unk1470;           //0x16F8\n    int unk1471;           //0x16FC\n    int unk1472;           //0x1700\n    int unk1473;           //0x1704\n    int unk1474;           //0x1708\n    int unk1475;           //0x170C\n    int unk1476;           //0x1710\n    int unk1477;           //0x1714\n    int unk1478;           //0x1718\n    int unk1479;           //0x171C\n    int unk1480;           //0x1720\n    int unk1481;           //0x1724\n    int unk1482;           //0x1728\n    int unk1483;           //0x172C\n    int unk1484;           //0x1730\n    int unk1485;           //0x1734\n    int unk1486;           //0x1738\n    int unk1487;           //0x173C\n    int unk1488;           //0x1740\n    int unk1489;           //0x1744\n    int unk1490;           //0x1748\n    int unk1491;           //0x174C\n    int unk1492;           //0x1750\n    int unk1493;           //0x1754\n    int unk1494;           //0x1758\n    int unk1495;           //0x175C\n    int unk1496;           //0x1760\n    int unk1497;           //0x1764\n    int unk1498;           //0x1768\n    int unk1499;           //0x176C\n    int unk1500;           //0x1770\n    int unk1501;           //0x1774\n    int unk1502;           //0x1778\n    int unk1503;           //0x177C\n    int unk1504;           //0x1780\n    int unk1505;           //0x1784\n    int unk1506;           //0x1788\n    int unk1507;           //0x178C\n    int unk1508;           //0x1790\n    int unk1509;           //0x1794\n    int unk1510;           //0x1798\n    int unk1511;           //0x179C\n    int unk1512;           //0x17A0\n    int unk1513;           //0x17A4\n    int unk1514;           //0x17A8\n    int unk1515;           //0x17AC\n    int unk1516;           //0x17B0\n    int unk1517;           //0x17B4\n    int unk1518;           //0x17B8\n    int unk1519;           //0x17BC\n    int unk1520;           //0x17C0\n    int unk1521;           //0x17C4\n    int unk1522;           //0x17C8\n    int unk1523;           //0x17CC\n    int unk1524;           //0x17D0\n    int unk1525;           //0x17D4\n    int unk1526;           //0x17D8\n    int unk1527;           //0x17DC\n    int unk1528;           //0x17E0\n    int unk1529;           //0x17E4\n    int unk1530;           //0x17E8\n    int unk1531;           //0x17EC\n    int unk1532;           //0x17F0\n    int unk1533;           //0x17F4\n    int unk1534;           //0x17F8\n    int unk1535;           //0x17FC\n    int unk1536;           //0x1800\n    int unk1537;           //0x1804\n    int unk1538;           //0x1808\n    int unk1539;           //0x180C\n    int unk1540;           //0x1810\n    int unk1541;           //0x1814\n    int unk1542;           //0x1818\n    int unk1543;           //0x181C\n    int unk1544;           //0x1820\n    int unk1545;           //0x1824\n    int unk1546;           //0x1828\n    int unk1547;           //0x182C\n    int unk1548;           //0x1830\n    int unk1549;           //0x1834\n    int unk1550;           //0x1838\n    int unk1551;           //0x183C\n    int unk1552;           //0x1840\n    int unk1553;           //0x1844\n    int unk1554;           //0x1848\n    int unk1555;           //0x184C\n    int unk1556;           //0x1850\n    int unk1557;           //0x1854\n    int unk1558;           //0x1858\n    int unk1559;           //0x185C\n    int unk1560;           //0x1860\n    int unk1561;           //0x1864\n    int unk1562;           //0x1868\n    int unk1563;           //0x186C\n    int unk1564;           //0x1870\n    int unk1565;           //0x1874\n    int unk1566;           //0x1878\n    int unk1567;           //0x187C\n    int unk1568;           //0x1880\n    int unk1569;           //0x1884\n    int unk1570;           //0x1888\n    int unk1571;           //0x188C\n    int unk1572;           //0x1890\n    int unk1573;           //0x1894\n    int unk1574;           //0x1898\n    int unk1575;           //0x189C\n    int unk1576;           //0x18A0\n    int unk1577;           //0x18A4\n    int unk1578;           //0x18A8\n    int unk1579;           //0x18AC\n    int unk1580;           //0x18B0\n    int unk1581;           //0x18B4\n    int unk1582;           //0x18B8\n    int unk1583;           //0x18BC\n    int unk1584;           //0x18C0\n    int unk1585;           //0x18C4\n    int unk1586;           //0x18C8\n    int unk1587;           //0x18CC\n    int unk1588;           //0x18D0\n    int unk1589;           //0x18D4\n    int unk1590;           //0x18D8\n    int unk1591;           //0x18DC\n    int unk1592;           //0x18E0\n    int unk1593;           //0x18E4\n    int unk1594;           //0x18E8\n    int unk1595;           //0x18EC\n    int unk1596;           //0x18F0\n    int unk1597;           //0x18F4\n    int unk1598;           //0x18F8\n    int unk1599;           //0x18FC\n    int unk1600;           //0x1900\n    int unk1601;           //0x1904\n    int unk1602;           //0x1908\n    int unk1603;           //0x190C\n    int unk1604;           //0x1910\n    int unk1605;           //0x1914\n    int unk1606;           //0x1918\n    int unk1607;           //0x191C\n    int unk1608;           //0x1920\n    int unk1609;           //0x1924\n    int unk1610;           //0x1928\n    int unk1611;           //0x192C\n    int unk1612;           //0x1930\n    int unk1613;           //0x1934\n    int unk1614;           //0x1938\n    int unk1615;           //0x193C\n    int unk1616;           //0x1940\n    int unk1617;           //0x1944\n    int unk1618;           //0x1948\n    int unk1619;           //0x194C\n    int unk1620;           //0x1950\n    int unk1621;           //0x1954\n    int unk1622;           //0x1958\n    int unk1623;           //0x195C\n    int unk1624;           //0x1960\n    int unk1625;           //0x1964\n    int unk1626;           //0x1968\n    int unk1627;           //0x196C\n    int unk1628;           //0x1970\n    int unk1629;           //0x1974\n    int unk1630;           //0x1978\n    int unk1631;           //0x197C\n    int unk1632;           //0x1980\n    int unk1633;           //0x1984\n    int unk1634;           //0x1988\n    int unk1635;           //0x198C\n    int unk1636;           //0x1990\n    int unk1637;           //0x1994\n    int unk1638;           //0x1998\n    int unk1639;           //0x199C\n    int unk1640;           //0x19A0\n    int unk1641;           //0x19A4\n    int unk1642;           //0x19A8\n    int unk1643;           //0x19AC\n    int unk1644;           //0x19B0\n    int unk1645;           //0x19B4\n    int unk1646;           //0x19B8\n    int unk1647;           //0x19BC\n    int unk1648;           //0x19C0\n    int unk1649;           //0x19C4\n    int unk1650;           //0x19C8\n    int unk1651;           //0x19CC\n    int unk1652;           //0x19D0\n    int unk1653;           //0x19D4\n    int unk1654;           //0x19D8\n    int unk1655;           //0x19DC\n    int unk1656;           //0x19E0\n    int unk1657;           //0x19E4\n    int unk1658;           //0x19E8\n    int unk1659;           //0x19EC\n    int unk1660;           //0x19F0\n    int unk1661;           //0x19F4\n    int unk1662;           //0x19F8\n    int unk1663;           //0x19FC\n    int unk1664;           //0x1A00\n    int unk1665;           //0x1A04\n    int unk1666;           //0x1A08\n    int unk1667;           //0x1A0C\n    int unk1668;           //0x1A10\n    int unk1669;           //0x1A14\n    int unk1670;           //0x1A18\n    int unk1671;           //0x1A1C\n    int unk1672;           //0x1A20\n    int unk1673;           //0x1A24\n    int unk1674;           //0x1A28\n    int unk1675;           //0x1A2C\n    int unk1676;           //0x1A30\n    int unk1677;           //0x1A34\n    int unk1678;           //0x1A38\n    int unk1679;           //0x1A3C\n    int unk1680;           //0x1A40\n    int unk1681;           //0x1A44\n    int unk1682;           //0x1A48\n    int unk1683;           //0x1A4C\n    int unk1684;           //0x1A50\n    int unk1685;           //0x1A54\n    int unk1686;           //0x1A58\n    int unk1687;           //0x1A5C\n    int unk1688;           //0x1A60\n    int unk1689;           //0x1A64\n    int unk1690;           //0x1A68\n    int unk1691;           //0x1A6C\n    int unk1692;           //0x1A70\n    int unk1693;           //0x1A74\n    int unk1694;           //0x1A78\n    int unk1695;           //0x1A7C\n    int unk1696;           //0x1A80\n    int unk1697;           //0x1A84\n    int unk1698;           //0x1A88\n    int unk1699;           //0x1A8C\n    int unk1700;           //0x1A90\n    int unk1701;           //0x1A94\n    int unk1702;           //0x1A98\n    int unk1703;           //0x1A9C\n    int unk1704;           //0x1AA0\n    int unk1705;           //0x1AA4\n    int unk1706;           //0x1AA8\n    int unk1707;           //0x1AAC\n    int unk1708;           //0x1AB0\n    int unk1709;           //0x1AB4\n    int unk1710;           //0x1AB8\n    int unk1711;           //0x1ABC\n    int unk1712;           //0x1AC0\n    int unk1713;           //0x1AC4\n    int unk1714;           //0x1AC8\n    int unk1715;           //0x1ACC\n    int unk1716;           //0x1AD0\n    int unk1717;           //0x1AD4\n    int unk1718;           //0x1AD8\n    int unk1719;           //0x1ADC\n    int unk1720;           //0x1AE0\n    int unk1721;           //0x1AE4\n    int unk1722;           //0x1AE8\n    int unk1723;           //0x1AEC\n    int unk1724;           //0x1AF0\n    int unk1725;           //0x1AF4\n    int unk1726;           //0x1AF8\n    int unk1727;           //0x1AFC\n    int unk1728;           //0x1B00\n    int unk1729;           //0x1B04\n    int unk1730;           //0x1B08\n    int unk1731;           //0x1B0C\n    int unk1732;           //0x1B10\n    int unk1733;           //0x1B14\n    int unk1734;           //0x1B18\n    int unk1735;           //0x1B1C\n    int unk1736;           //0x1B20\n    int unk1737;           //0x1B24\n    int unk1738;           //0x1B28\n    int unk1739;           //0x1B2C\n    int unk1740;           //0x1B30\n    int unk1741;           //0x1B34\n    int unk1742;           //0x1B38\n    int unk1743;           //0x1B3C\n    int unk1744;           //0x1B40\n    int unk1745;           //0x1B44\n    int unk1746;           //0x1B48\n    int unk1747;           //0x1B4C\n    int unk1748;           //0x1B50\n    int unk1749;           //0x1B54\n    int unk1750;           //0x1B58\n    int unk1751;           //0x1B5C\n    int unk1752;           //0x1B60\n    int unk1753;           //0x1B64\n    int unk1754;           //0x1B68\n    int unk1755;           //0x1B6C\n    int unk1756;           //0x1B70\n    int unk1757;           //0x1B74\n    int unk1758;           //0x1B78\n    int unk1759;           //0x1B7C\n    int unk1760;           //0x1B80\n    int unk1761;           //0x1B84\n    int unk1762;           //0x1B88\n    int unk1763;           //0x1B8C\n    int unk1764;           //0x1B90\n    int unk1765;           //0x1B94\n    int unk1766;           //0x1B98\n    int unk1767;           //0x1B9C\n    int unk1768;           //0x1BA0\n    int unk1769;           //0x1BA4\n    int unk1770;           //0x1BA8\n    int unk1771;           //0x1BAC\n    int unk1772;           //0x1BB0\n    int unk1773;           //0x1BB4\n    int unk1774;           //0x1BB8\n    int unk1775;           //0x1BBC\n    int unk1776;           //0x1BC0\n    int unk1777;           //0x1BC4\n    int unk1778;           //0x1BC8\n    int unk1779;           //0x1BCC\n    int unk1780;           //0x1BD0\n    int unk1781;           //0x1BD4\n    int unk1782;           //0x1BD8\n    int unk1783;           //0x1BDC\n    int unk1784;           //0x1BE0\n    int unk1785;           //0x1BE4\n    int unk1786;           //0x1BE8\n    int unk1787;           //0x1BEC\n    int unk1788;           //0x1BF0\n    int unk1789;           //0x1BF4\n    int unk1790;           //0x1BF8\n    int unk1791;           //0x1BFC\n    int unk1792;           //0x1C00\n    int unk1793;           //0x1C04\n    int unk1794;           //0x1C08\n    int unk1795;           //0x1C0C\n    int unk1796;           //0x1C10\n    int unk1797;           //0x1C14\n    int unk1798;           //0x1C18\n    int unk1799;           //0x1C1C\n    int unk1800;           //0x1C20\n    int unk1801;           //0x1C24\n    int unk1802;           //0x1C28\n    int unk1803;           //0x1C2C\n    int unk1804;           //0x1C30\n    int unk1805;           //0x1C34\n    int unk1806;           //0x1C38\n    int unk1807;           //0x1C3C\n    int unk1808;           //0x1C40\n    int unk1809;           //0x1C44\n    int unk1810;           //0x1C48\n    int unk1811;           //0x1C4C\n    int unk1812;           //0x1C50\n    int unk1813;           //0x1C54\n    int unk1814;           //0x1C58\n    int unk1815;           //0x1C5C\n    int unk1816;           //0x1C60\n    int unk1817;           //0x1C64\n    int unk1818;           //0x1C68\n    int unk1819;           //0x1C6C\n    int unk1820;           //0x1C70\n    int unk1821;           //0x1C74\n    int unk1822;           //0x1C78\n    int unk1823;           //0x1C7C\n    int unk1824;           //0x1C80\n    int unk1825;           //0x1C84\n    int unk1826;           //0x1C88\n    int unk1827;           //0x1C8C\n    int unk1828;           //0x1C90\n    int unk1829;           //0x1C94\n    int unk1830;           //0x1C98\n    int unk1831;           //0x1C9C\n    int unk1832;           //0x1CA0\n    int unk1833;           //0x1CA4\n    int unk1834;           //0x1CA8\n    int unk1835;           //0x1CAC\n    int unk1836;           //0x1CB0\n    int unk1837;           //0x1CB4\n    int unk1838;           //0x1CB8\n    int unk1839;           //0x1CBC\n    int unk1840;           //0x1CC0\n    int unk1841;           //0x1CC4\n    int unk1842;           //0x1CC8\n    int unk1843;           //0x1CCC\n    int unk1844;           //0x1CD0\n    int unk1845;           //0x1CD4\n    int unk1846;           //0x1CD8\n    int unk1847;           //0x1CDC\n    int unk1848;           //0x1CE0\n    int unk1849;           //0x1CE4\n    int unk1850;           //0x1CE8\n    int unk1851;           //0x1CEC\n    int unk1852;           //0x1CF0\n    int unk1853;           //0x1CF4\n    int unk1854;           //0x1CF8\n    int unk1855;           //0x1CFC\n    int unk1856;           //0x1D00\n    int unk1857;           //0x1D04\n    int unk1858;           //0x1D08\n    int unk1859;           //0x1D0C\n    int unk1860;           //0x1D10\n    int unk1861;           //0x1D14\n    int unk1862;           //0x1D18\n    int unk1863;           //0x1D1C\n    int unk1864;           //0x1D20\n    int unk1865;           //0x1D24\n    int unk1866;           //0x1D28\n    int unk1867;           //0x1D2C\n    int unk1868;           //0x1D30\n    int unk1869;           //0x1D34\n    int unk1870;           //0x1D38\n    int unk1871;           //0x1D3C\n    int unk1872;           //0x1D40\n    int unk1873;           //0x1D44\n    int unk1874;           //0x1D48\n    int unk1875;           //0x1D4C\n    int unk1876;           //0x1D50\n    int unk1877;           //0x1D54\n    int unk1878;           //0x1D58\n    int unk1879;           //0x1D5C\n    int unk1880;           //0x1D60\n    int unk1881;           //0x1D64\n    int unk1882;           //0x1D68\n    int unk1883;           //0x1D6C\n    int unk1884;           //0x1D70\n    int unk1885;           //0x1D74\n    int unk1886;           //0x1D78\n    int unk1887;           //0x1D7C\n    int unk1888;           //0x1D80\n    int unk1889;           //0x1D84\n    int unk1890;           //0x1D88\n    int unk1891;           //0x1D8C\n    int unk1892;           //0x1D90\n    int unk1893;           //0x1D94\n    int unk1894;           //0x1D98\n    int unk1895;           //0x1D9C\n    int unk1896;           //0x1DA0\n    int unk1897;           //0x1DA4\n    int unk1898;           //0x1DA8\n    int unk1899;           //0x1DAC\n    int unk1900;           //0x1DB0\n    int unk1901;           //0x1DB4\n    int unk1902;           //0x1DB8\n    int unk1903;           //0x1DBC\n    int unk1904;           //0x1DC0\n    int unk1905;           //0x1DC4\n    int unk1906;           //0x1DC8\n    int unk1907;           //0x1DCC\n    int unk1908;           //0x1DD0\n    int unk1909;           //0x1DD4\n    int unk1910;           //0x1DD8\n    int unk1911;           //0x1DDC\n    int unk1912;           //0x1DE0\n    int unk1913;           //0x1DE4\n    int unk1914;           //0x1DE8\n    int unk1915;           //0x1DEC\n    int unk1916;           //0x1DF0\n    int unk1917;           //0x1DF4\n    int unk1918;           //0x1DF8\n    int unk1919;           //0x1DFC\n    int unk1920;           //0x1E00\n    int unk1921;           //0x1E04\n    int unk1922;           //0x1E08\n    int unk1923;           //0x1E0C\n    int unk1924;           //0x1E10\n    int unk1925;           //0x1E14\n    int unk1926;           //0x1E18\n    int unk1927;           //0x1E1C\n    int unk1928;           //0x1E20\n    int unk1929;           //0x1E24\n    int unk1930;           //0x1E28\n    int unk1931;           //0x1E2C\n    int unk1932;           //0x1E30\n    int unk1933;           //0x1E34\n    int unk1934;           //0x1E38\n    int unk1935;           //0x1E3C\n    int unk1936;           //0x1E40\n    int unk1937;           //0x1E44\n    int unk1938;           //0x1E48\n    int unk1939;           //0x1E4C\n    int unk1940;           //0x1E50\n    int unk1941;           //0x1E54\n    int unk1942;           //0x1E58\n    int unk1943;           //0x1E5C\n    int unk1944;           //0x1E60\n    int unk1945;           //0x1E64\n    int unk1946;           //0x1E68\n    int unk1947;           //0x1E6C\n    int unk1948;           //0x1E70\n    int unk1949;           //0x1E74\n    int unk1950;           //0x1E78\n    int unk1951;           //0x1E7C\n    int unk1952;           //0x1E80\n    int unk1953;           //0x1E84\n    int unk1954;           //0x1E88\n    int unk1955;           //0x1E8C\n    int unk1956;           //0x1E90\n    int unk1957;           //0x1E94\n    int unk1958;           //0x1E98\n    int unk1959;           //0x1E9C\n    int unk1960;           //0x1EA0\n    int unk1961;           //0x1EA4\n    int unk1962;           //0x1EA8\n    int unk1963;           //0x1EAC\n    int unk1964;           //0x1EB0\n    int unk1965;           //0x1EB4\n    int unk1966;           //0x1EB8\n    int unk1967;           //0x1EBC\n    int unk1968;           //0x1EC0\n    int unk1969;           //0x1EC4\n    int unk1970;           //0x1EC8\n    int unk1971;           //0x1ECC\n    int unk1972;           //0x1ED0\n    int unk1973;           //0x1ED4\n    int unk1974;           //0x1ED8\n    int unk1975;           //0x1EDC\n    int unk1976;           //0x1EE0\n    int unk1977;           //0x1EE4\n    int unk1978;           //0x1EE8\n    int unk1979;           //0x1EEC\n    int unk1980;           //0x1EF0\n    int unk1981;           //0x1EF4\n    int unk1982;           //0x1EF8\n    int unk1983;           //0x1EFC\n    int unk1984;           //0x1F00\n    int unk1985;           //0x1F04\n    int unk1986;           //0x1F08\n    int unk1987;           //0x1F0C\n    int unk1988;           //0x1F10\n    int unk1989;           //0x1F14\n    int unk1990;           //0x1F18\n    int unk1991;           //0x1F1C\n    int unk1992;           //0x1F20\n    int TM_OSDEnabled;     //0x1F24\n    u8 TM_OSDMax;          //0x1F28\n    u8 TM_EventPage;       //0x1F29\n    u8 TM_OSDRecommended;  //0x1F2A\n    int unk1995;           //0x1F2C\n    int unk1996;           //0x1F30\n    int unk1997;           //0x1F34\n    int unk1998;           //0x1F38\n    int unk1999;           //0x1F3C\n    int unk2000;           //0x1F40\n    int unk2001;           //0x1F44\n    int unk2002;           //0x1F48\n    int unk2003;           //0x1F4C\n    int unk2004;           //0x1F50\n    int unk2005;           //0x1F54\n    int unk2006;           //0x1F58\n    int unk2007;           //0x1F5C\n    int unk2008;           //0x1F60\n    int unk2009;           //0x1F64\n    int unk2010;           //0x1F68\n    int unk2011;           //0x1F6C\n    int unk2012;           //0x1F70\n    int unk2013;           //0x1F74\n    int unk2014;           //0x1F78\n    int unk2015;           //0x1F7C\n    int unk2016;           //0x1F80\n    int unk2017;           //0x1F84\n    int unk2018;           //0x1F88\n    int unk2019;           //0x1F8C\n    int unk2020;           //0x1F90\n    int unk2021;           //0x1F94\n    int unk2022;           //0x1F98\n    int unk2023;           //0x1F9C\n    int unk2024;           //0x1FA0\n    int unk2025;           //0x1FA4\n    int unk2026;           //0x1FA8\n    int unk2027;           //0x1FAC\n    int unk2028;           //0x1FB0\n    int unk2029;           //0x1FB4\n    int unk2030;           //0x1FB8\n    int unk2031;           //0x1FBC\n    int unk2032;           //0x1FC0\n    int unk2033;           //0x1FC4\n    int unk2034;           //0x1FC8\n    int unk2035;           //0x1FCC\n    int unk2036;           //0x1FD0\n    int unk2037;           //0x1FD4\n    int unk2038;           //0x1FD8\n    int unk2039;           //0x1FDC\n    int unk2040;           //0x1FE0\n    int unk2041;           //0x1FE4\n    int unk2042;           //0x1FE8\n    int unk2043;           //0x1FEC\n    int unk2044;           //0x1FF0\n    int unk2045;           //0x1FF4\n    int unk2046;           //0x1FF8\n    int unk2047;           //0x1FFC\n};\n\nstruct SnapshotInfo\n{\n    int snap_id;\n    u16 is_exist;\n    u16 block_size;\n};\n\nstruct SnapshotList\n{\n    int x0;\n    int snap_num;\n    int x8;\n    int xc;\n    SnapshotInfo snap_info[128];\n};\n\nstruct MemSnapIconData\n{\n    _HSD_ImageDesc *banner;\n    _HSD_ImageDesc *icon;\n};\n\nstruct MemcardSave\n{\n    int size;   // size of the data, only used when writing to the card\n    int x4;     // unknown, is usually 3\n    void *data; // pointer to the save data\n    int xc;     // is -1 to signify end of data\n};\n\nstruct MemcardWork\n{\n\n    void *work_area;             // 0x0\n    void *buffer;                // 0x4, temp transfer buffer used during CARDReads. is 0x2000 bytes\n    int x8;                      // 0x8\n    int xc;                      // 0xc\n    int x10;                     // 0x10\n    int x14;                     // 0x14\n    void *icon_data;             // 0x18\n    void *banner_data;           // 0x1c\n    int x20;                     // 0x20\n    int x24;                     // 0x24\n    int x28;                     // 0x28\n    int x2c;                     // 0x2c\n    int x30;                     // 0x30\n    int x34;                     // 0x34\n    int x38;                     // 0x38\n    int x3c;                     // 0x3c\n    int x40;                     // 0x40\n    int x44;                     // 0x44\n    int x48;                     // 0x48\n    int x4c;                     // 0x4c\n    int x50;                     // 0x50\n    int x54;                     // 0x54\n    int x58;                     // 0x58\n    int x5c;                     // 0x5c\n    int x60;                     // 0x60\n    int x64;                     // 0x64\n    int x68;                     // 0x68\n    int x6c;                     // 0x6c\n    int x70;                     // 0x70\n    int x74;                     // 0x74\n    int x78;                     // 0x78\n    int x7c;                     // 0x7c\n    int x80;                     // 0x80\n    int x84;                     // 0x84\n    int x88;                     // 0x88\n    int x8c;                     // 0x8c\n    int x90;                     // 0x90\n    CARDFileInfo card_file_x94;  // 0x94\n    void *buffer_use;            // 0xa8, temp transfer buffer used during CARDReads\n    int xac;                     // 0xac\n    int buffer_size;             // 0xb0\n    CARDFileInfo card_file_info; // 0xb4    cancel vanilla memcard reads with this fileinfo\n    int xc8;                     // 0xc8\n    int card_data_start;         // 0xcc, data after header and banner and metadata\n    int xd0;                     // 0xd0\n    int xd4;                     // 0xd4\n    int xd8;                     // 0xd8\n    int xdc;                     // 0xdc\n    int xe0;                     // 0xe0\n    int xe4;                     // 0xe4\n    int xe8;                     // 0xe8\n    int xec;                     // 0xec\n    int xf0;                     // 0xf0\n    int xf4;                     // 0xf4\n    int xf8;                     // 0xf8\n    int xfc;                     // 0xfc\n    int x100;                    // 0x100\n    int x104;                    // 0x104\n    int x108;                    // 0x108\n    int x10c;                    // 0x10c\n    int x110;                    // 0x110\n    int x114;                    // 0x114\n    int x118;                    // 0x118\n    int x11c;                    // 0x11c\n    int x120;                    // 0x120\n    int x124;                    // 0x124\n    int x128;                    // 0x128\n    int x12c;                    // 0x12c\n    int x130;                    // 0x130\n    int x134;                    // 0x134\n    int x138;                    // 0x138\n    int x13c;                    // 0x13c\n    int x140;                    // 0x140\n    int x144;                    // 0x144\n    int x148;                    // 0x148\n    int x14c;                    // 0x14c\n    int x150;                    // 0x150\n    int x154;                    // 0x154\n    int x158;                    // 0x158\n    int x15c;                    // 0x15c\n    int x160;                    // 0x160\n    int x164;                    // 0x164\n    int x168;                    // 0x168\n    int x16c;                    // 0x16c\n    int x170;                    // 0x170\n    int x174;                    // 0x174\n    int x178;                    // 0x178\n    int x17c;                    // 0x17c\n    int x180;                    // 0x180\n    int x184;                    // 0x184\n    int x188;                    // 0x188\n    int x18c;                    // 0x18c\n    int x190;                    // 0x190\n    int x194;                    // 0x194\n    int x198;                    // 0x198\n    int x19c;                    // 0x19c\n    int x1a0;                    // 0x1a0\n    int x1a4;                    // 0x1a4\n    int x1a8;                    // 0x1a8\n    int x1ac;                    // 0x1ac\n    int x1b0;                    // 0x1b0\n    int x1b4;                    // 0x1b4\n    int x1b8;                    // 0x1b8\n    int x1bc;                    // 0x1bc\n    int x1c0;                    // 0x1c0\n    int x1c4;                    // 0x1c4\n    int x1c8;                    // 0x1c8\n    int x1cc;                    // 0x1cc\n    int x1d0;                    // 0x1d0\n    int x1d4;                    // 0x1d4\n    int x1d8;                    // 0x1d8\n    int x1dc;                    // 0x1dc\n    int x1e0;                    // 0x1e0\n    int x1e4;                    // 0x1e4\n    int x1e8;                    // 0x1e8\n    int x1ec;                    // 0x1ec\n    int x1f0;                    // 0x1f0\n    int x1f4;                    // 0x1f4\n    int x1f8;                    // 0x1f8\n    int x1fc;                    // 0x1fc\n    int x200;                    // 0x200\n    int x204;                    // 0x204\n    int x208;                    // 0x208\n    int x20c;                    // 0x20c\n    int x210;                    // 0x210\n    int x214;                    // 0x214\n    int x218;                    // 0x218\n    int x21c;                    // 0x21c\n    int x220;                    // 0x220\n    int x224;                    // 0x224\n    int x228;                    // 0x228\n    int x22c;                    // 0x22c\n    int x230;                    // 0x230\n    int x234;                    // 0x234\n    int x238;                    // 0x238\n    int x23c;                    // 0x23c\n    int x240;                    // 0x240\n    int x244;                    // 0x244\n    int x248;                    // 0x248\n    int x24c;                    // 0x24c\n    int x250;                    // 0x250\n    int x254;                    // 0x254\n    int x258;                    // 0x258\n    int x25c;                    // 0x25c\n    int x260;                    // 0x260\n    int x264;                    // 0x264\n    int x268;                    // 0x268\n    int x26c;                    // 0x26c\n    int x270;                    // 0x270\n    int x274;                    // 0x274\n    int x278;                    // 0x278\n    int x27c;                    // 0x27c\n    int x280;                    // 0x280\n    int x284;                    // 0x284\n    int x288;                    // 0x288\n    int x28c;                    // 0x28c\n    int x290;                    // 0x290\n    int x294;                    // 0x294\n    int x298;                    // 0x298\n    int x29c;                    // 0x29c\n    int x2a0;                    // 0x2a0\n    int x2a4;                    // 0x2a4\n    int x2a8;                    // 0x2a8\n    int x2ac;                    // 0x2ac\n    int x2b0;                    // 0x2b0\n    int x2b4;                    // 0x2b4\n    int x2b8;                    // 0x2b8\n    int x2bc;                    // 0x2bc\n    int x2c0;                    // 0x2c0\n    int x2c4;                    // 0x2c4\n    int x2c8;                    // 0x2c8\n    int x2cc;                    // 0x2cc\n    int x2d0;                    // 0x2d0\n    int x2d4;                    // 0x2d4\n    int x2d8;                    // 0x2d8\n    int x2dc;                    // 0x2dc\n    int x2e0;                    // 0x2e0\n    int x2e4;                    // 0x2e4\n    int x2e8;                    // 0x2e8\n    int x2ec;                    // 0x2ec\n    int x2f0;                    // 0x2f0\n    int x2f4;                    // 0x2f4\n    int x2f8;                    // 0x2f8\n    int x2fc;                    // 0x2fc\n    int x300;                    // 0x300\n    int x304;                    // 0x304\n    int x308;                    // 0x308\n    int x30c;                    // 0x30c\n    int x310;                    // 0x310\n    int x314;                    // 0x314\n    int x318;                    // 0x318\n    int x31c;                    // 0x31c\n    int x320;                    // 0x320\n    int x324;                    // 0x324\n    int x328;                    // 0x328\n    int x32c;                    // 0x32c\n    int x330;                    // 0x330\n    int x334;                    // 0x334\n    int x338;                    // 0x338\n    int x33c;                    // 0x33c\n    int x340;                    // 0x340\n    int x344;                    // 0x344\n    int x348;                    // 0x348\n    int x34c;                    // 0x34c\n    int x350;                    // 0x350\n    int x354;                    // 0x354\n    int x358;                    // 0x358\n    int x35c;                    // 0x35c\n    int x360;                    // 0x360\n    int x364;                    // 0x364\n    int x368;                    // 0x368\n    int x36c;                    // 0x36c\n    int x370;                    // 0x370\n    int x374;                    // 0x374\n    int x378;                    // 0x378\n    int x37c;                    // 0x37c\n    int x380;                    // 0x380\n    int x384;                    // 0x384\n    int x388;                    // 0x388\n    int x38c;                    // 0x38c\n    int x390;                    // 0x390\n    int x394;                    // 0x394\n    int x398;                    // 0x398\n    int x39c;                    // 0x39c\n    int x3a0;                    // 0x3a0\n    int x3a4;                    // 0x3a4\n    int x3a8;                    // 0x3a8\n    int x3ac;                    // 0x3ac\n    int x3b0;                    // 0x3b0\n    int x3b4;                    // 0x3b4\n    int x3b8;                    // 0x3b8\n    int x3bc;                    // 0x3bc\n    int x3c0;                    // 0x3c0\n    int x3c4;                    // 0x3c4\n    int x3c8;                    // 0x3c8\n    int x3cc;                    // 0x3cc\n    int x3d0;                    // 0x3d0\n    int x3d4;                    // 0x3d4\n    int x3d8;                    // 0x3d8\n    int x3dc;                    // 0x3dc\n    int x3e0;                    // 0x3e0\n    int x3e4;                    // 0x3e4\n    int x3e8;                    // 0x3e8\n    int x3ec;                    // 0x3ec\n    int x3f0;                    // 0x3f0\n    int x3f4;                    // 0x3f4\n    int x3f8;                    // 0x3f8\n    int x3fc;                    // 0x3fc\n    int x400;                    // 0x400\n    int x404;                    // 0x404\n    int x408;                    // 0x408\n    int x40c;                    // 0x40c\n    int x410;                    // 0x410\n    int x414;                    // 0x414\n    int x418;                    // 0x418\n    int x41c;                    // 0x41c\n    int x420;                    // 0x420\n    int x424;                    // 0x424\n    int x428;                    // 0x428\n    int x42c;                    // 0x42c\n    int x430;                    // 0x430\n    int x434;                    // 0x434\n    int x438;                    // 0x438\n    int x43c;                    // 0x43c\n    int x440;                    // 0x440\n    int x444;                    // 0x444\n    int x448;                    // 0x448\n    int x44c;                    // 0x44c\n    int x450;                    // 0x450\n    int x454;                    // 0x454\n    int x458;                    // 0x458\n    int x45c;                    // 0x45c\n    int x460;                    // 0x460\n    int x464;                    // 0x464\n    int x468;                    // 0x468\n    int x46c;                    // 0x46c\n    int x470;                    // 0x470\n    int x474;                    // 0x474\n    int x478;                    // 0x478\n    int x47c;                    // 0x47c\n    int x480;                    // 0x480\n    int x484;                    // 0x484\n    int x488;                    // 0x488\n    int x48c;                    // 0x48c\n    int x490;                    // 0x490\n    int x494;                    // 0x494\n    int x498;                    // 0x498\n    int x49c;                    // 0x49c\n    int x4a0;                    // 0x4a0\n    int x4a4;                    // 0x4a4\n    int x4a8;                    // 0x4a8\n    int x4ac;                    // 0x4ac\n    int x4b0;                    // 0x4b0\n    int x4b4;                    // 0x4b4\n    int x4b8;                    // 0x4b8\n    int x4bc;                    // 0x4bc\n    int x4c0;                    // 0x4c0\n    int x4c4;                    // 0x4c4\n    int x4c8;                    // 0x4c8\n    int x4cc;                    // 0x4cc\n    int x4d0;                    // 0x4d0\n    int x4d4;                    // 0x4d4\n    int x4d8;                    // 0x4d8\n    int x4dc;                    // 0x4dc\n    int x4e0;                    // 0x4e0\n    int x4e4;                    // 0x4e4\n    int x4e8;                    // 0x4e8\n    int x4ec;                    // 0x4ec\n    int x4f0;                    // 0x4f0\n    int x4f4;                    // 0x4f4\n    int x4f8;                    // 0x4f8\n    int x4fc;                    // 0x4fc\n    int x500;                    // 0x500\n    int x504;                    // 0x504\n    int x508;                    // 0x508\n    int x50c;                    // 0x50c\n    int x510;                    // 0x510\n    int x514;                    // 0x514\n    int x518;                    // 0x518\n    int x51c;                    // 0x51c\n    int x520;                    // 0x520\n    int x524;                    // 0x524\n    int x528;                    // 0x528\n    int x52c;                    // 0x52c\n    int x530;                    // 0x530\n    int x534;                    // 0x534\n    int x538;                    // 0x538\n    int x53c;                    // 0x53c\n    int x540;                    // 0x540\n    int x544;                    // 0x544\n    int x548;                    // 0x548\n    int x54c;                    // 0x54c\n    int x550;                    // 0x550\n    int x554;                    // 0x554\n    int x558;                    // 0x558\n    int x55c;                    // 0x55c\n    int x560;                    // 0x560\n    int x564;                    // 0x564\n    int x568;                    // 0x568\n    int x56c;                    // 0x56c\n    int x570;                    // 0x570\n    int x574;                    // 0x574\n    int x578;                    // 0x578\n    int x57c;                    // 0x57c\n    int x580;                    // 0x580\n    int x584;                    // 0x584\n    int x588;                    // 0x588\n    int x58c;                    // 0x58c\n    int x590;                    // 0x590\n    int x594;                    // 0x594\n    int x598;                    // 0x598\n    int x59c;                    // 0x59c\n    int x5a0;                    // 0x5a0\n    int x5a4;                    // 0x5a4\n    int x5a8;                    // 0x5a8\n    int x5ac;                    // 0x5ac\n    int x5b0;                    // 0x5b0\n    int x5b4;                    // 0x5b4\n    int x5b8;                    // 0x5b8\n    int x5bc;                    // 0x5bc\n    int x5c0;                    // 0x5c0\n    int x5c4;                    // 0x5c4\n    int x5c8;                    // 0x5c8\n    int x5cc;                    // 0x5cc\n    int x5d0;                    // 0x5d0\n    int x5d4;                    // 0x5d4\n    int x5d8;                    // 0x5d8\n    int x5dc;                    // 0x5dc\n    int x5e0;                    // 0x5e0\n    int x5e4;                    // 0x5e4\n    int x5e8;                    // 0x5e8\n    int x5ec;                    // 0x5ec\n    int x5f0;                    // 0x5f0\n    int x5f4;                    // 0x5f4\n    int x5f8;                    // 0x5f8\n    int x5fc;                    // 0x5fc\n    int x600;                    // 0x600\n    int x604;                    // 0x604\n    int x608;                    // 0x608\n    int x60c;                    // 0x60c\n    int x610;                    // 0x610\n    int x614;                    // 0x614\n    int x618;                    // 0x618\n    int x61c;                    // 0x61c\n    int x620;                    // 0x620\n    int x624;                    // 0x624\n    int x628;                    // 0x628\n    int x62c;                    // 0x62c\n    int x630;                    // 0x630\n    int x634;                    // 0x634\n    int x638;                    // 0x638\n    int x63c;                    // 0x63c\n    int x640;                    // 0x640\n    int x644;                    // 0x644\n    int x648;                    // 0x648\n    int x64c;                    // 0x64c\n    int x650;                    // 0x650\n    int x654;                    // 0x654\n    int x658;                    // 0x658\n    int x65c;                    // 0x65c\n    int x660;                    // 0x660\n    int x664;                    // 0x664\n    int x668;                    // 0x668\n    int x66c;                    // 0x66c\n    int x670;                    // 0x670\n    int x674;                    // 0x674\n    int x678;                    // 0x678\n    int x67c;                    // 0x67c\n    int x680;                    // 0x680\n    int x684;                    // 0x684\n    int x688;                    // 0x688\n    int x68c;                    // 0x68c\n    int x690;                    // 0x690\n    int x694;                    // 0x694\n    int x698;                    // 0x698\n    int x69c;                    // 0x69c\n    int x6a0;                    // 0x6a0\n    int x6a4;                    // 0x6a4\n    int x6a8;                    // 0x6a8\n    int x6ac;                    // 0x6ac\n    int x6b0;                    // 0x6b0\n    int x6b4;                    // 0x6b4\n    int x6b8;                    // 0x6b8\n    int x6bc;                    // 0x6bc\n    int x6c0;                    // 0x6c0\n    int x6c4;                    // 0x6c4\n    int x6c8;                    // 0x6c8\n    int x6cc;                    // 0x6cc\n    int x6d0;                    // 0x6d0\n    int x6d4;                    // 0x6d4\n    int x6d8;                    // 0x6d8\n    int x6dc;                    // 0x6dc\n    int x6e0;                    // 0x6e0\n    int x6e4;                    // 0x6e4\n    int x6e8;                    // 0x6e8\n    int x6ec;                    // 0x6ec\n    int x6f0;                    // 0x6f0\n    int x6f4;                    // 0x6f4\n    int x6f8;                    // 0x6f8\n    int x6fc;                    // 0x6fc\n    int x700;                    // 0x700\n    int x704;                    // 0x704\n    int x708;                    // 0x708\n    int x70c;                    // 0x70c\n    int x710;                    // 0x710\n    int x714;                    // 0x714\n    int x718;                    // 0x718\n    int x71c;                    // 0x71c\n    int x720;                    // 0x720\n    int x724;                    // 0x724\n    int x728;                    // 0x728\n    int x72c;                    // 0x72c\n    int x730;                    // 0x730\n    int x734;                    // 0x734\n    int x738;                    // 0x738\n    int x73c;                    // 0x73c\n    int x740;                    // 0x740\n    int x744;                    // 0x744\n    int x748;                    // 0x748\n    int x74c;                    // 0x74c\n    int x750;                    // 0x750\n    int x754;                    // 0x754\n    int x758;                    // 0x758\n    int x75c;                    // 0x75c\n    int x760;                    // 0x760\n    int x764;                    // 0x764\n    int x768;                    // 0x768\n    int x76c;                    // 0x76c\n    int x770;                    // 0x770\n    int x774;                    // 0x774\n    int x778;                    // 0x778\n    int x77c;                    // 0x77c\n    int x780;                    // 0x780\n    int x784;                    // 0x784\n    int x788;                    // 0x788\n    int x78c;                    // 0x78c\n    int x790;                    // 0x790\n    int x794;                    // 0x794\n    int x798;                    // 0x798\n    int x79c;                    // 0x79c\n    int x7a0;                    // 0x7a0\n    int x7a4;                    // 0x7a4\n    int x7a8;                    // 0x7a8\n    int x7ac;                    // 0x7ac\n    int x7b0;                    // 0x7b0\n    int x7b4;                    // 0x7b4\n    int x7b8;                    // 0x7b8\n    int x7bc;                    // 0x7bc\n    int x7c0;                    // 0x7c0\n    int x7c4;                    // 0x7c4\n    int x7c8;                    // 0x7c8\n    int x7cc;                    // 0x7cc\n    int x7d0;                    // 0x7d0\n    int x7d4;                    // 0x7d4\n    int x7d8;                    // 0x7d8\n    int x7dc;                    // 0x7dc\n    int x7e0;                    // 0x7e0\n    int x7e4;                    // 0x7e4\n    int x7e8;                    // 0x7e8\n    int x7ec;                    // 0x7ec\n    int x7f0;                    // 0x7f0\n    int x7f4;                    // 0x7f4\n    int x7f8;                    // 0x7f8\n    int x7fc;                    // 0x7fc\n    int x800;                    // 0x800\n    int x804;                    // 0x804\n    int x808;                    // 0x808\n    int x80c;                    // 0x80c\n    int x810;                    // 0x810\n    int x814;                    // 0x814\n    int x818;                    // 0x818\n    int x81c;                    // 0x81c\n    int x820;                    // 0x820\n    int x824;                    // 0x824\n    int x828;                    // 0x828\n    int x82c;                    // 0x82c\n    int x830;                    // 0x830\n    int x834;                    // 0x834\n    int x838;                    // 0x838\n    int x83c;                    // 0x83c\n    int x840;                    // 0x840\n    int x844;                    // 0x844\n    int x848;                    // 0x848\n    int x84c;                    // 0x84c\n    int x850;                    // 0x850\n    int x854;                    // 0x854\n    int x858;                    // 0x858\n    int x85c;                    // 0x85c\n    int x860;                    // 0x860\n    int x864;                    // 0x864\n    int x868;                    // 0x868\n    int x86c;                    // 0x86c\n    int x870;                    // 0x870\n    int x874;                    // 0x874\n    int x878;                    // 0x878\n    int x87c;                    // 0x87c\n    int x880;                    // 0x880\n    int x884;                    // 0x884\n    int x888;                    // 0x888\n    int x88c;                    // 0x88c\n    int x890;                    // 0x890\n    int x894;                    // 0x894\n    int x898;                    // 0x898\n    int x89c;                    // 0x89c\n    int x8a0;                    // 0x8a0\n    int x8a4;                    // 0x8a4\n    int x8a8;                    // 0x8a8\n    int is_done;                 // 0x8ac. operation callback sets this to 1 when the operation finishes\n};\n\nstruct MemcardUnk\n{\n    u8 block_size;\n    u8 x1;\n    u8 x2;\n    u8 x3;\n    u8 x4;\n    u8 x5;\n    u8 x6;\n    u8 x7;\n    u8 x8;\n    u8 x9;\n    u8 xa[8];\n};\n\nstruct MemcardInfo\n{\n    void *snap_data;            // 0x0 (should be 256,064 bytes)\n    char file_name[32];         // should end with spaces\n    char file_desc[32];         // should end with spaces\n    MemSnapIconData *icon_data; // 0x44\n    SnapshotList *snap_list;    // 0x48 (should be 2112 bytes) points to an allocation where info on the snapshots present on slot A exists\n    int memcard_probe;          // 0x4c 1 == is present. is updated every controller poll\n    int x50;                    // 0x50\n    int x54;                    // 0x54\n    int x58;                    // 0x58\n    int x5c;                    // 0x5c\n    int x60;                    // 0x60\n    int x64;                    // 0x64\n    int x68;                    // 0x68\n    int x6c;                    // 0x6c\n    int x70;                    // 0x70\n    int x74;                    // 0x74\n    int x78;                    // 0x78\n    int x7c;                    // 0x7c\n    int x80;                    // 0x80\n    int x84;                    // 0x84\n    int x88;                    // 0x88\n    int x8c;                    // 0x8c\n    int x90;                    // 0x90\n    int x94;                    // 0x94\n    int x98;                    // 0x98\n    int x9c;                    // 0x9c\n    int xa0;                    // 0xa0\n    int xa4;                    // 0xa4\n    int xa8;                    // 0xa8\n    int xac;                    // 0xac\n    int xb0;                    // 0xb0\n    int xb4;                    // 0xb4\n    int xb8;                    // 0xb8\n    int xbc;                    // 0xbc\n    int xc0;                    // 0xc0\n    int xc4;                    // 0xc4\n    int xc8;                    // 0xc8\n    int xcc;                    // 0xcc\n    int xd0;                    // 0xd0\n    int xd4;                    // 0xd4\n    int xd8;                    // 0xd8\n    int xdc;                    // 0xdc\n    int xe0;                    // 0xe0\n    int xe4;                    // 0xe4\n    int xe8;                    // 0xe8\n    int xec;                    // 0xec\n};\n\nstruct Rules1\n{\n    u8 x0;\n    u8 x1;\n    u8 x2;\n    u8 x3;\n    u8 x4;\n    u8 handicap;\n    u8 x6;\n    u8 x7;\n    u8 x8;\n    u8 x9;\n    u8 xa;\n    u8 xb;\n    u8 xc;\n};\n\n/*** Static Variables ***/\nstatic MemcardInfo *stc_memcard_info = 0x80433380;\nstatic MemcardUnk *stc_memcard_unk = 0x803bacc8;\nstatic MemcardWork *stc_memcard_work = 0x80432a68;\nint *stc_memcard_block_curr = R13 + (-0x3d20);\nint *stc_memcard_block_last = R13 + (-0x3d1c);\nint *stc_memcard_write_status = 0x804d1138;\nint *stc_CardXferredBytes = R13 + (-0x3D14);\n\n#endif"
  },
  {
    "path": "MexTK/include/mex.h",
    "content": "#ifndef MEX_H_MEX\n#define MEX_H_MEX\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"obj.h\"\n\n#define DB_FLAG 0\n\nenum MEX_GETDATA\n{\n    MXDT_FTINTNUM,\n    MXDT_FTEXTNUM,\n    MXDT_FTICONNUM,\n    MXDT_FTICONDATA,\n    MXDT_GRINTNUM,\n    MXDT_GREXTNUM,\n    MXDT_GRICONNUM,\n    MXDT_GRICONDATA,\n};\n\n/*** Structs ***/\n\nstruct PRIM\n{\n    void *data;\n};\n\nstruct Translation\n{\n    float frame;\n    float value;\n};\n\nstruct MEXPlaylist\n{\n    u16 bgm;\n    u16 chance;\n};\n\n/*** Functions ***/\nArchiveInfo *MEX_LoadRelArchive(char *file, void *functions, char *symbol);\nvoid MEX_IndexFighterItem(int fighter_kind, void *itemdata, int item_id);\nvoid SpawnMEXEffect(int effectID, int fighter, int arg1, int arg2, int arg3, int arg4, int arg5);\nint MEX_GetItemExtID(GOBJ *gobj, int item_id); // gobj can be fighter or stage\nint MEX_GetFtItemID(int ft_kind, int item_id); // gobj can be fighter or stage\nint MEX_GetGrItemID(int item_id);              // gobj can be fighter or stage\nvoid SFX_PlayStageSFX(int sfx_id);\nvoid *calloc(int size);\nPRIM *PRIM_NEW(int vert_count, int params1, int params2);\nvoid PRIM_CLOSE();\nMEXPlaylist *MEX_GetPlaylist();\nint MEX_GetStageItemExtID(int item_id);\nvoid KirbyStateChange(GOBJ *fighter, int state, float startFrame, float animSpeed, float animBlend);\nvoid *MEX_GetKirbyCpData(int copy_id);\nint MEX_GetCopyItemExtID(int copy_id, int item_id);\nvoid *MEX_GetData(int index);\n#endif\n"
  },
  {
    "path": "MexTK/include/obj.h",
    "content": "#ifndef MEX_H_OBJ\n#define MEX_H_OBJ\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"color.h\"\n\n// JObj Flags\n#define JOBJ_SKELETON (1 << 0)\n#define JOBJ_SKELETON_ROOT (1 << 1)\n#define JOBJ_ENVELOPE_MODEL (1 << 2)\n#define JOBJ_CLASSICAL_SCALING (1 << 3)\n#define JOBJ_HIDDEN (1 << 4)\n#define JOBJ_PTCL (1 << 5)\n#define JOBJ_MTX_DIRTY (1 << 6)\n#define JOBJ_LIGHTING (1 << 7)\n#define JOBJ_TEXGEN (1 << 8)\n#define JOBJ_BILLBOARD (1 << 9)\n#define JOBJ_VBILLBOARD (2 << 9)\n#define JOBJ_HBILLBOARD (3 << 9)\n#define JOBJ_RBILLBOARD (4 << 9)\n#define JOBJ_INSTANCE (1 << 12)\n#define JOBJ_PBILLBOARD (1 << 13)\n#define JOBJ_SPLINE (1 << 14)\n#define JOBJ_FLIP_IK (1 << 15)\n#define JOBJ_SPECULAR (1 << 16)\n#define JOBJ_USE_QUATERNION (1 << 17)\n#define JOBJ_OPA (1 << 18)\n#define JOBJ_XLU (1 << 19)\n#define JOBJ_TEXEDGE (1 << 20)\n#define JOBJ_NULL (0 << 21)\n#define JOBJ_JOINT1 (1 << 21)\n#define JOBJ_JOINT2 (2 << 21)\n#define JOBJ_EFFECTOR (3 << 21)\n#define JOBJ_USER_DEFINED_MTX (1 << 23)\n#define JOBJ_MTX_INDEPEND_PARENT (1 << 24)\n#define JOBJ_MTS_INDEPEND_SRT (1 << 25)\n#define JOBJ_GENERALFLAG (1 << 26)\n#define JOBJ_GENERALFLAG2 (1 << 27)\n#define JOBJ_ROOT_OPA (1 << 28)\n#define JOBJ_ROOT_XLU (1 << 29)\n#define JOBJ_ROOT_TEXEDGE (1 << 30)\n#define JOBJ_31 (1 << 31)\n\n// MObj Flags\n#define MOBJ_ANIM 0x4\n#define TOBJ_ANIM 0x10\n#define ALL_ANIM 0x7FF\n#define HSD_A_M_AMBIENT_R 1\n#define HSD_A_M_AMBIENT_G 2\n#define HSD_A_M_AMBIENT_B 3\n#define HSD_A_M_DIFFUSE_R 4\n#define HSD_A_M_DIFFUSE_G 5\n#define HSD_A_M_DIFFUSE_B 6\n#define HSD_A_M_SPECULAR_R 7\n#define HSD_A_M_SPECULAR_G 8\n#define HSD_A_M_SPECULAR_B 9\n#define HSD_A_M_ALPHA 10\n#define HSD_A_M_PE_REF0 11\n#define HSD_A_M_PE_REF1 12\n#define HSD_A_M_PE_DSTALPHA 13\n#define RENDER_DIFFUSE_SHIFT 0\n#define RENDER_DIFFUSE_BITS (3 << RENDER_DIFFUSE_SHIFT)\n#define RENDER_DIFFUSE_MAT0 (0 << RENDER_DIFFUSE_SHIFT)\n#define RENDER_DIFFUSE_MAT (1 << RENDER_DIFFUSE_SHIFT)\n#define RENDER_DIFFUSE_VTX (2 << RENDER_DIFFUSE_SHIFT)\n#define RENDER_DIFFUSE_BOTH (3 << RENDER_DIFFUSE_SHIFT)\n#define RENDER_CONSTANT (1 << 0)\n#define RENDER_VERTEX (1 << 1)\n#define RENDER_DIFFUSE (1 << 2)\n#define RENDER_SPECULAR (1 << 3)\n#define CHANNEL_FIELD (RENDER_CONSTANT | RENDER_VERTEX | RENDER_DIFFUSE | RENDER_SPECULAR)\n#define RENDER_TEX0 (1 << 4)\n#define RENDER_TEX1 (1 << 5)\n#define RENDER_TEX2 (1 << 6)\n#define RENDER_TEX3 (1 << 7)\n#define RENDER_TEX4 (1 << 8)\n#define RENDER_TEX5 (1 << 9)\n#define RENDER_TEX6 (1 << 10)\n#define RENDER_TEX7 (1 << 11)\n#define RENDER_TEXTURES (RENDER_TEX0 | RENDER_TEX1 | RENDER_TEX2 | RENDER_TEX3 | RENDER_TEX4 | RENDER_TEX5 | RENDER_TEX6 | RENDER_TEX7)\n#define RENDER_TOON (1 << 12)\n#define RENDER_ALPHA_SHIFT 13\n#define RENDER_ALPHA_BITS (3 << RENDER_ALPHA_SHIFT)\n#define RENDER_ALPHA_COMPAT (0 << RENDER_ALPHA_SHIFT)\n#define RENDER_ALPHA_MAT (1 << RENDER_ALPHA_SHIFT)\n#define RENDER_ALPHA_VTX (2 << RENDER_ALPHA_SHIFT)\n#define RENDER_ALPHA_BOTH (3 << RENDER_ALPHA_SHIFT)\n#define RENDER_SHADOW (1 << 26)\n#define RENDER_ZMODE_ALWAYS (1 << 27)\n#define RENDER_NO_ZUPDATE (1 << 29)\n#define RENDER_XLU (1 << 30)\n\n// DOBJ flags\n#define DOBJ_HIDDEN 1\n\n/*** Structs ***/\n\nstruct GOBJ\n{\n    short entity_class;      // 0x0\n    char p_link;             // 0x2\n    char gx_link;            // 0x3. 0-63 are gx. 64+ are reserved for camera objects\n    char p_priority;         // 0x4\n    char gx_pri;             // 0x5\n    char obj_kind;           // 0x6\n    char data_kind;          // 0x7\n    GOBJ *next;              // 0x8\n    GOBJ *previous;          // 0xC\n    GOBJ *nextOrdered;       // 0x10\n    GOBJ *previousOrdered;   // 0x14\n    GOBJProc *proc;          // 0x18\n    void *gx_cb;             // 0x1C\n    u64 cobj_links;          // 0x20. this is used to know which cobj to render to\n    void *hsd_object;        // 0x28\n    void *userdata;          // 0x2C\n    int destructor_function; // 0x30\n    int unk_linked_list;     // 0x34\n};\n\nstruct GOBJProc\n{\n    GOBJ *parent;\n    GOBJProc *next;\n    GOBJProc *prev;\n    char s_link;            // 0xC\n    char flags;             // 0xD\n    GOBJ *parentGOBJ;       // 0x10\n    void (*cb)(GOBJ *gobj); // function callback\n};\n\nstruct GOBJList\n{\n    // pointed to @ -0x3e74(r13)\n    // indexed by p_link\n    GOBJ *x0;\n    GOBJ *x4;\n    GOBJ *x8;\n    GOBJ *xc;\n    GOBJ *x10;\n    GOBJ *cobj;\n    GOBJ *x18;\n    GOBJ *x1c;\n    GOBJ *fighter;\n    GOBJ *item;\n    GOBJ *x28;\n    GOBJ *effect_model; // 0x2c\n    GOBJ *effect_unk;   // 0x30, used for blastzone effect\n    GOBJ *x34;\n    GOBJ *x38;\n    GOBJ *x3c;\n    GOBJ *x40;\n    GOBJ *x44;\n    GOBJ *match_cam; // 0x48, used for the match camera and shake gobjs\n};\n\nstruct GXList\n{\n    // pointed to @ -0x3e80(r13)\n    GOBJ *gx_render[63]; // pointer to 63 gobjs\n    GOBJ *gx_camera;     // pointer to the highest priority cobj gobj. they are linked together via the next member.\n};\n\nstruct TOBJ\n{\n    int *parent;\n    int x4;\n    TOBJ *next;\n    u32 id;                           //GXTexMapID\n    u32 src;                          //GXTexGenSrc 0x10\n    u32 mtxid;                        // 0x14\n    Vec4 rotate;                      // 0x18\n    Vec3 scale;                       // 0x28\n    Vec3 translate;                   // 0x34\n    u32 wrap_s;                       // 0x40 GXTexWrapMode\n    u32 wrap_t;                       // 0x44 GXTexWrapMode\n    u8 repeat_s;                      // 0x48\n    u8 repeat_t;                      // 0x49\n    u16 anim_id;                      // 0x4A\n    u32 flags;                        // 0x4C\n    f32 blending;                     // 0x50\n    u32 magFilt;                      // 0x54 GXTexFilter\n    struct _HSD_ImageDesc *imagedesc; // 0x58\n    struct _HSD_Tlut *tlut;           // 0x5C\n    struct _HSD_TexLODDesc *lod;      // 0x60\n    AOBJ *aobj;                       // 0x64\n    struct _HSD_ImageDesc **imagetbl;\n    struct _HSD_Tlut **tluttbl;\n    u8 tlut_no;\n    Mtx mtx;\n    u32 coord; //GXTexCoordID\n    struct _HSD_TObjTev *tev;\n};\n\nstruct AOBJ\n{\n    u32 flags;\n    f32 curr_frame;\n    f32 rewind_frame;\n    f32 end_frame;\n    f32 framerate;\n    struct _HSD_FObj *fobj;\n    struct _HSD_Obj *hsd_obj;\n};\n\nstruct MOBJ\n{\n    int *parent;\n    u32 rendermode;\n    TOBJ *tobj;\n    HSD_Material *mat;\n    struct _HSD_PEDesc *pe;\n    AOBJ *aobj;\n    /*\n    struct _HSD_TObj *ambient_tobj;\n    struct _HSD_TObj *specular_tobj;\n    */\n    struct _HSD_TExpTevDesc *tevdesc;\n    union _HSD_TExp *texp;\n\n    struct _HSD_TObj *tobj_toon;\n    struct _HSD_TObj *tobj_gradation;\n    struct _HSD_TObj *tobj_backlight;\n    f32 z_offset;\n};\n\nstruct JOBJDesc\n{\n    char *class_name;       //0x00\n    u32 flags;              //0x04\n    struct JOBJDesc *child; //0x08\n    struct JOBJDesc *next;  //0x0C\n    union\n    {\n        struct _HSD_DObjDesc *dobjdesc;\n        struct _HSD_Spline *spline;\n        struct _HSD_SList *ptcl;\n    } u;                            //0x10\n    Vec3 rotation;                  //0x14 - 0x1C\n    Vec3 scale;                     //0x20 - 0x28\n    Vec3 position;                  //0x2C - 0x34\n    Mtx mtx;                        //0x38\n    struct _HSD_RObjDesc *robjdesc; //0x3C\n};\n\nstruct COBJDesc\n{\n    char *class_name;                    //0x00\n    u16 flags;                           //0x04\n    u16 projection_type;                 //0x06\n    u16 viewport_left;                   //0x08\n    u16 viewport_right;                  //0x0A\n    u16 viewport_top;                    //0x0C\n    u16 viewport_bottom;                 //0x0E\n    u32 scissor_lr;                      //0x10\n    u32 scissor_tb;                      //0x14\n    struct _HSD_WObjDesc *eye_desc;      //0x18\n    struct _HSD_WObjDesc *interest_desc; //0x1C\n    f32 roll;                            //0x20\n    Vec3 *vector;                        //0x24\n    f32 near;                            //0x28\n    f32 far;                             //0x2C\n    union\n    {\n        struct\n        {\n            f32 fov;\n            f32 aspect;\n        } perspective;\n\n        struct\n        {\n            f32 top;\n            f32 bottom;\n            f32 left;\n            f32 right;\n        } frustrum;\n\n        struct\n        {\n            f32 top;\n            f32 bottom;\n            f32 left;\n            f32 right;\n        } ortho;\n    } projection_param;\n};\n\nstruct DOBJ\n{\n    int parent;\n    DOBJ *next; //0x04\n    MOBJ *mobj; //0x08\n    int *pobj;  //0x0C\n    AOBJ *aobj; //0x10\n    u32 flags;  //0x14\n    u32 unk;\n};\n\nstruct JOBJ\n{\n    int hsd_info;     //0x0\n    int class_parent; //0x4\n    JOBJ *sibling;    //0x08\n    JOBJ *parent;     //0x0C\n    JOBJ *child;      //0x10\n    int flags;        //0x14\n    DOBJ *dobj;       //0x18\n    Vec4 rot;         //0x1C 0x20 0x24 0x28\n    Vec3 scale;       //0x2C\n    Vec3 trans;\n    Mtx rotMtx;\n    Vec3 *VEC;\n    Mtx *MTX;\n    AOBJ *aobj;\n    int *RObj;\n    JOBJDesc *desc;\n};\n\nstruct WOBJ\n{\n    void *parent;\n    u32 flags;  //0x08\n    Vec3 pos;   //0xC\n    AOBJ *aobj; //0x18\n    void *robj; //0x1C\n};\n\nstruct COBJ\n{\n    u64 parent;          // 0x0\n    u32 flags;           //0x08\n    f32 viewport_left;   //0x0C\n    f32 viewport_right;  //0x10\n    f32 viewport_top;    //0x14\n    f32 viewport_bottom; //0x18\n    u16 scissor_left;    //0x1C\n    u16 scissor_right;   //0x1E\n    u16 scissor_top;     //0x20\n    u16 scissor_bottom;  //0x22\n    WOBJ *eye_position;  //0x24\n    WOBJ *interest;      //0x28\n    union\n    {\n        f32 roll; //0x28\n        Vec3 up;  //0x2C - 0x38\n    } u;\n    f32 near; //0x3C\n    f32 far;  //0x40\n    union\n    {\n        struct\n        {\n            f32 fov;\n            f32 aspect;\n        } perspective;\n\n        struct\n        {\n            f32 top;\n            f32 bottom;\n            f32 left;\n            f32 right;\n        } frustrum;\n\n        struct\n        {\n            f32 top;\n            f32 bottom;\n            f32 left;\n            f32 right;\n        } ortho;\n    } projection_param;\n    u8 projection_type; //0x50\n    Mtx view_mtx;       //0x54\n    AOBJ *aobj;         //0x84\n    Mtx proj_mtx;       //0x88\n};\n\nstruct _HSD_ImageDesc\n{\n    void *img_ptr;\n    u16 width;\n    u16 height;\n    u32 format;\n    u32 mipmap;\n    f32 minLOD;\n    f32 maxLOD;\n};\n\nstruct _HSD_LightPoint\n{\n    f32 cutoff;\n    u8 point_func;\n    f32 ref_br;\n    f32 ref_dist;\n    u8 dist_func;\n};\n\nstruct _HSD_LightPointDesc\n{\n    f32 cutoff;\n    u8 point_func;\n    f32 ref_br;\n    f32 ref_dist;\n    u8 dist_func;\n};\n\nstruct _HSD_LightSpot\n{\n    f32 cutoff;\n    u8 spot_func;\n    f32 ref_br;\n    f32 ref_dist;\n    u8 dist_func;\n};\n\nstruct _HSD_LightSpotDesc\n{\n    f32 cutoff;\n    u8 spot_func;\n    f32 ref_br;\n    f32 ref_dist;\n    u8 dist_func;\n};\n\nstruct _HSD_LightAttn\n{\n    f32 a0;\n    f32 a1;\n    f32 a2;\n    f32 k0;\n    f32 k1;\n    f32 k2;\n};\n\nstruct LOBJ\n{\n    u64 parent;        //0x00\n    u16 flags;         //0x08\n    u16 priority;      //0x0A\n    struct LOBJ *next; //0x0C\n    GXColor color;     //0x10\n    GXColor hw_color;  //0x14\n    WOBJ *position;    //0x18\n    WOBJ *interest;    //0x1C\n    union\n    {\n        _HSD_LightPoint point;\n        _HSD_LightSpot spot;\n        _HSD_LightAttn attn;\n    } u;\n    f32 shininess;\n    Vec3 lvec;\n    struct AOBJ *aobj;\n    u32 id; //GXLightID\n    //GXLightObj lightobj;      //0x50\n    u32 spec_id; //0x90 GXLightID\n    //GXLightObj spec_lightobj; //0x94\n};\n\nstruct JOBJAnimSet\n{\n    JOBJDesc *jobj;\n    void *animjoint;\n    void *matanimjoint;\n    void *shapeaninjoint;\n};\n\n/*** Static Variables ***/\nGOBJList **stc_gobj_list = R13 + (-0x3E74);\nu8 *obj_kind = R13 + -(0x3E55);\n\n/*** Functions ***/\nint JOBJ_GetWorldPosition(JOBJ *source, Vec3 *add, Vec3 *dest);\nvoid JOBJ_SetMtxDirtySub(JOBJ *jobj);\nJOBJ *JOBJ_LoadJoint(JOBJDesc *joint);\nvoid JOBJ_RemoveAll(JOBJ *joint);\nvoid JOBJ_Remove(JOBJ *joint);\nvoid JOBJ_GetChild(JOBJ *joint, int ptr, int index, ...);\nvoid JOBJ_AddChild(JOBJ *parent, JOBJ *child);\nfloat JOBJ_GetCurrentMatAnimFrame(JOBJ *joint);\nvoid JOBJ_SetFlags(JOBJ *joint, int flags);\nvoid JOBJ_SetFlagsAll(JOBJ *joint, int flags);\nvoid JOBJ_ClearFlags(JOBJ *joint, int flags);\nvoid JOBJ_ClearFlagsAll(JOBJ *joint, int flags);\nvoid JOBJ_BillBoard(JOBJ *joint, Mtx *m, Mtx *mx);\nvoid 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\nvoid JOBJ_Anim(JOBJ *joint);\nvoid JOBJ_AnimAll(JOBJ *joint);\nvoid JOBJ_AddAnimAll(JOBJ *joint, void *animjoint, void *matanimjoint, void *shapeanimjoint);\nvoid JOBJ_RemoveAnimAll(JOBJ *joint);\nvoid JOBJ_ReqAnim(JOBJ *joint, float frame);\nvoid JOBJ_ReqAnimByFlags(JOBJ *joint, int flags, float frame);\nvoid JOBJ_ReqAnimAll(JOBJ *joint, float unk);\nvoid JOBJ_ReqAnimAllByFlags(JOBJ *joint, int flags, float frame);\nfloat JOBJ_GetJointAnimFrameTotal(JOBJ *joint);\nfloat JOBJ_GetJointAnimNextFrame(JOBJ *joint);\nvoid JOBJ_SetAllMOBJFlags(JOBJ *joint, int flags);\nint JOBJ_CheckAObjEnd(JOBJ *joint);\nvoid AOBJ_ReqAnim(int *aobj, float unk);\nvoid AOBJ_StopAnim(JOBJ *jobj, int flags, int flags2);\nvoid AOBJ_SetRate(AOBJ *aobj, float rate);\nvoid DOBJ_SetFlags(DOBJ *dobj, int flags);\nvoid DOBJ_ClearFlags(DOBJ *dobj, int flags);\nCOBJ *COBJ_LoadDesc(COBJDesc *cobj);\nCOBJ *COBJ_LoadDescSetScissor(COBJDesc *cobj);\nCOBJ *COBJ_GetMatchCamera();\nvoid CObjThink_Common(GOBJ *gobj);\nGOBJ *GObj_Create(int type, int subclass, int flags);\nvoid GObj_Destroy(GOBJ *gobj);\nvoid GObj_AddGXLink(GOBJ *gobj, void *cb, int gx_link, int gx_pri);\nvoid GObj_DestroyGXLink(GOBJ *gobj);\nvoid GObj_GXReorder(GOBJ *gobj, int unk);\nvoid GObj_AddProc(GOBJ *gobj, void *callback, int priority);\nvoid GObj_RemoveProc(GOBJ *gobj);\nvoid GObj_AddObject(GOBJ *gobj, u8 unk, void *object);\nvoid GObj_FreeObject(GOBJ *gobj);\nvoid GObj_AddUserData(GOBJ *gobj, int userDataKind, void *destructor, void *userData);\nvoid GOBJ_InitCamera(GOBJ *gobj, void *cb, int gx_pri);\nvoid GXLink_Common(GOBJ *gobj, int pass);\nvoid GXLink_LObj(GOBJ *gobj, int pass);\nvoid GXLink_Fog(GOBJ *gobj, int pass);\nvoid *LObj_LoadDesc(void *lobjdesc);\nvoid *Fog_LoadDesc(void *fogdesc);\nDOBJ *JOBJ_GetDObj(JOBJ *jobj);\nvoid *MOBJ_SetAlpha(DOBJ *dobj);\nvoid GObj_CopyGXPri(GOBJ *target, GOBJ *source);\n\n#endif"
  },
  {
    "path": "MexTK/include/offsets.h",
    "content": "#ifndef MEX_H_OFFSETS\n#define MEX_H_OFFSETS\n\n#define R13 0x804db6a0\n#define STAGE_CONST -0x4C08 // this is an offset used on dreamland, should be safe to use for custom stages\n#define MEMCARD -0x77C0\n#define GOBJLIST -0x3E74\n#define PLCO_SHIELDCOLORS -0x5190\n#define PLCO_FTCOMMON -0x514C\n#define STAGE 0x8049e6c8 // this is the static stage struct, labelled Stage in this file\n#define EVMENU_ASSETS -0x4A08\n#define HSD_UPDATE 0x80479d58\n#define COLL_TEST -0x51f4\n#define MATCH_HUD 0x804a10c8\n#define COBJDESC_MATCHHUD 0x80b52980\n#define MATCH_CAM 0x80452c68\n#define MATCH 0x8046b6a0\n\n#endif\n"
  },
  {
    "path": "MexTK/include/preload.h",
    "content": "#ifndef MEX_H_PRELOAD\n#define MEX_H_PRELOAD\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n\nstruct PreloadChar\n{\n    int kind;\n    u8 costume;\n};\n\nstruct Preload\n{\n    int x0;\n    int x4;\n    u8 xc;\n    int stage;\n    PreloadChar fighters[8];\n    int defragNum;\n};\n\n/*** Functions ***/\n\nvoid Preload_Update();       // checks for new files to preload and begins loading them synchronously\nPreload *Preload_GetTable(); // gets preload table\n\n#endif\n"
  },
  {
    "path": "MexTK/include/result.h",
    "content": "#ifndef MEX_H_RESULT\n#define MEX_H_RESULT\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n\nstruct RstPlayer\n{\n    u8 type;           // x0 (0x00 is HMN, 0x01 is CPU, 0x02 is Demo, 0x03 n/a)\n    u8 ext_id;         // x1 (external fighter id)\n    u8 kind;           // x2 internal id\n    u8 costume : 6;    // x3 costume id\n    u8 is_rumble : 1;  // x3 rumble flag\n    u8 is_stamina : 1; // x3 stamina flag\n    u8 nametag;        // x4 nametag index\n    u8 x5;             // x5\n    u8 x6;             // x6\n    u8 team;           // x7 team id\n    u8 stock_num;      // x8 remaining stocks\n    u8 hp;             // x9 remaining hp\n    u8 sd_num;         // xa times self destructed\n    u8 fall_num;       // xb times died\n    u16 dmg_num;       // unk\n    u16 xe;            // absolutely dont know, takes stick inputs and scene into account??\n    int x10;           // unk\n    int x14;           // unk\n    int x18;           // unk\n    int coins;         // x1c\n    int x20;           // unk\n    int x24;           // unk\n    int frames_alive;  // unk\n    int x2c;           // unk\n    int x30;           // unk\n    int x34;           // unk\n    int hits_landed;   // x38\n    int attack_num;    // x3c total attacks\n    int x40;           // unk\n    int x44;           // unk\n    int x48;           // unk\n    int x4c;           // unk\n    int x50;           // unk\n    int x54;           // unk\n    int x58;           // unk\n    int x5c;           // unk\n    int x60;           // unk\n    int x64;           // unk\n    int x68;           // unk\n    int x6c;           // unk\n    int x70;           // unk\n    int x74;           // unk\n    int x78;           // unk\n    int x7c;           // unk\n    int x80;           // unk\n    int x84;           // unk\n    int x88;           // unk\n    int ledgegrab_num; // x8c\n    int x90;           // unk\n    int x94;           // unk\n    int x98;           // unk\n    int x9c;           // unk\n    int xa0;           // unk\n    int xa4;           // unk\n};\n\nstruct RstInit\n{\n    int x0;\n    u8 end_kind;          // how the match ended. (0x2 = GAME!, 0x1 = TIME!, and 0x7 = no contest)\n    u8 x5;                // unk\n    u8 match_kind;        // 0 = ffa, 1 = teams\n    int match_frames;     // how many frames passed in the match\n    u8 xc;                // unk\n    u8 winner_num;        // is greater than 1 when a tie occurs\n    u8 placings[4];       // array of player indices in order of placement\n    int x10;              // unk\n    int x14;              // unk\n    int x18;              // unk\n    int x1c;              // unk, totals up 0x88 of rstplayer\n    u8 x20;               // unk\n    u8 x21;               // unk\n    u8 x22;               // unk\n    u8 x23;               // unk\n    int x24;              // unk\n    int x28;              // unk\n    int x2c;              // unk\n    int x30;              // unk\n    int x34;              // unk\n    int x38;              // unk\n    int x3c;              // unk\n    int x40;              // unk\n    int x44;              // unk\n    int x48;              // unk\n    int x4c;              // unk\n    int x50;              // unk\n    RstPlayer players[6]; // unk\n};\n\n#endif\n"
  },
  {
    "path": "MexTK/include/scene.h",
    "content": "#ifndef MEX_H_SCENE\n#define MEX_H_SCENE\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"match.h\"\n#include \"result.h\"\n\n// Scene Enums\nenum HEAP_KIND\n{\n    HEAPKIND_UNK0,\n    HEAPKIND_UNK1,\n    HEAPKIND_UNK2,\n    HEAPKIND_UNK3,\n    HEAPKIND_UNK4,\n};\nenum MINOR_KIND\n{\n    MNRKIND_TITLE,      // Title Screen\n    MNRKIND_MNMA,       // Main Menu\n    MNRKIND_MATCH,      // VS Dairantou (In-Game)\n    MNRKIND_SUDDEATH,   // Sudden Death Dairantou (In-Game)\n    MNRKIND_TRAIN,      // Training Mode Dairantou (In-Game)\n    MNRKIND_RST,        // Result Screen\n    MNRKIND_X6,         //\n    MNRKIND_DB,         // Debug Menu\n    MNRKIND_CSS,        // CSS\n    MNRKIND_SSS,        // SSS\n    MNRKIND_XA,         //\n    MNRKIND_TYGAL,      // Trophy Gallery\n    MNRKIND_TYLOT,      // Trophy Lottery\n    MNRKIND_TYCOL,      // Trophy Collection\n    MNRKIND_ADVSPLSH,   // Adventure Mode Splash Screen\n    MNRKIND_TYFALL,     // 1P Mode Trophy Falling Cutscene\n    MNRKIND_ADVCGRT,    // Adventure Mode Congratulations\n    MNRKIND_VI1,        // VisualScene_Luigi\n    MNRKIND_VI2,        // VisualScene_BrinstarLava\n    MNRKIND_VI3,        // VisualScene_PlanetExplode\n    MNRKIND_VI4,        // VisualScene_3KirbysSpawn\n    MNRKIND_VI5,        // VisualScene_GiantKirbySpawns\n    MNRKIND_VI6,        // VisualScene_StarFoxDialog\n    MNRKIND_VI7,        // VisualScene_FZeroRace\n    MNRKIND_VI8,        // VisualScene_MetalMarioLuigi\n    MNRKIND_VI9,        // VisualScene_BowserTrophyFalls\n    MNRKIND_VI10,       // VisualScene_GigaBowserTransformation\n    MNRKIND_VI11,       // VisualScene_GigaBowserDefeated\n    MNRKIND_OP,         // Opening Movie\n    MNRKIND_1PENDMV,    // 1P Mode End Movie\n    MNRKIND_HOWMV,      // How to Play Movie\n    MNRKIND_OMAKE,      // Special Movie\n    MNRKIND_CLSCSPLSH,  // TEST\n    MNRKIND_ALSPLSH,    // TEST\n    MNRKIND_GMOV,       // Game over\n    MNRKIND_SOON,       // coming soon\n    MNRKIND_TOSETUP,    // tournament setup\n    MNRKIND_TOBRCK,     // tourn bracket\n    MNRKIND_TOUNK,      // tourn unk\n    MNRKIND_SPCLMSG,    // special msg\n    MNRKIND_PROG,       // progressive\n    MNRKIND_CHLG,       // challenger\n    MNRKIND_CARD,       // memcard prompt\n    MNRKIND_STAFF,      // credits\n    MNRKIND_CAMWARN,    // camera mode memcard prompt\n    MNRKIND_NULL,       // terminator\n    MNRKIND_SMSHDWNCSS, // custom smashdown css\n};\n\nstruct MajorScene\n{\n    u8 is_preload;\n    u8 major_id;\n    void *onLoad;\n    void *onExit;\n    void *onBoot;\n    void *MinorScene; // array of minor scenes\n};\nstruct MinorScene\n{\n    u8 minor_id;        // is 255 for last entry\n    u8 heap_kind;       // heap behavior\n    void *minor_prep;   // inits data for this minor (major exclusive)\n    void *minor_decide; // decides next minor scene\n    u8 minor_kind;      // index for a re-useable list of scene functions. contains a load, think, and leave function.\n    void *load_data;    // points to static data used throughout this minor. other minors may use the same pointer to exchange data between minors\n    void *unload_data;  // points to static data used throughout this minor. other minors may use the same pointer to exchange data between minors\n};\n\nstruct ScDataVS\n{\n    u8 x8;\n    u8 x9;\n    u8 xa;\n    int xc;\n    MatchInit match_init;\n};\n\nstruct ScDataRst\n{\n    int x0;\n    int x4;\n    int x8;\n    int xc;\n    RstInit rst_init;\n};\n\nvoid Scene_EnterMajor(int major_id);\nvoid CSS_DecideNext(MinorScene *minor_scene, ScDataVS *css_data);\nvoid CSS_ResetKOStars();\nvoid CSS_InitMajorData(ScDataVS *major_data);\nvoid CSS_InitMinorData(MinorScene *minor_scene, ScDataVS *major_data, int css_kind);\nvoid SSS_InitMinorData(MinorScene *minor_scene, ScDataVS *major_data);\nvoid Match_InitMinorData(MinorScene *minor_scene, ScDataVS *major_data, void *init_cb, void *startmelee_cb);\nvoid Match_SetNametags(MatchInit *match_init);\n#endif\n"
  },
  {
    "path": "MexTK/include/stage.h",
    "content": "#ifndef MEX_H_STAGE\n#define MEX_H_STAGE\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"hsd.h\"\n#include \"obj.h\"\n\n// map_gobjDesc Flags\n#define map_isBG 0x40000000\n#define map_isUnk 0x80000000\n\nenum GrInternal\n{\n    GR_DUMMY,\n    GR_TEST,\n    GR_CASTLE,\n    GR_RCRUISE,\n    GR_KONGO,\n    GR_GARDEN,\n    GR_GREATBAY,\n    GR_SHRINE,\n    GR_ZEBES,\n    GR_KRAID,\n    GR_STORY,\n    GR_YOSTER,\n    GR_IZUMI,\n    GR_GREENS,\n    GR_CORNERIA,\n    GR_VENOM,\n    GR_PSTAD,\n    GR_PURA,\n    GR_MUTECITY,\n    GR_BIGBLUE,\n    GR_ONETT,\n    GR_FOURSIDE,\n    GR_ICEMT,\n    GR_ICETOP,\n    GR_MK1,\n    GR_MK2,\n    GR_AKANEIA,\n    GR_FLATZONE,\n    GR_OLDPU,\n    GR_OLDSTORY,\n    GR_OLDKONGO,\n    GR_ADVKRAID,\n    GR_ADVSHRINE,\n    GR_ADVZR,\n    GR_ADVBR,\n    GR_ADVTE,\n    GR_BATTLE,\n    GR_FD,\n};\n\n/*** Structs ***/\n\nstruct map_gobjDesc\n{\n    void *(*onCreation)(GOBJ *map);\n    void *onDeletion;\n    void *onFrame;\n    void *onUnk;\n    int flags;\n};\n\nstruct map_gobjData\n{\n    int x0;                    // 0x0\n    GOBJ *gobj;                // 0x4\n    int x8;                    // 0x8\n    int xC;                    // 0xC\n    unsigned char flagx80 : 1; //  0x80\n    unsigned char flagx40 : 1; //  0x40\n    unsigned char isFog : 1;   //  0x20, checked @ 801c5e80 and 801c5f10\n    unsigned char flagx10 : 1; //  0x10\n    unsigned char flagx8 : 1;  //  0x08\n    unsigned char gx_unk1 : 1; //  0x04, checked @ 801c5e9c\n    unsigned char flagx2 : 1;  //  0x02\n    unsigned char flagx1 : 1;  //  0x01\n\n    unsigned char gx_unk2 : 3;  //  0x80\n    unsigned char flag2x10 : 1; //  0x10\n    unsigned char flag2x08 : 1; //  0x08\n    unsigned char flag2x04 : 1; //  0x04, checked @ 801c5e9c\n    unsigned char flag2x02 : 1; //  0x02\n    unsigned char flag2x01 : 1; //  0x01\n\n    int map_gobjID;      // 0x14\n    int x18;             // 0x18\n    int onUnk;           // 0x1c\n    int x20;             // 0x20\n    int x24;             // 0x24\n    int stateID;         // 0x28\n    int facingDirection; // 0x2c\n    int x30;             // 0x30\n    int x34;             // 0x34\n    float scale;         // 0x38\n    int x3c;             // 0x3c\n    float selfVelX;      // 0x40\n    float selfVelY;      // 0x44\n    float selfVelZ;      // 0x48\n    float posX;          // 0x4c\n    float posY;          // 0x50\n    float posZ;          // 0x54\n    int x58;             // 0x58\n    int x5c;             // 0x5c\n    int x60;             // 0x60\n    int x64;             // 0x64\n    int x68;             // 0x68\n    int x6c;             // 0x6c\n    int x70;             // 0x70\n    int x74;             // 0x74\n    int x78;             // 0x78\n    int x7c;             // 0x7c\n    int x80;             // 0x80\n    int x84;             // 0x84\n    int x88;             // 0x88\n    int x8c;             // 0x8c\n    int x90;             // 0x90\n    int x94;             // 0x94\n    int x98;             // 0x98\n    int x9c;             // 0x9c\n    int xa0;             // 0xa0\n    int xa4;             // 0xa4\n    int xa8;             // 0xa8\n    int xac;             // 0xac\n    int xb0;             // 0xb0\n    int xb4;             // 0xb4\n    int xb8;             // 0xb8\n    int xbc;             // 0xbc\n    int xc0;             // 0xc0\n    u8 xc4;              // 0xc4\n    u8 xc5;              // 0xc5\n    u8 xc6;              // 0xc6\n    u8 xc7;              // 0xc7\n    int xc8;             // 0xc8\n    int xcc;             // 0xcc\n    int xd0;             // 0xd0\n    int xd4;             // 0xd4\n    int xd8;             // 0xd8\n    int xdc;             // 0xdc\n    struct\n    {\n        int mapVar0; // 0xe0\n        int mapVar1; // 0xe4\n        int mapVar2; // 0xe8\n        int mapVar3; // 0xec\n        int mapVar4; // 0xf0\n        int mapVar5; // 0xf4\n        int mapVar6; // 0xf8\n        int mapVar7; // 0xfc\n        int x100;    // 0x100\n        int x104;    // 0x104\n        int x108;    // 0x108\n        int x10c;    // 0x10c\n        int x110;    // 0x110\n        int x114;    // 0x114\n        int x118;    // 0x118\n        int x11c;    // 0x11c\n        int x120;    // 0x120\n        int x124;    // 0x124\n        int x128;    // 0x128\n        int x12c;    // 0x12c\n        int x130;    // 0x130\n        int x134;    // 0x134\n        int x138;    // 0x138\n        int x13c;    // 0x13c\n        int x140;    // 0x140\n        int x144;    // 0x144\n        int x148;    // 0x148\n        int x14c;    // 0x14c\n        int x150;    // 0x150\n        int x154;    // 0x154\n        int x158;    // 0x158\n        int x15c;    // 0x15c\n        int x160;    // 0x160\n        int x164;    // 0x164\n        int x168;    // 0x168\n        int x16c;    // 0x16c\n        int x170;    // 0x170\n        int x174;    // 0x174\n        int x178;    // 0x178\n        int x17c;    // 0x17c\n        int x180;    // 0x180\n        int x184;    // 0x184\n        int x188;    // 0x188\n        int x18c;    // 0x18c\n        int x190;    // 0x190\n        int x194;    // 0x194\n        int x198;    // 0x198\n        int x19c;    // 0x19c\n        int x1a0;    // 0x1a0\n        int x1a4;    // 0x1a4\n        int x1a8;    // 0x1a8\n        int x1ac;    // 0x1ac\n        int x1b0;    // 0x1b0\n        int x1b4;    // 0x1b4\n        int x1b8;    // 0x1b8\n        int x1bc;    // 0x1bc\n        int x1c0;    // 0x1c0\n        int x1c4;    // 0x1c4\n        int x1c8;    // 0x1c8\n        int x1cc;    // 0x1cc\n        int x1d0;    // 0x1d0\n        int x1d4;    // 0x1d4\n        int x1d8;    // 0x1d8\n        int x1dc;    // 0x1dc\n        int x1e0;    // 0x1e0\n        int x1e4;    // 0x1e4\n        int x1e8;    // 0x1e8\n        int x1ec;    // 0x1ec\n        int x1f0;    // 0x1f0\n        int x1f4;    // 0x1f4\n        int x1f8;    // 0x1f8\n        int x1fc;    // 0x1fc\n        int x200;    // 0x200\n    } map_struct;\n};\n\nstruct StageOnGO\n{\n    StageOnGO *next;\n    GOBJ *map_gobj;\n    void *cb;\n};\n\nstruct Stage\n{\n    float cam_LeftBound;   // 0x0\n    float cam_RightBound;  // 0x4\n    float cam_TopBound;    // 0x8\n    float cam_BottomBound; // 0xc\n    float cam_HorizOffset; // 0x10\n    float crowdReactStart; // 0x14, begins checking for crowd gasps below this position\n    float fov_d;           // 0x18\n    float fov_u;           // 0x1c\n    float fov_r;           // 0x20, actually horizontal rotation?\n    float fov_l;           // 0x24\n    float x28;             // 0x28\n    float x2c;             // 0x2c\n    float x30;             // 0x30\n    float x34;             // 0x34, camera distance min\n    float x38;             // 0x38\n    float x3c;             // 0x3c\n    float x40;             // 0x40\n    int x44;               // 0x44\n    int x48;               // 0x48\n    int x4c;               // 0x4c\n    int x50;               // 0x50\n    int x54;               // 0x54\n    int x58;               // 0x58\n    int x5c;               // 0x5c\n    int x60;               // 0x60\n    int x64;               // 0x64\n    int x68;               // 0x68\n    int x6c;               // 0x6c\n    int x70;               // 0x70\n    float blastzoneLeft;   // 0x74\n    float blastzoneRight;  // 0x78\n    float blastzoneTop;    // 0x7c\n    float blastzoneBottom; // 0x80\n    int flags;             // 0x84\n    int stageID;           // 0x88\n    int flags2;            // 0x8c\n    int x90;               // 0x90\n    int x94;               // 0x94\n    int hpsID;             // 0x98\n    int x9c;               // 0x9c\n    int xa0;               // 0xa0\n    int xa4;               // 0xa4\n    int xa8;               // 0xa8\n    int xac;               // 0xac\n    int xb0;               // 0xb0\n    int xb4;               // 0xb4\n    int xb8;               // 0xb8\n    int xbc;               // 0xbc\n    int xc0;               // 0xc0\n    int xc4;               // 0xc4\n    int xc8;               // 0xc8\n    int xcc;               // 0xcc\n    int xd0;               // 0xd0\n    int xd4;               // 0xd4\n    int xd8;               // 0xd8\n    int xdc;               // 0xdc\n    int xe0;               // 0xe0\n    int xe4;               // 0xe4\n    int xe8;               // 0xe8\n    int xec;               // 0xec\n    int xf0;               // 0xf0\n    int xf4;               // 0xf4\n    int xf8;               // 0xf8\n    int xfc;               // 0xfc\n    int x100;              // 0x100\n    int x104;              // 0x104\n    int x108;              // 0x108\n    int x10c;              // 0x10c\n    int x110;              // 0x110\n    int x114;              // 0x114\n    int x118;              // 0x118\n    int x11c;              // 0x11c\n    int x120;              // 0x120\n    int x124;              // 0x124\n    int x128;              // 0x128\n    int x12c;              // 0x12c\n    int x130;              // 0x130\n    int x134;              // 0x134\n    int x138;              // 0x138\n    int x13c;              // 0x13c\n    int x140;              // 0x140\n    int x144;              // 0x144\n    int x148;              // 0x148\n    int x14c;              // 0x14c\n    int x150;              // 0x150\n    int x154;              // 0x154\n    int x158;              // 0x158\n    int x15c;              // 0x15c\n    int x160;              // 0x160\n    int x164;              // 0x164\n    int x168;              // 0x168\n    int x16c;              // 0x16c\n    int x170;              // 0x170\n    int x174;              // 0x174\n    int x178;              // 0x178\n    int x17c;              // 0x17c\n    GOBJ *map_gobjs[64];\n    JOBJ *general_points[256]; // 0x280\n    int x680;                  // 0x680\n    int x684;                  // 0x684\n    int x688;                  // 0x688\n    int x68c;                  // 0x68c\n    int x690;                  // 0x690\n    int x694;                  // 0x694\n    int x698;                  // 0x698\n    int x69c;                  // 0x69c\n    int x6a0;                  // 0x6a0\n    StageOnGO *on_go;          // 0x6a4\n    int *itemData;             // 0x6a8\n    int *coll_data;            // 0x6ac\n    int *grGroundParam;        // 0x6b0\n    int *ALDYakuAll;           // 0x6b4\n    int *map_ptcl;             // 0x6b8\n    int *map_texg;             // 0x6bc\n    int *yakumono_param;       // 0x6c0\n    int *map_plit;             // 0x6c4\n    int *x6c8;                 // 0x6c8\n    void *quake_model_set;     // 0x6cc\n    int *x6d0;                 // 0x6d0\n    int *targetsRemaining;     // 0x6d4\n    int x6d8;                  // 0x6d8\n    int x6dc;                  // 0x6dc\n    int x6e0;                  // 0x6e0\n    int x6e4;                  // 0x6e4\n    int x6e8;                  // 0x6e8\n    int x6ec;                  // 0x6ec\n    int x6f0;                  // 0x6f0\n    int x6f4;                  // 0x6f4\n    int x6f8;                  // 0x6f8\n    int x6fc;                  // 0x6fc\n    int x700;                  // 0x700\n    int x704;                  // 0x704\n    int x708;                  // 0x708\n    int x70c;                  // 0x70c\n    int x710;                  // 0x710\n    int x714;                  // 0x714\n    int x718;                  // 0x718\n    int x71c;                  // 0x71c\n    int x720;                  // 0x720\n    int x724;                  // 0x724\n    int x728;                  // 0x728\n    int x72C;                  // 0x728\n};\n\nstruct MapHead\n{\n    int *general_points;\n    int general_points_num;\n    int *map_gobjs; // pointer to array of map_gobjs\n    int map_gobj_num;\n    int *splines;\n    int splines_num;\n    int *lights;\n    int lights_num;\n};\n\nstruct StageFile\n{\n    ArchiveInfo *archive_info;\n    MapHead *map_head;\n};\n\n/*** Functions ***/\n\nStageFile *Stage_GetStageFiles();                 // returns an array of StageFiles\nStageFile *Stage_GetStageFile(int mapgobj_index); // returns the StageFile the ID belongs to\nvoid Stage_AddFtChkDevice(GOBJ *map, int hazard_kind, void *check);\nvoid Stage_SetChkDevicePos(float y_pos);\nvoid Stage_GetChkDevicePos(float *y_pos, float *y_delta);\nfloat Stage_GetScale();\nint *Stage_GetYakumonoParam();\nvoid Stage_MapStateChange(GOBJ *map, int map_gobjID, int anim_id);\nvoid Dynamics_DecayWind();\nGOBJ *Stage_CreateMapGObj(int mapgobjID);\nvoid Stage_DestroyMapGObj(GOBJ *map_gobj);\nvoid *GXLink_Stage(GOBJ *gobj, int pass);\nGOBJ *Stage_GetMapGObj(int mapgobjID);\nJOBJ *Stage_GetMapGObjJObj(GOBJ *mapgobj, int jointIndex);\nint Stage_GetLinesGroup(int line);\nint Stage_GetLinesDirection(int line);\nvoid Stage_SetGroundCallback(int line, void *userdata, void *callback);\nvoid Stage_SetCeilingCallback(int line, void *userdata, void *callback);\nvoid Stage_InitMovingColl(JOBJ *mapjoint, int mapgobjID);\nvoid Stage_UpdateMovingColl(GOBJ *mapgobj);\nParticle *Stage_SpawnEffectPos(int gfxID, int efFileID, Vec3 *pos);\nParticle *Stage_SpawnEffectJointPos(int gfxID, int efFileID, JOBJ *pos);\nParticle *Stage_SpawnEffectJointPos2(int gfxID, int efFileID, JOBJ *pos);\nGOBJ *Zako_Create(int item_id, Vec3 *pos, JOBJ *jobj, Vec3 *velocity, int isMovingItem);\nGOBJ *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.\nint Stage_CheckForNearbyFighters(Vec3 *pos, float radius);\nfloat Stage_GetBlastzoneRight();\nfloat Stage_GetBlastzoneLeft();\nfloat Stage_GetBlastzoneTop();\nfloat Stage_GetBlastzoneBottom();\nfloat Stage_GetCameraRight();\nfloat Stage_GetCameraLeft();\nfloat Stage_GetCameraTop();\nfloat Stage_GetCameraBottom();\nvoid Stage_GetGeneralPoint(int index, Vec3 *pos);\nvoid Stage_EnableLineGroup(int index);\nvoid Stage_DisableLineGroup(int index);\nint Stage_GetExternalID();\nint Stage_ExternalToInternal(int ext_id);\n\nStage *stc_stage = 0x8049e6c8;\nint *ftchkdevice_windnum = R13 + (-0x5128);\nint *ftchkdevice_grabnum = R13 + (-0x512C);\nint *ftchkdevice_dmgnum = R13 + (-0x5130);\n#endif\n"
  },
  {
    "path": "MexTK/include/structs.h",
    "content": "#ifndef MEX_H_STRUCTS\n#define MEX_H_STRUCTS\n\n/* \n *  defines typedefs for structs used throughout m-ex\n */\n\n// Basic Data Structs\ntypedef struct Vec2 Vec2;\ntypedef struct Vec3 Vec3;\ntypedef struct Vec4 Vec4;\n\n// OS\ntypedef struct OSInfo OSInfo;\ntypedef struct OSCalendarTime OSCalendarTime;\ntypedef struct CARDStat CARDStat;\ntypedef struct CARDFileInfo CARDFileInfo;\ntypedef struct RGB565 RGB565;\n\n// HSD Objects\ntypedef struct GOBJ GOBJ;\ntypedef struct GOBJProc GOBJProc;\ntypedef struct GOBJList GOBJList;\ntypedef struct GXList GXList;\ntypedef struct JOBJ JOBJ;\ntypedef struct JOBJDesc JOBJDesc;\ntypedef struct DOBJ DOBJ;\ntypedef struct TOBJ TOBJ;\ntypedef struct AOBJ AOBJ;\ntypedef struct MOBJ MOBJ;\ntypedef struct WOBJ WOBJ;\ntypedef struct COBJ COBJ;\ntypedef struct COBJDesc COBJDesc;\ntypedef struct _HSD_ImageDesc _HSD_ImageDesc;\ntypedef struct _HSD_LightPoint _HSD_LightPoint;\ntypedef struct _HSD_LightPointDesc _HSD_LightPointDesc;\ntypedef struct _HSD_LightSpot _HSD_LightSpot;\ntypedef struct _HSD_LightSpotDesc _HSD_LightSpotDesc;\ntypedef struct _HSD_LightAttn _HSD_LightAttn;\ntypedef struct LOBJ LOBJ;\ntypedef struct JOBJAnimSet JOBJAnimSet;\n\n// Archive\ntypedef struct ArchiveInfo ArchiveInfo;\ntypedef struct MapHead MapHead;\n\n// Stage\ntypedef struct Stage Stage;\ntypedef struct StageOnGO StageOnGO;\ntypedef struct map_gobjData map_gobjData;\ntypedef struct map_gobjDesc map_gobjDesc;\ntypedef struct StageFile StageFile;\n\n// Match\ntypedef struct MatchInit MatchInit;\ntypedef struct Match Match;\ntypedef struct MatchHUD MatchHUD;\ntypedef struct MatchCamera MatchCamera;\ntypedef struct CameraBox CameraBox;\ntypedef struct MatchOffscreen MatchOffscreen;\n\n// Text\ntypedef struct Text Text;\ntypedef struct TextAllocInfo TextAllocInfo;\n\n// DevText\ntypedef struct DevText DevText;\n\n// Effects\ntypedef struct Effect Effect;\ntypedef struct Particle Particle;\ntypedef struct Particle2 Particle2;\ntypedef struct ptclGen ptclGen;\ntypedef struct GeneratorAppSRT GeneratorAppSRT;\n\n// Color\ntypedef struct GXColor GXColor;\ntypedef struct ColorOverlay ColorOverlay;\n\n// Item\ntypedef struct ItemData ItemData;\ntypedef struct ItemState ItemState;\ntypedef struct SpawnItem SpawnItem;\ntypedef struct itData itData;\ntypedef struct itCommonAttr itCommonAttr;\ntypedef struct itHit itHit;\n\n// Fighter\ntypedef struct FighterData FighterData;\ntypedef struct FighterBone FighterBone;\ntypedef struct Playerblock Playerblock;\ntypedef struct PlayerData PlayerData;\ntypedef struct MoveLogic MoveLogic;\ntypedef struct SubactionHeader SubactionHeader;\ntypedef struct ftHit ftHit;\ntypedef struct HitVictim HitVictim;\ntypedef struct FtHurt FtHurt;\ntypedef struct ReflectDesc ReflectDesc;\ntypedef struct ShieldDesc ShieldDesc;\ntypedef struct AbsorbDesc AbsorbDesc;\ntypedef struct CPU CPU;\ntypedef struct ftData ftData;\ntypedef struct ftCommonData ftCommonData;\ntypedef struct ftChkDevice ftChkDevice;\ntypedef struct FtSymbolLookup FtSymbolLookup;\ntypedef struct FtSymbols FtSymbols;\ntypedef struct FtParts FtParts;\ntypedef struct FtPartsDesc FtPartsDesc;\ntypedef struct FtDOBJUnk FtDOBJUnk;\ntypedef struct FtPartsLookup FtPartsLookup;\ntypedef struct FtDOBJUnk2 FtDOBJUnk2;\ntypedef struct FtDOBJUnk3 FtDOBJUnk3;\ntypedef struct FtDynamicBoneset FtDynamicBoneset;\ntypedef struct FtDynamicRoot FtDynamicRoot;\ntypedef struct FtDynamicHit FtDynamicHit;\ntypedef struct DynamicsDesc DynamicsDesc;\ntypedef struct DynamicsHitDesc DynamicsHitDesc;\ntypedef struct DynamicsBehave DynamicsBehave;\ntypedef struct ftDynamics ftDynamics;\n\n// Fighter States\ntypedef struct FtCliffCatch FtCliffCatch;\n\n// CSS\ntypedef struct CSSBackup CSSBackup;\ntypedef struct MnSelectChrDataTable MnSelectChrDataTable;\ntypedef struct VSMinorData VSMinorData;\ntypedef struct CSSCursor CSSCursor;\ntypedef struct CSSPuck CSSPuck;\ntypedef struct MnSlChrData MnSlChrData;\ntypedef struct MnSlChrIcon MnSlChrIcon;\ntypedef struct MnSlChrDoor MnSlChrDoor;\ntypedef struct MnSlChrTag MnSlChrTag;\ntypedef struct MnSlChrTagData MnSlChrTagData;\ntypedef struct MnSlChrKOStar MnSlChrKOStar;\n\n// Memcard\ntypedef struct Memcard Memcard;\ntypedef struct MemcardWork MemcardWork;\ntypedef struct MemcardUnk MemcardUnk;\ntypedef struct MemcardSave MemcardSave;\ntypedef struct MemcardInfo MemcardInfo;\ntypedef struct SnapshotInfo SnapshotInfo;\ntypedef struct SnapshotList SnapshotList;\ntypedef struct MemSnapIconData MemSnapIconData;\ntypedef struct Rules1 Rules1;\n\n// Collision\ntypedef struct CollData CollData;\ntypedef struct ECBBones ECBBones;\ntypedef struct DmgHazard DmgHazard;\ntypedef struct CollLineInfo CollLineInfo;\ntypedef struct CollLine CollLine;\ntypedef struct CollVert CollVert;\ntypedef struct CollDataStage CollDataStage;\ntypedef struct CollGroupDesc CollGroupDesc;\ntypedef struct CollGroup CollGroup;\n\n// HSD\ntypedef struct HSD_Material HSD_Material;\ntypedef struct HSD_Pad HSD_Pad;\ntypedef struct HSD_Pads HSD_Pads;\ntypedef struct HSD_Update HSD_Update;\ntypedef struct HSD_VI HSD_VI;\ntypedef struct HSD_ObjAllocData HSD_ObjAllocData;\n\n// Scene\ntypedef struct MajorScene MajorScene;\ntypedef struct MinorScene MinorScene;\ntypedef struct ScDataVS ScDataVS;\ntypedef struct ScDataRst ScDataRst;\n\n// Results\ntypedef struct RstPlayer RstPlayer;\ntypedef struct RstInit RstInit;\n\n// Preload\ntypedef struct Preload Preload;\ntypedef struct PreloadChar PreloadChar;\n\n// Kirby\ntypedef struct FtVarKirby FtVarKirby;\n\n// Custom\ntypedef struct PRIM PRIM;\ntypedef struct MEXPlaylist MEXPlaylist;\ntypedef struct Translation Translation;\n\n#endif\n"
  },
  {
    "path": "MexTK/include/text.h",
    "content": "#ifndef MEX_H_TEXT\n#define MEX_H_TEXT\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"obj.h\"\n#include \"color.h\"\n\n/*** Structs ***/\n\nstruct TextAllocInfo\n{\n    u8 *curr;\n    u8 *start;\n    int size;\n};\n\nstruct Text\n{\n    Vec3 trans;  // 0x0-0xC\n    Vec2 aspect; // 0xC-0x14\n    int x14;\n    int x18;\n    int x1c;\n    int x20;\n    Vec2 scale; // 0x24-0x2C\n    int x2C;\n    GXColor color;\n    Vec2 stretch;  // 0x34-0x3C\n    int x3c;       // 0x3c\n    int x40;       // 0x40\n    int x44;       // 0x44\n    u8 use_aspect; // 0x48\n    u8 kerning;    // 0x49\n    u8 align;      // 0x4a\n    u8 x4b;\n    u8 x4c;\n    u8 hidden; // 0x4D\n    u8 x4e;\n    u8 sis_id; // 0x4F, id of the premade text file to use\n    int x50;\n    GOBJ *gobj;               // 0x54\n    void *callback;           // 0x58, read at 803a878c\n    u8 *textAlloc;            // 0x5C\n    u8 *textAlloc2;           // 0x60\n    TextAllocInfo *allocInfo; // 0x64\n};\n\n/*** Functions ***/\n\nint 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\nText *Text_CreateText(int SisIndex, int canvasID);\nText *Text_CreateText2(int SisIndex, int canvasID, float pos_x, float pos_y, float pos_z, float limit_x, float limit_y);\nvoid Text_Destroy(Text *text);\nint Text_AddSubtext(Text *text, float xPos, float yPos, char *string, ...);\nvoid Text_SetScale(Text *text, int subtext, float x, float y);\nvoid Text_SetColor(Text *text, int subtext, GXColor *color);\nvoid Text_SetPosition(Text *text, int subtext, float x, float y);\nvoid Text_SetText(Text *text, int subtext, char *string, ...);\nint Text_ConvertToMenuText(char *buffer, char *string);\nu8 *Text_Alloc(int size);\nvoid Text_DestroyAlloc(u8 *alloc);\nvoid Text_DestroyAllAlloc(Text *text);\nint Text_StringToMenuText(u8 *out, char *in);\nvoid Text_GX(GOBJ *gobj, int pass);\nvoid Text_LoadSdFile(int index, char *filename, char *symbol);\nvoid Text_SetSisText(Text *text, int text_index);\n\n#endif\n"
  },
  {
    "path": "MexTK/include/useful.h",
    "content": "#ifndef MEX_H_USEFUL\n#define MEX_H_USEFUL\n\n#include <stdarg.h>\n\n#include \"structs.h\"\n#include \"datatypes.h\"\n#include \"fighter.h\"\n#include \"devtext.h\"\n\n// OS Macros\n#define OSRoundUp32B(x) (((u32)(x) + 32 - 1) & ~(32 - 1))\n#define OSRoundDown32B(x) (((u32)(x)) & ~(32 - 1))\n#define OSRoundUp512B(x) (((u32)(x) + 512 - 1) & ~(512 - 1)) // using this for card reads\n#define OSRoundDown512B(x) (((u32)(x)) & ~(512 - 1))         // using this for card reads\n#define OSTicksToMilliseconds(ticks) ((ticks) / (os_info->bus_clock / 1000))\n#define BitCheck(num, bit) !!((num) & (1 << (bit))) // returns 0 or 1\n#define __FILENAME__ (strrchr(__FILE__, '\\\\') ? strrchr(__FILE__, '\\\\') + 1 : __FILE__)\n#define assert(msg) __assert(__FILENAME__, __LINE__, msg)\n#define divide_roundup(dividend, divisor) ((dividend + (divisor / 2)) / divisor)\n#define MTXDegToRad(a) ((a)*0.01745329252f)\n#define MTXRadToDeg(a) ((a)*57.29577951f)\n\n/** Console Definitions */ //\n#define OS_CONSOLE_RETAIL4 0x00000004\n#define OS_CONSOLE_RETAIL3 0x00000003\n#define OS_CONSOLE_RETAIL2 0x00000002\n#define OS_CONSOLE_RETAIL1 0x00000001\n#define OS_CONSOLE_DEVHW4 0x10000007\n#define OS_CONSOLE_DEVHW3 0x10000006\n#define OS_CONSOLE_DEVHW2 0x10000005\n#define OS_CONSOLE_DEVHW1 0x10000004\n#define OS_CONSOLE_MINNOW 0x10000003\n#define OS_CONSOLE_ARTHUR 0x10000002\n#define OS_CONSOLE_PC_EMULATOR 0x10000001\n#define OS_CONSOLE_EMULATOR 0x10000000\n#define OS_CONSOLE_DEVELOPMENT 0x10000000 // bit mask\n\n#define CARD_MAX_FILE 127\n#define CARD_FILENAME_MAX 32\n#define CARD_ICON_MAX 8\n#define CARD_COMMENT_SIZE 64\n#define CARD_WORKAREA_SIZE (5 * 8 * 1024)\n#define CARD_READ_SIZE 512\n#define CARD_RESULT_UNLOCKED 1\n#define CARD_RESULT_READY 0\n#define CARD_RESULT_BUSY -1\n#define CARD_RESULT_WRONGDEVICE -2\n#define CARD_RESULT_NOCARD -3\n#define CARD_RESULT_NOFILE -4\n#define CARD_RESULT_IOERROR -5\n#define CARD_RESULT_BROKEN -6\n#define CARD_RESULT_EXIST -7\n#define CARD_RESULT_NOENT -8\n#define CARD_RESULT_INSSPACE -9\n#define CARD_RESULT_NOPERM -10\n#define CARD_RESULT_LIMIT -11\n#define CARD_RESULT_NAMETOOLONG -12\n#define CARD_RESULT_ENCODING -13\n#define CARD_RESULT_CANCELED -14\n#define CARD_RESULT_FATAL_ERROR -128\n\n/*** Structs ***/\nstruct OSInfo\n{\n    // info obtained from https://www.gc-forever.com/yagcd/chap4.html#sec4.2.1\n\n    char gameName[4];      // 0x80000000\n    char company[2];       // 0x80000004\n    u8 disk_id;            // 0x80000006\n    u8 disk_version;       // 0x80000007\n    u8 is_audiostream;     // 0x80000008\n    u8 streambuffer_size;  // 0x80000009\n    int xc;                // 0x8000000C\n    int x10;               // 0x80000010\n    int x14;               // 0x80000014\n    int x18;               // 0x80000018\n    int dvd_magicword;     // 0x8000001C\n    int boot_magicword;    // 0x80000020\n    int sys_version;       // 0x80000024\n    int mem_size;          // 0x80000028\n    int console_type;      // 0x8000002C\n    int arena_lo;          // 0x80000030\n    int arena_hi;          // 0x80000034\n    void *fst;             // 0x80000038\n    int fst_maxsize;       // 0x8000003C\n    int x40;               // 0x80000040\n    int x44;               // 0x80000044\n    int x48;               // 0x80000048\n    int x4C;               // 0x8000004C\n    int x50;               // 0x80000050\n    int x54;               // 0x80000054\n    int x58;               // 0x80000058\n    int x5C;               // 0x8000005C\n    int x60;               // 0x80000060\n    int x64;               // 0x80000064\n    int x68;               // 0x80000068\n    int x6C;               // 0x8000006C\n    int x70;               // 0x80000070\n    int x74;               // 0x80000074\n    int x78;               // 0x80000078\n    int x7C;               // 0x8000007C\n    int x80;               // 0x80000080\n    int x84;               // 0x80000084\n    int x88;               // 0x80000088\n    int x8C;               // 0x8000008C\n    int x90;               // 0x80000090\n    int x94;               // 0x80000094\n    int x98;               // 0x80000098\n    int x9C;               // 0x8000009C\n    int xA0;               // 0x800000A0\n    int xA4;               // 0x800000A4\n    int xA8;               // 0x800000A8\n    int xAC;               // 0x800000AC\n    int xB0;               // 0x800000B0\n    int xB4;               // 0x800000B4\n    int xB8;               // 0x800000B8\n    int xBC;               // 0x800000BC\n    int xC0;               // 0x800000C0\n    int xC4;               // 0x800000C4\n    int xC8;               // 0x800000C8\n    int tv_mode;           // 0x800000CC\n    int aram_size;         // 0x800000D0\n    int xD4;               // 0x800000D4\n    int xD8;               // 0x800000D8\n    int xDC;               // 0x800000DC\n    int xE0;               // 0x800000E0\n    int curr_osthread;     // 0x800000E4\n    int xE8;               // 0x800000E8\n    int xEC;               // 0x800000EC\n    int simulated_memsize; // 0x800000F0\n    void *dvd_BI2;         // 0x800000F4\n    int bus_clock;         // 0x800000F8\n    int cpu_clock;         // 0x800000FC\n};\nstruct OSCalendarTime\n{\n    int sec;  // seconds after the minute [0, 61]\n    int min;  // minutes after the hour [0, 59]\n    int hour; // hours since midnight [0, 23]\n    int mday; // day of the month [1, 31]\n    int mon;  // month since January [0, 11]\n    int year; // years in AD [1, ...]\n    int wday; // days since Sunday [0, 6]\n    int yday; // days since January 1 [0, 365]\n\n    int msec; // milliseconds after the second [0,999]\n    int usec; // microseconds after the millisecond [0,999]\n};\nstruct CARDStat\n{\n    // read-only (Set by CARDGetStatus)\n    char fileName[CARD_FILENAME_MAX];\n    u32 length;\n    u32 time; // seconds since midnight 01/01/2000\n    u8 gameName[4];\n    u8 company[2];\n\n    // read/write (Set by CARDGetStatus/CARDSetStatus)\n    u8 bannerFormat;\n    u32 iconAddr;\n    u16 iconFormat;\n    u16 iconSpeed;\n    u32 commentAddr;\n\n    // read-only (Set by CARDGetStatus)\n    u32 offsetBanner;\n    u32 offsetBannerTlut;\n    u32 offsetIcon[CARD_ICON_MAX];\n    u32 offsetIconTlut;\n    u32 offsetData;\n};\nstruct CARDFileInfo\n{\n    s32 chan;\n    s32 fileNo;\n\n    s32 offset;\n    s32 length;\n    u16 iBlock;\n    u16 __padding;\n};\nstruct RGB565\n{\n    unsigned short r : 5;\n    unsigned short g : 6;\n    unsigned short b : 5;\n};\n\n/*** Static Vars ***/\nOSInfo *os_info = 0x80000000;\n\n/*** OS Library ***/\nint OSGetTick();\nu64 OSGetTime();\nvoid OSTicksToCalendarTime(u64 time, OSCalendarTime *td);\nvoid OSReport(char *, ...);\nvoid __assert(char *file, int line, char *assert);\nint OSCheckHeap(int heap);\nint OSGetConsoleType();\nvoid memcpy(void *dest, void *source, int size);\nvoid memset(void *dest, int fill, int size);\ns32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat *stat);\ns32 CARDMountAsync(s32 chan, void *workArea, void *detachCallback, void *attachCallback);\ns32 CARDUnmount(s32 chan);\ns32 CARDOpen(s32 chan, char *fileName, CARDFileInfo *fileInfo);\ns32 CARDClose(CARDFileInfo *fileInfo);\ns32 CARDProbeEx(s32 chan, s32 *memSize, s32 *sectorSize);\ns32 CARDCheckAsync(s32 chan, void *callback);\ns32 CARDFreeBlocks(s32 chan, s32 *byteNotUsed, s32 *filesNotUsed);\ns32 CARDDeleteAsync(s32 chan, char *fileName, void *callback);\ns32 CARDCreateAsync(s32 chan, char *fileName, u32 size, CARDFileInfo *fileInfo, void *callback);\ns32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat *stat, void *callback);\ns32 CARDRead(CARDFileInfo *fileInfo, void *buf, s32 length, s32 offset);\n\nvoid GXPixModeSync();\nvoid GXInvalidateTexAll();\nvoid DCFlushRange(void *startAddr, u32 nBytes);\nvoid TRK_FlushCache(void *startAddr, u32 nBytes);\nint memcmp(void *buf1, void *buf2, u32 nBytes);\nint GXGetTexBufferSize(u16 width, u16 height, u32 format, int mipmap, u8 max_lod);\nvoid GXSetDrawDone();\nvoid GXWaitDrawDone();\nvoid blr();\nvoid blr2();\n\n/*** HSD Library ***/\nint HSD_GetHeapID();\nvoid HSD_SetHeapID(int heap);\n\n/** String Library **/\n#define vsprintf(buffer, format, args) _vsprintf(buffer, -1, format, args)\n\nint sprintf(char *s, const char *format, ...);\nint _vsprintf(char *str, int unk, const char *format, va_list arg);\nint strlen(char *str);\nchar *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.\nint strcmp(char *str1, char *str2);\nint strncmp(char *str1, char *str2, int size);\nchar *strcpy(char *dest, char *src);            // copies the string pointed to, by src to dest.\nchar *strncpy(char *dest, char *src, int size); // copies the string pointed to, by src to dest.\nunsigned long int strtoul(const char *str, char **endptr, int base);\nchar *strcat(s, append) register char *s;\nregister const char *append;\n{\n    char *save = s;\n\n    for (; *s; ++s)\n        ;\n    while (*s++ = *append++)\n        ;\n    return (save);\n}\n\nvoid SFX_Play(int sfxID);\nvoid SFX_PlayRaw(int sfx, int volume, int pan, int unk, int unk2);\nvoid SFX_PlayCommon(int sfxID);\nvoid SFX_PlayCrowd(int sfxID);\nvoid SFX_StopCrowd();\nvoid SFX_StopAllFighterSFX(FighterData *fighter_data);\nvoid Music_Play(int hpsID);\nvoid BGM_Play(int hpsID);\n\nvoid DevelopMode_ResetCursorXY(DevText *text, int x, int y);\nvoid Develop_UpdateMatchHotkeys();\n\nvoid Wind_Create(Vec3 *pos, int radius, float x, float y, float z);\nvoid Wind_StageCreate(Vec3 *pos, int duration, float radius, float lifetime, float angle);\nvoid Wind_FighterCreate(Vec3 *pos, int duration, float radius, float lifetime, float angle);\n\nint Pause_CheckStatus(int type);\n#endif\n"
  },
  {
    "path": "MexTK/itFunction.txt",
    "content": "item_state_table\nonspawn\nondestroy\nonpickup\nondrop\nonthrow\nongivedamage\nontakedamage\nonenterair\nonreflect\nonunk1\nonunk2\nonhitshieldbounce\nonhitshielddeterminedestroy\nonunk3\n"
  },
  {
    "path": "MexTK/kbFunction.txt",
    "content": "onkirbyswallow\nonkirbyloseability\nkirbyspecialn\nkirbyspecialairn\nonkirbyhurt\ninitcopyitems\nmove_logic"
  },
  {
    "path": "MexTK/melee.link",
    "content": "80016c64:File_LoadInitReturnSymbol\n80380358:File_GetSymbol\n80041c8c:Coll_ECBCurrToPrev\n80041ee4:Coll_InitECB\n80048160:Coll_CheckLedge\n8004b21c:ECB_CollGround_PassLedge\n800475f4:ECB_CollAir\n801677f8:CSS_GetNametagRumble\n8016795c:CSS_InitPlayerData\n8022ba1c:CSS_CameraRotateThink\n80302834:DevelopText_CreateDataTable\n80302810:DevelopText_Activate\n80302d4c:DevelopText_AddString\n80302bb0:DevelopText_EraseAllText\n80302b90:DevelopText_StoreBGColor\n80302b00:DevelopText_HideText\n80302ae0:DevelopText_HideBG\n80302b10:DevelopText_StoreTextScale\n80008fc8:Develop_DrawSphere\n8005fddc:Effect_SpawnSync\n800676f0:Effect_SpawnAsync\n8009f834:Effect_SpawnFtEffectLookup\n80278800:Effect_SpawnItEffectLookup\n802787b4:Effect_SpawnItEffect\n8005b880:Effect_DestroyAll\n8039d5dc:Particle_DestroyAll\n803a4344:psRemoveParticleAppSRT\n8039d048:psDeletePntJObjwithParticle\n8039d3ac:psKillGenerator\n8005ba40:Effect_PauseAll\n8005bac4:Effect_ResumeAll\n800693ac:ActionStateChange\n8006eba4:Subaction_Update\n8006e7b8:Fighter_UpdateBonePos\n80085e50:Animation_GetAddress\n80085fd4:Fighter_GetSubactionHeader\n8001e8f8:Animation_GetLength\n800957f4:Fighter_EnterLightThrow\n80090780:Fighter_EnterDamageFall\n8008a2bc:Fighter_EnterWait\n800cc730:Fighter_EnterFall\n80096900:Fighter_EnterSpecialFall\n80082b1c:Fighter_EnterLanding\n800d5cb0:Fighter_EnterSpecialLanding\n800d4f24:Fighter_EnterSleep\n8009a804:Fighter_EnterCliffWait\n800d4ff4:Fighter_EnterRebirth\n800d5600:Fighter_EnterRebirthWait\n800d54a4:Fighter_UpdateRebirthPlatformPos\n80034110:Fighter_GetGObj\n8003418c:Fighter_GetSubcharGObj\n80031724:Fighter_GetPlayerblock\n80036244:Fighter_GetStaleMoveTable\n8007b760:Fighter_ApplyIntang\n8003241c:Fighter_GetSlotType\n80033bd8:Fighter_GetStocks\n80034e8c:Fighter_SetFallNum\n8007d5bc:Fighter_EnableECBBottomUpdate\n8008dce0:Fighter_EnterDamageState\n8007500c:Fighter_BoneLookup\n8006cc7c:Fighter_GiveDamage\n8006cf5c:Fighter_GiveHeal\n80034330:Fighter_SetHUDDamage\n80032828:Fighter_SetPosition\n8007db58:Fighter_RunOnHitCallbacks\n80033c60:Fighter_SetStocks\n8006f238:FrameTimerCheck\n8009a184:Fighter_EnterMiscPassState\n80082708:Fighter_CollGround_PassLedge\n80084104:Fighter_CollGround_StopLedge\n800831cc:Fighter_CollAir_GrabLedgeWalljump\n800822a4:Fighter_CollAir_GrabLedge\n80082c74:Fighter_CollAir_IgnoreLedge\n80081d0c:Fighter_CollAir_IgnoreLedge_NoCB\n80081298:Fighter_IASACheck_CliffCatch\n800cb870:Fighter_IASACheck_JumpAerial\n800caed0:Fighter_IASACheck_JumpF\n80099f1c:Fighter_IASACheck_PassConditions\n800c97a8:Fighter_IASACheck_Turn\n80084f3c:Fighter_PhysGround_ApplyFriction\n8007d494:Fighter_PhysAir_ApplyGravity\n8007cf58:Fighter_PhysAir_LimitVelocity\n80085134:Fighter_Phys_UseAnimPos\n80085154:Fighter_Phys_UseAnimPosAndStick\n8007d7fc:Fighter_SetGrounded2\n8007d5d4:Fighter_SetAirborne\n8007d5d4:Fighter_LoseGroundJump\n8007d5bc:Fighter_EnableCollUpdate\n8007e2fc:Fighter_KillAllVelocity\n8006eba4:Fighter_AdvanceScript\n8007db24:Fighter_GFXRemoveAll\n8007aef8:Fighter_EnableReflectUpdate\n8007b23c:Fighter_CreateReflect\n80075f48:Fighter_GetBoneRotation\n80075af0:Fighter_RotateBone_Pitch\n8007592c:Fighter_RotateBone_Yaw\n80075cb4:Fighter_RotateBone_Roll\n800881d8:Fighter_PlayVoiceSFX\n800bffd0:Fighter_ApplyOverlay\n800c0408:Fighter_UpdateOverlay\n8008a6d8:Fighter_DisableBlend\n8009e7b4:Fighter_UpdateDynamics\n800b4a78:Fighter_ZeroCPUInputs\n800921dc:Fighter_CreateShieldGFX\n80091e78:Fighter_UpdateShieldGFX\n80036538:Fighter_GetShieldColorIndex\n8007f694:Fighter_GetBaseScale\n800866a4:Fighter_SetScale\n8009cf84:Fighter_InitDynamics\n8009e0a8:Fighter_ProcDynamics\n80074148:Fighter_InitPObj\n80074170:Fighter_InitPObj2\n80075650:Fighter_IndexFtPartsDObjs\n8007487c:Fighter_InitFtPartsModel\n8007d6a4:Fighter_SetGrounded\n80081544:Fighter_MoveToCliff\n80086a8c:Fighter_UpdateOnscreenBool\n80380580:HSD_Randi\n80380528:HSD_Randf\n8037f1e4:HSD_MemAlloc\n8037f1b0:HSD_Free\n8037abc8:HSD_ObjAlloc\n8037ad20:HSD_ObjFree\n8026ab54:Item_Hold\n80094818:Item_Catch\n8026B3F8:Items_StoreItemDataToCharItemTable\n8026B3F8:Items_StoreItemDataToCharItemTable2\n80275158:Items_StoreTimeout\n8026862c:Item_CreateItem\n80268b18:Item_CreateItem1\n80268b5c:Item_CreateItem2\n80268b9c:Item_CreateItem3\n8026a8ec:Item_Destroy\n8026d62c:Item_CollGround_PassLedge\n8026d8a4:Item_CollGround_StopLedge\n8026e15c:Item_CollAir\n80268e5c:ItemStateChange\n80272c6c:ItemFrameTimer\n80276174:Item_PlaceOnGroundBelow\n80276348:Item_CheckIfTouchingWall\n80274f28:Item_InitGrab\n8027146c:Item_ResetAllHitPlayers\n8026b3c0:Item_CountActiveItems\n80225dd8:Item_CopyDevelopState\n80273130:Items_DecLife\n8026eecc:GXLink_Item\n80274658:Item_UpdateSpin\n802762bc:Item_EnableSpin\n802762b0:Item_DisableSpin\n80275158:Item_SetLifeTimer\n80273130:Item_DecLifeTimer\n80272cc0:Item_GetBoneJOBJ\n80266f3c:Item_CheckIfEnabled\n80029020:CameraBox_Alloc\n800290d4:CameraBox_Destroy\n802fa5bc:KOCount_Init\n802fa2d0:KOCount_Update\n801c39c0:Stage_CameraLimitInitialization\n801c3bb4:Stage_BlastzoneInitialization\n8016b33c:Match_SetEndGraphic\n8016b328:Match_EndImmediate\n8016c7f0:Match_EndVS\n8002063c:Match_FadeScreen\n8016b168:Match_CheckIfTeams\n8016b094:Match_CheckIfStock\n8016b364:Match_SetPostMatchSFX\n801a4634:Match_FreezeGame\n801a4674:Match_UnfreezeGame\n802f6e1c:Match_CreateHUD\n802f3394:Match_HideHUD\n802f33cc:Match_ShowHUD\n8002f3ac:Match_CorrectCamera\n801650e8:Match_SetNormalCamera\n801652b0:Match_SetFreeCamera\n80165190:Match_SetZoomCamera\n80165290:Match_SetFixedCamera\n8003006c:Match_SetDevelopCamera\n802279e8:DevCam_AdjustRotate\n80227fe0:DevCam_AdjustPan\n80227cac:DevCam_AdjustZoom\n80021c48:ScreenFlash_Create\n80030e44:ScreenRumble_Execute\n801c10b8:Match_StoreGoCallback\n80022e68:atan\n80022c30:atan2\n803263d4:sin\n80326240:cos\n80342734:MTXLookAt\n80342db8:VECNormalize\n80342d54:VECAdd\n80342d78:VECSubtract\n8000dc6c:VECMultAndAdd\n80342e38:VECDotProduct\n80342e58:VECCrossProduct\n80342690:MTXQuat\n80379c24:HSD_MtxGetRotation\n8037e708:MatToQuat\n8000d5bc:sqrtf\n80342418:MTXRotRad\n803d7058:MEX_IndexFighterItem\n803d7060:SpawnMEXEffect\n803d7064:MEX_GetItemExtID\n803d7088:MEX_GetFtItemID\n803d708C:MEX_GetGrItemID\n803d7078:SFX_PlayStageSFX\n803d706C:calloc\n804DD84C:PRIM_NEW\n804DD848:PRIM_CLOSE\n803d707C:MEX_GetPlaylist\n803d7064:MEX_GetStageItemExtID\n803d7080:KirbyStateChange\n803d7084:MEX_GetKirbyCpData\n803d7088:MEX_GetCopyItemExtID\n803d7094:MEX_GetData\n8000b1cc:JOBJ_GetWorldPosition\n803732e8:JOBJ_SetMtxDirtySub\n80370e44:JOBJ_LoadJoint\n80371590:JOBJ_RemoveAll\n80371370:JOBJ_Remove\n80011e24:JOBJ_GetChild\n803717a8:JOBJ_AddChild\n8022f298:JOBJ_GetCurrentMatAnimFrame\n80371d00:JOBJ_SetFlags\n80371d9c:JOBJ_SetFlagsAll\n80371f00:JOBJ_ClearFlags\n80371f9c:JOBJ_ClearFlagsAll\n803740e8:JOBJ_BillBoard\n80364c08:JOBJ_RunAOBJCallback\n80370780:JOBJ_Anim\n80370928:JOBJ_AnimAll\n8036fb5c:JOBJ_AddAnimAll\n8036f6b4:JOBJ_RemoveAnimAll\n8036f934:JOBJ_ReqAnim\n8036f718:JOBJ_ReqAnimByFlags\n8036f8bc:JOBJ_ReqAnimAll\n8036f7b0:JOBJ_ReqAnimAllByFlags\n8000be40:JOBJ_GetJointAnimFrameTotal\n8000bdb4:JOBJ_GetJointAnimNextFrame\n801c8858:JOBJ_SetAllMOBJFlags\n8036410c:AOBJ_ReqAnim\n8036414c:AOBJ_StopAnim\n8036530c:AOBJ_SetRate\n8000b09c:JOBJ_CheckAObjEnd\n8035ddb8:DOBJ_SetFlags\n8035ddd0:DOBJ_ClearFlags\n8036a590:COBJ_LoadDesc\n80030a50:COBJ_GetMatchCamera\n803910d8:CObjThink_Common\n803901f0:GObj_Create\n80390228:GObj_Destroy\n8039069c:GObj_AddGXLink\n8039084c:GObj_DestroyGXLink\n8039063c:GObj_GXReorder\n8038fd54:GObj_AddProc\n8038fed4:GObj_RemoveProc\n80390a70:GObj_AddObject\n80390b0c:GObj_FreeObject\n80390b68:GObj_AddUserData\n8039075c:GOBJ_InitCamera\n80391070:GXLink_Common\n80391044:GXLink_LObj\n8026407c:GXLink_Fog\n803672dc:LObj_LoadDesc\n8037dc38:Fog_LoadDesc\n80018254:Preload_Update\n8001822c:Preload_GetTable\n801a42f8:Scene_EnterMajor\n801a5680:CSS_DecideNext\n801a55c4:CSS_ResetKOStars\n80167b50:CSS_InitMajorData\n801a5618:CSS_InitMinorData\n801a5754:SSS_InitMinorData\n801a583c:Match_InitMinorData\n8016f088:Match_SetNametags\n801c6324:Stage_GetStageFiles\n801c6330:Stage_GetStageFile\n800c07f8:Stage_AddFtChkDevice\n801c438c:Stage_SetChkDevicePos\n801c4368:Stage_GetChkDevicePos\n801c0498:Stage_GetScale\n801c49f8:Stage_GetYakumonoParam\n801c8138:Stage_MapStateChange\n800115f4:Dynamics_DecayWind\n80223908:Stage_CreateMapGObj\n801c4a08:Stage_DestroyMapGObj\n801c5db0:GXLink_Stage\n801c2ba4:Stage_GetMapGObj\n801c3fa4:Stage_GetMapGObjJObj\n80056b6c:Stage_GetLinesGroup\n80054c6c:Stage_GetLinesDirection\n800580c8:Stage_SetGroundCallback\n800581a4:Stage_SetCeilingCallback\n801c2ed0:Stage_InitMovingColl\n801c2fe0:Stage_UpdateMovingColl\n801c96f8:Stage_SpawnEffectPos\n801c97dc:Stage_SpawnEffectJointPos\n801c9808:Stage_SpawnEffectJointPos2\n8004f008:GrColl_RaycastGround\n80056c54:GrColl_CrawlGround\n800567c0:GrColl_GetPosDifference\n80054dfc:GrColl_GetLineSlope\n80054ed8:GrColl_CheckIfLineEnabled\n8027b5b0:Zako_Create\n802e6aec:Stage_CreateMapItem\n801c9ee8:Stage_CheckForNearbyFighters\n80224b38:Stage_GetBlastzoneRight\n80224b50:Stage_GetBlastzoneLeft\n80224b68:Stage_GetBlastzoneTop\n80224b80:Stage_GetBlastzoneBottom\n80224a68:Stage_GetCameraRight\n80224a54:Stage_GetCameraLeft\n80224a80:Stage_GetCameraTop\n80224a98:Stage_GetCameraBottom\n801c2d24:Stage_GetGeneralPoint\n80057638:Stage_EnableLineGroup\n80057bc0:Stage_DisableLineGroup\n80054158:GrColl_GetLedgeLeft\n80053ff4:GrColl_GetLedgeRight\n80053ecc:GrColl_GetLedgeLeft2\n80053da4:GrColl_GetLedgeRight2\n803a611c:Text_CreateCanvas\n803a6754:Text_CreateText\n803a5cc4:Text_Destroy\n803a6b98:Text_AddSubtext\n803a7548:Text_SetScale\n803a74f0:Text_SetColor\n803a746c:Text_SetPosition\n803a70a0:Text_SetText\n803a67ec:Text_ConvertToMenuText\n803A5798:Text_Alloc\n803a594c:Text_DestroyAlloc\n803a5a2c:Text_DestroyAllAlloc\n803a67ec:Text_StringToMenuText\n803a84bc:Text_GX\n803456A8:OSReport\n800031f4:memcpy\n80003100:memset\n80005358:blr\n8021b2d8:bp\n801c53ec:SFX_Play\n8038cff4:SFX_PlayRaw\n80024030:SFX_PlayCommon\n8002411c:SFX_PlayCrowd\n80321ce8:SFX_StopCrowd\n80088a50:SFX_StopAllFighterSFX\n80023f28:Music_Play\n80023f28:BGM_Play\n80302a3c:DevelopMode_ResetCursorXY\n80225754:Develop_UpdateMatchHotkeys\n800119dc:Wind_Create\n80011a50:Wind_StageCreate\n800119dc:Wind_FighterCreate\n801a45e8:Pause_CheckStatus\n8001c550:Memcard_InitWorkArea\n8001d164:Memcard_LoadAssets\n803b31cc:Memcard_Deobfuscate\n8023754c:Nametag_GetText\n80026f2c:Audio_ResetCache\n8002702c:Audio_QueueFileLoad\n80027168:Audio_UpdateCache\n80027648:Audio_SyncLoadAll\n80016be0:File_Load\n803a62a0:Text_LoadSdFile\n8025f0e0:CSS_MenuModelThink\n802602a0:CSS_CursorThink\n80262648:CSS_PuckThink\n80164840:Fighter_CheckUnlocked\n802633b0:CSS_TagThink\n803a5acc:Text_CreateText2\n803a6368:Text_SetSisText\n8025bd30:CSS_UpdateRulesText\n8025d1c4:CSS_UpdateKOStars\n80262f44:CSS_StartThink\n801685d4:CSS_GetHandicapValue\n8025ee8c:CSS_SetModeTexture\n8015ecb0:BGM_GetMenuBGM\n8015cc34:Memcard_GetRules1\n80371bec:JOBJ_GetDObj\n80363c2c:MOBJ_SetAlpha\n8025fdec:CSS_ReturnPuck\n8025fb50:CSS_SetRandomFighter\n8025db34:CSS_UpdateCSP\n80169238:CSS_GetCostumeNum\n803909d8:GObj_CopyGXPri\n80168c5c:CSS_PlayFighterName\n80260094:CSS_CostumeChange\n8025d5ac:CSS_UpdateCSPTexture\n8003254c:Fighter_SetSlotType\n8003345c:Fighter_GetControllerPort\n80032330:Fighter_GetExternalID\n80033198:Fighter_GetCostumeID\n8008d7f0:Fighter_GetKnockbackAngle\n800761c8:Fighter_UpdateCameraBox\n8007af28:Fighter_SetAllHurtboxesNotUpdated\n800a0da4:Fighter_UpdateHurtboxes\n8006c5f4:Fighter_UpdateIK\n800c0200:Fighter_ColorRemove\n800a101c:Fighter_CPUInitialize\n80033670:Fighter_GetCPUKind\n80033548:Fighter_GetCPULevel\n80160980:Fighter_GetName\n800122c8:HSD_ImageDescCopyFromEFB\n802f40b8:Match_ShowTimer\n802f405c:Match_HideTimer\n80024e84:Match_AdjustSoundOnPause\n802f3424:Match_GetPlayerHUDPos\n80030a50:Match_GetCObj\n8001e218:Memcard_InitSnapshotList\n80253e90:Memcard_UpdateSnapshotList\n8001bb48:Memcard_CreateSnapshot\n8001d5fc:Memcard_DeleteSnapshot\n8001bf04:Memcard_LoadSnapshot\n8001b6f8:Memcard_CheckStatus\n8001a008:Memcard_RemovedCallback\n803d7080:MEX_LoadRelArchive\n80013b14:COBJ_LoadDescSetScissor\n80225194:Stage_GetExternalID\n8022519c:Stage_ExternalToInternal\n8034c408:OSGetTick\n8034c3f0:OSGetTime\n8034c668:OSTicksToCalendarTime\n80388220:__assert\n80344168:OSCheckHeap\n80342e94:OSGetConsoleType\n803585f8:CARDGetStatus\n80356688:CARDMountAsync\n803568c4:CARDUnmount\n80355f94:CARDProbeEx\n80355f34:CARDCheckAsync\n803532d4:CARDFreeBlocks\n803582f0:CARDDeleteAsync\n80000000:CARDCreateAsync\n80358724:CARDSetStatusAsync\n80357e88:CARDRead\n80357534:CARDOpen\n803576ac:CARDClose\n8034480c:DCFlushRange\n80328f50:TRK_FlushCache\n803238c8:memcmp\n8033e78c:GXGetTexBufferSize\n8033cc38:GXSetDrawDone\n8033ccd0:GXWaitDrawDone\n800121fc:GX_AllocImageData\n8033cd1c:GXPixModeSync\n8033f270:GXInvalidateTexAll\n803230a4:blr2\n80375404:HSD_GetHeapID\n8037540c:HSD_SetHeapID\n80323cf4:sprintf\n80323dc8:_vsprintf\n80325b04:strlen\n80325878:strchr\n803258e8:strcmp\n803258a8:strncmp\n80325a50:strcpy\n80325a0c:strncpy\n80325b24:strtoul\n802886c4:Barrel_EnterBreak\n8018f674:Pad_GetRapidHeld\n8022ba1c:MainMenu_CamRotateThink"
  },
  {
    "path": "MexTK/mex.h",
    "content": "#ifndef MEX_H\n#define MEX_H\n\n#include \"include/structs.h\"\n#include \"include/datatypes.h\"\n\n#include \"include/audio.h\"\n#include \"include/archive.h\"\n#include \"include/boneset.h\"\n#include \"include/match.h\"\n#include \"include/collision.h\"\n#include \"include/color.h\"\n#include \"include/css.h\"\n#include \"include/devtext.h\"\n#include \"include/effects.h\"\n#include \"include/fighter.h\"\n#include \"include/hsd.h\"\n#include \"include/inline.h\"\n#include \"include/item.h\"\n#include \"include/kirby.h\"\n#include \"include/math.h\"\n#include \"include/memcard.h\"\n#include \"include/mex.h\"\n#include \"include/obj.h\"\n#include \"include/offsets.h\"\n#include \"include/preload.h\"\n#include \"include/result.h\"\n#include \"include/scene.h\"\n#include \"include/stage.h\"\n#include \"include/text.h\"\n#include \"include/useful.h\"\n\n#endif"
  },
  {
    "path": "MexTK/mjFunction.txt",
    "content": "minor_scene\nmajor_load\nmajor_unload\ncss_load\nsss_load"
  },
  {
    "path": "MexTK/mnFunction.txt",
    "content": "minor_think\nminor_load\nminor_unload\n"
  },
  {
    "path": "MexTK/tmFunction.txt",
    "content": "eventPages\nGetEventName\nGetEventDescription\nGetEventTut\nGetPageName\nGetPageEventNum\nGetTMVersShort\nGetTMVersLong\nGetTMCompile\nGetPageNum\nGetIsChooseCPU\nGetIsSelectStage\nGetFighter\nGetCPUFighter\nGetStage\nGetEventFile\nGetCSSFile\nEventInit\nOnSceneChange\nOnBoot\nOnStartMelee\nOnFileLoad\nMessage_Display\nGetEventDesc"
  },
  {
    "path": "patch/events/lab/build.bat",
    "content": "xcopy /s /y \"assets\\labData.dat\" \"output/EvLab.dat\"\n\"../../../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\n\"../../../MexTK/MexTK.exe\" -trim \"output/EvLab.dat\"\n\nxcopy /s /y \"assets\\importData.dat\" \"output/EvLabCSS.dat\"\n\"../../../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\n\"../../../MexTK/MexTK.exe\" -trim \"output/EvLabCSS.dat\"\npause"
  },
  {
    "path": "patch/events/lab/notes.txt",
    "content": "Free Practice\n\nMenu\n-General Settings\n    -Player Percent (int option)\n    -CPU  Percent (int option)\n    -Move Staling\n    -Frame Advance (uses L like ultimate)\n    -Model Display\n        -On\n        -Off\n    -Fighter Collision Display\n        -Off\n        -On\n    -Environment Collision Display\n        -Off\n        -On\n    -DI Display\n        -Off\n        -On\n    -Input Display\n    -Info Display\n        -Toggle (On/Off)\n        -Player\n        -Row 1 \n            -None\n            -Position\n            -State Name\n            -Velocity - Self\n            -Velocity - Knockback\n            -Velocity - Animation\n            -Engine LStick Values\n            -System LStick Values\n            -Engine RStick Values\n            -System RStick Values\n            -Engine Trigger Value\n            -System Trigger Value\n            -Ledgegrab Cooldown\n            -Intangibility Remaining\n            -Hitlag Remaining\n            -Hitstun Remaining\n            -Shield Health\n            -Shield Stun Remaining\n            -Grab Timer\n            -ECB Lock Timer\n            -ECB Bottom offset\n            -Jumps Used\n            -Walljumps Used\n            -Jab Counter\n            -Blastzone Left/Right\n            -Blastzone Up/Down\n        -Row 2\n        -Row 3\n        -Row 4\n        -Row 5\n        -Row 6\n        -Row 7\n        -Row 8\n-CPU Settings\n    -CPU Intangibility\n    -Infinite Shields\n        -Off\n        -On Until Hit\n        -On\n    -Default Behavior\n        -Stand\n        -Shield\n        -Crouch\n        -Jump\n    -Directional Influence\n        -Random\n        -Survival\n        -Combo\n        -Floorhug\n        -None\n    -Tech\n        -Random\n        -Neutral Tech\n        -Tech Away\n        -Tech Towards\n        -None\n    -Reset After Actionable\n        -Off\n        -On\n    -Counter Action (ground)\n        -None\n        -Shield\n        -Grab\n        -Up B\n        -Down B\n        -Spotdodge\n        -Roll Away\n        -Roll Towards\n        -Nair\n        -Fair\n        -Dair\n        -Bair\n        -Uair\n        -Jump\n    -Counter Action (air)\n        -Airdodge\n        -Jump Away\n        -Jump Towards\n        -Nair\n        -Fair\n        -Dair\n        -Bair\n        -Uair\n        -Up B\n        -Down B\n        -Fastfall\n        -Wiggle\n        -Wiggle Fastfall\n    -Counter After Hits (int option)\n    -Counter After Frames (int option)\n-Replay Settings\n    -Record Slot\n        -Random\n        -Slot 1\n        -Slot 2\n        -Slot 3\n    -Mode\n        -Playback\n        -Record\n    -Reset After Playback\n        -Off\n        -On\n-Help\n-Exit"
  },
  {
    "path": "patch/events/lab/source/lab.c",
    "content": "#include \"lab.h\"\nstatic char nullString[] = \" \";\n\n// CPU Action Definitions\nstatic CPUAction Lab_CPUActionShield[] = {\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_TRIGGER_R,         // button to input\n        1,                     // is the last input\n        0,                     // specify stick direction\n    },\n    {\n        ASID_GUARDREFLECT, // state to perform this action. -1 for last\n        0,                 // first possible frame to perform this action\n        0,                 // last possible frame to perfrom this action\n        0,                 // left stick X value\n        0,                 // left stick Y value\n        0,                 // c stick X value\n        0,                 // c stick Y value\n        PAD_TRIGGER_R,     // button to input\n        1,                 // is the last input\n        0,                 // specify stick direction\n    },\n    {\n        ASID_GUARD,    // state to perform this action. -1 for last\n        0,             // first possible frame to perform this action\n        0,             // last possible frame to perfrom this action\n        0,             // left stick X value\n        0,             // left stick Y value\n        0,             // c stick X value\n        0,             // c stick Y value\n        PAD_TRIGGER_R, // button to input\n        1,             // is the last input\n        0,             // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionGrab[] = {\n    {\n        ASID_GUARD,                   // state to perform this action. -1 for last\n        0,                            // first possible frame to perform this action\n        0,                            // last possible frame to perfrom this action\n        0,                            // left stick X value\n        0,                            // left stick Y value\n        0,                            // c stick X value\n        0,                            // c stick Y value\n        PAD_BUTTON_A | PAD_TRIGGER_R, // button to input\n        1,                            // is the last input\n        0,                            // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_TRIGGER_Z,         // button to input\n        1,                     // is the last input\n        0,                     // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionUpB[] = {\n    {\n        ASID_GUARD,                   // state to perform this action. -1 for last\n        0,                            // first possible frame to perform this action\n        0,                            // last possible frame to perfrom this action\n        0,                            // left stick X value\n        0,                            // left stick Y value\n        0,                            // c stick X value\n        0,                            // c stick Y value\n        PAD_TRIGGER_R | PAD_BUTTON_X, // button to input\n        0,                            // is the last input\n        0,                            // specify stick direction\n    },\n    {\n        ASID_GUARD,   // state to perform this action. -1 for last\n        0,            // first possible frame to perform this action\n        0,            // last possible frame to perfrom this action\n        0,            // left stick X value\n        0,            // left stick Y value\n        0,            // c stick X value\n        0,            // c stick Y value\n        PAD_BUTTON_X, // button to input\n        0,            // is the last input\n        0,            // specify stick direction\n    },\n    {\n        ASID_KNEEBEND, // state to perform this action. -1 for last\n        0,             // first possible frame to perform this action\n        0,             // last possible frame to perfrom this action\n        0,             // left stick X value\n        127,           // left stick Y value\n        0,             // c stick X value\n        0,             // c stick Y value\n        PAD_BUTTON_B,  // button to input\n        1,             // is the last input\n        0,             // specify stick direction\n    },\n    {\n        ASID_ACTIONABLE, // state to perform this action. -1 for last\n        0,               // first possible frame to perform this action\n        0,               // last possible frame to perfrom this action\n        0,               // left stick X value\n        127,             // left stick Y value\n        0,               // c stick X value\n        0,               // c stick Y value\n        PAD_BUTTON_B,    // button to input\n        1,               // is the last input\n        0,               // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionDownB[] = {\n    {\n        ASID_GUARD,                   // state to perform this action. -1 for last\n        0,                            // first possible frame to perform this action\n        0,                            // last possible frame to perfrom this action\n        0,                            // left stick X value\n        0,                            // left stick Y value\n        0,                            // c stick X value\n        0,                            // c stick Y value\n        PAD_TRIGGER_R | PAD_BUTTON_X, // button to input\n        0,                            // is the last input\n        0,                            // specify stick direction\n    },\n    {\n        ASID_GUARD,   // state to perform this action. -1 for last\n        0,            // first possible frame to perform this action\n        0,            // last possible frame to perfrom this action\n        0,            // left stick X value\n        0,            // left stick Y value\n        0,            // c stick X value\n        0,            // c stick Y value\n        PAD_BUTTON_X, // button to input\n        1,            // is the last input\n        0,            // specify stick direction\n    },\n    {\n        ASID_ACTIONABLE, // state to perform this action. -1 for last\n        0,               // first possible frame to perform this action\n        0,               // last possible frame to perfrom this action\n        0,               // left stick X value\n        -127,            // left stick Y value\n        0,               // c stick X value\n        0,               // c stick Y value\n        PAD_BUTTON_B,    // button to input\n        1,               // is the last input\n        0,               // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionSpotdodge[] = {\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        -127,                  // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_TRIGGER_R,         // button to input\n        1,                     // is the last input\n        0,                     // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionRollAway[] = {\n    {\n        ASID_GUARD,    // state to perform this action. -1 for last\n        0,             // first possible frame to perform this action\n        0,             // last possible frame to perfrom this action\n        127,           // left stick X value\n        0,             // left stick Y value\n        0,             // c stick X value\n        0,             // c stick Y value\n        PAD_TRIGGER_R, // button to input\n        1,             // is the last input\n        STCKDIR_AWAY,  // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_TRIGGER_R,         // button to input\n        0,                     // is the last input\n        0,                     // specify stick direction\n    },\n    {\n        ASID_GUARDREFLECT, // state to perform this action. -1 for last\n        0,                 // first possible frame to perform this action\n        0,                 // last possible frame to perfrom this action\n        127,               // left stick X value\n        0,                 // left stick Y value\n        0,                 // c stick X value\n        0,                 // c stick Y value\n        PAD_TRIGGER_R,     // button to input\n        1,                 // is the last input\n        STCKDIR_AWAY,      // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionRollTowards[] = {\n    {\n        ASID_GUARD,     // state to perform this action. -1 for last\n        0,              // first possible frame to perform this action\n        0,              // last possible frame to perfrom this action\n        127,            // left stick X value\n        0,              // left stick Y value\n        0,              // c stick X value\n        0,              // c stick Y value\n        PAD_TRIGGER_R,  // button to input\n        1,              // is the last input\n        STCKDIR_TOWARD, // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_TRIGGER_R,         // button to input\n        0,                     // is the last input\n        0,                     // specify stick direction\n    },\n    {\n        ASID_GUARDREFLECT, // state to perform this action. -1 for last\n        0,                 // first possible frame to perform this action\n        0,                 // last possible frame to perfrom this action\n        127,               // left stick X value\n        0,                 // left stick Y value\n        0,                 // c stick X value\n        0,                 // c stick Y value\n        PAD_TRIGGER_R,     // button to input\n        1,                 // is the last input\n        STCKDIR_TOWARD,    // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionRollRandom[] = {\n    {\n        ASID_GUARD,    // state to perform this action. -1 for last\n        0,             // first possible frame to perform this action\n        0,             // last possible frame to perfrom this action\n        127,           // left stick X value\n        0,             // left stick Y value\n        0,             // c stick X value\n        0,             // c stick Y value\n        PAD_TRIGGER_R, // button to input\n        1,             // is the last input\n        STICKDIR_RDM,  // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_TRIGGER_R,         // button to input\n        0,                     // is the last input\n        0,                     // specify stick direction\n    },\n    {\n        ASID_GUARDREFLECT, // state to perform this action. -1 for last\n        0,                 // first possible frame to perform this action\n        0,                 // last possible frame to perfrom this action\n        127,               // left stick X value\n        0,                 // left stick Y value\n        0,                 // c stick X value\n        0,                 // c stick Y value\n        PAD_TRIGGER_R,     // button to input\n        1,                 // is the last input\n        STICKDIR_RDM,      // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionNair[] = {\n    {\n        ASID_GUARD,                   // state to perform this action. -1 for last\n        0,                            // first possible frame to perform this action\n        0,                            // last possible frame to perfrom this action\n        0,                            // left stick X value\n        0,                            // left stick Y value\n        0,                            // c stick X value\n        0,                            // c stick Y value\n        PAD_TRIGGER_R | PAD_BUTTON_X, // button to input\n        0,                            // is the last input\n        0,                            // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_BUTTON_X,          // button to input\n        0,                     // is the last input\n        0,                     // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEAIR, // state to perform this action. -1 for last\n        0,                  // first possible frame to perform this action\n        0,                  // last possible frame to perfrom this action\n        0,                  // left stick X value\n        0,                  // left stick Y value\n        0,                  // c stick X value\n        0,                  // c stick Y value\n        PAD_BUTTON_A,       // button to input\n        1,                  // is the last input\n        0,                  // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionFair[] = {\n    {\n        ASID_GUARD,                   // state to perform this action. -1 for last\n        0,                            // first possible frame to perform this action\n        0,                            // last possible frame to perfrom this action\n        0,                            // left stick X value\n        0,                            // left stick Y value\n        0,                            // c stick X value\n        0,                            // c stick Y value\n        PAD_TRIGGER_R | PAD_BUTTON_X, // button to input\n        0,                            // is the last input\n        0,                            // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_BUTTON_X,          // button to input\n        0,                     // is the last input\n        0,                     // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEAIR, // state to perform this action. -1 for last\n        0,                  // first possible frame to perform this action\n        0,                  // last possible frame to perfrom this action\n        0,                  // left stick X value\n        0,                  // left stick Y value\n        127,                // c stick X value\n        0,                  // c stick Y value\n        0,                  // button to input\n        1,                  // is the last input\n        3,                  // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionDair[] = {\n    {\n        ASID_GUARD,                   // state to perform this action. -1 for last\n        0,                            // first possible frame to perform this action\n        0,                            // last possible frame to perfrom this action\n        0,                            // left stick X value\n        0,                            // left stick Y value\n        0,                            // c stick X value\n        0,                            // c stick Y value\n        PAD_TRIGGER_R | PAD_BUTTON_X, // button to input\n        0,                            // is the last input\n        0,                            // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_BUTTON_X,          // button to input\n        0,                     // is the last input\n        0,                     // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEAIR, // state to perform this action. -1 for last\n        0,                  // first possible frame to perform this action\n        0,                  // last possible frame to perfrom this action\n        0,                  // left stick X value\n        0,                  // left stick Y value\n        0,                  // c stick X value\n        -127,               // c stick Y value\n        0,                  // button to input\n        1,                  // is the last input\n        0,                  // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionBair[] = {\n    {\n        ASID_GUARD,                   // state to perform this action. -1 for last\n        0,                            // first possible frame to perform this action\n        0,                            // last possible frame to perfrom this action\n        0,                            // left stick X value\n        0,                            // left stick Y value\n        0,                            // c stick X value\n        0,                            // c stick Y value\n        PAD_TRIGGER_R | PAD_BUTTON_X, // button to input\n        0,                            // is the last input\n        0,                            // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_BUTTON_X,          // button to input\n        0,                     // is the last input\n        0,                     // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEAIR, // state to perform this action. -1 for last\n        0,                  // first possible frame to perform this action\n        0,                  // last possible frame to perfrom this action\n        0,                  // left stick X value\n        0,                  // left stick Y value\n        127,                // c stick X value\n        0,                  // c stick Y value\n        0,                  // button to input\n        1,                  // is the last input\n        4,                  // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionUair[] = {\n    {\n        ASID_GUARD,                   // state to perform this action. -1 for last\n        0,                            // first possible frame to perform this action\n        0,                            // last possible frame to perfrom this action\n        0,                            // left stick X value\n        0,                            // left stick Y value\n        0,                            // c stick X value\n        0,                            // c stick Y value\n        PAD_TRIGGER_R | PAD_BUTTON_X, // button to input\n        0,                            // is the last input\n        0,                            // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_BUTTON_X,          // button to input\n        0,                     // is the last input\n        0,                     // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEAIR, // state to perform this action. -1 for last\n        0,                  // first possible frame to perform this action\n        0,                  // last possible frame to perfrom this action\n        0,                  // left stick X value\n        0,                  // left stick Y value\n        0,                  // c stick X value\n        127,                // c stick Y value\n        0,                  // button to input\n        1,                  // is the last input\n        0,                  // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionJump[] = {\n    {\n        ASID_GUARD,                   // state to perform this action. -1 for last\n        0,                            // first possible frame to perform this action\n        0,                            // last possible frame to perfrom this action\n        0,                            // left stick X value\n        0,                            // left stick Y value\n        0,                            // c stick X value\n        0,                            // c stick Y value\n        PAD_TRIGGER_R | PAD_BUTTON_X, // button to input\n        0,                            // is the last input\n        0,                            // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_BUTTON_X,          // button to input\n        1,                     // is the last input\n        0,                     // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEAIR, // state to perform this action. -1 for last\n        0,                  // first possible frame to perform this action\n        0,                  // last possible frame to perfrom this action\n        0,                  // left stick X value\n        0,                  // left stick Y value\n        0,                  // c stick X value\n        0,                  // c stick Y value\n        0,                  // button to input\n        1,                  // is the last input\n        0,                  // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionJumpFull[] = {\n    {\n        ASID_GUARD,                   // state to perform this action. -1 for last\n        0,                            // first possible frame to perform this action\n        0,                            // last possible frame to perfrom this action\n        0,                            // left stick X value\n        0,                            // left stick Y value\n        0,                            // c stick X value\n        0,                            // c stick Y value\n        PAD_TRIGGER_R | PAD_BUTTON_X, // button to input\n        0,                            // is the last input\n        0,                            // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_BUTTON_X,          // button to input\n        0,                     // is the last input\n        0,                     // specify stick direction\n    },\n    {\n        ASID_KNEEBEND, // state to perform this action. -1 for last\n        0,             // first possible frame to perform this action\n        0,             // last possible frame to perfrom this action\n        0,             // left stick X value\n        0,             // left stick Y value\n        0,             // c stick X value\n        0,             // c stick Y value\n        PAD_BUTTON_X,  // button to input\n        0,             // is the last input\n        0,             // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEAIR, // state to perform this action. -1 for last\n        0,                  // first possible frame to perform this action\n        0,                  // last possible frame to perfrom this action\n        0,                  // left stick X value\n        0,                  // left stick Y value\n        0,                  // c stick X value\n        0,                  // c stick Y value\n        0,                  // button to input\n        1,                  // is the last input\n        0,                  // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionJumpAway[] = {\n    {\n        ASID_JUMPS, // state to perform this action. -1 for last\n        0,          // first possible frame to perform this action\n        0,          // last possible frame to perfrom this action\n        127,        // left stick X value\n        0,          // left stick Y value\n        0,          // c stick X value\n        0,          // c stick Y value\n        0,          // button to input\n        0,          // is the last input\n        2,          // specify stick direction\n    },\n    {\n        ASID_ACTIONABLE, // state to perform this action. -1 for last\n        0,               // first possible frame to perform this action\n        0,               // last possible frame to perfrom this action\n        127,             // left stick X value\n        0,               // left stick Y value\n        0,               // c stick X value\n        0,               // c stick Y value\n        PAD_BUTTON_X,    // button to input\n        0,               // is the last input\n        STCKDIR_AWAY,    // specify stick direction\n    },\n\n    -1,\n};\nstatic CPUAction Lab_CPUActionJumpTowards[] = {\n    {\n        ASID_JUMPS, // state to perform this action. -1 for last\n        0,          // first possible frame to perform this action\n        0,          // last possible frame to perfrom this action\n        127,        // left stick X value\n        0,          // left stick Y value\n        0,          // c stick X value\n        0,          // c stick Y value\n        0,          // button to input\n        0,          // is the last input\n        1,          // specify stick direction\n    },\n    {\n        ASID_ACTIONABLE, // state to perform this action. -1 for last\n        0,               // first possible frame to perform this action\n        0,               // last possible frame to perfrom this action\n        127,             // left stick X value\n        0,               // left stick Y value\n        0,               // c stick X value\n        0,               // c stick Y value\n        PAD_BUTTON_X,    // button to input\n        0,               // is the last input\n        STCKDIR_TOWARD,  // specify stick direction\n    },\n\n    -1,\n};\nstatic CPUAction Lab_CPUActionAirdodge[] = {\n    {\n        ASID_DAMAGEAIR, // state to perform this action. -1 for last\n        0,              // first possible frame to perform this action\n        0,              // last possible frame to perfrom this action\n        127,            // left stick X value\n        0,              // left stick Y value\n        0,              // c stick X value\n        0,              // c stick Y value\n        0,              // button to input\n        0,              // is the last input\n        0,              // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEAIR, // state to perform this action. -1 for last\n        0,                  // first possible frame to perform this action\n        0,                  // last possible frame to perfrom this action\n        0,                  // left stick X value\n        0,                  // left stick Y value\n        0,                  // c stick X value\n        0,                  // c stick Y value\n        PAD_TRIGGER_R,      // button to input\n        1,                  // is the last input\n        0,                  // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionFFTumble[] = {\n    {\n        ASID_DAMAGEAIR, // state to perform this action. -1 for last\n        0,              // first possible frame to perform this action\n        0,              // last possible frame to perfrom this action\n        0,              // left stick X value\n        -127,           // left stick Y value\n        0,              // c stick X value\n        0,              // c stick Y value\n        0,              // button to input\n        1,              // is the last input\n        0,              // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionFFWiggle[] = {\n    {\n        ASID_DAMAGEAIR, // state to perform this action. -1 for last\n        0,              // first possible frame to perform this action\n        0,              // last possible frame to perfrom this action\n        127,            // left stick X value\n        0,              // left stick Y value\n        0,              // c stick X value\n        0,              // c stick Y value\n        0,              // button to input\n        0,              // is the last input\n        0,              // specify stick direction\n    },\n    {\n        ASID_ACTIONABLEAIR, // state to perform this action. -1 for last\n        0,                  // first possible frame to perform this action\n        0,                  // last possible frame to perfrom this action\n        0,                  // left stick X value\n        -127,               // left stick Y value\n        0,                  // c stick X value\n        0,                  // c stick Y value\n        0,                  // button to input\n        1,                  // is the last input\n        0,                  // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionJab[] = {\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_BUTTON_A,          // button to input\n        1,                     // is the last input\n        0,                     // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionFTilt[] = {\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        80,                    // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_BUTTON_A,          // button to input\n        1,                     // is the last input\n        STCKDIR_TOWARD,        // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionUTilt[] = {\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        80,                    // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_BUTTON_A,          // button to input\n        1,                     // is the last input\n        0,                     // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionDTilt[] = {\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        -80,                   // left stick Y value\n        0,                     // c stick X value\n        0,                     // c stick Y value\n        PAD_BUTTON_A,          // button to input\n        1,                     // is the last input\n        0,                     // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionUSmash[] = {\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        127,                   // c stick Y value\n        0,                     // button to input\n        1,                     // is the last input\n        0,                     // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionDSmash[] = {\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        0,                     // c stick X value\n        -127,                  // c stick Y value\n        0,                     // button to input\n        1,                     // is the last input\n        0,                     // specify stick direction\n    },\n    -1,\n};\nstatic CPUAction Lab_CPUActionFSmash[] = {\n    {\n        ASID_ACTIONABLEGROUND, // state to perform this action. -1 for last\n        0,                     // first possible frame to perform this action\n        0,                     // last possible frame to perfrom this action\n        0,                     // left stick X value\n        0,                     // left stick Y value\n        127,                   // c stick X value\n        0,                     // c stick Y value\n        0,                     // button to input\n        1,                     // is the last input\n        STCKDIR_TOWARD,        // specify stick direction\n    },\n    -1,\n};\n\nstatic CPUAction *Lab_CPUActions[] = {\n    // none 0\n    0,\n    // shield 1\n    &Lab_CPUActionShield,\n    // grab 2\n    &Lab_CPUActionGrab,\n    // up b 3\n    &Lab_CPUActionUpB,\n    // down b 4\n    &Lab_CPUActionDownB,\n    // spotdodge 5\n    &Lab_CPUActionSpotdodge,\n    // roll away 6\n    &Lab_CPUActionRollAway,\n    // roll towards 7\n    &Lab_CPUActionRollTowards,\n    // roll random\n    &Lab_CPUActionRollRandom,\n    // nair 8\n    &Lab_CPUActionNair,\n    // fair 9\n    &Lab_CPUActionFair,\n    // dair 10\n    &Lab_CPUActionDair,\n    // bair 11\n    &Lab_CPUActionBair,\n    // uair 12\n    &Lab_CPUActionUair,\n    // short hop 13\n    &Lab_CPUActionJump,\n    // full hop 14\n    &Lab_CPUActionJumpFull,\n    // jump away 15\n    &Lab_CPUActionJumpAway,\n    // jump towards 16\n    &Lab_CPUActionJumpTowards,\n    // airdodge 17\n    &Lab_CPUActionAirdodge,\n    // fastfall 18\n    &Lab_CPUActionFFTumble,\n    // wiggle fastfall 19\n    &Lab_CPUActionFFWiggle,\n    // wiggle fastfall 19\n    &Lab_CPUActionJab,\n    &Lab_CPUActionFTilt,\n    &Lab_CPUActionUTilt,\n    &Lab_CPUActionDTilt,\n    &Lab_CPUActionUSmash,\n    &Lab_CPUActionDSmash,\n    &Lab_CPUActionFSmash,\n};\nenum CPU_ACTIONS\n{\n    CPUACT_NONE,\n    CPUACT_SHIELD,\n    CPUACT_GRAB,\n    CPUACT_UPB,\n    CPUACT_DOWNB,\n    CPUACT_SPOTDODGE,\n    CPUACT_ROLLAWAY,\n    CPUACT_ROLLTOWARDS,\n    CPUACT_ROLLRDM,\n    CPUACT_NAIR,\n    CPUACT_FAIR,\n    CPUACT_DAIR,\n    CPUACT_BAIR,\n    CPUACT_UAIR,\n    CPUACT_SHORTHOP,\n    CPUACT_FULLHOP,\n    CPUACT_JUMPAWAY,\n    CPUACT_JUMPTOWARDS,\n    CPUACT_AIRDODGE,\n    CPUACT_FFTUMBLE,\n    CPUACT_FFWIGGLE,\n    CPUACT_JAB,\n    CPUACT_FTILT,\n    CPUACT_UTILT,\n    CPUACT_DTILT,\n    CPUACT_USMASH,\n    CPUACT_DSMASH,\n    CPUACT_FSMASH,\n};\nstatic char *CPU_ACTIONS_NAMES[] = {\n    \"CPUACT_NONE\",\n    \"CPUACT_SHIELD\",\n    \"CPUACT_GRAB\",\n    \"CPUACT_UPB\",\n    \"CPUACT_DOWNB\",\n    \"CPUACT_SPOTDODGE\",\n    \"CPUACT_ROLLAWAY\",\n    \"CPUACT_ROLLTOWARDS\",\n    \"CPUACT_ROLLRDM\",\n    \"CPUACT_NAIR\",\n    \"CPUACT_FAIR\",\n    \"CPUACT_DAIR\",\n    \"CPUACT_BAIR\",\n    \"CPUACT_UAIR\",\n    \"CPUACT_SHORTHOP\",\n    \"CPUACT_FULLHOP\",\n    \"CPUACT_JUMPAWAY\",\n    \"CPUACT_JUMPTOWARDS\",\n    \"CPUACT_AIRDODGE\",\n    \"CPUACT_FFTUMBLE\",\n    \"CPUACT_FFWIGGLE\",\n    \"CPUACT_JAB\",\n    \"CPUACT_FTILT\",\n    \"CPUACT_UTILT\",\n    \"CPUACT_DTILT\",\n    \"CPUACT_USMASH\",\n    \"CPUACT_DSMASH\",\n    \"CPUACT_FSMASH\",\n};\nstatic 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};\nstatic 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};\nstatic 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};\n\n// Main Menu\nstatic char **LabOptions_OffOn[] = {\"Off\", \"On\"};\nstatic EventOption LabOptions_Main[] = {\n    {\n        .option_kind = OPTKIND_MENU,                                                     // the type of option this is; menu, string list, integer list, etc\n        .value_num = 0,                                                                  // number of values for this option\n        .option_val = 0,                                                                 // value of this option\n        .menu = &LabMenu_General,                                                        // pointer to the menu that pressing A opens\n        .option_name = {\"General\"},                                                      // pointer to a string\n        .desc = \"Toggle player percent, overlays,\\nframe advance, and camera settings.\", // string describing what this option does\n        .option_values = 0,                                                              // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_MENU,       // the type of option this is; menu, string list, integers list, etc\n        .value_num = 0,                    // number of values for this option\n        .option_val = 0,                   // value of this option\n        .menu = &LabMenu_CPU,              // pointer to the menu that pressing A opens\n        .option_name = {\"CPU Options\"},    // pointer to a string\n        .desc = \"Configure CPU behavior.\", // string describing what this option does\n        .option_values = 0,                // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_MENU,           // the type of option this is; menu, string list, integers list, etc\n        .value_num = 0,                        // number of values for this option\n        .option_val = 0,                       // value of this option\n        .menu = &LabMenu_Record,               // pointer to the menu that pressing A opens\n        .option_name = \"Recording\",            // pointer to a string\n        .desc = \"Record and playback inputs.\", // string describing what this option does\n        .option_values = 0,                    // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // info display\n    {\n        .option_kind = OPTKIND_MENU,                          // the type of option this is; menu, string list, integer list, etc\n        .value_num = 0,                                       // number of values for this option\n        .option_val = 0,                                      // value of this option\n        .menu = &LabMenu_InfoDisplay,                         // pointer to the menu that pressing A opens\n        .option_name = \"Info Display\",                        // pointer to a string\n        .desc = \"Display various game information onscreen.\", // string describing what this option does\n        .option_values = 0,                                   // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_FUNC,                                                                                       // the type of option this is; menu, string list, integers list, etc\n        .value_num = 0,                                                                                                    // number of values for this option\n        .option_val = 0,                                                                                                   // value of this option\n        .menu = 0,                                                                                                         // pointer to the menu that pressing A opens\n        .option_name = \"Help\",                                                                                             // pointer to a string\n        .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\n        .option_values = 0,                                                                                                // pointer to an array of strings\n        .onOptionChange = Lab_Exit,\n    },\n    {\n        .option_kind = OPTKIND_FUNC,                  // the type of option this is; menu, string list, integers list, etc\n        .value_num = 0,                               // number of values for this option\n        .option_val = 0,                              // value of this option\n        .menu = 0,                                    // pointer to the menu that pressing A opens\n        .option_name = \"Exit\",                        // pointer to a string\n        .desc = \"Return to the Event Select Screen.\", // string describing what this option does\n        .option_values = 0,                           // pointer to an array of strings\n        .onOptionChange = 0,\n        .onOptionSelect = Lab_Exit,\n    },\n};\nstatic EventMenu LabMenu_Main = {\n    .name = \"Main Menu\",                                         // the name of this menu\n    .option_num = sizeof(LabOptions_Main) / sizeof(EventOption), // number of options this menu contains\n    .scroll = 0,                                                 // runtime variable used for how far down in the menu to start\n    .state = 0,                                                  // bool used to know if this menu is focused, used at runtime\n    .cursor = 0,                                                 // index of the option currently selected, used at runtime\n    .options = &LabOptions_Main,                                 // pointer to all of this menu's options\n    .prev = 0,                                                   // pointer to previous menu, used at runtime\n};\n// General\nstatic char **LabOptions_CamMode[] = {\"Normal\", \"Zoom\", \"Fixed\", \"Advanced\"};\nstatic char **LabOptions_FrameAdvButton[] = {\"L\", \"Z\", \"X\", \"Y\"};\nstatic EventOption LabOptions_General[] = {\n    // frame advance\n    {\n        .option_kind = OPTKIND_STRING,                                                                 // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabOptions_OffOn) / 4,                                                     // number of values for this option\n        .option_val = 0,                                                                               // value of this option\n        .menu = 0,                                                                                     // pointer to the menu that pressing A opens\n        .option_name = \"Frame Advance\",                                                                // pointer to a string\n        .desc = \"Enable frame advance. Press to advance one\\nframe. Hold to advance at normal speed.\", // string describing what this option does\n        .option_values = LabOptions_OffOn,                                                             // pointer to an array of strings\n        .onOptionChange = Lab_ChangeFrameAdvance,\n    },\n    // frame advance button\n    {\n        .option_kind = OPTKIND_STRING,                        // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabOptions_FrameAdvButton) / 4,   // number of values for this option\n        .option_val = 0,                                      // value of this option\n        .menu = 0,                                            // pointer to the menu that pressing A opens\n        .option_name = \"Frame Advance Button\",                // pointer to a string\n        .desc = \"Choose which button will advance the frame\", // string describing what this option does\n        .option_values = LabOptions_FrameAdvButton,           // pointer to an array of strings\n        .onOptionChange = 0,\n        .disable = 1,\n    },\n    // p1 percent\n    {\n        .option_kind = OPTKIND_INT,             // the type of option this is; menu, string list, integer list, etc\n        .value_num = 999,                       // number of values for this option\n        .option_val = 0,                        // value of this option\n        .menu = 0,                              // pointer to the menu that pressing A opens\n        .option_name = \"Player Percent\",        // pointer to a string\n        .desc = \"Adjust the player's percent.\", // string describing what this option does\n        .option_values = \"%d%%\",                // pointer to an array of strings\n        .onOptionChange = Lab_ChangePlayerPercent,\n    },\n    // model display\n    {\n        .option_kind = OPTKIND_STRING,                      // the type of option this is; menu, string list, integer list, etc\n        .value_num = 2,                                     // number of values for this option\n        .option_val = 1,                                    // value of this option\n        .menu = 0,                                          // pointer to the menu that pressing A opens\n        .option_name = \"Model Display\",                     // pointer to a string\n        .desc = \"Toggle player and item model visibility.\", // string describing what this option does\n        .option_values = LabOptions_OffOn,                  // pointer to an array of strings\n        .onOptionChange = Lab_ChangeModelDisplay,\n    },\n    // fighter collision\n    {\n        .option_kind = OPTKIND_STRING,                                                                                                                           // the type of option this is; menu, string list, integer list, etc\n        .value_num = 2,                                                                                                                                          // number of values for this option\n        .option_val = 0,                                                                                                                                         // value of this option\n        .menu = 0,                                                                                                                                               // pointer to the menu that pressing A opens\n        .option_name = \"Fighter Collision\",                                                                                                                      // pointer to a string\n        .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\n        .option_values = LabOptions_OffOn,                                                                                                                       // pointer to an array of strings\n        .onOptionChange = Lab_ChangeHitDisplay,\n    },\n    // environment collision\n    {\n        .option_kind = OPTKIND_STRING,                                                                                          // the type of option this is; menu, string list, integer list, etc\n        .value_num = 2,                                                                                                         // number of values for this option\n        .option_val = 0,                                                                                                        // value of this option\n        .menu = 0,                                                                                                              // pointer to the menu that pressing A opens\n        .option_name = \"Environment Collision\",                                                                                 // pointer to a string\n        .desc = \"Toggle environment collision visualization.\\nAlso displays the players' ECB (environmental \\ncollision box).\", // string describing what this option does\n        .option_values = LabOptions_OffOn,                                                                                      // pointer to an array of strings\n        .onOptionChange = Lab_ChangeEnvCollDisplay,\n    },\n    // camera mode\n    {\n        .option_kind = OPTKIND_STRING,                                                                                                      // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabOptions_CamMode) / 4,                                                                                        // number of values for this option\n        .option_val = 0,                                                                                                                    // value of this option\n        .menu = 0,                                                                                                                          // pointer to the menu that pressing A opens\n        .option_name = \"Camera Mode\",                                                                                                       // pointer to a string\n        .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\n        .option_values = LabOptions_CamMode,                                                                                                // pointer to an array of strings\n        .onOptionChange = Lab_ChangeCamMode,\n    },\n    // hud\n    {\n        .option_kind = OPTKIND_STRING,                          // the type of option this is; menu, string list, integer list, etc\n        .value_num = 2,                                         // number of values for this option\n        .option_val = 1,                                        // value of this option\n        .menu = 0,                                              // pointer to the menu that pressing A opens\n        .option_name = \"HUD\",                                   // pointer to a string\n        .desc = \"Toggle player percents and timer visibility.\", // string describing what this option does\n        .option_values = LabOptions_OffOn,                      // pointer to an array of strings\n        .onOptionChange = Lab_ChangeHUD,\n    },\n    // di display\n    {\n        .option_kind = OPTKIND_STRING,                                                                                      // the type of option this is; menu, string list, integer list, etc\n        .value_num = 2,                                                                                                     // number of values for this option\n        .option_val = 0,                                                                                                    // value of this option\n        .menu = 0,                                                                                                          // pointer to the menu that pressing A opens\n        .option_name = \"DI Display\",                                                                                        // pointer to a string\n        .desc = \"Display knockback trajectories.\\nUse frame advance to see the effects of DI\\nin realtime during hitstop.\", // string describing what this option does\n        .option_values = LabOptions_OffOn,                                                                                  // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // input display\n    {\n        .option_kind = OPTKIND_STRING,             // the type of option this is; menu, string list, integer list, etc\n        .value_num = 2,                            // number of values for this option\n        .option_val = 0,                           // value of this option\n        .menu = 0,                                 // pointer to the menu that pressing A opens\n        .option_name = \"Input Display\",            // pointer to a string\n        .desc = \"Display player inputs onscreen.\", // string describing what this option does\n        .option_values = LabOptions_OffOn,         // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // move staling\n    {\n        .option_kind = OPTKIND_STRING,                                                          // the type of option this is; menu, string list, integer list, etc\n        .value_num = 2,                                                                         // number of values for this option\n        .option_val = 1,                                                                        // value of this option\n        .menu = 0,                                                                              // pointer to the menu that pressing A opens\n        .option_name = \"Move Staling\",                                                          // pointer to a string\n        .desc = \"Toggle the staling of moves. Attacks become \\nweaker the more they are used.\", // string describing what this option does\n        .option_values = LabOptions_OffOn,                                                      // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n};\nstatic EventMenu LabMenu_General = {\n    .name = \"General\",                                              // the name of this menu\n    .option_num = sizeof(LabOptions_General) / sizeof(EventOption), // number of options this menu contains\n    .scroll = 0,                                                    // runtime variable used for how far down in the menu to start\n    .state = 0,                                                     // bool used to know if this menu is focused, used at runtime\n    .cursor = 0,                                                    // index of the option currently selected, used at runtime\n    .options = &LabOptions_General,                                 // pointer to all of this menu's options\n    .prev = 0,                                                      // pointer to previous menu, used at runtime\n};\n// Info Display\nstatic 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\"};\nstatic char **LabValues_InfoPresets[] = {\"None\", \"Custom\", \"Ledge\", \"Damage\"};\n//static char **LabValues_InfoPosition[] = {\"Top Left\", \"Top Mid\", \"Top Right\", \"Bottom Left\", \"Bottom Mid\", \"Bottom Right\"};\nstatic char **LabValues_InfoSize[] = {\"Small\", \"Medium\", \"Large\"};\nstatic char **LabValues_InfoPlayers[] = {\"Player 1\", \"Player 2\", \"Player 3\", \"Player 4\"};\nstatic EventOption LabOptions_InfoDisplay[] = {\n    {\n        .option_kind = OPTKIND_STRING,                           // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_InfoPlayers) / 4,          // number of values for this option\n        .option_val = 0,                                         // value of this option\n        .menu = 0,                                               // pointer to the menu that pressing A opens\n        .option_name = \"Player\",                                 // pointer to a string\n        .desc = \"Toggle which player's information to display.\", // string describing what this option does\n        .option_values = LabValues_InfoPlayers,                  // pointer to an array of strings\n        .onOptionChange = Lab_ChangeInfoPlayer,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                                                                                                        // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_InfoSize) / 4,                                                                                          // number of values for this option\n        .option_val = 1,                                                                                                                      // value of this option\n        .menu = 0,                                                                                                                            // pointer to the menu that pressing A opens\n        .option_name = \"Size\",                                                                                                                // pointer to a string\n        .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\n        .option_values = LabValues_InfoSize,                                                                                                  // pointer to an array of strings\n        .onOptionChange = Lab_ChangeInfoSizePos,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                       // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_InfoPresets) / 4,      // number of values for this option\n        .option_val = 0,                                     // value of this option\n        .menu = 0,                                           // pointer to the menu that pressing A opens\n        .option_name = \"Display Preset\",                     // pointer to a string\n        .desc = \"Choose between pre-configured selections.\", // string describing what this option does\n        .option_values = LabValues_InfoPresets,              // pointer to an array of strings\n        .onOptionChange = Lab_ChangeInfoPreset,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                   // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_InfoDisplay) / 4,  // number of values for this option\n        .option_val = 0,                                 // value of this option\n        .menu = 0,                                       // pointer to the menu that pressing A opens\n        .option_name = \"Row 1\",                          // pointer to a string\n        .desc = \"Adjust what is displayed in this row.\", // string describing what this option does\n        .option_values = LabValues_InfoDisplay,          // pointer to an array of strings\n        .onOptionChange = Lab_ChangeInfoRow,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                   // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_InfoDisplay) / 4,  // number of values for this option\n        .option_val = 0,                                 // value of this option\n        .menu = 0,                                       // pointer to the menu that pressing A opens\n        .option_name = \"Row 2\",                          // pointer to a string\n        .desc = \"Adjust what is displayed in this row.\", // string describing what this option does\n        .option_values = LabValues_InfoDisplay,          // pointer to an array of strings\n        .onOptionChange = Lab_ChangeInfoRow,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                   // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_InfoDisplay) / 4,  // number of values for this option\n        .option_val = 0,                                 // value of this option\n        .menu = 0,                                       // pointer to the menu that pressing A opens\n        .option_name = \"Row 3\",                          // pointer to a string\n        .desc = \"Adjust what is displayed in this row.\", // string describing what this option does\n        .option_values = LabValues_InfoDisplay,          // pointer to an array of strings\n        .onOptionChange = Lab_ChangeInfoRow,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                   // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_InfoDisplay) / 4,  // number of values for this option\n        .option_val = 0,                                 // value of this option\n        .menu = 0,                                       // pointer to the menu that pressing A opens\n        .option_name = \"Row 4\",                          // pointer to a string\n        .desc = \"Adjust what is displayed in this row.\", // string describing what this option does\n        .option_values = LabValues_InfoDisplay,          // pointer to an array of strings\n        .onOptionChange = Lab_ChangeInfoRow,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                   // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_InfoDisplay) / 4,  // number of values for this option\n        .option_val = 0,                                 // value of this option\n        .menu = 0,                                       // pointer to the menu that pressing A opens\n        .option_name = \"Row 5\",                          // pointer to a string\n        .desc = \"Adjust what is displayed in this row.\", // string describing what this option does\n        .option_values = LabValues_InfoDisplay,          // pointer to an array of strings\n        .onOptionChange = Lab_ChangeInfoRow,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                   // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_InfoDisplay) / 4,  // number of values for this option\n        .option_val = 0,                                 // value of this option\n        .menu = 0,                                       // pointer to the menu that pressing A opens\n        .option_name = \"Row 6\",                          // pointer to a string\n        .desc = \"Adjust what is displayed in this row.\", // string describing what this option does\n        .option_values = LabValues_InfoDisplay,          // pointer to an array of strings\n        .onOptionChange = Lab_ChangeInfoRow,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                   // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_InfoDisplay) / 4,  // number of values for this option\n        .option_val = 0,                                 // value of this option\n        .menu = 0,                                       // pointer to the menu that pressing A opens\n        .option_name = \"Row 7\",                          // pointer to a string\n        .desc = \"Adjust what is displayed in this row.\", // string describing what this option does\n        .option_values = LabValues_InfoDisplay,          // pointer to an array of strings\n        .onOptionChange = Lab_ChangeInfoRow,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                   // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_InfoDisplay) / 4,  // number of values for this option\n        .option_val = 0,                                 // value of this option\n        .menu = 0,                                       // pointer to the menu that pressing A opens\n        .option_name = \"Row 8\",                          // pointer to a string\n        .desc = \"Adjust what is displayed in this row.\", // string describing what this option does\n        .option_values = LabValues_InfoDisplay,          // pointer to an array of strings\n        .onOptionChange = Lab_ChangeInfoRow,\n    },\n};\nstatic EventMenu LabMenu_InfoDisplay = {\n    .name = \"Info Display\",             // the name of this menu\n    .option_num = 11,                   // number of options this menu contains\n    .scroll = 0,                        // runtime variable used for how far down in the menu to start\n    .state = 0,                         // bool used to know if this menu is focused, used at runtime\n    .cursor = 0,                        // index of the option currently selected, used at runtime\n    .options = &LabOptions_InfoDisplay, // pointer to all of this menu's options\n    .prev = 0,                          // pointer to previous menu, used at runtime\n};\n// CPU\nstatic char **LabValues_Shield[] = {\"Off\", \"On Until Hit\", \"On\"};\nstatic char **LabValues_CPUBehave[] = {\"Stand\", \"Shield\", \"Crouch\", \"Jump\"};\nstatic char **LabValues_TDI[] = {\"Random\", \"Inwards\", \"Outwards\", \"Floorhug\", \"Custom\", \"None\"};\nstatic char **LabValues_SDIFreq[] = {\"None\", \"Low\", \"Medium\", \"High\"};\nstatic char **LabValues_SDIDir[] = {\"Random\", \"Away\", \"Towards\"};\nstatic char **LabValues_Tech[] = {\"Random\", \"Neutral\", \"Away\", \"Towards\", \"None\"};\nstatic char **LabValues_Getup[] = {\"Random\", \"Stand\", \"Away\", \"Towards\", \"Attack\"};\nstatic 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\"};\nstatic 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\"};\nstatic 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\"};\nstatic char **LabValues_GrabEscape[] = {\"None\", \"Medium\", \"High\", \"Perfect\"};\nstatic EventOption LabOptions_CPU[] = {\n    // cpu percent\n    {\n        .option_kind = OPTKIND_INT,          // the type of option this is; menu, string list, integer list, etc\n        .value_num = 999,                    // number of values for this option\n        .option_val = 0,                     // value of this option\n        .menu = 0,                           // pointer to the menu that pressing A opens\n        .option_name = \"CPU Percent\",        // pointer to a string\n        .desc = \"Adjust the CPU's percent.\", // string describing what this option does\n        .option_values = \"%d%%\",             // pointer to an array of strings\n        .onOptionChange = Lab_ChangeCPUPercent,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_CPUBehave) / 4, // number of values for this option\n        .option_val = 0,                              // value of this option\n        .menu = 0,                                    // pointer to the menu that pressing A opens\n        .option_name = \"Behavior\",                    // pointer to a string\n        .desc = \"Adjust the CPU's default action.\",   // string describing what this option does\n        .option_values = LabValues_CPUBehave,         // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                    // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_Shield) / 4,        // number of values for this option\n        .option_val = 1,                                  // value of this option\n        .menu = 0,                                        // pointer to the menu that pressing A opens\n        .option_name = {\"Infinite Shields\"},              // pointer to a string\n        .desc = \"Adjust how shield health deteriorates.\", // string describing what this option does\n        .option_values = LabValues_Shield,                // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                      // the type of option this is; menu, string list, integer list, etc\n        .value_num = 2,                                     // number of values for this option\n        .option_val = 0,                                    // value of this option\n        .menu = 0,                                          // pointer to the menu that pressing A opens\n        .option_name = {\"Intangibility\"},                   // pointer to a string\n        .desc = \"Toggle the CPU's ability to take damage.\", // string describing what this option does\n        .option_values = LabOptions_OffOn,                  // pointer to an array of strings\n        .onOptionChange = Lab_ChangeCPUIntang,\n    },\n    // SDI Freq\n    {\n        .option_kind = OPTKIND_STRING,                                                 // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_SDIFreq) / 4,                                    // number of values for this option\n        .option_val = 2,                                                               // value of this option\n        .menu = 0,                                                                     // pointer to the menu that pressing A opens\n        .option_name = \"Smash DI Frequency\",                                           // pointer to a string\n        .desc = \"Adjust how often the CPU will alter their position\\nduring hitstop.\", // string describing what this option does\n        .option_values = LabValues_SDIFreq,                                            // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // SDI Direction\n    {\n        .option_kind = OPTKIND_STRING,                                                               // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_SDIDir) / 4,                                                   // number of values for this option\n        .option_val = 0,                                                                             // value of this option\n        .menu = 0,                                                                                   // pointer to the menu that pressing A opens\n        .option_name = \"Smash DI Direction\",                                                         // pointer to a string\n        .desc = \"Adjust the direction in which the CPU will alter \\ntheir position during hitstop.\", // string describing what this option does\n        .option_values = LabValues_SDIDir,                                                           // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                                        // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_TDI) / 4,                               // number of values for this option\n        .option_val = 0,                                                      // value of this option\n        .menu = 0,                                                            // pointer to the menu that pressing A opens\n        .option_name = \"Trajectory DI\",                                       // pointer to a string\n        .desc = \"Adjust how the CPU will alter their knockback\\ntrajectory.\", // string describing what this option does\n        .option_values = LabValues_TDI,                                       // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_FUNC,                                           // the type of option this is; menu, string list, integer list, etc\n        .value_num = 0,                                                        // number of values for this option\n        .option_val = 0,                                                       // value of this option\n        .menu = 0,                                                             // pointer to the menu that pressing A opens\n        .option_name = \"Custom TDI\",                                           // pointer to a string\n        .desc = \"Create custom trajectory DI values for the\\nCPU to perform.\", // string describing what this option does\n        .option_values = 0,                                                    // pointer to an array of strings\n        .onOptionChange = 0,\n        .onOptionSelect = Lab_SelectCustomTDI,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                                         // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_Tech) / 4,                               // number of values for this option\n        .option_val = 0,                                                       // value of this option\n        .menu = 0,                                                             // pointer to the menu that pressing A opens\n        .option_name = \"Tech Option\",                                          // pointer to a string\n        .desc = \"Adjust what the CPU will do upon colliding\\nwith the stage.\", // string describing what this option does\n        .option_values = LabValues_Tech,                                       // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                                      // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_Getup) / 4,                           // number of values for this option\n        .option_val = 0,                                                    // value of this option\n        .menu = 0,                                                          // pointer to the menu that pressing A opens\n        .option_name = \"Get Up Option\",                                     // pointer to a string\n        .desc = \"Adjust what the CPU will do after missing\\na tech input.\", // string describing what this option does\n        .option_values = LabValues_Getup,                                   // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                               // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_GrabEscape) / 4,               // number of values for this option\n        .option_val = CPUMASH_HIGH,                                  // value of this option\n        .menu = 0,                                                   // pointer to the menu that pressing A opens\n        .option_name = \"Grab Escape\",                                // pointer to a string\n        .desc = \"Adjust how the CPU will attempt to escape\\ngrabs.\", // string describing what this option does\n        .option_values = LabValues_GrabEscape,                       // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    /*\n    {\n        .option_kind = OPTKIND_STRING,                               // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabOptions_OffOn) / 4,                   // number of values for this option\n        .option_val = 0,                                             // value of this option\n        .menu = 0,                                                   // pointer to the menu that pressing A opens\n        .option_name = \"Auto Reset\",                                 // pointer to a string\n        .desc = \"Automatically reset after the CPU is\\nactionable.\", // string describing what this option does\n        .option_values = LabOptions_OffOn,                           // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n*/\n    {\n        .option_kind = OPTKIND_STRING,                                                     // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_CounterGround) / 4,                                  // number of values for this option\n        .option_val = 1,                                                                   // value of this option\n        .menu = 0,                                                                         // pointer to the menu that pressing A opens\n        .option_name = \"Counter Action (Ground)\",                                          // pointer to a string\n        .desc = \"Select the action to be performed after a\\ngrounded CPU's hitstun ends.\", // string describing what this option does\n        .option_values = LabValues_CounterGround,                                          // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                                                      // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_CounterAir) / 4,                                      // number of values for this option\n        .option_val = 1,                                                                    // value of this option\n        .menu = 0,                                                                          // pointer to the menu that pressing A opens\n        .option_name = \"Counter Action (Air)\",                                              // pointer to a string\n        .desc = \"Select the action to be performed after an\\nairborne CPU's hitstun ends.\", // string describing what this option does\n        .option_values = LabValues_CounterAir,                                              // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                                               // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_CounterShield) / 4,                            // number of values for this option\n        .option_val = 1,                                                             // value of this option\n        .menu = 0,                                                                   // pointer to the menu that pressing A opens\n        .option_name = \"Counter Action (Shield)\",                                    // pointer to a string\n        .desc = \"Select the action to be performed after the\\nCPU's shield is hit.\", // string describing what this option does\n        .option_values = LabValues_CounterShield,                                    // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_INT,                                                  // the type of option this is; menu, string list, integer list, etc\n        .value_num = 100,                                                            // number of values for this option\n        .option_val = 0,                                                             // value of this option\n        .menu = 0,                                                                   // pointer to the menu that pressing A opens\n        .option_name = \"Counter After Frames\",                                       // pointer to a string\n        .desc = \"Adjust the amount of actionable frames before \\nthe CPU counters.\", // string describing what this option does\n        .option_values = \"%d Frames\",                                                // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_INT,                                           // the type of option this is; menu, string list, integer list, etc\n        .value_num = 100,                                                     // number of values for this option\n        .option_val = 1,                                                      // value of this option\n        .menu = 0,                                                            // pointer to the menu that pressing A opens\n        .option_name = \"Counter After Hits\",                                  // pointer to a string\n        .desc = \"Adjust the amount of hits taken before the \\nCPU counters.\", // string describing what this option does\n        .option_values = \"%d Hits\",                                           // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_INT,                                                           // the type of option this is; menu, string list, integer list, etc\n        .value_num = 100,                                                                     // number of values for this option\n        .option_val = 1,                                                                      // value of this option\n        .menu = 0,                                                                            // pointer to the menu that pressing A opens\n        .option_name = \"Counter After Shield Hits\",                                           // pointer to a string\n        .desc = \"Adjust the amount of hits the CPU's shield\\nwill take before they counter.\", // string describing what this option does\n        .option_values = \"%d Hits\",                                                           // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n};\nstatic EventMenu LabMenu_CPU = {\n    .name = \"CPU Options\",                                      // the name of this menu\n    .option_num = sizeof(LabOptions_CPU) / sizeof(EventOption), // number of options this menu contains\n    .scroll = 0,                                                // runtime variable used for how far down in the menu to start\n    .state = 0,                                                 // bool used to know if this menu is focused, used at runtime\n    .cursor = 0,                                                // index of the option currently selected, used at runtime\n    .options = &LabOptions_CPU,                                 // pointer to all of this menu's options\n    .prev = 0,                                                  // pointer to previous menu, used at runtime\n};\n// Recording\nstatic char **LabValues_RecordSlot[] = {\"Random\", \"Slot 1\", \"Slot 2\", \"Slot 3\", \"Slot 4\", \"Slot 5\", \"Slot 6\"};\nstatic char **LabValues_HMNRecordMode[] = {\"Off\", \"Record\", \"Playback\"};\nstatic char **LabValues_CPURecordMode[] = {\"Off\", \"Control\", \"Record\", \"Playback\"};\nstatic EventOption LabOptions_Record[] = {\n    {\n        .option_kind = OPTKIND_FUNC,                                             // the type of option this is; menu, string list, integer list, etc\n        .value_num = 0,                                                          // number of values for this option\n        .option_val = 0,                                                         // value of this option\n        .menu = 0,                                                               // pointer to the menu that pressing A opens\n        .option_name = \"Save Positions\",                                         // pointer to a string\n        .desc = \"Save the current fighter positions\\nas the initial positions.\", // string describing what this option does\n        .option_values = 0,                                                      // pointer to an array of strings\n        .onOptionSelect = Record_InitState,\n    },\n    {\n        .option_kind = OPTKIND_FUNC,                                                             // the type of option this is; menu, string list, integer list, etc\n        .value_num = 0,                                                                          // number of values for this option\n        .option_val = 0,                                                                         // value of this option\n        .menu = 0,                                                                               // pointer to the menu that pressing A opens\n        .option_name = \"Restore Positions\",                                                      // pointer to a string\n        .desc = \"Load the saved fighter positions and \\nstart the sequence from the beginning.\", // string describing what this option does\n        .option_values = 0,                                                                      // pointer to an array of strings\n        .onOptionSelect = Record_RestoreState,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                               // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_HMNRecordMode) / 4,            // number of values for this option\n        .option_val = 0,                                             // value of this option\n        .menu = 0,                                                   // pointer to the menu that pressing A opens\n        .option_name = \"HMN Mode\",                                   // pointer to a string\n        .desc = \"Toggle between recording and playback of\\ninputs.\", // string describing what this option does\n        .option_values = LabValues_HMNRecordMode,                    // pointer to an array of strings\n        .onOptionChange = Record_ChangeHMNMode,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                                                                                       // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_RecordSlot) / 4,                                                                       // number of values for this option\n        .option_val = 1,                                                                                                     // value of this option\n        .menu = 0,                                                                                                           // pointer to the menu that pressing A opens\n        .option_name = \"HMN Record Slot\",                                                                                    // pointer to a string\n        .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\n        .option_values = LabValues_RecordSlot,                                                                               // pointer to an array of strings\n        .onOptionChange = Record_ChangeHMNSlot,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                               // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_CPURecordMode) / 4,            // number of values for this option\n        .option_val = 0,                                             // value of this option\n        .menu = 0,                                                   // pointer to the menu that pressing A opens\n        .option_name = \"CPU Mode\",                                   // pointer to a string\n        .desc = \"Toggle between recording and playback of\\ninputs.\", // string describing what this option does\n        .option_values = LabValues_CPURecordMode,                    // pointer to an array of strings\n        .onOptionChange = Record_ChangeCPUMode,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                                                                                       // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabValues_RecordSlot) / 4,                                                                       // number of values for this option\n        .option_val = 1,                                                                                                     // value of this option\n        .menu = 0,                                                                                                           // pointer to the menu that pressing A opens\n        .option_name = \"CPU Record Slot\",                                                                                    // pointer to a string\n        .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\n        .option_values = LabValues_RecordSlot,                                                                               // pointer to an array of strings\n        .onOptionChange = Record_ChangeCPUSlot,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                     // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabOptions_OffOn) / 4,         // number of values for this option\n        .option_val = 0,                                   // value of this option\n        .menu = 0,                                         // pointer to the menu that pressing A opens\n        .option_name = \"Loop Input Playback\",              // pointer to a string\n        .desc = \"Loop the recorded inputs when they end.\", // string describing what this option does\n        .option_values = LabOptions_OffOn,                 // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_STRING,                                              // the type of option this is; menu, string list, integer list, etc\n        .value_num = sizeof(LabOptions_OffOn) / 4,                                  // number of values for this option\n        .option_val = 0,                                                            // value of this option\n        .menu = 0,                                                                  // pointer to the menu that pressing A opens\n        .option_name = \"Auto Restore\",                                              // pointer to a string\n        .desc = \"Automatically restore saved positions \\nafter the playback ends.\", // string describing what this option does\n        .option_values = LabOptions_OffOn,                                          // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    {\n        .option_kind = OPTKIND_FUNC,                                                             // the type of option this is; menu, string list, integer list, etc\n        .value_num = 0,                                                                          // number of values for this option\n        .option_val = 0,                                                                         // value of this option\n        .menu = 0,                                                                               // pointer to the menu that pressing A opens\n        .option_name = \"Export\",                                                                 // pointer to a string\n        .desc = \"Export the recording to a memory card\\nfor later use or to share with others.\", // string describing what this option does\n        .option_values = 0,                                                                      // pointer to an array of strings\n        .onOptionSelect = Export_Init,\n    },\n};\nstatic EventMenu LabMenu_Record = {\n    .name = \"Recording\",                                           // the name of this menu\n    .option_num = sizeof(LabOptions_Record) / sizeof(EventOption), // number of options this menu contains\n    .scroll = 0,                                                   // runtime variable used for how far down in the menu to start\n    .state = 0,                                                    // bool used to know if this menu is focused, used at runtime\n    .cursor = 0,                                                   // index of the option currently selected, used at runtime\n    .options = &LabOptions_Record,                                 // pointer to all of this menu's options\n    .prev = 0,                                                     // pointer to previous menu, used at runtime\n};\n\n// Static Variables\nstatic DIDraw didraws[6];\nstatic GOBJ *infodisp_gobj;\nstatic RecData rec_data;\nstatic Savestate *rec_state;\nstatic _HSD_ImageDesc snap_image = {0};\nstatic _HSD_ImageDesc resized_image = {\n    .format = 4,\n    .height = RESIZE_HEIGHT,\n    .width = RESIZE_WIDTH,\n};\nstatic u8 snap_status;\nstatic u8 export_status;\nstatic Arch_LabData *stc_lab_data;\nstatic char *tm_filename = \"TMREC_%02d%02d%04d_%02d%02d%02d\";\nstatic char stc_save_name[32] = \"Training Mode Input Recording   \";\nstatic DevText *stc_devtext;\nstatic u8 stc_hmn_controller;             // making this static so importing recording doesnt overwrite\nstatic u8 stc_cpu_controller;             // making this static so importing recording doesnt overwrite\nstatic u8 stc_tdi_val_num;                // number of custom tdi values set\nstatic s8 stc_tdi_vals[TDI_HITNUM][2][2]; // contains the custom tdi values\nstatic u8 stc_sdifreqs[] = {6, 4, 2};\n\n// Static Export Variables\nstatic RecordingSave *stc_rec_save;\nstatic u32 stc_transfer_buf_size;\nstatic u8 *stc_transfer_buf;\nstatic MemcardSave memcard_save;\nstatic int chunk_num;\nstatic int save_pre_tick;\nstatic char *slots_names[] = {\"A\", \"B\"};\n\n// lz77 functions credited to https://github.com/andyherbert/lz1\nint x_to_the_n(int x, int n)\n{\n    int i; /* Variable used in loop counter */\n    int number = 1;\n\n    for (i = 0; i < n; ++i)\n        number *= x;\n\n    return (number);\n}\nu32 lz77_compress(u8 *uncompressed_text, u32 uncompressed_size, u8 *compressed_text, u8 pointer_length_width)\n{\n    u16 pointer_pos, temp_pointer_pos, output_pointer, pointer_length, temp_pointer_length;\n    u32 compressed_pointer, output_size, coding_pos, output_lookahead_ref, look_behind, look_ahead;\n    u16 pointer_pos_max, pointer_length_max;\n    pointer_pos_max = x_to_the_n(2, 16 - pointer_length_width);\n    pointer_length_max = x_to_the_n(2, pointer_length_width);\n\n    *((u32 *)compressed_text) = uncompressed_size;\n    *(compressed_text + 4) = pointer_length_width;\n    compressed_pointer = output_size = 5;\n\n    for (coding_pos = 0; coding_pos < uncompressed_size; ++coding_pos)\n    {\n        pointer_pos = 0;\n        pointer_length = 0;\n        for (temp_pointer_pos = 1; (temp_pointer_pos < pointer_pos_max) && (temp_pointer_pos <= coding_pos); ++temp_pointer_pos)\n        {\n            look_behind = coding_pos - temp_pointer_pos;\n            look_ahead = coding_pos;\n            for (temp_pointer_length = 0; uncompressed_text[look_ahead++] == uncompressed_text[look_behind++]; ++temp_pointer_length)\n                if (temp_pointer_length == pointer_length_max)\n                    break;\n            if (temp_pointer_length > pointer_length)\n            {\n                pointer_pos = temp_pointer_pos;\n                pointer_length = temp_pointer_length;\n                if (pointer_length == pointer_length_max)\n                    break;\n            }\n        }\n        coding_pos += pointer_length;\n        if ((coding_pos == uncompressed_size) && pointer_length)\n        {\n            output_pointer = (pointer_length == 1) ? 0 : ((pointer_pos << pointer_length_width) | (pointer_length - 2));\n            output_lookahead_ref = coding_pos - 1;\n        }\n        else\n        {\n            output_pointer = (pointer_pos << pointer_length_width) | (pointer_length ? (pointer_length - 1) : 0);\n            output_lookahead_ref = coding_pos;\n        }\n        *((u16 *)(compressed_text + compressed_pointer)) = output_pointer;\n        compressed_pointer += 2;\n        *(compressed_text + compressed_pointer++) = *(uncompressed_text + output_lookahead_ref);\n        output_size += 3;\n    }\n\n    return output_size;\n}\nu32 lz77_decompress(u8 *compressed_text, u8 *uncompressed_text)\n{\n    u8 pointer_length_width;\n    u16 input_pointer, pointer_length, pointer_pos, pointer_length_mask;\n    u32 compressed_pointer, coding_pos, pointer_offset, uncompressed_size;\n\n    uncompressed_size = *((u32 *)compressed_text);\n    pointer_length_width = *(compressed_text + 4);\n    compressed_pointer = 5;\n\n    pointer_length_mask = x_to_the_n(2, pointer_length_width) - 1;\n\n    for (coding_pos = 0; coding_pos < uncompressed_size; ++coding_pos)\n    {\n        input_pointer = *((u16 *)(compressed_text + compressed_pointer));\n        compressed_pointer += 2;\n        pointer_pos = input_pointer >> pointer_length_width;\n        pointer_length = pointer_pos ? ((input_pointer & pointer_length_mask) + 1) : 0;\n        if (pointer_pos)\n            for (pointer_offset = coding_pos - pointer_pos; pointer_length > 0; --pointer_length)\n                uncompressed_text[coding_pos++] = uncompressed_text[pointer_offset++];\n        *(uncompressed_text + coding_pos) = *(compressed_text + compressed_pointer++);\n    }\n\n    return coding_pos;\n}\n\n// Menu Callbacks\nvoid Lab_ChangePlayerPercent(GOBJ *menu_gobj, int value)\n{\n    GOBJ *fighter = Fighter_GetGObj(0);\n    FighterData *fighter_data = fighter->userdata;\n\n    fighter_data->dmg.percent = value;\n    Fighter_SetHUDDamage(0, value);\n\n    return;\n}\nvoid Lab_ChangeFrameAdvance(GOBJ *menu_gobj, int value)\n{\n\n    // remove colanim if toggling off\n    if (value == 0)\n        LabOptions_General[OPTGEN_FRAMEBTN].disable = 1;\n    // apply colanim\n    else\n        LabOptions_General[OPTGEN_FRAMEBTN].disable = 0;\n\n    return;\n}\nvoid Lab_ChangeCPUPercent(GOBJ *menu_gobj, int value)\n{\n    GOBJ *fighter = Fighter_GetGObj(1);\n    FighterData *fighter_data = fighter->userdata;\n\n    fighter_data->dmg.percent = value;\n    Fighter_SetHUDDamage(1, value);\n\n    return;\n}\nvoid Lab_ChangeCPUIntang(GOBJ *menu_gobj, int value)\n{\n\n    GOBJ *fighter = Fighter_GetGObj(1);\n    FighterData *fighter_data = fighter->userdata;\n\n    // remove colanim if toggling off\n    if (value == 0)\n        Fighter_ColorRemove(fighter_data, INTANG_COLANIM);\n    // apply colanim\n    else\n        Fighter_ApplyOverlay(fighter_data, INTANG_COLANIM, 0);\n\n    return;\n}\nvoid Lab_ChangeModelDisplay(GOBJ *menu_gobj, int value)\n{\n    // loop through all fighters\n    GOBJ **GOBJList = R13_PTR(-0x3E74);\n    GOBJ *this_fighter = GOBJList[8];\n    while (this_fighter != 0)\n    {\n        // get data\n        FighterData *thisFighterData = this_fighter->userdata;\n\n        // toggle\n        thisFighterData->show_model = value;\n\n        // get next fighter\n        this_fighter = this_fighter->next;\n    }\n\n    GOBJ *fighter = Fighter_GetGObj(0);\n    FighterData *fighter_data = fighter->userdata;\n\n    return;\n}\nvoid Lab_ChangeHitDisplay(GOBJ *menu_gobj, int value)\n{\n    // loop through all fighters\n    GOBJ **GOBJList = R13_PTR(-0x3E74);\n    GOBJ *this_fighter = GOBJList[8];\n    while (this_fighter != 0)\n    {\n        // get data\n        FighterData *thisFighterData = this_fighter->userdata;\n\n        // toggle\n        thisFighterData->show_hit = value;\n\n        // get next fighter\n        this_fighter = this_fighter->next;\n    }\n\n    GOBJ *fighter = Fighter_GetGObj(0);\n    FighterData *fighter_data = fighter->userdata;\n\n    return;\n}\nvoid Lab_ChangeEnvCollDisplay(GOBJ *menu_gobj, int value)\n{\n    stc_matchcam->show_coll = value;\n    return;\n}\nvoid Lab_ChangeCamMode(GOBJ *menu_gobj, int value)\n{\n    MatchCamera *cam = MATCH_CAM;\n\n    // normal cam\n    if (value == 0)\n    {\n        Match_SetNormalCamera();\n    }\n    // zoom cam\n    else if (value == 1)\n    {\n        Match_SetFreeCamera(0, 3);\n        cam->freecam_fov.X = 140;\n        cam->freecam_rotate.Y = 10;\n    }\n    // fixed\n    else if (value == 2)\n    {\n        Match_SetFixedCamera();\n    }\n    else if (value == 3)\n    {\n        Match_SetDevelopCamera();\n    }\n    Match_CorrectCamera();\n\n    return;\n}\nvoid Lab_ChangeInfoRow(GOBJ *menu_gobj, int value)\n{\n    EventOption *idOptions = &LabOptions_InfoDisplay;\n\n    // changed option, set preset to custom\n    idOptions[OPTINF_PRESET].option_val = 1;\n}\nvoid Lab_ChangeInfoPreset(GOBJ *menu_gobj, int value)\n{\n    static int idPresets[][8] =\n        {\n            // None\n            {\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n            },\n            // Ledge\n            {\n                2,\n                3,\n                8,\n                7,\n                14,\n                20,\n                21,\n                0,\n            },\n            // Damage\n            {\n                2,\n                3,\n                4,\n                5,\n                6,\n                15,\n                16,\n                18,\n            },\n        };\n\n    EventOption *idOptions = &LabOptions_InfoDisplay;\n    int *currPreset = 0;\n\n    // check for NONE\n    if (value == 0)\n        currPreset = idPresets[0];\n\n    // check for preset\n    value -= 2;\n    if (value >= 0)\n    {\n        currPreset = idPresets[value + 1];\n    }\n\n    // copy values\n    if (currPreset != 0)\n    {\n        for (int i = 0; i < 8; i++)\n        {\n            idOptions[i + OPTINF_ROW1].option_val = currPreset[i];\n        }\n    }\n}\nvoid Lab_ChangeInfoSizePos(GOBJ *menu_gobj, int value)\n{\n\n    return;\n}\nvoid Lab_ChangeInfoPlayer(GOBJ *menu_gobj, int value)\n{\n\n    return;\n}\nvoid Lab_ChangeHUD(GOBJ *menu_gobj, int value)\n{\n    // toggle HUD\n    u8 *hideHUD = (u8 *)(R13 + -0x4948);\n    if (value == 0)\n    {\n        *hideHUD = 1;\n    }\n    else\n    {\n        *hideHUD = 0;\n    }\n    return;\n}\nvoid Lab_Exit(int value)\n{\n    Match *match = MATCH;\n\n    // end game\n    match->state = 3;\n\n    // cleanup\n    Match_EndVS();\n\n    // Unfreeze\n    LabOptions_General[OPTGEN_FRAME].option_val = 0;\n    //HSD_Update *update = HSD_UPDATE;\n    //update->pause_develop = 0;\n    return;\n}\n\n// Event Functions\nGOBJ *InfoDisplay_Init()\n{\n    // Create Info Display GOBJ\n    GOBJ *idGOBJ = GObj_Create(0, 0, 0);\n    InfoDisplayData *idData = calloc(sizeof(InfoDisplayData));\n    GObj_AddUserData(idGOBJ, 4, HSD_Free, idData);\n    infodisp_gobj = idGOBJ;\n    // Load jobj\n    evMenu *menuAssets = event_vars->menu_assets;\n    JOBJ *menu = JOBJ_LoadJoint(menuAssets->popup);\n    idData->menuModel = menu;\n    // Add to gobj\n    GObj_AddObject(idGOBJ, 3, menu);\n    // Add gxlink\n    GObj_AddGXLink(idGOBJ, InfoDisplay_GX, GXLINK_INFDISP, GXPRI_INFDISP);\n    // Save pointers to corners\n    JOBJ *corners[4];\n    JOBJ_GetChild(menu, &corners, 2, 3, 4, 5, -1);\n    idData->botLeftEdge = corners[0];\n    idData->botRightEdge = corners[1];\n    // move into position\n    //menu->scale.X = INFDISP_SCALE;\n    //menu->scale.Y = INFDISP_SCALE;\n    //menu->scale.Z = INFDISP_SCALE;\n    menu->trans.X = INFDISP_X;\n    menu->trans.Y = INFDISP_Y;\n    corners[0]->trans.X = 0;\n    corners[1]->trans.X = INFDISP_WIDTH;\n    corners[2]->trans.X = 0;\n    corners[3]->trans.X = INFDISP_WIDTH;\n    corners[0]->trans.Y = 0;\n    corners[1]->trans.Y = 0;\n    corners[2]->trans.Y = 0;\n    corners[3]->trans.Y = 0;\n\n    //JOBJ_SetFlags(menu, JOBJ_HIDDEN);\n    menu->dobj->next->mobj->mat->alpha = 0.6;\n\n    // Create text object\n    int canvas_index = Text_CreateCanvas(2, idGOBJ, 14, 15, 0, GXLINK_INFDISPTEXT, GXPRI_INFDISPTEXT, 19);\n    Text *text = Text_CreateText(2, canvas_index);\n    text->kerning = 1;\n    text->use_aspect = 1;\n    text->aspect.X = 545;\n\n    // Create subtexts for each row\n    for (int i = 0; i < 8; i++)\n    {\n        Text_AddSubtext(text, 0, (INFDISPTEXT_YOFFSET * i), &nullString);\n    }\n    idData->text = text;\n\n    // adjust size based on the console / settings\n    if ((OSGetConsoleType() == OS_CONSOLE_DEVHW3) || (stc_HSD_VI->is_prog == 1)) // 480p / dolphin uses medium by default\n        LabOptions_InfoDisplay[OPT_SCALE].option_val = 1;\n    else // 480i on wii uses large (shitty composite!)\n        LabOptions_InfoDisplay[OPT_SCALE].option_val = 2;\n\n    // update size\n    Lab_ChangeInfoSizePos(0, 0);\n\n    // update to show/hide\n    InfoDisplay_Think(idGOBJ);\n\n    return idGOBJ;\n}\nvoid InfoDisplay_GX(GOBJ *gobj, int pass)\n{\n    GXLink_Common(gobj, pass);\n    return;\n}\nvoid InfoDisplay_Think(GOBJ *gobj)\n{\n\n    static Vec2 stc_info_pos[] = {\n        {-26.5, 21.5},\n        {-10, 21.5},\n        {6, 21.5},\n        {-26.5, -10.5},\n        {-10, -10.5},\n        {6, -10.5},\n    };\n    static float stc_info_scale[] = {\n        2,\n        3,\n        4,\n    };\n\n    InfoDisplayData *idData = gobj->userdata;\n    Text *text = idData->text;\n    EventOption *idOptions = &LabOptions_InfoDisplay;\n    if ((Pause_CheckStatus(1) != 2)) //&& (idOptions[OPTINF_TOGGLE].option_val == 1))\n    {\n        // get the last row enabled\n        int rowsEnabled = 8;\n        while (rowsEnabled > 0)\n        {\n            if (idOptions[rowsEnabled - 1 + OPTINF_ROW1].option_val != 0)\n                break;\n            rowsEnabled--;\n        }\n\n        // if a row is enabled, display\n        if (rowsEnabled != 0)\n        {\n            // show model and text\n            JOBJ_ClearFlags(idData->menuModel, JOBJ_HIDDEN);\n            idData->text->hidden = 0;\n\n            // scale window Y based on rows enabled\n            JOBJ *leftCorner = idData->botLeftEdge;\n            JOBJ *rightCorner = idData->botRightEdge;\n            float yPos = (rowsEnabled * INFDISP_BOTYOFFSET) + INFDISP_BOTY;\n            leftCorner->trans.Y = yPos;\n            rightCorner->trans.Y = yPos;\n            JOBJ_SetMtxDirtySub(idData->menuModel);\n\n            // update info display strings\n            int ply = idOptions[OPTINF_PLAYER].option_val;\n            GOBJ *fighter = Fighter_GetGObj(ply);\n            FighterData *fighter_data;\n            if (fighter != 0)\n                fighter_data = fighter->userdata;\n            for (int i = 0; i < 8; i++)\n            {\n\n                int value = idOptions[i + OPTINF_ROW1].option_val;\n\n                // hide text if set to 0 or fighter DNE\n                if ((idOptions[i + OPTINF_ROW1].option_val == 0) || fighter == 0)\n                {\n                    Text_SetText(text, i, \"\");\n                }\n\n                // display info\n                else\n                {\n                    switch (value)\n                    {\n                    case (INFDISPROW_POS):\n                    {\n                        Text_SetText(text, i, \"Pos: (%+.3f , %+.3f)\", fighter_data->phys.pos.X, fighter_data->phys.pos.Y);\n                        break;\n                    }\n                    case (INFDISPROW_STATE):\n                    {\n                        if (fighter_data->anim_id != -1)\n                        {\n                            SubactionHeader *subHeader = Fighter_GetSubactionHeader(fighter_data, fighter_data->anim_id);\n                            // extract state name from symbol\n                            int pos = 0;\n                            int posStart;\n                            int nameSize = 0;\n                            char *symbol = subHeader->symbol;\n                            for (int i = 0; pos < 50; pos++)\n                            {\n                                // search for \"N_\"\n                                if ((symbol[pos] == 'N') && (symbol[pos + 1] == '_'))\n                                {\n                                    // posStart = beginning of state name\n                                    pos++;\n                                    posStart = pos + 1;\n\n                                    // search for \"_\"\n                                    for (int i = 0; pos < 50; pos++)\n                                    {\n                                        if (symbol[pos] == '_')\n                                        {\n                                            nameSize = pos - posStart;\n                                        }\n                                    }\n                                }\n                            }\n                            if (nameSize != 0)\n                            {\n                                // copy string\n                                char stateNameBuffer[50];\n                                memcpy(&stateNameBuffer, &symbol[posStart], nameSize);\n                                stateNameBuffer[nameSize] = 0;\n                                Text_SetText(text, i, \"State: %s\", &stateNameBuffer);\n                            }\n                        }\n\n                        else\n                            Text_SetText(text, i, \"State: %s\", \"Unknown\");\n                        break;\n                    }\n                    case (INFDISPROW_FRAME):\n                    {\n                        float *animStruct = fighter_data->anim_curr_flags_ptr;\n                        int frameCurr = 0;\n                        int frameTotal = 0;\n\n                        // if exists\n                        if (animStruct != 0)\n                        {\n                            // determine how many frames shield stun is\n                            float animFrameTotal = animStruct[2];\n                            float animFrameCurr = fighter_data->stateFrame;\n                            float animSpeed = fighter_data->stateSpeed;\n                            frameTotal = (animFrameTotal / animSpeed);\n                            frameCurr = (animFrameCurr / animSpeed);\n                        }\n\n                        Text_SetText(text, i, \"State Frame: %d/%d\", frameCurr, frameTotal);\n                        break;\n                    }\n                    case (INFDISPROW_SELFVEL):\n                    {\n                        Text_SetText(text, i, \"SelfVel: (%+.3f , %+.3f)\", fighter_data->phys.self_vel.X, fighter_data->phys.self_vel.Y);\n                        break;\n                    }\n                    case (INFDISPROW_KBVEL):\n                    {\n                        Text_SetText(text, i, \"KBVel: (%+.3f , %+.3f)\", fighter_data->phys.kb_vel.X, fighter_data->phys.kb_vel.Y);\n                        break;\n                    }\n                    case (INFDISPROW_TOTALVEL):\n                    {\n                        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);\n                        break;\n                    }\n                    case (INFDISPROW_ENGLSTICK):\n                    {\n                        Text_SetText(text, i, \"LStick:      (%+.4f , %+.4f)\", fighter_data->input.lstick_x, fighter_data->input.lstick_y);\n                        break;\n                    }\n                    case (INFDISPROW_SYSLSTICK):\n                    {\n                        HSD_Pad *pad = PadGet(ply, PADGET_MASTER);\n                        Text_SetText(text, i, \"LStick Sys: (%+.4f , %+.4f)\", pad->fstickX, pad->fstickY);\n                        break;\n                    }\n                    case (INFDISPROW_ENGCSTICK):\n                    {\n                        Text_SetText(text, i, \"CStick:     (%+.4f , %+.4f)\", fighter_data->input.cstick_x, fighter_data->input.cstick_y);\n                        break;\n                    }\n                    case (INFDISPROW_SYSCSTICK):\n                    {\n                        HSD_Pad *pad = PadGet(ply, PADGET_MASTER);\n                        Text_SetText(text, i, \"CStick Sys: (%+.4f , %+.4f)\", pad->fsubstickX, pad->fsubstickY);\n                        break;\n                    }\n                    case (INFDISPROW_ENGTRIGGER):\n                    {\n                        Text_SetText(text, i, \"Trigger:     (%+.3f)\", fighter_data->input.trigger);\n                        break;\n                    }\n                    case (INFDISPROW_SYSTRIGGER):\n                    {\n                        HSD_Pad *pad = PadGet(ply, PADGET_MASTER);\n                        Text_SetText(text, i, \"Trigger Sys: (%+.3f , %+.3f)\", pad->ftriggerLeft, pad->ftriggerRight);\n                        break;\n                    }\n                    case (INFDISPROW_LEDGECOOLDOWN):\n                    {\n                        Text_SetText(text, i, \"Ledgegrab Timer: %d\", fighter_data->ledge_cooldown);\n                        break;\n                    }\n                    case (INFDISPROW_INTANGREMAIN):\n                    {\n                        int intang = fighter_data->hurtstatus.respawn_intang_left;\n                        if (fighter_data->hurtstatus.ledge_intang_left > fighter_data->hurtstatus.respawn_intang_left)\n                            intang = fighter_data->hurtstatus.ledge_intang_left;\n\n                        Text_SetText(text, i, \"Intangibility Timer: %d\", intang);\n                        break;\n                    }\n                    case (INFDISPROW_HITSTOP):\n                    {\n                        Text_SetText(text, i, \"Hitlag: %.0f\", fighter_data->dmg.hitlag_frames);\n                        break;\n                    }\n                    case (INFDISPROW_HITSTUN):\n                    {\n                        // get hitstun\n                        float hitstun = 0;\n                        if (fighter_data->flags.hitstun == 1)\n                            hitstun = AS_FLOAT(fighter_data->state_var.stateVar1);\n\n                        Text_SetText(text, i, \"Hitstun: %.0f\", hitstun);\n                        break;\n                    }\n                    case (INFDISPROW_SHIELDHEALTH):\n                    {\n                        Text_SetText(text, i, \"Shield Health: %.3f\", fighter_data->shield.health);\n                        break;\n                    }\n                    case (INFDISPROW_SHIELDSTUN):\n                    {\n                        int stunTotal = 0;\n                        int stunLeft = 0;\n\n                        // check if taking shield stun\n                        if (fighter_data->state == ASID_GUARDSETOFF)\n                        {\n                            // determine how many frames shield stun is\n                            float frameTotal = JOBJ_GetJointAnimFrameTotal(fighter->hsd_object);\n                            float frameCurr = fighter_data->stateFrame;\n                            float animSpeed = fighter_data->stateSpeed;\n                            stunTotal = (frameTotal / animSpeed);\n                            stunLeft = stunTotal - (frameCurr / animSpeed);\n                            // 0 index\n                            stunTotal++;\n                            stunLeft++;\n                        }\n\n                        Text_SetText(text, i, \"Shield Stun: %d/%d\", stunLeft, stunTotal);\n                        break;\n                    }\n                    case (INFDISPROW_GRIP):\n                    {\n                        float grip = 0;\n                        if (fighter_data->grab.grab_victim != 0)\n                        {\n                            GOBJ *victim = fighter_data->grab.grab_victim;\n                            FighterData *victim_data = victim->userdata;\n                            grip = victim_data->grab.grab_timer;\n                        }\n\n                        Text_SetText(text, i, \"Grip Strength: %.0f\", grip);\n                        break;\n                    }\n                    case (INFDISPROW_ECBLOCK):\n                    {\n                        Text_SetText(text, i, \"ECB Lock: %d\", fighter_data->coll_data.ecb_lock);\n                        break;\n                    }\n                    case (INFDISPROW_ECBBOT):\n                    {\n                        Text_SetText(text, i, \"ECB Bottom: %.3f\", fighter_data->coll_data.ecbCurr_bot.Y);\n                        break;\n                    }\n                    case (INFDISPROW_JUMPS):\n                    {\n                        Text_SetText(text, i, \"Jumps: %d/%d\", fighter_data->jump.jumps_used, fighter_data->attr.max_jumps);\n                        break;\n                    }\n                    case (INFDISPROW_WALLJUMPS):\n                    {\n                        Text_SetText(text, i, \"Walljumps: %d\", fighter_data->jump.walljumps_used);\n                        break;\n                    }\n                    case (INFDISPROW_JAB):\n                    {\n                        Text_SetText(text, i, \"Jab Counter: IDK\");\n                        break;\n                    }\n                    case (INFDISPROW_LINE):\n                    {\n                        CollData *colldata = &fighter_data->coll_data;\n                        int ground = -1;\n                        int ceil = -1;\n                        int left = -1;\n                        int right = -1;\n\n                        if ((colldata->envFlags & ECB_GROUND) != 0)\n                            ground = colldata->ground_index;\n                        if ((colldata->envFlags & ECB_CEIL) != 0)\n                            ceil = colldata->ceil_index;\n                        if ((colldata->envFlags & ECB_WALLLEFT) != 0)\n                            left = colldata->leftwall_index;\n                        if ((colldata->envFlags & ECB_WALLRIGHT) != 0)\n                            right = colldata->rightwall_index;\n\n                        Text_SetText(text, i, \"Lines: G:%d, C:%d, L:%d, R:%d,\", ground, ceil, left, right);\n                        break;\n                    }\n                    case (INFDISPROW_BLASTLR):\n                    {\n                        Stage *stage = STAGE;\n                        Text_SetText(text, i, \"Blastzone L/R: (%+.3f,%+.3f)\", stage->blastzoneLeft, stage->blastzoneRight);\n                        break;\n                    }\n                    case (INFDISPROW_BLASTUD):\n                    {\n                        Stage *stage = STAGE;\n                        Text_SetText(text, i, \"Blastzone U/D: (%.2f,%.2f)\", stage->blastzoneTop, stage->blastzoneBottom);\n                        break;\n                    }\n                    }\n                }\n            }\n\n            // adjust scale\n            JOBJ *info_jobj = idData->menuModel;\n            Text *info_text = idData->text;\n            Vec2 *pos = &info_jobj->trans;\n            //Vec2 *pos = &stc_info_pos[LabOptions_InfoDisplay[OPTINF_POS].option_val];\n            float scale = stc_info_scale[LabOptions_InfoDisplay[OPTINF_SIZE].option_val];\n            // background scale\n            info_jobj->scale.X = scale;\n            info_jobj->scale.Y = scale;\n            // text scale\n            info_text->scale.X = ((scale / 4.0) * INFDISPTEXT_SCALE);\n            info_text->scale.Y = ((scale / 4.0) * INFDISPTEXT_SCALE);\n            /*\n            // background position\n            info_jobj->trans.X = pos->X;\n            info_jobj->trans.Y = pos->Y;\n            */\n            // text position\n            info_text->trans.X = pos->X + (INFDISPTEXT_X * (scale / 4.0));\n            info_text->trans.Y = (pos->Y * -1) + (INFDISPTEXT_Y * (scale / 4.0));\n\n            // model color\n            int info_player = LabOptions_InfoDisplay[OPTINF_PLAYER].option_val;\n            GXColor *shield_color = *stc_shieldcolors;\n            GXColor *border_color = &info_jobj->dobj->mobj->mat->diffuse;\n            border_color->r = shield_color[info_player].r;\n            border_color->g = shield_color[info_player].g;\n            border_color->b = shield_color[info_player].b;\n\n            // update jobj\n            JOBJ_SetMtxDirtySub(info_jobj);\n        }\n        else\n        {\n            // hide model and text\n            JOBJ_SetFlags(idData->menuModel, JOBJ_HIDDEN);\n            idData->text->hidden = 1;\n        }\n    }\n    else\n    {\n        // hide model and text\n        JOBJ_SetFlags(idData->menuModel, JOBJ_HIDDEN);\n        idData->text->hidden = 1;\n    }\n\n    return;\n}\nfloat Fighter_GetOpponentDir(FighterData *from, FighterData *to)\n{\n    float dir = -1;\n    Vec3 *from_pos = &from->phys.pos;\n    Vec3 *to_pos = &to->phys.pos;\n\n    if (from_pos->X <= to_pos->X)\n        dir = 1;\n\n    return dir;\n}\nint CPUAction_CheckMultipleState(GOBJ *cpu, int group_kind)\n{\n    static u8 grActionable[] = {ASID_WAIT, ASID_WALKSLOW, ASID_WALKMIDDLE, ASID_WALKFAST, ASID_RUN, ASID_SQUATWAIT, ASID_OTTOTTOWAIT, ASID_GUARD};\n    static u8 airActionable[] = {ASID_JUMPF, ASID_JUMPB, ASID_JUMPAERIALF, ASID_JUMPAERIALB, ASID_FALL, ASID_FALLAERIALF, ASID_FALLAERIALB, ASID_DAMAGEFALL, ASID_DAMAGEFLYROLL, ASID_DAMAGEFLYTOP};\n    static u8 airDamage[] = {ASID_DAMAGEFLYHI, ASID_DAMAGEFLYN, ASID_DAMAGEFLYLW, ASID_DAMAGEFLYTOP, ASID_DAMAGEFLYROLL, ASID_DAMAGEFALL};\n    static u8 jumpStates[] = {ASID_JUMPF, ASID_JUMPB, ASID_JUMPAERIALF, ASID_JUMPAERIALB};\n    static u8 fallStates[] = {ASID_FALL, ASID_FALLAERIAL, ASID_FALLAERIALF, ASID_FALLAERIALB};\n\n    FighterData *cpu_data = cpu->userdata;\n    int isActionable = 0;\n    int cpu_state = cpu_data->state;\n\n    // if 0, check the one that corresponds with ground state\n    if (group_kind == 0)\n    {\n        group_kind = cpu_data->phys.air_state + 1;\n    }\n\n    // ground\n    if (group_kind == 1)\n    {\n        // check ground actionable\n        for (int i = 0; i < sizeof(grActionable); i++)\n        {\n            if (cpu_state == grActionable[i])\n            {\n                isActionable = 1;\n                break;\n            }\n        }\n        // landing\n        if ((cpu_data->state == ASID_LANDING) && (cpu_data->stateFrame >= cpu_data->attr.normal_landing_lag))\n            isActionable = 1;\n    }\n    // air\n    else if (group_kind == 2)\n    {\n        // check air actionable\n        for (int i = 0; i < sizeof(airActionable); i++)\n        {\n            if (cpu_state == airActionable[i])\n            {\n                isActionable = 1;\n                break;\n            }\n        }\n    }\n    // damage state that requires wiggling\n    else if (group_kind == 3)\n    {\n        // check air actionable\n        for (int i = 0; i < sizeof(airDamage); i++)\n        {\n            if (cpu_state == airDamage[i])\n            {\n                isActionable = 1;\n                break;\n            }\n        }\n    }\n    // jump states\n    else if (group_kind == 4)\n    {\n        for (int i = 0; i < sizeof(jumpStates); i++)\n        {\n            if (cpu_state == jumpStates[i])\n            {\n                isActionable = 1;\n                break;\n            }\n        }\n    }\n    // fall states\n    else if (group_kind == 5)\n    {\n        for (int i = 0; i < sizeof(fallStates); i++)\n        {\n            if (cpu_state == fallStates[i])\n            {\n                isActionable = 1;\n                break;\n            }\n        }\n    }\n\n    return isActionable;\n}\nint CPU_IsThrown(GOBJ *cpu)\n{\n    FighterData *cpu_data = cpu->userdata;\n\n    int is_thrown = 0;\n    int cpu_state = cpu_data->state;\n\n    // check if thrown\n    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)))\n        is_thrown = 1;\n\n    return is_thrown;\n}\nint CPU_IsGrabbed(GOBJ *cpu)\n{\n    FighterData *cpu_data = cpu->userdata;\n\n    int is_grabbed = 0;\n    int cpu_state = cpu_data->state;\n\n    // check if thrown\n    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)))\n        is_grabbed = 1;\n\n    return is_grabbed;\n}\nint LCancel_CPUPerformAction(GOBJ *cpu, int action_id, GOBJ *hmn)\n{\n    FighterData *cpu_data = cpu->userdata;\n    FighterData *hmn_data = hmn->userdata;\n\n    // get CPU action\n    int action_done = 0;\n    CPUAction *action_list = Lab_CPUActions[action_id];\n    int cpu_state = cpu_data->state;\n    s16 cpu_frame = cpu_data->stateFrame;\n    if (cpu_frame == -1)\n        cpu_frame = 0;\n\n    // clear inputs\n    Fighter_ZeroCPUInputs(cpu_data);\n\n    // if no action, report command as done\n    if (action_id == 0)\n        action_done = 1;\n\n    // perform command\n    else\n    {\n        // loop through all inputs\n        int action_parse = 0;\n        CPUAction *action_input = &action_list[action_parse];\n        while ((action_input != 0) && (action_input->state != 0xFFFF))\n        {\n\n            int isState = 0;\n            if ((action_input->state >= ASID_ACTIONABLE) && (action_input->state <= ASID_FALLS))\n                isState = CPUAction_CheckMultipleState(cpu, (action_input->state - ASID_ACTIONABLE));\n            else if (action_input->state == cpu_state)\n                isState = 1;\n\n            // check if this is the current state\n            if (isState == 1)\n            {\n                // check if im on the right frame\n                if (cpu_frame >= action_input->frameLow)\n                {\n\n                    OSReport(\"exec input %d of %s\\n\", action_parse, CPU_ACTIONS_NAMES[action_id]);\n\n                    // perform this action\n                    s8 dir;\n                    int held = action_input->input;\n                    s8 lstickX = action_input->stickX;\n                    s8 lstickY = action_input->stickY;\n                    s8 cstickX = action_input->cstickX;\n                    s8 cstickY = action_input->cstickY;\n\n                    // stick direction\n                    switch (action_input->stickDir)\n                    {\n                    case (STCKDIR_NONE):\n                    {\n                        break;\n                    }\n                    case (STCKDIR_TOWARD):\n                    {\n                        dir = Fighter_GetOpponentDir(cpu_data, hmn_data);\n                        lstickX *= dir;\n                        cstickX *= dir;\n                        break;\n                    }\n                    case (STCKDIR_AWAY):\n                    {\n                        dir = Fighter_GetOpponentDir(cpu_data, hmn_data) * -1;\n                        lstickX *= dir;\n                        cstickX *= dir;\n                        break;\n                    }\n                    case (STCKDIR_FRONT):\n                    {\n                        dir = cpu_data->facing_direction;\n                        lstickX *= dir;\n                        cstickX *= dir;\n                        break;\n                    }\n                    case (STCKDIR_BACK):\n                    {\n                        dir = cpu_data->facing_direction;\n                        lstickX *= (dir * -1);\n                        cstickX *= (dir * -1);\n                        break;\n                    }\n                    case (STICKDIR_RDM):\n                    {\n                        // random direction\n                        if (HSD_Randi(2) == 0)\n                            dir = 1;\n                        else\n                            dir = -1;\n\n                        lstickX *= dir;\n                        cstickX *= dir;\n                        break;\n                    }\n                    }\n\n                    // perform this action\n                    cpu_data->cpu.held = held;\n                    cpu_data->cpu.lstickX = lstickX;\n                    cpu_data->cpu.lstickY = lstickY;\n                    cpu_data->cpu.cstickX = cstickX;\n                    cpu_data->cpu.cstickY = cstickY;\n\n                    // check if this was the last action\n                    if (action_input->isLast == 1)\n                        action_done = 1;\n\n                    break;\n                }\n            }\n\n            // get next input\n            action_parse++;\n            action_input = &action_list[action_parse];\n        }\n    }\n\n    return action_done;\n}\nvoid LCancel_CPUThink(GOBJ *event, GOBJ *hmn, GOBJ *cpu)\n{\n    // get gobjs data\n    LCancelData *eventData = event->userdata;\n    FighterData *hmn_data = hmn->userdata;\n    FighterData *cpu_data = cpu->userdata;\n    GOBJ **gobjlist = R13_PTR(GOBJLIST);\n    int cpu_state = cpu_data->state;\n\n    // noact\n    cpu_data->cpu.ai = 15;\n\n    // if first throw frame, advance hitnum\n    int is_thrown = CPU_IsThrown(cpu);\n    if ((is_thrown == 1) && (eventData->cpu_isthrown == 0))\n    {\n        eventData->cpu_hitnum++;\n    }\n    eventData->cpu_isthrown = is_thrown;\n\n    // ALWAYS CHECK FOR X AND OVERRIDE STATE\n\n    // check if damaged\n    if (cpu_data->flags.hitstun == 1)\n    {\n        eventData->cpu_hitkind = HITKIND_DAMAGE;\n        // go to SDI state\n        eventData->cpu_state = CPUSTATE_SDI;\n        Fighter_ZeroCPUInputs(cpu_data);\n    }\n    // check if being held in a grab\n    if (CPU_IsGrabbed(cpu) == 1)\n    {\n        eventData->cpu_state = CPUSTATE_GRABBED;\n    }\n    // check if being thrown\n    if (is_thrown == 1)\n    {\n        eventData->cpu_state = CPUSTATE_TDI;\n    }\n    // check for shield hit\n    if ((cpu_state == ASID_GUARDSETOFF) || ((cpu_data->kind == 0xE) && (cpu_state == 344)))\n    {\n        Fighter_ZeroCPUInputs(cpu_data);\n\n        // check if new shield hit\n        if (eventData->cpu_lastshieldstun != cpu_data->moveID)\n        {\n            eventData->cpu_lastshieldstun = cpu_data->moveID;\n            eventData->cpu_hitshieldnum++;\n        }\n\n        eventData->cpu_hitkind = HITKIND_SHIELD;\n        eventData->cpu_state = CPUSTATE_SDI;\n        // go to Shield state\n        //eventData->cpu_state = CPUSTATE_SHIELD;\n    }\n    // check for missed tech\n    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))\n        eventData->cpu_state = CPUSTATE_GETUP;\n    // check for cliffgrab\n    if ((cpu_state == ASID_CLIFFWAIT))\n        eventData->cpu_state = CPUSTATE_RECOVER;\n    // check if dead\n    if (cpu_data->flags.dead == 1)\n        goto CPUSTATE_ENTERSTART;\n\n    // run CPU state logic\n    switch (eventData->cpu_state)\n    {\n    // Initial State, hasn't been hit yet\n    case (CPUSTATE_START):\n    CPULOGIC_START:\n    {\n\n        // if in the air somehow, enter recovery\n        if (cpu_data->phys.air_state == 1)\n        {\n            eventData->cpu_state = CPUSTATE_RECOVER;\n            goto CPULOGIC_RECOVER;\n        }\n\n        // clear held inputs\n        Fighter_ZeroCPUInputs(cpu_data);\n\n        // perform default behavior\n        int behavior = LabOptions_CPU[OPTCPU_BEHAVE].option_val;\n        switch (behavior)\n        {\n        case (CPUBEHAVE_STAND):\n        {\n            break;\n        }\n\n        case (CPUBEHAVE_SHIELD):\n        {\n            // hold R\n            cpu_data->cpu.held = PAD_TRIGGER_R;\n            break;\n        }\n\n        case (CPUBEHAVE_CROUCH):\n        {\n            // hold down\n            cpu_data->cpu.lstickY = -127;\n            break;\n        }\n\n        case (CPUBEHAVE_JUMP):\n        {\n            // run jump command\n            LCancel_CPUPerformAction(cpu, 12, hmn);\n            break;\n        }\n        }\n\n        break;\n    }\n\n    case (CPUSTATE_GRABBED):\n    CPULOGIC_GRABBED:\n    {\n        // if no longer being grabbed, exit\n        if (CPU_IsGrabbed(cpu) == 0)\n        {\n            eventData->cpu_state = CPUSTATE_RECOVER;\n            goto CPULOGIC_RECOVER;\n        }\n\n        switch (LabOptions_CPU[OPTCPU_MASH].option_val)\n        {\n        case (CPUMASH_NONE):\n        {\n            Fighter_ZeroCPUInputs(cpu_data);\n            break;\n        }\n        case (CPUMASH_MED):\n        {\n            if (HSD_Randi(100) <= CPUMASHRNG_MED)\n            {\n                // remove last frame inputs\n                cpu_data->input.held = 0;\n                cpu_data->input.lstick_x = 0;\n                cpu_data->input.lstick_y = 0;\n\n                // input\n                cpu_data->cpu.held = PAD_BUTTON_A;\n                cpu_data->cpu.lstickX = 127;\n            }\n            break;\n        }\n        case (CPUMASH_HIGH):\n        {\n            if (HSD_Randi(100) <= CPUMASHRNG_HIGH)\n            {\n                // remove last frame inputs\n                cpu_data->input.held = 0;\n                cpu_data->input.lstick_x = 0;\n                cpu_data->input.lstick_y = 0;\n\n                // input\n                cpu_data->cpu.held = PAD_BUTTON_A;\n                cpu_data->cpu.lstickX = 127;\n            }\n            break;\n        }\n        case (CPUMASH_PERFECT):\n        {\n            // remove last frame inputs\n            cpu_data->input.held = 0;\n            cpu_data->input.lstick_x = 0;\n            cpu_data->input.lstick_y = 0;\n\n            // input\n            cpu_data->cpu.held = PAD_BUTTON_A;\n            cpu_data->cpu.lstickX = 127;\n            break;\n        }\n        }\n\n        break;\n    }\n\n    case (CPUSTATE_SDI):\n    CPULOGIC_SDI:\n    {\n\n        // if no more hitlag, enter tech state\n        if (cpu_data->flags.hitlag == 0)\n        {\n            eventData->cpu_state = CPUSTATE_TECH;\n            goto CPULOGIC_TECH;\n        }\n\n        // if final frame of hitlag, enter TDI state\n        else if (cpu_data->dmg.hitlag_frames == 1)\n        {\n            eventData->cpu_state = CPUSTATE_TDI;\n            goto CPULOGIC_TDI;\n        }\n\n        // update move instance\n        if (eventData->cpu_lasthit != cpu_data->dmg.instancehitby)\n        {\n            eventData->cpu_sincehit = 0;\n            eventData->cpu_hitnum++;\n            eventData->cpu_lasthit = cpu_data->dmg.instancehitby;\n            //OSReport(\"hit count %d/%d\", eventData->cpu_hitnum, LabOptions_CPU[OPTCPU_CTRHITS].option_val);\n\n            // decide random SDI direction for grounded cpu\n            if ((LabOptions_CPU[OPTCPU_SDIFREQ].option_val != SDIFREQ_NONE) && (LabOptions_CPU[OPTCPU_SDIDIR].option_val == SDIDIR_RANDOM))\n            {\n                eventData->cpu_sdidir = HSD_Randi(2);\n            }\n        }\n\n        // to-do: shield SDI\n        if ((cpu_data->state >= ASID_GUARDON) && (cpu_data->state <= ASID_GUARDREFLECT))\n        {\n            ;\n        }\n\n        // perform SDI behavior\n        else if (LabOptions_CPU[OPTCPU_SDIFREQ].option_val != SDIFREQ_NONE)\n        {\n\n            int chance = stc_sdifreqs[LabOptions_CPU[OPTCPU_SDIFREQ].option_val - 1];\n\n            // chance to SDI\n            if (HSD_Randi(chance) == 0)\n            {\n\n                float angle, magnitude;\n\n                switch (LabOptions_CPU[OPTCPU_SDIDIR].option_val)\n                {\n                case SDIDIR_RANDOM:\n                {\n                    // when grounded, only left right\n                    if (cpu_data->phys.air_state == 0)\n                    {\n\n                        magnitude = 1;\n\n                        // decide left or right\n                        if (eventData->cpu_sdidir == 0)\n                            angle = 0; // right\n                        else\n                            angle = M_PI; // left\n                    }\n                    // when airborne, any direction\n                    else\n                    {\n                        // random input\n                        angle = HSD_Randi(360) * M_1DEGREE;\n                        magnitude = 0.49 + (HSD_Randf() * 0.51);\n                    }\n\n                    break;\n                }\n                case SDIDIR_AWAY:\n                {\n                    // get angle from center bubble to hit collision\n                    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);\n\n                    // flip\n                    angle += M_PI;\n                    while (angle > (M_PI * 2))\n                    {\n                        angle -= (M_PI * 2);\n                    }\n\n                    magnitude = 1;\n\n                    break;\n                }\n                case SDIDIR_TOWARD:\n                {\n                    // get angle from center bubble to hit collision\n                    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);\n\n                    magnitude = 1;\n\n                    break;\n                }\n                }\n\n                // store\n                cpu_data->cpu.lstickX = cos(angle) * 127 * magnitude;\n                cpu_data->cpu.lstickY = sin(angle) * 127 * magnitude;\n            }\n        }\n\n        break;\n    }\n\n    case (CPUSTATE_TDI):\n    CPULOGIC_TDI:\n    {\n\n        // if no more hitlag and not being thrown, enter tech state. this might never be hit, just being safe\n        if ((cpu_data->flags.hitlag == 0) && (is_thrown == 0))\n        {\n            eventData->cpu_state = CPUSTATE_TECH;\n            goto CPULOGIC_TECH;\n        }\n\n        // if in shield, no need to TDI\n        if ((cpu_data->state >= ASID_GUARDON) && (cpu_data->state <= ASID_GUARDREFLECT))\n        {\n            break;\n        }\n\n        // get knockback value\n        float kb_angle;\n        if (is_thrown == 1)\n        {\n            // if being thrown, get knockback info from attacker\n            FighterData *attacker_data = cpu_data->grab.grab_attacker->userdata;\n            kb_angle = ((float)attacker_data->throw_hitbox[0].angle * M_1DEGREE) * (attacker_data->facing_direction);\n        }\n        else\n        {\n            // not being thrown, get knockback angle normally\n            //kb_angle = Fighter_GetKnockbackAngle(cpu_data) * cpu_data->dmg.direction;\n            kb_angle = atan2(cpu_data->phys.kb_vel.Y, cpu_data->phys.kb_vel.X);\n        }\n\n        // perform TDI behavior\n        int tdi_kind = LabOptions_CPU[OPTCPU_TDI].option_val;\n\n    TDI_SWITCH:\n        switch (tdi_kind)\n        {\n        case (CPUTDI_RANDOM):\n        {\n            tdi_kind = HSD_Randi(CPUTDI_NUM - 1) + 1;\n            goto TDI_SWITCH;\n        }\n\n        case (CPUTDI_IN):\n        {\n\n            /*\n            NOTE: im using 94 degrees here because some moves like marth\n            uthrow use this angle, and drawing the line at 90 would make \n            inward DI cause the opponent to DI in the direction marth is facing\n            and looks confusing\n            */\n\n            float orig_dir;\n            if ((kb_angle > (-94 * M_1DEGREE)) && (kb_angle <= (94 * M_1DEGREE)))\n                orig_dir = -1;\n            else\n                orig_dir = 1;\n\n            // get optimal tdi\n            float tdi_angle = kb_angle + (orig_dir * -(M_PI / 2));\n\n            // convert to analog input\n            cpu_data->cpu.lstickX = cos(tdi_angle) * 127;\n            cpu_data->cpu.lstickY = sin(tdi_angle) * 127;\n\n            break;\n        }\n\n        case (CPUTDI_OUT):\n        TDI_OUT:\n        {\n\n            /*\n            NOTE: im using 94 degrees here because some moves like marth\n            uthrow use a 93 degree angle, and drawing the line at 90 would make \n            inward DI cause the opponent to DI in the direction marth is facing\n            and looks confusing\n            */\n\n            float orig_dir;\n            if ((kb_angle > (-94 * M_1DEGREE)) && (kb_angle <= (94 * M_1DEGREE)))\n                orig_dir = -1;\n            else\n                orig_dir = 1;\n\n            // get optimal tdi\n            float tdi_angle = kb_angle + (orig_dir * M_PI / 2);\n\n            // convert to analog input\n            cpu_data->cpu.lstickX = cos(tdi_angle) * 127;\n            cpu_data->cpu.lstickY = sin(tdi_angle) * 127;\n\n            break;\n        }\n\n        case (CPUTDI_FLOORHUG):\n        {\n\n            // floothug = full ASDI down + outward DI\n            cpu_data->cpu.cstickY = -127;\n            goto TDI_OUT;\n\n            break;\n        }\n\n        case (CPUTDI_CUSTOM):\n        {\n\n            int cpu_hitnum = eventData->cpu_hitnum;\n\n            // ensure we have a DI input for this hitnum\n            if (cpu_hitnum <= stc_tdi_val_num)\n            {\n\n                // get the stick values for this hit num\n                cpu_hitnum--;\n\n                s8 lstickX = stc_tdi_vals[cpu_hitnum][0][0];\n                s8 lstickY = stc_tdi_vals[cpu_hitnum][0][1];\n                s8 cstickX = stc_tdi_vals[cpu_hitnum][1][0];\n                s8 cstickY = stc_tdi_vals[cpu_hitnum][1][1];\n\n                cpu_data->cpu.lstickX = ((float)lstickX / 80) * 127.0;\n                cpu_data->cpu.lstickY = ((float)lstickY / 80) * 127.0;\n                cpu_data->cpu.cstickX = ((float)cstickX / 80) * 127.0;\n                cpu_data->cpu.cstickY = ((float)cstickY / 80) * 127.0;\n\n                // increment\n            }\n\n            break;\n        }\n\n        case (CPUTDI_NONE):\n        {\n            Fighter_ZeroCPUInputs(cpu_data);\n            break;\n        }\n        }\n\n        // this is kinda meh, maybe i can come up with something better later\n        // spoof last input as current input as to not trigger SDI\n        // also spoof input as held for more than the SDI window\n        cpu_data->input.lstick_x = ((float)cpu_data->cpu.lstickX * 0.0078125);\n        cpu_data->input.timer_lstick_tilt_x = 5;\n        cpu_data->input.lstick_y = ((float)cpu_data->cpu.lstickY * 0.0078125);\n        cpu_data->input.timer_lstick_tilt_y = 5;\n\n        break;\n    }\n\n    case (CPUSTATE_TECH):\n    CPULOGIC_TECH:\n    {\n\n        // if no more hitstun, go to counter\n        if (cpu_data->flags.hitstun == 0)\n        {\n            // also reset stick timer (messes with airdodge wiggle)\n            cpu_data->input.lstick_x = 0;\n            cpu_data->input.timer_lstick_tilt_x = 254;\n            eventData->cpu_state = CPUSTATE_COUNTER;\n            goto CPULOGIC_COUNTER;\n        }\n\n        // perform tech behavior\n        int tech_kind = LabOptions_CPU[OPTCPU_TECH].option_val;\n        s8 dir;\n        s8 stickX = 0;\n        s8 sincePress = 0;\n        s8 since2Press = -1;\n        s8 sinceXSmash = -1;\n    TECH_SWITCH:\n        switch (tech_kind)\n        {\n        case (CPUTECH_RANDOM):\n        {\n            tech_kind = (HSD_Randi((sizeof(LabValues_Tech) / 4) - 1) + 1);\n            goto TECH_SWITCH;\n            break;\n        }\n        case (CPUTECH_NEUTRAL):\n        {\n            break;\n        }\n        case (CPUTECH_AWAY):\n        {\n            dir = Fighter_GetOpponentDir(cpu_data, hmn_data);\n            stickX = 127 * (dir * -1);\n            break;\n        }\n        case (CPUTECH_TOWARDS):\n        {\n            dir = Fighter_GetOpponentDir(cpu_data, hmn_data);\n            stickX = 127 * (dir);\n            break;\n        }\n        case (CPUTECH_NONE):\n        {\n            sincePress = -1;\n            break;\n        }\n        }\n\n        // input tech\n        cpu_data->input.timer_LR = sincePress;\n        cpu_data->input.sinceRapidLR = since2Press;\n        cpu_data->cpu.lstickX = stickX;\n        cpu_data->input.timer_lstick_smash_x = sinceXSmash;\n\n        break;\n    }\n\n    case (CPUSTATE_GETUP):\n    CPULOGIC_GETUP:\n    {\n\n        // if im in downwait, perform getup logic\n        if ((cpu_data->state == ASID_DOWNWAITD) || (cpu_data->state == ASID_DOWNWAITU))\n        {\n            // perform getup behavior\n            int getup = LabOptions_CPU[OPTCPU_GETUP].option_val;\n            s8 dir;\n            int inputs = 0;\n            s8 stickX = 0;\n            s8 stickY = 0;\n\n        GETUP_SWITCH:\n            switch (getup)\n            {\n            case (CPUGETUP_RANDOM):\n            {\n                getup = (HSD_Randi((sizeof(LabValues_Tech) / 4) - 1) + 1);\n                goto GETUP_SWITCH;\n                break;\n            }\n            case (CPUGETUP_STAND):\n            {\n                stickY = 127;\n                break;\n            }\n            case (CPUGETUP_TOWARD):\n            {\n                dir = Fighter_GetOpponentDir(cpu_data, hmn_data);\n                stickX = 127 * (dir);\n                break;\n            }\n            case (CPUGETUP_AWAY):\n            {\n                dir = Fighter_GetOpponentDir(cpu_data, hmn_data);\n                stickX = 127 * (dir * -1);\n                break;\n            }\n            case (CPUGETUP_ATTACK):\n            {\n                inputs = PAD_BUTTON_A;\n                break;\n            }\n            }\n\n            // input getup option\n            cpu_data->cpu.held = inputs;\n            cpu_data->cpu.lstickX = stickX;\n            cpu_data->cpu.lstickY = stickY;\n        }\n\n        // if cpu is in any other down state, do nothing\n        else if ((cpu_data->state >= ASID_DOWNBOUNDU) && (cpu_data->state <= ASID_DOWNSPOTD))\n        {\n            break;\n        }\n\n        // if cpu is not in a down state, enter COUNTER\n        else\n        {\n            eventData->cpu_state = CPUSTATE_COUNTER;\n            goto CPULOGIC_COUNTER;\n            break;\n        }\n\n        break;\n    }\n\n    case (CPUSTATE_COUNTER):\n    CPULOGIC_COUNTER:\n    {\n\n        // check if the CPU has been actionable yet\n        if (eventData->cpu_isactionable == 0)\n        {\n            // check if actionable\n            if (CPUAction_CheckMultipleState(cpu, 0) == 0)\n            {\n                break;\n            }\n            else\n            {\n                eventData->cpu_isactionable = 1;                       // set actionable flag to begin running code\n                eventData->cpu_groundstate = cpu_data->phys.air_state; // remember initial ground state\n            }\n        }\n\n        // if started in the air, didnt finish action, but now grounded, perform ground action\n        if ((eventData->cpu_groundstate == 1) && (cpu_data->phys.air_state == 0))\n        {\n            eventData->cpu_groundstate = 0;\n        }\n\n        // increment frames since actionable\n        eventData->cpu_sincehit++;\n\n        // ensure hit count and frame count criteria are met\n        int action_id;\n        if (eventData->cpu_hitkind == HITKIND_DAMAGE)\n        {\n            if ((eventData->cpu_hitnum < LabOptions_CPU[OPTCPU_CTRHITS].option_val) || (eventData->cpu_sincehit < LabOptions_CPU[OPTCPU_CTRFRAMES].option_val))\n            {\n                break;\n            }\n\n            // get counter action\n            if (cpu_data->phys.air_state == 0 || (eventData->cpu_groundstate == 0)) // if am grounded or started grounded\n            {\n                int grndCtr = LabOptions_CPU[OPTCPU_CTRGRND].option_val;\n                action_id = GrAcLookup[grndCtr];\n            }\n            else if (cpu_data->phys.air_state == 1) // only if in the air at the time of hitstun ending\n            {\n                int airCtr = LabOptions_CPU[OPTCPU_CTRAIR].option_val;\n                action_id = AirAcLookup[airCtr];\n            }\n        }\n        else if (eventData->cpu_hitkind == HITKIND_SHIELD)\n        {\n\n            // if the shield wasnt hit enough times, return to start\n            if (eventData->cpu_hitshieldnum < LabOptions_CPU[OPTCPU_SHIELDHITS].option_val)\n            {\n                eventData->cpu_state = CPUSTATE_START;\n                goto CPULOGIC_START;\n                break;\n            }\n\n            // if this isnt the frame to counter, keep holding shield\n            if (eventData->cpu_sincehit < LabOptions_CPU[OPTCPU_CTRFRAMES].option_val)\n            {\n                cpu_data->cpu.held = PAD_TRIGGER_R;\n                break;\n            }\n\n            // get action to perform\n            int shieldCtr = LabOptions_CPU[OPTCPU_CTRSHIELD].option_val;\n            action_id = ShieldAcLookup[shieldCtr];\n        }\n        else\n        {\n            // wasnt hit, fell or something idk. enter start again\n            goto CPUSTATE_ENTERSTART;\n        }\n\n        // if none, enter recover\n        if (action_id == 0)\n        {\n            eventData->cpu_state = CPUSTATE_RECOVER;\n            goto CPULOGIC_RECOVER;\n        }\n\n        // perform counter behavior\n        //OSReport(\"executing input\");\n        if (LCancel_CPUPerformAction(cpu, action_id, hmn) == 1)\n        {\n            eventData->cpu_state = CPUSTATE_RECOVER;\n            //goto CPULOGIC_RECOVER;\n        }\n\n        break;\n    }\n\n    case (CPUSTATE_RECOVER):\n    CPULOGIC_RECOVER:\n    {\n\n        // if onstage, go back to start\n        if (cpu_data->phys.air_state == 0)\n        {\n\n        CPUSTATE_ENTERSTART:\n            // clear inputs\n\n            // go to start\n            eventData->cpu_state = CPUSTATE_START;\n            eventData->cpu_hitshield = 0;\n            eventData->cpu_hitnum = 0;\n            eventData->cpu_sincehit = 0;\n            eventData->cpu_hitshield = 0;\n            eventData->cpu_lasthit = -1;\n            eventData->cpu_lastshieldstun = -1;\n            eventData->cpu_hitkind = -1;\n            eventData->cpu_hitshieldnum = 0;\n            eventData->cpu_isactionable = 0;\n            goto CPULOGIC_START;\n        }\n\n        // recover with CPU AI\n        cpu_data->cpu.ai = 0;\n\n        break;\n    }\n    }\n\n    // update isthrown\n    eventData->cpu_isthrown = is_thrown;\n\n    // update cpu_hitshield\n    if (eventData->cpu_hitshield == 0)\n    {\n        GOBJ *fighter = gobjlist[8];\n        while (fighter != 0)\n        {\n            FighterData *fighter_data = fighter->userdata;\n\n            // check if in guard off\n            if (fighter_data->state == ASID_GUARDSETOFF)\n            {\n                eventData->cpu_hitshield = 1;\n                break;\n            }\n\n            fighter = fighter->next;\n        }\n    }\n\n    // update shield deterioration\n    int infShield = LabOptions_CPU[OPTCPU_SHIELD].option_val;\n    if (infShield == 1)\n    {\n        if (eventData->cpu_hitshield == 0)\n        {\n            // inf shield\n            GOBJ *fighter = gobjlist[8];\n            while (fighter != 0)\n            {\n                FighterData *fighter_data = fighter->userdata;\n                fighter_data->shield.health = 60;\n                fighter = fighter->next;\n            }\n        }\n    }\n    else if (infShield == 2)\n    {\n        // inf shield\n        GOBJ *fighter = gobjlist[8];\n        while (fighter != 0)\n        {\n            FighterData *fighter_data = fighter->userdata;\n            fighter_data->shield.health = 60;\n\n            fighter = fighter->next;\n        }\n    }\n\n    return;\n}\nint Update_CheckPause()\n{\n    HSD_Update *update = HSD_UPDATE;\n    int isChange = 0;\n\n    // get their pad\n    int controller = Fighter_GetControllerPort(0);\n    HSD_Pad *pad = PadGet(controller, PADGET_MASTER);\n\n    // if event menu not showing, develop mode + pause input, toggle frame advance\n    if ((Pause_CheckStatus(1) != 2) && (*stc_dblevel >= 3) && (pad->down & HSD_BUTTON_START))\n    {\n        LabOptions_General[OPTGEN_FRAME].option_val ^= 1;\n        Lab_ChangeFrameAdvance(0, LabOptions_General[OPTGEN_FRAME].option_val);\n        isChange = 1;\n    }\n\n    // menu paused\n    else if (LabOptions_General[OPTGEN_FRAME].option_val == 1)\n    {\n        // check if unpaused\n        if (update->pause_develop != 1)\n        {\n            // pause\n            isChange = 1;\n        }\n    }\n\n    // menu unpaused\n    else\n    {\n        // check if paused\n        if (update->pause_develop == 1)\n        {\n            // unpause\n            isChange = 1;\n        }\n    }\n\n    return isChange;\n}\nint Update_CheckAdvance()\n{\n\n    static int timer = 0;\n\n    HSD_Update *update = HSD_UPDATE;\n    int isAdvance = 0;\n\n    int controller = Fighter_GetControllerPort(0);\n\n    // get their pad\n    HSD_Pad *pad = PadGet(controller, PADGET_MASTER);\n\n    // get their advance input\n    static int stc_advance_btns[] = {HSD_TRIGGER_L, HSD_TRIGGER_Z, HSD_BUTTON_X, HSD_BUTTON_Y};\n    int advance_btn = stc_advance_btns[LabOptions_General[OPTGEN_FRAMEBTN].option_val];\n\n    // check if holding L\n    if ((pad->held & advance_btn))\n    {\n        timer++;\n\n        // advance if first press or holding more than 10 frames\n        if (timer == 1 || timer > 30)\n        {\n            isAdvance = 1;\n\n            // remove button input\n            pad->down &= ~advance_btn;\n            pad->held &= ~advance_btn;\n\n            // if using L, remove analog press too\n            if (LabOptions_CPU[OPTGEN_FRAMEBTN].option_val == 0)\n            {\n                pad->triggerLeft = 0;\n                pad->ftriggerLeft = 0;\n            }\n        }\n    }\n\n    else\n    {\n        update->advance = 0;\n        timer = 0;\n    }\n\n    return isAdvance;\n}\nvoid DIDraw_Init()\n{\n    // Create DIDraw GOBJ\n    GOBJ *didraw_gobj = GObj_Create(0, 0, 0);\n    // Add gxlink\n    GObj_AddGXLink(didraw_gobj, DIDraw_GX, 6, 0);\n    // init didraw pointers\n    for (int i = 0; i < 6; i++)\n    {\n        // for each subchar\n        for (int j = 0; j < 2; j++)\n        {\n            didraws[i].num[j] = 0;\n            didraws[i].vertices[j] = 0;\n        }\n    }\n\n    return;\n}\nvoid DIDraw_Update()\n{\n    static ECBBones ecb_bones_def = {\n        .topY = 9,\n        .botY = 2.5,\n        .left = {-3.3, 5.7},\n        .right = {3.3, 5.7},\n    };\n\n    // if enabled and pause menu isnt shown, update di draw\n    if ((LabOptions_General[OPTGEN_DI].option_val == 1)) //  && (Pause_CheckStatus(1) != 2)\n    {\n        // loop through all fighters\n        GOBJList *gobj_list = R13_PTR(GOBJLIST);\n        GOBJ *fighter = gobj_list->fighter;\n        while (fighter != 0)\n        {\n\n            FighterData *fighter_data = fighter->userdata;\n            int ply = fighter_data->ply;\n            DIDraw *didraw = &didraws[ply];\n\n            // if in hitlag and hitstun simulate and update trajectory\n            if ((fighter_data->flags.hitlag == 1) && (fighter_data->flags.hitstun == 1))\n            {\n                // free old\n                if (didraw->vertices[ply] != 0)\n                {\n                    HSD_Free(didraw->vertices[ply]);\n                    didraw->num[ply] = 0;\n                    didraw->vertices[ply] = 0;\n                }\n\n                //OSReport(\"######### BEGIN ##########\\n\");\n\n                // get player's inputs\n                float lstickX;\n                float lstickY;\n                float cstickX;\n                float cstickY;\n                // for HMN players\n                if (Fighter_GetSlotType(fighter_data->ply) == 0)\n                {\n                    int input_kind;\n                    if (Pause_CheckStatus(0) == 1) // if frame advance enabled, use master inputs\n                        input_kind = PADGET_MASTER;\n                    else\n                        input_kind = PADGET_ENGINE; // no frame advance, use engine inputs\n                    HSD_Pad *pad = PadGet(fighter_data->player_controller_number, input_kind);\n                    lstickX = pad->fstickX;\n                    lstickY = pad->fstickY;\n                    cstickX = pad->fsubstickX;\n                    cstickY = pad->fsubstickY;\n                }\n                // for CPUs\n                else\n                {\n                    lstickX = fighter_data->input.lstick_x;\n                    lstickY = fighter_data->input.lstick_y;\n                    cstickX = fighter_data->input.cstick_x;\n                    cstickY = fighter_data->input.cstick_y;\n                }\n\n                // get kb vector\n                Vec3 kb = fighter_data->phys.kb_vel;\n                float kb_angle = atan2(kb.Y, kb.X);\n                // init ASDI vector\n                Vec3 asdi_orig;\n                Vec3 asdi = {0, 0, 0};\n                // get fighter constants\n                ftCommonData *ftCmDt = R13_PTR(PLCO_FTCOMMON);\n\n                // Calculate ASDI\n                float asdi_mag = pow(ftCmDt->asdi_mag, 2);\n                float asdi_units = ftCmDt->asdi_units;\n                // CStick has priority, check if mag > 0.7\n                if (pow(cstickX, 2) + (pow(cstickY, 2)) >= asdi_mag)\n                {\n                    asdi.X = cstickX * asdi_units;\n                    asdi.Y = cstickY * asdi_units;\n                }\n                // now check if lstick mag > 0.7\n                else if (pow(lstickX, 2) + (pow(lstickY, 2)) >= asdi_mag)\n                {\n                    asdi.X = lstickX * asdi_units;\n                    asdi.Y = lstickY * asdi_units;\n                }\n                // Remember original ASDI\n                asdi_orig = asdi;\n                //OSReport(\"ASDI:  %f , %f\\n\", asdi.X, asdi.Y);\n\n                // Calculate TDI\n                //OSReport(\"KB Pre TDI:  %f , %f\\n\", kb.X, kb.Y);\n                if ((lstickX != 0) || (lstickY != 0)) // exclude input vector 0,0\n                {\n                    // kb vector must exceed 0.00001\n                    float kb_mult = (kb.Y * kb.Y) + (kb.X * kb.X);\n                    if (kb_mult >= 0.00001)\n                    {\n\n                        // get values\n                        float tdi_input = pow((-1 * kb.X * lstickY) + (lstickX * kb.Y), 2) / kb_mult;\n                        float max_angle = ftCmDt->tdi_maxAngle * M_1DEGREE;\n                        float kb_mag = sqrtf(kb_mult);\n\n                        // check to negate\n                        Vec3 inputs = {lstickX, lstickY, 0};\n                        Vec3 result;\n                        VECCrossProduct(&kb, &inputs, &result);\n                        if (result.Z < 0)\n                            tdi_input *= -1;\n\n                        // apply TDI\n                        kb_angle = (max_angle * tdi_input) + kb_angle;\n\n                        // New X KB\n                        kb.X = cos(kb_angle) * kb_mag;\n                        // New Y KB\n                        kb.Y = sin(kb_angle) * kb_mag;\n                    }\n                }\n                //OSReport(\"KB Post TDI:  %f , %f\\n\", kb.X, kb.Y);\n\n                //simulation variables\n                int air_state = fighter_data->phys.air_state;\n                float gravity = 0;\n                Vec3 pos = fighter_data->phys.pos;\n                ftCommonData *ftCommon = R13_PTR(-0x514C);\n                float decay = ftCommon->kb_frameDecay;\n                int hitstun_frames = AS_FLOAT(fighter_data->state_var.stateVar1);\n                int vertices_num = 0;    // used to track how many vertices will be needed\n                int override_frames = 0; // used as an alternate countdown\n                DIDrawCalculate *DICollData = calloc(sizeof(DIDrawCalculate) * hitstun_frames);\n                CollData ecb;\n                ECBBones ecb_bones;\n\n                // init ecb struct\n                Coll_InitECB(&ecb);\n                if (fighter_data->phys.air_state == 0) // copy ecb struct if grounded\n                {\n                    memcpy(&ecb.envFlags, &fighter_data->coll_data.envFlags, 0x28);\n                }\n\n                // simulate each frame of knockback\n                for (int i = 0; i < hitstun_frames; i++)\n                {\n\n                    // update bone positions.  If loop count < noECBUpdate-remaining hitlag fraes, use current ECB bottom Y offset\n                    if (vertices_num < (fighter_data->coll_data.ecb_lock - fighter_data->dmg.hitlag_frames))\n                    {\n\n                        ecb_bones.topY = fighter_data->coll_data.ecbCurr_top.Y;\n                        ecb_bones.botY = fighter_data->coll_data.ecbCurr_bot.Y;\n                        ecb_bones.left = fighter_data->coll_data.ecbCurr_left;\n                        ecb_bones.right = fighter_data->coll_data.ecbCurr_right;\n\n                        // if grounded, ECB bottom is 0\n                        if (air_state == 0)\n                        {\n                            ecb_bones.botY = 0;\n                        }\n                    }\n                    else\n                    {\n                        // use default ecb size\n                        memcpy(&ecb_bones, &ecb_bones_def, sizeof(ECBBones));\n                    }\n                    // update ecb topN position\n                    ecb.topN_Curr = pos;\n                    ecb.topN_CurrCorrect = pos;\n\n                    // apply ASDI\n                    pos.X += asdi.X;\n                    if (air_state != 0) // only apply Y asdi in the air\n                    {\n                        pos.Y += asdi.Y;\n                    }\n                    asdi.X = 0; // zero out ASDI\n                    asdi.Y = 0; // zero out ASDI\n\n                    // update gravity\n                    gravity -= fighter_data->attr.gravity;\n                    float terminal_velocity = fighter_data->attr.terminal_velocity * -1;\n                    if (gravity < terminal_velocity)\n                        gravity = terminal_velocity;\n                    // decay KB vector\n                    float angle = atan2(kb.Y, kb.X);\n                    kb.X = kb.X - (cos(angle) * decay);\n                    kb.Y = kb.Y - (sin(angle) * decay);\n\n                    // add knockback\n                    VECAdd(&pos, &kb, &pos);\n                    // apply gravity\n                    pos.Y += gravity;\n\n                    // ecb prev = ecb curr\n                    ecb.topN_Prev = ecb.topN_Curr;\n                    // ecb curr = new position\n                    ecb.topN_Curr = pos;\n\n                    // only run X collision checks because theyre expensive\n                    if (vertices_num >= DI_MaxColl)\n                    {\n                        DICollData[i].envFlags = 0; // spoof as not touching\n                        pos = ecb.topN_Curr;        // position = projected\n                    }\n\n                    // update collision\n                    else\n                    {\n                        // ground coll\n                        if (air_state == 0)\n                        {\n                            int result = ECB_CollGround_PassLedge(&ecb, &ecb_bones);\n                            if (result == 0)\n                            {\n                                air_state = 1;\n                            }\n                        }\n                        // air coll\n                        else\n                        {\n                            ECB_CollAir(&ecb, &ecb_bones);\n                        }\n\n                        // get corrected position\n                        pos = ecb.topN_Curr;\n\n                        // increment collision ID\n                        ecb.coll_test += 1;\n\n                        // perform stage collision code\n                        if ((ecb.envFlags & ECB_GROUND) != 0)\n                        {\n                            // check if air->ground just occurred\n                            if (air_state == 1)\n                            {\n                                // set grounded\n                                air_state = 0;\n\n                                // check if over max horizontal velocity\n                                if (kb.X > ftCmDt->kb_maxVelX)\n                                    kb.X = ftCmDt->kb_maxVelX;\n                                if (kb.X < -ftCmDt->kb_maxVelX)\n                                    kb.X = -ftCmDt->kb_maxVelX;\n\n                                // adjust KB direction from slope\n                                kb.X *= ecb.ground_slope.Y;\n                                kb.Y *= ecb.ground_slope.X;\n\n                                // zero out gravity\n                                gravity = 0;\n\n                                // zero out Y KB\n                                kb.Y = 0;\n                            }\n                        }\n                        else if ((ecb.envFlags & ECB_CEIL) != 0)\n                        {\n                            // only run this code when in the air\n                            if (air_state == 1)\n                            {\n                                // combine KB and Gravity\n                                Vec3 kb_temp = kb;\n                                Vec3 vel_temp = {0, gravity, 0};\n                                VECAdd(&vel_temp, &kb_temp, &vel_temp);\n\n                                // apply slope\n                                VECMultAndAdd(&vel_temp, &ecb.ceil_slope);\n\n                                // decay kb\n                                kb.X = vel_temp.X * ftCmDt->kb_bounceDecay;\n                                kb.Y = vel_temp.Y * ftCmDt->kb_bounceDecay;\n                            }\n                        }\n                        else if ((ecb.envFlags & (ECB_WALLLEFT | ECB_WALLRIGHT)) != 0)\n                        {\n                            // only run this code when in the air\n                            if (air_state == 1)\n                            {\n\n                                // get slope\n                                Vec3 *slope;\n                                if ((ecb.envFlags & ECB_WALLLEFT) != 0)\n                                {\n                                    slope = &ecb.leftwall_slope;\n                                }\n                                else\n                                {\n                                    slope = &ecb.rightwall_slope;\n                                }\n\n                                // combine KB and Gravity\n                                Vec3 kb_temp = kb;\n                                Vec3 vel_temp = {0, gravity, 0};\n                                VECAdd(&vel_temp, &kb_temp, &vel_temp);\n\n                                // apply slope\n                                VECMultAndAdd(&vel_temp, slope);\n\n                                // decay kb\n                                kb.X = vel_temp.X * ftCmDt->kb_bounceDecay;\n                                kb.Y = vel_temp.Y * ftCmDt->kb_bounceDecay;\n\n                                // zero gravity\n                                gravity = 0;\n                            }\n                        }\n\n                        // check for slide off\n                        if (((ecb.envFlags & ECB_GROUND) == 0) && ((ecb.envFlags_prev & ECB_GROUND) != 0)) // not touching ground this frame, was touching last frame\n                        {\n                            if (override_frames == 0)\n                                override_frames = 5; // terminate in 5 frames\n                        }\n                    }\n\n                    //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);\n\n                    // save this position\n                    DICollData[i].pos.X = pos.X;\n                    DICollData[i].pos.Y = pos.Y;\n                    DICollData[i].kb_Y = kb.Y;\n                    DICollData[i].ECBLeftY = ecb_bones.left.Y;\n                    DICollData[i].ECBTopY = ecb_bones.topY;\n\n                    // inc vertices count\n                    vertices_num++;\n\n                    // if override frames are set, decrement and exit\n                    if (override_frames > 0)\n                    {\n                        override_frames--;\n                        if (override_frames == 0)\n                            break;\n                    }\n                }\n\n                // alloc draw struct\n                didraw->num[ply] = vertices_num + 2; // +2 for ASDI vertices\n                // alloc vertices\n                didraw->vertices[ply] = calloc(sizeof(Vec2) * (vertices_num + 2));\n\n                // save ASDI first\n                didraw->vertices[ply][0].X = fighter_data->coll_data.topN_Curr.X;\n                didraw->vertices[ply][0].Y = fighter_data->coll_data.topN_Curr.Y + fighter_data->coll_data.ecbCurr_left.Y;\n                didraw->vertices[ply][1].X = fighter_data->coll_data.topN_Curr.X + asdi_orig.X;\n                didraw->vertices[ply][1].Y = fighter_data->coll_data.topN_Curr.Y + fighter_data->coll_data.ecbCurr_left.Y + asdi_orig.Y;\n\n                // save this info to the draw struct\n                for (int i = 0; i < vertices_num; i++)\n                {\n                    didraw->vertices[ply][i + 2].X = DICollData[i].pos.X;\n                    didraw->vertices[ply][i + 2].Y = DICollData[i].pos.Y + ((DICollData[i].ECBLeftY + DICollData[i].ECBTopY) / 2);\n\n                    // get vertex color\n                    static GXColor airColor = {0, 138, 255, 255};\n                    static GXColor groundColor = {255, 255, 255, 255};\n                    static GXColor ceilColor = {255, 0, 0, 255};\n                    static GXColor wallColor = {0, 255, 0, 255};\n                    GXColor *color;\n                    if ((ecb.envFlags & ECB_GROUND) != 0)\n                        color = &groundColor;\n                    else if ((ecb.envFlags & ECB_CEIL) != 0)\n                        color = &ceilColor;\n                    else if ((ecb.envFlags & ECB_WALLLEFT | ECB_WALLRIGHT) != 0)\n                        color = &wallColor;\n                    else\n                        color = &airColor;\n                    // set vertex color\n                    didraw->color.r = color->r;\n                    didraw->color.g = color->g;\n                    didraw->color.b = color->b;\n                    didraw->color.a = color->a;\n                }\n\n                // free the collision info\n                HSD_Free(DICollData);\n            }\n            // if not in hitstun, zero out didraw\n            else if (fighter_data->flags.hitstun == 0)\n            {\n                if (didraw->vertices[ply] != 0)\n                {\n                    HSD_Free(didraw->vertices[ply]);\n                    didraw->num[ply] = 0;\n                    didraw->vertices[ply] = 0;\n                }\n            }\n\n            fighter = fighter->next;\n        }\n    }\n\n    // is off, remove all di draw\n    else\n    {\n        // all slots\n        for (int i = 0; i < 6; i++)\n        {\n            DIDraw *didraw = &didraws[i];\n\n            // all subchars\n            for (int j = 0; j < 2; j++)\n            {\n                if (didraw->vertices[j] != 0)\n                {\n                    HSD_Free(didraw->vertices[j]);\n                    didraw->num[j] = 0;\n                    didraw->vertices[j] = 0;\n                }\n            }\n        }\n    }\n\n    return;\n}\nvoid DIDraw_GX()\n{\n    // if toggle enabled\n    if (LabOptions_General[OPTGEN_DI].option_val == 1)\n    {\n\n        // draw each\n        for (int i = 0; i < 6; i++)\n        {\n            // for each subchar\n            for (int j = 0; j < 2; j++)\n            {\n                DIDraw *didraw = &didraws[i];\n                // if it exists\n                if (didraw->num != 0)\n                {\n                    int vertex_num = didraw->num[j];\n                    Vec2 *vertices = didraw->vertices[j];\n\n                    // alloc prim\n                    PRIM *gx = PRIM_NEW(vertex_num, 0x001F1306, 0x00000C55);\n\n                    // draw each\n                    for (int k = 0; k < vertex_num; k++)\n                    {\n                        PRIM_DRAW(gx, vertices[k].X, vertices[k].Y, 0, 0x008affff);\n                    }\n\n                    // close\n                    PRIM_CLOSE();\n                }\n            }\n        }\n    }\n    return;\n}\nvoid Update_Camera()\n{\n    // if camera is set to advanced\n    if (LabOptions_General[OPTGEN_CAM].option_val == 3)\n    {\n\n        // Get player gobj\n        GOBJ *fighter = Fighter_GetGObj(0);\n        if (fighter != 0)\n        {\n\n            // get players inputs\n            FighterData *fighter_data = fighter->userdata;\n            HSD_Pad *pad = PadGet(fighter_data->player_controller_number, PADGET_MASTER);\n            int held = pad->held;\n            float stickX = pad->fsubstickX;\n            float stickY = pad->fsubstickY;\n            float deadzone = 0.2;\n\n            if (fabs(stickX) < deadzone)\n                stickX = 0;\n            if (fabs(stickY) < deadzone)\n                stickY = 0;\n\n            // ensure stick exceeds deadzone\n            if ((stickX != 0) || (stickY != 0))\n            {\n                COBJ *cobj = COBJ_GetMatchCamera();\n\n                // adjust pan\n                if ((held & HSD_BUTTON_A) != 0)\n                {\n                    DevCam_AdjustPan(cobj, stickX * -1, stickY * -1);\n                }\n                // adjust zoom\n                else if ((held & HSD_BUTTON_Y) != 0)\n                {\n                    DevCam_AdjustZoom(cobj, stickY);\n                }\n                // adjust rotate\n                else if ((held & HSD_BUTTON_B) != 0)\n                {\n                    MatchCamera *matchCam = MATCH_CAM;\n                    DevCam_AdjustRotate(cobj, &matchCam->devcam_rot, &matchCam->devcam_pos, stickX, stickY);\n                }\n            }\n        }\n    }\n\n    return;\n}\nvoid Lab_SelectCustomTDI(GOBJ *menu_gobj)\n{\n    MenuData *menu_data = menu_gobj->userdata;\n    EventMenu *curr_menu = menu_data->currMenu;\n    evMenu *menuAssets = event_vars->menu_assets;\n    GOBJ *event_gobj = event_vars->event_gobj;\n    LCancelData *event_data = event_gobj->userdata;\n    Arch_LabData *LabAssets = stc_lab_data;\n\n    // set menu state to wait\n    //curr_menu->state = EMSTATE_WAIT;\n\n    // create bg gobj\n    GOBJ *tdi_gobj = GObj_Create(0, 0, 0);\n    TDIData *userdata = calloc(sizeof(TDIData));\n    GObj_AddUserData(tdi_gobj, 4, HSD_Free, userdata);\n\n    // load menu joint\n    JOBJ *tdi_joint = JOBJ_LoadJoint(menuAssets->menu);\n    GObj_AddObject(tdi_gobj, 3, tdi_joint);                                     // add to gobj\n    GObj_AddGXLink(tdi_gobj, GXLink_Common, GXLINK_MENUMODEL, GXPRI_MENUMODEL); // add gx link\n    menu_data->custom_gobj_think = CustomTDI_Update;                            // set callback\n\n    // load current stick joints\n    JOBJ *stick_joint = JOBJ_LoadJoint(stc_lab_data->stick);\n    stick_joint->scale.X = 2;\n    stick_joint->scale.Y = 2;\n    stick_joint->scale.Z = 2;\n    stick_joint->trans.X = -6;\n    stick_joint->trans.Y = -6;\n    userdata->stick_curr[0] = stick_joint;\n    JOBJ_AddChild(tdi_gobj->hsd_object, stick_joint);\n    // current c stick\n    stick_joint = JOBJ_LoadJoint(stc_lab_data->cstick);\n    stick_joint->scale.X = 2;\n    stick_joint->scale.Y = 2;\n    stick_joint->scale.Z = 2;\n    stick_joint->trans.X = 6;\n    stick_joint->trans.Y = -6;\n    userdata->stick_curr[1] = stick_joint;\n    JOBJ_AddChild(tdi_gobj->hsd_object, stick_joint);\n\n    // create stick curr text\n    Text *text_curr = Text_CreateText(2, menu_data->canvas_menu);\n    userdata->text_curr = text_curr;\n    // enable align and kerning\n    text_curr->align = 0;\n    text_curr->kerning = 1;\n    // scale canvas\n    text_curr->scale.X = MENU_CANVASSCALE;\n    text_curr->scale.Y = MENU_CANVASSCALE;\n    text_curr->trans.Z = MENU_TEXTZ;\n    // create hit num\n    Text_AddSubtext(text_curr, -50, 185, &nullString);\n    // create lstick coords\n    for (int i = 0; i < 2; i++)\n    {\n        Text_AddSubtext(text_curr, -400, (80 + i * 40), &nullString);\n    }\n    // create cstick coords\n    for (int i = 0; i < 2; i++)\n    {\n        Text_AddSubtext(text_curr, 250, (80 + i * 40), &nullString);\n    }\n\n    // create prev sticks\n    for (int i = 0; i < TDI_DISPNUM; i++)\n    {\n        // left stick\n        JOBJ *prevstick_joint = JOBJ_LoadJoint(stc_lab_data->stick);\n        prevstick_joint->scale.X = 1;\n        prevstick_joint->scale.Y = 1;\n        prevstick_joint->scale.Z = 1;\n        prevstick_joint->rot.X = 0.4;\n        prevstick_joint->trans.X = -22 + (i * (55 / TDI_DISPNUM));\n        prevstick_joint->trans.Y = 10;\n        JOBJ_SetFlags(prevstick_joint, JOBJ_HIDDEN);\n        userdata->stick_prev[i][0] = prevstick_joint;\n        JOBJ_AddChild(tdi_gobj->hsd_object, prevstick_joint);\n\n        // cstick\n        prevstick_joint = JOBJ_LoadJoint(stc_lab_data->cstick);\n        prevstick_joint->scale.X = 1;\n        prevstick_joint->scale.Y = 1;\n        prevstick_joint->scale.Z = 1;\n        prevstick_joint->rot.X = 0.4;\n        prevstick_joint->trans.X = -18 + (i * (55 / TDI_DISPNUM));\n        prevstick_joint->trans.Y = 8;\n        JOBJ_SetFlags(prevstick_joint, JOBJ_HIDDEN);\n        userdata->stick_prev[i][1] = prevstick_joint;\n        JOBJ_AddChild(tdi_gobj->hsd_object, prevstick_joint);\n\n        // create text\n        Text_AddSubtext(text_curr, (-460 + (i * ((55 * 19.6) / TDI_DISPNUM))), -100, &nullString);\n    }\n\n    // create description text\n    Text_AddSubtext(text_curr, -460, 240, \"Input TDI angles for the CPU to use.\");\n    Text_AddSubtext(text_curr, -460, 285, \"A = Save Input  X = Delete Input  B = Return\");\n\n    // hide original menu\n    event_vars->hide_menu = 1;\n\n    // set pointers to custom gobj\n    menu_data->custom_gobj = tdi_gobj;\n    menu_data->custom_gobj_destroy = CustomTDI_Destroy;\n\n    return;\n\n    /*\n    // Change color\n    GXColor gx_color = TEXT_BGCOLOR;\n    popup_joint->dobj->mobj->mat->diffuse = gx_color;\n*/\n}\nvoid CustomTDI_Update(GOBJ *gobj)\n{\n    // get data\n    TDIData *tdi_data = gobj->userdata;\n    MenuData *menu_data = event_vars->menu_gobj->userdata;\n    LCancelData *event_data = event_vars->event_gobj->userdata;\n\n    // get pausing players inputs\n    HSD_Pad *pad = PadGet(menu_data->controller_index, PADGET_MASTER);\n    int inputs = pad->down;\n\n    // if press A, save stick\n    if ((inputs & HSD_BUTTON_A) != 0)\n    {\n        if (stc_tdi_val_num < TDI_HITNUM)\n        {\n            stc_tdi_vals[stc_tdi_val_num][0][0] = (pad->fstickX * 80);\n            stc_tdi_vals[stc_tdi_val_num][0][1] = (pad->fstickY * 80);\n            stc_tdi_vals[stc_tdi_val_num][1][0] = (pad->fsubstickX * 80);\n            stc_tdi_vals[stc_tdi_val_num][1][1] = (pad->fsubstickY * 80);\n            stc_tdi_val_num++;\n            SFX_PlayCommon(1);\n        }\n    }\n\n    // if press X, go back a hit\n    if ((inputs & HSD_BUTTON_X) != 0)\n    {\n        if (stc_tdi_val_num > 0)\n        {\n            stc_tdi_val_num--;\n            SFX_PlayCommon(0);\n        }\n    }\n\n    // if press B, exit\n    if ((inputs & HSD_BUTTON_B) != 0)\n    {\n        CustomTDI_Destroy(gobj);\n        return;\n    }\n\n    // update curr lstick\n    JOBJ *stick_curr = tdi_data->stick_curr[0];\n    stick_curr->rot.Y = pad->fstickX * 0.75;\n    stick_curr->rot.X = pad->fstickY * 0.75 * -1;\n    // update curr cstick\n    stick_curr = tdi_data->stick_curr[1];\n    stick_curr->rot.Y = pad->fsubstickX * 0.75;\n    stick_curr->rot.X = pad->fsubstickY * 0.75 * -1;\n\n    // Update curr stick coordinates\n    Text *text_curr = tdi_data->text_curr;\n    Text_SetText(text_curr, 0, \"Hit: %d\", stc_tdi_val_num + 1);\n    Text_SetText(text_curr, 1, \"X: %+.4f\", pad->fstickX);\n    Text_SetText(text_curr, 2, \"Y: %+.4f\", pad->fstickY);\n    Text_SetText(text_curr, 3, \"X: %+.4f\", pad->fsubstickX);\n    Text_SetText(text_curr, 4, \"Y: %+.4f\", pad->fsubstickY);\n\n    // display previous sticks\n    for (int i = 0; i < TDI_DISPNUM; i++)\n    {\n        JOBJ *lstick_prev = tdi_data->stick_prev[i][0];\n        JOBJ *cstick_prev = tdi_data->stick_prev[i][1];\n        int this_hit = i;\n        if (stc_tdi_val_num > TDI_DISPNUM)\n            this_hit = (stc_tdi_val_num - TDI_DISPNUM + i);\n\n        // show stick\n        if (i < stc_tdi_val_num)\n        {\n            // remove hidden flag\n            JOBJ_ClearFlags(lstick_prev, JOBJ_HIDDEN);\n            JOBJ_ClearFlags(cstick_prev, JOBJ_HIDDEN);\n\n            // update rotation\n            lstick_prev->rot.Y = ((float)(stc_tdi_vals[this_hit][0][0]) * 1 / 80) * 0.75;\n            lstick_prev->rot.X = ((float)(stc_tdi_vals[this_hit][0][1]) * 1 / 80) * 0.75 * -1;\n            cstick_prev->rot.Y = ((float)(stc_tdi_vals[this_hit][1][0]) * 1 / 80) * 0.75;\n            cstick_prev->rot.X = ((float)(stc_tdi_vals[this_hit][1][1]) * 1 / 80) * 0.75 * -1;\n\n            // update text\n            Text_SetText(text_curr, i + 5, \"Hit %d\", this_hit + 1);\n        }\n        // hide stick\n        else\n        {\n            // set hidden flag\n            JOBJ_SetFlags(lstick_prev, JOBJ_HIDDEN);\n            JOBJ_SetFlags(cstick_prev, JOBJ_HIDDEN);\n\n            Text_SetText(text_curr, i + 5, nullString);\n        }\n    }\n\n    // update jobj\n    JOBJ_SetMtxDirtySub(gobj->hsd_object);\n\n    return;\n}\nvoid CustomTDI_Destroy(GOBJ *gobj)\n{\n    // get data\n    TDIData *tdi_data = gobj->userdata;\n    MenuData *menu_data = event_vars->menu_gobj->userdata;\n    LCancelData *event_data = event_vars->event_gobj->userdata;\n\n    // set TDI to custom\n    if (stc_tdi_val_num > 0)\n        LabOptions_CPU[OPTCPU_TDI].option_val = CPUTDI_CUSTOM;\n    else\n        LabOptions_CPU[OPTCPU_TDI].option_val = CPUTDI_RANDOM;\n\n    // free text\n    Text_Destroy(tdi_data->text_curr);\n\n    // destroy\n    GObj_Destroy(gobj);\n\n    // show menu\n    event_vars->hide_menu = 0;\n    menu_data->custom_gobj = 0;\n    menu_data->custom_gobj_think = 0;\n    menu_data->custom_gobj_destroy = 0;\n\n    // play sfx\n    SFX_PlayCommon(0);\n\n    return;\n}\nvoid Inputs_GX(GOBJ *gobj, int pass)\n{\n    // only render when enabled and unpaused\n    if ((LabOptions_General[OPTGEN_INPUT].option_val == 1) && (Pause_CheckStatus(1) != 2))\n    {\n        GXLink_Common(gobj, pass);\n    }\n\n    return;\n}\nvoid Inputs_Think(GOBJ *gobj)\n{\n    InputData *input_data = gobj->userdata;\n\n    // update controllers\n    for (int i = 0; i < (sizeof(input_data->controller_joint) / 4); i++)\n    {\n        JOBJ *controller = input_data->controller_joint[i];\n\n        if (controller != 0)\n        {\n\n            // get port and controller data\n            int port = Fighter_GetControllerPort(i);\n            HSD_Pad *pad = PadGet(port, PADGET_ENGINE);\n\n            // move lstick\n            JOBJ *lstick_joint;\n            JOBJ_GetChild(controller, &lstick_joint, 10, -1);\n            lstick_joint->trans.X = (pad->fstickX * 2.3);\n            lstick_joint->trans.Y = (pad->fstickY * 2.3);\n\n            // move lstick\n            JOBJ *rstick_joint;\n            JOBJ_GetChild(controller, &rstick_joint, 8, -1);\n            rstick_joint->trans.X = (pad->fsubstickX * 2.3);\n            rstick_joint->trans.Y = (pad->fsubstickY * 2.3);\n\n            // move ltrigger\n            JOBJ *ltrig_joint;\n            JOBJ_GetChild(controller, &ltrig_joint, button_lookup[BTN_L].jobj, -1);\n            ltrig_joint->trans.X = (pad->ftriggerLeft * 0.5) + input_data->ltrig_origin.X;\n            ltrig_joint->trans.Z = (pad->ftriggerLeft * 1.5) + input_data->ltrig_origin.Y;\n\n            // move rtrigger\n            JOBJ *rtrig_joint;\n            JOBJ_GetChild(controller, &rtrig_joint, button_lookup[BTN_R].jobj, -1);\n            rtrig_joint->trans.X = (pad->ftriggerRight * -0.5) + input_data->rtrig_origin.X;\n            rtrig_joint->trans.Z = (pad->ftriggerRight * 1.5) + input_data->rtrig_origin.Y;\n\n            // update button colors\n            int held = pad->held;\n            for (int i = 0; i < (BTN_NUM); i++)\n            {\n\n                // Get buttons jobj and dobj from the lookup table\n                JOBJ *button_jobj;\n                JOBJ_GetChild(controller, &button_jobj, button_lookup[i].jobj, -1);\n                DOBJ *button_dobj = JOBJ_GetDObjChild(button_jobj, button_lookup[i].dobj);\n\n                // check if button is pressed\n                if (held & button_bits[i])\n                {\n                    // make white i guess for now\n                    GXColor color_pressed = INPUT_COLOR_PRESSED;\n                    button_dobj->mobj->mat->diffuse = color_pressed;\n                }\n                // not pressed, make the default color\n                else\n                {\n                    GXColor *color_released = &button_colors[i];\n                    button_dobj->mobj->mat->diffuse = *color_released;\n                }\n            }\n\n            JOBJ_SetMtxDirtySub(controller);\n        }\n    }\n\n    // toggle visibility\n    JOBJ *root = gobj->hsd_object;\n    if ((LabOptions_General[OPTGEN_INPUT].option_val == 1) && (Pause_CheckStatus(1) != 2))\n    {\n        Match_HideTimer();\n        JOBJ_ClearFlags(root, JOBJ_HIDDEN);\n    }\n    else if ((LabOptions_General[OPTGEN_INPUT].option_val == 0) && (Pause_CheckStatus(1) != 2))\n    {\n        Match_ShowTimer();\n        JOBJ_SetFlags(root, JOBJ_HIDDEN);\n    }\n\n    /*\n        // toggle timer visibility\n        if (LabOptions_General[OPTGEN_INPUT].option_val == 1)\n            Match_HideTimer();\n        else if (Pause_CheckStatus(1) != 2)\n            Match_ShowTimer();\n*/\n    return;\n}\nvoid Inputs_Init()\n{\n    // Create Input Display GOBJ\n    GOBJ *input_gobj = GObj_Create(0, 0, 0);\n    InputData *input_data = calloc(sizeof(InputData));\n    GObj_AddUserData(input_gobj, 4, HSD_Free, input_data);\n    GObj_AddProc(input_gobj, Inputs_Think, 4);\n\n    // alloc a dummy root jobj\n    JOBJDesc *root_desc = calloc(sizeof(JOBJDesc));\n    root_desc->flags = JOBJ_ROOT_XLU | JOBJ_ROOT_TEXEDGE;\n    root_desc->scale.X = 1;\n    root_desc->scale.Y = 1;\n    root_desc->scale.Z = 1;\n    JOBJ *root = JOBJ_LoadJoint(root_desc);\n\n    // init jobj pointers\n    for (int i = 0; i < (sizeof(input_data->controller_joint) / 4); i++)\n    {\n        input_data->controller_joint[i] = 0;\n    }\n\n    // count humans in this match\n    int hmn_count = 0;\n    for (int i = 0; i < 4; i++)\n    {\n        if (Fighter_GetSlotType(i) == 0)\n            hmn_count++;\n    }\n\n    // create X controllers\n    int found_origin = 0;\n    for (int i = 0; i < hmn_count; i++)\n    {\n\n        JOBJ *controller = JOBJ_LoadJoint(stc_lab_data->controller); // Load jobj\n        input_data->controller_joint[i] = controller;                // store jobj pointer\n\n        // Add to root\n        JOBJ_AddChild(root, controller);\n\n        if (found_origin == 0)\n        {\n            // save trigger origins\n            JOBJ *ltrig_jobj, *rtrig_jobj;\n            JOBJ_GetChild(controller, &ltrig_jobj, button_lookup[BTN_L].jobj, -1);\n            JOBJ_GetChild(controller, &rtrig_jobj, button_lookup[BTN_R].jobj, -1);\n            input_data->ltrig_origin.X = ltrig_jobj->trans.X;\n            input_data->ltrig_origin.Y = ltrig_jobj->trans.Z;\n            input_data->rtrig_origin.X = rtrig_jobj->trans.X;\n            input_data->rtrig_origin.Y = rtrig_jobj->trans.Z;\n\n            found_origin = 1;\n        }\n\n        /*\n        // adjust size based on the console / settings\n        if ((OSGetConsoleType() == OS_CONSOLE_DEVHW3) || (stc_HSD_VI->is_prog == 1)) // 480p / dolphin uses medium by default\n            LabOptions_InfoDisplay[OPT_SCALE].option_val = 1;\n        else // 480i on wii uses large (shitty composite!)\n            LabOptions_InfoDisplay[OPT_SCALE].option_val = 2;\n        */\n    }\n\n    GObj_AddObject(input_gobj, 3, root);                              // add to gobj\n    GObj_AddGXLink(input_gobj, Inputs_GX, INPUT_GXLINK, INPUT_GXPRI); // add gx link\n\n    return;\n}\n\n// Recording Functions\nGOBJ *Record_Init()\n{\n    // Create GOBJ\n    GOBJ *rec_gobj = GObj_Create(0, 7, 0);\n    // Add per frame process\n    GObj_AddProc(rec_gobj, Record_Think, 3);\n\n    // create cobj\n    GOBJ *cam_gobj = GObj_Create(19, 20, 0);\n    COBJDesc ***dmgScnMdls = File_GetSymbol(ACCESS_PTR(0x804d6d5c), 0x803f94d0);\n    COBJDesc *cam_desc = dmgScnMdls[1][0];\n    COBJ *rec_cobj = COBJ_LoadDesc(cam_desc);\n    // init camera\n    GObj_AddObject(cam_gobj, R13_U8(-0x3E55), rec_cobj);\n    GOBJ_InitCamera(cam_gobj, Record_CObjThink, RECCAM_GXPRI);\n    cam_gobj->cobj_links = RECCAM_COBJGXLINK;\n\n    evMenu *menuAssets = event_vars->menu_assets;\n    JOBJ *playback = JOBJ_LoadJoint(menuAssets->playback);\n\n    // save seek jobj\n    JOBJ *seek;\n    JOBJ_GetChild(playback, &seek, REC_SEEKJOINT, -1);\n    rec_data.seek_jobj = seek;\n\n    // save left and right seek bounds\n    JOBJ *seek_bound[2];\n    JOBJ_GetChild(playback, &seek_bound, REC_LEFTBOUNDJOINT, REC_RIGHTBOUNDJOINT, -1);\n    Vec3 seek_bound_pos;\n    JOBJ_GetWorldPosition(seek_bound[0], 0, &seek_bound_pos);\n    rec_data.seek_left = seek_bound_pos.X;\n    JOBJ_GetWorldPosition(seek_bound[1], 0, &seek_bound_pos);\n    rec_data.seek_right = seek_bound_pos.X;\n\n    // Add to gobj\n    GObj_AddObject(rec_gobj, 3, playback);\n    // Add gxlink\n    GObj_AddGXLink(rec_gobj, Record_GX, REC_GXLINK, GXPRI_RECJOINT);\n\n    // Create text\n    int canvas_index = Text_CreateCanvas(2, rec_gobj, 14, 15, 0, REC_GXLINK, GXPRI_RECTEXT, 19);\n    Text *text = Text_CreateText(2, canvas_index);\n    text->align = 1;\n    text->kerning = 1;\n    text->scale.X = INFDISPTEXT_SCALE;\n    text->scale.Y = INFDISPTEXT_SCALE;\n\n    // Get text positions\n    JOBJ *text_joint[2];\n    JOBJ_GetChild(playback, &text_joint, REC_LEFTTEXTJOINT, REC_RIGHTTEXTJOINT, -1);\n    Vec3 text_left, text_right;\n    JOBJ_GetWorldPosition(text_joint[0], 0, &text_left);\n    JOBJ_GetWorldPosition(text_joint[1], 0, &text_right);\n\n    // Create subtexts for each side\n    Text_AddSubtext(text, (text_left.X * 25), -(text_left.Y * 25), &nullString);\n    Text_AddSubtext(text, (text_right.X * 25), -(text_right.Y) * 25, &nullString);\n    rec_data.text = text;\n\n    // alloc rec_state\n    rec_state = calloc(sizeof(Savestate));\n    // set as not exist\n    rec_state->is_exist = 0;\n\n    // disable menu options\n    for (int i = 1; i < sizeof(LabOptions_Record) / sizeof(EventOption); i++)\n    {\n        LabOptions_Record[i].disable = 1;\n    }\n\n    // allocate input arrays\n    for (int i = 0; i < REC_SLOTS; i++)\n    {\n        rec_data.hmn_inputs[i] = calloc(sizeof(RecInputData));\n        rec_data.cpu_inputs[i] = calloc(sizeof(RecInputData));\n\n        // init frame this recording starts on\n        rec_data.hmn_inputs[i]->start_frame = -1;\n        rec_data.cpu_inputs[i]->start_frame = -1;\n    }\n\n    // init memcard stuff\n    Memcard_InitWorkArea();\n    Memcard_InitSnapshotList(HSD_MemAlloc(2112), HSD_MemAlloc(256064));\n\n    // Create snapshot cam\n    snap_image.img_ptr = 0;\n    GOBJ *snap_gobj = GObj_Create(18, 18, 0);\n    GOBJ_InitCamera(snap_gobj, Snap_CObjThink, 4);\n    GX_AllocImageData(&snap_image, EXP_SCREENSHOT_WIDTH, EXP_SCREENSHOT_HEIGHT, 4, 2006);\n    export_status = EXSTAT_NONE;\n\n    /*\n    // init dev text\n    int height = 18;\n    int width = 28;\n    int x = -50;\n    int y = 410;\n    DevText *dev_text = DevelopText_CreateDataTable(x, y, 0, width, height, HSD_MemAlloc(height * width * 2));\n    stc_devtext = dev_text;\n    DevelopText_Activate(0, dev_text);\n    dev_text->cursorBlink = 0;\n    GXColor color = {21, 20, 59, 135};\n    DevelopText_StoreBGColor(dev_text, &color);\n    DevelopText_StoreTextScale(dev_text, 7.5, 10);\n    */\n    return rec_gobj;\n}\nvoid Record_CObjThink(GOBJ *gobj)\n{\n    // hide UI if set to off\n    if ((rec_state->is_exist == 1) && ((LabOptions_Record[OPTREC_CPUMODE].option_val != 0) || (LabOptions_Record[OPTREC_HMNMODE].option_val != 0)))\n    {\n        CObjThink_Common(gobj);\n    }\n\n    return;\n}\nvoid Record_GX(GOBJ *gobj, int pass)\n{\n    // update UI position\n    // the reason im doing this here is because i want it to update in the menu\n    if (pass == 0)\n    {\n        // get hmn slot\n        int hmn_slot = LabOptions_Record[OPTREC_HMNSLOT].option_val;\n        if (hmn_slot == 0) // use random slot\n            hmn_slot = rec_data.hmn_rndm_slot;\n        else\n            hmn_slot--;\n\n        // get cpu slot\n        int cpu_slot = LabOptions_Record[OPTREC_CPUSLOT].option_val;\n        if (cpu_slot == 0) // use random slot\n            cpu_slot = rec_data.cpu_rndm_slot;\n        else\n            cpu_slot--;\n\n        RecInputData *hmn_inputs = rec_data.hmn_inputs[hmn_slot];\n        RecInputData *cpu_inputs = rec_data.cpu_inputs[cpu_slot];\n        JOBJ *seek = rec_data.seek_jobj;\n        Text *text = rec_data.text;\n\n        // get curr frame (the current position in the recording)\n        int curr_frame = Record_GetCurrFrame();\n        int end_frame = Record_GetEndFrame();\n\n        // hide seek bar during recording\n        if ((LabOptions_Record[OPTREC_CPUMODE].option_val == 2) || (LabOptions_Record[OPTREC_HMNMODE].option_val == 1))\n        {\n            JOBJ_SetFlags(seek, JOBJ_HIDDEN);\n\n            // correct record frame\n            if (curr_frame >= REC_LENGTH)\n                curr_frame = REC_LENGTH;\n\n            // update seek bar frames\n            Text_SetText(text, 0, \"%d\", curr_frame + 1);\n            Text_SetText(text, 1, &nullString);\n\n            // update color\n            GXColor text_color;\n            if (curr_frame == REC_LENGTH)\n            {\n                text_color.r = 255;\n                text_color.g = 57;\n                text_color.b = 62;\n            }\n            else if (((float)curr_frame / (float)REC_LENGTH) >= 0.75)\n            {\n                text_color.r = 255;\n                text_color.g = 124;\n                text_color.b = 36;\n            }\n            else\n            {\n                text_color.r = 255;\n                text_color.g = 255;\n                text_color.b = 255;\n            }\n            Text_SetColor(text, 0, &text_color);\n        }\n        // during playback\n        else\n        {\n            JOBJ_ClearFlags(seek, JOBJ_HIDDEN);\n\n            // if playing back with no recording, adjust both numbers\n            int local_frame_seek = curr_frame + 1;\n            if (curr_frame >= end_frame)\n            {\n                local_frame_seek = curr_frame + 1;\n                end_frame = curr_frame + 1;\n            }\n\n            // update seek bar position\n            float range = rec_data.seek_right - rec_data.seek_left;\n            float curr_pos;\n            curr_pos = (float)local_frame_seek / (float)end_frame;\n            seek->trans.X = rec_data.seek_left + (curr_pos * range);\n            JOBJ_ClearFlagsAll(seek, JOBJ_HIDDEN);\n            JOBJ_SetMtxDirtySub(seek);\n\n            // update seek bar frames\n            Text_SetText(text, 0, \"%d\", local_frame_seek);\n            Text_SetText(text, 1, \"%d\", end_frame);\n\n            // if random playback, hide frame count and bar\n            if ((LabOptions_Record[OPTREC_CPUSLOT].option_val == 0) || (LabOptions_Record[OPTREC_HMNSLOT].option_val == 0))\n            {\n                Text_SetText(text, 1, \"?\");          // hide count\n                JOBJ_SetFlagsAll(seek, JOBJ_HIDDEN); // hide bar\n            }\n\n            // update color\n            GXColor text_color;\n            text_color.r = 255;\n            text_color.g = 255;\n            text_color.b = 255;\n            Text_SetColor(text, 0, &text_color);\n        }\n    }\n\n    GXLink_Common(gobj, pass);\n\n    return;\n}\nvoid Record_Think(GOBJ *rec_gobj)\n{\n    // get current hmn recording slot\n    int hmn_slot = LabOptions_Record[OPTREC_HMNSLOT].option_val;\n    if (hmn_slot == 0) // use random slot\n        hmn_slot = rec_data.hmn_rndm_slot;\n    else\n        hmn_slot--;\n\n    // get current cpu recording slot\n    int cpu_slot = LabOptions_Record[OPTREC_CPUSLOT].option_val;\n    if (cpu_slot == 0) // use random slot\n        cpu_slot = rec_data.cpu_rndm_slot;\n    else\n        cpu_slot--;\n\n    RecInputData *hmn_inputs = rec_data.hmn_inputs[hmn_slot];\n    RecInputData *cpu_inputs = rec_data.cpu_inputs[cpu_slot];\n\n    // ensure the state exists\n    if (rec_state->is_exist == 1)\n    {\n        // get longest recording\n        int input_num = hmn_inputs->num;\n        if (cpu_inputs->num > hmn_inputs->num)\n            input_num = cpu_inputs->num;\n\n        // get curr frame (the current position in the recording)\n        int curr_frame = Record_GetCurrFrame();\n        int end_frame = Record_GetEndFrame();\n\n        // if at the end of the recording\n        if ((input_num != 0) && (curr_frame >= end_frame))\n        {\n\n            // but not during a recording/control\n            if ((LabOptions_Record[OPTREC_HMNMODE].option_val != 1) && (LabOptions_Record[OPTREC_CPUMODE].option_val != 1) && (LabOptions_Record[OPTREC_CPUMODE].option_val != 2))\n            {\n\n                // init flag\n                int is_loop = 0;\n\n                // check to auto reset\n                if ((LabOptions_Record[OPTREC_AUTOLOAD].option_val == 1))\n                {\n                    event_vars->Savestate_Load(rec_state);\n                    event_vars->game_timer = rec_state->frame + 1;\n                    is_loop = 1;\n                }\n\n                // check to loop inputs\n                else if ((LabOptions_Record[OPTREC_LOOP].option_val == 1))\n                {\n                    event_vars->game_timer = rec_state->frame + 1;\n                    is_loop = 1;\n                }\n\n                // if recording looped, check to re-roll random slot\n                if (is_loop == 1)\n                {\n                    // re-roll random slot\n                    if (LabOptions_Record[OPTREC_HMNSLOT].option_val == 0)\n                    {\n                        rec_data.hmn_rndm_slot = Record_GetRandomSlot(&rec_data.hmn_inputs);\n                    }\n                    if (LabOptions_Record[OPTREC_CPUSLOT].option_val == 0)\n                    {\n                        rec_data.cpu_rndm_slot = Record_GetRandomSlot(&rec_data.cpu_inputs);\n                    }\n                }\n            }\n        }\n\n        // check record mode for HMN\n        int hmn_mode = LabOptions_Record[OPTREC_HMNMODE].option_val;\n        if (hmn_mode > 0) // adjust mode\n            hmn_mode++;\n        Record_Update(0, hmn_inputs, hmn_mode);\n        // check record mode for CPU\n        int cpu_mode = LabOptions_Record[OPTREC_CPUMODE].option_val;\n        Record_Update(1, cpu_inputs, cpu_mode);\n    }\n    /*\n    GOBJ *cpu = Fighter_GetGObj(1);\n    FighterData *cpu_data = cpu->userdata;\n\n    DevText *dev_text = stc_devtext;\n    // clear text\n    DevelopText_EraseAllText(dev_text);\n    DevelopMode_ResetCursorXY(dev_text, 0, 0);\n    DevelopText_AddString(dev_text, \"isthrown: %d\\n\", cpu_data->flags.is_thrown);\n    */\n    return;\n}\nvoid Record_Update(int ply, RecInputData *input_data, int rec_mode)\n{\n    GOBJ *fighter = Fighter_GetGObj(ply);\n    FighterData *fighter_data = fighter->userdata;\n\n    // get curr frame (the time since saving positions)\n    int curr_frame = (event_vars->game_timer - rec_state->frame);\n\n    // get the frame the recording starts on. i actually hate this code and need to change how this works\n    int rec_start;\n    if (input_data->start_frame == -1) // case 1: recording didnt start, use current frame\n    {\n        rec_start = curr_frame - 1;\n    }\n    else // case 2: recording has started, use the frame saved\n    {\n        rec_start = input_data->start_frame - rec_state->frame;\n    }\n    int end_frame = rec_start + input_data->num;\n\n    // Get HSD Pad\n    HSD_Pad *pad = PadGet(fighter_data->player_controller_number, PADGET_ENGINE);\n\n    // if the current frame before the recording ends\n    if ((curr_frame) < (rec_start + REC_LENGTH))\n    {\n\n        switch (rec_mode)\n        {\n        case RECMODE_OFF:\n        {\n            break;\n        }\n        case RECMODE_CTRL:\n        {\n            break;\n        }\n        case RECMODE_REC:\n        {\n\n            // recording has started BUT the player has jumped back behind it, move the start frame back\n            if ((input_data->start_frame == -1) || (curr_frame < rec_start))\n            {\n                input_data->start_frame = (event_vars->game_timer - 1);\n                rec_start = curr_frame - 1;\n            }\n\n            // store inputs\n            int held = pad->held;\n            RecInputs *inputs = &input_data->inputs[curr_frame - 1];\n            inputs->btn_a = !!((held)&HSD_BUTTON_A);\n            inputs->btn_b = !!((held)&HSD_BUTTON_B);\n            inputs->btn_x = !!((held)&HSD_BUTTON_X);\n            inputs->btn_y = !!((held)&HSD_BUTTON_Y);\n            inputs->btn_L = !!((held)&HSD_TRIGGER_L);\n            inputs->btn_R = !!((held)&HSD_TRIGGER_R);\n            inputs->btn_Z = !!((held)&HSD_TRIGGER_Z);\n            inputs->btn_dpadup = !!((held)&HSD_BUTTON_DPAD_UP);\n\n            inputs->stickX = pad->stickX;\n            inputs->stickY = pad->stickY;\n            inputs->substickX = pad->substickX;\n            inputs->substickY = pad->substickY;\n\n            // trigger - find the one pressed down more\n            u8 trigger = pad->triggerLeft;\n            if (pad->triggerRight > trigger)\n                trigger = pad->triggerRight;\n            inputs->trigger = trigger;\n\n            // update input_num\n            input_data->num = (curr_frame - rec_start);\n\n            // clear inputs henceforth\n            //memset(&input_data->inputs[curr_frame + 1], 0, (REC_LENGTH - curr_frame) * sizeof(RecInputs));\n\n            break;\n        }\n        case RECMODE_PLAY:\n        {\n            // ensure we have an input for this frame\n            if ((curr_frame >= rec_start) && ((curr_frame - rec_start) <= (input_data->num)))\n            {\n                int held = 0;\n                RecInputs *inputs = &input_data->inputs[curr_frame - 1];\n                // read inputs\n                held |= inputs->btn_a << 8;\n                held |= inputs->btn_b << 9;\n                held |= inputs->btn_x << 10;\n                held |= inputs->btn_y << 11;\n                held |= inputs->btn_L << 6;\n                held |= inputs->btn_R << 5;\n                held |= inputs->btn_Z << 4;\n                held |= inputs->btn_dpadup << 3;\n                pad->held = held;\n\n                // stick signed bytes\n                pad->stickX = inputs->stickX;\n                pad->stickY = inputs->stickY;\n                pad->substickX = inputs->substickX;\n                pad->substickY = inputs->substickY;\n\n                // stick floats\n                pad->fstickX = ((float)inputs->stickX / 80);\n                pad->fstickY = ((float)inputs->stickY / 80);\n                pad->fsubstickX = ((float)inputs->substickX / 80);\n                pad->fsubstickY = ((float)inputs->substickY / 80);\n\n                // trigger byte\n                pad->triggerRight = inputs->trigger;\n                pad->triggerLeft = 0;\n\n                // trigger float\n                pad->ftriggerRight = ((float)inputs->trigger / 255);\n                pad->ftriggerLeft = 0;\n            }\n            break;\n        }\n        }\n    }\n\n    return;\n}\nvoid Record_InitState(GOBJ *menu_gobj)\n{\n    if (event_vars->Savestate_Save(rec_state))\n    {\n\n        Record_OnSuccessfulSave();\n    }\n    return;\n}\nvoid Record_RestoreState(GOBJ *menu_gobj)\n{\n    event_vars->Savestate_Load(rec_state);\n\n    return;\n}\nvoid Record_ChangeHMNSlot(GOBJ *menu_gobj, int value)\n{\n    // upon changing to random\n    if (value == 0)\n    {\n        // if set to record\n        if (LabOptions_Record[OPTREC_HMNMODE].option_val == 1)\n        {\n            // change to slot 1\n            LabOptions_Record[OPTREC_HMNSLOT].option_val = 1;\n        }\n\n        // update random slot\n        else\n        {\n            rec_data.hmn_rndm_slot = Record_GetRandomSlot(&rec_data.hmn_inputs);\n        }\n    }\n\n    // reload save\n    event_vars->Savestate_Load(rec_state);\n\n    return;\n}\nvoid Record_ChangeCPUSlot(GOBJ *menu_gobj, int value)\n{\n    // upon changing to random\n    if (value == 0)\n    {\n        // if set to record\n        if (LabOptions_Record[OPTREC_CPUMODE].option_val == 2)\n        {\n            // change to slot 1\n            LabOptions_Record[OPTREC_CPUSLOT].option_val = 1;\n        }\n\n        // update random slot\n        else\n        {\n            rec_data.cpu_rndm_slot = Record_GetRandomSlot(&rec_data.cpu_inputs);\n        }\n    }\n\n    // reload save\n    event_vars->Savestate_Load(rec_state);\n\n    return;\n}\nvoid Record_ChangeHMNMode(GOBJ *menu_gobj, int value)\n{\n    // upon changing to record\n    if (value == 1)\n    {\n        // if set to random\n        if (LabOptions_Record[OPTREC_HMNSLOT].option_val == 0)\n        {\n            LabOptions_Record[OPTREC_HMNSLOT].option_val = 1;\n        }\n    }\n\n    // upon changing to playback\n    if (value == 2)\n    {\n        event_vars->Savestate_Load(rec_state);\n    }\n\n    // disable loop options if recording is in use\n    if ((LabOptions_Record[OPTREC_HMNMODE].option_val != 1) && (LabOptions_Record[OPTREC_CPUMODE].option_val != 2))\n    {\n        LabOptions_Record[OPTREC_LOOP].disable = 0;\n        LabOptions_Record[OPTREC_AUTOLOAD].disable = 0;\n    }\n    else\n    {\n        LabOptions_Record[OPTREC_LOOP].disable = 1;\n        LabOptions_Record[OPTREC_AUTOLOAD].disable = 1;\n    }\n\n    return;\n}\nvoid Record_ChangeCPUMode(GOBJ *menu_gobj, int value)\n{\n    // upon changing to record\n    if (value == 2)\n    {\n        // if set to random\n        if (LabOptions_Record[OPTREC_CPUSLOT].option_val == 0)\n        {\n            // change to slot 1\n            LabOptions_Record[OPTREC_CPUSLOT].option_val = 1;\n        }\n    }\n\n    // upon toggling playback\n    if (value == 3)\n    {\n        event_vars->Savestate_Load(rec_state);\n    }\n\n    // disable loop options if recording is in use\n    if ((LabOptions_Record[OPTREC_HMNMODE].option_val != 1) && (LabOptions_Record[OPTREC_CPUMODE].option_val != 2))\n    {\n        LabOptions_Record[OPTREC_LOOP].disable = 0;\n        LabOptions_Record[OPTREC_AUTOLOAD].disable = 0;\n    }\n    else\n    {\n        LabOptions_Record[OPTREC_LOOP].disable = 1;\n        LabOptions_Record[OPTREC_AUTOLOAD].disable = 1;\n    }\n\n    return;\n}\nint Record_GetRandomSlot(RecInputData **input_data)\n{\n    // create array of slots in use\n    u8 slot_num = 0;\n    u8 arr[REC_SLOTS];\n    for (int i = 0; i < REC_SLOTS; i++)\n    {\n        // if this recording slot is in use\n        if (input_data[i]->num != 0)\n        {\n            arr[slot_num] = i;\n            slot_num++;\n        }\n    }\n\n    // ensure at least one slot found\n    if (slot_num == 0)\n    {\n        return 0;\n    }\n\n    // get random slot in use\n    return arr[(HSD_Randi(slot_num))];\n}\nint Record_GetCurrFrame()\n{\n    return (event_vars->game_timer - 1) - rec_state->frame;\n}\nint Record_GetEndFrame()\n{\n\n    // get hmn slot\n    int hmn_slot = LabOptions_Record[OPTREC_HMNSLOT].option_val;\n    if (hmn_slot == 0) // use random slot\n        hmn_slot = rec_data.hmn_rndm_slot;\n    else\n        hmn_slot--;\n\n    // get cpu slot\n    int cpu_slot = LabOptions_Record[OPTREC_CPUSLOT].option_val;\n    if (cpu_slot == 0) // use random slot\n        cpu_slot = rec_data.cpu_rndm_slot;\n    else\n        cpu_slot--;\n\n    int curr_frame = Record_GetCurrFrame();\n    RecInputData *hmn_inputs = rec_data.hmn_inputs[hmn_slot];\n    RecInputData *cpu_inputs = rec_data.cpu_inputs[cpu_slot];\n\n    // get what frame the longest recording ends on (savestate frame + recording start frame + recording time)\n    int hmn_end_frame = 0;\n    int cpu_end_frame = 0;\n    if (hmn_inputs->start_frame != -1) // ensure a recording exists\n        hmn_end_frame = (hmn_inputs->start_frame + hmn_inputs->num);\n    if (cpu_inputs->start_frame != -1) // ensure a recording exists\n        cpu_end_frame = (cpu_inputs->start_frame + cpu_inputs->num);\n\n    // find the larger recording\n    RecInputData *input_data = hmn_inputs;\n    if (cpu_end_frame > hmn_end_frame)\n        input_data = cpu_inputs;\n\n    // get the frame the recording starts on. i actually hate this code and need to change how this works\n    int rec_start;\n    if (input_data->start_frame == -1) // case 1: recording didnt start, use current frame\n        rec_start = curr_frame - 1;\n    else // case 2: recording has started, use the frame saved\n        rec_start = input_data->start_frame - rec_state->frame;\n\n    // get end frame\n    int end_frame = rec_start + input_data->num;\n\n    return end_frame;\n}\nvoid Record_OnSuccessfulSave()\n{\n    // enable other options\n    for (int i = 1; i < sizeof(LabOptions_Record) / sizeof(EventOption); i++)\n    {\n        LabOptions_Record[i].disable = 0;\n    }\n\n    // clear slots\n    for (int i = 0; i < REC_SLOTS; i++)\n    {\n        // clear data\n        memset(rec_data.hmn_inputs[i], 0, sizeof(RecInputData));\n        memset(rec_data.cpu_inputs[i], 0, sizeof(RecInputData));\n\n        // init frame this recording starts on\n        rec_data.hmn_inputs[i]->start_frame = -1;\n        rec_data.cpu_inputs[i]->start_frame = -1;\n    }\n\n    // init settings\n    LabOptions_Record[OPTREC_HMNMODE].option_val = 0; // set hmn to off\n    LabOptions_Record[OPTREC_HMNSLOT].option_val = 1; // set hmn to slot 1\n    LabOptions_Record[OPTREC_CPUMODE].option_val = 0; // set cpu to off\n    LabOptions_Record[OPTREC_CPUSLOT].option_val = 1; // set cpu to slot 1\n\n    // also save to personal savestate\n    event_vars->Savestate_Save(event_vars->savestate);\n\n    // take screenshot\n    snap_status = 1;\n\n    return;\n}\nvoid Memcard_Wait()\n{\n\n    while (stc_memcard_work->is_done == 0)\n    {\n        blr2();\n    }\n\n    return;\n}\nvoid Record_MemcardLoad(int slot, int file_no)\n{\n    // search card for this save file\n    u8 file_found = 0;\n    char filename[32];\n    int file_size;\n    s32 memSize, sectorSize;\n    if (CARDProbeEx(slot, &memSize, &sectorSize) == CARD_RESULT_READY)\n    {\n        // mount card\n        stc_memcard_work->is_done = 0;\n        if (CARDMountAsync(slot, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY)\n        {\n            // check card\n            Memcard_Wait();\n            stc_memcard_work->is_done = 0;\n            if (CARDCheckAsync(slot, Memcard_RemovedCallback) == CARD_RESULT_READY)\n            {\n                Memcard_Wait();\n\n                // search for nth file with name TM_DEBUG\n                int tmrec_num = 0;\n                for (int i = 0; i < CARD_MAX_FILE; i++)\n                {\n\n                    CARDStat card_stat;\n\n                    if (CARDGetStatus(slot, i, &card_stat) == CARD_RESULT_READY)\n                    {\n                        // check company code\n                        if (strncmp(os_info->company, card_stat.company, sizeof(os_info->company)) == 0)\n                        {\n                            // check game name\n                            if (strncmp(os_info->gameName, card_stat.gameName, sizeof(os_info->gameName)) == 0)\n                            {\n                                // check file name\n                                if (strncmp(\"TMREC\", card_stat.fileName, 5) == 0)\n                                {\n\n                                    // if the desired file\n                                    if (tmrec_num == file_no)\n                                    {\n                                        file_found = 1;\n                                        memcpy(&filename, card_stat.fileName, sizeof(filename)); // copy filename to load after this\n                                        file_size = card_stat.length;\n                                        break;\n                                    }\n\n                                    // increment tmrec num\n                                    tmrec_num++;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            CARDUnmount(slot);\n            stc_memcard_work->is_done = 0;\n        }\n    }\n\n    // if found, load it\n    if (file_found == 1)\n    {\n\n        int load_pre_tick = OSGetTick();\n\n        // setup load\n        MemcardSave memcard_save;\n        memcard_save.data = HSD_MemAlloc(file_size);\n        memcard_save.x4 = 3;\n        memcard_save.size = file_size;\n        memcard_save.xc = -1;\n        Memcard_LoadSnapshot(slot, filename, &memcard_save, &stc_memcard_info->file_name, 0, 0, 0);\n\n        // wait to load\n        int memcard_status = Memcard_CheckStatus();\n        while (memcard_status == 11)\n        {\n            memcard_status = Memcard_CheckStatus();\n        }\n\n        // if file loaded successfully\n        if (memcard_status == 0)\n        {\n\n            // enable other options\n            for (int i = 1; i < sizeof(LabOptions_Record) / sizeof(EventOption); i++)\n            {\n                LabOptions_Record[i].disable = 0;\n            }\n\n            // take screenshot\n            snap_status = 1;\n\n            // begin unpacking\n            u8 *transfer_buf = memcard_save.data;\n            ExportHeader *header = transfer_buf;\n            u8 *compressed_recording = transfer_buf + header->lookup.ofst_recording;\n            RGB565 *img = transfer_buf + header->lookup.ofst_screenshot;\n            ExportMenuSettings *menu_settings = transfer_buf + header->lookup.ofst_menusettings;\n            OSReport(\"rec: ft %d vs ft %d on stage %d\\n\", header->metadata.hmn, header->metadata.cpu, header->metadata.stage_internal);\n\n            // decompress\n            RecordingSave *loaded_recsave = calloc(sizeof(RecordingSave) * 1.06);\n            lz77_decompress(compressed_recording, loaded_recsave);\n\n            // copy buffer to savestate\n            memcpy(rec_state, &loaded_recsave->savestate, sizeof(Savestate));\n\n            // restore controller indices\n            rec_state->ft_state[0].player_block.controller = stc_hmn_controller;\n            rec_state->ft_state[1].player_block.controller = stc_cpu_controller;\n\n            // load state\n            event_vars->Savestate_Load(rec_state);\n\n            // copy recordings\n            for (int i = 0; i < REC_SLOTS; i++)\n            {\n                memcpy(rec_data.hmn_inputs[i], &loaded_recsave->hmn_inputs[i], sizeof(RecInputData));\n                memcpy(rec_data.cpu_inputs[i], &loaded_recsave->cpu_inputs[i], sizeof(RecInputData));\n            }\n\n            HSD_Free(loaded_recsave);\n\n            // copy recording settings\n            LabOptions_Record[OPTREC_HMNMODE].option_val = menu_settings->hmn_mode;\n            LabOptions_Record[OPTREC_HMNSLOT].option_val = menu_settings->hmn_slot;\n            LabOptions_Record[OPTREC_CPUMODE].option_val = menu_settings->cpu_mode;\n            LabOptions_Record[OPTREC_CPUSLOT].option_val = menu_settings->cpu_slot;\n            LabOptions_Record[OPTREC_LOOP].option_val = menu_settings->loop_inputs;\n            LabOptions_Record[OPTREC_AUTOLOAD].option_val = menu_settings->auto_restore;\n\n            // enter recording menu\n            MenuData *menu_data = event_vars->menu_gobj->userdata;\n            EventMenu *curr_menu = menu_data->currMenu;\n            curr_menu->state = EMSTATE_OPENSUB;\n            // update curr_menu\n            EventMenu *next_menu = curr_menu->options[2].menu;\n            next_menu->prev = curr_menu;\n            next_menu->state = EMSTATE_FOCUS;\n            curr_menu = next_menu;\n            menu_data->currMenu = curr_menu;\n\n            // save to personal savestate\n            event_vars->Savestate_Save(event_vars->savestate);\n        }\n\n        HSD_Free(memcard_save.data);\n\n        int load_post_tick = OSGetTick();\n        int load_time = OSTicksToMilliseconds(load_post_tick - load_pre_tick);\n        OSReport(\"processed memcard load in %dms\\n\", load_time);\n    }\n\n    return;\n}\nint Record_MenuThink(GOBJ *menu_gobj)\n{\n\n    int is_update = 1;\n\n    // check to run export logic\n    if (export_status != EXSTAT_NONE)\n    {\n        is_update = Record_ExportThink();\n    }\n\n    return is_update;\n}\nvoid Record_StartExport(GOBJ *menu_gobj)\n{\n\n    export_status = EXSTAT_REQSAVE;\n\n    return;\n}\nvoid Snap_CObjThink(GOBJ *gobj)\n{\n\n    // logic based on state\n    switch (snap_status)\n    {\n    case (1):\n    {\n        // take snap\n        HSD_ImageDescCopyFromEFB(&snap_image, 0, 0, 0);\n        snap_status = 0;\n        OSReport(\"got snap!\\n\");\n\n        break;\n    }\n    }\n\n    return;\n}\nvoid Savestates_Update()\n{\n\n    /*\n    So i have code to do this in events.c that runs based a variable in\n    the EventDesc, but i need to execute code directly after loading state\n    so im just gonna do this here...\n    */\n\n    // not when pause menu is showing\n    if (Pause_CheckStatus(1) != 2)\n    {\n        // loop through all humans\n        for (int i = 0; i < 6; i++)\n        {\n            // check if fighter exists\n            GOBJ *fighter = Fighter_GetGObj(i);\n            if (fighter != 0)\n            {\n                // get fighter data\n                FighterData *fighter_data = fighter->userdata;\n                HSD_Pad *pad = PadGet(fighter_data->ply, PADGET_MASTER);\n\n                // check for savestate\n                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);\n                if (((pad->down & HSD_BUTTON_DPAD_RIGHT) != 0) && ((pad->held & (blacklist)) == 0))\n                {\n                    // save state\n                    event_vars->Savestate_Save(event_vars->savestate);\n                }\n                else if (((pad->down & HSD_BUTTON_DPAD_LEFT) != 0) && ((pad->held & (blacklist)) == 0))\n                {\n                    // load state\n                    event_vars->Savestate_Load(event_vars->savestate);\n\n                    // re-roll random slot\n                    if (LabOptions_Record[OPTREC_HMNSLOT].option_val == 0)\n                    {\n                        rec_data.hmn_rndm_slot = Record_GetRandomSlot(&rec_data.hmn_inputs);\n                    }\n                    if (LabOptions_Record[OPTREC_CPUSLOT].option_val == 0)\n                    {\n                        rec_data.cpu_rndm_slot = Record_GetRandomSlot(&rec_data.cpu_inputs);\n                    }\n                }\n            }\n        }\n    }\n\n    return;\n}\n\n// Export functions\nstatic char *keyboard_rows[2][4] = {\n    {\"1234567890\", \"qwertyuiop\", \"asdfghjkl-\", \"zxcvbnm,./\"},\n    {\"!@#$%^&*()\", \"QWERTYUIOP\", \"ASDFGHJKL: \", \"ZXCVBNM<>?\"}};\nint RowPixelToBlockPixel(int pixel_x, int pixel_y, int width, int height)\n{\n\n    // get block width and height\n    int block_width = divide_roundup(width, 4);\n\n    // get block num\n    int block_num = ((pixel_y / 4) * block_width) + (pixel_x / 4);\n\n    // get pixels x and y within this block\n    int block_pos_x = pixel_x % 4;\n    int block_pos_y = pixel_y % 4;\n\n    // get block pixel index\n    int block_pixel = (block_num * 16) + (block_pos_y * 4) + block_pos_x;\n\n    return block_pixel;\n}\nvoid ImageScale(RGB565 *out_img, RGB565 *in_img, int OutWidth, int OutHeight, int InWidth, int InHeight)\n{\n\n    int x_ratio = (InWidth / OutWidth);\n    int y_ratio = (InHeight / OutHeight);\n    int px, py;\n    int in_pixel, out_pixel;\n\n    for (int y = 0; y < (OutHeight); y++)\n    {\n        for (int x = 0; x < (OutWidth); x++)\n        {\n            px = x * x_ratio;\n            py = y * y_ratio;\n            in_pixel = RowPixelToBlockPixel(x, y, OutWidth, OutHeight);\n            out_pixel = RowPixelToBlockPixel(px, py, InWidth, InHeight);\n            out_img[in_pixel] = in_img[out_pixel];\n        }\n    }\n\n    return;\n}\nvoid Export_Init(GOBJ *menu_gobj)\n{\n\n    MenuData *menu_data = menu_gobj->userdata;\n    EventMenu *curr_menu = menu_data->currMenu;\n    evMenu *menuAssets = event_vars->menu_assets;\n\n    // create gobj\n    GOBJ *export_gobj = GObj_Create(0, 0, 0);\n    ExportData *export_data = calloc(sizeof(ExportData));\n    GObj_AddUserData(export_gobj, 4, HSD_Free, export_data);\n\n    // load menu joint\n    JOBJ *export_joint = JOBJ_LoadJoint(stc_lab_data->export_menu);\n    GObj_AddObject(export_gobj, 3, export_joint);                                  // add to gobj\n    GObj_AddGXLink(export_gobj, GXLink_Common, GXLINK_MENUMODEL, GXPRI_MENUMODEL); // add gx link\n    menu_data->custom_gobj_think = Export_Think;                                   // set callback\n\n    // save jobj pointers\n    JOBJ_GetChild(export_joint, &export_data->memcard_jobj[0], EXP_MEMCARDAJOBJ, -1);\n    JOBJ_GetChild(export_joint, &export_data->memcard_jobj[1], EXP_MEMCARDBJOBJ, -1);\n    JOBJ_GetChild(export_joint, &export_data->screenshot_jobj, EXP_SCREENSHOTJOBJ, -1);\n    JOBJ_GetChild(export_joint, &export_data->textbox_jobj, EXP_TEXTBOXJOBJ, -1);\n\n    // hide all\n    JOBJ_SetFlags(export_data->memcard_jobj[0], JOBJ_HIDDEN);\n    JOBJ_SetFlags(export_data->memcard_jobj[1], JOBJ_HIDDEN);\n    JOBJ_SetFlags(export_data->screenshot_jobj, JOBJ_HIDDEN);\n    JOBJ_SetFlags(export_data->textbox_jobj, JOBJ_HIDDEN);\n\n    // alloc a buffer for all of the recording data\n    RecordingSave *temp_rec_save = calloc(sizeof(RecordingSave));\n\n    // copy match data to buffer\n    memcpy(&temp_rec_save->match_data, &stc_match->match, sizeof(MatchInit));\n    // copy savestate to buffer\n    memcpy(&temp_rec_save->savestate, rec_state, sizeof(Savestate));\n    // copy recordings\n    for (int i = 0; i < REC_SLOTS; i++)\n    {\n        memcpy(&temp_rec_save->hmn_inputs[i], rec_data.hmn_inputs[i], sizeof(RecInputData));\n        memcpy(&temp_rec_save->cpu_inputs[i], rec_data.cpu_inputs[i], sizeof(RecInputData));\n    }\n\n    // compress all recording data\n    u8 *recording_buffer = calloc(sizeof(RecordingSave));\n    int compress_size = Export_Compress(recording_buffer, temp_rec_save, sizeof(RecordingSave));\n    HSD_Free(temp_rec_save); // free original data buffer\n\n    // resize screenshot\n    int img_size = GXGetTexBufferSize(RESIZE_WIDTH, RESIZE_HEIGHT, 4, 0, 0);\n    RGB565 *orig_img = snap_image.img_ptr;\n    RGB565 *new_img = calloc(img_size);\n    export_data->scaled_image = new_img;\n    ImageScale(new_img, orig_img, RESIZE_WIDTH, RESIZE_HEIGHT, EXP_SCREENSHOT_WIDTH, EXP_SCREENSHOT_HEIGHT);\n    OSReport(\"scaled image to %d kb\\n\", (img_size / 1000));\n    resized_image.img_ptr = new_img;                                            // store pointer to resized image\n    export_data->screenshot_jobj->dobj->mobj->tobj->imagedesc = &resized_image; // replace pointer to imagedesc\n\n    // get curr date\n    OSCalendarTime td;\n    OSTicksToCalendarTime(OSGetTime(), &td);\n\n    // alloc a buffer to transfer to memcard\n    stc_transfer_buf_size = sizeof(ExportHeader) + img_size + sizeof(ExportMenuSettings) + compress_size;\n    stc_transfer_buf = calloc(stc_transfer_buf_size);\n\n    // init header\n    ExportHeader *header = stc_transfer_buf;\n    header->metadata.version = REC_VERS;\n    header->metadata.image_width = RESIZE_WIDTH;\n    header->metadata.image_height = RESIZE_HEIGHT;\n    header->metadata.image_fmt = 4;\n    header->metadata.hmn = Fighter_GetExternalID(0);\n    header->metadata.hmn_costume = Fighter_GetCostumeID(0);\n    header->metadata.cpu = Fighter_GetExternalID(1);\n    header->metadata.cpu_costume = Fighter_GetCostumeID(1);\n    header->metadata.stage_external = Stage_GetExternalID();\n    header->metadata.stage_internal = Stage_ExternalToInternal(header->metadata.stage_external);\n    header->metadata.month = td.mon + 1;\n    header->metadata.day = td.mday;\n    header->metadata.year = td.year;\n    header->metadata.hour = td.hour;\n    header->metadata.minute = td.min;\n    header->metadata.second = td.sec;\n    header->lookup.ofst_screenshot = sizeof(ExportHeader);\n    header->lookup.ofst_recording = sizeof(ExportHeader) + img_size;\n    header->lookup.ofst_menusettings = sizeof(ExportHeader) + img_size + compress_size;\n    OSReport(\"prepared buffer of %d kb\\n\", (stc_transfer_buf_size / 1000));\n\n    // copy data to buffer\n    // image\n    memcpy(stc_transfer_buf + header->lookup.ofst_screenshot, new_img, img_size);\n    // menu settings\n    ExportMenuSettings *menu_settings = stc_transfer_buf + header->lookup.ofst_menusettings;\n    menu_settings->hmn_mode = LabOptions_Record[OPTREC_HMNMODE].option_val;\n    menu_settings->hmn_slot = LabOptions_Record[OPTREC_HMNSLOT].option_val;\n    menu_settings->cpu_mode = LabOptions_Record[OPTREC_CPUMODE].option_val;\n    menu_settings->cpu_slot = LabOptions_Record[OPTREC_CPUSLOT].option_val;\n    menu_settings->loop_inputs = LabOptions_Record[OPTREC_LOOP].option_val;\n    menu_settings->auto_restore = LabOptions_Record[OPTREC_AUTOLOAD].option_val;\n    // recording data\n    memcpy(stc_transfer_buf + header->lookup.ofst_recording, recording_buffer, compress_size); // compressed recording\n\n    // free compresed data buffer\n    HSD_Free(recording_buffer);\n\n    // alloc filename buffer\n    export_data->filename_buffer = calloc(32 + 2); // +2 for terminator and cursor\n\n    // initialize memcard menu\n    Export_SelCardInit(export_gobj);\n\n    event_vars->hide_menu = 1;                       // hide original menu\n    menu_data->custom_gobj = export_gobj;            // set custom gobj\n    menu_data->custom_gobj_think = Export_Think;     // set think function\n    menu_data->custom_gobj_destroy = Export_Destroy; // set destroy function\n\n    return;\n}\nint Export_Think(GOBJ *export_gobj)\n{\n    ExportData *export_data = export_gobj->userdata;\n    int can_unpause = 0;\n\n    switch (export_data->menu_index)\n    {\n    case (EXMENU_SELCARD):\n    {\n        can_unpause = Export_SelCardThink(export_gobj);\n        break;\n    }\n    case (EXMENU_NAME):\n    {\n        can_unpause = Export_EnterNameThink(export_gobj);\n        break;\n    }\n    case (EXMENU_CONFIRM):\n    {\n        can_unpause = Export_ConfirmThink(export_gobj);\n        break;\n    }\n    }\n\n    return can_unpause;\n}\nvoid Export_Destroy(GOBJ *export_gobj)\n{\n    ExportData *export_data = export_gobj->userdata;\n    MenuData *menu_data = event_vars->menu_gobj->userdata;\n\n    switch (export_data->menu_index)\n    {\n    case (EXMENU_SELCARD):\n    {\n        Export_SelCardExit(export_gobj);\n        break;\n    }\n    case (EXMENU_NAME):\n    {\n        Export_EnterNameExit(export_gobj);\n        break;\n    }\n    }\n\n    // free buffer allocs\n    HSD_Free(stc_transfer_buf);\n    HSD_Free(export_data->filename_buffer);\n    HSD_Free(export_data->scaled_image);\n\n    // destroy gobj\n    GObj_Destroy(export_gobj);\n\n    // show menu\n    event_vars->hide_menu = 0;\n    menu_data->custom_gobj = 0;\n    menu_data->custom_gobj_think = 0;\n    menu_data->custom_gobj_destroy = 0;\n\n    return;\n}\nvoid Export_SelCardInit(GOBJ *export_gobj)\n{\n    ExportData *export_data = export_gobj->userdata;\n    MenuData *menu_data = event_vars->menu_gobj->userdata;\n\n    // show menu jobjs\n    JOBJ_ClearFlags(export_data->memcard_jobj[0], JOBJ_HIDDEN);\n    JOBJ_ClearFlags(export_data->memcard_jobj[1], JOBJ_HIDDEN);\n\n    // create text\n    Text *text_misc = Text_CreateText(2, menu_data->canvas_menu);\n    export_data->text_misc = text_misc;\n    // enable align and kerning\n    text_misc->align = 1;\n    text_misc->kerning = 1;\n    // scale canvas\n    text_misc->scale.X = MENU_CANVASSCALE;\n    text_misc->scale.Y = MENU_CANVASSCALE;\n    text_misc->trans.Z = MENU_TEXTZ;\n\n    // create title text\n    Text *text_title = Text_CreateText(2, menu_data->canvas_menu);\n    export_data->text_title = text_title;\n    // enable align and kerning\n    text_title->align = 0;\n    text_title->kerning = 1;\n    // scale canvas\n    text_title->trans.X = -23;\n    text_title->trans.Y = -18;\n    text_title->scale.X = MENU_CANVASSCALE * 2;\n    text_title->scale.Y = MENU_CANVASSCALE * 2;\n    text_title->trans.Z = MENU_TEXTZ;\n\n    // create desc text\n    Text *text_desc = Text_CreateText(2, menu_data->canvas_menu);\n    export_data->text_desc = text_desc;\n    // enable align and kerning\n    text_desc->align = 0;\n    text_desc->kerning = 1;\n    // scale canvas\n    text_desc->trans.X = -23;\n    text_desc->trans.Y = 12;\n    text_desc->scale.X = MENU_CANVASSCALE;\n    text_desc->scale.Y = MENU_CANVASSCALE;\n    text_desc->trans.Z = MENU_TEXTZ;\n\n    Text_AddSubtext(text_title, 0, 0, \"Select a Memory Card\"); // add title\n    Text_AddSubtext(text_desc, 0, 0, \"\");                      // add description\n\n    // add dummy text\n    Text_AddSubtext(text_misc, -165, 67, \"Slot A\");\n    Text_AddSubtext(text_misc, 165, 67, \"Slot B\");\n\n    // init memcard inserted status\n    for (int i = 0; i < 2; i++)\n    {\n        export_data->is_inserted[i] = 0;\n    }\n\n    // init cursor\n    export_data->menu_index = EXMENU_SELCARD;\n    export_data->slot = 0;\n\n    return;\n}\nint Export_SelCardThink(GOBJ *export_gobj)\n{\n\n    ExportData *export_data = export_gobj->userdata;\n\n    int req_blocks = (divide_roundup(stc_transfer_buf_size, 8192) + 1);\n\n    // get pausing players inputs\n    HSD_Pad *pad = PadGet(stc_hmn_controller, PADGET_MASTER);\n    int inputs = pad->down;\n\n    // update memcard info\n    for (int i = 1; i >= 0; i--)\n    {\n        // probe slot\n        u8 is_inserted;\n\n        s32 memSize, sectorSize;\n        if (CARDProbeEx(i, &memSize, &sectorSize) == CARD_RESULT_READY)\n        {\n            // if it was just inserted, get info\n            if (export_data->is_inserted[i] == 0)\n            {\n\n                // mount card\n                stc_memcard_work->is_done = 0;\n                if (CARDMountAsync(i, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY)\n                {\n                    // check card\n                    Memcard_Wait();\n                    stc_memcard_work->is_done = 0;\n                    if (CARDCheckAsync(i, Memcard_RemovedCallback) == CARD_RESULT_READY)\n                    {\n                        Memcard_Wait();\n\n                        // if we get this far, a valid memcard is inserted\n                        is_inserted = 1;\n                        SFX_PlayCommon(2);\n                        //export_data->slot = i;  // move cursor to this\n\n                        // get free blocks\n                        s32 byteNotUsed, filesNotUsed;\n                        if (CARDFreeBlocks(i, &byteNotUsed, &filesNotUsed) == CARD_RESULT_READY)\n                        {\n                            export_data->free_blocks[i] = (byteNotUsed / 8192);\n                            export_data->free_files[i] = filesNotUsed;\n                        }\n                    }\n                    else\n                        is_inserted = 0;\n\n                    CARDUnmount(i);\n                    stc_memcard_work->is_done = 0;\n                }\n                else\n                    is_inserted = 0;\n            }\n            else\n                is_inserted = 1;\n        }\n        else\n            is_inserted = 0;\n\n        export_data->is_inserted[i] = is_inserted;\n    }\n\n    // if left\n    if ((inputs & HSD_BUTTON_LEFT) || (inputs & HSD_BUTTON_DPAD_LEFT))\n    {\n        if (export_data->slot > 0)\n        {\n            export_data->slot--;\n            SFX_PlayCommon(2);\n        }\n    }\n\n    // if right\n    if ((inputs & HSD_BUTTON_RIGHT) || (inputs & HSD_BUTTON_DPAD_RIGHT))\n    {\n        if (export_data->slot < 1)\n        {\n            export_data->slot++;\n            SFX_PlayCommon(2);\n        }\n    }\n\n    int cursor = export_data->slot;\n    // if press A,\n    if ((inputs & HSD_BUTTON_A) || (inputs & HSD_BUTTON_START))\n    {\n        // ensure it can be saved\n        if ((export_data->is_inserted[cursor] == 1) && (export_data->free_files[cursor] >= 1) && (export_data->free_blocks[cursor] >= req_blocks))\n        {\n            // can save move to next screen\n            Export_SelCardExit(export_gobj);\n\n            // init next menu\n            Export_EnterNameInit(export_gobj);\n\n            SFX_PlayCommon(1);\n\n            return;\n        }\n\n        else\n            SFX_PlayCommon(3);\n    }\n\n    // if press B,\n    if ((inputs & HSD_BUTTON_B))\n    {\n        Export_Destroy(export_gobj);\n\n        // play sfx\n        SFX_PlayCommon(0);\n\n        return;\n    }\n\n    // update selection\n    Text *text = export_data->text_misc;\n    for (int i = 0; i < 2; i++)\n    {\n        static GXColor white = {255, 255, 255, 255};\n        static GXColor yellow = {201, 178, 0, 255};\n        GXColor *color;\n\n        // highlight cursor only\n        if (export_data->slot == i)\n            color = &yellow;\n        else\n            color = &white;\n\n        Text_SetColor(text, i, color);\n    }\n\n    // update description\n    Text *text_desc = export_data->text_desc;\n    if (export_data->is_inserted[cursor] == 0)\n    {\n        Text_SetText(text_desc, 0, \"No device is inserted in Slot %s.\", slots_names[cursor]);\n    }\n    else if (export_data->free_files[cursor] < 1)\n    {\n        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]);\n    }\n    else if (export_data->free_blocks[cursor] < req_blocks)\n    {\n        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);\n    }\n    else\n    {\n        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);\n    }\n    return 1;\n}\nvoid Export_SelCardExit(GOBJ *export_gobj)\n{\n    ExportData *export_data = export_gobj->userdata;\n\n    // hide menu jobjs\n    JOBJ_SetFlags(export_data->memcard_jobj[0], JOBJ_HIDDEN);\n    JOBJ_SetFlags(export_data->memcard_jobj[1], JOBJ_HIDDEN);\n\n    Text_Destroy(export_data->text_title);\n    Text_Destroy(export_data->text_desc);\n    Text_Destroy(export_data->text_misc);\n}\nvoid Export_EnterNameInit(GOBJ *export_gobj)\n{\n    ExportData *export_data = export_gobj->userdata;\n    MenuData *menu_data = event_vars->menu_gobj->userdata;\n\n    // show menu jobjs\n    JOBJ_ClearFlags(export_data->screenshot_jobj, JOBJ_HIDDEN);\n    JOBJ_ClearFlags(export_data->textbox_jobj, JOBJ_HIDDEN);\n\n    // create keyboard text\n    Text *text_keyboard = Text_CreateText(2, menu_data->canvas_menu);\n    export_data->text_keyboard = text_keyboard;\n    // enable align and kerning\n    text_keyboard->align = 1;\n    text_keyboard->kerning = 1;\n    // scale canvas\n    text_keyboard->trans.X = EXP_KEYBOARD_X;\n    text_keyboard->trans.Y = EXP_KEYBOARD_Y;\n    text_keyboard->scale.X = MENU_CANVASSCALE * EXP_KEYBOARD_SIZE;\n    text_keyboard->scale.Y = MENU_CANVASSCALE * EXP_KEYBOARD_SIZE;\n    // init keyboard\n    for (int i = 0; i < 4; i++)\n    {\n        // iterate through columns\n        for (int j = 0; j < 10; j++)\n        {\n            Text_AddSubtext(text_keyboard, (-(9.0 / 2.0) * 60) + (j * 60), -80 + (i * 60), \"\");\n        }\n    }\n    export_data->key_cursor[0] = 0;\n    export_data->key_cursor[1] = 0;\n    export_data->caps_lock = 0;\n    Export_EnterNameUpdateKeyboard(export_gobj);\n\n    // create file details\n    ExportHeader *header = stc_transfer_buf;\n    char *stage_name = stage_names[header->metadata.stage_internal];\n    char *hmn_name = Fighter_GetName(header->metadata.hmn);\n    char *cpu_name = Fighter_GetName(header->metadata.cpu);\n    Text *text_filedetails = Text_CreateText(2, menu_data->canvas_menu);\n    export_data->text_filedetails = text_filedetails;\n    // enable align and kerning\n    text_filedetails->align = 0;\n    text_filedetails->kerning = 1;\n    // scale canvas\n    text_filedetails->trans.X = EXP_FILEDETAILS_X;\n    text_filedetails->trans.Y = EXP_FILEDETAILS_Y;\n    text_filedetails->scale.X = MENU_CANVASSCALE * EXP_FILEDETAILS_SIZE;\n    text_filedetails->scale.Y = MENU_CANVASSCALE * EXP_FILEDETAILS_SIZE;\n\n    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\n\n    // create title text\n    Text *text_title = Text_CreateText(2, menu_data->canvas_menu);\n    export_data->text_title = text_title;\n    // enable align and kerning\n    text_title->align = 0;\n    text_title->kerning = 1;\n    // scale canvas\n    text_title->trans.X = -23;\n    text_title->trans.Y = -18;\n    text_title->scale.X = MENU_CANVASSCALE * 2;\n    text_title->scale.Y = MENU_CANVASSCALE * 2;\n    text_title->trans.Z = MENU_TEXTZ;\n    Text_AddSubtext(text_title, 0, 0, \"Enter File Name\");\n\n    // create desc text\n    Text *text_desc = Text_CreateText(2, menu_data->canvas_menu);\n    export_data->text_desc = text_desc;\n    // enable align and kerning\n    text_desc->align = 0;\n    text_desc->kerning = 1;\n    // scale canvas\n    text_desc->trans.X = -23;\n    text_desc->trans.Y = 12;\n    text_desc->scale.X = MENU_CANVASSCALE;\n    text_desc->scale.Y = MENU_CANVASSCALE;\n    Text_AddSubtext(text_desc, 0, 0, \"A: Select  B: Backspace  Y: Caps  Start: Confirm\"); // add description\n    Text_AddSubtext(text_desc, 0, 40, \"     X: Space  L: Cursor left  R: Cursor right\");  // add description\n\n    // create filename\n    Text *text_filename = Text_CreateText(2, menu_data->canvas_menu);\n    export_data->text_filename = text_filename;\n    // enable align and kerning\n    text_filename->align = 0;\n    text_filename->kerning = 1;\n    text_filename->use_aspect = 1;\n    GXColor filename_color = {225, 225, 225, 255};\n    text_filename->color = filename_color;\n    // scale canvas\n    text_filename->trans.X = EXP_FILENAME_X;\n    text_filename->trans.Y = EXP_FILENAME_Y;\n    text_filename->aspect.X = EXP_FILENAME_ASPECTX;\n    text_filename->aspect.Y = EXP_FILENAME_ASPECTY;\n    text_filename->scale.X = MENU_CANVASSCALE * EXP_FILENAME_SIZE;\n    text_filename->scale.Y = MENU_CANVASSCALE * EXP_FILENAME_SIZE;\n    // init filename buffer\n    export_data->filename_buffer[0] = '_';\n    export_data->filename_buffer[1] = '\\0';\n    Text_AddSubtext(text_filename, 0, 0, export_data->filename_buffer); // add title\n\n    // init menu variables\n    export_data->menu_index = EXMENU_NAME;\n    export_data->filename_cursor = 0;\n\n    return;\n}\nint Export_EnterNameThink(GOBJ *export_gobj)\n{\n\n    ExportData *export_data = export_gobj->userdata;\n\n    // get pausing players inputs\n    HSD_Pad *pad = PadGet(stc_hmn_controller, PADGET_MASTER);\n    int inputs = pad->rapidFire;\n    int input_down = pad->down;\n    u8 *cursor = export_data->key_cursor;\n    int update_keyboard = 0;\n    int update_filename = 0;\n    char *filename_buffer = export_data->filename_buffer;\n\n    // first ensure memcard is still inserted\n    s32 memSize, sectorSize;\n    if (CARDProbeEx(export_data->slot, &memSize, &sectorSize) != CARD_RESULT_READY)\n        goto EXIT;\n\n    // if left\n    if ((inputs & HSD_BUTTON_LEFT) || (inputs & HSD_BUTTON_DPAD_LEFT))\n    {\n        if (cursor[0] > 0)\n        {\n            cursor[0]--;\n        }\n        else\n        {\n            cursor[0] = (10 - 1);\n        }\n        update_keyboard = 1;\n    }\n    // if right\n    else if ((inputs & HSD_BUTTON_RIGHT) || (inputs & HSD_BUTTON_DPAD_RIGHT))\n    {\n        if (cursor[0] < (10 - 1))\n        {\n            cursor[0]++;\n        }\n        else\n        {\n            cursor[0] = 0;\n        }\n        update_keyboard = 1;\n    }\n    // if up\n    else if ((inputs & HSD_BUTTON_UP) || (inputs & HSD_BUTTON_DPAD_UP))\n    {\n        if (cursor[1] > 0)\n        {\n            cursor[1]--;\n        }\n        else\n        {\n            cursor[1] = (4 - 1);\n        }\n        update_keyboard = 1;\n    }\n    // if down\n    else if ((inputs & HSD_BUTTON_DOWN) || (inputs & HSD_BUTTON_DPAD_DOWN))\n    {\n        if (cursor[1] < 4 - 1)\n        {\n            cursor[1]++;\n        }\n        else\n        {\n            cursor[1] = 0;\n        }\n        update_keyboard = 1;\n    }\n    // if A\n    else if ((inputs & HSD_BUTTON_A))\n    {\n\n        // check if any remaining characters\n        if (export_data->filename_cursor < 32)\n        {\n\n            // get correct set of letters\n            char **keyboard_letters = keyboard_rows[export_data->caps_lock];\n\n            // add character to buffer\n            filename_buffer[export_data->filename_cursor] = keyboard_letters[cursor[1]][cursor[0]];\n\n            // add cursor and terminator\n            filename_buffer[export_data->filename_cursor + 1] = '_';\n            filename_buffer[export_data->filename_cursor + 2] = '\\0';\n\n            // inc cursor\n            export_data->filename_cursor++;\n\n            // update filename\n            update_filename = 1;\n\n            // remove caps lock\n            export_data->caps_lock = 0;\n            update_keyboard = 1;\n\n            SFX_PlayCommon(1);\n        }\n        else\n        {\n            SFX_PlayCommon(3);\n        }\n    }\n    // if B\n    else if ((inputs & HSD_BUTTON_B))\n    {\n\n        // check if can delete\n        if (export_data->filename_cursor > 0)\n        {\n            // dec cursor\n            export_data->filename_cursor--;\n\n            // add cursor and terminator\n            filename_buffer[export_data->filename_cursor] = '_';\n            filename_buffer[export_data->filename_cursor + 1] = '\\0';\n\n            // update filename\n            update_filename = 1;\n\n            SFX_PlayCommon(0);\n        }\n\n        // exit here\n        else if (input_down & HSD_BUTTON_B)\n        {\n        EXIT:\n            Export_EnterNameExit(export_gobj);\n            Export_SelCardInit(export_gobj);\n            SFX_PlayCommon(0);\n            return 0;\n        }\n    }\n    // if Y\n    if ((inputs & HSD_BUTTON_Y))\n    {\n        // toggle capslock\n        if (export_data->caps_lock == 0)\n            export_data->caps_lock = 1;\n        else\n            export_data->caps_lock = 0;\n\n        // update keyboard\n        update_keyboard = 1;\n\n        SFX_PlayCommon(1);\n    }\n    // if X\n    if ((inputs & HSD_BUTTON_X))\n    {\n\n        // check if any remaining characters\n        if (export_data->filename_cursor < 32)\n        {\n            // add character to buffer\n            filename_buffer[export_data->filename_cursor] = ' ';\n\n            // add cursor and terminator\n            filename_buffer[export_data->filename_cursor + 1] = '_';\n            filename_buffer[export_data->filename_cursor + 2] = '\\0';\n\n            // inc cursor\n            export_data->filename_cursor++;\n\n            // update filename\n            update_filename = 1;\n\n            SFX_PlayCommon(1);\n        }\n        else\n        {\n            OSReport(\"max characters!\\n\");\n        }\n    }\n    // if START\n    if ((inputs & HSD_BUTTON_START))\n    {\n        // at least 1 character\n        if (export_data->filename_cursor > 0)\n        {\n            Export_ConfirmInit(export_gobj);\n\n            // play sfx\n            SFX_PlayCommon(1);\n        }\n        else\n        {\n            SFX_PlayCommon(3);\n        }\n\n        return 0;\n    }\n\n    // update keyboard\n    if (update_keyboard == 1)\n    {\n        Export_EnterNameUpdateKeyboard(export_gobj);\n        SFX_PlayCommon(2);\n    }\n\n    // update filename if changed\n    if (update_filename == 1)\n    {\n        Text_SetText(export_data->text_filename, 0, filename_buffer);\n    }\n\n    return 0;\n}\nvoid Export_EnterNameExit(GOBJ *export_gobj)\n{\n    ExportData *export_data = export_gobj->userdata;\n\n    // hide menu jobjs\n    JOBJ_SetFlags(export_data->screenshot_jobj, JOBJ_HIDDEN);\n    JOBJ_SetFlags(export_data->textbox_jobj, JOBJ_HIDDEN);\n\n    Text_Destroy(export_data->text_title);\n    Text_Destroy(export_data->text_desc);\n    Text_Destroy(export_data->text_keyboard);\n    Text_Destroy(export_data->text_filename);\n    Text_Destroy(export_data->text_filedetails);\n}\nvoid Export_ConfirmInit(GOBJ *export_gobj)\n{\n    ExportData *export_data = export_gobj->userdata;\n    MenuData *menu_data = event_vars->menu_gobj->userdata;\n\n    // create gobj\n    GOBJ *confirm_gobj = GObj_Create(0, 0, 0);\n    export_data->confirm_gobj = confirm_gobj;\n\n    // load menu joint\n    JOBJ *confirm_jobj = JOBJ_LoadJoint(stc_lab_data->export_popup);\n    GObj_AddObject(confirm_gobj, 3, confirm_jobj);                                   // add to gobj\n    GObj_AddGXLink(confirm_gobj, GXLink_Common, GXLINK_MENUMODEL, GXPRI_POPUPMODEL); // add gx link\n\n    // create text\n    Text *confirm_text = Text_CreateText(2, menu_data->canvas_popup);\n    export_data->confirm_text = confirm_text;\n    // enable align and kerning\n    confirm_text->align = 1;\n    confirm_text->kerning = 1;\n    // scale canvas\n    confirm_text->trans.X = 0;\n    confirm_text->trans.Y = 0;\n    confirm_text->scale.X = MENU_CANVASSCALE;\n    confirm_text->scale.Y = MENU_CANVASSCALE;\n    confirm_text->trans.Z = MENU_TEXTZ;\n    Text_AddSubtext(confirm_text, 0, -40, \"Save File to Slot %s?\", slots_names[export_data->slot]);\n    int yes_subtext = Text_AddSubtext(confirm_text, -60, 20, \"Yes\");\n    GXColor yellow = {201, 178, 0, 255};\n    Text_SetColor(confirm_text, yes_subtext, &yellow);\n    Text_AddSubtext(confirm_text, 60, 20, \"No\");\n\n    export_data->menu_index = EXMENU_CONFIRM;\n    export_data->confirm_state = EXPOP_CONFIRM;\n    export_data->confirm_cursor = 0;\n\n    return 0;\n}\nint Export_ConfirmThink(GOBJ *export_gobj)\n{\n    ExportData *export_data = export_gobj->userdata;\n\n    // get pausing players inputs\n    HSD_Pad *pad = PadGet(stc_hmn_controller, PADGET_MASTER);\n    int inputs = pad->down;\n\n    // if unplugged exit\n    s32 memSize, sectorSize;\n    if (CARDProbeEx(export_data->slot, &memSize, &sectorSize) != CARD_RESULT_READY)\n    {\n        Export_ConfirmExit(export_gobj);\n        Export_EnterNameExit(export_gobj);\n\n        // play sfx\n        SFX_PlayCommon(0);\n    }\n\n    switch (export_data->confirm_state)\n    {\n    case (EXPOP_CONFIRM):\n    {\n\n        int update_cursor = 0;\n\n        // if left\n        if ((inputs & HSD_BUTTON_LEFT) || (inputs & HSD_BUTTON_DPAD_LEFT))\n        {\n            if (export_data->confirm_cursor > 0)\n            {\n                export_data->confirm_cursor--;\n                update_cursor = 1;\n            }\n        }\n        // if right\n        else if ((inputs & HSD_BUTTON_RIGHT) || (inputs & HSD_BUTTON_DPAD_RIGHT))\n        {\n            if (export_data->confirm_cursor < 1)\n            {\n                export_data->confirm_cursor++;\n                update_cursor = 1;\n            }\n        }\n\n        // if b\n        else if ((inputs & HSD_BUTTON_B))\n        {\n            Export_ConfirmExit(export_gobj);\n\n            // play sfx\n            SFX_PlayCommon(0);\n\n            return 0;\n        }\n        // if a\n        else if ((inputs & HSD_BUTTON_A) || (inputs & HSD_BUTTON_START))\n        {\n\n            // begin save\n            if (export_data->confirm_cursor == 0)\n            {\n\n                MenuData *menu_data = event_vars->menu_gobj->userdata;\n\n                // free current text\n                Text_Destroy(export_data->confirm_text);\n\n                // create text\n                Text *confirm_text = Text_CreateText(2, menu_data->canvas_popup);\n                export_data->confirm_text = confirm_text;\n                // enable align and kerning\n                confirm_text->align = 1;\n                confirm_text->kerning = 1;\n                // scale canvas\n                confirm_text->trans.X = 0;\n                confirm_text->trans.Y = 0;\n                confirm_text->scale.X = MENU_CANVASSCALE;\n                confirm_text->scale.Y = MENU_CANVASSCALE;\n                confirm_text->trans.Z = MENU_TEXTZ;\n                Text_AddSubtext(confirm_text, 0, -20, \"\");\n\n                export_data->confirm_state = EXPOP_SAVE;\n\n                export_status = EXSTAT_REQSAVE;\n\n                // play sfx\n                SFX_PlayCommon(1);\n\n                return 0;\n            }\n            // go back to keyboard menu\n            else\n            {\n                Export_ConfirmExit(export_gobj);\n\n                // play sfx\n                SFX_PlayCommon(0);\n\n                return 0;\n            }\n        }\n\n        if (update_cursor == 1)\n        {\n            for (int i = 0; i < 2; i++)\n            {\n                static GXColor white = {255, 255, 255, 255};\n                static GXColor yellow = {201, 178, 0, 255};\n                GXColor *color;\n\n                // highlight cursor only\n                if (export_data->confirm_cursor == i)\n                    color = &yellow;\n                else\n                    color = &white;\n\n                Text_SetColor(export_data->confirm_text, i + 1, color);\n            }\n\n            SFX_PlayCommon(2);\n        }\n        break;\n    }\n    case (EXPOP_SAVE):\n    {\n        // wait for save to finish\n        if (Export_Process(export_gobj) == 1)\n        {\n            Export_ConfirmExit(export_gobj);\n            Export_Destroy(export_gobj);\n\n            // play sfx\n            SFX_PlayCommon(1);\n\n            return 0;\n        }\n        break;\n    }\n    }\n    return 0;\n}\nvoid Export_ConfirmExit(GOBJ *export_gobj)\n{\n    ExportData *export_data = export_gobj->userdata;\n\n    GObj_Destroy(export_data->confirm_gobj);\n    Text_Destroy(export_data->confirm_text);\n\n    export_data->menu_index = EXMENU_NAME;\n}\nvoid Export_EnterNameUpdateKeyboard(GOBJ *export_gobj)\n{\n    ExportData *export_data = export_gobj->userdata;\n    Text *text_keyboard = export_data->text_keyboard;\n    u8 *cursor = export_data->key_cursor;\n\n    // get correct set of letters\n    char **keyboard_letters = keyboard_rows[export_data->caps_lock];\n\n    // iterate through rows\n    for (int i = 0; i < 4; i++)\n    {\n        // iterate through columns\n        for (int j = 0; j < 10; j++)\n        {\n\n            int this_subtext = (i * 10) + j;\n\n            // update letter text\n            char letter[2];\n            letter[0] = keyboard_letters[i][j];\n            letter[1] = '\\0';\n            Text_SetText(text_keyboard, this_subtext, &letter);\n\n            // update letter color\n            static GXColor white = {255, 255, 255, 255};\n            static GXColor yellow = {201, 178, 0, 255};\n            GXColor *color;\n            // check for cursor\n            if ((cursor[0] == j) && (cursor[1] == i))\n                color = &yellow;\n            else\n                color = &white;\n            Text_SetColor(text_keyboard, this_subtext, color);\n        }\n    }\n\n    return;\n}\nint Export_Process(GOBJ *export_gobj)\n{\n\n    ExportData *export_data = export_gobj->userdata;\n    Text *text = export_data->confirm_text;\n\n    int finished = 0;\n\n    // if snapshot is processing, dont update\n    switch (export_status)\n    {\n    case (EXSTAT_REQSAVE):\n    {\n\n        int slot = export_data->slot;\n\n        save_pre_tick = OSGetTick();\n\n        // create filename string\n        ExportHeader *header = stc_transfer_buf;\n        char filename[32];\n        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\n\n        // save file name to metadata\n        memcpy(&header->metadata.filename, export_data->filename_buffer, export_data->filename_cursor);\n\n        // check if file exists and delete it\n        s32 memSize, sectorSize;\n        if (CARDProbeEx(slot, &memSize, &sectorSize) == CARD_RESULT_READY)\n        {\n            // mount card\n            stc_memcard_work->is_done = 0;\n            if (CARDMountAsync(slot, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY)\n            {\n                // check card\n                Memcard_Wait();\n                stc_memcard_work->is_done = 0;\n                if (CARDCheckAsync(slot, Memcard_RemovedCallback) == CARD_RESULT_READY)\n                {\n                    Memcard_Wait();\n                    // get free blocks\n                    s32 byteNotUsed, filesNotUsed;\n                    if (CARDFreeBlocks(slot, &byteNotUsed, &filesNotUsed) == CARD_RESULT_READY)\n                    {\n                        // search for file with this name\n                        for (int i = 0; i < CARD_MAX_FILE; i++)\n                        {\n                            CARDStat card_stat;\n\n                            if (CARDGetStatus(slot, i, &card_stat) == CARD_RESULT_READY)\n                            {\n                                // check company code\n                                if (strncmp(os_info->company, card_stat.company, sizeof(os_info->company)) == 0)\n                                {\n                                    // check game name\n                                    if (strncmp(os_info->gameName, card_stat.gameName, sizeof(os_info->gameName)) == 0)\n                                    {\n                                        // check file name\n                                        if (strncmp(&filename, card_stat.fileName, sizeof(filename)) == 0)\n                                        {\n                                            // delete\n                                            CARDDeleteAsync(slot, &filename, Memcard_RemovedCallback);\n                                            stc_memcard_work->is_done = 0;\n                                            Memcard_Wait();\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n                CARDUnmount(slot);\n                stc_memcard_work->is_done = 0;\n            }\n        }\n\n        // setup save\n        memcpy(stc_memcard_info->file_name, &stc_save_name, sizeof(stc_save_name));\n        memset(stc_memcard_info->file_desc, '\\0', 32);                                                   // fill with spaces\n        memcpy(stc_memcard_info->file_desc, export_data->filename_buffer, export_data->filename_cursor); // copy inputted name\n        memcard_save.data = stc_transfer_buf;\n        memcard_save.x4 = 3;\n        memcard_save.size = stc_transfer_buf_size;\n        memcard_save.xc = -1;\n        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);\n\n        // change status\n        export_status = EXSTAT_SAVEWAIT;\n        OSReport(\"now saving...\\n\");\n\n        break;\n    }\n    case (EXSTAT_SAVEWAIT):\n    {\n\n        // wait to finish writing\n        if (Memcard_CheckStatus() != 11)\n        {\n            // change state\n            export_status = EXSTAT_DONE;\n        }\n        else\n        {\n            OSReport(\"status %d // progress %d/%d\\n\", *stc_memcard_write_status, *stc_memcard_block_curr, *stc_memcard_block_last);\n\n            if (*stc_memcard_write_status == 6)\n            {\n                Text_SetText(text, 0, \"Writing Data...\");\n            }\n            else\n            {\n                Text_SetText(text, 0, \"Creating File\");\n            }\n        }\n\n        break;\n    }\n    case (EXSTAT_DONE):\n    {\n\n        export_status = EXSTAT_NONE;\n        finished = 1;\n\n        Text_Destroy(text);\n\n        // done saving, output time\n        int save_post_tick = OSGetTick();\n        int save_time = OSTicksToMilliseconds(save_post_tick - save_pre_tick);\n        OSReport(\"wrote save in %dms\\n\", save_time);\n\n        break;\n    }\n    }\n\n    return finished;\n}\nint Export_Compress(u8 *dest, u8 *source, u32 size)\n{\n\n    int pre_tick = OSGetTick();\n    int compress_size = lz77_compress(source, size, dest, 8);\n    int post_tick = OSGetTick();\n    int time_dif = OSTicksToMilliseconds(post_tick - pre_tick);\n\n    OSReport(\"compressed %d bytes to %d bytes (%.2fx) in %dms\\n\", size, compress_size, ((float)size / (float)compress_size), time_dif);\n\n    return compress_size;\n}\n\n// Init Function\nvoid Event_Init(GOBJ *gobj)\n{\n    LCancelData *eventData = gobj->userdata;\n    EventDesc *eventInfo = eventData->eventInfo;\n    GOBJ *hmn = Fighter_GetGObj(0);\n    FighterData *hmn_data = hmn->userdata;\n    GOBJ *cpu = Fighter_GetGObj(1);\n    FighterData *cpu_data = cpu->userdata;\n\n    // theres got to be a better way to do this...\n    event_vars = *event_vars_ptr;\n\n    // get this events assets\n    stc_lab_data = File_GetSymbol(event_vars->event_archive, \"labData\");\n\n    // Init Info Display\n    InfoDisplay_Init();\n\n    // Init DIDraw\n    DIDraw_Init();\n\n    // Init Recording\n    Record_Init();\n\n    // Init Input Display\n    Inputs_Init();\n\n    // store hsd_update functions\n    HSD_Update *hsd_update = HSD_UPDATE;\n    hsd_update->checkPause = Update_CheckPause;\n    hsd_update->checkAdvance = Update_CheckAdvance;\n\n    // determine cpu controller\n    stc_hmn_controller = Fighter_GetControllerPort(hmn_data->ply);\n    u8 cpu_controller = 1;\n    if (stc_hmn_controller != 0)\n        cpu_controller = 0;\n    stc_cpu_controller = cpu_controller;\n\n    // set CPU AI to no_act 15\n    cpu_data->cpu.ai = 0;\n\n    // check to immediately load recording\n    if (*onload_fileno != -1)\n    {\n        Record_MemcardLoad(*onload_slot, *onload_fileno);\n    }\n\n    return;\n}\n// Update Function\nvoid Event_Update()\n{\n    // update DI draw\n    DIDraw_Update();\n\n    // update info display\n    InfoDisplay_Think(infodisp_gobj);\n\n    // update advanced cam\n    Update_Camera();\n\n    // Check for savestates\n    Savestates_Update();\n}\n// Think Function\nvoid Event_Think(GOBJ *event)\n{\n    LCancelData *eventData = event->userdata;\n\n    // get fighter data\n    GOBJ *hmn = Fighter_GetGObj(0);\n    FighterData *hmn_data = hmn->userdata;\n    GOBJ *cpu = Fighter_GetGObj(1);\n    FighterData *cpu_data = cpu->userdata;\n    HSD_Pad *pad = PadGet(hmn_data->player_controller_number, PADGET_ENGINE);\n\n    // update menu's percent\n    LabOptions_General[OPTGEN_HMNPCNT].option_val = hmn_data->dmg.percent;\n    LabOptions_CPU[OPTCPU_PCNT].option_val = cpu_data->dmg.percent;\n\n    // reset stale moves\n    if (LabOptions_General[OPTGEN_STALE].option_val == 0)\n    {\n        for (int i = 0; i < 6; i++)\n        {\n            // check if fighter exists\n            GOBJ *fighter = Fighter_GetGObj(i);\n            if (fighter != 0)\n            {\n                // reset stale move table\n                int *staleMoveTable = Fighter_GetStaleMoveTable(i);\n                memset(staleMoveTable, 0, 0x2C);\n            }\n        }\n    }\n\n    // apply intangibility\n    if (LabOptions_CPU[OPTCPU_INTANG].option_val == 1)\n    {\n        cpu_data->flags.no_reaction_always = 1;\n        cpu_data->flags.nudge_disable = 1;\n        cpu_data->grab.vuln = 0x1FF;\n        cpu_data->dmg.percent = 0;\n        Fighter_SetHUDDamage(cpu_data->ply, 0);\n\n        // if new state, apply colanim\n        if (cpu_data->TM.state_frame <= 1)\n        {\n            Fighter_ApplyOverlay(cpu_data, INTANG_COLANIM, 0);\n        }\n    }\n    else\n    {\n        cpu_data->flags.no_reaction_always = 0;\n        cpu_data->flags.nudge_disable = 0;\n    }\n\n    // Move CPU\n    if (pad->down == PAD_BUTTON_DPAD_DOWN)\n    {\n        // ensure CPU is not dead\n        if (cpu_data->flags.dead == 0)\n        {\n            // ensure player is grounded\n            int isGround = 0;\n            if (hmn_data->phys.air_state == 0)\n            {\n\n                // check for ground in front of player\n                Vec3 coll_pos;\n                int line_index;\n                int line_kind;\n                Vec3 line_unk;\n                float fromX = (hmn_data->phys.pos.X) + (hmn_data->facing_direction * 16);\n                float toX = fromX;\n                float fromY = (hmn_data->phys.pos.Y + 5);\n                float toY = fromY - 10;\n                isGround = GrColl_RaycastGround(&coll_pos, &line_index, &line_kind, &line_unk, -1, -1, -1, 0, fromX, fromY, toX, toY, 0);\n                if (isGround == 1)\n                {\n\n                    // do this for every subfighter (thanks for complicated code ice climbers)\n                    int is_moved = 0;\n                    for (int i = 0; i < 2; i++)\n                    {\n                        GOBJ *this_fighter = Fighter_GetSubcharGObj(cpu_data->ply, i);\n\n                        if (this_fighter != 0)\n                        {\n\n                            FighterData *this_fighter_data = this_fighter->userdata;\n\n                            if ((this_fighter_data->flags.sleep == 0) && (this_fighter_data->flags.dead == 0))\n                            {\n\n                                is_moved = 1;\n\n                                // place CPU here\n                                this_fighter_data->phys.pos = coll_pos;\n                                this_fighter_data->coll_data.ground_index = line_index;\n\n                                // facing player\n                                this_fighter_data->facing_direction = hmn_data->facing_direction * -1;\n\n                                // set grounded\n                                this_fighter_data->phys.air_state = 0;\n                                //Fighter_SetGrounded(this_fighter);\n\n                                // kill velocity\n                                Fighter_KillAllVelocity(this_fighter);\n\n                                // enter wait\n                                Fighter_EnterWait(this_fighter);\n\n                                // update ECB\n                                this_fighter_data->coll_data.topN_Curr = this_fighter_data->phys.pos; // move current ECB location to new position\n                                Coll_ECBCurrToPrev(&this_fighter_data->coll_data);\n                                this_fighter_data->cb.Coll(this_fighter);\n\n                                // update camera box\n                                Fighter_UpdateCameraBox(this_fighter);\n                                this_fighter_data->cameraBox->boundleft_curr = this_fighter_data->cameraBox->boundleft_proj;\n                                this_fighter_data->cameraBox->boundright_curr = this_fighter_data->cameraBox->boundright_proj;\n\n                                // init CPU logic (for nana's popo position history...)\n                                int cpu_kind = Fighter_GetCPUKind(this_fighter_data->ply);\n                                int cpu_level = Fighter_GetCPULevel(this_fighter_data->ply);\n                                Fighter_CPUInitialize(this_fighter_data, cpu_kind, cpu_level, 0);\n\n                                // place subfighter in the Z axis\n                                if (this_fighter_data->flags.ms == 1)\n                                {\n                                    ftCommonData *ft_common = *stc_ftcommon;\n                                    this_fighter_data->phys.pos.Z = ft_common->ms_zjostle_max * -1;\n                                }\n                            }\n                        }\n                    }\n\n                    if (is_moved == 1)\n                    {\n\n                        // reset CPU think variables\n                        eventData->cpu_state = CPUSTATE_START;\n                        eventData->cpu_hitshield = 0;\n                        eventData->cpu_hitnum = 0;\n                        eventData->cpu_sincehit = 0;\n                        eventData->cpu_hitshield = 0;\n                        eventData->cpu_lasthit = -1;\n                        eventData->cpu_lastshieldstun = -1;\n                        eventData->cpu_hitkind = -1;\n                        eventData->cpu_hitshieldnum = 0;\n                        eventData->cpu_isactionable = 0;\n\n                        // savestate\n                        event_vars->Savestate_Save(event_vars->savestate);\n                    }\n                }\n            }\n\n            // play SFX\n            if (isGround == 0)\n            {\n                SFX_PlayCommon(3);\n            }\n            else\n            {\n                SFX_Play(221);\n            }\n        }\n    }\n\n    // Adjust control of fighters\n    switch (LabOptions_Record[OPTREC_CPUMODE].option_val)\n    {\n    case RECMODE_OFF:\n    {\n        // human is human\n        hmn_data->player_controller_number = stc_hmn_controller;\n\n        // cpu is cpu\n        Fighter_SetSlotType(cpu_data->ply, 1);\n        cpu_data->player_controller_number = stc_cpu_controller;\n\n        break;\n    }\n    case RECMODE_PLAY:\n    {\n\n        // human is human\n        hmn_data->player_controller_number = stc_hmn_controller;\n\n        // cpu is hmn\n        Fighter_SetSlotType(cpu_data->ply, 0);\n        cpu_data->player_controller_number = stc_cpu_controller;\n\n        break;\n    }\n    case RECMODE_CTRL:\n    case RECMODE_REC:\n    {\n        // human is human\n        hmn_data->player_controller_number = stc_cpu_controller;\n\n        // cpu is hmn\n        Fighter_SetSlotType(cpu_data->ply, 0);\n        cpu_data->player_controller_number = stc_hmn_controller;\n\n        break;\n    }\n    }\n\n    // CPU Think if not using recording\n    if ((LabOptions_Record[OPTREC_CPUMODE].option_val == 0) && (LabOptions_Record[OPTREC_HMNMODE].option_val == 0))\n        LCancel_CPUThink(event, hmn, cpu);\n\n    return;\n}\n// Initial Menu\nstatic EventMenu *Event_Menu = &LabMenu_Main;"
  },
  {
    "path": "patch/events/lab/source/lab.h",
    "content": "#include \"../../../../MexTK/mex.h\"\n#include \"../../../tmdata/source/events.h\"\n\n// Labbing event\n// Custom TDI definitions\n#define TDI_HITNUM 10\n#define TDI_DISPNUM 4\n// menu model\n#define TDIMENU_SCALE 1\n#define TDIMENU_X 0\n#define TDIMENU_Y 0\n#define TDIMENU_Z 0\n#define TDIMENU_WIDTH 55 / TDIMENU_SCALE\n#define TDIMENU_HEIGHT 40 / TDIMENU_SCALE\n// menu text object\n#define TDITEXT_CANVASSCALE 0.05\n#define TDITEXT_TEXTSCALE 1\n#define TDITEXT_TEXTZ 0\n\n// recording\n#define REC_VERS 1\n/*\nRecording Version History:\nv0 = 3.0 Alpha 1-3.\nv1 = 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.\nv2 = not released\n*/\n\n#define GXPRI_RECJOINT 80\n#define REC_GXLINK 18\n#define GXPRI_RECTEXT GXPRI_RECJOINT + 1\n// cobj\n#define RECCAM_COBJGXLINK (1 << REC_GXLINK)\n#define RECCAM_GXPRI 8\n// params\n#define REC_LENGTH (1 * 60 * 60)\n#define REC_SLOTS 6\n#define REC_SEEKJOINT 7\n#define REC_LEFTBOUNDJOINT 5\n#define REC_RIGHTBOUNDJOINT 6\n#define REC_LEFTTEXTJOINT 2\n#define REC_RIGHTTEXTJOINT 3\n\n// export\nenum export_status\n{\n    EXSTAT_NONE,\n    EXSTAT_REQSAVE,\n    EXSTAT_SAVEWAIT,\n    EXSTAT_DONE,\n};\nenum export_menuindex\n{\n    EXMENU_SELCARD,\n    EXMENU_NAME,\n    EXMENU_CONFIRM,\n};\nenum export_popup\n{\n    EXPOP_CONFIRM,\n    EXPOP_SAVE,\n};\n#define EXP_MEMCARDAJOBJ 9\n#define EXP_MEMCARDBJOBJ 11\n#define EXP_TEXTBOXJOBJ 12\n#define EXP_SCREENSHOTJOBJ 18\n\n#define EXP_KEYBOARD_X 0\n#define EXP_KEYBOARD_Y 3.5\n#define EXP_KEYBOARD_SIZE 1\n\n#define EXP_FILEDETAILS_X -8\n#define EXP_FILEDETAILS_Y -11.7\n#define EXP_FILEDETAILS_SIZE 0.7\n\n#define EXP_FILENAME_X -7\n#define EXP_FILENAME_Y -4.8\n#define EXP_FILENAME_ASPECTX 560\n#define EXP_FILENAME_ASPECTY 100\n#define EXP_FILENAME_SIZE 1\n\n#define EXP_SCREENSHOT_WIDTH (640)\n#define EXP_SCREENSHOT_HEIGHT (480)\n\n#define RESIZE_MULT (0.15)\n#define RESIZE_WIDTH (EXP_SCREENSHOT_WIDTH * RESIZE_MULT)\n#define RESIZE_HEIGHT (EXP_SCREENSHOT_HEIGHT * RESIZE_MULT)\n\n// input display\ntypedef struct ButtonLookup\n{\n    u8 jobj;\n    u8 dobj;\n} ButtonLookup;\ntypedef enum buttons_enum\n{\n    BTN_A,\n    BTN_B,\n    BTN_X,\n    BTN_Y,\n    BTN_START,\n    BTN_DPADUP,\n    BTN_DPADRIGHT,\n    BTN_DPADLEFT,\n    BTN_DPADDOWN,\n    BTN_L,\n    BTN_R,\n    BTN_Z,\n    BTN_NUM,\n} buttons_enum;\nstatic ButtonLookup button_lookup[] = {\n    {1, 0},  // A\n    {2, 0},  // B\n    {3, 0},  // X\n    {4, 0},  // Y\n    {5, 0},  // Start\n    {6, 1},  // Dpad Up\n    {6, 2},  // Dpad Right\n    {6, 3},  // Dpad Left\n    {6, 4},  // Dpad Down\n    {11, 0}, // L\n    {12, 0}, // R\n    {13, 0}, // Z\n};\nstatic GXColor button_colors[] = {\n    {50, 180, 50, 255},   // A\n    {255, 50, 50, 255},   // B\n    {127, 127, 127, 255}, // X\n    {127, 127, 127, 255}, // Y\n    {192, 192, 192, 255}, // Start\n    {192, 192, 192, 255}, // Dpad Up\n    {192, 192, 192, 255}, // Dpad Right\n    {192, 192, 192, 255}, // Dpad Left\n    {192, 192, 192, 255}, // Dpad Down\n    {127, 127, 127, 255}, // L\n    {127, 127, 127, 255}, // R\n    {0, 0, 255, 255},     // Z\n};\nstatic int button_bits[] = {\n    HSD_BUTTON_A,          // A\n    HSD_BUTTON_B,          // B\n    HSD_BUTTON_X,          // X\n    HSD_BUTTON_Y,          // Y\n    HSD_BUTTON_START,      // Start\n    HSD_BUTTON_DPAD_UP,    // Dpad Up\n    HSD_BUTTON_DPAD_RIGHT, // Dpad Right\n    HSD_BUTTON_DPAD_LEFT,  // Dpad Left\n    HSD_BUTTON_DPAD_DOWN,  // Dpad Down\n    HSD_TRIGGER_L,         // L\n    HSD_TRIGGER_R,         // R\n    HSD_TRIGGER_Z,         // Z\n};\n// GX\n#define INPUT_GXLINK 12\n#define INPUT_GXPRI 80\n// params\n#define INPUT_SHELL_JOBJ 14\n#define INPUT_SHELL_DOBJ 0\n#define INPUT_COLOR_PRESSED \\\n    {                       \\\n        255, 255, 255, 255  \\\n    }\n\ntypedef struct Arch_ImportData\n{\n    JOBJDesc *import_button;\n    JOBJDesc *import_menu;\n    COBJDesc *import_cam;\n    JOBJDesc *import_popup;\n} Arch_ImportData;\ntypedef struct Arch_LabData\n{\n    JOBJDesc *stick;\n    JOBJDesc *cstick;\n    void *save_icon;\n    void *save_banner;\n    JOBJDesc *controller;\n    JOBJDesc *export_menu;\n    JOBJDesc *export_popup;\n} Arch_LabData;\ntypedef struct LCancelData\n{\n    EventDesc *eventInfo;\n    u8 cpu_state;\n    u8 cpu_hitshield;\n    u8 cpu_hitnum;\n    u8 cpu_sdidir;\n    u8 cpu_sincehit;\n    s16 cpu_lasthit;\n    s16 cpu_lastshieldstun; // last move instance of the opponent in shield stun. used to tell how many times the shield was hit\n    s8 cpu_hitkind;         // how the CPU was hit, damage or shield\n    u8 cpu_hitshieldnum;    // times the CPUs shield was hit\n    u8 cpu_isactionable;    // flag that indicates if a cpu has become actionable\n    u8 cpu_groundstate;     // indicates if the player was touching ground upon being actionable\n    s32 timer;\n    u8 cpu_isthrown; // bool for if the cpu is being thrown\n    GOBJ *rec_gobj;\n    u8 hmn_controller;\n    u8 cpu_controller;\n} LCancelData;\ntypedef struct InfoDisplayData\n{\n    JOBJ *menuModel;\n    JOBJ *botLeftEdge;\n    JOBJ *botRightEdge;\n    Text *text;\n} InfoDisplayData;\ntypedef struct DIDraw\n{\n    int num[2];        // number of vertices\n    Vec2 *vertices[2]; // pointer to vertex to draw\n    GXColor color;     // color of this vertex\n} DIDraw;\ntypedef struct DIDrawCalculate\n{\n    Vec2 pos;       // position of vertices\n    int envFlags;   // environment flags\n    float ECBTopY;  // used for determining middle of body\n    float ECBLeftY; // used for determining middle of body\n    float kb_Y;     // used to determine ceiling KOs\n} DIDrawCalculate;\ntypedef struct TDIData\n{\n    JOBJ *stick_curr[2];\n    JOBJ *stick_prev[6][2];\n    Text *text_curr;\n} TDIData;\ntypedef struct CPUAction\n{\n    u16 state;                  // state to perform this action. -1 for last\n    u8 frameLow;                // first possible frame to perform this action\n    u8 frameHi;                 // last possible frame to perfrom this action\n    s8 stickX;                  // left stick X value\n    s8 stickY;                  // left stick Y value\n    s8 cstickX;                 // c stick X value\n    s8 cstickY;                 // c stick Y value\n    int input;                  // button to input\n    unsigned char isLast : 1;   // flag to indicate this was the final input\n    unsigned char stickDir : 3; // 0 = none, 1 = towards opponent, 2 = away from opponent, 3 = forward, 4 = backward\n\n} CPUAction;\ntypedef struct RecInputs\n{\n    unsigned char btn_dpadup : 1;\n    unsigned char btn_a : 1;\n    unsigned char btn_b : 1;\n    unsigned char btn_x : 1;\n    unsigned char btn_y : 1;\n    unsigned char btn_L : 1;\n    unsigned char btn_R : 1;\n    unsigned char btn_Z : 1;\n    s8 stickX;\n    s8 stickY;\n    s8 substickX;\n    s8 substickY;\n    u8 trigger;\n} RecInputs;\ntypedef struct RecInputData\n{\n    int start_frame; // the frame these inputs start on\n    int num;\n    RecInputs inputs[REC_LENGTH]\n} RecInputData;\ntypedef struct RecData\n{\n    int timer; // this is updated at runtime to know which frames inputs to use.\n    int hmn_rndm_slot;\n    RecInputData *hmn_inputs[REC_SLOTS];\n    int cpu_rndm_slot;\n    RecInputData *cpu_inputs[REC_SLOTS];\n    JOBJ *seek_jobj;\n    Text *text;\n    float seek_left;\n    float seek_right;\n} RecData;\ntypedef struct RecordingSave\n{\n    MatchInit match_data; // this will point to a struct containing match info\n    Savestate savestate;\n    RecInputData hmn_inputs[REC_SLOTS];\n    RecInputData cpu_inputs[REC_SLOTS];\n} RecordingSave;\ntypedef struct InputData\n{\n    JOBJ *controller_joint[4];\n    Vec2 ltrig_origin;\n    Vec2 rtrig_origin;\n} InputData;\ntypedef struct ExportData\n{\n    u16 menu_index;\n    u16 menu_state;\n    JOBJ *memcard_jobj[2];\n    JOBJ *screenshot_jobj;\n    JOBJ *textbox_jobj;\n    RGB565 *scaled_image;\n    Text *text_title;\n    Text *text_desc;\n    Text *text_misc;\n    int slot;\n    u8 is_inserted[2];\n    int free_blocks[2];\n    int free_files[2];\n    Text *text_keyboard;\n    Text *text_filename;\n    Text *text_filedetails;\n    u8 key_cursor[2];\n    u8 filename_cursor;\n    u8 caps_lock;\n    char *filename_buffer;\n    GOBJ *confirm_gobj;\n    Text *confirm_text;\n    u8 confirm_cursor;\n    u8 confirm_state;\n    int hmn_id;\n    int cpu_id;\n    int stage_id;\n} ExportData;\ntypedef struct ExportMenuSettings\n{\n    u8 hmn_mode;\n    u8 hmn_slot;\n    u8 cpu_mode;\n    u8 cpu_slot;\n    u8 loop_inputs;\n    u8 auto_restore;\n} ExportMenuSettings;\ntypedef struct ExportHeader\n{\n    struct rec_metadata // metadata\n    {\n        u16 version;\n        u16 image_width;\n        u16 image_height;\n        u16 image_fmt;\n        u8 hmn;\n        u8 hmn_costume;\n        u8 cpu;\n        u8 cpu_costume;\n        u16 stage_external; // instance of the stage\n        u16 stage_internal; //  unique stage\n        u8 month;\n        u8 day;\n        u16 year;\n        u8 hour;\n        u8 minute;\n        u8 second;\n        char filename[32];\n    } metadata;\n    struct // lookup\n    {\n        int ofst_screenshot;\n        int ofst_recording;\n        int ofst_menusettings;\n        // to-do, add menu data offset\n    } lookup;\n} ExportHeader;\n\nvoid Event_Init(GOBJ *gobj);\nvoid Event_Update();\nvoid Event_Think(GOBJ *event);\n\nvoid Button_Think(GOBJ *button_gobj);\n\nvoid Lab_ChangePlayerPercent(GOBJ *menu_gobj, int value);\nvoid Lab_ChangeFrameAdvance(GOBJ *menu_gobj, int value);\nvoid Lab_ChangeCPUPercent(GOBJ *menu_gobj, int value);\nvoid Lab_ChangeCPUIntang(GOBJ *menu_gobj, int value);\nvoid Lab_ChangeModelDisplay(GOBJ *menu_gobj, int value);\nvoid Lab_ChangeHitDisplay(GOBJ *menu_gobj, int value);\nvoid Lab_ChangeEnvCollDisplay(GOBJ *menu_gobj, int value);\nvoid Lab_ChangeCamMode(GOBJ *menu_gobj, int value);\nvoid Lab_ChangeInfoPreset(GOBJ *menu_gobj, int value);\nvoid Lab_ChangeInfoRow(GOBJ *menu_gobj, int value);\nvoid Lab_ChangeInfoSizePos(GOBJ *menu_gobj, int value);\nvoid Lab_ChangeInfoPlayer(GOBJ *menu_gobj, int value);\nvoid Lab_ChangeHUD(GOBJ *menu_gobj, int value);\nvoid Lab_SelectCustomTDI(GOBJ *menu_gobj);\nvoid DIDraw_GX();\nvoid Record_ChangeHMNSlot(GOBJ *menu_gobj, int value);\nvoid Record_ChangeCPUSlot(GOBJ *menu_gobj, int value);\nvoid Record_ChangeHMNMode(GOBJ *menu_gobj, int value);\nvoid Record_ChangeCPUMode(GOBJ *menu_gobj, int value);\nvoid Record_ChangeSlot(GOBJ *menu_gobj, int value);\nvoid Record_MemcardSave(GOBJ *menu_gobj);\nvoid Record_MemcardLoad(int slot, int file_no);\nvoid Record_InitState(GOBJ *menu_gobj);\nvoid Record_RestoreState(GOBJ *menu_gobj);\nvoid Record_CObjThink(GOBJ *gobj);\nvoid Record_GX(GOBJ *gobj, int pass);\nvoid Record_Think(GOBJ *rec_gobj);\nvoid Record_Update(int ply, RecInputData *inputs, int rec_mode);\nint Record_MenuThink(GOBJ *menu_gobj);\nint Record_OptimizedSave(Savestate *savestate);\nint Record_OptimizedLoad(Savestate *savestate);\nint Record_GetRandomSlot(RecInputData **input_data);\nint Record_GOBJToID(GOBJ *gobj);\nint Record_FtDataToID(FighterData *fighter_data);\nint Record_BoneToID(FighterData *fighter_data, JOBJ *bone);\nGOBJ *Record_IDToGOBJ(int id);\nFighterData *Record_IDToFtData(int id);\nJOBJ *Record_IDToBone(FighterData *fighter_data, int id);\nvoid Snap_CObjThink(GOBJ *gobj);\nvoid Record_StartExport(GOBJ *menu_gobj);\nvoid Export_Init(GOBJ *menu_gobj);\nint Export_Think(GOBJ *export_gobj);\nvoid Export_Destroy(GOBJ *export_gobj);\nvoid Export_SelCardInit(GOBJ *export_gobj);\nint Export_SelCardThink(GOBJ *export_gobj);\nint Export_Compress(u8 *dest, u8 *source, u32 size);\nvoid CustomTDI_Update(GOBJ *gobj);\nvoid CustomTDI_Destroy(GOBJ *gobj);\nvoid Lab_Exit(int value);\nvoid InfoDisplay_Think(GOBJ *gobj);\nvoid InfoDisplay_GX(GOBJ *gobj, int pass);\n\nstatic EventOption LabOptions_Main[];\nstatic EventOption LabOptions_General[];\nstatic EventOption LabOptions_InfoDisplay[];\nstatic EventMenu LabMenu_General;\nstatic EventMenu LabMenu_InfoDisplay;\nstatic EventMenu LabMenu_CPU;\nstatic EventMenu LabMenu_Record;\n\n// info display\n#define GXPRI_INFDISP GXPRI_MENUMODEL - 2\n#define GXLINK_INFDISP 12\n#define GXPRI_INFDISPTEXT GXPRI_INFDISP + 1\n#define GXLINK_INFDISPTEXT 12\n\n// info display jobj\n#define INFDISP_WIDTH 6\n#define INFDISP_SCALE 4\n#define INFDISP_X -26.5\n#define INFDISP_Y 21.5\n#define INFDISP_Z 0.01\n#define INFDISP_YOFFSET -2.5\n#define INFDISP_BOTY -0.5\n#define INFDISP_BOTYOFFSET -0.30\n// info display text\n#define INFDISPTEXT_SCALE 0.04\n#define INFDISPTEXT_X 1\n#define INFDISPTEXT_Y 1\n#define INFDISPTEXT_YOFFSET 30\n\n// General Options\nenum gen_option\n{\n    OPTGEN_FRAME,\n    OPTGEN_FRAMEBTN,\n    OPTGEN_HMNPCNT,\n    OPTGEN_MODEL,\n    OPTGEN_HIT,\n    OPTGEN_COLL,\n    OPTGEN_CAM,\n    OPTGEN_HUD,\n    OPTGEN_DI,\n    OPTGEN_INPUT,\n    OPTGEN_STALE,\n};\n\n// CPU Options\nenum cpu_option\n{\n    OPTCPU_PCNT,\n    OPTCPU_BEHAVE,\n    OPTCPU_SHIELD,\n    OPTCPU_INTANG,\n    OPTCPU_SDIFREQ,\n    OPTCPU_SDIDIR,\n    OPTCPU_TDI,\n    OPTCPU_CUSTOMTDI,\n    OPTCPU_TECH,\n    OPTCPU_GETUP,\n    OPTCPU_MASH,\n    //OPTCPU_RESET,\n    OPTCPU_CTRGRND,\n    OPTCPU_CTRAIR,\n    OPTCPU_CTRSHIELD,\n    OPTCPU_CTRFRAMES,\n    OPTCPU_CTRHITS,\n    OPTCPU_SHIELDHITS,\n};\n\n// SDI Freq\nenum sdi_freq\n{\n    SDIFREQ_NONE,\n    SDIFREQ_LOW,\n    SDIFREQ_MED,\n    SDIFREQ_HIGH,\n};\n\n// SDI Freq\nenum sdi_dir\n{\n    SDIDIR_RANDOM,\n    SDIDIR_AWAY,\n    SDIDIR_TOWARD,\n};\n\n// Recording Options\n#define OPTREC_SAVE 0\n#define OPTREC_LOAD 1\n#define OPTREC_HMNMODE 2\n#define OPTREC_HMNSLOT 3\n#define OPTREC_CPUMODE 4\n#define OPTREC_CPUSLOT 5\n#define OPTREC_LOOP 6\n#define OPTREC_AUTOLOAD 7\n\n// Recording Modes\n#define RECMODE_OFF 0\n#define RECMODE_CTRL 1\n#define RECMODE_REC 2\n#define RECMODE_PLAY 3\n\n// Info Display Options\n//#define OPTINF_TOGGLE 0\n#define OPTINF_PLAYER 0\n#define OPTINF_SIZE 1\n#define OPTINF_PRESET 2\n#define OPTINF_ROW1 3\n\n// Info Display Rows\nenum infdisp_rows\n{\n    INFDISPROW_NONE,\n    INFDISPROW_POS,\n    INFDISPROW_STATE,\n    INFDISPROW_FRAME,\n    INFDISPROW_SELFVEL,\n    INFDISPROW_KBVEL,\n    INFDISPROW_TOTALVEL,\n    INFDISPROW_ENGLSTICK,\n    INFDISPROW_SYSLSTICK,\n    INFDISPROW_ENGCSTICK,\n    INFDISPROW_SYSCSTICK,\n    INFDISPROW_ENGTRIGGER,\n    INFDISPROW_SYSTRIGGER,\n    INFDISPROW_LEDGECOOLDOWN,\n    INFDISPROW_INTANGREMAIN,\n    INFDISPROW_HITSTOP,\n    INFDISPROW_HITSTUN,\n    INFDISPROW_SHIELDHEALTH,\n    INFDISPROW_SHIELDSTUN,\n    INFDISPROW_GRIP,\n    INFDISPROW_ECBLOCK,\n    INFDISPROW_ECBBOT,\n    INFDISPROW_JUMPS,\n    INFDISPROW_WALLJUMPS,\n    INFDISPROW_JAB,\n    INFDISPROW_LINE,\n    INFDISPROW_BLASTLR,\n    INFDISPROW_BLASTUD,\n};\n\n// CPU States\nenum cpu_state\n{\n    CPUSTATE_START,\n    CPUSTATE_GRABBED,\n    CPUSTATE_SDI,\n    CPUSTATE_TDI,\n    CPUSTATE_TECH,\n    CPUSTATE_GETUP,\n    CPUSTATE_COUNTER,\n    CPUSTATE_RECOVER,\n};\n\n// Grab Escape Options\nenum cpu_mash\n{\n    CPUMASH_NONE,\n    CPUMASH_MED,\n    CPUMASH_HIGH,\n    CPUMASH_PERFECT,\n};\n\n#define INTANG_COLANIM 10\n\n// Grab Escape RNG Def\n#define CPUMASHRNG_MED 35\n#define CPUMASHRNG_HIGH 55\n\n// Behavior Definitions\n#define CPUBEHAVE_STAND 0\n#define CPUBEHAVE_SHIELD 1\n#define CPUBEHAVE_CROUCH 2\n#define CPUBEHAVE_JUMP 3\n\n// SDI Definitions\n#define CPUSDI_RANDOM 0\n#define CPUSDI_NONE 1\n\n// TDI Definitions\n#define CPUTDI_RANDOM 0\n#define CPUTDI_IN 1\n#define CPUTDI_OUT 2\n#define CPUTDI_FLOORHUG 3\n#define CPUTDI_CUSTOM 4\n#define CPUTDI_NONE 5\n#define CPUTDI_NUM 6\n\n// Tech Definitions\n#define CPUTECH_RANDOM 0\n#define CPUTECH_NEUTRAL 1\n#define CPUTECH_AWAY 2\n#define CPUTECH_TOWARDS 3\n#define CPUTECH_NONE 4\n\n// Getup Definitions\n#define CPUGETUP_RANDOM 0\n#define CPUGETUP_STAND 1\n#define CPUGETUP_AWAY 2\n#define CPUGETUP_TOWARD 3\n#define CPUGETUP_ATTACK 4\n\n// Stick Direction Definitions\nenum STICKDIR\n{\n    STCKDIR_NONE,\n    STCKDIR_TOWARD,\n    STCKDIR_AWAY,\n    STCKDIR_FRONT,\n    STCKDIR_BACK,\n    STICKDIR_RDM,\n};\n\n// Hit kind defintions\n#define HITKIND_DAMAGE 0\n#define HITKIND_SHIELD 1\n\n// DI Draw Constants\n#define DI_MaxColl 50\n\nstatic char *stage_names[] = {\n    \"\",\n    \"\",\n    \"Princess Peach's Castle\",\n    \"Rainbow Cruise\",\n    \"Kongo Jungle\",\n    \"Jungle Japes\",\n    \"Great Bay\",\n    \"Hyrule Temple\",\n    \"Brinstar\",\n    \"Brinstar Depths\",\n    \"Yoshi's Story\",\n    \"Yoshi's Island\",\n    \"Fountain of Dreams\",\n    \"Green Greens\",\n    \"Corneria\",\n    \"Venom\",\n    \"Pokemon Stadium\",\n    \"Poke Floats\",\n    \"Mute City\",\n    \"Big Blue\",\n    \"Onett\",\n    \"Fourside\",\n    \"Icicle Mountain\",\n    \"\",\n    \"Mushroom Kingdom\",\n    \"Mushroom Kingdom II\",\n    \"\",\n    \"Flat Zone\",\n    \"Dream Land\",\n    \"Yoshi's Island (64)\",\n    \"Kongo Jungle (64)\",\n    \"\",\n    \"\",\n    \"\",\n    \"\",\n    \"\",\n    \"Battlefield\",\n    \"Final Destination\",\n};\n\n// CSS Import\ns8 *onload_fileno = R13 + (-0x4670);\ns8 *onload_slot = R13 + (-0x466F);\n#define IMPORT_FILESPERPAGE 10\ntypedef enum ImportMenuStates\n{\n    IMP_SELCARD,\n    IMP_SELFILE,\n    IMP_CONFIRM,\n};\ntypedef enum ImportConfirmKind\n{\n    CFRM_LOAD,\n    CFRM_OLD,\n    CFRM_NEW,\n    CFRM_DEL,\n    CFRM_ERR,\n};\ntypedef struct FileInfo\n{\n    char **file_name; // pointer to file name array\n    int file_size;    // number of files on card\n    int file_no;      // index of this file on the card\n} FileInfo;\ntypedef struct ImportData\n{\n    GOBJ *menu_gobj;\n    u16 canvas;\n    u8 menu_state;\n    u8 cursor;\n    u8 memcard_inserted[2];     // memcard inserted bools\n    u16 memcard_free_files[2];  // free files on this card\n    u16 memcard_free_blocks[2]; // free blocks on this card\n    u16 memcard_slot;           // selected slot\n    JOBJ *memcard_jobj[2];\n    JOBJ *screenshot_jobj;\n    JOBJ *scroll_jobj;\n    JOBJ *scroll_top;\n    JOBJ *scroll_bot;\n    Text *title_text;\n    Text *desc_text;\n    Text *option_text;\n    Text *filename_text;\n    Text *fileinfo_text;\n    int file_num;         // number of files on card\n    FileInfo *file_info;  // pointer to file info array\n    ExportHeader *header; // pointer to header array for the files on the current page\n    u8 page;              // file page\n    u8 files_on_page;     // number of files on the current page\n    struct\n    {\n        GOBJ *gobj; // confirm gobj\n        u16 canvas;\n        u8 kind; // which kind of confirm dialog this is\n        u8 cursor;\n        Text *text;\n    } confirm;\n    struct\n    {\n        _HSD_ImageDesc *orig_image;           // pointer to jobj's original image desc\n        RGB565 *image;                        // pointer to 32 byte aligned image allocation (one being displayed)\n        int loaded_num;                       // number of completed snaps loaded\n        u8 load_inprogress;                   // bool for if a file is being loaded\n        u8 file_loading;                      // page local index of the file being loaded\n        void *file_data[IMPORT_FILESPERPAGE]; // pointer to each files data\n        u8 is_loaded[IMPORT_FILESPERPAGE];    // bools for which snap has been loaded\n    } snap;\n} ImportData;\nvoid Button_Create();\nvoid Button_Think(GOBJ *button_gobj);\nvoid Menu_Confirm_Init(GOBJ *menu_gobj, int kind);\nvoid Menu_Confirm_Think(GOBJ *menu_gobj);\nvoid Menu_Confirm_Exit(GOBJ *menu_gobj);\nGOBJ *Menu_Create();\nvoid Menu_Think(GOBJ *menu_gobj);\n#define MENUCAM_GXLINK 5\n#define SIS_ID 0"
  },
  {
    "path": "patch/events/lab/source/lab_css.c",
    "content": "#include \"lab.h\"\n\n// Static Variables\nstatic Arch_ImportData *stc_import_assets;\nstatic ImportData import_data;\nstatic char *slots_names[] = {\"A\", \"B\"};\nstatic _HSD_ImageDesc image_desc = {\n    .format = 4,\n    .height = RESIZE_HEIGHT,\n    .width = RESIZE_WIDTH,\n};\nstatic GXColor text_white = {255, 255, 255, 255};\nstatic GXColor text_gold = {255, 211, 0, 255};\n\n// OnLoad\nvoid OnCSSLoad(ArchiveInfo *archive)\n{\n    EventVars *event_vars = *event_vars_ptr;\n\n    // get assets from this file\n    stc_import_assets = File_GetSymbol(archive, \"importData\");\n\n    Button_Create();\n\n    // Create a cobj for the menu\n    COBJ *cam_cobj = COBJ_LoadDesc(stc_import_assets->import_cam);\n    GOBJ *cam_gobj = GObj_Create(2, 3, 128);\n    GObj_AddObject(cam_gobj, R13_U8(-0x3E55), cam_cobj);\n    GOBJ_InitCamera(cam_gobj, CObjThink_Common, 1);\n    GObj_AddProc(cam_gobj, MainMenu_CamRotateThink, 5);\n    cam_gobj->cobj_links = 1 << MENUCAM_GXLINK;\n\n    // Create text canvas\n    import_data.canvas = Text_CreateCanvas(SIS_ID, 0, 2, 3, 128, MENUCAM_GXLINK, 129, 0);\n    import_data.confirm.canvas = Text_CreateCanvas(SIS_ID, 0, 2, 3, 128, MENUCAM_GXLINK, 131, 0);\n\n    // allocate filename array\n    import_data.file_info = calloc(CARD_MAX_FILE * sizeof(FileInfo)); // allocate 128 entries\n    // allocate filename buffers\n    for (int i = 0; i < CARD_MAX_FILE; i++)\n    {\n        import_data.file_info[i].file_name = calloc(CARD_FILENAME_MAX);\n    }\n\n    // alloc file header array\n    import_data.header = calloc(IMPORT_FILESPERPAGE * sizeof(ExportHeader));\n\n    // alloc image (needs to be 32 byte aligned)\n    import_data.snap.image = calloc(GXGetTexBufferSize(RESIZE_WIDTH, RESIZE_HEIGHT, 4, 0, 0)); // allocate 128 entries\n\n    // HUGE HACK ALERT\n    EventDesc *(*GetEventDesc)(int page, int event) = RTOC_PTR(TM_DATA + (24 * 4));\n    EventDesc *event_desc = GetEventDesc(1, 0);\n    event_desc->isSelectStage = 1;\n    event_desc->matchData->stage = -1;\n    *onload_fileno = -1;\n\n    return;\n}\n\n// Button Functions\nvoid Button_Create()\n{\n    // Create GOBJ\n    GOBJ *button_gobj = GObj_Create(4, 5, 0);\n    GObj_AddGXLink(button_gobj, GXLink_Common, 1, 128);\n    GObj_AddProc(button_gobj, Button_Think, 8);\n    JOBJ *button_jobj = JOBJ_LoadJoint(stc_import_assets->import_button);\n    GObj_AddObject(button_gobj, R13_U8(-0x3E55), button_jobj);\n\n    // scale message jobj\n    Vec3 *scale = &button_jobj->scale;\n\n    // Create text object\n    Text *button_text = Text_CreateText(SIS_ID, 0);\n    button_text->kerning = 1;\n    button_text->align = 1;\n    button_text->use_aspect = 1;\n    button_text->scale.X = (scale->X * 0.01) * 3;\n    button_text->scale.Y = (scale->Y * 0.01) * 3;\n    button_text->trans.X = button_jobj->trans.X + (0 * (scale->X / 4.0));\n    button_text->trans.Y = (button_jobj->trans.Y * -1) + (-1.6 * (scale->Y / 4.0));\n    Text_AddSubtext(button_text, 0, 0, \"Import\");\n\n    return;\n}\nvoid Button_Think(GOBJ *button_gobj)\n{\n\n#define BUTTON_WIDTH 5\n#define BUTTON_HEIGHT 2.2\n\n    // init\n    CSSCursor *this_cursor = stc_css_cursors[0]; // get the main player's hand cursor data\n    Vec2 cursor_pos = this_cursor->pos;\n    cursor_pos.X += 5;\n    cursor_pos.Y -= 1;\n    HSD_Pad *pads = stc_css_pad;\n    HSD_Pad *this_pad = &pads[*stc_css_hmnport];\n    int down = this_pad->down;                   // get this cursors inputs\n    JOBJ *button_jobj = button_gobj->hsd_object; // get jobj\n    Vec3 *button_pos = &button_jobj->trans;\n\n    // check if cursor is hovered over button\n    if ((import_data.menu_gobj == 0) &&\n        (cursor_pos.X < (button_pos->X + BUTTON_WIDTH)) &&\n        (cursor_pos.X > (button_pos->X - BUTTON_WIDTH)) &&\n        (cursor_pos.Y < (button_pos->Y + BUTTON_HEIGHT)) &&\n        (cursor_pos.Y > (button_pos->Y - BUTTON_HEIGHT)) &&\n        (down & HSD_BUTTON_A))\n    {\n        import_data.menu_gobj = Menu_Create();\n        SFX_PlayCommon(1);\n    }\n\n    return;\n}\n\n// Import Menu Functions\nGOBJ *Menu_Create()\n{\n    // Create GOBJ\n    GOBJ *menu_gobj = GObj_Create(4, 5, 0);\n    GObj_AddGXLink(menu_gobj, GXLink_Common, MENUCAM_GXLINK, 128);\n    GObj_AddProc(menu_gobj, Menu_Think, 1);\n    JOBJ *menu_jobj = JOBJ_LoadJoint(stc_import_assets->import_menu);\n    GObj_AddObject(menu_gobj, R13_U8(-0x3E55), menu_jobj);\n\n    // save jobj pointers\n    JOBJ_GetChild(menu_jobj, &import_data.memcard_jobj[0], 2, -1);\n    JOBJ_GetChild(menu_jobj, &import_data.memcard_jobj[1], 4, -1);\n    JOBJ_GetChild(menu_jobj, &import_data.screenshot_jobj, 6, -1);\n    JOBJ_GetChild(menu_jobj, &import_data.scroll_jobj, 7, -1);\n    JOBJ_GetChild(menu_jobj, &import_data.scroll_top, 9, -1);\n    JOBJ_GetChild(menu_jobj, &import_data.scroll_bot, 10, -1);\n\n    // hide all\n    JOBJ_SetFlagsAll(import_data.memcard_jobj[0], JOBJ_HIDDEN);\n    JOBJ_SetFlagsAll(import_data.memcard_jobj[1], JOBJ_HIDDEN);\n    JOBJ_SetFlagsAll(import_data.screenshot_jobj, JOBJ_HIDDEN);\n    JOBJ_SetFlagsAll(import_data.scroll_jobj, JOBJ_HIDDEN);\n\n    // create title and desc text\n    Text *title_text = Text_CreateText(SIS_ID, import_data.canvas);\n    title_text->kerning = 1;\n    title_text->use_aspect = 1;\n    title_text->aspect.X = 305;\n    title_text->trans.X = -28;\n    title_text->trans.Y = -21;\n    title_text->trans.Z = menu_jobj->trans.Z;\n    title_text->scale.X = (menu_jobj->scale.X * 0.01) * 11;\n    title_text->scale.Y = (menu_jobj->scale.Y * 0.01) * 11;\n    Text_AddSubtext(title_text, 0, 0, \"-\");\n    import_data.title_text = title_text;\n    Text *desc_text = Text_CreateText(SIS_ID, import_data.canvas);\n    desc_text->kerning = 1;\n    desc_text->use_aspect = 1;\n    desc_text->aspect.X = 930;\n    desc_text->trans.X = -28;\n    desc_text->trans.Y = 14.5;\n    desc_text->trans.Z = menu_jobj->trans.Z;\n    desc_text->scale.X = (menu_jobj->scale.X * 0.01) * 5;\n    desc_text->scale.Y = (menu_jobj->scale.Y * 0.01) * 5;\n    Text_AddSubtext(desc_text, 0, 0, \"-\");\n    import_data.desc_text = desc_text;\n\n    // save original snapshot imagedesc pointer\n    import_data.snap.orig_image = import_data.screenshot_jobj->dobj->mobj->tobj->imagedesc;\n\n    // disable inputs for CSS\n    *stc_css_exitkind = 5;\n\n    // init card select menu\n    Menu_SelCard_Init(menu_gobj);\n\n    return menu_gobj;\n}\nvoid Menu_Destroy(GOBJ *menu_gobj)\n{\n    // run specific menu state code\n    switch (import_data.menu_state)\n    {\n    case (IMP_SELCARD):\n    {\n        Menu_SelCard_Exit(menu_gobj);\n        break;\n    }\n    case (IMP_SELFILE):\n    {\n        Menu_SelFile_Exit(menu_gobj);\n        break;\n    }\n    }\n\n    // destroy text\n    Text_Destroy(import_data.title_text);\n    import_data.title_text = 0;\n    Text_Destroy(import_data.desc_text);\n    import_data.desc_text = 0;\n\n    // destroy gobj\n    GObj_Destroy(menu_gobj);\n    import_data.menu_gobj = 0;\n\n    // enable CSS inputs\n    *stc_css_exitkind = 0;\n    *stc_css_delay = 0;\n\n    return;\n}\nvoid Menu_Think(GOBJ *menu_gobj)\n{\n\n    *stc_css_delay = 2;\n\n    switch (import_data.menu_state)\n    {\n    case (IMP_SELCARD):\n    {\n        Menu_SelCard_Think(menu_gobj);\n        break;\n    }\n    case (IMP_SELFILE):\n    {\n        Menu_SelFile_Think(menu_gobj);\n        break;\n    }\n    case (IMP_CONFIRM):\n    {\n        Menu_Confirm_Think(menu_gobj);\n        break;\n    }\n    }\n\n    return;\n}\n// Select Card\nvoid Menu_SelCard_Init(GOBJ *menu_gobj)\n{\n\n    // get jobj\n    JOBJ *menu_jobj = menu_gobj->hsd_object;\n\n    // init state and cursor\n    import_data.menu_state = IMP_SELCARD;\n    import_data.cursor = 0;\n\n    // init memcard inserted state\n    import_data.memcard_inserted[0] = 0;\n    import_data.memcard_inserted[1] = 0;\n\n    // show memcards\n    JOBJ_ClearFlagsAll(import_data.memcard_jobj[0], JOBJ_HIDDEN);\n    JOBJ_ClearFlagsAll(import_data.memcard_jobj[1], JOBJ_HIDDEN);\n\n    // create memcard text\n    Text *memcard_text = Text_CreateText(SIS_ID, import_data.canvas);\n    memcard_text->kerning = 1;\n    memcard_text->align = 1;\n    memcard_text->trans.Z = menu_jobj->trans.Z + 2;\n    memcard_text->scale.X = (menu_jobj->scale.X * 0.01) * 5;\n    memcard_text->scale.Y = (menu_jobj->scale.Y * 0.01) * 5;\n    import_data.option_text = memcard_text;\n    Text_AddSubtext(memcard_text, -159, 45, \"Slot A\");\n    Text_AddSubtext(memcard_text, 159, 45, \"Slot B\");\n\n    // edit title\n    Text_SetText(import_data.title_text, 0, \"Select Memory Card\");\n\n    // edit description\n    Text_SetText(import_data.desc_text, 0, \"\");\n\n    return;\n}\nvoid Menu_SelCard_Think(GOBJ *menu_gobj)\n{\n\n    // init\n    int down = Pad_GetRapidHeld(*stc_css_hmnport);\n\n    // update memcard info\n    for (int i = 1; i >= 0; i--)\n    {\n        // probe slot\n        u8 is_inserted;\n\n        s32 memSize, sectorSize;\n        if (CARDProbeEx(i, &memSize, &sectorSize) == CARD_RESULT_READY)\n        {\n            // if it was just inserted, get info\n            if (import_data.memcard_inserted[i] == 0)\n            {\n\n                // mount card\n                stc_memcard_work->is_done = 0;\n                if (CARDMountAsync(i, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY)\n                {\n                    // check card\n                    Memcard_Wait();\n                    stc_memcard_work->is_done = 0;\n                    if (CARDCheckAsync(i, Memcard_RemovedCallback) == CARD_RESULT_READY)\n                    {\n                        Memcard_Wait();\n\n                        // if we get this far, a valid memcard is inserted\n                        is_inserted = 1;\n                        SFX_PlayCommon(2);\n                        //import_data.cursor = i; // move cursor to this\n\n                        // get free blocks\n                        s32 byteNotUsed, filesNotUsed;\n                        if (CARDFreeBlocks(i, &byteNotUsed, &filesNotUsed) == CARD_RESULT_READY)\n                        {\n                            import_data.memcard_free_blocks[i] = (byteNotUsed / 8192);\n                            import_data.memcard_free_files[i] = filesNotUsed;\n                        }\n                    }\n                    else\n                        is_inserted = 0;\n\n                    CARDUnmount(i);\n                    stc_memcard_work->is_done = 0;\n                }\n                else\n                    is_inserted = 0;\n            }\n            else\n                is_inserted = 1;\n        }\n        else\n            is_inserted = 0;\n\n        import_data.memcard_inserted[i] = is_inserted;\n    }\n\n    // cursor movement\n    if (down & (HSD_BUTTON_LEFT | HSD_BUTTON_DPAD_LEFT)) // check for cursor left\n    {\n        if (import_data.cursor > 0)\n        {\n            import_data.cursor--;\n            SFX_PlayCommon(2);\n        }\n    }\n    else if (down & (HSD_BUTTON_RIGHT | HSD_BUTTON_DPAD_RIGHT)) // check for cursor right\n    {\n        if (import_data.cursor < 1)\n        {\n            import_data.cursor++;\n            SFX_PlayCommon(2);\n        }\n    }\n\n    // highlight cursor\n    for (int i = 0; i < 2; i++)\n    {\n        Text_SetColor(import_data.option_text, i, &text_white);\n    }\n    Text_SetColor(import_data.option_text, import_data.cursor, &text_gold);\n\n    Text *desc_text = import_data.desc_text;\n    int cursor = import_data.cursor;\n    if (import_data.memcard_inserted[cursor] == 0)\n        Text_SetText(desc_text, 0, \"No device is inserted in Slot %s.\", slots_names[cursor]);\n    else\n        Text_SetText(desc_text, 0, \"Load recording from the memory card in Slot %s.\", slots_names[cursor]);\n\n    // check for exit\n    if (down & HSD_BUTTON_B)\n    {\n        Menu_Destroy(menu_gobj);\n        SFX_PlayCommon(0);\n    }\n\n    // check for A\n    else if (down & HSD_BUTTON_A)\n    {\n        // check if valid memcard inserted\n        if (import_data.memcard_inserted[cursor] == 0)\n            SFX_PlayCommon(3);\n\n        // is inserted\n        else\n        {\n            import_data.memcard_slot = cursor;\n            SFX_PlayCommon(1);\n            Menu_SelCard_Exit(menu_gobj);\n            Menu_SelFile_Init(menu_gobj);\n        }\n    }\n\n    return;\n}\nvoid Menu_SelCard_Exit(GOBJ *menu_gobj)\n{\n    JOBJ_SetFlagsAll(import_data.memcard_jobj[0], JOBJ_HIDDEN);\n    JOBJ_SetFlagsAll(import_data.memcard_jobj[1], JOBJ_HIDDEN);\n\n    // destroy memcard text\n    Text_Destroy(import_data.option_text);\n    import_data.option_text = 0;\n\n    return;\n}\n// Select File\nvoid Menu_SelFile_Init(GOBJ *menu_gobj)\n{\n\n    // get jobj\n    JOBJ *menu_jobj = menu_gobj->hsd_object;\n\n    // init state and cursor\n    import_data.menu_state = IMP_SELFILE;\n    import_data.cursor = 0;\n    import_data.page = 0;\n\n    // show memcards\n    JOBJ_ClearFlagsAll(import_data.scroll_jobj, JOBJ_HIDDEN);\n    JOBJ_ClearFlagsAll(import_data.screenshot_jobj, JOBJ_HIDDEN);\n\n    // create file name text\n    Text *filename_text = Text_CreateText(SIS_ID, import_data.canvas);\n    filename_text->kerning = 1;\n    filename_text->align = 0;\n    filename_text->use_aspect = 1;\n    filename_text->aspect.X = 525;\n    filename_text->trans.X = -27.8;\n    filename_text->trans.Y = -13.6;\n    filename_text->trans.Z = menu_jobj->trans.Z;\n    filename_text->scale.X = (menu_jobj->scale.X * 0.01) * 5;\n    filename_text->scale.Y = (menu_jobj->scale.Y * 0.01) * 5;\n    import_data.filename_text = filename_text;\n    for (int i = 0; i < IMPORT_FILESPERPAGE; i++)\n    {\n        Text_AddSubtext(filename_text, 0, i * 40, \"\");\n    }\n\n#define FILEINFO_X 235\n#define FILEINFO_Y -20\n#define FILEINFO_YOFFSET 35\n#define FILEINFO_STAGEY FILEINFO_Y\n#define FILEINFO_HMNY FILEINFO_STAGEY + FILEINFO_YOFFSET\n#define FILEINFO_CPUY FILEINFO_HMNY + FILEINFO_YOFFSET\n#define FILEINFO_DATEY FILEINFO_CPUY + (FILEINFO_YOFFSET * 2)\n#define FILEINFO_TIMEY FILEINFO_DATEY + FILEINFO_YOFFSET\n\n    // create file info text\n    Text *fileinfo_text = Text_CreateText(SIS_ID, import_data.canvas);\n    fileinfo_text->kerning = 1;\n    fileinfo_text->align = 0;\n    fileinfo_text->use_aspect = 1;\n    fileinfo_text->aspect.X = 300;\n    fileinfo_text->trans.Z = menu_jobj->trans.Z;\n    fileinfo_text->scale.X = (menu_jobj->scale.X * 0.01) * 4.5;\n    fileinfo_text->scale.Y = (menu_jobj->scale.Y * 0.01) * 4.5;\n    import_data.fileinfo_text = fileinfo_text;\n    Text_AddSubtext(fileinfo_text, FILEINFO_X, FILEINFO_STAGEY, \"Stage: \");\n    Text_AddSubtext(fileinfo_text, FILEINFO_X, FILEINFO_HMNY, \"HMN: \");\n    Text_AddSubtext(fileinfo_text, FILEINFO_X, FILEINFO_CPUY, \"CPU: \");\n    Text_AddSubtext(fileinfo_text, FILEINFO_X, FILEINFO_DATEY, \"Date: \");\n    Text_AddSubtext(fileinfo_text, FILEINFO_X, FILEINFO_TIMEY, \"Time: \");\n\n    // edit title\n    Text_SetText(import_data.title_text, 0, \"Select Recording\");\n\n    // edit description\n    Text_SetText(import_data.desc_text, 0, \"A = Select          B = Return          X = Delete\");\n\n    // search card for save files\n    import_data.file_num = 0;\n    int slot = import_data.memcard_slot;\n    char *filename[32];\n    int file_size;\n    s32 memSize, sectorSize;\n    if (CARDProbeEx(slot, &memSize, &sectorSize) == CARD_RESULT_READY)\n    {\n        // mount card\n        stc_memcard_work->is_done = 0;\n        if (CARDMountAsync(slot, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY)\n        {\n            // check card\n            Memcard_Wait();\n            stc_memcard_work->is_done = 0;\n            if (CARDCheckAsync(slot, Memcard_RemovedCallback) == CARD_RESULT_READY)\n            {\n                Memcard_Wait();\n\n                // get free blocks\n                s32 byteNotUsed, filesNotUsed;\n                if (CARDFreeBlocks(slot, &byteNotUsed, &filesNotUsed) == CARD_RESULT_READY)\n                {\n\n                    // search for files with name TMREC\n                    for (int i = 0; i < CARD_MAX_FILE; i++)\n                    {\n\n                        CARDStat card_stat;\n\n                        if (CARDGetStatus(slot, i, &card_stat) == CARD_RESULT_READY)\n                        {\n                            // check company code\n                            if (strncmp(os_info->company, card_stat.company, sizeof(os_info->company)) == 0)\n                            {\n                                // check game name\n                                if (strncmp(os_info->gameName, card_stat.gameName, sizeof(os_info->gameName)) == 0)\n                                {\n                                    // check file name\n                                    if (strncmp(\"TMREC\", card_stat.fileName, 5) == 0)\n                                    {\n                                        OSReport(\"found recording file %s with size %d\\n\", card_stat.fileName, card_stat.length);\n                                        import_data.file_info[import_data.file_num].file_size = card_stat.length;                                      // save file size\n                                        import_data.file_info[import_data.file_num].file_no = i;                                                       // save file no\n                                        memcpy(import_data.file_info[import_data.file_num].file_name, card_stat.fileName, sizeof(card_stat.fileName)); // save file name\n                                        import_data.file_num++;                                                                                        // increment file amount\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            CARDUnmount(slot);\n            stc_memcard_work->is_done = 0;\n        }\n    }\n\n    // init scroll bar according to import_data.file_num\n    int page_total = import_data.file_num / (IMPORT_FILESPERPAGE + 1);\n    if (page_total == 0)\n        JOBJ_SetFlagsAll(import_data.scroll_jobj, JOBJ_HIDDEN);\n    else\n        import_data.scroll_bot->trans.Y = (-16.2 / (page_total + 1));\n\n    // display orig texture\n    import_data.screenshot_jobj->dobj->mobj->tobj->imagedesc = import_data.snap.orig_image;\n\n    // load in first page recordsings\n    int page_result = Menu_SelFile_LoadPage(menu_gobj, 0);\n    if (page_result == -1)\n    {\n        // create dialog\n        Menu_Confirm_Init(menu_gobj, CFRM_ERR);\n        SFX_PlayCommon(3);\n    }\n\n    return;\n}\nvoid Menu_SelFile_Think(GOBJ *menu_gobj)\n{\n\n    // init\n    int down = Pad_GetRapidHeld(*stc_css_hmnport);\n\n    // first ensure memcard is still inserted\n    s32 memSize, sectorSize;\n    if (CARDProbeEx(import_data.memcard_slot, &memSize, &sectorSize) != CARD_RESULT_READY)\n        goto EXIT;\n\n    // if no files exist\n    if (import_data.file_num == 0)\n    {\n        // check for exit\n        if (down & (HSD_BUTTON_B | HSD_BUTTON_A))\n            goto EXIT;\n    }\n\n    // navigation think\n    else\n    {\n\n        // cursor movement\n        if (down & (HSD_BUTTON_UP | HSD_BUTTON_DPAD_UP)) // check for cursor up\n        {\n            // if cursor is at the top of the page, try to advance to prev\n            if (import_data.cursor == 0)\n            {\n                // try to load prev page\n                int page_result = Menu_SelFile_LoadPage(menu_gobj, import_data.page - 1);\n                if (page_result == 1) // page loaded, update cursor\n                {\n                    SFX_PlayCommon(2);\n                    import_data.cursor = (IMPORT_FILESPERPAGE - 1);\n                    import_data.page--;\n                }\n                else if (page_result == -1)\n                {\n                    // create dialog\n                    Menu_Confirm_Init(menu_gobj, CFRM_ERR);\n                    SFX_PlayCommon(3);\n                    goto EXIT_FUNC; // gotos are weird but i couldnt think of another way\n                }\n            }\n            // if cursor can be advanced\n            else if (import_data.cursor > 0)\n            {\n                import_data.cursor--;\n                SFX_PlayCommon(2);\n            }\n        }\n        else if (down & (HSD_BUTTON_LEFT | HSD_BUTTON_DPAD_LEFT)) // check for cursor down\n        {\n            // try to load prev page\n            int page_result = Menu_SelFile_LoadPage(menu_gobj, import_data.page - 1);\n            if (page_result == 1) // page loaded, update cursor\n            {\n                SFX_PlayCommon(2);\n                import_data.cursor = 0;\n                import_data.page--;\n            }\n            else if (page_result == -1)\n            {\n                // create dialog\n                Menu_Confirm_Init(menu_gobj, CFRM_ERR);\n                SFX_PlayCommon(3);\n                goto EXIT_FUNC; // gotos are weird but i couldnt think of another way\n            }\n        }\n        else if (down & (HSD_BUTTON_DOWN | HSD_BUTTON_DPAD_DOWN)) // check for cursor down\n        {\n\n            // if cursor is at the end of the page, try to advance to next\n            if (import_data.cursor == (IMPORT_FILESPERPAGE - 1))\n            {\n                // try to load next page\n                int page_result = Menu_SelFile_LoadPage(menu_gobj, import_data.page + 1);\n                if (page_result == 1) // page loaded, update cursor\n                {\n                    SFX_PlayCommon(2);\n                    import_data.cursor = 0;\n                    import_data.page++;\n                }\n                else if (page_result == -1)\n                {\n                    // create dialog\n                    Menu_Confirm_Init(menu_gobj, CFRM_ERR);\n                    SFX_PlayCommon(3);\n                    goto EXIT_FUNC; // gotos are weird but i couldnt think of another way\n                }\n            }\n\n            // if cursor can be advanced\n            else if ((import_data.cursor < import_data.files_on_page - 1))\n            {\n                import_data.cursor++;\n                SFX_PlayCommon(2);\n            }\n        }\n        else if (down & (HSD_BUTTON_RIGHT | HSD_BUTTON_DPAD_RIGHT)) // check for cursor right\n        {\n            // try to load next page\n            int page_result = Menu_SelFile_LoadPage(menu_gobj, import_data.page + 1);\n            if (page_result == 1) // page loaded, update cursor\n            {\n                SFX_PlayCommon(2);\n                import_data.cursor = 0;\n                import_data.page++;\n            }\n            else if (page_result == -1)\n            {\n                // create dialog\n                Menu_Confirm_Init(menu_gobj, CFRM_ERR);\n                SFX_PlayCommon(3);\n                goto EXIT_FUNC; // gotos are weird but i couldnt think of another way\n            }\n        }\n\n        // highlight cursor\n        int cursor = import_data.cursor;\n        for (int i = 0; i < IMPORT_FILESPERPAGE; i++)\n        {\n            Text_SetColor(import_data.filename_text, i, &text_white);\n        }\n        Text_SetColor(import_data.filename_text, cursor, &text_gold);\n\n        // update file info text\n        /*\n    u8 *transfer_buf = import_data.snap.file_data[cursor];\n    ExportHeader *header = transfer_buf;\n    u8 *compressed_recording = transfer_buf + header->lookup.ofst_recording;\n    Text_SetText(import_data.fileinfo_text, 0, \"Stage: %s\", stage_names[header->metadata.stage_internal]);\n    Text_SetText(import_data.fileinfo_text, 1, \"HMN: %s\", Fighter_GetName(header->metadata.hmn));\n    Text_SetText(import_data.fileinfo_text, 2, \"CPU: %s\", Fighter_GetName(header->metadata.cpu));\n    Text_SetText(import_data.fileinfo_text, 3, \"Created: %d/%d/%d\", 10, 30, 1995);\n    */\n\n        // update file info text from header data\n        int this_file_index = (import_data.page * IMPORT_FILESPERPAGE) + cursor;\n        ExportHeader *header = &import_data.header[cursor];\n\n        // update file info text\n        Text_SetText(import_data.fileinfo_text, 0, \"Stage: %s\", stage_names[header->metadata.stage_internal]);\n        Text_SetText(import_data.fileinfo_text, 1, \"HMN: %s\", Fighter_GetName(header->metadata.hmn));\n        Text_SetText(import_data.fileinfo_text, 2, \"CPU: %s\", Fighter_GetName(header->metadata.cpu));\n        Text_SetText(import_data.fileinfo_text, 3, \"Date: %d/%d/%d\", header->metadata.month, header->metadata.day, header->metadata.year);\n        Text_SetText(import_data.fileinfo_text, 4, \"Time: %d:%02d:%02d\", header->metadata.hour, header->metadata.minute, header->metadata.second);\n\n        // async load snapshots\n        Menu_SelFile_LoadAsyncThink(menu_gobj);\n\n        // update file image\n        // if this file is loaded\n        if (import_data.snap.is_loaded[cursor] == 1)\n        {\n            // copy screenshot data to buffer\n            void *file_data = import_data.snap.file_data[cursor];\n            RGB565 *img = file_data + header->lookup.ofst_screenshot;\n            int img_size = GXGetTexBufferSize(header->metadata.image_width, header->metadata.image_height, 4, 0, 0);\n            memcpy(import_data.snap.image, img, img_size); // copu image to 32 byte aligned buffer\n\n            // invalidate cache\n            DCFlushRange(import_data.snap.image, img_size);\n\n            // display this texture\n            image_desc.img_ptr = import_data.snap.image;                            // store pointer to resized image\n            import_data.screenshot_jobj->dobj->mobj->tobj->imagedesc = &image_desc; // replace pointer to imagedesc\n        }\n        else\n        {\n            // display orig texture\n            import_data.screenshot_jobj->dobj->mobj->tobj->imagedesc = import_data.snap.orig_image;\n        }\n\n        // check for exit\n        if (down & HSD_BUTTON_B)\n        {\n        EXIT:\n            SFX_PlayCommon(0);\n            Menu_SelFile_Exit(menu_gobj);\n            Menu_SelCard_Init(menu_gobj);\n        }\n\n        // check to delete\n        else if (down & HSD_BUTTON_X)\n        {\n            Menu_Confirm_Init(menu_gobj, CFRM_DEL);\n            SFX_PlayCommon(1);\n        }\n\n        // check for select\n        else if (down & HSD_BUTTON_A)\n        {\n            int kind;                                               // init confirm kind\n            int vers = import_data.header[cursor].metadata.version; // get version number\n\n            // check if version is compatible with this release\n            if (vers == REC_VERS)\n                kind = CFRM_LOAD;\n            else if (vers > REC_VERS)\n                kind = CFRM_NEW;\n            else if (vers < REC_VERS)\n                kind = CFRM_OLD;\n\n            // open confirm dialog\n            Menu_Confirm_Init(menu_gobj, kind);\n            SFX_PlayCommon(1);\n        }\n    }\nEXIT_FUNC:\n    return;\n}\nvoid Menu_SelFile_Exit(GOBJ *menu_gobj)\n{\n    JOBJ_SetFlagsAll(import_data.scroll_jobj, JOBJ_HIDDEN);\n    JOBJ_SetFlagsAll(import_data.screenshot_jobj, JOBJ_HIDDEN);\n\n    // destroy option text\n    Text_Destroy(import_data.filename_text);\n    import_data.filename_text = 0;\n    Text_Destroy(import_data.fileinfo_text);\n    import_data.fileinfo_text = 0;\n\n    // cancel card read if in progress\n    int memcard_status = Memcard_CheckStatus();\n    if (memcard_status == 11)\n    {\n        // cancel read\n        stc_memcard_work->card_file_info.length = -1;\n\n        // wait for callback to fire\n        // i do this because the callback will always set some\n        // variable in the workarea regardless of its cancelled\n        while (memcard_status == 11)\n        {\n            memcard_status = Memcard_CheckStatus();\n        }\n    }\n\n    // free prev buffers\n    for (int i = 0; i < IMPORT_FILESPERPAGE; i++)\n    {\n        // if exists\n        if (import_data.snap.file_data[i] != 0)\n        {\n            HSD_Free(import_data.snap.file_data[i]);\n            import_data.snap.file_data[i] = 0;\n        }\n    }\n\n    return;\n}\nint Menu_SelFile_LoadPage(GOBJ *menu_gobj, int page)\n{\n\n    int result = 0;\n    int files_on_page;\n    int cursor = import_data.cursor; // start at cursor\n    int page_total = import_data.file_num / IMPORT_FILESPERPAGE;\n\n    // ensure page exists\n    if ((page >= 0) && (page <= page_total))\n    {\n        // determine files on page\n        if (((page + 1) * IMPORT_FILESPERPAGE) < import_data.file_num)\n            files_on_page = IMPORT_FILESPERPAGE; // page is filled with files\n        else\n            files_on_page = import_data.file_num - (page * IMPORT_FILESPERPAGE); // remaining files\n\n        // ensure page has at least one recording\n        if (files_on_page > 0)\n        {\n\n            // cancel card read if in progress\n            int memcard_status = Memcard_CheckStatus();\n            if (memcard_status == 11)\n            {\n                // cancel read\n                stc_memcard_work->card_file_info.length = -1;\n\n                // wait for callback to fire\n                while (memcard_status == 11)\n                {\n                    memcard_status = Memcard_CheckStatus();\n                }\n            }\n\n            void *buffer = calloc(CARD_READ_SIZE);\n            import_data.files_on_page = files_on_page; // update amount of files on page\n            import_data.snap.loaded_num = 0;\n            import_data.snap.load_inprogress = 0;\n            for (int i = 0; i < IMPORT_FILESPERPAGE; i++)\n            {\n                import_data.snap.is_loaded[i] = 0; // init files as unloaded\n            }\n            result = 1; // set page as toggled\n            int slot = import_data.memcard_slot;\n\n            // update scroll bar position\n            import_data.scroll_top->trans.Y = ((float)page / (float)(page_total)) * (import_data.scroll_bot->trans.Y);\n            JOBJ_SetMtxDirtySub(menu_gobj->hsd_object);\n\n            // free prev buffers\n            for (int i = 0; i < IMPORT_FILESPERPAGE; i++)\n            {\n                // if exists\n                if (import_data.snap.file_data[i] != 0)\n                {\n                    HSD_Free(import_data.snap.file_data[i]);\n                    import_data.snap.file_data[i] = 0;\n                }\n            }\n\n            // blank out all text\n            for (int i = 0; i < IMPORT_FILESPERPAGE; i++)\n            {\n                Text_SetText(import_data.filename_text, i, \"\");\n            }\n\n            // mount card\n            s32 memSize, sectorSize;\n            if (CARDProbeEx(slot, &memSize, &sectorSize) == CARD_RESULT_READY)\n            {\n                // mount card\n                stc_memcard_work->is_done = 0;\n                if (CARDMountAsync(slot, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY)\n                {\n                    Memcard_Wait();\n\n                    // check card\n                    stc_memcard_work->is_done = 0;\n                    if (CARDCheckAsync(slot, Memcard_RemovedCallback) == CARD_RESULT_READY)\n                    {\n                        Memcard_Wait();\n\n                        // begin loading this page's files\n                        for (int i = 0; i < files_on_page; i++)\n                        {\n\n                            // get file info\n                            int this_file_index = (page * IMPORT_FILESPERPAGE) + i;\n                            char *file_name = import_data.file_info[this_file_index].file_name;\n                            int file_size = import_data.file_info[this_file_index].file_size;\n                            int file_no = import_data.file_info[this_file_index].file_no;\n\n                            // get comment from card\n                            CARDFileInfo card_file_info;\n                            CARDStat card_stat;\n\n                            // get status\n                            if (CARDGetStatus(slot, file_no, &card_stat) == CARD_RESULT_READY)\n                            {\n                                // open card (get file info)\n                                if (CARDOpen(slot, file_name, &card_file_info) == CARD_RESULT_READY)\n                                {\n                                    // try to get header\n                                    if (CARDRead(&card_file_info, buffer, CARD_READ_SIZE, 0x1E00) == CARD_RESULT_READY)\n                                    {\n                                        // deobfuscate stupid melee bullshit\n                                        Memcard_Deobfuscate(buffer, CARD_READ_SIZE);\n                                        ExportHeader *header = buffer + 0x90; // get to header (need to find a less hardcoded way of doing this)\n\n                                        // ensure header contains filename (REC_VERS 1+)\n                                        if (header->metadata.version < 1)\n                                        {\n                                            result = -1;\n                                            CARDClose(&card_file_info);\n                                            break;\n                                        }\n\n                                        else\n                                        {\n                                            // save header\n                                            memcpy(&import_data.header[i], header, sizeof(ExportHeader));\n\n                                            // print user file name\n                                            Text_SetText(import_data.filename_text, i, header->metadata.filename);\n                                        }\n                                    }\n\n                                    CARDClose(&card_file_info);\n                                }\n                            }\n\n                            /*\n                // setup load\n                MemcardSave stc_memcard_save;\n                void *buffer = HSD_MemAlloc(file_size); // alloc buffer for this save\n                import_data.snap.file_data[i] = buffer;      // save buffer pointer\n                stc_memcard_save.data = buffer;             // store pointer to buffer for memcard load operation\n                stc_memcard_save.x4 = 3;\n                stc_memcard_save.size = file_size;\n                stc_memcard_save.xc = -1;\n                Memcard_LoadSnapshot(import_data.memcard_slot, file_name, &stc_memcard_save, &stc_memcard_info->file_name, 0, 0, 0);\n\n                // wait to load\n                int memcard_status = Memcard_CheckStatus();\n                while (memcard_status == 11)\n                {\n                    memcard_status = Memcard_CheckStatus();\n                }\n\n                // if file loaded successfully\n                if (memcard_status == 0)\n                    Text_SetText(import_data.filename_text, i, &stc_memcard_info->file_name[32]);\n                */\n                        }\n                    }\n                    // unmount\n                    CARDUnmount(slot);\n                    stc_memcard_work->is_done = 0;\n                }\n            }\n\n            // free temp read buffer\n            HSD_Free(buffer);\n        }\n    }\n\n    return result;\n}\nvoid Menu_SelFile_DeleteUnsupported(GOBJ *menu_gobj)\n{\n\n    void *buffer = calloc(CARD_READ_SIZE);\n    int slot = import_data.memcard_slot;\n\n    // mount card\n    s32 memSize, sectorSize;\n    if (CARDProbeEx(slot, &memSize, &sectorSize) == CARD_RESULT_READY)\n    {\n        // mount card\n        stc_memcard_work->is_done = 0;\n        if (CARDMountAsync(slot, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY)\n        {\n            Memcard_Wait();\n\n            // check card\n            stc_memcard_work->is_done = 0;\n            if (CARDCheckAsync(slot, Memcard_RemovedCallback) == CARD_RESULT_READY)\n            {\n                Memcard_Wait();\n\n                // loop through all detected TMREC files\n                for (int i = 0; i < import_data.file_num; i++)\n                {\n\n                    // get file info\n                    char *file_name = import_data.file_info[i].file_name;\n                    int file_size = import_data.file_info[i].file_size;\n                    CARDFileInfo card_file_info;\n\n                    /*\n                    so at this point, i have filenames for every TMREC file\n                    present on the memcard. all i have to do is:\n                    - cardopen each file\n                    - cardread the header\n                    - deobfuscate\n                    - check version\n                    - delete file using filename if its a bad file\n                    */\n\n                    // open card (get file info)\n                    if (CARDOpen(slot, file_name, &card_file_info) == CARD_RESULT_READY)\n                    {\n                        // read header\n                        if (CARDRead(&card_file_info, buffer, CARD_READ_SIZE, 0x1E00) == CARD_RESULT_READY)\n                        {\n                            // deobfuscate stupid melee bullshit\n                            Memcard_Deobfuscate(buffer, CARD_READ_SIZE);\n                            ExportHeader *header = buffer + 0x90; // get to header (need to find a less hardcoded way of doing this)\n\n                            // check if unsupported version\n                            if (header->metadata.version < 1)\n                            {\n                                // delete this file\n                                stc_memcard_work->is_done = 0;\n                                if (CARDDeleteAsync(slot, file_name, Memcard_RemovedCallback) == CARD_RESULT_READY)\n                                {\n                                    Memcard_Wait();\n                                }\n                            }\n                        }\n\n                        CARDClose(&card_file_info);\n                    }\n                }\n            }\n            // unmount\n            CARDUnmount(slot);\n            stc_memcard_work->is_done = 0;\n        }\n    }\n\n    // free temp read buffer\n    HSD_Free(buffer);\n\n    return;\n}\nint Menu_SelFile_DeleteFile(GOBJ *menu_gobj, int file_index)\n{\n\n    int result = 0;\n    int slot = import_data.memcard_slot;\n\n    // mount card\n    s32 memSize, sectorSize;\n    if (CARDProbeEx(slot, &memSize, &sectorSize) == CARD_RESULT_READY)\n    {\n        // mount card\n        stc_memcard_work->is_done = 0;\n        if (CARDMountAsync(slot, stc_memcard_work->work_area, 0, Memcard_RemovedCallback) == CARD_RESULT_READY)\n        {\n            Memcard_Wait();\n\n            // check card\n            stc_memcard_work->is_done = 0;\n            if (CARDCheckAsync(slot, Memcard_RemovedCallback) == CARD_RESULT_READY)\n            {\n                Memcard_Wait();\n\n                // get file info\n                char *file_name = import_data.file_info[file_index].file_name;\n                int file_size = import_data.file_info[file_index].file_size;\n                CARDFileInfo card_file_info;\n\n                // open card (get file info)\n                if (CARDOpen(slot, file_name, &card_file_info) == CARD_RESULT_READY)\n                {\n\n                    // delete this file\n                    stc_memcard_work->is_done = 0;\n                    if (CARDDeleteAsync(slot, file_name, Memcard_RemovedCallback) == CARD_RESULT_READY)\n                    {\n                        Memcard_Wait();\n                        result = 1;\n                    }\n\n                    CARDClose(&card_file_info);\n                }\n            }\n            // unmount\n            CARDUnmount(slot);\n            stc_memcard_work->is_done = 0;\n        }\n    }\n\n    return result;\n}\nvoid Menu_SelFile_LoadAsyncThink(GOBJ *menu_gobj)\n{\n\n    // is there a load in progress?\n    if (import_data.snap.load_inprogress == 1)\n    {\n        // is it done?\n        if (Memcard_CheckStatus() != 11)\n        {\n            // increment number of loaded files\n            import_data.snap.loaded_num++;\n\n            // no more load in progress\n            import_data.snap.load_inprogress = 0;\n\n            // set as loaded\n            import_data.snap.is_loaded[import_data.snap.file_loading] = 1;\n        }\n    }\n\n    // check if any pending files to load\n    if ((import_data.snap.load_inprogress == 0) && // checking inprogress again in case the code above set it to 0 this tick\n        (import_data.snap.loaded_num < import_data.files_on_page))\n    {\n\n        // find nearest unloaded file\n        int file_to_load;\n        int cursor = import_data.cursor;\n\n        // check if cursor is loaded\n        if (import_data.snap.is_loaded[cursor] == 0)\n            file_to_load = cursor;\n        // find nearest unloaded file\n        else\n        {\n            // search for unloaded snap nearest to the cursor\n            int search_up = cursor;\n            int search_down = cursor;\n            for (int i = 0; i < (IMPORT_FILESPERPAGE - 1); i++)\n            {\n                search_up--;\n                search_down++;\n\n                // if still on page\n                if (search_up >= 0)\n                {\n                    if (import_data.snap.is_loaded[search_up] == 0)\n                    {\n                        // load this next\n                        file_to_load = search_up;\n                        break;\n                    }\n                }\n\n                // if still on page\n                if (search_down < IMPORT_FILESPERPAGE)\n                {\n                    if (import_data.snap.is_loaded[search_down] == 0)\n                    {\n                        // load this next\n                        file_to_load = search_down;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // get filename and size for this file\n        int this_file_index = (import_data.page * IMPORT_FILESPERPAGE) + file_to_load; // page file index -> TMREC file index\n        int file_size = import_data.file_info[this_file_index].file_size;\n        char *file_name = import_data.file_info[this_file_index].file_name;\n\n        // load next\n        static MemcardSave stc_memcard_save;\n        void *buffer = HSD_MemAlloc(file_size);            // alloc buffer for this save\n        import_data.snap.file_data[file_to_load] = buffer; // save buffer pointer\n        stc_memcard_save.data = buffer;                    // store pointer to buffer for memcard load operation\n        stc_memcard_save.x4 = 3;\n        stc_memcard_save.size = file_size;\n        stc_memcard_save.xc = -1;\n        Memcard_LoadSnapshot(import_data.memcard_slot, file_name, &stc_memcard_save, &stc_memcard_info->file_name, 0, 0, 0);\n\n        import_data.snap.load_inprogress = 1;\n        import_data.snap.file_loading = file_to_load;\n    }\n\n    return;\n}\n// Confirm Dialog\nvoid Menu_Confirm_Init(GOBJ *menu_gobj, int kind)\n{\n\n    // init cursor\n    import_data.confirm.cursor = 0;\n    import_data.menu_state = IMP_CONFIRM;\n    import_data.confirm.kind = kind;\n\n    // Create GOBJ\n    GOBJ *confirm_gobj = GObj_Create(4, 5, 0);\n    GObj_AddGXLink(confirm_gobj, GXLink_Common, MENUCAM_GXLINK, 130);\n    JOBJ *confirm_jobj = JOBJ_LoadJoint(stc_import_assets->import_popup);\n    GObj_AddObject(confirm_gobj, R13_U8(-0x3E55), confirm_jobj);\n    import_data.confirm.gobj = confirm_gobj;\n\n    // create text\n    Text *text = Text_CreateText(SIS_ID, import_data.confirm.canvas);\n    text->kerning = 1;\n    text->align = 1;\n    text->use_aspect = 1;\n    text->aspect.X = 380;\n    text->trans.Z = confirm_jobj->trans.Z;\n    text->scale.X = (confirm_jobj->scale.X * 0.01) * 6;\n    text->scale.Y = (confirm_jobj->scale.Y * 0.01) * 6;\n    import_data.confirm.text = text;\n\n    // decide text based on kind\n    switch (kind)\n    {\n    case (CFRM_LOAD):\n    {\n        Text_AddSubtext(text, 0, -50, \"Load this recording?\");\n        Text_AddSubtext(text, -65, 20, \"Yes\");\n        Text_AddSubtext(text, 65, 20, \"No\");\n        break;\n    }\n    case (CFRM_OLD):\n    {\n        Text_AddSubtext(text, 0, -50, \"Cannot load outdated recording.\");\n        Text_AddSubtext(text, 0, 20, \"OK\");\n        Text_SetColor(import_data.confirm.text, 1, &text_gold);\n        break;\n    }\n    case (CFRM_NEW):\n    {\n        Text_AddSubtext(text, 0, -50, \"Cannot load newer recording.\");\n        Text_AddSubtext(text, 0, 20, \"OK\");\n        Text_SetColor(import_data.confirm.text, 1, &text_gold);\n        break;\n    }\n    case (CFRM_DEL):\n    {\n        Text_AddSubtext(text, 0, -50, \"Delete this recording?\");\n        Text_AddSubtext(text, -65, 20, \"Yes\");\n        Text_AddSubtext(text, 65, 20, \"No\");\n        break;\n    }\n    case (CFRM_ERR):\n    {\n        Text_AddSubtext(text, 0, -70, \"Corrupted recording(s) detected.\");\n        Text_AddSubtext(text, 0, -35, \"Would you like to delete them?\");\n        Text_AddSubtext(text, -65, 40, \"Yes\");\n        Text_AddSubtext(text, 65, 40, \"No\");\n        break;\n    }\n    }\n\n    return;\n}\nvoid Menu_Confirm_Think(GOBJ *menu_gobj)\n{\n\n    // init\n    int down = Pad_GetRapidHeld(*stc_css_hmnport);\n\n    // first ensure memcard is still inserted\n    s32 memSize, sectorSize;\n    if (CARDProbeEx(import_data.memcard_slot, &memSize, &sectorSize) != CARD_RESULT_READY)\n        goto EXIT;\n\n    switch (import_data.confirm.kind)\n    {\n    case (CFRM_LOAD):\n    {\n        // cursor movement\n        if (down & (HSD_BUTTON_RIGHT | HSD_BUTTON_DPAD_RIGHT)) // check for cursor right\n        {\n            if (import_data.confirm.cursor < 1)\n            {\n                import_data.confirm.cursor++;\n                SFX_PlayCommon(2);\n            }\n        }\n        else if (down & (HSD_BUTTON_LEFT | HSD_BUTTON_DPAD_LEFT)) // check for cursor down\n        {\n            if (import_data.confirm.cursor > 0)\n            {\n                import_data.confirm.cursor--;\n                SFX_PlayCommon(2);\n            }\n        }\n\n        // highlight cursor\n        int cursor = import_data.confirm.cursor;\n        for (int i = 0; i < 2; i++)\n        {\n            Text_SetColor(import_data.confirm.text, i + 1, &text_white);\n        }\n        Text_SetColor(import_data.confirm.text, cursor + 1, &text_gold);\n\n        // check for exit\n        if (down & HSD_BUTTON_B)\n        {\n        EXIT:\n            Menu_Confirm_Exit(menu_gobj);\n            SFX_PlayCommon(0);\n            import_data.menu_state = IMP_SELFILE;\n        }\n\n        // check for select\n        else if (down & HSD_BUTTON_A)\n        {\n            // check which option is selected\n            if (cursor == 0)\n            {\n\n                // get variables and junk\n                VSMinorData *css_minorscene = *stc_css_minorscene;\n                int this_file_index = (import_data.page * IMPORT_FILESPERPAGE) + import_data.cursor;\n                ExportHeader *header = &import_data.header[import_data.cursor];\n                Preload *preload = Preload_GetTable();\n\n                // get match data\n                u8 hmn_kind = header->metadata.hmn;\n                u8 hmn_costume = header->metadata.hmn_costume;\n                u8 cpu_kind = header->metadata.cpu;\n                u8 cpu_costume = header->metadata.cpu_costume;\n                u16 stage_kind = header->metadata.stage_external;\n\n                // determine which player index for hmn and cpu\n                u8 hmn_index, cpu_index;\n                if (*stc_css_hmnport > 0)\n                {\n                    cpu_index = 0;\n                    hmn_index = 1;\n                }\n                else\n                {\n                    hmn_index = 0;\n                    cpu_index = 1;\n                }\n\n                // set fighters\n                css_minorscene->vs_data.match_init.playerData[hmn_index].kind = hmn_kind;\n                css_minorscene->vs_data.match_init.playerData[hmn_index].costume = hmn_costume; // header->metadata.hmn_costume;\n                preload->fighters[hmn_index].kind = hmn_kind;\n                preload->fighters[hmn_index].costume = hmn_costume;\n                css_minorscene->vs_data.match_init.playerData[cpu_index].kind = cpu_kind;\n                css_minorscene->vs_data.match_init.playerData[cpu_index].costume = cpu_costume; // header->metadata.cpu_costume;\n                preload->fighters[cpu_index].kind = cpu_kind;\n                preload->fighters[cpu_index].costume = cpu_costume;\n\n                // set stage\n                css_minorscene->vs_data.match_init.stage = stage_kind;\n                preload->stage = stage_kind;\n\n                // load files\n                Preload_Update();\n\n                // advance scene\n                *stc_css_exitkind = 1;\n\n                // HUGE HACK ALERT\n                EventDesc *(*GetEventDesc)(int page, int event) = RTOC_PTR(TM_DATA + (24 * 4));\n                EventDesc *event_desc = GetEventDesc(1, 0);\n                event_desc->isSelectStage = 0;\n                event_desc->matchData->stage = stage_kind;\n                *onload_fileno = this_file_index;\n                *onload_slot = import_data.memcard_slot;\n\n                SFX_PlayCommon(1);\n            }\n            else\n                goto EXIT;\n        }\n\n        break;\n    }\n    case (CFRM_OLD):\n    {\n        // check for select\n        if (down & (HSD_BUTTON_A | HSD_BUTTON_B))\n        {\n            Menu_Confirm_Exit(menu_gobj);\n            SFX_PlayCommon(0);\n            import_data.menu_state = IMP_SELFILE;\n        }\n        break;\n    }\n    case (CFRM_NEW):\n    {\n        // check for select\n        if (down & (HSD_BUTTON_A | HSD_BUTTON_B))\n        {\n            Menu_Confirm_Exit(menu_gobj);\n            SFX_PlayCommon(0);\n            import_data.menu_state = IMP_SELFILE;\n        }\n        break;\n    }\n    case (CFRM_DEL):\n    {\n\n        // cursor movement\n        if (down & (HSD_BUTTON_RIGHT | HSD_BUTTON_DPAD_RIGHT)) // check for cursor right\n        {\n            if (import_data.confirm.cursor < 1)\n            {\n                import_data.confirm.cursor++;\n                SFX_PlayCommon(2);\n            }\n        }\n        else if (down & (HSD_BUTTON_LEFT | HSD_BUTTON_DPAD_LEFT)) // check for cursor down\n        {\n            if (import_data.confirm.cursor > 0)\n            {\n                import_data.confirm.cursor--;\n                SFX_PlayCommon(2);\n            }\n        }\n\n        // highlight cursor\n        int cursor = import_data.confirm.cursor;\n        for (int i = 0; i < 2; i++)\n        {\n            Text_SetColor(import_data.confirm.text, i + 1, &text_white);\n        }\n        Text_SetColor(import_data.confirm.text, cursor + 1, &text_gold);\n\n        // check for back\n        if (down & HSD_BUTTON_B)\n        {\n        RETURN_TO_FILESEL:\n            Menu_Confirm_Exit(menu_gobj);\n            SFX_PlayCommon(0);\n            import_data.menu_state = IMP_SELFILE;\n        }\n\n        // check for confirm\n        else if (down & HSD_BUTTON_A)\n        {\n\n            if (cursor == 0)\n            {\n                SFX_PlayCommon(1);\n\n                // delete selected recording\n                int this_file_index = (import_data.page * IMPORT_FILESPERPAGE) + import_data.cursor;\n                Menu_SelFile_DeleteFile(menu_gobj, this_file_index);\n\n                // close dialog\n                Menu_Confirm_Exit(menu_gobj);\n\n                // reload selfile\n                Menu_SelFile_Exit(menu_gobj); // close select file\n                Menu_SelFile_Init(menu_gobj); // open select file\n            }\n            else\n                goto RETURN_TO_FILESEL;\n        }\n        break;\n    }\n    case (CFRM_ERR):\n    {\n\n        // cursor movement\n        if (down & (HSD_BUTTON_RIGHT | HSD_BUTTON_DPAD_RIGHT)) // check for cursor right\n        {\n            if (import_data.confirm.cursor < 1)\n            {\n                import_data.confirm.cursor++;\n                SFX_PlayCommon(2);\n            }\n        }\n        else if (down & (HSD_BUTTON_LEFT | HSD_BUTTON_DPAD_LEFT)) // check for cursor down\n        {\n            if (import_data.confirm.cursor > 0)\n            {\n                import_data.confirm.cursor--;\n                SFX_PlayCommon(2);\n            }\n        }\n\n        // highlight cursor\n        int cursor = import_data.confirm.cursor;\n        for (int i = 0; i < 2; i++)\n        {\n            Text_SetColor(import_data.confirm.text, i + 2, &text_white);\n        }\n        Text_SetColor(import_data.confirm.text, cursor + 2, &text_gold);\n\n        // check for back\n        if (down & HSD_BUTTON_B)\n        {\n        NO_DELETE_CORRUPT:\n            Menu_Confirm_Exit(menu_gobj); // close dialog\n            Menu_SelFile_Exit(menu_gobj); // close select file\n            Menu_SelCard_Init(menu_gobj); // open select card\n            SFX_PlayCommon(0);\n            //import_data.menu_state = IMP_SELCARD;\n        }\n\n        // check for confirm\n        else if (down & HSD_BUTTON_A)\n        {\n\n            if (cursor == 0)\n            {\n                SFX_PlayCommon(1);\n\n                // delete bad recordings\n                Menu_SelFile_DeleteUnsupported(menu_gobj);\n\n                // close dialog\n                Menu_Confirm_Exit(menu_gobj);\n\n                // reload selfile\n                Menu_SelFile_Exit(menu_gobj); // close select file\n                Menu_SelFile_Init(menu_gobj); // open select file\n            }\n            else\n                goto NO_DELETE_CORRUPT;\n        }\n        break;\n    }\n    }\n\n    return;\n}\nvoid Menu_Confirm_Exit(GOBJ *menu_gobj)\n{\n    // destroy option text\n    Text_Destroy(import_data.confirm.text);\n    import_data.confirm.text = 0;\n\n    // destroy gobj\n    GObj_Destroy(import_data.confirm.gobj);\n    import_data.confirm.gobj = 0;\n\n    return;\n}\n\n// Misc functions\nvoid Memcard_Wait()\n{\n\n    while (stc_memcard_work->is_done == 0)\n    {\n        blr2();\n    }\n\n    return;\n}"
  },
  {
    "path": "patch/events/lcancel/build.bat",
    "content": "xcopy /s /y \"assets\\lclData.dat\" \"output/EvLCl.dat\"\n\"../../../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\n\"../../../MexTK/MexTK.exe\" -trim \"output/EvLCl.dat\"\n\npause"
  },
  {
    "path": "patch/events/lcancel/source/lcancel.c",
    "content": "#include \"lcancel.h\"\nstatic char nullString[] = \" \";\n\n// Main Menu\nstatic char **LcOptions_Barrel[] = {\"Off\", \"Stationary\", \"Move\"};\nstatic char **LcOptions_HUD[] = {\"On\", \"Off\"};\nstatic EventOption LcOptions_Main[] = {\n    // Target\n    {\n        .option_kind = OPTKIND_STRING,                                            // the type of option this is; menu, string list, integers list, etc\n        .value_num = sizeof(LcOptions_Barrel) / 4,                                // number of values for this option\n        .option_val = 0,                                                          // value of this option\n        .menu = 0,                                                                // pointer to the menu that pressing A opens\n        .option_name = \"Target\",                                                  // pointer to a string\n        .desc = \"Enable a target to attack. Use DPad down to\\nmanually move it.\", // string describing what this option does\n        .option_values = LcOptions_Barrel,                                        // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // HUD\n    {\n        .option_kind = OPTKIND_STRING,           // the type of option this is; menu, string list, integers list, etc\n        .value_num = sizeof(LcOptions_HUD) / 4,  // number of values for this option\n        .option_val = 0,                         // value of this option\n        .menu = 0,                               // pointer to the menu that pressing A opens\n        .option_name = \"HUD\",                    // pointer to a string\n        .desc = \"Toggle visibility of the HUD.\", // string describing what this option does\n        .option_values = LcOptions_HUD,          // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // Tips\n    {\n        .option_kind = OPTKIND_STRING,                  // the type of option this is; menu, string list, integers list, etc\n        .value_num = sizeof(LcOptions_HUD) / 4,         // number of values for this option\n        .option_val = 0,                                // value of this option\n        .menu = 0,                                      // pointer to the menu that pressing A opens\n        .option_name = \"Tips\",                          // pointer to a string\n        .desc = \"Toggle the onscreen display of tips.\", // string describing what this option does\n        .option_values = LcOptions_HUD,                 // pointer to an array of strings\n        .onOptionChange = Tips_Toggle,\n    },\n    // Help\n    {\n        .option_kind = OPTKIND_FUNC,                                                                                                                                                                                       // the type of option this is; menu, string list, integers list, etc\n        .value_num = 0,                                                                                                                                                                                                    // number of values for this option\n        .option_val = 0,                                                                                                                                                                                                   // value of this option\n        .menu = 0,                                                                                                                                                                                                         // pointer to the menu that pressing A opens\n        .option_name = \"Help\",                                                                                                                                                                                             // pointer to a string\n        .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\n        .option_values = 0,                                                                                                                                                                                                // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // Exit\n    {\n        .option_kind = OPTKIND_FUNC,                     // the type of option this is; menu, string list, integers list, etc\n        .value_num = 0,                                  // number of values for this option\n        .option_val = 0,                                 // value of this option\n        .menu = 0,                                       // pointer to the menu that pressing A opens\n        .option_name = \"Exit\",                           // pointer to a string\n        .desc = \"Return to the Event Selection Screen.\", // string describing what this option does\n        .option_values = 0,                              // pointer to an array of strings\n        .onOptionChange = 0,\n        .onOptionSelect = Event_Exit,\n    },\n};\nstatic EventMenu LabMenu_Main = {\n    .name = \"L-Cancel Training\",                                // the name of this menu\n    .option_num = sizeof(LcOptions_Main) / sizeof(EventOption), // number of options this menu contains\n    .scroll = 0,                                                // runtime variable used for how far down in the menu to start\n    .state = 0,                                                 // bool used to know if this menu is focused, used at runtime\n    .cursor = 0,                                                // index of the option currently selected, used at runtime\n    .options = &LcOptions_Main,                                 // pointer to all of this menu's options\n    .prev = 0,                                                  // pointer to previous menu, used at runtime\n};\n\n// Init Function\nvoid Event_Init(GOBJ *gobj)\n{\n    LCancelData *event_data = gobj->userdata;\n    EventDesc *event_desc = event_data->event_desc;\n    GOBJ *hmn = Fighter_GetGObj(0);\n    FighterData *hmn_data = hmn->userdata;\n    //GOBJ *cpu = Fighter_GetGObj(1);\n    //FighterData *cpu_data = cpu->userdata;\n\n    // theres got to be a better way to do this...\n    event_vars = *event_vars_ptr;\n\n    // get l-cancel assets\n    event_data->lcancel_assets = File_GetSymbol(event_vars->event_archive, \"lclData\");\n\n    // create HUD\n    LCancel_Init(event_data);\n\n    // set CPU AI to no_act 15\n    //cpu_data->cpu.ai = 0;\n\n    return;\n}\n// Think Function\nvoid Event_Think(GOBJ *event)\n{\n    LCancelData *event_data = event->userdata;\n\n    // get fighter data\n    GOBJ *hmn = Fighter_GetGObj(0);\n    FighterData *hmn_data = hmn->userdata;\n    //GOBJ *cpu = Fighter_GetGObj(1);\n    //FighterData *cpu_data = cpu->userdata;\n    HSD_Pad *pad = PadGet(hmn_data->player_controller_number, PADGET_ENGINE);\n\n    /*\n    // give intangibility to cpu\n    cpu_data->flags.no_reaction_always = 1;\n    cpu_data->flags.nudge_disable = 1;\n    Fighter_ApplyOverlay(cpu_data, 9, 0);\n    Fighter_UpdateOverlay(cpu);\n    cpu_data->dmg.percent = 0;\n    Fighter_SetHUDDamage(cpu_data->ply, 0);\n\n\n    // Move CPU\n    if (pad->down == PAD_BUTTON_DPAD_DOWN)\n    {\n        // ensure player is grounded\n        int is_ground = 0;\n        if (hmn_data->phys.air_state == 0)\n        {\n\n            // check for ground in front of player\n            Vec3 coll_pos;\n            int line_index;\n            int line_kind;\n            Vec3 line_unk;\n            float from_x = (hmn_data->phys.pos.X) + (hmn_data->facing_direction * 16);\n            float to_x = from_x;\n            float from_y = (hmn_data->phys.pos.Y + 5);\n            float to_y = from_y - 10;\n            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);\n            if (is_ground == 1)\n            {\n\n                // do this for every subfighter (thanks for complicated code ice climbers)\n                int is_moved = 0;\n                for (int i = 0; i < 2; i++)\n                {\n                    GOBJ *this_fighter = Fighter_GetSubcharGObj(cpu_data->ply, i);\n\n                    if (this_fighter != 0)\n                    {\n\n                        FighterData *this_fighter_data = this_fighter->userdata;\n\n                        if ((this_fighter_data->flags.sleep == 0) && (this_fighter_data->flags.dead == 0))\n                        {\n\n                            is_moved = 1;\n\n                            // place CPU here\n                            this_fighter_data->phys.pos = coll_pos;\n                            this_fighter_data->coll_data.ground_index = line_index;\n\n                            // facing player\n                            this_fighter_data->facing_direction = hmn_data->facing_direction * -1;\n\n                            // update camera box\n                            Fighter_UpdateCameraBox(this_fighter);\n                            this_fighter_data->cameraBox->boundleft_curr = this_fighter_data->cameraBox->boundleft_proj;\n                            this_fighter_data->cameraBox->boundright_curr = this_fighter_data->cameraBox->boundright_proj;\n\n                            // set grounded\n                            this_fighter_data->phys.air_state = 0;\n                            //Fighter_SetGrounded(this_fighter);\n\n                            // kill velocity\n                            Fighter_KillAllVelocity(this_fighter);\n\n                            // enter wait\n                            Fighter_EnterWait(this_fighter);\n\n                            // update ECB\n                            this_fighter_data->coll_data.topN_Curr = this_fighter_data->phys.pos; // move current ECB location to new position\n                            Coll_ECBCurrToPrev(&this_fighter_data->coll_data);\n                            this_fighter_data->cb.Coll(this_fighter);\n\n                            // init CPU logic (for nana's popo position history...)\n                            int cpu_kind = Fighter_GetCPUKind(this_fighter_data->ply);\n                            int cpu_level = Fighter_GetCPULevel(this_fighter_data->ply);\n                            Fighter_CPUInitialize(this_fighter_data, cpu_kind, cpu_level, 0);\n\n                            // place subfighter in the Z axis\n                            if (this_fighter_data->flags.ms == 1)\n                            {\n                                ftCommonData *ft_common = *stc_ftcommon;\n                                this_fighter_data->phys.pos.Z = ft_common->ms_zjostle_max * -1;\n                            }\n                        }\n                    }\n                }\n\n                if (is_moved == 1)\n                {\n                    // savestate\n                    event_vars->Savestate_Save(event_vars->savestate);\n                }\n            }\n        }\n\n        // play SFX\n        if (is_ground == 0)\n        {\n            SFX_PlayCommon(3);\n        }\n        else\n        {\n            SFX_Play(221);\n        }\n    }\n    */\n\n    LCancel_Think(event_data, hmn_data);\n    Barrel_Think(event_data);\n\n    return;\n}\nvoid Event_Exit()\n{\n    Match *match = MATCH;\n\n    // end game\n    match->state = 3;\n\n    // cleanup\n    Match_EndVS();\n\n    // unfreeze\n    HSD_Update *update = HSD_UPDATE;\n    update->pause_develop = 0;\n    return;\n}\n\n// L-Cancel functions\nvoid LCancel_Init(LCancelData *event_data)\n{\n\n    // create hud cobj\n    GOBJ *hudcam_gobj = GObj_Create(19, 20, 0);\n    ArchiveInfo **ifall_archive = 0x804d6d5c;\n    COBJDesc ***dmgScnMdls = File_GetSymbol(*ifall_archive, 0x803f94d0);\n    COBJDesc *cam_desc = dmgScnMdls[1][0];\n    COBJ *hud_cobj = COBJ_LoadDesc(cam_desc);\n    // init camera\n    GObj_AddObject(hudcam_gobj, R13_U8(-0x3E55), hud_cobj);\n    GOBJ_InitCamera(hudcam_gobj, LCancel_HUDCamThink, 7);\n    hudcam_gobj->cobj_links = 1 << 18;\n\n    GOBJ *hud_gobj = GObj_Create(0, 0, 0);\n    event_data->hud.gobj = hud_gobj;\n    // Load jobj\n    JOBJ *hud_jobj = JOBJ_LoadJoint(event_data->lcancel_assets->hud);\n    GObj_AddObject(hud_gobj, 3, hud_jobj);\n    GObj_AddGXLink(hud_gobj, GXLink_Common, 18, 80);\n\n    /*\n    // account for widescreen\n    float aspect = (hud_cobj->projection_param.perspective.aspect / 1.216667) - 1;\n    JOBJ *this_jobj;\n    JOBJ_GetChild(hud_jobj, &this_jobj, 1, -1);\n    this_jobj->trans.X += (this_jobj->trans.X * aspect);\n    JOBJ_SetMtxDirtySub(hud_jobj);\n    */\n\n    // create text canvas\n    int canvas = Text_CreateCanvas(2, hud_gobj, 14, 15, 0, 18, 81, 19);\n    event_data->hud.canvas = canvas;\n\n    // init text\n    Text **text_arr = &event_data->hud.text_time;\n    for (int i = 0; i < 3; i++)\n    {\n\n        // Create text object\n        Text *hud_text = Text_CreateText(2, canvas);\n        text_arr[i] = hud_text;\n        hud_text->kerning = 1;\n        hud_text->align = 1;\n        hud_text->use_aspect = 1;\n\n        // Get position\n        Vec3 text_pos;\n        JOBJ *text_jobj;\n        JOBJ_GetChild(hud_jobj, &text_jobj, 2 + i, -1);\n        JOBJ_GetWorldPosition(text_jobj, 0, &text_pos);\n\n        // adjust scale\n        Vec3 *scale = &hud_jobj->scale;\n        // text scale\n        hud_text->scale.X = (scale->X * 0.01) * LCLTEXT_SCALE;\n        hud_text->scale.Y = (scale->Y * 0.01) * LCLTEXT_SCALE;\n        hud_text->aspect.X = 165;\n\n        // text position\n        hud_text->trans.X = text_pos.X + (scale->X / 4.0);\n        hud_text->trans.Y = (text_pos.Y * -1) + (scale->Y / 4.0);\n\n        // dummy text\n        Text_AddSubtext(hud_text, 0, 0, \"-\");\n    }\n\n    // save initial arrow position\n    JOBJ *arrow_jobj;\n    JOBJ_GetChild(hud_jobj, &arrow_jobj, LCLARROW_JOBJ, -1);\n    event_data->hud.arrow_base_x = arrow_jobj->trans.X;\n    event_data->hud.arrow_timer = 0;\n    arrow_jobj->trans.X = 0;\n    JOBJ_SetFlags(arrow_jobj, JOBJ_HIDDEN);\n\n    return 0;\n}\nvoid LCancel_Think(LCancelData *event_data, FighterData *hmn_data)\n{\n\n    // run tip logic\n    Tips_Think(event_data, hmn_data);\n\n    JOBJ *hud_jobj = event_data->hud.gobj->hsd_object;\n\n    // log fastfall frame\n    // if im in a fastfall-able state\n    int state = hmn_data->state;\n    //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))\n    {\n        if (hmn_data->phys.self_vel.Y < 0) // can i fastfall?\n        {\n            // did i fastfall yet?\n            if (hmn_data->flags.is_fastfall)\n                event_data->is_fastfall = 1; // set as fastfall this session\n            else\n                event_data->fastfall_frame++; // increment frames\n        }\n        else // cant fastfall, reset frames\n        {\n            event_data->fastfall_frame = 0;\n        }\n    }\n\n    // if aerial landing\n    if (((hmn_data->state >= ASID_LANDINGAIRN) && (hmn_data->state <= ASID_LANDINGAIRLW)) && (hmn_data->TM.state_frame == 0))\n    {\n        // increment total lcls\n        event_data->hud.lcl_total++;\n\n        // determine succession\n        int is_fail = 1;\n        if (hmn_data->input.timer_trigger_any_ignore_hitlag < 7)\n        {\n            is_fail = 0;\n            event_data->hud.lcl_success++;\n        }\n        event_data->is_fail = is_fail; // save l-cancel bool\n\n        // Play appropriate sfx\n        if (is_fail == 0)\n            SFX_PlayRaw(303, 255, 128, 20, 3);\n        else\n            SFX_PlayCommon(3);\n\n        // update timing text\n        int frame_box_id;\n        if (hmn_data->input.timer_trigger_any_ignore_hitlag >= 30)\n        {\n            // update text\n            Text_SetText(event_data->hud.text_time, 0, \"No Press\");\n            frame_box_id = 29;\n        }\n        else\n        {\n            Text_SetText(event_data->hud.text_time, 0, \"%df/7f\", hmn_data->input.timer_trigger_any_ignore_hitlag + 1);\n            frame_box_id = hmn_data->input.timer_trigger_any_ignore_hitlag;\n        }\n\n        // update arrow\n        JOBJ *arrow_jobj;\n        JOBJ_GetChild(hud_jobj, &arrow_jobj, LCLARROW_JOBJ, -1);\n        event_data->hud.arrow_prevpos = arrow_jobj->trans.X;\n        event_data->hud.arrow_nextpos = event_data->hud.arrow_base_x - (frame_box_id * LCLARROW_OFFSET);\n        JOBJ_ClearFlags(arrow_jobj, JOBJ_HIDDEN);\n        event_data->hud.arrow_timer = LCLARROW_ANIMFRAMES;\n\n        // Print airborne frames\n        if (event_data->is_fastfall)\n            Text_SetText(event_data->hud.text_air, 0, \"%df\", event_data->fastfall_frame - 1);\n        else\n            Text_SetText(event_data->hud.text_air, 0, \"-\");\n        event_data->is_fastfall = 0; // reset fastfall bool\n\n        // Print succession\n        float succession = ((float)event_data->hud.lcl_success / (float)event_data->hud.lcl_total) * 100.0;\n        Text_SetText(event_data->hud.text_scs, 0, \"%.1f%%\", succession);\n\n        // Play HUD anim\n        JOBJ_RemoveAnimAll(hud_jobj);\n        JOBJ_AddAnimAll(hud_jobj, 0, event_data->lcancel_assets->hudmatanim[is_fail], 0);\n        JOBJ_ReqAnimAll(hud_jobj, 0);\n    }\n\n    // if autocancel landing\n    if (((hmn_data->state == ASID_LANDING) && (hmn_data->TM.state_frame == 0)) &&                   // if first frame of landing\n        ((hmn_data->TM.state_prev[0] >= ASID_ATTACKAIRN) && (hmn_data->state <= ASID_ATTACKAIRLW))) // came from aerial attack\n    {\n        // state as autocancelled\n        Text_SetText(event_data->hud.text_time, 0, \"Auto-canceled\");\n\n        // Play HUD anim\n        JOBJ_RemoveAnimAll(hud_jobj);\n        JOBJ_AddAnimAll(hud_jobj, 0, event_data->lcancel_assets->hudmatanim[2], 0);\n        JOBJ_ReqAnimAll(hud_jobj, 0);\n    }\n\n    // update arrow animation\n    if (event_data->hud.arrow_timer > 0)\n    {\n        // decrement timer\n        event_data->hud.arrow_timer--;\n\n        // get this frames position\n        float time = 1 - ((float)event_data->hud.arrow_timer / (float)LCLARROW_ANIMFRAMES);\n        float xpos = Bezier(time, event_data->hud.arrow_prevpos, event_data->hud.arrow_nextpos);\n\n        // update position\n        JOBJ *arrow_jobj;\n        JOBJ_GetChild(hud_jobj, &arrow_jobj, LCLARROW_JOBJ, -1); // get timing bar jobj\n        arrow_jobj->trans.X = xpos;\n        JOBJ_SetMtxDirtySub(arrow_jobj);\n    }\n\n    // update HUD anim\n    JOBJ_AnimAll(hud_jobj);\n\n    return;\n}\nvoid LCancel_HUDCamThink(GOBJ *gobj)\n{\n\n    // if HUD enabled and not paused\n    if ((LcOptions_Main[1].option_val == 0) && (Pause_CheckStatus(1) != 2))\n    {\n        CObjThink_Common(gobj);\n    }\n\n    return;\n}\n\n// Tips Functions\nvoid Tips_Toggle(GOBJ *menu_gobj, int value)\n{\n    // destroy existing tips when disabling\n    if (value == 1)\n        event_vars->Tip_Destroy();\n\n    return;\n}\nvoid Tips_Think(LCancelData *event_data, FighterData *hmn_data)\n{\n\n    if (LcOptions_Main[2].option_val == 0)\n    {\n        // shield tip\n        if (event_data->tip.shield_isdisp == 0) // if not shown\n        {\n\n            // update tip conditions\n            // look for a freshly buffered guard off\n            if (((hmn_data->state == ASID_GUARDOFF) && (hmn_data->TM.state_frame == 0)) &&                               // currently in guardoff first frame\n                (hmn_data->TM.state_prev[0] == ASID_GUARD) &&                                                            // was just in wait\n                ((hmn_data->TM.state_prev[3] >= ASID_LANDINGAIRN) && (hmn_data->TM.state_prev[3] <= ASID_LANDINGAIRLW))) // was in aerial landing a few frames ago\n            {\n                // increment condition count\n                event_data->tip.shield_num++;\n\n                // if condition met X times, show tip\n                if (event_data->tip.shield_num >= 3)\n                {\n                    // display tip\n                    char *shield_string = \"Tip:\\nDon't hold the trigger! Quickly \\npress and release to prevent \\nshielding after landing.\";\n                    if (event_vars->Tip_Display(5 * 60, shield_string))\n                    {\n                        // set as shown\n                        //event_data->tip.shield_isdisp = 1;\n                        event_data->tip.shield_num = 0;\n                    }\n                }\n            }\n        }\n\n        // hitbox tip\n        if (event_data->tip.hitbox_isdisp == 0) // if not shown\n        {\n            // update hitbox active bool\n            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\n            {\n\n                // reset hitbox bool on first frame of aerial attack\n                if (hmn_data->TM.state_frame == 0)\n                    event_data->tip.hitbox_active = 0;\n\n                // check if hitbox active\n                for (int i = 0; i < (sizeof(hmn_data->hitbox) / sizeof(ftHit)); i++)\n                {\n                    if (hmn_data->hitbox[i].active != 0)\n                    {\n                        event_data->tip.hitbox_active = 1;\n                        break;\n                    }\n                }\n            }\n\n            // update tip conditions\n            if ((hmn_data->state >= ASID_LANDINGAIRN) && (hmn_data->state <= ASID_LANDINGAIRLW) && (hmn_data->TM.state_frame == 0) && // is in aerial landing\n                (event_data->is_fail == 0) &&\n                (event_data->tip.hitbox_active == 0)) // succeeded the last aerial landing\n            {\n                // increment condition count\n                event_data->tip.hitbox_num++;\n\n                // if condition met X times, show tip\n                if (event_data->tip.hitbox_num >= 3)\n                {\n                    // display tip\n                    char *hitbox_string = \"Tip:\\nDon't land too quickly! Make \\nsure you land after the \\nattack becomes active.\";\n                    if (event_vars->Tip_Display(5 * 60, hitbox_string))\n                    {\n\n                        // set as shown\n                        //event_data->tip.hitbox_isdisp = 1;\n                        event_data->tip.hitbox_num = 0;\n                    }\n                }\n            }\n        }\n\n        // fastfall tip\n        if (event_data->tip.fastfall_isdisp == 0) // if not shown\n        {\n            // update fastfell bool\n            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\n            {\n\n                // reset hitbox bool on first frame of aerial attack\n                if (hmn_data->TM.state_frame == 0)\n                    event_data->tip.fastfall_active = 0;\n\n                // check if fastfalling\n                if (hmn_data->flags.is_fastfall == 1)\n                    event_data->tip.fastfall_active = 1;\n            }\n\n            // update tip conditions\n            if ((hmn_data->state >= ASID_LANDINGAIRN) && (hmn_data->state <= ASID_LANDINGAIRLW) && (hmn_data->TM.state_frame == 0) &&  // is in aerial landing\n                ((hmn_data->input.timer_trigger_any_ignore_hitlag >= 7) && (hmn_data->input.timer_trigger_any_ignore_hitlag <= 15)) && // was early for an l-cancel\n                (event_data->tip.fastfall_active == 0))                                                                                // succeeded the last aerial landing\n            {\n                // increment condition count\n                event_data->tip.fastfall_num++;\n\n                // if condition met X times, show tip\n                if (event_data->tip.fastfall_num >= 3)\n                {\n                    // display tip\n                    char *fastfall_string = \"Tip:\\nDon't forget to fastfall!\\nIt will let you act sooner \\nand help with your \\ntiming.\";\n                    if (event_vars->Tip_Display(5 * 60, fastfall_string))\n                    {\n\n                        // set as shown\n                        //event_data->tip.hitbox_isdisp = 1;\n                        event_data->tip.fastfall_num = 0;\n                    }\n                }\n            }\n        }\n\n        // late tip\n        if (event_data->tip.late_isdisp == 0) // if not shown\n        {\n\n            // update tip conditions\n            if ((hmn_data->state >= ASID_LANDINGAIRN) && (hmn_data->state <= ASID_LANDINGAIRLW) && // is in aerial landing\n                (event_data->is_fail == 1) &&                                                      // failed the l-cancel\n                (hmn_data->input.down & (HSD_TRIGGER_L | HSD_TRIGGER_R | HSD_TRIGGER_Z)))          // was late for an l-cancel by pressing it just now\n            {\n                // increment condition count\n                event_data->tip.late_num++;\n\n                // if condition met X times, show tip\n                if (event_data->tip.late_num >= 3)\n                {\n                    // display tip\n                    char *late_string = \"Tip:\\nTry pressing the trigger a\\nbit earlier, before the\\nfighter lands.\";\n                    if (event_vars->Tip_Display(5 * 60, late_string))\n                    {\n\n                        // set as shown\n                        //event_data->tip.hitbox_isdisp = 1;\n                        event_data->tip.late_num = 0;\n                    }\n                }\n            }\n        }\n    }\n    return;\n}\n\n// Barrel Functions\nvoid Barrel_Think(LCancelData *event_data)\n{\n    GOBJ *barrel_gobj = event_data->barrel_gobj;\n\n    switch (LcOptions_Main[0].option_val)\n    {\n    case (0): // off\n    {\n        // if spawned, remove\n        if (barrel_gobj != 0)\n        {\n            Item_Destroy(barrel_gobj);\n            event_data->barrel_gobj = 0;\n        }\n\n        break;\n    }\n    case (1): // stationary\n    {\n\n        // if not spawned, spawn\n        if (barrel_gobj == 0)\n        {\n            // spawn barrel at center stage\n            barrel_gobj = Barrel_Spawn(0);\n            event_data->barrel_gobj = barrel_gobj;\n        }\n\n        ItemData *barrel_data = barrel_gobj->userdata;\n        barrel_data->can_hold = 0;\n\n        // check to move barrel\n        // get fighter data\n        GOBJ *hmn = Fighter_GetGObj(0);\n        FighterData *hmn_data = hmn->userdata;\n        if (hmn_data->input.down & PAD_BUTTON_DPAD_DOWN)\n        {\n            // ensure player is grounded\n            int isGround = 0;\n            if (hmn_data->phys.air_state == 0)\n            {\n\n                // check for ground in front of player\n                Vec3 coll_pos;\n                int line_index;\n                int line_kind;\n                Vec3 line_unk;\n                float fromX = (hmn_data->phys.pos.X) + (hmn_data->facing_direction * 16);\n                float toX = fromX;\n                float fromY = (hmn_data->phys.pos.Y + 5);\n                float toY = fromY - 10;\n                isGround = GrColl_RaycastGround(&coll_pos, &line_index, &line_kind, &line_unk, -1, -1, -1, 0, fromX, fromY, toX, toY, 0);\n                if (isGround == 1)\n                {\n\n                    // update last pos\n                    event_data->barrel_lastpos = coll_pos;\n\n                    // place barrel here\n                    barrel_data->pos = coll_pos;\n                    barrel_data->coll_data.ground_index = line_index;\n\n                    // update ECB\n                    barrel_data->coll_data.topN_Curr = barrel_data->pos; // move current ECB location to new position\n                    Coll_ECBCurrToPrev(&barrel_data->coll_data);\n                    barrel_data->cb.coll(barrel_gobj);\n\n                    SFX_Play(221);\n                }\n                else\n                {\n                    // play SFX\n                    SFX_PlayCommon(3);\n                }\n            }\n            break;\n        }\n    }\n    case (2): // move\n    {\n        // if not spawned, spawn\n        if (barrel_gobj == 0)\n        {\n            // spawn barrel at center stage\n            barrel_gobj = Barrel_Spawn(1);\n            event_data->barrel_gobj = barrel_gobj;\n        }\n\n        ItemData *barrel_data = barrel_gobj->userdata;\n        barrel_data->can_hold = 0;\n        barrel_data->can_nudge = 0;\n\n        break;\n    }\n    }\n\n    return;\n}\nGOBJ *Barrel_Spawn(int pos_kind)\n{\n\n    LCancelData *event_data = event_vars->event_gobj->userdata;\n    Vec3 *barrel_lastpos = &event_data->barrel_lastpos;\n\n    // determine position to spawn\n    Vec3 pos;\n    pos.Z = 0;\n    switch (pos_kind)\n    {\n    case (0): // center stage\n    {\n        // get position\n        int line_index;\n        int line_kind;\n        Vec3 line_angle;\n        float from_x = 0;\n        float to_x = from_x;\n        float from_y = 6;\n        float to_y = from_y - 1000;\n        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);\n        if (is_ground == 0)\n            goto BARREL_RANDPOS;\n        break;\n    }\n    case (1): // random pos\n    {\n        // setup time\n        int raycast_num = 0;\n        int raytime_start, raytime_end, raytime_time;\n        raytime_start = OSGetTick();\n    BARREL_RANDPOS:\n    {\n\n        // get position\n        int line_index;\n        int line_kind;\n        Vec3 line_angle;\n        float from_x = Stage_GetCameraLeft() + (HSD_Randi(Stage_GetCameraRight() - Stage_GetCameraLeft())) + HSD_Randf();\n        float to_x = from_x;\n        float from_y = Stage_GetCameraBottom() + (HSD_Randi(Stage_GetCameraTop() - Stage_GetCameraBottom())) + HSD_Randf();\n        float to_y = from_y - 1000;\n        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);\n        raycast_num++;\n        if (is_ground == 0)\n            goto BARREL_RANDPOS;\n\n        // ensure it isnt too close to the previous\n        float distance = sqrtf(pow((pos.X - barrel_lastpos->X), 2) + pow((pos.Y - barrel_lastpos->Y), 2));\n        if (distance < 25)\n            goto BARREL_RANDPOS;\n\n        // ensure left and right have ground\n        Vec3 near_pos;\n        float near_fromX = pos.X + 8;\n        float near_fromY = pos.Y + 4;\n        to_y = near_fromY - 4;\n        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);\n        raycast_num++;\n        if (is_ground == 0)\n            goto BARREL_RANDPOS;\n        near_fromX = pos.X - 8;\n        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);\n        raycast_num++;\n        if (is_ground == 0)\n            goto BARREL_RANDPOS;\n\n        // output num and time\n        raytime_end = OSGetTick();\n        raytime_time = OSTicksToMilliseconds(raytime_end - raytime_start);\n        OSReport(\"lcl: %d ray in %dms\\n\", raycast_num, raytime_time);\n\n        break;\n    }\n    }\n    }\n\n    // spawn item\n    SpawnItem spawnItem;\n    spawnItem.parent_gobj = 0;\n    spawnItem.parent_gobj2 = 0;\n    spawnItem.it_kind = ITEM_BARREL;\n    spawnItem.hold_kind = 0;\n    spawnItem.unk2 = 0;\n    spawnItem.pos = pos;\n    spawnItem.pos2 = pos;\n    spawnItem.vel.X = 0;\n    spawnItem.vel.Y = 0;\n    spawnItem.vel.Z = 0;\n    spawnItem.facing_direction = 1;\n    spawnItem.damage = 0;\n    spawnItem.unk5 = 0;\n    spawnItem.unk6 = 0;\n    spawnItem.unk7 = 0x80;\n    spawnItem.is_spin = 0;\n    GOBJ *barrel_gobj = Item_CreateItem2(&spawnItem);\n    Item_CollAir(barrel_gobj, Barrel_Null);\n\n    // replace collision callback\n    ItemData *barrel_data = barrel_gobj->userdata;\n    barrel_data->it_cb = item_callbacks;\n    barrel_data->camerabox->kind = 0;\n\n    // update last barrel pos\n    event_data->barrel_lastpos = pos;\n\n    return barrel_gobj;\n}\nvoid Barrel_Null()\n{\n    return;\n}\nvoid Barrel_Break(GOBJ *barrel_gobj)\n{\n\n    ItemData *barrel_data = barrel_gobj->userdata;\n    Effect_SpawnSync(1063, barrel_gobj, &barrel_data->pos);\n    SFX_Play(251);\n    ScreenRumble_Execute(2, &barrel_data->pos);\n    JOBJ *barrel_jobj = barrel_gobj->hsd_object;\n    JOBJ_SetFlagsAll(barrel_jobj, JOBJ_HIDDEN);\n    barrel_data->xd0c = 2;\n    barrel_data->self_vel.X = 0;\n    barrel_data->self_vel.Y = 0;\n    barrel_data->itemVar1 = 1;\n    barrel_data->itemVar2 = 40;\n    barrel_data->xdcf3 = 1;\n    ItemStateChange(barrel_gobj, 7, 2);\n\n    return;\n}\nint Barrel_OnHurt(GOBJ *barrel_gobj)\n{\n\n    // get event data\n    LCancelData *event_data = event_vars->event_gobj->userdata;\n\n    switch (LcOptions_Main[0].option_val)\n    {\n    case (0): // off\n    {\n\n        break;\n    }\n    case (1): // stationary\n    {\n        break;\n    }\n    case (2): // move\n    {\n        // Break this barrel\n        Barrel_Break(event_data->barrel_gobj);\n\n        // spawn new barrel at a random position\n        barrel_gobj = Barrel_Spawn(1);\n        event_data->barrel_gobj = barrel_gobj;\n        break;\n    }\n    }\n\n    return 0;\n}\nint Barrel_OnDestroy(GOBJ *barrel_gobj)\n{\n\n    // get event data\n    LCancelData *event_data = event_vars->event_gobj->userdata;\n\n    // if this barrel is still the current barrel\n    if (barrel_gobj == event_data->barrel_gobj)\n        event_data->barrel_gobj = 0;\n\n    return 0;\n}\nstatic void *item_callbacks[] = {\n    0x803f58e0,\n    0x80287458,\n    Barrel_OnDestroy, // onDestroy\n    0x80287e68,\n    0x80287ea8,\n    0x80287ec8,\n    0x80288818,\n    Barrel_OnHurt, // onhurt\n    0x802889f8,\n    0x802888b8,\n    0x00000000,\n    0x00000000,\n    0x80288958,\n    0x80288c68,\n    0x803f5988,\n};\n\n// Misc\nfloat Bezier(float time, float start, float end)\n{\n    float bez = time * time * (3.0f - 2.0f * time);\n    return bez * (end - start) + start;\n}\n\n// Initial Menu\nstatic EventMenu *Event_Menu = &LabMenu_Main;"
  },
  {
    "path": "patch/events/lcancel/source/lcancel.h",
    "content": "#include \"../../../../MexTK/mex.h\"\n#include \"../../../tmdata/source/events.h\"\n\ntypedef struct LCancelData LCancelData;\ntypedef struct LCancelAssets LCancelAssets;\n\nstruct LCancelData\n{\n    EventDesc *event_desc;\n    LCancelAssets *lcancel_assets;\n    GOBJ *barrel_gobj;\n    Vec3 barrel_lastpos;\n    u8 is_fail;        // status of the last l-cancel\n    u8 is_fastfall;    // bool used to detect fastfall frame\n    u8 fastfall_frame; // frame the player fastfell on\n    struct\n    {\n        GOBJ *gobj;\n        u16 lcl_success;\n        u16 lcl_total;\n        Text *text_time;\n        Text *text_air;\n        Text *text_scs;\n        int canvas;\n        float arrow_base_x; // starting X position of arrow\n        float arrow_prevpos;\n        float arrow_nextpos;\n        int arrow_timer;\n    } hud;\n    struct\n    {\n        u8 shield_isdisp;   // whether tip has been shown to the player\n        u8 shield_num;      // number of times condition has been met\n        u8 hitbox_active;   // whether or not the last aerial used had a hitbox active\n        u8 hitbox_isdisp;   // whether tip has been shown to the player\n        u8 hitbox_num;      // number of times condition has been met\n        u8 fastfall_active; // whether or not the last aerial used had a hitbox active\n        u8 fastfall_isdisp; // whether tip has been shown to the player\n        u8 fastfall_num;    // number of times condition has been met\n        u8 late_isdisp;     // whether tip has been shown to the player\n        u8 late_num;        // number of times condition has been met\n    } tip;\n};\n\ntypedef struct LCancelAssets\n{\n    JOBJ *hud;\n    void **hudmatanim; // pointer to array\n};\n\n#define LCLTEXT_SCALE 4.2\n#define LCLARROW_ANIMFRAMES 4\n#define LCLARROW_JOBJ 7\n#define LCLARROW_OFFSET 0.365\n\nstatic void *item_callbacks[];\nfloat Bezier(float time, float start, float end);\nvoid Tips_Toggle(GOBJ *menu_gobj, int value);\nvoid LCancel_HUDCamThink(GOBJ *gobj);\nvoid Barrel_Think(LCancelData *event_data);\nvoid Barrel_Toggle(GOBJ *menu_gobj, int value);\nGOBJ *Barrel_Spawn(int pos_kind);\nvoid Barrel_Null();\nvoid Event_Exit();"
  },
  {
    "path": "patch/events/ledgedash/build.bat",
    "content": "xcopy /s /y \"assets\\ldshData.dat\" \"output/EvLdsh.dat\"\n\"../../../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\n\"../../../MexTK/MexTK.exe\" -trim \"output/EvLdsh.dat\"\n\npause"
  },
  {
    "path": "patch/events/ledgedash/source/ledgedash.c",
    "content": "#include \"ledgedash.h\"\nstatic char nullString[] = \" \";\n\nstatic GXColor tmgbar_black = {40, 40, 40, 255};\nstatic GXColor tmgbar_grey = {80, 80, 80, 255};\nstatic GXColor tmgbar_blue = {128, 128, 255, 255};\nstatic GXColor tmgbar_green = {128, 255, 128, 255};\nstatic GXColor tmgbar_yellow = {255, 255, 128, 255};\nstatic GXColor tmgbar_red = {255, 128, 128, 255};\nstatic GXColor tmgbar_indigo = {255, 128, 255, 255};\nstatic GXColor tmgbar_white = {255, 255, 255, 255};\nstatic GXColor *tmgbar_colors[] = {\n    &tmgbar_black,\n    &tmgbar_grey,\n    &tmgbar_green,\n    &tmgbar_yellow,\n    &tmgbar_indigo,\n    &tmgbar_white,\n    &tmgbar_red,\n};\n\n// Main Menu\nstatic char **LdshOptions_Start[] = {\"Ledge\", \"Respawn Platform\"};\nstatic char **LdshOptions_Reset[] = {\"On\", \"Off\"};\nstatic char **LdshOptions_HUD[] = {\"On\", \"Off\"};\nstatic EventOption LdshOptions_Main[] = {\n    // Position\n    {\n        .option_kind = OPTKIND_STRING,                                             // the type of option this is; menu, string list, integers list, etc\n        .value_num = sizeof(LdshOptions_Start) / 4,                                // number of values for this option\n        .option_val = 0,                                                           // value of this option\n        .menu = 0,                                                                 // pointer to the menu that pressing A opens\n        .option_name = \"Starting Position\",                                        // pointer to a string\n        .desc = \"Choose where the fighter is placed \\nafter resetting positions.\", // string describing what this option does\n        .option_values = LdshOptions_Start,                                        // pointer to an array of strings\n        .onOptionChange = Ledgedash_ToggleStartPosition,\n    },\n    // Reset\n    {\n        .option_kind = OPTKIND_STRING,                                                                  // the type of option this is; menu, string list, integers list, etc\n        .value_num = sizeof(LdshOptions_Reset) / 4,                                                     // number of values for this option\n        .option_val = 0,                                                                                // value of this option\n        .menu = 0,                                                                                      // pointer to the menu that pressing A opens\n        .option_name = \"Auto-Reset\",                                                                    // pointer to a string\n        .desc = \"Toggle the automatic resetting of the \\nfighter's position after ledgedash attempts.\", // string describing what this option does\n        .option_values = LdshOptions_Reset,                                                             // pointer to an array of strings\n        .onOptionChange = Ledgedash_ToggleAutoReset,\n    },\n    // HUD\n    {\n        .option_kind = OPTKIND_STRING,            // the type of option this is; menu, string list, integers list, etc\n        .value_num = sizeof(LdshOptions_HUD) / 4, // number of values for this option\n        .option_val = 0,                          // value of this option\n        .menu = 0,                                // pointer to the menu that pressing A opens\n        .option_name = \"HUD\",                     // pointer to a string\n        .desc = \"Toggle visibility of the HUD.\",  // string describing what this option does\n        .option_values = LdshOptions_HUD,         // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // Tips\n    {\n        .option_kind = OPTKIND_STRING,                  // the type of option this is; menu, string list, integers list, etc\n        .value_num = sizeof(LdshOptions_HUD) / 4,       // number of values for this option\n        .option_val = 0,                                // value of this option\n        .menu = 0,                                      // pointer to the menu that pressing A opens\n        .option_name = \"Tips\",                          // pointer to a string\n        .desc = \"Toggle the onscreen display of tips.\", // string describing what this option does\n        .option_values = LdshOptions_HUD,               // pointer to an array of strings\n        .onOptionChange = Tips_Toggle,\n    },\n    // Help\n    {\n        .option_kind = OPTKIND_FUNC,                                                                                                                                                                                                                                                  // the type of option this is; menu, string list, integers list, etc\n        .value_num = 0,                                                                                                                                                                                                                                                               // number of values for this option\n        .option_val = 0,                                                                                                                                                                                                                                                              // value of this option\n        .menu = 0,                                                                                                                                                                                                                                                                    // pointer to the menu that pressing A opens\n        .option_name = \"About\",                                                                                                                                                                                                                                                       // pointer to a string\n        .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\n        .option_values = 0,                                                                                                                                                                                                                                                           // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // Exit\n    {\n        .option_kind = OPTKIND_FUNC,                     // the type of option this is; menu, string list, integers list, etc\n        .value_num = 0,                                  // number of values for this option\n        .option_val = 0,                                 // value of this option\n        .menu = 0,                                       // pointer to the menu that pressing A opens\n        .option_name = \"Exit\",                           // pointer to a string\n        .desc = \"Return to the Event Selection Screen.\", // string describing what this option does\n        .option_values = 0,                              // pointer to an array of strings\n        .onOptionChange = 0,\n        .onOptionSelect = Event_Exit,\n    },\n};\nstatic EventMenu LdshMenu_Main = {\n    .name = \"Ledgedash Training\",                                 // the name of this menu\n    .option_num = sizeof(LdshOptions_Main) / sizeof(EventOption), // number of options this menu contains\n    .scroll = 0,                                                  // runtime variable used for how far down in the menu to start\n    .state = 0,                                                   // bool used to know if this menu is focused, used at runtime\n    .cursor = 0,                                                  // index of the option currently selected, used at runtime\n    .options = &LdshOptions_Main,                                 // pointer to all of this menu's options\n    .prev = 0,                                                    // pointer to previous menu, used at runtime\n};\n\n// Init Function\nvoid Event_Init(GOBJ *gobj)\n{\n    LedgedashData *event_data = gobj->userdata;\n\n    // theres got to be a better way to do this...\n    event_vars = *event_vars_ptr;\n\n    // get assets\n    event_data->assets = File_GetSymbol(event_vars->event_archive, \"ldshData\");\n\n    // standardize camera\n    Stage *stage = stc_stage;\n    float *unk_cam = 0x803bcca0;\n    stc_stage->fov_r = 0; // no camera rotation\n    stc_stage->x28 = 1;   // pan value?\n    stc_stage->x2c = 1;   // pan value?\n    stc_stage->x30 = 1;   // pan value?\n    stc_stage->x34 = 130; // zoom out\n    unk_cam[0x40 / 4] = 30;\n\n    // Init hitlog\n    event_data->hitlog_gobj = Ledgedash_HitLogInit();\n\n    // Init HUD\n    Ledgedash_HUDInit(event_data);\n\n    // Init Fighter\n    Ledgedash_FtInit(event_data);\n\n    return;\n}\n// Think Function\nvoid Event_Think(GOBJ *event)\n{\n    LedgedashData *event_data = event->userdata;\n\n    // get fighter data\n    GOBJ *hmn = Fighter_GetGObj(0);\n    FighterData *hmn_data = hmn->userdata;\n    HSD_Pad *pad = PadGet(hmn_data->player_controller_number, PADGET_ENGINE);\n\n    // no ledgefall\n    FtCliffCatch *ft_state = &hmn_data->state_var;\n    if (hmn_data->state == ASID_CLIFFWAIT)\n        ft_state->fall_timer = 2;\n\n    Ledgedash_HUDThink(event_data, hmn_data);\n    Ledgedash_HitLogThink(event_data, hmn);\n    Ledgedash_ResetThink(event_data, hmn);\n    Ledgedash_ChangeLedgeThink(event_data, hmn);\n\n    return;\n}\nvoid Event_Exit()\n{\n    Match *match = MATCH;\n\n    // end game\n    match->state = 3;\n\n    // cleanup\n    Match_EndVS();\n\n    // unfreeze\n    HSD_Update *update = HSD_UPDATE;\n    update->pause_develop = 0;\n    return;\n}\n\n// Ledgedash functions\nvoid Ledgedash_HUDInit(LedgedashData *event_data)\n{\n\n    // create hud cobj\n    GOBJ *hudcam_gobj = GObj_Create(19, 20, 0);\n    ArchiveInfo **ifall_archive = 0x804d6d5c;\n    COBJDesc ***dmgScnMdls = File_GetSymbol(*ifall_archive, 0x803f94d0);\n    COBJDesc *cam_desc = dmgScnMdls[1][0];\n    COBJ *hud_cobj = COBJ_LoadDesc(cam_desc);\n    // init camera\n    GObj_AddObject(hudcam_gobj, R13_U8(-0x3E55), hud_cobj);\n    GOBJ_InitCamera(hudcam_gobj, Ledgedash_HUDCamThink, 7);\n    hudcam_gobj->cobj_links = 1 << 18;\n\n    GOBJ *hud_gobj = GObj_Create(0, 0, 0);\n    event_data->hud.gobj = hud_gobj;\n    // Load jobj\n    JOBJ *hud_jobj = JOBJ_LoadJoint(event_data->assets->hud);\n    GObj_AddObject(hud_gobj, 3, hud_jobj);\n    GObj_AddGXLink(hud_gobj, GXLink_Common, 18, 80);\n\n    // account for widescreen\n    /*\n    float aspect = (hud_cobj->projection_param.perspective.aspect / 1.216667) - 1;\n    JOBJ *this_jobj;\n    JOBJ_GetChild(hud_jobj, &this_jobj, 1, -1);\n    this_jobj->trans.X += (this_jobj->trans.X * aspect);\n    JOBJ_SetMtxDirtySub(hud_jobj);\n    */\n\n    // create text canvas\n    int canvas = Text_CreateCanvas(2, hud_gobj, 14, 15, 0, 18, 81, 19);\n    event_data->hud.canvas = canvas;\n\n    // init text\n    Text **text_arr = &event_data->hud.text_angle;\n    for (int i = 0; i < 2; i++)\n    {\n\n        // Create text object\n        Text *hud_text = Text_CreateText(2, canvas);\n        text_arr[i] = hud_text;\n        hud_text->kerning = 1;\n        hud_text->align = 1;\n        hud_text->use_aspect = 1;\n\n        // Get position\n        Vec3 text_pos;\n        JOBJ *text_jobj;\n        JOBJ_GetChild(hud_jobj, &text_jobj, 2 + i, -1);\n        JOBJ_GetWorldPosition(text_jobj, 0, &text_pos);\n\n        // adjust scale\n        Vec3 *scale = &hud_jobj->scale;\n        // text scale\n        hud_text->scale.X = (scale->X * 0.01) * LCLTEXT_SCALE;\n        hud_text->scale.Y = (scale->Y * 0.01) * LCLTEXT_SCALE;\n        hud_text->aspect.X = 165;\n\n        // text position\n        hud_text->trans.X = text_pos.X + (scale->X / 4.0);\n        hud_text->trans.Y = (text_pos.Y * -1) + (scale->Y / 4.0);\n\n        // dummy text\n        Text_AddSubtext(hud_text, 0, 0, \"-\");\n    }\n\n    // reset all bar colors\n    JOBJ *timingbar_jobj;\n    JOBJ_GetChild(hud_jobj, &timingbar_jobj, LCLJOBJ_BAR, -1); // get timing bar jobj\n    DOBJ *d = timingbar_jobj->dobj;\n    int count = 0;\n    while (d != 0)\n    {\n        // if a box dobj\n        if ((count >= 0) && (count < 30))\n        {\n\n            // if mobj exists (it will)\n            MOBJ *m = d->mobj;\n            if (m != 0)\n            {\n\n                HSD_Material *mat = m->mat;\n\n                // set alpha\n                mat->alpha = 0.7;\n\n                // set color\n                mat->diffuse = tmgbar_black;\n            }\n        }\n\n        // inc\n        count++;\n        d = d->next;\n    }\n\n    return 0;\n}\nvoid Ledgedash_HUDThink(LedgedashData *event_data, FighterData *hmn_data)\n{\n\n    // run tip logic\n    Tips_Think(event_data, hmn_data);\n\n    JOBJ *hud_jobj = event_data->hud.gobj->hsd_object;\n\n    // only run logic if ledge exists\n    if (event_data->ledge_line != -1)\n    {\n        // increment timer\n        event_data->hud.timer++;\n\n        // check to initialize timer\n        if ((hmn_data->state == ASID_CLIFFWAIT) && (hmn_data->TM.state_frame == 1))\n        {\n            Ledgedash_InitVariables(event_data);\n\n            event_data->tip.refresh_num++;\n        }\n\n        int curr_frame = event_data->hud.timer;\n\n        // update action log\n        if (curr_frame < (sizeof(event_data->hud.action_log) / sizeof(u8)))\n        {\n            // look for cliffwait\n            if (hmn_data->state == ASID_CLIFFWAIT)\n            {\n                event_data->hud.action_log[curr_frame] = LDACT_CLIFFWAIT;\n            }\n            // look for release\n            else if (hmn_data->state == ASID_FALL)\n            {\n                event_data->hud.is_release = 1;\n                event_data->hud.action_log[curr_frame] = LDACT_FALL;\n            }\n            // look for jump\n            else if ((hmn_data->state == ASID_JUMPAERIALF) || (hmn_data->state == ASID_JUMPAERIALB) ||\n                     (((hmn_data->kind == 4) || (hmn_data->kind == 15)) && ((hmn_data->state >= 341) && (hmn_data->state <= 345)))) // check for kirby and jiggs jump\n            {\n                event_data->hud.is_jump = 1;\n                event_data->hud.action_log[curr_frame] = LDACT_JUMP;\n            }\n            // look for airdodge\n            else if (hmn_data->state == ASID_ESCAPEAIR)\n            {\n                //event_data->hud.is_airdodge = 1;\n                event_data->hud.action_log[curr_frame] = LDACT_AIRDODGE;\n            }\n            // look for aerial\n            else if (hmn_data->attack_kind != 1)\n            {\n                event_data->hud.is_aerial = 1;\n                event_data->hud.action_log[curr_frame] = LDACT_ATTACK;\n            }\n            // look for land\n            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\n            {\n                event_data->hud.is_land = 1;\n                event_data->hud.action_log[curr_frame] = LDACT_LANDING;\n            }\n        }\n\n        // grab airdodge angle\n        if (event_data->hud.is_airdodge == 0)\n        {\n\n            if ((hmn_data->state == ASID_ESCAPEAIR) || (hmn_data->TM.state_prev[0] == ASID_ESCAPEAIR))\n            {\n                // determine airdodge angle\n                float angle = atan2(hmn_data->input.lstick_y, hmn_data->input.lstick_x) - -(M_PI / 2);\n\n                // save airdodge angle\n                event_data->hud.airdodge_angle = angle;\n                event_data->hud.is_airdodge = 1;\n            }\n        }\n\n        // look for actionable\n        if (((event_data->hud.is_actionable == 0) && (event_data->hud.is_release == 1)) &&\n            (((((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\n             ((hmn_data->state == ASID_LANDING) && (hmn_data->TM.state_frame >= hmn_data->attr.normal_landing_lag)) ||\n             ((hmn_data->TM.state_prev[0] == ASID_LANDING) && (hmn_data->TM.state_prev_frames[0] >= hmn_data->attr.normal_landing_lag))))\n        {\n            event_data->hud.is_actionable = 1;\n            event_data->hud.actionable_frame = event_data->hud.timer;\n\n            // destroy any tips\n            event_vars->Tip_Destroy();\n\n            // update bar colors\n            JOBJ *timingbar_jobj;\n            JOBJ_GetChild(hud_jobj, &timingbar_jobj, LCLJOBJ_BAR, -1); // get timing bar jobj\n            DOBJ *d = timingbar_jobj->dobj;\n            int count = 0;\n            while (d != 0)\n            {\n                // if a box dobj\n                if ((count >= 0) && (count < 30))\n                {\n\n                    // if mobj exists (it will)\n                    MOBJ *m = d->mobj;\n                    if (m != 0)\n                    {\n\n                        HSD_Material *mat = m->mat;\n                        int this_frame = 29 - count;\n                        GXColor *bar_color;\n\n                        // check if GALINT frame\n                        if ((this_frame >= curr_frame) && ((this_frame <= (curr_frame + hmn_data->hurtstatus.ledge_intang_left))))\n                            bar_color = &tmgbar_blue;\n                        else\n                            bar_color = tmgbar_colors[event_data->hud.action_log[this_frame]];\n\n                        mat->diffuse = *bar_color;\n                    }\n                }\n\n                // inc\n                count++;\n                d = d->next;\n            }\n\n            // output remaining airdodge angle\n            if (event_data->hud.is_airdodge == 1)\n                Text_SetText(event_data->hud.text_angle, 0, \"%.2f\", fabs(event_data->hud.airdodge_angle / M_1DEGREE));\n            else\n                Text_SetText(event_data->hud.text_angle, 0, \"-\");\n\n            // output remaining GALINT\n            void *matanim;\n            Text *text_galint = event_data->hud.text_galint;\n            if (hmn_data->hurtstatus.ledge_intang_left > 0)\n            {\n                SFX_Play(303);\n                matanim = event_data->assets->hudmatanim[0];\n                Text_SetText(text_galint, 0, \"%df\", hmn_data->hurtstatus.ledge_intang_left);\n            }\n            else if (hmn_data->TM.vuln_frames < 25)\n            {\n                matanim = event_data->assets->hudmatanim[1];\n                Text_SetText(text_galint, 0, \"-%df\", hmn_data->TM.vuln_frames);\n            }\n            else\n            {\n                matanim = event_data->assets->hudmatanim[1];\n                Text_SetText(text_galint, 0, \"-\");\n            }\n\n            // init hitbox num\n            LdshHitlogData *hitlog_data = event_data->hitlog_gobj->userdata;\n            hitlog_data->num = 0;\n\n            // apply HUD animation\n            JOBJ_RemoveAnimAll(hud_jobj);\n            JOBJ_AddAnimAll(hud_jobj, 0, matanim, 0);\n            JOBJ_ReqAnimAll(hud_jobj, 0);\n        }\n    }\n\n    // update HUD anim\n    JOBJ_AnimAll(hud_jobj);\n\n    return;\n}\nvoid Ledgedash_HUDCamThink(GOBJ *gobj)\n{\n\n    // if HUD enabled and not paused\n    if ((LdshOptions_Main[2].option_val == 0) && (Pause_CheckStatus(1) != 2))\n    {\n        CObjThink_Common(gobj);\n    }\n\n    return;\n}\nvoid Ledgedash_ResetThink(LedgedashData *event_data, GOBJ *hmn)\n{\n\n    FighterData *hmn_data = hmn->userdata;\n    JOBJ *hud_jobj = event_data->hud.gobj->hsd_object;\n\n    // check if enabled and ledge exists\n    if ((LdshOptions_Main[1].option_val == 0) && (event_data->ledge_line != -1))\n    {\n\n        // check if reset timer is set\n        if (event_data->reset_timer > 0)\n        {\n            // decrement reset timer\n            event_data->reset_timer--;\n\n            // if reset timer is up, go back to ledge\n            if (event_data->reset_timer == 0)\n            {\n                Fighter_PlaceOnLedge(event_data, hmn, event_data->ledge_line, (float)event_data->ledge_dir);\n            }\n        }\n        // check to set reset timner\n        else if (event_data->hud.is_actionable)\n        {\n            event_data->reset_timer = 30;\n        }\n        else\n        {\n            int state = hmn_data->state;\n\n            // reset actions\n            if ((hmn_data->flags.dead == 1) ||                                              // if dead\n                ((hmn_data->state == ASID_ESCAPEAIR) && (hmn_data->TM.state_frame >= 9)) || // missed airdodge\n                ((((state >= ASID_CLIFFCLIMBSLOW) && (state <= ASID_CLIFFJUMPQUICK2)) ||    // reset if any other ledge action\n                  ((state >= ASID_ATTACKAIRN) && (state <= ASID_ATTACKAIRLW)) ||\n                  ((hmn_data->phys.air_state == 0) && ((state != ASID_LANDING) && (state != ASID_LANDINGFALLSPECIAL) && (state != ASID_REBIRTHWAIT)))) && // reset if grounded non landing\n                 (hmn_data->TM.state_frame >= 7)))\n            {\n                // reset and play sfx\n                Fighter_PlaceOnLedge(event_data, hmn, event_data->ledge_line, (float)event_data->ledge_dir);\n                SFX_PlayCommon(3);\n            }\n        }\n    }\n\n    return;\n}\nvoid Ledgedash_InitVariables(LedgedashData *event_data)\n{\n    event_data->hud.timer = 0;\n    event_data->tip.is_input_release = 0;\n    event_data->tip.is_input_jump = 0;\n    event_data->tip.refresh_displayed = 0;\n    event_data->hud.is_release = 0;\n    event_data->hud.is_jump = 0;\n    event_data->hud.is_airdodge = 0;\n    event_data->hud.is_aerial = 0;\n    event_data->hud.is_land = 0;\n    event_data->hud.is_actionable = 0;\n\n    // init action log\n    for (int i = 0; i < sizeof(event_data->hud.action_log) / sizeof(u8); i++)\n    {\n        event_data->hud.action_log[i] = 0;\n    }\n}\n\n// Menu Toggle functions\nvoid Ledgedash_ToggleStartPosition(GOBJ *menu_gobj, int value)\n{\n\n    // get fighter data\n    GOBJ *hmn = Fighter_GetGObj(0);\n    LedgedashData *event_data = event_vars->event_gobj->userdata;\n\n    Fighter_PlaceOnLedge(event_data, hmn, event_data->ledge_line, (float)event_data->ledge_dir);\n\n    return;\n}\nvoid Ledgedash_ToggleAutoReset(GOBJ *menu_gobj, int value)\n{\n\n    LedgedashData *event_data = event_vars->event_gobj->userdata;\n\n    // enable camera\n    if (value == 0)\n        event_data->cam->kind = 0;\n    // disable camera\n    else\n        event_data->cam->kind = 1;\n\n    return;\n}\n\n// Hitlog functions\nGOBJ *Ledgedash_HitLogInit()\n{\n\n    GOBJ *hit_gobj = GObj_Create(0, 0, 0);\n    LdshHitlogData *hit_data = calloc(sizeof(LdshHitlogData));\n    GObj_AddUserData(hit_gobj, 4, HSD_Free, hit_data);\n    GObj_AddGXLink(hit_gobj, Ledgedash_HitLogGX, 5, 0);\n\n    // init array\n    hit_data->num = 0;\n\n    return hit_gobj;\n}\nvoid Ledgedash_HitLogThink(LedgedashData *event_data, GOBJ *hmn)\n{\n    FighterData *hmn_data = hmn->userdata;\n    LdshHitlogData *hitlog_data = event_data->hitlog_gobj->userdata;\n\n    // log hitboxes\n    if ((event_data->hud.is_actionable == 1) && (hmn_data->hurtstatus.ledge_intang_left > 0))\n    {\n\n        // iterate through fighter hitboxes\n        for (int i = 0; i < sizeof(hmn_data->hitbox) / sizeof(ftHit); i++)\n        {\n\n            ftHit *this_hit = &hmn_data->hitbox[i];\n\n            if ((this_hit->active != 0) &&           // if hitbox is active\n                (hitlog_data->num < LDSH_HITBOXNUM)) // if not over max\n            {\n\n                // log info\n                LdshHitboxData *this_ldsh_hit = &hitlog_data->hitlog[hitlog_data->num];\n                this_ldsh_hit->size = this_hit->size;\n                this_ldsh_hit->pos_curr = this_hit->pos;\n                this_ldsh_hit->pos_prev = this_hit->pos_prev;\n                this_ldsh_hit->kind = this_hit->attribute;\n\n                // increment hitboxes\n                hitlog_data->num++;\n            }\n        }\n\n        // iterate through items belonging to fighter\n        GOBJList *gobj_list = *stc_gobj_list;\n        GOBJ *this_item = gobj_list->item;\n        while (this_item != 0)\n        {\n            ItemData *this_itemdata = this_item->userdata;\n\n            // ensure belongs to the fighter\n            if (this_itemdata->fighter == hmn)\n            {\n                // iterate through item hitboxes\n                for (int i = 0; i < sizeof(hmn_data->hitbox) / sizeof(ftHit); i++)\n                {\n\n                    itHit *this_hit = &this_itemdata->hitbox[i];\n\n                    if ((this_hit->active != 0) &&           // if hitbox is active\n                        (hitlog_data->num < LDSH_HITBOXNUM)) // if not over max\n                    {\n\n                        // log info\n                        LdshHitboxData *this_ldsh_hit = &hitlog_data->hitlog[hitlog_data->num];\n                        this_ldsh_hit->size = this_hit->size;\n                        this_ldsh_hit->pos_curr = this_hit->pos;\n                        this_ldsh_hit->pos_prev = this_hit->pos_prev;\n                        this_ldsh_hit->kind = this_hit->attribute;\n\n                        // increment hitboxes\n                        hitlog_data->num++;\n                    }\n                }\n            }\n\n            this_item = this_item->next;\n        }\n    }\n\n    return;\n}\nvoid Ledgedash_HitLogGX(GOBJ *gobj, int pass)\n{\n\n    static GXColor hitlog_ambient = {128, 0, 0, 50};\n    static GXColor hit_diffuse = {255, 99, 99, 50};\n    static GXColor grab_diffuse = {255, 0, 255, 50};\n    static GXColor detect_diffuse = {255, 255, 255, 50};\n\n    LdshHitlogData *hitlog_data = gobj->userdata;\n\n    for (int i = 0; i < hitlog_data->num; i++)\n    {\n        LdshHitboxData *this_ldsh_hit = &hitlog_data->hitlog[i];\n\n        // determine color\n        GXColor *diffuse, *ambient;\n        if (this_ldsh_hit->kind == 0)\n            diffuse = &hit_diffuse;\n        else if (this_ldsh_hit->kind == 8)\n            diffuse = &grab_diffuse;\n        else if (this_ldsh_hit->kind == 11)\n            diffuse = &detect_diffuse;\n        else\n            diffuse = &hit_diffuse;\n\n        Develop_DrawSphere(this_ldsh_hit->size, &this_ldsh_hit->pos_curr, &this_ldsh_hit->pos_prev, diffuse, &hitlog_ambient);\n    }\n\n    return;\n}\n\n// Fighter fuctions\nvoid Ledgedash_FtInit(LedgedashData *event_data)\n{\n    GOBJ *hmn = Fighter_GetGObj(0);\n    FighterData *hmn_data = hmn->userdata;\n\n    // create camera box\n    CameraBox *cam = CameraBox_Alloc();\n    cam->boundleft_proj = -10;\n    cam->boundright_proj = 10;\n    cam->boundtop_proj = 10;\n    cam->boundbottom_proj = -10;\n    cam->boundleft_curr = cam->boundleft_proj;\n    cam->boundright_curr = cam->boundright_proj;\n    cam->boundtop_curr = cam->boundtop_proj;\n    cam->boundbottom_curr = cam->boundbottom_proj;\n    event_data->cam = cam;\n\n    // search for nearest ledge\n    float ledge_dir;\n    int line_index = Ledge_Find(0, 0, &ledge_dir);\n    if (line_index != -1)\n        Fighter_PlaceOnLedge(event_data, hmn, line_index, ledge_dir);\n    else\n    {\n        event_data->cam->flags = 0;\n        event_data->ledge_line = -1;\n        event_vars->Tip_Display(500 * 60, \"Error:\\nIt appears there are no \\nledges on this stage...\");\n    }\n\n    return;\n}\nvoid Ledgedash_ChangeLedgeThink(LedgedashData *event_data, GOBJ *hmn)\n{\n    FighterData *hmn_data = hmn->userdata;\n\n    if (hmn_data->input.down & (HSD_BUTTON_DPAD_LEFT | HSD_BUTTON_DPAD_RIGHT))\n    {\n\n        // get current ledge position\n        CollVert *collvert = *stc_collvert;\n        CollLine *collline = *stc_collline;\n        CollVert *this_vert;\n        CollLine *this_line = &collline[event_data->ledge_line];\n        float ledge_pos;\n        if (event_data->ledge_dir == -1)\n            ledge_pos = collvert[this_line->info->vert_next].pos_curr.X;\n        else if (event_data->ledge_dir == 1)\n            ledge_pos = collvert[this_line->info->vert_prev].pos_curr.X;\n\n        // find ledge\n        float ledge_dir;\n        int line_index = -1;\n        if (hmn_data->input.down & HSD_BUTTON_DPAD_LEFT)\n            line_index = Ledge_Find(-1, ledge_pos, &ledge_dir);\n        else if (hmn_data->input.down & HSD_BUTTON_DPAD_RIGHT)\n            line_index = Ledge_Find(1, ledge_pos, &ledge_dir);\n\n        if (line_index != -1)\n            Fighter_PlaceOnLedge(event_data, hmn, line_index, ledge_dir);\n        else\n            Fighter_PlaceOnLedge(event_data, hmn, event_data->ledge_line, (float)event_data->ledge_dir);\n    }\n\n    return;\n}\nint Ledge_Find(int search_dir, float xpos_start, float *ledge_dir)\n{\n\n    // get line and vert pointers\n    CollLine *collline = *stc_collline;\n    CollVert *collvert = *stc_collvert;\n    CollDataStage *coll_data = *stc_colldata;\n\n    // get initial closest\n    float xpos_closest;\n    if (search_dir == -1) // search left\n        xpos_closest = -5000;\n    else if (search_dir == 1) // search right\n        xpos_closest = 5000;\n    else // search both\n        xpos_closest = 5000;\n\n    // look for the closest ledge\n    CollLine *line_closest = 0;\n    int index_closest = -1;\n    int group_index = 0;                  // first ground link\n    int group_num = coll_data->group_num; // ground link num\n    CollGroup *this_group = *stc_firstcollgroup;\n    while (this_group != 0) // loop through ground links\n    {\n\n        // 2 passes, one for ground and one for dynamic lines\n        int line_index, line_num;\n        for (int i = 0; i < 2; i++)\n        {\n            // first pass, use floors\n            if (i == 0)\n            {\n                line_index = this_group->desc->floor_start;          // first ground link\n                line_num = line_index + this_group->desc->floor_num; // ground link num\n            }\n            // second pass, use dynamics\n            else if (i == 1)\n            {\n                line_index = this_group->desc->dyn_start;          // first ground link\n                line_num = line_index + this_group->desc->dyn_num; // ground link num\n            }\n\n            // loop through lines\n            while (line_index < line_num)\n            {\n                // get all data for this line\n                CollLine *this_line = &collline[line_index]; // ??? i actually dont know why i cant access this directly\n                CollLineInfo *this_lineinfo = this_line->info;\n\n                // check if this link is a ledge\n                if (this_lineinfo->is_ledge)\n                {\n\n                    // check both sides of this ledge\n                    Vec3 ledge_pos;\n                    for (int j = 0; j < 2; j++)\n                    {\n                        // first pass, check left\n                        if (j == 0)\n                        {\n                            GrColl_GetLedgeLeft2(line_index, &ledge_pos);\n                        }\n                        else if (j == 1)\n                        {\n                            GrColl_GetLedgeRight2(line_index, &ledge_pos);\n                        }\n\n                        // is within the camera range\n                        if ((ledge_pos.X > Stage_GetCameraLeft()) && (ledge_pos.X < Stage_GetCameraRight()) && (ledge_pos.Y > Stage_GetCameraBottom()) && (ledge_pos.Y < Stage_GetCameraTop()))\n                        {\n\n                            // check for any obstructions\n                            float dir_mult;\n                            if (j == 0) // left ledge\n                                dir_mult = -1;\n                            else if (j == 1) // right ledge\n                                dir_mult = 1;\n                            int ray_index;\n                            int ray_kind;\n                            Vec2 ray_angle;\n                            Vec3 ray_pos;\n                            float from_x = ledge_pos.X + (2 * dir_mult);\n                            float to_x = from_x;\n                            float from_y = ledge_pos.Y + 5;\n                            float to_y = from_y - 10;\n                            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);\n                            if (is_ground == 0)\n                            {\n                                int is_closer = 0;\n\n                                if (search_dir == -1) // check if to the left\n                                {\n                                    if ((ledge_pos.X > xpos_closest) && (ledge_pos.X < xpos_start))\n                                        is_closer = 1;\n                                }\n                                else if (search_dir == 1) // check if to the right\n                                {\n                                    if ((ledge_pos.X < xpos_closest) && (ledge_pos.X > xpos_start))\n                                        is_closer = 1;\n                                }\n                                else // check if any direction\n                                {\n                                    float dist_old = fabs(xpos_start - xpos_closest);\n                                    float dist_new = fabs(xpos_start - ledge_pos.X);\n                                    if (dist_new < dist_old)\n                                        is_closer = 1;\n                                }\n\n                                // determine direction\n                                if (is_closer)\n                                {\n\n                                    // now determine if this line is a ledge in this direction\n                                    if (j == 0) // left ledge\n                                    {\n                                        CollLine *prev_line = &collline[this_lineinfo->line_prev];          // ??? i actually dont know why i cant access this directly\n                                        if ((this_lineinfo->line_prev == -1) || (prev_line->is_rwall == 1)) // if prev line is a right wall / if prev line doesnt exist\n                                        {\n\n                                            // save info on this line\n                                            xpos_closest = ledge_pos.X; // save left vert's X position\n                                            line_closest = this_line;\n                                            index_closest = line_index;\n                                            *ledge_dir = 1;\n                                        }\n                                    }\n                                    else if (j == 1) // right ledge\n                                    {\n                                        CollLine *next_line = &collline[this_lineinfo->line_next];          // ??? i actually dont know why i cant access this directly\n                                        if ((this_lineinfo->line_prev == -1) || (next_line->is_lwall == 1)) // if prev line is a right wall / if prev line doesnt exist\n                                        {\n\n                                            // save info on this line\n                                            xpos_closest = ledge_pos.X; // save left vert's X position\n                                            line_closest = this_line;\n                                            index_closest = line_index;\n                                            *ledge_dir = -1;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n\n                line_index++;\n            }\n        }\n\n        // get next\n        this_group = this_group->next;\n    }\n\n    return index_closest;\n}\nvoid Fighter_PlaceOnLedge(LedgedashData *event_data, GOBJ *hmn, int line_index, float ledge_dir)\n{\n    FighterData *hmn_data = hmn->userdata;\n\n    // save ledge info\n    event_data->ledge_line = line_index;\n    event_data->ledge_dir = ledge_dir;\n\n    // get ledge position\n    Vec3 ledge_pos;\n    if (ledge_dir > 0)\n        GrColl_GetLedgeLeft2(line_index, &ledge_pos);\n    else\n        GrColl_GetLedgeRight2(line_index, &ledge_pos);\n\n    // remove velocity\n    hmn_data->phys.self_vel.X = 0;\n    hmn_data->phys.self_vel.Y = 0;\n\n    // restore tether\n    hmn_data->flags.used_tether = 0;\n\n    // check if starting on ledge\n    if (LdshMenu_Main.options[0].option_val == 0)\n    {\n\n        // init refresh num\n        event_data->tip.refresh_num = -1; // setting this to -1 because the per frame code will add 1 and make it 0\n\n        // Sleep first\n        Fighter_EnterSleep(hmn, 0);\n        Fighter_EnterRebirth(hmn);\n\n        // place player on this ledge\n        FtCliffCatch *ft_state = &hmn_data->state_var;\n        hmn_data->facing_direction = ledge_dir;\n        ft_state->ledge_index = line_index; // store line index\n        Fighter_EnterCliffWait(hmn);\n        ft_state->timer = 0; // spoof as on ledge for a frame already\n        Fighter_LoseGroundJump(hmn_data);\n        Fighter_EnableCollUpdate(hmn_data);\n        Coll_CheckLedge(&hmn_data->coll_data);\n        Fighter_MoveToCliff(hmn);\n        Fighter_UpdatePosition(hmn);\n        hmn_data->phys.self_vel.X = 0;\n        hmn_data->phys.self_vel.Y = 0;\n        ftCommonData *ftcommon = *stc_ftcommon;\n        Fighter_ApplyIntang(hmn, ftcommon->cliff_invuln_time);\n    }\n    else\n    {\n\n        // init refresh num\n        event_data->tip.refresh_num = 0; // setting this to -1 because the per frame code will add 1 and make it 0\n\n        // place player in a random position in respawn wait\n        Fighter_EnterSleep(hmn, 0);\n        Fighter_EnterRebirth(hmn);\n        hmn_data->facing_direction = ledge_dir;\n\n        // get random position\n        float xpos_min = 40;\n        float xpos_max = 65;\n        float ypos_min = -30;\n        float ypos_max = 30;\n        hmn_data->phys.pos.X = ((ledge_dir * -1) * (xpos_min + HSD_Randi(xpos_max - xpos_min) + HSD_Randf())) + (ledge_pos.X);\n        hmn_data->phys.pos.Y = ((ledge_dir * -1) * (ypos_min + HSD_Randi(ypos_max - ypos_min) + HSD_Randf())) + (ledge_pos.Y);\n\n        // enter rebirth\n        Fighter_EnterRebirthWait(hmn);\n        hmn_data->cb.Phys = RebirthWait_Phys;\n        hmn_data->cb.IASA = RebirthWait_IASA;\n\n        Fighter_UpdateRebirthPlatformPos(hmn);\n\n        Ledgedash_InitVariables(event_data);\n    }\n\n    // update camera box\n    CameraBox *cam = event_data->cam;\n    cam->cam_pos.X = ledge_pos.X + (ledge_dir * 20);\n    cam->cam_pos.Y = ledge_pos.Y + 15;\n\n    Fighter_UpdateCamera(hmn);\n\n    // remove all particles\n    for (int i = 0; i < PTCL_LINKMAX; i++)\n    {\n        Particle2 **ptcls = &stc_ptcl[i];\n        Particle2 *ptcl = *ptcls;\n        while (ptcl != 0)\n        {\n\n            Particle2 *ptcl_next = ptcl->next;\n\n            // begin destroying this particle\n\n            // subtract some value, 8039c9f0\n            if (ptcl->x88 != 0)\n            {\n                int *arr = ptcl->x88;\n                arr[0x50 / 4]--;\n            }\n            // remove from generator? 8039ca14\n            if (ptcl->gen != 0)\n                psRemoveParticleAppSRT(ptcl);\n\n            // delete parent jobj, 8039ca48\n            psDeletePntJObjwithParticle(ptcl);\n\n            // update most recent ptcl pointer\n            *ptcls = ptcl->next;\n\n            // free alloc, 8039ca54\n            HSD_ObjFree(0x804d0f60, ptcl);\n\n            // decrement ptcl total\n            u16 ptclnum = *stc_ptclnum;\n            ptclnum--;\n            *stc_ptclnum = ptclnum;\n\n            // get next\n            ptcl = ptcl_next;\n        }\n    }\n\n    /*\n    // remove all generators with linkNo 2 (blastzone)\n    ptclGen *gen = *stc_ptclgen;\n    while (gen != 0)\n    {\n        // get next\n        ptclGen *gen_next = gen->next;\n\n        // if linkNo 2, destroy it\n        if (gen->link_no == 2)\n        {\n            // set a flag for some reason\n            gen->type |= 0x80;\n\n            // kill gen\n            gen = psKillGenerator(gen, *stc_ptclgencurr);\n        }\n\n        // save last\n        *stc_ptclgencurr = gen;\n        // get next\n        gen = gen_next;\n    }\n*/\n    // remove all camera shake gobjs (p_link 18, entity_class 3)\n    GOBJList *gobj_list = *stc_gobj_list;\n    GOBJ *gobj = gobj_list->match_cam;\n    while (gobj != 0)\n    {\n\n        GOBJ *gobj_next = gobj->next;\n\n        // if entity class 3 (quake)\n        if (gobj->entity_class == 3)\n        {\n            GObj_Destroy(gobj);\n        }\n\n        gobj = gobj_next;\n    }\n\n    return;\n}\nvoid Fighter_UpdatePosition(GOBJ *fighter)\n{\n\n    FighterData *fighter_data = fighter->userdata;\n\n    // Update Position (Copy Physics XYZ into all ECB XYZ)\n    fighter_data->coll_data.topN_Curr.X = fighter_data->phys.pos.X;\n    fighter_data->coll_data.topN_Curr.Y = fighter_data->phys.pos.Y;\n    fighter_data->coll_data.topN_Prev.X = fighter_data->phys.pos.X;\n    fighter_data->coll_data.topN_Prev.Y = fighter_data->phys.pos.Y;\n    fighter_data->coll_data.topN_CurrCorrect.X = fighter_data->phys.pos.X;\n    fighter_data->coll_data.topN_CurrCorrect.Y = fighter_data->phys.pos.Y;\n    fighter_data->coll_data.topN_Proj.X = fighter_data->phys.pos.X;\n    fighter_data->coll_data.topN_Proj.Y = fighter_data->phys.pos.Y;\n\n    // Update Collision Frame ID\n    fighter_data->coll_data.coll_test = *stc_colltest;\n\n    // Adjust JObj position (code copied from 8006c324)\n    JOBJ *fighter_jobj = fighter->hsd_object;\n    fighter_jobj->trans.X = fighter_data->phys.pos.X;\n    fighter_jobj->trans.Y = fighter_data->phys.pos.Y;\n    fighter_jobj->trans.Z = fighter_data->phys.pos.Z;\n    JOBJ_SetMtxDirtySub(fighter_jobj);\n\n    // Update Static Player Block Coords\n    Fighter_SetPosition(fighter_data->ply, fighter_data->flags.ms, &fighter_data->phys.pos);\n    return;\n}\nvoid Fighter_UpdateCamera(GOBJ *fighter)\n{\n    FighterData *fighter_data = fighter->userdata;\n\n    // Update camerabox pos\n    Fighter_UpdateCameraBox(fighter);\n\n    // Update tween\n    fighter_data->cameraBox->boundleft_curr = fighter_data->cameraBox->boundleft_proj;\n    fighter_data->cameraBox->boundright_curr = fighter_data->cameraBox->boundright_proj;\n\n    // update camera position\n    Match_CorrectCamera();\n\n    // reset onscreen bool\n    //Fighter_UpdateOnscreenBool(fighter);\n    fighter_data->flags.is_offscreen = 0;\n}\nvoid RebirthWait_Phys(GOBJ *fighter)\n{\n\n    FighterData *fighter_data = fighter->userdata;\n\n    // infinite time\n    fighter_data->state_var.stateVar1 = 2;\n\n    return;\n}\nint RebirthWait_IASA(GOBJ *fighter)\n{\n\n    FighterData *fighter_data = fighter->userdata;\n\n    if (Fighter_IASACheck_JumpAerial(fighter))\n    {\n    }\n    else\n    {\n        ftCommonData *ftcommon = *stc_ftcommon;\n\n        // check for lstick movement\n        float stick_x = fabs(fighter_data->input.lstick_x);\n        float stick_y = fighter_data->input.lstick_y;\n        if ((stick_x > 0.2875) && (fighter_data->input.timer_lstick_tilt_x < 2) ||\n            (stick_y < (ftcommon->lstick_rebirthfall * -1)) && (fighter_data->input.timer_lstick_tilt_y < 4))\n        {\n            Fighter_EnterFall(fighter);\n            return 1;\n        }\n    }\n\n    return 0;\n}\nint Fighter_CheckFall(FighterData *hmn_data)\n{\n\n    int is_fall = 0;\n\n    // look for Fall input\n    float stick_x = fabs(hmn_data->input.lstick_x);\n    float stick_y = hmn_data->input.lstick_y;\n    if ((stick_x >= 0.2875) && (hmn_data->input.timer_lstick_tilt_x < 2) ||\n        (stick_y <= -0.2875) && (hmn_data->input.timer_lstick_tilt_y < 2))\n    {\n        is_fall = 1;\n    }\n\n    return is_fall;\n}\n\n// Tips Functions\nvoid Tips_Toggle(GOBJ *menu_gobj, int value)\n{\n    // destroy existing tips when disabling\n    if (value == 1)\n        event_vars->Tip_Destroy();\n\n    return;\n}\nvoid Tips_Think(LedgedashData *event_data, FighterData *hmn_data)\n{\n\n    if (LdshOptions_Main[3].option_val == 0)\n    {\n\n        // check for early fall input in cliffcatch\n        if ((event_data->tip.is_input_release == 0) && (hmn_data->state == ASID_CLIFFCATCH) && (Fighter_CheckFall(hmn_data) == 1))\n        {\n            event_data->tip.is_input_release = 1;\n            event_vars->Tip_Destroy();\n\n            // determine how many frames early\n            float *anim_ptr = Animation_GetAddress(hmn_data, hmn_data->anim_id);\n            float frame_total = anim_ptr[0x8 / 4];\n            float frames_early = frame_total - hmn_data->stateFrame;\n            event_vars->Tip_Display(3 * 60, \"Misinput:\\nFell %d frames early.\", (int)frames_early + 1);\n        }\n\n        // check for early fall input on cliffwait frame 0\n        if ((event_data->tip.is_input_release == 0) && (hmn_data->state == ASID_CLIFFWAIT) && (hmn_data->TM.state_frame == 1) && (Fighter_CheckFall(hmn_data) == 1))\n        {\n            event_data->tip.is_input_release = 1;\n            event_vars->Tip_Destroy();\n            event_vars->Tip_Display(LSDH_TIPDURATION, \"Misinput:\\nFell 1 frame early.\");\n        }\n\n        // check for late fall input\n        if ((event_data->tip.is_input_release == 0) && (hmn_data->state == ASID_CLIFFJUMPQUICK1) && (Fighter_CheckFall(hmn_data) == 1))\n        {\n            event_data->tip.is_input_release = 1;\n            event_vars->Tip_Destroy();\n\n            // jumped and fell on same frame\n            if (hmn_data->TM.state_frame == 0)\n                event_vars->Tip_Display(LSDH_TIPDURATION, \"Misinput:\\nInputted jump and fall \\non the same frame.\");\n\n            // fell late\n            else\n                event_vars->Tip_Display(LSDH_TIPDURATION, \"Misinput:\\nJumped %d frame(s) early.\", hmn_data->TM.state_frame);\n        }\n\n        // check for ledgedash without refreshing\n        if ((event_data->tip.refresh_displayed == 0) && (event_data->hud.is_actionable == 1) && (event_data->tip.refresh_num == 0))\n        {\n\n            event_data->tip.refresh_displayed = 1;\n\n            // increment condition count\n            event_data->tip.refresh_cond_num++;\n\n            // after 3 conditions, display tip\n            if (event_data->tip.refresh_cond_num >= 3)\n            {\n                // if tip is displayed, reset cond num\n                if (event_vars->Tip_Display(5 * 60, \"Warning:\\nIt is higly recommended to\\nre-grab ledge after \\nbeing reset to simulate \\na realistic scenario!\"))\n                    event_data->tip.refresh_cond_num = 0;\n            }\n        }\n    }\n    return;\n}\n\n// Initial Menu\nstatic EventMenu *Event_Menu = &LdshMenu_Main;"
  },
  {
    "path": "patch/events/ledgedash/source/ledgedash.h",
    "content": "#include \"../../../../MexTK/mex.h\"\n#include \"../../../tmdata/source/events.h\"\n\ntypedef struct LedgedashData LedgedashData;\ntypedef struct LedgedashAssets LedgedashAssets;\ntypedef struct LdshHitlogData LdshHitlogData;\ntypedef struct LdshHitboxData LdshHitboxData;\n\n#define LSDH_TIPDURATION 1.7 * 60\n#define LDSH_HITBOXNUM 30 * 4\n#define LCLTEXT_SCALE 4.5\n#define LCLJOBJ_BAR 4\n\nstruct LedgedashData\n{\n    EventDesc *event_desc;\n    LedgedashAssets *assets;\n    s16 ledge_line;\n    s16 ledge_dir;\n    s16 reset_timer;\n    GOBJ *hitlog_gobj;\n    CameraBox *cam;\n    struct\n    {\n        GOBJ *gobj;\n        Text *text_angle;\n        Text *text_galint;\n        int canvas;\n        int timer;\n        float airdodge_angle;\n        u8 is_release : 1;\n        u8 is_jump : 1;\n        u8 is_airdodge : 1;\n        u8 is_aerial : 1;\n        u8 is_land : 1;\n        u8 is_actionable : 1;\n        u16 release_frame;\n        u16 jump_frame;\n        u16 airdodge_frame;\n        u16 aerial_frame;\n        u16 land_frame;\n        u16 actionable_frame;\n        u8 action_log[30];\n    } hud;\n    struct\n    {\n        s16 refresh_num;     // number of times refreshed\n        u8 refresh_cond_num; // number of times tip condition has been met\n        u8 refresh_displayed : 1;\n        u8 is_input_release : 1;\n        u8 is_input_jump : 1;\n    } tip;\n};\n\nstruct LedgedashAssets\n{\n    JOBJ *hud;\n    void **hudmatanim; // pointer to array\n};\n\nstruct LdshHitboxData\n{\n    int kind;\n    float size;\n    Vec3 pos_curr;\n    Vec3 pos_prev;\n};\n\nstruct LdshHitlogData\n{\n    int num;\n    LdshHitboxData hitlog[LDSH_HITBOXNUM];\n};\n\ntypedef enum LDSH_ACTION\n{\n    LDACT_NONE,\n    LDACT_CLIFFWAIT,\n    LDACT_FALL,\n    LDACT_JUMP,\n    LDACT_AIRDODGE,\n    LDACT_ATTACK,\n    LDACT_LANDING,\n};\n\nvoid Event_Exit();\nvoid Tips_Toggle(GOBJ *menu_gobj, int value);\nvoid Ledgedash_ToggleStartPosition(GOBJ *menu_gobj, int value);\nvoid Ledgedash_ToggleAutoReset(GOBJ *menu_gobj, int value);\nvoid Ledgedash_HUDCamThink(GOBJ *gobj);\nGOBJ *Ledgedash_HitLogInit();\nvoid Ledgedash_HitLogGX(GOBJ *gobj, int pass);\nvoid RebirthWait_Phys(GOBJ *fighter);\nint RebirthWait_IASA(GOBJ *fighter);\nint Ledge_Find(int search_dir, float xpos_start, float *ledge_dir);"
  },
  {
    "path": "patch/events/wavedash/build.bat",
    "content": "SET \"OUTPUT_FOLDER=output\"\nSET \"FILENAME=EvWdsh.dat\"\nSET \"SOURCEFILE=wavedash\"\nSET \"ASSETS=wdshData\"\n\nxcopy /s /y \"assets\\%ASSETS%.dat\" \"%OUTPUT_FOLDER%/%FILENAME%\"\n\"../../../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\n\"../../../MexTK/MexTK.exe\" -trim \"%OUTPUT_FOLDER%\\%FILENAME%\"\n\npause"
  },
  {
    "path": "patch/events/wavedash/source/wavedash.c",
    "content": "#include \"wavedash.h\"\nstatic char nullString[] = \" \";\n\n// Main Menu\nstatic char **WdOptions_Target[] = {\"Off\", \"On\"};\nstatic char **WdOptions_HUD[] = {\"On\", \"Off\"};\nstatic EventOption WdOptions_Main[] = {\n    // Target\n    {\n        .option_kind = OPTKIND_STRING,                                 // the type of option this is; menu, string list, integers list, etc\n        .value_num = sizeof(WdOptions_Target) / 4,                     // number of values for this option\n        .option_val = 0,                                               // value of this option\n        .menu = 0,                                                     // pointer to the menu that pressing A opens\n        .option_name = \"Target\",                                       // pointer to a string\n        .desc = \"Highlight an area of the stage to wavedash towards.\", // string describing what this option does\n        .option_values = WdOptions_Target,                             // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // HUD\n    {\n        .option_kind = OPTKIND_STRING,           // the type of option this is; menu, string list, integers list, etc\n        .value_num = sizeof(WdOptions_HUD) / 4,  // number of values for this option\n        .option_val = 0,                         // value of this option\n        .menu = 0,                               // pointer to the menu that pressing A opens\n        .option_name = \"HUD\",                    // pointer to a string\n        .desc = \"Toggle visibility of the HUD.\", // string describing what this option does\n        .option_values = WdOptions_HUD,          // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // Tips\n    {\n        .option_kind = OPTKIND_STRING,                  // the type of option this is; menu, string list, integers list, etc\n        .value_num = sizeof(WdOptions_HUD) / 4,         // number of values for this option\n        .option_val = 0,                                // value of this option\n        .menu = 0,                                      // pointer to the menu that pressing A opens\n        .option_name = \"Tips\",                          // pointer to a string\n        .desc = \"Toggle the onscreen display of tips.\", // string describing what this option does\n        .option_values = WdOptions_HUD,                 // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // Help\n    {\n        .option_kind = OPTKIND_FUNC,                                                                                                                                                                                                                               // the type of option this is; menu, string list, integers list, etc\n        .value_num = 0,                                                                                                                                                                                                                                            // number of values for this option\n        .option_val = 0,                                                                                                                                                                                                                                           // value of this option\n        .menu = 0,                                                                                                                                                                                                                                                 // pointer to the menu that pressing A opens\n        .option_name = \"Help\",                                                                                                                                                                                                                                     // pointer to a string\n        .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\n        .option_values = 0,                                                                                                                                                                                                                                        // pointer to an array of strings\n        .onOptionChange = 0,\n    },\n    // Exit\n    {\n        .option_kind = OPTKIND_FUNC,                     // the type of option this is; menu, string list, integers list, etc\n        .value_num = 0,                                  // number of values for this option\n        .option_val = 0,                                 // value of this option\n        .menu = 0,                                       // pointer to the menu that pressing A opens\n        .option_name = \"Exit\",                           // pointer to a string\n        .desc = \"Return to the Event Selection Screen.\", // string describing what this option does\n        .option_values = 0,                              // pointer to an array of strings\n        .onOptionChange = 0,\n        .onOptionSelect = Event_Exit,\n    },\n};\nstatic EventMenu WdMenu_Main = {\n    .name = \"Wavedash Training\",                                // the name of this menu\n    .option_num = sizeof(WdOptions_Main) / sizeof(EventOption), // number of options this menu contains\n    .scroll = 0,                                                // runtime variable used for how far down in the menu to start\n    .state = 0,                                                 // bool used to know if this menu is focused, used at runtime\n    .cursor = 0,                                                // index of the option currently selected, used at runtime\n    .options = &WdOptions_Main,                                 // pointer to all of this menu's options\n    .prev = 0,                                                  // pointer to previous menu, used at runtime\n};\n\n// Init Function\nvoid Event_Init(GOBJ *gobj)\n{\n    WavedashData *event_data = gobj->userdata;\n    EventDesc *event_desc = event_data->event_desc;\n    GOBJ *hmn = Fighter_GetGObj(0);\n    FighterData *hmn_data = hmn->userdata;\n    //GOBJ *cpu = Fighter_GetGObj(1);\n    //FighterData *cpu_data = cpu->userdata;\n\n    // theres got to be a better way to do this...\n    event_vars = *event_vars_ptr;\n\n    // get l-cancel assets\n    event_data->assets = File_GetSymbol(event_vars->event_archive, \"wdshData\");\n\n    // create HUD\n    Wavedash_Init(event_data);\n\n    // init target\n    Target_Init(event_data, hmn_data);\n\n    return;\n}\n// Think Function\nvoid Event_Think(GOBJ *event)\n{\n    WavedashData *event_data = event->userdata;\n    GOBJ *hmn = Fighter_GetGObj(0);\n    FighterData *hmn_data = hmn->userdata;\n\n    // infinite shields\n    hmn_data->shield.health = 60;\n\n    Wavedash_Think(event_data, hmn_data);\n\n    return;\n}\nvoid Event_Exit()\n{\n    Match *match = MATCH;\n\n    // end game\n    match->state = 3;\n\n    // cleanup\n    Match_EndVS();\n\n    // unfreeze\n    HSD_Update *update = HSD_UPDATE;\n    update->pause_develop = 0;\n    return;\n}\n\n// Event functions\nvoid Wavedash_Init(WavedashData *event_data)\n{\n\n    // create hud cobj\n    GOBJ *hudcam_gobj = GObj_Create(19, 20, 0);\n    ArchiveInfo **ifall_archive = 0x804d6d5c;\n    COBJDesc ***dmgScnMdls = File_GetSymbol(*ifall_archive, 0x803f94d0);\n    COBJDesc *cam_desc = dmgScnMdls[1][0];\n    COBJ *hud_cobj = COBJ_LoadDesc(cam_desc);\n    // init camera\n    GObj_AddObject(hudcam_gobj, R13_U8(-0x3E55), hud_cobj);\n    GOBJ_InitCamera(hudcam_gobj, Wavedash_HUDCamThink, 7);\n    hudcam_gobj->cobj_links = 1 << 18;\n\n    GOBJ *hud_gobj = GObj_Create(0, 0, 0);\n    event_data->hud.gobj = hud_gobj;\n    // Load jobj\n    JOBJ *hud_jobj = JOBJ_LoadJoint(event_data->assets->hud);\n    GObj_AddObject(hud_gobj, 3, hud_jobj);\n    GObj_AddGXLink(hud_gobj, GXLink_Common, 18, 80);\n\n    // create text canvas\n    int canvas = Text_CreateCanvas(2, hud_gobj, 14, 15, 0, 18, 81, 19);\n    event_data->hud.canvas = canvas;\n\n    // init text\n    Text **text_arr = &event_data->hud.text_timing;\n    for (int i = 0; i < 3; i++)\n    {\n\n        // Create text object\n        Text *hud_text = Text_CreateText(2, canvas);\n        text_arr[i] = hud_text;\n        hud_text->kerning = 1;\n        hud_text->align = 1;\n        hud_text->use_aspect = 1;\n\n        // Get position\n        Vec3 text_pos;\n        JOBJ *text_jobj;\n        JOBJ_GetChild(hud_jobj, &text_jobj, WDJOBJ_TEXT + i, -1);\n        JOBJ_GetWorldPosition(text_jobj, 0, &text_pos);\n\n        // adjust scale\n        Vec3 *scale = &hud_jobj->scale;\n        // text scale\n        hud_text->scale.X = (scale->X * 0.01) * TEXT_SCALE;\n        hud_text->scale.Y = (scale->Y * 0.01) * TEXT_SCALE;\n        hud_text->aspect.X = 165;\n\n        // text position\n        hud_text->trans.X = text_pos.X + (scale->X / 4.0);\n        hud_text->trans.Y = (text_pos.Y * -1) + (scale->Y / 4.0);\n\n        // dummy text\n        Text_AddSubtext(hud_text, 0, 0, \"-\");\n    }\n\n    // init timer\n    event_data->timer = -1;\n    event_data->since_wavedash = 255;\n    return 0;\n}\nvoid Wavedash_Think(WavedashData *event_data, FighterData *hmn_data)\n{\n\n    // check to enter is_wavedashing\n    if (event_data->is_wavedashing == 0)\n    {\n        // increment time since wavedash\n        if (event_data->since_wavedash < 255)\n            event_data->since_wavedash++;\n\n        // check to enter wavedash state\n        if ((hmn_data->state == ASID_LANDINGFALLSPECIAL) && hmn_data->TM.state_prev[2] == ASID_KNEEBEND)\n        {\n            event_data->is_wavedashing = 1;\n            event_data->since_wavedash = 0;\n        }\n\n        // check to null timer\n        if (((hmn_data->state >= ASID_WALKSLOW) && (hmn_data->state <= ASID_KNEEBEND)) ||                    // no ground movement or jumping\n            (hmn_data->phys.air_state == 1) ||                                                               // airborne\n            ((hmn_data->attack_kind >= ATKKIND_SPECIALN) && (hmn_data->attack_kind <= ATKKIND_SPECIALLW)) || // any special move\n            ((hmn_data->state >= ASID_ESCAPEF) && (hmn_data->state >= ASID_ESCAPEB)))                        // rolls\n            event_data->since_wavedash = 255;\n    }\n    // check to exit is_wavedashing\n    if (event_data->is_wavedashing == 1)\n    {\n        if ((hmn_data->state != ASID_LANDINGFALLSPECIAL))\n            event_data->is_wavedashing = 0;\n    }\n\n    //OSReport(\"is_wavedashing: %d since_wavedash: %d\", event_data->is_wavedashing, event_data->since_wavedash);\n\n    JOBJ *hud_jobj = event_data->hud.gobj->hsd_object;\n\n    // start sequence on jump squat\n    if ((hmn_data->state == ASID_KNEEBEND) && (hmn_data->TM.state_frame == 0))\n    {\n        event_data->is_airdodge = 0;\n\n        // start timer\n        event_data->timer = 0;\n\n        // save line and position\n        event_data->restore.pos.X = hmn_data->phys.pos.X;\n        event_data->restore.pos.Y = hmn_data->phys.pos.Y;\n        event_data->restore.line_index = hmn_data->coll_data.ground_index;\n    }\n\n    // if sequence started\n    if (event_data->timer >= 0)\n    {\n        event_data->timer++; // inc timer\n\n        // if grounded and not in kneebend, stop sequence\n        if ((hmn_data->state != ASID_KNEEBEND) && (hmn_data->state != ASID_LANDINGFALLSPECIAL) && (hmn_data->phys.air_state == 0))\n        {\n            event_data->timer = -1;\n            event_data->is_airdodge = 0;\n            event_data->is_early_airdodge = 0;\n        }\n\n        // run sequence logic\n        else\n        {\n\n            // catch early airdodge input\n            if (hmn_data->input.down & (PAD_TRIGGER_L | PAD_TRIGGER_R))\n            {\n                event_data->airdodge_frame = event_data->timer; // save airdodge frame\n                event_data->is_early_airdodge = 1;\n            }\n\n            // save airdodge angle\n            if ((event_data->is_airdodge == 0) &&\n                (((hmn_data->state == ASID_ESCAPEAIR) && (hmn_data->TM.state_frame == 0)) || // if entered airdodge\n                 ((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))))\n            {\n                // save airdodge angle\n                float angle = atan2(hmn_data->input.lstick_y, hmn_data->input.lstick_x) - -(M_PI / 2);\n                event_data->wd_angle = angle;\n\n                event_data->is_early_airdodge = 0;\n                event_data->is_airdodge = 1;\n                event_data->airdodge_frame = event_data->timer; // save airdodge frame\n            }\n\n            int is_finished = 0;\n            void *mat_anim = 0;\n\n            // look for successful WD\n            if ((hmn_data->state == ASID_LANDINGFALLSPECIAL) && (hmn_data->TM.state_frame == 0) && // is in special landing\n                (hmn_data->TM.state_prev[0] == ASID_ESCAPEAIR) &&                                  // came from airdodge\n                (hmn_data->TM.state_prev[2] == ASID_KNEEBEND))                                     // came from jump\n            {\n\n                is_finished = 1;\n                mat_anim = event_data->assets->hudmatanim[0];\n                event_data->wd_succeeded++;\n\n                // check for perfect\n                //if (WdOptions_Main[0].option_val == 0)\n                {\n                    if (event_data->airdodge_frame == ((int)hmn_data->attr.jump_startup_time + 1))\n                        SFX_Play(303);\n                }\n            }\n\n            // look for failed WD\n            else if ((event_data->is_early_airdodge == 1) && (((hmn_data->state == ASID_JUMPF) || (hmn_data->state == ASID_JUMPB)) && (hmn_data->TM.state_frame >= 10)) ||\n                     ((hmn_data->state == ASID_ESCAPEAIR) && (hmn_data->TM.state_frame >= 10) && (hmn_data->TM.state_prev[1] == ASID_KNEEBEND)))\n            {\n                is_finished = 1;\n                mat_anim = event_data->assets->hudmatanim[1];\n                SFX_PlayCommon(3);\n\n                // restore position\n                int ray_index;\n                int ray_kind;\n                Vec2 ray_angle;\n                Vec3 ray_pos;\n                float from_x = event_data->restore.pos.X;\n                float to_x = from_x;\n                float from_y = event_data->restore.pos.Y + 3;\n                float to_y = from_y - 6;\n                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);\n                if ((is_ground == 1) && (ray_index == event_data->restore.line_index))\n                {\n                    // do this for every subfighter (thanks for complicated code ice climbers)\n                    for (int i = 0; i < 2; i++)\n                    {\n                        GOBJ *this_fighter = Fighter_GetSubcharGObj(hmn_data->ply, i);\n\n                        if (this_fighter != 0)\n                        {\n\n                            FighterData *this_fighter_data = this_fighter->userdata;\n\n                            if ((this_fighter_data->flags.sleep == 0) && (this_fighter_data->flags.dead == 0))\n                            {\n\n                                // place CPU here\n                                this_fighter_data->phys.pos = ray_pos;\n                                this_fighter_data->coll_data.ground_index = ray_index;\n\n                                // set grounded\n                                this_fighter_data->phys.air_state = 0;\n                                //Fighter_SetGrounded(this_fighter);\n\n                                // kill velocity\n                                Fighter_KillAllVelocity(this_fighter);\n\n                                // enter wait\n                                ActionStateChange(0, 1, -1, this_fighter, ASID_WAIT, 0, 0);\n                                this_fighter_data->stateBlend = 0;\n\n                                // update ECB\n                                this_fighter_data->coll_data.topN_Curr = this_fighter_data->phys.pos; // move current ECB location to new position\n                                Coll_ECBCurrToPrev(&this_fighter_data->coll_data);\n                                this_fighter_data->cb.Coll(this_fighter);\n\n                                // update camera box\n                                Fighter_UpdateCameraBox(this_fighter);\n                                this_fighter_data->cameraBox->boundleft_curr = this_fighter_data->cameraBox->boundleft_proj;\n                                this_fighter_data->cameraBox->boundright_curr = this_fighter_data->cameraBox->boundright_proj;\n\n                                // init CPU logic (for nana's popo position history...)\n                                int cpu_kind = Fighter_GetCPUKind(this_fighter_data->ply);\n                                int cpu_level = Fighter_GetCPULevel(this_fighter_data->ply);\n                                Fighter_CPUInitialize(this_fighter_data, cpu_kind, cpu_level, 0);\n\n                                // place subfighter in the Z axis\n                                if (this_fighter_data->flags.ms == 1)\n                                {\n                                    ftCommonData *ft_common = *stc_ftcommon;\n                                    this_fighter_data->phys.pos.Z = ft_common->ms_zjostle_max * -1;\n                                }\n                            }\n                        }\n                    }\n\n                    // update camera\n                    Match_CorrectCamera();\n                }\n            }\n\n            // update bar\n            if (is_finished)\n            {\n                // reset variables\n                event_data->timer = -1;\n                event_data->is_airdodge = 0;\n                event_data->is_early_airdodge = 0;\n\n                // update bar frame colors\n                JOBJ *arrow_jobj;\n                JOBJ_GetChild(hud_jobj, &arrow_jobj, WDJOBJ_ARROW, -1); // get timing bar jobj\n                // get in terms of bar timeframe\n                int jump_frame = ((WDFRAMES - 1) / 2) - (int)hmn_data->attr.jump_startup_time;\n                int input_frame = jump_frame + event_data->airdodge_frame - 1;\n\n                // update arrow position\n                if (input_frame < WDFRAMES)\n                {\n                    event_data->hud.arrow_prevpos = arrow_jobj->trans.X;\n                    event_data->hud.arrow_nextpos = (-WDARROW_OFFSET * ((WDFRAMES - 1) / 2)) + (input_frame * 0.36);\n                    JOBJ_ClearFlags(arrow_jobj, JOBJ_HIDDEN);\n                    event_data->hud.arrow_timer = WDARROW_ANIMFRAMES;\n                }\n                // hide arrow for this wd attempt\n                else\n                {\n                    event_data->hud.arrow_timer = 0;\n                    arrow_jobj->trans.X = 0;\n                    JOBJ_SetFlags(arrow_jobj, JOBJ_HIDDEN);\n                }\n\n                // updating timing text\n                if (input_frame < ((WDFRAMES - 1) / 2)) // is early\n                    Text_SetText(event_data->hud.text_timing, 0, \"%df Early\", ((WDFRAMES - 1) / 2) - input_frame);\n                else if (input_frame == ((WDFRAMES - 1) / 2))\n                    Text_SetText(event_data->hud.text_timing, 0, \"Perfect\");\n                else if (input_frame > ((WDFRAMES - 1) / 2))\n                    Text_SetText(event_data->hud.text_timing, 0, \"%df Late\", input_frame - ((WDFRAMES - 1) / 2));\n\n                // update airdodge angle\n                Text_SetText(event_data->hud.text_angle, 0, \"%.2f\", fabs(event_data->wd_angle / M_1DEGREE));\n\n                // update succession\n                event_data->wd_attempted++;\n                Text_SetText(event_data->hud.text_succession, 0, \"%.2f%\", ((float)event_data->wd_succeeded / (float)event_data->wd_attempted) * 100.0);\n\n                // hide tip so bar is unobscured\n                //event_vars->Tip_Destroy();\n\n                // apply HUD animation\n                JOBJ_RemoveAnimAll(hud_jobj);\n                JOBJ_AddAnimAll(hud_jobj, 0, mat_anim, 0);\n                JOBJ_ReqAnimAll(hud_jobj, 0);\n            }\n        }\n    }\n\n    // update target\n    Target_Manager(event_data, hmn_data);\n\n    // run tip logic\n    Tips_Think(event_data, hmn_data);\n\n    // update HUD anim\n    JOBJ_AnimAll(hud_jobj);\n\n    // update arrow animation\n    if (event_data->hud.arrow_timer > 0)\n    {\n        // decrement timer\n        event_data->hud.arrow_timer--;\n\n        // get this frames position\n        float time = 1 - ((float)event_data->hud.arrow_timer / (float)WDARROW_ANIMFRAMES);\n        float xpos = Bezier(time, event_data->hud.arrow_prevpos, event_data->hud.arrow_nextpos);\n\n        // update position\n        JOBJ *arrow_jobj;\n        JOBJ_GetChild(hud_jobj, &arrow_jobj, WDJOBJ_ARROW, -1); // get timing bar jobj\n        arrow_jobj->trans.X = xpos;\n        JOBJ_SetMtxDirtySub(arrow_jobj);\n    }\n\n    return;\n}\nvoid Wavedash_HUDCamThink(GOBJ *gobj)\n{\n\n    // if HUD enabled and not paused\n    if ((WdOptions_Main[1].option_val == 0) && (Pause_CheckStatus(1) != 2))\n    {\n        CObjThink_Common(gobj);\n    }\n\n    return;\n}\nfloat Bezier(float time, float start, float end)\n{\n    float bez = time * time * (3.0f - 2.0f * time);\n    return bez * (end - start) + start;\n}\n\n// Target functions\nvoid Target_Init(WavedashData *event_data, FighterData *hmn_data)\n{\n\n    ftCommonData *ftcommon = *stc_ftcommon;\n    float mag;\n\n    // determine best wavedash distance (not taking into account friction doubling)\n    mag = ftcommon->escapeair_vel * cos(atan2(-0.2875, 0.9500));\n    float wd_maxdstn = Target_GetWdashDistance(hmn_data, mag);\n    OSReport(\"%s wd_maxdstn: %.2f\\n\", Fighter_GetName(Fighter_GetExternalID(hmn_data->ply)), wd_maxdstn);\n    event_data->wd_maxdstn = wd_maxdstn;\n\n    // determine scale based on wd distance\n    float dist = event_data->wd_maxdstn;\n    if (dist < TRGTSCL_DISTMIN)\n        dist = TRGTSCL_DISTMIN;\n    else if (dist > TRGTSCL_DISTMAX)\n        dist = TRGTSCL_DISTMAX;\n    event_data->target.scale = (((dist - TRGTSCL_DISTMIN) / (TRGTSCL_DISTMAX - TRGTSCL_DISTMIN)) * (TRGTSCL_SCALEMAX - TRGTSCL_SCALEMIN)) + TRGTSCL_SCALEMIN;\n\n    // get width of the target\n    JOBJ *target = JOBJ_LoadJoint(event_data->assets->target_jobj); // create dummy\n    float scale = event_data->target.scale;                         // scale\n    target->scale.X *= scale;\n    target->scale.Z *= scale;\n\n    // get children\n    JOBJ *left_jobj, *right_jobj;\n    JOBJ_GetChild(target, &left_jobj, TRGTJOBJ_LBOUND, -1);\n    JOBJ_GetChild(target, &right_jobj, TRGTJOBJ_RBOUND, -1);\n    // get offsets\n    JOBJ_GetWorldPosition(left_jobj, 0, &event_data->target.left_offset);\n    JOBJ_GetWorldPosition(right_jobj, 0, &event_data->target.right_offset);\n\n    // free jobj\n    JOBJ_RemoveAll(target);\n\n    return;\n}\nvoid Target_Manager(WavedashData *event_data, FighterData *hmn_data)\n{\n    GOBJ *target_gobj = event_data->target.gobj;\n\n    switch (WdOptions_Main[0].option_val)\n    {\n    case (0): // off\n    {\n        // if spawned, remove\n        if (target_gobj != 0)\n        {\n            Target_ChangeState(target_gobj, TRGSTATE_DESPAWN);\n            event_data->target.gobj = 0;\n        }\n\n        break;\n    }\n    case (1): // on\n    {\n        // if not spawned, spawn\n        if (target_gobj == 0)\n        {\n            if (hmn_data->phys.air_state == 0)\n            {\n                // spawn target\n                target_gobj = Target_Spawn(event_data, hmn_data);\n                event_data->target.gobj = target_gobj;\n            }\n        }\n\n        // update target logic\n        if (target_gobj != 0)\n        {\n\n            TargetData *target_data = target_gobj->userdata;\n\n            // update fighter backed up position\n\n            // restore position if not a wavedash\n\n            // check current target state\n            if (target_data->state == TRGSTATE_DESPAWN)\n            {\n                // create new one\n                target_gobj = Target_Spawn(event_data, hmn_data);\n                event_data->target.gobj = target_gobj;\n            }\n        }\n\n        break;\n    }\n    }\n\n    return;\n}\nGOBJ *Target_Spawn(WavedashData *event_data, FighterData *hmn_data)\n{\n\n    Vec3 ray_angle;\n    Vec3 ray_pos;\n    int ray_index;\n    float max = (event_data->wd_maxdstn * TRGT_RANGEMAX);\n    float min = (event_data->wd_maxdstn * TRGT_RANGEMIN);\n\n    // ensure min exists\n    int min_exists = 0;\n    min_exists += Target_CheckArea(event_data, hmn_data->coll_data.ground_index, &hmn_data->phys.pos, max, 0, 0, 0);\n    min_exists += Target_CheckArea(event_data, hmn_data->coll_data.ground_index, &hmn_data->phys.pos, max * -1, 0, 0, 0);\n    if (min_exists != 0)\n    {\n\n        // begin looking for valid ground at a random distance\n        int is_ground = 0;\n        while (is_ground != 1)\n        {\n\n            // select random direction\n            float direction;\n            int temp = HSD_Randi(2);\n            if (temp == 0)\n                direction = -1;\n            else\n                direction = 1;\n\n            // random distance\n            float distance = (HSD_Randf() * (max - min)) + min;\n\n            // check if valid\n            is_ground = Target_CheckArea(event_data, hmn_data->coll_data.ground_index, &hmn_data->phys.pos, distance * direction, &ray_index, &ray_pos, &ray_angle);\n        }\n\n        // create target gobj\n        GOBJ *target_gobj = GObj_Create(10, 11, 0);\n\n        // target data\n        TargetData *target_data = calloc(sizeof(TargetData));\n        GObj_AddUserData(target_gobj, 4, HSD_Free, target_data);\n\n        // add proc\n        GObj_AddProc(target_gobj, Target_Think, 16);\n\n        // create jobj\n        JOBJ *target_jobj = JOBJ_LoadJoint(event_data->assets->target_jobj);\n        GObj_AddObject(target_gobj, 3, target_jobj);\n        GObj_AddGXLink(target_gobj, GXLink_Common, 5, 0);\n\n        // scale target\n        float scale = event_data->target.scale;\n        target_jobj->scale.X *= scale;\n        target_jobj->scale.Z *= scale;\n\n        // move target\n        target_jobj->trans.X = ray_pos.X;\n        target_jobj->trans.Y = ray_pos.Y;\n        target_jobj->trans.Z = ray_pos.Z;\n\n        // adjust rotation based on line slope\n        JOBJ *aura_jobj;\n        JOBJ_GetChild(target_jobj, &aura_jobj, TRGTJOBJ_AURA, -1);\n        aura_jobj->rot.Z = -1 * atan2(ray_angle.X, ray_angle.Y);\n\n        // create camera box\n        CameraBox *cam = CameraBox_Alloc();\n        cam->boundleft_proj = -10;\n        cam->boundright_proj = 10;\n        cam->boundtop_proj = 10;\n        cam->boundbottom_proj = -10;\n\n        // update camerabox position\n        cam->cam_pos.X = target_jobj->trans.X;\n        cam->cam_pos.Y = target_jobj->trans.Y + 15;\n        cam->cam_pos.Z = target_jobj->trans.Z;\n\n        // init target data\n        Target_ChangeState(target_gobj, TRGSTATE_SPAWN); // enter spawn state\n        target_data->cam = cam;                          // save camera\n        target_data->line_index = ray_index;             // save line index\n        target_data->pos = ray_pos;                      // save position\n        target_data->left = event_data->target.left_offset.X;\n        target_data->right = event_data->target.right_offset.X;\n\n        return target_gobj;\n    }\n    else\n    {\n        return 0;\n    }\n}\nvoid Target_Think(GOBJ *target_gobj)\n{\n    JOBJ *target_jobj = target_gobj->hsd_object;\n    TargetData *target_data = target_gobj->userdata;\n    WavedashData *event_data = event_vars->event_gobj->userdata;\n\n    // update anim\n    JOBJ_AnimAll(target_jobj);\n\n    // ensure line still exists\n    if (GrColl_CheckIfLineEnabled(target_data->line_index) == 0)\n    {\n        // enter exit state\n        Target_ChangeState(target_gobj, TRGSTATE_DESPAWN);\n    }\n\n    // update target position (look into how fighters are rooted on ground)\n    Vec3 pos_diff;\n    GrColl_GetPosDifference(target_data->line_index, &target_data->pos, &pos_diff);\n    VECAdd(&target_data->pos, &pos_diff, &target_data->pos);\n\n    // update target orientation\n    Vec3 slope;\n    GrColl_GetLineSlope(target_data->line_index, &slope);\n    JOBJ *aura_jobj;\n    JOBJ_GetChild(target_jobj, &aura_jobj, TRGTJOBJ_AURA, -1);\n    aura_jobj->rot.Z = -1 * atan2(slope.X, slope.Y);\n\n    // update camerabox position\n    CameraBox *cam = target_data->cam;\n    cam->cam_pos.X = target_data->pos.X;\n    cam->cam_pos.Y = target_data->pos.Y + 15;\n    cam->cam_pos.Z = target_data->pos.Z;\n\n    // update position\n    target_jobj->trans = target_data->pos;\n    JOBJ_SetMtxDirtySub(target_jobj);\n\n    // state based logic\n    switch (target_data->state)\n    {\n    case (TRGSTATE_SPAWN):\n    {\n        // check if ended\n        if (JOBJ_CheckAObjEnd(target_jobj) == 0)\n            Target_ChangeState(target_gobj, TRGSTATE_WAIT);\n\n        break;\n    }\n    case (TRGSTATE_WAIT):\n    {\n        // get position\n        Vec3 pos;\n        JOBJ_GetWorldPosition(target_jobj, 0, &pos);\n\n        // check for collision\n        FighterData *hmn_data = Fighter_GetGObj(0)->userdata;\n\n        Vec3 *ft_pos = &hmn_data->phys.pos;\n        if ((hmn_data->phys.air_state == 0) &&\n            ((event_data->since_wavedash > 0) && (event_data->since_wavedash < 255) && (fabs(hmn_data->phys.self_vel.X) < 0.5)) && // check if a wavedash\n            (ft_pos->X > (pos.X + target_data->left)) &&\n            (ft_pos->X < (pos.X + target_data->right)) &&\n            (ft_pos->Y > (pos.Y + -1)) &&\n            (ft_pos->Y < (pos.Y + 1)))\n        {\n\n            // sfx\n            SFX_Play(173);\n\n            Target_ChangeState(target_gobj, TRGSTATE_DESPAWN);\n        }\n\n        break;\n    }\n    case (TRGSTATE_DESPAWN):\n    {\n        // check if ended\n        if (JOBJ_CheckAObjEnd(target_jobj) == 0)\n        {\n            // destroy camera\n            CameraBox_Destroy(target_data->cam);\n\n            // destroy this target\n            GObj_Destroy(target_gobj);\n        }\n\n        break;\n    }\n    }\n\n    return;\n}\nvoid Target_ChangeState(GOBJ *target_gobj, int state)\n{\n    WavedashData *event_data = event_vars->event_gobj->userdata;\n    TargetData *target_data = target_gobj->userdata;\n    JOBJ *target_jobj = target_gobj->hsd_object;\n\n    // update state\n    target_data->state = state;\n\n    // add anim\n    JOBJ_AddAnimAll(target_jobj, event_data->assets->target_jointanim[state], event_data->assets->target_matanim[state], 0);\n    JOBJ_ReqAnimAll(target_jobj, 0); // req anim\n\n    return;\n}\nfloat Target_GetWdashDistance(FighterData *hmn_data, float mag)\n{\n\n    float distance = 0;\n    ftCommonData *ftcommon = *stc_ftcommon;\n\n    // now simulate\n    mag *= ftcommon->escapeair_veldecaymult; // first frame multiply by 0.9 ( in airdodge still)\n    distance += mag;\n\n    // subsequent, apply friction until at 0\n    while (mag > 0)\n    {\n\n        // get friction\n        float friction = hmn_data->attr.ground_friction;\n        if (mag > hmn_data->attr.walk_maximum_velocity) // double friction if speed > walk max speed\n            friction *= ftcommon->friction_mult;\n\n        // apply it\n        mag -= friction;\n\n        // ensure not under 0\n        if (mag < 0)\n            mag = 0;\n\n        distance += mag;\n    }\n\n    return distance;\n}\nint Target_CheckArea(WavedashData *event_data, int line, Vec3 *pos, float x_offset, int *ret_line, Vec3 *ret_pos, Vec3 *ret_slope)\n{\n\n    int status = 0;\n\n    // init\n    int is_ground = 0;\n    // check left\n    is_ground += GrColl_CrawlGround(line, pos, ret_line, ret_pos, 0, ret_slope, x_offset + event_data->target.left_offset.X, 0);\n    // check right\n    is_ground += GrColl_CrawlGround(line, pos, ret_line, ret_pos, 0, ret_slope, x_offset + event_data->target.right_offset.X, 0);\n    // check center\n    is_ground += GrColl_CrawlGround(line, pos, ret_line, ret_pos, 0, ret_slope, x_offset + event_data->target.center_offset.X, 0);\n\n    if (is_ground == 3)\n        status = 1;\n\n    return status;\n}\n\n// Tips\nTips_Think(WavedashData *event_data, FighterData *hmn_data)\n{\n\n    // only if enabled\n    if (WdOptions_Main[2].option_val == 0)\n    {\n\n        // shield after wavedash\n        // look successful wavedash\n        if (event_data->since_wavedash <= 10)\n        {\n            // look for frame 1 of guard off\n            if ((hmn_data->state == ASID_GUARDOFF) && (hmn_data->TM.state_frame == 0) &&                  // just let go of shield\n                ((hmn_data->TM.state_prev[0] == ASID_GUARD) && (hmn_data->TM.state_prev_frames[0] == 1))) // only guarded for 1 frame\n            {\n                event_data->tip.shield_num++;\n\n                if (event_data->tip.shield_num >= 3)\n                {\n                    event_vars->Tip_Display(5 * 60, \"Tip:\\nDon't hold the trigger! Quickly \\npress and release to prevent \\nshielding after wavedashing.\");\n                    event_data->tip.shield_num = 0;\n                }\n            }\n        }\n    }\n\n    return;\n}\n\n// Initial Menu\nstatic EventMenu *Event_Menu = &WdMenu_Main;"
  },
  {
    "path": "patch/events/wavedash/source/wavedash.h",
    "content": "#include \"../../../../MexTK/mex.h\"\n#include \"../../../tmdata/source/events.h\"\n\n#define TEXT_SCALE 4.2\n#define WDJOBJ_TEXT 6\n#define WDJOBJ_ARROW 3\n#define WDARROW_OFFSET 0.36\n#define WDARROW_ANIMFRAMES 4\n#define WDFRAMES 15\n\n#define TRGT_RANGEMAX 0.8\n#define TRGT_RANGEMIN 0.55\n\n#define TRGTJOBJ_AURA 3\n#define TRGTJOBJ_LBOUND 4\n#define TRGTJOBJ_RBOUND 5\n\n#define TRGTSCL_DISTMIN 20\n#define TRGTSCL_DISTMAX 50\n#define TRGTSCL_SCALEMIN 1.0\n#define TRGTSCL_SCALEMAX 1.7\n\ntypedef struct WavedashData WavedashData;\ntypedef struct WavedashAssets WavedashAssets;\ntypedef struct TargetData TargetData;\n\nstruct WavedashData\n{\n    EventDesc *event_desc;\n    WavedashAssets *assets;\n    struct\n    {\n        GOBJ *gobj;\n        int canvas;\n        Text *text_timing;\n        Text *text_angle;\n        Text *text_succession;\n        float arrow_prevpos;\n        float arrow_nextpos;\n        int arrow_timer;\n    } hud;\n    struct\n    {\n        GOBJ *gobj;\n        float scale;\n        Vec3 left_offset;\n        Vec3 center_offset;\n        Vec3 right_offset;\n    } target;\n    struct\n    {\n        u8 shield_num;\n    } tip;\n    float wd_maxdstn;\n    int timer;\n    u8 airdodge_frame;\n    u8 is_airdodge;\n    u8 is_early_airdodge;\n    u8 is_wavedashing;\n    u8 since_wavedash;\n    float wd_angle;\n    int wd_attempted;\n    int wd_succeeded;\n    struct\n    {\n        u16 line_index;\n        Vec2 pos;\n    } restore;\n    GXColor orig_colors[WDFRAMES];\n};\n\nstruct WavedashAssets\n{\n    JOBJ *hud;\n    void **hudmatanim; // pointer to array\n    JOBJ *target_jobj;\n    void **target_jointanim;\n    void **target_matanim;\n};\n\nenum TargetState\n{\n    TRGSTATE_SPAWN,\n    TRGSTATE_WAIT,\n    TRGSTATE_DESPAWN,\n};\nstruct TargetData\n{\n    int state;\n    Vec3 pos;\n    int line_index;\n    float left;\n    float right;\n    CameraBox *cam;\n};\n\nfloat Bezier(float time, float start, float end);\nfloat Target_GetWdashDistance(FighterData *hmn_data, float mag);\nGOBJ *Target_Spawn(WavedashData *event_data, FighterData *fighter_data);\nint Target_CheckArea(WavedashData *event_data, int line, Vec3 *pos, float x_offset, int *ret_line, Vec3 *ret_pos, Vec3 *ret_slope);\nvoid Target_Think(GOBJ *target_gobj);\nvoid Wavedash_HUDCamThink(GOBJ *gobj);\nvoid Event_Exit();"
  },
  {
    "path": "patch/tmdata/build.bat",
    "content": "xcopy /s /y \"assets\\evMenu.dat\" \"output/TmDt.dat\"\n\"../../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\n\"../../MexTK/MexTK.exe\" -trim \"output/TmDt.dat\"\n\npause"
  },
  {
    "path": "patch/tmdata/source/events.c",
    "content": "#include \"events.h\"\n#include <stdarg.h>\n\nvoid Event_Init(GOBJ *gobj)\n{\n    int *EventData = gobj->userdata;\n    EventDesc *event_desc = EventData[0];\n\n    return;\n}\n\n/////////////////////\n// Mod Information //\n/////////////////////\n\nstatic char TM_VersShort[] = TM_VERSSHORT \"\\n\";\nstatic char TM_VersLong[] = TM_VERSLONG \"\\n\";\nstatic char TM_Compile[] = \"COMPILED: \" __DATE__ \" \" __TIME__;\nstatic char nullString[] = \" \";\n\n////////////////////////\n/// Event Defintions ///\n////////////////////////\n\n// Lab\n// Match Data\nstatic EventMatchData Lab_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = false,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = true,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = false,      // 0x10\n    .isCheckForZRetry = false,  // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = -1,        // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc Lab = {\n    // Event Name\n    .eventName = \"Training Lab\\n\",\n    .eventDescription = \"Free practice with\\ncomplete control.\\n\",\n    .eventTutorial = \"\",\n    .eventFile = \"EvLab\",\n    .eventCSSFile = \"TM/EvLabCSS.dat\",\n    .isChooseCPU = true,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &Lab_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData LCancel_MatchData = {\n    .timer = MATCH_TIMER_HIDE,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = false,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = false,\n    .isDisablePause = true,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = false,      // 0x10\n    .isCheckForZRetry = false,  // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = -1,        // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc LCancel = {\n    // Event Name\n    .eventName = \"L-Cancel Training\\n\",\n    .eventDescription = \"Practice L-Cancelling on\\na stationary CPU.\\n\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = \"EvLcl\",\n    .isChooseCPU = false,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 15,\n    .matchData = &LCancel_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// Ledgedash Training\n// Match Data\nstatic EventMatchData Ledgedash_MatchData = {\n    .timer = MATCH_TIMER_HIDE,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = false,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = false,\n    .isDisablePause = true,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = false,      // 0x10\n    .isCheckForZRetry = false,  // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = -1,        // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc Ledgedash = {\n    .eventName = \"Ledgedash Training\\n\",\n    .eventDescription = \"Practice Ledgedashes!\\nUse D-Pad to change ledge.\\n\",\n    .eventTutorial = \"TvLedDa\",\n    .eventFile = \"EvLdsh\",\n    .isChooseCPU = false,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 15,\n    .matchData = &Ledgedash_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// Wavedash Training\n// Match Data\nstatic EventMatchData Wavedash_MatchData = {\n    .timer = MATCH_TIMER_HIDE,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = false,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = false,\n    .isDisablePause = true,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = false,      // 0x10\n    .isCheckForZRetry = false,  // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = -1,        // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc Wavedash = {\n    .eventName = \"Wavedash Training\\n\",\n    .eventDescription = \"Practice timing your wavedash,\\na fundamental movement technique.\\n\",\n    .eventTutorial = \"TvWvDsh\",\n    .eventFile = \"EvWdsh\",\n    .isChooseCPU = false,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 15,\n    .matchData = &Wavedash_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// Combo Training\n// Match Data\nstatic EventMatchData Combo_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = -1,        // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc Combo = {\n\n    .eventName = \"Combo Training\\n\",\n    .eventDescription = \"L+DPad adjusts percent | DPadDown moves CPU\\nDPad right/left saves and loads positions.\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = true,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &Combo_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// Attack On Shield Training\n// Match Data\nstatic EventMatchData AttackOnShield_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = -1,        // 0xFF=\n    .stage = 32,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc AttackOnShield = {\n    .eventName = \"Attack on Shield\\n\",\n    .eventDescription = \"Practice attacks on a shielding opponent\\nPause to change their OoS option\\n\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = true,\n    .isSelectStage = false,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &AttackOnShield_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// Reversal Training\n// Match Data\nstatic EventMatchData Reversal_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = -1,        // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc Reversal = {\n    .eventName = \"Reversal Training\\n\",\n    .eventDescription = \"Practice OoS punishes! DPad left/right\\nmoves characters close and further apart.\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = true,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &Reversal_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData SDI_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = 2,         // 0xFF=\n    .stage = 32,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc SDI = {\n    .eventName = \"SDI Training\\n\",\n    .eventDescription = \"Use Smash DI to escape\\nFox's up-air attack!\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = false,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &SDI_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData Powershield_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = 20,        // 0xFF=\n    .stage = 32,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc Powershield = {\n    .eventName = \"Powershield Training\\n\",\n    .eventDescription = \"Powershield Falco's laser!\\nPause to change to fire-rate.\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = false,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &Powershield_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData Ledgetech_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = 20,        // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc Ledgetech = {\n    .eventName = \"Ledge-Tech Training\\n\",\n    .eventDescription = \"Practice ledge-teching\\nFalco's down-smash\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &Ledgetech_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData AmsahTech_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = 9,         // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc AmsahTech = {\n    .eventName = \"Amsah-Tech Training\\n\",\n    .eventDescription = \"Taunt to have Marth Up-B,\\nthen ASDI down and tech!\\n\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &AmsahTech_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData ShieldDrop_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = -1,        // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc ShieldDrop = {\n    .eventName = \"Shield Drop Training\\n\",\n    .eventDescription = \"Counter with a shield-drop aerial!\\nDPad left/right moves players apart.\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = true,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &ShieldDrop_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData WaveshineSDI_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = 2,         // 0xFF=\n    .stage = 32,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc WaveshineSDI = {\n    .eventName = \"Waveshine SDI\\n\",\n    .eventDescription = \"Use Smash DI to get out\\nof Fox's waveshine!\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = false,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &WaveshineSDI_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData SlideOff_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = 9,         // 0xFF=\n    .stage = 3,           // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc SlideOff = {\n    .eventName = \"Slide-Off Training\\n\",\n    .eventDescription = \"Use Slide-Off DI to slide off\\nthe platform and counter attack!\\n\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = false,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &SlideOff_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData GrabMash_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = 9,         // 0xFF=\n    .stage = 32,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc GrabMash = {\n    .eventName = \"Grab Mash Training\\n\",\n    .eventDescription = \"Mash buttons to escape the grab\\nas quickly as possible!\\n\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = false,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &GrabMash_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData TechCounter_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = 9,         // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc TechCounter = {\n    .eventName = \"Ledgetech Marth Counter\\n\",\n    .eventDescription = \"Practice ledge-teching\\nMarth's counter!\\n\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &TechCounter_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData ArmadaShine_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = 2,         // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc ArmadaShine = {\n    .eventName = \"Armada-Shine Training\\n\",\n    .eventDescription = \"Finish the enemy Fox\\nwith an Armada Shine!\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &ArmadaShine_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData SideBSweet_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = 9,         // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc SideBSweet = {\n    .eventName = \"Side-B Sweetspot\\n\",\n    .eventDescription = \"Use a sweetspot Side-B to avoid Marth's\\ndown-tilt and grab the ledge!\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &SideBSweet_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData EscapeSheik_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = 19,        // 0xFF=\n    .stage = 32,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc EscapeSheik = {\n    .eventName = \"Escape Sheik Techchase\\n\",\n    .eventDescription = \"Practice escaping the tech chase with a\\nframe perfect shine or jab SDI!\\n\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = false,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &EscapeSheik_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData Eggs_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = -1,        // 0xFF=\n    .stage = -1,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc Eggs = {\n    .eventName = \"Eggs-ercise\\n\",\n    .eventDescription = \"Break the eggs! Only strong hits will\\nbreak them. DPad down = free practice.\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = true,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &Eggs_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData Multishine_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = -1,        // 0xFF=\n    .stage = 32,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc Multishine = {\n    .eventName = \"Shined Blind\\n\",\n    .eventDescription = \"How many shines can you\\nperform in 10 seconds?\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = false,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &Multishine_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData Reaction_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = 2,         // 0xFF=\n    .stage = 32,          // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc Reaction = {\n    .eventName = \"Reaction Test\\n\",\n    .eventDescription = \"Test your reaction time by pressing\\nany button when you see/hear Fox shine!\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = false,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &Reaction_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n// L-Cancel Training\n// Match Data\nstatic EventMatchData Ledgestall_MatchData = {\n    .timer = MATCH_TIMER_COUNTUP,\n    .matchType = MATCH_MATCHTYPE_TIME,\n    .isDisableMusic = true,\n    .hideGo = true,\n    .hideReady = true,\n    .isCreateHUD = true,\n    .isDisablePause = false,\n    // byte 0x3\n    .timerRunOnPause = false,   // 0x01\n    .isHidePauseHUD = true,     // 0x02\n    .isShowLRAStart = true,     // 0x04\n    .isCheckForLRAStart = true, // 0x08\n    .isShowZRetry = true,       // 0x10\n    .isCheckForZRetry = true,   // 0x20\n    .isShowAnalogStick = true,  // 0x40\n    .isShowScore = false,       // 0x80\n\n    .isRunStockLogic = false, // 0x20\n    .isDisableHit = false,    // 0x20\n    .useKOCounter = false,\n    .playerKind = -1,\n    .cpuKind = -1,        // 0xFF=\n    .stage = 6,           // 0xFFFF\n    .timerSeconds = 0,    // 0xFFFFFFFF\n    .timerSubSeconds = 0, // 0xFF\n    .onCheckPause = 0,\n    .onMatchEnd = 0,\n};\n// Event Struct\nstatic EventDesc Ledgestall = {\n    .eventName = \"Under Fire\\n\",\n    .eventDescription = \"Ledgestall to remain\\ninvincible while the lava rises!\\n\",\n    .eventTutorial = \"TvLC\",\n    .eventFile = 0,\n    .isChooseCPU = false,\n    .isSelectStage = false,\n    .use_savestates = false,\n    .disable_hazards = true,\n    .scoreType = 0,\n    .callbackPriority = 3,\n    .matchData = &Ledgestall_MatchData,\n    .defaultOSD = 0xFFFFFFFF,\n};\n\n///////////////////////\n/// Page Defintions ///\n///////////////////////\n\n// Minigames\nstatic EventDesc *Minigames_Events[] = {\n    &Eggs,\n    &Multishine,\n    &Reaction,\n    &Ledgestall,\n};\nstatic EventPage Minigames_Page = {\n    .name = \"Minigames\",\n    .eventNum = (sizeof(Minigames_Events) / 4) - 1,\n    .events = Minigames_Events,\n};\n\n// Page 2 Events\nstatic EventDesc *General_Events[] = {\n    &Lab,\n    &LCancel,\n    &Ledgedash,\n    &Wavedash,\n    &Combo,\n    &AttackOnShield,\n    &Reversal,\n    &SDI,\n    &Powershield,\n    &Ledgetech,\n    &AmsahTech,\n    &ShieldDrop,\n    &WaveshineSDI,\n    &SlideOff,\n    &GrabMash,\n};\nstatic EventPage General_Page = {\n    .name = \"General Tech\",\n    (sizeof(General_Events) / 4) - 1,\n    General_Events,\n};\n\n// Page 3 Events\nstatic EventDesc *Spacie_Events[] = {\n    &TechCounter,\n    &ArmadaShine,\n    &SideBSweet,\n    &EscapeSheik,\n};\nstatic EventPage Spacie_Page = {\n    .name = \"Spacie Tech\",\n    (sizeof(Spacie_Events) / 4) - 1,\n    Spacie_Events,\n};\n\n//////////////////\n/// Page Order ///\n//////////////////\n\nstatic EventPage **EventPages[] = {\n    &Minigames_Page,\n    &General_Page,\n    &Spacie_Page,\n};\n\n////////////////////////\n/// Static Variables ///\n////////////////////////\n\nstatic EventVars stc_event_vars = {\n    .event_desc = 0,\n    .menu_assets = 0,\n    .event_gobj = 0,\n    .menu_gobj = 0,\n    .game_timer = 0,\n    .hide_menu = 0,\n    .Savestate_Save = Savestate_Save,\n    .Savestate_Load = Savestate_Load,\n    .Message_Display = Message_Display,\n    .Tip_Display = Tip_Display,\n    .Tip_Destroy = Tip_Destroy,\n    .savestate = 0,\n};\nstatic Savestate *stc_savestate;\nstatic EventDesc *static_eventInfo;\nstatic MenuData *static_menuData;\nstatic int show_console = 1;\nstatic int *eventDataBackup;\nstatic TipMgr stc_tipmgr;\n\n///////////////////////\n/// Event Functions ///\n///////////////////////\n\nvoid EventInit(int page, int eventID, MatchInit *matchData)\n{\n\n    /* \n    This function runs when leaving the main menu/css and handles\n    setting up the match information, such as rules, players, stage.\n    All of this data comes from the EventDesc in events.c\n    */\n\n    // get event pointer\n    EventDesc *event = GetEventDesc(page, eventID);\n\n    //Init default match info\n    matchData->timer_unk2 = 0;\n    matchData->unk2 = 1;\n    matchData->unk7 = 1;\n    matchData->isCheckStockSteal = 1;\n    matchData->unk10 = 3;\n    matchData->isSkipEndCheck = 1;\n    matchData->itemFreq = MATCH_ITEMFREQ_OFF;\n    matchData->onStartMelee = EventLoad;\n\n    //Copy event's match info struct\n    EventMatchData *eventMatchData = event->matchData;\n    matchData->timer = eventMatchData->timer;\n    matchData->matchType = eventMatchData->matchType;\n    matchData->isDisableMusic = eventMatchData->isDisableMusic;\n    matchData->hideGo = eventMatchData->hideGo;\n    matchData->hideReady = eventMatchData->hideReady;\n    matchData->isCreateHUD = eventMatchData->isCreateHUD;\n    matchData->isDisablePause = eventMatchData->isDisablePause;\n    matchData->timerRunOnPause = eventMatchData->timerRunOnPause;\n    matchData->isHidePauseHUD = eventMatchData->isHidePauseHUD;\n    matchData->isShowLRAStart = eventMatchData->isShowLRAStart;\n    matchData->isCheckForLRAStart = eventMatchData->isCheckForLRAStart;\n    matchData->isShowZRetry = eventMatchData->isShowZRetry;\n    matchData->isCheckForZRetry = eventMatchData->isCheckForZRetry;\n    matchData->isShowAnalogStick = eventMatchData->isShowAnalogStick;\n    matchData->isShowScore = eventMatchData->isShowScore;\n    matchData->isRunStockLogic = eventMatchData->isRunStockLogic;\n    matchData->isDisableHit = eventMatchData->isDisableHit;\n    matchData->timerSeconds = eventMatchData->timerSeconds;\n    matchData->timerSubSeconds = eventMatchData->timerSubSeconds;\n    matchData->onCheckPause = eventMatchData->onCheckPause;\n    matchData->onMatchEnd = eventMatchData->onMatchEnd;\n\n    // Initialize all player data\n    Memcard *memcard = R13_PTR(MEMCARD);\n    CSSBackup eventBackup = memcard->EventBackup;\n    for (int i = 0; i < 6; i++)\n    {\n        // initialize data\n        CSS_InitPlayerData(&matchData->playerData[i]);\n\n        // set to enter fall on match start\n        matchData->playerData[i].isEntry = false;\n\n        // copy nametag id for the player\n        if (i == 0)\n        {\n            // Update the player's nametag ID\n            matchData->playerData[i].nametag = eventBackup.nametag;\n\n            // Update the player's rumble setting\n            int tagRumble = CSS_GetNametagRumble(0, matchData->playerData[0].nametag);\n            matchData->playerData[0].isRumble = tagRumble;\n        }\n    }\n\n    // Determine player ports\n    u8 hmn_port = *stc_css_hmnport + 1;\n    u8 cpu_port = *stc_css_cpuport + 1;\n\n    // Determine the Player\n    s32 playerKind;\n    s32 playerCostume;\n    Preload *preload = Preload_GetTable();\n    // If fighter is -1, copy the player from event data\n    if (eventMatchData->playerKind != -1)\n    {\n        playerKind = eventMatchData->playerKind;\n        playerCostume = 0;\n    }\n    // use the fighter chosen on the CSS\n    else\n    {\n        playerKind = preload->fighters[0].kind;\n        playerCostume = preload->fighters[0].costume;\n    }\n\n    // Determine the CPU\n    s32 cpuKind;\n    s32 cpuCostume;\n    // If isChooseCPU is true, use the selected CPU\n    if (event->isChooseCPU == true)\n    {\n        cpuKind = preload->fighters[1].kind;\n        cpuCostume = preload->fighters[1].costume;\n\n        // change zelda to sheik\n        if (cpuKind == 18)\n        {\n            cpuKind = 19;\n            preload->fighters[1].kind = cpuKind;\n        }\n    }\n    // If isChooseCPU is false, copy the CPU from event data\n    else\n    {\n        cpuKind = eventMatchData->cpuKind;\n        cpuCostume = 0;\n        cpuCostume = 0;\n    }\n\n    // Check if CPU is using the same character and color as P1\n    if ((playerKind == cpuKind) && (playerCostume == cpuCostume))\n    {\n        // this doesnt account for if theyre both using the last costume\n        cpuCostume += 1;\n    }\n\n    // Copy player data to match info struct (update their rumble setting 801bb1ec)\n    matchData->playerData[0].kind = playerKind;\n    matchData->playerData[0].costume = playerCostume;\n    matchData->playerData[0].status = 0;\n    matchData->playerData[0].portNumberOverride = hmn_port;\n\n    // Copy CPU if they exist for this event\n    if (cpuKind != -1)\n    {\n        matchData->playerData[1].kind = cpuKind;\n        matchData->playerData[1].costume = cpuCostume;\n        matchData->playerData[1].status = 1;\n        matchData->playerData[1].portNumberOverride = cpu_port;\n    }\n\n    // Determine the correct HUD position for this amount of players\n    int hudPos = 0;\n    for (int i = 0; i < 6; i++)\n    {\n        if (matchData->playerData[i].status != 3)\n            hudPos++;\n    }\n    matchData->hudPos = hudPos;\n\n    // Determine the Stage\n    int stage;\n    // If isSelectStage is true, use the selected stage\n    if (event->isSelectStage == true)\n    {\n        stage = preload->stage;\n    }\n    // If isSelectStage is false, copy the stage from event data\n    else\n    {\n        stage = eventMatchData->stage;\n    }\n    // Update match struct with this stage\n    matchData->stage = stage;\n\n    //Update preload table? (801bb63c)\n\n    return;\n};\n\nvoid EventLoad()\n{\n    // get this event\n    Memcard *memcard = R13_PTR(MEMCARD);\n    int page = memcard->TM_EventPage;\n    int eventID = memcard->EventBackup.event;\n    EventDesc *event_desc = GetEventDesc(page, eventID);\n    evFunction *evFunction = &stc_event_vars.evFunction;\n\n    // clear evFunction\n    memset(evFunction, 0, sizeof(*evFunction));\n\n    // append extension\n    static char *extension = \"TM/%s.dat\";\n    char *buffer[20];\n    sprintf(buffer, extension, event_desc->eventFile);\n\n    // load this events file\n    ArchiveInfo *archive = MEX_LoadRelArchive(buffer, evFunction, \"evFunction\");\n    stc_event_vars.event_archive = archive;\n\n    // Create this event's gobj\n    int pri = event_desc->callbackPriority;\n    void *cb = evFunction->Event_Think;\n    GOBJ *gobj = GObj_Create(0, 7, 0);\n    int *userdata = calloc(EVENT_DATASIZE);\n    GObj_AddUserData(gobj, 4, HSD_Free, userdata);\n    GObj_AddProc(gobj, cb, pri);\n\n    // store pointer to the event's data\n    userdata[0] = event_desc;\n\n    // Create a gobj to track match time\n    stc_event_vars.game_timer = 0;\n    GOBJ *timer_gobj = GObj_Create(0, 7, 0);\n    GObj_AddProc(timer_gobj, Event_IncTimer, 0);\n\n    // init the pause menu\n    GOBJ *menu_gobj = EventMenu_Init(event_desc, *evFunction->menu_start);\n\n    // Init static structure containing event variables\n    stc_event_vars.event_desc = event_desc;\n    stc_event_vars.event_gobj = gobj;\n    stc_event_vars.menu_gobj = menu_gobj;\n\n    // init savestate struct\n    stc_savestate = calloc(sizeof(Savestate));\n    eventDataBackup = calloc(EVENT_DATASIZE);\n    stc_savestate->is_exist = 0;\n    stc_event_vars.savestate = stc_savestate;\n\n    // disable hazards if enabled\n    if (event_desc->disable_hazards == 1)\n        Hazards_Disable();\n\n    // Run this event's init function\n    if (evFunction->Event_Init != 0)\n    {\n        evFunction->Event_Init(gobj);\n    }\n\n    // Store update function\n    HSD_Update *update = HSD_UPDATE;\n    update->onFrame = EventUpdate;\n\n    return;\n};\n\nvoid EventUpdate()\n{\n\n    // get event info\n    EventDesc *event_desc = stc_event_vars.event_desc;\n    evFunction *evFunction = &stc_event_vars.evFunction;\n    GOBJ *menu_gobj = stc_event_vars.menu_gobj;\n\n    // run savestate logic if enabled\n    if (event_desc->use_savestates == true)\n    {\n        Update_Savestates();\n    }\n\n    // run menu logic if exists\n    if (menu_gobj != 0)\n    {\n        // update menu\n        EventMenu_Update(menu_gobj);\n    }\n\n    // run custom event update function\n    if (evFunction->Event_Update != 0)\n    {\n        evFunction->Event_Update();\n    }\n    else\n        Develop_UpdateMatchHotkeys();\n\n    return;\n}\n\n//////////////////////\n/// Hook Functions ///\n//////////////////////\n\nvoid TM_ConsoleThink(GOBJ *gobj)\n{\n    // init variables\n    int *data = gobj->userdata;\n    DevText *text = data[0];\n\n    // check to toggle console\n    for (int i = 0; i < 4; i++)\n    {\n        HSD_Pad *pad = PadGet(i, PADGET_MASTER);\n        if (pad->held & (HSD_TRIGGER_L | HSD_TRIGGER_R) && (pad->down & HSD_TRIGGER_Z))\n        {\n            // toggle visibility\n            text->show_text ^= 1;\n            text->show_background ^= 1;\n            show_console ^= 1;\n\n            break;\n        }\n    }\n\n    // clear text\n    //DevelopText_EraseAllText(text);\n    //DevelopMode_ResetCursorXY(text, 0, 0);\n}\nvoid TM_CreateConsole()\n{\n    // init dev text\n    GOBJ *gobj = GObj_Create(0, 0, 0);\n    int *data = calloc(32);\n    GObj_AddUserData(gobj, 4, HSD_Free, data);\n    GObj_AddProc(gobj, TM_ConsoleThink, 0);\n\n    DevText *text = DevelopText_CreateDataTable(13, 0, 0, 28, 8, HSD_MemAlloc(0x1000));\n    DevelopText_Activate(0, text);\n    text->show_cursor = 0;\n    data[0] = text;\n    GXColor color = {21, 20, 59, 135};\n    DevelopText_StoreBGColor(text, &color);\n    DevelopText_StoreTextScale(text, 10, 12);\n    stc_event_vars.db_console_text = text;\n\n    if (show_console != 1)\n    {\n        // toggle visibility\n        DevelopText_HideBG(text);\n        DevelopText_HideText(text);\n    }\n\n    return;\n}\n\nvoid OnFileLoad(ArchiveInfo *archive) // this function is run right after TmDt is loaded into memory on boot\n{\n    // init event menu assets\n    stc_event_vars.menu_assets = File_GetSymbol(archive, \"evMenu\");\n\n    // store pointer to static variables\n    *event_vars_ptr = &stc_event_vars;\n    event_vars = *event_vars_ptr;\n\n    return;\n}\n\nvoid OnSceneChange()\n{\n    // Hook exists at 801a4c94\n\n    TM_CreateWatermark();\n\n#if TM_DEBUG == 2\n    TM_CreateConsole();\n#endif\n\n    return;\n};\n\nvoid OnBoot()\n{\n    // OSReport(\"hi this is boot\\n\");\n    return;\n};\n\nvoid OnStartMelee()\n{\n\n    Message_Init();\n    Tip_Init();\n\n    return;\n}\n\n///////////////////////////////\n/// Miscellaneous Functions ///\n///////////////////////////////\n\nint Savestate_Save(Savestate *savestate)\n{\n    typedef struct BackupQueue\n    {\n        GOBJ *fighter;\n        FighterData *fighter_data;\n    } BackupQueue;\n\n#if TM_DEBUG > 0\n    int save_pre_tick = OSGetTick();\n#endif\n\n    // ensure no players are in problematic states\n    int canSave = 1;\n    GOBJ **gobj_list = R13_PTR(GOBJLIST);\n    GOBJ *fighter = gobj_list[8];\n    while (fighter != 0)\n    {\n\n        FighterData *fighter_data = fighter->userdata;\n\n        if ((fighter_data->cb.OnDeath != 0) ||\n            (fighter_data->cb.OnDeath2 != 0) ||\n            (fighter_data->cb.OnDeath3 != 0) ||\n            (fighter_data->heldItem != 0) ||\n            (fighter_data->x1978 != 0) ||\n            (fighter_data->accessory != 0) ||\n            ((fighter_data->kind == 8) && ((fighter_data->state >= 342) && (fighter_data->state <= 344)))) // hardcode ness' usmash because it doesnt destroy the yoyo via onhit callback...\n        {\n            // cannot save\n            canSave = 0;\n            break;\n        }\n\n        fighter = fighter->next;\n    }\n\n    // loop through all players\n    int isSaved = 0;\n    if (canSave == 1)\n    {\n\n        savestate->is_exist = 1;\n\n        // save frame\n        savestate->frame = stc_event_vars.game_timer;\n\n        // save event data\n        memcpy(&savestate->event_data, stc_event_vars.event_gobj->userdata, sizeof(savestate->event_data));\n\n        // backup all players\n        for (int i = 0; i < 6; i++)\n        {\n            // get fighter gobjs\n            BackupQueue queue[2];\n            for (int j = 0; j < 2; j++)\n            {\n                GOBJ *fighter = 0;\n                FighterData *fighter_data = 0;\n\n                // get fighter gobj and data if they exist\n                fighter = Fighter_GetSubcharGObj(i, j);\n                if (fighter != 0)\n                    fighter_data = fighter->userdata;\n\n                // store fighter pointers\n                queue[j].fighter = fighter;\n                queue[j].fighter_data = fighter_data;\n            }\n\n            // if the main fighter exists\n            if (queue[0].fighter != 0)\n            {\n\n                FtState *ft_state = &savestate->ft_state[i];\n\n                isSaved = 1;\n\n                // save playerblock\n                Playerblock *playerblock = Fighter_GetPlayerblock(queue[0].fighter_data->ply);\n                memcpy(&ft_state->player_block, playerblock, sizeof(Playerblock));\n\n                // save stale moves\n                int *stale_queue = Fighter_GetStaleMoveTable(queue[0].fighter_data->ply);\n                memcpy(&ft_state->stale_queue, stale_queue, sizeof(ft_state->stale_queue));\n\n                // backup each subfighters data\n                for (int j = 0; j < 2; j++)\n                {\n                    // if exists\n                    if (queue[j].fighter != 0)\n                    {\n\n                        FtStateData *ft_data = &ft_state->data[j];\n                        FighterData *fighter_data = queue[j].fighter_data;\n\n                        // backup to ft_state\n                        ft_data->is_exist = 1;\n                        ft_data->state = fighter_data->state;\n                        ft_data->facing_direction = fighter_data->facing_direction;\n                        ft_data->stateFrame = fighter_data->stateFrame;\n                        ft_data->stateSpeed = fighter_data->stateSpeed;\n                        ft_data->stateBlend = fighter_data->stateBlend;\n                        memcpy(&ft_data->phys, &fighter_data->phys, sizeof(fighter_data->phys));                               // copy physics\n                        memcpy(&ft_data->color, &fighter_data->color, sizeof(fighter_data->color));                            // copy color overlay\n                        memcpy(&ft_data->input, &fighter_data->input, sizeof(fighter_data->input));                            // copy inputs\n                        memcpy(&ft_data->coll_data, &fighter_data->coll_data, sizeof(fighter_data->coll_data));                // copy collision\n                        memcpy(&ft_data->cameraBox, fighter_data->cameraBox, sizeof(CameraBox));                               // copy camerabox\n                        memcpy(&ft_data->hitbox, &fighter_data->hitbox, sizeof(fighter_data->hitbox));                         // copy hitbox\n                        memcpy(&ft_data->throw_hitbox, &fighter_data->throw_hitbox, sizeof(fighter_data->throw_hitbox));       // copy hitbox\n                        memcpy(&ft_data->unk_hitbox, &fighter_data->unk_hitbox, sizeof(fighter_data->unk_hitbox));             // copy hitbox\n                        memcpy(&ft_data->flags, &fighter_data->flags, sizeof(fighter_data->flags));                            // copy flags\n                        memcpy(&ft_data->fighter_var, &fighter_data->fighter_var, sizeof(fighter_data->fighter_var));          // copy var\n                        memcpy(&ft_data->state_var, &fighter_data->state_var, sizeof(fighter_data->state_var));                // copy var\n                        memcpy(&ft_data->ftcmd_var, &fighter_data->ftcmd_var, sizeof(fighter_data->ftcmd_var));                // copy var\n                        memcpy(&ft_data->jump, &fighter_data->jump, sizeof(fighter_data->jump));                               // copy var\n                        memcpy(&ft_data->smash, &fighter_data->smash, sizeof(fighter_data->smash));                            // copy var\n                        memcpy(&ft_data->hurtstatus, &fighter_data->hurtstatus, sizeof(fighter_data->hurtstatus));             // copy var\n                        memcpy(&ft_data->shield, &fighter_data->shield, sizeof(fighter_data->shield));                         // copy hitbox\n                        memcpy(&ft_data->shield_bubble, &fighter_data->shield_bubble, sizeof(fighter_data->shield_bubble));    // copy hitbox\n                        memcpy(&ft_data->reflect_bubble, &fighter_data->reflect_bubble, sizeof(fighter_data->reflect_bubble)); // copy hitbox\n                        memcpy(&ft_data->absorb_bubble, &fighter_data->absorb_bubble, sizeof(fighter_data->absorb_bubble));    // copy hitbox\n                        memcpy(&ft_data->reflect_hit, &fighter_data->reflect_hit, sizeof(fighter_data->reflect_hit));          // copy hitbox\n                        memcpy(&ft_data->absorb_hit, &fighter_data->absorb_hit, sizeof(fighter_data->absorb_hit));             // copy hitbox\n\n                        // copy dmg\n                        memcpy(&ft_data->dmg, &fighter_data->dmg, sizeof(fighter_data->dmg));\n                        ft_data->dmg.source = GOBJToID(ft_data->dmg.source);\n\n                        // copy grab\n                        memcpy(&ft_data->grab, &fighter_data->grab, sizeof(fighter_data->grab));\n                        ft_data->grab.grab_attacker = GOBJToID(ft_data->grab.grab_attacker);\n                        ft_data->grab.grab_victim = GOBJToID(ft_data->grab.grab_victim);\n\n                        // copy callbacks\n                        memcpy(&ft_data->cb, &fighter_data->cb, sizeof(fighter_data->cb)); // copy hitbox\n\n                        // convert hitbox pointers\n                        for (int k = 0; k < (sizeof(fighter_data->hitbox) / sizeof(ftHit)); k++)\n                        {\n\n                            ft_data->hitbox[k].bone = BoneToID(fighter_data, ft_data->hitbox[k].bone);\n                            for (int l = 0; l < (sizeof(fighter_data->hitbox->victims) / sizeof(HitVictim)); l++) // pointers to hitbox victims\n                            {\n                                ft_data->hitbox[k].victims[l].victim_data = FtDataToID(ft_data->hitbox[k].victims[l].victim_data);\n                            }\n                        }\n                        for (int k = 0; k < (sizeof(fighter_data->throw_hitbox) / sizeof(ftHit)); k++)\n                        {\n                            ft_data->throw_hitbox[k].bone = BoneToID(fighter_data, ft_data->throw_hitbox[k].bone);\n                            for (int l = 0; l < (sizeof(fighter_data->throw_hitbox->victims) / sizeof(HitVictim)); l++) // pointers to hitbox victims\n                            {\n                                ft_data->throw_hitbox[k].victims[l].victim_data = FtDataToID(ft_data->throw_hitbox[k].victims[l].victim_data);\n                            }\n                        }\n\n                        ft_data->unk_hitbox.bone = BoneToID(fighter_data, ft_data->unk_hitbox.bone);\n                        for (int k = 0; k < (sizeof(fighter_data->unk_hitbox.victims) / sizeof(HitVictim)); k++) // pointers to hitbox victims\n                        {\n\n                            ft_data->unk_hitbox.victims[k].victim_data = FtDataToID(ft_data->unk_hitbox.victims[k].victim_data);\n                        }\n\n                        // copy XRotN rotation\n                        s8 XRotN_id = Fighter_BoneLookup(fighter_data, XRotN);\n                        if (XRotN_id != -1)\n                        {\n                            ft_data->XRotN_rot = fighter_data->bones[XRotN_id].joint->rot;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Play SFX\n    if (isSaved == 0)\n    {\n        SFX_PlayCommon(3);\n    }\n    if (isSaved == 1)\n    {\n        // play sfx\n        SFX_PlayCommon(1);\n\n        // if not in frame advance, flash screen. I wrote it like this because the second condition kept getting optimized out\n        if ((Pause_CheckStatus(0) != 1))\n        {\n            if ((Pause_CheckStatus(1) != 2))\n            {\n                ScreenFlash_Create(2, 0);\n            }\n        }\n    }\n\n#if TM_DEBUG > 0\n    int save_post_tick = OSGetTick();\n    int save_time = OSTicksToMilliseconds(save_post_tick - save_pre_tick);\n    OSReport(\"processed save in %dms\\n\", save_time);\n#endif\n\n    return isSaved;\n}\nint Savestate_Load(Savestate *savestate)\n{\n    typedef struct BackupQueue\n    {\n        GOBJ *fighter;\n        FighterData *fighter_data;\n    } BackupQueue;\n\n#if TM_DEBUG > 0\n    int load_pre_tick = OSGetTick();\n#endif\n\n    // loop through all players\n    int isLoaded = 0;\n    for (int i = 0; i < 6; i++)\n    {\n        // get fighter gobjs\n        BackupQueue queue[2];\n        for (int j = 0; j < 2; j++)\n        {\n            GOBJ *fighter = 0;\n            FighterData *fighter_data = 0;\n\n            // get fighter gobj and data if they exist\n            fighter = Fighter_GetSubcharGObj(i, j);\n            if (fighter != 0)\n                fighter_data = fighter->userdata;\n\n            // store fighter pointers\n            queue[j].fighter = fighter;\n            queue[j].fighter_data = fighter_data;\n        }\n\n        // if the main fighter and backup exists\n        if ((queue[0].fighter != 0) && (savestate->ft_state[i].data[0].is_exist == 1))\n        {\n\n            FtState *ft_state = &savestate->ft_state[i];\n\n            isLoaded = 1;\n\n            // restore playerblock\n            Playerblock *playerblock = Fighter_GetPlayerblock(queue[0].fighter_data->ply);\n            GOBJ *fighter_gobj[2];\n            fighter_gobj[0] = playerblock->fighterData;\n            fighter_gobj[1] = playerblock->fighterDataSub;\n            memcpy(playerblock, &ft_state->player_block, sizeof(Playerblock));\n            playerblock->fighterData = fighter_gobj[0];\n            playerblock->fighterDataSub = fighter_gobj[1];\n\n            // restore stale moves\n            int *stale_queue = Fighter_GetStaleMoveTable(queue[0].fighter_data->ply);\n            memcpy(stale_queue, &ft_state->stale_queue, sizeof(ft_state->stale_queue));\n\n            // restore fighter data\n            for (int j = 0; j < 2; j++)\n            {\n\n                GOBJ *fighter = queue[j].fighter;\n\n                if (fighter != 0)\n                {\n\n                    // get state\n                    FtStateData *ft_data = &ft_state->data[j];\n                    FighterData *fighter_data = queue[j].fighter_data;\n\n                    // sleep\n                    Fighter_EnterSleep(fighter, 0);\n\n                    fighter_data->state = ft_data->state;\n                    fighter_data->facing_direction = ft_data->facing_direction;\n                    fighter_data->stateFrame = ft_data->stateFrame;\n                    fighter_data->stateSpeed = ft_data->stateSpeed;\n                    fighter_data->stateBlend = ft_data->stateBlend;\n\n                    // restore phys struct\n                    memcpy(&fighter_data->phys, &ft_data->phys, sizeof(fighter_data->phys)); // copy physics\n\n                    // restore inputs\n                    memcpy(&fighter_data->input, &ft_data->input, sizeof(fighter_data->input)); // copy inputs\n\n                    // restore coll data\n                    CollData *thiscoll = &fighter_data->coll_data;\n                    CollData *savedcoll = &ft_data->coll_data;\n                    GOBJ *gobj = thiscoll->gobj;                                                            // 0x0\n                    JOBJ *joint_1 = thiscoll->joint_1;                                                      // 0x108\n                    JOBJ *joint_2 = thiscoll->joint_2;                                                      // 0x10c\n                    JOBJ *joint_3 = thiscoll->joint_3;                                                      // 0x110\n                    JOBJ *joint_4 = thiscoll->joint_4;                                                      // 0x114\n                    JOBJ *joint_5 = thiscoll->joint_5;                                                      // 0x118\n                    JOBJ *joint_6 = thiscoll->joint_6;                                                      // 0x11c\n                    JOBJ *joint_7 = thiscoll->joint_7;                                                      // 0x120\n                    memcpy(&fighter_data->coll_data, &ft_data->coll_data, sizeof(fighter_data->coll_data)); // copy collision\n                    thiscoll->gobj = gobj;\n                    thiscoll->joint_1 = joint_1;\n                    thiscoll->joint_2 = joint_2;\n                    thiscoll->joint_3 = joint_3;\n                    thiscoll->joint_4 = joint_4;\n                    thiscoll->joint_5 = joint_5;\n                    thiscoll->joint_6 = joint_6;\n                    thiscoll->joint_7 = joint_7;\n\n                    // restore hitboxes\n                    memcpy(&fighter_data->hitbox, &ft_data->hitbox, sizeof(fighter_data->hitbox));                   // copy hitbox\n                    memcpy(&fighter_data->throw_hitbox, &ft_data->throw_hitbox, sizeof(fighter_data->throw_hitbox)); // copy hitbox\n                    memcpy(&fighter_data->unk_hitbox, &ft_data->unk_hitbox, sizeof(fighter_data->unk_hitbox));       // copy hitbox\n\n                    // copy grab\n                    memcpy(&fighter_data->grab, &ft_data->grab, sizeof(fighter_data->grab));\n                    fighter_data->grab.grab_attacker = IDToGOBJ(fighter_data->grab.grab_attacker);\n                    fighter_data->grab.grab_victim = IDToGOBJ(fighter_data->grab.grab_victim);\n\n                    // convert pointers\n                    for (int k = 0; k < (sizeof(fighter_data->hitbox) / sizeof(ftHit)); k++)\n                    {\n                        fighter_data->hitbox[k].bone = IDToBone(fighter_data, ft_data->hitbox[k].bone);\n                        for (int l = 0; l < (sizeof(fighter_data->hitbox->victims) / sizeof(HitVictim)); l++) // pointers to hitbox victims\n                        {\n                            fighter_data->hitbox[k].victims[l].victim_data = IDToFtData(ft_data->hitbox[k].victims[l].victim_data);\n                        }\n                    }\n                    for (int k = 0; k < (sizeof(fighter_data->throw_hitbox) / sizeof(ftHit)); k++)\n                    {\n                        fighter_data->throw_hitbox[k].bone = IDToBone(fighter_data, ft_data->throw_hitbox[k].bone);\n                        for (int l = 0; l < (sizeof(fighter_data->throw_hitbox->victims) / sizeof(HitVictim)); l++) // pointers to hitbox victims\n                        {\n                            fighter_data->throw_hitbox[k].victims[l].victim_data = IDToFtData(ft_data->throw_hitbox[k].victims[l].victim_data);\n                        }\n                    }\n                    fighter_data->unk_hitbox.bone = IDToBone(fighter_data, ft_data->unk_hitbox.bone);\n                    for (int k = 0; k < (sizeof(fighter_data->unk_hitbox.victims) / sizeof(HitVictim)); k++) // pointers to hitbox victims\n                    {\n\n                        fighter_data->unk_hitbox.victims[k].victim_data = IDToFtData(ft_data->unk_hitbox.victims[k].victim_data);\n                    }\n\n                    // restore fighter variables\n                    memcpy(&fighter_data->fighter_var, &ft_data->fighter_var, sizeof(fighter_data->fighter_var)); // copy hitbox\n\n                    // zero pointer to cached animations to force anim load (fixes fall crash)\n                    fighter_data->anim_curr_ARAM = 0;\n                    fighter_data->anim_persist_ARAM = 0;\n\n                    // enter backed up state\n                    GOBJ *anim_source = 0;\n                    if (fighter_data->flags.is_thrown == 1)\n                        anim_source = fighter_data->grab.grab_attacker;\n                    Fighter_SetAllHurtboxesNotUpdated(fighter);\n                    ActionStateChange(ft_data->stateFrame, ft_data->stateSpeed, -1, fighter, ft_data->state, 0, anim_source);\n                    fighter_data->stateBlend = 0;\n\n                    // restore XRotN rotation\n                    s8 XRotN_id = Fighter_BoneLookup(fighter_data, XRotN);\n                    if (XRotN_id != -1)\n                    {\n                        fighter_data->bones[XRotN_id].joint->rot = ft_data->XRotN_rot;\n                    }\n\n                    // restore state variables\n                    memcpy(&fighter_data->state_var, &ft_data->state_var, sizeof(fighter_data->state_var)); // copy hitbox\n\n                    // restore ftcmd variables\n                    memcpy(&fighter_data->ftcmd_var, &ft_data->ftcmd_var, sizeof(fighter_data->ftcmd_var)); // copy hitbox\n\n                    // restore damage variables\n                    memcpy(&fighter_data->dmg, &ft_data->dmg, sizeof(fighter_data->dmg)); // copy hitbox\n                    fighter_data->dmg.source = IDToGOBJ(fighter_data->dmg.source);\n\n                    // restore jump variables\n                    memcpy(&fighter_data->jump, &ft_data->jump, sizeof(fighter_data->jump)); // copy hitbox\n\n                    // restore flags\n                    memcpy(&fighter_data->flags, &ft_data->flags, sizeof(fighter_data->flags)); // copy hitbox\n\n                    // restore hurtstatus variables\n                    memcpy(&fighter_data->hurtstatus, &ft_data->hurtstatus, sizeof(fighter_data->hurtstatus)); // copy hitbox\n\n                    // update jobj position\n                    JOBJ *fighter_jobj = fighter->hsd_object;\n                    fighter_jobj->trans = fighter_data->phys.pos;\n                    // dirtysub their jobj\n                    JOBJ_SetMtxDirtySub(fighter_jobj);\n\n                    // update hurtbox position\n                    Fighter_UpdateHurtboxes(fighter_data);\n\n                    // remove color overlay\n                    Fighter_ColorRemove(fighter_data, 9);\n\n                    // restore color\n                    for (int k = 0; k < (sizeof(fighter_data->color) / sizeof(ColorOverlay)); k++)\n                    {\n\n                        ColorOverlay *thiscolor = &fighter_data->color[k];\n                        ColorOverlay *savedcolor = &ft_data->color[k];\n\n                        // backup nono pointers\n                        int *ptr1 = thiscolor->ptr1;\n                        int *ptr2 = thiscolor->ptr2;\n                        int *alloc = thiscolor->alloc;\n\n                        // mempcy entire\n                        memcpy(thiscolor, savedcolor, sizeof(ColorOverlay));\n\n                        // restore nono pointers\n                        thiscolor->ptr1 = ptr1;\n                        thiscolor->ptr2 = ptr2;\n                        thiscolor->alloc = alloc;\n                    }\n\n                    // restore smash variables\n                    memcpy(&fighter_data->smash, &ft_data->smash, sizeof(fighter_data->smash)); // copy hitbox\n\n                    // restore shield/reflect/absorb variables\n                    memcpy(&fighter_data->shield, &ft_data->shield, sizeof(fighter_data->shield));                         // copy hitbox\n                    memcpy(&fighter_data->shield_bubble, &ft_data->shield_bubble, sizeof(fighter_data->shield_bubble));    // copy hitbox\n                    memcpy(&fighter_data->reflect_bubble, &ft_data->reflect_bubble, sizeof(fighter_data->reflect_bubble)); // copy hitbox\n                    memcpy(&fighter_data->absorb_bubble, &ft_data->absorb_bubble, sizeof(fighter_data->absorb_bubble));    // copy hitbox\n                    memcpy(&fighter_data->reflect_hit, &ft_data->reflect_hit, sizeof(fighter_data->reflect_hit));          // copy hitbox\n                    memcpy(&fighter_data->absorb_hit, &ft_data->absorb_hit, sizeof(fighter_data->absorb_hit));             // copy hitbox\n\n                    // restore callback functions\n                    memcpy(&fighter_data->cb, &ft_data->cb, sizeof(fighter_data->cb)); // copy hitbox\n\n                    // stop player SFX\n                    SFX_StopAllFighterSFX(fighter_data);\n\n                    // update colltest frame\n                    fighter_data->coll_data.coll_test = *stc_colltest;\n\n                    // restore camera box\n                    CameraBox *thiscam = fighter_data->cameraBox;\n                    CameraBox *savedcam = &ft_data->cameraBox;\n                    void *alloc = thiscam->alloc;\n                    CameraBox *next = thiscam->next;\n                    memcpy(thiscam, savedcam, sizeof(CameraBox)); // copy camerabox\n                    thiscam->alloc = alloc;\n                    thiscam->next = next;\n\n                    // update their IK\n                    Fighter_UpdateIK(fighter);\n\n                    // if shield is up, update shield\n                    if ((fighter_data->state >= ASID_GUARDON) && (fighter_data->state <= ASID_GUARDREFLECT))\n                    {\n                        // get gfx ID\n                        int shieldGFX;\n                        static u16 ShieldGFXLookup[] = {1047, 1048, -1, 1049, -1}; // covers GUARDON -> GUARDREFLECT\n                        shieldGFX = ShieldGFXLookup[fighter_data->state - ASID_GUARDON];\n\n                        // create GFX\n                        int color_index = Fighter_GetShieldColorIndex(fighter_data->ply);\n                        GXColor *shieldColors = R13_PTR(-0x5194);\n                        GXColor *shieldColor = &shieldColors[color_index];\n                        JOBJ *shieldBone = fighter_data->bones[fighter_data->ftData->modelLookup[0x11]].joint;\n                        int shieldColorParam = (shieldColor->r << 16) | (shieldColor->b << 8) | (shieldColor->g);\n                        Effect_SpawnSync(shieldGFX, fighter, shieldBone, shieldColorParam);\n\n                        Fighter_UpdateShieldGFX(fighter, 1);\n                    }\n\n                    // process dynamics\n\n#if TM_DEBUG > 0\n                    int dyn_pre_tick = OSGetTick();\n#endif\n                    int dyn_proc_num = 45;\n\n                    // simulate dynamics a bunch to fall in place\n                    for (int d = 0; d < dyn_proc_num; d++)\n                    {\n                        Fighter_ProcDynamics(fighter);\n                    }\n\n#if TM_DEBUG > 0\n                    int dyn_post_tick = OSGetTick();\n                    int dyn_time = OSTicksToMilliseconds(dyn_post_tick - dyn_pre_tick);\n                    OSReport(\"processed dyn %d times in %dms\\n\", dyn_proc_num, dyn_time);\n#endif\n\n                    // remove all items belonging to this fighter\n                    GOBJList *gobj_list = *stc_gobj_list;\n                    GOBJ *item = gobj_list->item;\n                    while (item != 0)\n                    {\n\n                        // get next\n                        GOBJ *next_item = item->next;\n\n                        // check to delete\n                        ItemData *item_data = item->userdata;\n                        if (fighter == item_data->fighter)\n                        {\n                            // destroy it\n                            Item_Destroy(item);\n                        }\n\n                        item = next_item;\n                    }\n                }\n            }\n\n            sizeof(FtStateData);\n\n            // check to recreate HUD\n            MatchHUD *hud = &stc_matchhud[i];\n\n            // check if fighter is perm dead\n            if (Match_CheckIfStock() == 1)\n            {\n                // remove HUD if no stocks left\n                if (Fighter_GetStocks(i) <= 0)\n                {\n                    hud->is_removed = 0;\n                }\n            }\n\n            // check to create it\n            if (hud->is_removed == 1)\n            {\n                Match_CreateHUD(i);\n            }\n\n            // snap camera to the new positions\n            Match_CorrectCamera();\n\n            // stop crowd cheer\n            SFX_StopCrowd();\n        }\n    }\n\n    // Restore event data and Play SFX\n    if (isLoaded == 0)\n    {\n        SFX_PlayCommon(3);\n    }\n    if (isLoaded == 1)\n    {\n\n        // restore frame\n        Match *match = stc_match;\n        match->time_frames = savestate->frame;\n        stc_event_vars.game_timer = savestate->frame;\n\n        // update timer\n        int frames = match->time_frames - 1; // this is because the scenethink function runs once before the gobj procs do\n        match->time_seconds = frames / 60;\n        match->time_ms = frames % 60;\n\n        // restore event data\n        memcpy(stc_event_vars.event_gobj->userdata, &savestate->event_data, sizeof(savestate->event_data));\n\n        // remove all particles\n        for (int i = 0; i < PTCL_LINKMAX; i++)\n        {\n            Particle2 **ptcls = &stc_ptcl[i];\n            Particle2 *ptcl = *ptcls;\n            while (ptcl != 0)\n            {\n\n                Particle2 *ptcl_next = ptcl->next;\n\n                // begin destroying this particle\n\n                // subtract some value, 8039c9f0\n                if (ptcl->x88 != 0)\n                {\n                    int *arr = ptcl->x88;\n                    arr[0x50 / 4]--;\n                }\n                // remove from generator? 8039ca14\n                if (ptcl->gen != 0)\n                    psRemoveParticleAppSRT(ptcl);\n\n                // delete parent jobj, 8039ca48\n                psDeletePntJObjwithParticle(ptcl);\n\n                // update most recent ptcl pointer\n                *ptcls = ptcl->next;\n\n                // free alloc, 8039ca54\n                HSD_ObjFree(0x804d0f60, ptcl);\n\n                // decrement ptcl total\n                u16 ptclnum = *stc_ptclnum;\n                ptclnum--;\n                *stc_ptclnum = ptclnum;\n\n                // get next\n                ptcl = ptcl_next;\n            }\n        }\n\n        /*\n    // remove all generators with linkNo 2 (blastzone)\n    ptclGen *gen = *stc_ptclgen;\n    while (gen != 0)\n    {\n        // get next\n        ptclGen *gen_next = gen->next;\n\n        // if linkNo 2, destroy it\n        if (gen->link_no == 2)\n        {\n            // set a flag for some reason\n            gen->type |= 0x80;\n\n            // kill gen\n            gen = psKillGenerator(gen, *stc_ptclgencurr);\n        }\n\n        // save last\n        *stc_ptclgencurr = gen;\n        // get next\n        gen = gen_next;\n    }\n*/\n\n        // remove all camera shake gobjs (p_link 18, entity_class 3)\n        GOBJList *gobj_list = *stc_gobj_list;\n        GOBJ *gobj = gobj_list->match_cam;\n        while (gobj != 0)\n        {\n\n            GOBJ *gobj_next = gobj->next;\n\n            // if entity class 3 (quake)\n            if (gobj->entity_class == 3)\n            {\n                GObj_Destroy(gobj);\n            }\n\n            gobj = gobj_next;\n        }\n\n        // play sfx\n        SFX_PlayCommon(0);\n    }\n\n#if TM_DEBUG > 0\n    int load_post_tick = OSGetTick();\n    int load_time = OSTicksToMilliseconds(load_post_tick - load_pre_tick);\n    OSReport(\"processed load in %dms\\n\", load_time);\n    sizeof(FtState);\n#endif\n\n    return isLoaded;\n}\nvoid Update_Savestates()\n{\n\n    // not when pause menu is showing\n    if (Pause_CheckStatus(1) != 2)\n    {\n        // loop through all humans\n        for (int i = 0; i < 6; i++)\n        {\n            // check if fighter exists\n            GOBJ *fighter = Fighter_GetGObj(i);\n            if (fighter != 0)\n            {\n                // get fighter data\n                FighterData *fighter_data = fighter->userdata;\n                HSD_Pad *pad = PadGet(fighter_data->ply, PADGET_MASTER);\n\n                // check for savestate\n                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);\n                if (((pad->down & HSD_BUTTON_DPAD_RIGHT) != 0) && ((pad->held & (blacklist)) == 0))\n                {\n                    // save state\n                    Savestate_Save(stc_savestate);\n                }\n                else if (((pad->down & HSD_BUTTON_DPAD_LEFT) != 0) && ((pad->held & (blacklist)) == 0))\n                {\n                    // load state\n                    Savestate_Load(stc_savestate);\n                }\n            }\n        }\n    }\n\n    return;\n}\nint GOBJToID(GOBJ *gobj)\n{\n    // ensure valid pointer\n    if (gobj == 0)\n        return -1;\n\n    // ensure its a fighter\n    if (gobj->entity_class != 4)\n        return -1;\n\n    // access the data\n    FighterData *ft_data = gobj->userdata;\n    u8 ply = ft_data->ply;\n    u8 ms = ft_data->flags.ms;\n\n    return ((ply << 4) | ms);\n}\nint FtDataToID(FighterData *fighter_data)\n{\n    // ensure valid pointer\n    if (fighter_data == 0)\n        return -1;\n\n    // ensure its a fighter\n    if (fighter_data->fighter == 0)\n        return -1;\n\n    // get ply and ms\n    u8 ply = fighter_data->ply;\n    u8 ms = fighter_data->flags.ms;\n\n    return ((ply << 4) | ms);\n}\nint BoneToID(FighterData *fighter_data, JOBJ *bone)\n{\n\n    // ensure bone exists\n    if (bone == 0)\n        return -1;\n\n    int bone_id = -1;\n\n    // painstakingly look for a match\n    for (int i = 0; i < fighter_data->bone_num; i++)\n    {\n        if (bone == fighter_data->bones[i].joint)\n        {\n            bone_id = i;\n            break;\n        }\n    }\n\n#if TM_DEBUG > 0\n    // no bone found\n    if (bone_id == -1)\n    {\n        assert(\"no bone found\");\n    }\n#endif\n\n    return bone_id;\n}\nGOBJ *IDToGOBJ(int id)\n{\n    // ensure valid pointer\n    if (id == -1)\n        return 0;\n\n    // get ply and ms\n    u8 ply = (id >> 4) & 0xF;\n    u8 ms = id & 0xF;\n\n    // get the gobj for this fighter\n    GOBJ *gobj = Fighter_GetSubcharGObj(ply, ms);\n\n    return gobj;\n}\nFighterData *IDToFtData(int id)\n{\n    // ensure valid pointer\n    if (id == -1)\n        return 0;\n\n    // get ply and ms\n    u8 ply = (id >> 4) & 0xF;\n    u8 ms = id & 0xF;\n\n    // get the gobj for this fighter\n    GOBJ *gobj = Fighter_GetSubcharGObj(ply, ms);\n    FighterData *fighter_data = gobj->userdata;\n\n    return fighter_data;\n}\nJOBJ *IDToBone(FighterData *fighter_data, int id)\n{\n    // ensure valid pointer\n    if (id == -1)\n        return 0;\n\n    // get the bone\n    JOBJ *bone = fighter_data->bones[id].joint;\n\n    return bone;\n}\n\nvoid Event_IncTimer(GOBJ *gobj)\n{\n    stc_event_vars.game_timer++;\n    return;\n}\nvoid TM_CreateWatermark()\n{\n    // create text canvas\n    int canvas = Text_CreateCanvas(10, 0, 9, 13, 0, 14, 0, 19);\n\n    // create text\n    Text *text = Text_CreateText(10, canvas);\n    // enable align and kerning\n    text->align = 2;\n    text->kerning = 1;\n    // scale canvas\n    text->scale.X = 0.4;\n    text->scale.Y = 0.4;\n    text->trans.X = 615;\n    text->trans.Y = 446;\n\n    // print string\n    int shadow = Text_AddSubtext(text, 2, 2, TM_VersShort);\n    GXColor shadow_color = {0, 0, 0, 0};\n    Text_SetColor(text, shadow, &shadow_color);\n\n    int shadow1 = Text_AddSubtext(text, 2, -2, TM_VersShort);\n    Text_SetColor(text, shadow1, &shadow_color);\n\n    int shadow2 = Text_AddSubtext(text, -2, 2, TM_VersShort);\n    Text_SetColor(text, shadow2, &shadow_color);\n\n    int shadow3 = Text_AddSubtext(text, -2, -2, TM_VersShort);\n    Text_SetColor(text, shadow3, &shadow_color);\n\n    Text_AddSubtext(text, 0, 0, TM_VersShort);\n\n    return;\n}\nvoid Hazards_Disable()\n{\n    // get stage id\n    int stage_internal = Stage_ExternalToInternal(Stage_GetExternalID());\n    int is_fixwind = 0;\n\n    switch (stage_internal)\n    {\n    case (GR_STORY):\n    {\n        // remove shyguy map gobj proc\n        GOBJ *shyguy_gobj = Stage_GetMapGObj(3);\n        GObj_RemoveProc(shyguy_gobj);\n\n        // remove randall\n        GOBJ *randall_gobj = Stage_GetMapGObj(2);\n        Stage_DestroyMapGObj(randall_gobj);\n\n        is_fixwind = 1;\n\n        break;\n    }\n    case (GR_PSTAD):\n    {\n        // remove map gobj proc\n        GOBJ *map_gobj = Stage_GetMapGObj(2);\n        GObj_RemoveProc(map_gobj);\n\n        is_fixwind = 1;\n\n        break;\n    }\n    case (GR_OLDPU):\n    {\n        // remove map gobj proc\n        GOBJ *map_gobj = Stage_GetMapGObj(7);\n        GObj_RemoveProc(map_gobj);\n\n        // remove map gobj proc\n        map_gobj = Stage_GetMapGObj(6);\n        GObj_RemoveProc(map_gobj);\n\n        // set wind hazard num to 0\n        *ftchkdevice_windnum = 0;\n\n        break;\n    }\n    case (GR_FD):\n    {\n        // set bg skip flag\n        GOBJ *map_gobj = Stage_GetMapGObj(3);\n        map_gobjData *map_data = map_gobj->userdata;\n        map_data->xc4 |= 0x40;\n\n        // remove on-go function that changes this flag\n        StageOnGO *on_go = stc_stage->on_go;\n        stc_stage->on_go = on_go->next;\n        HSD_Free(on_go);\n\n        break;\n    }\n    }\n\n    // Certain stages have an essential ragdoll function\n    // in their map_gobj think function. If the think function is removed,\n    // the ragdoll function must be re-scheduled to function properly.\n    if (is_fixwind == 1)\n    {\n        GOBJ *wind_gobj = GObj_Create(3, 5, 0);\n        GObj_AddProc(wind_gobj, Dynamics_DecayWind, 4);\n    }\n}\n\n// Message Functions\nvoid Message_Init()\n{\n\n    // create cobj\n    GOBJ *cam_gobj = GObj_Create(19, 20, 0);\n    COBJDesc *cam_desc = stc_event_vars.menu_assets->hud_cobjdesc;\n    COBJ *cam_cobj = COBJ_LoadDescSetScissor(cam_desc);\n    cam_cobj->scissor_bottom = 400;\n    // init camera\n    GObj_AddObject(cam_gobj, R13_U8(-0x3E55), cam_cobj); //R13_U8(-0x3E55)\n    GOBJ_InitCamera(cam_gobj, Message_CObjThink, MSG_COBJLGXPRI);\n    cam_gobj->cobj_links = MSG_COBJLGXLINKS;\n\n    // Create manager GOBJ\n    GOBJ *mgr_gobj = GObj_Create(0, 7, 0);\n    MsgMngrData *mgr_data = calloc(sizeof(MsgMngrData));\n    GObj_AddUserData(mgr_gobj, 4, HSD_Free, mgr_data);\n    GObj_AddProc(mgr_gobj, Message_Manager, 18);\n\n    // create text canvas\n    int canvas = Text_CreateCanvas(2, mgr_gobj, 14, 15, 0, MSG_GXLINK, MSGTEXT_GXPRI, 19);\n    mgr_data->canvas = canvas;\n\n    // store cobj\n    mgr_data->cobj = cam_cobj;\n\n    // store gobj pointer\n    stc_msgmgr = mgr_gobj;\n\n    return;\n}\nGOBJ *Message_Display(int msg_kind, int queue_num, int msg_color, char *format, ...)\n{\n\n    va_list args;\n\n    MsgMngrData *mgr_data = stc_msgmgr->userdata;\n\n    // Create GOBJ\n    GOBJ *msg_gobj = GObj_Create(0, 7, 0);\n    MsgData *msg_data = calloc(sizeof(MsgData));\n    GObj_AddUserData(msg_gobj, 4, HSD_Free, msg_data);\n    GObj_AddGXLink(msg_gobj, GXLink_Common, MSG_GXLINK, MSG_GXPRI);\n    JOBJ *msg_jobj = JOBJ_LoadJoint(stc_event_vars.menu_assets->message);\n    GObj_AddObject(msg_gobj, R13_U8(-0x3E55), msg_jobj);\n    msg_data->lifetime = MSG_LIFETIME;\n    msg_data->kind = msg_kind;\n    msg_data->state = MSGSTATE_SHIFT;\n    msg_data->anim_timer = MSGTIMER_SHIFT;\n    msg_jobj->scale.X = MSGJOINT_SCALE;\n    msg_jobj->scale.Y = MSGJOINT_SCALE;\n    msg_jobj->scale.Z = MSGJOINT_SCALE;\n    msg_jobj->trans.X = MSGJOINT_X;\n    msg_jobj->trans.Y = MSGJOINT_Y;\n    msg_jobj->trans.Z = MSGJOINT_Z;\n\n    // Create text object\n    Text *msg_text = Text_CreateText(2, mgr_data->canvas);\n    msg_data->text = msg_text;\n    msg_text->kerning = 1;\n    msg_text->align = 1;\n    msg_text->use_aspect = 1;\n    msg_text->color = stc_msg_colors[msg_color];\n\n    // adjust scale\n    Vec3 scale = msg_jobj->scale;\n    // background scale\n    msg_jobj->scale = scale;\n    // text scale\n    msg_text->scale.X = (scale.X * 0.01) * MSGTEXT_BASESCALE;\n    msg_text->scale.Y = (scale.Y * 0.01) * MSGTEXT_BASESCALE;\n    msg_text->aspect.X = MSGTEXT_BASEWIDTH;\n\n    JOBJ_SetMtxDirtySub(msg_jobj);\n\n    // build string\n    char buffer[(MSG_LINEMAX * MSG_CHARMAX) + 1];\n    va_start(args, format);\n    vsprintf(buffer, format, args);\n    va_end(args);\n    char *msg = &buffer;\n\n    // count newlines\n    int line_num = 1;\n    int line_length_arr[MSG_LINEMAX];\n    char *msg_cursor_prev, *msg_cursor_curr; // declare char pointers\n    msg_cursor_prev = msg;\n    msg_cursor_curr = strchr(msg_cursor_prev, '\\n'); // check for occurrence\n    while (msg_cursor_curr != 0)                     // if occurrence found, increment values\n    {\n        // check if exceeds max lines\n        if (line_num >= MSG_LINEMAX)\n            assert(\"MSG_LINEMAX exceeded!\");\n\n        // Save information about this line\n        line_length_arr[line_num - 1] = msg_cursor_curr - msg_cursor_prev; // determine length of the line\n        line_num++;                                                        // increment number of newlines found\n        msg_cursor_prev = msg_cursor_curr + 1;                             // update prev cursor\n        msg_cursor_curr = strchr(msg_cursor_prev, '\\n');                   // check for another occurrence\n    }\n\n    // get last lines length\n    msg_cursor_curr = strchr(msg_cursor_prev, 0);\n    line_length_arr[line_num - 1] = msg_cursor_curr - msg_cursor_prev;\n\n    // copy each line to an individual char array\n    char *msg_cursor = &msg;\n    for (int i = 0; i < line_num; i++)\n    {\n\n        // check if over char max\n        u8 line_length = line_length_arr[i];\n        if (line_length > MSG_CHARMAX)\n            assert(\"MSG_CHARMAX exceeded!\");\n\n        // copy char array\n        char msg_line[MSG_CHARMAX + 1];\n        memcpy(msg_line, msg, line_length);\n\n        // add null terminator\n        msg_line[line_length] = '\\0';\n\n        // increment msg\n        msg += (line_length + 1); // +1 to skip past newline\n\n        // print line\n        int y_base = (line_num - 1) * ((-1 * MSGTEXT_YOFFSET) / 2);\n        int y_delta = (i * MSGTEXT_YOFFSET);\n        Text_AddSubtext(msg_text, 0, y_base + y_delta, msg_line);\n    }\n\n    // Add to queue\n    Message_Add(msg_gobj, queue_num);\n\n    return msg_gobj;\n}\nvoid Message_Manager(GOBJ *mngr_gobj)\n{\n    MsgMngrData *mgr_data = mngr_gobj->userdata;\n\n    // Iterate through each queue\n    for (int i = 0; i < MSGQUEUE_NUM; i++)\n    {\n        GOBJ **msg_queue = &mgr_data->msg_queue[i];\n\n        // anim update (time based logic)\n        for (int j = (MSGQUEUE_SIZE - 2); j >= 0; j--) // iterate through backwards (because deletions)\n        {\n            GOBJ *this_msg_gobj = msg_queue[j];\n\n            // if message exists\n            if (this_msg_gobj != 0)\n            {\n                MsgData *this_msg_data = this_msg_gobj->userdata;\n                Text *this_msg_text = this_msg_data->text;\n                JOBJ *this_msg_jobj = this_msg_gobj->hsd_object;\n\n                // check if the message moved this frame\n                if (this_msg_data->orig_index != j)\n                {\n                    this_msg_data->orig_index = j;              // moved so update this\n                    this_msg_data->state = MSGSTATE_SHIFT;      // enter shift\n                    this_msg_data->anim_timer = MSGTIMER_SHIFT; // shift timer\n                }\n\n                // decrement state timer if above 0\n                if (this_msg_data->anim_timer > 0)\n                    this_msg_data->anim_timer--;\n\n                switch (this_msg_data->state)\n                {\n                case (MSGSTATE_WAIT):\n                case (MSGSTATE_SHIFT):\n                {\n\n                    // increment alive time\n                    this_msg_data->alive_timer++;\n\n                    // if lifetime is ended, enter delete state\n                    if (this_msg_data->alive_timer >= this_msg_data->lifetime)\n                    {\n                        // if using frame advance, instantly remove this message\n                        if (Pause_CheckStatus(0) == 1)\n                        {\n                            Message_Destroy(msg_queue, j);\n                        }\n                        else\n                        {\n                            this_msg_data->state = MSGSTATE_DELETE;\n                            this_msg_data->anim_timer = MSGTIMER_DELETE;\n                        }\n                    }\n\n                    break;\n                }\n\n                case (MSGSTATE_DELETE):\n                {\n\n                    // if timer is ended, remove the message\n                    if ((this_msg_data->anim_timer <= 0))\n                    {\n                        Message_Destroy(msg_queue, j);\n                    }\n\n                    break;\n                }\n                }\n            }\n        }\n\n        // position update (update messages' onscreen positions)\n        for (int j = 0; j < MSGQUEUE_SIZE; j++)\n        {\n            GOBJ *this_msg_gobj = msg_queue[j];\n\n            // if message exists\n            if (this_msg_gobj != 0)\n            {\n                MsgData *this_msg_data = this_msg_gobj->userdata;\n                Text *this_msg_text = this_msg_data->text;\n                JOBJ *this_msg_jobj = this_msg_gobj->hsd_object;\n\n                // Get the onscreen position for this queue\n                Vec3 base_pos;\n                Vec3 this_msg_pos;\n                float pos_delta = stc_msg_queue_offsets[i];\n                if (i < 6)\n                {\n                    Vec3 *hud_pos = Match_GetPlayerHUDPos(i);\n\n                    base_pos.X = hud_pos->X;\n                    base_pos.Y = hud_pos->Y + MSG_HUDYOFFSET;\n                    base_pos.Z = hud_pos->Z;\n                }\n                else if (i == MSGQUEUE_GENERAL)\n                {\n                    base_pos = stc_msg_queue_general_pos;\n                }\n                this_msg_pos.X = base_pos.X; // Get this messages position\n\n                switch (this_msg_data->state)\n                {\n                case (MSGSTATE_WAIT):\n                case (MSGSTATE_SHIFT):\n                {\n\n                    // get time\n                    float t = (((float)MSGTIMER_SHIFT - this_msg_data->anim_timer) / MSGTIMER_SHIFT);\n\n                    // get initial and final position for animation\n                    float final_pos = base_pos.Y + ((float)j * pos_delta);\n                    float initial_pos = base_pos.Y + ((float)this_msg_data->prev_index * pos_delta);\n                    if (Pause_CheckStatus(0) == 1) // if using frame advance, do not animate\n                    {\n                        this_msg_pos.Y = final_pos;\n                    }\n                    else\n                    {\n                        this_msg_pos.Y = (BezierBlend(t) * (final_pos - initial_pos)) + initial_pos;\n                    }\n\n                    Vec3 scale = this_msg_jobj->scale;\n\n                    // BG position\n                    this_msg_jobj->trans.X = this_msg_pos.X;\n                    this_msg_jobj->trans.Y = this_msg_pos.Y;\n                    // text position\n                    this_msg_text->trans.X = this_msg_pos.X + (MSGTEXT_BASEX * (scale.X / 4.0));\n                    this_msg_text->trans.Y = (this_msg_pos.Y * -1) + (MSGTEXT_BASEY * (scale.Y / 4.0));\n\n                    // adjust bar\n                    JOBJ *bar;\n                    JOBJ_GetChild(this_msg_jobj, &bar, 4, -1);\n                    bar->trans.X = (float)(this_msg_data->lifetime - this_msg_data->alive_timer) / (float)this_msg_data->lifetime;\n\n                    break;\n                }\n                case (MSGSTATE_DELETE):\n                {\n                    // get time\n                    float t = ((this_msg_data->anim_timer) / (float)MSGTIMER_DELETE);\n\n                    Vec3 *scale = &this_msg_jobj->scale;\n                    Vec3 *pos = &this_msg_jobj->trans;\n\n                    // BG scale\n                    scale->Y = BezierBlend(t);\n                    // text scale\n                    this_msg_text->scale.Y = (scale->Y * 0.01) * MSGTEXT_BASESCALE;\n                    // text position\n                    this_msg_text->trans.Y = (pos->Y * -1) + (MSGTEXT_BASEY * (scale->Y / 4.0));\n\n                    break;\n                }\n                }\n\n                JOBJ_SetMtxDirtySub(this_msg_jobj);\n            }\n        }\n    }\n}\nvoid Message_Destroy(GOBJ **msg_queue, int msg_num)\n{\n\n    GOBJ *msg_gobj = msg_queue[msg_num];\n    MsgData *msg_data = msg_gobj->userdata;\n\n    // Destroy text\n    Text *text = msg_data->text;\n    if (text != 0)\n        Text_Destroy(text);\n\n    // Destroy GOBJ\n    GObj_Destroy(msg_gobj);\n\n    // null pointer\n    msg_queue[msg_num] = 0;\n\n    // shift others\n    for (int i = (msg_num); i < (MSGQUEUE_SIZE - 1); i++)\n    {\n        msg_queue[i] = msg_queue[i + 1];\n\n        // update its prev pos\n        GOBJ *this_msg_gobj = msg_queue[i];\n        if (this_msg_gobj != 0)\n        {\n            MsgData *this_msg_data = this_msg_gobj->userdata;\n            this_msg_data->prev_index = i + 1; // prev position\n        }\n    }\n\n    return;\n}\nvoid Message_Add(GOBJ *msg_gobj, int queue_num)\n{\n\n    MsgData *msg_data = msg_gobj->userdata;\n    MsgMngrData *mgr_data = stc_msgmgr->userdata;\n    GOBJ **msg_queue = &mgr_data->msg_queue[queue_num];\n\n    // ensure this queue exists\n    if (queue_num >= MSGQUEUE_NUM)\n        assert(\"queue_num over!\");\n\n    // remove any existing messages of this kind\n    for (int i = 0; i < MSGQUEUE_SIZE; i++)\n    {\n        GOBJ *this_msg_gobj = msg_queue[i];\n\n        // if it exists\n        if (this_msg_gobj != 0)\n        {\n            MsgData *this_msg_data = this_msg_gobj->userdata;\n\n            // Remove this message if its of the same kind\n            if ((this_msg_data->kind == msg_data->kind))\n            {\n\n                Message_Destroy(msg_queue, i); // remove the message and shift others\n\n                // if the message we're replacing is the most recent message, instantly\n                // remove the old one and do not animate the new one\n                if (i == 0)\n                {\n                    msg_data->state = MSGSTATE_WAIT;\n                    msg_data->anim_timer = 0;\n                }\n            }\n        }\n    }\n\n    // first remove last message in the queue\n    if (msg_queue[MSGQUEUE_SIZE - 1] != 0)\n    {\n        Message_Destroy(msg_queue, MSGQUEUE_SIZE - 1);\n    }\n\n    // shift other messages\n    for (int i = (MSGQUEUE_SIZE - 2); i >= 0; i--)\n    {\n        // shift message\n        msg_queue[i + 1] = msg_queue[i];\n\n        // update its prev pos\n        GOBJ *this_msg_gobj = msg_queue[i + 1];\n        if (this_msg_gobj != 0)\n        {\n            MsgData *this_msg_data = this_msg_gobj->userdata;\n            this_msg_data->prev_index = i; // prev position\n        }\n    }\n\n    // add this new message\n    msg_queue[0] = msg_gobj;\n\n    // set prev pos to -1 (slides in)\n    msg_data->prev_index = -1;\n    msg_data->orig_index = 0;\n\n    return;\n}\nvoid Message_CObjThink(GOBJ *gobj)\n{\n\n    if (Pause_CheckStatus(1) != 2)\n        CObjThink_Common(gobj);\n\n    return;\n}\n\nfloat BezierBlend(float t)\n{\n    return t * t * (3.0f - 2.0f * t);\n}\n\n// Tips Functions\nvoid Tip_Init()\n{\n    // init static struct\n    memset(&stc_tipmgr, 0, sizeof(TipMgr));\n\n    // create tipmgr gobj\n    GOBJ *tipmgr_gobj = GObj_Create(0, 7, 0);\n    GObj_AddProc(tipmgr_gobj, Tip_Think, 18);\n\n    return;\n}\nvoid Tip_Think(GOBJ *gobj)\n{\n\n    GOBJ *tip_gobj = stc_tipmgr.gobj;\n\n    stc_event_vars.menu_assets->tip_jobj;\n\n    // update tip\n    if (tip_gobj != 0)\n    {\n\n        // update anim\n        JOBJ_AnimAll(tip_gobj->hsd_object);\n\n        // update text position\n        JOBJ *tip_jobj;\n        Vec3 tip_pos;\n        JOBJ_GetChild(tip_gobj->hsd_object, &tip_jobj, TIP_TXTJOINT, -1);\n        JOBJ_GetWorldPosition(tip_jobj, 0, &tip_pos);\n        Text *tip_text = stc_tipmgr.text;\n        tip_text->trans.X = tip_pos.X + (0 * (tip_jobj->scale.X / 4.0));\n        tip_text->trans.Y = (tip_pos.Y * -1) + (0 * (tip_jobj->scale.Y / 4.0));\n\n        // state logic\n        switch (stc_tipmgr.state)\n        {\n        case (0): // in\n        {\n            // if anim is done, enter wait\n            if (JOBJ_CheckAObjEnd(tip_gobj->hsd_object) == 0)\n                stc_tipmgr.state = 1; // enter wait\n\n            break;\n        }\n        case (1): // wait\n        {\n            // sub timer\n            stc_tipmgr.lifetime--;\n            if (stc_tipmgr.lifetime <= 0)\n            {\n                // apply exit anim\n                JOBJ *tip_root = tip_gobj->hsd_object;\n                JOBJ_RemoveAnimAll(tip_root);\n                JOBJ_AddAnimAll(tip_root, stc_event_vars.menu_assets->tip_jointanim[1], 0, 0);\n                JOBJ_ReqAnimAll(tip_root, 0);\n\n                stc_tipmgr.state = 2; // enter wait\n            }\n\n            break;\n        }\n        case (2): // out\n        {\n            // if anim is done, destroy\n            if (JOBJ_CheckAObjEnd(tip_gobj->hsd_object) == 0)\n            {\n                // remove text\n                Text_Destroy(stc_tipmgr.text);\n                GObj_Destroy(stc_tipmgr.gobj);\n                stc_tipmgr.gobj = 0;\n            }\n            break;\n        }\n        }\n    }\n\n    return;\n}\nint Tip_Display(int lifetime, char *fmt, ...)\n{\n\n#define TIP_TXTSIZE 4.7\n#define TIP_TXTSIZEX TIP_TXTSIZE * 0.85\n#define TIP_TXTSIZEY TIP_TXTSIZE\n#define TIP_TXTASPECT 2430\n#define TIP_LINEMAX 5\n#define TIP_CHARMAX 48\n\n    va_list args;\n\n    // if tip exists\n    if (stc_tipmgr.gobj != 0)\n    {\n        // if tip is in the process of exiting\n        if (stc_tipmgr.state == 2)\n        {\n            // remove text\n            Text_Destroy(stc_tipmgr.text);\n            GObj_Destroy(stc_tipmgr.gobj);\n            stc_tipmgr.gobj = 0;\n        }\n        // if is active onscreen do nothing\n        else\n            return 0;\n    }\n\n    MsgMngrData *msgmngr_data = stc_msgmgr->userdata; // using message canvas cause there are so many god damn text canvases\n\n    // Create bg\n    GOBJ *tip_gobj = GObj_Create(0, 0, 0);\n    stc_tipmgr.gobj = tip_gobj;\n    GObj_AddGXLink(tip_gobj, GXLink_Common, MSG_GXLINK, 80);\n    JOBJ *tip_jobj = JOBJ_LoadJoint(stc_event_vars.menu_assets->tip_jobj);\n    GObj_AddObject(tip_gobj, R13_U8(-0x3E55), tip_jobj);\n\n    // account for widescreen\n    /*\n    float aspect = (msgmngr_data->cobj->projection_param.perspective.aspect / 1.216667) - 1;\n    tip_jobj->trans.X += (tip_jobj->trans.X * aspect);\n    JOBJ_SetMtxDirtySub(tip_jobj);\n    */\n\n    // Create text object\n    Text *tip_text = Text_CreateText(2, msgmngr_data->canvas);\n    stc_tipmgr.text = tip_text;\n    stc_tipmgr.lifetime = lifetime;\n    stc_tipmgr.state = 0;\n    tip_text->kerning = 1;\n    tip_text->align = 0;\n    tip_text->use_aspect = 1;\n\n    // adjust text scale\n    Vec3 scale = tip_jobj->scale;\n    // background scale\n    tip_jobj->scale = scale;\n    // text scale\n    tip_text->scale.X = (scale.X * 0.01) * TIP_TXTSIZEX;\n    tip_text->scale.Y = (scale.Y * 0.01) * TIP_TXTSIZEY;\n    tip_text->aspect.X = (TIP_TXTASPECT / TIP_TXTSIZEX);\n\n    // apply enter anim\n    JOBJ_RemoveAnimAll(tip_jobj);\n    JOBJ_AddAnimAll(tip_jobj, stc_event_vars.menu_assets->tip_jointanim[0], 0, 0);\n    JOBJ_ReqAnimAll(tip_jobj, 0);\n\n    // build string\n    char buffer[(TIP_LINEMAX * TIP_CHARMAX) + 1];\n    va_start(args, fmt);\n    vsprintf(buffer, fmt, args);\n    va_end(args);\n    char *msg = &buffer;\n\n    // count newlines\n    int line_num = 1;\n    int line_length_arr[TIP_LINEMAX];\n    char *msg_cursor_prev, *msg_cursor_curr; // declare char pointers\n    msg_cursor_prev = msg;\n    msg_cursor_curr = strchr(msg_cursor_prev, '\\n'); // check for occurrence\n    while (msg_cursor_curr != 0)                     // if occurrence found, increment values\n    {\n        // check if exceeds max lines\n        if (line_num >= TIP_LINEMAX)\n            assert(\"TIP_LINEMAX exceeded!\");\n\n        // Save information about this line\n        line_length_arr[line_num - 1] = msg_cursor_curr - msg_cursor_prev; // determine length of the line\n        line_num++;                                                        // increment number of newlines found\n        msg_cursor_prev = msg_cursor_curr + 1;                             // update prev cursor\n        msg_cursor_curr = strchr(msg_cursor_prev, '\\n');                   // check for another occurrence\n    }\n\n    // get last lines length\n    msg_cursor_curr = strchr(msg_cursor_prev, 0);\n    line_length_arr[line_num - 1] = msg_cursor_curr - msg_cursor_prev;\n\n    // copy each line to an individual char array\n    char *msg_cursor = &msg;\n    for (int i = 0; i < line_num; i++)\n    {\n\n        // check if over char max\n        u8 line_length = line_length_arr[i];\n        if (line_length > TIP_CHARMAX)\n            assert(\"TIP_CHARMAX exceeded!\");\n\n        // copy char array\n        char msg_line[TIP_CHARMAX + 1];\n        memcpy(msg_line, msg, line_length);\n\n        // add null terminator\n        msg_line[line_length] = '\\0';\n\n        // increment msg\n        msg += (line_length + 1); // +1 to skip past newline\n\n        // print line\n        int y_delta = (i * MSGTEXT_YOFFSET);\n        Text_AddSubtext(tip_text, 0, y_delta, msg_line);\n    }\n\n    return 1; // tip created\n}\nvoid Tip_Destroy()\n{\n    // check if tip exists and isnt in exit state, enter exit\n    if ((stc_tipmgr.gobj != 0) && (stc_tipmgr.state != 2))\n    {\n        // apply exit anim\n        JOBJ *tip_root = stc_tipmgr.gobj->hsd_object;\n        JOBJ_RemoveAnimAll(tip_root);\n        JOBJ_AddAnimAll(tip_root, stc_event_vars.menu_assets->tip_jointanim[1], 0, 0);\n        JOBJ_ReqAnimAll(tip_root, 0);\n        JOBJ_RunAOBJCallback(tip_root, 6, 0xfb7f, AOBJ_SetRate, 1, (float)2);\n\n        stc_tipmgr.state = 2; // enter wait\n    }\n\n    return;\n}\n\n////////////////////////////\n/// Event Menu Functions ///\n////////////////////////////\n\nGOBJ *EventMenu_Init(EventDesc *event_desc, EventMenu *start_menu)\n{\n    // Ensure this event has a menu\n    if (start_menu == 0)\n        return 0;\n\n    // Create a cobj for the event menu\n    COBJDesc ***dmgScnMdls = File_GetSymbol(ACCESS_PTR(0x804d6d5c), 0x803f94d0);\n    COBJDesc *cam_desc = dmgScnMdls[1][0];\n    COBJ *cam_cobj = COBJ_LoadDesc(cam_desc);\n    GOBJ *cam_gobj = GObj_Create(19, 20, 0);\n    GObj_AddObject(cam_gobj, R13_U8(-0x3E55), cam_cobj);\n    GOBJ_InitCamera(cam_gobj, CObjThink_Common, MENUCAM_GXPRI);\n    cam_gobj->cobj_links = MENUCAM_COBJGXLINK;\n\n    // Create menu gobj\n    GOBJ *gobj = GObj_Create(0, 0, 0);\n    MenuData *menuData = calloc(sizeof(MenuData));\n    GObj_AddUserData(gobj, 4, HSD_Free, menuData);\n\n    // store pointer to the gobj's data\n    menuData->event_desc = event_desc;\n\n    // Add gx_link\n    GObj_AddGXLink(gobj, GXLink_Common, GXLINK_MENUMODEL, GXPRI_MENUMODEL);\n\n    // Create 2 text canvases (menu and popup)\n    menuData->canvas_menu = Text_CreateCanvas(2, cam_gobj, 9, 13, 0, GXLINK_MENUTEXT, GXPRI_MENUTEXT, MENUCAM_GXPRI);\n    menuData->canvas_popup = Text_CreateCanvas(2, cam_gobj, 9, 13, 0, GXLINK_MENUTEXT, GXPRI_POPUPTEXT, MENUCAM_GXPRI);\n\n    // Init currMenu\n    menuData->currMenu = start_menu;\n\n    // set menu as not hidden\n    stc_event_vars.hide_menu = 0;\n\n    return gobj;\n};\n\nvoid EventMenu_Update(GOBJ *gobj)\n{\n\n    //MenuCamData *camData = gobj->userdata;\n    MenuData *menuData = gobj->userdata;\n    EventDesc *event_desc = menuData->event_desc;\n    EventMenu *currMenu = menuData->currMenu;\n\n    int update_menu = 1;\n\n    // if a custom menu is in use, run its function\n    if (menuData->custom_gobj_think != 0)\n    {\n        update_menu = menuData->custom_gobj_think(menuData->custom_gobj);\n    }\n\n    // if this menu has an upate function, run its function\n    else if ((menuData->isPaused == 1) && (currMenu->menu_think != 0))\n    {\n        update_menu = currMenu->menu_think(gobj);\n    }\n\n    if (update_menu == 1)\n    {\n        // Check if being pressed\n        int isPress = 0;\n        for (int i = 0; i < 6; i++)\n        {\n\n            // humans only\n            if (Fighter_GetSlotType(i) == 0)\n            {\n                GOBJ *fighter = Fighter_GetGObj(i);\n                FighterData *fighter_data = fighter->userdata;\n                int controller_index = Fighter_GetControllerPort(i);\n\n                HSD_Pad *pad = PadGet(controller_index, PADGET_MASTER);\n\n                // in develop mode, use X+DPad up\n                if (*stc_dblevel >= 3)\n                {\n                    if ((pad->held & HSD_BUTTON_X) && (pad->down & HSD_BUTTON_DPAD_UP))\n                    {\n                        isPress = 1;\n                        menuData->controller_index = controller_index;\n                        break;\n                    }\n                }\n                else\n                {\n                    if ((pad->down & HSD_BUTTON_START) != 0)\n                    {\n                        isPress = 1;\n                        menuData->controller_index = controller_index;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // change pause state\n        if (isPress != 0)\n        {\n\n            // pause game\n            if (menuData->isPaused == 0)\n            {\n\n                // set state\n                menuData->isPaused = 1;\n\n                // Create menu\n                EventMenu_CreateModel(gobj, currMenu);\n                EventMenu_CreateText(gobj, currMenu);\n                EventMenu_UpdateText(gobj, currMenu);\n                if (currMenu->state == EMSTATE_OPENPOP)\n                {\n                    EventOption *currOption = &currMenu->options[currMenu->cursor];\n                    EventMenu_CreatePopupModel(gobj, currMenu);\n                    EventMenu_CreatePopupText(gobj, currMenu);\n                    EventMenu_UpdatePopupText(gobj, currOption);\n                }\n\n                // Freeze the game\n                Match_FreezeGame(1);\n                SFX_PlayCommon(5);\n                Match_HideHUD();\n                Match_AdjustSoundOnPause(1);\n            }\n            // unpause game\n            else\n            {\n\n                menuData->isPaused = 0;\n\n                // destroy menu\n                EventMenu_DestroyMenu(gobj);\n\n                // Unfreeze the game\n                Match_UnfreezeGame(1);\n                Match_ShowHUD();\n                Match_AdjustSoundOnPause(0);\n            }\n        }\n\n        // run menu logic if the menu is shown\n        else if ((menuData->isPaused == 1) && (stc_event_vars.hide_menu == 0))\n        {\n            // Get the current menu\n            EventMenu *currMenu = menuData->currMenu;\n\n            // menu think\n            if (currMenu->state == EMSTATE_FOCUS)\n            {\n                // check to run custom menu think function\n                EventMenu_MenuThink(gobj, currMenu);\n            }\n\n            // popup think\n            else if (currMenu->state == EMSTATE_OPENPOP)\n                EventMenu_PopupThink(gobj, currMenu);\n        }\n    }\n\n    return;\n}\n\nvoid EventMenu_MenuGX(GOBJ *gobj, int pass)\n{\n    if (stc_event_vars.hide_menu == 0)\n        GXLink_Common(gobj, pass);\n    return;\n}\n\nvoid EventMenu_TextGX(GOBJ *gobj, int pass)\n{\n\n    if (stc_event_vars.hide_menu == 0)\n        Text_GX(gobj, pass);\n    return;\n}\n\nvoid EventMenu_MenuThink(GOBJ *gobj, EventMenu *currMenu)\n{\n\n    MenuData *menuData = gobj->userdata;\n    EventDesc *event_desc = menuData->event_desc;\n\n    // get player who paused\n    u8 pauser = menuData->controller_index;\n    // get their  inputs\n    HSD_Pad *pad = PadGet(pauser, PADGET_MASTER);\n    int inputs_rapid = Pad_GetRapidHeld(pauser); //pad->rapidFire;\n    int inputs_held = pad->held;\n    int inputs = inputs_rapid;\n    if ((inputs_held & HSD_TRIGGER_R) != 0)\n        inputs = inputs_held;\n\n    // get menu variables\n    int isChanged = 0;\n    s32 cursor = currMenu->cursor;\n    s32 scroll = currMenu->scroll;\n    EventOption *currOption = &currMenu->options[cursor + scroll];\n    s32 cursor_min = 0;\n    s32 option_num = currMenu->option_num;\n    s32 cursor_max = option_num;\n    if (cursor_max > MENU_MAXOPTION)\n        cursor_max = MENU_MAXOPTION;\n\n    // get option variables\n    s16 option_val = currOption->option_val;\n    s16 value_min = 0;\n    s16 value_max = currOption->value_num;\n\n    // check for dpad down\n    if (((inputs & HSD_BUTTON_DOWN) != 0) || ((inputs & HSD_BUTTON_DPAD_DOWN) != 0))\n    {\n\n        // loop to find next option\n        int count = 1;       //\n        int cursor_next = 0; // how much to move the cursor by\n        while (((cursor + count + scroll) < option_num))\n        {\n            // option exists, check if its enabled\n            if (currMenu->options[cursor + count + scroll].disable == 0)\n            {\n                cursor_next = count;\n                break;\n            }\n\n            // option is disabled, loop\n            count++;\n        }\n\n        // if another option exists, move down\n        if (cursor_next > 0)\n        {\n            cursor += cursor_next;\n\n            // cursor is in bounds, move down\n            if (cursor < cursor_max)\n            {\n                isChanged = 1;\n\n                // update cursor\n                currMenu->cursor = cursor;\n\n                // also play sfx\n                SFX_PlayCommon(2);\n            }\n\n            // cursor overflowed, correct it\n            else\n            {\n\n                // adjust\n                scroll -= (cursor_max - (cursor + 1));\n                cursor = (cursor_max - 1);\n\n                // update cursor\n                currMenu->cursor = cursor;\n                currMenu->scroll = scroll;\n\n                isChanged = 1;\n\n                // also play sfx\n                SFX_PlayCommon(2);\n            }\n        }\n    }\n    // check for dpad up\n    else if (((inputs & HSD_BUTTON_UP) != 0) || ((inputs & HSD_BUTTON_DPAD_UP) != 0))\n    {\n        // loop to find next option\n        int count = 1;       //\n        int cursor_next = 0; // how much to move the cursor by\n        while (((cursor + scroll - count) >= 0))\n        {\n            // option exists, check if its enabled\n            if (currMenu->options[cursor + scroll - count].disable == 0)\n            {\n                cursor_next = count;\n                break;\n            }\n\n            // option is disabled, loop\n            count++;\n        }\n\n        // if another option exists, move up\n        if (cursor_next > 0)\n        {\n            cursor -= cursor_next;\n\n            // cursor is in bounds, move up\n            if (cursor >= 0)\n            {\n                isChanged = 1;\n\n                // update cursor\n                currMenu->cursor = cursor;\n\n                // also play sfx\n                SFX_PlayCommon(2);\n            }\n\n            // cursor overflowed, correct it\n            else\n            {\n\n                // adjust\n                scroll += cursor; // effectively scroll up by adding a negative number\n                cursor = 0;       // cursor is positioned at 0\n\n                // update cursor\n                currMenu->cursor = cursor;\n                currMenu->scroll = scroll;\n\n                isChanged = 1;\n\n                // also play sfx\n                SFX_PlayCommon(2);\n            }\n        }\n    }\n\n    // check for left\n    else if (((inputs & HSD_BUTTON_LEFT) != 0) || ((inputs & HSD_BUTTON_DPAD_LEFT) != 0))\n    {\n        if ((currOption->option_kind == OPTKIND_STRING) || (currOption->option_kind == OPTKIND_INT) || (currOption->option_kind == OPTKIND_FLOAT))\n        {\n\n            option_val -= 1;\n            if (option_val >= value_min)\n            {\n                isChanged = 1;\n\n                // also play sfx\n                SFX_PlayCommon(2);\n\n                // update val\n                currOption->option_val = option_val;\n\n                // run on change function if it exists\n                if (currOption->onOptionChange != 0)\n                    currOption->onOptionChange(gobj, currOption->option_val);\n            }\n        }\n    }\n    // check for right\n    else if (((inputs & HSD_BUTTON_RIGHT) != 0) || ((inputs & HSD_BUTTON_DPAD_RIGHT) != 0))\n    {\n        // check for valid option kind\n        if ((currOption->option_kind == OPTKIND_STRING) || (currOption->option_kind == OPTKIND_INT) || (currOption->option_kind == OPTKIND_FLOAT))\n        {\n            option_val += 1;\n            if (option_val < value_max)\n            {\n                isChanged = 1;\n\n                // also play sfx\n                SFX_PlayCommon(2);\n\n                // update val\n                currOption->option_val = option_val;\n\n                // run on change function if it exists\n                if (currOption->onOptionChange != 0)\n                    currOption->onOptionChange(gobj, currOption->option_val);\n            }\n        }\n    }\n\n    // check for A\n    else if (inputs_rapid & HSD_BUTTON_A)\n    {\n        // check to advance a menu\n        if ((currOption->option_kind == OPTKIND_MENU))\n        {\n            // access this menu\n            currMenu->state = EMSTATE_OPENSUB;\n\n            // update currMenu\n            EventMenu *nextMenu = currMenu->options[cursor + scroll].menu;\n            nextMenu->prev = currMenu;\n            nextMenu->state = EMSTATE_FOCUS;\n            currMenu = nextMenu;\n            menuData->currMenu = currMenu;\n\n            // recreate everything\n            EventMenu_DestroyMenu(gobj);\n            EventMenu_CreateModel(gobj, currMenu);\n            EventMenu_CreateText(gobj, currMenu);\n            EventMenu_UpdateText(gobj, currMenu);\n\n            // also play sfx\n            SFX_PlayCommon(1);\n        }\n\n        /*\n        // check to create a popup\n        if ((currOption->option_kind == OPTKIND_STRING) || (currOption->option_kind == OPTKIND_INT))\n        {\n            // access this menu\n            currMenu->state = EMSTATE_OPENPOP;\n\n            // init cursor and scroll value\n            s32 cursor = 0;\n            s32 scroll = currOption->option_val;\n\n            // correct scroll\n            s32 max_scroll;\n            if (currOption->value_num <= MENU_POPMAXOPTION)\n                max_scroll = 0;\n            else\n                max_scroll = currOption->value_num - MENU_POPMAXOPTION;\n            // check if scrolled too far\n            if (scroll > max_scroll)\n            {\n                cursor = scroll - max_scroll;\n                scroll = max_scroll;\n            }\n\n            // update cursor and scroll\n            menuData->popup_cursor = cursor;\n            menuData->popup_scroll = scroll;\n\n            // create popup menu and update\n            EventMenu_CreatePopupModel(gobj, currMenu);\n            EventMenu_CreatePopupText(gobj, currMenu);\n            EventMenu_UpdatePopupText(gobj, currOption);\n\n            // also play sfx\n            SFX_PlayCommon(1);\n        }\n        */\n\n        // check to run a function\n        if ((currOption->option_kind == OPTKIND_FUNC) && (currOption->onOptionSelect != 0))\n        {\n\n            // execute function\n            currOption->onOptionSelect(gobj);\n\n            // update text\n            EventMenu_UpdateText(gobj, currMenu);\n\n            // also play sfx\n            SFX_PlayCommon(1);\n        }\n    }\n    // check to go back a menu\n    else if (inputs_rapid & HSD_BUTTON_B)\n    {\n        // check if a prev menu exists\n        EventMenu *prevMenu = currMenu->prev;\n        if (prevMenu != 0)\n        {\n\n            // clear previous menu\n            EventMenu *prevMenu = currMenu->prev;\n            currMenu->prev = 0;\n\n            // reset this menu's cursor\n            currMenu->scroll = 0;\n            currMenu->cursor = 0;\n\n            // update currMenu\n            currMenu = prevMenu;\n            menuData->currMenu = currMenu;\n\n            // close this menu\n            currMenu->state = EMSTATE_FOCUS;\n\n            // recreate everything\n            EventMenu_DestroyMenu(gobj);\n            EventMenu_CreateModel(gobj, currMenu);\n            EventMenu_CreateText(gobj, currMenu);\n            EventMenu_UpdateText(gobj, currMenu);\n\n            // also play sfx\n            SFX_PlayCommon(0);\n        }\n\n        /*\n        // no previous menu, unpause\n        else\n        {\n            SFX_PlayCommon(0);\n\n            menuData->isPaused = 0;\n\n            // destroy menu\n            EventMenu_DestroyMenu(gobj);\n\n            // Unfreeze the game\n            Match_UnfreezeGame(1);\n            Match_ShowHUD();\n            Match_AdjustSoundOnPause(0);\n        }\n        */\n    }\n\n    // if anything changed, update text\n    if (isChanged != 0)\n    {\n        // update menu\n        EventMenu_UpdateText(gobj, currMenu);\n    }\n\n    return;\n}\n\nvoid EventMenu_PopupThink(GOBJ *gobj, EventMenu *currMenu)\n{\n\n    MenuData *menuData = gobj->userdata;\n    EventDesc *event_desc = menuData->event_desc;\n\n    // get player who paused\n    u8 pauser = menuData->controller_index; // get their  inputs\n    HSD_Pad *pad = PadGet(pauser, PADGET_MASTER);\n    int inputs_rapid = pad->rapidFire;\n    int inputs_held = pad->held;\n    int inputs = inputs_rapid;\n    if ((inputs_held & HSD_TRIGGER_R) != 0)\n        inputs = inputs_held;\n\n    // get option variables\n    int isChanged = 0;\n    s32 cursor = menuData->popup_cursor;\n    s32 scroll = menuData->popup_scroll;\n    EventOption *currOption = &currMenu->options[currMenu->cursor + currMenu->scroll];\n    s32 value_num = currOption->value_num;\n    s32 cursor_min = 0;\n    s32 cursor_max = value_num;\n    if (cursor_max > MENU_POPMAXOPTION)\n    {\n        cursor_max = MENU_POPMAXOPTION;\n    }\n\n    // check for dpad down\n    if (((inputs & HSD_BUTTON_DOWN) != 0) || ((inputs & HSD_BUTTON_DPAD_DOWN) != 0))\n    {\n        cursor += 1;\n\n        // cursor is in bounds, move down\n        if (cursor < cursor_max)\n        {\n            isChanged = 1;\n\n            // update cursor\n            menuData->popup_cursor = cursor;\n\n            // also play sfx\n            SFX_PlayCommon(2);\n        }\n\n        // cursor overflowed, check to scroll\n        else\n        {\n            // cursor+scroll is in bounds, increment scroll\n            if ((cursor + scroll) < value_num)\n            {\n                // adjust\n                scroll++;\n                cursor--;\n\n                // update cursor\n                menuData->popup_cursor = cursor;\n                menuData->popup_scroll = scroll;\n\n                isChanged = 1;\n\n                // also play sfx\n                SFX_PlayCommon(2);\n            }\n        }\n    }\n    // check for dpad up\n    else if (((inputs & HSD_BUTTON_UP) != 0) || ((inputs & HSD_BUTTON_DPAD_UP) != 0))\n    {\n        cursor -= 1;\n\n        // cursor is in bounds, move up\n        if (cursor >= 0)\n        {\n            isChanged = 1;\n\n            // update cursor\n            menuData->popup_cursor = cursor;\n\n            // also play sfx\n            SFX_PlayCommon(2);\n        }\n\n        // cursor overflowed, check to scroll\n        else\n        {\n            // scroll is in bounds, decrement scroll\n            if (scroll > 0)\n            {\n                // adjust\n                scroll--;\n                cursor++;\n\n                // update cursor\n                menuData->popup_cursor = cursor;\n                menuData->popup_scroll = scroll;\n\n                isChanged = 1;\n\n                // also play sfx\n                SFX_PlayCommon(2);\n            }\n        }\n    }\n\n    // check for A\n    else if ((inputs_rapid & HSD_BUTTON_A) != 0)\n    {\n\n        // update option_val\n        currOption->option_val = cursor + scroll;\n\n        // run on change function if it exists\n        if (currOption->onOptionChange != 0)\n            currOption->onOptionChange(gobj, currOption->option_val);\n\n        EventMenu_DestroyPopup(gobj);\n\n        // update menu\n        EventMenu_UpdateText(gobj, currMenu);\n\n        // play sfx\n        SFX_PlayCommon(1);\n    }\n    // check to go back a menu\n    else if ((inputs_rapid & HSD_BUTTON_B) != 0)\n    {\n\n        EventMenu_DestroyPopup(gobj);\n\n        // update menu\n        EventMenu_UpdateText(gobj, currMenu);\n\n        // play sfx\n        SFX_PlayCommon(0);\n    }\n\n    // if anything changed, update text\n    if (isChanged != 0)\n    {\n        // update menu\n        EventMenu_UpdatePopupText(gobj, currOption);\n    }\n\n    return;\n}\n\nvoid EventMenu_CreateModel(GOBJ *gobj, EventMenu *menu)\n{\n\n    MenuData *menuData = gobj->userdata;\n\n    // create options background\n    evMenu *menuAssets = stc_event_vars.menu_assets;\n    JOBJ *jobj_options = JOBJ_LoadJoint(menuAssets->menu);\n    // Add to gobj\n    GObj_AddObject(gobj, 3, jobj_options);\n    GObj_DestroyGXLink(gobj);\n    GObj_AddGXLink(gobj, EventMenu_MenuGX, GXLINK_MENUMODEL, GXPRI_MENUMODEL);\n\n    // JOBJ array for getting the corner joints\n    JOBJ *corners[4];\n\n    // create a border and arrow for every row\n    s32 option_num = menu->option_num;\n    if (option_num > MENU_MAXOPTION)\n        option_num = MENU_MAXOPTION;\n    for (int i = 0; i < option_num; i++)\n    {\n        // create a border jobj\n        JOBJ *jobj_border = JOBJ_LoadJoint(menuAssets->popup);\n        // attach to root jobj\n        JOBJ_AddChild(gobj->hsd_object, jobj_border);\n        // move it into position\n        JOBJ_GetChild(jobj_border, &corners, 2, 3, 4, 5, -1);\n        // Modify scale and position\n        jobj_border->trans.Z = ROWBOX_Z;\n        jobj_border->scale.X = 1;\n        jobj_border->scale.Y = 1;\n        jobj_border->scale.Z = 1;\n        corners[0]->trans.X = -(ROWBOX_WIDTH / 2) + ROWBOX_X;\n        corners[0]->trans.Y = (ROWBOX_HEIGHT / 2) + ROWBOX_Y + (i * ROWBOX_YOFFSET);\n        corners[1]->trans.X = (ROWBOX_WIDTH / 2) + ROWBOX_X;\n        corners[1]->trans.Y = (ROWBOX_HEIGHT / 2) + ROWBOX_Y + (i * ROWBOX_YOFFSET);\n        corners[2]->trans.X = -(ROWBOX_WIDTH / 2) + ROWBOX_X;\n        corners[2]->trans.Y = -(ROWBOX_HEIGHT / 2) + ROWBOX_Y + (i * ROWBOX_YOFFSET);\n        corners[3]->trans.X = (ROWBOX_WIDTH / 2) + ROWBOX_X;\n        corners[3]->trans.Y = -(ROWBOX_HEIGHT / 2) + ROWBOX_Y + (i * ROWBOX_YOFFSET);\n        JOBJ_SetFlags(jobj_border, JOBJ_HIDDEN);\n        DOBJ_SetFlags(jobj_border->dobj, DOBJ_HIDDEN);\n        jobj_border->dobj->next->mobj->mat->alpha = 0.6;\n        //GXColor border_color = ROWBOX_COLOR;\n        //jobj_border->dobj->next->mobj->mat->diffuse = border_color;\n        // store pointer\n        menuData->row_joints[i][0] = jobj_border;\n\n        // create an arrow jobj\n        JOBJ *jobj_arrow = JOBJ_LoadJoint(menuAssets->arrow);\n        // attach to root jobj\n        JOBJ_AddChild(gobj->hsd_object, jobj_arrow);\n        // move it into position\n        jobj_arrow->trans.X = TICKBOX_X;\n        jobj_arrow->trans.Y = TICKBOX_Y + (i * ROWBOX_YOFFSET);\n        jobj_arrow->trans.Z = ROWBOX_Z;\n        jobj_arrow->scale.X = TICKBOX_SCALE;\n        jobj_arrow->scale.Y = TICKBOX_SCALE;\n        jobj_arrow->scale.Z = TICKBOX_SCALE;\n        // change color\n        //GXColor gx_color = {30, 40, 50, 255};\n        //jobj_arrow->dobj->next->mobj->mat->diffuse = gx_color;\n\n        JOBJ_SetFlags(jobj_arrow, JOBJ_HIDDEN);\n        // store pointer\n        menuData->row_joints[i][1] = jobj_arrow;\n    }\n\n    // create a highlight jobj\n    JOBJ *jobj_highlight = JOBJ_LoadJoint(menuAssets->popup);\n    // remove outline\n    DOBJ_SetFlags(jobj_highlight->dobj, DOBJ_HIDDEN);\n    // attach to root jobj\n    JOBJ_AddChild(gobj->hsd_object, jobj_highlight);\n    // move it into position\n    JOBJ_GetChild(jobj_highlight, &corners, 2, 3, 4, 5, -1);\n    // Modify scale and position\n    jobj_highlight->trans.Z = MENUHIGHLIGHT_Z;\n    jobj_highlight->scale.X = MENUHIGHLIGHT_SCALE;\n    jobj_highlight->scale.Y = MENUHIGHLIGHT_SCALE;\n    jobj_highlight->scale.Z = MENUHIGHLIGHT_SCALE;\n    corners[0]->trans.X = -(MENUHIGHLIGHT_WIDTH / 2) + MENUHIGHLIGHT_X;\n    corners[0]->trans.Y = (MENUHIGHLIGHT_HEIGHT / 2) + MENUHIGHLIGHT_Y;\n    corners[1]->trans.X = (MENUHIGHLIGHT_WIDTH / 2) + MENUHIGHLIGHT_X;\n    corners[1]->trans.Y = (MENUHIGHLIGHT_HEIGHT / 2) + MENUHIGHLIGHT_Y;\n    corners[2]->trans.X = -(MENUHIGHLIGHT_WIDTH / 2) + MENUHIGHLIGHT_X;\n    corners[2]->trans.Y = -(MENUHIGHLIGHT_HEIGHT / 2) + MENUHIGHLIGHT_Y;\n    corners[3]->trans.X = (MENUHIGHLIGHT_WIDTH / 2) + MENUHIGHLIGHT_X;\n    corners[3]->trans.Y = -(MENUHIGHLIGHT_HEIGHT / 2) + MENUHIGHLIGHT_Y;\n    GXColor highlight = MENUHIGHLIGHT_COLOR;\n    jobj_highlight->dobj->next->mobj->mat->alpha = 0.6;\n    jobj_highlight->dobj->next->mobj->mat->diffuse = highlight;\n    menuData->highlight_menu = jobj_highlight;\n\n    // check to create scroll bar\n    if (menuData->currMenu->option_num > MENU_MAXOPTION)\n    {\n        // create scroll bar\n        JOBJ *scroll_jobj = JOBJ_LoadJoint(menuAssets->scroll);\n        // attach to root jobj\n        JOBJ_AddChild(gobj->hsd_object, scroll_jobj);\n        // move it into position\n        JOBJ_GetChild(scroll_jobj, &corners, 2, 3, -1);\n        // scale scrollbar accordingly\n        scroll_jobj->scale.X = MENUSCROLL_SCALE;\n        scroll_jobj->scale.Y = MENUSCROLL_SCALEY;\n        scroll_jobj->scale.Z = MENUSCROLL_SCALE;\n        scroll_jobj->trans.X = MENUSCROLL_X;\n        scroll_jobj->trans.Y = MENUSCROLL_Y;\n        scroll_jobj->trans.Z = MENUSCROLL_Z;\n        menuData->scroll_top = corners[0];\n        menuData->scroll_bot = corners[1];\n        GXColor highlight = MENUSCROLL_COLOR;\n        scroll_jobj->dobj->next->mobj->mat->alpha = 0.6;\n        scroll_jobj->dobj->next->mobj->mat->diffuse = highlight;\n\n        // calculate scrollbar size\n        int max_steps = menuData->currMenu->option_num - MENU_MAXOPTION;\n        float botPos = MENUSCROLL_MAXLENGTH + (max_steps * MENUSCROLL_PEROPTION);\n        if (botPos > MENUSCROLL_MINLENGTH)\n            botPos = MENUSCROLL_MINLENGTH;\n\n        // set size\n        corners[1]->trans.Y = botPos;\n    }\n    else\n    {\n        menuData->scroll_bot = 0;\n        menuData->scroll_top = 0;\n    }\n\n    return;\n}\n\nvoid EventMenu_CreateText(GOBJ *gobj, EventMenu *menu)\n{\n\n    // Get event info\n    MenuData *menuData = gobj->userdata;\n    EventDesc *event_desc = menuData->event_desc;\n    Text *text;\n    int subtext;\n    int canvasIndex = menuData->canvas_menu;\n    s32 cursor = menu->cursor;\n\n    // free text if it exists\n    if (menuData->text_name != 0)\n    {\n        // free text\n        Text_Destroy(menuData->text_name);\n        menuData->text_name = 0;\n        Text_Destroy(menuData->text_value);\n        menuData->text_value = 0;\n        Text_Destroy(menuData->text_title);\n        menuData->text_title = 0;\n        Text_Destroy(menuData->text_desc);\n        menuData->text_desc = 0;\n    }\n    if (menuData->text_popup != 0)\n    {\n        Text_Destroy(menuData->text_popup);\n        menuData->text_popup = 0;\n    }\n\n    /*******************\n    *** Create Title ***\n    *******************/\n\n    text = Text_CreateText(2, canvasIndex);\n    text->gobj->gx_cb = EventMenu_TextGX;\n    menuData->text_title = text;\n    // enable align and kerning\n    text->align = 0;\n    text->kerning = 1;\n    text->use_aspect = 1;\n    // scale canvas\n    text->scale.X = MENU_CANVASSCALE;\n    text->scale.Y = MENU_CANVASSCALE;\n    text->trans.Z = MENU_TEXTZ;\n    text->aspect.X = MENU_TITLEASPECT;\n\n    // output menu title\n    float optionX = MENU_TITLEXPOS;\n    float optionY = MENU_TITLEYPOS;\n    subtext = Text_AddSubtext(text, optionX, optionY, &nullString);\n    Text_SetScale(text, subtext, MENU_TITLESCALE, MENU_TITLESCALE);\n\n    /**************************\n    *** Create Description ***\n    *************************/\n\n    text = Text_CreateText(2, canvasIndex);\n    text->gobj->gx_cb = EventMenu_TextGX;\n    menuData->text_desc = text;\n\n    /*******************\n    *** Create Names ***\n    *******************/\n\n    text = Text_CreateText(2, canvasIndex);\n    text->gobj->gx_cb = EventMenu_TextGX;\n    menuData->text_name = text;\n    // enable align and kerning\n    text->align = 0;\n    text->kerning = 1;\n    text->use_aspect = 1;\n    // scale canvas\n    text->scale.X = MENU_CANVASSCALE;\n    text->scale.Y = MENU_CANVASSCALE;\n    text->trans.Z = MENU_TEXTZ;\n    text->aspect.X = MENU_NAMEASPECT;\n\n    // Output all options\n    s32 option_num = menu->option_num;\n    if (option_num > MENU_MAXOPTION)\n        option_num = MENU_MAXOPTION;\n    for (int i = 0; i < option_num; i++)\n    {\n\n        // output option name\n        float optionX = MENU_OPTIONNAMEXPOS;\n        float optionY = MENU_OPTIONNAMEYPOS + (i * MENU_TEXTYOFFSET);\n        subtext = Text_AddSubtext(text, optionX, optionY, &nullString);\n    }\n\n    /********************\n    *** Create Values ***\n    ********************/\n\n    text = Text_CreateText(2, canvasIndex);\n    text->gobj->gx_cb = EventMenu_TextGX;\n    menuData->text_value = text;\n    // enable align and kerning\n    text->align = 1;\n    text->kerning = 1;\n    text->use_aspect = 1;\n    // scale canvas\n    text->scale.X = MENU_CANVASSCALE;\n    text->scale.Y = MENU_CANVASSCALE;\n    text->trans.Z = MENU_TEXTZ;\n    text->aspect.X = MENU_VALASPECT;\n\n    // Output all values\n    for (int i = 0; i < option_num; i++)\n    {\n        // output option value\n        float optionX = MENU_OPTIONVALXPOS;\n        float optionY = MENU_OPTIONVALYPOS + (i * MENU_TEXTYOFFSET);\n        subtext = Text_AddSubtext(text, optionX, optionY, &nullString);\n    }\n\n    return;\n}\n\nvoid EventMenu_UpdateText(GOBJ *gobj, EventMenu *menu)\n{\n\n    // Get event info\n    MenuData *menuData = gobj->userdata;\n    EventDesc *event_desc = menuData->event_desc;\n    s32 cursor = menu->cursor;\n    s32 scroll = menu->scroll;\n    s32 option_num = menu->option_num;\n    if (option_num > MENU_MAXOPTION)\n        option_num = MENU_MAXOPTION;\n    Text *text;\n\n    // Update Title\n\n    text = menuData->text_title;\n    Text_SetText(text, 0, menu->name);\n\n    // Update Description\n    Text_Destroy(menuData->text_desc); // i think its best to recreate it...\n    text = Text_CreateText(2, menuData->canvas_menu);\n    text->gobj->gx_cb = EventMenu_TextGX;\n    menuData->text_desc = text;\n    EventOption *currOption = &menu->options[menu->cursor + menu->scroll];\n\n#define DESC_TXTSIZEX 5\n#define DESC_TXTSIZEY 5\n#define DESC_TXTASPECT 885\n#define DESC_LINEMAX 4\n#define DESC_CHARMAX 100\n#define DESC_YOFFSET 30\n\n    text->kerning = 1;\n    text->align = 0;\n    text->use_aspect = 1;\n\n    // scale canvas\n    text->scale.X = 0.01 * DESC_TXTSIZEX;\n    text->scale.Y = 0.01 * DESC_TXTSIZEY;\n    text->trans.X = MENU_DESCXPOS;\n    text->trans.Y = MENU_DESCYPOS;\n    text->trans.Z = MENU_TEXTZ;\n    text->aspect.X = (DESC_TXTASPECT);\n\n    char *msg = currOption->desc;\n\n    // count newlines\n    int line_num = 1;\n    int line_length_arr[DESC_LINEMAX];\n    char *msg_cursor_prev, *msg_cursor_curr; // declare char pointers\n    msg_cursor_prev = msg;\n    msg_cursor_curr = strchr(msg_cursor_prev, '\\n'); // check for occurrence\n    while (msg_cursor_curr != 0)                     // if occurrence found, increment values\n    {\n        // check if exceeds max lines\n        if (line_num >= DESC_LINEMAX)\n            assert(\"DESC_LINEMAX exceeded!\");\n\n        // Save information about this line\n        line_length_arr[line_num - 1] = msg_cursor_curr - msg_cursor_prev; // determine length of the line\n        line_num++;                                                        // increment number of newlines found\n        msg_cursor_prev = msg_cursor_curr + 1;                             // update prev cursor\n        msg_cursor_curr = strchr(msg_cursor_prev, '\\n');                   // check for another occurrence\n    }\n\n    // get last lines length\n    msg_cursor_curr = strchr(msg_cursor_prev, 0);\n    line_length_arr[line_num - 1] = msg_cursor_curr - msg_cursor_prev;\n\n    // copy each line to an individual char array\n    char *msg_cursor = &msg;\n    for (int i = 0; i < line_num; i++)\n    {\n\n        // check if over char max\n        u8 line_length = line_length_arr[i];\n        if (line_length > DESC_CHARMAX)\n            assert(\"DESC_CHARMAX exceeded!\");\n\n        // copy char array\n        char msg_line[DESC_CHARMAX + 1];\n        memcpy(msg_line, msg, line_length);\n\n        // add null terminator\n        msg_line[line_length] = '\\0';\n\n        // increment msg\n        msg += (line_length + 1); // +1 to skip past newline\n\n        // print line\n        int y_delta = (i * DESC_YOFFSET);\n        Text_AddSubtext(text, 0, y_delta, msg_line);\n    }\n\n    /* \n    Update Names\n    */\n\n    // Output all options\n    text = menuData->text_name;\n    for (int i = 0; i < option_num; i++)\n    {\n        // get this option\n        EventOption *currOption = &menu->options[scroll + i];\n\n        // output option name\n        int optionVal = currOption->option_val;\n        Text_SetText(text, i, currOption->option_name);\n\n        // output color\n        GXColor color;\n        if (currOption->disable == 0)\n        {\n            color.r = 255;\n            color.b = 255;\n            color.g = 255;\n            color.a = 255;\n        }\n        else\n        {\n            color.r = 128;\n            color.b = 128;\n            color.g = 128;\n            color.a = 0;\n        }\n        Text_SetColor(text, i, &color);\n    }\n\n    /* \n    Update Values\n    */\n\n    // Output all values\n    text = menuData->text_value;\n    for (int i = 0; i < option_num; i++)\n    {\n        // get this option\n        EventOption *currOption = &menu->options[scroll + i];\n        int optionVal = currOption->option_val;\n\n        // hide row models\n        JOBJ_SetFlags(menuData->row_joints[i][0], JOBJ_HIDDEN);\n        JOBJ_SetFlags(menuData->row_joints[i][1], JOBJ_HIDDEN);\n\n        // if this option has string values\n        if (currOption->option_kind == OPTKIND_STRING)\n        {\n            // output option value\n            Text_SetText(text, i, currOption->option_values[optionVal]);\n\n            // show box\n            JOBJ_ClearFlags(menuData->row_joints[i][0], JOBJ_HIDDEN);\n        }\n\n        // if this option has int values\n        else if (currOption->option_kind == OPTKIND_INT)\n        {\n            // output option value\n            Text_SetText(text, i, currOption->option_values, optionVal);\n\n            // show box\n            JOBJ_ClearFlags(menuData->row_joints[i][0], JOBJ_HIDDEN);\n        }\n\n        // if this option is a menu or function\n        else if ((currOption->option_kind == OPTKIND_MENU) || (currOption->option_kind == OPTKIND_FUNC))\n        {\n            Text_SetText(text, i, &nullString);\n\n            // show arrow\n            //JOBJ_ClearFlags(menuData->row_joints[i][1], JOBJ_HIDDEN);\n        }\n\n        // output color\n        GXColor color;\n        if (currOption->disable == 0)\n        {\n            color.r = 255;\n            color.b = 255;\n            color.g = 255;\n            color.a = 255;\n        }\n        else\n        {\n            color.r = 128;\n            color.b = 128;\n            color.g = 128;\n            color.a = 0;\n        }\n        Text_SetColor(text, i, &color);\n    }\n\n    // update cursor position\n    JOBJ *highlight_joint = menuData->highlight_menu;\n    highlight_joint->trans.Y = cursor * MENUHIGHLIGHT_YOFFSET;\n\n    // update scrollbar position\n    if (menuData->scroll_top != 0)\n    {\n        float curr_steps = menuData->currMenu->scroll;\n        float max_steps;\n        if (menuData->currMenu->option_num < MENU_MAXOPTION)\n            max_steps = 0;\n        else\n            max_steps = menuData->currMenu->option_num - MENU_MAXOPTION;\n\n        // scrollTop = -1 * ((curr_steps/max_steps) * (botY - -10))\n        menuData->scroll_top->trans.Y = -1 * (curr_steps / max_steps) * (menuData->scroll_bot->trans.Y - MENUSCROLL_MAXLENGTH);\n    }\n\n    // update jobj\n    JOBJ_SetMtxDirtySub(gobj->hsd_object);\n\n    return;\n}\n\nvoid EventMenu_DestroyMenu(GOBJ *gobj)\n{\n    MenuData *menuData = gobj->userdata; // userdata\n\n    // remove\n    Text_Destroy(menuData->text_name);\n    menuData->text_name = 0;\n    // remove\n    Text_Destroy(menuData->text_value);\n    menuData->text_value = 0;\n    // remove\n    Text_Destroy(menuData->text_title);\n    menuData->text_title = 0;\n    // remove\n    Text_Destroy(menuData->text_desc);\n    menuData->text_desc = 0;\n\n    // if popup box exists\n    if (menuData->text_popup != 0)\n        EventMenu_DestroyPopup(gobj);\n\n    // if custom menu gobj exists\n    if (menuData->custom_gobj != 0)\n    {\n        // run on destroy function\n        if (menuData->custom_gobj_destroy != 0)\n            menuData->custom_gobj_destroy(menuData->custom_gobj);\n\n        // null pointers\n        menuData->custom_gobj = 0;\n        menuData->custom_gobj_destroy = 0;\n        menuData->custom_gobj_think = 0;\n    }\n\n    // set menu as visible\n    stc_event_vars.hide_menu = 0;\n\n    // remove jobj\n    GObj_FreeObject(gobj);\n    //GObj_DestroyGXLink(gobj);\n\n    return;\n}\n\nvoid EventMenu_CreatePopupModel(GOBJ *gobj, EventMenu *menu)\n{\n    // init variables\n    MenuData *menuData = gobj->userdata; // userdata\n    s32 cursor = menu->cursor;\n    EventOption *option = &menu->options[cursor];\n\n    // create options background\n    evMenu *menuAssets = stc_event_vars.menu_assets;\n\n    // create popup gobj\n    GOBJ *popup_gobj = GObj_Create(0, 0, 0);\n\n    // load popup joint\n    JOBJ *popup_joint = JOBJ_LoadJoint(menuAssets->popup);\n\n    // Get each corner's joints\n    JOBJ *corners[4];\n    JOBJ_GetChild(popup_joint, &corners, 2, 3, 4, 5, -1);\n\n    // Modify scale and position\n    popup_joint->scale.X = POPUP_SCALE;\n    popup_joint->scale.Y = POPUP_SCALE;\n    popup_joint->scale.Z = POPUP_SCALE;\n    popup_joint->trans.Z = POPUP_Z;\n    corners[0]->trans.X = -(POPUP_WIDTH / 2);\n    corners[0]->trans.Y = (POPUP_HEIGHT / 2);\n    corners[1]->trans.X = (POPUP_WIDTH / 2);\n    corners[1]->trans.Y = (POPUP_HEIGHT / 2);\n    corners[2]->trans.X = -(POPUP_WIDTH / 2);\n    corners[2]->trans.Y = -(POPUP_HEIGHT / 2);\n    corners[3]->trans.X = (POPUP_WIDTH / 2);\n    corners[3]->trans.Y = -(POPUP_HEIGHT / 2);\n\n    /*\n    // Change color\n    GXColor gx_color = TEXT_BGCOLOR;\n    popup_joint->dobj->mobj->mat->diffuse = gx_color;\n*/\n\n    // add to gobj\n    GObj_AddObject(popup_gobj, 3, popup_joint);\n    // add gx link\n    GObj_AddGXLink(popup_gobj, EventMenu_MenuGX, GXLINK_POPUPMODEL, GXPRI_POPUPMODEL);\n    // save pointer\n    menuData->popup = popup_gobj;\n\n    // adjust scrollbar scale\n\n    // position popup X and Y (based on cursor value)\n    popup_joint->trans.X = POPUP_X;\n    popup_joint->trans.Y = POPUP_Y + (POPUP_YOFFSET * cursor);\n\n    // create a highlight jobj\n    JOBJ *jobj_highlight = JOBJ_LoadJoint(menuAssets->popup);\n    // attach to root jobj\n    JOBJ_AddChild(popup_gobj->hsd_object, jobj_highlight);\n    // move it into position\n    JOBJ_GetChild(jobj_highlight, &corners, 2, 3, 4, 5, -1);\n    // Modify scale and position\n    jobj_highlight->trans.Z = POPUPHIGHLIGHT_Z;\n    jobj_highlight->scale.X = 1;\n    jobj_highlight->scale.Y = 1;\n    jobj_highlight->scale.Z = 1;\n    corners[0]->trans.X = -(POPUPHIGHLIGHT_WIDTH / 2) + POPUPHIGHLIGHT_X;\n    corners[0]->trans.Y = (POPUPHIGHLIGHT_HEIGHT / 2) + POPUPHIGHLIGHT_Y;\n    corners[1]->trans.X = (POPUPHIGHLIGHT_WIDTH / 2) + POPUPHIGHLIGHT_X;\n    corners[1]->trans.Y = (POPUPHIGHLIGHT_HEIGHT / 2) + POPUPHIGHLIGHT_Y;\n    corners[2]->trans.X = -(POPUPHIGHLIGHT_WIDTH / 2) + POPUPHIGHLIGHT_X;\n    corners[2]->trans.Y = -(POPUPHIGHLIGHT_HEIGHT / 2) + POPUPHIGHLIGHT_Y;\n    corners[3]->trans.X = (POPUPHIGHLIGHT_WIDTH / 2) + POPUPHIGHLIGHT_X;\n    corners[3]->trans.Y = -(POPUPHIGHLIGHT_HEIGHT / 2) + POPUPHIGHLIGHT_Y;\n    GXColor highlight = POPUPHIGHLIGHT_COLOR;\n    jobj_highlight->dobj->next->mobj->mat->alpha = 0.6;\n    jobj_highlight->dobj->next->mobj->mat->diffuse = highlight;\n\n    menuData->highlight_popup = jobj_highlight;\n\n    return;\n}\n\nvoid EventMenu_CreatePopupText(GOBJ *gobj, EventMenu *menu)\n{\n    // init variables\n    MenuData *menuData = gobj->userdata;\n    s32 cursor = menu->cursor;\n    EventOption *option = &menu->options[cursor];\n    int subtext;\n    int canvasIndex = menuData->canvas_popup;\n    s32 value_num = option->value_num;\n    if (value_num > MENU_POPMAXOPTION)\n        value_num = MENU_POPMAXOPTION;\n\n    ///////////////////\n    // Create Values //\n    ///////////////////\n\n    Text *text = Text_CreateText(2, canvasIndex);\n    text->gobj->gx_cb = EventMenu_TextGX;\n    menuData->text_popup = text;\n    // enable align and kerning\n    text->align = 1;\n    text->kerning = 1;\n    // scale canvas\n    text->scale.X = POPUP_CANVASSCALE;\n    text->scale.Y = POPUP_CANVASSCALE;\n    text->trans.Z = POPUP_TEXTZ;\n\n    // determine base Y value\n    float baseYPos = POPUP_OPTIONVALYPOS + (cursor * MENU_TEXTYOFFSET);\n\n    // Output all values\n    for (int i = 0; i < value_num; i++)\n    {\n        // output option value\n        float optionX = POPUP_OPTIONVALXPOS;\n        float optionY = baseYPos + (i * POPUP_TEXTYOFFSET);\n        subtext = Text_AddSubtext(text, optionX, optionY, &nullString);\n    }\n\n    return;\n}\n\nvoid EventMenu_UpdatePopupText(GOBJ *gobj, EventOption *option)\n{\n    // init variables\n    MenuData *menuData = gobj->userdata; // userdata\n    s32 cursor = menuData->popup_cursor;\n    s32 scroll = menuData->popup_scroll;\n    s32 value_num = option->value_num;\n    if (value_num > MENU_POPMAXOPTION)\n        value_num = MENU_POPMAXOPTION;\n\n    ///////////////////\n    // Update Values //\n    ///////////////////\n\n    Text *text = menuData->text_popup;\n\n    // update int list\n    if (option->option_kind == OPTKIND_INT)\n    {\n        // Output all values\n        for (int i = 0; i < value_num; i++)\n        {\n            // output option value\n            Text_SetText(text, i, \"%d\", scroll + i);\n        }\n    }\n\n    // update string list\n    else if (option->option_kind == OPTKIND_STRING)\n    {\n        // Output all values\n        for (int i = 0; i < value_num; i++)\n        {\n            // output option value\n            Text_SetText(text, i, option->option_values[scroll + i]);\n        }\n    }\n\n    // update cursor position\n    JOBJ *highlight_joint = menuData->highlight_popup;\n    highlight_joint->trans.Y = cursor * POPUPHIGHLIGHT_YOFFSET;\n    JOBJ_SetMtxDirtySub(highlight_joint);\n\n    return;\n}\n\nvoid EventMenu_DestroyPopup(GOBJ *gobj)\n{\n    MenuData *menuData = gobj->userdata; // userdata\n\n    // remove text\n    Text_Destroy(menuData->text_popup);\n    menuData->text_popup = 0;\n\n    // destory gobj\n    GObj_Destroy(menuData->popup);\n    menuData->popup = 0;\n\n    // also change the menus state\n    EventMenu *currMenu = menuData->currMenu;\n    currMenu->state = EMSTATE_FOCUS;\n}\n\n///////////////////////////////\n/// Member-Access Functions ///\n///////////////////////////////\n\nEventDesc *GetEventDesc(int page, int event)\n{\n    EventPage *thisPage = EventPages[page];\n    EventDesc *thisEvent = thisPage->events[event];\n    return (thisEvent);\n}\nchar *GetEventName(int page, int event)\n{\n    EventDesc *thisEvent = GetEventDesc(page, event);\n    return (thisEvent->eventName);\n}\nchar *GetEventDescription(int page, int event)\n{\n    EventDesc *thisEvent = GetEventDesc(page, event);\n    return (thisEvent->eventDescription);\n}\nchar *GetEventTut(int page, int event)\n{\n    EventDesc *thisEvent = GetEventDesc(page, event);\n    return (thisEvent->eventTutorial);\n}\nchar *GetPageName(int page)\n{\n    EventPage *thisPage = EventPages[page];\n    return (thisPage->name);\n}\nchar *GetEventFile(int page, int event)\n{\n    EventDesc *thisEvent = GetEventDesc(page, event);\n    return (thisEvent->eventFile);\n}\nchar *GetCSSFile(int page, int event)\n{\n    EventDesc *thisEvent = GetEventDesc(page, event);\n    return (thisEvent->eventCSSFile);\n}\nint GetPageEventNum(int page)\n{\n    EventPage *thisPage = EventPages[page];\n    return (thisPage->eventNum);\n}\nchar *GetTMVersShort()\n{\n    return (TM_VersShort);\n}\nchar *GetTMVersLong()\n{\n    return (TM_VersLong);\n}\nchar *GetTMCompile()\n{\n    return (TM_Compile);\n}\nint GetPageNum()\n{\n    int pageNum = (sizeof(EventPages) / 4) - 1;\n    return (pageNum);\n}\nu8 GetIsChooseCPU(int page, int event)\n{\n    EventDesc *thisEvent = GetEventDesc(page, event);\n    return (thisEvent->isChooseCPU);\n}\nu8 GetIsSelectStage(int page, int event)\n{\n    EventDesc *thisEvent = GetEventDesc(page, event);\n    return (thisEvent->isSelectStage);\n}\ns8 GetFighter(int page, int event)\n{\n    EventDesc *thisEvent = GetEventDesc(page, event);\n    return (thisEvent->matchData->playerKind);\n}\ns8 GetCPUFighter(int page, int event)\n{\n    EventDesc *thisEvent = GetEventDesc(page, event);\n    return (thisEvent->matchData->cpuKind);\n}\ns16 GetStage(int page, int event)\n{\n    EventDesc *thisEvent = GetEventDesc(page, event);\n    return (thisEvent->matchData->stage);\n}\n"
  },
  {
    "path": "patch/tmdata/source/events.h",
    "content": "#include \"../../../MexTK/mex.h\"\n\n#define TM_VERSSHORT \"TM v3.0-a8\"\n#define TM_VERSLONG \"Training Mode v3.0 Alpha 8\"\n#define TM_DEBUG 0 // 0 = release (no logging), 1 = OSReport logs, 2 = onscreen logs\n#define EVENT_DATASIZE 512\n#define TM_DATA -(50 * 4) - 4\n#define MENU_MAXOPTION 9\n#define MENU_POPMAXOPTION 5\n\n#define TMLOG(...) DevelopText_AddString(event_vars->db_console_text, __VA_ARGS__)\n\n// disable all logs in release mode\n#if TM_DEBUG == 0\n#define OSReport (void)sizeof\n#define TMLOG (void)sizeof\n//#define assert (void)sizeof\n#endif\n\n// use OSReport for all logs\n#if TM_DEBUG == 1\n#define OSReport OSReport\n#endif\n\n// use TMLog for all logs\n#if TM_DEBUG == 2\n#define OSReport TMLOG\n#endif\n\n// Custom File Structs\ntypedef struct evMenu\n{\n    JOBJDesc *menu;\n    JOBJDesc *popup;\n    JOBJDesc *scroll;\n    JOBJDesc *check;\n    JOBJDesc *arrow;\n    JOBJDesc *playback;\n    JOBJDesc *message;\n    COBJDesc *hud_cobjdesc;\n    JOBJ *tip_jobj;\n    void **tip_jointanim; // pointer to array\n} evMenu;\n\n// Structure Definitions\ntypedef struct EventMenu EventMenu;\ntypedef struct EventMatchData\n{\n    unsigned int timer : 2;\n    unsigned int matchType : 3;\n    unsigned int isDisableMusic : 1;\n    unsigned int hideGo : 1;\n    unsigned int hideReady : 1;\n    unsigned int isCreateHUD : 1;\n    unsigned int isDisablePause : 1;\n    unsigned int timerRunOnPause : 1;    // 0x01\n    unsigned int isHidePauseHUD : 1;     // 0x02\n    unsigned int isShowLRAStart : 1;     // 0x04\n    unsigned int isCheckForLRAStart : 1; // 0x08\n    unsigned int isShowZRetry : 1;       // 0x10\n    unsigned int isCheckForZRetry : 1;   // 0x20\n    unsigned int isShowAnalogStick : 1;  // 0x40\n    unsigned int isShowScore : 1;        // 0x80\n    unsigned int isRunStockLogic : 1;    // 0x20\n    unsigned int isDisableHit : 1;       // 0x20\n    unsigned int useKOCounter : 1;\n    s8 playerKind;                    // -1 = use selected fighter\n    s8 cpuKind;                       // -1 = no CPU\n    s16 stage;                        // -1 = use selected stage\n    unsigned int timerSeconds : 32;   // 0xFFFFFFFF\n    unsigned int timerSubSeconds : 8; // 0xFF\n    void *onCheckPause;\n    void *onMatchEnd;\n} EventMatchData;\ntypedef struct EventDesc\n{\n    char *eventName;\n    char *eventDescription;\n    char *eventTutorial;\n    char *eventFile;\n    char *eventCSSFile;\n    u8 isChooseCPU : 1;\n    u8 isSelectStage : 1;\n    u8 use_savestates : 1;  // enables dpad left and right savestates\n    u8 disable_hazards : 1; // removes stage hazards\n    u8 scoreType;\n    u8 callbackPriority;\n    EventMatchData *matchData;\n    int defaultOSD;\n} EventDesc;\ntypedef struct EventPage\n{\n    char *name;\n    int eventNum;\n    EventDesc **events;\n} EventPage;\ntypedef struct EventOption\n{\n    u8 option_kind;                                     // the type of option this is; string, integers, etc\n    u8 disable;                                         // boolean for disabling the option\n    u16 value_num;                                      // number of values\n    u16 option_val;                                     // value of this option\n    EventMenu *menu;                                    // pointer to the menu that pressing A opens\n    char *option_name;                                  // pointer to the name of this option\n    char *desc;                                         // pointer to the description string for this option\n    void **option_values;                               // pointer to an array of strings\n    void (*onOptionChange)(GOBJ *menu_gobj, int value); // function that runs when option is changed\n    GOBJ *(*onOptionSelect)(GOBJ *menu_gobj);           // function that runs when option is selected\n} EventOption;\nstruct EventMenu\n{\n    char *name;                         // name of this menu\n    u8 option_num;                      // number of options this menu contains\n    u8 scroll;                          //\n    u8 state;                           // bool used to know if this menu is focused\n    u8 cursor;                          // index of the option currently selected\n    EventOption *options;               // pointer to all of this menu's options\n    EventMenu *prev;                    // pointer to previous menu, used at runtime\n    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\n};\ntypedef struct MenuData\n{\n    EventDesc *event_desc;\n    EventMenu *currMenu;\n    u16 canvas_menu;\n    u16 canvas_popup;\n    u8 isPaused;\n    u8 controller_index; // index of the controller who paused\n    Text *text_name;\n    Text *text_value;\n    Text *text_popup;\n    Text *text_title;\n    Text *text_desc;\n    u16 popup_cursor;\n    u16 popup_scroll;\n    GOBJ *popup;\n    evMenu *menu_assets;\n    JOBJ *row_joints[MENU_MAXOPTION][2]; // pointers to row jobjs\n    JOBJ *highlight_menu;                // pointer to the highlight jobj\n    JOBJ *highlight_popup;               // pointer to the highlight jobj\n    JOBJ *scroll_top;\n    JOBJ *scroll_bot;\n    GOBJ *custom_gobj;                               // onSelect gobj\n    int (*custom_gobj_think)(GOBJ *custom_gobj);     // per frame function. Returns bool indicating if the program should check to unpause\n    void *(*custom_gobj_destroy)(GOBJ *custom_gobj); // on destroy function\n} MenuData;\ntypedef struct FtStateData\n{\n    int is_exist;\n    int state;\n    float facing_direction;\n    float stateFrame;\n    float stateSpeed;\n    float stateBlend;\n    Vec4 XRotN_rot; // XRotN\n    struct\n    {                                                          //\n        Vec3 anim_vel;                                         // 0x74\n        Vec3 self_vel;                                         // 0x80\n        Vec3 kb_vel;                                           // 0x8C\n        int x98;                                               // 0x98\n        int x9c;                                               // 0x9C\n        int xa0;                                               // 0xA0\n        int xa4;                                               // 0xA4\n        int xa8;                                               // 0xA8\n        int xac;                                               // 0xAC\n        Vec3 pos;                                              // 0xb0\n        Vec3 pos_prev;                                         // 0xBC\n        Vec3 pos_delta;                                        // 0xC8\n        Vec3 unknownD4;                                        // 0xD4\n        int air_state;                                         // 0xE0\n        float horzitonal_velocity_queue_will_be_added_to_0xec; // 0xE4\n        float vertical_velocity_queue_will_be_added_to_0xec;   // 0xE8\n        Vec3 selfVelGround;                                    // 0xEC\n        int unknownF8;                                         // 0xF8\n        int unknownFC;                                         // 0xFC\n        int unknown100;                                        // 0x100\n    } phys;                                                    //\n    ColorOverlay color[3];\n    struct\n    {                               //\n        float lstick_x;             // 0x620\n        float lstick_y;             // 0x624\n        float lstick_prev_x;        // 0x628\n        float lstick_prev_y;        // 0x62C\n        int unknown630;             // 0x630\n        int unknown634;             // 0x634\n        float cstick_x;             // 0x638\n        float cstick_y;             // 0x63C\n        int x640;                   // 0x640\n        int unknown644;             // 0x644\n        int unknown648;             // 0x648\n        int unknown64C;             // 0x64C\n        float trigger;              // 0x650\n        int unknown654;             // 0x654\n        int unknown658;             // 0x658\n        int held;                   // 0x65C\n        int held_prev;              // 0x660\n        int unknown664;             // 0x664\n        int pressed;                // 0x668\n        int unknown66C;             // 0x66C\n        char timer_lstick_tilt_x;   // 0x670\n        char timer_lstick_tilt_y;   // 0x671\n        char timer_trigger_analog;  // 0x672\n        char timer_lstick_smash_x;  // 0x673\n        char timer_lstick_smash_y;  // 0x674\n        char timer_trigger_digital; // 0x675\n        char timer_lstick_any_x;    // 0x676\n        char timer_lstick_any_y;    // 0x677\n        char timer_trigger_any;     // 0x678\n        char x679;                  // 0x679\n        char x67A;                  // 0x67A\n        char x67B;                  // 0x67B\n        char timer_a;               // 0x67C\n        char timer_b;               // 0x67D\n        char timer_xy;              // 0x67E\n        char timer_z;               // 0x67F\n        char timer_LR;              // 0x680\n        char timer_padup;           // 0x681\n        char timer_paddown;         // 0x682\n        char timer_item_release;    // 0x683\n        char sinceRapidLR;          // 0x684\n        char timer_unk2;            // 0x685\n        char timer_unk3;            // 0x686\n        char timer_unk4;            // 0x687\n        char timer_sideb;           // 0x688\n        char timer_neutralb;        // 0x689\n        char timer_unk5;            // 0x68A\n        char timer_unk6;            // 0x68B\n    } input;                        //\n    CollData coll_data;\n    CameraBox cameraBox;\n    ftHit hitbox[4];\n    ftHit throw_hitbox[2];\n    ftHit unk_hitbox;\n    struct\n    {\n        unsigned char throw_1 : 1;               // 0x80 - x2210\n        unsigned char throw_2 : 1;               // 0x40 - x2210\n        unsigned char throw_3 : 1;               // 0x20 - x2210\n        unsigned char throw_release : 1;         // 0x10 - x2210. also used to change users direction during aerial attacks\n        unsigned char throw_turn : 1;            // 0x8 - x2210\n        unsigned char throw_6 : 1;               // 0x4 - x2210\n        unsigned char throw_7 : 1;               // 0x2 - x2210\n        unsigned char throw_8 : 1;               // 0x1 - x2210\n        float throw_timerval;                    // equal to script_event_timer of the attacker\n        unsigned char x2218_1 : 1;               // 0x80 - x2218\n        unsigned char x2218_2 : 1;               // 0x40 - x2218\n        unsigned char x2218_3 : 1;               // 0x20 - x2218\n        unsigned char reflect_enable : 1;        // 0x10 - x2218\n        unsigned char reflect_nochangeowner : 1; // 0x8 - x2218\n        unsigned char x2218_6 : 1;               // 0x4 - x2218\n        unsigned char absorb_enable : 1;         // 0x2 - x2218\n        unsigned char absorb_unk : 1;            // 0x1 - x2218\n        unsigned char shield : 1;                // is shielding bool. 0x80 - 0x2219\n        unsigned char immune : 1;                // 0x40 - 0x2219\n        unsigned char x2219_3 : 1;               // 0x20 - 0x2219\n        unsigned char hitbox_active : 1;         // 0x10 - 0x2219\n        unsigned char x2219_5 : 1;               // 0x8 - 0x2219\n        unsigned char freeze : 1;                // 0x4 - 0x2219\n        unsigned char hitlag_unk : 1;            // 0x2 - 0x2219\n        unsigned char hitlag_unk2 : 1;           // 0x1 - 0x2219\n        unsigned char x221a_1 : 1;               // 0x80 - 0x221a\n        unsigned char x221a_2 : 1;               // 0x40 - 0x221a\n        unsigned char hitlag : 1;                // 0x20 - 0x221a\n        unsigned char x221a_4 : 1;               // 0x10 - 0x221a\n        unsigned char fastfall : 1;              // 0x8 - 0x221a\n        unsigned char no_hurt_script : 1;        // 0x4 - 0x221a\n        unsigned char x221a_7 : 1;               // 0x2 - 0x221a\n        unsigned char gfx_persist : 1;           // 0x1 - 0x221a\n        unsigned char shield_enable : 1;         // 0x80 - 0x221b\n        unsigned char shield_x40 : 1;            // 0x40 - 0x221b\n        unsigned char shield_x20 : 1;            // 0x20 - 0x221b\n        unsigned char shield_x10 : 1;            // 0x10 - 0x221b\n        unsigned char shield_x8 : 1;             //  0x8 - 0x221b\n        unsigned char x221b_6 : 1;               // 0x4 - 0x221b\n        unsigned char x221b_7 : 1;               // 0x2 - 0x221b\n        unsigned char x221b_8 : 1;               // 0x1 - 0x221b\n        unsigned char x221c_1 : 1;               // 0x80 - 0x221c\n        unsigned char x221c_2 : 1;               // 0x40 - 0x221c\n        unsigned char x221c_3 : 1;               // 0x20 - 0x221c\n        unsigned char x221c_4 : 1;               // 0x10 - 0x221c\n        unsigned char x221c_5 : 1;               // 0x8 - 0x221c\n        unsigned char x221c_6 : 1;               // 0x4 - 0x221c\n        unsigned char hitstun : 1;               // 0x2 - 0x221c\n        unsigned char x221c_8 : 1;               // 0x1 = 0x221c\n        unsigned char x221d_1 : 1;               // 0x80 - 0x221d\n        unsigned char x221d_2 : 1;               // 0x40 - 0x221d\n        unsigned char x221d_3 : 1;               // 0x20 - 0x221d\n        unsigned char input_enable : 1;          // 0x10 - 0x221d\n        unsigned char x221d_5 : 1;               // 0x8 - 0x221d\n        unsigned char nudge_disable : 1;         // 0x4 - 0x221d\n        unsigned char ground_ignore : 1;         // 0x2 - 0x221d\n        unsigned char x221d_8 : 1;               // 0x1 - 0x221d\n        unsigned char invisible : 1;             // 0x80 - 0x221e\n        unsigned char x221e_2 : 1;               // 0x40 - 0x221e\n        unsigned char x221e_3 : 1;               // 0x20 - 0x221e\n        unsigned char isItemVisible : 1;         // 0x10 - 0x221e\n        unsigned char x221e_5 : 1;               // 0x8 - 0x221e\n        unsigned char x221e_6 : 1;               // 0x4 - 0x221e\n        unsigned char x221e_7 : 1;               // 0x2 - 0x221e\n        unsigned char x221e_8 : 1;               // 0x1 - 0x221e\n        unsigned char mag_glass : 1;             // 0x80 - 0x221f\n        unsigned char dead : 1;                  // 0x40 - 0x221f\n        unsigned char x221f_3 : 1;               // 0x20 - 0x221f\n        unsigned char sleep : 1;                 // 0x10\n        unsigned char ms : 1;                    // ms = master/slave. is 1 when the player is a slave\n        unsigned char x221f_6 : 1;\n        unsigned char x221f_7 : 1;\n        unsigned char x221f_8 : 1;\n        char flags_2220;                      // 0x2220\n        char flags_2221;                      // 0x2221\n        char flags_2222;                      // 0x2222\n        char flags_2223;                      // 0x2223\n        unsigned char x2224_1 : 1;            // 0x80 - 0x2224\n        unsigned char x2224_2 : 1;            // 0x40 - 0x2224\n        unsigned char stamina_dead : 1;       // 0x20 - 0x2224\n        unsigned char x2224_4 : 1;            // 0x10 - 0x2224\n        unsigned char x2224_5 : 1;            // 0x8 - 0x2224\n        unsigned char x2224_6 : 1;            // 0x4 - 0x2224\n        unsigned char x2224_7 : 1;            // 0x2 - 0x2224\n        unsigned char x2224_8 : 1;            // 0x1 - 0x2224\n        char flags_2225;                      // 0x2225\n        unsigned char x2226_1 : 1;            // 0x80 - 0x2226\n        unsigned char x2226_2 : 1;            // 0x40 - 0x2226\n        unsigned char is_thrown : 1;          // 0x20 - 0x2226\n        unsigned char x2226_4 : 1;            // 0x10 - 0x2226\n        unsigned char x2226_5 : 1;            // 0x8 - 0x2226\n        unsigned char x2226_6 : 1;            // 0x4 - 0x2226\n        unsigned char x2226_7 : 1;            // 0x2 - 0x2226\n        unsigned char x2226_8 : 1;            // 0x1 - 0x2226\n        char flags_2227;                      // 0x2227\n        char flags_2228;                      // 0x2228\n        unsigned char x2229_1 : 1;            // 0x80 - 0x2229\n        unsigned char x2229_2 : 1;            // 0x40 - 0x2229\n        unsigned char x2229_3 : 1;            // 0x20 - 0x2229\n        unsigned char x2229_4 : 1;            // 0x10 - 0x2229\n        unsigned char x2229_5 : 1;            // 0x8 - 0x2229\n        unsigned char x2229_6 : 1;            // 0x4 - 0x2229\n        unsigned char x2229_7 : 1;            // 0x2 - 0x2229\n        unsigned char no_reaction_always : 1; // 0x1 - 0x2229\n        char flags_222A;                      // 0x222A\n        char flags_222B;                      // 0x222B\n    } flags;                                  //\n    struct\n    {\n        int charVar1;  // 0x222c\n        int charVar2;  // 0x2230\n        int charVar3;  // 0x2234\n        int charVar4;  // 0x2238\n        int charVar5;  // 0x223c\n        int charVar6;  // 0x2240\n        int charVar7;  // 0x2244\n        int charVar8;  // 0x2248\n        int charVar9;  // 0x224c\n        int charVar10; // 0x2250\n        int charVar11; // 0x2254\n        int charVar12; // 0x2258\n        int charVar13; // 0x225c\n        int charVar14; // 0x2260\n        int charVar15; // 0x2264\n        int charVar16; // 0x2268\n        int charVar17; // 0x226c\n        int charVar18; // 0x2270\n        int charVar19; // 0x2274\n        int charVar20; // 0x2278\n        int charVar21; // 0x227c\n        int charVar22; // 0x2280\n        int charVar23; // 0x2284\n        int charVar24; // 0x2288\n        int charVar25; // 0x228c\n        int charVar26; // 0x2290\n        int charVar27; // 0x2294\n        int charVar28; // 0x2298\n        int charVar29; // 0x229c\n        int charVar30; // 0x22a0\n        int charVar31; // 0x22a4\n        int charVar32; // 0x22a8\n        int charVar33; // 0x22ac\n        int charVar34; // 0x22b0\n        int charVar35; // 0x22b4\n        int charVar36; // 0x22b8\n        int charVar37; // 0x22bc\n        int charVar38; // 0x22c0\n        int charVar39; // 0x22c4\n        int charVar40; // 0x22c8\n        int charVar41; // 0x22cc\n        int charVar42; // 0x22d0\n        int charVar43; // 0x22d4\n        int charVar44; // 0x22d8\n        int charVar45; // 0x22dc\n        int charVar46; // 0x22e0\n        int charVar47; // 0x22e4\n        int charVar48; // 0x22e8\n        int charVar49; // 0x22ec\n        int charVar50; // 0x22f0\n        int charVar51; // 0x22f4\n        int charVar52; // 0x22f8\n    } fighter_var;\n    struct\n    {                   //\n        int stateVar1;  // 0x2340\n        int stateVar2;  // 0x2344\n        int stateVar3;  // 0x2348\n        int stateVar4;  // 0x234c\n        int stateVar5;  // 0x2350\n        int stateVar6;  // 0x2354\n        int stateVar7;  // 0x2358\n        int stateVar8;  // 0x235c\n        int stateVar9;  // 0x2360\n        int stateVar10; // 0x2364\n        int stateVar11; // 0x2368\n        int stateVar12; // 0x236c\n        int stateVar13; // 0x2370\n        int stateVar14; // 0x2374\n        int stateVar15; // 0x2378\n        int stateVar16; // 0x237c\n        int stateVar17; // 0x2380\n        int stateVar18; // 0x2384\n    } state_var;        //\n    struct\n    {                       //\n        int subactionFlag0; // 0x2200\n        int subactionFlag1; // 0x2204\n        int subactionFlag2; // 0x2208\n        int subactionFlag3; // 0x220C\n    } ftcmd_var;            //\n    struct\n    {                           //\n        int behavior;           // 0x182c\n        float percent;          // 0x1830\n        int x1834;              // 0x1834\n        float percent_temp;     // 0x1838\n        float applied;          // 0x183c\n        int x1840;              // 0x1840\n        float direction;        // 0x1844\n        int kb_angle;           // 0x1848\n        int damaged_hurtbox;    // 0x184c\n        float force_applied;    // 0x1850\n        Vec3 collpos;           // 0x1854\n        int dealt;              // 0x1860\n        int x1864;              // 0x1864\n        GOBJ *source;           // 0x1868\n        int x186c;              // 0x186c\n        int x1870;              // 0x1870\n        int x1874;              // 0x1874\n        int x1878;              // 0x1878\n        int x187c;              // 0x187c\n        int x1880;              // 0x1880\n        int x1884;              // 0x1884\n        int x1888;              // 0x1888\n        int x188c;              // 0x188c\n        int x1890;              // 0x1890\n        int x1894;              // 0x1894\n        int x1898;              // 0x1898\n        int x189c;              // 0x189c\n        int x18a0;              // 0x18a0\n        float kb_mag;           // 0x18a4  kb magnitude\n        int x18a8;              // 0x18a8\n        int time_since_hit;     // 0x18ac   in frames\n        int x18b0;              // 0x18b0\n        float armor;            // 0x18b4\n        int x18b8;              // 0x18b8\n        int x18bc;              // 0x18bc\n        int x18c0;              // 0x18c0\n        int source_ply;         // 0x18c4   damage source ply number\n        int x18c8;              // 0x18c8\n        int x18cc;              // 0x18cc\n        int x18d0;              // 0x18d0\n        int x18d4;              // 0x18d4\n        int x18d8;              // 0x18d8\n        int x18dc;              // 0x18dc\n        int x18e0;              // 0x18e0\n        int x18e4;              // 0x18e4\n        int x18e8;              // 0x18e8\n        u16 instancehitby;      // 0x18ec. Last Move Instance This Player Was Hit by\n        int x18f0;              // 0x18f0\n        int x18f4;              // 0x18f4\n        u8 x18f8;               // 0x18f8\n        u8 x18f9;               // 0x18f8\n        u16 model_shift_frames; // 0x18f8\n        int x18fc;              // 0x18fc\n        int x1900;              // 0x1900\n        int x1904;              // 0x1904\n        int x1908;              // 0x1908\n        int x190c;              // 0x190c\n        int x1910;              // 0x1910\n        int x1914;              // 0x1914\n        int x1918;              // 0x1918\n        int x191c;              // 0x191c\n        int x1920;              // 0x1920\n        int x1924;              // 0x1924\n        int x1928;              // 0x1928\n        int x192c;              // 0x192c\n        int x1930;              // 0x1930\n        int x1934;              // 0x1934\n        int x1938;              // 0x1938\n        int x193c;              // 0x193c\n        int x1940;              // 0x1940\n        int x1944;              // 0x1944\n        int x1948;              // 0x1948\n        int x194c;              // 0x194c\n        int x1950;              // 0x1950\n        int x1954;              // 0x1954\n        int x1958;              // 0x1958\n        float hitlag_frames;    // 0x195c\n    } dmg;                      //\n    struct\n    {                        //\n        float grab_timer;    // 0x1a4c\n        int x1a50;           // 0x1a50\n        int x1a54;           // 0x1a54\n        GOBJ *grab_attacker; // 0x1a58\n        GOBJ *grab_victim;   // 0x1a5c\n        int x1a60;           // 0x1a60\n        int x1a64;           // 0x1a64\n        u16 x1a68;           // 0x1a68\n        u16 vuln;            // 0x1a6a\n        int x1a6c;           // 0x1a6c\n        int x1a70;           // 0x1a70\n        int x1a74;           // 0x1a74\n        int x1a78;           // 0x1a78\n        int x1a7c;           // 0x1a7c\n        int x1a80;           // 0x1a80\n        int x1a84;           // 0x1a84\n    } grab;                  //\n    struct                   // 0x1968\n    {                        //\n        char jumps_used;     // 0x1968\n        char walljumps_used; // 0x1969\n    } jump;\n    struct // 0x2114\n    {\n        int state;          // 0x2114 0 = none, 1 = pre-charge, 2 = charging, 3 = release\n        int frame;          // 0x2118 number of frames fighter has charged for\n        float hold_frame;   // 0x211c frame that charge begins/ends\n        float dmg_mult;     // 0x2120 damage multiplier\n        float speed_mult;   // 0x2124 speed multiplier?\n        int x2128;          // 0x2128\n        int x212c;          // 0x212c\n        int is_sfx_played;  // 0x2130 bool for smash sfx?\n        u8 vibrate_frame;   // 0x2134\n        u8 x2135;           // 0x2135\n        float since_hitbox; // 0x2138\n    } smash;\n    struct                       // 0x1988\n    {                            //\n        int script;              // 0x1988\n        int game;                // 0x198c\n        int ledge_intang_left;   // 0x1990\n        int respawn_intang_left; // 0x1994\n    } hurtstatus;\n    struct\n    {\n        float health;          // 0x1998\n        float lightshield_amt; // 0x199c\n        int dmg_taken;         // 0x19a0, seems to be all damage taken during the frame, is reset at the end of the frame\n        int dmg_taken2;        // 0x19a4, idk there so many of these\n        GOBJ *dmg_source;      // 0x19a8, points to the entity that hit the shield\n        float hit_direction;   // 0x19ac\n        int hit_attr;          // 0x19b0, attribute of the hitbox that collided\n        float x19b4;           // 0x19b4\n        float x19b8;           // 0x19b8\n        int dmg_taken3;        // 0x19bc, seems to be the most recent amount of damage taken\n    } shield;\n    struct\n    {\n        JOBJ *bone;                   // 0x19c0\n        unsigned char is_checked : 1; // 0x19d0 0x80. is checked for collision when 0\n        Vec3 pos;                     // 19d4\n        Vec3 offset;                  // 0x19d4\n        float size_mult;              // 0x19e0\n    } shield_bubble;\n    struct\n    {\n        JOBJ *bone;                   // 0x19e4\n        unsigned char is_checked : 1; // 0x19d0 0x80. is checked for collision when 0\n        Vec3 pos;                     // 0x19d4\n        Vec3 offset;                  // 0x19f8\n        float size_mult;              // 0x1a04\n    } reflect_bubble;\n    struct\n    {\n        JOBJ *bone;                   // 0x1a08\n        unsigned char is_checked : 1; // 0x1a0c 0x80. is checked for collision when 0\n        Vec3 pos;                     // 0x1a10\n        Vec3 offset;                  // 0x1a1c\n        float size_mult;              // 0x1a28\n    } absorb_bubble;\n    struct\n    {                        //\n        float hit_direction; // 0x1a2c\n        int max_dmg;         // 0x1a30\n        float dmg_mult;      // 0x1a34\n        int is_break;        // 0x1a38\n    } reflect_hit;           //\n    struct\n    {                        //\n        int x1a3c;           // 0x1a3c\n        float hit_direction; // 0x1a40\n        int dmg_taken;       // 0x1a44\n        int hits_taken;      // 0x1a48\n    } absorb_hit;            //\n    struct\n    {\n        void (*OnGrabFighter_Self)(GOBJ *fighter);   // 0x2190\n        void (*x2194)(GOBJ *fighter);                // 0x2194\n        void (*OnGrabFighter_Victim)(GOBJ *fighter); // 0x2198\n        void (*IASA)(GOBJ *fighter);                 // 0x219C\n        void (*Anim)(GOBJ *fighter);                 // 0x21A0\n        void (*Phys)(GOBJ *fighter);                 // 0x21a4\n        void (*Coll)(GOBJ *fighter);                 // 0x21a8\n        void (*Cam)(GOBJ *fighter);                  // 0x21ac\n        void (*Accessory1)(GOBJ *fighter);           // 0x21b0\n        void (*Accessory2)(GOBJ *fighter);           // 0x21b4\n        void (*Accessory3)(GOBJ *fighter);           // 0x21b8\n        void (*Accessory4)(GOBJ *fighter);           // 0x21bc\n        void (*OnGiveDamage)(GOBJ *fighter);         // 0x21c0\n        void (*OnShieldHit)(GOBJ *fighter);          // 0x21c4\n        void (*OnReflectHit)(GOBJ *fighter);         // 0x21c8\n        void (*x21cc)(GOBJ *fighter);                // 0x21cc\n        void (*EveryHitlag)(GOBJ *fighter);          // 0x21d0\n        void (*EnterHitlag)(GOBJ *fighter);          // 0x21d4\n        void (*ExitHitlag)(GOBJ *fighter);           // 0x21d8\n        void (*OnTakeDamage)(GOBJ *fighter);         // 0x21dc\n        void (*OnDeath)(GOBJ *fighter);              // 0x21e0\n        void (*OnDeath2)(GOBJ *fighter);             // 0x21e4\n        void (*OnDeath3)(GOBJ *fighter);             // 0x21e8\n        void (*OnActionStateChange)(GOBJ *fighter);  // 0x21ec\n        void (*OnTakeDamage2)(GOBJ *fighter);        // 0x21f0\n        void (*OnHurtboxDetect)(GOBJ *fighter);      // 0x21f4\n        void (*OnSpin)(GOBJ *fighter);               // 0x21f8\n    } cb;\n} FtStateData;\ntypedef struct FtState\n{\n    FtStateData data[2];\n    Playerblock player_block;\n    int stale_queue[11];\n} FtState;\ntypedef struct Savestate\n{\n    int is_exist;\n    int frame;\n    u8 event_data[EVENT_DATASIZE];\n    FtState ft_state[6];\n} Savestate;\ntypedef struct evFunction\n{\n    void (*Event_Init)(GOBJ *event);\n    void (*Event_Update)();\n    void (*Event_Think)(GOBJ *event);\n    EventMenu **menu_start;\n} evFunction;\ntypedef struct EventVars\n{\n    EventDesc *event_desc;                                                                   // event information\n    evMenu *menu_assets;                                                                     // menu assets\n    GOBJ *event_gobj;                                                                        // event gobj\n    GOBJ *menu_gobj;                                                                         // event menu gobj\n    int game_timer;                                                                          // amount of game frames passed\n    u8 hide_menu;                                                                            // enable this to hide the base menu. used for custom menus.\n    int (*Savestate_Save)(Savestate *savestate);                                             // function pointer to save state\n    int (*Savestate_Load)(Savestate *savestate);                                             // function pointer to load state\n    GOBJ *(*Message_Display)(int msg_kind, int queue_num, int msg_color, char *format, ...); // function pointer to display message\n    int *(*Tip_Display)(int lifetime, char *fmt, ...);\n    void (*Tip_Destroy)();      // function pointer to destroy tip\n    Savestate *savestate;       // points to the events main savestate\n    evFunction evFunction;      // event specific functions\n    ArchiveInfo *event_archive; // event archive header\n    DevText *db_console_text;\n} EventVars;\n\n// Function prototypes\nEventDesc *GetEventDesc(int page, int event);\nvoid EventInit(int page, int eventID, MatchInit *matchData);\nvoid EventLoad();\nGOBJ *EventMenu_Init(EventDesc *event_desc, EventMenu *start_menu);\nvoid EventMenu_Think(GOBJ *eventMenu, int pass);\nvoid EventMenu_COBJThink(GOBJ *gobj);\nvoid EventMenu_Draw(GOBJ *eventMenu);\nint Text_AddSubtextManual(Text *text, char *string, int posx, int posy, int scalex, int scaley);\nEventMenu *EventMenu_GetCurrentMenu(GOBJ *gobj);\nint Savestate_Save(Savestate *savestate);\nint Savestate_Load(Savestate *savestate);\nvoid Update_Savestates();\nint GOBJToID(GOBJ *gobj);\nint FtDataToID(FighterData *fighter_data);\nint BoneToID(FighterData *fighter_data, JOBJ *bone);\nGOBJ *IDToGOBJ(int id);\nFighterData *IDToFtData(int id);\nJOBJ *IDToBone(FighterData *fighter_data, int id);\nvoid EventUpdate();\nvoid Event_IncTimer(GOBJ *gobj);\nvoid Test_Think(GOBJ *gobj);\nstatic EventDesc *static_eventInfo;\nstatic MenuData *static_menuData;\nstatic EventVars stc_event_vars;\nstatic int *eventDataBackup;\n\nstatic EventVars **event_vars_ptr = 0x803d7054; //R13 + (-0x4730)\nstatic EventVars *event_vars;\n\n// EventOption option_kind definitions\n#define OPTKIND_MENU 0\n#define OPTKIND_STRING 1\n#define OPTKIND_INT 2\n#define OPTKIND_FLOAT 3\n#define OPTKIND_FUNC 4\n\n// EventMenu state definitions\n#define EMSTATE_FOCUS 0\n#define EMSTATE_OPENSUB 1\n#define EMSTATE_OPENPOP 2\n#define EMSTATE_WAIT 3 // pauses menu logic, used for when a custom window is being shown\n\n// GX Link args\n#define GXLINK_MENUMODEL 12\n#define GXPRI_MENUMODEL 80\n#define GXLINK_MENUTEXT 12\n#define GXPRI_MENUTEXT GXPRI_MENUMODEL + 1\n// popup menu\n#define GXPRI_POPUPMODEL GXPRI_MENUTEXT + 1\n#define GXLINK_POPUPMODEL 12\n#define GXPRI_POPUPTEXT GXPRI_POPUPMODEL + 1\n#define GXLINK_POPUPTEXT 12\n// cobj\n#define MENUCAM_COBJGXLINK (1 << GXLINK_MENUMODEL) | (1 << GXLINK_MENUTEXT) | (1 << GXLINK_POPUPMODEL) | (1 << GXLINK_POPUPTEXT)\n#define MENUCAM_GXPRI 9\n\n// menu model\n#define OPT_SCALE 1\n#define OPT_X 0 //0.5\n#define OPT_Y -1\n#define OPT_Z 0\n#define OPT_WIDTH 55 / OPT_SCALE\n#define OPT_HEIGHT 40 / OPT_SCALE\n// menu text object\n#define MENU_CANVASSCALE 0.05\n#define MENU_TEXTSCALE 1\n#define MENU_TEXTZ 0\n// menu title\n#define MENU_TITLEXPOS -430\n#define MENU_TITLEYPOS -366\n#define MENU_TITLESCALE 2.3\n#define MENU_TITLEASPECT 870\n// menu description\n#define MENU_DESCXPOS -21.5\n#define MENU_DESCYPOS 12\n#define MENU_DESCSCALE 1\n// menu option name\n#define MENU_OPTIONNAMEXPOS -430\n#define MENU_OPTIONNAMEYPOS -230\n#define MENU_NAMEASPECT 440\n// menu option value\n#define MENU_OPTIONVALXPOS 250\n#define MENU_OPTIONVALYPOS -230\n#define MENU_TEXTYOFFSET 50\n#define MENU_VALASPECT 280\n// menu highlight\n#define MENUHIGHLIGHT_SCALE 1 // OPT_SCALE\n#define MENUHIGHLIGHT_HEIGHT ROWBOX_HEIGHT\n#define MENUHIGHLIGHT_WIDTH (OPT_WIDTH * 0.785)\n#define MENUHIGHLIGHT_X OPT_X\n#define MENUHIGHLIGHT_Y 10.8 //10.3\n#define MENUHIGHLIGHT_Z 0.01\n#define MENUHIGHLIGHT_YOFFSET ROWBOX_YOFFSET\n#define MENUHIGHLIGHT_COLOR \\\n    {                       \\\n        255, 211, 0, 255    \\\n    }\n// menu scroll\n#define MENUSCROLL_SCALE 2                         // OPT_SCALE\n#define MENUSCROLL_SCALEY 1.105 * MENUSCROLL_SCALE // OPT_SCALE\n#define MENUSCROLL_X 22.5\n#define MENUSCROLL_Y 12\n#define MENUSCROLL_Z 0.01\n#define MENUSCROLL_PEROPTION 1\n#define MENUSCROLL_MINLENGTH -1\n#define MENUSCROLL_MAXLENGTH -10\n#define MENUSCROLL_COLOR \\\n    {                    \\\n        255, 211, 0, 255 \\\n    }\n\n// row jobj\n#define ROWBOX_HEIGHT 2.3\n#define ROWBOX_WIDTH 18\n#define ROWBOX_X 12.5 //13\n#define ROWBOX_Y 10.8 //10.3\n#define ROWBOX_Z 0\n#define ROWBOX_YOFFSET -2.5\n#define ROWBOX_COLOR       \\\n    {                      \\\n        104, 105, 129, 100 \\\n    }\n// arrow jobj\n#define TICKBOX_SCALE 1.8\n#define TICKBOX_X 11.7\n#define TICKBOX_Y 11.7\n\n// popup model\n#define POPUP_WIDTH ROWBOX_WIDTH\n#define POPUP_HEIGHT 19\n#define POPUP_SCALE 1\n#define POPUP_X 12.5\n#define POPUP_Y 8.3\n#define POPUP_Z 0.01\n#define POPUP_YOFFSET -2.5\n// popup text object\n#define POPUP_CANVASSCALE 0.05\n#define POPUP_TEXTSCALE 1\n#define POPUP_TEXTZ 0.01\n// popup text\n#define POPUP_OPTIONVALXPOS 250\n#define POPUP_OPTIONVALYPOS -280\n#define POPUP_TEXTYOFFSET 50\n// popup highlight\n#define POPUPHIGHLIGHT_HEIGHT ROWBOX_HEIGHT\n#define POPUPHIGHLIGHT_WIDTH (POPUP_WIDTH * 0.785)\n#define POPUPHIGHLIGHT_X 0\n#define POPUPHIGHLIGHT_Y 5\n#define POPUPHIGHLIGHT_Z 1\n#define POPUPHIGHLIGHT_YOFFSET ROWBOX_YOFFSET\n#define POPUPHIGHLIGHT_COLOR \\\n    {                        \\\n        255, 211, 0, 255     \\\n    }\n\n// Message\nvoid Message_Init();\nGOBJ *Message_Display(int msg_kind, int queue_num, int msg_color, char *format, ...);\nvoid Message_Manager(GOBJ *mngr_gobj);\nvoid Message_Destroy(GOBJ **msg_queue, int msg_num);\nvoid Message_Add(GOBJ *msg_gobj, int queue_num);\nvoid Message_CObjThink(GOBJ *gobj);\nfloat BezierBlend(float t);\n\n#define MSGQUEUE_NUM 7\n#define MSGQUEUE_SIZE 5\n#define MSGQUEUE_GENERAL 6\nenum MsgState\n{\n    MSGSTATE_WAIT,\n    MSGSTATE_SHIFT,\n    MSGSTATE_DELETE,\n};\nenum MsgArea\n{\n    MSGKIND_P1,\n    MSGKIND_P2,\n    MSGKIND_P3,\n    MSGKIND_P4,\n    MSGKIND_P5,\n    MSGKIND_P6,\n    MSGKIND_GENERAL,\n};\ntypedef struct MsgData\n{\n    Text *text;      // text pointer\n    int kind;        // the type of message this is\n    int state;       // unused atm\n    int prev_index;  // used to animate the messages position during shifts\n    int orig_index;  // used to tell if the message moved throughout the course of the frame\n    int anim_timer;  // used to track animation frame\n    int lifetime;    // amount of frames after spawning to kill this message\n    int alive_timer; // amount of frames this message has been alive for\n} MsgData;\ntypedef struct MsgMngrData\n{\n    COBJ *cobj;\n    int state;\n    int canvas;\n    GOBJ *msg_queue[MSGQUEUE_NUM][MSGQUEUE_SIZE]; // array 7 is for miscellaneous messages, not related to a player\n} MsgMngrData;\nstatic GOBJ *stc_msgmgr;\nstatic 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\nstatic Vec3 stc_msg_queue_general_pos = {-21, 18.5, 0};\nenum MsgColors\n{\n    MSGCOLOR_WHITE,\n    MSGCOLOR_GREEN,\n    MSGCOLOR_RED,\n    MSGCOLOR_YELLOW\n};\nstatic GXColor stc_msg_colors[] = {\n    {255, 255, 255, 255},\n    {141, 255, 110, 255},\n    {255, 162, 186, 255},\n    {255, 240, 0, 255},\n};\n\n#define MSGTIMER_SHIFT 6\n#define MSGTIMER_DELETE 6\n#define MSG_LIFETIME (2 * 60)\n#define MSG_LINEMAX 3  // lines per message\n#define MSG_CHARMAX 32 // characters per line\n#define MSG_HUDYOFFSET 8\n#define MSGJOINT_SCALE 3\n#define MSGJOINT_X 0\n#define MSGJOINT_Y 0\n#define MSGJOINT_Z 0\n#define MSGTEXT_BASESCALE 1.4\n#define MSGTEXT_BASEWIDTH (330 / MSGTEXT_BASESCALE)\n#define MSGTEXT_BASEX 0\n#define MSGTEXT_BASEY -1\n#define MSGTEXT_YOFFSET 30\n\n// GX stuff\n#define MSG_GXLINK 13\n#define MSG_GXPRI 80\n#define MSGTEXT_GXPRI MSG_GXPRI + 1\n#define MSG_COBJLGXLINKS (1 << MSG_GXLINK)\n#define MSG_COBJLGXPRI 8\n\ntypedef struct TipMgr\n{\n    GOBJ *gobj;   // tip gobj\n    Text *text;   // tip text object\n    int state;    // state this tip is in. 0 = in, 1 = wait, 2 = out\n    int lifetime; // tips time spent onscreen\n} TipMgr;\n\nint Tip_Display(int lifetime, char *fmt, ...);\nvoid Tip_Destroy(); // 0 = immediately destroy, 1 = force exit\nvoid Tip_Think(GOBJ *gobj);\n\n#define TIP_TXTJOINT 2\n"
  }
]