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