ff7_field_engine.h 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  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), is_line_(false){}
  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. /**
  111. * Indicates if the entity is a line.
  112. * @TODO: Make private.
  113. */
  114. bool is_line_;
  115. /**
  116. * The first point of the line.
  117. * @TODO: Make private.
  118. */
  119. std::vector<float> point_a_;
  120. /**
  121. * The first point of the line.
  122. * @TODO: Make private.
  123. */
  124. std::vector<float> point_b_;
  125. float ax, ay, az, bx, by, bz;
  126. private:
  127. /**
  128. * Entity name.
  129. */
  130. std::string mName;
  131. /**
  132. * Function list.
  133. * @todo What is a function here? An Opcode?
  134. */
  135. std::map< size_t, std::string > mFunctions;
  136. };
  137. /**
  138. * Retrieves the dissasembler.
  139. *
  140. * @param insts[in] List of instructions.
  141. * @param rawScriptData[in] Script data, raw format.
  142. * @return Pointer to the dissasembler.
  143. * @todo Understand and document properly.
  144. */
  145. virtual std::unique_ptr<Disassembler> getDisassembler(
  146. InstVec &insts, const std::vector<unsigned char>& rawScriptData
  147. ) override;
  148. /**
  149. * Retrieves the dissasembler.
  150. *
  151. * @param insts[in] List of instructions.
  152. * @return Pointer to the dissasembler.
  153. * @todo Understand and document properly.
  154. */
  155. virtual std::unique_ptr<Disassembler> getDisassembler(
  156. InstVec &insts
  157. ) override;
  158. /**
  159. * Retrieves the code generator.
  160. *
  161. * @param insts[in] List of instructions.
  162. * @param output[in] Pointer to the output (file, stream...).
  163. * @return Pointer to the generator.
  164. * @todo Understand and document properly.
  165. */
  166. virtual std::unique_ptr<CodeGenerator> getCodeGenerator(
  167. const InstVec& insts, std::ostream &output
  168. ) override;
  169. /**
  170. * Postprocessing actions to apply to the scripts.
  171. *
  172. * @param insts[in] Instruction list.
  173. * @param g[in] Code graph.
  174. * @todo Understand and document properly.
  175. * @todo What is the graph used to?
  176. */
  177. virtual void postCFG(InstVec &insts, Graph g) override;
  178. /**
  179. * Indicates if instructions are purely grouped.
  180. *
  181. * @return True if instructions are purely grouped.
  182. * @todo What is pure grouping?
  183. */
  184. virtual bool usePureGrouping() const override{return false;}
  185. /**
  186. * Retrieves all entities in the map.
  187. *
  188. * @return A map of entities, with the name and index.
  189. */
  190. std::map<std::string, int> GetEntities() const;
  191. /**
  192. * Retrieves all line entities in the map.
  193. *
  194. * @param A list of line entities.
  195. */
  196. std::vector<SUDM::FF7::Field::Line> GetLineList() const;
  197. /**
  198. * Retrieves all entities in the map.
  199. *
  200. * @return A map of entities, with the name and index.
  201. */
  202. std::map<size_t, Entity> GetEntityIndexMap() const{
  203. return mEntityIndexMap;
  204. }
  205. /**
  206. * Adds a function to an entity.
  207. *
  208. * @param entityName Name of the entity.
  209. * @param entityIndex Index of the entity.
  210. * @param functionName Name of the function.
  211. * @param functionIndex Index of the function.
  212. */
  213. void AddEntityFunction(
  214. const std::string& entityName, size_t entityIndex,
  215. const std::string& funcName, size_t funcIndex
  216. );
  217. /**
  218. * Marks an entity as a line.
  219. *
  220. * @param entity_index Index of the entity.
  221. * @param line[in] True to mark the entity as a line, false to
  222. * unmark it.
  223. * @param point_a[in] First point of the line. Can be null if line
  224. * is false.
  225. * @param point_b[in] Second point of the line. Can be null if
  226. * line is false.
  227. */
  228. void MarkEntityAsLine(
  229. size_t entity_index, bool line,
  230. std::vector<float> point_a, std::vector<float> point_b
  231. );
  232. /**
  233. * Retrieves an entity.
  234. *
  235. * @param index[in] Index of the entity to retrieve.
  236. * @throws InternalDecompilerError if there is no entity at the
  237. * specified index.
  238. */
  239. const Entity& EntityByIndex(size_t index) const{
  240. auto it = mEntityIndexMap.find(index);
  241. if (it == std::end(mEntityIndexMap)){
  242. throw InternalDecompilerError();
  243. }
  244. return it->second;
  245. }
  246. /**
  247. * Retrieves the scale factor for the map.
  248. *
  249. * @return Map scale factor.
  250. */
  251. float ScaleFactor() const {return mScaleFactor;}
  252. /**
  253. * Retrieves the script name.
  254. *
  255. * @return The script name.
  256. */
  257. const std::string& ScriptName() const { return mScriptName; }
  258. private:
  259. /**
  260. * Removes extraneous return statements.
  261. *
  262. * Usefull for scripts that only contain one one return
  263. * statement.
  264. *
  265. * @param insts[in|out] List of instructions to proccess. Extraneous
  266. * return statements will be deleted from the instructions.
  267. * @param g[in] Code graph.
  268. * @todo What is the graph used to?
  269. */
  270. void RemoveExtraneousReturnStatements(InstVec& insts, Graph g);
  271. /**
  272. * Removes trailing infinite loops.
  273. *
  274. * In FF7 some scripts ends with an infinite loop to keep it alive.
  275. * in QGears this isn't required, and can cause infinite loops, so
  276. * they can be removed.
  277. *
  278. * @param insts[in|out] List of instructions to proccess. Trailing
  279. * infinite loops will be deleted from the instructions.
  280. * @param g[in] Code graph.
  281. * @todo What is the graph used to?
  282. */
  283. void RemoveTrailingInfiniteLoops(InstVec& insts, Graph g);
  284. /**
  285. * Tries to detect scripts with trailing infinite loops.
  286. *
  287. * In FF7 some scripts ends with an infinite loop to keep it alive.
  288. * in QGears this isn't required, and can cause infinite loops, so
  289. * they can be removed. This function marks them, so they can be
  290. * deleted with @{see FF7FieldEngine::RemoveTrailingInfiniteLoops}
  291. */
  292. void MarkInfiniteLoopGroups(InstVec& insts, Graph g);
  293. /**
  294. * The script formatter.
  295. */
  296. SUDM::IScriptFormatter& mFormatter;
  297. /**
  298. * The entity index map for the field.
  299. */
  300. std::map<size_t, Entity> mEntityIndexMap;
  301. /**
  302. * The map scale factor.
  303. */
  304. float mScaleFactor = 1.0f;
  305. /**
  306. * The script name.
  307. */
  308. std::string mScriptName;
  309. };
  310. /**
  311. * An unconditional map jump instruction.
  312. */
  313. class FF7UncondJumpInstruction : public UncondJumpInstruction{
  314. public:
  315. /**
  316. * Whether or not this is really a call to a script function.
  317. */
  318. bool _isCall;
  319. /**
  320. * Constructor.
  321. */
  322. FF7UncondJumpInstruction() : _isCall(false) {}
  323. /**
  324. * Indicates if the instruction is a function call.
  325. *
  326. * @return true if the instruction is a function call, false if not.
  327. */
  328. virtual bool isFuncCall() const;
  329. /**
  330. * Indicates if the instruction is an unconditional jump.
  331. *
  332. * @return true if the instruction is an unconditional jump, false
  333. * if it's not.
  334. */
  335. virtual bool isUncondJump() const;
  336. /**
  337. * Retrieves the destination address of the jump.
  338. *
  339. * @return The offset (number of bytes) to jump from the beginning
  340. * of the instruction.
  341. */
  342. virtual uint32 getDestAddress() const;
  343. /**
  344. * Processes the instruction.
  345. *
  346. * @param func[in] Function to process.
  347. * @param stack[out] Function stack.
  348. * @param engine[in] Engine.
  349. * @param codeGen[in] Code generator.
  350. * @todo Func and engine are unused?
  351. * @todo Understand and document properly.
  352. */
  353. virtual void processInst(
  354. Function& func, ValueStack &stack,
  355. Engine *engine, CodeGenerator *codeGen
  356. ) override;
  357. /**
  358. * Prints the instruction
  359. *
  360. * @param output The stram to print the instruction to.
  361. * @todo Understand and document properly.
  362. */
  363. virtual std::ostream& print(std::ostream &output) const override;
  364. };
  365. /**
  366. * A conditional map jump instruction.
  367. */
  368. class FF7CondJumpInstruction : public CondJumpInstruction{
  369. public:
  370. /**
  371. * Processes the instruction.
  372. *
  373. * @param func[in] Function to process.
  374. * @param stack[out] Function stack.
  375. * @param engine[in] Engine.
  376. * @param codeGen[in] Code generator.
  377. * @todo Func and engine are unused?
  378. * @todo Understand and document properly.
  379. */
  380. virtual void processInst(
  381. Function& func, ValueStack &stack,
  382. Engine *engine, CodeGenerator *codeGen
  383. ) override;
  384. /**
  385. * Retrieves the destination address of the jump.
  386. *
  387. * @return The offset (number of bytes) to jump from the beginning
  388. * of the instruction.
  389. */
  390. virtual uint32 getDestAddress() const override;
  391. /**
  392. * Prints the instruction
  393. *
  394. * @param output The stram to print the instruction to.
  395. * @todo Understand and document properly.
  396. */
  397. virtual std::ostream& print(std::ostream &output) const override;
  398. };
  399. /**
  400. * A script flow control instruction.
  401. */
  402. class FF7ControlFlowInstruction : public KernelCallInstruction{
  403. public:
  404. /**
  405. * Create a FF7ControlFlowInstruction.
  406. *
  407. * @return Pointer to the newly created instruction.
  408. */
  409. static InstPtr Create(){return new FF7ControlFlowInstruction();}
  410. /**
  411. * Processes the instruction.
  412. *
  413. * @param func[in] Function to process.
  414. * @param stack[out] Function stack.
  415. * @param engine[in] Engine.
  416. * @param codeGen[in] Code generator.
  417. * @todo Func and engine are unused?
  418. * @todo Understand and document properly.
  419. */
  420. virtual void processInst(
  421. Function& func, ValueStack &stack,
  422. Engine *engine, CodeGenerator *codeGen
  423. ) override;
  424. private:
  425. /**
  426. * Processes a REQ command.
  427. *
  428. * Opcode: 0x01
  429. * Short name: REQ
  430. * Long name: Request remote execution (asynchronous,
  431. * non-guaranteed)
  432. *
  433. * Memory layout
  434. * 0x01
  435. * E
  436. * P/F
  437. *
  438. * Arguments
  439. *
  440. * const UByte E: The ID of the target entity.
  441. * const Bit[3] P: The priority at which we want to execute the
  442. * remote script (high 3 bits of byte).
  443. * const Bit[5] F: The ID of the specific member function of E to be
  444. * executed (low 5 bits of byte).
  445. *
  446. * Requests that a remote entity executes one of its member
  447. * functions at a specified priority. The request is asynchronous
  448. * and returns immediately without waiting for the remote execution
  449. * to start or finish. If the specified priority is already busy
  450. * executing, the request will fail silently.
  451. *
  452. * @param codegen[in|out] Code generator. Output lines are appended
  453. * to it.
  454. * @param engine[in] The engine instance to fetch entities.
  455. */
  456. void processREQ(
  457. CodeGenerator* codeGen,
  458. const FF7FieldEngine& engine
  459. );
  460. /**
  461. * Processes a REQSW command.
  462. *
  463. * Opcode: 0x02
  464. * Short name: REQSW
  465. * Long name: Request remote execution (asynchronous execution,
  466. * guaranteed)
  467. *
  468. * Memory layout
  469. * 0x02
  470. * E
  471. * P/F
  472. *
  473. * Arguments
  474. *
  475. * const UByte E: The ID of the target entity.
  476. * const Bit[3] P: The priority at which we want to execute the
  477. * remote script (high 3 bits of byte).
  478. * const Bit[5] F: The ID of the specific member function of E to be
  479. * executed (low 5 bits of byte).
  480. *
  481. * Requests that a remote entity executes one of its member
  482. * functions at a specified priority. If the specified priority is
  483. * already busy executing, the request will block until it becomes
  484. * available and only then return. The remote execution is still
  485. * carried out asynchronously, with no notification of completion.
  486. *
  487. * @param codegen[in|out] Code generator. Output lines are appended
  488. * to it.
  489. * @param engine[in] The engine instance to fetch entities.
  490. */
  491. void processREQSW(
  492. CodeGenerator* codeGen,
  493. const FF7FieldEngine& engine
  494. );
  495. /**
  496. * Processes a REQEW command.
  497. *
  498. * Opcode: 0x03
  499. * Short name: REQEW
  500. * Long name: Request remote execution (synchronous, guaranteed)
  501. *
  502. * Memory layout
  503. * 0x03
  504. * E
  505. * P/F
  506. *
  507. * Arguments
  508. *
  509. * const UByte E: The ID of the target entity.
  510. * const Bit[3] P: The priority at which we want to execute the
  511. * remote script (high 3 bits of byte).
  512. * const Bit[5] F: The ID of the specific member function of E to be
  513. * executed (low 5 bits of byte).
  514. *
  515. * Requests that a remote entity executes one of its member
  516. * functions at a specified priority. The request will block until
  517. * remote execution has finished before returning.
  518. *
  519. * @param codegen[in|out] Code generator. Output lines are appended
  520. * to it.
  521. * @param engine[in] The engine instance to fetch entities.
  522. */
  523. void processREQEW(
  524. CodeGenerator* codeGen,
  525. const FF7FieldEngine& engine
  526. );
  527. /**
  528. * Processes a RETTO command.
  529. *
  530. * Opcode: 0x07
  531. * Short name: RETTO
  532. * Long name: Return To
  533. *
  534. * Memory layout
  535. * 0x07
  536. * P/F
  537. *
  538. * Arguments
  539. * const Bit[3] P: The priority at which we want to execute the
  540. * remote script (high 3 bits of byte).
  541. * const Bit[5] F: The ID of the specific member function of the
  542. * current entity to be executed to (low 5 bits
  543. * of byte).
  544. *
  545. * Stops the active script loop for this entity and also any script
  546. * loops (except the main) that are queuing to be executed after the
  547. * current script. This is essentially the same as adding a RET onto
  548. * each of the active / queued scripts next execution position and
  549. * returning the current op index to index for each script. Then the
  550. * script control is passed to the script F within the current
  551. * entity with the priority P.
  552. *
  553. * @param codegen[in|out] Code generator. Output lines are appended
  554. * to it.
  555. */
  556. void processRETTO(CodeGenerator* codeGen);
  557. /**
  558. * Processes a WAIT command.
  559. *
  560. * Opcode: 0x24
  561. * Short name: WAIT
  562. * Long name: Wait
  563. *
  564. * Memory layout
  565. * 0x24
  566. * A
  567. *
  568. * Arguments
  569. * const UShort A: Amount (number of frames) to wait.
  570. *
  571. * Pauses current script execution for a specific amount of time.
  572. * Rather than a specific time value in milliseconds/seconds,
  573. * the amount specifies the number of frames that must be drawn
  574. * before execution resumes. Since the game runs at 30fps,
  575. * WAIT(0x1E) (or WAIT(30) in decimal) will pause script execution
  576. * for 1 second, WAIT(0x96) will pause for 5 seconds, and so on.
  577. *
  578. * @param codegen[in|out] Code generator. Output lines are appended
  579. * to it.
  580. */
  581. void processWAIT(CodeGenerator* codeGen);
  582. };
  583. /**
  584. * A module instruction.
  585. */
  586. class FF7ModuleInstruction : public KernelCallInstruction{
  587. public:
  588. /**
  589. * Processes the instruction.
  590. *
  591. * @param func[in] Function to process.
  592. * @param stack[out] Function stack.
  593. * @param engine[in] Engine.
  594. * @param codeGen[in] Code generator.
  595. * @todo Func and engine are unused?
  596. * @todo Understand and document properly.
  597. */
  598. virtual void processInst(
  599. Function& func, ValueStack &stack,
  600. Engine *engine, CodeGenerator *codeGen
  601. ) override;
  602. private:
  603. /**
  604. * Processes a BATTLE command.
  605. *
  606. * Opcode: 0x70
  607. * Short name: BATTLE
  608. * Long name: Start battle
  609. *
  610. * Memory layout
  611. * 0x70
  612. * B
  613. * N
  614. * N
  615. *
  616. * Arguments
  617. * const UByte B: Bank (16-bit) to retrieve the address of the
  618. * battle ID, or zero if it is given as a literal
  619. * value.
  620. * const UWord N: Battle ID, or address to find ID if B is
  621. * non-zero.
  622. *
  623. * This launches the battle module with whatever battle number is
  624. * used in the argument, or the value retrieved from memory location
  625. * N if B is non-zero. Battle 1, 2, and 999 (0x03E7) are debug
  626. * battles.
  627. *
  628. * @param codegen[in|out] Code generator. Output lines are appended
  629. * to it.
  630. */
  631. void processBATTLE(CodeGenerator* codeGen);
  632. /**
  633. * Processes a BTLON command.
  634. *
  635. * Opcode: 0x71
  636. * Short name: BTLON
  637. * Long name: Battle switch
  638. *
  639. * Memory layout
  640. * 0x71
  641. * S
  642. *
  643. * Arguments
  644. * const UByte S: Switch battles on/off (0/1, respectively).
  645. *
  646. * Turns random encounters on or off for this field. Note that if a
  647. * field does not have any Encounter Data set in its field file,
  648. * battles will not occur regardless of the argument passed with
  649. * this opcode.
  650. *
  651. * @param codegen[in|out] Code generator. Output lines are appended
  652. * to it.
  653. */
  654. void processBTLON(CodeGenerator* codeGen);
  655. /**
  656. * Processes a MAPJUMP command.
  657. *
  658. * Opcode: 0x60
  659. * Short name: BTLON
  660. * Long name: Change Field
  661. *
  662. * Memory layout
  663. * 0x60
  664. * I
  665. * I
  666. * X
  667. * X
  668. * Y
  669. * Y
  670. * Z
  671. * Z
  672. * D
  673. *
  674. * Arguments
  675. * const UShort I: Field ID of the map to jump to.
  676. * const Short X: X-coordinate of the player on the next field.
  677. * const Short Y: Y-coordinate of the player on the next field.
  678. * const Short Z: Z-coordinate of the player on the next field.
  679. * const UByte D: Direction the character will be facing on the
  680. * next field, in the standard game format.
  681. *
  682. * Switches fields to the one indicated by I, and places the
  683. * character at the coordinates and direction specified. This is an
  684. * alternative to using a gateway, and can complement their usage as
  685. * it allows for more than 12 gateways by simulating their behaviour
  686. * through a LINE which, when crossed, executes a MAPJUMP.
  687. *
  688. * @param codegen[in|out] Code generator. Output lines are appended
  689. * to it.
  690. * @param func[in] Function
  691. * @todo What is func for?
  692. */
  693. void processMAPJUMP(CodeGenerator* codeGen, Function& func);
  694. };
  695. class FF7MathInstruction : public StoreInstruction
  696. {
  697. public:
  698. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  699. private:
  700. void processSaturatedPLUS(CodeGenerator* codeGen);
  701. void processSaturatedPLUS2(CodeGenerator* codeGen);
  702. void processSaturatedMINUS(CodeGenerator* codeGen);
  703. void processSaturatedMINUS2(CodeGenerator* codeGen);
  704. void processSaturatedINC(CodeGenerator* codeGen);
  705. void processSaturatedINC2(CodeGenerator* codeGen);
  706. void processSaturatedDEC(CodeGenerator* codeGen);
  707. void processSaturatedDEC2(CodeGenerator* codeGen);
  708. void processRDMSD(CodeGenerator* codeGen);
  709. void processSETBYTE_SETWORD(CodeGenerator* codeGen);
  710. void processBITON(CodeGenerator* codeGen);
  711. void processPLUSx_MINUSx(CodeGenerator* codeGen, const std::string& op);
  712. void processINCx_DECx(CodeGenerator* codeGen, const std::string& op);
  713. void processRANDOM(CodeGenerator* codeGen);
  714. };
  715. class FF7WindowInstruction : public KernelCallInstruction
  716. {
  717. public:
  718. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  719. private:
  720. void processMESSAGE(CodeGenerator* codeGen, const std::string& scriptName);
  721. void processMPNAM(CodeGenerator* codeGen);
  722. void processMENU2(CodeGenerator* codeGen);
  723. void processWINDOW(CodeGenerator* codeGen);
  724. void processWCLSE(CodeGenerator* codeGen);
  725. };
  726. class FF7PartyInstruction : public KernelCallInstruction
  727. {
  728. public:
  729. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  730. private:
  731. void processSTITM(CodeGenerator* codeGen);
  732. void processPRTYE(CodeGenerator* codeGen);
  733. };
  734. class FF7ModelInstruction : public KernelCallInstruction
  735. {
  736. public:
  737. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  738. private:
  739. void processTLKON(CodeGenerator* codeGen, const std::string& entity);
  740. void processPC(CodeGenerator* codeGen, const std::string& entity);
  741. void processCHAR(CodeGenerator* codeGen, const std::string& entity);
  742. void processDFANM(CodeGenerator* codeGen, const std::string& entity, int charId);
  743. void processANIME1(CodeGenerator* codeGen, const std::string& entity, int charId);
  744. void processVISI(CodeGenerator* codeGen, const std::string& entity);
  745. void processXYZI(CodeGenerator* codeGen, const std::string& entity);
  746. void processMOVE(CodeGenerator* codeGen, const std::string& entity);
  747. void processMSPED(CodeGenerator* codeGen, const std::string& entity);
  748. void processDIR(CodeGenerator* codeGen, const std::string& entity);
  749. void processTURNGEN(CodeGenerator* codeGen, const std::string& entity);
  750. void processGETAI(CodeGenerator* codeGen, const FF7FieldEngine& engine);
  751. void processANIM_2(CodeGenerator* codeGen, const std::string& entity, int charId);
  752. void processCANIM2(CodeGenerator* codeGen, const std::string& entity, int charId);
  753. void processCANM_2(CodeGenerator* codeGen, const std::string& entity, int charId);
  754. void processCC(CodeGenerator* codeGen, const FF7FieldEngine& engine);
  755. void processSOLID(CodeGenerator* codeGen, const std::string& entity);
  756. /**
  757. * Processes an OFST opcode.
  758. *
  759. * Opcode: 0xC3
  760. * Short name: OFST
  761. * Long name: Offset Object
  762. *
  763. * Memory layout (8 bytes)
  764. * |0xC3|B1/B2|B3/B4|T|X|Y|Z|S|
  765. *
  766. * Arguments:
  767. * - const Bit[4] B1: Bank to retrieve X offset, or zero if X is
  768. * specified as a literal.
  769. * - const Bit[4] B2: Bank to retrieve Y offset, or zero if Y is
  770. * specified as a literal.
  771. * - const Bit[4] B3: Bank to retrieve Z offset, or zero if Z is
  772. * specified as a literal.
  773. * - const Bit[4] B4: Bank to retrieve speed, or zero if S is specified
  774. * as a literal.
  775. * - const UByte T: Type of movement.
  776. * - const Short X: X offset amount, relative to current position, or
  777. * address to find X offset, if B1 is non-zero.
  778. * - const Short Y: Y offset amount, relative to current position, or
  779. * address to find Y offset, if B2 is non-zero.
  780. * - const Short Z: Z offset amount, relative to current position, or
  781. * address to find Z offset, if B3 is non-zero.
  782. * - const UShort S: Speed of the offset movement, if type is non-zero,
  783. * or address to find speed, if B4 is non-zero.
  784. *
  785. * Offsets the field object, belonging to the entity whose script this
  786. * opcode resides in, by a certain amount. After being offset, the
  787. * character continues to be constrained in movement as defined by the
  788. * walkmesh's shape, but at a certain distance away from the normal
  789. * walkmesh position. Other field objects are unaffected, and their
  790. * position or movements are maintained on the walkmesh's original
  791. * position. If B1, B2, B3 or B4 is non-zero, then the value for that
  792. * particular component is taken from memory using the corresponding
  793. * bank and address specified, rather than as a literal value. Both
  794. * retrieved values and literals can be used for different components.
  795. * If using T, X, Y or S as addresses, the lower byte should hold the
  796. * address whilst the higher byte should be zero. The amount to offset
  797. * is specified relative to the current position. If Type is specified,
  798. * the object moves gradually from its current point to the offset
  799. * position; this can be used to simulate movements such as elevators.
  800. * Any type outside the range in the table will cause the offset not to
  801. * occur. If the object is set to move gradually, then the speed of
  802. * offset can be set; the greater the number, the slower the object
  803. * moves to its target offset. Script execution may also be halted
  804. * until the gradual offset has been completed. For this, see OFSTW.
  805. *
  806. * @param codeGen The code generator.
  807. * @param entity[in] The entity name.
  808. */
  809. void processOFST(CodeGenerator* codegen, const std::string& entity);
  810. };
  811. class FF7WalkmeshInstruction : public KernelCallInstruction
  812. {
  813. public:
  814. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  815. private:
  816. void processUC(CodeGenerator* codeGen);
  817. /**
  818. * Processes a LINE opcode.
  819. *
  820. * Opcode: 0xD0
  821. * Short name: LINE
  822. * Long name: Line definition
  823. *
  824. * Memory layout (7 bytes)
  825. * |0xD0|XA|YA|ZA|XB|YB|ZB|
  826. *
  827. * Arguments:
  828. * - const Short XA: X-coordinate of the first point of the line.
  829. * - const Short YA: Y-coordinate of the first point of the line.
  830. * - const Short ZA: Z-coordinate of the first point of the line.
  831. * - const Short XB: X-coordinate of the second point of the line.
  832. * - const Short YB: Y-coordinate of the second point of the line.
  833. * - const Short ZB: Z-coordinate of the second point of the line.
  834. *
  835. * Defines a line on the walkmesh that, when crossed by a playable
  836. * character, causes one of the entity's scripts to be executed. These
  837. * are similar to the triggers in Section 8. All the lines in the
  838. * current field can be turned on or off by using the LINON opcode.
  839. *
  840. * There are generally 6 scripts (other than the init and main) if the entity is a LINE.
  841. * - script index 2 -> S1 - [OK].
  842. * - script index 3 -> S2 - Move.
  843. * - script index 4 -> S3 - Move.
  844. * - script index 5 -> S4 - Go.
  845. * - script index 6 -> S5 - Go 1x.
  846. * - script index 7 -> S6 - Go away.
  847. *
  848. * @param codeGen The code generator.
  849. * @param entity[in] The entity name.
  850. */
  851. void processLINE(CodeGenerator* codeGen, const std::string& entity);
  852. };
  853. class FF7BackgroundInstruction : public KernelCallInstruction
  854. {
  855. public:
  856. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  857. private:
  858. void processBGON(CodeGenerator* codeGen);
  859. void processBGOFF(CodeGenerator* codeGen);
  860. void processBGCLR(CodeGenerator* codeGen);
  861. void processSTPAL(CodeGenerator* codeGen);
  862. void processLDPAL(CodeGenerator* codeGen);
  863. void processCPPAL(CodeGenerator* codeGen);
  864. void processADPAL(CodeGenerator* codeGen);
  865. void processMPPAL2(CodeGenerator* codeGen);
  866. void processSTPLS(CodeGenerator* codeGen);
  867. void processLDPLS(CodeGenerator* codeGen);
  868. };
  869. class FF7CameraInstruction : public KernelCallInstruction
  870. {
  871. public:
  872. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  873. private:
  874. void processNFADE(CodeGenerator* codeGen);
  875. void processSCR2D(CodeGenerator* codeGen);
  876. void processSCR2DC(CodeGenerator* codeGen);
  877. void processFADE(CodeGenerator* codeGen);
  878. };
  879. class FF7AudioVideoInstruction : public KernelCallInstruction
  880. {
  881. public:
  882. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  883. private:
  884. void processAKAO2(CodeGenerator* codeGen);
  885. void processMUSIC(CodeGenerator* codeGen);
  886. void processSOUND(CodeGenerator* codeGen);
  887. void processAKAO(CodeGenerator* codeGen);
  888. void processMULCK(CodeGenerator* codeGen);
  889. void processPMVIE(CodeGenerator* codeGen);
  890. void processMOVIE(CodeGenerator* codeGen);
  891. void processMVIEF(CodeGenerator* codeGen);
  892. };
  893. class FF7UncategorizedInstruction : public KernelCallInstruction
  894. {
  895. public:
  896. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  897. };
  898. class FF7NoOperationInstruction : public Instruction
  899. {
  900. public:
  901. static InstPtr Create() { return new FF7NoOperationInstruction(); }
  902. virtual void processInst(Function& func, ValueStack &stack, Engine *engine, CodeGenerator *codeGen) override;
  903. };
  904. }