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:"); |