void Script::o_sub() { uint16 varnum1 = readScript8or16bits(); uint16 varnum2 = readScript16bits(); debugScript(1, true, "SUB var[0x%04X] -= var[0x%04X]", varnum1, varnum2); setVariable(varnum1, _variables[varnum1] - _variables[varnum2]); }
void Script::o_add() { uint16 varnum1 = readScript8or16bits(); uint16 varnum2 = readScript16bits(); debugScript(1, true, "ADD var[0x%04X] += var[0x%04X]", varnum1, varnum2); setVariable(varnum1, _variables[varnum1] + _variables[varnum2]); }
void Script::o_mov() { uint16 varnum1 = readScript8or16bits(); uint16 varnum2 = readScript16bits(); debugScript(1, true, "MOV var[0x%04X] = var[0x%04X]", varnum1, varnum2); setVariable(varnum1, _variables[varnum2]); }
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_hotspotbottom_4() { //0x30 uint16 address = readScript16bits(); debugScript(5, true, "HOTSPOT-BOTTOM @0x%04X", address); // Mark the 80 pixels under the game area Common::Rect rect(0, 400, 640, 480); hotspot(rect, address, 4); }
void Script::o_playsong() { // 0x02 uint16 fileref = readScript16bits(); debugScript(1, true, "PlaySong(0x%04X): Play xmidi file", fileref); if (fileref == 0x4C17) { warning("this song is special somehow"); // don't save the reference? } _vm->_musicPlayer->playSong(fileref); }
void Script::o_hotspot_left() { uint16 address = readScript16bits(); debugScript(5, true, "HOTSPOT-LEFT @0x%04X", address); // Mark the leftmost 100 pixels of the game area Common::Rect rect(0, 80, 100, 400); hotspot(rect, address, 1); }
void Script::o_hotspot_right() { uint16 address = readScript16bits(); debugScript(5, true, "HOTSPOT-RIGHT @0x%04X", address); // Mark the rightmost 100 pixels of the game area Common::Rect rect(540, 80, 640, 400); hotspot(rect, address, 2); }
void Script::o_hotspot_center() { uint16 address = readScript16bits(); debugScript(5, true, "HOTSPOT-CENTER @0x%04X", address); // Mark the centremost 240 pixels of the game area Common::Rect rect(200, 80, 440, 400); hotspot(rect, address, 0); }
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_hotspot_outrect() { uint16 left = readScript16bits(); uint16 top = readScript16bits(); uint16 right = readScript16bits(); uint16 bottom = readScript16bits(); uint16 address = readScript16bits(); debugScript(1, true, "HOTSPOT-OUTRECT(%d,%d,%d,%d) @0x%04X (TODO)", left, top, right, bottom, address); // Test if the current mouse position is outside the specified rectangle Common::Rect rect(left, top, right, bottom); Common::Point mousepos = _vm->_system->getEventManager()->getMousePos(); bool contained = rect.contains(mousepos); if (!contained) { error("hotspot-outrect unimplemented"); // TODO: what to do with address? } }
void Script::o_hotspot_current() { uint16 address = readScript16bits(); debugScript(5, true, "HOTSPOT-CURRENT @0x%04X", address); // The original interpreter doesn't check the position, so accept the // whole screen Common::Rect rect(0, 0, 640, 480); hotspot(rect, address, 0); }
void Script::o_swap() { uint16 varnum1 = readScript8or16bits(); uint16 varnum2 = readScript16bits(); debugScript(1, true, "SWAP var[0x%04X] <-> var[0x%04X]", varnum1, varnum2); uint8 tmp = _variables[varnum1]; setVariable(varnum1, _variables[varnum2]); setVariable(varnum2, tmp); }
void Script::o_copyrecttobg() { // 0x37 uint16 left = readScript16bits(); uint16 top = readScript16bits(); uint16 right = readScript16bits(); uint16 bottom = readScript16bits(); uint16 i, width = right - left, height = bottom - top; uint32 offset = 0; byte *fg, *bg; debugScript(1, true, "COPYRECT((%d,%d)->(%d,%d))", left, top, right, bottom); fg = (byte *)_vm->_graphicsMan->_foreground.getBasePtr(left, top - 80); bg = (byte *)_vm->_graphicsMan->_background.getBasePtr(left, top - 80); for (i = 0; i < height; i++) { memcpy(bg + offset, fg + offset, width); offset += 640; } _vm->_system->copyRectToScreen((byte *)_vm->_graphicsMan->_background.getBasePtr(left, top - 80), 640, left, top, width, height); _vm->_graphicsMan->change(); }
void Script::o_call() { uint16 address = readScript16bits(); debugScript(1, true, "CALL @0x%04X", address); // Save return address in the call stack _stack[_stacktop] = _currentInstruction; _stacktop++; // Change the current instruction _currentInstruction = address; }
void Script::o_strcmpnejmp_var() { // 0x21 uint16 data = readScriptVar(); if (data > 9) { data -= 7; } data = _variables[data + 0x19]; bool stringsmatch = 1; do { if (_variables[data++] != readScriptChar(true, true, true)) { stringsmatch = 0; } } while (!(getCodeByte(_currentInstruction - 1) & 0x80)); uint16 offset = readScript16bits(); if (!stringsmatch) { _currentInstruction = offset; } }
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_videofromref() { // 0x09 uint16 fileref = readScript16bits(); // Show the debug information just when starting the playback if (fileref != _videoRef) { debugScript(1, false, "VIDEOFROMREF(0x%04X) (Not fully imp): Play video file from ref", fileref); debugC(5, kGroovieDebugVideo | kGroovieDebugAll, "Playing video 0x%04X via 0x09", fileref); } switch (fileref) { case 0x1C03: // Trilobyte logo case 0x1C04: // Virgin logo case 0x1C05: // Credits if (fileref != _videoRef) { debugScript(1, true, "Use external file if available"); } break; case 0x400D: // floating objects in music room case 0x5060: // a sound from gamwav? case 0x5098: // a sound from gamwav? case 0x2402: // House becomes book in intro? case 0x1426: // Turn to face front in hall: played after intro case 0x206D: // Cards on table puzzle (bedroom) case 0x2001: // Coins on table puzzle (bedroom) if (fileref != _videoRef) { debugScript(1, false, " (This video is special somehow!)"); warning("(This video (0x%04X) is special somehow!)", fileref); } } if (fileref != _videoRef) { debugScript(1, false, "\n"); } // Play the video if (!playvideofromref(fileref)) { // Move _currentInstruction back _currentInstruction -= 3; } }
void Script::o_charlessjmp() { uint16 varnum = readScript8or16bits(); uint8 result = 0; debugScript(1, false, "CHARLESS-JMP: var[0x%04X..],", varnum); do { uint8 val = readScriptChar(true, true, true); if (val > _variables[varnum]) { result = 1; } varnum++; debugScript(1, false, " 0x%02X", val); } while (!(getCodeByte(_currentInstruction - 1) & 0x80)); uint16 address = readScript16bits(); if (result) { debugScript(1, true, " jumping to @0x%04X", address); _currentInstruction = address; } else { debugScript(1, true, " not jumping"); } }
void Script::o_strcmpeqjmp() { // 0x23 uint16 varnum = readScript8or16bits(); uint8 result = 1; debugScript(1, false, "STRCMP-EQJMP: var[0x%04X..],", varnum); do { uint8 val = readScriptChar(true, true, true); if (_variables[varnum] != val) { result = 0; } varnum++; debugScript(1, false, " 0x%02X", val); } while (!(getCodeByte(_currentInstruction - 1) & 0x80)); uint16 address = readScript16bits(); if (result) { debugScript(1, true, " jumping to @0x%04X", address); _currentInstruction = address; } else { debugScript(1, true, " not jumping"); } }
void Script::o2_copyscreentobg() { uint16 val = readScript16bits(); debugScript(1, true, "CopyScreenToBG3: 0x%04X", val); error("Unimplemented Opcode 0x4F"); }
void Script::o2_copybgtoscreen() { uint16 val = readScript16bits(); debugScript(1, true, "CopyBG3ToScreen: 0x%04X", val); error("Unimplemented Opcode 0x50"); }
void Script::o_setbackgroundsong() { // 0x08 uint16 fileref = readScript16bits(); debugScript(1, true, "SetBackgroundSong(0x%04X)", fileref); _vm->_musicPlayer->setBackgroundSong(fileref); }
void Script::o2_setvideoskip() { _videoSkipAddress = readScript16bits(); debugScript(1, true, "SetVideoSkip (0x%04X)", _videoSkipAddress); }
void Script::o_nop16() { uint16 tmp = readScript16bits(); debugScript(1, true, "NOP16: 0x%04X", tmp); }
uint32 Script::readScript32bits() { uint16 lower = readScript16bits(); uint16 upper = readScript16bits(); return lower | (upper << 16); }
void Script::o2_setscriptend() { uint16 arg = readScript16bits(); debugScript(1, true, "SetScriptEnd (0x%04X)", arg); }