codegen.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /* ScummVM Tools
  2. *
  3. * ScummVM Tools is the legal property of its developers, whose
  4. * names are too numerous to list here. Please refer to the
  5. * COPYRIGHT file distributed with this source distribution.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. */
  21. #include "codegen.h"
  22. std::ostream &Scumm::v6::ListValue::print(std::ostream &output) const {
  23. output << "[";
  24. for (ValueList::const_iterator i = _items.begin(); i != _items.end(); ++i) {
  25. if (i != _items.begin())
  26. output << ", ";
  27. output << *i;
  28. }
  29. output << "]";
  30. return output;
  31. }
  32. ValuePtr Scumm::v6::Scummv6CodeGenerator::createListValue() {
  33. ValueList list;
  34. ValuePtr countValue = _stack.pop();
  35. std::stringstream s;
  36. s << countValue;
  37. int count = atoi(s.str().c_str());
  38. for (int i = 0; i < count; i++) {
  39. list.push_front(_stack.pop());
  40. }
  41. return new ListValue(list);
  42. }
  43. const char *var_names[] = {
  44. /* 0 */
  45. NULL,
  46. "VAR_EGO",
  47. "VAR_CAMERA_POS_X",
  48. "VAR_HAVE_MSG",
  49. /* 4 */
  50. "VAR_ROOM",
  51. "VAR_OVERRIDE",
  52. "VAR_MACHINE_SPEED",
  53. NULL,
  54. /* 8 */
  55. "VAR_NUM_ACTOR",
  56. "VAR_V6_SOUNDMODE",
  57. "VAR_CURRENTDRIVE",
  58. "VAR_TMR_1",
  59. /* 12 */
  60. "VAR_TMR_2",
  61. "VAR_TMR_3",
  62. NULL,
  63. NULL,
  64. /* 16 */
  65. NULL,
  66. "VAR_CAMERA_MIN_X",
  67. "VAR_CAMERA_MAX_X",
  68. "VAR_TIMER_NEXT",
  69. /* 20 */
  70. "VAR_VIRT_MOUSE_X",
  71. "VAR_VIRT_MOUSE_Y",
  72. "VAR_ROOM_RESOURCE",
  73. "VAR_LAST_SOUND",
  74. /* 24 */
  75. "VAR_CUTSCENEEXIT_KEY",
  76. "VAR_TALK_ACTOR",
  77. "VAR_CAMERA_FAST_X",
  78. "VAR_SCROLL_SCRIPT",
  79. /* 28 */
  80. "VAR_ENTRY_SCRIPT",
  81. "VAR_ENTRY_SCRIPT2",
  82. "VAR_EXIT_SCRIPT",
  83. "VAR_EXIT_SCRIPT2",
  84. /* 32 */
  85. "VAR_VERB_SCRIPT",
  86. "VAR_SENTENCE_SCRIPT",
  87. "VAR_INVENTORY_SCRIPT",
  88. "VAR_CUTSCENE_START_SCRIPT",
  89. /* 36 */
  90. "VAR_CUTSCENE_END_SCRIPT",
  91. "VAR_CHARINC",
  92. "VAR_WALKTO_OBJ",
  93. "VAR_DEBUGMODE",
  94. /* 40 */
  95. "VAR_HEAPSPACE",
  96. "VAR_ROOM_WIDTH",
  97. "VAR_RESTART_KEY",
  98. "VAR_PAUSE_KEY",
  99. /* 44 */
  100. "VAR_MOUSE_X",
  101. "VAR_MOUSE_Y",
  102. "VAR_TIMER",
  103. "VAR_TMR_4",
  104. /* 48 */
  105. NULL,
  106. "VAR_VIDEOMODE",
  107. "VAR_MAINMENU_KEY",
  108. "VAR_FIXEDDISK",
  109. /* 52 */
  110. "VAR_CURSORSTATE",
  111. "VAR_USERPUT",
  112. "VAR_ROOM_HEIGHT",
  113. NULL,
  114. /* 56 */
  115. "VAR_SOUNDRESULT",
  116. "VAR_TALKSTOP_KEY",
  117. NULL,
  118. "VAR_FADE_DELAY",
  119. /* 60 */
  120. "VAR_NOSUBTITLES",
  121. "VAR_SAVELOAD_SCRIPT",
  122. "VAR_SAVELOAD_SCRIPT2",
  123. NULL,
  124. /* 64 */
  125. "VAR_SOUNDPARAM",
  126. "VAR_SOUNDPARAM2",
  127. "VAR_SOUNDPARAM3",
  128. "VAR_INPUTMODE",
  129. /* 68 */
  130. "VAR_MEMORY_PERFORMANCE",
  131. "VAR_VIDEO_PERFORMANCE",
  132. "VAR_ROOM_FLAG",
  133. "VAR_GAME_LOADED",
  134. /* 72 */
  135. "VAR_NEW_ROOM",
  136. NULL,
  137. "VAR_LEFTBTN_DOWN",
  138. "VAR_RIGHTBTN_DOWN",
  139. /* 76 */
  140. "VAR_V6_EMSSPACE",
  141. NULL,
  142. NULL,
  143. NULL,
  144. /* 80 */
  145. NULL,
  146. NULL,
  147. NULL,
  148. NULL,
  149. /* 84 */
  150. NULL,
  151. NULL,
  152. NULL,
  153. NULL,
  154. /* 88 */
  155. NULL,
  156. NULL,
  157. "VAR_GAME_DISK_MSG",
  158. "VAR_OPEN_FAILED_MSG",
  159. /* 92 */
  160. "VAR_READ_ERROR_MSG",
  161. "VAR_PAUSE_MSG",
  162. "VAR_RESTART_MSG",
  163. "VAR_QUIT_MSG",
  164. /* 96 */
  165. "VAR_SAVE_BTN",
  166. "VAR_LOAD_BTN",
  167. "VAR_PLAY_BTN",
  168. "VAR_CANCEL_BTN",
  169. /* 100 */
  170. "VAR_QUIT_BTN",
  171. "VAR_OK_BTN",
  172. "VAR_SAVE_DISK_MSG",
  173. "VAR_ENTER_NAME_MSG",
  174. /* 104 */
  175. "VAR_NOT_SAVED_MSG",
  176. "VAR_NOT_LOADED_MSG",
  177. "VAR_SAVE_MSG",
  178. "VAR_LOAD_MSG",
  179. /* 108 */
  180. "VAR_SAVE_MENU_TITLE",
  181. "VAR_LOAD_MENU_TITLE",
  182. "VAR_GUI_COLORS",
  183. "VAR_DEBUG_PASSWORD",
  184. /* 112 */
  185. NULL,
  186. NULL,
  187. NULL,
  188. NULL,
  189. /* 116 */
  190. NULL,
  191. "VAR_MAIN_MENU_TITLE",
  192. "VAR_RANDOM_NR",
  193. "VAR_TIMEDATE_YEAR",
  194. /* 120 */
  195. NULL,
  196. "VAR_GAME_VERSION",
  197. NULL,
  198. "VAR_CHARSET_MASK",
  199. /* 124 */
  200. NULL,
  201. "VAR_TIMEDATE_HOUR",
  202. "VAR_TIMEDATE_MINUTE",
  203. NULL,
  204. /* 128 */
  205. "VAR_TIMEDATE_DAY",
  206. "VAR_TIMEDATE_MONTH",
  207. NULL,
  208. NULL,
  209. };
  210. const char *Scumm::v6::Scummv6CodeGenerator::getVarName(uint16 varID) {
  211. if (varID >= sizeof(var_names) / sizeof(var_names[0]))
  212. return NULL;
  213. return var_names[varID];
  214. }
  215. std::string Scumm::v6::Scummv6CodeGenerator::decodeVarName(uint16 varID) {
  216. std::stringstream s;
  217. if (!(varID & 0xF000)) {
  218. uint16 var = varID & 0xFFF;
  219. const char* varName = getVarName(var);
  220. if (varName != NULL)
  221. return varName;
  222. else
  223. s << boost::format("var%d") % (varID & 0xFFF);
  224. } else if (varID & 0x8000) {
  225. s << boost::format("bitvar%d") % (varID & 0x7FFF);
  226. } else if (varID & 0x4000) {
  227. s << boost::format("localvar%d") % (varID & 0xFFF);
  228. } else {
  229. s << boost::format("?var?%d") % varID;
  230. }
  231. return s.str();
  232. }
  233. std::string Scumm::v6::Scummv6CodeGenerator::decodeArrayName(uint16 arrID) {
  234. std::stringstream s;
  235. const char *varName;
  236. if (!(arrID & 0xF000) && (varName = getVarName(arrID & 0xFFF)) != NULL)
  237. return varName;
  238. s << boost::format("array%d") % arrID;
  239. return s.str();
  240. }
  241. void Scumm::v6::Scummv6CodeGenerator::processSpecialMetadata(const InstPtr inst, char c, int pos) {
  242. switch (c) {
  243. // All of these meanings are taken from descumm.
  244. case 'l':
  245. addArg(createListValue());
  246. break;
  247. // No SCUMMv6 opcodes using these types have more than one parameter, so it's safe to assume it's the first parameter we want.
  248. case 'w':
  249. case 'j':
  250. case 'i':
  251. addArg(inst->_params[0]);
  252. case 'v':
  253. addArg(new VarValue(decodeVarName(static_cast<uint16>(inst->_params[0]->getUnsigned()))));
  254. break;
  255. case 's':
  256. addArg(inst->_params[0]);
  257. break;
  258. case 'z':
  259. addArg(_stack.pop());
  260. addArg(_stack.pop());
  261. break;
  262. default:
  263. CodeGenerator::processSpecialMetadata(inst, c, pos);
  264. break;
  265. }
  266. }