ff7_field_engine.h 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371
  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(SUDM::IScriptFormatter& formatter, std::string scriptName) :
  38. mFormatter(formatter), mScriptName(scriptName)
  39. {setOutputStackEffect(false);}
  40. /**
  41. * Destructor.
  42. */
  43. FF7FieldEngine(const FF7FieldEngine&) = delete;
  44. /**
  45. * Destructor.
  46. */
  47. FF7FieldEngine& operator = (const FF7FieldEngine&) = delete;
  48. /**
  49. * Represents an entity.
  50. *
  51. * An entity can be almost anything in a field map: the playable
  52. * character, an NPC, an item, a line...
  53. */
  54. class Entity{
  55. public:
  56. /**
  57. * Entity constructor.
  58. *
  59. * It doesn't initialize any of the fields.
  60. */
  61. Entity() = default;
  62. /**
  63. * Entity constructor.
  64. *
  65. * Instantiates an entity with a name.
  66. *
  67. * @param name[in] Entity name.
  68. */
  69. Entity(const std::string& name): mName(name), is_line_(false){}
  70. /**
  71. * Retrieves the entity name.
  72. *
  73. * @return The entity name
  74. */
  75. std::string Name() const{return mName;}
  76. /**
  77. * Retrieves a function.
  78. *
  79. * Retrieves the name of a function from it's index.
  80. *
  81. * @param index[in] Function index.
  82. * @return Function name.
  83. * @throws InternalDecompilerError if there is no function
  84. * with the specified index.
  85. * @todo What is a function here? An Opcode?
  86. */
  87. std::string FunctionByIndex(size_t index) const{
  88. auto it = mFunctions.find(index);
  89. if (it == std::end(mFunctions)) throw InternalDecompilerError();
  90. return it->second;
  91. }
  92. /**
  93. * Adds a function to the engine.
  94. *
  95. * Must be added by name and index.
  96. *
  97. * @param name[in] Function name. If the entity is a line,
  98. * the name will be overridden.
  99. * @param index[in] Function index.
  100. * @todo What is a function here? An Opcode?
  101. */
  102. void AddFunction(const std::string& name, size_t index){
  103. // TODO: Delete renaming and test. It should work.
  104. std::string new_name = name;
  105. if (is_line_){
  106. switch (index){
  107. case 2: new_name = "on_enter_line"; break;
  108. case 3: new_name = "on_move_to_line"; break;
  109. case 4: new_name = "on_cross_line"; break;
  110. case 5: new_name = "on_leave_line"; break;
  111. }
  112. }
  113. mFunctions[index] = new_name;
  114. }
  115. /**
  116. * Marks the entity as a line.
  117. *
  118. * @param line[in] True to mark the entity as a line,
  119. * false to unmark it.
  120. * @param point_a[in] First point of the line. Can be null
  121. * if line is false.
  122. * @param point_b[in] Second point of the line. Can be
  123. * null if line is false.
  124. */
  125. void MarkAsLine(
  126. bool line, std::vector<float> point_a, std::vector<float> point_b
  127. ){
  128. is_line_ = line;
  129. point_a_.clear();
  130. point_b_.clear();
  131. if (line){
  132. if (point_a.size() >= 3 && point_b.size() >= 3){
  133. point_a_.push_back(point_a[0]);
  134. point_a_.push_back(point_a[1]);
  135. point_a_.push_back(point_a[2]);
  136. point_b_.push_back(point_b[0]);
  137. point_b_.push_back(point_b[1]);
  138. point_b_.push_back(point_b[2]);
  139. }
  140. // TODO: Notify on else.
  141. }
  142. // TODO: These are not getting to the final script.
  143. // Maybe this can be removed?
  144. AddFunction("on_enter_line", 1);
  145. AddFunction("on_move_to_line", 2);
  146. AddFunction("on_cross_line", 3);
  147. AddFunction("on_leave_line", 4);
  148. }
  149. /**
  150. * Checks if the entity is a line.
  151. *
  152. * Note that an entity is not considered to be a line
  153. * until a function has been found containing the opcode
  154. * LINE and {@see MarkAsLine} has been called.
  155. *
  156. * @return true if the entity is a line.
  157. */
  158. bool IsLine(){return is_line_;}
  159. /**
  160. * Retrieves the first point of the line entity.
  161. *
  162. * If the entity is not a line, the behavior is undefined.
  163. *
  164. * @return The first point of the line entity.
  165. */
  166. std::vector<float> GetLinePointA(){return point_a_;}
  167. /**
  168. * Retrieves the second point of the line entity.
  169. *
  170. * If the entity is not a line, the behavior is undefined.
  171. *
  172. * @return The second point of the line entity.
  173. */
  174. std::vector<float> GetLinePointB(){return point_b_;}
  175. private:
  176. /**
  177. * Entity name.
  178. */
  179. std::string mName;
  180. /**
  181. * Function list.
  182. * @todo What is a function here? An Opcode?
  183. */
  184. std::map< size_t, std::string > mFunctions;
  185. /**
  186. * Indicates if the entity is a line.
  187. */
  188. bool is_line_;
  189. /**
  190. * The first point of a line entity.
  191. *
  192. * If the entity is not a line, it may not be initializer.
  193. */
  194. std::vector<float> point_a_;
  195. /**
  196. * The second point of a line entity.
  197. *
  198. * If the entity is not a line, it may not be initializer.
  199. */
  200. std::vector<float> point_b_;
  201. };
  202. /**
  203. * Retrieves the dissasembler.
  204. *
  205. * @param insts[in] List of instructions.
  206. * @param raw_script_data[in] Script data, raw format.
  207. * @return Pointer to the dissasembler.
  208. * @todo Understand and document properly.
  209. */
  210. virtual std::unique_ptr<Disassembler> getDisassembler(
  211. InstVec &insts, const std::vector<unsigned char>& raw_script_data
  212. ) override;
  213. /**
  214. * Retrieves the dissasembler.
  215. *
  216. * @param insts[in] List of instructions.
  217. * @return Pointer to the dissasembler.
  218. * @todo Understand and document properly.
  219. */
  220. virtual std::unique_ptr<Disassembler> getDisassembler(InstVec &insts) override;
  221. /**
  222. * Retrieves the code generator.
  223. *
  224. * @param insts[in] List of instructions.
  225. * @param output[in] Pointer to the output (file, stream...).
  226. * @return Pointer to the generator.
  227. * @todo Understand and document properly.
  228. */
  229. virtual std::unique_ptr<CodeGenerator> getCodeGenerator(
  230. const InstVec& insts, std::ostream &output
  231. ) override;
  232. /**
  233. * Postprocessing actions to apply to the scripts.
  234. *
  235. * @param insts[in] Instruction list.
  236. * @param g[in] Code graph.
  237. * @todo Understand and document properly.
  238. * @todo What is the graph used to?
  239. */
  240. virtual void postCFG(InstVec &insts, Graph g) override;
  241. /**
  242. * Indicates if instructions are purely grouped.
  243. *
  244. * @return True if instructions are purely grouped.
  245. * @todo What is pure grouping?
  246. */
  247. virtual bool usePureGrouping() const override{return false;}
  248. /**
  249. * Retrieves all entities in the map.
  250. *
  251. * @return A map of entities, with the name and index.
  252. */
  253. std::map<std::string, int> GetEntities() const;
  254. /**
  255. * Retrieves all line entities in the map.
  256. *
  257. * @param A list of line entities.
  258. */
  259. std::vector<SUDM::FF7::Field::Line> GetLineList() const;
  260. /**
  261. * Retrieves all entities in the map.
  262. *
  263. * @return A map of entities, with the name and index.
  264. */
  265. std::map<size_t, Entity> GetEntityIndexMap() const{return mEntityIndexMap;}
  266. /**
  267. * Adds a function to an entity.
  268. *
  269. * @param entity_name Name of the entity.
  270. * @param entity_index Index of the entity.
  271. * @param func_name Name of the function.
  272. * @param func_index Index of the function.
  273. */
  274. void AddEntityFunction(
  275. const std::string& entity_name, size_t entity_index,
  276. const std::string& func_name, size_t func_index
  277. );
  278. /**
  279. * Marks an entity as a line.
  280. *
  281. * @param entity_index Index of the entity.
  282. * @param line[in] True to mark the entity as a line, false to
  283. * unmark it.
  284. * @param point_a[in] First point of the line. Can be null if line
  285. * is false.
  286. * @param point_b[in] Second point of the line. Can be null if
  287. * line is false.
  288. */
  289. void MarkEntityAsLine(
  290. size_t entity_index, bool line,
  291. std::vector<float> point_a, std::vector<float> point_b
  292. );
  293. /**
  294. * Checks if an entity has been marked as a line.
  295. *
  296. * @param entity_index[in] Index of the entity to check.
  297. * @return True if the entity is a line. False if it isn't, or if
  298. * there is no such entity.
  299. */
  300. bool EntityIsLine(size_t entity_index);
  301. /**
  302. * Retrieves an entity.
  303. *
  304. * @param index[in] Index of the entity to retrieve.
  305. * @throws InternalDecompilerError if there is no entity at the
  306. * specified index.
  307. */
  308. const Entity& EntityByIndex(size_t index) const{
  309. auto it = mEntityIndexMap.find(index);
  310. if (it == std::end(mEntityIndexMap)) throw InternalDecompilerError();
  311. return it->second;
  312. }
  313. /**
  314. * Retrieves the scale factor for the map.
  315. *
  316. * @return Map scale factor.
  317. */
  318. float ScaleFactor() const {return mScaleFactor;}
  319. /**
  320. * Retrieves the script name.
  321. *
  322. * @return The script name.
  323. */
  324. const std::string& ScriptName() const {return mScriptName;}
  325. private:
  326. /**
  327. * Removes extraneous return statements.
  328. *
  329. * Usefull for scripts that only contain one one return
  330. * statement.
  331. *
  332. * @param insts[in|out] List of instructions to proccess.
  333. * Extraneous return statements will be deleted from the
  334. * instructions.
  335. * @param g[in] Code graph. Unused.
  336. */
  337. void RemoveExtraneousReturnStatements(InstVec& insts, Graph g);
  338. /**
  339. * Removes trailing infinite loops.
  340. *
  341. * In FF7 some scripts ends with an infinite loop to keep it
  342. * alive. in QGears this isn't required, and can cause infinite
  343. * loops, so they can be removed.
  344. *
  345. * @param insts[in|out] List of instructions to proccess. Trailing
  346. * infinite loops will be deleted from the instructions.
  347. * @param g[in] Code graph.
  348. * @todo What is the graph used to?
  349. */
  350. void RemoveTrailingInfiniteLoops(InstVec& insts, Graph g);
  351. /**
  352. * Tries to detect scripts with trailing infinite loops.
  353. *
  354. * In FF7 some scripts ends with an infinite loop to keep it
  355. * alive. in QGears this isn't required, and can cause infinite
  356. * loops, so they can be removed. This function marks them, so
  357. * they can be deleted with
  358. * @{see FF7FieldEngine::RemoveTrailingInfiniteLoops}.
  359. */
  360. void MarkInfiniteLoopGroups(InstVec& insts, Graph g);
  361. /**
  362. * The script formatter.
  363. */
  364. SUDM::IScriptFormatter& mFormatter;
  365. /**
  366. * The entity index map for the field.
  367. */
  368. std::map<size_t, Entity> mEntityIndexMap;
  369. /**
  370. * The map scale factor.
  371. */
  372. float mScaleFactor = 1.0f;
  373. /**
  374. * The script name.
  375. */
  376. std::string mScriptName;
  377. };
  378. /**
  379. * An unconditional map jump instruction.
  380. */
  381. class FF7UncondJumpInstruction : public UncondJumpInstruction{
  382. public:
  383. // TODO: Make private and add accessors.
  384. /**
  385. * Whether or not this is really a call to a script function.
  386. */
  387. bool _isCall;
  388. /**
  389. * Constructor.
  390. */
  391. FF7UncondJumpInstruction() : _isCall(false) {}
  392. /**
  393. * Indicates if the instruction is a function call.
  394. *
  395. * @return true if the instruction is a function call, false if not.
  396. */
  397. virtual bool isFuncCall() const;
  398. /**
  399. * Indicates if the instruction is an unconditional jump.
  400. *
  401. * @return true if the instruction is an unconditional jump, false
  402. * if it's not.
  403. */
  404. virtual bool isUncondJump() const;
  405. /**
  406. * Retrieves the destination address of the jump.
  407. *
  408. * @return The offset (number of bytes) to jump from the beginning
  409. * of the instruction.
  410. */
  411. virtual uint32 getDestAddress() const;
  412. /**
  413. * Processes the instruction.
  414. *
  415. * @param func[in] Function to process.
  416. * @param stack[out] Function stack.
  417. * @param engine[in] Engine.
  418. * @param code_gen[in] Code generator.
  419. * @todo Func and engine are unused?
  420. * @todo Understand and document properly.
  421. */
  422. virtual void processInst(
  423. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  424. ) override;
  425. /**
  426. * Prints the instruction
  427. *
  428. * @param output The stram to print the instruction to.
  429. * @todo Understand and document properly.
  430. */
  431. virtual std::ostream& print(std::ostream &output) const override;
  432. };
  433. /**
  434. * A conditional map jump instruction.
  435. */
  436. class FF7CondJumpInstruction : public CondJumpInstruction{
  437. public:
  438. /**
  439. * Processes a conditional jump instruction.
  440. *
  441. * Checks if the condition is a function or a comparison, and
  442. * adds the function to the stack.
  443. *
  444. * @param function[in] Function to process. Unused.
  445. * @param stack[out] Function stack. The Instruction will be added
  446. * here.
  447. * @param engine[in] Engine. Unused.
  448. * @param code_gen[in] Code generator.
  449. */
  450. virtual void processInst(
  451. Function& function, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  452. ) override;
  453. /**
  454. * Retrieves the destination address of the jump.
  455. *
  456. * @return The offset (number of bytes) to jump from the beginning
  457. * of the instruction.
  458. */
  459. virtual uint32 getDestAddress() const override;
  460. /**
  461. * Prints the instruction
  462. *
  463. * @param output The stram to print the instruction to.
  464. * @todo Understand and document properly.
  465. */
  466. virtual std::ostream& print(std::ostream &output) const override;
  467. };
  468. /**
  469. * A script flow control instruction.
  470. */
  471. class FF7ControlFlowInstruction : public KernelCallInstruction{
  472. public:
  473. /**
  474. * Create a FF7ControlFlowInstruction.
  475. *
  476. * @return Pointer to the newly created instruction.
  477. */
  478. static InstPtr Create(){return new FF7ControlFlowInstruction();}
  479. /**
  480. * Processes the instruction.
  481. *
  482. * @param func[in] Function to process.
  483. * @param stack[out] Function stack.
  484. * @param engine[in] Engine.
  485. * @param code_gen[in] Code generator.
  486. */
  487. virtual void processInst(
  488. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  489. ) override;
  490. private:
  491. /**
  492. * Processes a REQ command.
  493. *
  494. * Opcode: 0x01
  495. * Short name: REQ
  496. * Long name: Request remote execution (asynchronous,
  497. * non-guaranteed)
  498. *
  499. * Memory layout
  500. * 0x01
  501. * E
  502. * P/F
  503. *
  504. * Arguments
  505. *
  506. * const UByte E: The ID of the target entity.
  507. * const Bit[3] P: The priority at which we want to execute the
  508. * remote script (high 3 bits of byte).
  509. * const Bit[5] F: The ID of the specific member function of E to
  510. * be executed (low 5 bits of byte).
  511. *
  512. * Requests that a remote entity executes one of its member
  513. * functions at a specified priority. The request is asynchronous
  514. * and returns immediately without waiting for the remote
  515. * execution to start or finish. If the specified priority is
  516. * already busy executing, the request will fail silently.
  517. *
  518. * @param codegen[in|out] Code generator. Output lines are
  519. * appended to it.
  520. * @param engine[in] The engine instance to fetch entities.
  521. */
  522. void processREQ(CodeGenerator* code_gen, const FF7FieldEngine& engine);
  523. /**
  524. * Processes a REQSW command.
  525. *
  526. * Opcode: 0x02
  527. * Short name: REQSW
  528. * Long name: Request remote execution (asynchronous execution,
  529. * guaranteed)
  530. *
  531. * Memory layout
  532. * 0x02
  533. * E
  534. * P/F
  535. *
  536. * Arguments
  537. *
  538. * const UByte E: The ID of the target entity.
  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 E to
  542. * be executed (low 5 bits of byte).
  543. *
  544. * Requests that a remote entity executes one of its member
  545. * functions at a specified priority. If the specified priority is
  546. * already busy executing, the request will block until it becomes
  547. * available and only then return. The remote execution is still
  548. * carried out asynchronously, with no notification of completion.
  549. *
  550. * @param codegen[in|out] Code generator. Output lines are
  551. * appended to it.
  552. * @param engine[in] The engine instance to fetch entities.
  553. */
  554. void processREQSW(CodeGenerator* code_gen, const FF7FieldEngine& engine);
  555. /**
  556. * Processes a REQEW command.
  557. *
  558. * Opcode: 0x03
  559. * Short name: REQEW
  560. * Long name: Request remote execution (synchronous, guaranteed)
  561. *
  562. * Memory layout
  563. * 0x03
  564. * E
  565. * P/F
  566. *
  567. * Arguments
  568. *
  569. * const UByte E: The ID of the target entity.
  570. * const Bit[3] P: The priority at which we want to execute the
  571. * remote script (high 3 bits of byte).
  572. * const Bit[5] F: The ID of the specific member function of E to
  573. * be executed (low 5 bits of byte).
  574. *
  575. * Requests that a remote entity executes one of its member
  576. * functions at a specified priority. The request will block until
  577. * remote execution has finished before returning.
  578. *
  579. * @param codegen[in|out] Code generator. Output lines are
  580. * appended to it.
  581. * @param engine[in] The engine instance to fetch entities.
  582. */
  583. void processREQEW(CodeGenerator* code_gen, const FF7FieldEngine& engine);
  584. /**
  585. * Processes a RETTO command.
  586. *
  587. * Opcode: 0x07
  588. * Short name: RETTO
  589. * Long name: Return To
  590. *
  591. * Memory layout
  592. * 0x07
  593. * P/F
  594. *
  595. * Arguments
  596. * const Bit[3] P: The priority at which we want to execute the
  597. * remote script (high 3 bits of byte).
  598. * const Bit[5] F: The ID of the specific member function of the
  599. * current entity to be executed to (low 5 bits
  600. * of byte).
  601. *
  602. * Stops the active script loop for this entity and also any
  603. * script loops (except the main) that are queuing to be executed
  604. * after the current script. This is essentially the same as
  605. * adding a RET onto each of the active / queued scripts next
  606. * execution position and returning the current op index to index
  607. * for each script. Then the script control is passed to the
  608. * script F within the current entity with the priority P.
  609. *
  610. * @param codegen[in|out] Code generator. Output lines are
  611. * appended to it.
  612. */
  613. void processRETTO(CodeGenerator* code_gen);
  614. /**
  615. * Processes a WAIT command.
  616. *
  617. * Opcode: 0x24
  618. * Short name: WAIT
  619. * Long name: Wait
  620. *
  621. * Memory layout
  622. * 0x24
  623. * A
  624. *
  625. * Arguments
  626. * const UShort A: Amount (number of frames) to wait.
  627. *
  628. * Pauses current script execution for a specific amount of time.
  629. * Rather than a specific time value in milliseconds/seconds,
  630. * the amount specifies the number of frames that must be drawn
  631. * before execution resumes. Since the game runs at 30fps,
  632. * WAIT(0x1E) (or WAIT(30) in decimal) will pause script execution
  633. * for 1 second, WAIT(0x96) will pause for 5 seconds, and so on.
  634. *
  635. * @param codegen[in|out] Code generator. Output lines are
  636. * appended to it.
  637. */
  638. void processWAIT(CodeGenerator* code_gen);
  639. };
  640. /**
  641. * A module instruction.
  642. */
  643. class FF7ModuleInstruction : public KernelCallInstruction{
  644. public:
  645. /**
  646. * Processes the instruction.
  647. *
  648. * @param func[in] Function to process.
  649. * @param stack[out] Function stack.
  650. * @param engine[in] Engine. Unused.
  651. * @param code_gen[in] Code generator.
  652. */
  653. virtual void processInst(
  654. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  655. ) override;
  656. private:
  657. /**
  658. * Processes a BATTLE opcode.
  659. *
  660. * Opcode: 0x70
  661. * Short name: BATTLE
  662. * Long name: Start battle
  663. *
  664. * Memory layout
  665. * 0x70
  666. * B
  667. * N
  668. * N
  669. *
  670. * Arguments
  671. * const UByte B: Bank (16-bit) to retrieve the address of the
  672. * battle ID, or zero if it is given as a literal
  673. * value.
  674. * const UWord N: Battle ID, or address to find ID if B is
  675. * non-zero.
  676. *
  677. * This launches the battle module with whatever battle number is
  678. * used in the argument, or the value retrieved from memory location
  679. * N if B is non-zero. Battle 1, 2, and 999 (0x03E7) are debug
  680. * battles.
  681. *
  682. * @param codegen[in|out] Code generator. Output lines are appended
  683. * to it.
  684. */
  685. void processBATTLE(CodeGenerator* code_gen);
  686. /**
  687. * Processes a BTLON opcode.
  688. *
  689. * Opcode: 0x71
  690. * Short name: BTLON
  691. * Long name: Battle switch
  692. *
  693. * Memory layout
  694. * 0x71
  695. * S
  696. *
  697. * Arguments
  698. * const UByte S: Switch battles on/off (0/1, respectively).
  699. *
  700. * Turns random encounters on or off for this field. Note that if
  701. * a field does not have any Encounter Data set in its field file,
  702. * battles will not occur regardless of the argument passed with
  703. * this opcode.
  704. *
  705. * @param codegen[in|out] Code generator. Output lines are
  706. * appended to it.
  707. */
  708. void processBTLON(CodeGenerator* code_gen);
  709. /**
  710. * Processes a MAPJUMP opcode.
  711. *
  712. * Opcode: 0x60
  713. * Short name: BTLON
  714. * Long name: Change Field
  715. *
  716. * Memory layout
  717. * 0x60
  718. * I
  719. * I
  720. * X
  721. * X
  722. * Y
  723. * Y
  724. * Z
  725. * Z
  726. * D
  727. *
  728. * Arguments
  729. * const UShort I: Field ID of the map to jump to.
  730. * const Short X: X-coordinate of the player on the next field.
  731. * const Short Y: Y-coordinate of the player on the next field.
  732. * const Short Z: Z-coordinate of the player on the next field.
  733. * const UByte D: Direction the character will be facing on the
  734. * next field, in the standard game format.
  735. *
  736. * Switches fields to the one indicated by I, and places the
  737. * character at the coordinates and direction specified. This is
  738. * an alternative to using a gateway, and can complement their
  739. * usage as it allows for more than 12 gateways by simulating
  740. * their behavior through a LINE which, when crossed, executes a
  741. * MAPJUMP.
  742. *
  743. * @param codegen[in|out] Code generator. Output lines are
  744. * appended to it.
  745. * @param func[in] Function
  746. * @todo What is func for?
  747. */
  748. void processMAPJUMP(CodeGenerator* code_gen, Function& func);
  749. };
  750. /**
  751. * A math instruction.
  752. */
  753. class FF7MathInstruction : public StoreInstruction{
  754. public:
  755. /**
  756. * Processes the instruction.
  757. *
  758. * @param func[in] Function to process.
  759. * @param stack[out] Function stack.
  760. * @param engine[in] Engine. Unused.
  761. * @param code_gen[in] Code generator.
  762. */
  763. virtual void processInst(
  764. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  765. ) override;
  766. private:
  767. void processSaturatedPLUS(CodeGenerator* code_gen);
  768. void processSaturatedPLUS2(CodeGenerator* code_gen);
  769. void processSaturatedMINUS(CodeGenerator* code_gen);
  770. void processSaturatedMINUS2(CodeGenerator* code_gen);
  771. void processSaturatedINC(CodeGenerator* code_gen);
  772. void processSaturatedINC2(CodeGenerator* code_gen);
  773. void processSaturatedDEC(CodeGenerator* code_gen);
  774. void processSaturatedDEC2(CodeGenerator* code_gen);
  775. void processRDMSD(CodeGenerator* code_gen);
  776. void processSETBYTE_SETWORD(CodeGenerator* code_gen);
  777. /**
  778. * Processes a BITON opcode.
  779. *
  780. * Opcode: 0x82
  781. * Short name: BITON
  782. * Long name: Set Bit
  783. *
  784. * Memory layout (4 bytes)
  785. * |0x82|D/S|A|B|
  786. *
  787. * Arguments
  788. * - const Bit[4] D: Destination bank.
  789. * - const Bit[4] S: Source bank.
  790. * - const UByte A: Destination address.
  791. * - const UByte Bit: The number of the bit to turn on.
  792. *
  793. * Sets the nth bit in the "A" location, where n is a number
  794. * between 0-7 supplied in B. A value of zero in B will set the
  795. * least significant bit. If the Source Bank is 0 then the bit to
  796. * be set is taken from "Bit". If the Source Bank is an 8 bit
  797. * bank, then the bit is the address in that bank where the
  798. * operand is.
  799. *
  800. * @param code_gen[in|out] Code generator. Output lines are
  801. * appended to it.
  802. */
  803. void processBITON(CodeGenerator* code_gen);
  804. /**
  805. * Processes a BITON opcode.
  806. *
  807. * Opcode: 0x83
  808. * Short name: BITOFF
  809. * Long name: Reset Bit
  810. *
  811. * Memory layout (4 bytes)
  812. * |0x83|D/S|A|B|
  813. *
  814. * Arguments
  815. * - const Bit[4] D: Destination bank.
  816. * - const Bit[4] S: Source bank.
  817. * - const UByte A: Destination address.
  818. * - const UByte Bit: The number of the bit to turn off.
  819. *
  820. * Sets the nth bit in the "A" location, where n is a number
  821. * between 0-7 supplied in B. A value of zero in B will reset the
  822. * least significant bit. If the Source Bank is 0 then the bit to
  823. * be set is taken from "Bit". If the Source Bank is an 8 bit
  824. * bank, then the bit is the address in that bank where the
  825. * operand is.
  826. *
  827. * @param code_gen[in|out] Code generator. Output lines are
  828. * appended to it.
  829. */
  830. void processBITOFF(CodeGenerator* code_gen);
  831. void processPLUSx_MINUSx(CodeGenerator* code_gen, const std::string& op);
  832. void processINCx_DECx(CodeGenerator* code_gen, const std::string& op);
  833. void processRANDOM(CodeGenerator* code_gen);
  834. };
  835. /**
  836. * A window instruction.
  837. */
  838. class FF7WindowInstruction : public KernelCallInstruction{
  839. public:
  840. /**
  841. * Processes the instruction.
  842. *
  843. * @param func[in] Function to process.
  844. * @param stack[out] Function stack.
  845. * @param engine[in] Engine.
  846. * @param code_gen[in] Code generator.
  847. */
  848. virtual void processInst(
  849. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  850. ) override;
  851. private:
  852. void processMESSAGE(CodeGenerator* code_gen, const std::string& script_name);
  853. void processMPNAM(CodeGenerator* code_gen);
  854. void processMENU2(CodeGenerator* code_gen);
  855. void processWINDOW(CodeGenerator* code_gen);
  856. void processWCLSE(CodeGenerator* code_gen);
  857. };
  858. /**
  859. * A party instruction
  860. */
  861. class FF7PartyInstruction : public KernelCallInstruction{
  862. public:
  863. /**
  864. * Processes the instruction.
  865. *
  866. * @param func[in] Function to process.
  867. * @param stack[out] Function stack.
  868. * @param engine[in] Engine. Unused
  869. * @param code_gen[in] Code generator.
  870. */
  871. virtual void processInst(
  872. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  873. ) override;
  874. private:
  875. void processSTITM(CodeGenerator* code_gen);
  876. void processPRTYE(CodeGenerator* code_gen);
  877. };
  878. /**
  879. * A model instruction.
  880. */
  881. class FF7ModelInstruction : public KernelCallInstruction{
  882. public:
  883. /**
  884. * Processes the instruction.
  885. *
  886. * @param func[in] Function to process.
  887. * @param stack[out] Function stack.
  888. * @param engine[in] Engine.
  889. * @param code_gen[in] Code generator.
  890. */
  891. virtual void processInst(
  892. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  893. ) override;
  894. private:
  895. /**
  896. * Processes a JOIN opcode.
  897. *
  898. * Opcode: 0x08
  899. * Short name: JOIN
  900. * Long name: Party Field Join
  901. * Memory layout (2 bytes)
  902. * |0x08|S|
  903. *
  904. * Arguments
  905. * - const UByte S: Speed that the characters join back together.
  906. *
  907. * Causes seperated party characters that have previously been
  908. * SPLIT onto the field, to be joined back together again; that
  909. * is, only the party leader becomes visible on the field. This
  910. * should be called if a previous SPLIT has completed (the party
  911. * members have finished speaking, or performing their actions,
  912. * for example). As with SPLIT, the speed of the join is
  913. * specified, from a scale of 1 (almost instant) to FF (very slow
  914. * walk), and must be non-zero. In contrast to most MOVE related
  915. * op codes, the speed is this setting is actually the total
  916. * number of frames required. Depending on the distance from the
  917. * player character and the number of frames required, the entity
  918. * plays a run or walk animation. Also, all characters take the
  919. * same time irrespective of distance. Calling JOIN without having
  920. * previously SPLIT the characters will cause the party members to
  921. * appear at the walkmesh origin and attempt to JOIN from there.
  922. * This is not normally the required behaviour and should be
  923. * avoided.
  924. *
  925. * @param code_gen The code generator.
  926. */
  927. void processJOIN(CodeGenerator* code_gen);
  928. /**
  929. * Processes a SPLIT opcode.
  930. *
  931. * Opcode: 0x09
  932. * Short name: SPLIT
  933. * Long name: Party Field Split
  934. *
  935. * Memory layout (15 bytes)
  936. * |0x20|B1/B2|B3/B4|B5/B6|XA|XA|YA|YA|DA|XB|XB|YB|YB|DB|S|
  937. *
  938. * Arguments
  939. * - const Bit[4] B1: Bank for XA, or zero if XA is specified as a
  940. * literal value.
  941. * - const Bit[4] B2: Bank for YA, or zero if YA is specified as a
  942. * literal value.
  943. * - const Bit[4] B3: Bank for DA, or zero if DA is specified as a
  944. * literal value.
  945. * - const Bit[4] B4: Bank for XB, or zero if XB is specified as a
  946. * literal value.
  947. * - const Bit[4] B5: Bank for YB, or zero if YB is specified as a
  948. * literal value.
  949. * - const Bit[4] B6: Bank for DB, or zero if DB is specified as a
  950. * literal value.
  951. * - const Short XA: X-coordinate of the second character in the
  952. * party after the split, or address for the value if B1 is
  953. * non-zero.
  954. * - const Short YA: Y-coordinate of the second character in the
  955. * party after the split, or address for the value if B2 is
  956. * non-zero.
  957. * - const UByte DA: Direction the second character faces after the
  958. * split, or address for the value if B3 is non-zero.
  959. * - const Short XB: X-coordinate of the third character in the
  960. * party after the split, or address for the value if B4 is
  961. * non-zero.
  962. * - const Short YB: Y-coordinate of the third character in the
  963. * party after the split, or address for the value if B5 is
  964. * non-zero.
  965. * - const UByte DB: Direction the third character faces after the
  966. * split, or address for the value if B6 is non-zero.
  967. * - const UByte S: Speed that the characters split.
  968. *
  969. * Causes the common 'split effect' whereby the second and third
  970. * characters in the current party 'come out' from the party
  971. * leader. That is, they become visible in the field, starting
  972. * from the center of the party leader, and move out to the
  973. * coordinates specified in the argument list. This is commonly
  974. * used when the other characters in the current party have an
  975. * action or dialog to perform and must be individually visible in
  976. * the field. As well as specifying final coordinates for the two
  977. * other party characters, the directions each character faces
  978. * after the split are specified as a byte, using the common
  979. * direction values found throughout the game. Speed is also given
  980. * and is used to specify the rate at which the characters leave
  981. * the party leader, using a scale from 1 (almost instant) to FF
  982. * (extremely slow walk); this must be non-zero. In contrast to
  983. * most MOVE related op codes, the speed is this setting is
  984. * actually the total number of frames required. Depending on the
  985. * distance from the player character and the number of frames
  986. * required, the entity plays a run or walk animation. Also, all
  987. * characters take the same time irrespective of distance.
  988. *
  989. * @param code_gen The code generator.
  990. */
  991. void processSPLIT(CodeGenerator* code_gen);
  992. void processTLKON(CodeGenerator* code_gen, const std::string& entity);
  993. void processPC(CodeGenerator* code_gen, const std::string& entity);
  994. void processCHAR(CodeGenerator* code_gen, const std::string& entity);
  995. void processDFANM(CodeGenerator* code_gen, const std::string& entity, int char_id);
  996. void processANIME1(CodeGenerator* code_gen, const std::string& entity, int char_id);
  997. void processVISI(CodeGenerator* code_gen, const std::string& entity);
  998. void processXYZI(CodeGenerator* code_gen, const std::string& entity);
  999. void processMOVE(CodeGenerator* code_gen, const std::string& entity);
  1000. void processMSPED(CodeGenerator* code_gen, const std::string& entity);
  1001. void processDIR(CodeGenerator* code_gen, const std::string& entity);
  1002. void processTURNGEN(CodeGenerator* code_gen, const std::string& entity);
  1003. void processGETAI(CodeGenerator* code_gen, const FF7FieldEngine& engine);
  1004. void processANIM_2(CodeGenerator* code_gen, const std::string& entity, int char_id);
  1005. void processCANIM2(CodeGenerator* code_gen, const std::string& entity, int char_id);
  1006. void processCANM_2(CodeGenerator* code_gen, const std::string& entity, int char_id);
  1007. void processCC(CodeGenerator* code_gen, const FF7FieldEngine& engine);
  1008. void processSOLID(CodeGenerator* code_gen, const std::string& entity);
  1009. /**
  1010. * Processes an OFST opcode.
  1011. *
  1012. * Opcode: 0xC3
  1013. * Short name: OFST
  1014. * Long name: Offset Object
  1015. *
  1016. * Memory layout (8 bytes)
  1017. * |0xC3|B1/B2|B3/B4|T|X|Y|Z|S|
  1018. *
  1019. * Arguments:
  1020. * - const Bit[4] B1: Bank to retrieve X offset, or zero if X is
  1021. * specified as a literal.
  1022. * - const Bit[4] B2: Bank to retrieve Y offset, or zero if Y is
  1023. * specified as a literal.
  1024. * - const Bit[4] B3: Bank to retrieve Z offset, or zero if Z is
  1025. * specified as a literal.
  1026. * - const Bit[4] B4: Bank to retrieve speed, or zero if S is
  1027. * specified as a literal.
  1028. * - const UByte T: Type of movement.
  1029. * - const Short X: X offset amount, relative to current position,
  1030. * or address to find X offset, if B1 is non-zero.
  1031. * - const Short Y: Y offset amount, relative to current position,
  1032. * or address to find Y offset, if B2 is non-zero.
  1033. * - const Short Z: Z offset amount, relative to current position,
  1034. * or address to find Z offset, if B3 is non-zero.
  1035. * - const UShort S: Speed of the offset movement, if type is
  1036. * non-zero, or address to find speed, if B4 is non-zero.
  1037. *
  1038. * Offsets the field object, belonging to the entity whose script
  1039. * this opcode resides in, by a certain amount. After being
  1040. * offset, the character continues to be constrained in movement
  1041. * as defined by the walkmesh's shape, but at a certain distance
  1042. * away from the normal walkmesh position. Other field objects are
  1043. * unaffected, and their position or movements are maintained on
  1044. * the walkmesh's original position. If B1, B2, B3 or B4 is
  1045. * non-zero, then the value for that particular component is taken
  1046. * from memory using the corresponding bank and address specified,
  1047. * rather than as a literal value. Both retrieved values and
  1048. * literals can be used for different components. If using T, X, Y
  1049. * or S as addresses, the lower byte should hold the address
  1050. * whilst the higher byte should be zero. The amount to offset is
  1051. * specified relative to the current position. If Type is
  1052. * specified, the object moves gradually from its current point to
  1053. * the offset position; this can be used to simulate movements
  1054. * such as elevators. Any type outside the range in the table will
  1055. * cause the offset not to occur. If the object is set to move
  1056. * gradually, then the speed of offset can be set; the greater the
  1057. * number, the slower the object moves to its target offset.
  1058. * Script execution may also be halted until the gradual offset
  1059. * has been completed. For this, see OFSTW.
  1060. *
  1061. * @param codegen The code generator.
  1062. * @param entity[in] The entity name.
  1063. */
  1064. void processOFST(CodeGenerator* codegen, const std::string& entity);
  1065. };
  1066. /**
  1067. * A walkmesh instruction.
  1068. */
  1069. class FF7WalkmeshInstruction : public KernelCallInstruction{
  1070. public:
  1071. /**
  1072. * Processes the instruction.
  1073. *
  1074. * @param func[in] Function to process.
  1075. * @param stack[out] Function stack.
  1076. * @param engine[in] Engine. Unused.
  1077. * @param code_gen[in] Code generator.
  1078. */
  1079. virtual void processInst(
  1080. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  1081. ) override;
  1082. private:
  1083. void processUC(CodeGenerator* code_gen);
  1084. /**
  1085. * Processes a LINE opcode.
  1086. *
  1087. * Opcode: 0xD0
  1088. * Short name: LINE
  1089. * Long name: Line definition
  1090. *
  1091. * Memory layout (7 bytes)
  1092. * |0xD0|XA|YA|ZA|XB|YB|ZB|
  1093. *
  1094. * Arguments:
  1095. * - const Short XA: X-coordinate of the first point of the line.
  1096. * - const Short YA: Y-coordinate of the first point of the line.
  1097. * - const Short ZA: Z-coordinate of the first point of the line.
  1098. * - const Short XB: X-coordinate of the second point of the line.
  1099. * - const Short YB: Y-coordinate of the second point of the line.
  1100. * - const Short ZB: Z-coordinate of the second point of the line.
  1101. *
  1102. * Defines a line on the walkmesh that, when crossed by a playable
  1103. * character, causes one of the entity's scripts to be executed.
  1104. * These are similar to the triggers in Section 8. All the lines
  1105. * in the current field can be turned on or off by using the LINON
  1106. * opcode.
  1107. *
  1108. * There are generally 6 scripts (other than the init and main) if
  1109. * the entity is a LINE.
  1110. * - script index 2 -> S1 - [OK].
  1111. * - script index 3 -> S2 - Move.
  1112. * - script index 4 -> S3 - Move.
  1113. * - script index 5 -> S4 - Go.
  1114. * - script index 6 -> S5 - Go 1x.
  1115. * - script index 7 -> S6 - Go away.
  1116. *
  1117. * @param code_gen The code generator.
  1118. * @param entity[in] The entity name.
  1119. */
  1120. void processLINE(CodeGenerator* code_gen, const std::string& entity);
  1121. };
  1122. /**
  1123. * A background instruction.
  1124. */
  1125. class FF7BackgroundInstruction : public KernelCallInstruction{
  1126. public:
  1127. /**
  1128. * Processes the instruction.
  1129. *
  1130. * @param func[in] Function to process.
  1131. * @param stack[out] Function stack.
  1132. * @param engine[in] Engine. Unused
  1133. * @param code_gen[in] Code generator.
  1134. */
  1135. virtual void processInst(
  1136. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  1137. ) override;
  1138. private:
  1139. void processBGON(CodeGenerator* code_gen);
  1140. void processBGOFF(CodeGenerator* code_gen);
  1141. void processBGCLR(CodeGenerator* code_gen);
  1142. void processSTPAL(CodeGenerator* code_gen);
  1143. void processLDPAL(CodeGenerator* code_gen);
  1144. void processCPPAL(CodeGenerator* code_gen);
  1145. void processADPAL(CodeGenerator* code_gen);
  1146. void processMPPAL2(CodeGenerator* code_gen);
  1147. void processSTPLS(CodeGenerator* code_gen);
  1148. void processLDPLS(CodeGenerator* code_gen);
  1149. };
  1150. /**
  1151. * A camera instruction.
  1152. */
  1153. class FF7CameraInstruction : public KernelCallInstruction{
  1154. public:
  1155. /**
  1156. * Processes the instruction.
  1157. *
  1158. * @param func[in] Function to process.
  1159. * @param stack[out] Function stack.
  1160. * @param engine[in] Engine. Unused
  1161. * @param code_gen[in] Code generator.
  1162. */
  1163. virtual void processInst(
  1164. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  1165. ) override;
  1166. private:
  1167. void processNFADE(CodeGenerator* code_gen);
  1168. void processSCR2D(CodeGenerator* code_gen);
  1169. void processSCR2DC(CodeGenerator* code_gen);
  1170. void processFADE(CodeGenerator* code_gen);
  1171. };
  1172. /**
  1173. * An audio or video (or both) instruction.
  1174. */
  1175. class FF7AudioVideoInstruction : public KernelCallInstruction{
  1176. public:
  1177. /**
  1178. * Processes the instruction.
  1179. *
  1180. * @param func[in] Function to process.
  1181. * @param stack[out] Function stack.
  1182. * @param engine[in] Engine. Unused
  1183. * @param code_gen[in] Code generator.
  1184. */
  1185. virtual void processInst(
  1186. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  1187. ) override;
  1188. private:
  1189. void processAKAO2(CodeGenerator* code_gen);
  1190. void processMUSIC(CodeGenerator* code_gen);
  1191. void processSOUND(CodeGenerator* code_gen);
  1192. void processAKAO(CodeGenerator* code_gen);
  1193. void processMULCK(CodeGenerator* code_gen);
  1194. void processPMVIE(CodeGenerator* code_gen);
  1195. void processMOVIE(CodeGenerator* code_gen);
  1196. void processMVIEF(CodeGenerator* code_gen);
  1197. };
  1198. /**
  1199. * An instructions that doesn't fall in any other category.
  1200. */
  1201. class FF7UncategorizedInstruction : public KernelCallInstruction{
  1202. public:
  1203. /**
  1204. * Processes the instruction.
  1205. *
  1206. * @param func[in] Function to process.
  1207. * @param stack[out] Function stack.
  1208. * @param engine[in] Engine. Unused.
  1209. * @param code_gen[in] Code generator.
  1210. */
  1211. virtual void processInst(
  1212. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  1213. ) override;
  1214. };
  1215. /**
  1216. * An instruction that does nothing.
  1217. */
  1218. class FF7NoOperationInstruction : public Instruction{
  1219. public:
  1220. /**
  1221. * Generates a instruction that does nothing.
  1222. *
  1223. * @return The generated instruction.
  1224. */
  1225. static InstPtr Create(){return new FF7NoOperationInstruction();}
  1226. /**
  1227. * Processes the instruction.
  1228. *
  1229. * It doesn't do anything.
  1230. *
  1231. * @param func[in] Function to process. Unused.
  1232. * @param stack[out] Function stack. Unused.
  1233. * @param engine[in] Engine. Unused.
  1234. * @param code_gen[in] Code generator. Unused.
  1235. */
  1236. virtual void processInst(
  1237. Function& func, ValueStack &stack, Engine *engine, CodeGenerator *code_gen
  1238. ) override;
  1239. };
  1240. }