void Script::o_stub56() { uint32 val1 = readScript32bits(); uint8 val2 = readScript8bits(); uint8 val3 = readScript8bits(); debugScript(1, true, "STUB56: 0x%08X 0x%02X 0x%02X", val1, val2, val3); }
uint8 Script::readScriptChar(bool allow7C, bool limitVal, bool limitVar) { uint8 result; uint8 data = readScript8bits(); if (limitVal) { data &= 0x7F; } if (allow7C && (data == 0x7C)) { // Index a bidimensional array uint8 parta, partb; parta = readScriptChar(false, false, false); partb = readScriptChar(false, true, true); result = _variables[0x0A * parta + partb + 0x19]; } else if (data == 0x23) { // Index an array data = readScript8bits(); if (limitVar) { data &= 0x7F; } result = _variables[data - 0x61]; } else { // Immediate value result = data - 0x30; } return result; }
void Script::o_returnscript() { uint8 val = readScript8bits(); debugScript(1, true, "RETURNSCRIPT @0x%02X", val); // Are we returning from a sub-script? if (!_savedCode) { error("Tried to return from the main script"); } // Set the return value setVariable(0x102, val); // Restore the code delete[] _code; _code = _savedCode; _codeSize = _savedCodeSize; _savedCode = NULL; _currentInstruction = _savedInstruction; // Restore the stack _stacktop = _savedStacktop; // Restore the variables memcpy(_variables + 0x107, _savedVariables, 0x180); // Restore the filename of the script _scriptFile = _savedScriptFile; _vm->_videoPlayer->resetFlags(); _vm->_videoPlayer->setOrigin(0, 0); }
void Script::o_loadscript() { Common::String filename; char c; while ((c = readScript8bits())) { filename += c; } debugScript(1, true, "LOADSCRIPT %s", filename.c_str()); // Just 1 level of sub-scripts are allowed if (_savedCode) { error("Tried to load a level 2 sub-script"); } // Save the current code _savedCode = _code; _savedCodeSize = _codeSize; _savedInstruction = _currentInstruction; // Save the filename of the current script _savedScriptFile = _scriptFile; // Load the sub-script if (!loadScript(filename)) { error("Couldn't load sub-script %s", filename.c_str()); } // Save the current stack top _savedStacktop = _stacktop; // Save the variables memcpy(_savedVariables, _variables + 0x107, 0x180); }
uint16 Script::readScript8or16bits() { if (_firstbit) { return readScript8bits(); } else { return readScript16bits(); } }
void Script::step() { // Prepare the base debug string char debugstring[10]; sprintf(debugstring, "@0x%04X: ", _currentInstruction); _debugString = _scriptFile + debugstring; // Get the current opcode byte opcode = readScript8bits(); _firstbit = ((opcode & 0x80) != 0); opcode = opcode & 0x7F; // Show the opcode debug string sprintf(debugstring, "op 0x%02X: ", opcode); _debugString += debugstring; // Only output if we're not re-doing the previous instruction if (_currentInstruction != _oldInstruction) { debugScript(1, false, "%s", _debugString.c_str()); _oldInstruction = _currentInstruction; } // Detect invalid opcodes if (opcode >= NUM_OPCODES) { o_invalid(); return; } // Execute the current opcode OpcodeFunc op = _opcodes[opcode]; (this->*op)(); }
void Script::o_random() { uint16 varnum = readScript8or16bits(); uint8 maxnum = readScript8bits(); debugScript(1, true, "RANDOM: var[0x%04X] = rand(%d)", varnum, maxnum); setVariable(varnum, _random.getRandomNumber(maxnum)); }
void Script::o_mod() { uint16 varnum = readScript8or16bits(); uint8 val = readScript8bits(); debugScript(1, true, "MOD var[0x%04X] %%= %d", varnum, val); setVariable(varnum, _variables[varnum] % val); }
void Script::o_hotspot_slot() { uint16 slot = readScript8bits(); uint16 left = readScript16bits(); uint16 top = readScript16bits(); uint16 right = readScript16bits(); uint16 bottom = readScript16bits(); uint16 address = readScript16bits(); uint16 cursor = readScript8bits(); debugScript(1, true, "HOTSPOT-SLOT %d (%d,%d,%d,%d) @0x%04X cursor=%d (TODO)", slot, left, top, right, bottom, address, cursor); Common::Rect rect(left, top, right, bottom); if (hotspot(rect, address, cursor)) { if (_hotspotSlot == slot) { return; } Common::Rect topbar(640, 80); Graphics::Surface *gamescreen = _vm->_system->lockScreen(); // Clear the top bar gamescreen->fillRect(topbar, 0); printString(gamescreen, _saveNames[slot].c_str()); _vm->_system->unlockScreen(); // Save the currently highlighted slot _hotspotSlot = slot; } else { if (_hotspotSlot == slot) { Common::Rect topbar(640, 80); Graphics::Surface *gamescreen; gamescreen = _vm->_system->lockScreen(); gamescreen->fillRect(topbar, 0); _vm->_system->unlockScreen(); // Removing the slot highlight _hotspotSlot = (uint16)-1; } } }
void Script::o_sethotspotbottom() { uint16 address = readScript16bits(); uint8 cursor = readScript8bits(); debugScript(5, true, "SETHOTSPOTBOTTOM @0x%04X cursor=%d", address, cursor); _hotspotBottomAction = address; _hotspotBottomCursor = cursor; }
void Script::o_playcd() { uint8 val = readScript8bits(); debugScript(1, true, "PLAYCD %d", val); if (val == 2) { // TODO: Play the alternative logo } _vm->_musicPlayer->playCD(val); }
uint16 Script::getVideoRefString() { Common::String str; byte c; while ((c = readScript8bits())) { switch (c) { case 0x23: c = readScript8bits(); c = _variables[c - 0x61] + 0x30; if (c >= 0x41 && c <= 0x5A) { c += 0x20; } break; case 0x7C: uint8 parta, partb; parta = readScriptChar(false, false, false); partb = readScriptChar(false, false, false); c = _variables[0x0A * parta + partb + 0x19] + 0x30; break; default: if (c >= 0x41 && c <= 0x5A) { c += 0x20; } } // Append the current character at the end of the string str += c; } // Add a trailing dot str += 0x2E; debugScript(0, false, "%s", str.c_str()); // Extract the script name. Common::String scriptname(_scriptFile.c_str(), _scriptFile.size() - 4); // Get the fileref of the resource return _vm->_resMan->getRef(str, scriptname); }
void Script::o_hotspot_rect() { uint16 left = readScript16bits(); uint16 top = readScript16bits(); uint16 right = readScript16bits(); uint16 bottom = readScript16bits(); uint16 address = readScript16bits(); uint8 cursor = readScript8bits(); debugScript(5, true, "HOTSPOT-RECT(%d,%d,%d,%d) @0x%04X cursor=%d", left, top, right, bottom, address, cursor); // Mark the specified rectangle Common::Rect rect(left, top, right, bottom); hotspot(rect, address, cursor); }
void Script::o_xor_obfuscate() { uint16 varnum = readScript8or16bits(); debugScript(1, false, "XOR OBFUSCATE: var[0x%04X..] = ", varnum); do { uint8 val = readScript8bits(); _firstbit = ((val & 0x80) != 0); val &= 0x4F; setVariable(varnum, _variables[varnum] ^ val); debugScript(1, false, "%c", _variables[varnum]); varnum++; } while (!_firstbit); debugScript(1, false, "\n"); }
void Script::o_ret() { uint8 val = readScript8bits(); debugScript(1, true, "RET %d", val); // Set the return value setVariable(0x102, val); // Get the return address if (_stacktop > 0) { _stacktop--; _currentInstruction = _stack[_stacktop]; } else { error("Return: Stack is empty"); } }
void Script::o_keyboardaction() { uint8 val = readScript8bits(); uint16 address = readScript16bits(); debugScript(5, true, "Test key == 0x%02X @0x%04X", val, address); // If there's an already planned action, do nothing if (_inputAction != -1) { return; } // Check the typed key if (_kbdChar == val) { // Exit the input loop _inputLoopAddress = 0; // Save the action address _inputAction = address; } }
void Script::o_cellmove() { uint16 depth = readScript8bits(); byte *scriptBoard = &_variables[0x19]; byte startX, startY, endX, endY; debugScript(1, true, "CELL MOVE var[0x%02X]", depth); if (!_staufsMove) _staufsMove = new CellGame; _staufsMove->playStauf(2, depth, scriptBoard); startX = _staufsMove->getStartX(); startY = _staufsMove->getStartY(); endX = _staufsMove->getEndX(); endY = _staufsMove->getEndY(); // Set the movement origin setVariable(0, startY); // y setVariable(1, startX); // x // Set the movement destination setVariable(2, endY); setVariable(3, endX); }
void Script::o_nop8() { uint8 tmp = readScript8bits(); debugScript(1, true, "NOP8: 0x%02X", tmp); }
void Script::o_stub59() { uint16 val1 = readScript8or16bits(); uint8 val2 = readScript8bits(); debugScript(1, true, "STUB59: 0x%04X 0x%02X", val1, val2); }
uint16 Script::readScript16bits() { uint8 lower = readScript8bits(); uint8 upper = readScript8bits(); return lower | (upper << 8); }
void Script::o2_stub52(){ uint8 arg = readScript8bits(); debugScript(1, true, "STUB52 (0x%02X)", arg); }