FieldModelInstruction.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. /*
  2. * Copyright (C) 2022 V-Gears Team
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #pragma once
  18. #include "decompiler/instruction.h"
  19. #include "decompiler/field/FieldEngine.h"
  20. namespace FF7{
  21. /**
  22. * A model instruction.
  23. */
  24. class FieldModelInstruction : public KernelCallInstruction{
  25. public:
  26. /**
  27. * Processes the instruction.
  28. *
  29. * @param func[in] Function to process.
  30. * @param stack[out] Function stack.
  31. * @param engine[in] Engine.
  32. * @param code_gen[in] Code generator.
  33. */
  34. virtual void ProcessInst(
  35. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  36. ) override;
  37. private:
  38. /**
  39. * Processes a JOIN opcode.
  40. *
  41. * Opcode: 0x08
  42. * Short name: JOIN
  43. * Long name: Party Field Join
  44. * Memory layout (2 bytes)
  45. * |0x08|S|
  46. *
  47. * Arguments
  48. * - const UByte S: Speed that the characters join back together.
  49. *
  50. * Causes seperated party characters that have previously been
  51. * SPLIT onto the field, to be joined back together again; that
  52. * is, only the party leader becomes visible on the field. This
  53. * should be called if a previous SPLIT has completed (the party
  54. * members have finished speaking, or performing their actions,
  55. * for example). As with SPLIT, the speed of the join is
  56. * specified, from a scale of 1 (almost instant) to FF (very slow
  57. * walk), and must be non-zero. In contrast to most MOVE related
  58. * op codes, the speed is this setting is actually the total
  59. * number of frames required. Depending on the distance from the
  60. * player character and the number of frames required, the entity
  61. * plays a run or walk animation. Also, all characters take the
  62. * same time irrespective of distance. Calling JOIN without having
  63. * previously SPLIT the characters will cause the party members to
  64. * appear at the walkmesh origin and attempt to JOIN from there.
  65. * This is not normally the required behaviour and should be
  66. * avoided.
  67. *
  68. * @param codegen[in|out] Code generator to append lines.
  69. */
  70. void ProcessJOIN(CodeGenerator* code_gen);
  71. /**
  72. * Processes a SPLIT opcode.
  73. *
  74. * Opcode: 0x09
  75. * Short name: SPLIT
  76. * Long name: Party Field Split
  77. *
  78. * Memory layout (15 bytes)
  79. * |0x20|B1/B2|B3/B4|B5/B6|XA|XA|YA|YA|DA|XB|XB|YB|YB|DB|S|
  80. *
  81. * Arguments
  82. * - const Bit[4] B1: Bank for XA, or zero if XA is specified as a
  83. * literal value.
  84. * - const Bit[4] B2: Bank for YA, or zero if YA is specified as a
  85. * literal value.
  86. * - const Bit[4] B3: Bank for DA, or zero if DA is specified as a
  87. * literal value.
  88. * - const Bit[4] B4: Bank for XB, or zero if XB is specified as a
  89. * literal value.
  90. * - const Bit[4] B5: Bank for YB, or zero if YB is specified as a
  91. * literal value.
  92. * - const Bit[4] B6: Bank for DB, or zero if DB is specified as a
  93. * literal value.
  94. * - const Short XA: X-coordinate of the second character in the
  95. * party after the split, or address for the value if B1 is
  96. * non-zero.
  97. * - const Short YA: Y-coordinate of the second character in the
  98. * party after the split, or address for the value if B2 is
  99. * non-zero.
  100. * - const UByte DA: Direction the second character faces after the
  101. * split, or address for the value if B3 is non-zero.
  102. * - const Short XB: X-coordinate of the third character in the
  103. * party after the split, or address for the value if B4 is
  104. * non-zero.
  105. * - const Short YB: Y-coordinate of the third character in the
  106. * party after the split, or address for the value if B5 is
  107. * non-zero.
  108. * - const UByte DB: Direction the third character faces after the
  109. * split, or address for the value if B6 is non-zero.
  110. * - const UByte S: Speed that the characters split.
  111. *
  112. * Causes the common 'split effect' whereby the second and third
  113. * characters in the current party 'come out' from the party
  114. * leader. That is, they become visible in the field, starting
  115. * from the center of the party leader, and move out to the
  116. * coordinates specified in the argument list. This is commonly
  117. * used when the other characters in the current party have an
  118. * action or dialog to perform and must be individually visible in
  119. * the field. As well as specifying final coordinates for the two
  120. * other party characters, the directions each character faces
  121. * after the split are specified as a byte, using the common
  122. * direction values found throughout the game. Speed is also given
  123. * and is used to specify the rate at which the characters leave
  124. * the party leader, using a scale from 1 (almost instant) to FF
  125. * (extremely slow walk); this must be non-zero. In contrast to
  126. * most MOVE related op codes, the speed is this setting is
  127. * actually the total number of frames required. Depending on the
  128. * distance from the player character and the number of frames
  129. * required, the entity plays a run or walk animation. Also, all
  130. * characters take the same time irrespective of distance.
  131. *
  132. * @param codegen[in|out] Code generator to append lines.
  133. */
  134. void ProcessSPLIT(CodeGenerator* code_gen);
  135. void ProcessTLKON(CodeGenerator* code_gen, const std::string& entity);
  136. void ProcessPC(CodeGenerator* code_gen, const std::string& entity);
  137. void ProcessCHAR(CodeGenerator* code_gen, const std::string& entity);
  138. void ProcessDFANM(CodeGenerator* code_gen, const std::string& entity, int char_id);
  139. void ProcessANIME1(CodeGenerator* code_gen, const std::string& entity, int char_id);
  140. void ProcessVISI(CodeGenerator* code_gen, const std::string& entity);
  141. void ProcessXYZI(CodeGenerator* code_gen, const std::string& entity);
  142. void ProcessMOVE(CodeGenerator* code_gen, const std::string& entity);
  143. void ProcessMSPED(CodeGenerator* code_gen, const std::string& entity);
  144. void ProcessDIR(CodeGenerator* code_gen, const std::string& entity);
  145. void ProcessTURNGEN(CodeGenerator* code_gen, const std::string& entity);
  146. void ProcessGETAI(CodeGenerator* code_gen, const FieldEngine& engine);
  147. void ProcessANIM_2(CodeGenerator* code_gen, const std::string& entity, int char_id);
  148. void ProcessCANIM2(CodeGenerator* code_gen, const std::string& entity, int char_id);
  149. void ProcessCANM_2(CodeGenerator* code_gen, const std::string& entity, int char_id);
  150. void ProcessCC(CodeGenerator* code_gen, const FieldEngine& engine);
  151. /**
  152. * Processes a JUMP opcode.
  153. *
  154. * Opcode: 0xC0
  155. * Short name: JUMP
  156. * Long name: Jump
  157. *
  158. * Memory layout (7 bytes)
  159. * |0xC2|B1/B2|B3/B4|X|Y|I|Steps|
  160. *
  161. * Arguments
  162. * - const Bit[4] B1: Bank to retrieve X-coordinate, or zero if
  163. * specifying X as a literal value.
  164. * - const Bit[4] B2: Bank to retrieve Y-coordinate, or zero if
  165. * specifying Y as a literal value.
  166. * - const Bit[4] B3: Bank to retrieve triangle ID, or zero if
  167. * specifying Z as a literal value.
  168. * - const Bit[4] B4: Bank to retrieve jump height, or zero if
  169. * specifying H as a literal value.
  170. * - const Short X: X-coordinate of the target to jump to, or
  171. * lower byte specifying address if B1 is non-zero.
  172. * - const Short Y: Y-coordinate of the target to jump to, or
  173. * lower byte specifying address if B2 is non-zero.
  174. * - const Short I: Triangle ID of the target to jump to, or
  175. * lower byte specifying address if B3 is non-zero.
  176. * - const UShort Steps: Steps in jump. Must be non-zero if a
  177. * literal value. Alternatively, lower byte specifies address if
  178. * B4 is non-zero.
  179. *
  180. * Causes the character to jump to the specified point and
  181. * triangle ID, with the jump curve peaking at a height which is
  182. * increased by using a larger value for the H argument. In
  183. * addition, the larger the number, the longer the jump will take
  184. * to complete. A "normal" value is around 0x15, 0x01 is fast and
  185. * instantaneous; the argument must not be zero or the game will
  186. * crash. Whilst this is an unsigned two-byte number, a large
  187. * value (beyond around 0x60) will not only cause a vast jump
  188. * height, but also cause the screen to scroll erratically (the
  189. * larger the number, the more erratic).
  190. * Main update function go through all entity with JUMP state and
  191. * if stage is 0 it calculates final Z point according to triangle
  192. * id. It sets current coords as start coords. The main thing this
  193. * function does is set B coefficient for later calculation. It
  194. * defines as follows:
  195. * B = (Z_final - Z_start) / steps - steps * 1.45;
  196. * Then it set current step to 0 and stage to 1. On next update
  197. * other part of function works. It's calculate real position.
  198. * First it increment current step number. Then it calculate X and
  199. * Y. They change linear so nothing interesting here. The Z
  200. * calculation is as follows:
  201. * Z_current = - step^2 * 1.45 + step * B + Z_start;
  202. * If current substep equal number of steps then we set current
  203. * triangle to final triangle and set stage to 2. Which finalizes
  204. * the routine on next opcode call. Neither animation nor sound is
  205. * specified in this opcode. An animation is played by using an
  206. * animation opcode such as DFANM, and a SOUND played, before the
  207. * jump.
  208. *
  209. * @param codegen[in|out] Code generator to append lines.
  210. * @param entity[in] The name of the entity.
  211. */
  212. void ProcessJUMP(CodeGenerator* code_gen, const std::string& entity);
  213. /**
  214. * Processes a AXYZI opcode
  215. *
  216. * Opcode: 0xC1
  217. * Short name: AXYZI
  218. * Long name: Entity Get Position
  219. *
  220. * Memory layout (8 bytes)
  221. * |0xC1|B1/B2|B3/B4|A|X|Y|Z|I|
  222. *
  223. * Arguments
  224. * - const Bit[4] B1: Bank to store X.
  225. * - const Bit[4] B2: Bank to store Y.
  226. * - const Bit[4] B3: Bank to store Z.
  227. * - const Bit[4] B4: Bank to store I.
  228. * - const UByte A: Entity ID whose field object will have its
  229. * position retrieved from.
  230. * - const UByte X: Address to store the X-coordinate.
  231. * - const UByte Y: Address to store the Y-coordinate.
  232. * - const UByte Z: Address to store the Z-coordinate.
  233. * - const UByte I: Address to store the ID of the walkmesh
  234. * triangle the object is standing on.
  235. *
  236. * Retrieves the coordinates of the field object that the entity,
  237. * whose ID specified in A, is associated with. This opcode uses
  238. * an entity ID, not a field object offset; as such, if an entity
  239. * ID is given that does not have a field object, this opcode will
  240. * store zero in each of the four address specified.
  241. *
  242. * @param codegen[in|out] Code generator to append lines.
  243. */
  244. void ProcessAXYZI(CodeGenerator* code_gen);
  245. /**
  246. * Processes a LADER opcode.
  247. *
  248. * Opcode: 0xC2
  249. * Short name: LADER
  250. * Long name: Ladder
  251. *
  252. * Memory layout (15 bytes)
  253. * |0xC2|B1/B2|B3/B4|X|X|Y|Y|Z|Z|I|I|K|A|D|S|
  254. *
  255. * Arguments
  256. * - const Bit[4] B1: Bank to retrieve X-coordinate, or zero if X
  257. * is specified as a literal value.
  258. * - const Bit[4] B2: Bank to retrieve Y-coordinate, or zero if Y
  259. * is specified as a literal value.
  260. * - const Bit[4] B3: Bank to retrieve Z-coordinate, or zero if Z
  261. * is specified as a literal value.
  262. * - const Bit[4] B4: Bank to retrieve ID, or zero if I is
  263. * specified as a literal value.
  264. * - const Short X: X-coordinate of the end of the ladder, or
  265. * address to find X-coordinate if B1 is non-zero.
  266. * - const Short Y: Y-coordinate of the end of the ladder, or
  267. * address to find Y-coordinate if B2 is non-zero.
  268. * - const Short Z: Z-coordinate of the end of the ladder, or
  269. * address to find Z-coordinate if B3 is non-zero.
  270. * - const UShort I: ID of the walkmesh triangle found at the end
  271. * of the ladder, or address to find ID if B4 is non-zero.
  272. * - const UByte K: The keys used to move the character on the
  273. * ladder.
  274. * - const UByte A: Animation ID for the field object's movement
  275. * animation.
  276. * - const UByte D: Direction the character faces when climbing
  277. * the ladder.
  278. * - const UByte S: Speed of the animation whilst climbing the
  279. * ladder.
  280. *
  281. * Causes the character to climb a ladder; that is, switching from
  282. * standard walkmesh movement, to climbing along a line connecting
  283. * two points on the walkmesh. If B1, B2, B3 or B4 is non-zero,
  284. * then the value for that particular component is taken from
  285. * memory using the corresponding bank and address specified,
  286. * rather than as a literal value. Both retrieved values and
  287. * literals can be used for different components. If using X, Y, Z
  288. * or I as addresses, the lower byte should hold the address
  289. * whilst the higher byte should be zero. The coordinates specify
  290. * the end-point of the ladder; the current position of the
  291. * character is used as the start point. The ID of the walkmesh
  292. * triangle must be specified; this is the triangle the character
  293. * will step onto after reaching the end point of the ladder. The
  294. * K value specifies the keys used to move the character across
  295. * the ladder; keys outside the range found in the table will
  296. * cause unpredictable behaviour. The animation ID specifies an
  297. * offset into the field object's animation list; this animation
  298. * is played at the speed specified by S whilst the character
  299. * climbs. Finally, the D argument is a direction value in the
  300. * game's standard direction format, which orients the character
  301. * on the ladder. This opcode is used as part of the character's
  302. * entity, rather than in a seperate entity, as with a LINE. A
  303. * LINE is used to set the start point of the ladder on the
  304. * walkmesh. When this LINE is crossed by the player, a script in
  305. * the LINE then uses a PREQ (or one of its variants), calling the
  306. * script in the party leader that defines the LADER, causing the
  307. * character to switch to 'climbing mode'. To set up a two-way
  308. * ladder, two LINEs are used at either end, with different values
  309. * for the LADER arguments, such as differing end points. If this
  310. * opcode is used as part of a non-playable character entity, the
  311. * NPC object will automatically climb from the start to the end
  312. * point without need for player interaction.
  313. *
  314. * @param codegen[in|out] Code generator to append lines.
  315. * @param entity[in] The name of the entity.
  316. */
  317. void ProcessLADER(CodeGenerator* code_gen, const std::string& entity);
  318. void ProcessSOLID(CodeGenerator* code_gen, const std::string& entity);
  319. /**
  320. * Processes an OFST opcode.
  321. *
  322. * Opcode: 0xC3
  323. * Short name: OFST
  324. * Long name: Offset Object
  325. *
  326. * Memory layout (8 bytes)
  327. * |0xC3|B1/B2|B3/B4|T|X|Y|Z|S|
  328. *
  329. * Arguments:
  330. * - const Bit[4] B1: Bank to retrieve X offset, or zero if X is
  331. * specified as a literal.
  332. * - const Bit[4] B2: Bank to retrieve Y offset, or zero if Y is
  333. * specified as a literal.
  334. * - const Bit[4] B3: Bank to retrieve Z offset, or zero if Z is
  335. * specified as a literal.
  336. * - const Bit[4] B4: Bank to retrieve speed, or zero if S is
  337. * specified as a literal.
  338. * - const UByte T: Type of movement.
  339. * - const Short X: X offset amount, relative to current position,
  340. * or address to find X offset, if B1 is non-zero.
  341. * - const Short Y: Y offset amount, relative to current position,
  342. * or address to find Y offset, if B2 is non-zero.
  343. * - const Short Z: Z offset amount, relative to current position,
  344. * or address to find Z offset, if B3 is non-zero.
  345. * - const UShort S: Speed of the offset movement, if type is
  346. * non-zero, or address to find speed, if B4 is non-zero.
  347. *
  348. * Offsets the field object, belonging to the entity whose script
  349. * this opcode resides in, by a certain amount. After being
  350. * offset, the character continues to be constrained in movement
  351. * as defined by the walkmesh's shape, but at a certain distance
  352. * away from the normal walkmesh position. Other field objects are
  353. * unaffected, and their position or movements are maintained on
  354. * the walkmesh's original position. If B1, B2, B3 or B4 is
  355. * non-zero, then the value for that particular component is taken
  356. * from memory using the corresponding bank and address specified,
  357. * rather than as a literal value. Both retrieved values and
  358. * literals can be used for different components. If using T, X, Y
  359. * or S as addresses, the lower byte should hold the address
  360. * whilst the higher byte should be zero. The amount to offset is
  361. * specified relative to the current position. If Type is
  362. * specified, the object moves gradually from its current point to
  363. * the offset position; this can be used to simulate movements
  364. * such as elevators. Any type outside the range in the table will
  365. * cause the offset not to occur. If the object is set to move
  366. * gradually, then the speed of offset can be set; the greater the
  367. * number, the slower the object moves to its target offset.
  368. * Script execution may also be halted until the gradual offset
  369. * has been completed. For this, see OFSTW.
  370. *
  371. * @param codegen[in|out] Code generator to append lines.
  372. * @param entity[in] The entity name.
  373. */
  374. void ProcessOFST(CodeGenerator* codegen, const std::string& entity);
  375. };
  376. }