Guest User

King's Field: The Ancient City - Analog Control Patch Pseudocode

a guest
Jan 5th, 2022
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.22 KB | None | 0 0
  1. $f21 = Y rotation max
  2. $f26 = Y rotation decel (same as X)
  3. $f28 = Y rotation accel (X is nearly twice as fast and probably better to use for overall feel)
  4.  
  5. $01b8(a0) = current Y speed
  6.  
  7. $f22 = X rotation max
  8. $f26 = X rotation decel
  9. $f29 = X rotation accel
  10.  
  11. $01bc(v0) = current X speed
  12.  
  13. $f20 = movement max (regular and strafing)
  14. $f25 = movement decel
  15. $f27 = movement accel
  16.  
  17. $01b4(v0) = current movement speed
  18. $01b0(v0) = current strafe speed
  19.  
  20.  
  21. ; Code snippet for converting analog values to digital bitmasks based on current mapping
  22.  
  23. ; a2 = base pointer for live gamepad status
  24. ; s0 = base pointer for effective button mask status
  25.  
  26. ; $9dbc(gp) = move foreward
  27. ; $9dbe(gp) = move backward
  28. ; $9dc2(gp) = turn left
  29. ; $9dc0(gp) = turn right
  30. ; $9dca(gp) = look down
  31. ; $9dc8(gp) = look up
  32. ; $9dc6(gp) = strafe left
  33. ; $9dc4(gp) = strafe right
  34.  
  35. ; Start modifying at 001b55f4
  36.  
  37. lhu v0, $0008(s0) ; Copy last frames calculated mask
  38. sh zero, $0008(s0)
  39. sh v0, $000a(s0)
  40.  
  41. addu s1, zero, zero
  42.  
  43. lbu v0, $0004(a2) ; v0 = right X axis value
  44. lhu v1, $9dc2(gp) ; v1 = Button mapping for "turn left"
  45. sltiu at, v0, $007F
  46. bnel at, zero, right_x_done
  47. or s1, s1, v1
  48. lhu v1, $9dc0(gp) ; v1 = Button mapping for "turn right"
  49. addi v0, v0, $ff81 ; subtract 0x7F
  50. bnel v0, zero, right_x_done
  51. or s1, s1, v1
  52.  
  53. right_x_done:
  54.  
  55. lbu v0, $0005(a2) ; v0 = right Y axis value
  56. lhu v1, $9dca(gp) ; v1 = Button mapping for "look down"
  57. sltiu at, v0, $007F
  58. bnel at, zero, right_y_done
  59. or s1, s1, v1
  60. lhu v1, $9dc8(gp) ; v1 = Button mapping for "look up"
  61. addi v0, v0, $ff81 ; subtract 0x7F
  62. bnel v0, zero, right_y_done
  63. or s1, s1, v1
  64.  
  65. right_y_done:
  66.  
  67. lbu v0, $0006(a2) ; v0 = left X axis value
  68. lhu v1, $9dc6(gp) ; v1 = Button mapping for "strafe left"
  69. sltiu at, v0, $007F
  70. bnel at, zero, left_x_done
  71. or s1, s1, v1
  72. lhu v1, $9dc4(gp) ; v1 = Button mapping for "strafe right"
  73. addi v0, v0, $ff81 ; subtract 0x7F
  74. bnel v0, zero, left_x_done
  75. or s1, s1, v1
  76.  
  77. left_x_done:
  78.  
  79. lbu v0, $0007(a2) ; v0 = left Y axis value
  80. lhu v1, $9dbc(gp) ; v1 = Button mapping for "move forward"
  81. sltiu at, v0, $007F
  82. bnel at, zero, left_y_done
  83. or s1, s1, v1
  84. lhu v1, $9dbe(gp) ; v1 = Button mapping for "move backward"
  85. addi v0, v0, $ff81 ; subtract 0x7F
  86. bnel v0, zero, left_y_done
  87. or s1, s1, v1
  88.  
  89. left_y_done:
  90.  
  91. ; At this point s1 has the calculated mask for this frame
  92.  
  93. lhu v0, $000a(s0) ; v0 = calculated buttons pressed last frame
  94. lhu v1, $0000(s0) ; v1 = current real button mask
  95. sh s1, $0008(s0) ; s1 = calculated presses this frame
  96. nor v0, zero, v0 ; v0 now contains all calculated buttons not pressed last frame
  97. lhu a0, $0002(s0) ; a0 = real new buttons pressed this frame
  98. and v0, s1, v0 ; v0 = new calculated buttons pressed this frame
  99. or v1, v1, s1 ; v1 = effective button mask
  100. or a0, a0, v0 ; a0 = effective new button mask
  101. sh v1, $0000(s0)
  102. beq zero, zero, $001b5760
  103. sh a0, $0002(s0)
  104.  
  105. ; Modify jump at 001b55ec to go here
  106. skip_effective_processing:
  107.  
  108. sh zero, $0008(s0)
  109. beq zero, zero, $001b5760
  110. sh zero, $000a(s0)
  111.  
  112.  
  113. ; ----------------------------------------------------------------------
  114. ; Code snippet for transforming axis input into player axis speed values
  115.  
  116. lui at, $0041
  117. addiu at, at, $3DB8
  118. lw v0, $0004(at)
  119. addiu at, zero, $00FF
  120. beq v0, at, <skip>
  121.  
  122. lui at, $3C01 ; load literal float value of 1/127
  123. addiu at, at, $0204
  124. mtc1 at, $f1 ; Move 1/127 to coprocessor register f1
  125.  
  126. lui v1, $01E0 ; Load upper bytes of memory address from next instruction
  127. lbu v0, $DC05(v1) ; right stick x axis byte loaded to v0 (0 to 255) from 1E0DC06
  128. addiu at, zero, $00ff
  129. beql v0, at, <adjust>
  130. addi v0, v0, $FFFF
  131.  
  132. adjust:
  133.  
  134. addiu v1, zero, $007f ; load constant 127 to v1 (li v1, 0x7F)
  135. sub v0, v0, v1 ; subtract 127 to adjust joystick value range from (0 to 255) to (-127 to 128)
  136. add v1, v0, zero ; save a copy for later
  137.  
  138. mtc1 v0, $f0 ; Send joystick values to coprocessor to allow float operations
  139. cvt.s.w $f0, $f0 ; convert joystick values from integer to float
  140. mul.s $f0, $f0, $f1 ; scale joystick range from( -127 to 127 ) to ( -1.0 to 1.0 )
  141. mul.s $f0, $f0, <axis max register> ; calculate target speed
  142.  
  143. addiu v0, s7, $3F80
  144. lwc1 $f1, <current speed>(v0) ; Read current speed
  145.  
  146. ; A this point $f0 contains target speed, $f1 contains current speed, v1 has integer axis value (PS2 has no concept of a signed 0, so deceleration towards 0
  147. ; from a negative speed is a special case), v0 is pointer to player status struct that contains their current rotational and movement speeds. The game stores
  148. ; all needed acceleration and max speed values in FPU registers for input processing, and these take into account status effects and other modifiers already.
  149.  
  150. abs.s $f2, $f0
  151. c.eq.s $f2, $f0
  152. nop
  153. bc1t positive_target
  154. abs.s $f2, $f1
  155.  
  156. negative_target:
  157.  
  158. c.eq.s $f2, $f1
  159. nop
  160. bc1tl negative_target_and_positive_current
  161. sub.s $f1, $f1, <axis accel register>
  162.  
  163. negative_target_and_negative_current
  164.  
  165. c.lt.s $f0, $f1
  166. neg.s $f3, <axis accel register>
  167. bc1fl decel1
  168. add.s $f1, $f1, <axis decel register>
  169.  
  170. add.s $f1, $f1, $f3
  171.  
  172. negative_target_and_positive_current:
  173.  
  174. c.lt.s $f1, $f0
  175. beq zero, zero, <overshoot>
  176. swc1 $f1, <current speed>(v0)
  177.  
  178. decel1:
  179.  
  180. c.lt.s $f0, $f1
  181. beq zero, zero, <overshoot>
  182. swc1 $f1, <current speed>(v0)
  183.  
  184. positive_target:
  185.  
  186. beq v1, zero, decel_toward_neutral
  187. mov.s $f3, <axis decel register>
  188. mov.s $f3, <axis accel register>
  189.  
  190. decel_toward_neutral:
  191.  
  192. c.eq.s $f2, $f1
  193. nop
  194. bc1fl positive_target_and_negative_current
  195. add.s $f1, $f1, $f3
  196.  
  197. positive_target_and_positive_current
  198.  
  199. c.lt.s $f1, $f0
  200. mov.s $f3, <axis accel register>
  201. bc1fl decel2
  202. sub.s $f1, $f1, <axis decel register>
  203.  
  204. add.s $f1, $f1, $f3
  205.  
  206. positive_target_and_negative_current
  207.  
  208. c.lt.s $f0, $f1
  209. beq zero, zero, <overshoot>
  210. swc1 $f1, <current speed>(v0)
  211.  
  212. decel2:
  213.  
  214. c.lt.s $f1, $f0
  215. beq zero, zero, <overshoot>
  216. swc1 $f1, <current speed>(v0)
  217.  
  218. overshoot:
  219.  
  220. bc1tl overshot
  221. swcl $f0, <current speed>(v0)
  222.  
  223. overshot:
  224. skip:
Advertisement
Add Comment
Please, Sign In to add comment