| 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 | |
|---|
| 29 | #include "scn2k.h" |
|---|
| 30 | |
|---|
| 31 | #include <stdlib.h> |
|---|
| 32 | #include <stdarg.h> |
|---|
| 33 | #include <stdio.h> |
|---|
| 34 | #include <string.h> |
|---|
| 35 | #include <string> |
|---|
| 36 | #include "system/file.h" |
|---|
| 37 | |
|---|
| 38 | using namespace std; |
|---|
| 39 | |
|---|
| 40 | |
|---|
| 41 | // #define SCN_DUMP |
|---|
| 42 | /* 泚æç¹ïŒ @@@ ã§è¡šèš */ |
|---|
| 43 | |
|---|
| 44 | |
|---|
| 45 | |
|---|
| 46 | //bool debug_flag = true; |
|---|
| 47 | bool debug_flag = false; |
|---|
| 48 | void dprintf(const char* fmt, ...) { |
|---|
| 49 | if (debug_flag) { |
|---|
| 50 | va_list ap; |
|---|
| 51 | va_start(ap, fmt); |
|---|
| 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; |
|---|
| 80 | return (v >= 0 && v < 7) || v == 25; |
|---|
| 81 | } |
|---|
| 82 | |
|---|
| 83 | int Flags::MaxIndex(int type) const { |
|---|
| 84 | switch (type / 26) { |
|---|
| 85 | case 1: |
|---|
| 86 | return 63999; |
|---|
| 87 | case 2: |
|---|
| 88 | return 31999; |
|---|
| 89 | case 3: |
|---|
| 90 | return 15999; |
|---|
| 91 | case 4: |
|---|
| 92 | return 7999; |
|---|
| 93 | default: |
|---|
| 94 | return 1999; |
|---|
| 95 | } |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | int Flags::operator()() const { |
|---|
| 99 | return sys; // rand() % 10000; |
|---|
| 100 | } |
|---|
| 101 | |
|---|
| 102 | int Flags::operator() (VarInfo info) const { |
|---|
| 103 | return Get(info.type, info.number); |
|---|
| 104 | } |
|---|
| 105 | |
|---|
| 106 | int Flags::Get(int type, int number) const { |
|---|
| 107 | int index = type % 26; |
|---|
| 108 | type /= 26; |
|---|
| 109 | if (index == 25) { |
|---|
| 110 | if (var[7][number] != 0) return var[7][number]; |
|---|
| 111 | if (cgm_data.find(number) == cgm_data.end()) return 0; |
|---|
| 112 | else return 1; |
|---|
| 113 | } |
|---|
| 114 | if (index == 10) index = 8; |
|---|
| 115 | if (index == 11) index = 9; |
|---|
| 116 | if (index > TYPE_VARMAX || uint(type) > 4) return 0; |
|---|
| 117 | if (type == 0) { |
|---|
| 118 | // A[]..G[], Z[] ãçŽã«èªã |
|---|
| 119 | if (uint(number) >= 2000) return 0; |
|---|
| 120 | return var[index][number]; |
|---|
| 121 | } else { |
|---|
| 122 | // Ab[]..G4b[], Z8b[] ãªã©ãèªã |
|---|
| 123 | int factor = 1 << (type - 1); |
|---|
| 124 | int eltsize = 32 / factor; |
|---|
| 125 | if (uint(number) >= (64000 / factor)) return 0; |
|---|
| 126 | return (var[index][number / eltsize] >> ((number % eltsize) * factor)) & ((1 << factor) - 1); |
|---|
| 127 | } |
|---|
| 128 | } |
|---|
| 129 | |
|---|
| 130 | void Flags::Set(VarInfo info, int value) { |
|---|
| 131 | int type = info.type / 26; |
|---|
| 132 | int index = info.type % 26; |
|---|
| 133 | if (index == 25) { |
|---|
| 134 | if (uint(info.number) >= 2000) return; |
|---|
| 135 | if (value == 0) |
|---|
| 136 | cgm_data.erase(info.number); |
|---|
| 137 | else |
|---|
| 138 | cgm_data.insert(info.number); |
|---|
| 139 | index = 7; |
|---|
| 140 | } |
|---|
| 141 | if (index == 10) index = 8; |
|---|
| 142 | if (index == 11) index = 9; |
|---|
| 143 | if (index < 0 || index > TYPE_VARMAX) { |
|---|
| 144 | fprintf(stderr,"Error: invalid access to Var<%d>[%d]\n",info.type,info.number); |
|---|
| 145 | } |
|---|
| 146 | if (type == 0) { |
|---|
| 147 | // A[]..G[], Z[] ãçŽã«æžã |
|---|
| 148 | if (uint(info.number) >= 2000) return; |
|---|
| 149 | var[index][info.number] = value; |
|---|
| 150 | } else { |
|---|
| 151 | // Ab[]..G4b[], Z8b[] ãªã©ãæžã |
|---|
| 152 | int factor = 1 << (type - 1); |
|---|
| 153 | int eltsize = 32 / factor; |
|---|
| 154 | int eltmask = (1 << factor) - 1; |
|---|
| 155 | int shift = (info.number % eltsize) * factor; |
|---|
| 156 | if (uint(info.number) >= (64000 / factor)) return; |
|---|
| 157 | var[index][info.number / eltsize] = |
|---|
| 158 | (var[index][info.number / eltsize] & ~(eltmask << shift)) |
|---|
| 159 | | (value & eltmask) << shift; |
|---|
| 160 | } |
|---|
| 161 | } |
|---|
| 162 | |
|---|
| 163 | void Flags::SetSys(int value) { |
|---|
| 164 | sys = value; |
|---|
| 165 | } |
|---|
| 166 | |
|---|
| 167 | void Flags::SetStr(VarInfo info, string val) { |
|---|
| 168 | switch(info.type) { |
|---|
| 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; |
|---|
| 181 | } |
|---|
| 182 | return; |
|---|
| 183 | } |
|---|
| 184 | |
|---|
| 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) { |
|---|
| 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; |
|---|
| 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 | } |
|---|
| 210 | |
|---|
| 211 | string Flags::Str(int type, unsigned int number) const { |
|---|
| 212 | switch(type) { |
|---|
| 213 | case TYPE_VARLOCSTR: |
|---|
| 214 | if (number >= 3) return ""; |
|---|
| 215 | return loc_str[number]; |
|---|
| 216 | case TYPE_VARSYSSTR: |
|---|
| 217 | if (number >= 2000) return ""; |
|---|
| 218 | return sys_str[number]; |
|---|
| 219 | case TYPE_VARSTR: |
|---|
| 220 | if (number >= 2000) return ""; |
|---|
| 221 | return str[number]; |
|---|
| 222 | } |
|---|
| 223 | return ""; |
|---|
| 224 | } |
|---|
| 225 | |
|---|
| 226 | void Flags::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 | |
|---|
| 298 | void Flags::Save(string& save) { |
|---|
| 299 | char buf[1024]; |
|---|
| 300 | save = "\n[Flags]\n"; |
|---|
| 301 | int i, j; |
|---|
| 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 | } |
|---|
| 317 | |
|---|
| 318 | void Flags::SaveSys(string& save) { //FIXME: see how to factorize with Save |
|---|
| 319 | char buf[1024]; |
|---|
| 320 | int j; |
|---|
| 321 | save = "\n[Flags]\n"; |
|---|
| 322 | for (j=0; j<2000; j++) { |
|---|
| 323 | if (var[6][j] != 0) { |
|---|
| 324 | sprintf(buf, "V<6>[%04d]=%d\n", j, var[6][j]); |
|---|
| 325 | save += buf; |
|---|
| 326 | } |
|---|
| 327 | } |
|---|
| 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 | } |
|---|
| 341 | |
|---|
| 342 | bool Flags::Exec(Cmd& cmd) { |
|---|
| 343 | if (cmd.cmd_type == CMD_FLAGS) { // 代å
¥æŒç® |
|---|
| 344 | if (cmd.args.size() != 2) return false; |
|---|
| 345 | Set(cmd.args[0], cmd.args[1].value); |
|---|
| 346 | cmd.clear(); |
|---|
| 347 | return true; |
|---|
| 348 | } |
|---|
| 349 | if (cmd.cmd1 == 1 && cmd.cmd2 == 0x0a) { // æååæŒç® |
|---|
| 350 | VarInfo arg1 = cmd.args[0]; |
|---|
| 351 | switch(cmd.cmd3) { |
|---|
| 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 | } |
|---|
| 363 | s.erase(i); // å
šè§ã§ len æåãŸã§åãè©°ãã |
|---|
| 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) { |
|---|
| 374 | // é åæå®ã§æååã¯ãªã¢ |
|---|
| 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(); |
|---|
| 388 | } |
|---|
| 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); |
|---|
| 406 | cmd.clear(); |
|---|
| 407 | break; } |
|---|
| 408 | case 5: // substring, index from left |
|---|
| 409 | case 6: // substring, index from right |
|---|
| 410 | // å
šè§å¯Ÿå¿ããã |
|---|
| 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; |
|---|
| 418 | // å
é N æåãèªã¿é£ã°ã |
|---|
| 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, ""); |
|---|
| 427 | } else if (cmd.cmd4 == 0) { // é·ãå¶éãªã |
|---|
| 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; |
|---|
| 435 | } |
|---|
| 436 | string result(s, offset_top, offset_end-offset_top); |
|---|
| 437 | SetStr(arg1, result); |
|---|
| 438 | } |
|---|
| 439 | cmd.clear(); |
|---|
| 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; } |
|---|
| 450 | case 8: // æååãåã£ãŠçããã |
|---|
| 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; |
|---|
| 458 | case 0x0e: // 挢åã¢ãŒãã§itoa |
|---|
| 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); |
|---|
| 470 | } |
|---|
| 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; |
|---|
| 486 | } |
|---|
| 487 | SetStr(cmd.args[1], result); |
|---|
| 488 | cmd.clear(); |
|---|
| 489 | } |
|---|
| 490 | break; |
|---|
| 491 | case 0x0f: case 0x11: // itoa (0x11 ã®æ¹ã¯ zero padding ããã£ãœã) |
|---|
| 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) { |
|---|
| 498 | // 挢å(SJIS) : 82 [4f+N] |
|---|
| 499 | // ãã¯ã挢åãããªãïŒ |
|---|
| 500 | int arg1 = cmd.args[0].value; |
|---|
| 501 | char buf[1024]; char fmt[1024]; |
|---|
| 502 | if (cmd.cmd3 == 0x0f) { |
|---|
| 503 | sprintf(fmt, "%%%dd",cmd.args[2].value); /* 空çœã§ããã£ã³ã° */ |
|---|
| 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; |
|---|
| 512 | case 0x64: // æååã®è¡šç€º : åŒæ°ãããã¹ããŠã£ã³ããŠã«è¡šç€º |
|---|
| 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; |
|---|
| 522 | } |
|---|
| 523 | } |
|---|
| 524 | if (cmd.cmd1 == 1 && cmd.cmd2 == 0x0b) { // æ°å€å€æ°æŒç® |
|---|
| 525 | if (cmd.cmd3 == 0 && cmd.cmd4 == 0) { |
|---|
| 526 | /* è€æ°ã®å€æ°ãã»ãã */ |
|---|
| 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) { |
|---|
| 542 | /* é åæå®ã§å€æ°ãã¯ãªã¢ */ |
|---|
| 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) { |
|---|
| 555 | /* é åæå®ã§å€æ°ãã»ãã */ |
|---|
| 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(); |
|---|
| 568 | } else if (cmd.cmd3 == 4 && cmd.cmd4 == 1) { // é åã¯ãªã¢(sysfunc.txt) |
|---|
| 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(); |
|---|
| 579 | } else if (cmd.cmd3 == 0x64 && cmd.cmd4 == 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 | /********************************************************************* |
|---|
| 599 | ** SimpleCmd |
|---|
| 600 | */ |
|---|
| 601 | |
|---|
| 602 | SimpleCmd::SimpleCmd(int a, int b, int c) |
|---|
| 603 | { |
|---|
| 604 | cmd1 = a; |
|---|
| 605 | cmd2 = b; |
|---|
| 606 | cmd3 = c; |
|---|
| 607 | } |
|---|
| 608 | |
|---|
| 609 | SimpleCmd::SimpleCmd(void) |
|---|
| 610 | { |
|---|
| 611 | cmd1 = cmd2 = cmd3 = 0; |
|---|
| 612 | } |
|---|
| 613 | |
|---|
| 614 | bool SimpleCmd::operator<(const SimpleCmd& cmd) const |
|---|
| 615 | { |
|---|
| 616 | if (cmd1 < cmd.cmd1) return true; |
|---|
| 617 | else if (cmd1 > cmd.cmd1) return false; |
|---|
| 618 | |
|---|
| 619 | if (cmd2 < cmd.cmd2) return true; |
|---|
| 620 | else if (cmd2 > cmd.cmd2) return false; |
|---|
| 621 | |
|---|
| 622 | if (cmd3 < cmd.cmd3) return true; |
|---|
| 623 | else return false; |
|---|
| 624 | } |
|---|
| 625 | |
|---|
| 626 | bool SimpleCmd::operator==(const SimpleCmd& cmd) const |
|---|
| 627 | { |
|---|
| 628 | return (cmd1 == cmd.cmd1 && cmd2 == cmd.cmd2 && cmd3 == cmd.cmd3); |
|---|
| 629 | } |
|---|
| 630 | |
|---|
| 631 | |
|---|
| 632 | /********************************************************************* |
|---|
| 633 | ** Cmd |
|---|
| 634 | */ |
|---|
| 635 | |
|---|
| 636 | /* æ°å€ num := 0x24 0xff <int num> */ |
|---|
| 637 | /* 倿° var := 0x24 <uchar type> 0x5b <exp> 0x5d */ |
|---|
| 638 | /* é
token := num | var | 0x28 <exp> 0x29 | <plus|minus> token */ |
|---|
| 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) { |
|---|
| 651 | // if ( (d[0] == 0x30 || d[0] == 0x31) && d[1] == 0x24 && ((unsigned const char*)d)[2] == 0xff) /* @@@ not supported; selection å
ã§ã0x30|0x31 ãä»éããããšããã */ |
|---|
| 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 | |
|---|
| 688 | static const char* op_str[70] = { |
|---|
| 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 | |
|---|
| 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 | |
|---|
| 749 | /* æŒç®å op := 0x5c <uchar op> */ |
|---|
| 750 | /* æ°åŒ exp: [op] <token> [op <token> [...]] */ |
|---|
| 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 | |
|---|
| 758 | // 第äžé
ã®èªã¿èŸŒã¿ |
|---|
| 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; |
|---|
| 775 | return value; // åçŽãªleft-termã¯ããã§çµäºãæå¹ãªinfo_ptrãåž°ãïŒå¯èœæ§ãããïŒ |
|---|
| 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) { |
|---|
| 786 | // åªå
é äœã®é«ããå
è¡ããæŒç®ãè¡ã |
|---|
| 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) { |
|---|
| 801 | // æªå®è¡ã®æŒç®ãçµãããã |
|---|
| 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 */ |
|---|
| 806 | // bracket çµç«¯ãããã°ãéããŠãã |
|---|
| 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 | |
|---|
| 822 | // æ¡ä»¶åå²å°çšã«ãæ¡ä»¶æŒç®ãšç®è¡æŒç®ã®æ··åãæ€ç¥ã§ããå°çšã«ãŒãã³ïŒæ¬æ¥ã¯GetExpressionã§å·®ãæ¯ããªã) |
|---|
| 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 | |
|---|
| 831 | // 第äžé
ã®èªã¿èŸŒã¿ |
|---|
| 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) { |
|---|
| 853 | // åªå
é äœã®é«ããå
è¡ããæŒç®ãè¡ã |
|---|
| 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) { |
|---|
| 876 | // æªå®è¡ã®æŒç®ãçµãããã |
|---|
| 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--; |
|---|
| 886 | // bracket çµç«¯ãããã°ãéããŠãã |
|---|
| 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) { |
|---|
| 908 | if (*d != 0x28) return 0; /* åŒæ°ãªã */ |
|---|
| 909 | d++; |
|---|
| 910 | dprintf("args:"); |
|---|
| 911 | VarInfo var; |
|---|
| 912 | int i; for (i=0; i<100 ; i++) { |
|---|
| 913 | /* number, variable, string ã®çš®å¥ãªãå€ãåŸã */ |
|---|
| 914 | if (*d == 0x61) { // ããããããªã(æºä»£ã¢ãã¿ãŒ) |
|---|
| 915 | dprintf("@%d",d[1]); |
|---|
| 916 | d += 2; |
|---|
| 917 | if (*d == 0x28) { |
|---|
| 918 | dprintf("{"); |
|---|
| 919 | GetArgs(d); // (A,B,C)ç¯ãå«ãŸããããšããã |
|---|
| 920 | dprintf("}"); |
|---|
| 921 | } else { |
|---|
| 922 | dprintf("{}"); |
|---|
| 923 | } |
|---|
| 924 | } else if (d[0] == 0x0a || d[0] == 0x40) { // ããããããªã (Little Busters!) |
|---|
| 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; |
|---|
| 938 | if (*d == 0x2c) {d++;} // 次㮠arg ãæŒç®åã§å§ãŸãããªã©ããªããã°ååšããªã |
|---|
| 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) { |
|---|
| 947 | if (*d != 0x28) return 0; /* åŒæ°ãªã */ |
|---|
| 948 | d++; |
|---|
| 949 | dprintf("args:"); |
|---|
| 950 | int i; for (i=0; i<normal_args; i++) { |
|---|
| 951 | /* number, variable, string ã®çš®å¥ãªãå€ãåŸã */ |
|---|
| 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; |
|---|
| 958 | if (*d == 0x2c) {d++;} // 次㮠arg ãæŒç®åã§å§ãŸãããªã©ããªããã°ååšããªã |
|---|
| 959 | dprintf(","); |
|---|
| 960 | } |
|---|
| 961 | for (i=0; i<argc ; i++) { |
|---|
| 962 | if (*d == 0x28) { |
|---|
| 963 | /* |
|---|
| 964 | ** cmd 01-22:0c1c, 01-22:0835 |
|---|
| 965 | ** Princess Bride ã®ã«ãŒããèœã¡ãã¢ãã¡ã®å Žé¢ |
|---|
| 966 | ** ãªãã_PBCARDANM* ã®ç»åã¯ãã®ã³ãã³ãã§ã®ã¿äœ¿ãããŠããã®ã§ãç¹æ®åŠçãšããŠç¡èŠããããšãå¯èœ |
|---|
| 967 | ** |
|---|
| 968 | ** cmd 01-04:0276, 026c, 0270 |
|---|
| 969 | ** è€æ°ã® enum ã args ã®æ°ã ãç¶ãåŠçãç¹æ®åŠçãšããŠåé¢ãã |
|---|
| 970 | */ |
|---|
| 971 | dprintf("enum.<"); |
|---|
| 972 | /* (...) ã¯åæå or æ§é äœã®å¯èœæ§ããã */ |
|---|
| 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 ) { |
|---|
| 979 | /* 䜿ãããã³ãã³ã㯠01-21:004b, 01-28:0064 ã®ããããïŒR,C,PB,LO) |
|---|
| 980 | ** ãããã®ã³ãã³ã㯠|
|---|
| 981 | ** arg1: ç»åãã¡ã€ã«å |
|---|
| 982 | ** arg2 : Sel çªå· |
|---|
| 983 | ** ããããarg3 以éã 0x61 <00-04> (a,b,c,...) ãšãªãïŒãã³ãäžã¯ enum ãšè¡šèšããã) |
|---|
| 984 | ** () å
ã®åŒæ°ã¯ããŸããŸã§ãa ã®ã¿ïŒç»åãã¡ã€ã«åïŒã |
|---|
| 985 | ** a,b b=SEL? |
|---|
| 986 | ** a,b,c (b,c)=座æšïŒ |
|---|
| 987 | ** a,(b,c,d,e,f,g) b-g = src / dest? |
|---|
| 988 | ** ããã |
|---|
| 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))) { |
|---|
| 997 | /* cmd 01-15:0028 ; å§ãã« 0x24 ç¯ããããç¶ã㊠0x28 ç¯ã«ãªã */ |
|---|
| 998 | VarInfo var; |
|---|
| 999 | GetExpression(d, &var); |
|---|
| 1000 | args.push_back(var); |
|---|
| 1001 | i--; // ãã®åŒæ°ã¯argc ã®æ°ã«ã¯å
¥ããªã |
|---|
| 1002 | } else SetError(); |
|---|
| 1003 | if (d[0] == 0x0a || d[0] == 0x40) { |
|---|
| 1004 | /* cmd 01-15:0028 ; 0x28 ç¯ã®åŸã«æ¯å 0x0a ç¯ãæ¥ã */ |
|---|
| 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; |
|---|
| 1011 | if (*d == 0x2c) {d++;} // 次㮠arg ãæŒç®åã§å§ãŸãããªã©ããªããã°ååšããªã |
|---|
| 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) { |
|---|
| 1127 | if (cond_result) ; // æ¡ä»¶ç¯ã true ãªã衚瀺ããªã |
|---|
| 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) { |
|---|
| 1148 | int result = GetExpressionCond(d); // PRINT- ç¯ã§ãªãã°ãããæ¡ä»¶è¡šç€ºãæ¬¡ã¯æåç¯ããŸãã¯PRINTç¯ã®ã¯ã |
|---|
| 1149 | if (*d == 0x32) { // 0x32 ãªããçŸåšã®æ¡ä»¶ç¯ã衚瀺ããªã |
|---|
| 1150 | d++; dprintf("##"); |
|---|
| 1151 | cond_result = result; |
|---|
| 1152 | } else if (*d == 0x31) { // 0x31 ãªããçŸåšã®æ¡ä»¶ç¯ã衚瀺ãã |
|---|
| 1153 | // Little Busters! : ãã®æ¡ä»¶ã§æ£ãããã¯æªæ€èšŒ |
|---|
| 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(); |
|---|
| 1168 | else { // æå倿°ã®å
容ã®è¡šç€º |
|---|
| 1169 | d++; |
|---|
| 1170 | dprintf("Print."); |
|---|
| 1171 | VarInfo info; |
|---|
| 1172 | GetLeftToken(d, info); |
|---|
| 1173 | if (d[0] != 0x29 || info.type == -1) SetError(); |
|---|
| 1174 | d++; |
|---|
| 1175 | dprintf(";");/* |
|---|
| 1176 | // æ°å€ãå
šè§æåã«å€æããŠç»é² |
|---|
| 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 | } |
|---|
| 1183 | str2[i*2] = 0;*/ |
|---|
| 1184 | text += strheap + info.value; |
|---|
| 1185 | } |
|---|
| 1186 | } else { SetError(); break;} |
|---|
| 1187 | } |
|---|
| 1188 | d++; |
|---|
| 1189 | /* @@@ */ |
|---|
| 1190 | /* äžèŽããªãå Žåãããã®ã§ã³ã¡ã³ãã¢ãŠã */ |
|---|
| 1191 | // if (arg_count != argc) SetError(); |
|---|
| 1192 | dprintf("\n}\n"); |
|---|
| 1193 | } |
|---|
| 1194 | |
|---|
| 1195 | void Cmd::GetCmd(Flags& flags_orig, const char*& d ) { |
|---|
| 1196 | if (d == NULL) { SetError(); return;} |
|---|
| 1197 | if (cmd_type != CMD_NOP) return; |
|---|
| 1198 | |
|---|
| 1199 | cmdstr[0] = 0; |
|---|
| 1200 | rawdata = d; |
|---|
| 1201 | if (*d == 0x23) { /* ã³ãã³ã */ |
|---|
| 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); |
|---|
| 1211 | sprintf(cmdstr, "%02x-%02x:%04x:%02x : %s",cmd1,cmd2,cmd3,cmd4, CmdDescr(cmd1,cmd2,cmd3,cmd4)); |
|---|
| 1212 | /* åŒæ°ãåŸã */ |
|---|
| 1213 | /* ç¹æ®åŒæ°ã®ãã® */ |
|---|
| 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); |
|---|
| 1232 | if (cmd3 == 1) cond = !cond; // éã«ãªã |
|---|
| 1233 | if (*d++ != 0x29) { SetError(); return; } |
|---|
| 1234 | int jumpto = read_little_endian_int(d); |
|---|
| 1235 | d += 4; |
|---|
| 1236 | dprintf("-> %d\n", jumpto); |
|---|
| 1237 | if (! cond) jump_arg = jumpto; /* condition ãæºããããªãå Žåããžã£ã³ã */ |
|---|
| 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: |
|---|
| 1267 | /* äžè¬åŒæ°ã®ãã® */ |
|---|
| 1268 | if (!is_special) { |
|---|
| 1269 | dprintf(" 0x23 - cmd %02x-%02x:%04x:%02x[%2d] : %s\n",cmd1,cmd2,cmd3,cmd4,argc,CmdDescr(cmd1,cmd2,cmd3,cmd4)); |
|---|
| 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); |
|---|
| 1276 | else if (cmd1 == 1 && ((cmd2 == 0x21 && cmd3 == 0x4b) || (cmd2 == 0x28 && cmd3 == 0x64))) GetArgsSpecial(2,d); |
|---|
| 1277 | else GetArgs(d); |
|---|
| 1278 | dprintf("\n"); |
|---|
| 1279 | |
|---|
| 1280 | } |
|---|
| 1281 | } else if (*d == 0x24) { /* 代å
¥æŒç® */ |
|---|
| 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); |
|---|
| 1294 | // 代å
¥æ
å ±ãåã蟌ã |
|---|
| 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"); |
|---|
| 1300 | } else if (StrType(d)) { /* æååºå */ |
|---|
| 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"); |
|---|
| 1307 | } else if (*d == 0x0a || *d == 0x40 || *d == 0x21) { /* ãããã°çšããŒã¿ãšæ¢èªãã©ã° */ |
|---|
| 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 */ |
|---|
| 1322 | // æ¢èªããŒã«ãŒãããããšã³ããªãŒãã€ã³ããšã»ãŒããã€ã³ãã䜿ãããã |
|---|
| 1323 | // RealLive 1.2.5ããã0x40ã¯ã»ãŒããã€ã³ãã0x21ã¯ãšã³ããªãŒãã€ã³ãã |
|---|
| 1324 | // 1.2.5以åãã©ã¡ãã0x40ã䜿ãããã |
|---|
| 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); |
|---|
| 1335 | // text_readflagã¯ããã®kidoku_indexã䜿ã£ããè¯ãããªã |
|---|
| 1336 | } |
|---|
| 1337 | } else if (*d == 0x2c) { /* ??? */ |
|---|
| 1338 | dprintf("commd;0x2c\n"); // conditional jump ã®è¡ãå
ã«ãããããããïŒåžžã«ããã¯ããããªãïŒ |
|---|
| 1339 | d++; |
|---|
| 1340 | } else { |
|---|
| 1341 | SetError(); |
|---|
| 1342 | } |
|---|
| 1343 | } |
|---|
| 1344 | |
|---|
| 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++; |
|---|
| 1387 | } else if ((stype = StrType(d))) { |
|---|
| 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 | |
|---|
| 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) { |
|---|
| 1459 | // 1-0a-0064 ã¯ãããããã®ãå¿
èŠããã |
|---|
| 1460 | int start = strend; |
|---|
| 1461 | while (*s) strheap[strend++] = *s++; |
|---|
| 1462 | strheap[strend++] = 0; |
|---|
| 1463 | return start; |
|---|
| 1464 | } |
|---|
| 1465 | |
|---|
| 1466 | |
|---|
| 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; |
|---|
| 1477 | /* args ã®èªã¿èŸŒã¿ */ |
|---|
| 1478 | args.clear(); |
|---|
| 1479 | char* d = from.args; |
|---|
| 1480 | if (d == NULL) return; |
|---|
| 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 | } |
|---|
| 1505 | |
|---|
| 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; |
|---|
| 1520 | /* args ã®æžã蟌㿠*/ |
|---|
| 1521 | if (args.empty()) { |
|---|
| 1522 | to.args = NULL; |
|---|
| 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 | } |
|---|
| 1547 | |
|---|
| 1548 | void CmdSimplified::copy(const CmdSimplified& from, char*& args_buffer) { |
|---|
| 1549 | *this = from; |
|---|
| 1550 | if (args == NULL) return; |
|---|
| 1551 | char* args_old = from.args; |
|---|
| 1552 | /* args ã®ã³ã㌠*/ |
|---|
| 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 | } |
|---|
| 1566 | |
|---|
| 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 | |
|---|
| 1572 | /* args ã®ã³ã㌠*/ |
|---|
| 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; |
|---|
| 1579 | } else { /* TYPE_STR ãšä»®å® */ |
|---|
| 1580 | d++; |
|---|
| 1581 | if (strlen(d) > 1000) d[1000] = 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, ','); |
|---|
| 1604 | if (save == NULL) { |
|---|
| 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"; |
|---|
| 1647 | char* outname = NULL; |
|---|
| 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) { |
|---|
| 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(); |
|---|
| 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,""); |
|---|
| 1680 | if (info == NULL) continue; |
|---|
| 1681 | char* data = info->CopyRead(); |
|---|
| 1682 | char* d = data; |
|---|
| 1683 | char* dend = d + info->Size(); |
|---|
| 1684 | /* version ç¢ºèª */ |
|---|
| 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; |
|---|
| 1706 | /* æåããæåŸãŸã§ã³ãã³ãååŸ -> åºåãç¹°ãè¿ã */ |
|---|
| 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 | |
|---|