void Script::o_loadgame() { uint16 varnum = readScript8or16bits(); uint8 slot = _variables[varnum]; debugScript(1, true, "LOADGAME var[0x%04X] -> slot=%d (TODO)", varnum, slot); loadgame(slot); _vm->_system->fillScreen(0); }
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_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_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_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_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_playcd() { uint8 val = readScript8bits(); debugScript(1, true, "PLAYCD %d", val); if (val == 2) { // TODO: Play the alternative logo } _vm->_musicPlayer->playCD(val); }
void Script::o_setvideoorigin() { // Read the two offset arguments int16 origX = readScript16bits(); int16 origY = readScript16bits(); // Set bitflag 7 _bitflags |= 1 << 7; debugScript(1, true, "SetVideoOrigin(0x%04X,0x%04X) (%d, %d)", origX, origY, origX, origY); _vm->_videoPlayer->setOrigin(origX, origY); }
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_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_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_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::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::o2_videofromref(){ uint32 fileref = readScript32bits(); // Show the debug information just when starting the playback if (fileref != _videoRef) { debugScript(1, true, "VIDEOFROMREF(0x%08X) (Not fully imp): Play video file from ref", fileref); debugC(5, kGroovieDebugVideo | kGroovieDebugAll, "Playing video 0x%08X via 0x09", fileref); } // Play the video if (!playvideofromref(fileref)) { // Move _currentInstruction back _currentInstruction -= 5; } }
void Script::o_inputloopend() { debugScript(5, true, "Input loop end"); // Handle the predefined hotspots if (_hotspotTopAction) { Common::Rect rect(0, 0, 640, 80); hotspot(rect, _hotspotTopAction, _hotspotTopCursor); } if (_hotspotBottomAction) { Common::Rect rect(0, 400, 640, 480); hotspot(rect, _hotspotBottomAction, _hotspotBottomCursor); } if (_hotspotRightAction) { Common::Rect rect(560, 0, 640, 480); hotspot(rect, _hotspotRightAction, 2); } if (_hotspotLeftAction) { Common::Rect rect(0, 0, 80, 480); hotspot(rect, _hotspotLeftAction, 1); } // Actually execute the planned action if (_inputAction != -1) { // Jump to the planned address _currentInstruction = _inputAction; // Exit the input loop _inputLoopAddress = 0; _vm->_grvCursorMan->show(false); // Force immediate hiding of the mouse cursor (required when the next // video just contains audio) _vm->_graphicsMan->change(); } // Nothing to do if (_inputLoopAddress) { if (_newCursorStyle != _vm->_grvCursorMan->getStyle()) { _vm->_grvCursorMan->setStyle(_newCursorStyle); } _vm->_grvCursorMan->show(true); // Go back to the begining of the loop _currentInstruction = _inputLoopAddress; // There's nothing to do until we get some input _vm->waitForInput(); } }
void Script::o_videofromstring1() { uint16 instStart = _currentInstruction; uint16 fileref = getVideoRefString(); // Show the debug information just when starting the playback if (fileref != _videoRef) { debugScript(0, true, "VIDEOFROMSTRING1 0x%04X", fileref); } // Play the video if (!playvideofromref(fileref)) { // Move _currentInstruction back _currentInstruction = instStart - 1; } }
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_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_obscureswap() { uint16 var1, var2, tmp; debugScript(1, true, "OBSCSWAP"); // Read the first variable var1 = readScriptChar(false, true, true) * 10; var1 += readScriptChar(false, true, true) + 0x19; // Read the second variable var2 = readScriptChar(false, true, true) * 10; var2 += readScriptChar(false, true, true) + 0x19; // Swap the values tmp = _variables[var1]; setVariable(var1, _variables[var2]); setVariable(var2, tmp); }
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_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_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_inputloopstart() { //0x0B debugScript(5, true, "Input loop start"); // Reset the input action and the mouse cursor _inputAction = -1; _newCursorStyle = 5; // Save the input loop address _inputLoopAddress = _currentInstruction - 1; // Save the current mouse state for the whole loop _mouseClicked = _eventMouseClicked; _eventMouseClicked = false; // Save the current pressed character for the whole loop _kbdChar = _eventKbdChar; _eventKbdChar = 0; _vm->_musicPlayer->startBackground(); }
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_videofromstring2() { uint16 instStart = _currentInstruction; uint32 fileref = getVideoRefString(); // Show the debug information just when starting the playback if (fileref != _videoRef) { debugScript(0, true, "VIDEOFROMSTRING2 0x%04X", fileref); } // Set bit 1 _bitflags |= 1 << 1; // Set bit 2 if _firstbit if (_firstbit) { _bitflags |= 1 << 2; } // Play the video if (!playvideofromref(fileref)) { // Move _currentInstruction back _currentInstruction = instStart - 1; } }
void Script::o2_vdxtransition(){ uint32 fileref = readScript32bits(); // Show the debug information just when starting the playback if (fileref != _videoRef) { debugScript(1, true, "VDX transition fileref = 0x%08X", fileref); debugC(1, kGroovieDebugVideo | kGroovieDebugAll, "Playing video 0x%08X with transition", fileref); } // Set bit 1 _bitflags |= 1 << 1; // Set bit 2 if _firstbit if (_firstbit) { _bitflags |= 1 << 2; } // Play the video if (!playvideofromref(fileref)) { // Move _currentInstruction back _currentInstruction -= 5; } }
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_getcd() { debugScript(1, true, "GETCD"); // By default set it to no CD available int8 cd = -1; // Try to open one file from each CD Common::File cdfile; if (cdfile.open("b.gjd")) { cdfile.close(); cd = 1; } if (cdfile.open("at.gjd")) { cdfile.close(); if (cd == 1) { // Both CDs are available cd = 0; } else { cd = 2; } } setVariable(0x106, cd); }
void Script::o_copybgtofg() { // 0x22 debugScript(1, true, "COPY_BG_TO_FG"); memcpy(_vm->_graphicsMan->_foreground.getBasePtr(0, 0), _vm->_graphicsMan->_background.getBasePtr(0, 0), 640 * 320); }