scummvm/engines/bladerunner/bladerunner.cpp

298 lines
6.9 KiB
C++
Raw Normal View History

/* 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 "bladerunner/bladerunner.h"
#include "bladerunner/chapters.h"
#include "bladerunner/gameinfo.h"
#include "bladerunner/image.h"
#include "bladerunner/outtake.h"
#include "bladerunner/scene.h"
#include "bladerunner/script/script.h"
#include "bladerunner/settings.h"
#include "bladerunner/vqa_decoder.h"
#include "common/error.h"
#include "common/events.h"
#include "common/system.h"
#include "engines/util.h"
#include "graphics/pixelformat.h"
namespace BladeRunner {
BladeRunnerEngine::BladeRunnerEngine(OSystem *syst) : Engine(syst) {
_gameInfo = nullptr;
_windowIsActive = true;
_gameIsRunning = true;
_chapters = nullptr;
_scene = new Scene(this);
_script = new Script(this);
_settings = new Settings(this);
}
bool BladeRunnerEngine::hasFeature(EngineFeature f) const {
return f == kSupportsRTL;
}
Common::Error BladeRunnerEngine::run() {
initGraphics(640, 480, true, &RGB555);
startup();
if (warnUserAboutUnsupportedGame()) {
init2();
/* TODO: Check for save games and enter KIA */
gameLoop();
}
shutdown();
return Common::kNoError;
}
bool BladeRunnerEngine::startup() {
bool r;
_surface1.create(640, 480, RGB555);
r = openArchive("STARTUP.MIX");
if (!r)
return false;
loadSplash();
_gameInfo = new GameInfo(this);
if (!_gameInfo)
return false;
r = _gameInfo->open("GAMEINFO.DAT");
if (!r)
return false;
_chapters = new Chapters(this);
if (!_chapters)
return false;
r = openArchive("MUSIC.MIX");
if (!r)
return false;
r = openArchive("SFX.MIX");
if (!r)
return false;
r = openArchive("SPCHSFX.TLK");
if (!r)
return false;
initChapterAndScene();
return true;
}
void BladeRunnerEngine::initChapterAndScene() {
// TODO: Init actors...
_settings->setChapter(1);
_settings->setNewSetAndScene(_gameInfo->getInitialSetId(), _gameInfo->getInitialSceneId());
}
void BladeRunnerEngine::shutdown() {
if (_chapters) {
if (_chapters->hasOpenResources())
_chapters->closeResources();
delete _chapters;
_chapters = 0;
}
if (isArchiveOpen("MUSIC.MIX"))
closeArchive("MUSIC.MIX");
if (isArchiveOpen("SFX.MIX"))
closeArchive("SFX.MIX");
if (isArchiveOpen("SPCHSFX.TLK"))
closeArchive("SPCHSFX.TLK");
if (isArchiveOpen("STARTUP.MIX"))
closeArchive("STARTUP.MIX");
}
void BladeRunnerEngine::loadSplash() {
Image img(this);
if (!img.open("SPLASH.IMG"))
return;
img.copyToSurface(&_surface1);
_system->copyRectToScreen(_surface1.getPixels(), _surface1.pitch, 0, 0, _surface1.w, _surface1.h);
_system->updateScreen();
}
bool BladeRunnerEngine::init2() {
return true;
}
void BladeRunnerEngine::gameLoop() {
_gameIsRunning = true;
do {
/* TODO: check player death */
gameTick();
} while (_gameIsRunning && !shouldQuit());
}
void BladeRunnerEngine::gameTick() {
handleEvents();
if (_gameIsRunning && _windowIsActive) {
// TODO: Only run if not in Kia, script, nor AI
_settings->openNewScene();
// TODO: Autosave
// TODO: Kia
// TODO: Spinner
// TODO: Esper
// TODO: VK
// TODO: Elevators
// TODO: Scores
// TODO: Call Script_Player_Walked_In if applicable
// TODO: Gun range announcements
// TODO: ZBUF repair dirty rects
// TODO: Tick Ambient Audio (in Replicant)
bool backgroundChanged = false;
int frame = _scene->advanceFrame(_surface1);
if (frame >= 0) {
_script->SceneFrameAdvanced(frame);
backgroundChanged = true;
}
// TODO: Render overlays (mostly in Replicant)
// TODO: Tick Actor AI and Timers (timers in Replicant)
if (_settings->getNewScene() == -1 || _script->_inScriptCounter /* || in_ai */) {
// TODO: Tick and draw all actors in current set (drawing works in Replicant)
// TODO: Draw items (drawing works in Replicant)
// TODO: Draw item pickup (understood, drawing works in Replicant)
// TODO: Draw dialogue menu
// TODO: Draw mouse (understood)
// TODO: Process AUD (audio in Replicant)
// TODO: Footstep sound
_system->copyRectToScreen((const byte *) _surface1.getBasePtr(0, 0), _surface1.pitch, 0, 0, 640, 480);
_system->updateScreen();
_system->delayMillis(10);
}
}
}
void BladeRunnerEngine::handleEvents() {
Common::Event event;
Common::EventManager *eventMan = _system->getEventManager();
while (eventMan->pollEvent(event)) {
}
}
void BladeRunnerEngine::outtakePlay(int id, bool noLocalization, int container) {
Common::String name = _gameInfo->getOuttake(id);
OuttakePlayer player(this);
player.play(name, noLocalization, -1);
}
bool BladeRunnerEngine::openArchive(const Common::String &name) {
uint i;
// If archive is already open, return true
for (i = 0; i != kArchiveCount; ++i) {
if (_archives[i].isOpen() && _archives[i].getName() == name)
return true;
}
// Find first available slot
for (i = 0; i != kArchiveCount; ++i) {
if (!_archives[i].isOpen())
break;
}
if (i == kArchiveCount) {
/* TODO: BLADE.EXE retires the least recently used
* archive when it runs out of slots. */
error("openArchive: No more archive slots");
return false;
}
_archives[i].open(name);
return _archives[i].isOpen();
}
bool BladeRunnerEngine::closeArchive(const Common::String &name) {
for (uint i = 0; i != 10; ++i) {
if (_archives[i].isOpen() &&_archives[i].getName() == name) {
_archives[i].close();
return true;
}
}
debug("closeArchive: Archive %s not open.", name.c_str());
return false;
}
bool BladeRunnerEngine::isArchiveOpen(const Common::String &name) {
for (uint i = 0; i != 10; ++i) {
if (_archives[i].isOpen() &&_archives[i].getName() == name)
return true;
}
return false;
}
Common::SeekableReadStream *BladeRunnerEngine::getResourceStream(const Common::String &name) {
for (uint i = 0; i != 10; ++i) {
if (!_archives[i].isOpen())
continue;
if (false)
debug("getResource: Searching archive %s for %s.", _archives[i].getName().c_str(), name.c_str());
Common::SeekableReadStream *stream = _archives[i].createReadStreamForMember(name);
if (stream)
return stream;
}
debug("getResource: Resource %s not found.", name.c_str());
return 0;
}
void BladeRunnerEngine::ISez(const char *str) {
debug("\t%s", str);
}
} // End of namespace BladeRunner