diff options
Diffstat (limited to 'engines/mads/nebular/menu_nebular.cpp')
| -rw-r--r-- | engines/mads/nebular/menu_nebular.cpp | 776 | 
1 files changed, 603 insertions, 173 deletions
diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp index c47272624c..cb8f56bd05 100644 --- a/engines/mads/nebular/menu_nebular.cpp +++ b/engines/mads/nebular/menu_nebular.cpp @@ -37,53 +37,166 @@ namespace Nebular {  MenuView::MenuView(MADSEngine *vm) : FullScreenDialog(vm) {  	_breakFlag = false; +	_redrawFlag = true; +	_palFlag = false;  } -void MenuView::execute() { -	Common::Event event; +void MenuView::show() { +	Scene &scene = _vm->_game->_scene;	 +	EventsManager &events = *_vm->_events; +	display(); -	// Main event loop to show the view -	while (!_breakFlag) { -		// Handle events -		while (g_system->getEventManager()->pollEvent(event)) { -			onEvent(event); -		} +	events.setEventTarget(this); +	events.hideCursor(); + +	while (!_breakFlag && !_vm->shouldQuit()) { +		if (_redrawFlag) { +			scene.drawElements(_vm->_game->_fx, _vm->_game->_fx); -		if (_vm->_events->checkForNextFrameCounter()) { -			// Next frame drawn, so allow view to prepare for following one -			doFrame(); +			_vm->_screen.copyRectToScreen(Common::Rect(0, 0, 320, 200)); +			_redrawFlag = false;  		} -		// Slight delay -		g_system->delayMillis(10); -		_breakFlag = _vm->shouldQuit(); +		_vm->_events->waitForNextFrame(); +		_vm->_game->_fx = kTransitionNone; +		doFrame();  	} + +	events.setEventTarget(nullptr); +} + +void MenuView::display() { +	_vm->_palette->resetGamePalette(4, 8); + +	FullScreenDialog::display();  }  /*------------------------------------------------------------------------*/  MainMenu::MainMenu(MADSEngine *vm): MenuView(vm) { -	_itemPosList[0] = Common::Point(12, 68); -	_itemPosList[1] = Common::Point(12, 87); -	_itemPosList[2] = Common::Point(12, 107); -	_itemPosList[3] = Common::Point(184, 75); -	_itemPosList[4] = Common::Point(245, 75); -	_itemPosList[5] = Common::Point(184, 99); - +	Common::fill(&_menuItems[0], &_menuItems[7], (SpriteAsset *)nullptr); +	Common::fill(&_menuItemIndexes[0], &_menuItemIndexes[7], -1);  	_delayTimeout = 0; -	_menuItem = NULL; -	_menuItemIndex = 0; +	_menuItemIndex = -1;  	_frameIndex = 0; -	_highlightedIndex = -1;  	_skipFlag = false; +	_highlightedIndex = -1; +	_selectedIndex = -1; +	_buttonDown = false;  }  MainMenu::~MainMenu() { -	if (_menuItem) -		delete _menuItem; +} + +void MainMenu::display() { +	MenuView::display(); +	Scene &scene = _vm->_game->_scene; +	ScreenObjects &screenObjects = _vm->_game->_screenObjects; +	screenObjects.clear(); + +	// Load each of the menu item assets and add to the scene sprites list +	for (int i = 0; i < 7; ++i) { +		Common::String spritesName = Resources::formatName(NEBULAR_MENUSCREEN, +			'A', i + 1, EXT_SS, ""); +		_menuItems[i] = new SpriteAsset(_vm, spritesName, 0); +		_menuItemIndexes[i] = scene._sprites.add(_menuItems[i]); + +		// Register the menu item area in the screen objects +		MSprite *frame0 = _menuItems[i]->getFrame(0); +		Common::Point pt(frame0->_offset.x - (frame0->w / 2), +			frame0->_offset.y - frame0->h + _vm->_screen._offset.y); +		screenObjects.add( +			Common::Rect(pt.x, pt.y, pt.x + frame0->w, pt.y + frame0->h), +			LAYER_GUI, CAT_COMMAND, i); +	} + +	// Set the cursor for when it's shown +	_vm->_events->setCursor(CURSOR_ARROW); +} + +void MainMenu::doFrame() { +	// Delay between animation frames on the menu +	uint32 currTime = g_system->getMillis(); +	if (currTime < _delayTimeout) +		return; +	_delayTimeout = currTime + MADS_MENU_ANIM_DELAY; + +	// If an item has already been selected, handle rotating out the other menu items +	if (_selectedIndex != -1) { +		if (_frameIndex == _menuItems[0]->getCount()) { +			handleAction((MADSGameAction)_selectedIndex); +		} else { +			for (_menuItemIndex = 0; _menuItemIndex < 6; ++_menuItemIndex) { +				if (_menuItemIndex != _selectedIndex) { +					addSpriteSlot(); +				} +			} + +			// Move the menu items to the next frame +			++_frameIndex; +		} +		return; +	} + +	// If we've alerady reached the end of the menuitem animation, exit immediately +	if (_menuItemIndex == 6) +		return; + +	// If the user has chosen to skip the animation, show the full menu immediately +	if (_skipFlag && _menuItemIndex >= 0) { +		// Quickly loop through all the menu items to display each's final frame		 +		for (; _menuItemIndex < 6; ++_menuItemIndex) { +			// Draw the final frame of the menuitem +			_frameIndex = 0; +			addSpriteSlot(); +		} + +		_vm->_events->showCursor(); +	} else { +		if ((_menuItemIndex == -1) || (_frameIndex == 0)) { +			if (++_menuItemIndex == 6) { +				// Reached end of display animation +				_vm->_events->showCursor(); +				return; +			} + +			_frameIndex = _menuItems[_menuItemIndex]->getCount() - 1; +		} else { +			--_frameIndex; +		} + +		// Move to the next menuitem frame +		addSpriteSlot(); +	} +} + +void MainMenu::addSpriteSlot() { +	Scene &scene = _vm->_game->_scene; +	SpriteSlots &spriteSlots = scene._spriteSlots; +	 +	int seqIndex = (_menuItemIndex < 6) ? _menuItemIndex : _frameIndex; +	spriteSlots.deleteTimer(seqIndex); + +	SpriteAsset *menuItem = _menuItems[_menuItemIndex]; +	MSprite *spr = menuItem->getFrame(_frameIndex); + +	SpriteSlot &slot = spriteSlots[spriteSlots.add()]; +	slot._flags = IMG_UPDATE; +	slot._seqIndex = seqIndex; +	slot._spritesIndex = _menuItemIndexes[_menuItemIndex]; +	slot._frameNumber = _frameIndex + 1; +	slot._position = spr->_offset; +	slot._depth = 1; +	slot._scale = 100; + +	_redrawFlag = true;  }  bool MainMenu::onEvent(Common::Event &event) { +	Scene &scene = _vm->_game->_scene; +	if (_selectedIndex != -1) +		return false; +  	// Handle keypresses - these can be done at any time, even when the menu items are being drawn  	if (event.type == Common::EVENT_KEYDOWN) {  		switch (event.kbd.keycode) { @@ -114,23 +227,12 @@ bool MainMenu::onEvent(Common::Event &event) {  		case Common::KEYCODE_s: {  			// Goodness knows why, but Rex has a key to restart the menuitem animations - -			// Delete the current menu items -			if (_menuItem) -				delete _menuItem; -			/* -			_vm->_palette->deleteRange(_bgPalData); -			delete _bgPalData; -			for (uint i = 0; i < _itemPalData.size(); ++i) { -				_vm->_palette->deleteRange(_itemPalData[i]); -				delete _itemPalData[i]; -			} -			_itemPalData.clear(); -			*/  			// Restart the animation -			_menuItemIndex = 0; +			_menuItemIndex = -1; +			for (int i = 0; i < 6; ++i) +				scene._spriteSlots.deleteTimer(i); +  			_skipFlag = false; -			_menuItem = NULL;  			_vm->_events->hideCursor();  			break;  		} @@ -144,21 +246,19 @@ bool MainMenu::onEvent(Common::Event &event) {  		return true;  	} -	int menuIndex; -  	switch (event.type) {  	case Common::EVENT_LBUTTONDOWN:  		if (_vm->_events->isCursorVisible()) { -			menuIndex = getHighlightedItem(event.mouse.x, event.mouse.y); +			_buttonDown = true; +			int menuIndex = getHighlightedItem(event.mouse);  			if (menuIndex != _highlightedIndex) { -//				_bgSurface->copyTo(this, Common::Point(0, MADS_MENU_Y)); +				scene._spriteSlots.deleteTimer(menuIndex);  				_highlightedIndex = menuIndex;  				if (_highlightedIndex != -1) { -					MSprite *spr = _menuItem->getFrame(_highlightedIndex); -					const Common::Point &pt = _itemPosList[_highlightedIndex]; -					spr->copyTo(&_vm->_screen, Common::Point(pt.x, MADS_MENU_Y + pt.y)); +					_frameIndex = _highlightedIndex; +					addSpriteSlot();  				}  			}  		} else { @@ -167,178 +267,508 @@ bool MainMenu::onEvent(Common::Event &event) {  		}  		return true; +	case Common::EVENT_MOUSEMOVE:  +		if (_buttonDown) { +			int menuIndex = getHighlightedItem(event.mouse); +			if (menuIndex != _highlightedIndex) { +				if (_highlightedIndex != -1) { +					// Revert to the unselected menu item +					unhighlightItem(); +				} + +				if (menuIndex != -1) { +					// Highlight new item +					_highlightedIndex = menuIndex; +					_frameIndex = _highlightedIndex; +					addSpriteSlot(); +				} +			} +		} +		break; +  	case Common::EVENT_LBUTTONUP: -		if (_highlightedIndex != -1) -			handleAction((MADSGameAction)_highlightedIndex); +		_buttonDown = false; +		if (_highlightedIndex != -1) { +			_selectedIndex = _highlightedIndex; +			unhighlightItem(); +			_frameIndex = 0; +		} +  		return true;  	default:  		break;  	} - +	  	return false;  } -void MainMenu::doFrame() { -	int itemSize; +int MainMenu::getHighlightedItem(const Common::Point &pt) { +	return _vm->_game->_screenObjects.scan(pt, LAYER_GUI) - 1; +} -	uint32 currTime = g_system->getMillis(); -	if (currTime < _delayTimeout) +void MainMenu::unhighlightItem() { +	// Revert to the unselected menu item +	_vm->_game->_scene._spriteSlots.deleteTimer(_highlightedIndex); +	_menuItemIndex = _highlightedIndex; +	_frameIndex = 0; +	addSpriteSlot(); + +	_menuItemIndex = 6; +	_highlightedIndex = -1; +} + +void MainMenu::handleAction(MADSGameAction action) { +	_vm->_events->hideCursor(); +	_breakFlag = true; + +	switch (action) { +	case START_GAME: +		// Show the difficulty dialog +		_vm->_dialogs->_pendingDialog = DIALOG_DIFFICULTY; +		break; + +	case RESUME_GAME: +		// The original resumed the most recently saved game. Instead,  +		// just show the load game scren +		_vm->_dialogs->_pendingDialog = DIALOG_RESTORE;  		return; -	_delayTimeout = currTime + MADS_MENU_ANIM_DELAY; -	// Rex Nebular handling to cycle through the animated display of the menu items -	if (_menuItemIndex == 7) +	case SHOW_INTRO: +		AnimationView::execute(_vm, "@rexopen"); +		break; + +	case CREDITS: +		TextView::execute(_vm, "credits");  		return; -	// If the user has chosen to skip the menu animation, show the menu immediately -	if (_skipFlag && !_vm->_events->isCursorVisible()) { -		// Clear any pending animation -//		_savedSurface.copyTo(&_vm->_screen, Common::Point(0, MADS_MENU_Y)); -		 -		// Quickly loop through all the menuitems to display each's final frame -		while (_menuItemIndex < 7) { - -			if (_menuItem) { -				// Draw the final frame of the menuitem -				MSprite *spr = _menuItem->getFrame(0); -				itemSize = _menuItem->getFrame(0)->h; -				spr->copyTo(&_vm->_screen, Common::Point(_itemPosList[_menuItemIndex - 1].x, -					_itemPosList[_menuItemIndex - 1].y + MADS_MENU_Y + (itemSize / 2) - (spr->h / 2))); - -				delete _menuItem; -				//copyTo(_bgSurface, Common::Rect(0, row, width(), row + MADS_SCENE_HEIGHT), 0, 0); +	case QUOTES: +		TextView::execute(_vm, "quotes"); +		return; + +	case EXIT: +		_vm->_dialogs->_pendingDialog = DIALOG_ADVERT; +		break; +	default: +		break; +	} +} + +/*------------------------------------------------------------------------*/ + +AdvertView::AdvertView(MADSEngine *vm): EventTarget(), _vm(vm) { +	_breakFlag = false; +} + +void AdvertView::show() { +	bool altAdvert = _vm->getRandomNumber(1000) >= 500; +	int screenId = altAdvert ? 995 : 996; +	uint32 expiryTime = g_system->getMillis() + 10 * 1000; + +	_vm->_palette->resetGamePalette(4, 8); +	 +	// Load the advert background onto the screen +	SceneInfo *sceneInfo = SceneInfo::init(_vm); +	sceneInfo->load(screenId, 0, Common::String(), 0, _vm->_game->_scene._depthSurface, +		_vm->_screen); +	_vm->_screen.copyRectToScreen(_vm->_screen.getBounds()); +	delete sceneInfo; + +	EventsManager &events = *_vm->_events; +	events.setEventTarget(this); +	events.hideCursor(); + +	while (!_breakFlag && !_vm->shouldQuit()) { +		_vm->_events->waitForNextFrame(); +		_vm->_game->_fx = kTransitionNone; + +		_breakFlag |= g_system->getMillis() >= expiryTime; +	} + +	events.setEventTarget(nullptr); +	_vm->quitGame(); +} + +bool AdvertView::onEvent(Common::Event &event) { +	if (event.type == Common::EVENT_KEYDOWN || event.type == Common::EVENT_LBUTTONDOWN) { +		_breakFlag = true; +		return true; +	} + +	return false; +} + +/*------------------------------------------------------------------------*/ + +char TextView::_resourceName[100]; +#define TEXTVIEW_LINE_SPACING 2 +#define TEXT_ANIMATION_DELAY 100 +#define TV_NUM_FADE_STEPS 40 +#define TV_FADE_DELAY_MILLI 50 + +void TextView::execute(MADSEngine *vm, const Common::String &resName) { +	assert(resName.size() < 100); +	strcpy(_resourceName, resName.c_str()); +	vm->_dialogs->_pendingDialog = DIALOG_TEXTVIEW; +} + +TextView::TextView(MADSEngine *vm) : MenuView(vm), +		_textSurface(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT + _vm->_font->getHeight()) { +	_animating = false; +	_panSpeed = 0; +	Common::fill(&_spareScreens[0], &_spareScreens[10], 0); +	_spareScreen = nullptr; +	_scrollCount = 0; +	_lineY = -1; +	_scrollTimeout = 0; +	_panCountdown = 0; +	_translationX = 0; +} + +TextView::~TextView() { +	delete _spareScreen; +} + +void TextView::load() { +	if (!_script.open(_resourceName)) +		error("Could not open resource %s", _resourceName); + +	processLines(); +} + +void TextView::processLines() { +	if (_script.eos()) +		error("Attempted to read past end of response file"); + +	while (!_script.eos()) { +		_script.readLine(_currentLine, 79); + +		// Commented out line, so go loop for another +		if (_currentLine[0] == '#') +			continue; + +		// Process the line +		char *cStart = strchr(_currentLine, '['); +		if (cStart) { +			while (cStart) { +				// Loop for possible multiple commands on one line +				char *cEnd = strchr(_currentLine, ']'); +				if (!cEnd) +					error("Unterminated command '%s' in response file", _currentLine); + +				*cEnd = '\0'; +				processCommand(); + +				// Copy rest of line (if any) to start of buffer +				strcpy(_currentLine, cEnd + 1); + +				cStart = strchr(_currentLine, '[');  			} -			// Get the next sprite set -			Common::String spritesName = Resources::formatName(NEBULAR_MENUSCREEN,  -				'A', ++_menuItemIndex, EXT_SS, ""); -			_menuItem = new SpriteAsset(_vm, spritesName, 0); - -			// Slot it into available palette space -/* -			RGBList *palData = _menuItem->getRgbList(); -			_vm->_palette->addRange(palData); -			_menuItem->translate(palData, true); -			_itemPalData.push_back(palData); -*/ -		} +			if (_currentLine[0]) { +				processText(); +				break; +			} -		_vm->_events->showCursor(); -		return; +		} else { +			processText(); +			break; +		}  	} +} -	if ((_menuItemIndex == 0) || (_frameIndex == 0)) { -		// Get the next menu item -		if (_menuItem) { -			delete _menuItem; +void TextView::processCommand() { +	Scene &scene = _vm->_game->_scene; +	Common::String scriptLine(_currentLine + 1); +	scriptLine.toUppercase(); +	const char *paramP; +	const char *commandStr = scriptLine.c_str(); + +	if (!strncmp(commandStr, "BACKGROUND", 10)) { +		// Set the background +		paramP = commandStr + 10; +		int screenId = getParameter(¶mP); +		 +		SceneInfo *sceneInfo = SceneInfo::init(_vm); +		sceneInfo->load(screenId, 0, Common::String(), 0, scene._depthSurface, +			scene._backgroundSurface); +	 +	} else if (!strncmp(commandStr, "GO", 2)) { +		_animating = true; + +		// Grab what the final palete will be +		byte destPalette[PALETTE_SIZE]; +		_vm->_palette->grabPalette(destPalette, 0, 256); + +		// Copy the loaded background, if any, to the view surface +		//int yp = 22; +		//scene._backgroundSurface.copyTo(this, 0, 22); + +		// Handle fade-in +		//byte srcPalette[768]; +		//Common::fill(&srcPalette[0], &srcPalette[PALETTE_SIZE], 0); +		//_vm->_palette->fadeIn(srcPalette, destPalette, 0, PALETTE_COUNT, 0, 0, +		//	TV_FADE_DELAY_MILLI, TV_NUM_FADE_STEPS); +		_vm->_game->_fx = kTransitionFadeIn; + +	} else if (!strncmp(commandStr, "PAN", 3)) { +		// Set panning values +		paramP = commandStr + 3; +		int panX = getParameter(¶mP); +		int panY = getParameter(¶mP); +		int panSpeed = getParameter(¶mP); + +		if ((panX != 0) || (panY != 0)) { +			_pan = Common::Point(panX, panY); +			_panSpeed = panSpeed; +		} -			// Copy over the current display surface area to the background, so the final frame  -			// of the previous menuitem should be kept on the screen -//			copyTo(_bgSurface, Common::Rect(0, row, width(), row + MADS_SCENE_HEIGHT), 0, 0); +	} else if (!strncmp(commandStr, "DRIVER", 6)) { +		// Set the driver to use +		paramP = commandStr + 6; +		int driverNum = getParameter(¶mP); +		_vm->_sound->init(driverNum); + +	} else if (!strncmp(commandStr, "SOUND", 5)) { +		// Set sound number +		paramP = commandStr + 5; +		int soundId = getParameter(¶mP); +		_vm->_sound->command(soundId); + +	} else if (!strncmp(commandStr, "COLOR", 5) && ((commandStr[5] == '0') ||  +			(commandStr[5] == '1'))) { +		// Set the text colors +		int index = commandStr[5] - '0'; +		paramP = commandStr + 6; + +		byte palEntry[3]; +		palEntry[0] = getParameter(¶mP) << 2; +		palEntry[1] = getParameter(¶mP) << 2; +		palEntry[2] = getParameter(¶mP) << 2; +		_vm->_palette->setPalette(&palEntry[0], 5 + index, 1); + +	} else if (!strncmp(commandStr, "SPARE", 5)) { +		// Sets a secondary background number that can be later switched in with a PAGE command +		paramP = commandStr + 6; +		int spareIndex = commandStr[5] - '0'; +		if ((spareIndex >= 0) && (spareIndex <= 9)) { +			int screenId = getParameter(¶mP); + +			_spareScreens[spareIndex] = screenId;  		} -		// Get the next menuitem resource -		Common::String spritesName = Resources::formatName(NEBULAR_MENUSCREEN, -			'A', ++_menuItemIndex, EXT_SS, ""); - -		/* -		//sprintf(resName, "RM%dA%d.SS", REX_MENUSCREEN, ++_menuItemIndex); -		data = _vm->res()->get(resName); -		_menuItem = new SpriteAsset(_vm, data, data->size(), resName); -		_vm->res()->toss(resName); -		*/ -		// Slot it into available palette space -		/* -		RGBList *palData = _menuItem->getRgbList(); -		_vm->_palette->addRange(palData); -		_menuItem->translate(palData, true); -		_itemPalData.push_back(palData); -		*/ -		_frameIndex = _menuItem->getCount() - 1; - -		// If the final resource is now loaded, which contains the highlighted versions of  -		// each menuitem, then the startup animation is complete -		if (_menuItemIndex == 7) { -			_vm->_events->showCursor(); -			return; +	} else if (!strncmp(commandStr, "PAGE", 4)) { +		// Signals to change to a previous specified secondary background +		paramP = commandStr + 4; +		int spareIndex = getParameter(¶mP); + +		// Only allow background switches if one isn't currently in progress +		if (!_spareScreen && (_spareScreens[spareIndex] != 0)) { +			_spareScreen = new MSurface(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT); +			//_spareScreen->loadBackground(_spareScreens[spareIndex], &_bgSpare); + +			_translationX = 0;  		} +  	} else { -		--_frameIndex; +		error("Unknown response command: '%s'", commandStr);  	} +} -	// Move to the next menuitem frame +int TextView::getParameter(const char **paramP) { +	if ((**paramP != '=') && (**paramP != ',')) +		return 0; -	itemSize = _menuItem->getFrame(0)->h; +	int result = 0; +	++*paramP; +	while ((**paramP >= '0') && (**paramP <= '9')) { +		result = result * 10 + (**paramP - '0'); +		++*paramP; +	} -	//_bgSurface->copyTo(this, 0, row); -	MSprite *spr = _menuItem->getFrame(_frameIndex); -	 -	spr->copyTo(&_vm->_screen,  -		Common::Point(_itemPosList[_menuItemIndex - 1].x,  -			_itemPosList[_menuItemIndex - 1].y + MADS_MENU_Y +  -			(itemSize / 2) - (spr->h / 2))); +	return result;  } -int MainMenu::getHighlightedItem(int x, int y) { -	y -= MADS_MENU_Y; +void TextView::processText() { +	int lineWidth, xStart; -	for (int index = 0; index < 6; ++index) { -		const Common::Point &pt = _itemPosList[index]; -		MSprite *spr = _menuItem->getFrame(index); +	if (!strcmp(_currentLine, "***")) { +		// Special signifier for end of script +		_scrollCount = _vm->_font->getHeight() * 13; +		_lineY = -1; +		return; +	} + +	_lineY = 0; + +	// Lines are always centered, except if line contains a '@', in which case the +	// '@' marks the position that must be horizontally centered +	char *centerP = strchr(_currentLine, '@'); +	if (centerP) { +		*centerP = '\0'; +		xStart = (MADS_SCREEN_WIDTH / 2) - _vm->_font->getWidth(_currentLine); -		if ((x >= pt.x) && (y >= pt.y) && (x < (pt.x + spr->w)) && (y < (pt.y + spr->h))) -			return index; +		// Delete the @ character and shift back the remainder of the string +		char *p = centerP + 1; +		if (*p == ' ') ++p; +		strcpy(centerP, p); + +	} else { +		lineWidth = _vm->_font->getWidth(_currentLine); +		xStart = (MADS_SCREEN_WIDTH - lineWidth) / 2;  	} -	return -1; +	// Copy the text line onto the bottom of the textSurface surface, which will allow it +	// to gradually scroll onto the screen +	int yp = _textSurface.h - _vm->_font->getHeight() - TEXTVIEW_LINE_SPACING; +	_textSurface.fillRect(Common::Rect(0, yp, MADS_SCREEN_WIDTH, _textSurface.h), 0); +	_vm->_font->writeString(&_textSurface, _currentLine, Common::Point(xStart, yp));  } -void MainMenu::handleAction(MADSGameAction action) { -	_vm->_events->hideCursor(); -	/* -	switch (action) { -	case START_GAME: -	case RESUME_GAME: -		// Load a sample starting scene - note that, currently, calling loadScene automatically -		// removes this menu screen from being displayed -		_vm->_mouse->cursorOn(); -		_vm->_viewManager->addView(_vm->_scene); -		_vm->_scene->loadScene(101); -		return; +/*------------------------------------------------------------------------*/ -	case SHOW_INTRO: -		_vm->_viewManager->showAnimView("@rexopen"); -		break; +char AnimationView::_resourceName[100]; -	case CREDITS: -		_vm->_viewManager->showTextView("credits"); +void AnimationView::execute(MADSEngine *vm, const Common::String &resName) { +	assert(resName.size() < 100); +	strcpy(_resourceName, resName.c_str()); +	vm->_dialogs->_pendingDialog = DIALOG_ANIMVIEW; +} + +AnimationView::AnimationView(MADSEngine *vm) : MenuView(vm) { +	_soundDriverLoaded = false; +} + +void AnimationView::load() { +	Common::String resName(_resourceName); +	if (!resName.hasSuffix(".")) +		resName += ".res"; + +	if (!_script.open(resName)) +		error("Could not open resource %s", resName.c_str()); + +	processLines(); +} + +bool AnimationView::onEvent(Common::Event &event) { +	// Wait for the Escape key or a mouse press +	if (((event.type == Common::EVENT_KEYDOWN) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) || +			(event.type == Common::EVENT_RBUTTONUP)) { +		scriptDone(); +		return true; +	} + +	return false; +} + +void AnimationView::doFrame() { +	Scene &scene = _vm->_game->_scene; +	int bgNumber = 0; + +	// Only update state if wait period has expired +	if (_previousUpdate > 0) { +		if (g_system->getMillis() - _previousUpdate < 3000) { +			return; +		} else { +			// time for an update +			_previousUpdate = g_system->getMillis(); +		} +	} else { +		_previousUpdate = g_system->getMillis();  		return; +	} -	case QUOTES: -		_vm->_viewManager->showTextView("quotes"); +	char bgFile[10]; +	strncpy(bgFile, _currentFile, 5); +	bgFile[0] = bgFile[2]; +	bgFile[1] = bgFile[3]; +	bgFile[2] = bgFile[4]; +	bgFile[3] = '\0'; +	bgNumber = atoi(bgFile); +	sprintf(bgFile, "rm%i.art", bgNumber); + +	// Not all scenes have a background. If there is one, refresh it +	if (Common::File::exists(bgFile)) { +		_vm->_palette->resetGamePalette(4, 8); +		SceneInfo *sceneInfo = SceneInfo::init(_vm); +		sceneInfo->load(bgNumber, 0, Common::String(), 0, scene._depthSurface, +			scene._backgroundSurface); +	} + +	// Read next line +	processLines(); +} + +void AnimationView::scriptDone() { +	_breakFlag = true; +	_vm->_dialogs->_pendingDialog = DIALOG_MAIN_MENU; +} + +void AnimationView::processLines() { +	if (_script.eos()) { +		// end of script, end animation +		scriptDone();  		return; +	} -	case EXIT: -	{ -					// When the Exit action is done from the menu, show one of two possible advertisements +	while (!_script.eos()) { +		_script.readLine(_currentLine, 79); + +		// Process the line +		char *cStart = strchr(_currentLine, '-'); +		if (cStart) { +			while (cStart) { +				// Loop for possible multiple commands on one line +				char *cEnd = strchr(_currentLine, ' '); +				if (!cEnd) +					error("Unterminated command '%s' in response file", _currentLine); -					// Activate the scene display with the specified scene -					bool altAdvert = _vm->_random->getRandomNumber(1000) >= 500; -					_vm->_scene->loadScene(altAdvert ? 995 : 996); -					_vm->_viewManager->addView(_vm->_scene); +				*cEnd = '\0'; +				processCommand(); -					_vm->_viewManager->refreshAll(); -					_vm->delay(10000); +				// Copy rest of line (if any) to start of buffer +				// Don't use strcpy() here, because if the +				// rest of the line is the longer of the two +				// strings, the memory areas will overlap. +				memmove(_currentLine, cEnd + 1, strlen(cEnd + 1) + 1); -					_vm->_events->quitFlag = true; -					return; +				cStart = strchr(_currentLine, '-'); +			} + +			if (_currentLine[0]) { +				sprintf(_currentFile, "%s", _currentLine); +				//printf("File: %s\n", _currentLine); +				break; +			} + +		} else { +			sprintf(_currentFile, "%s", _currentLine); +			warning("File: %s\n", _currentLine); +			break; +		}  	} -		break; -	default: -		break; +} + +void AnimationView::processCommand() { +	Common::String commandLine(_currentLine + 1); +	commandLine.toUppercase(); +	const char *commandStr = commandLine.c_str(); +	const char *param = commandStr; + +	if (!strncmp(commandStr, "X", 1)) { +		//printf("X "); +	} else if (!strncmp(commandStr, "W", 1)) { +		//printf("W "); +	} else if (!strncmp(commandStr, "R", 1)) { +		param = param + 2; +		//printf("R:%s ", param); +	} else if (!strncmp(commandStr, "O", 1)) { +		// Set the transition effect +		param = param + 2; +		_vm->_game->_fx = (ScreenTransition)atoi(param); +	} else { +		error("Unknown response command: '%s'", commandStr);  	} -	*/  }  } // End of namespace Nebular  | 
