ff7_field_engine.h 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  1. /*
  2. * Q-Gears
  3. * Copyright (C) 2022 Q-Gears Team
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #pragma once
  19. #include "decompiler/decompiler_engine.h"
  20. #include <string>
  21. #include <vector>
  22. #include "sudm.h"
  23. namespace FF7{
  24. /**
  25. * Represents the FF7 Field engine.
  26. */
  27. class FF7FieldEngine : public Engine{
  28. public:
  29. /**
  30. * FF7FieldEngine constructor.
  31. *
  32. * Generates a FF7FieldEngine.
  33. *
  34. * @param formatter[in] The formatter to be used by the engine.
  35. * @param scriptName The script name.
  36. */
  37. FF7FieldEngine(
  38. SUDM::IScriptFormatter& formatter, std::string scriptName
  39. ) : mFormatter(formatter), mScriptName(scriptName){
  40. setOutputStackEffect(false);
  41. }
  42. /**
  43. * Destructor.
  44. */
  45. FF7FieldEngine(const FF7FieldEngine&) = delete;
  46. /**
  47. * Destructor.
  48. */
  49. FF7FieldEngine& operator = (const FF7FieldEngine&) = delete;
  50. /**
  51. * Represents an entity.
  52. *
  53. * An entity can be almost anything in a field map: the playable
  54. * character, an NPC, an item, a line...
  55. */
  56. class Entity{
  57. public:
  58. /**
  59. * Entity constructor.
  60. *
  61. * It doesn't initialize any of the fields.
  62. */
  63. Entity() = default;
  64. /**
  65. * Entity constructor.
  66. *
  67. * Instantiates an entity with a name.
  68. *
  69. * @param name[in] Entity name.
  70. */
  71. Entity(const std::string& name): mName(name){}
  72. /**
  73. * Retrieves the entity name.
  74. *
  75. * @return The entity name
  76. */
  77. std::string Name() const{
  78. return mName;
  79. }
  80. /**
  81. * Retrieves a function.
  82. *
  83. * Retrieves the name of a function from it's index.
  84. *
  85. * @param index[in] Function index.
  86. * @return Function name.
  87. * @throws InternalDecompilerError if there is no function
  88. * with the specified index.
  89. * @todo What is a function here? An Opcode?
  90. */
  91. std::string FunctionByIndex(size_t index) const{
  92. auto it = mFunctions.find(index);
  93. if (it == std::end(mFunctions)){
  94. throw InternalDecompilerError();
  95. }
  96. return it->second;
  97. }
  98. /**
  99. * Adds a function to the engine.
  100. *
  101. * Must be added by name and index.
  102. *
  103. * @param name[in] Function name.
  104. * @param index[in] Function index.
  105. * @todo What is a function here? An Opcode?
  106. */
  107. void AddFunction(const std::string& name, size_t index){
  108. mFunctions[index] = name;
  109. }
  110. private:
  111. /**
  112. * Entity name.
  113. */
  114. std::string mName;
  115. /**
  116. * Function list.
  117. * @todo What is a function here? An Opcode?
  118. */
  119. std::map< size_t, std::string > mFunctions;
  120. };
  121. /**
  122. * Retrieves the dissasembler.
  123. *
  124. * @param insts[in] List of instructions.
  125. * @param rawScriptData[in] Script data, raw format.
  126. * @return Pointer to the dissasembler.
  127. * @todo Understand and document properly.
  128. */
  129. virtual std::unique_ptr<Disassembler> getDisassembler(
  130. InstVec &insts, const std::vector<unsigned char>& rawScriptData
  131. ) override;
  132. /**
  133. * Retrieves the dissasembler.
  134. *
  135. * @param insts[in] List of instructions.
  136. * @return Pointer to the dissasembler.
  137. * @todo Understand and document properly.
  138. */
  139. virtual std::unique_ptr<Disassembler> getDisassembler(
  140. InstVec &insts
  141. ) override;
  142. /**
  143. * Retrieves the code generator.
  144. *
  145. * @param insts[in] List of instructions.
  146. * @param output[in] Pointer to the output (file, stream...).
  147. * @return Pointer to the generator.
  148. * @todo Understand and document properly.
  149. */
  150. virtual std::unique_ptr<CodeGenerator> getCodeGenerator(
  151. const InstVec& insts, std::ostream &output
  152. ) override;
  153. /**
  154. * Postprocessing actions to apply to the scripts.
  155. *
  156. * @param insts[in] Instruction list.
  157. * @param g[in] Code graph.
  158. * @todo Understand and document properly.
  159. * @todo What is the graph used to?
  160. */
  161. virtual void postCFG(InstVec &insts, Graph g) override;
  162. /**
  163. * Indicates if instructions are purely grouped.
  164. *
  165. * @return True if instructions are purely grouped.
  166. * @todo What is pure grouping?
  167. */
  168. virtual bool usePureGrouping() const override{return false;}
  169. /**
  170. * Retrieves all entities in the map.
  171. *
  172. * @return A map of entities, with the name and index.
  173. */
  174. std::map<std::string, int> GetEntities() const;
  175. /**
  176. * Adds a function to an entity.
  177. *
  178. * @param entityName Name of the entity.
  179. * @param entityIndex Index of the entity.
  180. * @param functionName Name of the function.
  181. * @param functionIndex Index of the function.
  182. */
  183. void AddEntityFunction(
  184. const std::string& entityName, size_t entityIndex,
  185. const std::string& funcName, size_t funcIndex
  186. );
  187. /**
  188. * Retrieves an entity.
  189. *
  190. * @param index[in] Index of the entity to retrieve.
  191. * @throws InternalDecompilerError if there is no entity at the
  192. * specified index.
  193. */
  194. const Entity& EntityByIndex(size_t index) const{
  195. auto it = mEntityIndexMap.find(index);
  196. if (it == std::end(mEntityIndexMap)){
  197. throw InternalDecompilerError();
  198. }
  199. return it->second;
  200. }
  201. /**
  202. * Retrieves the scale factor for the map.
  203. *
  204. * @return Map scale factor.
  205. */
  206. float ScaleFactor() const {return mScaleFactor;}
  207. /**
  208. * Retrieves the script name.
  209. *
  210. * @return The script name.
  211. */
  212. const std::string& ScriptName() const { return mScriptName; }
  213. private:
  214. /**
  215. * Removes extraneous return statements.
  216. *
  217. * Usefull for scripts that only contain one one return
  218. * statement.
  219. *
  220. * @param insts[in|out] List of instructions to proccess. Extraneous
  221. * return statements will be deleted from the instructions.
  222. * @param g[in] Code graph.
  223. * @todo What is the graph used to?
  224. */
  225. void RemoveExtraneousReturnStatements(InstVec& insts, Graph g);
  226. /**
  227. * Removes trailing infinite loops.
  228. *
  229. * In FF7 some scripts ends with an infinite loop to keep it alive.
  230. * in QGears this isn't required, and can cause infinite loops, so
  231. * they can be removed.
  232. *
  233. * @param insts[in|out] List of instructions to proccess. Trailing
  234. * infinite loops will be deleted from the instructions.
  235. * @param g[in] Code graph.
  236. * @todo What is the graph used to?
  237. */
  238. void RemoveTrailingInfiniteLoops(InstVec& insts, Graph g);
  239. /**
  240. * Tries to detect scripts with trailing infinite loops.
  241. *
  242. * In FF7 some scripts ends with an infinite loop to keep it alive.
  243. * in QGears this isn't required, and can cause infinite loops, so
  244. * they can be removed. This function marks them, so they can be
  245. * deleted with @{see FF7FieldEngine::RemoveTrailingInfiniteLoops}
  246. */
  247. void MarkInfiniteLoopGroups(InstVec& insts, Graph g);
  248. /**
  249. * The script formatter.
  250. */
  251. SUDM::IScriptFormatter& mFormatter;
  252. /**
  253. * The entity index map for the field.
  254. */
  255. std::map<size_t, Entity> mEntityIndexMap;
  256. /**
  257. * The map scale factor.
  258. */
  259. float mScaleFactor = 1.0f;
  260. /**
  261. * The script name.
  262. */
  263. std::string mScriptName;
  264. };
  265. /**
  266. * An unconditional map jump instruction.
  267. */
  268. class FF7UncondJumpInstruction : public UncondJumpInstruction{
  269. public:
  270. /**
  271. * Whether or not this is really a call to a script function.
  272. */
  273. bool _isCall;
  274. /**
  275. * Constructor.
  276. */
  277. FF7UncondJumpInstruction() : _isCall(false) {}
  278. /**
  279. * Indicates if the instruction is a function call.
  280. *
  281. * @return true if the instruction is a function call, false if not.
  282. */
  283. virtual bool isFuncCall() const;
  284. /**
  285. * Indicates if the instruction is an unconditional jump.
  286. *
  287. * @return true if the instruction is an unconditional jump, false
  288. * if it's not.
  289. */
  290. virtual bool isUncondJump() const;
  291. /**
  292. * Retrieves the destination address of the jump.
  293. *
  294. * @return The offset (number of bytes) to jump from the beginning
  295. * of the instruction.
  296. */
  297. virtual uint32 getDestAddress() const;
  298. /**
  299. * Processes the instruction.
  300. *
  301. * @param func[in] Function to process.
  302. * @param stack[out] Function stack.
  303. * @param engine[in] Engine.
  304. * @param codeGen[in] Code generator.
  305. * @todo Func and engine are unused?
  306. * @todo Understand and document properly.
  307. */
  308. virtual void processInst(
  309. Function& func, ValueStack &stack,
  310. Engine *engine, CodeGenerator *codeGen
  311. ) override;
  312. /**
  313. * Prints the instruction
  314. *
  315. * @param output The stram to print the instruction to.
  316. * @todo Understand and document properly.
  317. */
  318. virtual std::ostream& print(std::ostream &output) const override;
  319. };
  320. /**
  321. * A conditional map jump instruction.
  322. */
  323. class FF7CondJumpInstruction : public CondJumpInstruction{
  324. public:
  325. /**
  326. * Processes the instruction.
  327. *
  328. * @param func[in] Function to process.
  329. * @param stack[out] Function stack.
  330. * @param engine[in] Engine.
  331. * @param codeGen[in] Code generator.
  332. * @todo Func and engine are unused?
  333. * @todo Understand and document properly.
  334. */
  335. virtual void processInst(
  336. Function& func, ValueStack &stack,
  337. Engine *engine, CodeGenerator *codeGen
  338. ) override;
  339. /**
  340. * Retrieves the destination address of the jump.
  341. *
  342. * @return The offset (number of bytes) to jump from the beginning
  343. * of the instruction.
  344. */
  345. virtual uint32 getDestAddress() const override;
  346. /**
  347. * Prints the instruction
  348. *
  349. * @param output The stram to print the instruction to.
  350. * @todo Understand and document properly.
  351. */
  352. virtual std::ostream& print(std::ostream &output) const override;
  353. };
  354. /**
  355. * A script flow control instruction.
  356. */
  357. class FF7ControlFlowInstruction : public KernelCallInstruction{
  358. public:
  359. /**
  360. * Create a FF7ControlFlowInstruction.
  361. *
  362. * @return Pointer to the newly created instruction.
  363. */
  364. static InstPtr Create(){return new FF7ControlFlowInstruction();}
  365. /**
  366. * Processes the instruction.
  367. *
  368. * @param func[in] Function to process.
  369. * @param stack[out] Function stack.
  370. * @param engine[in] Engine.
  371. * @param codeGen[in] Code generator.
  372. * @todo Func and engine are unused?
  373. * @todo Understand and document properly.
  374. */
  375. virtual void processInst(
  376. Function& func, ValueStack &stack,
  377. Engine *engine, CodeGenerator *codeGen
  378. ) override;
  379. private:
  380. /**
  381. * Processes a REQ command.
  382. *
  383. * Opcode: 0x01
  384. * Short name: REQ
  385. * Long name: Request remote execution (asynchronous,
  386. * non-guaranteed)
  387. *
  388. * Memory layout
  389. * 0x01
  390. * E
  391. * P/F
  392. *
  393. * Arguments
  394. *
  395. * const UByte E: The ID of the target entity.
  396. * const Bit[3] P: The priority at which we want to execute the
  397. * remote script (high 3 bits of byte).
  398. * const Bit[5] F: The ID of the specific member function of E to be
  399. * executed (low 5 bits of byte).
  400. *
  401. * Requests that a remote entity executes one of its member
  402. * functions at a specified priority. The request is asynchronous
  403. * and returns immediately without waiting for the remote execution
  404. * to start or finish. If the specified priority is already busy
  405. * executing, the request will fail silently.
  406. *
  407. * @param codegen[in|out] Code generator. Output lines are appended
  408. * to it.
  409. * @param engine[in] The engine instance to fetch entities.
  410. */
  411. void processREQ(
  412. CodeGenerator* codeGen,
  413. const FF7FieldEngine& engine
  414. );
  415. /**
  416. * Processes a REQSW command.
  417. *
  418. * Opcode: 0x02
  419. * Short name: REQSW
  420. * Long name: Request remote execution (asynchronous execution,
  421. * guaranteed)
  422. *
  423. * Memory layout
  424. * 0x02
  425. * E
  426. * P/F
  427. *
  428. * Arguments
  429. *
  430. * const UByte E: The ID of the target entity.
  431. * const Bit[3] P: The priority at which we want to execute the
  432. * remote script (high 3 bits of byte).
  433. * const Bit[5] F: The ID of the specific member function of E to be
  434. * executed (low 5 bits of byte).
  435. *
  436. * Requests that a remote entity executes one of its member
  437. * functions at a specified priority. If the specified priority is
  438. * already busy executing, the request will block until it becomes
  439. * available and only then return. The remote execution is still
  440. * carried out asynchronously, with no notification of completion.
  441. *
  442. * @param codegen[in|out] Code generator. Output lines are appended
  443. * to it.
  444. * @param engine[in] The engine instance to fetch entities.
  445. */
  446. void processREQSW(
  447. CodeGenerator* codeGen,
  448. const FF7FieldEngine& engine
  449. );
  450. /**
  451. * Processes a REQEW command.
  452. *
  453. * Opcode: 0x03
  454. * Short name: REQEW
  455. * Long name: Request remote execution (synchronous, guaranteed)
  456. *
  457. * Memory layout
  458. * 0x03
  459. * E
  460. * P/F
  461. *
  462. * Arguments
  463. *
  464. * const UByte E: The ID of the target entity.
  465. * const Bit[3] P: The priority at which we want to execute the
  466. * remote script (high 3 bits of byte).
  467. * const Bit[5] F: The ID of the specific member function of E to be
  468. * executed (low 5 bits of byte).
  469. *
  470. * Requests that a remote entity executes one of its member
  471. * functions at a specified priority. The request will block until
  472. * remote execution has finished before returning.
  473. *
  474. * @param codegen[in|out] Code generator. Output lines are appended
  475. * to it.
  476. * @param engine[in] The engine instance to fetch entities.
  477. */
  478. void processREQEW(
  479. CodeGenerator* codeGen,
  480. const FF7FieldEngine& engine
  481. );
  482. /**
  483. * Processes a RETTO command.
  484. *
  485. * Opcode: 0x07
  486. * Short name: RETTO
  487. * Long name: Return To
  488. *
  489. * Memory layout
  490. * 0x07
  491. * P/F
  492. *
  493. * Arguments
  494. * const Bit[3] P: The priority at which we want to execute the
  495. * remote script (high 3 bits of byte).
  496. * const Bit[5] F: The ID of the specific member function of the
  497. * current entity to be executed to (low 5 bits
  498. * of byte).
  499. *
  500. * Stops the active script loop for this entity and also any script
  501. * loops (except the main) that are queuing to be executed after the
  502. * current script. This is essentially the same as adding a RET onto
  503. * each of the active / queued scripts next execution position and
  504. * returning the current op index to index for each script. Then the
  505. * script control is passed to the script F within the current
  506. * entity with the priority P.
  507. *
  508. * @param codegen[in|out] Code generator. Output lines are appended
  509. * to it.
  510. */
  511. void processRETTO(CodeGenerator* codeGen);
  512. /**
  513. * Processes a WAIT command.
  514. *
  515. * Opcode: 0x24
  516. * Short name: WAIT
  517. * Long name: Wait
  518. *
  519. * Memory layout
  520. * 0x24
  521. * A
  522. *
  523. * Arguments
  524. * const UShort A: Amount (number of frames) to wait.
  525. *
  526. * Pauses current script execution for a specific amount of time.
  527. * Rather than a specific time value in milliseconds/seconds,
  528. * the amount specifies the number of frames that must be drawn
  529. * before execution resumes. Since the game runs at 30fps,
  530. * WAIT(0x1E) (or WAIT(30) in decimal) will pause script execution
  531. * for 1 second, WAIT(0x96) will pause for 5 seconds, and so on.
  532. *
  533. * @param codegen[in|out] Code generator. Output lines are appended
  534. * to it.
  535. */
  536. void processWAIT(CodeGenerator* codeGen);
  537. };
  538. /**
  539. * A module instruction.
  540. */
  541. class FF7ModuleInstruction : public KernelCallInstruction{
  542. public:
  543. /**
  544. * Processes the instruction.
  545. *
  546. * @param func[in] Function to process.
  547. * @param stack[out] Function stack.
  548. * @param engine[in] Engine.
  549. * @param codeGen[in] Code generator.
  550. * @todo Func and engine are unused?
  551. * @todo Understand and document properly.
  552. */
  553. virtual void processInst(
  554. Function& func, ValueStack &stack,
  555. Engine *engine, CodeGenerator *codeGen
  556. ) override;
  557. private:
  558. /**
  559. * Processes a BATTLE command.
  560. *
  561. * Opcode: 0x70
  562. * Short name: BATTLE
  563. * Long name: Start battle
  564. *
  565. * Memory layout
  566. * 0x70
  567. * B
  568. * N
  569. * N
  570. *
  571. * Arguments
  572. * const UByte B: Bank (16-bit) to retrieve the address of the
  573. * battle ID, or zero if it is given as a literal
  574. * value.
  575. * const UWord N: Battle ID, or address to find ID if B is
  576. * non-zero.
  577. *
  578. * This launches the battle module with whatever battle number is
  579. * used in the argument, or the value retrieved from memory location
  580. * N if B is non-zero. Battle 1, 2, and 999 (0x03E7) are debug
  581. * battles.
  582. *
  583. * @param codegen[in|out] Code generator. Output lines are appended
  584. * to it.
  585. */
  586. void processBATTLE(CodeGenerator* codeGen);
  587. /**
  588. * Processes a BTLON command.
  589. *
  590. * Opcode: 0x71
  591. * Short name: BTLON
  592. * Long name: Battle switch
  593. *
  594. * Memory layout
  595. * 0x71
  596. * S
  597. *
  598. * Arguments
  599. * const UByte S: Switch battles on/off (0/1, respectively).
  600. *
  601. * Turns random encounters on or off for this field. Note that if a
  602. * field does not have any Encounter Data set in its field file,
  603. * battles will not occur regardless of the argument passed with
  604. * this opcode.
  605. *
  606. * @param codegen[in|out] Code generator. Output lines are appended
  607. * to it.
  608. */
  609. void processBTLON(CodeGenerator* codeGen);
  610. /**
  611. * Processes a MAPJUMP command.
  612. *
  613. * Opcode: 0x60
  614. * Short name: BTLON
  615. * Long name: Change Field
  616. *
  617. * Memory layout
  618. * 0x60
  619. * I
  620. * I
  621. * X
  622. * X
  623. * Y
  624. * Y
  625. * Z
  626. * Z
  627. * D
  628. *
  629. * Arguments
  630. * const UShort I: Field ID of the map to jump to.
  631. * const Short X: X-coordinate of the player on the next field.
  632. * const Short Y: Y-coordinate of the player on the next field.
  633. * const Short Z: Z-coordinate of the player on the next field.
  634. * const UByte D: Direction the character will be facing on the
  635. * next field, in the standard game format.
  636. *
  637. * Switches fields to the one indicated by I, and places the
  638. * character at the coordinates and direction specified. This is an
  639. * alternative to using a gateway, and can complement their usage as
  640. * it allows for more than 12 gateways by simulating their behaviour
  641. * through a LINE which, when crossed, executes a MAPJUMP.
  642. *
  643. * @param codegen[in|out] Code generator. Output lines are appended
  644. * to it.
  645. * @param func[in] Function
  646. * @todo What is func for?
  647. */
  648. void processMAPJUMP(CodeGenerator* codeGen, Function& func);
  649. };
  650. class FF7MathInstruction : public StoreInstruction
  651. {
  652. public:
  653. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  654. private:
  655. void processSaturatedPLUS(CodeGenerator* codeGen);
  656. void processSaturatedPLUS2(CodeGenerator* codeGen);
  657. void processSaturatedMINUS(CodeGenerator* codeGen);
  658. void processSaturatedMINUS2(CodeGenerator* codeGen);
  659. void processSaturatedINC(CodeGenerator* codeGen);
  660. void processSaturatedINC2(CodeGenerator* codeGen);
  661. void processSaturatedDEC(CodeGenerator* codeGen);
  662. void processSaturatedDEC2(CodeGenerator* codeGen);
  663. void processRDMSD(CodeGenerator* codeGen);
  664. void processSETBYTE_SETWORD(CodeGenerator* codeGen);
  665. void processBITON(CodeGenerator* codeGen);
  666. void processPLUSx_MINUSx(CodeGenerator* codeGen, const std::string& op);
  667. void processINCx_DECx(CodeGenerator* codeGen, const std::string& op);
  668. void processRANDOM(CodeGenerator* codeGen);
  669. };
  670. class FF7WindowInstruction : public KernelCallInstruction
  671. {
  672. public:
  673. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  674. private:
  675. void processMESSAGE(CodeGenerator* codeGen, const std::string& scriptName);
  676. void processMPNAM(CodeGenerator* codeGen);
  677. void processMENU2(CodeGenerator* codeGen);
  678. void processWINDOW(CodeGenerator* codeGen);
  679. void processWCLSE(CodeGenerator* codeGen);
  680. };
  681. class FF7PartyInstruction : public KernelCallInstruction
  682. {
  683. public:
  684. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  685. private:
  686. void processSTITM(CodeGenerator* codeGen);
  687. void processPRTYE(CodeGenerator* codeGen);
  688. };
  689. class FF7ModelInstruction : public KernelCallInstruction
  690. {
  691. public:
  692. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  693. private:
  694. void processTLKON(CodeGenerator* codeGen, const std::string& entity);
  695. void processPC(CodeGenerator* codeGen, const std::string& entity);
  696. void processCHAR(CodeGenerator* codeGen, const std::string& entity);
  697. void processDFANM(CodeGenerator* codeGen, const std::string& entity, int charId);
  698. void processANIME1(CodeGenerator* codeGen, const std::string& entity, int charId);
  699. void processVISI(CodeGenerator* codeGen, const std::string& entity);
  700. void processXYZI(CodeGenerator* codeGen, const std::string& entity);
  701. void processMOVE(CodeGenerator* codeGen, const std::string& entity);
  702. void processMSPED(CodeGenerator* codeGen, const std::string& entity);
  703. void processDIR(CodeGenerator* codeGen, const std::string& entity);
  704. void processTURNGEN(CodeGenerator* codeGen, const std::string& entity);
  705. void processGETAI(CodeGenerator* codeGen, const FF7FieldEngine& engine);
  706. void processANIM_2(CodeGenerator* codeGen, const std::string& entity, int charId);
  707. void processCANIM2(CodeGenerator* codeGen, const std::string& entity, int charId);
  708. void processCANM_2(CodeGenerator* codeGen, const std::string& entity, int charId);
  709. void processCC(CodeGenerator* codeGen, const FF7FieldEngine& engine);
  710. void processSOLID(CodeGenerator* codeGen, const std::string& entity);
  711. };
  712. class FF7WalkmeshInstruction : public KernelCallInstruction
  713. {
  714. public:
  715. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  716. private:
  717. void processUC(CodeGenerator* codeGen);
  718. };
  719. class FF7BackgroundInstruction : public KernelCallInstruction
  720. {
  721. public:
  722. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  723. private:
  724. void processBGON(CodeGenerator* codeGen);
  725. void processBGOFF(CodeGenerator* codeGen);
  726. void processBGCLR(CodeGenerator* codeGen);
  727. void processSTPAL(CodeGenerator* codeGen);
  728. void processLDPAL(CodeGenerator* codeGen);
  729. void processCPPAL(CodeGenerator* codeGen);
  730. void processADPAL(CodeGenerator* codeGen);
  731. void processMPPAL2(CodeGenerator* codeGen);
  732. void processSTPLS(CodeGenerator* codeGen);
  733. void processLDPLS(CodeGenerator* codeGen);
  734. };
  735. class FF7CameraInstruction : public KernelCallInstruction
  736. {
  737. public:
  738. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  739. private:
  740. void processNFADE(CodeGenerator* codeGen);
  741. void processSCR2D(CodeGenerator* codeGen);
  742. void processSCR2DC(CodeGenerator* codeGen);
  743. void processFADE(CodeGenerator* codeGen);
  744. };
  745. class FF7AudioVideoInstruction : public KernelCallInstruction
  746. {
  747. public:
  748. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  749. private:
  750. void processAKAO2(CodeGenerator* codeGen);
  751. void processMUSIC(CodeGenerator* codeGen);
  752. void processSOUND(CodeGenerator* codeGen);
  753. void processAKAO(CodeGenerator* codeGen);
  754. void processMULCK(CodeGenerator* codeGen);
  755. void processPMVIE(CodeGenerator* codeGen);
  756. void processMOVIE(CodeGenerator* codeGen);
  757. void processMVIEF(CodeGenerator* codeGen);
  758. };
  759. class FF7UncategorizedInstruction : public KernelCallInstruction
  760. {
  761. public:
  762. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  763. };
  764. class FF7NoOperationInstruction : public Instruction
  765. {
  766. public:
  767. static InstPtr Create() { return new FF7NoOperationInstruction(); }
  768. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  769. };
  770. }