reg_t reg_t::operator+(const reg_t right) const { if (isPointer() && right.isNumber()) { // Pointer arithmetics. Only some pointer types make sense here SegmentObj *mobj = g_sci->getEngineState()->_segMan->getSegmentObj(getSegment()); if (!mobj) error("[VM]: Attempt to add %d to invalid pointer %04x:%04x", right.getOffset(), PRINT_REG(*this)); switch (mobj->getType()) { case SEG_TYPE_LOCALS: case SEG_TYPE_SCRIPT: case SEG_TYPE_STACK: case SEG_TYPE_DYNMEM: return make_reg(getSegment(), getOffset() + right.toSint16()); default: return lookForWorkaround(right, "addition"); } } else if (isNumber() && right.isPointer()) { // Adding a pointer to a number, flip the order return right + *this; } else if (isNumber() && right.isNumber()) { // Normal arithmetics return make_reg(0, toSint16() + right.toSint16()); } else { return lookForWorkaround(right, "addition"); } }
reg_t reg_t::operator-(const reg_t right) const { if (getSegment() == right.getSegment()) { // We can subtract numbers, or pointers with the same segment, // an operation which will yield a number like in C return make_reg(0, toSint16() - right.toSint16()); } else { return *this + make_reg(right.getSegment(), -right.toSint16()); } }
void GuestAdditions::syncAudioVolumeGlobalsToScummVM(const int index, const reg_t value) const { switch (g_sci->getGameId()) { case GID_GK2: if (index == kGlobalVarGK2MusicVolume) { const int16 musicVolume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / Audio32::kMaxVolume; ConfMan.setInt("music_volume", musicVolume); } break; case GID_LSL6HIRES: if (index == kGlobalVarLSL6HiresMusicVolume) { const int16 musicVolume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / kLSL6HiresUIVolumeMax; ConfMan.setInt("music_volume", musicVolume); } break; case GID_PHANTASMAGORIA: if (index == kGlobalVarPhant1MusicVolume) { const int16 musicVolume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / MUSIC_MASTERVOLUME_MAX; ConfMan.setInt("music_volume", musicVolume); } else if (index == kGlobalVarPhant1DACVolume) { const int16 dacVolume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / Audio32::kMaxVolume; ConfMan.setInt("sfx_volume", dacVolume); ConfMan.setInt("speech_volume", dacVolume); } break; case GID_TORIN: if (index == kGlobalVarTorinMusicVolume || index == kGlobalVarTorinSFXVolume || index == kGlobalVarTorinSpeechVolume) { const int16 volume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / 100; switch (index) { case kGlobalVarTorinMusicVolume: ConfMan.setInt("music_volume", volume); break; case kGlobalVarTorinSFXVolume: ConfMan.setInt("sfx_volume", volume); break; case kGlobalVarTorinSpeechVolume: ConfMan.setInt("speech_volume", volume); break; } } break; default: break; } }
void GuestAdditions::syncMessageTypeToScummVMUsingDefaultStrategy(const int index, const reg_t value) { if (index == kGlobalVarMessageType) { // ScummVM audio options haven't been applied yet. Use this set call // as a trigger to apply defaults from ScummVM, ignoring the default // value that was just received from the game scripts if (!_messageTypeSynced || _state->variables[VAR_GLOBAL][kGlobalVarQuit] == TRUE_REG) { _messageTypeSynced = true; syncAudioOptionsFromScummVM(); return; } ConfMan.setBool("subtitles", value.toSint16() & kMessageTypeSubtitles); ConfMan.setBool("speech_mute", !(value.toSint16() & kMessageTypeSpeech)); } }
reg_t reg_t::operator%(const reg_t right) const { if (isNumber() && right.isNumber() && !right.isNull()) { // Support for negative numbers was added in Iceman, and perhaps in // SCI0 0.000.685 and later. Theoretically, this wasn't really used // in SCI0, so the result is probably unpredictable. Such a case // would indicate either a script bug, or a modulo on an unsigned // integer larger than 32767. In any case, such a case should be // investigated, instead of being silently accepted. if (getSciVersion() <= SCI_VERSION_0_LATE && (toSint16() < 0 || right.toSint16() < 0)) warning("Modulo of a negative number has been requested for SCI0. This *could* lead to issues"); int16 value = toSint16(); int16 modulo = ABS(right.toSint16()); int16 result = value % modulo; if (result < 0) result += modulo; return make_reg(0, result); } else return lookForWorkaround(right, "modulo"); }
reg_t reg_t::operator/(const reg_t right) const { if (isNumber() && right.isNumber() && !right.isNull()) return make_reg(0, toSint16() / right.toSint16()); else return lookForWorkaround(right, "division"); }
reg_t reg_t::operator*(const reg_t right) const { if (isNumber() && right.isNumber()) return make_reg(0, toSint16() * right.toSint16()); else return lookForWorkaround(right, "multiplication"); }
void GuestAdditions::syncTextSpeedToScummVM(const int index, const reg_t value) const { if (index == kGlobalVarTextSpeed) { ConfMan.setInt("talkspeed", (8 - value.toSint16()) * 255 / 8); } }