Mercurial > otakunoraifu
annotate scn2k/scn2k_cmd.cc @ 66:d112357a0ec1
Fix a bug with savegames introduced with changeset c7bcc0ec2267.
Warning: savegames created since c7bcc0ec2267 are probably corrupted,
you may have to start the game over.
If you chose not to do so, you should replace all occurrences of 'TextWindow' by 'TextImplWindow',
and 'Text Window' by 'TextImpl Window' in your save files.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Sat, 11 Dec 2010 18:36:20 +0100 |
parents | 4416cfac86ae |
children | e4a12dd9a51b |
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 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
42 /* 注意点: @@@ で表記 */ |
0 | 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) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
118 // A[]..G[], Z[] を直に読む |
0 | 119 if (uint(number) >= 2000) return 0; |
120 return var[index][number]; | |
121 } else { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
122 // Ab[]..G4b[], Z8b[] などを読む |
0 | 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) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
147 // A[]..G[], Z[] を直に書く |
0 | 148 if (uint(info.number) >= 2000) return; |
149 var[index][info.number] = value; | |
150 } else { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
151 // Ab[]..G4b[], Z8b[] などを書く |
0 | 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 | |
63 | 226 void Flags::Load(const char* save) { |
227 Load(save, false); | |
228 } | |
229 | |
230 void Flags::LoadSys(const char* save) { | |
231 Load(save, true); | |
232 } | |
233 | |
234 void Flags::Load(const char* save, bool sys) { | |
235 int i, j; | |
236 int start, end; | |
237 std::string *var_str; | |
238 char string_field[] = "V<?>[%04d]="; | |
239 | |
240 start = (sys) ? (TYPE_NONSYSVARMAX + 1) : 0; | |
241 end = (sys) ? (TYPE_NONSYSVARMAX + 2) : TYPE_NONSYSVARMAX; | |
242 | |
243 var_str = (sys) ? sys_str : str; | |
244 string_field[2] = (sys) ? 'M' : 'C'; | |
245 | |
246 for (i=start; i <= end; i++) { | |
247 for (j=0; j < 2000; j++) { | |
248 var[i][j] = 0; | |
249 } | |
250 } | |
251 for (j=0; j<2000; j++) { | |
252 var_str[j] = ""; | |
253 } | |
254 sys = 0; | |
255 | |
256 save = strstr(save, "\n[Flags]\n"); | |
257 | |
258 if (save) { | |
259 save += strlen("\n[Flags]\n"); | |
260 do { | |
261 if (save[0] == '[') break; // next section | |
262 if (strncmp(save, string_field, 2) == 0) { | |
263 if (strncmp(save, string_field, 5) == 0) { // string | |
264 char buf[1024]; | |
265 int n; | |
266 if (sscanf(save, string_field, &n) == 1) { | |
267 const char* s = strchr(save, '='); | |
268 s++; | |
269 const char* send = strchr(s, '\n'); | |
270 int slen = send - s; | |
271 strncpy(buf, s, slen); | |
272 buf[slen] = 0; | |
273 if (n >= 0 && n < 2000) | |
274 var_str[n] = buf; | |
275 } | |
276 } else if (save[2] >= '0' && save[2] <= '9') { | |
277 int c, n, v; | |
278 if (sscanf(save, "V<%d>[%04d]=%d\n",&c,&n,&v) == 3) { | |
279 if (n >= 0 && n < 2000) | |
280 { | |
281 if (!sys && c >= 0 && c <= TYPE_NONSYSVARMAX) | |
282 var[c][n] = v; | |
283 else if (sys && c == TYPE_NONSYSVARMAX + 1) | |
284 var[TYPE_NONSYSVARMAX + 1][n] = v; | |
285 else if (sys && c == 25) | |
286 var[7][n] = v; | |
287 } | |
288 } | |
289 } | |
290 } | |
291 save = strchr(save, '\n'); | |
292 if (save) | |
293 save++; | |
294 } while (save); | |
295 } | |
296 } | |
297 | |
0 | 298 void Flags::Save(string& save) { |
299 char buf[1024]; | |
300 save = "\n[Flags]\n"; | |
63 | 301 int i, j; |
0 | 302 for (i=0; i<=TYPE_NONSYSVARMAX; i++) { |
303 for (j=0; j<2000; j++) { | |
304 if (var[i][j] != 0) { | |
305 sprintf(buf, "V<%d>[%04d]=%d\n",i,j,var[i][j]); | |
306 save += buf; | |
307 } | |
308 } | |
309 } | |
310 for (j=0; j<2000; j++) { | |
311 if (str[j].length() != 0) { | |
312 sprintf(buf, "V<C>[%04d]=%s\n", j, str[j].c_str()); | |
313 save += buf; | |
314 } | |
315 } | |
316 } | |
52 | 317 |
318 void Flags::SaveSys(string& save) { //FIXME: see how to factorize with Save | |
0 | 319 char buf[1024]; |
320 int j; | |
321 save = "\n[Flags]\n"; | |
63 | 322 for (j=0; j<2000; j++) { |
0 | 323 if (var[6][j] != 0) { |
63 | 324 sprintf(buf, "V<6>[%04d]=%d\n", j, var[6][j]); |
325 save += buf; | |
0 | 326 } |
63 | 327 } |
0 | 328 for (j=0; j<2000; j++) { |
329 if (var[7][j] != 0) { | |
330 sprintf(buf, "V<25>[%04d]=%d\n",j,var[7][j]); | |
331 save += buf; | |
332 } | |
333 } | |
334 for (j=0; j<2000; j++) { | |
335 if (sys_str[j].length() != 0) { | |
336 sprintf(buf, "V<M>[%04d]=%s\n", j, sys_str[j].c_str()); | |
337 save += buf; | |
338 } | |
339 } | |
340 } | |
52 | 341 |
0 | 342 bool Flags::Exec(Cmd& cmd) { |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
343 if (cmd.cmd_type == CMD_FLAGS) { // 代入演算 |
0 | 344 if (cmd.args.size() != 2) return false; |
345 Set(cmd.args[0], cmd.args[1].value); | |
346 cmd.clear(); | |
347 return true; | |
348 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
349 if (cmd.cmd1 == 1 && cmd.cmd2 == 0x0a) { // 文字列演算 |
0 | 350 VarInfo arg1 = cmd.args[0]; |
351 switch(cmd.cmd3) { | |
52 | 352 case 0: |
353 if (cmd.cmd4 == 0) { | |
354 SetStr(arg1, cmd.Str(cmd.args[1])); | |
355 } else if (cmd.cmd4 == 1) { | |
356 string s = cmd.Str(cmd.args[1]); | |
357 const char* sc = s.c_str(); | |
358 int len = cmd.args[2].value; | |
359 int i; | |
360 for (i=0; i < sc[i] && len != 0; i++, len--) { | |
361 if (sc[i]<0 && sc[i+1]!=0) i++; | |
362 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
363 s.erase(i); // 全角で len 文字まで切り詰める |
52 | 364 SetStr(arg1, s); |
365 // fprintf(stderr,"Set[%d,%d]<-%s\n",arg1.type,arg1.number,s.c_str()); | |
366 } else break; | |
367 cmd.clear(); | |
368 break; | |
369 case 1: | |
370 if (cmd.cmd4 == 0) { | |
371 SetStr(arg1, ""); | |
372 cmd.clear(); | |
373 } else if (cmd.cmd4 == 1) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
374 // 領域指定で文字列クリア |
52 | 375 VarInfo v1 = cmd.args[0]; |
376 VarInfo v2 = cmd.args[1]; | |
377 eprintf("memclear(str). Var[%d]<%d> - Var[%d]<%d>\n",v1.type, v1.number, v2.type, v2.number); | |
378 if (v1.type != v2.type || (v1.type != TYPE_VARSTR && v1.type != TYPE_VARSYSSTR && v1.type != TYPE_VARLOCSTR)) { | |
379 eprintf(" error: bad args\n"); | |
380 } else { | |
381 if (v1.number < 0) v1.number = 0; | |
382 if (v2.number > 2000) v2.number = 2000; | |
383 for (; v1.number <= v2.number; v1.number++) { | |
384 SetStr(v1, ""); | |
385 } | |
386 } | |
387 cmd.clear(); | |
0 | 388 } |
52 | 389 case 2: |
390 SetStr(arg1, Str(arg1.type,arg1.number) + cmd.Str(cmd.args[1])); | |
391 // 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); | |
392 cmd.clear(); | |
393 break; | |
394 case 3: | |
395 SetSys(strlen(cmd.Str(cmd.args[0]))); | |
396 cmd.clear(); | |
397 break; | |
398 case 4: | |
399 { int v = strcmp(cmd.Str(cmd.args[0]), cmd.Str(cmd.args[1])); | |
400 // string s1=cmd.Str(cmd.args[0]); | |
401 // string s2=cmd.Str(cmd.args[1]); | |
402 // 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); | |
403 if (v < 0) SetSys(-1); | |
404 else if (v > 0) SetSys(1); | |
405 else SetSys(0); | |
0 | 406 cmd.clear(); |
52 | 407 break; } |
408 case 5: // substring, index from left | |
409 case 6: // substring, index from right | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
410 // 全角対応らしい |
52 | 411 //FIXME: Make sure it works properly |
412 { int offset = cmd.args[2].value; | |
413 int len = strlen(cmd.Str(cmd.args[1])); | |
414 string str = cmd.Str(cmd.args[1]); | |
415 const char* s = str.c_str(); | |
416 if (cmd.cmd3 == 6) offset = len - offset; | |
417 if (offset < 0) offset = 0; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
418 // 先頭 N 文字を読み飛ばす |
52 | 419 int i; |
420 int offset_top = 0; | |
421 for (i=0; i<offset && s[offset_top] != 0; i++) { | |
422 if (s[offset_top] < 0 && s[offset_top+1] != 0) offset_top += 2; | |
423 else offset_top += 1; | |
424 } | |
425 if (s[offset_top] == 0) { | |
426 SetStr(arg1, ""); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
427 } else if (cmd.cmd4 == 0) { // 長さ制限なし |
52 | 428 SetStr(arg1, string(s, offset_top, len-offset_top)); |
429 } else { // cmd.cmd4 == 1 | |
430 int slen = cmd.args[3].value; | |
431 int offset_end = offset_top; | |
432 for (i=0; i<slen && s[offset_end] != 0; i++) { | |
433 if (s[offset_end] < 0 && s[offset_end]+1 != 0) offset_end += 2; | |
434 else offset_end += 1; | |
0 | 435 } |
52 | 436 string result(s, offset_top, offset_end-offset_top); |
437 SetStr(arg1, result); | |
0 | 438 } |
439 cmd.clear(); | |
52 | 440 break; } |
441 case 7: {// strlen w/ kanji | |
442 const char* s = cmd.Str(cmd.args[0]); int i; | |
443 for (i=0; *s != 0; i++) { | |
444 if (*s < 0 && s[1] != 0) s += 2; | |
445 else s++; | |
446 } | |
447 SetSys(i); | |
448 cmd.clear(); | |
449 break; } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
450 case 8: // 文字列を切って短くする |
52 | 451 if (cmd.args[1].value <= 0) { |
452 SetStr(arg1, ""); | |
453 } else if (cmd.args[1].value < strlen(cmd.Str(cmd.args[1]))) { | |
454 Str(arg1.type,arg1.number).erase(cmd.args[1].value); | |
455 } | |
456 cmd.clear(); | |
457 break; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
458 case 0x0e: // 漢字モードでitoa |
52 | 459 { |
460 int arg1 = cmd.args[0].value; | |
461 string result; | |
462 char wc[3]; wc[2]=0; | |
463 char buf[20]; | |
464 if (cmd.cmd4 == 0) { | |
465 sprintf(buf, "%d", arg1); | |
466 } else { // cmd.cmd4 == 1 | |
467 char fmt[20]; | |
468 sprintf(fmt, "%%%dd", cmd.args[2].value); | |
469 sprintf(buf, fmt, arg1); | |
0 | 470 } |
52 | 471 int i; |
472 for (i=0; buf[i] != 0; i++) { | |
473 if (buf[i] == ' ') { | |
474 wc[0] = 0x81; // ' ' in SHIFT_JIS | |
475 wc[1] = 0x40; | |
476 } else if (buf[i] == '-') { | |
477 wc[0] = 0x81; // '-' in SHIFT_JIS | |
478 wc[1] = 0x7c; | |
479 } else if (isdigit(buf[i])) { | |
480 wc[0] = 0x82; // number in SHIFT_JIS | |
481 wc[1] = buf[i] - '0' + 0x4f; | |
482 } else { | |
483 continue; | |
484 } | |
485 result += wc; | |
0 | 486 } |
52 | 487 SetStr(cmd.args[1], result); |
0 | 488 cmd.clear(); |
489 } | |
52 | 490 break; |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
491 case 0x0f: case 0x11: // itoa (0x11 の方は zero padding するっぽい) |
52 | 492 if (cmd.cmd4 == 0) { |
493 int arg1 = cmd.args[0].value; | |
494 char buf[1024]; sprintf(buf, "%d", arg1); | |
495 SetStr(cmd.args[1], buf); | |
496 cmd.clear(); | |
497 } else if (cmd.cmd4 == 1) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
498 // 漢字(SJIS) : 82 [4f+N] |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
499 // やはり漢字じゃない? |
52 | 500 int arg1 = cmd.args[0].value; |
501 char buf[1024]; char fmt[1024]; | |
502 if (cmd.cmd3 == 0x0f) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
503 sprintf(fmt, "%%%dd",cmd.args[2].value); /* 空白でパディング */ |
52 | 504 } else { |
505 sprintf(fmt, "%%0%dd",cmd.args[2].value); | |
506 } | |
507 sprintf(buf, fmt, arg1); | |
508 SetStr(cmd.args[1], buf); | |
509 cmd.clear(); | |
510 } | |
511 break; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
512 case 0x64: // 文字列の表示 : 引数をテキストウィンドウに表示 |
52 | 513 if (cmd.cmd4 == 1) { |
514 char buf[256]; | |
515 snprintf(buf, 255, "%d", Get(cmd.args[0].type, cmd.args[0].number)); | |
516 cmd.args[0].type = TYPE_STR; | |
517 cmd.args[0].value = cmd.AddStr(buf); | |
518 cmd.cmd4 = 0; | |
519 } | |
520 cmd.cmd_type = CMD_TEXT; | |
521 break; | |
0 | 522 } |
523 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
524 if (cmd.cmd1 == 1 && cmd.cmd2 == 0x0b) { // 数値変数演算 |
0 | 525 if (cmd.cmd3 == 0 && cmd.cmd4 == 0) { |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
526 /* 複数の変数をセット */ |
0 | 527 VarInfo v1 = cmd.args[0]; |
528 eprintf("set multiple-var Var[%d]<%d> <- ",v1.type, v1.number); | |
529 int i; | |
530 if (cmd.args.size() < cmd.argc) { | |
531 eprintf(" error: argsize changed %d -> %d\n",cmd.argc, cmd.args.size()); | |
532 cmd.argc = cmd.args.size(); | |
533 } | |
534 for (i=0; i<cmd.argc; i++) { | |
535 eprintf("%d, ",cmd.args[i+1].value); | |
536 Set(v1, cmd.args[i+1].value); | |
537 v1.number++; | |
538 } | |
539 eprintf("\n"); | |
540 cmd.clear(); | |
541 } else if (cmd.cmd3 == 1 && cmd.cmd4 == 0) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
542 /* 領域指定で変数をクリア */ |
0 | 543 VarInfo v1 = cmd.args[0]; |
544 VarInfo v2 = cmd.args[1]; | |
545 eprintf("memclear. Var[%d]<%d> - Var[%d]<%d>\n",v1.type, v1.number, v2.type, v2.number); | |
546 if (v1.type != v2.type || !IsInt(v1.type)) eprintf(" error: bad args\n"); | |
547 else { | |
548 if (v1.number < 0) v1.number = 0; | |
549 if (v2.number > MaxIndex(v2.type)) v2.number = MaxIndex(v2.type); | |
550 for (; v1.number <= v2.number; v1.number++) | |
551 Set(v1, 0); | |
552 } | |
553 cmd.clear(); | |
554 } else if (cmd.cmd3 == 1 && cmd.cmd4 == 1) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
555 /* 領域指定で変数をセット */ |
0 | 556 VarInfo v1 = cmd.args[0]; |
557 VarInfo v2 = cmd.args[1]; | |
558 int value = cmd.args[2].value; | |
559 eprintf("memset. Var[%d]<%d> - Var[%d]<%d> <- %d\n",v1.type, v1.number, v2.type, v2.number, value); | |
560 if (v1.type != v2.type || !IsInt(v1.type)) eprintf(" error: bad args\n"); | |
561 else { | |
562 if (v1.number < 0) v1.number = 0; | |
563 if (v2.number > MaxIndex(v2.type)) v2.number = MaxIndex(v2.type); | |
564 for (; v1.number <= v2.number; v1.number++) | |
565 Set(v1, value); | |
566 } | |
567 cmd.clear(); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
568 } else if (cmd.cmd3 == 4 && cmd.cmd4 == 1) { // 領域クリア(sysfunc.txt) |
0 | 569 VarInfo v1 = cmd.args[0]; |
570 int step = cmd.args[1].value; | |
571 int deal = cmd.args[2].value; | |
572 int val = cmd.args[3].value; | |
573 eprintf("memclear. Var[%d]<%d> step %d deal %d <- val %d\n",v1.type, v1.number, step, deal, val); | |
574 int i; for (i=0; i<deal; i++) { | |
575 Set(v1, val); | |
576 v1.number += step; | |
577 } | |
578 cmd.clear(); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
579 } else if (cmd.cmd3 == 0x64 && cmd.cmd4 == 0) { //領域で数値を合計する |
0 | 580 VarInfo v1 = cmd.args[0]; |
581 VarInfo v2 = cmd.args[1]; | |
582 eprintf("sum var. Var[%d]<%d> - Var[%d]<%d>\n",v1.type, v1.number, v2.type, v2.number); | |
583 int sum = 0; | |
584 if (v1.type != v2.type || !IsInt(v1.type)) eprintf(" error: bad args\n"); | |
585 else { | |
586 if (v1.number < 0) v1.number = 0; | |
587 if (v2.number > MaxIndex(v2.type)) v2.number = MaxIndex(v2.type); | |
588 for (; v1.number <= v2.number; v1.number++) | |
589 sum += (*this)(v1); | |
590 } | |
591 eprintf(" ret %d\n",sum); | |
592 cmd.SetSysvar(sum); | |
593 } | |
594 } | |
595 return false; | |
596 } | |
597 | |
598 /********************************************************************* | |
54
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
599 ** SimpleCmd |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
600 */ |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
601 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
602 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
|
603 { |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
604 cmd1 = a; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
605 cmd2 = b; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
606 cmd3 = c; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
607 } |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
608 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
609 SimpleCmd::SimpleCmd(void) |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
610 { |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
611 cmd1 = cmd2 = cmd3 = 0; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
612 } |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
613 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
614 bool SimpleCmd::operator<(const SimpleCmd& cmd) const |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
615 { |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
616 if (cmd1 < cmd.cmd1) return true; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
617 else if (cmd1 > cmd.cmd1) return false; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
618 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
619 if (cmd2 < cmd.cmd2) return true; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
620 else if (cmd2 > cmd.cmd2) return false; |
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 if (cmd3 < cmd.cmd3) return true; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
623 else return false; |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
624 } |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
625 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
626 bool SimpleCmd::operator==(const SimpleCmd& cmd) const |
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 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
|
629 } |
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 |
d7cde171a1de
* scn2k_grp.cc now handles commands in a cleanier way \o/
thib
parents:
52
diff
changeset
|
632 /********************************************************************* |
0 | 633 ** Cmd |
634 */ | |
635 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
636 /* 数値 num := 0x24 0xff <int num> */ |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
637 /* 変数 var := 0x24 <uchar type> 0x5b <exp> 0x5d */ |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
638 /* 項 token := num | var | 0x28 <exp> 0x29 | <plus|minus> token */ |
0 | 639 |
640 int Cmd::GetLeftToken(const char*& d, VarInfo& info) { | |
641 bool var_flag = true; | |
642 int minus_flag = 0; | |
643 int value = 0; | |
644 if (d[0] == 0x5c && (d[1] == 1 || d[1] == 0) ) { | |
645 if (d[1] == 1) {dprintf("minus-"); minus_flag ^= 1;} | |
646 else dprintf("plus-"); | |
647 d += 2; | |
648 var_flag = false; | |
649 } | |
650 if (d[0] == 0x24 && ((unsigned const char*)d)[1] == 0xff) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
651 // if ( (d[0] == 0x30 || d[0] == 0x31) && d[1] == 0x24 && ((unsigned const char*)d)[2] == 0xff) /* @@@ not supported; selection 内で、0x30|0x31 が付随することがある */ |
0 | 652 // numerical atom |
653 d += 6; | |
654 value = read_little_endian_int(d-4); | |
655 dprintf("%d",value); | |
656 var_flag = false; | |
657 } else if (d[0] == 0x24 && *(unsigned char*)(d+1) == 0xc8) { | |
658 dprintf("V<sys>"); | |
659 d += 2; | |
660 info.type = TYPE_SYS; info.number = 0; | |
661 value = info.value = flags(); | |
662 } else if (d[0] == 0x24 && d[2] == 0x5b) { | |
663 // 0x24,<type>,0x5b,<expr>,0x5d-terminated term | |
664 info.type = *(unsigned char*)(d+1); | |
665 d += 3; | |
666 dprintf("V<%d>[",info.type); | |
667 info.number = GetExpression(d); | |
668 dprintf("]"); | |
669 if (*d == 0x5d) d++; | |
670 else SetError(); | |
671 if (info.type == TYPE_VARSTR || info.type == TYPE_VARSYSSTR || info.type == TYPE_VARLOCSTR) { | |
672 value = 0; | |
673 info.value = StrVar(info.type, info.number); | |
674 } else { | |
675 value = info.value = flags(info); | |
676 } | |
677 dprintf("(=%d)",value); | |
678 } else SetError(); | |
679 | |
680 if (minus_flag) value = -value; | |
681 if (!var_flag) { | |
682 info.type = TYPE_VAL; | |
683 info.value = value; | |
684 } | |
685 return value; | |
686 } | |
687 | |
47
5f548e5957a8
* get rid of the "deprecated conversion from string constant to ‘char*’" warnings
thib
parents:
44
diff
changeset
|
688 static const char* op_str[70] = { |
0 | 689 // 0 1 2 3 4 5 6 7 8 9 |
690 "+", "-", "*", "/", "%", "&", "|", "^", "<<", ">>", // +00 | |
691 "err.","err.","err.","err.","err.","err.","err.","err.","err.","err.", // +10 | |
692 "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>=", // +20 | |
693 "=", "err.","err.","err.","err.","err.","err.","err.","err.","err.", // +30 | |
694 "==", "!=", "<=", "<", ">=", ">", "err.","err.","err.","err.", // +40 | |
695 "err.","err.","err.","err.","err.","err.","err.","err.","err.","err.", // +50 | |
696 "&&", "||", "err.","err.","err.","err.","err.","err.","err.","err.", // +60 | |
697 }; | |
698 | |
699 static int op_pri_tbl[12] = { | |
700 // + - * / % & | ^ << >> | |
701 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10}; | |
702 | |
703 inline int op_pri(int op) { | |
704 if (op > 11) return 10; | |
705 return op_pri_tbl[op]; | |
706 } | |
707 inline int op_pri_cond(int op) { | |
708 if (op <= 11) return op_pri_tbl[op]; | |
709 else if (op < 50) return 7; | |
710 else if (op == 60) return 8; | |
711 else if (op == 61) return 8; | |
712 else return 10; | |
713 } | |
714 | |
715 | |
716 inline int eval(int v1, int op, int v2) { | |
717 switch(op) { | |
718 case 0: return v1+v2; | |
719 case 1: return v1-v2; | |
720 case 2: return v1*v2; | |
721 case 3: return v2!=0 ? v1/v2 : v1; | |
722 case 4: return v2!=0 ? v1%v2 : v1; | |
723 case 5: return v1&v2; | |
724 case 6: return v1|v2; | |
725 case 7: return v1^v2; | |
726 case 8: return v1<<v2; | |
727 case 9: return v1>>v2; | |
728 case 40: return v1 == v2; | |
729 case 41: return v1 != v2; | |
730 case 42: return v1 <= v2; | |
731 case 43: return v1 < v2; | |
732 case 44: return v1 >= v2; | |
733 case 45: return v1 > v2; | |
734 case 60: return v1 && v2; | |
735 case 61: return v1 || v2; | |
736 } | |
737 return v2; | |
738 } | |
739 | |
52 | 740 Cmd::Cmd(const Flags& f, int _sys_ver) : flags(f), system_version(_sys_ver) { |
741 cmd_type = CMD_NOP; | |
742 argc = 0; | |
743 errorflag = false; | |
744 cmdstr[0] = 0; | |
745 strend = 0; | |
746 pos = -1; | |
747 } | |
748 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
749 /* 演算子 op := 0x5c <uchar op> */ |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
750 /* 数式 exp: [op] <token> [op <token> [...]] */ |
0 | 751 int Cmd::GetExpression(const char*& d, VarInfo* info_ptr) { |
752 #define STACK_DEPTH 1024 | |
753 #define OP_LB 11 | |
754 char op_stack[STACK_DEPTH]; | |
755 int val_stack[STACK_DEPTH]; | |
756 int stack_count = 0; | |
757 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
758 // 第一項の読み込み |
0 | 759 while(*d == 0x28) { |
760 d++; | |
761 dprintf("("); | |
762 op_stack[stack_count++] = OP_LB; | |
763 } | |
764 VarInfo info; | |
765 int value = GetLeftToken(d, info); | |
766 | |
767 while(*d == 0x29 && stack_count > 0 && op_stack[stack_count-1] == OP_LB) { | |
768 d++; | |
769 dprintf(")"); | |
770 stack_count--; | |
771 } | |
772 | |
773 if (*d != 0x5c && stack_count == 0) { | |
774 if (info_ptr) *info_ptr = info; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
775 return value; // 単純なleft-termはここで終了。有効なinfo_ptrを帰す(可能性がある) |
0 | 776 } |
777 | |
778 while(*d == 0x5c) { | |
779 int op_type = *(unsigned char*)(d+1); | |
780 d += 2; | |
781 if (op_type < 70) dprintf("%s",op_str[op_type]); | |
782 else dprintf("err."); | |
783 if (op_type >= 10) SetError(); | |
784 int cur_pri = op_pri(op_type); | |
785 while(stack_count != 0 && op_pri(op_stack[stack_count-1]) <= cur_pri) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
786 // 優先順位の高い、先行する演算を行う |
0 | 787 value = eval(val_stack[stack_count-1], op_stack[stack_count-1], value); |
788 stack_count--; | |
789 } | |
790 val_stack[stack_count] = value; | |
791 op_stack[stack_count++] = op_type; | |
792 while(*d == 0x28) { | |
793 d++; | |
794 dprintf("("); | |
795 op_stack[stack_count++] = OP_LB; | |
796 } | |
797 if (stack_count >= STACK_DEPTH) SetError(); | |
798 value = GetLeftToken(d, info); | |
799 | |
800 while (*d != 0x5c && stack_count > 0) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
801 // 未実行の演算を終わらせる |
0 | 802 if (op_stack[stack_count-1] != OP_LB) { |
803 value = eval(val_stack[stack_count-1], op_stack[stack_count-1], value); | |
804 stack_count--; | |
805 } else if (*d == 0x29) { /* op_stack == OP_LB */ | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
806 // bracket 終端があれば、閉じておく |
0 | 807 d++; |
808 dprintf(")"); | |
809 stack_count--; | |
810 } else break; // error | |
811 } | |
812 } | |
813 if (stack_count) SetError(); // unbalanced bracket | |
814 dprintf("(=%d)",value); | |
815 if (info_ptr) { | |
816 info_ptr->type = TYPE_VAL; | |
817 info_ptr->value = value; | |
818 } | |
819 return value; | |
820 } | |
821 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
822 // 条件分岐専用に、条件演算と算術演算の混合を検知できる専用ルーチン(本来はGetExpressionで差し支えない) |
0 | 823 int Cmd::GetExpressionCond(const char*& d) { |
824 char op_stack[STACK_DEPTH]; | |
825 int val_stack[STACK_DEPTH]; | |
826 int valattr_stack[STACK_DEPTH]; | |
827 #define ATTR_VAL 0 | |
828 #define ATTR_FLAG 1 | |
829 int stack_count = 0; | |
830 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
831 // 第一項の読み込み |
0 | 832 while(*d == 0x28) { |
833 d++; | |
834 dprintf("("); | |
835 op_stack[stack_count++] = OP_LB; | |
836 } | |
837 VarInfo info; | |
838 int value = GetLeftToken(d, info); | |
839 while(*d == 0x29 && stack_count > 0 && op_stack[stack_count-1] == OP_LB) { | |
840 d++; | |
841 dprintf(")"); | |
842 stack_count--; | |
843 } | |
844 bool valattr = ATTR_VAL; | |
845 | |
846 while(*d == 0x5c) { | |
847 int op_type = *(unsigned char*)(d+1); | |
848 d += 2; | |
849 if (op_type < 70) dprintf("%s",op_str[op_type]); | |
850 else dprintf("err."); | |
851 int cur_pri = op_pri_cond(op_type); | |
852 while(stack_count != 0 && op_pri_cond(op_stack[stack_count-1]) <= cur_pri) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
853 // 優先順位の高い、先行する演算を行う |
0 | 854 if (op_stack[stack_count-1] >= 60) { |
855 if (valattr_stack[stack_count-1] != ATTR_FLAG || valattr != ATTR_FLAG) SetError(); | |
856 } else { | |
857 if (valattr_stack[stack_count-1] != ATTR_VAL || valattr != ATTR_VAL) SetError(); | |
858 } | |
859 value = eval(val_stack[stack_count-1], op_stack[stack_count-1], value); | |
860 if (op_stack[stack_count-1] >= 40) valattr = ATTR_FLAG; | |
861 stack_count--; | |
862 } | |
863 val_stack[stack_count] = value; | |
864 valattr_stack[stack_count] = valattr; | |
865 op_stack[stack_count++] = op_type; | |
866 while(*d == 0x28) { | |
867 d++; | |
868 dprintf("("); | |
869 op_stack[stack_count++] = OP_LB; | |
870 } | |
871 if (stack_count >= STACK_DEPTH) SetError(); | |
872 value = GetLeftToken(d, info); | |
873 valattr = ATTR_VAL; | |
874 | |
875 while (*d != 0x5c && stack_count > 0) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
876 // 未実行の演算を終わらせる |
0 | 877 if (op_stack[stack_count-1] != OP_LB) { |
878 if (op_stack[stack_count-1] >= 60) { | |
879 if (valattr_stack[stack_count-1] != ATTR_FLAG || valattr != ATTR_FLAG) SetError(); | |
880 } else { | |
881 if (valattr_stack[stack_count-1] != ATTR_VAL || valattr != ATTR_VAL) SetError(); | |
882 } | |
883 value = eval(val_stack[stack_count-1], op_stack[stack_count-1], value); | |
884 if (op_stack[stack_count-1] >= 40) valattr = ATTR_FLAG; | |
885 stack_count--; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
886 // bracket 終端があれば、閉じておく |
0 | 887 } else if (*d == 0x29) { /* op_stack == OP_LB */ |
888 d++; | |
889 dprintf(")"); | |
890 stack_count--; | |
891 } else break; // error | |
892 } | |
893 } | |
894 if (stack_count) SetError(); // unbalanced bracket | |
895 if (value) dprintf("(=true)"); | |
896 else dprintf("(=false)"); | |
897 return value; | |
898 } | |
899 | |
900 | |
901 /* | |
902 str = | |
903 arg = | |
904 args = 0x28 <exp> [[0x2c] <exp> [[0x2c] <exp> [...] ]] | |
905 */ | |
906 | |
907 int Cmd::GetArgs(const char*& d) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
908 if (*d != 0x28) return 0; /* 引数なし */ |
0 | 909 d++; |
910 dprintf("args:"); | |
911 VarInfo var; | |
912 int i; for (i=0; i<100 ; i++) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
913 /* number, variable, string の種別なく値を得る */ |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
914 if (*d == 0x61) { // よくわからない(智代アフター) |
29
d229cce98f50
* no more (or, at least, less) duplicate code between scn2kdump and the rest
thib
parents:
21
diff
changeset
|
915 dprintf("@%d",d[1]); |
0 | 916 d += 2; |
917 if (*d == 0x28) { | |
918 dprintf("{"); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
919 GetArgs(d); // (A,B,C)節が含まれることがある |
0 | 920 dprintf("}"); |
921 } else { | |
922 dprintf("{}"); | |
923 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
924 } else if (d[0] == 0x0a || d[0] == 0x40) { // よくわからない (Little Busters!) |
0 | 925 int var; |
926 if (system_version == 0) { var = read_little_endian_int(d+1); d += 5;} | |
927 else { var = read_little_endian_short(d+1); d += 3;} | |
928 dprintf("line %d; ",var); | |
929 } else if (*d == 0x24 || (*d == 0x5c && (d[1] == 1 || d[1] == 0)) || *d == 0x28) { | |
930 GetExpression(d, &var); | |
931 args.push_back(var); | |
932 } else if (StrType(d)) { | |
933 var.type = TYPE_STR; | |
934 var.value = GetString(d); | |
935 args.push_back(var); | |
936 } else SetError(); | |
937 if (*d == 0x29) break; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
938 if (*d == 0x2c) {d++;} // 次の arg が演算子で始まる、などがなければ存在しない |
0 | 939 dprintf(","); |
940 } | |
941 if (*d == 0x29) d++; | |
942 else SetError(); | |
943 return i; | |
944 } | |
945 | |
946 int Cmd::GetArgsSpecial(int normal_args,const char*& d) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
947 if (*d != 0x28) return 0; /* 引数なし */ |
0 | 948 d++; |
949 dprintf("args:"); | |
950 int i; for (i=0; i<normal_args; i++) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
951 /* number, variable, string の種別なく値を得る */ |
0 | 952 if (*d == 0x24 || (*d == 0x5c && (d[1] == 1 || d[1] == 0)) || *d == 0x28) { |
953 GetExpression(d); | |
954 } else if (StrType(d)) { | |
955 GetString(d); | |
956 } else SetError(); | |
957 if (*d == 0x29) break; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
958 if (*d == 0x2c) {d++;} // 次の arg が演算子で始まる、などがなければ存在しない |
0 | 959 dprintf(","); |
960 } | |
961 for (i=0; i<argc ; i++) { | |
962 if (*d == 0x28) { | |
963 /* | |
964 ** cmd 01-22:0c1c, 01-22:0835 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
965 ** Princess Bride のカードが落ちるアニメの場面 |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
966 ** なお、_PBCARDANM* の画像はこのコマンドでのみ使われているので、特殊処理として無視することも可能 |
0 | 967 ** |
968 ** cmd 01-04:0276, 026c, 0270 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
969 ** 複数の enum が args の数だけ続く処理。特殊処理として分離する |
0 | 970 */ |
971 dprintf("enum.<"); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
972 /* (...) は列挙型 or 構造体の可能性がある */ |
0 | 973 const char* d_orig = d; |
974 int pt = args.size(); args.push_back(VarInfo(0)); | |
975 int count = GetArgs(d); | |
976 args[pt] = VarInfo(count); | |
977 dprintf(">"); | |
978 } else if (*d == 0x61 && (d[1] >= 0x00 && d[1] <= 0x04) && d[2] == 0x28 ) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
979 /* 使われるコマンドは 01-21:004b, 01-28:0064 のいずれか(R,C,PB,LO) |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
980 ** それらのコマンドは |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
981 ** arg1: 画像ファイル名 |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
982 ** arg2 : Sel 番号 |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
983 ** らしく、arg3 以降が 0x61 <00-04> (a,b,c,...) となる(ダンプ上は enum と表記される) |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
984 ** () 内の引数はさまざまで、a のみ(画像ファイル名)、 |
0 | 985 ** a,b b=SEL? |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
986 ** a,b,c (b,c)=座標? |
0 | 987 ** a,(b,c,d,e,f,g) b-g = src / dest? |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
988 ** らしい |
0 | 989 */ |
990 dprintf("kasane. #%d <",d[1]); | |
991 d += 2; | |
992 int pt = args.size(); args.push_back(VarInfo(0)); | |
993 int count = GetArgs(d); | |
994 args[pt] = VarInfo(count); | |
995 dprintf(">"); | |
996 } else if (*d == 0x24 || (*d == 0x5c && (d[1] == 1 || d[1] == 0))) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
997 /* cmd 01-15:0028 ; 始めに 0x24 節があり、続いて 0x28 節になる */ |
0 | 998 VarInfo var; |
999 GetExpression(d, &var); | |
1000 args.push_back(var); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1001 i--; // この引数はargc の数には入らない |
0 | 1002 } else SetError(); |
1003 if (d[0] == 0x0a || d[0] == 0x40) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1004 /* cmd 01-15:0028 ; 0x28 節の後に毎回 0x0a 節が来る */ |
0 | 1005 int var; |
1006 if (system_version == 0) { var = read_little_endian_int(d+1); d += 5;} | |
1007 else { var = read_little_endian_short(d+1); d += 3;} | |
1008 dprintf("line %d; ",var); | |
1009 } | |
1010 if (*d == 0x29) break; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1011 if (*d == 0x2c) {d++;} // 次の arg が演算子で始まる、などがなければ存在しない |
0 | 1012 dprintf(","); |
1013 } | |
1014 if (*d == 0x29) d++; | |
1015 else SetError(); | |
1016 return 0; | |
1017 } | |
1018 | |
1019 /* switch | |
1020 <exp> | |
1021 0x7b | |
1022 <exp> <int> | |
1023 ... | |
1024 0x7d | |
1025 */ | |
1026 | |
1027 int Cmd::GetSwitch(const char*& d) { | |
1028 if (*d != 0x28) {SetError(); return -1;} | |
1029 d++; | |
1030 dprintf("switch. "); | |
1031 int var = GetExpression(d); | |
1032 if (*d != 0x29) {SetError(); return -1;} | |
1033 d++; | |
1034 dprintf("->\n"); | |
1035 if (*d == 0x7b) { | |
1036 d++; | |
1037 } else SetError(); | |
1038 | |
1039 int default_jmp = -1; int jmpto = -1; | |
1040 int i; for (i=0; i<argc; i++) { | |
1041 dprintf("\t"); | |
1042 if (*d++ != 0x28) {SetError(); return -1;} | |
1043 if (*d != 0x29) { | |
1044 int item = GetExpression(d); | |
1045 if (*d++ != 0x29) {SetError(); return -1;} | |
1046 int jmp = read_little_endian_int(d); | |
1047 if (var == item) { | |
1048 dprintf("(selected)"); | |
1049 jmpto = jmp; | |
1050 } | |
1051 dprintf(" -> %d\n", jmp); | |
1052 } else { | |
1053 d++; | |
1054 default_jmp = read_little_endian_int(d); | |
1055 } | |
1056 d += 4; | |
1057 } | |
1058 if (default_jmp != -1) { | |
1059 dprintf("default -> %d\n",default_jmp); | |
1060 if (jmpto == -1) jmpto = default_jmp; | |
1061 } | |
1062 if (*d == 0x7d) { | |
1063 d++; | |
1064 } else SetError(); | |
1065 return jmpto; | |
1066 } | |
1067 /* simple switch | |
1068 <exp> | |
1069 0x7b | |
1070 <int> | |
1071 ... | |
1072 0x7d | |
1073 */ | |
1074 int Cmd::GetSimpleSwitch(const char*& d) { | |
1075 if (*d != 0x28) {SetError(); return -1;} | |
1076 d++; | |
1077 dprintf("simple switch. "); | |
1078 int var = GetExpression(d); | |
1079 if (*d != 0x29) {SetError(); return -1;} | |
1080 d++; | |
1081 dprintf(" ->\n"); | |
1082 int jumpto = -1; | |
1083 if (*d == 0x7b) { | |
1084 d++; | |
1085 } else SetError(); | |
1086 int i; for (i=0; i<argc; i++) { | |
1087 int j = read_little_endian_int(d); | |
1088 d += 4; | |
1089 dprintf("\t%d -> %d\n", i+1, j); | |
1090 if (var == i) jumpto = j; | |
1091 } | |
1092 if (*d == 0x7d) { | |
1093 d++; | |
1094 } else SetError(); | |
1095 return jumpto; | |
1096 } | |
1097 | |
1098 /* | |
1099 selection | |
1100 ? <exp> | |
1101 0x7b | |
1102 <0x0a|0x40> <ushort | uint> | |
1103 */ | |
1104 void Cmd::GetSelection(const char*& d) { | |
1105 dprintf("selection. "); | |
1106 if (*d == 0x28) { | |
1107 d++; | |
1108 GetExpression(d); | |
1109 if (*d != 0x29) { SetError(); return;} | |
1110 d++; | |
1111 } | |
1112 if (*d == 0x7b) { | |
1113 d++; | |
1114 dprintf("{\n\t"); | |
1115 } else SetError(); | |
1116 int arg_count = 0; | |
1117 string text = ""; | |
1118 int cond_result = false; | |
1119 int sel_no = 0; | |
1120 while(*d != 0x7d) { | |
1121 if (d[0] == 0x0a || d[0] == 0x40) { | |
1122 int var; | |
1123 if (system_version == 0) { var = read_little_endian_int(d+1); d += 5;} | |
1124 else { var = read_little_endian_short(d+1); d += 3;} | |
1125 dprintf("Line %d; ",var); | |
1126 if (text.length() != 0) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1127 if (cond_result) ; // 条件節が true なら表示しない |
0 | 1128 else { |
1129 const char* str = text.c_str(); | |
1130 VarInfo var; | |
1131 var.type = TYPE_STR; | |
1132 var.value = CopyString(str); | |
1133 args.push_back(var); | |
1134 var.type = TYPE_VAL; | |
1135 var.value = sel_no; | |
1136 args.push_back(var); | |
1137 } | |
1138 sel_no++; | |
1139 } | |
1140 text = ""; | |
1141 cond_result = false; | |
1142 } else if (d[0] == 0x2c) { | |
1143 dprintf(":comma:"); | |
1144 } else if (d[0] == 0x28) { | |
1145 dprintf(":cond:"); | |
1146 d++; | |
1147 while(d[0] != 0x29) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1148 int result = GetExpressionCond(d); // PRINT- 節でないばあい、条件表示。次は文字節、またはPRINT節のはず |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1149 if (*d == 0x32) { // 0x32 なら、現在の条件節を表示しない |
0 | 1150 d++; dprintf("##"); |
1151 cond_result = result; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1152 } else if (*d == 0x31) { // 0x31 なら、現在の条件節を表示する |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1153 // Little Busters! : この条件で正しいかは未検証 |
0 | 1154 d++; dprintf("***"); |
1155 cond_result = !result; | |
1156 } | |
1157 dprintf(":"); | |
1158 } | |
1159 d++; | |
1160 } else if (StrType(d)) { | |
1161 int strpt = GetString(d); | |
1162 text += strheap + strpt; | |
1163 arg_count++; | |
1164 dprintf("\n\t"); | |
1165 } else if (*d == 0x23 && strncmp(d,"###PRINT",8) == 0) { | |
1166 d += 8; | |
1167 if (d[0] != 0x28) SetError(); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1168 else { // 文字変数の内容の表示 |
0 | 1169 d++; |
1170 dprintf("Print."); | |
1171 VarInfo info; | |
1172 GetLeftToken(d, info); | |
1173 if (d[0] != 0x29 || info.type == -1) SetError(); | |
1174 d++; | |
21
d1bb7b365816
Fixed dynamic strings in selections (Fuko Pranks for instance)
thib
parents:
13
diff
changeset
|
1175 dprintf(";");/* |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1176 // 数値を全角文字に変換して登録 |
0 | 1177 char str[10], str2[20]; // itoa |
1178 sprintf(str, "%d", info.value); | |
1179 int i; for (i=0; str[i] != 0; i++) { | |
1180 str2[i*2] = 0xa3; | |
1181 str2[i*2+1] = 0xb0 + str[i]-'0'; | |
1182 } | |
21
d1bb7b365816
Fixed dynamic strings in selections (Fuko Pranks for instance)
thib
parents:
13
diff
changeset
|
1183 str2[i*2] = 0;*/ |
d1bb7b365816
Fixed dynamic strings in selections (Fuko Pranks for instance)
thib
parents:
13
diff
changeset
|
1184 text += strheap + info.value; |
0 | 1185 } |
1186 } else { SetError(); break;} | |
1187 } | |
1188 d++; | |
1189 /* @@@ */ | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1190 /* 一致しない場合があるのでコメントアウト */ |
0 | 1191 // if (arg_count != argc) SetError(); |
1192 dprintf("\n}\n"); | |
1193 } | |
1194 | |
1195 void Cmd::GetCmd(Flags& flags_orig, const char*& d ) { | |
52 | 1196 if (d == NULL) { SetError(); return;} |
0 | 1197 if (cmd_type != CMD_NOP) return; |
1198 | |
1199 cmdstr[0] = 0; | |
1200 rawdata = d; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1201 if (*d == 0x23) { /* コマンド */ |
0 | 1202 cmd_type = CMD_OTHER; |
1203 cmd1 = *(unsigned const char*)(d+1); | |
1204 cmd2 = *(unsigned const char*)(d+2); | |
1205 cmd3 = read_little_endian_short(d+3); | |
1206 argc = read_little_endian_short(d+5); | |
1207 cmd4 = *(unsigned const char*)(d+7); | |
1208 d += 8; | |
1209 /* verbose */ | |
1210 // 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
|
1211 sprintf(cmdstr, "%02x-%02x:%04x:%02x : %s",cmd1,cmd2,cmd3,cmd4, CmdDescr(cmd1,cmd2,cmd3,cmd4)); |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1212 /* 引数を得る */ |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1213 /* 特殊引数のもの */ |
0 | 1214 int is_special = 0; |
1215 if (cmd1 == 0) { | |
1216 if (cmd2 == 1) { | |
1217 int jump_arg = -1; | |
1218 if (cmd3 == 0 || cmd3 == 5) { | |
1219 /* gosub / goto */ | |
1220 jump_arg =read_little_endian_int(d); | |
1221 d += 4; | |
1222 if (cmd3 == 0) | |
1223 dprintf("\tjmp -> %d\n", jump_arg); | |
1224 else /* cmd3 == 5 */ | |
1225 dprintf("\tcall -> %d\n", jump_arg); | |
1226 is_special = 1; | |
1227 } else if (cmd3 == 1 || cmd3 == 2) { | |
1228 /* conditional jump (if / unless) */ | |
1229 if (*d++ != 0x28) { SetError(); return;} | |
1230 dprintf("\t"); | |
1231 int cond = GetExpressionCond(d); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1232 if (cmd3 == 1) cond = !cond; // 逆になる |
0 | 1233 if (*d++ != 0x29) { SetError(); return; } |
1234 int jumpto = read_little_endian_int(d); | |
1235 d += 4; | |
1236 dprintf("-> %d\n", jumpto); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1237 if (! cond) jump_arg = jumpto; /* condition が満たされない場合、ジャンプ */ |
0 | 1238 is_special = 1; |
1239 } else if (cmd3 == 4) { | |
1240 /* switch to */ | |
1241 jump_arg = GetSwitch(d); | |
1242 is_special = 1; | |
1243 } else if (cmd3 == 8 || cmd3 == 3) { | |
1244 /* switch to */ | |
1245 jump_arg = GetSimpleSwitch(d); | |
1246 is_special = 1; | |
1247 } else if (cmd3 == 16) { // call with parameters | |
1248 GetArgs(d); | |
1249 jump_arg = read_little_endian_int(d); | |
1250 d += 4; | |
1251 is_special = 1; | |
1252 } else goto retry; | |
1253 if (jump_arg == -1) { | |
1254 cmd_type = CMD_NOP; | |
1255 } | |
1256 else { | |
1257 cmd_type = CMD_JMP; | |
1258 args.push_back(VarInfo(jump_arg)); | |
1259 } | |
1260 } else if (cmd2 == 2 && (cmd3 == 0 || cmd3 == 1 || cmd3 == 2 || cmd3 == 3 || cmd3 == 0x0d) ) { | |
1261 /* selection */ | |
1262 GetSelection(d); | |
1263 is_special = 1; | |
1264 } | |
1265 } | |
1266 retry: | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1267 /* 一般引数のもの */ |
0 | 1268 if (!is_special) { |
29
d229cce98f50
* no more (or, at least, less) duplicate code between scn2kdump and the rest
thib
parents:
21
diff
changeset
|
1269 dprintf(" 0x23 - cmd %02x-%02x:%04x:%02x[%2d] : %s\n",cmd1,cmd2,cmd3,cmd4,argc,CmdDescr(cmd1,cmd2,cmd3,cmd4)); |
0 | 1270 dprintf("\t"); |
1271 if (cmd1 == 1 && cmd2 == 0x22 && (cmd3 == 0xc1c || cmd3 == 0x835)) GetArgsSpecial(3, d); | |
1272 else if (cmd1 == 1 && cmd2 == 0x0b && cmd3 == 0x65) GetArgsSpecial(0, d); | |
1273 else if (cmd1 == 1 && cmd2 == 0x15 && cmd3 == 0x28) GetArgsSpecial(0, d); | |
1274 else if (cmd1 == 1 && cmd2 == 4 && (cmd3 == 0x26c || cmd3 == 0x26d || cmd3 == 0x270 || cmd3 == 0x276)) GetArgsSpecial(0, d); | |
1275 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
|
1276 else if (cmd1 == 1 && ((cmd2 == 0x21 && cmd3 == 0x4b) || (cmd2 == 0x28 && cmd3 == 0x64))) GetArgsSpecial(2,d); |
0 | 1277 else GetArgs(d); |
1278 dprintf("\n"); | |
1279 | |
1280 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1281 } else if (*d == 0x24) { /* 代入演算 */ |
0 | 1282 if (d[1] == 0x12 || d[2] != 0x5b) SetError(); |
1283 dprintf("expr: "); | |
1284 sprintf(cmdstr, "expr"); | |
1285 | |
1286 VarInfo info; | |
1287 int value = GetLeftToken(d, info); | |
1288 if (d[0] != 0x5c) SetError(); | |
1289 int type = d[1]; | |
1290 if (type < 20 || type > 30) SetError(); | |
1291 else dprintf("%s",op_str[type]); | |
1292 d += 2; | |
1293 int value2 = GetExpression(d); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1294 // 代入情報を埋め込む |
0 | 1295 if (type != 30) value2 = eval(value, type-20, value2); |
1296 cmd_type = CMD_FLAGS; | |
1297 args.push_back(info); | |
1298 args.push_back(value2); | |
1299 dprintf("\n"); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1300 } else if (StrType(d)) { /* 文字出力 */ |
0 | 1301 VarInfo info; |
1302 info.type = TYPE_STR; | |
1303 info.value = GetString(d); | |
1304 args.push_back(info); | |
1305 cmd_type = CMD_TEXT; | |
1306 dprintf("\n"); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1307 } else if (*d == 0x0a || *d == 0x40 || *d == 0x21) { /* デバッグ用データと既読フラグ */ |
0 | 1308 cmd_type = CMD_NOP; |
1309 if (*d == 0x0a) { | |
1310 dprintf("line "); | |
1311 d++; | |
1312 int l; | |
1313 if (system_version == 0) { | |
1314 l = read_little_endian_int(d); | |
1315 d += 4; | |
1316 } else { | |
1317 l = read_little_endian_short(d); | |
1318 d += 2; | |
1319 } | |
1320 dprintf("%d\n", l); | |
1321 } else { /* 0x40, 0x21 */ | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1322 // 既読マーカーらしい。エントリーポイントとセーブポイントも使われる。 |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1323 // RealLive 1.2.5から、0x40はセーブポイント、0x21はエントリーポイント。 |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1324 // 1.2.5以前、どちらも0x40が使われる。 |
0 | 1325 int kidoku_index; |
1326 d++; | |
1327 if (system_version == 0) { | |
1328 kidoku_index = read_little_endian_int(d); | |
1329 d += 4; | |
1330 } else { | |
1331 kidoku_index = read_little_endian_short(d); | |
1332 d += 2; | |
1333 } | |
1334 dprintf("kidoku marker %d\n", kidoku_index); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1335 // text_readflagは、このkidoku_indexを使ったら良いかな。 |
0 | 1336 } |
1337 } else if (*d == 0x2c) { /* ??? */ | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1338 dprintf("commd;0x2c\n"); // conditional jump の行き先によくあるらしい(常に、かはわからない) |
0 | 1339 d++; |
1340 } else { | |
1341 SetError(); | |
1342 } | |
1343 } | |
52 | 1344 |
0 | 1345 void Cmd::clear(void) { |
1346 cmd_type = CMD_NOP; | |
1347 ResetString(); | |
1348 args.clear(); | |
1349 errorflag = false; | |
1350 pos = -1; | |
1351 } | |
1352 | |
1353 char Cmd::strtype[256] = { | |
1354 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* +00 */ | |
1355 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* +10 */ // 0123456789ABCDEF | |
1356 1,0,3,0, 0,0,0,1, 0,0,0,0, 0,1,1,0, /* +20 */ // !"#$%&'()*+,-./ | |
1357 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, /* +30 */ // 0123456789:;<=>? | |
1358 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, /* +40 */ // @ABCDEFGHIJKLMNO | |
1359 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, /* +50 */ // PQRSTUVWXYZ[\]^_ | |
1360 0,0,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, /* +60 */ // `abcdefghijklmno | |
1361 1,1,1,1, 1,1,1,1, 1,1,1,1, 0,0,0,0, /* +70 */ // pqrstuvwxyz{|}~ | |
1362 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, /* +80 */ | |
1363 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, /* +90 */ | |
1364 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* +A0 */ | |
1365 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* +B0 */ | |
1366 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* +C0 */ | |
1367 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* +D0 */ | |
1368 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, /* +E0 */ | |
1369 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,0,0 /* +F0 */ | |
1370 }; | |
1371 | |
1372 int Cmd::GetString(const char*& d) { | |
1373 int retnum = -1; | |
1374 bool quote_flag = false; | |
1375 int stype; | |
1376 retnum = strend; | |
1377 while(1) { | |
1378 if (*d == '\\') { | |
1379 d++; | |
1380 strheap[strend++] = *d++; | |
1381 } else if (*d == '"') { | |
1382 if (quote_flag) quote_flag = false; | |
1383 else quote_flag = true; | |
1384 d++; | |
1385 } else if (quote_flag) { | |
1386 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
|
1387 } else if ((stype = StrType(d))) { |
0 | 1388 strheap[strend++] = *d++; |
1389 if (stype == 2) strheap[strend++] = *d++; | |
1390 } else break; | |
1391 } | |
1392 strheap[strend++] = 0; | |
1393 dprintf("\"%s\"", strheap + retnum); | |
1394 if (strend >= STRHEAP_SIZE) { | |
1395 dprintf("Error: string heap overflow\n"); | |
1396 } | |
1397 return retnum; | |
1398 } | |
1399 | |
1400 int Cmd::CopyString(const char* d) { | |
1401 int retnum = strend; | |
1402 int len = strlen(d); | |
1403 memcpy(strheap+strend, d, len+1); | |
1404 strend += len+1; | |
1405 d += len+1; | |
1406 return retnum; | |
1407 } | |
1408 | |
1409 int Cmd::StrVar(int type, int var_num) { | |
1410 int retnum = strend; | |
1411 flags.Str(type, var_num, strheap+strend, STRHEAP_SIZE-strend); | |
1412 strend += strlen(strheap+strend)+1; | |
1413 return retnum; | |
1414 } | |
1415 | |
1416 void Cmd::SetSysvar(int n, int val) { | |
1417 VarInfo info; | |
1418 if (cmd_type != CMD_SYSVAR) { | |
1419 args.clear(); | |
1420 } | |
1421 cmd_type = CMD_SYSVAR; | |
1422 | |
1423 info.type = TYPE_SYS; | |
1424 info.number = n; | |
1425 info.value = val; | |
1426 args.push_back(info); | |
1427 } | |
1428 void Cmd::SetFlagvar(VarInfo info, int val) { | |
1429 if (cmd_type != CMD_SYSVAR) { | |
1430 args.clear(); | |
1431 } | |
1432 cmd_type = CMD_SYSVAR; | |
1433 | |
1434 info.value = val; | |
1435 args.push_back(info); | |
1436 } | |
1437 | |
1438 void Cmd::SetStrvar(VarInfo info, const string& s) { | |
1439 if (cmd_type != CMD_SYSVAR) { | |
1440 args.clear(); | |
1441 } | |
1442 | |
1443 cmd_type = CMD_SYSVAR; | |
1444 const char* ss = s.c_str(); | |
1445 info.value = CopyString(ss); | |
1446 args.push_back(info); | |
1447 } | |
1448 | |
52 | 1449 |
1450 const char* Cmd::Str(const VarInfo& info) const { | |
1451 if (info.type != TYPE_STR && info.type != TYPE_VARSTR && info.type != TYPE_VARLOCSTR && info.type != TYPE_VARSYSSTR) | |
1452 return ""; | |
1453 int pt = info.value; | |
1454 if (pt < 0 || pt >= STRHEAP_SIZE) return ""; | |
1455 return strheap + pt; | |
1456 } | |
1457 | |
1458 int Cmd::AddStr(char* s) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1459 // 1-0a-0064 はこういうものが必要らしい |
52 | 1460 int start = strend; |
1461 while (*s) strheap[strend++] = *s++; | |
1462 strheap[strend++] = 0; | |
1463 return start; | |
1464 } | |
1465 | |
1466 | |
0 | 1467 void Cmd::read(const CmdSimplified& from) { |
1468 errorflag = false; | |
1469 ResetString(); | |
1470 | |
1471 cmd_type = Cmdtype(from.type); | |
1472 cmd1 = from.cmd1; | |
1473 cmd2 = from.cmd2; | |
1474 cmd3 = from.cmd3; | |
1475 cmd4 = from.cmd4; | |
1476 argc = from.argc; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1477 /* args の読み込み */ |
0 | 1478 args.clear(); |
1479 char* d = from.args; | |
52 | 1480 if (d == NULL) return; |
0 | 1481 while(*d != TYPE_END) { |
1482 VarInfo info; | |
1483 switch(*d) { | |
1484 case TYPE_VAL: | |
1485 info.type = TYPE_VAL; | |
1486 info.number = 0; | |
1487 info.value = read_little_endian_int(d+1); | |
1488 d += 5; | |
1489 args.push_back(info); | |
1490 break; | |
1491 case TYPE_STR: | |
1492 info.type = TYPE_STR; | |
1493 info.number = 0; | |
1494 d++; | |
1495 info.value = CopyString( d); | |
1496 d += strlen(d)+1; | |
1497 args.push_back(info); | |
1498 break; | |
1499 default: | |
1500 fprintf(stderr,"Cmd::read: Invalid Load Data\n"); | |
1501 *d = TYPE_END; | |
1502 } | |
1503 } | |
1504 } | |
52 | 1505 |
0 | 1506 void Cmd::write(CmdSimplified& to, char*& buffer) const { |
1507 /* | |
1508 if (cmd_type != CMD_OTHER) { | |
1509 fprintf(stderr,"Cmd::write: Invalid Cmd during Saving Data\n"); | |
1510 to.cmd1 = 0; to.cmd2 = 0; to.cmd3 = 0; to.cmd4 = 0; to.argc = 0; to.args = 0; | |
1511 return; | |
1512 } | |
1513 */ | |
1514 to.type = cmd_type; | |
1515 to.cmd1 = cmd1; | |
1516 to.cmd2 = cmd2; | |
1517 to.cmd3 = cmd3; | |
1518 to.cmd4 = cmd4; | |
1519 to.argc = argc; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1520 /* args の書き込み */ |
0 | 1521 if (args.empty()) { |
52 | 1522 to.args = NULL; |
0 | 1523 } else { |
1524 to.args = buffer; | |
1525 char* d = to.args; | |
1526 vector<VarInfo>::const_iterator it; | |
1527 for (it = args.begin(); it != args.end(); it++) { | |
1528 int type = it->type; | |
1529 if ( (type >= 0 && type < 7) || type == TYPE_VAL || type == char(TYPE_SYS)) { // digits | |
1530 *d++ = TYPE_VAL; | |
1531 write_little_endian_int(d, it->value); | |
1532 d += 4; | |
1533 } else if (type == TYPE_VARSTR || type == TYPE_VARSYSSTR || type == TYPE_VARLOCSTR || type == TYPE_STR) { // string | |
1534 *d++ = TYPE_STR; | |
1535 const char* s = Str(*it); | |
1536 int len = strlen(s); | |
1537 memcpy(d, s, len+1); | |
1538 d += len+1; | |
1539 } else { | |
1540 fprintf(stderr,"Cmd::write: Invalid Cmd args during Saving Data\n"); | |
1541 } | |
1542 } | |
1543 *d++ = TYPE_END; | |
1544 buffer = d; | |
1545 } | |
1546 } | |
52 | 1547 |
0 | 1548 void CmdSimplified::copy(const CmdSimplified& from, char*& args_buffer) { |
1549 *this = from; | |
52 | 1550 if (args == NULL) return; |
0 | 1551 char* args_old = from.args; |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1552 /* args のコピー */ |
0 | 1553 while(*args_old != TYPE_END) { |
1554 if (*args_old == TYPE_VAL) { | |
1555 args_old += 5; | |
1556 } else { /* TYPE_STR */ | |
1557 args_old += strlen(args_old)+1; | |
1558 } | |
1559 } | |
1560 args_old++; | |
1561 int args_len = args_old - from.args; | |
1562 memmove(args_buffer, from.args, args_len); | |
1563 args = args_buffer; | |
1564 args_buffer += args_len; | |
1565 } | |
52 | 1566 |
0 | 1567 void CmdSimplified::Save(string& saveret) { |
1568 char buf[1024]; | |
1569 sprintf(buf, "%02x-%02x:%04x:%02x(%02d),", cmd1, cmd2, cmd3, cmd4, argc); | |
1570 saveret += buf; | |
1571 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1572 /* args のコピー */ |
0 | 1573 char* d = args; |
1574 while(d && *d != TYPE_END) { | |
1575 if (*d == TYPE_VAL) { | |
1576 d++; | |
1577 sprintf(buf, "%d,", read_little_endian_int(d)); | |
1578 d += 4; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1579 } else { /* TYPE_STR と仮定 */ |
0 | 1580 d++; |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1581 if (strlen(d) > 1000) d[1000] = 0; // ありえない・・・ |
0 | 1582 int i; int cnt = 0; |
1583 buf[cnt++] = '"'; | |
1584 for (i=0; d[i] != 0; i++) { | |
1585 if (d[i] == '"') buf[cnt++] = '"'; | |
1586 buf[cnt++] = d[i]; | |
1587 } | |
1588 buf[cnt++]='"'; | |
1589 buf[cnt++] = ','; | |
1590 buf[cnt++] = 0; | |
1591 d += strlen(d)+1; | |
1592 } | |
1593 saveret += buf; | |
1594 } | |
1595 saveret += 'E'; | |
1596 } | |
1597 | |
1598 void CmdSimplified::Load(const char* save, char*& args_buffer) { | |
1599 args = args_buffer; | |
1600 | |
1601 type = CMD_OTHER; | |
1602 sscanf(save, "%02x-%02x:%04x:%02x(%02d),", &cmd1, &cmd2, &cmd3, &cmd4, &argc); | |
1603 save = strchr(save, ','); | |
52 | 1604 if (save == NULL) { |
0 | 1605 *args_buffer++ = TYPE_END; |
1606 return; | |
1607 } | |
1608 save++; | |
1609 while(*save != 'E' && *save != '\n' && *save != '\0') { | |
1610 if (isdigit(*save)) { | |
1611 int v; | |
1612 sscanf(save,"%d,",&v); | |
1613 *args_buffer++ = TYPE_VAL; | |
1614 write_little_endian_int(args_buffer, v); | |
1615 args_buffer+= 4; | |
1616 save = strchr(save, ','); | |
1617 if (save) save++; | |
1618 } else { // *save == '"' | |
1619 save++; | |
1620 *args_buffer++ = TYPE_STR; | |
1621 while(1) { | |
1622 if (*save == 0) break; | |
1623 if (*save == '"') { | |
1624 if (save[1] != '"') break; | |
1625 save++; | |
1626 } | |
1627 *args_buffer++ = *save++; | |
1628 } | |
1629 save += 2; | |
1630 *args_buffer++ = 0; | |
1631 } | |
1632 } | |
1633 *args_buffer++ = TYPE_END; | |
1634 } | |
1635 | |
1636 #ifdef SCN_DUMP | |
1637 void usage(void) { | |
1638 fprintf(stderr,"usage : scn2kdump [inputfile] [outputfile]\n"); | |
1639 fprintf(stderr," inputfile: seen.txt(default)\n"); | |
1640 fprintf(stderr," outputfile: seen.txt_out(default)\n"); | |
1641 exit(-1); | |
1642 } | |
1643 int main(int argc, char** argv) { | |
1644 /* determine file names */ | |
1645 bool verbose = false; | |
1646 char* inname = "seen.txt"; | |
52 | 1647 char* outname = NULL; |
0 | 1648 if (argc > 2 && strcmp(argv[1],"-v") == 0) { |
1649 int i; for (i=1; i<argc; i++) argv[i] = argv[i+1]; | |
1650 argc--; | |
1651 verbose = true; | |
1652 } | |
1653 switch(argc) { | |
52 | 1654 case 1: break; |
1655 case 2: | |
1656 inname = argv[1]; | |
1657 break; | |
1658 case 3: | |
1659 inname = argv[1]; | |
1660 outname = argv[2]; | |
1661 break; | |
1662 default: usage(); | |
0 | 1663 } |
1664 /* open output file */ | |
1665 FILE* outstream = stdout; | |
1666 /* create archive instance */ | |
1667 SCN2kFILE archive(inname); | |
1668 archive.Init(); | |
1669 if (archive.Deal() == 0) { | |
1670 fprintf(stderr,"Cannot open / Invalid archive file %s\n",inname); | |
1671 usage(); | |
1672 } | |
1673 /* dump files */ | |
1674 archive.InitList(); | |
1675 char* fname; | |
1676 fprintf(stderr,"Dump start\n"); | |
1677 int system_version = 0; | |
1678 while( (fname = archive.ListItem()) != 0) { | |
1679 ARCINFO* info = archive.Find(fname,""); | |
52 | 1680 if (info == NULL) continue; |
0 | 1681 char* data = info->CopyRead(); |
1682 char* d = data; | |
1683 char* dend = d + info->Size(); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1684 /* version 確認 */ |
0 | 1685 if (read_little_endian_int(d) == 0x1cc) { |
1686 system_version = 0; | |
1687 } else if (read_little_endian_int(d) == 0x1d0) { | |
1688 system_version = 1; | |
1689 } else { | |
1690 continue; | |
1691 } | |
1692 if (read_little_endian_int(d+4) == 0x1adb2) ; // little busters! | |
1693 else if (read_little_endian_int(d+4) != 0x2712) continue; | |
1694 int header_size; | |
1695 if (system_version == 0) { | |
1696 header_size = 0x1cc + read_little_endian_int(d+0x20) * 4; | |
1697 } else { | |
1698 header_size = read_little_endian_int(d+0x20); | |
1699 } | |
1700 d += header_size; | |
1701 | |
1702 const char* dcur = d; | |
1703 const char* dstart = d; | |
1704 fprintf(stderr,"Dumping %s\n",fname); | |
1705 Flags flags; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
63
diff
changeset
|
1706 /* 最初から最後までコマンド取得 -> 出力を繰り返す */ |
0 | 1707 while(dcur<dend) { |
1708 const char* dprev = dcur; | |
1709 Cmd cmd(flags, system_version); cmd.ClearError(); | |
1710 | |
1711 /* end? */ | |
1712 if (*dcur == -1) { | |
1713 /* 0xff x 32byte + 0x00 : end sign */ | |
1714 int i; for (i=0; i<0x20; i++) | |
1715 if (dcur[i] != -1) break; | |
1716 if (i == 0x20 && dcur[i] == 0) break; | |
1717 } | |
1718 dprintf("%d : ",dcur-dstart); | |
1719 cmd.GetCmd(flags, dcur); | |
1720 if (cmd.IsError()) { | |
1721 fprintf(outstream, "Error at %6d\n",dprev-dstart); | |
1722 while(dcur < dend) { | |
1723 if (*dcur == 0x29 && dcur[1] == 0x0a) {dcur++;break;} | |
1724 dcur++; | |
1725 } | |
1726 dprev -= 2*16; | |
1727 int ilen = (dcur-dprev+15)/16; | |
1728 int i; for (i=0; i<ilen; i++) { | |
1729 fprintf(outstream, "%6d: ",dprev-dstart); | |
1730 int j; for (j=0; j<16; j++) { | |
1731 if (dprev >= dend) break; | |
1732 if (dprev < data) continue; | |
1733 fprintf(outstream, "%02x ",*(unsigned char*)(dprev)); | |
1734 dprev++; | |
1735 } | |
1736 fprintf(outstream, "\n"); | |
1737 } | |
1738 } | |
1739 } | |
1740 delete info; | |
1741 } | |
1742 return 0; | |
1743 } | |
1744 #endif | |
1745 |