scummvm/engines/bagel/baglib/bagel.cpp
2024-06-16 23:45:36 +01:00

269 lines
6.9 KiB
C++

/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/engine_data.h"
#include "common/file.h"
#include "engines/engine.h"
#include "bagel/baglib/bagel.h"
#include "bagel/boflib/sound.h"
#include "bagel/dialogs/next_cd_dialog.h"
#include "bagel/dialogs/opt_window.h"
#include "bagel/baglib/paint_table.h"
#include "bagel/baglib/master_win.h"
#include "bagel/boflib/debug.h"
#include "bagel/boflib/file_functions.h"
#include "bagel/boflib/log.h"
namespace Bagel {
// Initialize global variables.
//
CBofWindow *g_hackWindow;
CBagel::CBagel(const BagelReg *gameReg) {
assert(gameReg != nullptr);
registerGame(gameReg);
}
CBagel::~CBagel() {
assert(isValidObject(this));
// Release options file
release();
_szAppName[0] = '\0';
_pMainWnd = nullptr;
_gameReg = nullptr;
}
void CBagel::registerGame(const BagelReg *gameReg) {
assert(isValidObject(this));
_gameReg = gameReg;
// Init statics
g_hackWindow = nullptr;
// Use registration info to init this game object
if (gameReg != nullptr) {
// Keep application name
setAppName(gameReg->_gameName);
// Load this game's .ini file
if (gameReg->_optionFile != nullptr)
loadOptionFile(gameReg->_optionFile);
}
}
ErrorCode CBagel::setOption(const char *section, const char *option, const char *stringValue) {
assert(isValidObject(this));
return writeSetting(section, option, stringValue);
}
ErrorCode CBagel::setOption(const char *section, const char *option, int intValue) {
assert(isValidObject(this));
return writeSetting(section, option, intValue);
}
ErrorCode CBagel::getOption(const char *section, const char *option, char *stringValue, const char *defaultValue, uint32 size) {
assert(isValidObject(this));
return readSetting(section, option, stringValue, defaultValue, size);
}
ErrorCode CBagel::getOption(const char *section, const char *option, int *intValue, int defaultValue) {
assert(isValidObject(this));
return readSetting(section, option, intValue, defaultValue);
}
ErrorCode CBagel::getOption(const char *section, const char *option, bool *boolValue, int defaultValue) {
assert(isValidObject(this));
return readSetting(section, option, boolValue, defaultValue);
}
ErrorCode CBagel::initialize() {
assert(isValidObject(this));
// Game must already be registered with registerGame()
assert(_gameReg != nullptr);
CBofApp::initialize();
// Initialise engine data for the game
Common::U32String errMsg;
if (!Common::load_engine_data("bagel.dat", "", 1, 0, errMsg)) {
GUIErrorMessage("Could not find bagel.dat data file");
const Common::String msg(errMsg);
bofMessageBox("Engine Data", msg.c_str());
_errCode = ERR_FREAD;
return _errCode;
}
Common::File paintTable;
if (!paintTable.open("paint_table.txt")) {
bofMessageBox("Engine Data", "Invalid Paint Table");
_errCode = ERR_FREAD;
return _errCode;
}
PaintTable::initialize(paintTable);
getOption("UserOptions", "WrongCDRetries", &_numRetries, 20);
if (_numRetries < 1) {
_numRetries = 100;
}
logInfo("Initializing BAGEL");
// Turn off System cursor
CBofCursor::hide();
// Initialize local game paths
initLocalFilePaths();
// Child class must instantiate the Main Window
return _errCode;
}
ErrorCode CBagel::runApp() {
assert(isValidObject(this));
// The main game window must have been created by now
assert(_pMainWnd != nullptr);
return CBofApp::runApp();
}
ErrorCode CBagel::shutdown() {
assert(isValidObject(this));
logInfo("Shutting down BAGEL");
// Just in case the child class forgot to delete the main window,
// I'll do it.
delete _pMainWnd;
_pMainWnd = nullptr;
return CBofApp::shutdown();
}
ErrorCode CBagel::initLocalFilePaths() {
assert(isValidObject(this));
// Check for Installed state of game
getOption("Startup", "InstallCode", &_installCode, BAG_INSTALL_DEFAULT);
return _errCode;
}
ErrorCode CBagel::verifyCDInDrive(int diskId, const char *waveFile) {
assert(isValidObject(this));
if (_gameReg->_numberOfCDs > 0) {
char szBuf[MAX_DIRPATH];
// Find the drive that this disk is in
Common::sprintf_s(szBuf, "DISK%d", diskId);
Common::sprintf_s(szBuf, "$SBARDIR%sDISK%d", PATH_DELIMETER, diskId);
CBofString cString(szBuf, MAX_DIRPATH);
fixPathName(cString);
// If the disk is not in drive, then inform the user
int i = 0;
while (!shouldQuit() && !fileExists(cString.getBuffer())) {
// display a dialog box that tells the user to put the CD back into
// the drive, or Abort.
logInfo(buildString("Unable to find game's DiskID as '%s'", cString.getBuffer()));
if (i++ > _numRetries) {
reportError(ERR_FFIND, "Could not recover from missing CD");
break;
}
// Play the Zelda "Alias, you should insert disk 1 at this time."
if (i == 1 && waveFile != nullptr) {
BofPlaySound(waveFile, SOUND_WAVE | SOUND_ASYNCH);
}
if (g_hackWindow == nullptr) {
showNextCDDialog(_pMainWnd, diskId);
} else {
showNextCDDialog(g_hackWindow, diskId);
}
}
}
return _errCode;
}
void fixPathName(CBofString &s) {
// Remove any homedir prefix. In ScummVM, all paths are relative
// to the game folder automatically
char *p = strstr(s.getBuffer(), HOMEDIR_TOKEN);
if (p != nullptr)
s = p + strlen(HOMEDIR_TOKEN) + 1;
// Replace any backslashes with forward slashes
while ((p = strchr(s.getBuffer(), '\\')) != nullptr)
*p = '/';
}
void CBagel::showNextCDDialog(CBofWindow *parentWin, int diskId) {
CBagNextCDDialog cNextCDDialog;
// Use specified bitmap as this dialog's image
CBofPalette *pPal = nullptr;
CBofBitmap *pBmp = nullptr;
switch (diskId) {
case 1:
pBmp = Bagel::loadBitmap(buildSysDir("DISK1.BMP"), pPal);
break;
case 2:
pBmp = Bagel::loadBitmap(buildSysDir("DISK2.BMP"), pPal);
break;
case 3:
pBmp = Bagel::loadBitmap(buildSysDir("DISK3.BMP"), pPal);
break;
// Shouldn't ever get here
default:
assert(false);
break;
}
cNextCDDialog.setBackdrop(pBmp);
const CBofRect cRect = cNextCDDialog.getBackdrop()->getRect();
// Create the dialog box
cNextCDDialog.create("NextCD", cRect.left, cRect.top, cRect.width(), cRect.height(), parentWin);
cNextCDDialog.center();
cNextCDDialog.doModal();
}
} // namespace Bagel