mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
Waxworks DOS has both digital and limited MIDI SFX. The game scripts use two different opcodes for trigging digital and MIDI SFX; if a sound effect has both a digital and a MIDI version, both opcodes are triggered. When digital SFX are active, ScummVM would try to handle both the digital and the MIDI opcode by playing a digital SFX. This would crash the game if the MIDI SFX ID was invalid as a digital SFX ID. Strangely enough, this bug also seems to affect the Amiga version. Apparently both opcodes are still in the scripts of this version, even though it does not support MIDI at all AFAIK. This commit fixes the issue by only playing the MIDI SFX if digital SFX are turned off and ignoring them otherwise.
727 lines
16 KiB
C++
727 lines
16 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
#include "agos/agos.h"
|
|
#include "agos/intern.h"
|
|
|
|
namespace AGOS {
|
|
|
|
#define OPCODE(x) _OPCODE(AGOSEngine_Elvira2, x)
|
|
|
|
void AGOSEngine_Elvira2::setupOpcodes() {
|
|
static const OpcodeEntryElvira2 opcodes[] = {
|
|
/* 00 */
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_at),
|
|
OPCODE(o_notAt),
|
|
OPCODE(o_invalid),
|
|
/* 04 */
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_carried),
|
|
OPCODE(o_notCarried),
|
|
OPCODE(o_isAt),
|
|
/* 08 */
|
|
OPCODE(oe1_isNotAt),
|
|
OPCODE(oe1_sibling),
|
|
OPCODE(oe1_notSibling),
|
|
OPCODE(o_zero),
|
|
/* 12 */
|
|
OPCODE(o_notZero),
|
|
OPCODE(o_eq),
|
|
OPCODE(o_notEq),
|
|
OPCODE(o_gt),
|
|
/* 16 */
|
|
OPCODE(o_lt),
|
|
OPCODE(o_eqf),
|
|
OPCODE(o_notEqf),
|
|
OPCODE(o_ltf),
|
|
/* 20 */
|
|
OPCODE(o_gtf),
|
|
OPCODE(oe1_isIn),
|
|
OPCODE(oe1_isNotIn),
|
|
OPCODE(o_chance),
|
|
/* 24 */
|
|
OPCODE(oe1_isPlayer),
|
|
OPCODE(o_isRoom),
|
|
OPCODE(o_isObject),
|
|
OPCODE(o_state),
|
|
/* 28 */
|
|
OPCODE(o_oflag),
|
|
OPCODE(oe1_canPut),
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_destroy),
|
|
/* 32 */
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_place),
|
|
OPCODE(oe1_copyof),
|
|
OPCODE(oe1_copyfo),
|
|
/* 36 */
|
|
OPCODE(o_copyff),
|
|
OPCODE(oe1_whatO),
|
|
OPCODE(o_invalid),
|
|
OPCODE(oe1_weigh),
|
|
/* 40 */
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_clear),
|
|
OPCODE(o_let),
|
|
OPCODE(o_add),
|
|
/* 44 */
|
|
OPCODE(o_sub),
|
|
OPCODE(o_addf),
|
|
OPCODE(o_subf),
|
|
OPCODE(o_mul),
|
|
/* 48 */
|
|
OPCODE(o_div),
|
|
OPCODE(o_mulf),
|
|
OPCODE(o_divf),
|
|
OPCODE(o_mod),
|
|
/* 52 */
|
|
OPCODE(o_modf),
|
|
OPCODE(o_random),
|
|
OPCODE(oe2_moveDirn),
|
|
OPCODE(o_goto),
|
|
/* 56 */
|
|
OPCODE(o_oset),
|
|
OPCODE(o_oclear),
|
|
OPCODE(o_putBy),
|
|
OPCODE(o_inc),
|
|
/* 60 */
|
|
OPCODE(o_dec),
|
|
OPCODE(o_setState),
|
|
OPCODE(o_print),
|
|
OPCODE(o_message),
|
|
/* 64 */
|
|
OPCODE(o_msg),
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_invalid),
|
|
/* 68 */
|
|
OPCODE(o_end),
|
|
OPCODE(o_done),
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_process),
|
|
/* 72 */
|
|
OPCODE(oe2_doClass),
|
|
OPCODE(oe2_pObj),
|
|
OPCODE(oe1_pName),
|
|
OPCODE(oe1_pcName),
|
|
/* 76 */
|
|
OPCODE(o_when),
|
|
OPCODE(o_if1),
|
|
OPCODE(o_if2),
|
|
OPCODE(oe2_isCalled),
|
|
/* 80 */
|
|
OPCODE(o_is),
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_debug),
|
|
OPCODE(oe1_rescan),
|
|
/* 84 */
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_comment),
|
|
/* 88 */
|
|
OPCODE(o_invalid),
|
|
OPCODE(oe1_loadGame),
|
|
OPCODE(o_getParent),
|
|
OPCODE(o_getNext),
|
|
/* 92 */
|
|
OPCODE(o_getChildren),
|
|
OPCODE(o_invalid),
|
|
OPCODE(oe1_findMaster),
|
|
OPCODE(oe1_nextMaster),
|
|
/* 96 */
|
|
OPCODE(o_picture),
|
|
OPCODE(o_loadZone),
|
|
OPCODE(oe1_animate),
|
|
OPCODE(oe1_stopAnimate),
|
|
/* 100 */
|
|
OPCODE(o_killAnimate),
|
|
OPCODE(o_defWindow),
|
|
OPCODE(o_window),
|
|
OPCODE(o_cls),
|
|
/* 104 */
|
|
OPCODE(o_closeWindow),
|
|
OPCODE(oe2_menu),
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_addBox),
|
|
/* 108 */
|
|
OPCODE(o_delBox),
|
|
OPCODE(o_enableBox),
|
|
OPCODE(o_disableBox),
|
|
OPCODE(o_moveBox),
|
|
/* 112 */
|
|
OPCODE(o_invalid),
|
|
OPCODE(oe2_drawItem),
|
|
OPCODE(o_doIcons),
|
|
OPCODE(o_isClass),
|
|
/* 116 */
|
|
OPCODE(o_setClass),
|
|
OPCODE(o_unsetClass),
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_waitSync),
|
|
/* 120*/
|
|
OPCODE(o_sync),
|
|
OPCODE(o_defObj),
|
|
OPCODE(o_invalid),
|
|
OPCODE(oe1_setTime),
|
|
/* 124 */
|
|
OPCODE(oe1_ifTime),
|
|
OPCODE(o_here),
|
|
OPCODE(o_doClassIcons),
|
|
OPCODE(o_playTune),
|
|
/* 128 */
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_setAdjNoun),
|
|
OPCODE(o_invalid),
|
|
/* 132 */
|
|
OPCODE(o_saveUserGame),
|
|
OPCODE(o_loadUserGame),
|
|
OPCODE(o_invalid),
|
|
OPCODE(oe2_pauseGame),
|
|
/* 136 */
|
|
OPCODE(o_copysf),
|
|
OPCODE(o_restoreIcons),
|
|
OPCODE(o_freezeZones),
|
|
OPCODE(o_placeNoIcons),
|
|
/* 140 */
|
|
OPCODE(o_clearTimers),
|
|
OPCODE(o_setDollar),
|
|
OPCODE(o_isBox),
|
|
OPCODE(oe2_doTable),
|
|
/* 144 */
|
|
OPCODE(oe2_setDoorOpen),
|
|
OPCODE(oe2_setDoorClosed),
|
|
OPCODE(oe2_setDoorLocked),
|
|
OPCODE(oe2_setDoorClosed),
|
|
/* 148 */
|
|
OPCODE(oe2_ifDoorOpen),
|
|
OPCODE(oe2_ifDoorClosed),
|
|
OPCODE(oe2_ifDoorLocked),
|
|
OPCODE(oe2_storeItem),
|
|
/* 152 */
|
|
OPCODE(oe2_getItem),
|
|
OPCODE(oe2_bSet),
|
|
OPCODE(oe2_bClear),
|
|
OPCODE(oe2_bZero),
|
|
/* 156 */
|
|
OPCODE(oe2_bNotZero),
|
|
OPCODE(oe2_getOValue),
|
|
OPCODE(oe2_setOValue),
|
|
OPCODE(o_invalid),
|
|
/* 160 */
|
|
OPCODE(oe2_ink),
|
|
OPCODE(oe2_printStats),
|
|
OPCODE(o_invalid),
|
|
OPCODE(o_invalid),
|
|
/* 164 */
|
|
OPCODE(o_invalid),
|
|
OPCODE(oe2_setSuperRoom),
|
|
OPCODE(oe2_getSuperRoom),
|
|
OPCODE(oe2_setExitOpen),
|
|
/* 168 */
|
|
OPCODE(oe2_setExitClosed),
|
|
OPCODE(oe2_setExitLocked),
|
|
OPCODE(oe2_setExitClosed),
|
|
OPCODE(oe2_ifExitOpen),
|
|
/* 172 */
|
|
OPCODE(oe2_ifExitClosed),
|
|
OPCODE(oe2_ifExitLocked),
|
|
OPCODE(oe2_playEffect),
|
|
OPCODE(oe2_getDollar2),
|
|
/* 176 */
|
|
OPCODE(oe2_setSRExit),
|
|
OPCODE(oe2_printPlayerDamage),
|
|
OPCODE(oe2_printMonsterDamage),
|
|
OPCODE(oe2_isAdjNoun),
|
|
/* 180 */
|
|
OPCODE(oe2_b2Set),
|
|
OPCODE(oe2_b2Clear),
|
|
OPCODE(oe2_b2Zero),
|
|
OPCODE(oe2_b2NotZero)
|
|
};
|
|
|
|
_opcodesElvira2 = opcodes;
|
|
_numOpcodes = 184;
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::executeOpcode(int opcode) {
|
|
OpcodeProcElvira2 op = _opcodesElvira2[opcode].proc;
|
|
(this->*op) ();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Elvira 2 Opcodes
|
|
// -----------------------------------------------------------------------
|
|
|
|
void AGOSEngine_Elvira2::oe2_moveDirn() {
|
|
// 54: move direction
|
|
int16 d = getVarOrByte();
|
|
moveDirn(me(), d);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_doClass() {
|
|
// 72: do class
|
|
Item *i = getNextItemPtr();
|
|
byte cm = getByte();
|
|
int16 num = getVarOrWord();
|
|
|
|
_classMask = (cm != 0xFF) ? 1 << cm : 0;
|
|
_classLine = (SubroutineLine *)((byte *)_currentTable + _currentLine->next);
|
|
if (num == 1) {
|
|
_subjectItem = findInByClass(i, (1 << cm));
|
|
if (_subjectItem)
|
|
_classMode1 = 1;
|
|
else
|
|
_classMode1 = 0;
|
|
} else {
|
|
_objectItem = findInByClass(i, (1 << cm));
|
|
if (_objectItem)
|
|
_classMode2 = 1;
|
|
else
|
|
_classMode2 = 0;
|
|
}
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_pObj() {
|
|
// 73: print object
|
|
SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), kObjectType);
|
|
|
|
if (subObject != nullptr && subObject->objectFlags & kOFText)
|
|
showMessageFormat("%s", (const char *)getStringPtrByID(subObject->objectFlagValue[0]));
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_isCalled() {
|
|
// 79: childstruct fr2 is
|
|
Item *i = getNextItemPtr();
|
|
uint stringId = getNextStringID();
|
|
setScriptCondition(i->itemName == stringId);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_menu() {
|
|
// 105: set agos menu
|
|
_agosMenu = getVarOrByte();
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_drawItem() {
|
|
// 113: draw item
|
|
Item *i = getNextItemPtr();
|
|
int a = getVarOrByte();
|
|
int x = getVarOrWord();
|
|
int y = getVarOrWord();
|
|
mouseOff();
|
|
drawIcon(_windowArray[a % 8], itemGetIconNumber(i), x, y);
|
|
mouseOn();
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_doTable() {
|
|
// 143: start item sub
|
|
Item *i = getNextItemPtr();
|
|
|
|
SubRoom *r = (SubRoom *)findChildOfType(i, kRoomType);
|
|
if (r != nullptr) {
|
|
Subroutine *sub = getSubroutineByID(r->subroutine_id);
|
|
if (sub) {
|
|
startSubroutine(sub);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (getGameType() == GType_ELVIRA2) {
|
|
SubSuperRoom *sr = (SubSuperRoom *)findChildOfType(i, kSuperRoomType);
|
|
if (sr != nullptr) {
|
|
Subroutine *sub = getSubroutineByID(sr->subroutine_id);
|
|
if (sub) {
|
|
startSubroutine(sub);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_pauseGame() {
|
|
// 135: pause game
|
|
HitArea *ha;
|
|
|
|
uint32 pauseTime = getTime();
|
|
haltAnimation();
|
|
|
|
while (!shouldQuit()) {
|
|
_lastHitArea = nullptr;
|
|
_lastHitArea3 = nullptr;
|
|
|
|
while (!shouldQuit()) {
|
|
if (processSpecialKeys() != 0 || _lastHitArea3 != nullptr)
|
|
break;
|
|
delay(1);
|
|
}
|
|
|
|
ha = _lastHitArea;
|
|
|
|
if (ha == nullptr) {
|
|
} else if (ha->id == 201) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
restartAnimation();
|
|
_gameStoppedClock = getTime() - pauseTime + _gameStoppedClock;
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_setDoorOpen() {
|
|
// 144: set door open
|
|
Item *i = getNextItemPtr();
|
|
setDoorState(i, getVarOrByte(), 1);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_setDoorClosed() {
|
|
// 145: set door closed
|
|
Item *i = getNextItemPtr();
|
|
setDoorState(i, getVarOrByte(), 2);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_setDoorLocked() {
|
|
// 146: set door locked
|
|
Item *i = getNextItemPtr();
|
|
setDoorState(i, getVarOrByte(), 3);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_ifDoorOpen() {
|
|
// 148: if door open
|
|
Item *i = getNextItemPtr();
|
|
uint16 d = getVarOrByte();
|
|
|
|
if (getGameType() == GType_WW) {
|
|
// WORKAROUND bug #4229: A NULL item can occur when
|
|
// walking through Jack the Ripper scene
|
|
if (i == nullptr) {
|
|
setScriptCondition(false);
|
|
return;
|
|
}
|
|
}
|
|
|
|
setScriptCondition(getDoorState(i, d) == 1);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_ifDoorClosed() {
|
|
// 149: if door closed
|
|
Item *i = getNextItemPtr();
|
|
uint16 d = getVarOrByte();
|
|
setScriptCondition(getDoorState(i, d) == 2);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_ifDoorLocked() {
|
|
// 150: if door locked
|
|
Item *i=getNextItemPtr();
|
|
uint16 d = getVarOrByte();
|
|
setScriptCondition(getDoorState(i, d) == 3);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_storeItem() {
|
|
// 151: set array6 to item
|
|
uint var = getVarOrByte();
|
|
Item *item = getNextItemPtr();
|
|
_itemStore[var] = item;
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_getItem() {
|
|
// 152: set m1 to m3 to array 6
|
|
Item *item = _itemStore[getVarOrByte()];
|
|
uint var = getVarOrByte();
|
|
if (var == 1) {
|
|
_subjectItem = item;
|
|
} else {
|
|
_objectItem = item;
|
|
}
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_bSet() {
|
|
// 153: set bit
|
|
setBitFlag(getVarWrapper(), true);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_bClear() {
|
|
// 154: clear bit
|
|
setBitFlag(getVarWrapper(), false);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_bZero() {
|
|
// 155: is bit clear
|
|
setScriptCondition(!getBitFlag(getVarWrapper()));
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_bNotZero() {
|
|
// 156: is bit set
|
|
uint bit = getVarWrapper();
|
|
|
|
// WORKAROUND: Enable copy protection again, in cracked version.
|
|
if (getGameType() == GType_SIMON1 && _currentTable && _currentTable->id == 2962 && bit == 63) {
|
|
bit = 50;
|
|
}
|
|
|
|
setScriptCondition(getBitFlag(bit));
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_getOValue() {
|
|
// 157: get item int prop
|
|
Item *item = getNextItemPtr();
|
|
SubObject *subObject = (SubObject *)findChildOfType(item, kObjectType);
|
|
uint prop = getVarOrByte();
|
|
|
|
if (subObject != nullptr && subObject->objectFlags & (1 << prop) && prop < 16) {
|
|
uint offs = getOffsetOfChild2Param(subObject, 1 << prop);
|
|
writeNextVarContents(subObject->objectFlagValue[offs]);
|
|
} else {
|
|
writeNextVarContents(0);
|
|
}
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_setOValue() {
|
|
// 158: set item prop
|
|
Item *item = getNextItemPtr();
|
|
SubObject *subObject = (SubObject *)findChildOfType(item, kObjectType);
|
|
uint prop = getVarOrByte();
|
|
int value = getVarOrWord();
|
|
|
|
if (subObject != nullptr && subObject->objectFlags & (1 << prop) && prop < 16) {
|
|
uint offs = getOffsetOfChild2Param(subObject, 1 << prop);
|
|
subObject->objectFlagValue[offs] = value;
|
|
}
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_ink() {
|
|
// 160
|
|
setTextColor(getVarOrByte());
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_printStats() {
|
|
// 161: print stats
|
|
printStats();
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_setSuperRoom() {
|
|
// 165: set super room
|
|
_superRoomNumber = getVarOrWord();
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_getSuperRoom() {
|
|
// 166: get super room
|
|
writeNextVarContents(_superRoomNumber);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_setExitOpen() {
|
|
// 167: set exit open
|
|
Item *i = getNextItemPtr();
|
|
uint16 n = getVarOrWord();
|
|
uint16 d = getVarOrByte();
|
|
setExitState(i, n, d, 1);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_setExitClosed() {
|
|
// 168: set exit closed
|
|
Item *i = getNextItemPtr();
|
|
uint16 n = getVarOrWord();
|
|
uint16 d = getVarOrByte();
|
|
setExitState(i, n, d, 2);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_setExitLocked() {
|
|
// 169: set exit locked
|
|
Item *i = getNextItemPtr();
|
|
uint16 n = getVarOrWord();
|
|
uint16 d = getVarOrByte();
|
|
setExitState(i, n, d, 3);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_ifExitOpen() {
|
|
// 171: if exit open
|
|
Item *i = getNextItemPtr();
|
|
uint16 n = getVarOrWord();
|
|
uint16 d = getVarOrByte();
|
|
setScriptCondition(getExitState(i, n, d) == 1);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_ifExitClosed() {
|
|
// 172: if exit closed
|
|
Item *i = getNextItemPtr();
|
|
uint16 n = getVarOrWord();
|
|
uint16 d = getVarOrByte();
|
|
setScriptCondition(getExitState(i, n, d) == 2);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_ifExitLocked() {
|
|
// 173: if exit locked
|
|
Item *i = getNextItemPtr();
|
|
uint16 n = getVarOrWord();
|
|
uint16 d = getVarOrByte();
|
|
setScriptCondition(getExitState(i, n, d) == 3);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_playEffect() {
|
|
// 174: play sound
|
|
uint soundId = getVarOrWord();
|
|
playSfx(soundId, 0, 0);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_getDollar2() {
|
|
// 175
|
|
_showPreposition = true;
|
|
|
|
setup_cond_c_helper();
|
|
|
|
_objectItem = _hitAreaObjectItem;
|
|
|
|
if (_objectItem == _dummyItem2)
|
|
_objectItem = me();
|
|
|
|
if (_objectItem == _dummyItem3)
|
|
_objectItem = derefItem(me()->parent);
|
|
|
|
if (_objectItem != nullptr) {
|
|
_scriptNoun2 = _objectItem->noun;
|
|
_scriptAdj2 = _objectItem->adjective;
|
|
} else {
|
|
_scriptNoun2 = -1;
|
|
_scriptAdj2 = -1;
|
|
}
|
|
|
|
_showPreposition = false;
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_setSRExit() {
|
|
// 176: set super room exit
|
|
Item *i = getNextItemPtr();
|
|
uint n = getVarOrWord();
|
|
uint d = getVarOrByte();
|
|
uint s = getVarOrByte();
|
|
setSRExit(i, n, d, s);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_printPlayerDamage() {
|
|
// 177: set player damage event
|
|
uint a = getVarOrByte();
|
|
if (_opcode177Var1 && !_opcode177Var2 && a != 0 && a <= 10) {
|
|
addVgaEvent(_vgaBaseDelay, PLAYER_DAMAGE_EVENT, nullptr, 0, a);
|
|
_opcode177Var2 = 0;
|
|
_opcode177Var1 = 0;
|
|
}
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_printMonsterDamage() {
|
|
// 178: set monster damage event
|
|
uint a = getVarOrByte();
|
|
if (_opcode178Var1 && !_opcode178Var2 && a != 0 && a <= 10) {
|
|
addVgaEvent(_vgaBaseDelay, MONSTER_DAMAGE_EVENT, nullptr, 0, a);
|
|
_opcode178Var2 = 0;
|
|
_opcode178Var1 = 0;
|
|
}
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_isAdjNoun() {
|
|
// 179: item unk1 unk2 is
|
|
Item *item = getNextItemPtr();
|
|
int16 a = getNextWord();
|
|
int16 n = getNextWord();
|
|
|
|
if (getGameType() == GType_ELVIRA2 && item == nullptr) {
|
|
// WORKAROUND bug #3281: A NULL item can occur when
|
|
// interacting with items in the dinning room
|
|
setScriptCondition(false);
|
|
return;
|
|
}
|
|
|
|
assert(item);
|
|
setScriptCondition(item->adjective == a && item->noun == n);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_b2Set() {
|
|
// 180: set bit2
|
|
uint bit = getVarOrByte();
|
|
_bitArrayTwo[bit / 16] |= (1 << (bit & 15));
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_b2Clear() {
|
|
// 181: clear bit2
|
|
uint bit = getVarOrByte();
|
|
_bitArrayTwo[bit / 16] &= ~(1 << (bit & 15));
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_b2Zero() {
|
|
// 182: is bit2 clear
|
|
uint bit = getVarOrByte();
|
|
setScriptCondition((_bitArrayTwo[bit / 16] & (1 << (bit & 15))) == 0);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::oe2_b2NotZero() {
|
|
// 183: is bit2 set
|
|
uint bit = getVarOrByte();
|
|
setScriptCondition((_bitArrayTwo[bit / 16] & (1 << (bit & 15))) != 0);
|
|
}
|
|
|
|
void AGOSEngine_Elvira2::printStats() {
|
|
WindowBlock *window = _dummyWindow;
|
|
int val;
|
|
const uint8 y = (getPlatform() == Common::kPlatformAtariST) ? 132 : 134;
|
|
|
|
window->flags = 1;
|
|
|
|
mouseOff();
|
|
|
|
// Level
|
|
val = _variableArray[20];
|
|
if (val < -99)
|
|
val = -99;
|
|
if (val > 99)
|
|
val = 99;
|
|
writeChar(window, 10, y, 0, val);
|
|
|
|
// PP
|
|
val = _variableArray[22];
|
|
if (val < -99)
|
|
val = -99;
|
|
if (val > 99)
|
|
val = 99;
|
|
writeChar(window, 16, y, 6, val);
|
|
|
|
// HP
|
|
val = _variableArray[23];
|
|
if (val < -99)
|
|
val = -99;
|
|
if (val > 99)
|
|
val = 99;
|
|
writeChar(window, 23, y, 4, val);
|
|
|
|
// Experience
|
|
val = _variableArray[21];
|
|
if (val < -99)
|
|
val = -99;
|
|
if (val > 9999)
|
|
val = 9999;
|
|
writeChar(window, 30, y, 6, val / 100);
|
|
writeChar(window, 32, y, 2, val % 100);
|
|
|
|
mouseOn();
|
|
}
|
|
|
|
} // End of namespace AGOS
|