Exemple #1
0
void AGOSEngine::openTextWindow() {
	if (_textWindow) {
		if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
			if (_textWindow->flags & 0x80)
				clearWindow(_textWindow);
		}
		return;
	}

	if (getGameType() == GType_FF || getGameType() == GType_PP)
		_textWindow = openWindow(64, 96, 384, 172, 1, 0, 15);
	else
		_textWindow = openWindow(8, 144, 24, 6, 1, 0, 15);
}
Exemple #2
0
void AGOSEngine_Feeble::timerProc() {
	if (_videoLockOut & 0x80E9 || _videoLockOut & 2)
		return;

	_syncCount++;

	_videoLockOut |= 2;

	if (!(_videoLockOut & 0x10)) {
		_syncFlag2 = !_syncFlag2;
		if (!_syncFlag2) {
			processVgaEvents();
		} else {
			// Double speed on Oracle
			if (getGameType() == GType_FF && getBitFlag(99)) {
				processVgaEvents();
			} else if (_scrollCount == 0) {
				_videoLockOut &= ~2;
				return;
			}
		}

		if (getGameType() == GType_FF && _interactiveVideo) {
			// Controls Omni TV videos
			if (getBitFlag(42)) {
				stopInteractiveVideo();
			} else {
				_moviePlayer->nextFrame();
			}
		}

		animateSprites();
	}

	if (_displayFlag) {
		if (getGameType() == GType_FF && !(getFeatures() & GF_DEMO)) {
			if (!getBitFlag(78)) {
				oracleLogo();
			}
			if (getBitFlag(76)) {
				swapCharacterLogo();
			}
		}
		handleMouseMoved();
		displayScreen();
		_displayFlag = 0;
	}

	_videoLockOut &= ~2;
}
Exemple #3
0
void AGOSEngine::playModule(uint16 music) {
	char filename[15];
	Common::File f;
	uint32 offs = 0;

	if (getPlatform() == Common::kPlatformAmiga && getGameType() == GType_WW) {
		// Multiple tunes are stored in music files for main locations
		for (uint i = 0; i < 20; i++) {
			if (amigaWaxworksOffs[i].tune == music) {
				music = amigaWaxworksOffs[i].fileNum;
				offs = amigaWaxworksOffs[i].offs;
			}
		}
	}

	if (getGameType() == GType_ELVIRA1 && getFeatures() & GF_DEMO)
		sprintf(filename, "elvira2");
	else if (getPlatform() == Common::kPlatformAcorn)
		sprintf(filename, "%dtune.DAT", music);
	else
		sprintf(filename, "%dtune", music);

	f.open(filename);
	if (f.isOpen() == false) {
		error("playModule: Can't load module from '%s'", filename);
	}

	Audio::AudioStream *audioStream;
	if (!(getGameType() == GType_ELVIRA1 && getFeatures() & GF_DEMO) &&
		getFeatures() & GF_CRUNCHED) {

		uint32 srcSize = f.size();
		byte *srcBuf = (byte *)malloc(srcSize);
		if (f.read(srcBuf, srcSize) != srcSize)
			error("playModule: Read failed");

		uint32 dstSize = READ_BE_UINT32(srcBuf + srcSize - 4);
		byte *dstBuf = (byte *)malloc(dstSize);
		decrunchFile(srcBuf, dstBuf, srcSize);
		free(srcBuf);

		Common::MemoryReadStream stream(dstBuf, dstSize);
		audioStream = Audio::makeProtrackerStream(&stream, offs);
		free(dstBuf);
	} else {
		audioStream = Audio::makeProtrackerStream(&f);
	}

	_mixer->playStream(Audio::Mixer::kMusicSoundType, &_modHandle, audioStream);
}
Exemple #4
0
void AGOSEngine::dumpAllVgaScriptFiles() {
	uint8 start = (getGameType() == GType_PN) ? 0 : 2;
	uint16 end = (getGameType() == GType_PN) ? 26 : 450;

	for (int z = start; z < end; z++) {
		uint16 zoneNum = (getGameType() == GType_PN) ? 0 : z;
		loadZone(z, false);

		VgaPointersEntry *vpe = &_vgaBufferPointers[zoneNum];
		if (vpe->vgaFile1 != NULL) {
			_curVgaFile1 = vpe->vgaFile1;
			dumpVgaFile(_curVgaFile1);
		}
	}
}
Exemple #5
0
uint AGOSEngine::readVariable(uint16 variable) {
	if (variable >= _numVars)
		error("readVariable: Variable %d out of range", variable);

	if (getGameType() == GType_PP) {
		return (uint16)_variableArray[variable];
	} else if (getGameType() == GType_FF) {
		if (getBitFlag(83))
			return (uint16)_variableArray2[variable];
		else
			return (uint16)_variableArray[variable];
	} else {
			return _variableArray[variable];
	}
}
Exemple #6
0
HitArea *AGOSEngine::findBox(uint hitarea_id) {
	HitArea *ha = _hitAreas;
	uint count = ARRAYSIZE(_hitAreas);

	do {
		if (getGameType() == GType_FF || getGameType() == GType_PP) {
			if (ha->id == hitarea_id && ha->flags != 0)
				return ha;
		} else {
			if (ha->id == hitarea_id)
				return ha;
		}
	} while (ha++, --count);
	return NULL;
}
Exemple #7
0
void AGOSEngine_Simon1::vc22_setPalette() {
	byte *offs, *palptr = 0, *src;
	uint16 a = 0, b, num, palSize = 0;

	a = vcReadNextWord();
	b = vcReadNextWord();

	if (getGameType() == GType_FF || getGameType() == GType_PP) {
		num = 256;
		palSize = 768;

		palptr = _displayPalette;
	} else {
		num = a == 0 ? 32 : 16;
		palSize = 96;

		palptr = &_displayPalette[(a * 64)];
	}

	offs = _curVgaFile1 + 6;
	src = offs + b * palSize;

	do {
		palptr[0] = src[0] * 4;
		palptr[1] = src[1] * 4;
		palptr[2] = src[2] * 4;
		palptr[3] = 0;

		palptr += 4;
		src += 3;
	} while (--num);

	if (getFeatures() & GF_32COLOR) {
		// Custom palette used for verb area
		palptr = &_displayPalette[(13 * 64)];
		for (uint8 c = 0; c < 32; c++) {
			palptr[0] = customPalette[c * 3 + 0];
			palptr[1] = customPalette[c * 3 + 1];
			palptr[2] = customPalette[c * 3 + 2];
			palptr[3] = 0;

			palptr += 4;
		};
	}

	_paletteFlag = 2;
	_vgaSpriteChanged++;
}
Exemple #8
0
void AGOSEngine::readItemFromGamePc(Common::SeekableReadStream *in, Item *item) {
	uint32 type;

	if (getGameType() == GType_ELVIRA1) {
		item->itemName = (uint16)in->readUint32BE();
		item->adjective = in->readUint16BE();
		item->noun = in->readUint16BE();
		item->state = in->readUint16BE();
		in->readUint16BE();
		item->next = (uint16)fileReadItemID(in);
		item->child = (uint16)fileReadItemID(in);
		item->parent = (uint16)fileReadItemID(in);
		in->readUint16BE();
		in->readUint16BE();
		in->readUint16BE();
		item->classFlags = in->readUint16BE();
		item->children = NULL;
	} else if (getGameType() == GType_ELVIRA2) {
		item->itemName = (uint16)in->readUint32BE();
		item->adjective = in->readUint16BE();
		item->noun = in->readUint16BE();
		item->state = in->readUint16BE();
		item->next = (uint16)fileReadItemID(in);
		item->child = (uint16)fileReadItemID(in);
		item->parent = (uint16)fileReadItemID(in);
		in->readUint16BE();
		item->classFlags = in->readUint16BE();
		item->children = NULL;
	} else {
		item->adjective = in->readUint16BE();
		item->noun = in->readUint16BE();
		item->state = in->readUint16BE();
		item->next = (uint16)fileReadItemID(in);
		item->child = (uint16)fileReadItemID(in);
		item->parent = (uint16)fileReadItemID(in);
		in->readUint16BE();
		item->classFlags = in->readUint16BE();
		item->children = NULL;
	}


	type = in->readUint32BE();
	while (type) {
		type = in->readUint16BE();
		if (type != 0)
			readItemChildren(in, item, type);
	}
}
Exemple #9
0
void AGOSEngine::vc60_stopAnimation() {
	uint16 sprite, zoneNum;

	if (getGameType() == GType_PP) {
		zoneNum = vcReadNextWord();
		sprite = vcReadVarOrWord();
	} else if (getGameType() == GType_SIMON2 || getGameType() == GType_FF) {
		zoneNum = vcReadNextWord();
		sprite = vcReadNextWord();
	} else {
		sprite = vcReadNextWord();
		zoneNum = sprite / 100;
	}

	vcStopAnimation(zoneNum, sprite);
}
Exemple #10
0
void AGOSEngine_Simon2::setupGame() {
	gss = &simon2_settings;
	_tableIndexBase = 1580 / 4;
	_textIndexBase = 1500 / 4;
	_numVideoOpcodes = 75;
#if defined(__DS__)
	_vgaMemSize = 1300000;
#else
	_vgaMemSize = 2000000;
#endif
	_itemMemSize = 20000;
	_tableMemSize = 100000;
	// Check whether to use MT-32 MIDI tracks in Simon the Sorcerer 2
	if (getGameType() == GType_SIMON2 && _midi.hasNativeMT32())
		_musicIndexBase = (1128 + 612) / 4;
	else
		_musicIndexBase = 1128 / 4;
	_soundIndexBase = 1660 / 4;
	_frameCount = 1;
	_vgaBaseDelay = 1;
	_vgaPeriod = 45;
	_numBitArray1 = 16;
	_numBitArray2 = 16;
	_numItemStore = 10;
	_numTextBoxes = 20;
	_numVars = 255;

	_numMusic = 93;
	_numSFX = 222;
	_numSpeech = 11997;

	AGOSEngine::setupGame();
}
Exemple #11
0
Common::Error MadsM4Engine::run() {
	// Initialize backend
	_screen = new M4Surface(true); // Special form for creating screen reference

	_midi = new MidiPlayer(this);
	_midi->setGM(true);	// FIXME: Really? Always?

	_saveLoad = new SaveLoad(this);
	_palette = new Palette(this);
	_mouse = new Mouse(this);
	_events = new Events(this);
	_kernel = new Kernel(this);
	_player = new Player(this);
	_font = new FontManager(this);
	if (getGameType() == GType_Burger) {
		_actor = new Actor(this);
		_conversationView = new ConversationView(this);
	} else {
		_actor = NULL;
	}
	_rails = new Rails();	// needs to be initialized before _scene
	_dialogs = new Dialogs();
	_viewManager = new ViewManager(this);
	_inventory = new Inventory(this);
	_sound = new Sound(this, _mixer, 255);
	_script = new ScriptInterpreter(this);
	_ws = new WoodScript(this);
	//_callbacks = new Callbacks(this);
	_random = new Common::RandomSource();
	g_eventRec.registerRandomSource(*_random, "m4");

	return Common::kNoError;
}
Exemple #12
0
void AGOSEngine_Simon2::playSpeech(uint16 speech_id, uint16 vgaSpriteId) {
	if (speech_id == 0xFFFF) {
		if (_subtitles)
			return;
		if (!getBitFlag(14) && !getBitFlag(28)) {
			setBitFlag(14, true);
			_variableArray[100] = 5;
			animate(4, 1, 30, 0, 0, 0);
			waitForSync(130);
		}
		_skipVgaWait = true;
	} else {
		if (getGameType() == GType_SIMON2 && _subtitles && _language != Common::HE_ISR) {
			loadVoice(speech_id);
			return;
		}

		if (_subtitles && _scriptVar2) {
			animate(4, 2, 5, 0, 0, 0);
			waitForSync(205);
			stopAnimateSimon2(2,5);
		}

		stopAnimateSimon2(2, vgaSpriteId + 2);
		loadVoice(speech_id);
		animate(4, 2, vgaSpriteId + 2, 0, 0, 0);
	}
}
Exemple #13
0
void AGOSEngine::loadVoice(uint speechId) {
	if (getGameType() == GType_PP && speechId == 99) {
		_sound->stopVoice();
		return;
	}

	if (getFeatures() & GF_ZLIBCOMP) {
		char filename[15];

		uint32 file, offset, srcSize, dstSize;
		if (getPlatform() == Common::kPlatformAmiga) {
			loadOffsets((const char*)"spindex.dat", speechId, file, offset, srcSize, dstSize);
		} else {
			loadOffsets((const char*)"speech.wav", speechId, file, offset, srcSize, dstSize);
		}

		// Voice segment doesn't exist
		if (offset == 0xFFFFFFFF && srcSize == 0xFFFFFFFF && dstSize == 0xFFFFFFFF) {
			debug(0, "loadVoice: speechId %d removed", speechId);
			return;
		}

		if (getPlatform() == Common::kPlatformAmiga)
			sprintf(filename, "sp%d.wav", file);
		else
			sprintf(filename, "speech.wav");

		byte *dst = (byte *)malloc(dstSize);
		decompressData(filename, dst, offset, srcSize, dstSize);
		_sound->playVoiceData(dst, speechId);
	} else {
		_sound->playVoice(speechId);
	}
}
Exemple #14
0
void AGOSEngine::o_clearTimers() {
	// 140: clear timers
	killAllTimers();

	if (getGameType() == GType_SIMON1)
		addTimeEvent(3, 160);
}
Exemple #15
0
void AGOSEngine::o_haltAnimation() {
	// 88: stop animation
	_videoLockOut |= 0x10;

	if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
		VgaTimerEntry *vte = _vgaTimerList;
		while (vte->delay) {
			if (vte->type == ANIMATE_EVENT)
				vte->delay += 10;
			vte++;
		}

		_scrollCount = 0;
		_scrollFlag = 0;
	}
}
Exemple #16
0
void AGOSEngine::showActionString(const byte *string) {
	WindowBlock *window;
	uint x;
	const uint len = (getGameType() == GType_WW) ? 29 : 53;

	window = _windowArray[1];
	if (window == NULL || window->textColor == 0)
		return;

	// Arisme : hack for long strings in the French version
	if ((strlen((const char*)string) - 1) <= len)
		x = (len - (strlen((const char *)string) - 1)) * 3;
	else
		x = 0;

	window->textColumn = x / 8;
	window->textColumnOffset = x & 7;
	if (_language == Common::HE_ISR && window->textColumnOffset != 0) {
		window->textColumnOffset = 8 - window->textColumnOffset;
		window->textColumn++;
	}

	for (; *string; string++)
		windowPutChar(window, *string);
}
Exemple #17
0
void AGOSEngine_Simon2::os2_mouseOn() {
	// 180: force mouseOn
	if (getGameType() == GType_SIMON2 && getBitFlag(79)) {
		_mouseCursor = 0;
	}
	_mouseHideCount = 0;
}
Exemple #18
0
void AGOSEngine::scrollEvent() {
	if (_scrollCount == 0)
		return;

	if (getGameType() == GType_FF) {
		if (_scrollCount < 0) {
			if (_scrollFlag != -8) {
				_scrollFlag = -8;
				_scrollCount += 8;
			}
		} else {
			if (_scrollFlag != 8) {
				_scrollFlag = 8;
				_scrollCount -= 8;
			}
		}
	} else {
		if (_scrollCount < 0) {
			if (_scrollFlag != -1) {
				_scrollFlag = -1;
				if (++_scrollCount == 0)
					return;
			}
		} else {
			if (_scrollFlag != 1) {
				_scrollFlag = 1;
				if (--_scrollCount == 0)
					return;
			}
		}

		addVgaEvent(6, SCROLL_EVENT, NULL, 0, 0);
	}
}
Exemple #19
0
void AGOSEngine_Feeble::runSubroutine101() {
    if ((getPlatform() == Common::kPlatformAmiga || getPlatform() == Common::kPlatformMacintosh) &&
            getGameType() == GType_FF) {
        playVideo("epic.dxa");
    }

    AGOSEngine::runSubroutine101();
}
Exemple #20
0
byte *AGOSEngine::convertImage(VC10_state *state, bool compressed) {
	int length, i, j;

	uint8 colorDepth = 4;
	if (getGameType() == GType_SIMON1) {
		if (((_videoLockOut & 0x20) && !state->palette) || ((getFeatures() & GF_32COLOR) &&
			state->palette != 0xC0)) {
			colorDepth = 5;
		}
	}

	const byte *src = state->srcPtr;
	int width = state->width * 16;
	int height = state->height;

	free(_planarBuf);
	_planarBuf = (byte *)malloc(width * height);
	byte *dst = _planarBuf;

	if (compressed) {
		convertCompressedImage(src, dst, colorDepth, height, width, (getGameType() == GType_PN));
	} else {
		length = (width + 15) / 16 * height;
		for (i = 0; i < length; i++) {
			uint16 w[kMaxColorDepth];
			if (getGameType() == GType_SIMON1 && colorDepth == 4) {
				for (j = 0; j < colorDepth; ++j) {
					w[j] = READ_BE_UINT16(src + j * length * 2);
				}
				if (state->palette == 0xC0) {
					bitplaneToChunkyText(w, colorDepth, dst);
				} else {
					bitplaneToChunky(w, colorDepth, dst);
				}
				src += 2;
			} else {
				for (j = 0; j < colorDepth; ++j) {
					w[j] = READ_BE_UINT16(src); src += 2;
				}
				bitplaneToChunky(w, colorDepth, dst);
			}
		}
	}

	return _planarBuf;
}
Exemple #21
0
CineEngine::~CineEngine() {
	if (getGameType() == Cine::GType_OS) {
		freeErrmessDat();
	}

	DebugMan.clearAllDebugChannels();
	delete _console;
}
Exemple #22
0
bool AGOSEngine::drawImage_clip(VC10_state *state) {
	const uint16 *vlut;
	uint maxWidth, maxHeight;
	int cur;

	vlut = &_videoWindows[_windowNum * 4];

	if (getGameType() != GType_FF && getGameType() != GType_PP) {
		state->draw_width = state->width * 2;
	}

	cur = state->x;
	if (cur < 0) {
		do {
			if (!--state->draw_width)
				return 0;
			state->x_skip++;
		} while (++cur);
	}
	state->x = cur;

	maxWidth = (getGameType() == GType_FF || getGameType() == GType_PP) ? _screenWidth : (vlut[2] * 2);
	cur += state->draw_width - maxWidth;
	if (cur > 0) {
		do {
			if (!--state->draw_width)
				return 0;
		} while (--cur);
	}

	cur = state->y;
	if (cur < 0) {
		do {
			if (!--state->draw_height)
				return 0;
			state->y_skip++;
		} while (++cur);
	}
	state->y = cur;

	maxHeight = (getGameType() == GType_FF || getGameType() == GType_PP) ? _screenHeight : vlut[3];
	cur += state->draw_height - maxHeight;
	if (cur > 0) {
		do {
			if (!--state->draw_height)
				return 0;
		} while (--cur);
	}

	if (getGameType() != GType_FF && getGameType() != GType_PP) {
		state->draw_width *= 4;
	}

	return (state->draw_width != 0 && state->draw_height != 0);
}
Exemple #23
0
void AGOSEngine::writeVariable(uint16 variable, uint16 contents) {
	if (variable >= _numVars)
		error("writeVariable: Variable %d out of range", variable);

	if (getGameType() == GType_FF && getBitFlag(83))
		_variableArray2[variable] = contents;
	else
		_variableArray[variable] = contents;
}
Exemple #24
0
Sprite *ComposerEngine::addSprite(uint16 id, uint16 animId, uint16 zorder, const Common::Point &pos) {
	Sprite sprite;
	bool foundSprite = false;

	// re-use old sprite, if any (the BMAP for this id might well have
	// changed in the meantime, but the scripts depend on that!)
	for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) {
		if (i->_id != id)
			continue;
		if (getGameType() == GType_ComposerV1) {
			if (i->_animId != animId)
				continue;
		} else if (i->_animId && animId && (i->_animId != animId))
			continue;

		dirtySprite(*i);

		// if the zordering is identical, modify it in-place
		if (i->_zorder == zorder) {
			i->_animId = animId;
			i->_pos = pos;
			dirtySprite(*i);
			return &(*i);
		}

		// otherwise, take a copy and remove it from the list
		sprite = *i;
		foundSprite = true;
		_sprites.erase(i);
		break;
	}

	sprite._animId = animId;
	sprite._zorder = zorder;
	sprite._pos = pos;

	if (!foundSprite) {
		sprite._id = id;
		if (!initSprite(sprite)) {
			debug(1, "ignoring addSprite on invalid sprite %d", id);
			return NULL;
		}
	}

	dirtySprite(sprite);

	for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) {
		if (sprite._zorder <= i->_zorder)
			continue;
		// insert *before* this sprite
		_sprites.insert(i, sprite);
		--i;
		return &(*i);
	}
	_sprites.push_back(sprite);
	return &_sprites.back();
}
Exemple #25
0
const byte *AGOSEngine::getStringPtrByID(uint16 stringId, bool upperCase) {
	const byte *stringPtr;
	byte *dst;

	_freeStringSlot ^= 1;
	dst = _stringReturnBuffer[_freeStringSlot];

	if (getGameType() == GType_ELVIRA1 && getPlatform() == Common::kPlatformAtariST) {
		byte *ptr = _stringTabPtr[stringId];
		_textCount = 0;
		_awaitTwoByteToken = 0;
		uncompressText(ptr);
		_textBuffer[_textCount] = 0;
		Common::strlcpy((char *)dst, (const char *)_textBuffer, 180);
	} else {
		if (stringId < 0x8000) {
			stringPtr = _stringTabPtr[stringId];
		} else {
			stringPtr = getLocalStringByID(stringId);
		}
		Common::strlcpy((char *)dst, (const char *)stringPtr, 180);
	}

	// WORKAROUND bug #1538873: The French version of Simon 1 and the
	// Polish version of Simon 2 used excess spaces, at the end of many
	// messages, so we strip off those excess spaces.
	if ((getGameType() == GType_SIMON1 && _language == Common::FR_FRA) ||
		(getGameType() == GType_SIMON2 && _language == Common::PL_POL)) {
		uint16 len = strlen((const char *)dst) - 1;

		while (len && dst[len] == 32) {
			dst[len] = 0;
			len--;
		}

	}

	if (upperCase && *dst) {
		if (Common::isLower(*dst))
			*dst = toupper(*dst);
	}

	return dst;
}
Exemple #26
0
void AGOSEngine::displayName(HitArea *ha) {
	if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_PP)
		return;

	bool result;
	int x = 0, y = 0;

	if (getGameType() == GType_FF) {
		if (ha->flags & kBFHyperBox) {
			_lastNameOn = ha;
			return;
		}
		if (findBox(50))
			return;

		if (getBitFlag(99))
			_animatePointer = ((ha->flags & kBFTextBox) == 0);
		else
			_animatePointer = true;

		if (!getBitFlag(73))
			return;

		y = ha->y;
		if (getBitFlag(99) && y > 288)
			y = 288;
		y -= 17;
		if (y < 0)
			y = 0;
		y += 2;
		x = ha->width / 2 + ha->x;
	} else {
		resetNameWindow();
	}

	if (ha->flags & kBFTextBox) {
		result = printTextOf(ha->flags / 256, x, y);
	} else {
		result = printNameOf(ha->itemPtr, x, y);
	}

	if (result)
		_lastNameOn = ha;
}
Exemple #27
0
uint AGOSEngine::getVarOrByte() {
	if (getGameType() == GType_ELVIRA1) {
		return getVarOrWord();
	} else {
		uint a = *_codePtr++;
		if (a != 255)
			return a;
		return readVariable(*_codePtr++);
	}
}
Exemple #28
0
void AGOSEngine::hitarea_leave(HitArea *ha, bool state) {
	if (getGameType() == GType_SIMON2) {
		invertBox(ha, 231, 229, 230, 1);
	} else {
		if (getFeatures() & GF_32COLOR)
			invertBox(ha, 220, 212, 216, 4);
		else
			invertBox(ha, 223, 213, 218, 5);
	}
}
Exemple #29
0
void Ship::die() 
{
	Ship* temp;
	//changing owner's ship from this to new ship (pod)
	temp = getGameType()->RespawnShip(this->loc, this->dir, this->vel, pod, this->owner->number);

	if(abilityTimer)
		EndSpecialAbility(this);
	Kill();
}
Exemple #30
0
void AGOSEngine::o_add() {
	// 43: add
	uint var = getVarWrapper();
	writeVariable(var, readVariable(var) + getVarOrWord());

	// WORKAROUND: The conversation of the male in Vid-Phone Booth at Dave's Space Bar
	// is based on variable 116, but stops due to a missing option (37).
	if (getGameType() == GType_FF && _currentTable->id == 10538 && readVariable(116) == 37)
			writeVariable(116, 38);
}