Advertisement
Guest User

Creator Variant Source by Melg

a guest
Aug 25th, 2021
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.05 KB | None | 0 0
  1. #Very unoptimized code but frankly I am very lazy and I do not want to optimize this considering the use people will make of it.
  2. # inject at 8057c3a8 (PAL)
  3. # inject at 80575b44 (NTSC-U)
  4. # inject at 8057bd28 (NTSC-J)
  5. # inject at 8056a400 (NTSC-K)
  6.  
  7. .set region, 'P'
  8.  
  9. .if (region == 'P')
  10.  
  11. .set swprintf, 0x80017814
  12. .set ScreenElement_setTextSrc, 0x805cdd00
  13. .set MtxtoEuler, 0x8022FB04
  14. .set CheckAreaIn, 0x805163f4
  15. .set Memset, 0x80006038
  16.  
  17. .set RACEDATA, 0x809bd728
  18. .set MENUDATA, 0x809c1e38
  19. .set RACEINFO, 0x809bd730
  20. .set INPUTDATA, 0x809bd70c
  21. .set ITEMHOLDER, 0x809c3618
  22. .set KCLHOLDER, 0x809c27f8
  23. .set KMPHOLDER, 0x809BD6E8
  24. .set DEG2RAD, 0x808abaa4
  25. .set OFFSET, -0x5CF0
  26. .elseif (region == 'E')
  27.  
  28.  
  29.  
  30.  
  31.  
  32. .set swprintf, 0x80016cb4
  33. .set ScreenElement_setTextSrc, 0x805c11e0
  34. .set MtxtoEuler, 0x8022F780
  35. .set CheckAreaIn, 0x80511F80
  36. .set Memset, 0x80006038
  37.  
  38. .set RACEDATA, 0x809b8f68
  39. .set MENUDATA, 0x809bd508
  40. .set RACEINFO, 0x809B8F70
  41. .set INPUTDATA, 0x809b8f4c
  42. .set ITEMHOLDER, 0x809bee20
  43. .set KCLHOLDER, 0x809bdbb8
  44. .set KMPHOLDER, 0x809B8F28
  45. .set DEG2RAD, 0x808a5D24
  46. .set OFFSET, -0x5CF0
  47.  
  48.  
  49. .elseif (region == 'J')
  50. .set swprintf, 0x80017738
  51. .set ScreenElement_setTextSrc, 0x805cd5dc
  52. .set MtxtoEuler, 0x8022FA24
  53. .set CheckAreaIn, 0x80515D74
  54. .set Memset, 0x80006038
  55.  
  56.  
  57. .set RACEDATA, 0x809bc788
  58. .set MENUDATA, 0x809c0e98
  59. .set INPUTDATA, 0x809BC76C
  60. .set RACEINFO, 0x809BC790
  61. .set ITEMHOLDER, 0x809c2678
  62. .set KCLHOLDER, 0x809c1858
  63. .set KMPHOLDER, 0x809BC748
  64. .set DEG2RAD, 0x808AAC04
  65. .set OFFSET, -0x5CF0
  66.  
  67. .elseif (region == 'K')
  68. .set swprintf, 0x8001787C
  69. .set ScreenElement_setTextSrc, 0x805BBCC0
  70. .set MtxtoEuler, 0x8022FE78
  71. .set CheckAreaIn, 0x80504414
  72. .set Memset, 0x80006038
  73.  
  74. .set RACEDATA, 0x809abd68
  75. .set MENUDATA, 0x809B0478
  76. .set INPUTDATA, 0x809ABD4C
  77. .set RACEINFO, 0x809ABD70
  78. .set ITEMHOLDER, 0x809B1C58
  79. .set KCLHOLDER, 0x809B0E38
  80. .set KMPHOLDER, 0x809ABD28
  81. .set DEG2RAD, 0x80899f04
  82. .set OFFSET, -0x5CF0
  83.  
  84. .set MENUDATA, 0x809b0478
  85. .set swprintf, 0x8001787c
  86. .set ScreenElement_setTextSrc, 0x805bbcc0
  87. .set OFFSET, -0x5CD0
  88. .else
  89. .err
  90. .endif
  91.  
  92.  
  93.  
  94. # get the player index of the player on which the hooked function is working
  95. lis r31, RACEDATA@ha
  96. lwz r10, RACEINFO@l (r31)
  97. lwz r11, 0x28 (r10)
  98. cmpwi r11, 0 #If race has not started, do not display the panel; this avoid the panel warping in position
  99. beq- end
  100. lwz r11, 0x0 (r29)
  101. lwz r3, 0x0 (r11)
  102. lbz r3, 0x10 (r3)
  103.  
  104. # get the player index from the first hud slot
  105.  
  106. lwz r7, RACEDATA@l (r31)
  107. lbz r7, 0xb84 (r7)
  108.  
  109. # if they don't match, the speedometer will not be updated
  110. cmpw r3, r7
  111. bne end
  112.  
  113.  
  114. # check if a single player gameplay screen is active
  115. lwz r4, MENUDATA@l (r31)
  116. lwz r3, 0x0 (r4)
  117.  
  118.  
  119. lwz r28, 0x38 (r3) # grand prix
  120. cmpwi r28, 0x0
  121. bne found
  122.  
  123. lwz r28, 0x3c (r3) # time trial
  124. cmpwi r28, 0x0
  125. bne found
  126.  
  127. lwz r28, 0x40 (r3) # 1 player offline vs
  128. cmpwi r28, 0x0
  129. bne found
  130.  
  131. lwz r28, 0x50 (r3) # 1 player battle
  132. cmpwi r28, 0x0
  133. bne found
  134.  
  135. lwz r28, 0x108 (r3) # 1 player ww/regional vs
  136. cmpwi r28, 0x0
  137. bne found
  138.  
  139. lwz r28, 0x110 (r3) # 1 player friend room vs
  140. cmpwi r28, 0x0
  141. beq end
  142.  
  143. found:
  144. lwz r28, 0x5c (r28)
  145. bl format
  146. .short 0x001a, 0x0800, 0x0001, 0x0030
  147. .short 0x001a, 0x0800, 0x0001, 0x0030 # bmg escape sequence for yellow text
  148. .llong 0x0052006500730070
  149. .llong 0x00610077006e0020
  150. .llong 0x00250032002e0030
  151. .llong 0x0066000a00430075
  152. .llong 0x0072004300500020
  153. .llong 0x0020002000200025
  154. .llong 0x0033002e00300066
  155. .llong 0x000a004300750072
  156. .llong 0x004b004300500020
  157. .llong 0x0020002000250032
  158. .llong 0x002e00300066000a
  159. .llong 0x0052006100630065
  160. .llong 0x0025002500200025
  161. .llong 0x0031002e00330066
  162. .llong 0x000a004900540050
  163. .llong 0x0054002000200020
  164. .llong 0x0020002000200020
  165. .llong 0x00250033002e0030
  166. .llong 0x0066000a00420069
  167. .llong 0x006c006c00200063
  168. .llong 0x0061006e00250073
  169. .llong 0x002000640072006f
  170. .llong 0x0070000a00250073
  171. .llong 0x002d007000720069
  172. .llong 0x006f007200690074
  173. .llong 0x0079000a004b0043
  174. .llong 0x004c0046006c0061
  175. .llong 0x0067002000250030
  176. .llong 0x00320078000a0056
  177. .llong 0x0061007200690061
  178. .llong 0x006e007400200020
  179. .llong 0x0025003000320078
  180. .llong 0x000a002500730020
  181. .llong 0x0054007200690063
  182. .llong 0x006b00610062006c
  183. .long 0x00650000
  184. .string "'t"
  185. .string "High"
  186. .string "Low"
  187. .string "Not"
  188. .string " "
  189. .align 2
  190. .short 0x001a, 0x0800, 0x0001, 0x0030
  191. .short 0x001a, 0x0800, 0x0001, 0x0030 # bmg escape sequence for yellow text
  192. .llong 0x0058002000250037
  193. .llong 0x002e00300066000a
  194. .llong 0x0059002000250037
  195. .llong 0x002e00300066000a
  196. .llong 0x005a002000250037
  197. .llong 0x002e00300066000a
  198. .llong 0x0072005800200025
  199. .llong 0x0037002e00300066
  200. .llong 0x000a007200590020
  201. .llong 0x00250037002e0030
  202. .llong 0x0066000a0072005a
  203. .llong 0x002000250037002e
  204. .llong 0x00300066000a0053
  205. .llong 0x0070006500650064
  206. .llong 0x002000250033002e
  207. .llong 0x00300066000a0041
  208. .llong 0x0052004500410020
  209. .llong 0x0025007300000000
  210. format:
  211. mflr r30
  212.  
  213. lwz r5, INPUTDATA@l(r31)
  214. lbz r4, 0x3F(r4) #load active controller
  215. lhz r6, 0x4A (r5) #Previous Frame Input
  216. lhz r5, 0x32(r5) #Current Frame Input
  217.  
  218.  
  219. andc r5, r6, r5 #Check if Minus/Y has been pressed once
  220. andi. r6, r5, 0x1000
  221. cmpwi cr1, r4, 0x24
  222. bne+ cr1, check
  223. andi. r6, r5, 0x800
  224.  
  225. check:
  226. lbz r4, 0x13F (r30) #Page Toggling
  227. beq+ compare
  228. addi r4, r4, 1
  229. cmpwi r4, 2
  230. ble+ compare
  231. li r4, 0
  232.  
  233. compare:
  234. stb r4, 0x13F (r30)
  235. cmpwi r4, 2
  236. bne+ display
  237. li r5, 1 #"Page 3" = Panel disabled
  238. stb r5, 0x80 (r28)
  239. b end
  240.  
  241. display:
  242. li r5, 0
  243. stb r5, 0x80 (r28)
  244.  
  245.  
  246.  
  247. # prepare the arguments for swprintf 1
  248. lwz r29, 0x8 (r11)
  249. lwz r29, 0x90 (r29) #Prepare the pointers for position/speed load
  250.  
  251.  
  252. cmpwi r4, 0x1
  253. beq+ page2
  254. b next
  255. routine: #swprintf not enough int args, small routine to convert ints to floats
  256. xoris r3, r3, 0x8000
  257. stw r3, -0x4 (sp)
  258. lfd f6, -0x8 (sp)
  259. fsub f6, f6, f7
  260. blr
  261.  
  262.  
  263. next:
  264. #PAGE 1: f1 = Respawn/f2 = CP/f3 = CurrentKCP/f4 = race completion/f5 = ITPT/r6 = pointer to string/r7 = pointer to string/r8 = KCL Type/r9 = KCL Variant/r10 = pointer to string
  265. mr r5, r30 #For page 1, swprintf pointer to string
  266. lis r3, 0x4330
  267. stw r3, -0x8 (sp)
  268. lis r3, 0x8000
  269. stw r3, -0x4 (sp)
  270. lfd f7, -0x8 (sp) # load magic double into f7
  271.  
  272.  
  273. lwz r4, 0xC (r10)
  274. mulli r7, r7, 4
  275. lwzx r4, r4, r7 #My RACEINFO
  276. lbz r3, 0x21 (r4) #respawn
  277. bl routine
  278. fmr f1, f6
  279. lbz r3, 0xB (r4) #CP
  280. bl routine
  281. fmr f2, f6
  282. lbz r3, 0x27 (r4) #currentKCP
  283. bl routine
  284. fmr f3, f6
  285. lfs f4, 0xC (r4) #race completion
  286. lwz r3, ITEMHOLDER@l (r31)
  287. lwz r3, 0x14 (r3)
  288. lbz r3, 0x44 (r3) #ITPT
  289. bl routine
  290. fmr f5, f6
  291.  
  292. lwz r6, KMPHOLDER@l (r31)
  293. lwz r4, 0x18 (r6)
  294. lwz r4, 0 (r4)
  295. mulli r3, r3, 4
  296. lwzx r4, r4, r3
  297. lwz r4, 0 (r4)
  298. lha r3, 0x12 (r4) #low prio and bill drop
  299.  
  300. li r6, 0
  301. addi r7, r30, 0x12F #r7 = pointer to string for priority
  302. andi. r4, r3, 0x1
  303. beq+ priocheck
  304. addi r6, r30, 0x12C #r6 = pointer to string for bill dropping
  305.  
  306. priocheck:
  307. andi. r4, r3, 0xA
  308. beq+ normal
  309. addi r7, r30, 0x134
  310. normal:
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319. addi r10, r30, 0x138
  320. lwz r3, KCLHOLDER@l (r31)
  321. lwz r3, 0x18 (r3)
  322. lbz r8, 0xF1 (r3) #KCL Type
  323. lbz r9, 0xF3 (r3) #KCL Variant
  324. cmpwi r8, 0x7 #Checks if trickable boost ramp/halfpipe KCL type
  325. beq- trickable
  326. cmpwi r8, 0x13
  327. beq- trickable
  328. cmpwi r8, 0x8
  329. beq- trickable
  330. lwz r3, 0x10 (r11)
  331. lwz r3, 0 (r3)
  332. lwz r3, 0x98 (r3)
  333. lwz r3, 0x1C (r3)
  334. lwz r3, 0x8 (r3)
  335. cmpwi r3, 0x9 #Convoluted check to see if trickable bit is set
  336. bne+ call
  337. trickable:
  338. addi r10, r30, 0x13C
  339. b call
  340.  
  341. page2:
  342. #PAGE2: f1 = X/f2 = Y/f3 = Z/f4 = X rotation/f5 = Y rotation/f6 = Z rotation/f7 = speed/r6 = Pointer to AREA string
  343. lis r3, 0x8150
  344. ori r3, r3, 0x1500
  345. li r4, 0
  346. li r5, 0x50
  347. lis r12, Memset@h
  348. ori r12, r12, Memset@l
  349. mtctr r12
  350. bctrl #Clears the spot in memory where AREA string is stored
  351.  
  352.  
  353. lis r12, CheckAreaIn@h #Preparation of the AREA loop. This function uses a pointer to an AREA, a pointer to a point and checks if the point is inside the AREA
  354. ori r12, r12, CheckAreaIn@l
  355. mtctr r12
  356.  
  357. lwz r6, KMPHOLDER@l (r31)
  358. lwz r6, 0x2C (r6)
  359. lhz r11, 0x4 (r6) #AreaCount = loop count
  360. lwz r6, 0x0010 (r6)
  361. subi r8, r3, 2 #Pointer to string
  362. li r10, 0
  363. li r12, 0 #r12 will count the number of AREAs the player is in
  364.  
  365. looparea:
  366. lwz r4, 0x4 (r29)
  367. addi r4, r4, 0x68 #Adjusts the pointer for player's current position
  368. mulli r3, r10, 4
  369. lwzx r3, r6, r3 #INTO CURRENT AREA, also arg for the function below
  370. mr r9, r3
  371. bctrl
  372. cmpwi r3, 0 #If r3 = 0, the player is not in the AREA currently checked
  373. beq+ decrement
  374.  
  375. #The string is entirely built manually. This is super convoluted and long, there is 100% a better way to do this but lazy
  376. cmpwi r12, 0 #If this is the first AREA the player is in, do not put a comma in the string
  377. beq- nocomma
  378. li r3, 0x2c #ASCII for Comma
  379. stb r3, 0x1 (r8)
  380. nocomma:
  381. addi r12, r12, 0x1
  382. lwz r3, 0x4 (r9) #for type and ID
  383. lbz r3, 0x1 (r3) #TYPE
  384. addi r3, r3, 0x30
  385. stb r3, 0x2 (r8)
  386. li r3, 0x28 #ASCII for "("
  387. stb r3, 0x3 (r8)
  388. lha r3, 0x44 (r9) #ID, the instructions after are used to separate each figure of the ID (for example 0x10 -> 1 and 0)
  389. srwi r5, r3, 0x4
  390. addi r5, r5, 0x30
  391. stb r5, 0x4 (r8) #Store upper half of the ID
  392. clrlwi r3, r3, 27
  393. addi r5, r3, 0x30
  394. cmpwi r3, 0xA
  395. blt+ small
  396. addi r5, r3, 0x37
  397. small:
  398. stb r5, 0x5 (r8) #Store Lower Half of the ID
  399. li r3, 0x29 #ASCII for ")"
  400. stbu r3, 0x6 (r8) #Store ")" and update the pointer for next iteration
  401.  
  402.  
  403.  
  404. decrement:
  405. addi r10, r10, 1 #Loop until r10 = r11 = AREA Count
  406. cmplw r10, r11
  407. blt+ looparea
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415. #XYZ rot XYZ speed
  416. addi r3, r29, 0x9C #Adjusts r3 to point to the rotation Matrix in PlayerHolderPlayer
  417. lis r12, MtxtoEuler@h #Credits to Stebler for this function which converts a rotation Matrix to Euler Angles
  418. ori r12, r12, MtxtoEuler@l
  419. addi r4, sp, -0x100
  420. mtctr r12
  421. bctrl
  422. lwz r3, 0x4 (r29)
  423. lfs f1, 0x68 (r3) #Load the player's position
  424. lfs f2, 0x6c (r3)
  425. lfs f3, 0x70 (r3)
  426. lis r5, DEG2RAD@ha
  427. lfs f7, DEG2RAD@l (r5) #Load Deg2RAD constant
  428. fres f7, f7 #Invert it to RAD2Deg
  429. addi r4, sp, -0x100
  430. lfs f4, 0x0 (r4) #Load Euler Angles; X and Z hard to interpret but Y is the angle around the vertical axis
  431. lfs f5, 0x4 (r4)
  432. lfs f6, 0x8 (r4)
  433. fmuls f4, f4, f7 #Convert the Euler Angles to Degrees
  434. fmuls f5, f5, f7
  435. fmuls f6, f6, f7
  436. lfs f7, 0xE0 (r3) #XYZ Speed
  437. lis r6, 0x8150 #r6 = Pointer to AREA String
  438. ori r6, r6, 0x1500
  439. addi r5, r30, 0x140 #Adjusts pointer to swprintf string to format
  440.  
  441.  
  442. call:
  443. addi sp, sp, -0x200 #Call swprintf; very cautious with the buffer size but I had issues with buffer overflows and corrupted panels; difficult to know exactly how much I need considering the AREA string has a dynamic length
  444. addi r3, sp, 0x8
  445. li r4, 0x200
  446. crset 4 * cr1 + eq #Set cr1 so that swprintf handles the floats
  447. lis r12, swprintf@h
  448. ori r12, r12, swprintf@l
  449. mtctr r12
  450. bctrl
  451.  
  452.  
  453. addi r5, sp, 0x8
  454.  
  455.  
  456. addi r4, r5, 0xE # we do not want to process the bmg escape sequence
  457.  
  458. # replace digits, dashes and dots with the timer versions
  459. loop:
  460. lhzu r3, 0x2 (r4)
  461. cmpwi r3, 0x0
  462. beq out
  463.  
  464. cmpwi r3, 0x2d
  465. bne not_a_dash
  466. li r3, 0x246d
  467.  
  468. not_a_dash:
  469. cmpwi r3, 0x2e
  470. bne not_a_dot
  471. li r3, 0x246b
  472.  
  473. not_a_dot:
  474. cmpwi r3, 0x30
  475. blt not_a_digit
  476. cmpwi r3, 0x3a
  477. bge not_a_digit
  478. addi r3, r3, 0x2430
  479.  
  480. not_a_digit:
  481. sth r3, 0x0 (r4)
  482. b loop
  483.  
  484.  
  485. out:
  486. #size
  487. size:
  488. li r4, 77
  489. stw r4, 0x4 (r5)
  490.  
  491.  
  492. # set the position of the hud element
  493. lis r12, 0x4000
  494. lis r4, 0xC3A0
  495. lwz r30, OFFSET (r13) #r13 value to check if 4/3 or 16/9
  496. cmpwi r30, 1
  497. beq+ goodres
  498. lis r12, 0x4150
  499. lis r4, 0xC360
  500.  
  501.  
  502. goodres:
  503. stw r4, 0x4c (r28)
  504. stw r12, 0x50 (r28)
  505.  
  506. # align the text to the right
  507. lwz r3, 0x114 (r28)
  508. lwz r7, 0x0 (r3)
  509. stb r4, 0x100 (r7)
  510. lis r12, 0x43B0
  511. stw r12, 0x50 (r7)
  512. lis r12, 0x4380
  513. stw r12, 0x4C (r7)
  514. li r4, 0
  515.  
  516.  
  517. lis r12, ScreenElement_setTextSrc@h #Call the function that will display the screenelement
  518. ori r12, r12, ScreenElement_setTextSrc@l
  519. mtctr r12
  520. bctrl
  521.  
  522. end2:
  523. addi sp, sp, 0x200
  524.  
  525. end:
  526. lwz r31, 0x7c (sp) # original instruction
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement