Mercurial > otakunoraifu
comparison scn2k/scn2k_cmd.cc @ 52:15a18fbe6f21
* Known bugs added to the README
* Code cleaning (0 -> NULL when needed, indentation, spaces, ...)
author | thib |
---|---|
date | Sat, 18 Apr 2009 18:35:39 +0000 |
parents | 5f548e5957a8 |
children | d7cde171a1de |
comparison
equal
deleted
inserted
replaced
51:cbb301016a4e | 52:15a18fbe6f21 |
---|---|
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 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. | 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 */ | 26 */ |
27 | 27 |
28 | 28 |
29 #include"scn2k.h" | 29 #include "scn2k.h" |
30 | 30 |
31 #include<stdlib.h> | 31 #include <stdlib.h> |
32 #include<stdarg.h> | 32 #include <stdarg.h> |
33 #include<stdio.h> | 33 #include <stdio.h> |
34 #include<string.h> | 34 #include <string.h> |
35 #include<string> | 35 #include <string> |
36 #include"system/file.h" | 36 #include "system/file.h" |
37 | 37 |
38 using namespace std; | 38 using namespace std; |
39 | 39 |
40 | 40 |
41 // #define SCN_DUMP | 41 // #define SCN_DUMP |
45 | 45 |
46 //bool debug_flag = true; | 46 //bool debug_flag = true; |
47 bool debug_flag = false; | 47 bool debug_flag = false; |
48 void dprintf(const char* fmt, ...) { | 48 void dprintf(const char* fmt, ...) { |
49 if (debug_flag) { | 49 if (debug_flag) { |
50 va_list ap; va_start(ap, fmt); | 50 va_list ap; |
51 va_start(ap, fmt); | |
51 vprintf(fmt, ap); | 52 vprintf(fmt, ap); |
52 va_end(ap); | 53 va_end(ap); |
53 } | 54 } |
54 } | 55 } |
55 | 56 |
160 } | 161 } |
161 | 162 |
162 void Flags::SetSys(int value) { | 163 void Flags::SetSys(int value) { |
163 sys = value; | 164 sys = value; |
164 } | 165 } |
166 | |
165 void Flags::SetStr(VarInfo info, string val) { | 167 void Flags::SetStr(VarInfo info, string val) { |
166 switch(info.type) { | 168 switch(info.type) { |
167 case TYPE_VARLOCSTR: | 169 case TYPE_VARLOCSTR: |
168 if (info.number >= 3) return; | 170 if (info.number >= 3) return; |
169 loc_str[info.number] = val; | 171 loc_str[info.number] = val; |
170 break; | 172 break; |
171 case TYPE_VARSYSSTR: | 173 case TYPE_VARSYSSTR: |
172 if (info.number >= 2000) return; | 174 if (info.number >= 2000) return; |
173 sys_str[info.number] = val; | 175 sys_str[info.number] = val; |
174 break; | 176 break; |
175 case TYPE_VARSTR: | 177 case TYPE_VARSTR: |
176 if (info.number >= 2000) return; | 178 if (info.number >= 2000) return; |
177 str[info.number] = val; | 179 str[info.number] = val; |
178 break; | 180 break; |
179 } | 181 } |
180 return; | 182 return; |
181 } | 183 } |
184 | |
182 void Flags::Str(int type, unsigned int number, char* buf, int sz) const { | 185 void Flags::Str(int type, unsigned int number, char* buf, int sz) const { |
183 if (sz <= 0) return; | 186 if (sz <= 0) return; |
184 buf[0] = 0; | 187 buf[0] = 0; |
185 const string* sptr; | 188 const string* sptr; |
186 switch(type) { | 189 switch(type) { |
187 case TYPE_VARLOCSTR: | 190 case TYPE_VARLOCSTR: |
188 if (number >= 3) return; | 191 if (number >= 3) return; |
189 sptr = &loc_str[number]; | 192 sptr = &loc_str[number]; |
190 break; | 193 break; |
191 case TYPE_VARSYSSTR: | 194 case TYPE_VARSYSSTR: |
192 if (number >= 2000) return; | 195 if (number >= 2000) return; |
193 sptr = &sys_str[number]; | 196 sptr = &sys_str[number]; |
194 break; | 197 break; |
195 case TYPE_VARSTR: | 198 case TYPE_VARSTR: |
196 if (number >= 2000) return; | 199 if (number >= 2000) return; |
197 sptr = &str[number]; | 200 sptr = &str[number]; |
198 break; | 201 break; |
199 } | 202 } |
200 | 203 |
201 int len = sptr->length(); | 204 int len = sptr->length(); |
202 if (sz-1 > len) sz = len; | 205 if (sz-1 > len) sz = len; |
203 sptr->copy(buf, sz, 0); | 206 sptr->copy(buf, sz, 0); |
204 buf[sz] = 0; | 207 buf[sz] = 0; |
205 return; | 208 return; |
206 } | 209 } |
210 | |
207 string Flags::Str(int type, unsigned int number) const { | 211 string Flags::Str(int type, unsigned int number) const { |
208 switch(type) { | 212 switch(type) { |
209 case TYPE_VARLOCSTR: | 213 case TYPE_VARLOCSTR: |
210 if (number >= 3) return ""; | 214 if (number >= 3) return ""; |
211 return loc_str[number]; | 215 return loc_str[number]; |
236 sprintf(buf, "V<C>[%04d]=%s\n", j, str[j].c_str()); | 240 sprintf(buf, "V<C>[%04d]=%s\n", j, str[j].c_str()); |
237 save += buf; | 241 save += buf; |
238 } | 242 } |
239 } | 243 } |
240 } | 244 } |
245 | |
241 void Flags::Load(const char* save) { | 246 void Flags::Load(const char* save) { |
242 int i,j; | 247 int i,j; |
243 for (i=0; i<=TYPE_NONSYSVARMAX; i++) { | 248 for (i=0; i<=TYPE_NONSYSVARMAX; i++) { |
244 for (j=0; j<2000; j++) { | 249 for (j=0; j<2000; j++) { |
245 var[i][j] = 0; | 250 var[i][j] = 0; |
279 } | 284 } |
280 save = strchr(save, '\n'); | 285 save = strchr(save, '\n'); |
281 if (save) save++; | 286 if (save) save++; |
282 } while (save); | 287 } while (save); |
283 } | 288 } |
284 return; | 289 } |
285 } | 290 |
286 | 291 void Flags::SaveSys(string& save) { //FIXME: see how to factorize with Save |
287 void Flags::SaveSys(string& save) { | |
288 char buf[1024]; | 292 char buf[1024]; |
289 int j; | 293 int j; |
290 save = "\n[Flags]\n"; | 294 save = "\n[Flags]\n"; |
291 for (j=0; j<2000; j++) { | 295 for (j=0; j<2000; j++) { |
292 if (var[6][j] != 0) { | 296 if (var[6][j] != 0) { |
305 sprintf(buf, "V<M>[%04d]=%s\n", j, sys_str[j].c_str()); | 309 sprintf(buf, "V<M>[%04d]=%s\n", j, sys_str[j].c_str()); |
306 save += buf; | 310 save += buf; |
307 } | 311 } |
308 } | 312 } |
309 } | 313 } |
310 void Flags::LoadSys(const char* save) { | 314 |
315 void Flags::LoadSys(const char* save) { //FIXME: Same as Save and SaveSys | |
311 int i,j; | 316 int i,j; |
312 for (i=6; i<=7; i++) { | 317 for (i=6; i<=7; i++) { |
313 for (j=0; j<2000; j++) { | 318 for (j=0; j<2000; j++) { |
314 var[i][j] = 0; | 319 var[i][j] = 0; |
315 } | 320 } |
350 } | 355 } |
351 save = strchr(save, '\n'); | 356 save = strchr(save, '\n'); |
352 if (save) save++; | 357 if (save) save++; |
353 } while (save); | 358 } while (save); |
354 } | 359 } |
355 return; | |
356 } | 360 } |
357 | 361 |
358 bool Flags::Exec(Cmd& cmd) { | 362 bool Flags::Exec(Cmd& cmd) { |
359 if (cmd.cmd_type == CMD_FLAGS) { // 代入演算 | 363 if (cmd.cmd_type == CMD_FLAGS) { // 代入演算 |
360 if (cmd.args.size() != 2) return false; | 364 if (cmd.args.size() != 2) return false; |
363 return true; | 367 return true; |
364 } | 368 } |
365 if (cmd.cmd1 == 1 && cmd.cmd2 == 0x0a) { // 文字列演算 | 369 if (cmd.cmd1 == 1 && cmd.cmd2 == 0x0a) { // 文字列演算 |
366 VarInfo arg1 = cmd.args[0]; | 370 VarInfo arg1 = cmd.args[0]; |
367 switch(cmd.cmd3) { | 371 switch(cmd.cmd3) { |
368 case 0: | 372 case 0: |
369 if (cmd.cmd4 == 0) { | 373 if (cmd.cmd4 == 0) { |
370 SetStr(arg1, cmd.Str(cmd.args[1])); | 374 SetStr(arg1, cmd.Str(cmd.args[1])); |
371 } else if (cmd.cmd4 == 1) { | 375 } else if (cmd.cmd4 == 1) { |
372 string s = cmd.Str(cmd.args[1]); | 376 string s = cmd.Str(cmd.args[1]); |
373 const char* sc = s.c_str(); | 377 const char* sc = s.c_str(); |
374 int len = cmd.args[2].value; | 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(); | |
408 } | |
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); | |
426 cmd.clear(); | |
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 文字を読み飛ばす | |
375 int i; | 439 int i; |
376 for (i=0; i < sc[i] && len != 0; i++, len--) { | 440 int offset_top = 0; |
377 if (sc[i]<0 && sc[i+1]!=0) i++; | 441 for (i=0; i<offset && s[offset_top] != 0; i++) { |
378 } | 442 if (s[offset_top] < 0 && s[offset_top+1] != 0) offset_top += 2; |
379 s.erase(i); // 全角で len 文字まで切り詰める | 443 else offset_top += 1; |
380 SetStr(arg1, s); | 444 } |
381 // fprintf(stderr,"Set[%d,%d]<-%s\n",arg1.type,arg1.number,s.c_str()); | 445 if (s[offset_top] == 0) { |
382 } else break; | 446 SetStr(arg1, ""); |
383 cmd.clear(); | 447 } else if (cmd.cmd4 == 0) { // 長さ制限なし |
384 break; | 448 SetStr(arg1, string(s, offset_top, len-offset_top)); |
385 case 1: | 449 } else { // cmd.cmd4 == 1 |
386 if (cmd.cmd4 == 0) { | 450 int slen = cmd.args[3].value; |
387 SetStr(arg1, ""); | 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; | |
455 } | |
456 string result(s, offset_top, offset_end-offset_top); | |
457 SetStr(arg1, result); | |
458 } | |
388 cmd.clear(); | 459 cmd.clear(); |
389 } else if (cmd.cmd4 == 1) { | 460 break; } |
390 // 領域指定で文字列クリア | 461 case 7: {// strlen w/ kanji |
391 VarInfo v1 = cmd.args[0]; | 462 const char* s = cmd.Str(cmd.args[0]); int i; |
392 VarInfo v2 = cmd.args[1]; | 463 for (i=0; *s != 0; i++) { |
393 eprintf("memclear(str). Var[%d]<%d> - Var[%d]<%d>\n",v1.type, v1.number, v2.type, v2.number); | 464 if (*s < 0 && s[1] != 0) s += 2; |
394 if (v1.type != v2.type || (v1.type != TYPE_VARSTR && v1.type != TYPE_VARSYSSTR && v1.type != TYPE_VARLOCSTR)) { | 465 else s++; |
395 eprintf(" error: bad args\n"); | 466 } |
396 } else { | 467 SetSys(i); |
397 if (v1.number < 0) v1.number = 0; | 468 cmd.clear(); |
398 if (v2.number > 2000) v2.number = 2000; | 469 break; } |
399 for (; v1.number <= v2.number; v1.number++) { | 470 case 8: // 文字列を切って短くする |
400 SetStr(v1, ""); | 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); | |
490 } | |
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; | |
401 } | 504 } |
402 } | 505 result += wc; |
506 } | |
507 SetStr(cmd.args[1], result); | |
403 cmd.clear(); | 508 cmd.clear(); |
404 } | 509 } |
405 case 2: | 510 break; |
406 SetStr(arg1, Str(arg1.type,arg1.number) + cmd.Str(cmd.args[1])); | 511 case 0x0f: case 0x11: // itoa (0x11 の方は zero padding するっぽい) |
407 // 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); | 512 if (cmd.cmd4 == 0) { |
408 cmd.clear(); | 513 int arg1 = cmd.args[0].value; |
409 break; | 514 char buf[1024]; sprintf(buf, "%d", arg1); |
410 case 3: | 515 SetStr(cmd.args[1], buf); |
411 SetSys(strlen(cmd.Str(cmd.args[0]))); | 516 cmd.clear(); |
412 cmd.clear(); | 517 } else if (cmd.cmd4 == 1) { |
413 break; | 518 // 漢字(SJIS) : 82 [4f+N] |
414 case 4: | 519 // やはり漢字じゃない? |
415 { int v = strcmp(cmd.Str(cmd.args[0]), cmd.Str(cmd.args[1])); | 520 int arg1 = cmd.args[0].value; |
416 // string s1=cmd.Str(cmd.args[0]); | 521 char buf[1024]; char fmt[1024]; |
417 // string s2=cmd.Str(cmd.args[1]); | 522 if (cmd.cmd3 == 0x0f) { |
418 // 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); | 523 sprintf(fmt, "%%%dd",cmd.args[2].value); /* 空白でパディング */ |
419 if (v < 0) SetSys(-1); | 524 } else { |
420 else if (v > 0) SetSys(1); | 525 sprintf(fmt, "%%0%dd",cmd.args[2].value); |
421 else SetSys(0); | 526 } |
422 cmd.clear(); | 527 sprintf(buf, fmt, arg1); |
423 break; } | 528 SetStr(cmd.args[1], buf); |
424 case 5: // substring, index from left | 529 cmd.clear(); |
425 case 6: // substring, index from right | 530 } |
426 // 全角対応らしい | 531 break; |
427 //FIXME: Make sure it works properly | 532 case 0x64: // 文字列の表示 : 引数をテキストウィンドウに表示 |
428 { int offset = cmd.args[2].value; | 533 if (cmd.cmd4 == 1) { |
429 int len = strlen(cmd.Str(cmd.args[1])); | 534 char buf[256]; |
430 string str = cmd.Str(cmd.args[1]); | 535 snprintf(buf, 255, "%d", Get(cmd.args[0].type, cmd.args[0].number)); |
431 const char* s = str.c_str(); | 536 cmd.args[0].type = TYPE_STR; |
432 if (cmd.cmd3 == 6) offset = len - offset; | 537 cmd.args[0].value = cmd.AddStr(buf); |
433 if (offset < 0) offset = 0; | 538 cmd.cmd4 = 0; |
434 // 先頭 N 文字を読み飛ばす | 539 } |
435 int i; | 540 cmd.cmd_type = CMD_TEXT; |
436 int offset_top = 0; | 541 break; |
437 for (i=0; i<offset && s[offset_top] != 0; i++) { | |
438 if (s[offset_top] < 0 && s[offset_top+1] != 0) offset_top += 2; | |
439 else offset_top += 1; | |
440 } | |
441 if (s[offset_top] == 0) { | |
442 SetStr(arg1, ""); | |
443 } else if (cmd.cmd4 == 0) { // 長さ制限なし | |
444 SetStr(arg1, string(s, offset_top, len-offset_top)); | |
445 } else { // cmd.cmd4 == 1 | |
446 int slen = cmd.args[3].value; | |
447 int offset_end = offset_top; | |
448 for (i=0; i<slen && s[offset_end] != 0; i++) { | |
449 if (s[offset_end] < 0 && s[offset_end]+1 != 0) offset_end += 2; | |
450 else offset_end += 1; | |
451 } | |
452 string result(s, offset_top, offset_end-offset_top); | |
453 SetStr(arg1, result); | |
454 } | |
455 cmd.clear(); | |
456 break; } | |
457 case 7: {// strlen w/ kanji | |
458 const char* s = cmd.Str(cmd.args[0]); int i; | |
459 for (i=0; *s != 0; i++) { | |
460 if (*s < 0 && s[1] != 0) s += 2; | |
461 else s++; | |
462 } | |
463 SetSys(i); | |
464 cmd.clear(); | |
465 break; } | |
466 case 8: // 文字列を切って短くする | |
467 if (cmd.args[1].value <= 0) { | |
468 SetStr(arg1, ""); | |
469 } else if (cmd.args[1].value < strlen(cmd.Str(cmd.args[1]))) { | |
470 Str(arg1.type,arg1.number).erase(cmd.args[1].value); | |
471 } | |
472 cmd.clear(); | |
473 break; | |
474 case 0x0e: // 漢字モードでitoa | |
475 { | |
476 int arg1 = cmd.args[0].value; | |
477 string result; | |
478 char wc[3]; wc[2]=0; | |
479 char buf[20]; | |
480 if (cmd.cmd4 == 0) { | |
481 sprintf(buf, "%d", arg1); | |
482 } else { // cmd.cmd4 == 1 | |
483 char fmt[20]; | |
484 sprintf(fmt, "%%%dd", cmd.args[2].value); | |
485 sprintf(buf, fmt, arg1); | |
486 } | |
487 int i; | |
488 for (i=0; buf[i] != 0; i++) { | |
489 if (buf[i] == ' ') { | |
490 wc[0] = 0x81; // ' ' in SHIFT_JIS | |
491 wc[1] = 0x40; | |
492 } else if (buf[i] == '-') { | |
493 wc[0] = 0x81; // '-' in SHIFT_JIS | |
494 wc[1] = 0x7c; | |
495 } else if (isdigit(buf[i])) { | |
496 wc[0] = 0x82; // number in SHIFT_JIS | |
497 wc[1] = buf[i] - '0' + 0x4f; | |
498 } else { | |
499 continue; | |
500 } | |
501 result += wc; | |
502 } | |
503 SetStr(cmd.args[1], result); | |
504 cmd.clear(); | |
505 } | |
506 break; | |
507 case 0x0f: case 0x11: // itoa (0x11 の方は zero padding するっぽい) | |
508 if (cmd.cmd4 == 0) { | |
509 int arg1 = cmd.args[0].value; | |
510 char buf[1024]; sprintf(buf, "%d", arg1); | |
511 SetStr(cmd.args[1], buf); | |
512 cmd.clear(); | |
513 } else if (cmd.cmd4 == 1) { | |
514 // 漢字(SJIS) : 82 [4f+N] | |
515 // やはり漢字じゃない? | |
516 int arg1 = cmd.args[0].value; | |
517 char buf[1024]; char fmt[1024]; | |
518 if (cmd.cmd3 == 0x0f) { | |
519 sprintf(fmt, "%%%dd",cmd.args[2].value); /* 空白でパディング */ | |
520 } else { | |
521 sprintf(fmt, "%%0%dd",cmd.args[2].value); | |
522 } | |
523 sprintf(buf, fmt, arg1); | |
524 SetStr(cmd.args[1], buf); | |
525 cmd.clear(); | |
526 } | |
527 break; | |
528 case 0x64: // 文字列の表示 : 引数をテキストウィンドウに表示 | |
529 if (cmd.cmd4 == 1) { | |
530 char buf[256]; | |
531 snprintf(buf, 255, "%d", Get(cmd.args[0].type, cmd.args[0].number)); | |
532 cmd.args[0].type = TYPE_STR; | |
533 cmd.args[0].value = cmd.AddStr(buf); | |
534 cmd.cmd4 = 0; | |
535 } | |
536 | |
537 #if 0 | |
538 @@@ | |
539 save 27 | |
540 ともよメガネのところ | |
541 - オブジェクト関連:seen9061:0 呼び出しで黒い背景画をかさねるところ、変になる | |
542 @@@ | |
543 %Xで置換する名前の設定。0x51e で読みだし。セーブファイルごとに保存されるはずなので実装を考えること | |
544 %は0-3 (4 以降は使ってない)で、渚、秋生、渚、伊吹先生、など | |
545 StrVar を拡張して代入すること | |
546 初期値はこの辺 | |
547 Text側に納め、セーブファイルでも同じようにすべきだろうなあ | |
548 args:0,"渚" | |
549 args:1,"秋生" | |
550 args:2,"渚" | |
551 args:3,"伊吹先生" | |
552 args:4,"朋也くん" | |
553 args:5,"岡崎さん" | |
554 | |
555 | |
556 106737 : 0x23 - cmd 01-04:051f:00[ 2] | |
557 args:0,"古河" | |
558 106758 : line 1712 | |
559 106761 : 0x23 - cmd 01-04:051f:00[ 2] | |
560 args:2,"古河" | |
561 106782 : line 1713 | |
562 106785 : 0x23 - cmd 01-04:051f:00[ 2] | |
563 args:4,"岡崎さん" | |
564 | |
565 47382 : 0x23 - cmd 01-04:051e:00[ 2] | |
566 args:4,V<18>[0](=0) | |
567 | |
568 47408 : 0x23 - cmd 01-0a:0004:00[ 2] | |
569 args:V<18>[0](=0),"岡崎さん" | |
570 47437 : expr: V<0>[1000](=0)=V<sys> | |
571 47451 : 0x23 - cmd 01-0a:0004:00[ 2] | |
572 args:V<18>[0](=0),"朋也くん" | |
573 47480 : expr: V<0>[1001](=0)=V<sys> | |
574 47494 : V<0>[1000](=0)==0(=true)-> 47589 | |
575 47526 : 0x23 - cmd 01-04:0514:00[ 2] | |
576 args:0,V<18>[0](=0) /* NAME.A を帰す */ | |
577 47552 : 0x23 - cmd 01-0a:0002:00[ 2] | |
578 args:V<18>[0](=0),"さん" | |
579 47577 : jmp -> 47672 | |
580 47589 : V<0>[1001](=0)==0(=true)-> 47672 | |
581 47621 : 0x23 - cmd 01-04:0514:00[ 2] | |
582 args:1,V<18>[0](=0) /* NAME.B を帰す */ | |
583 47647 : 0x23 - cmd 01-0a:0002:00[ 2] | |
584 args:V<18>[0](=0),"くん" | |
585 47672 : pos. 279 | |
586 47675 : 0x23 - cmd 01-0a:0064:00[ 1] | |
587 args:V<18>[0](=0) | |
588 | |
589 #endif | |
590 cmd.cmd_type = CMD_TEXT; | |
591 break; | |
592 } | 542 } |
593 } | 543 } |
594 if (cmd.cmd1 == 1 && cmd.cmd2 == 0x0b) { // 数値変数演算 | 544 if (cmd.cmd1 == 1 && cmd.cmd2 == 0x0b) { // 数値変数演算 |
595 if (cmd.cmd3 == 0 && cmd.cmd4 == 0) { | 545 if (cmd.cmd3 == 0 && cmd.cmd4 == 0) { |
596 /* 複数の変数をセット */ | 546 /* 複数の変数をセット */ |
769 case 45: return v1 > v2; | 719 case 45: return v1 > v2; |
770 case 60: return v1 && v2; | 720 case 60: return v1 && v2; |
771 case 61: return v1 || v2; | 721 case 61: return v1 || v2; |
772 } | 722 } |
773 return v2; | 723 return v2; |
724 } | |
725 | |
726 Cmd::Cmd(const Flags& f, int _sys_ver) : flags(f), system_version(_sys_ver) { | |
727 cmd_type = CMD_NOP; | |
728 argc = 0; | |
729 errorflag = false; | |
730 cmdstr[0] = 0; | |
731 strend = 0; | |
732 pos = -1; | |
774 } | 733 } |
775 | 734 |
776 /* 演算子 op := 0x5c <uchar op> */ | 735 /* 演算子 op := 0x5c <uchar op> */ |
777 /* 数式 exp: [op] <token> [op <token> [...]] */ | 736 /* 数式 exp: [op] <token> [op <token> [...]] */ |
778 int Cmd::GetExpression(const char*& d, VarInfo* info_ptr) { | 737 int Cmd::GetExpression(const char*& d, VarInfo* info_ptr) { |
1215 d++; | 1174 d++; |
1216 /* @@@ */ | 1175 /* @@@ */ |
1217 /* 一致しない場合があるのでコメントアウト */ | 1176 /* 一致しない場合があるのでコメントアウト */ |
1218 // if (arg_count != argc) SetError(); | 1177 // if (arg_count != argc) SetError(); |
1219 dprintf("\n}\n"); | 1178 dprintf("\n}\n"); |
1220 return; | |
1221 } | 1179 } |
1222 | 1180 |
1223 void Cmd::GetCmd(Flags& flags_orig, const char*& d ) { | 1181 void Cmd::GetCmd(Flags& flags_orig, const char*& d ) { |
1224 if (d == 0) { SetError(); return;} | 1182 if (d == NULL) { SetError(); return;} |
1225 if (cmd_type != CMD_NOP) return; | 1183 if (cmd_type != CMD_NOP) return; |
1226 | 1184 |
1227 cmdstr[0] = 0; | 1185 cmdstr[0] = 0; |
1228 rawdata = d; | 1186 rawdata = d; |
1229 if (*d == 0x23) { /* コマンド */ | 1187 if (*d == 0x23) { /* コマンド */ |
1366 dprintf("commd;0x2c\n"); // conditional jump の行き先によくあるらしい(常に、かはわからない) | 1324 dprintf("commd;0x2c\n"); // conditional jump の行き先によくあるらしい(常に、かはわからない) |
1367 d++; | 1325 d++; |
1368 } else { | 1326 } else { |
1369 SetError(); | 1327 SetError(); |
1370 } | 1328 } |
1371 return; | 1329 } |
1372 } | 1330 |
1373 void Cmd::clear(void) { | 1331 void Cmd::clear(void) { |
1374 cmd_type = CMD_NOP; | 1332 cmd_type = CMD_NOP; |
1375 ResetString(); | 1333 ResetString(); |
1376 args.clear(); | 1334 args.clear(); |
1377 errorflag = false; | 1335 errorflag = false; |
1472 const char* ss = s.c_str(); | 1430 const char* ss = s.c_str(); |
1473 info.value = CopyString(ss); | 1431 info.value = CopyString(ss); |
1474 args.push_back(info); | 1432 args.push_back(info); |
1475 } | 1433 } |
1476 | 1434 |
1435 | |
1436 const char* Cmd::Str(const VarInfo& info) const { | |
1437 if (info.type != TYPE_STR && info.type != TYPE_VARSTR && info.type != TYPE_VARLOCSTR && info.type != TYPE_VARSYSSTR) | |
1438 return ""; | |
1439 int pt = info.value; | |
1440 if (pt < 0 || pt >= STRHEAP_SIZE) return ""; | |
1441 return strheap + pt; | |
1442 } | |
1443 | |
1444 int Cmd::AddStr(char* s) { | |
1445 // 1-0a-0064 はこういうものが必要らしい | |
1446 int start = strend; | |
1447 while (*s) strheap[strend++] = *s++; | |
1448 strheap[strend++] = 0; | |
1449 return start; | |
1450 } | |
1451 | |
1452 | |
1477 void Cmd::read(const CmdSimplified& from) { | 1453 void Cmd::read(const CmdSimplified& from) { |
1478 errorflag = false; | 1454 errorflag = false; |
1479 ResetString(); | 1455 ResetString(); |
1480 | 1456 |
1481 cmd_type = Cmdtype(from.type); | 1457 cmd_type = Cmdtype(from.type); |
1485 cmd4 = from.cmd4; | 1461 cmd4 = from.cmd4; |
1486 argc = from.argc; | 1462 argc = from.argc; |
1487 /* args の読み込み */ | 1463 /* args の読み込み */ |
1488 args.clear(); | 1464 args.clear(); |
1489 char* d = from.args; | 1465 char* d = from.args; |
1490 if (d == 0) return; | 1466 if (d == NULL) return; |
1491 while(*d != TYPE_END) { | 1467 while(*d != TYPE_END) { |
1492 VarInfo info; | 1468 VarInfo info; |
1493 switch(*d) { | 1469 switch(*d) { |
1494 case TYPE_VAL: | 1470 case TYPE_VAL: |
1495 info.type = TYPE_VAL; | 1471 info.type = TYPE_VAL; |
1509 default: | 1485 default: |
1510 fprintf(stderr,"Cmd::read: Invalid Load Data\n"); | 1486 fprintf(stderr,"Cmd::read: Invalid Load Data\n"); |
1511 *d = TYPE_END; | 1487 *d = TYPE_END; |
1512 } | 1488 } |
1513 } | 1489 } |
1514 return; | 1490 } |
1515 } | 1491 |
1516 void Cmd::write(CmdSimplified& to, char*& buffer) const { | 1492 void Cmd::write(CmdSimplified& to, char*& buffer) const { |
1517 /* | 1493 /* |
1518 if (cmd_type != CMD_OTHER) { | 1494 if (cmd_type != CMD_OTHER) { |
1519 fprintf(stderr,"Cmd::write: Invalid Cmd during Saving Data\n"); | 1495 fprintf(stderr,"Cmd::write: Invalid Cmd during Saving Data\n"); |
1520 to.cmd1 = 0; to.cmd2 = 0; to.cmd3 = 0; to.cmd4 = 0; to.argc = 0; to.args = 0; | 1496 to.cmd1 = 0; to.cmd2 = 0; to.cmd3 = 0; to.cmd4 = 0; to.argc = 0; to.args = 0; |
1527 to.cmd3 = cmd3; | 1503 to.cmd3 = cmd3; |
1528 to.cmd4 = cmd4; | 1504 to.cmd4 = cmd4; |
1529 to.argc = argc; | 1505 to.argc = argc; |
1530 /* args の書き込み */ | 1506 /* args の書き込み */ |
1531 if (args.empty()) { | 1507 if (args.empty()) { |
1532 to.args = 0; | 1508 to.args = NULL; |
1533 } else { | 1509 } else { |
1534 to.args = buffer; | 1510 to.args = buffer; |
1535 char* d = to.args; | 1511 char* d = to.args; |
1536 vector<VarInfo>::const_iterator it; | 1512 vector<VarInfo>::const_iterator it; |
1537 for (it = args.begin(); it != args.end(); it++) { | 1513 for (it = args.begin(); it != args.end(); it++) { |
1552 } | 1528 } |
1553 *d++ = TYPE_END; | 1529 *d++ = TYPE_END; |
1554 buffer = d; | 1530 buffer = d; |
1555 } | 1531 } |
1556 } | 1532 } |
1533 | |
1557 void CmdSimplified::copy(const CmdSimplified& from, char*& args_buffer) { | 1534 void CmdSimplified::copy(const CmdSimplified& from, char*& args_buffer) { |
1558 *this = from; | 1535 *this = from; |
1559 if (args == 0) return; | 1536 if (args == NULL) return; |
1560 char* args_old = from.args; | 1537 char* args_old = from.args; |
1561 /* args のコピー */ | 1538 /* args のコピー */ |
1562 while(*args_old != TYPE_END) { | 1539 while(*args_old != TYPE_END) { |
1563 if (*args_old == TYPE_VAL) { | 1540 if (*args_old == TYPE_VAL) { |
1564 args_old += 5; | 1541 args_old += 5; |
1570 int args_len = args_old - from.args; | 1547 int args_len = args_old - from.args; |
1571 memmove(args_buffer, from.args, args_len); | 1548 memmove(args_buffer, from.args, args_len); |
1572 args = args_buffer; | 1549 args = args_buffer; |
1573 args_buffer += args_len; | 1550 args_buffer += args_len; |
1574 } | 1551 } |
1552 | |
1575 void CmdSimplified::Save(string& saveret) { | 1553 void CmdSimplified::Save(string& saveret) { |
1576 char buf[1024]; | 1554 char buf[1024]; |
1577 sprintf(buf, "%02x-%02x:%04x:%02x(%02d),", cmd1, cmd2, cmd3, cmd4, argc); | 1555 sprintf(buf, "%02x-%02x:%04x:%02x(%02d),", cmd1, cmd2, cmd3, cmd4, argc); |
1578 saveret += buf; | 1556 saveret += buf; |
1579 | 1557 |
1607 args = args_buffer; | 1585 args = args_buffer; |
1608 | 1586 |
1609 type = CMD_OTHER; | 1587 type = CMD_OTHER; |
1610 sscanf(save, "%02x-%02x:%04x:%02x(%02d),", &cmd1, &cmd2, &cmd3, &cmd4, &argc); | 1588 sscanf(save, "%02x-%02x:%04x:%02x(%02d),", &cmd1, &cmd2, &cmd3, &cmd4, &argc); |
1611 save = strchr(save, ','); | 1589 save = strchr(save, ','); |
1612 if (save == 0) { | 1590 if (save == NULL) { |
1613 *args_buffer++ = TYPE_END; | 1591 *args_buffer++ = TYPE_END; |
1614 return; | 1592 return; |
1615 } | 1593 } |
1616 save++; | 1594 save++; |
1617 while(*save != 'E' && *save != '\n' && *save != '\0') { | 1595 while(*save != 'E' && *save != '\n' && *save != '\0') { |
1637 save += 2; | 1615 save += 2; |
1638 *args_buffer++ = 0; | 1616 *args_buffer++ = 0; |
1639 } | 1617 } |
1640 } | 1618 } |
1641 *args_buffer++ = TYPE_END; | 1619 *args_buffer++ = TYPE_END; |
1642 return; | |
1643 } | 1620 } |
1644 | 1621 |
1645 #ifdef SCN_DUMP | 1622 #ifdef SCN_DUMP |
1646 void usage(void) { | 1623 void usage(void) { |
1647 fprintf(stderr,"usage : scn2kdump [inputfile] [outputfile]\n"); | 1624 fprintf(stderr,"usage : scn2kdump [inputfile] [outputfile]\n"); |
1651 } | 1628 } |
1652 int main(int argc, char** argv) { | 1629 int main(int argc, char** argv) { |
1653 /* determine file names */ | 1630 /* determine file names */ |
1654 bool verbose = false; | 1631 bool verbose = false; |
1655 char* inname = "seen.txt"; | 1632 char* inname = "seen.txt"; |
1656 char* outname = 0; | 1633 char* outname = NULL; |
1657 if (argc > 2 && strcmp(argv[1],"-v") == 0) { | 1634 if (argc > 2 && strcmp(argv[1],"-v") == 0) { |
1658 int i; for (i=1; i<argc; i++) argv[i] = argv[i+1]; | 1635 int i; for (i=1; i<argc; i++) argv[i] = argv[i+1]; |
1659 argc--; | 1636 argc--; |
1660 verbose = true; | 1637 verbose = true; |
1661 } | 1638 } |
1662 switch(argc) { | 1639 switch(argc) { |
1663 case 1: break; | 1640 case 1: break; |
1664 case 2: inname = argv[1]; break; | 1641 case 2: |
1665 case 3: inname = argv[1]; outname = argv[2]; break; | 1642 inname = argv[1]; |
1666 default: usage(); | 1643 break; |
1644 case 3: | |
1645 inname = argv[1]; | |
1646 outname = argv[2]; | |
1647 break; | |
1648 default: usage(); | |
1667 } | 1649 } |
1668 /* open output file */ | 1650 /* open output file */ |
1669 FILE* outstream = stdout; | 1651 FILE* outstream = stdout; |
1670 /* create archive instance */ | 1652 /* create archive instance */ |
1671 SCN2kFILE archive(inname); | 1653 SCN2kFILE archive(inname); |
1679 char* fname; | 1661 char* fname; |
1680 fprintf(stderr,"Dump start\n"); | 1662 fprintf(stderr,"Dump start\n"); |
1681 int system_version = 0; | 1663 int system_version = 0; |
1682 while( (fname = archive.ListItem()) != 0) { | 1664 while( (fname = archive.ListItem()) != 0) { |
1683 ARCINFO* info = archive.Find(fname,""); | 1665 ARCINFO* info = archive.Find(fname,""); |
1684 if (info == 0) continue; | 1666 if (info == NULL) continue; |
1685 char* data = info->CopyRead(); | 1667 char* data = info->CopyRead(); |
1686 char* d = data; | 1668 char* d = data; |
1687 char* dend = d + info->Size(); | 1669 char* dend = d + info->Size(); |
1688 /* version 確認 */ | 1670 /* version 確認 */ |
1689 if (read_little_endian_int(d) == 0x1cc) { | 1671 if (read_little_endian_int(d) == 0x1cc) { |