* Run the next opcode of a script. * * @param script The script engine to run. * @return Returns false if and only if there was an scripting error, like * invalid opcode. */
| 312 | * invalid opcode. |
| 313 | */ |
| 314 | bool Script_Run(ScriptEngine *script) |
| 315 | { |
| 316 | ScriptInfo *scriptInfo; |
| 317 | uint16 current, parameter; |
| 318 | uint8 opcode; |
| 319 | |
| 320 | if (!Script_IsLoaded(script)) return false; |
| 321 | scriptInfo = script->scriptInfo; |
| 322 | |
| 323 | current = BETOH16(*script->script); |
| 324 | script->script++; |
| 325 | |
| 326 | opcode = (current >> 8) & 0x1F; |
| 327 | parameter = 0; |
| 328 | |
| 329 | if ((current & 0x8000) != 0) { |
| 330 | /* When this flag is set, the instruction is a GOTO with a 13bit address */ |
| 331 | opcode = 0; |
| 332 | parameter = current & 0x7FFF; |
| 333 | } else if ((current & 0x4000) != 0) { |
| 334 | /* When this flag is set, the parameter is part of the instruction */ |
| 335 | parameter = (int16)(int8)(current & 0xFF); |
| 336 | } else if ((current & 0x2000) != 0) { |
| 337 | /* When this flag is set, the parameter is in the next opcode */ |
| 338 | parameter = BETOH16(*script->script); |
| 339 | script->script++; |
| 340 | } |
| 341 | |
| 342 | switch (opcode) { |
| 343 | case SCRIPT_JUMP: { |
| 344 | script->script = scriptInfo->start + parameter; |
| 345 | return true; |
| 346 | } |
| 347 | |
| 348 | case SCRIPT_SETRETURNVALUE: { |
| 349 | script->returnValue = parameter; |
| 350 | return true; |
| 351 | } |
| 352 | |
| 353 | case SCRIPT_PUSH_RETURN_OR_LOCATION: { |
| 354 | if (parameter == 0) { /* PUSH RETURNVALUE */ |
| 355 | STACK_PUSH(script->returnValue); |
| 356 | return true; |
| 357 | } |
| 358 | |
| 359 | if (parameter == 1) { /* PUSH NEXT LOCATION + FRAMEPOINTER */ |
| 360 | uint32 location; |
| 361 | location = (uint32)(script->script - scriptInfo->start) + 1; |
| 362 | |
| 363 | STACK_PUSH(location); |
| 364 | STACK_PUSH(script->framePointer); |
| 365 | script->framePointer = script->stackPointer + 2; |
| 366 | |
| 367 | return true; |
| 368 | } |
| 369 | |
| 370 | Script_Error("Unknown parameter %d for opcode 2", parameter); |
| 371 | script->script = NULL; |
no test coverage detected