diff options
Diffstat (limited to 'engines/voyeur/events.cpp')
| -rw-r--r-- | engines/voyeur/events.cpp | 615 | 
1 files changed, 615 insertions, 0 deletions
| diff --git a/engines/voyeur/events.cpp b/engines/voyeur/events.cpp new file mode 100644 index 0000000000..13fadd3ced --- /dev/null +++ b/engines/voyeur/events.cpp @@ -0,0 +1,615 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "voyeur/events.h" +#include "voyeur/voyeur.h" +#include "voyeur/staticres.h" +#include "common/events.h" +#include "graphics/cursorman.h" +#include "graphics/font.h" +#include "graphics/fontman.h" +#include "graphics/palette.h" + +namespace Voyeur { + +IntNode::IntNode() { +	_intFunc = NULL; +	_curTime = 0; +	_timeReset = 0; +	_flags = 0; +} + +IntNode::IntNode(uint16 curTime, uint16 timeReset, uint16 flags) { +	_intFunc = NULL; +	_curTime = curTime; +	_timeReset = timeReset; +	_flags = flags; +} + +/*------------------------------------------------------------------------*/ + +IntData::IntData() { +	_flipWait = false; +	_hasPalette = false; +	_flashTimer = 0; +	_flashStep = 0; +	field26 = 0; +	_skipFading = false; +	_palStartIndex = 0; +	_palEndIndex = 0; +	_palette = NULL; +} + +/*------------------------------------------------------------------------*/ + +EventsManager::EventsManager(VoyeurEngine *vm) : _intPtr(_gameData), +		_fadeIntNode(0, 0, 3), _cycleIntNode(0, 0, 3), _vm(vm) { +	_cycleStatus = 0; +	_fadeStatus = 0; +	_priorFrameTime = g_system->getMillis(); +	_gameCounter = 0; +	_counterFlag = false; +	_recordBlinkCounter = 0; +	_cursorBlinked = false; + +	Common::fill(&_cycleTime[0], &_cycleTime[4], 0); +	Common::fill(&_cycleNext[0], &_cycleNext[4], (byte *)nullptr); +	_cyclePtr = NULL; +	 +	_leftClick = _rightClick = false; +	_mouseClicked = _newMouseClicked = false; +	_newLeftClick = _newRightClick = false;; + +	_videoDead = 0; + +	_fadeFirstCol = _fadeLastCol = 0; +	_fadeCount = 1; +} + +void EventsManager::startMainClockInt() { +	_mainIntNode._intFunc = &EventsManager::mainVoyeurIntFunc; +	_mainIntNode._flags = 0; +	_mainIntNode._curTime = 0; +	_mainIntNode._timeReset = 60; +} + +void EventsManager::mainVoyeurIntFunc() { +	if (!(_vm->_voy->_eventFlags & EVTFLAG_TIME_DISABLED)) { +		++_vm->_voy->_switchBGNum; + +		if (_vm->_debugger->_isTimeActive) { +			// Increase camera discharge +			++_vm->_voy->_RTVNum; + +			// If the murder threshold has been set, and is passed, then flag the victim +			// as murdered, which prevents sending the tape from succeeding +			if (_vm->_voy->_RTVNum >= _vm->_voy->_murderThreshold) +				_vm->_voy->_victimMurdered = true; +		} +	} +} + +void EventsManager::sWaitFlip() { +	Common::Array<ViewPortResource *> &viewPorts = _vm->_graphicsManager->_viewPortListPtr->_entries; +	for (uint idx = 0; idx < viewPorts.size(); ++idx) { +		ViewPortResource &viewPort = *viewPorts[idx]; + +		if (_vm->_graphicsManager->_saveBack && (viewPort._flags & DISPFLAG_40)) { +			Common::Rect *clipPtr = _vm->_graphicsManager->_clipPtr; +			_vm->_graphicsManager->_clipPtr = &viewPort._clipRect; + +			if (viewPort._restoreFn) +				(_vm->_graphicsManager->*viewPort._restoreFn)(&viewPort); + +			_vm->_graphicsManager->_clipPtr = clipPtr; +			viewPort._rectListCount[viewPort._pageIndex] = 0; +			viewPort._rectListPtr[viewPort._pageIndex]->clear(); +			viewPort._flags &= ~DISPFLAG_40; +		} +	} + +	while (_gameData._flipWait && !_vm->shouldQuit()) { +		pollEvents(); +		g_system->delayMillis(10); +	} +} + +void EventsManager::checkForNextFrameCounter() { +	// Check for next game frame +	uint32 milli = g_system->getMillis(); +	if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) { +		_counterFlag = !_counterFlag; +		if (_counterFlag) +			++_gameCounter; +		_priorFrameTime = milli; + +		// Run the timer-based updates +		voyeurTimer(); + +		if ((_gameCounter % GAME_FRAME_RATE) == 0) +			mainVoyeurIntFunc(); + +		// Give time to the debugger +		_vm->_debugger->onFrame(); + +		// If mouse position display is on, display the position +		if (_vm->_debugger->_showMousePosition) +			showMousePosition(); + +		// Display the frame +		g_system->copyRectToScreen((byte *)_vm->_graphicsManager->_screenSurface.getPixels(),  +			SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); +		g_system->updateScreen(); + +		// Signal the ScummVM debugger +		_vm->_debugger->onFrame(); +	} +} + +void EventsManager::showMousePosition() { +	const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kConsoleFont)); +	Common::String mousePos = Common::String::format("(%d,%d)", _mousePos.x, _mousePos.y); +	if (_vm->_voyeurArea == AREA_INTERFACE) { +		Common::Point pt = _mousePos + _vm->_mansionViewPos - Common::Point(40, 27); +		if (pt.x < 0) pt.x = 0; +		if (pt.y < 0) pt.y = 0; + +		mousePos += Common::String::format(" - (%d,%d)", pt.x, pt.y); +	} + +	_vm->_graphicsManager->_screenSurface.fillRect( +		Common::Rect(0, 0, 110, font.getFontHeight()), 0); +	font.drawString(&_vm->_graphicsManager->_screenSurface, mousePos, +		0, 0, 110, 63); +} + +void EventsManager::voyeurTimer() { +	_gameData._flashTimer += _gameData._flashStep; + +	if (--_gameData.field26 <= 0) { +		if (_gameData._flipWait) { +			_gameData._flipWait = false; +			_gameData._skipFading = false; +		} + +		_gameData.field26 >>= 8; +	} + +	videoTimer(); + +	// Iterate through the list of registered nodes +	Common::List<IntNode *>::iterator i; +	for (i = _intNodes.begin(); i != _intNodes.end(); ++i) { +		IntNode &node = **i; + +		if (node._flags & 1) +			continue; +		if (!(node._flags & 2)) { +			if (--node._curTime != 0) +				continue; + +			node._curTime = node._timeReset; +		} + +		(this->*node._intFunc)(); +	} + +} + +void EventsManager::videoTimer() { +	if (_gameData._hasPalette) { +		_gameData._hasPalette = false; + +		g_system->getPaletteManager()->setPalette(_gameData._palette + +			_gameData._palStartIndex * 3, _gameData._palStartIndex,  +			_gameData._palEndIndex - _gameData._palStartIndex + 1); +	} +} + +void EventsManager::delay(int cycles) { +	uint32 totalMilli = cycles * 1000 / GAME_FRAME_RATE; +	uint32 delayEnd = g_system->getMillis() + totalMilli; + +	while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) { +		g_system->delayMillis(10); + +		pollEvents(); +	} +} + +void EventsManager::delayClick(int cycles) { +	uint32 totalMilli = cycles * 1000 / GAME_FRAME_RATE; +	uint32 delayEnd = g_system->getMillis() + totalMilli; + +	do { +		g_system->delayMillis(10); +		getMouseInfo(); +	} while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd  +			&& !_vm->_eventsManager->_mouseClicked); +} + +void EventsManager::pollEvents() { +	checkForNextFrameCounter(); + +	Common::Event event; +	while (g_system->getEventManager()->pollEvent(event)) { +		// Handle keypress +		switch (event.type) { +		case Common::EVENT_QUIT: +		case Common::EVENT_RTL: +		case Common::EVENT_KEYUP: +			return; + +		case Common::EVENT_KEYDOWN: +			// Check for debugger +			if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL)) { +				// Attach to the debugger +				_vm->_debugger->attach(); +				_vm->_debugger->onFrame(); +			} +			return; +		case Common::EVENT_LBUTTONDOWN: +			_vm->_eventsManager->_newLeftClick = true; +			_vm->_eventsManager->_newMouseClicked = true; +			return; +		case Common::EVENT_RBUTTONDOWN: +			_vm->_eventsManager->_newRightClick = true; +			_vm->_eventsManager->_newMouseClicked = true; +			return; +		case Common::EVENT_LBUTTONUP: +		case Common::EVENT_RBUTTONUP: +			_vm->_eventsManager->_newMouseClicked = false; +			_vm->_eventsManager->_newLeftClick = false; +			_vm->_eventsManager->_newRightClick = false; +			return; +		case Common::EVENT_MOUSEMOVE: +			_mousePos = event.mouse; +			break; +		default: + 			break; +		} +	} +} + +void EventsManager::startFade(CMapResource *cMap) { +	_fadeIntNode._flags |= 1; +	if (_cycleStatus & 1) +		_cycleIntNode._flags |= 1; + +	_fadeFirstCol = cMap->_start; +	_fadeLastCol = cMap->_end; +	_fadeCount = cMap->_steps + 1; + +	if (cMap->_steps > 0) { +		_fadeStatus = cMap->_fadeStatus | 1; +		byte *vgaP = &_vm->_graphicsManager->_VGAColors[_fadeFirstCol * 3]; +		int mapIndex = 0; + +		for (int idx = _fadeFirstCol; idx <= _fadeLastCol; ++idx, vgaP += 3) { +			ViewPortPalEntry &palEntry = _vm->_graphicsManager->_viewPortListPtr->_palette[idx]; +			palEntry._rEntry = vgaP[0] << 8; +			int rDiff = (cMap->_entries[mapIndex * 3] << 8) - palEntry._rEntry; +			palEntry._rChange = rDiff / cMap->_steps; + +			palEntry._gEntry = vgaP[1] << 8; +			int gDiff = (cMap->_entries[mapIndex * 3 + 1] << 8) - palEntry._gEntry; +			palEntry._gChange = gDiff / cMap->_steps; + +			palEntry._bEntry = vgaP[2] << 8; +			int bDiff = (cMap->_entries[mapIndex * 3 + 2] << 8) - palEntry._bEntry; +			palEntry._bChange = bDiff / cMap->_steps; +			 +			palEntry._palIndex = idx; +			if (!(cMap->_fadeStatus & 1)) +				++mapIndex; +		} + +		if (cMap->_fadeStatus & 2) +			_intPtr._skipFading = true; +		_fadeIntNode._flags &= ~1; +	} else { +		byte *vgaP = &_vm->_graphicsManager->_VGAColors[_fadeFirstCol * 3]; +		int mapIndex = 0; + +		for (int idx = _fadeFirstCol; idx <= _fadeLastCol; ++idx, vgaP += 3) { +			Common::copy(&cMap->_entries[mapIndex], &cMap->_entries[mapIndex + 3], vgaP); + +			if (!(cMap->_fadeStatus & 1)) +				mapIndex += 3; +		} + +		if (_intPtr._palStartIndex > _fadeFirstCol) +			_intPtr._palStartIndex = _fadeFirstCol; +		if (_intPtr._palEndIndex < _fadeLastCol) +			_intPtr._palEndIndex = _fadeLastCol; + +		_intPtr._hasPalette = true; +	} + +	if (_cycleStatus & 1) +		_cycleIntNode._flags &= ~1; +} + +void EventsManager::addIntNode(IntNode *node) { +	_intNodes.push_back(node); +} + +void EventsManager::addFadeInt() { +	IntNode &node = _fade2IntNode; +	node._intFunc = &EventsManager::fadeIntFunc; +	node._flags = 0; +	node._curTime = 0; +	node._timeReset = 1; + +	addIntNode(&node); +} + +void EventsManager::vDoFadeInt() { +	if (_intPtr._skipFading) +		return; +	if (--_fadeCount == 0) { +		_fadeIntNode._flags |= 1; +		_fadeStatus &= ~1; +		return; +	} + +	for (int i = _fadeFirstCol; i <= _fadeLastCol; ++i) { +		ViewPortPalEntry &palEntry = _vm->_graphicsManager->_viewPortListPtr->_palette[i]; +		byte *vgaP = &_vm->_graphicsManager->_VGAColors[palEntry._palIndex * 3]; + +		palEntry._rEntry += palEntry._rChange; +		palEntry._gEntry += palEntry._gChange; +		palEntry._bEntry += palEntry._bChange; + +		vgaP[0] = palEntry._rEntry >> 8; +		vgaP[1] = palEntry._gEntry >> 8; +		vgaP[2] = palEntry._bEntry >> 8; +	} + +	if (_intPtr._palStartIndex > _fadeFirstCol) +		_intPtr._palStartIndex = _fadeFirstCol; +	if (_intPtr._palEndIndex < _fadeLastCol) +		_intPtr._palEndIndex = _fadeLastCol; + +	_intPtr._hasPalette = true; +} + +void EventsManager::vDoCycleInt() { +	for (int idx = 3; idx >= 0; --idx) { +		if (_cyclePtr->_type[idx] && --_cycleTime[idx] <= 0) { +			byte *pSrc = _cycleNext[idx]; +			byte *pPal = _vm->_graphicsManager->_VGAColors; + +			if (_cyclePtr->_type[idx] != 1) { +				// New palette data being specified - loop to set entries +				do { +					int palIndex = READ_LE_UINT16(pSrc); +					pPal[palIndex * 3] = pSrc[3]; +					pPal[palIndex * 3 + 1] = pSrc[4]; +					pPal[palIndex * 3 + 1] = pSrc[5]; +					pSrc += 6; + +					if ((int16)READ_LE_UINT16(pSrc) >= 0) { +						// Resetting back to start of cycle data +						pSrc = _cycleNext[idx]; +						break; +					} +				} while (*(pSrc + 2) == 0); + +				_cycleNext[idx] = pSrc; +				_cycleTime[idx] = pSrc[2]; +			} else { +				// Palette rotation to be done +				_cycleTime[idx] = pSrc[4]; + +				if (pSrc[5] == 1) { +					// Move palette entry to end of range +					int start = READ_LE_UINT16(pSrc); +					int end = READ_LE_UINT16(&pSrc[2]); +					assert(start < 0x100 && end < 0x100); + +					// Store the RGB of the first entry to be moved +					byte r = pPal[start * 3]; +					byte g = pPal[start * 3 + 1]; +					byte b = pPal[start * 3 + 2]; + +					Common::copy(&pPal[start * 3 + 3], &pPal[end * 3 + 3], &pPal[start * 3]); +					 +					// Place the original saved entry at the end of the range +					pPal[end * 3] = r; +					pPal[end * 3 + 1] = g; +					pPal[end * 3 + 2] = b; +					 +					if (_fadeStatus & 1) { +						//dx = start, di = end +						warning("TODO: Adjustment of ViewPortListResource"); +					} +				} else { +					// Move palette entry to start of range +					int start = READ_LE_UINT16(pSrc); +					int end = READ_LE_UINT16(&pSrc[2]); +					assert(start < 0x100 && end < 0x100); + +					// Store the RGB of the entry to be moved +					byte r = pPal[end * 3]; +					byte g = pPal[end * 3 + 1]; +					byte b = pPal[end * 3 + 2]; + +					// Move the remainder of the range forwards one entry +					Common::copy_backward(&pPal[start * 3], &pPal[end * 3], &pPal[end * 3 + 3]); +					 +					// Place the original saved entry at the end of the range +					pPal[start * 3] = r; +					pPal[start * 3 + 1] = g; +					pPal[start * 3 + 2] = b; +					 +					if (_fadeStatus & 1) { +						//dx = start, di = end +						warning("TODO: Adjustment of ViewPortListResource"); +					} +				} +			} + +			_intPtr._hasPalette = true; +		} +	} +} + + +void EventsManager::fadeIntFunc() { +	switch (_vm->_voy->_fadingType) { +	case 1: +		if (_vm->_voy->_fadingAmount1 < 63) +			_vm->_voy->_fadingAmount1 += _vm->_voy->_fadingStep1; +		if (_vm->_voy->_fadingAmount2 < 63) +			_vm->_voy->_fadingAmount2 += _vm->_voy->_fadingStep2; +		if (_vm->_voy->_fadingAmount1 > 63) +			_vm->_voy->_fadingAmount1 = 63; +		if (_vm->_voy->_fadingAmount2 > 63) +			_vm->_voy->_fadingAmount2 = 63; +		if ((_vm->_voy->_fadingAmount1 == 63) && (_vm->_voy->_fadingAmount2 == 63)) +			_vm->_voy->_fadingType = 0; +		break; +	case 2: +		if (_vm->_voy->_fadingAmount1 > 0) +			_vm->_voy->_fadingAmount1 -= _vm->_voy->_fadingStep1; +		if (_vm->_voy->_fadingAmount2 > 0) +			_vm->_voy->_fadingAmount2 -= _vm->_voy->_fadingStep2; +		if (_vm->_voy->_fadingAmount1 < 0) +			_vm->_voy->_fadingAmount1 = 0; +		if (_vm->_voy->_fadingAmount2 < 0) +			_vm->_voy->_fadingAmount2 = 0; +		if ((_vm->_voy->_fadingAmount1 == 0) && (_vm->_voy->_fadingAmount2 == 0)) +			_vm->_voy->_fadingType = 0; +		break; +	default: +		break; +	} +} + +void EventsManager::deleteIntNode(IntNode *node) { +	_intNodes.remove(node); +} + +void EventsManager::vInitColor() { +	_fadeIntNode._intFunc = &EventsManager::vDoFadeInt; +	_cycleIntNode._intFunc = &EventsManager::vDoCycleInt; + +	addIntNode(&_fadeIntNode); +	addIntNode(&_cycleIntNode); +} + +void EventsManager::setCursor(PictureResource *pic) { +	PictureResource cursor; +	cursor._bounds = pic->_bounds; +	cursor._flags = DISPFLAG_CURSOR; + +	_vm->_graphicsManager->sDrawPic(pic, &cursor, Common::Point()); +} + +void EventsManager::setCursor(byte *cursorData, int width, int height) { +	CursorMan.replaceCursor(cursorData, width, height, width / 2, height / 2, 0); +} + +void EventsManager::setCursorColor(int idx, int mode) { +	switch (mode) { +	case 0: +		_vm->_graphicsManager->setColor(idx, 90, 90, 232); +		break; +	case 1: +		_vm->_graphicsManager->setColor(idx, 232, 90, 90); +		break; +	case 2: +		_vm->_graphicsManager->setColor(idx, 90, 232, 90); +		break; +	case 3: +		_vm->_graphicsManager->setColor(idx, 90, 232, 232); +		break; +	default: +		break; +	} +} + +void EventsManager::showCursor() { +	CursorMan.showMouse(true); +} + +void EventsManager::hideCursor() { +	CursorMan.showMouse(false); +} + +void EventsManager::getMouseInfo() { +	pollEvents(); + +	if (_vm->_voy->_eventFlags & EVTFLAG_RECORDING) { +		if ((_gameCounter - _recordBlinkCounter) > 8) { +			_recordBlinkCounter = _gameCounter; + +			if (_cursorBlinked) { +				_cursorBlinked = false; +				_vm->_graphicsManager->setOneColor(128, 220, 20, 20); +				_vm->_graphicsManager->setColor(128, 220, 20, 20); +			} else { +				_cursorBlinked = true; +				_vm->_graphicsManager->setOneColor(128, 220, 220, 220); +				_vm->_graphicsManager->setColor(128, 220, 220, 220); +			} +		} +	} + +	_vm->_eventsManager->_mouseClicked = _vm->_eventsManager->_newMouseClicked; +	_vm->_eventsManager->_leftClick = _vm->_eventsManager->_newLeftClick; +	_vm->_eventsManager->_rightClick = _vm->_eventsManager->_newRightClick; + +	_vm->_eventsManager->_newMouseClicked = false; +	_vm->_eventsManager->_newLeftClick = false; +	_vm->_eventsManager->_newRightClick = false; +} + +void EventsManager::startCursorBlink() { +	if (_vm->_voy->_eventFlags & EVTFLAG_RECORDING) { +		_vm->_graphicsManager->setOneColor(128, 55, 5, 5); +		_vm->_graphicsManager->setColor(128, 220, 20, 20); +		_intPtr._hasPalette = true; + +		_vm->_graphicsManager->drawDot(); +		//copySection(); +	} +} + +void EventsManager::incrementTime(int amt) { +	for (int i = 0; i < amt; ++i) +		mainVoyeurIntFunc(); +} + +void EventsManager::stopEvidDim() { +	deleteIntNode(&_evIntNode); +} + +Common::String EventsManager::getEvidString(int eventIndex) { +	assert(eventIndex <= _vm->_voy->_eventCount); +	VoyeurEvent &e = _vm->_voy->_events[eventIndex]; +	return Common::String::format("%03d %.2d:%.2d %s %s", eventIndex + 1, +		e._hour, e._minute, e._isAM ? AM : PM, EVENT_TYPE_STRINGS[e._type - 1]); +} + +} // End of namespace Voyeur | 
