FieldCameraInstruction.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * V-Gears
  3. * Copyright (C) 2022 V-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. #include <iostream>
  19. #include <sstream>
  20. #include <boost/format.hpp>
  21. #include "decompiler/field/instruction/FieldCameraInstruction.h"
  22. #include "decompiler/field/FieldEngine.h"
  23. #include "decompiler/field/FieldCodeGenerator.h"
  24. #include "decompiler/field/FieldDisassembler.h"
  25. void FieldCameraInstruction::ProcessInst(
  26. Function& func, ValueStack&, Engine* engine, CodeGenerator *code_gen
  27. ){
  28. FunctionMetaData md(func.metadata);
  29. //std::cout << "Camera opcode: " << opcode_ << "\n";
  30. switch (opcode_){
  31. case OPCODES::NFADE: ProcessNFADE(code_gen); break;
  32. case OPCODES::SHAKE: code_gen->WriteTodo(md.GetEntityName(), "SHAKE"); break;
  33. case OPCODES::SCRLO: code_gen->WriteTodo(md.GetEntityName(), "SCRLO"); break;
  34. case OPCODES::SCRLC: code_gen->WriteTodo(md.GetEntityName(), "SCRLC"); break;
  35. case OPCODES::SCR2D: ProcessSCR2D(code_gen); break;
  36. case OPCODES::SCRCC: code_gen->WriteTodo(md.GetEntityName(), "SCRCC"); break;
  37. case OPCODES::SCR2DC: ProcessSCR2DC(code_gen); break;
  38. case OPCODES::SCRLW: code_gen->WriteTodo(md.GetEntityName(), "SCRLW"); break;
  39. case OPCODES::SCR2DL: code_gen->WriteTodo(md.GetEntityName(), "SCR2DL"); break;
  40. case OPCODES::VWOFT: ProcessVWOFT(code_gen); break;
  41. case OPCODES::FADE: ProcessFADE(code_gen); break;
  42. case OPCODES::FADEW: code_gen->WriteTodo(md.GetEntityName(), "FADEW"); break;
  43. case OPCODES::SCRLP: code_gen->WriteTodo(md.GetEntityName(), "SCRLP"); break;
  44. case OPCODES::MVCAM: code_gen->WriteTodo(md.GetEntityName(), "MVCAM"); break;
  45. case OPCODES::SCRLA: code_gen->WriteTodo(md.GetEntityName(), "SCRLA"); break;
  46. default:
  47. code_gen->AddOutputLine(FieldCodeGenerator::FormatInstructionNotImplemented(
  48. md.GetEntityName(), address_, opcode_
  49. ));
  50. }
  51. }
  52. void FieldCameraInstruction::ProcessNFADE(CodeGenerator* code_gen){
  53. // TODO: Not fully reversed.
  54. auto raw_type = params_[4]->GetUnsigned();
  55. if (raw_type == 0){
  56. code_gen->AddOutputLine("-- fade:clear()");
  57. return;
  58. }
  59. FieldCodeGenerator* cg = static_cast<FieldCodeGenerator*>(code_gen);
  60. const std::string type = raw_type == 12 ? "Fade.SUBTRACT" : "Fade.ADD";
  61. const auto& r = FieldCodeGenerator::FormatValueOrVariable(
  62. cg->GetFormatter(), params_[0]->GetUnsigned(), params_[5]->GetUnsigned()
  63. );
  64. const auto& g = FieldCodeGenerator::FormatValueOrVariable(
  65. cg->GetFormatter(), params_[1]->GetUnsigned(), params_[6]->GetUnsigned()
  66. );
  67. const auto& b = FieldCodeGenerator::FormatValueOrVariable(
  68. cg->GetFormatter(), params_[2]->GetUnsigned(), params_[7]->GetUnsigned()
  69. );
  70. const auto& unknown = FieldCodeGenerator::FormatValueOrVariable(
  71. cg->GetFormatter(), params_[3]->GetUnsigned(), params_[8]->GetUnsigned()
  72. );
  73. code_gen->AddOutputLine(
  74. (boost::format("-- fade:fade(%2%, %3%, %4%, %1%, %5%)") % type % r % g % b % unknown).str()
  75. );
  76. }
  77. void FieldCameraInstruction::ProcessSCR2D(CodeGenerator* code_gen){
  78. // kUpScaler.
  79. FieldCodeGenerator* cg = static_cast<FieldCodeGenerator*>(code_gen);
  80. const auto& x = FieldCodeGenerator::FormatValueOrVariable(
  81. cg->GetFormatter(), params_[0]->GetUnsigned(), params_[2]->GetSigned()
  82. );
  83. const auto& y = FieldCodeGenerator::FormatValueOrVariable(
  84. cg->GetFormatter(), params_[1]->GetUnsigned(), params_[3]->GetSigned()
  85. );
  86. code_gen->AddOutputLine((
  87. boost::format("background2d:scroll_to_position(%1% * 3, %2% * 3, Background2D.NONE, 0)")
  88. % x % y
  89. ).str());
  90. }
  91. void FieldCameraInstruction::ProcessSCR2DC(CodeGenerator* code_gen){
  92. FieldCodeGenerator* cg = static_cast<FieldCodeGenerator*>(code_gen);
  93. const auto& x = FieldCodeGenerator::FormatValueOrVariable(
  94. cg->GetFormatter(), params_[0]->GetUnsigned(), params_[4]->GetSigned()
  95. );
  96. const auto& y = FieldCodeGenerator::FormatValueOrVariable(
  97. cg->GetFormatter(), params_[1]->GetUnsigned(), params_[5]->GetSigned()
  98. );
  99. const auto& speed = FieldCodeGenerator::FormatValueOrVariable(
  100. cg->GetFormatter(), params_[3]->GetUnsigned(), params_[6]->GetUnsigned(),
  101. FieldCodeGenerator::ValueType::Float, 30.0f
  102. );
  103. code_gen->AddOutputLine((
  104. boost::format("background2d:scroll_to_position(%1% * 3, %2% * 3, Background2D.SMOOTH, %3%)")
  105. % x % y % speed
  106. ).str());
  107. }
  108. void FieldCameraInstruction::ProcessVWOFT(CodeGenerator* code_gen){
  109. FieldCodeGenerator* cg = static_cast<FieldCodeGenerator*>(code_gen);
  110. const auto& y = FieldCodeGenerator::FormatValueOrVariable(
  111. cg->GetFormatter(), params_[0]->GetUnsigned(), params_[2]->GetSigned()
  112. );
  113. const auto& x = FieldCodeGenerator::FormatValueOrVariable(
  114. cg->GetFormatter(), params_[1]->GetUnsigned(), params_[3]->GetSigned()
  115. );
  116. const auto& speed = params_[4]->GetUnsigned();
  117. code_gen->AddOutputLine((
  118. boost::format("background2d:offset(%1%, %2%) -- Speed %3%")
  119. % x % y % speed
  120. ).str());
  121. }
  122. void FieldCameraInstruction::ProcessFADE(CodeGenerator* code_gen){
  123. // TODO: not fully reversed
  124. auto raw_type = params_[8]->GetUnsigned();
  125. std::string type;
  126. switch (raw_type) {
  127. case 1:
  128. case 2:
  129. case 7:
  130. case 8:
  131. type = "Fade.SUBTRACT";
  132. break;
  133. case 4: code_gen->AddOutputLine("-- fade:black()"); return;
  134. default: type = "Fade.ADD"; break;
  135. }
  136. FieldCodeGenerator* cg = static_cast<FieldCodeGenerator*>(code_gen);
  137. const auto& r = FieldCodeGenerator::FormatValueOrVariable(
  138. cg->GetFormatter(), params_[0]->GetUnsigned(), params_[4]->GetUnsigned()
  139. );
  140. const auto& g = FieldCodeGenerator::FormatValueOrVariable(
  141. cg->GetFormatter(), params_[1]->GetUnsigned(), params_[5]->GetUnsigned()
  142. );
  143. const auto& b = FieldCodeGenerator::FormatValueOrVariable(
  144. cg->GetFormatter(), params_[2]->GetUnsigned(), params_[6]->GetUnsigned()
  145. );
  146. // TODO: needs to be divided by 30.0f?
  147. auto speed = params_[7]->GetUnsigned();
  148. auto start = params_[9]->GetUnsigned();
  149. code_gen->AddOutputLine((
  150. boost::format("-- fade:fade(%2%, %3%, %4%, %1%, %5%, %6%)") % type % r % g % b % speed % start
  151. ).str());
  152. }