Mercurial > otakunoraifu
annotate scn2k/scn2k_cmd.cc @ 57:6d9146f56ccf
* Move some opcodes
* Merge last changes from xclannad
author | Thibaut GIRKA <thib@sitedethib.com> |
---|---|
date | Sat, 14 Nov 2009 23:31:51 +0100 |
parents | d7cde171a1de |
children | 3b1593186f12 |
rev | line source |
---|---|
0 | 1 /* |
2 * Copyright (c) 2004-2006 Kazunori "jagarl" Ueno | |
3 * All rights reserved. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions | |
7 * are met: | |
8 * 1. Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright | |
11 * notice, this list of conditions and the following disclaimer in the | |
12 * documentation and/or other materials provided with the distribution. | |
13 * 3. The name of the author may not be used to endorse or promote products | |
14 * derived from this software without specific prior written permission. | |
15 * | |
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 */ | |
27 | |
28 | |
52 | 29 #include "scn2k.h" |
0 | 30 |
52 | 31 #include <stdlib.h> |
32 #include <stdarg.h> | |
33 #include <stdio.h> | |
34 #include <string.h> | |
35 #include <string> | |
36 #include "system/file.h" | |
0 | 37 |
38 using namespace std; | |
39 | |
40 | |
41 // #define SCN_DUMP | |
42 /* Ãí°ÕÅÀ¡§ @@@ ¤Çɽµ */ | |
43 | |
44 | |
45 | |
46 //bool debug_flag = true; | |
47 bool debug_flag = false; | |
48 void dprintf(const char* fmt, ...) { | |
49 if (debug_flag) { | |
52 | 50 va_list ap; |
51 va_start(ap, fmt); | |
0 | 52 vprintf(fmt, ap); |
53 va_end(ap); | |
54 } | |
55 } | |
56 | |
57 | |
58 void eprintf(const char* fmt, ...) { | |
59 va_list ap; va_start(ap, fmt); | |
60 // vprintf(fmt, ap); | |
61 va_end(ap); | |
62 } | |
63 | |
64 /************************************************************** | |
65 ** Flag | |
66 */ | |
67 | |
68 Flags::Flags(void) { | |
69 int i,j; | |
70 for (i=0; i<=TYPE_VARMAX; i++) { | |
71 for (j=0; j<2000; j++) { | |
72 var[i][j] = 0; | |
73 } | |
74 } | |
75 sys = 0; | |
76 } | |
77 | |
78 bool Flags::IsInt(int type) const { | |
79 int v = type % 26; | |
43
01aa5ddf7dc8
A lot of very minor improvements (deleted some unused variables, and other things like that...)
thib
parents:
29
diff
changeset
|
80 return (v >= 0 && v < 7) || v == 25; |
0 | 81 } |
82 | |
83 int Flags::MaxIndex(int type) const { | |
84 switch (type / 26) { | |
85 case 1: | |
86 return 63999; | |
87 case 2: | |
88 return 31999; | |
89 case 3: | |
90 return 15999; | |
91 case 4: | |
92 return 7999; | |
93 default: | |
94 return 1999; | |
95 } | |
96 } | |
97 | |
98 int Flags::operator()() const { | |
99 return sys; // rand() % 10000; | |
100 } | |
101 | |
102 int Flags::operator() (VarInfo info) const { | |
103 return Get(info.type, info.number); | |
104 } | |
105 | |
106 int Flags::Get(int type, int number) const { | |
107 int index = type % 26; | |
108 type /= 26; | |
109 if (index == 25) { | |
110 if (var[7][number] != 0) return var[7][number]; | |
111 if (cgm_data.find(number) == cgm_data.end()) return 0; | |
112 else return 1; | |
113 } | |
114 if (index == 10) index = 8; | |
115 if (index == 11) index = 9; | |
116 if (index > TYPE_VARMAX || uint(type) > 4) return 0; | |
117 if (type == 0) { | |
118 // A[]..G[], Z[] ¤òľ¤ËÆɤà | |
119 if (uint(number) >= 2000) return 0; | |
120 return var[index][number]; | |
121 } else { | |
122 // Ab[]..G4b[], Z8b[] ¤Ê¤É¤òÆɤà | |
123 int factor = 1 << (type - 1); | |
124 int eltsize = 32 / factor; | |
125 if (uint(number) >= (64000 / factor)) return 0; | |
126 return (var[index][number / eltsize] >> ((number % eltsize) * factor)) & ((1 << factor) - 1); | |
127 } | |
128 } | |
129 | |
130 void Flags::Set(VarInfo info, int value) { | |
131 int type = info.type / 26; | |
132 int index = info.type % 26; | |
133 if (index == 25) { | |
134 if (uint(info.number) >= 2000) return; | |
135 if (value == 0) | |
136 cgm_data.erase(info.number); | |
137 else | |
138 cgm_data.insert(info.number); | |
139 index = 7; | |
140 } | |
141 if (index == 10) index = 8; | |
142 if (index == 11) index = 9; | |
143 if (index < 0 || index > TYPE_VARMAX) { | |
144 fprintf(stderr,"Error: invalid access to Var<%d>[%d]\n",info.type,info.number); | |
145 } | |
146 if (type == 0) { | |
147 // A[]..G[], Z[] ¤òľ¤Ë½ñ¤¯ | |
148 if (uint(info.number) >= 2000) return; | |
149 var[index][info.number] = value; | |
150 } else { | |
151 // Ab[]..G4b[], Z8b[] ¤Ê¤É¤ò½ñ¤¯ | |
152 int factor = 1 << (type - 1); | |
153 int eltsize = 32 / factor; | |
154 int eltmask = (1 << factor) - 1; | |
155 int shift = (info.number % eltsize) * factor; | |
156 if (uint(info.number) >= (64000 / factor)) return; | |
157 var[index][info.number / eltsize] = | |
158 (var[index][info.number / eltsize] & ~(eltmask << shift)) | |
159 | (value & eltmask) << shift; | |
160 } | |
161 } | |
162 | |
163 void Flags::SetSys(int value) { | |
164 sys = value; | |
165 } | |
52 | 166 |
0 | 167 void Flags::SetStr(VarInfo info, string val) { |
168 switch(info.type) { | |
52 | 169 case TYPE_VARLOCSTR: |
170 if (info.number >= 3) return; | |
171 loc_str[info.number] = val; | |
172 break; | |
173 case TYPE_VARSYSSTR: | |
174 if (info.number >= 2000) return; | |
175 sys_str[info.number] = val; | |
176 break; | |
177 case TYPE_VARSTR: | |
178 if (info.number >= 2000) return; | |
179 str[info.number] = val; | |
180 break; | |
0 | 181 } |
182 return; | |
183 } | |
52 | 184 |
0 | 185 void Flags::Str(int type, unsigned int number, char* buf, int sz) const { |
186 if (sz <= 0) return; | |
187 buf[0] = 0; | |
188 const string* sptr; | |
189 switch(type) { | |
52 | 190 case TYPE_VARLOCSTR: |
191 if (number >= 3) return; | |
192 sptr = &loc_str[number]; | |
193 break; | |
194 case TYPE_VARSYSSTR: | |
195 if (number >= 2000) return; | |
196 sptr = &sys_str[number]; | |
197 break; | |
198 case TYPE_VARSTR: | |
199 if (number >= 2000) return; | |
200 sptr = &str[number]; | |
201 break; | |
0 | 202 } |
203 | |
204 int len = sptr->length(); | |
205 if (sz-1 > len) sz = len; | |
206 sptr->copy(buf, sz, 0); | |
207 buf[sz] = 0; | |
208 return; | |
209 } | |
52 | 210 |
0 | 211 string Flags::Str(int type, unsigned int number) const { |
212 switch(type) { | |
213 case TYPE_VARLOCSTR: | |
214 if (number >= 3) return ""; | |
215 return loc_str[number]; | |
216 case TYPE_VARSYSSTR: | |
217 if (number >= 2000) return ""; | |
218 return sys_str[number]; | |
219 case TYPE_VARSTR: | |
220 if (number >= 2000) return ""; | |
221 return str[number]; | |
222 } | |
223 return ""; | |
224 } | |
225 | |
226 void Flags::Save(string& save) { | |
227 char buf[1024]; | |
228 save = "\n[Flags]\n"; | |
229 int i,j; | |
230 for (i=0; i<=TYPE_NONSYSVARMAX; i++) { | |
231 for (j=0; j<2000; j++) { | |
232 if (var[i][j] != 0) { | |
233 sprintf(buf, "V<%d>[%04d]=%d\n",i,j,var[i][j]); | |
234 save += buf; | |
235 } | |
236 } | |
237 } | |
238 for (j=0; j<2000; j++) { | |
239 if (str[j].length() != 0) { | |
240 sprintf(buf, "V<C>[%04d]=%s\n", j, str[j].c_str()); | |
241 save += buf; | |
242 } | |
243 } | |
244 } | |
52 | 245 |
0 | 246 void Flags::Load(const char* save) { |
247 int i,j; | |
248 for (i=0; i<=TYPE_NONSYSVARMAX; i++) { | |
249 for (j=0; j<2000; j++) { | |
250 var[i][j] = 0; | |
251 } | |
252 } | |
253 sys = 0; | |
254 for (j=0; j<2000; j++) { | |
255 str[j] = ""; | |
256 } | |
257 | |
258 save = strstr(save, "\n[Flags]\n"); | |
259 | |
260 if (save) { | |
261 save += strlen("\n[Flags]\n"); | |
262 do { | |
263 if (save[0] == '[') break; // next section | |
264 if (strncmp(save, "V<",2) == 0) { | |
265 if (strncmp(save, "V<C>[",5) == 0) { // string | |
266 char buf[1024]; | |
267 int n; | |
268 if (sscanf(save, "V<C>[%04d]=",&n) == 1) { | |
269 char* s = strchr(save, '='); | |
270 s++; | |
271 char* send = strchr(s, '\n'); | |
272 int slen = send - s; | |
273 strncpy(buf, s, slen); | |
274 buf[slen] = 0; | |
275 if (n >= 0 && n < 2000) str[n] = buf; | |
276 } | |
277 } else if (save[2] >= '0' && save[2] <= '9') { | |
278 int c,n,v; | |
279 if (sscanf(save, "V<%d>[%04d]=%d\n",&c,&n,&v) == 3) { | |
280 if (c >= 0 && c <= TYPE_NONSYSVARMAX && n >= 0 && n < 2000) | |
281 var[c][n] = v; | |
282 } | |
283 } | |
284 } | |
285 save = strchr(save, '\n'); | |
286 if (save) save++; | |
287 } while (save); | |
288 } | |
289 } | |
290 | |
52 | 291 void Flags::SaveSys(string& save) { //FIXME: see how to factorize with Save |
0 | 292 char buf[1024]; |
293 int j; | |
294 save = "\n[Flags]\n"; | |
295 for (j=0; j<2000; j++) { | |
296 if (var[6][j] != 0) { | |
297 sprintf(buf, "V<6>[%04d]=%d\n",j,var[6][j]); | |
298 save += buf; | |
299 } | |
300 } | |
301 for (j=0; j<2000; j++) { | |
302 if (var[7][j] != 0) { | |
303 sprintf(buf, "V<25>[%04d]=%d\n",j,var[7][j]); | |
304 save += buf; | |
305 } | |
306 } | |
307 for (j=0; j<2000; j++) { | |
308 if (sys_str[j].length() != 0) { | |
309 sprintf(buf, "V<M>[%04d]=%s\n", j, sys_str[j].c_str()); | |
310 save += buf; | |
311 } | |
312 } | |
313 } | |
52 | 314 |
315 void Flags::LoadSys(const char* save) { //FIXME: Same as Save and SaveSys | |
0 | 316 int i,j; |
317 for (i=6; i<=7; i++) { | |
318 for (j=0; j<2000; j++) { | |
319 var[i][j] = 0; | |
320 } | |
321 } | |
322 for (j=0; j<2000; j++) { | |
323 sys_str[j] = ""; | |
324 } | |
325 sys = 0; | |
326 | |
327 save = strstr(save, "\n[Flags]\n"); | |
328 | |
329 if (save) { | |
330 save += strlen("\n[Flags]\n"); | |
331 do { | |
332 if (save[0] == '[') break; // next section | |
333 if (strncmp(save, "V<",2) == 0) { | |
334 if (strncmp(save, "V<M>[",5) == 0) { // string | |
335 char buf[1024]; | |
336 int n; | |
337 if (sscanf(save, "V<M>[%04d]=",&n) == 1) { | |
338 char* s = strchr(save, '='); | |
339 s++; | |
340 char* send = strchr(s, '\n'); | |
341 int slen = send - s; | |
342 strncpy(buf, s, slen); | |
343 buf[slen] = 0; | |
344 if (n >= 0 && n < 2000) sys_str[n] = buf; | |
345 } | |
346 } else if (save[2] >= '0' && save[2] <= '9') { | |
347 int c,n,v; | |
348 if (sscanf(save, "V<%d>[%04d]=%d\n",&c,&n,&v) == 3) { | |
349 if (c == 6 && n >= 0 && n < 2000) | |
350 var[6][n] = v; | |
351 else if (c == 25 && n >= 0 && n < 2000) | |
352 var[7][n] = v; | |
353 } | |
354 } | |
355 } | |
356 save = strchr(save, '\n'); | |
357 if (save) save++; | |
358 } while (save); | |
359 } | |
360 } | |
361 | |
362 bool Flags::Exec(Cmd& cmd) { | |
363 if (cmd.cmd_type == CMD_FLAGS) { // ÂåÆþ±é»» | |
364 if (cmd.args.size() != 2) return false; | |
365 Set(cmd.args[0], cmd.args[1].value); | |
366 cmd.clear(); | |
367 return true; | |
368 } | |
369 if (cmd.cmd1 == 1 && cmd.cmd2 == 0x0a) { // ʸ»úÎó±é»» | |
370 VarInfo arg1 = cmd.args[0]; | |
371 switch(cmd.cmd3) { | |
52 | 372 case 0: |
373 if (cmd.cmd4 == 0) { | |
374 SetStr(arg1, cmd.Str(cmd.args[1])); | |
375 } else if (cmd.cmd4 == 1) { | |
376 string s = cmd.Str(cmd.args[1]); | |
377 const char* sc = s.c_str(); | |
378 int len = cmd.args[2].value; | |
379 int i; | |
380 for (i=0; i < sc[i] && len != 0; i++, len--) { | |
381 if (sc[i]<0 && sc[i+1]!=0) i++; | |
382 } | |
383 s.erase(i); // Á´³Ñ¤Ç len ʸ»ú¤Þ¤ÇÀÚ¤êµÍ¤á¤ë | |
384 SetStr(arg1, s); | |
385 // fprintf(stderr,"Set[%d,%d]<-%s\n",arg1.type,arg1.number,s.c_str()); | |
386 } else break; | |
387 cmd.clear(); | |
388 break; | |
389 case 1: | |
390 if (cmd.cmd4 == 0) { | |
391 SetStr(arg1, ""); | |
392 cmd.clear(); | |
393 } else if (cmd.cmd4 == 1) { | |
394 // Îΰè»ØÄê¤Çʸ»úÎ󥯥ꥢ | |
395 VarInfo v1 = cmd.args[0]; | |
396 VarInfo v2 = cmd.args[1]; | |
397 eprintf("memclear(str). Var[%d]<%d> - Var[%d]<%d>\n",v1.type, v1.number, v2.type, v2.number); | |
398 if (v1.type != v2.type || (v1.type != TYPE_VARSTR && v1.type != TYPE_VARSYSSTR && v1.type != TYPE_VARLOCSTR)) { | |
399 eprintf(" error: bad args\n"); | |
400 } else { | |
401 if (v1.number < 0) v1.number = 0; | |
402 if (v2.number > 2000) v2.number = 2000; | |
403 for (; v1.number <= v2.number; v1.number++) { | |
404 SetStr(v1, ""); | |
405 } | |
406 } | |
407 cmd.clear(); | |
0 | 408 } |
52 | 409 case 2: |
410 SetStr(arg1, Str(arg1.type,arg1.number) + cmd.Str(cmd.args[1])); | |
411 // fprintf(stderr,"Append[%d,%d]<-%s(%d:%d)\n",arg1.type,arg1.number,Str(arg1.type,arg1.number).c_str(),cmd.args[1].type,cmd.args[1].number); | |
412 cmd.clear(); | |
413 break; | |
414 case 3: | |
415 SetSys(strlen(cmd.Str(cmd.args[0]))); | |
416 cmd.clear(); | |
417 break; | |
418 case 4: | |
419 { int v = strcmp(cmd.Str(cmd.args[0]), cmd.Str(cmd.args[1])); | |
420 // string s1=cmd.Str(cmd.args[0]); | |
421 // string s2=cmd.Str(cmd.args[1]); | |
422 // fprintf(stderr,"Cmp %s(%d:%d):%s(%d:%d):%d\n",s1.c_str(),cmd.args[0].type,cmd.args[0].number,s2.c_str(),cmd.args[1].type,cmd.args[1].number,v); | |
423 if (v < 0) SetSys(-1); | |
424 else if (v > 0) SetSys(1); | |
425 else SetSys(0); | |
0 | 426 cmd.clear(); |
52 | 427 break; } |
428 case 5: // substring, index from left | |
429 case 6: // substring, index from right | |
430 // Á´³ÑÂбþ¤é¤·¤¤ | |
431 //FIXME: Make sure it works properly | |
432 { int offset = cmd.args[2].value; | |
433 int len = strlen(cmd.Str(cmd.args[1])); | |
434 string str = cmd.Str(cmd.args[1]); | |
435 const char* s = str.c_str(); | |
436 if (cmd.cmd3 == 6) offset = len - offset; | |
437 if (offset < 0) offset = 0; | |
438 // ÀèƬ N ʸ»ú¤òÆɤßÈô¤Ð¤¹ | |
439 int i; | |
440 int offset_top = 0; | |
441 for (i=0; i<offset && s[offset_top] != 0; i++) { | |
442 if (s[offset_top] < 0 && s[offset_top+1] != 0) offset_top += 2; | |
443 else offset_top += 1; | |
444 } | |
445 if (s[offset_top] == 0) { | |
446 SetStr(arg1, ""); | |
447 } else if (cmd.cmd4 == 0) { // ŤµÀ©¸Â¤Ê¤· | |
448 SetStr(arg1, string(s, offset_top, len-offset_top)); | |
449 } else { // cmd.cmd4 == 1 | |
450 int slen = cmd.args[3].value; | |
451 int offset_end = offset_top; | |
452 for (i=0; i<slen && s[offset_end] != 0; i++) { | |
453 if (s[offset_end] < 0 && s[offset_end]+1 != 0) offset_end += 2; | |
454 else offset_end += 1; | |
0 | 455 } |
52 | 456 string result(s, offset_top, offset_end-offset_top); |
457 SetStr(arg1, result); | |
0 | 458 } |
459 cmd.clear(); | |
52 | 460 break; } |
461 case 7: {// strlen w/ kanji | |
462 const char* s = cmd.Str(cmd.args[0]); int i; | |
463 for (i=0; *s != 0; i++) { | |
464 if (*s < 0 && s[1] != 0) s += 2; | |
465 else s++; | |
466 } | |
467 SetSys(i); | |
468 cmd.clear(); | |
469 break; } | |
470 case 8: // ʸ»úÎó¤òÀڤäÆû¤¯¤¹¤ë | |
471 if (cmd.args[1].value <= 0) { | |
472 SetStr(arg1, ""); | |
473 } else if (cmd.args[1].value < strlen(cmd.Str(cmd.args[1]))) { | |
474 Str(arg1.type,arg1.number).erase(cmd.args[1].value); | |
475 } | |
476 cmd.clear(); | |
477 break; | |
478 case 0x0e: // ´Á»ú¥â¡¼¥É¤Çitoa | |
479 { | |
480 int arg1 = cmd.args[0].value; | |
481 string result; | |
482 char wc[3]; wc[2]=0; | |
483 char buf[20]; | |
484 if (cmd.cmd4 == 0) { | |
485 sprintf(buf, "%d", arg1); | |
486 } else { // cmd.cmd4 == 1 | |
487 char fmt[20]; | |
488 sprintf(fmt, "%%%dd", cmd.args[2].value); | |
489 sprintf(buf, fmt, arg1); | |
0 | 490 } |
52 | 491 int i; |
492 for (i=0; buf[i] != 0; i++) { | |
493 if (buf[i] == ' ') { | |
494 wc[0] = 0x81; // ' ' in SHIFT_JIS | |
495 wc[1] = 0x40; | |
496 } else if (buf[i] == '-') { | |
497 wc[0] = 0x81; // '-' in SHIFT_JIS | |
498 wc[1] = 0x7c; | |
499 } else if (isdigit(buf[i])) { | |
500 wc[0] = 0x82; // number in SHIFT_JIS | |
501 wc[1] = buf[i] - '0' + 0x4f; | |
502 } else { | |
503 continue; | |
504 } | |
505 result += wc; | |
0 | 506 } |
52 | 507 SetStr(cmd.args[1], result); |
0 | 508 cmd.clear(); |
509 } | |
52 | 510 break; |
511 case 0x0f: case 0x11: // itoa (0x11 ¤ÎÊý¤Ï zero padding ¤¹¤ë¤Ã¤Ý¤¤) | |
512 if (cmd.cmd4 == 0) { | |
513 int arg1 = cmd.args[0].value; | |
514 char buf[1024]; sprintf(buf, "%d", arg1); | |
515 SetStr(cmd.args[1], buf); | |
516 cmd.clear(); | |
517 } else if (cmd.cmd4 == 1) { | |
518 // ´Á»ú(SJIS) : 82 [4f+N] | |
519 // ¤ä¤Ï¤ê´Á»ú¤¸¤ã¤Ê¤¤¡© | |
520 int arg1 = cmd.args[0].value; | |
521 char buf[1024]; char fmt[1024]; | |
522 if (cmd.cmd3 == 0x0f) { | |
523 sprintf(fmt, "%%%dd",cmd.args[2].value); /* ¶õÇò¤Ç¥Ñ¥Ç¥£¥ó¥° */ | |
524 } else { | |
525 sprintf(fmt, "%%0%dd",cmd.args[2].value); | |
526 } | |
527 sprintf(buf, fmt, arg1); | |
528 SetStr(cmd.args[1], buf); | |
529 cmd.clear(); | |
530 } | |
531 break; | |
532 case 0x64: // ʸ»úÎó¤Îɽ¼¨ : °ú¿ô¤ò¥Æ¥¥¹¥È¥¦¥£¥ó¥É¥¦¤Ëɽ¼¨ | |
533 if (cmd.cmd4 == 1) { | |
534 char buf[256]; | |
535 snprintf(buf, 255, "%d", Get(cmd.args[0].type, cmd.args[0].number)); | |
536 cmd.args[0].type = TYPE_STR; | |
537 cmd.args[0].value = cmd.AddStr(buf); | |
538 cmd.cmd4 = 0; | |
539 } | |
540 cmd.cmd_type = CMD_TEXT; | |
541 break; | |
0 | 542 } |
543 } | |
544 if (cmd.cmd1 == 1 && cmd.cmd2 == 0x0b) { // ¿ôÃÍÊÑ¿ô±é»» | |
545 if (cmd.cmd3 == 0 && cmd.cmd4 == 0) { | |
546 /* Ê£¿ô¤ÎÊÑ¿ô¤ò¥»¥Ã¥È */ | |
547 VarInfo v1 = cmd.args[0]; | |
548 eprintf("set multiple-var Var[%d]<%d> <- ",v1.type, v1.number); | |
549 int i; | |
550 if (cmd.args.size() < cmd.argc) { | |
551 eprintf(" error: argsize changed %d -> %d\n",cmd.argc, cmd.args.size()); | |
552 cmd.argc = cmd.args.size(); | |
553 } | |
554 for (i=0; i<cmd.argc; i++) { | |
555 eprintf("%d, ",cmd.args[i+1].value); | |
556 Set(v1, cmd.args[i+1].value); | |
557 v1.number++; | |
558 } | |
559 eprintf("\n"); | |
560 cmd.clear(); | |
561 } else if (cmd.cmd3 == 1 && cmd.cmd4 == 0) { | |
562 /* Îΰè»ØÄê¤ÇÊÑ¿ô¤ò¥¯¥ê¥¢ */ | |
563 VarInfo v1 = cmd.args[0]; | |
564 VarInfo v2 = cmd.args[1]; | |
565 eprintf("memclear. Var[%d]<%d> - Var[%d]<%d>\n",v1.type, v1.number, v2.type, v2.number); | |
566 if (v1.type != v2.type || !IsInt(v1.type)) eprintf(" error: bad args\n"); | |
567 else { | |
568 if (v1.number < 0) v1.number = 0; | |
569 if (v2.number > MaxIndex(v2.type)) v2.number = MaxIndex(v2.type); | |
570 for (; v1.number <= v2.number; v1.number++) | |
571 Set(v1, 0); | |
572 } | |
573 cmd.clear(); | |
574 } else if (cmd.cmd3 == 1 && cmd.cmd4 == 1) { | |
575 /* Îΰè»ØÄê¤ÇÊÑ¿ô¤ò¥»¥Ã¥È */ | |
576 VarInfo v1 = cmd.args[0]; | |
577 VarInfo v2 = cmd.args[1]; | |
578 int value = cmd.args[2].value; | |
579 eprintf("memset. Var[%d]<%d> - Var[%d]<%d> <- %d\n",v1.type, v1.number, v2.type, v2.number, value); | |
580 if (v1.type != v2.type || !IsInt(v1.type)) eprintf(" error: bad args\n"); | |
581 else { | |
582 if (v1.number < 0) v1.number = 0; | |
583 if (v2.number > MaxIndex(v2.type)) v2.number = MaxIndex(v2.type); | |
584 for (; v1.number <= v2.number; v1.number++) | |
585 Set(v1, value); | |
586 } | |
587 cmd.clear(); | |
588 } else if (cmd.cmd3 == 4 && cmd.cmd4 == 1) { // Îΰ襯¥ê¥¢(sysfunc.txt) | |
589 VarInfo v1 = cmd.args[0]; | |
590 int step = cmd.args[1].value; | |
591 int deal = cmd.args[2].value; | |
592 int val = cmd.args[3].value; | |
593 eprintf("memclear. Var[%d]<%d> step %d deal %d <- val %d\n",v1.type, v1.number, step, deal, val); | |
594 int i; for (i=0; i<deal; i++) { | |
595 Set(v1, val); | |
596 v1.number += step; | |
597 } | |
598 cmd.clear(); | |
599 } else if (cmd.cmd3 == 0x64 && cmd.cmd4 == 0) { //Îΰè¤Ç¿ôÃͤò¹ç·×¤¹¤ë | |
600 VarInfo v1 = cmd.args[0]; | |
601 VarInfo v2 = cmd.args[1]; | |
602 eprintf("sum var. Var[%d]<%d> - Var[%d]<%d>\n",v1.type, v1.number, v2.type, v2.number); | |
603 int sum = 0; | |
604 if (v1.type != v2.type || !IsInt(v1.type)) eprintf(" error: bad args\n"); | |
605 else { | |
606 if (v1.number < 0) v1.number = 0; | |
607 if (v2.number > MaxIndex(v2.type)) v2.number = MaxIndex(v2.type); | |
608 for (; v1.number <= v2.number; v1.number++) | |
609 sum += (*this)(v1); | |
610 } | |
611 eprintf(" ret %d\n",sum); | |
612 cmd.SetSysvar(sum); | |
613 } | |
614 } | |
615 return false; | |
616 } | |
617 | |
618 /********************************************************************* | |
54
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
619 ** SimpleCmd |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
620 */ |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
621 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
622 SimpleCmd::SimpleCmd(int a, int b, int c) |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
623 { |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
624 cmd1 = a; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
625 cmd2 = b; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
626 cmd3 = c; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
627 } |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
628 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
629 SimpleCmd::SimpleCmd(void) |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
630 { |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
631 cmd1 = cmd2 = cmd3 = 0; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
632 } |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
633 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
634 bool SimpleCmd::operator<(const SimpleCmd& cmd) const |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
635 { |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
636 if (cmd1 < cmd.cmd1) return true; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
637 else if (cmd1 > cmd.cmd1) return false; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
638 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
639 if (cmd2 < cmd.cmd2) return true; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
640 else if (cmd2 > cmd.cmd2) return false; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
641 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
642 if (cmd3 < cmd.cmd3) return true; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
643 else return false; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
644 } |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
645 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
646 bool SimpleCmd::operator==(const SimpleCmd& cmd) const |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
647 { |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
648 return (cmd1 == cmd.cmd1 && cmd2 == cmd.cmd2 && cmd3 == cmd.cmd3); |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
649 } |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
650 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
651 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
652 /********************************************************************* |
0 | 653 ** Cmd |
654 */ | |
655 | |
656 /* ¿ôÃÍ num := 0x24 0xff <int num> */ | |
657 /* ÊÑ¿ô var := 0x24 <uchar type> 0x5b <exp> 0x5d */ | |
658 /* ¹à token := num | var | 0x28 <exp> 0x29 | <plus|minus> token */ | |
659 | |
660 int Cmd::GetLeftToken(const char*& d, VarInfo& info) { | |
661 bool var_flag = true; | |
662 int minus_flag = 0; | |
663 int value = 0; | |
664 if (d[0] == 0x5c && (d[1] == 1 || d[1] == 0) ) { | |
665 if (d[1] == 1) {dprintf("minus-"); minus_flag ^= 1;} | |
666 else dprintf("plus-"); | |
667 d += 2; | |
668 var_flag = false; | |
669 } | |
670 if (d[0] == 0x24 && ((unsigned const char*)d)[1] == 0xff) { | |
671 // if ( (d[0] == 0x30 || d[0] == 0x31) && d[1] == 0x24 && ((unsigned const char*)d)[2] == 0xff) /* @@@ not supported; selection Æâ¤Ç¡¢0x30|0x31 ¤¬Éտ魯¤ë¤³¤È¤¬¤¢¤ë */ | |
672 // numerical atom | |
673 d += 6; | |
674 value = read_little_endian_int(d-4); | |
675 dprintf("%d",value); | |
676 var_flag = false; | |
677 } else if (d[0] == 0x24 && *(unsigned char*)(d+1) == 0xc8) { | |
678 dprintf("V<sys>"); | |
679 d += 2; | |
680 info.type = TYPE_SYS; info.number = 0; | |
681 value = info.value = flags(); | |
682 } else if (d[0] == 0x24 && d[2] == 0x5b) { | |
683 // 0x24,<type>,0x5b,<expr>,0x5d-terminated term | |
684 info.type = *(unsigned char*)(d+1); | |
685 d += 3; | |
686 dprintf("V<%d>[",info.type); | |
687 info.number = GetExpression(d); | |
688 dprintf("]"); | |
689 if (*d == 0x5d) d++; | |
690 else SetError(); | |
691 if (info.type == TYPE_VARSTR || info.type == TYPE_VARSYSSTR || info.type == TYPE_VARLOCSTR) { | |
692 value = 0; | |
693 info.value = StrVar(info.type, info.number); | |
694 } else { | |
695 value = info.value = flags(info); | |
696 } | |
697 dprintf("(=%d)",value); | |
698 } else SetError(); | |
699 | |
700 if (minus_flag) value = -value; | |
701 if (!var_flag) { | |
702 info.type = TYPE_VAL; | |
703 info.value = value; | |
704 } | |
705 return value; | |
706 } | |
707 | |
47
5f548e5957a8
* get rid of the "deprecated conversion from string constant to ‘char*’" warnings
thib
parents:
44
diff
changeset
|
708 static const char* op_str[70] = { |
0 | 709 // 0 1 2 3 4 5 6 7 8 9 |
710 "+", "-", "*", "/", "%", "&", "|", "^", "<<", ">>", // +00 | |
711 "err.","err.","err.","err.","err.","err.","err.","err.","err.","err.", // +10 | |
712 "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>=", // +20 | |
713 "=", "err.","err.","err.","err.","err.","err.","err.","err.","err.", // +30 | |
714 "==", "!=", "<=", "<", ">=", ">", "err.","err.","err.","err.", // +40 | |
715 "err.","err.","err.","err.","err.","err.","err.","err.","err.","err.", // +50 | |
716 "&&", "||", "err.","err.","err.","err.","err.","err.","err.","err.", // +60 | |
717 }; | |
718 | |
719 static int op_pri_tbl[12] = { | |
720 // + - * / % & | ^ << >> | |
721 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10}; | |
722 | |
723 inline int op_pri(int op) { | |
724 if (op > 11) return 10; | |
725 return op_pri_tbl[op]; | |
726 } | |
727 inline int op_pri_cond(int op) { | |
728 if (op <= 11) return op_pri_tbl[op]; | |
729 else if (op < 50) return 7; | |
730 else if (op == 60) return 8; | |
731 else if (op == 61) return 8; | |
732 else return 10; | |
733 } | |
734 | |
735 | |
736 inline int eval(int v1, int op, int v2) { | |
737 switch(op) { | |
738 case 0: return v1+v2; | |
739 case 1: return v1-v2; | |
740 case 2: return v1*v2; | |
741 case 3: return v2!=0 ? v1/v2 : v1; | |
742 case 4: return v2!=0 ? v1%v2 : v1; | |
743 case 5: return v1&v2; | |
744 case 6: return v1|v2; | |
745 case 7: return v1^v2; | |
746 case 8: return v1<<v2; | |
747 case 9: return v1>>v2; | |
748 case 40: return v1 == v2; | |
749 case 41: return v1 != v2; | |
750 case 42: return v1 <= v2; | |
751 case 43: return v1 < v2; | |
752 case 44: return v1 >= v2; | |
753 case 45: return v1 > v2; | |
754 case 60: return v1 && v2; | |
755 case 61: return v1 || v2; | |
756 } | |
757 return v2; | |
758 } | |
759 | |
52 | 760 Cmd::Cmd(const Flags& f, int _sys_ver) : flags(f), system_version(_sys_ver) { |
761 cmd_type = CMD_NOP; | |
762 argc = 0; | |
763 errorflag = false; | |
764 cmdstr[0] = 0; | |
765 strend = 0; | |
766 pos = -1; | |
767 } | |
768 | |
0 | 769 /* ±é»»»Ò op := 0x5c <uchar op> */ |
770 /* ¿ô¼° exp: [op] <token> [op <token> [...]] */ | |
771 int Cmd::GetExpression(const char*& d, VarInfo* info_ptr) { | |
772 #define STACK_DEPTH 1024 | |
773 #define OP_LB 11 | |
774 char op_stack[STACK_DEPTH]; | |
775 int val_stack[STACK_DEPTH]; | |
776 int stack_count = 0; | |
777 | |
778 // Âè°ì¹à¤ÎÆɤ߹þ¤ß | |
779 while(*d == 0x28) { | |
780 d++; | |
781 dprintf("("); | |
782 op_stack[stack_count++] = OP_LB; | |
783 } | |
784 VarInfo info; | |
785 int value = GetLeftToken(d, info); | |
786 | |
787 while(*d == 0x29 && stack_count > 0 && op_stack[stack_count-1] == OP_LB) { | |
788 d++; | |
789 dprintf(")"); | |
790 stack_count--; | |
791 } | |
792 | |
793 if (*d != 0x5c && stack_count == 0) { | |
794 if (info_ptr) *info_ptr = info; | |
795 return value; // ñ½ã¤Êleft-term¤Ï¤³¤³¤Ç½ªÎ»¡£Í¸ú¤Êinfo_ptr¤òµ¢¤¹¡Ê²ÄǽÀ¤¬¤¢¤ë¡Ë | |
796 } | |
797 | |
798 while(*d == 0x5c) { | |
799 int op_type = *(unsigned char*)(d+1); | |
800 d += 2; | |
801 if (op_type < 70) dprintf("%s",op_str[op_type]); | |
802 else dprintf("err."); | |
803 if (op_type >= 10) SetError(); | |
804 int cur_pri = op_pri(op_type); | |
805 while(stack_count != 0 && op_pri(op_stack[stack_count-1]) <= cur_pri) { | |
806 // Í¥Àè½ç°Ì¤Î¹â¤¤¡¢Àè¹Ô¤¹¤ë±é»»¤ò¹Ô¤¦ | |
807 value = eval(val_stack[stack_count-1], op_stack[stack_count-1], value); | |
808 stack_count--; | |
809 } | |
810 val_stack[stack_count] = value; | |
811 op_stack[stack_count++] = op_type; | |
812 while(*d == 0x28) { | |
813 d++; | |
814 dprintf("("); | |
815 op_stack[stack_count++] = OP_LB; | |
816 } | |
817 if (stack_count >= STACK_DEPTH) SetError(); | |
818 value = GetLeftToken(d, info); | |
819 | |
820 while (*d != 0x5c && stack_count > 0) { | |
821 // ̤¼Â¹Ô¤Î±é»»¤ò½ª¤ï¤é¤»¤ë | |
822 if (op_stack[stack_count-1] != OP_LB) { | |
823 value = eval(val_stack[stack_count-1], op_stack[stack_count-1], value); | |
824 stack_count--; | |
825 } else if (*d == 0x29) { /* op_stack == OP_LB */ | |
826 // bracket ½ªÃ¼¤¬¤¢¤ì¤Ð¡¢ÊĤ¸¤Æ¤ª¤¯ | |
827 d++; | |
828 dprintf(")"); | |
829 stack_count--; | |
830 } else break; // error | |
831 } | |
832 } | |
833 if (stack_count) SetError(); // unbalanced bracket | |
834 dprintf("(=%d)",value); | |
835 if (info_ptr) { | |
836 info_ptr->type = TYPE_VAL; | |
837 info_ptr->value = value; | |
838 } | |
839 return value; | |
840 } | |
841 | |
842 // ¾ò·ïʬ´ôÀìÍѤˡ¢¾ò·ï±é»»¤È»»½Ñ±é»»¤Îº®¹ç¤ò¸¡ÃΤǤ¤ëÀìÍѥ롼¥Á¥ó¡ÊËÜÍè¤ÏGetExpression¤Çº¹¤·»Ù¤¨¤Ê¤¤) | |
843 int Cmd::GetExpressionCond(const char*& d) { | |
844 char op_stack[STACK_DEPTH]; | |
845 int val_stack[STACK_DEPTH]; | |
846 int valattr_stack[STACK_DEPTH]; | |
847 #define ATTR_VAL 0 | |
848 #define ATTR_FLAG 1 | |
849 int stack_count = 0; | |
850 | |
851 // Âè°ì¹à¤ÎÆɤ߹þ¤ß | |
852 while(*d == 0x28) { | |
853 d++; | |
854 dprintf("("); | |
855 op_stack[stack_count++] = OP_LB; | |
856 } | |
857 VarInfo info; | |
858 int value = GetLeftToken(d, info); | |
859 while(*d == 0x29 && stack_count > 0 && op_stack[stack_count-1] == OP_LB) { | |
860 d++; | |
861 dprintf(")"); | |
862 stack_count--; | |
863 } | |
864 bool valattr = ATTR_VAL; | |
865 | |
866 while(*d == 0x5c) { | |
867 int op_type = *(unsigned char*)(d+1); | |
868 d += 2; | |
869 if (op_type < 70) dprintf("%s",op_str[op_type]); | |
870 else dprintf("err."); | |
871 int cur_pri = op_pri_cond(op_type); | |
872 while(stack_count != 0 && op_pri_cond(op_stack[stack_count-1]) <= cur_pri) { | |
873 // Í¥Àè½ç°Ì¤Î¹â¤¤¡¢Àè¹Ô¤¹¤ë±é»»¤ò¹Ô¤¦ | |
874 if (op_stack[stack_count-1] >= 60) { | |
875 if (valattr_stack[stack_count-1] != ATTR_FLAG || valattr != ATTR_FLAG) SetError(); | |
876 } else { | |
877 if (valattr_stack[stack_count-1] != ATTR_VAL || valattr != ATTR_VAL) SetError(); | |
878 } | |
879 value = eval(val_stack[stack_count-1], op_stack[stack_count-1], value); | |
880 if (op_stack[stack_count-1] >= 40) valattr = ATTR_FLAG; | |
881 stack_count--; | |
882 } | |
883 val_stack[stack_count] = value; | |
884 valattr_stack[stack_count] = valattr; | |
885 op_stack[stack_count++] = op_type; | |
886 while(*d == 0x28) { | |
887 d++; | |
888 dprintf("("); | |
889 op_stack[stack_count++] = OP_LB; | |
890 } | |
891 if (stack_count >= STACK_DEPTH) SetError(); | |
892 value = GetLeftToken(d, info); | |
893 valattr = ATTR_VAL; | |
894 | |
895 while (*d != 0x5c && stack_count > 0) { | |
896 // ̤¼Â¹Ô¤Î±é»»¤ò½ª¤ï¤é¤»¤ë | |
897 if (op_stack[stack_count-1] != OP_LB) { | |
898 if (op_stack[stack_count-1] >= 60) { | |
899 if (valattr_stack[stack_count-1] != ATTR_FLAG || valattr != ATTR_FLAG) SetError(); | |
900 } else { | |
901 if (valattr_stack[stack_count-1] != ATTR_VAL || valattr != ATTR_VAL) SetError(); | |
902 } | |
903 value = eval(val_stack[stack_count-1], op_stack[stack_count-1], value); | |
904 if (op_stack[stack_count-1] >= 40) valattr = ATTR_FLAG; | |
905 stack_count--; | |
906 // bracket ½ªÃ¼¤¬¤¢¤ì¤Ð¡¢ÊĤ¸¤Æ¤ª¤¯ | |
907 } else if (*d == 0x29) { /* op_stack == OP_LB */ | |
908 d++; | |
909 dprintf(")"); | |
910 stack_count--; | |
911 } else break; // error | |
912 } | |
913 } | |
914 if (stack_count) SetError(); // unbalanced bracket | |
915 if (value) dprintf("(=true)"); | |
916 else dprintf("(=false)"); | |
917 return value; | |
918 } | |
919 | |
920 | |
921 /* | |
922 str = | |
923 arg = | |
924 args = 0x28 <exp> [[0x2c] <exp> [[0x2c] <exp> [...] ]] | |
925 */ | |
926 | |
927 int Cmd::GetArgs(const char*& d) { | |
928 if (*d != 0x28) return 0; /* °ú¿ô¤Ê¤· */ | |
929 d++; | |
930 dprintf("args:"); | |
931 VarInfo var; | |
932 int i; for (i=0; i<100 ; i++) { | |
933 /* number, variable, string ¤Î¼ïÊ̤ʤ¯ÃͤòÆÀ¤ë */ | |
934 if (*d == 0x61) { // ¤è¤¯¤ï¤«¤é¤Ê¤¤(ÃÒÂ奢¥Õ¥¿¡¼) | |
29
d229cce98f50
* no more (or, at least, less) duplicate code between scn2kdump and the rest
thib
parents:
21
diff
changeset
|
935 dprintf("@%d",d[1]); |
0 | 936 d += 2; |
937 if (*d == 0x28) { | |
938 dprintf("{"); | |
939 GetArgs(d); // (A,B,C)À᤬´Þ¤Þ¤ì¤ë¤³¤È¤¬¤¢¤ë | |
940 dprintf("}"); | |
941 } else { | |
942 dprintf("{}"); | |
943 } | |
944 } else if (d[0] == 0x0a || d[0] == 0x40) { // ¤è¤¯¤ï¤«¤é¤Ê¤¤ (Little Busters!) | |
945 int var; | |
946 if (system_version == 0) { var = read_little_endian_int(d+1); d += 5;} | |
947 else { var = read_little_endian_short(d+1); d += 3;} | |
948 dprintf("line %d; ",var); | |
949 } else if (*d == 0x24 || (*d == 0x5c && (d[1] == 1 || d[1] == 0)) || *d == 0x28) { | |
950 GetExpression(d, &var); | |
951 args.push_back(var); | |
952 } else if (StrType(d)) { | |
953 var.type = TYPE_STR; | |
954 var.value = GetString(d); | |
955 args.push_back(var); | |
956 } else SetError(); | |
957 if (*d == 0x29) break; | |
958 if (*d == 0x2c) {d++;} // ¼¡¤Î arg ¤¬±é»»»Ò¤Ç»Ï¤Þ¤ë¡¢¤Ê¤É¤¬¤Ê¤±¤ì¤Ð¸ºß¤·¤Ê¤¤ | |
959 dprintf(","); | |
960 } | |
961 if (*d == 0x29) d++; | |
962 else SetError(); | |
963 return i; | |
964 } | |
965 | |
966 int Cmd::GetArgsSpecial(int normal_args,const char*& d) { | |
967 if (*d != 0x28) return 0; /* °ú¿ô¤Ê¤· */ | |
968 d++; | |
969 dprintf("args:"); | |
970 int i; for (i=0; i<normal_args; i++) { | |
971 /* number, variable, string ¤Î¼ïÊ̤ʤ¯ÃͤòÆÀ¤ë */ | |
972 if (*d == 0x24 || (*d == 0x5c && (d[1] == 1 || d[1] == 0)) || *d == 0x28) { | |
973 GetExpression(d); | |
974 } else if (StrType(d)) { | |
975 GetString(d); | |
976 } else SetError(); | |
977 if (*d == 0x29) break; | |
978 if (*d == 0x2c) {d++;} // ¼¡¤Î arg ¤¬±é»»»Ò¤Ç»Ï¤Þ¤ë¡¢¤Ê¤É¤¬¤Ê¤±¤ì¤Ð¸ºß¤·¤Ê¤¤ | |
979 dprintf(","); | |
980 } | |
981 for (i=0; i<argc ; i++) { | |
982 if (*d == 0x28) { | |
983 /* | |
984 ** cmd 01-22:0c1c, 01-22:0835 | |
985 ** Princess Bride ¤Î¥«¡¼¥É¤¬Íî¤Á¤ë¥¢¥Ë¥á¤Î¾ìÌÌ | |
986 ** ¤Ê¤ª¡¢_PBCARDANM* ¤Î²èÁü¤Ï¤³¤Î¥³¥Þ¥ó¥É¤Ç¤Î¤ß»È¤ï¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢Æüì½èÍý¤È¤·¤Æ̵»ë¤¹¤ë¤³¤È¤â²Äǽ | |
987 ** | |
988 ** cmd 01-04:0276, 026c, 0270 | |
989 ** Ê£¿ô¤Î enum ¤¬ args ¤Î¿ô¤À¤±Â³¤¯½èÍý¡£Æüì½èÍý¤È¤·¤ÆʬΥ¤¹¤ë | |
990 */ | |
991 dprintf("enum.<"); | |
992 /* (...) ¤ÏÎóµó·¿ or ¹½Â¤ÂΤβÄǽÀ¤¬¤¢¤ë */ | |
993 const char* d_orig = d; | |
994 int pt = args.size(); args.push_back(VarInfo(0)); | |
995 int count = GetArgs(d); | |
996 args[pt] = VarInfo(count); | |
997 dprintf(">"); | |
998 } else if (*d == 0x61 && (d[1] >= 0x00 && d[1] <= 0x04) && d[2] == 0x28 ) { | |
999 /* »È¤ï¤ì¤ë¥³¥Þ¥ó¥É¤Ï 01-21:004b, 01-28:0064 ¤Î¤¤¤º¤ì¤«¡ÊR,C,PB,LO) | |
1000 ** ¤½¤ì¤é¤Î¥³¥Þ¥ó¥É¤Ï | |
1001 ** arg1: ²èÁü¥Õ¥¡¥¤¥ë̾ | |
1002 ** arg2 : Sel ÈÖ¹æ | |
1003 ** ¤é¤·¤¯¡¢arg3 °Ê¹ß¤¬ 0x61 <00-04> (a,b,c,...) ¤È¤Ê¤ë¡Ê¥À¥ó¥×¾å¤Ï enum ¤Èɽµ¤µ¤ì¤ë) | |
1004 ** () Æâ¤Î°ú¿ô¤Ï¤µ¤Þ¤¶¤Þ¤Ç¡¢a ¤Î¤ß¡Ê²èÁü¥Õ¥¡¥¤¥ë̾¡Ë¡¢ | |
1005 ** a,b b=SEL? | |
1006 ** a,b,c (b,c)=ºÂɸ¡© | |
1007 ** a,(b,c,d,e,f,g) b-g = src / dest? | |
1008 ** ¤é¤·¤¤ | |
1009 */ | |
1010 dprintf("kasane. #%d <",d[1]); | |
1011 d += 2; | |
1012 int pt = args.size(); args.push_back(VarInfo(0)); | |
1013 int count = GetArgs(d); | |
1014 args[pt] = VarInfo(count); | |
1015 dprintf(">"); | |
1016 } else if (*d == 0x24 || (*d == 0x5c && (d[1] == 1 || d[1] == 0))) { | |
1017 /* cmd 01-15:0028 ; »Ï¤á¤Ë 0x24 À᤬¤¢¤ê¡¢Â³¤¤¤Æ 0x28 Àá¤Ë¤Ê¤ë */ | |
1018 VarInfo var; | |
1019 GetExpression(d, &var); | |
1020 args.push_back(var); | |
1021 i--; // ¤³¤Î°ú¿ô¤Ïargc ¤Î¿ô¤Ë¤ÏÆþ¤é¤Ê¤¤ | |
1022 } else SetError(); | |
1023 if (d[0] == 0x0a || d[0] == 0x40) { | |
1024 /* cmd 01-15:0028 ; 0x28 Àá¤Î¸å¤ËËè²ó 0x0a À᤬Íè¤ë */ | |
1025 int var; | |
1026 if (system_version == 0) { var = read_little_endian_int(d+1); d += 5;} | |
1027 else { var = read_little_endian_short(d+1); d += 3;} | |
1028 dprintf("line %d; ",var); | |
1029 } | |
1030 if (*d == 0x29) break; | |
1031 if (*d == 0x2c) {d++;} // ¼¡¤Î arg ¤¬±é»»»Ò¤Ç»Ï¤Þ¤ë¡¢¤Ê¤É¤¬¤Ê¤±¤ì¤Ð¸ºß¤·¤Ê¤¤ | |
1032 dprintf(","); | |
1033 } | |
1034 if (*d == 0x29) d++; | |
1035 else SetError(); | |
1036 return 0; | |
1037 } | |
1038 | |
1039 /* switch | |
1040 <exp> | |
1041 0x7b | |
1042 <exp> <int> | |
1043 ... | |
1044 0x7d | |
1045 */ | |
1046 | |
1047 int Cmd::GetSwitch(const char*& d) { | |
1048 if (*d != 0x28) {SetError(); return -1;} | |
1049 d++; | |
1050 dprintf("switch. "); | |
1051 int var = GetExpression(d); | |
1052 if (*d != 0x29) {SetError(); return -1;} | |
1053 d++; | |
1054 dprintf("->\n"); | |
1055 if (*d == 0x7b) { | |
1056 d++; | |
1057 } else SetError(); | |
1058 | |
1059 int default_jmp = -1; int jmpto = -1; | |
1060 int i; for (i=0; i<argc; i++) { | |
1061 dprintf("\t"); | |
1062 if (*d++ != 0x28) {SetError(); return -1;} | |
1063 if (*d != 0x29) { | |
1064 int item = GetExpression(d); | |
1065 if (*d++ != 0x29) {SetError(); return -1;} | |
1066 int jmp = read_little_endian_int(d); | |
1067 if (var == item) { | |
1068 dprintf("(selected)"); | |
1069 jmpto = jmp; | |
1070 } | |
1071 dprintf(" -> %d\n", jmp); | |
1072 } else { | |
1073 d++; | |
1074 default_jmp = read_little_endian_int(d); | |
1075 } | |
1076 d += 4; | |
1077 } | |
1078 if (default_jmp != -1) { | |
1079 dprintf("default -> %d\n",default_jmp); | |
1080 if (jmpto == -1) jmpto = default_jmp; | |
1081 } | |
1082 if (*d == 0x7d) { | |
1083 d++; | |
1084 } else SetError(); | |
1085 return jmpto; | |
1086 } | |
1087 /* simple switch | |
1088 <exp> | |
1089 0x7b | |
1090 <int> | |
1091 ... | |
1092 0x7d | |
1093 */ | |
1094 int Cmd::GetSimpleSwitch(const char*& d) { | |
1095 if (*d != 0x28) {SetError(); return -1;} | |
1096 d++; | |
1097 dprintf("simple switch. "); | |
1098 int var = GetExpression(d); | |
1099 if (*d != 0x29) {SetError(); return -1;} | |
1100 d++; | |
1101 dprintf(" ->\n"); | |
1102 int jumpto = -1; | |
1103 if (*d == 0x7b) { | |
1104 d++; | |
1105 } else SetError(); | |
1106 int i; for (i=0; i<argc; i++) { | |
1107 int j = read_little_endian_int(d); | |
1108 d += 4; | |
1109 dprintf("\t%d -> %d\n", i+1, j); | |
1110 if (var == i) jumpto = j; | |
1111 } | |
1112 if (*d == 0x7d) { | |
1113 d++; | |
1114 } else SetError(); | |
1115 return jumpto; | |
1116 } | |
1117 | |
1118 /* | |
1119 selection | |
1120 ? <exp> | |
1121 0x7b | |
1122 <0x0a|0x40> <ushort | uint> | |
1123 */ | |
1124 void Cmd::GetSelection(const char*& d) { | |
1125 dprintf("selection. "); | |
1126 if (*d == 0x28) { | |
1127 d++; | |
1128 GetExpression(d); | |
1129 if (*d != 0x29) { SetError(); return;} | |
1130 d++; | |
1131 } | |
1132 if (*d == 0x7b) { | |
1133 d++; | |
1134 dprintf("{\n\t"); | |
1135 } else SetError(); | |
1136 int arg_count = 0; | |
1137 string text = ""; | |
1138 int cond_result = false; | |
1139 int sel_no = 0; | |
1140 while(*d != 0x7d) { | |
1141 if (d[0] == 0x0a || d[0] == 0x40) { | |
1142 int var; | |
1143 if (system_version == 0) { var = read_little_endian_int(d+1); d += 5;} | |
1144 else { var = read_little_endian_short(d+1); d += 3;} | |
1145 dprintf("Line %d; ",var); | |
1146 if (text.length() != 0) { | |
1147 if (cond_result) ; // ¾ò·ïÀ᤬ true ¤Ê¤éɽ¼¨¤·¤Ê¤¤ | |
1148 else { | |
1149 const char* str = text.c_str(); | |
1150 VarInfo var; | |
1151 var.type = TYPE_STR; | |
1152 var.value = CopyString(str); | |
1153 args.push_back(var); | |
1154 var.type = TYPE_VAL; | |
1155 var.value = sel_no; | |
1156 args.push_back(var); | |
1157 } | |
1158 sel_no++; | |
1159 } | |
1160 text = ""; | |
1161 cond_result = false; | |
1162 } else if (d[0] == 0x2c) { | |
1163 dprintf(":comma:"); | |
1164 } else if (d[0] == 0x28) { | |
1165 dprintf(":cond:"); | |
1166 d++; | |
1167 while(d[0] != 0x29) { | |
1168 int result = GetExpressionCond(d); // PRINT- Àá¤Ç¤Ê¤¤¤Ð¤¢¤¤¡¢¾ò·ïɽ¼¨¡£¼¡¤Ïʸ»úÀá¡¢¤Þ¤¿¤ÏPRINTÀá¤Î¤Ï¤º | |
1169 if (*d == 0x32) { // 0x32 ¤Ê¤é¡¢¸½ºß¤Î¾ò·ïÀá¤òɽ¼¨¤·¤Ê¤¤ | |
1170 d++; dprintf("##"); | |
1171 cond_result = result; | |
1172 } else if (*d == 0x31) { // 0x31 ¤Ê¤é¡¢¸½ºß¤Î¾ò·ïÀá¤òɽ¼¨¤¹¤ë | |
1173 // Little Busters! : ¤³¤Î¾ò·ï¤ÇÀµ¤·¤¤¤«¤Ï̤¸¡¾Ú | |
1174 d++; dprintf("***"); | |
1175 cond_result = !result; | |
1176 } | |
1177 dprintf(":"); | |
1178 } | |
1179 d++; | |
1180 } else if (StrType(d)) { | |
1181 int strpt = GetString(d); | |
1182 text += strheap + strpt; | |
1183 arg_count++; | |
1184 dprintf("\n\t"); | |
1185 } else if (*d == 0x23 && strncmp(d,"###PRINT",8) == 0) { | |
1186 d += 8; | |
1187 if (d[0] != 0x28) SetError(); | |
1188 else { // ʸ»úÊÑ¿ô¤ÎÆâÍƤÎɽ¼¨ | |
1189 d++; | |
1190 dprintf("Print."); | |
1191 VarInfo info; | |
1192 GetLeftToken(d, info); | |
1193 if (d[0] != 0x29 || info.type == -1) SetError(); | |
1194 d++; | |
21
d1bb7b365816
Fixed dynamic strings in selections (Fuko Pranks for instance)
thib
parents:
13
diff
changeset
|
1195 dprintf(";");/* |
0 | 1196 // ¿ôÃͤòÁ´³Ñʸ»ú¤ËÊÑ´¹¤·¤ÆÅÐÏ¿ |
1197 char str[10], str2[20]; // itoa | |
1198 sprintf(str, "%d", info.value); | |
1199 int i; for (i=0; str[i] != 0; i++) { | |
1200 str2[i*2] = 0xa3; | |
1201 str2[i*2+1] = 0xb0 + str[i]-'0'; | |
1202 } | |
21
d1bb7b365816
Fixed dynamic strings in selections (Fuko Pranks for instance)
thib
parents:
13
diff
changeset
|
1203 str2[i*2] = 0;*/ |
d1bb7b365816
Fixed dynamic strings in selections (Fuko Pranks for instance)
thib
parents:
13
diff
changeset
|
1204 text += strheap + info.value; |
0 | 1205 } |
1206 } else { SetError(); break;} | |
1207 } | |
1208 d++; | |
1209 /* @@@ */ | |
1210 /* °ìÃפ·¤Ê¤¤¾ì¹ç¤¬¤¢¤ë¤Î¤Ç¥³¥á¥ó¥È¥¢¥¦¥È */ | |
1211 // if (arg_count != argc) SetError(); | |
1212 dprintf("\n}\n"); | |
1213 } | |
1214 | |
1215 void Cmd::GetCmd(Flags& flags_orig, const char*& d ) { | |
52 | 1216 if (d == NULL) { SetError(); return;} |
0 | 1217 if (cmd_type != CMD_NOP) return; |
1218 | |
1219 cmdstr[0] = 0; | |
1220 rawdata = d; | |
1221 if (*d == 0x23) { /* ¥³¥Þ¥ó¥É */ | |
1222 cmd_type = CMD_OTHER; | |
1223 cmd1 = *(unsigned const char*)(d+1); | |
1224 cmd2 = *(unsigned const char*)(d+2); | |
1225 cmd3 = read_little_endian_short(d+3); | |
1226 argc = read_little_endian_short(d+5); | |
1227 cmd4 = *(unsigned const char*)(d+7); | |
1228 d += 8; | |
1229 /* verbose */ | |
1230 // dprintf(" 0x23 - cmd %02x-%02x:%04x:%02x[%2d] \n",cmd1,cmd2,cmd3,cmd4,argc); | |
29
d229cce98f50
* no more (or, at least, less) duplicate code between scn2kdump and the rest
thib
parents:
21
diff
changeset
|
1231 sprintf(cmdstr, "%02x-%02x:%04x:%02x : %s",cmd1,cmd2,cmd3,cmd4, CmdDescr(cmd1,cmd2,cmd3,cmd4)); |
0 | 1232 /* °ú¿ô¤òÆÀ¤ë */ |
1233 /* Æüì°ú¿ô¤Î¤â¤Î */ | |
1234 int is_special = 0; | |
1235 if (cmd1 == 0) { | |
1236 if (cmd2 == 1) { | |
1237 int jump_arg = -1; | |
1238 if (cmd3 == 0 || cmd3 == 5) { | |
1239 /* gosub / goto */ | |
1240 jump_arg =read_little_endian_int(d); | |
1241 d += 4; | |
1242 if (cmd3 == 0) | |
1243 dprintf("\tjmp -> %d\n", jump_arg); | |
1244 else /* cmd3 == 5 */ | |
1245 dprintf("\tcall -> %d\n", jump_arg); | |
1246 is_special = 1; | |
1247 } else if (cmd3 == 1 || cmd3 == 2) { | |
1248 /* conditional jump (if / unless) */ | |
1249 if (*d++ != 0x28) { SetError(); return;} | |
1250 dprintf("\t"); | |
1251 int cond = GetExpressionCond(d); | |
1252 if (cmd3 == 1) cond = !cond; // µÕ¤Ë¤Ê¤ë | |
1253 if (*d++ != 0x29) { SetError(); return; } | |
1254 int jumpto = read_little_endian_int(d); | |
1255 d += 4; | |
1256 dprintf("-> %d\n", jumpto); | |
1257 if (! cond) jump_arg = jumpto; /* condition ¤¬Ëþ¤¿¤µ¤ì¤Ê¤¤¾ì¹ç¡¢¥¸¥ã¥ó¥× */ | |
1258 is_special = 1; | |
1259 } else if (cmd3 == 4) { | |
1260 /* switch to */ | |
1261 jump_arg = GetSwitch(d); | |
1262 is_special = 1; | |
1263 } else if (cmd3 == 8 || cmd3 == 3) { | |
1264 /* switch to */ | |
1265 jump_arg = GetSimpleSwitch(d); | |
1266 is_special = 1; | |
1267 } else if (cmd3 == 16) { // call with parameters | |
1268 GetArgs(d); | |
1269 jump_arg = read_little_endian_int(d); | |
1270 d += 4; | |
1271 is_special = 1; | |
1272 } else goto retry; | |
1273 if (jump_arg == -1) { | |
1274 cmd_type = CMD_NOP; | |
1275 } | |
1276 else { | |
1277 cmd_type = CMD_JMP; | |
1278 args.push_back(VarInfo(jump_arg)); | |
1279 } | |
1280 } else if (cmd2 == 2 && (cmd3 == 0 || cmd3 == 1 || cmd3 == 2 || cmd3 == 3 || cmd3 == 0x0d) ) { | |
1281 /* selection */ | |
1282 GetSelection(d); | |
1283 is_special = 1; | |
1284 } | |
1285 } | |
1286 retry: | |
1287 /* °ìÈÌ°ú¿ô¤Î¤â¤Î */ | |
1288 if (!is_special) { | |
29
d229cce98f50
* no more (or, at least, less) duplicate code between scn2kdump and the rest
thib
parents:
21
diff
changeset
|
1289 dprintf(" 0x23 - cmd %02x-%02x:%04x:%02x[%2d] : %s\n",cmd1,cmd2,cmd3,cmd4,argc,CmdDescr(cmd1,cmd2,cmd3,cmd4)); |
0 | 1290 dprintf("\t"); |
1291 if (cmd1 == 1 && cmd2 == 0x22 && (cmd3 == 0xc1c || cmd3 == 0x835)) GetArgsSpecial(3, d); | |
1292 else if (cmd1 == 1 && cmd2 == 0x0b && cmd3 == 0x65) GetArgsSpecial(0, d); | |
1293 else if (cmd1 == 1 && cmd2 == 0x15 && cmd3 == 0x28) GetArgsSpecial(0, d); | |
1294 else if (cmd1 == 1 && cmd2 == 4 && (cmd3 == 0x26c || cmd3 == 0x26d || cmd3 == 0x270 || cmd3 == 0x276)) GetArgsSpecial(0, d); | |
1295 else if (cmd1 == 1 && cmd2 == 4 && cmd3 == 0x586) GetArgsSpecial(1, d); | |
43
01aa5ddf7dc8
A lot of very minor improvements (deleted some unused variables, and other things like that...)
thib
parents:
29
diff
changeset
|
1296 else if (cmd1 == 1 && ((cmd2 == 0x21 && cmd3 == 0x4b) || (cmd2 == 0x28 && cmd3 == 0x64))) GetArgsSpecial(2,d); |
0 | 1297 else GetArgs(d); |
1298 dprintf("\n"); | |
1299 | |
1300 } | |
1301 } else if (*d == 0x24) { /* ÂåÆþ±é»» */ | |
1302 if (d[1] == 0x12 || d[2] != 0x5b) SetError(); | |
1303 dprintf("expr: "); | |
1304 sprintf(cmdstr, "expr"); | |
1305 | |
1306 VarInfo info; | |
1307 int value = GetLeftToken(d, info); | |
1308 if (d[0] != 0x5c) SetError(); | |
1309 int type = d[1]; | |
1310 if (type < 20 || type > 30) SetError(); | |
1311 else dprintf("%s",op_str[type]); | |
1312 d += 2; | |
1313 int value2 = GetExpression(d); | |
1314 // ÂåÆþ¾ðÊó¤òËä¤á¹þ¤à | |
1315 if (type != 30) value2 = eval(value, type-20, value2); | |
1316 cmd_type = CMD_FLAGS; | |
1317 args.push_back(info); | |
1318 args.push_back(value2); | |
1319 dprintf("\n"); | |
1320 } else if (StrType(d)) { /* ʸ»ú½ÐÎÏ */ | |
1321 VarInfo info; | |
1322 info.type = TYPE_STR; | |
1323 info.value = GetString(d); | |
1324 args.push_back(info); | |
1325 cmd_type = CMD_TEXT; | |
1326 dprintf("\n"); | |
1327 } else if (*d == 0x0a || *d == 0x40 || *d == 0x21) { /* ¥Ç¥Ð¥Ã¥°Íѥǡ¼¥¿¤È´ûÆɥե饰 */ | |
1328 cmd_type = CMD_NOP; | |
1329 if (*d == 0x0a) { | |
1330 dprintf("line "); | |
1331 d++; | |
1332 int l; | |
1333 if (system_version == 0) { | |
1334 l = read_little_endian_int(d); | |
1335 d += 4; | |
1336 } else { | |
1337 l = read_little_endian_short(d); | |
1338 d += 2; | |
1339 } | |
1340 dprintf("%d\n", l); | |
1341 } else { /* 0x40, 0x21 */ | |
1342 // ´ûÆÉ¥Þ¡¼¥«¡¼¤é¤·¤¤¡£¥¨¥ó¥È¥ê¡¼¥Ý¥¤¥ó¥È¤È¥»¡¼¥Ö¥Ý¥¤¥ó¥È¤â»È¤ï¤ì¤ë¡£ | |
1343 // RealLive 1.2.5¤«¤é¡¢0x40¤Ï¥»¡¼¥Ö¥Ý¥¤¥ó¥È¡¢0x21¤Ï¥¨¥ó¥È¥ê¡¼¥Ý¥¤¥ó¥È¡£ | |
1344 // 1.2.5°ÊÁ°¡¢¤É¤Á¤é¤â0x40¤¬»È¤ï¤ì¤ë¡£ | |
1345 int kidoku_index; | |
1346 d++; | |
1347 if (system_version == 0) { | |
1348 kidoku_index = read_little_endian_int(d); | |
1349 d += 4; | |
1350 } else { | |
1351 kidoku_index = read_little_endian_short(d); | |
1352 d += 2; | |
1353 } | |
1354 dprintf("kidoku marker %d\n", kidoku_index); | |
1355 // text_readflag¤Ï¡¢¤³¤Îkidoku_index¤ò»È¤Ã¤¿¤éÎɤ¤¤«¤Ê¡£ | |
1356 } | |
1357 } else if (*d == 0x2c) { /* ??? */ | |
1358 dprintf("commd;0x2c\n"); // conditional jump ¤Î¹Ô¤Àè¤Ë¤è¤¯¤¢¤ë¤é¤·¤¤¡Ê¾ï¤Ë¡¢¤«¤Ï¤ï¤«¤é¤Ê¤¤¡Ë | |
1359 d++; | |
1360 } else { | |
1361 SetError(); | |
1362 } | |
1363 } | |
52 | 1364 |
0 | 1365 void Cmd::clear(void) { |
1366 cmd_type = CMD_NOP; | |
1367 ResetString(); | |
1368 args.clear(); | |
1369 errorflag = false; | |
1370 pos = -1; | |
1371 } | |
1372 | |
1373 char Cmd::strtype[256] = { | |
1374 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* +00 */ | |
1375 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* +10 */ // 0123456789ABCDEF | |
1376 1,0,3,0, 0,0,0,1, 0,0,0,0, 0,1,1,0, /* +20 */ // !"#$%&'()*+,-./ | |
1377 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, /* +30 */ // 0123456789:;<=>? | |
1378 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, /* +40 */ // @ABCDEFGHIJKLMNO | |
1379 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, /* +50 */ // PQRSTUVWXYZ[\]^_ | |
1380 0,0,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, /* +60 */ // `abcdefghijklmno | |
1381 1,1,1,1, 1,1,1,1, 1,1,1,1, 0,0,0,0, /* +70 */ // pqrstuvwxyz{|}~ | |
1382 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, /* +80 */ | |
1383 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, /* +90 */ | |
1384 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* +A0 */ | |
1385 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* +B0 */ | |
1386 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* +C0 */ | |
1387 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* +D0 */ | |
1388 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, /* +E0 */ | |
1389 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,0,0 /* +F0 */ | |
1390 }; | |
1391 | |
1392 int Cmd::GetString(const char*& d) { | |
1393 int retnum = -1; | |
1394 bool quote_flag = false; | |
1395 int stype; | |
1396 retnum = strend; | |
1397 while(1) { | |
1398 if (*d == '\\') { | |
1399 d++; | |
1400 strheap[strend++] = *d++; | |
1401 } else if (*d == '"') { | |
1402 if (quote_flag) quote_flag = false; | |
1403 else quote_flag = true; | |
1404 d++; | |
1405 } else if (quote_flag) { | |
1406 strheap[strend++] = *d++; | |
43
01aa5ddf7dc8
A lot of very minor improvements (deleted some unused variables, and other things like that...)
thib
parents:
29
diff
changeset
|
1407 } else if ((stype = StrType(d))) { |
0 | 1408 strheap[strend++] = *d++; |
1409 if (stype == 2) strheap[strend++] = *d++; | |
1410 } else break; | |
1411 } | |
1412 strheap[strend++] = 0; | |
1413 dprintf("\"%s\"", strheap + retnum); | |
1414 if (strend >= STRHEAP_SIZE) { | |
1415 dprintf("Error: string heap overflow\n"); | |
1416 } | |
1417 return retnum; | |
1418 } | |
1419 | |
1420 int Cmd::CopyString(const char* d) { | |
1421 int retnum = strend; | |
1422 int len = strlen(d); | |
1423 memcpy(strheap+strend, d, len+1); | |
1424 strend += len+1; | |
1425 d += len+1; | |
1426 return retnum; | |
1427 } | |
1428 | |
1429 int Cmd::StrVar(int type, int var_num) { | |
1430 int retnum = strend; | |
1431 flags.Str(type, var_num, strheap+strend, STRHEAP_SIZE-strend); | |
1432 strend += strlen(strheap+strend)+1; | |
1433 return retnum; | |
1434 } | |
1435 | |
1436 void Cmd::SetSysvar(int n, int val) { | |
1437 VarInfo info; | |
1438 if (cmd_type != CMD_SYSVAR) { | |
1439 args.clear(); | |
1440 } | |
1441 cmd_type = CMD_SYSVAR; | |
1442 | |
1443 info.type = TYPE_SYS; | |
1444 info.number = n; | |
1445 info.value = val; | |
1446 args.push_back(info); | |
1447 } | |
1448 void Cmd::SetFlagvar(VarInfo info, int val) { | |
1449 if (cmd_type != CMD_SYSVAR) { | |
1450 args.clear(); | |
1451 } | |
1452 cmd_type = CMD_SYSVAR; | |
1453 | |
1454 info.value = val; | |
1455 args.push_back(info); | |
1456 } | |
1457 | |
1458 void Cmd::SetStrvar(VarInfo info, const string& s) { | |
1459 if (cmd_type != CMD_SYSVAR) { | |
1460 args.clear(); | |
1461 } | |
1462 | |
1463 cmd_type = CMD_SYSVAR; | |
1464 const char* ss = s.c_str(); | |
1465 info.value = CopyString(ss); | |
1466 args.push_back(info); | |
1467 } | |
1468 | |
52 | 1469 |
1470 const char* Cmd::Str(const VarInfo& info) const { | |
1471 if (info.type != TYPE_STR && info.type != TYPE_VARSTR && info.type != TYPE_VARLOCSTR && info.type != TYPE_VARSYSSTR) | |
1472 return ""; | |
1473 int pt = info.value; | |
1474 if (pt < 0 || pt >= STRHEAP_SIZE) return ""; | |
1475 return strheap + pt; | |
1476 } | |
1477 | |
1478 int Cmd::AddStr(char* s) { | |
1479 // 1-0a-0064 ¤Ï¤³¤¦¤¤¤¦¤â¤Î¤¬É¬Íפ餷¤¤ | |
1480 int start = strend; | |
1481 while (*s) strheap[strend++] = *s++; | |
1482 strheap[strend++] = 0; | |
1483 return start; | |
1484 } | |
1485 | |
1486 | |
0 | 1487 void Cmd::read(const CmdSimplified& from) { |
1488 errorflag = false; | |
1489 ResetString(); | |
1490 | |
1491 cmd_type = Cmdtype(from.type); | |
1492 cmd1 = from.cmd1; | |
1493 cmd2 = from.cmd2; | |
1494 cmd3 = from.cmd3; | |
1495 cmd4 = from.cmd4; | |
1496 argc = from.argc; | |
1497 /* args ¤ÎÆɤ߹þ¤ß */ | |
1498 args.clear(); | |
1499 char* d = from.args; | |
52 | 1500 if (d == NULL) return; |
0 | 1501 while(*d != TYPE_END) { |
1502 VarInfo info; | |
1503 switch(*d) { | |
1504 case TYPE_VAL: | |
1505 info.type = TYPE_VAL; | |
1506 info.number = 0; | |
1507 info.value = read_little_endian_int(d+1); | |
1508 d += 5; | |
1509 args.push_back(info); | |
1510 break; | |
1511 case TYPE_STR: | |
1512 info.type = TYPE_STR; | |
1513 info.number = 0; | |
1514 d++; | |
1515 info.value = CopyString( d); | |
1516 d += strlen(d)+1; | |
1517 args.push_back(info); | |
1518 break; | |
1519 default: | |
1520 fprintf(stderr,"Cmd::read: Invalid Load Data\n"); | |
1521 *d = TYPE_END; | |
1522 } | |
1523 } | |
1524 } | |
52 | 1525 |
0 | 1526 void Cmd::write(CmdSimplified& to, char*& buffer) const { |
1527 /* | |
1528 if (cmd_type != CMD_OTHER) { | |
1529 fprintf(stderr,"Cmd::write: Invalid Cmd during Saving Data\n"); | |
1530 to.cmd1 = 0; to.cmd2 = 0; to.cmd3 = 0; to.cmd4 = 0; to.argc = 0; to.args = 0; | |
1531 return; | |
1532 } | |
1533 */ | |
1534 to.type = cmd_type; | |
1535 to.cmd1 = cmd1; | |
1536 to.cmd2 = cmd2; | |
1537 to.cmd3 = cmd3; | |
1538 to.cmd4 = cmd4; | |
1539 to.argc = argc; | |
1540 /* args ¤Î½ñ¤¹þ¤ß */ | |
1541 if (args.empty()) { | |
52 | 1542 to.args = NULL; |
0 | 1543 } else { |
1544 to.args = buffer; | |
1545 char* d = to.args; | |
1546 vector<VarInfo>::const_iterator it; | |
1547 for (it = args.begin(); it != args.end(); it++) { | |
1548 int type = it->type; | |
1549 if ( (type >= 0 && type < 7) || type == TYPE_VAL || type == char(TYPE_SYS)) { // digits | |
1550 *d++ = TYPE_VAL; | |
1551 write_little_endian_int(d, it->value); | |
1552 d += 4; | |
1553 } else if (type == TYPE_VARSTR || type == TYPE_VARSYSSTR || type == TYPE_VARLOCSTR || type == TYPE_STR) { // string | |
1554 *d++ = TYPE_STR; | |
1555 const char* s = Str(*it); | |
1556 int len = strlen(s); | |
1557 memcpy(d, s, len+1); | |
1558 d += len+1; | |
1559 } else { | |
1560 fprintf(stderr,"Cmd::write: Invalid Cmd args during Saving Data\n"); | |
1561 } | |
1562 } | |
1563 *d++ = TYPE_END; | |
1564 buffer = d; | |
1565 } | |
1566 } | |
52 | 1567 |
0 | 1568 void CmdSimplified::copy(const CmdSimplified& from, char*& args_buffer) { |
1569 *this = from; | |
52 | 1570 if (args == NULL) return; |
0 | 1571 char* args_old = from.args; |
1572 /* args ¤Î¥³¥Ô¡¼ */ | |
1573 while(*args_old != TYPE_END) { | |
1574 if (*args_old == TYPE_VAL) { | |
1575 args_old += 5; | |
1576 } else { /* TYPE_STR */ | |
1577 args_old += strlen(args_old)+1; | |
1578 } | |
1579 } | |
1580 args_old++; | |
1581 int args_len = args_old - from.args; | |
1582 memmove(args_buffer, from.args, args_len); | |
1583 args = args_buffer; | |
1584 args_buffer += args_len; | |
1585 } | |
52 | 1586 |
0 | 1587 void CmdSimplified::Save(string& saveret) { |
1588 char buf[1024]; | |
1589 sprintf(buf, "%02x-%02x:%04x:%02x(%02d),", cmd1, cmd2, cmd3, cmd4, argc); | |
1590 saveret += buf; | |
1591 | |
1592 /* args ¤Î¥³¥Ô¡¼ */ | |
1593 char* d = args; | |
1594 while(d && *d != TYPE_END) { | |
1595 if (*d == TYPE_VAL) { | |
1596 d++; | |
1597 sprintf(buf, "%d,", read_little_endian_int(d)); | |
1598 d += 4; | |
1599 } else { /* TYPE_STR ¤È²¾Äê */ | |
1600 d++; | |
1601 if (strlen(d) > 1000) d[1000] = 0; // ¤¢¤ê¤¨¤Ê¤¤¡¦¡¦¡¦ | |
1602 int i; int cnt = 0; | |
1603 buf[cnt++] = '"'; | |
1604 for (i=0; d[i] != 0; i++) { | |
1605 if (d[i] == '"') buf[cnt++] = '"'; | |
1606 buf[cnt++] = d[i]; | |
1607 } | |
1608 buf[cnt++]='"'; | |
1609 buf[cnt++] = ','; | |
1610 buf[cnt++] = 0; | |
1611 d += strlen(d)+1; | |
1612 } | |
1613 saveret += buf; | |
1614 } | |
1615 saveret += 'E'; | |
1616 } | |
1617 | |
1618 void CmdSimplified::Load(const char* save, char*& args_buffer) { | |
1619 args = args_buffer; | |
1620 | |
1621 type = CMD_OTHER; | |
1622 sscanf(save, "%02x-%02x:%04x:%02x(%02d),", &cmd1, &cmd2, &cmd3, &cmd4, &argc); | |
1623 save = strchr(save, ','); | |
52 | 1624 if (save == NULL) { |
0 | 1625 *args_buffer++ = TYPE_END; |
1626 return; | |
1627 } | |
1628 save++; | |
1629 while(*save != 'E' && *save != '\n' && *save != '\0') { | |
1630 if (isdigit(*save)) { | |
1631 int v; | |
1632 sscanf(save,"%d,",&v); | |
1633 *args_buffer++ = TYPE_VAL; | |
1634 write_little_endian_int(args_buffer, v); | |
1635 args_buffer+= 4; | |
1636 save = strchr(save, ','); | |
1637 if (save) save++; | |
1638 } else { // *save == '"' | |
1639 save++; | |
1640 *args_buffer++ = TYPE_STR; | |
1641 while(1) { | |
1642 if (*save == 0) break; | |
1643 if (*save == '"') { | |
1644 if (save[1] != '"') break; | |
1645 save++; | |
1646 } | |
1647 *args_buffer++ = *save++; | |
1648 } | |
1649 save += 2; | |
1650 *args_buffer++ = 0; | |
1651 } | |
1652 } | |
1653 *args_buffer++ = TYPE_END; | |
1654 } | |
1655 | |
1656 #ifdef SCN_DUMP | |
1657 void usage(void) { | |
1658 fprintf(stderr,"usage : scn2kdump [inputfile] [outputfile]\n"); | |
1659 fprintf(stderr," inputfile: seen.txt(default)\n"); | |
1660 fprintf(stderr," outputfile: seen.txt_out(default)\n"); | |
1661 exit(-1); | |
1662 } | |
1663 int main(int argc, char** argv) { | |
1664 /* determine file names */ | |
1665 bool verbose = false; | |
1666 char* inname = "seen.txt"; | |
52 | 1667 char* outname = NULL; |
0 | 1668 if (argc > 2 && strcmp(argv[1],"-v") == 0) { |
1669 int i; for (i=1; i<argc; i++) argv[i] = argv[i+1]; | |
1670 argc--; | |
1671 verbose = true; | |
1672 } | |
1673 switch(argc) { | |
52 | 1674 case 1: break; |
1675 case 2: | |
1676 inname = argv[1]; | |
1677 break; | |
1678 case 3: | |
1679 inname = argv[1]; | |
1680 outname = argv[2]; | |
1681 break; | |
1682 default: usage(); | |
0 | 1683 } |
1684 /* open output file */ | |
1685 FILE* outstream = stdout; | |
1686 /* create archive instance */ | |
1687 SCN2kFILE archive(inname); | |
1688 archive.Init(); | |
1689 if (archive.Deal() == 0) { | |
1690 fprintf(stderr,"Cannot open / Invalid archive file %s\n",inname); | |
1691 usage(); | |
1692 } | |
1693 /* dump files */ | |
1694 archive.InitList(); | |
1695 char* fname; | |
1696 fprintf(stderr,"Dump start\n"); | |
1697 int system_version = 0; | |
1698 while( (fname = archive.ListItem()) != 0) { | |
1699 ARCINFO* info = archive.Find(fname,""); | |
52 | 1700 if (info == NULL) continue; |
0 | 1701 char* data = info->CopyRead(); |
1702 char* d = data; | |
1703 char* dend = d + info->Size(); | |
1704 /* version ³Îǧ */ | |
1705 if (read_little_endian_int(d) == 0x1cc) { | |
1706 system_version = 0; | |
1707 } else if (read_little_endian_int(d) == 0x1d0) { | |
1708 system_version = 1; | |
1709 } else { | |
1710 continue; | |
1711 } | |
1712 if (read_little_endian_int(d+4) == 0x1adb2) ; // little busters! | |
1713 else if (read_little_endian_int(d+4) != 0x2712) continue; | |
1714 int header_size; | |
1715 if (system_version == 0) { | |
1716 header_size = 0x1cc + read_little_endian_int(d+0x20) * 4; | |
1717 } else { | |
1718 header_size = read_little_endian_int(d+0x20); | |
1719 } | |
1720 d += header_size; | |
1721 | |
1722 const char* dcur = d; | |
1723 const char* dstart = d; | |
1724 fprintf(stderr,"Dumping %s\n",fname); | |
1725 Flags flags; | |
1726 /* ºÇ½é¤«¤éºÇ¸å¤Þ¤Ç¥³¥Þ¥ó¥É¼èÆÀ -> ½ÐÎϤò·«¤êÊÖ¤¹ */ | |
1727 while(dcur<dend) { | |
1728 const char* dprev = dcur; | |
1729 Cmd cmd(flags, system_version); cmd.ClearError(); | |
1730 | |
1731 /* end? */ | |
1732 if (*dcur == -1) { | |
1733 /* 0xff x 32byte + 0x00 : end sign */ | |
1734 int i; for (i=0; i<0x20; i++) | |
1735 if (dcur[i] != -1) break; | |
1736 if (i == 0x20 && dcur[i] == 0) break; | |
1737 } | |
1738 dprintf("%d : ",dcur-dstart); | |
1739 cmd.GetCmd(flags, dcur); | |
1740 if (cmd.IsError()) { | |
1741 fprintf(outstream, "Error at %6d\n",dprev-dstart); | |
1742 while(dcur < dend) { | |
1743 if (*dcur == 0x29 && dcur[1] == 0x0a) {dcur++;break;} | |
1744 dcur++; | |
1745 } | |
1746 dprev -= 2*16; | |
1747 int ilen = (dcur-dprev+15)/16; | |
1748 int i; for (i=0; i<ilen; i++) { | |
1749 fprintf(outstream, "%6d: ",dprev-dstart); | |
1750 int j; for (j=0; j<16; j++) { | |
1751 if (dprev >= dend) break; | |
1752 if (dprev < data) continue; | |
1753 fprintf(outstream, "%02x ",*(unsigned char*)(dprev)); | |
1754 dprev++; | |
1755 } | |
1756 fprintf(outstream, "\n"); | |
1757 } | |
1758 } | |
1759 } | |
1760 delete info; | |
1761 } | |
1762 return 0; | |
1763 } | |
1764 #endif | |
1765 |