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) {