1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "common/file.h"
24 #include "common/config-manager.h"
25 #include "common/textconsole.h"
26
27 #include "audio/mixer.h"
28
29 #include "base/plugins.h"
30 #include "base/version.h"
31
32 #include "graphics/cursorman.h"
33
34 #include "engines/util.h"
35
36 #include "neverhood/neverhood.h"
37 #include "neverhood/blbarchive.h"
38 #include "neverhood/console.h"
39 #include "neverhood/gamemodule.h"
40 #include "neverhood/gamevars.h"
41 #include "neverhood/graphics.h"
42 #include "neverhood/resourceman.h"
43 #include "neverhood/resource.h"
44 #include "neverhood/screen.h"
45 #include "neverhood/sound.h"
46 #include "neverhood/staticdata.h"
47
48 namespace Neverhood {
49
NeverhoodEngine(OSystem * syst,const ADGameDescription * gameDesc)50 NeverhoodEngine::NeverhoodEngine(OSystem *syst, const ADGameDescription *gameDesc) :
51 Engine(syst), _gameDescription(gameDesc) {
52 // Setup mixer
53 if (!_mixer->isReady()) {
54 warning("Sound initialization failed.");
55 }
56
57 _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
58 _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
59
60 _rnd = new Common::RandomSource("neverhood");
61
62 }
63
~NeverhoodEngine()64 NeverhoodEngine::~NeverhoodEngine() {
65 delete _rnd;
66 }
67
run()68 Common::Error NeverhoodEngine::run() {
69 initGraphics(640, 480);
70
71 const Common::FSNode gameDataDir(ConfMan.get("path"));
72
73 SearchMan.addSubDirectoryMatching(gameDataDir, "data");
74
75 _isSaveAllowed = false;
76
77 _mouseX = 0;
78 _mouseY = 0;
79
80 _gameState.sceneNum = 0;
81 _gameState.which = 0;
82
83 _staticData = new StaticData();
84 _staticData->load("neverhood.dat");
85 _gameVars = new GameVars();
86 _screen = new Screen(this);
87 _res = new ResourceMan();
88 setDebugger(new Console(this));
89
90 if (isDemo()) {
91 _res->addArchive("a.blb");
92 _res->addArchive("nevdemo.blb");
93 } else {
94 _res->addArchive("a.blb");
95 _res->addArchive("c.blb");
96 _res->addArchive("hd.blb");
97 _res->addArchive("i.blb");
98 _res->addArchive("m.blb");
99 _res->addArchive("s.blb");
100 _res->addArchive("t.blb");
101 }
102
103 CursorMan.showMouse(false);
104
105 _soundMan = new SoundMan(this);
106 _audioResourceMan = new AudioResourceMan(this);
107
108 _gameModule = new GameModule(this);
109
110 _isSaveAllowed = true;
111 _updateSound = true;
112 _enableMusic = !_mixer->isSoundTypeMuted(Audio::Mixer::kMusicSoundType);
113
114 if (isDemo() && !isBigDemo()) {
115 // Adjust this navigation list for the demo version
116 NavigationList *navigationList = _staticData->getNavigationList(0x004B67E8);
117 (*navigationList)[0].middleSmackerFileHash = 0;
118 (*navigationList)[0].middleFlag = 1;
119 (*navigationList)[2].middleSmackerFileHash = 0;
120 (*navigationList)[2].middleFlag = 1;
121 (*navigationList)[4].middleSmackerFileHash = 0;
122 (*navigationList)[4].middleFlag = 1;
123 (*navigationList)[5].middleSmackerFileHash = 0;
124 (*navigationList)[5].middleFlag = 1;
125 }
126
127 if (ConfMan.hasKey("save_slot")) {
128 if (loadGameState(ConfMan.getInt("save_slot")).getCode() != Common::kNoError)
129 _gameModule->startup();
130 } else
131 _gameModule->startup();
132
133 mainLoop();
134
135 delete _gameModule;
136 delete _soundMan;
137 delete _audioResourceMan;
138
139 delete _res;
140 delete _screen;
141
142 delete _gameVars;
143 delete _staticData;
144
145 return Common::kNoError;
146 }
147
mainLoop()148 void NeverhoodEngine::mainLoop() {
149 uint32 nextFrameTime = 0;
150 while (!shouldQuit()) {
151 Common::Event event;
152 Common::EventManager *eventMan = _system->getEventManager();
153 while (eventMan->pollEvent(event)) {
154 switch (event.type) {
155 case Common::EVENT_KEYDOWN:
156 _gameModule->handleKeyDown(event.kbd.keycode);
157 _gameModule->handleAsciiKey(event.kbd.ascii);
158 break;
159 case Common::EVENT_KEYUP:
160 break;
161 case Common::EVENT_MOUSEMOVE:
162 _mouseX = event.mouse.x;
163 _mouseY = event.mouse.y;
164 _gameModule->handleMouseMove(event.mouse.x, event.mouse.y);
165 break;
166 case Common::EVENT_LBUTTONDOWN:
167 case Common::EVENT_RBUTTONDOWN:
168 _gameModule->handleMouseDown(event.mouse.x, event.mouse.y);
169 break;
170 case Common::EVENT_LBUTTONUP:
171 case Common::EVENT_RBUTTONUP:
172 _gameModule->handleMouseUp(event.mouse.x, event.mouse.y);
173 break;
174 case Common::EVENT_WHEELUP:
175 _gameModule->handleWheelUp();
176 break;
177 case Common::EVENT_WHEELDOWN:
178 _gameModule->handleWheelDown();
179 break;
180 default:
181 break;
182 }
183 }
184 if (_system->getMillis() >= nextFrameTime) {
185 _gameModule->checkRequests();
186 _gameModule->handleUpdate();
187 _gameModule->draw();
188 _screen->update();
189 if (_updateSound)
190 _soundMan->update();
191 nextFrameTime = _screen->getNextFrameTime();
192 };
193
194 _audioResourceMan->updateMusic();
195
196 _system->updateScreen();
197 _system->delayMillis(10);
198 }
199 }
200
getMousePos()201 NPoint NeverhoodEngine::getMousePos() {
202 NPoint pt;
203 pt.x = _mouseX;
204 pt.y = _mouseY;
205 return pt;
206 }
207
208 } // End of namespace Neverhood
209