rasm.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569
  1. #include "rasm.h"
  2. #include <ctype.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. int cm3[] = { IMM_U16 | STRING };
  7. int cm4[] = { IMM_U16 | STRING };
  8. int cm5[] = { DIR, IMM_U16 | STRING };
  9. int cm6[] = { DIR };
  10. int cm7[] = { COLOR | STRING, THING, PARAM };
  11. int cm8[] = { CHARACTER | STRING | IMM_U16 };
  12. int cm9[] = { COLOR | STRING };
  13. int cm10[] = { IMM_S16 | STRING, IMM_S16 | STRING };
  14. int cm11[] = { STRING, IMM_U16 | STRING };
  15. int cm12[] = { STRING, IMM_U16 | STRING };
  16. int cm13[] = { STRING, IMM_U16 | STRING };
  17. int cm14[] = { STRING, STRING };
  18. int cm15[] = { STRING, STRING };
  19. int cm16[] = { STRING, STRING };
  20. int cm17[] = { STRING, EQUALITY, IMM_U16 | STRING, STRING };
  21. int cm18[] = { STRING, EQUALITY, STRING, STRING };
  22. int cm19[] = { CONDITION, STRING };
  23. int cm20[] = { CMD_NOT, CONDITION, STRING };
  24. int cm21[] = { CMD_ANY, COLOR | STRING, THING, PARAM, STRING };
  25. int cm22[] = { CMD_NOT, CMD_ANY, COLOR | STRING, THING, PARAM, STRING };
  26. int cm23[] = { COLOR | STRING, THING, PARAM, DIR, STRING };
  27. int cm24[] = { CMD_NOT, COLOR | STRING, THING, PARAM, DIR, STRING };
  28. int cm25[] = { COLOR | STRING, THING, PARAM, IMM_S16 | STRING, IMM_S16 | STRING, STRING };
  29. int cm26[] = { IMM_S16 | STRING, IMM_S16 | STRING, STRING };
  30. int cm27[] = { DIR, CMD_PLAYER, COLOR | STRING, THING, PARAM, STRING };
  31. int cm28[] = { STRING };
  32. int cm29[] = { STRING };
  33. int cm30[] = { STRING };
  34. int cm31[] = { STRING, STRING };
  35. int cm32[] = { IMM_U16 | STRING };
  36. int cm33[] = { COLOR | STRING, THING, PARAM, DIR };
  37. int cm34[] = { IMM_U16 | STRING, ITEM };
  38. int cm35[] = { IMM_U16 | STRING, ITEM };
  39. int cm36[] = { IMM_U16 | STRING, ITEM, STRING };
  40. int cm39[] = { STRING };
  41. int cm40[] = { IMM_U16 | STRING, STRING };
  42. int cm41[] = { IMM_U16 | STRING };
  43. int cm42[] = { CMD_MOD };
  44. int cm43[] = { CMD_SAM };
  45. int cm44[] = { STRING };
  46. int cm45[] = { CMD_PLAY };
  47. int cm46[] = { CMD_PLAY, STRING };
  48. int cm47[] = { CMD_PLAY };
  49. int cm49[] = { IMM_U16 | STRING };
  50. int cm50[] = { CMD_SFX, STRING };
  51. int cm51[] = { DIR };
  52. int cm54[] = { DIR, STRING };
  53. int cm55[] = { STRING, IMM_U16 | STRING };
  54. int cm56[] = { STRING, IMM_U16 | STRING };
  55. int cm59[] = { CMD_NS };
  56. int cm60[] = { CMD_EW };
  57. int cm61[] = { CMD_ATTACK };
  58. int cm62[] = { CMD_PLAYER, DIR };
  59. int cm63[] = { CMD_PLAYER, DIR, STRING };
  60. int cm64[] = { CMD_PLAYER, IMM_S16 | STRING, IMM_S16 | STRING };
  61. int cm65[] = { CMD_PLAYER, DIR, STRING };
  62. int cm66[] = { CMD_PLAYER, CMD_NOT, DIR, STRING };
  63. int cm67[] = { CMD_PLAYER, IMM_S16 | STRING, IMM_S16 | STRING, STRING };
  64. int cm68[] = { CMD_PLAYER, DIR };
  65. int cm69[] = { DIR, STRING };
  66. int cm72[] = { STRING, STRING };
  67. int cm73[] = { DIR };
  68. int cm74[] = { DIR };
  69. int cm75[] = { CMD_HIGH, DIR };
  70. int cm76[] = { DIR };
  71. int cm77[] = { DIR };
  72. int cm78[] = { DIR };
  73. int cm79[] = { DIR, IMM_U16 | STRING };
  74. int cm80[] = { COLOR | STRING, THING, PARAM, IMM_S16 | STRING, IMM_S16 | STRING };
  75. int cm81[] = { CMD_ITEM };
  76. int cm82[] = { IMM_S16 | STRING, IMM_S16 | STRING, STRING };
  77. int cm83[] = { STRING };
  78. int cm84[] = { IMM_S16 | STRING, IMM_S16 | STRING };
  79. int cm85[] = { DIR };
  80. int cm86[] = { CMD_SELF, DIR };
  81. int cm87[] = { CMD_SELF, IMM_S16 | STRING, IMM_S16 | STRING };
  82. int cm88[] = { CHARACTER | STRING | IMM_U16 };
  83. int cm89[] = { CHARACTER | STRING | IMM_U16 };
  84. int cm90[] = { CHARACTER | STRING | IMM_U16 };
  85. int cm91[] = { CHARACTER | STRING | IMM_U16 };
  86. int cm92[] = { COLOR | STRING };
  87. int cm93[] = { COLOR | STRING, STRING };
  88. int cm94[] = { COLOR | STRING };
  89. int cm95[] = { COLOR | STRING, STRING };
  90. int cm96[] = { STRING, CMD_RANDOM, IMM_U16 | STRING, IMM_U16 | STRING };
  91. int cm97[] = { STRING, CMD_RANDOM, IMM_U16 | STRING, IMM_U16 | STRING };
  92. int cm98[] = { STRING, CMD_RANDOM, IMM_U16 | STRING, IMM_U16 | STRING };
  93. int cm99[] = { IMM_U16 | STRING, ITEM, IMM_U16 | STRING, ITEM, STRING };
  94. int cm100[] = { DIR, CMD_PLAYER, STRING };
  95. int cm101[] = { COLOR | STRING, THING, PARAM, DIR, CMD_PLAYER };
  96. int cm102[] = { STRING };
  97. int cm103[] = { STRING };
  98. int cm104[] = { STRING };
  99. int cm105[] = { STRING, STRING };
  100. int cm106[] = { STRING, STRING, STRING };
  101. int cm107[] = { STRING };
  102. int cm108[] = { STRING };
  103. int cm109[] = { STRING };
  104. int cm110[] = { CMD_PLAYER, STRING, IMM_S16 | STRING, IMM_S16 | STRING };
  105. int cm111[] = { DIR, IMM_U16 | STRING };
  106. int cm112[] = { CMD_STRING, STRING };
  107. int cm113[] = { CMD_STRING, STRING, STRING };
  108. int cm114[] = { CMD_STRING, CMD_NOT, STRING, STRING };
  109. int cm115[] = { CMD_STRING, CMD_MATCHES, STRING, STRING };
  110. int cm116[] = { CMD_CHAR, CHARACTER | STRING | IMM_U16 };
  111. int cm117[] = { STRING };
  112. int cm118[] = { STRING };
  113. int cm119[] = { CMD_ALL, COLOR | STRING, THING, PARAM, DIR };
  114. int cm120[] = { IMM_S16 | STRING, IMM_S16 | STRING, IMM_S16 | STRING, IMM_S16 | STRING };
  115. int cm121[] = { CMD_EDGE, CMD_COLOR, COLOR };
  116. int cm122[] = { DIR, STRING };
  117. int cm123[] = { DIR, CMD_NONE };
  118. int cm124[] = { CMD_EDIT, CHARACTER | STRING | IMM_U16, IMM_U16 | STRING, IMM_U16 | STRING,
  119. IMM_U16 | STRING, IMM_U16 | STRING, IMM_U16 | STRING, IMM_U16 | STRING, IMM_U16 | STRING,
  120. IMM_U16 | STRING, IMM_U16 | STRING, IMM_U16 | STRING, IMM_U16 | STRING, IMM_U16 | STRING,
  121. IMM_U16 | STRING, IMM_U16 | STRING };
  122. int cm125[] = { CMD_PUSHABLE };
  123. int cm126[] = { CMD_NONPUSHABLE };
  124. int cm127[] = { IMM_U16 | STRING };
  125. int cm128[] = { IMM_U16 | STRING };
  126. int cm129[] = { IMM_U16 | STRING };
  127. int cm130[] = { IMM_U16 | STRING };
  128. int cm131[] = { IMM_U16 | STRING };
  129. int cm133[] = { DIR, DIR };
  130. int cm134[] = { CMD_LAVAWALKER };
  131. int cm135[] = { CMD_NONLAVAWALKER };
  132. int cm136[] = { COLOR | STRING, THING, PARAM, COLOR | STRING, THING, PARAM };
  133. int cm137[] = { COLOR };
  134. int cm138[] = { COLOR };
  135. int cm139[] = { COLOR };
  136. int cm140[] = { CMD_ROW, IMM_U16 | STRING };
  137. int cm141[] = { CMD_SELF };
  138. int cm142[] = { CMD_PLAYER };
  139. int cm143[] = { CMD_COUNTERS };
  140. int cm144[] = { CMD_CHAR, CMD_ID, IMM_U16 | STRING, CHARACTER | STRING | IMM_U16 };
  141. int cm145[] = { CMD_MOD, CMD_ORDER, IMM_U16 | STRING };
  142. int cm146[] = { STRING };
  143. int cm148[] = { CMD_THICK, CMD_ARROW, CMD_CHAR, DIR, CHARACTER | STRING | IMM_U16 };
  144. int cm149[] = { CMD_THIN, CMD_ARROW, CMD_CHAR, DIR, CHARACTER | STRING | IMM_U16 };
  145. int cm150[] = { CMD_MAXHEALTH, IMM_U16 | STRING };
  146. int cm151[] = { CMD_PLAYER, CMD_POSITION };
  147. int cm152[] = { CMD_PLAYER, CMD_POSITION };
  148. int cm153[] = { CMD_PLAYER, CMD_POSITION };
  149. int cm154[] = { CMD_MESG, CMD_COLUMN, IMM_U16 | STRING };
  150. int cm155[] = { CMD_MESG };
  151. int cm156[] = { CMD_MESG };
  152. int cm158[] = { IMM_U16 | STRING, IMM_U16 | STRING };
  153. int cm159[] = { STRING };
  154. int cm160[] = { CMD_COLOR, COLOR | STRING };
  155. int cm161[] = { CMD_COLOR, COLOR | STRING };
  156. int cm162[] = { CMD_COLOR, COLOR | STRING };
  157. int cm163[] = { CMD_COLOR, COLOR | STRING };
  158. int cm164[] = { CMD_COLOR, COLOR | STRING };
  159. int cm165[] = { IMM_U16 | STRING, IMM_U16 | STRING };
  160. int cm166[] = { CMD_SIZE, IMM_U16 | STRING, IMM_U16 | STRING };
  161. int cm167[] = { CMD_MESG, CMD_COLUMN, STRING };
  162. int cm168[] = { CMD_ROW, STRING };
  163. int cm169[] = { CMD_PLAYER, CMD_POSITION, IMM_U16 | STRING };
  164. int cm170[] = { CMD_PLAYER, CMD_POSITION, IMM_U16 | STRING };
  165. int cm171[] = { CMD_PLAYER, CMD_POSITION, IMM_U16 | STRING };
  166. int cm172[] = { CMD_PLAYER, CMD_POSITION, IMM_U16 | STRING, CMD_DUPLICATE, CMD_SELF };
  167. int cm173[] = { CMD_PLAYER, CMD_POSITION, IMM_U16 | STRING, CMD_DUPLICATE, CMD_SELF };
  168. int cm174[] = { CMD_BULLETN, CHARACTER | STRING | IMM_U16 };
  169. int cm175[] = { CMD_BULLETS, CHARACTER | STRING | IMM_U16 };
  170. int cm176[] = { CMD_BULLETE, CHARACTER | STRING | IMM_U16 };
  171. int cm177[] = { CMD_BULLETW, CHARACTER | STRING | IMM_U16 };
  172. int cm178[] = { CMD_BULLETN, CHARACTER | STRING | IMM_U16 };
  173. int cm179[] = { CMD_BULLETS, CHARACTER | STRING | IMM_U16 };
  174. int cm180[] = { CMD_BULLETE, CHARACTER | STRING | IMM_U16 };
  175. int cm181[] = { CMD_BULLETW, CHARACTER | STRING | IMM_U16 };
  176. int cm182[] = { CMD_BULLETN, CHARACTER | STRING | IMM_U16 };
  177. int cm183[] = { CMD_BULLETS, CHARACTER | STRING | IMM_U16 };
  178. int cm184[] = { CMD_BULLETE, CHARACTER | STRING | IMM_U16 };
  179. int cm185[] = { CMD_BULLETW, CHARACTER | STRING | IMM_U16 };
  180. int cm186[] = { CMD_BULLETCOLOR, COLOR | STRING };
  181. int cm187[] = { CMD_BULLETCOLOR, COLOR | STRING };
  182. int cm188[] = { CMD_BULLETCOLOR, COLOR | STRING };
  183. int cm194[] = { CMD_SELF, CMD_FIRST };
  184. int cm195[] = { CMD_SELF, CMD_LAST };
  185. int cm196[] = { CMD_PLAYER, CMD_FIRST };
  186. int cm197[] = { CMD_PLAYER, CMD_LAST };
  187. int cm198[] = { CMD_COUNTERS, CMD_FIRST };
  188. int cm199[] = { CMD_COUNTERS, CMD_LAST };
  189. int cm200[] = { CMD_FADE, CMD_OUT };
  190. int cm201[] = { CMD_FADE, CMD_IN, STRING };
  191. int cm202[] = { CMD_BLOCK, IMM_S16 | STRING, IMM_S16 | STRING, IMM_U16 | STRING,
  192. IMM_U16 | STRING, IMM_S16 | STRING, IMM_S16 | STRING };
  193. int cm203[] = { CMD_INPUT };
  194. int cm204[] = { CMD_DIR };
  195. int cm205[] = { CMD_CHAR, CHARACTER | STRING | IMM_U16, DIR };
  196. int cm206[] = { CMD_CHAR, CHARACTER | STRING | IMM_U16, DIR };
  197. int cm207[] = { CMD_CHAR, CHARACTER | STRING | IMM_U16, CHARACTER | STRING | IMM_U16 };
  198. int cm211[] = { CMD_SFX, IMM_U16 | STRING, STRING };
  199. int cm212[] = { CMD_INTENSITY, IMM_U16 | STRING, CMD_PERCENT };
  200. int cm213[] = { CMD_INTENSITY, IMM_U16 | STRING, IMM_U16 | STRING, CMD_PERCENT };
  201. int cm214[] = { CMD_FADE, CMD_OUT };
  202. int cm215[] = { CMD_FADE, CMD_IN };
  203. int cm216[] = { CMD_COLOR, IMM_U16 | STRING, IMM_U16 | STRING, IMM_U16 | STRING,
  204. IMM_U16 | STRING };
  205. int cm217[] = { CMD_CHAR, CMD_SET, STRING };
  206. int cm218[] = { STRING, IMM_U16 | STRING };
  207. int cm219[] = { STRING, IMM_U16 | STRING };
  208. int cm220[] = { STRING, IMM_U16 | STRING };
  209. int cm221[] = { CMD_CHAR, DIR, CHARACTER | STRING | IMM_U16 };
  210. int cm223[] = { CMD_PALETTE, STRING };
  211. int cm225[] = { CMD_FADE, IMM_U16 | STRING, IMM_U16 | STRING };
  212. int cm226[] = { CMD_POSITION, IMM_S16 | STRING, IMM_S16 | STRING };
  213. int cm227[] = { CMD_WORLD, STRING };
  214. int cm228[] = { CMD_ALIGNEDROBOT, STRING, STRING };
  215. int cm232[] = { CMD_FIRST, CMD_STRING, STRING, STRING };
  216. int cm233[] = { CMD_GO, STRING };
  217. int cm234[] = { CMD_MOD, CMD_FADE };
  218. int cm236[] = { CMD_SAVING };
  219. int cm237[] = { CMD_SAVING };
  220. int cm238[] = { CMD_SENSORONLY, CMD_SAVING };
  221. int cm239[] = { CMD_COUNTER, IMM_U16 | STRING, STRING };
  222. int cm240[] = { CMD_ON };
  223. int cm241[] = { CMD_STATIC };
  224. int cm242[] = { CMD_TRANSPARENT };
  225. int cm243[] = { COLOR | STRING, CHARACTER | STRING | IMM_U16, CMD_OVERLAY, IMM_S16 | STRING,
  226. IMM_S16 | STRING };
  227. int cm244[] = { CMD_OVERLAY, CMD_BLOCK, IMM_S16 | STRING, IMM_S16 | STRING,
  228. IMM_U16 | STRING, IMM_U16 | STRING, IMM_S16 | STRING, IMM_S16 | STRING };
  229. int cm246[] = { CMD_OVERLAY, COLOR | STRING, CHARACTER | STRING | IMM_U16,
  230. COLOR | STRING, CHARACTER | STRING };
  231. int cm247[] = { CMD_OVERLAY, COLOR | STRING, COLOR | STRING };
  232. int cm248[] = { CMD_OVERLAY, COLOR | STRING, STRING, IMM_S16 | STRING, IMM_S16 | STRING };
  233. int cm252[] = { CMD_START };
  234. int cm253[] = { IMM_U16 | STRING };
  235. int cm254[] = { CMD_LOOP };
  236. int cm255[] = { CMD_MESG, CMD_EDGE };
  237. int cm256[] = { CMD_MESG, CMD_EDGE };
  238. mzx_command command_list[] =
  239. {
  240. { "End", 0, NULL },
  241. { "Die", 0, NULL },
  242. { "Wait", 1, cm3 },
  243. { "Cycle", 1, cm4 },
  244. { "Go", 2, cm5 },
  245. { "Walk", 1, cm6 },
  246. { "Become", 3, cm7 },
  247. { "Char", 1, cm8 },
  248. { "Color", 1, cm9 },
  249. { "Gotoxy", 2, cm10 },
  250. { "Set", 2, cm11 },
  251. { "Inc", 2, cm12 },
  252. { "Dec", 2, cm13 },
  253. { "Set", 2, cm14 },
  254. { "Inc", 2, cm15 },
  255. { "Dec", 2, cm16 },
  256. { "If", 4, cm17 },
  257. { "If", 4, cm18 },
  258. { "If", 2, cm19 },
  259. { "If", 3, cm20 },
  260. { "If", 5, cm21 },
  261. { "If", 6, cm22 },
  262. { "If", 5, cm23 },
  263. { "If", 6, cm24 },
  264. { "If", 6, cm25 },
  265. { "If", 3, cm26 },
  266. { "If", 6, cm27 },
  267. { "Double", 1, cm28 },
  268. { "Half", 1, cm29 },
  269. { "Goto", 1, cm30 },
  270. { "Send", 2, cm31 },
  271. { "Explode", 1, cm32 },
  272. { "Put", 4, cm33 },
  273. { "Give", 2, cm34 },
  274. { "Take", 2, cm35 },
  275. { "Take", 3, cm36 },
  276. { "Endgame", 0, NULL },
  277. { "Endlife", 0, NULL },
  278. { "Mod", 1, cm39 },
  279. { "Sam", 2, cm40 },
  280. { "Volume", 1, cm41 },
  281. { "End", 1, cm42 },
  282. { "End", 1, cm43 },
  283. { "Play", 1, cm44 },
  284. { "End", 1, cm45 },
  285. { "Wait", 2, cm46 },
  286. { "Wait", 1, cm47 },
  287. { "_blank_line", 0, NULL },
  288. { "Sfx", 1, cm49 },
  289. { "Play", 2, cm50 },
  290. { "Open", 1, cm51 },
  291. { "Lockself", 0, NULL },
  292. { "Unlockself", 0, NULL },
  293. { "Send", 2, cm54 },
  294. { "Zap", 2, cm55 },
  295. { "Restore", 2, cm56 },
  296. { "Lockplayer", 0, NULL },
  297. { "Unlockplayer", 0, NULL },
  298. { "Lockplayer", 1, cm59 },
  299. { "Lockplayer", 1, cm60 },
  300. { "Lockplayer", 1, cm61 },
  301. { "Move", 2, cm62 },
  302. { "Move", 3, cm63 },
  303. { "Put", 2, cm64 },
  304. { "If", 3, cm65 },
  305. { "If", 4, cm66 },
  306. { "If", 4, cm67 },
  307. { "Put", 2, cm68 },
  308. { "Try", 2, cm69 },
  309. { "Rotatecw", 0, NULL },
  310. { "Rotateccw", 0, NULL },
  311. { "Switch", 2, cm72 },
  312. { "Shoot", 1, cm73 },
  313. { "Laybomb", 1, cm74 },
  314. { "Laybomb", 1, cm75 },
  315. { "Shootmissile", 1, cm76 },
  316. { "Shootseeker", 1, cm77 },
  317. { "Spitfire", 1, cm78 },
  318. { "Lazerwall", 2, cm79 },
  319. { "Put", 5, cm80 },
  320. { "Die", 1, cm81 },
  321. { "Send", 3, cm82 },
  322. { "Copyrobot", 1, cm83 },
  323. { "Copyrobot", 2, cm84 },
  324. { "Copyrobot", 1, cm85 },
  325. { "Duplicate", 2, cm86 },
  326. { "Duplicate", 3, cm87 },
  327. { "Bulletn", 1, cm88 },
  328. { "Bullets", 1, cm89 },
  329. { "Bullete", 1, cm90 },
  330. { "Bulletw", 1, cm91 },
  331. { "Givekey", 1, cm92 },
  332. { "Givekey", 2, cm93 },
  333. { "Takekey", 1, cm94 },
  334. { "Takekey", 2, cm95 },
  335. { "Inc", 4, cm96 },
  336. { "Dec", 4, cm97 },
  337. { "Set", 4, cm98 },
  338. { "Trade", 5, cm99 },
  339. { "Send", 3, cm100 },
  340. { "Put", 5, cm101 },
  341. { "//", 1, cm102 },
  342. { "*", 1, cm103 },
  343. { "[", 1, cm104 },
  344. { "?", 2, cm105 },
  345. { "?", 3, cm106 },
  346. { ":", 1, cm107 },
  347. { ".", 1, cm108 },
  348. { "|", 1, cm109 },
  349. { "Teleport", 4, cm110 },
  350. { "Scrollview", 2, cm111 },
  351. { "Input", 2, cm112 },
  352. { "If", 3, cm113 },
  353. { "If", 4, cm114 },
  354. { "If", 4, cm115 },
  355. { "Player", 2, cm116 },
  356. { "%", 1, cm117 },
  357. { "&", 1, cm118 },
  358. { "Move", 5, cm119 },
  359. { "Copy", 4, cm120 },
  360. { "Set", 3, cm121 },
  361. { "Board", 2, cm122 },
  362. { "Board", 2, cm123 },
  363. { "Char", 16, cm124 },
  364. { "Become", 1, cm125 },
  365. { "Become", 1, cm126 },
  366. { "Blind", 1, cm127 },
  367. { "Firewalker", 1, cm128 },
  368. { "Freezetime", 1, cm129 },
  369. { "Slowtime", 1, cm130 },
  370. { "Wind", 1, cm131 },
  371. { "Avalanche", 0, NULL },
  372. { "Copy", 2, cm133 },
  373. { "Become", 1, cm134 },
  374. { "Become", 1, cm135 },
  375. { "Change", 6, cm136 },
  376. { "Playercolor", 1, cm137 },
  377. { "Bulletcolor", 1, cm138 },
  378. { "Missilecolor", 1, cm139 },
  379. { "Message", 2, cm140 },
  380. { "Rel", 1, cm141 },
  381. { "Rel", 1, cm142 },
  382. { "Rel", 1, cm143 },
  383. { "Change", 4, cm144 },
  384. { "Jump", 2, cm145 },
  385. { "Ask", 1, cm146 },
  386. { "Fillhealth", 0, NULL },
  387. { "Change", 5, cm148 },
  388. { "Change", 5, cm149 },
  389. { "Set", 2, cm150 },
  390. { "Save", 2, cm151 },
  391. { "Restore", 2, cm152 },
  392. { "Exchange", 2, cm153 },
  393. { "Set", 3, cm154 },
  394. { "Center", 1, cm155 },
  395. { "Clear", 1, cm156 },
  396. { "Resetview", 0, NULL },
  397. { "Sam", 2, cm158 },
  398. { "Volume", 1, cm159 },
  399. { "Scrollbase", 2, cm160 },
  400. { "Scrollcorner", 2, cm161 },
  401. { "Scrolltitle", 2, cm162 },
  402. { "Scrollpointer", 2, cm163 },
  403. { "Scrollarrow", 2, cm164 },
  404. { "Viewport", 2, cm165 },
  405. { "Viewport", 3, cm166 },
  406. { "Set", 3, cm167 },
  407. { "Message", 2, cm168 },
  408. { "Save", 3, cm169 },
  409. { "Restore", 3, cm170 },
  410. { "Exchange", 3, cm171 },
  411. { "Restore", 5, cm172 },
  412. { "Exchange", 5, cm173 },
  413. { "Player", 2, cm174 },
  414. { "Player", 2, cm175 },
  415. { "Player", 2, cm176 },
  416. { "Player", 2, cm177 },
  417. { "Neutral", 2, cm178 },
  418. { "Neutral", 2, cm179 },
  419. { "Neutral", 2, cm180 },
  420. { "Neutral", 2, cm181 },
  421. { "Enemy", 2, cm182 },
  422. { "Enemy", 2, cm183 },
  423. { "Enemy", 2, cm184 },
  424. { "Enemy", 2, cm185 },
  425. { "Player", 2, cm186 },
  426. { "Neutral", 2, cm187 },
  427. { "Enemy", 2, cm188 },
  428. { "__unused", 0, NULL },
  429. { "__unused", 0, NULL },
  430. { "__unused", 0, NULL },
  431. { "__unused", 0, NULL },
  432. { "__unused", 0, NULL },
  433. { "Rel", 2, cm194 },
  434. { "Rel", 2, cm195 },
  435. { "Rel", 2, cm196 },
  436. { "Rel", 2, cm197 },
  437. { "Rel", 2, cm198 },
  438. { "Rel", 2, cm199 },
  439. { "Mod", 2, cm200 },
  440. { "Mod", 3, cm201 },
  441. { "Copy", 7, cm202 },
  442. { "Clip", 1, cm203 },
  443. { "Push", 1, cm204 },
  444. { "Scroll", 3, cm205 },
  445. { "Flip", 3, cm206 },
  446. { "Copy", 3, cm207 },
  447. { "__unused", 0, NULL },
  448. { "__unused", 0, NULL },
  449. { "__unused", 0, NULL },
  450. { "Change", 3, cm211 },
  451. { "Color", 3, cm212 },
  452. { "Color", 4, cm213 },
  453. { "Color", 2, cm214 },
  454. { "Color", 2, cm215 },
  455. { "Set", 5, cm216 },
  456. { "Load", 3, cm217 },
  457. { "Multiply", 2, cm218 },
  458. { "Divide", 2, cm219 },
  459. { "Modulo", 2, cm220 },
  460. { "Player", 3, cm221 },
  461. { "__unused", 0, NULL },
  462. { "Load", 2, cm223 },
  463. { "__unused", 0, NULL },
  464. { "Mod", 3, cm225 },
  465. { "Scrollview", 3, cm226 },
  466. { "Swap", 2, cm227 },
  467. { "If", 3, cm228 },
  468. { "__unused", 0, NULL },
  469. { "Lockscroll", 0, NULL },
  470. { "Unlockscroll", 0, NULL },
  471. { "If", 4, cm232 },
  472. { "Persistent", 2, cm233 },
  473. { "Wait", 2, cm234 },
  474. { "__unused", 0, NULL },
  475. { "Enable", 1, cm236 },
  476. { "Disable", 1, cm237 },
  477. { "Enable", 2, cm238 },
  478. { "Status", 3, cm239 },
  479. { "Overlay", 1, cm240 },
  480. { "Overlay", 1, cm241 },
  481. { "Overlay", 1, cm242 },
  482. { "Put", 5, cm243 },
  483. { "Copy", 8, cm244 },
  484. { "__unused", 0, NULL },
  485. { "Change", 5, cm246 },
  486. { "Change", 3, cm247 },
  487. { "Write", 5, cm248 },
  488. { "__unused", 0, NULL },
  489. { "__unused", 0, NULL },
  490. { "__unused", 0, NULL },
  491. { "Loop", 1, cm252 },
  492. { "Loop", 1, cm253 },
  493. { "Abort", 1, cm254 },
  494. { "Disable", 2, cm255 },
  495. { "Enable", 2, cm256 }
  496. };
  497. char *dir_types1[20] =
  498. {
  499. "IDLE", "NORTH", "SOUTH", "EAST", "WEST", "RANDNS", "RANDEW", "RANDNE", "RANDNB",
  500. "SEEK", "RANDANY", "BENEATH", "ANYDIR", "FLOW", "NODIR", "RANDB", "RANDP", "CW",
  501. "OPP", "RANDNOT"
  502. };
  503. char *dir_types2[20] =
  504. {
  505. "IDLE", "N", "S", "E", "W", "RANDNS", "RANDEW", "RANDNE", "RANDNB",
  506. "SEEK", "RANDANY", "UNDER", "ANYDIR", "FLOW", "NODIR", "RANDB", "RANDP", "CW",
  507. "OPP", "RANDNOT"
  508. };
  509. char *dir_types3[20] =
  510. {
  511. "IDLE", "UP", "DOWN", "RIGHT", "LEFT", "RANDNS", "RANDEW", "RANDNE", "RANDNB",
  512. "SEEK", "RANDANY", "BENEATH", "ANYDIR", "FLOW", "NODIR", "RANDB", "RANDP", "CW",
  513. "OPP", "RANDNOT"
  514. };
  515. char *equality_types1[6] =
  516. {
  517. "=", "!=", ">", "<", ">=", "<="
  518. };
  519. char *equality_types2[6] =
  520. {
  521. "==", "<>", ">", "<", "=?", "=<"
  522. };
  523. char *equality_types3[6] =
  524. {
  525. "=", "><", ">", "<", ">=", "<="
  526. };
  527. char *condition_types[18] =
  528. {
  529. "Walking", "Swimming", "Firewalking", "Touching", "Blocked", "Aligned", "Alignedns",
  530. "Alignedew", "Lastshot", "Lasttouch", "Rightpressed", "Leftpressed", "Uppressed",
  531. "Downpressed", "Spacepressed", "Delpressed", "Musicon", "Pcsfxon"
  532. };
  533. char *item_types[9] =
  534. {
  535. "GEMS", "AMMOS", "TIME", "SCORE", "HEALTHS", "LIVES", "LOBOMBS", "HIBOMBS", "COINS"
  536. };
  537. char *thing_types[128] =
  538. {
  539. "Space",
  540. "Normal",
  541. "Solid",
  542. "Tree",
  543. "Line",
  544. "CustomBlock",
  545. "Breakaway",
  546. "CustomBreak",
  547. "Boulder",
  548. "Crate",
  549. "CustomPush",
  550. "Box",
  551. "CustomBox",
  552. "Fake",
  553. "Carpet",
  554. "Floor",
  555. "Tiles",
  556. "CustomFloor",
  557. "Web",
  558. "ThickWeb",
  559. "StillWater",
  560. "NWater",
  561. "SWater",
  562. "EWater",
  563. "WWater",
  564. "Ice",
  565. "Lava",
  566. "Chest",
  567. "Gem",
  568. "MagicGem",
  569. "Health",
  570. "Ring",
  571. "Potion",
  572. "Energizer",
  573. "Goop",
  574. "Ammo",
  575. "Bomb",
  576. "LitBomb",
  577. "Explosion",
  578. "Key",
  579. "Lock",
  580. "Door",
  581. "OpenDoor",
  582. "Stairs",
  583. "Cave",
  584. "CWRotate",
  585. "CCWRotate",
  586. "Gate",
  587. "OpenGate",
  588. "Transport",
  589. "Coin",
  590. "NMovingWall",
  591. "SMovingWall",
  592. "EMovingWall",
  593. "WMovingWall",
  594. "Pouch",
  595. "Pusher",
  596. "SliderNS",
  597. "SliderEW",
  598. "Lazer",
  599. "LazerGun",
  600. "Bullet",
  601. "Missile",
  602. "Fire",
  603. "[unknown]",
  604. "Forest",
  605. "Life",
  606. "Whirlpool",
  607. "Whirlpool2",
  608. "Whirlpool3",
  609. "Whirlpool4",
  610. "InvisWall",
  611. "RicochetPanel",
  612. "Ricochet",
  613. "Mine",
  614. "Spike",
  615. "CustomHurt",
  616. "Text",
  617. "ShootingFire",
  618. "Seeker",
  619. "Snake",
  620. "Eye",
  621. "Thief",
  622. "Slimeblob",
  623. "Runner",
  624. "Ghost",
  625. "Dragon",
  626. "Fish",
  627. "Shark",
  628. "Spider",
  629. "Goblin",
  630. "SpittingTiger",
  631. "BulletGun",
  632. "SpinningGun",
  633. "Bear",
  634. "BearCub",
  635. "[unknown]",
  636. "MissileGun",
  637. "Sprite",
  638. "Sprite_colliding",
  639. "Image_file",
  640. "__unused",
  641. "__unused",
  642. "__unused",
  643. "__unused",
  644. "__unused",
  645. "__unused",
  646. "__unused",
  647. "__unused",
  648. "__unused",
  649. "__unused",
  650. "__unused",
  651. "__unused",
  652. "__unused",
  653. "__unused",
  654. "__unused",
  655. "__unused",
  656. "__unused",
  657. "__unused",
  658. "__unused",
  659. "__unused",
  660. "__unused",
  661. "Sensor",
  662. "PushableRobot",
  663. "Robot",
  664. "Sign",
  665. "Scroll",
  666. "Player"
  667. };
  668. char *command_fragments[68] =
  669. {
  670. "not",
  671. "any",
  672. "player",
  673. "ns",
  674. "ew",
  675. "attack",
  676. "item",
  677. "self",
  678. "random",
  679. "string",
  680. "char",
  681. "all",
  682. "edit",
  683. "pushable",
  684. "nonpushable",
  685. "lavawalker",
  686. "nonlavawalker",
  687. "row",
  688. "counters",
  689. "id",
  690. "mod",
  691. "order",
  692. "thick",
  693. "arrow",
  694. "thin",
  695. "maxhealth",
  696. "position",
  697. "mesg",
  698. "column",
  699. "color",
  700. "size",
  701. "bulletn",
  702. "bullets",
  703. "bullete",
  704. "bulletw",
  705. "bulletcolor",
  706. "first",
  707. "last",
  708. "fade",
  709. "out",
  710. "in",
  711. "block",
  712. "sfx",
  713. "intensity",
  714. "set",
  715. "palette",
  716. "world",
  717. "alignedrobot",
  718. "go",
  719. "saving",
  720. "sensoronly",
  721. "on",
  722. "static",
  723. "transparent",
  724. "overlay",
  725. "start",
  726. "loop",
  727. "edge",
  728. "sam",
  729. "play",
  730. "percent",
  731. "high",
  732. "matches",
  733. "none",
  734. "input",
  735. "dir",
  736. "counter",
  737. "duplicate"
  738. };
  739. char *ignore_list[21] =
  740. {
  741. ",", ";", "a", "an", "and", "as", "at", "by", "else", "for", "from",
  742. "into", "is", "of", "the", "then", "there", "through", "thru", "to", "with"
  743. };
  744. int parse_argument(char *cmd_line, char **next, int *arg_translated, int *error)
  745. {
  746. int i;
  747. char *tmp_next;
  748. char current = *cmd_line;
  749. *error = 0;
  750. // If the first character is a quote it'll be a string; make sure it can find the end though.
  751. if(current == '\"')
  752. {
  753. do
  754. {
  755. cmd_line++;
  756. current = *cmd_line;
  757. } while (current != '\"');
  758. *arg_translated = 0;
  759. *next = cmd_line + 1;
  760. return STRING;
  761. }
  762. // If the first character is a negative sign or a numerical constant, it's an immediate
  763. // number. I can't figure out the difference between IMM_U16 and IMM_S16 to Robotic so
  764. // I'm giving IMM_U16 for now.
  765. if((current == '-') || isdigit(current))
  766. {
  767. *arg_translated = strtol(cmd_line, next, 10);
  768. return IMM_U16;
  769. }
  770. // If the first letter is a single quote then it's a character; make sure there's only
  771. // one constant there and a close quote.
  772. if(current == '\'')
  773. {
  774. if(cmd_line[2] != '\'')
  775. {
  776. *error = ERR_BADCHARACTER;
  777. return -1;
  778. }
  779. *arg_translated = (int)(cmd_line[1]);
  780. *next = cmd_line + 3;
  781. return CHARACTER;
  782. }
  783. // Is it a color?
  784. if(is_color(cmd_line))
  785. {
  786. *arg_translated = (int)get_color(cmd_line);
  787. *next = cmd_line + 3;
  788. return COLOR;
  789. }
  790. // Is it a parameter?
  791. if(is_param(cmd_line))
  792. {
  793. *arg_translated = (int)get_param(cmd_line);
  794. *next = cmd_line + 3;
  795. return PARAM;
  796. }
  797. // Is it a condition?
  798. i = is_condition(cmd_line, &tmp_next);
  799. if(i != -1)
  800. {
  801. *arg_translated = i;
  802. *next = tmp_next;
  803. return CONDITION;
  804. }
  805. // Is it an item?
  806. i = is_item(cmd_line, &tmp_next);
  807. if(i != -1)
  808. {
  809. *arg_translated = i;
  810. *next = tmp_next;
  811. return ITEM;
  812. }
  813. // Is it a direction?
  814. i = is_dir(cmd_line, &tmp_next);
  815. if(i != -1)
  816. {
  817. *arg_translated = i;
  818. *next = tmp_next;
  819. return DIR;
  820. }
  821. // Is it a command fragment?
  822. i = is_command_fragment(cmd_line, &tmp_next);
  823. if(i != -1)
  824. {
  825. if(i == (CMD_PLAYER))
  826. {
  827. *arg_translated = 127;
  828. }
  829. else
  830. {
  831. *arg_translated = i;
  832. }
  833. *next = tmp_next;
  834. return CMD | i;
  835. }
  836. // Is it a thing?
  837. i = is_thing(cmd_line, &tmp_next);
  838. if(i != -1)
  839. {
  840. *arg_translated = i;
  841. *next = tmp_next;
  842. return THING;
  843. }
  844. // Is it an equality?
  845. i = is_equality(cmd_line, &tmp_next);
  846. if(i != -1)
  847. {
  848. *arg_translated = i;
  849. *next = tmp_next;
  850. return EQUALITY;
  851. }
  852. // It may be an extra; ignore it then
  853. i = is_extra(cmd_line, &tmp_next);
  854. if(i != -1)
  855. {
  856. *arg_translated = i;
  857. *next = tmp_next;
  858. return EXTRA;
  859. }
  860. // It's invalid.
  861. *error = ERR_INVALID;
  862. return -1;
  863. }
  864. int is_color(char *cmd_line)
  865. {
  866. if( (cmd_line[0] == 'c') &&
  867. ( (isxdigit(cmd_line[1]) && (cmd_line[2] == '?')) ||
  868. (isxdigit(cmd_line[2]) && (cmd_line[1] == '?')) ||
  869. (isxdigit(cmd_line[1]) && isxdigit(cmd_line[2])) ||
  870. ((cmd_line[1] == '?') && (cmd_line[2] == '?')) ) )
  871. {
  872. return 1;
  873. }
  874. else
  875. {
  876. return 0;
  877. }
  878. }
  879. int get_color(char *cmd_line)
  880. {
  881. if(cmd_line[1] == '?')
  882. {
  883. if(cmd_line[2] == '?')
  884. {
  885. return 288;
  886. }
  887. else
  888. {
  889. return strtol(cmd_line + 2, NULL, 16) + 256;
  890. }
  891. }
  892. if(cmd_line[2] == '?')
  893. {
  894. char temp[2];
  895. temp[0] = cmd_line[1];
  896. temp[1] = 0;
  897. return (strtol(temp, NULL, 16) + 256 + 16);
  898. }
  899. return strtol(cmd_line + 1, NULL, 16);
  900. }
  901. int is_param(char *cmd_line)
  902. {
  903. if( (cmd_line[0] == 'p') &&
  904. ( (isxdigit(cmd_line[1]) && isxdigit(cmd_line[2])) ||
  905. ((cmd_line[1] == '?') && (cmd_line[2] == '?')) ) )
  906. {
  907. return 1;
  908. }
  909. else
  910. {
  911. return 0;
  912. }
  913. }
  914. int get_param(char *cmd_line)
  915. {
  916. if((cmd_line[1] == '?') && (cmd_line[2] == '?'))
  917. {
  918. return 256;
  919. }
  920. return strtol(cmd_line + 1, NULL, 16);
  921. }
  922. int is_equality(char *cmd_line, char **next)
  923. {
  924. char temp[256];
  925. int i = 0;
  926. get_word(temp, cmd_line, ' ');
  927. for(i = 0; i < 6; i++)
  928. {
  929. if(!strcasecmp(temp, equality_types1[i]))
  930. {
  931. *next = cmd_line + strlen(temp);
  932. return i;
  933. }
  934. }
  935. for(i = 0; i < 6; i++)
  936. {
  937. if(!strcasecmp(temp, equality_types2[i]))
  938. {
  939. *next = cmd_line + strlen(temp);
  940. return i;
  941. }
  942. }
  943. for(i = 0; i < 6; i++)
  944. {
  945. if(!strcasecmp(temp, equality_types3[i]))
  946. {
  947. *next = cmd_line + strlen(temp);
  948. return i;
  949. }
  950. }
  951. return -1;
  952. }
  953. int is_dir(char *cmd_line, char **next)
  954. {
  955. char temp[256];
  956. int i = 0;
  957. get_word(temp, cmd_line, ' ');
  958. for(i = 0; i < 20; i++)
  959. {
  960. if(!strcasecmp(temp, dir_types1[i]))
  961. {
  962. *next = cmd_line + strlen(temp);
  963. return i;
  964. }
  965. }
  966. for(i = 0; i < 20; i++)
  967. {
  968. if(!strcasecmp(temp, dir_types2[i]))
  969. {
  970. *next = cmd_line + strlen(temp);
  971. return i;
  972. }
  973. }
  974. for(i = 0; i < 20; i++)
  975. {
  976. if(!strcasecmp(temp, dir_types3[i]))
  977. {
  978. *next = cmd_line + strlen(temp);
  979. return i;
  980. }
  981. }
  982. return -1;
  983. }
  984. int is_condition(char *cmd_line, char **next)
  985. {
  986. char temp[256];
  987. int i = 0;
  988. get_word(temp, cmd_line, ' ');
  989. for(i = 0; i < 18; i++)
  990. {
  991. if(!strcasecmp(temp, condition_types[i]))
  992. {
  993. *next = cmd_line + strlen(temp);
  994. return i;
  995. }
  996. }
  997. return -1;
  998. }
  999. int is_item(char *cmd_line, char **next)
  1000. {
  1001. char temp[256];
  1002. int i = 0;
  1003. get_word(temp, cmd_line, ' ');
  1004. for(i = 0; i < 9; i++)
  1005. {
  1006. if(!strcasecmp(temp, item_types[i]))
  1007. {
  1008. *next = cmd_line + strlen(temp);
  1009. return i;
  1010. }
  1011. }
  1012. return -1;
  1013. }
  1014. int is_thing(char *cmd_line, char **next)
  1015. {
  1016. char temp[256];
  1017. int i = 0;
  1018. get_word(temp, cmd_line, ' ');
  1019. // It shouldn't actually check thing #127, the player.
  1020. for(i = 0; i < 127; i++)
  1021. {
  1022. if(!strcasecmp(temp, thing_types[i]))
  1023. {
  1024. *next = cmd_line + strlen(temp);
  1025. return i;
  1026. }
  1027. }
  1028. return -1;
  1029. }
  1030. int is_command_fragment(char *cmd_line, char **next)
  1031. {
  1032. char temp[256];
  1033. int i;
  1034. get_word(temp, cmd_line, ' ');
  1035. for(i = 0; i < 68; i++)
  1036. {
  1037. if(!strcasecmp(temp, command_fragments[i]))
  1038. {
  1039. *next = cmd_line + strlen(temp);
  1040. return i;
  1041. }
  1042. }
  1043. return -1;
  1044. }
  1045. int is_extra(char *cmd_line, char **next)
  1046. {
  1047. char temp[256];
  1048. int i;
  1049. get_word(temp, cmd_line, ' ');
  1050. for(i = 0; i < 21; i++)
  1051. {
  1052. if(!strcasecmp(temp, ignore_list[i]))
  1053. {
  1054. *next = cmd_line + strlen(temp);
  1055. return i;
  1056. }
  1057. }
  1058. return -1;
  1059. }
  1060. void get_word(char *str, char *source, char t)
  1061. {
  1062. int i = 0;
  1063. char current = *source;
  1064. do
  1065. {
  1066. str[i] = current;
  1067. source++;
  1068. current = *source;
  1069. i++;
  1070. } while((current != t) && (current != 0) && (i < 256));
  1071. str[i] = 0;
  1072. }
  1073. int match_command(mzx_command *cmd)
  1074. {
  1075. int i, i2;
  1076. for(i = 0; i < 256; i++)
  1077. {
  1078. if(strcasecmp(cmd->name, command_list[i].name))
  1079. {
  1080. continue;
  1081. }
  1082. if(cmd->parameters != command_list[i].parameters)
  1083. {
  1084. continue;
  1085. }
  1086. for(i2 = 0; i2 < cmd->parameters; i2++)
  1087. {
  1088. if(command_list[i].param_types[i2] & CMD)
  1089. {
  1090. if(cmd->param_types[i2] != command_list[i].param_types[i2])
  1091. {
  1092. break;
  1093. }
  1094. }
  1095. else
  1096. {
  1097. if((cmd->param_types[i2] & command_list[i].param_types[i2]) !=
  1098. cmd->param_types[i2])
  1099. {
  1100. break;
  1101. }
  1102. }
  1103. }
  1104. if(i2 == cmd->parameters) break;
  1105. }
  1106. return i;
  1107. }
  1108. int assemble_text(char *input_name, char *output_name)
  1109. {
  1110. FILE *input_file, *output_file;
  1111. char current_line[256];
  1112. char *current_line_position;
  1113. char *next_line_position;
  1114. char object_file[65536];
  1115. char *object_file_position = object_file + 1;
  1116. char *next_object_file_position;
  1117. int line_number = 1;
  1118. int bytes_assembled = 1;
  1119. int translated_command = 0;
  1120. mzx_command current_command;
  1121. char name[256];
  1122. char temp[256];
  1123. void *param_list[32];
  1124. int i;
  1125. int current_arg_type;
  1126. int current_arg_translation;
  1127. int last_arg_type;
  1128. int last_arg_translation;
  1129. int arg_count;
  1130. int error = 0;
  1131. int bytes_used;
  1132. int advance;
  1133. object_file[0] = -1;
  1134. input_file = fopen(input_name, "rb");
  1135. if(input_file == NULL)
  1136. {
  1137. printf("Failed to open %s.\n", input_name);
  1138. return -1;
  1139. }
  1140. printf("Opening source file %s\n", input_name);
  1141. while(1)
  1142. {
  1143. current_command.name = (char *)malloc(32);
  1144. current_command.param_types = (int *)malloc(32 * 4);
  1145. if(get_line(current_line, input_file) == -1)
  1146. {
  1147. *object_file_position = 0;
  1148. break;
  1149. }
  1150. arg_count = 0;
  1151. if(current_line[0] == 0)
  1152. {
  1153. translated_command = 47;
  1154. strcpy(current_command.name, command_list[47].name);
  1155. current_command.parameters = 0;
  1156. last_arg_type = current_arg_type;
  1157. last_arg_translation = current_arg_translation;
  1158. arg_count++;
  1159. }
  1160. else
  1161. {
  1162. current_line_position = current_line;
  1163. get_word(name, current_line_position, ' ');
  1164. strcpy(current_command.name, name);
  1165. current_line_position += strlen(name);
  1166. last_arg_type = 0;
  1167. while(*current_line_position != 0)
  1168. {
  1169. skip_whitespace(current_line_position, &current_line_position);
  1170. current_arg_type = parse_argument(current_line_position, &next_line_position,
  1171. &current_arg_translation, &error);
  1172. current_command.param_types[arg_count] = current_arg_type;
  1173. if(error == ERR_BADSTRING)
  1174. {
  1175. printf("%d: Unterminated string.\n", line_number);
  1176. return -1;
  1177. }
  1178. if(error == ERR_BADCHARACTER)
  1179. {
  1180. printf("%d: Unterminated char constant.\n", line_number);
  1181. return -1;
  1182. }
  1183. if(error == ERR_INVALID)
  1184. {
  1185. get_word(temp, current_line_position, ' ');
  1186. printf("%d: Invalid argument '%s'\n", line_number, temp);
  1187. return -1;
  1188. }
  1189. if(current_arg_type != EXTRA)
  1190. {
  1191. if(current_arg_type == STRING)
  1192. {
  1193. // Grab the string off the command list.
  1194. int str_size;
  1195. get_word(temp, current_line_position + 1, '\"');
  1196. str_size = strlen(temp);
  1197. param_list[arg_count] = (void *)malloc(str_size + 1);
  1198. strcpy((char *)param_list[arg_count], temp);
  1199. }
  1200. else
  1201. {
  1202. // Store the translation into the command list.
  1203. param_list[arg_count] = (void *)malloc(2);
  1204. *((short *)param_list[arg_count]) = current_arg_translation;
  1205. }
  1206. advance = 1;
  1207. if((arg_count > 0) && (current_arg_type == DIR))
  1208. {
  1209. if((last_arg_type == CONDITION) &&
  1210. ((last_arg_translation == 0) || (last_arg_translation == 3) ||
  1211. (last_arg_translation == 4)))
  1212. {
  1213. *((short *)param_list[arg_count - 1])
  1214. |= (current_arg_translation << 8);
  1215. advance = 0;
  1216. }
  1217. if((last_arg_type == DIR) && (last_arg_translation >= 16))
  1218. {
  1219. *((short *)param_list[arg_count - 1])
  1220. += (1 << (last_arg_translation - 12));
  1221. advance = 0;
  1222. }
  1223. }
  1224. if(advance)
  1225. {
  1226. last_arg_type = current_arg_type;
  1227. last_arg_translation = current_arg_translation;
  1228. arg_count++;
  1229. }
  1230. if(arg_count == 32)
  1231. {
  1232. printf("%d: Too many arguments to parse.\n", line_number);
  1233. return -1;
  1234. }
  1235. }
  1236. current_line_position = next_line_position;
  1237. }
  1238. current_command.parameters = arg_count;
  1239. translated_command = match_command(&current_command);
  1240. if(translated_command == 256)
  1241. {
  1242. printf("%d: Line '%s':\n", line_number, current_line);
  1243. printf("%d: Command does not exist: ", line_number);
  1244. print_command(&current_command);
  1245. return -1;
  1246. }
  1247. for(i = 0; i < arg_count; i++)
  1248. {
  1249. free(param_list[i]);
  1250. }
  1251. line_number++;
  1252. }
  1253. bytes_used =
  1254. assemble_command(translated_command, &current_command, param_list,
  1255. object_file_position, &next_object_file_position);
  1256. printf("%d bytes: ", bytes_used);
  1257. print_command(&current_command);
  1258. bytes_assembled += bytes_used;
  1259. if(bytes_assembled >= MAX_OBJ_SIZE)
  1260. {
  1261. printf("%d: Maximum robot size exceeded.\n", line_number);
  1262. return -1;
  1263. }
  1264. object_file_position = next_object_file_position;
  1265. }
  1266. fclose(input_file);
  1267. *object_file_position = 0;
  1268. bytes_assembled++;
  1269. output_file = fopen(output_name, "wb");
  1270. fwrite(object_file, 1, bytes_assembled, output_file);
  1271. printf("Assembled object file: %s, %d bytes\n", output_name, bytes_assembled);
  1272. fclose(output_file);
  1273. return 0;
  1274. }
  1275. void print_command(mzx_command *cmd)
  1276. {
  1277. int i;
  1278. printf("%s ", cmd->name);
  1279. for(i = 0; i < cmd->parameters; i++)
  1280. {
  1281. switch(cmd->param_types[i])
  1282. {
  1283. case IMM_U16:
  1284. {
  1285. printf("[##] ");
  1286. break;
  1287. }
  1288. case STRING:
  1289. {
  1290. printf("[str] ");
  1291. break;
  1292. }
  1293. case COLOR:
  1294. {
  1295. printf("[col] ");
  1296. break;
  1297. }
  1298. case PARAM:
  1299. {
  1300. printf("[par] ");
  1301. break;
  1302. }
  1303. case CHARACTER:
  1304. {
  1305. printf("[chr] ");
  1306. break;
  1307. }
  1308. case CONDITION:
  1309. {
  1310. printf("[cond] ");
  1311. break;
  1312. }
  1313. case EQUALITY:
  1314. {
  1315. printf("[!<>=] ");
  1316. break;
  1317. }
  1318. case DIR:
  1319. {
  1320. printf("[dir] ");
  1321. break;
  1322. }
  1323. case ITEM:
  1324. {
  1325. printf("[dir] ");
  1326. break;
  1327. }
  1328. case THING:
  1329. {
  1330. printf("[thing] ");
  1331. break;
  1332. }
  1333. default:
  1334. {
  1335. if(cmd->param_types[i] & CMD)
  1336. {
  1337. printf("%s ", command_fragments[cmd->param_types[i] & ~CMD]);
  1338. }
  1339. else
  1340. {
  1341. printf("[unknown] ");
  1342. break;
  1343. }
  1344. }
  1345. }
  1346. }
  1347. printf("\n");
  1348. }
  1349. int assemble_command(int command_number, mzx_command *cmd, void *params[32],
  1350. char *obj_pos, char **next_obj_pos)
  1351. {
  1352. int i;
  1353. int size;
  1354. char *c_obj_pos = obj_pos + 2;
  1355. obj_pos[1] = (char)command_number;
  1356. for(i = 0; i < cmd->parameters; i++)
  1357. {
  1358. if(cmd->param_types[i] == STRING)
  1359. {
  1360. int str_size = strlen((char *)params[i]);
  1361. *(c_obj_pos) = str_size + 1;
  1362. strcpy(c_obj_pos + 1, (char *)params[i]);
  1363. c_obj_pos += str_size + 2;
  1364. }
  1365. else
  1366. {
  1367. if(!(cmd->param_types[i] & CMD))
  1368. {
  1369. // It's not a command fragment
  1370. *c_obj_pos = 0;
  1371. *((short int *)(obj_pos + 1)) = *((short *)params[i]);
  1372. c_obj_pos += 3;
  1373. }
  1374. }
  1375. }
  1376. size = c_obj_pos - obj_pos - 1;
  1377. *obj_pos = size;
  1378. *c_obj_pos = size;
  1379. *next_obj_pos = c_obj_pos;
  1380. return size + 2;
  1381. }
  1382. int get_line(char *buffer, FILE *fp)
  1383. {
  1384. int current;
  1385. int escape_1 = 0;
  1386. int i;
  1387. // Should ignore \0, \n, and \r while in ' or "
  1388. for(i = 0; i < 256; i++)
  1389. {
  1390. current = fgetc(fp);
  1391. if(current == -1)
  1392. {
  1393. return -1;
  1394. }
  1395. if(current == '\"')
  1396. {
  1397. if(escape_1 == 0)
  1398. {
  1399. escape_1 = 1;
  1400. }
  1401. else
  1402. {
  1403. escape_1 = 0;
  1404. }
  1405. }
  1406. if(!escape_1)
  1407. {
  1408. if(current == '\r')
  1409. {
  1410. fgetc(fp);
  1411. buffer[i] = 0;
  1412. return 0;
  1413. }
  1414. if(current == '\n')
  1415. {
  1416. buffer[i] = 0;
  1417. return 0;
  1418. }
  1419. }
  1420. buffer[i] = current;
  1421. }
  1422. buffer[255] = 0;
  1423. return -2;
  1424. }
  1425. void skip_whitespace(char *cpos, char **next)
  1426. {
  1427. while(*cpos == ' ')
  1428. {
  1429. cpos++;
  1430. }
  1431. *next = cpos;
  1432. }
  1433. int main(int argc, char *argv[])
  1434. {
  1435. if(argc != 3)
  1436. {
  1437. printf("Usage: <robotic code> <object file>\n");
  1438. return -1;
  1439. }
  1440. if(assemble_text(argv[1], argv[2]) == -1)
  1441. {
  1442. printf("Fatal error; aborting.\n");
  1443. return -1;
  1444. }
  1445. return 0;
  1446. }