diff options
| author | Paweł Kołodziejski | 2004-11-19 19:50:22 +0000 | 
|---|---|---|
| committer | Paweł Kołodziejski | 2004-11-19 19:50:22 +0000 | 
| commit | 20e9cf6f20dde6aed31b83698940786a783c2125 (patch) | |
| tree | 51be5f26a2a58c008c4fa8a11f4941b1ed75a3e9 | |
| parent | c4a8b3c8b54022664fe231253f8314f0557a958f (diff) | |
| download | scummvm-rg350-20e9cf6f20dde6aed31b83698940786a783c2125.tar.gz scummvm-rg350-20e9cf6f20dde6aed31b83698940786a783c2125.tar.bz2 scummvm-rg350-20e9cf6f20dde6aed31b83698940786a783c2125.zip  | |
added walkthrough
svn-id: r15835
| -rw-r--r-- | base/engine.cpp | 5 | ||||
| -rw-r--r-- | base/engine.h | 3 | ||||
| -rw-r--r-- | gui/module.mk | 1 | ||||
| -rw-r--r-- | gui/walkthrough.cpp | 247 | ||||
| -rw-r--r-- | gui/walkthrough.h | 76 | ||||
| -rw-r--r-- | kyra/kyra.cpp | 5 | ||||
| -rw-r--r-- | queen/input.cpp | 6 | ||||
| -rw-r--r-- | queen/queen.cpp | 3 | ||||
| -rw-r--r-- | saga/input.cpp | 2 | ||||
| -rw-r--r-- | saga/saga.cpp | 3 | ||||
| -rw-r--r-- | scumm/input.cpp | 2 | ||||
| -rw-r--r-- | scumm/scumm.cpp | 6 | ||||
| -rw-r--r-- | simon/simon.cpp | 7 | ||||
| -rw-r--r-- | sky/sky.cpp | 7 | ||||
| -rw-r--r-- | sword1/sword1.cpp | 8 | ||||
| -rw-r--r-- | sword2/sword2.cpp | 10 | 
16 files changed, 388 insertions, 3 deletions
diff --git a/base/engine.cpp b/base/engine.cpp index a75ff7d1b5..5dbdd28e8d 100644 --- a/base/engine.cpp +++ b/base/engine.cpp @@ -47,6 +47,8 @@ Engine::Engine(OSystem *syst)  	g_debugLevel = ConfMan.getInt("debuglevel");  	_saveFileMan = _system->getSavefileManager(); + +	_walkthroughDialog = new GUI::WalkthroughDialog(1.0, 1.0);  }  Engine::~Engine() { @@ -54,8 +56,9 @@ Engine::~Engine() {  	delete _mixer;  	delete _saveFileMan; +	delete _walkthroughDialog; -	g_engine = 0; +	g_engine = NULL;  }  const char *Engine::getSavePath() const { diff --git a/base/engine.h b/base/engine.h index 509d8cd526..24d58e51f4 100644 --- a/base/engine.h +++ b/base/engine.h @@ -25,6 +25,8 @@  #include "common/str.h"  #include "common/system.h" +#include "gui/walkthrough.h" +  class SoundMixer;  class Timer; @@ -37,6 +39,7 @@ public:  protected:  	const Common::String _gameDataPath;  	SaveFileManager *_saveFileMan; +	GUI::WalkthroughDialog *_walkthroughDialog;  public:  	Engine(OSystem *syst); diff --git a/gui/module.mk b/gui/module.mk index 443cb96fef..ca6946740c 100644 --- a/gui/module.mk +++ b/gui/module.mk @@ -16,6 +16,7 @@ MODULE_OBJS := \  	gui/PopUpWidget.o \  	gui/ScrollBarWidget.o \  	gui/TabWidget.o \ +	gui/walkthrough.o \  	gui/widget.o  MODULE_DIRS += \ diff --git a/gui/walkthrough.cpp b/gui/walkthrough.cpp new file mode 100644 index 0000000000..706f729f9e --- /dev/null +++ b/gui/walkthrough.cpp @@ -0,0 +1,247 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002-2004 The ScummVM project + * + * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + * $Header$ + */ + +#include "stdafx.h" + +#include "common/file.h" + +#include "graphics/font.h" + +#include "gui/walkthrough.h" +#include "gui/ScrollBarWidget.h" + +namespace GUI { + +extern const Graphics::NewFont g_consolefont; + +#define kConsoleCharWidth	(g_consolefont.getMaxCharWidth()) +#define kConsoleLineHeight	(g_consolefont.getFontHeight() + 2) + + + +WalkthroughDialog::WalkthroughDialog(float widthPercent, float heightPercent) +	: Dialog(0, 0, 1, 1), +	_initialized(false), _widthPercent(widthPercent), _heightPercent(heightPercent) { +} + +WalkthroughDialog::~WalkthroughDialog() { +	destroy(); +} + +static int getNextWordLength(byte *src, int maxLength) { +	int l; + +	for (l = 0; l < maxLength; l++) { +		byte tmp = src[l]; +		if ((tmp >= 0) && (tmp <= ' ')) +			break; +	} + +	return l; +} + +bool WalkthroughDialog::loadWalkthroughText(const char *gameName) { +	char filename[MAX_PATH]; +	File file; + +	sprintf(filename, "%s.wkt", gameName); +	file.open(filename); +	if (!file.isOpen()) +		return false; +	int bufferSize = file.size(); +	byte *buffer = (byte *)malloc(bufferSize); +	file.read(buffer, bufferSize); +	file.close(); + +	int currentLinePos = 0; +	byte *currentBuffer = buffer; +	byte *lineBuffer = (byte *)malloc(_lineWidth + 1); +	lineBuffer[0] = 0; + +	for (;;) { +		if ((currentBuffer - buffer) >= bufferSize) +			break; +		int wordLength = getNextWordLength(currentBuffer, _lineWidth); +		if (((currentLinePos + wordLength) < _lineWidth) &&  +				((*currentBuffer != 0x0a) && (*currentBuffer != 0x0d))) { +			if ((*currentBuffer >= 0) && (*currentBuffer <= ' ')) { +				lineBuffer[currentLinePos++] = ' '; +				currentBuffer++; +			} else { +				memcpy(lineBuffer + currentLinePos, currentBuffer, wordLength); +				currentLinePos += wordLength; +				currentBuffer += wordLength; +				if ((currentLinePos + 1) < _lineWidth) { +					lineBuffer[currentLinePos] = ' '; +					currentLinePos++; +				} +			} +		} else { +			if (*currentBuffer == 0x0d) { +				currentBuffer++; +				if ((*currentBuffer == 0x0a) && ((currentBuffer - buffer) < bufferSize)) { +					currentBuffer++; +				} +			} else if (*currentBuffer == 0x0a) { +				currentBuffer++; +			} +			lineBuffer[currentLinePos] = 0; +			Entry line; +			line.text = String((char *)lineBuffer); +			_linesArray.push_back(line); +			lineBuffer[0] = 0; +			currentLinePos = 0; +		} +	} + +	free(buffer); +	free(lineBuffer); + +	return true; +} + +void WalkthroughDialog::create(const char *gameName) { +	// Setup basic layout/dialog size +	reflowLayout(); + +	// Add scrollbar +	_scrollBar = new ScrollBarWidget(this, _w - kScrollBarWidth - 1, 0, kScrollBarWidth, _h); +	_scrollBar->setTarget(this); + +	_currentPos = 0; +	_scrollLine = _linesPerPage - 1; + +	loadWalkthroughText(gameName); + +	_initialized = true; +} + +void WalkthroughDialog::destroy() { +	if (!_initialized) +		return; + +	_linesArray.clear(); + +	_initialized = false; +} + +void WalkthroughDialog::reflowLayout() { +	// Calculate the real width/height (rounded to char/line multiples) +	_w = (uint16)(_widthPercent * g_system->getOverlayWidth()); +	_h = (uint16)((_heightPercent * g_system->getOverlayHeight() - 2) / kConsoleLineHeight); +	_h = _h * kConsoleLineHeight + 2; + +	// Calculate depending values +	_lineWidth = (_w - kScrollBarWidth - 2) / kConsoleCharWidth; +	_linesPerPage = (_h - 2) / kConsoleLineHeight; +} + +void WalkthroughDialog::open() { +	Dialog::open(); +} + +void WalkthroughDialog::drawDialog() { +	// Blend over the background +	g_gui.fillRect(_x, _y, _w, _h, g_gui._bgcolor); + +	// Draw a border +	g_gui.hLine(_x, _y + _h - 1, _x + _w - 1, g_gui._color); + +	// Draw text +	int y = _y + 2; + +	for (int line = 0; (line < _linesPerPage) && ((_currentPos + line) < (int)_linesArray.size()); line++) { +		const char *text = _linesArray[line + _currentPos].text.c_str(); +		int textLen = strlen(text); +		int x = _x + 1; +		for (int column = 0; (column < _lineWidth) && (column < textLen); column++) { +			byte c = text[column]; +			g_gui.drawChar(c, x, y, g_gui._textcolor, &g_consolefont); +			x += kConsoleCharWidth; +		} +		y += kConsoleLineHeight; +	} + +	// Draw the scrollbar +	_scrollBar->_numEntries = _linesArray.size(); +	_scrollBar->_currentPos = _currentPos; +	_scrollBar->_entriesPerPage = _linesPerPage; +	_scrollBar->recalc(); +	_scrollBar->draw(); + +	// Finally blit it all to the screen +	g_gui.addDirtyRect(_x, _y, _w, _h); +} + + +void WalkthroughDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { +	switch (cmd) { +	case kSetPositionCmd: +		_currentPos = _scrollBar->_currentPos; +		drawDialog(); +		break; +	default: +		return; +	} +} + +void WalkthroughDialog::handleMouseWheel(int x, int y, int direction) { +	_scrollBar->handleMouseWheel(x, y, direction); +} + +void WalkthroughDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { +	if ((modifiers == OSystem::KBD_CTRL) && (keycode == 'w')) { +		close(); +		return; +	} +	switch (keycode) { +	case 256 + 17:	// up arrow +		_currentPos--; +		break; +	case 256 + 18:	// down arrow +		_currentPos++; +		break; +	case 256 + 22:	// home +		_currentPos = 0; +		break; +	case 256 + 23:	// end +		_currentPos = _linesArray.size() - _linesPerPage; +		break; +	case 256 + 24:	// page up +		_currentPos -= _linesPerPage; +		break; +	case 256 + 25:	// page down +		_currentPos += _linesPerPage; +		break; +	default: +		return; +	} +	if (_currentPos < 0) { +		_currentPos = 0; +	} +	if ((_currentPos + _linesPerPage) >= (int)_linesArray.size()) { +		_currentPos = _linesArray.size() - _linesPerPage; +	} + +	drawDialog(); +} + + +} // End of namespace GUI diff --git a/gui/walkthrough.h b/gui/walkthrough.h new file mode 100644 index 0000000000..2162156ba6 --- /dev/null +++ b/gui/walkthrough.h @@ -0,0 +1,76 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002-2004 The ScummVM project + * + * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + * $Header$ + */ + +#ifndef WALKTHROUGH_DIALOG_H +#define WALKTHROUGH_DIALOG_H + +#include "common/array.h" +#include "common/str.h" + +#include "gui/dialog.h" +#include "gui/newgui.h" + +#include <stdarg.h> + +namespace GUI { + +class ScrollBarWidget; + +class WalkthroughDialog : public Dialog { +private: +	bool _initialized; +	int	_lineWidth; +	int	_linesPerPage; +	int	_currentPos; +	int	_scrollLine; +	int	_firstLineInBuffer; + +	typedef Common::String String; + +	struct Entry { +		String text; +	}; +	typedef Common::Array<Entry> EntryList; +	EntryList _linesArray; + +	ScrollBarWidget *_scrollBar; + +	float _widthPercent, _heightPercent; + +	void reflowLayout(); +	bool loadWalkthroughText(const char *gameName); + +public: +	WalkthroughDialog(float widthPercent, float heightPercent); +	~WalkthroughDialog(); + +	void create(const char *gameName); +	void destroy(); +	void open(); +	void drawDialog(); + +	void handleMouseWheel(int x, int y, int direction); +	void handleKeyDown(uint16 ascii, int keycode, int modifiers); +	void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); +}; + +} // End of namespace GUI + +#endif diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp index 440c1bced1..d62f32f2cf 100644 --- a/kyra/kyra.cpp +++ b/kyra/kyra.cpp @@ -169,6 +169,9 @@ KyraEngine::KyraEngine(GameDetector *detector, OSystem *syst)  	assert(_npcScript);  	assert(_currentScript); + +	_walkthroughDialog->setGameName(detector->_game.name); +	_walkthroughDialog->create();  }  KyraEngine::~KyraEngine() { @@ -179,6 +182,8 @@ KyraEngine::~KyraEngine() {  	delete _npcScript;  	delete _currentScript;  	delete _font; + +	_walkthroughDialog->destroy();  }  void KyraEngine::errorString(const char *buf1, char *buf2) { diff --git a/queen/input.cpp b/queen/input.cpp index fc3b9f8ca6..23d174efb7 100644 --- a/queen/input.cpp +++ b/queen/input.cpp @@ -20,9 +20,11 @@   */  #include "stdafx.h" -#include "queen/input.h" +  #include "common/system.h" +#include "queen/input.h" +  namespace Queen {  const char *Input::_commandKeys[LANGUAGE_COUNT] = { @@ -102,6 +104,8 @@ void Input::delay(uint amount) {  						_debugger = true;  					} else if (event.kbd.keycode == 'f') {  						_fastMode = !_fastMode; +					} else if (event.kbd.keycode == 'w') { +//						_walkthroughDialog->runModal(); // FIXME  					}  				} else {  					_inKey = event.kbd.keycode; diff --git a/queen/queen.cpp b/queen/queen.cpp index 93f2e70e35..3b08da89aa 100644 --- a/queen/queen.cpp +++ b/queen/queen.cpp @@ -91,6 +91,7 @@ namespace Queen {  QueenEngine::QueenEngine(GameDetector *detector, OSystem *syst)  	: Engine(syst) { +	_walkthroughDialog->setGameName(detector->_game.name);  }  QueenEngine::~QueenEngine() { @@ -107,6 +108,8 @@ QueenEngine::~QueenEngine() {  	delete _music;  	delete _sound;  	delete _walk; + +	_walkthroughDialog->destroy();  }  void QueenEngine::registerDefaultSettings() { diff --git a/saga/input.cpp b/saga/input.cpp index 37f764eee4..425bb2467d 100644 --- a/saga/input.cpp +++ b/saga/input.cpp @@ -42,6 +42,8 @@ int SagaEngine::processInput() {  		switch (event.event_code) {  		case OSystem::EVENT_KEYDOWN: +			if (event.kbd.keycode == 'w') +				_walkthroughDialog->runModal();  			if (_vm->_console->isActive()) {  				in_char = event.kbd.ascii;  				switch (event.kbd.keycode) { diff --git a/saga/saga.cpp b/saga/saga.cpp index 03f8be3555..d12f1b2113 100644 --- a/saga/saga.cpp +++ b/saga/saga.cpp @@ -115,9 +115,12 @@ SagaEngine::SagaEngine(GameDetector *detector, OSystem *syst)  	_mixer->setVolume(ConfMan.getInt("sfx_volume") * ConfMan.getInt("master_volume") / 255);  	_vm = this; + +	_walkthroughDialog->setGameName(detector->_game.name);  }  SagaEngine::~SagaEngine() { +	_walkthroughDialog->destroy();  }  void SagaEngine::errorString(const char *buf1, char *buf2) { diff --git a/scumm/input.cpp b/scumm/input.cpp index ed809142d7..100e5813f0 100644 --- a/scumm/input.cpp +++ b/scumm/input.cpp @@ -65,6 +65,8 @@ void ScummEngine::parseEvents() {  					_debugger->attach();  				else if (event.kbd.keycode == 's')  					resourceStats(); +				else if (event.kbd.keycode == 'w') +					_walkthroughDialog->runModal();  				else  					_keyPressed = event.kbd.ascii;	// Normal key press, pass on to the game.  			} else if (event.kbd.flags & OSystem::KBD_ALT) { diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index f8abc97773..3fc1f0e94d 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -897,6 +897,8 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS  	}  	_midi = gs.midi; + +	_walkthroughDialog->setGameName(detector->_game.name);  }  ScummEngine::~ScummEngine() { @@ -943,6 +945,8 @@ ScummEngine::~ScummEngine() {  	free(_languageIndex);  	delete _debugger; + +	_walkthroughDialog->destroy();  }  ScummEngine_v6::ScummEngine_v6(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16])  @@ -986,6 +990,8 @@ void ScummEngine::mainInit() {  	// Initialize backend  	_system->initSize(_screenWidth, _screenHeight); +	_walkthroughDialog->create(); +  	int cd_num = ConfMan.getInt("cdrom");  	if (cd_num >= 0 && (_features & GF_AUDIOTRACKS))  		_system->openCD(cd_num); diff --git a/simon/simon.cpp b/simon/simon.cpp index b7519e8ca4..8bfdaf7f1e 100644 --- a/simon/simon.cpp +++ b/simon/simon.cpp @@ -718,6 +718,9 @@ SimonEngine::SimonEngine(GameDetector *detector, OSystem *syst)  	// FIXME Use auto dirty rects cleanup code to reduce CPU usage  	g_system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, true); + +	_walkthroughDialog->setGameName(detector->_game.name); +	_walkthroughDialog->create();  }  SimonEngine::~SimonEngine() { @@ -729,6 +732,8 @@ SimonEngine::~SimonEngine() {  	delete _sound;  	delete _debugger; + +	_walkthroughDialog->destroy();  }  void SimonEngine::errorString(const char *buf1, char *buf2) { @@ -4848,6 +4853,8 @@ void SimonEngine::delay(uint amount) {  						_aboutDialog->runModal();  					} else if (event.kbd.keycode == 'f')  						_fast_mode ^= 1; +					else if (event.kbd.keycode == 'w') +						_walkthroughDialog->runModal();  					else if (event.kbd.keycode == 'd')  						_debugger->attach();  				} diff --git a/sky/sky.cpp b/sky/sky.cpp index 072c958525..e43a6bca29 100644 --- a/sky/sky.cpp +++ b/sky/sky.cpp @@ -116,6 +116,8 @@ SystemVars SkyEngine::_systemVars = {0, 0, 0, 0, 4316, 0, 0, false, false };  SkyEngine::SkyEngine(GameDetector *detector, OSystem *syst)  	: Engine(syst), _fastMode(0) { +	_walkthroughDialog->setGameName(detector->_game.name); +	_walkthroughDialog->create();  }  SkyEngine::~SkyEngine() { @@ -127,6 +129,8 @@ SkyEngine::~SkyEngine() {  	delete _skyMouse;  	delete _skyScreen;  	delete _debugger; + +	_walkthroughDialog->destroy();  }  void SkyEngine::errorString(const char *buf1, char *buf2) { @@ -461,6 +465,9 @@ void SkyEngine::delay(uint amount) {  					if (event.kbd.keycode == 'd') {  						_debugger->attach();  					} +					if (event.kbd.keycode == 'w') { +						_walkthroughDialog->runModal(); +					}  				}  				// Make sure backspace works right (this fixes a small issue on OS X) diff --git a/sword1/sword1.cpp b/sword1/sword1.cpp index 1e56aa0944..f7db821c6a 100644 --- a/sword1/sword1.cpp +++ b/sword1/sword1.cpp @@ -109,6 +109,8 @@ SwordEngine::SwordEngine(GameDetector *detector, OSystem *syst)  	if (!_mixer->isReady())  		warning("Sound initialization failed"); + +	_walkthroughDialog->setGameName(detector->_game.name);  }  SwordEngine::~SwordEngine() { @@ -121,6 +123,8 @@ SwordEngine::~SwordEngine() {  	delete _mouse;  	delete _objectMan;  	delete _resMan; + +	_walkthroughDialog->destroy();  }  void SwordEngine::initialize(void) { @@ -198,6 +202,8 @@ void SwordEngine::initialize(void) {  	_objectMan->initialize();  	_mouse->initialize();  	_control = new Control(_saveFileMan, _resMan, _objectMan, _system, _mouse, _sound, _music, getSavePath()); + +	_walkthroughDialog->create();  }  void SwordEngine::reinitialize(void) { @@ -1283,6 +1289,8 @@ void SwordEngine::delay(uint amount) { //copied and mutilated from sky.cpp  					_keyPressed = 8;  				else  					_keyPressed = (uint8)event.kbd.ascii; +				if (event.kbd.keycode == 'w') +					_walkthroughDialog->runModal();  				break;  			case OSystem::EVENT_MOUSEMOVE:  				_mouseX = event.mouse.x; diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp index 732b99b743..9d4857087b 100644 --- a/sword2/sword2.cpp +++ b/sword2/sword2.cpp @@ -180,6 +180,8 @@ Sword2Engine::Sword2Engine(GameDetector *detector, OSystem *syst) : Engine(syst)  	_gameCycle = 0;  	_quit = false; + +	_walkthroughDialog->setGameName(detector->_game.name);  }  Sword2Engine::~Sword2Engine() { @@ -193,6 +195,8 @@ Sword2Engine::~Sword2Engine() {  	delete _logic;  	delete _resman;  	delete _memory; + +	_walkthroughDialog->destroy();  }  void Sword2Engine::errorString(const char *buf1, char *buf2) { @@ -296,6 +300,8 @@ void Sword2Engine::mainInit() {  		startGame();  	_graphics->initialiseRenderCycle(); + +	_walkthroughDialog->create();  }  void Sword2Engine::mainRun() { @@ -315,6 +321,8 @@ void Sword2Engine::mainRun() {  		if (ke) {  			if ((ke->modifiers == OSystem::KBD_CTRL && ke->keycode == 'd') || ke->ascii == '#' || ke->ascii == '~') {  				_debugger->attach(); +			} else if ((ke->modifiers == OSystem::KBD_SHIFT) && (ke->keycode == 'w')) { +				_walkthroughDialog->runModal();  			} else if (ke->modifiers == 0 || ke->modifiers == OSystem::KBD_SHIFT) {  				switch (ke->keycode) {  				case 'p': @@ -511,7 +519,7 @@ void Sword2Engine::startGame() {  	// script #1, but with different ScreenManager objects depending on  	// if it's the demo or the full game, or if we're using a boot param. -	int screen_manager_id; +	int screen_manager_id = 0;  	debug(5, "startGame() STARTING:");  | 
