Initial commit
This commit is contained in:
725
engines/plumbers/3do.cpp
Normal file
725
engines/plumbers/3do.cpp
Normal file
@@ -0,0 +1,725 @@
|
||||
/* 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 "plumbers/plumbers.h"
|
||||
#include "plumbers/console.h"
|
||||
|
||||
#include "audio/decoders/aiff.h"
|
||||
#include "audio/decoders/wave.h"
|
||||
#include "audio/audiostream.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/debug-channels.h"
|
||||
#include "common/error.h"
|
||||
#include "common/events.h"
|
||||
#include "common/file.h"
|
||||
#include "common/system.h"
|
||||
#include "common/timer.h"
|
||||
|
||||
#include "engines/util.h"
|
||||
|
||||
#include "graphics/cursorman.h"
|
||||
#include "graphics/font.h"
|
||||
#include "graphics/fontman.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
#include "image/cel_3do.h"
|
||||
|
||||
#include "video/3do_decoder.h"
|
||||
|
||||
namespace Plumbers {
|
||||
// TODO(3do):
|
||||
// * effect when changing between scenes
|
||||
// * 3do boot logo
|
||||
// * return to previous scene
|
||||
// * hide cursor
|
||||
|
||||
namespace {
|
||||
// TODO: discover correct offsets
|
||||
Common::Point getMikeStart(uint num, uint total) {
|
||||
if (total == 2)
|
||||
return Common::Point(140 * num + 10, 120 * num + 10);
|
||||
return Common::Point(60 * num + 20, 70 * num + 20);
|
||||
}
|
||||
|
||||
// TODO: discover correct offsets
|
||||
Common::Point getMikeSize(uint total) {
|
||||
if (total == 2)
|
||||
return Common::Point(80, 100);
|
||||
return Common::Point(80, 60);
|
||||
}
|
||||
|
||||
void makeMikeDecision(Scene &scene, uint num) {
|
||||
scene._bitmapNum = 0;
|
||||
scene._startBitmap = 0;
|
||||
scene._decisionChoices = num;
|
||||
scene._waveFilename = "";
|
||||
scene._style = Scene::STYLE_DECISION_MIKE;
|
||||
|
||||
Common::Point sz = getMikeSize(num);
|
||||
|
||||
for (uint i = 0; i < num; i++) {
|
||||
Common::Point ms = getMikeStart(i, num);
|
||||
scene._choices[i]._region = Common::Rect(ms.x, ms.y, ms.x + 2 * sz.x, ms.y + sz.y);
|
||||
}
|
||||
}
|
||||
|
||||
void makeVideo(Scene &scene, const Common::String &videoName, const Common::String &nextScene) {
|
||||
scene._bitmapNum = 0;
|
||||
scene._startBitmap = 0;
|
||||
scene._decisionChoices = 1;
|
||||
scene._waveFilename = "";
|
||||
scene._style = Scene::STYLE_VIDEO;
|
||||
scene._sceneName = videoName;
|
||||
scene._decisionBitmap = "";
|
||||
scene._choices[0]._sceneName = nextScene;
|
||||
}
|
||||
|
||||
const struct {
|
||||
const char *from;
|
||||
struct {
|
||||
const char *scene;
|
||||
int points;
|
||||
} to[kMaxChoice];
|
||||
} tungraph[] = {
|
||||
{
|
||||
"dec13",
|
||||
{
|
||||
{"sc15", -10000},
|
||||
{"sc17", -10000},
|
||||
{"sc20", -50000}
|
||||
}
|
||||
},
|
||||
{
|
||||
"dec16",
|
||||
{
|
||||
{"dec13", -20000},
|
||||
{"restart", 0}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
"dec18",
|
||||
{
|
||||
{"dec13", -30000},
|
||||
{"restart", 0}
|
||||
}
|
||||
},
|
||||
{
|
||||
"dec20",
|
||||
{
|
||||
{"sc21", -90000},
|
||||
{"sc22", -90000}
|
||||
}
|
||||
},
|
||||
{
|
||||
"dec22",
|
||||
{
|
||||
{"dec20", -90000},
|
||||
{"restart", 0}
|
||||
}
|
||||
},
|
||||
{
|
||||
"dec23",
|
||||
{
|
||||
{"sc24", 50000},
|
||||
{"sc28", -50000}
|
||||
}
|
||||
},
|
||||
{
|
||||
"dec25",
|
||||
{
|
||||
{"sc26", -75000},
|
||||
{"sc27", -90000}
|
||||
}
|
||||
},
|
||||
{
|
||||
"dec26",
|
||||
{
|
||||
{"dec25", -75000},
|
||||
{"restart", 0}
|
||||
}
|
||||
},
|
||||
{
|
||||
"dec28",
|
||||
{
|
||||
{"dec23", -75000},
|
||||
{"restart", 0}
|
||||
}
|
||||
},
|
||||
{
|
||||
"dec29",
|
||||
{
|
||||
{"sc30", -20000},
|
||||
{"sc31", 90000}
|
||||
}
|
||||
},
|
||||
{
|
||||
"dec30",
|
||||
{
|
||||
{"sc32", 0},
|
||||
{"restart", 0},
|
||||
{"end", 0}
|
||||
}
|
||||
},
|
||||
{
|
||||
"dec31",
|
||||
{
|
||||
{"dec29", -20000},
|
||||
{"end", 0}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
static const Common::KeyCode cheatKbd[] = {
|
||||
Common::KEYCODE_UP,
|
||||
Common::KEYCODE_DOWN,
|
||||
Common::KEYCODE_RIGHT,
|
||||
Common::KEYCODE_LEFT,
|
||||
Common::KEYCODE_DOWN,
|
||||
Common::KEYCODE_RIGHT,
|
||||
Common::KEYCODE_RETURN
|
||||
};
|
||||
|
||||
static const Common::JoystickButton cheatJoy[] = {
|
||||
Common::JOYSTICK_BUTTON_DPAD_UP,
|
||||
Common::JOYSTICK_BUTTON_DPAD_DOWN,
|
||||
Common::JOYSTICK_BUTTON_DPAD_RIGHT,
|
||||
Common::JOYSTICK_BUTTON_DPAD_LEFT,
|
||||
Common::JOYSTICK_BUTTON_DPAD_DOWN,
|
||||
Common::JOYSTICK_BUTTON_DPAD_RIGHT,
|
||||
Common::JOYSTICK_BUTTON_X
|
||||
};
|
||||
} // end of anonymous namespace
|
||||
|
||||
PlumbersGame3DO::PlumbersGame3DO(OSystem *syst, const ADGameDescription *gameDesc) :
|
||||
PlumbersGame(syst, gameDesc), _ctrlHelpImage(nullptr), _cheatEnabled(false), _cheatFSM(0), _leftShoulderPressed(false),
|
||||
_hiLite(-1), _mouseHiLite(-1), _kbdHiLite(-1) {
|
||||
}
|
||||
|
||||
void PlumbersGame3DO::readTables() {
|
||||
Common::File file;
|
||||
if (!file.open("launchme"))
|
||||
error("sReadTables(): Error reading launchme file");
|
||||
|
||||
initTables();
|
||||
|
||||
file.seek(0x1ec08);
|
||||
|
||||
Common::HashMap<Common::String, int> imgCounter, firstImg;
|
||||
|
||||
uint bitmapCtr = 0;
|
||||
|
||||
for (; bitmapCtr < 287; bitmapCtr++) {
|
||||
char buf[16];
|
||||
file.read(buf, 16);
|
||||
_bitmaps[bitmapCtr]._filename = Common::String(buf);
|
||||
_bitmaps[bitmapCtr]._duration = (file.readSint32BE() * 1000) / 60;
|
||||
Common::String scene = Common::String(buf).substr(0, 4);
|
||||
scene.toLowercase();
|
||||
imgCounter[scene]++;
|
||||
if (!firstImg.contains(scene))
|
||||
firstImg[scene] = bitmapCtr;
|
||||
}
|
||||
|
||||
file.seek(0x205d0);
|
||||
|
||||
for (; bitmapCtr < 704; bitmapCtr++) {
|
||||
char buf[16];
|
||||
file.read(buf, 16);
|
||||
_bitmaps[bitmapCtr]._filename = Common::String(buf);
|
||||
_bitmaps[bitmapCtr]._duration = (file.readSint32BE() * 1000) / 60;
|
||||
Common::String scene = Common::String(buf).substr(0, 4);
|
||||
scene.toLowercase();
|
||||
imgCounter[scene]++;
|
||||
if (!firstImg.contains(scene))
|
||||
firstImg[scene] = bitmapCtr;
|
||||
}
|
||||
|
||||
uint scPtr = 0;
|
||||
makeVideo(_scenes[scPtr++], "kirinweaver", "janp1weaver");
|
||||
makeVideo(_scenes[scPtr++], "janp1weaver", "janp2weaver");
|
||||
makeVideo(_scenes[scPtr++], "janp2weaver", "janp3weaver");
|
||||
makeVideo(_scenes[scPtr++], "janp3weaver", "titleweaver");
|
||||
makeVideo(_scenes[scPtr++], "titleweaver", "miketest/sc00");
|
||||
|
||||
makeMikeDecision(_scenes[scPtr], 2);
|
||||
_scenes[scPtr]._sceneName = "miketest/sc00";
|
||||
_scenes[scPtr]._decisionBitmap = "DEC00";
|
||||
_scenes[scPtr]._choices[0]._sceneName = "miketest/sc01";
|
||||
_scenes[scPtr++]._choices[1]._sceneName = "miketest/sc07a";
|
||||
|
||||
for (uint scNo = 1; scNo <= 13; scNo++, scPtr++) {
|
||||
Common::String imgScene = scNo == 5 ?
|
||||
"sc44" : Common::String::format("sc%02d", scNo);
|
||||
_scenes[scPtr]._bitmapNum = imgCounter[imgScene];
|
||||
_scenes[scPtr]._startBitmap = firstImg[imgScene];
|
||||
_scenes[scPtr]._sceneName = scNo == 5 ? "miketest/sc04a" : Common::String::format("miketest/sc%02d", scNo);
|
||||
_scenes[scPtr]._waveFilename = Common::String::format("DIA%02d.aiff", scNo == 5 ? 4 : scNo);
|
||||
_scenes[scPtr]._style = Scene::STYLE_PC;
|
||||
_scenes[scPtr]._decisionChoices = 1;
|
||||
switch(scNo) {
|
||||
case 4:
|
||||
case 5:
|
||||
_scenes[scPtr]._choices[0]._sceneName = "miketest/sc06";
|
||||
break;
|
||||
case 11:
|
||||
_scenes[scPtr]._choices[0]._sceneName = "miketest/sc13";
|
||||
break;
|
||||
case 13:
|
||||
_scenes[scPtr]._choices[0]._sceneName = "tuntest/dec/dec13";
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
case 12:
|
||||
_scenes[scPtr]._choices[0]._sceneName = Common::String::format("miketest/sc%02da", scNo);
|
||||
break;
|
||||
default:
|
||||
_scenes[scPtr]._choices[0]._sceneName = Common::String::format("miketest/sc%02d", scNo + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
makeMikeDecision(_scenes[scPtr], 3);
|
||||
_scenes[scPtr]._sceneName = "miketest/sc07a";
|
||||
_scenes[scPtr]._decisionBitmap = "DEC07";
|
||||
_scenes[scPtr]._choices[0]._sceneName = "miketest/sc08";
|
||||
_scenes[scPtr]._choices[0]._points = -10000;
|
||||
_scenes[scPtr]._choices[1]._sceneName = "miketest/sc11";
|
||||
_scenes[scPtr]._choices[1]._points = 10000;
|
||||
_scenes[scPtr]._choices[2]._sceneName = "miketest/sc12";
|
||||
_scenes[scPtr]._choices[2]._points = -20000;
|
||||
scPtr++;
|
||||
|
||||
makeMikeDecision(_scenes[scPtr], 2);
|
||||
_scenes[scPtr]._sceneName = "miketest/sc08a";
|
||||
_scenes[scPtr]._decisionBitmap = "DEC08";
|
||||
_scenes[scPtr]._choices[0]._sceneName = "miketest/sc09";
|
||||
_scenes[scPtr]._choices[0]._points = 0;
|
||||
_scenes[scPtr]._choices[1]._sceneName = "miketest/sc09";
|
||||
_scenes[scPtr]._choices[1]._points = 10000;
|
||||
scPtr++;
|
||||
|
||||
makeMikeDecision(_scenes[scPtr], 2);
|
||||
_scenes[scPtr]._sceneName = "miketest/sc12a";
|
||||
_scenes[scPtr]._decisionBitmap = "DEC12";
|
||||
_scenes[scPtr]._choices[0]._sceneName = "miketest/sc07a";
|
||||
_scenes[scPtr]._choices[0]._points = 0;
|
||||
_scenes[scPtr]._choices[1]._sceneName = "restart";
|
||||
_scenes[scPtr]._choices[1]._points = 0;
|
||||
scPtr++;
|
||||
|
||||
for (uint scNo = 15; scNo <= 32; scNo++) {
|
||||
// there is no sc19
|
||||
if (scNo == 19)
|
||||
continue;
|
||||
Common::String imgScene = Common::String::format("sc%02d", scNo);
|
||||
_scenes[scPtr]._bitmapNum = imgCounter[imgScene];
|
||||
_scenes[scPtr]._startBitmap = firstImg[imgScene];
|
||||
_scenes[scPtr]._sceneName = Common::String::format("tuntest/sc%02d", scNo);
|
||||
_scenes[scPtr]._waveFilename = Common::String::format("sc%02d.aiff", scNo);
|
||||
_scenes[scPtr]._style = Scene::STYLE_PC;
|
||||
_scenes[scPtr]._decisionChoices = 1;
|
||||
if (scNo == 32)
|
||||
_scenes[scPtr]._choices[0]._sceneName = "end";
|
||||
else if (scNo == 16 || scNo == 18 || scNo == 20 || scNo == 22 || scNo == 23 || scNo == 25
|
||||
|| scNo == 26 || scNo == 28 || scNo == 29 || scNo == 30 || scNo == 31)
|
||||
_scenes[scPtr]._choices[0]._sceneName = Common::String::format("tuntest/dec/dec%02d", scNo);
|
||||
else
|
||||
_scenes[scPtr]._choices[0]._sceneName = Common::String::format("tuntest/sc%02d", scNo + 1);
|
||||
scPtr++;
|
||||
}
|
||||
|
||||
file.seek(0x20290);
|
||||
|
||||
for (int i = 0; i < 26; i++) {
|
||||
char buf[16];
|
||||
file.read(buf, 16);
|
||||
uint32 x = file.readUint32BE();
|
||||
uint32 y = file.readUint32BE();
|
||||
uint32 w = file.readUint32BE();
|
||||
uint32 h = file.readUint32BE();
|
||||
Common::String shortName = Common::String(buf, 5);
|
||||
Common::String sceneName = "tuntest/dec/" + shortName;
|
||||
if (i == 0 || _scenes[scPtr - 1]._sceneName != sceneName) {
|
||||
_scenes[scPtr]._bitmapNum = 0;
|
||||
_scenes[scPtr]._startBitmap = 0;
|
||||
_scenes[scPtr]._decisionChoices = 0;
|
||||
_scenes[scPtr]._waveFilename = "";
|
||||
_scenes[scPtr]._style = Scene::STYLE_DECISION_TUN;
|
||||
_scenes[scPtr]._sceneName = sceneName;
|
||||
_scenes[scPtr]._decisionBitmap = shortName;
|
||||
scPtr++;
|
||||
}
|
||||
|
||||
Scene &scene = _scenes[scPtr - 1];
|
||||
assert(scene._decisionChoices < kMaxChoice);
|
||||
scene._choices[scene._decisionChoices]._region = Common::Rect(x, y, x + w, y + h);
|
||||
for (uint j = 0 ; j < ARRAYSIZE(tungraph); j++) {
|
||||
if (shortName == tungraph[j].from) {
|
||||
Common::String target = tungraph[j].to[scene._decisionChoices].scene;
|
||||
if (target[0] == 's')
|
||||
scene._choices[scene._decisionChoices]._sceneName = "tuntest/" + target;
|
||||
else
|
||||
scene._choices[scene._decisionChoices]._sceneName = "tuntest/dec/" + target;
|
||||
scene._choices[scene._decisionChoices]._points = tungraph[j].to[scene._decisionChoices].points;
|
||||
break;
|
||||
}
|
||||
}
|
||||
scene._decisionChoices++;
|
||||
}
|
||||
|
||||
_totScene = scPtr;
|
||||
}
|
||||
|
||||
void PlumbersGame3DO::loadMikeDecision(const Common::String &dirname, const Common::String &baseFilename, uint num) {
|
||||
Common::String baseName = dirname + "/" + baseFilename;
|
||||
debugC(1, kDebugGeneral, "%s : %s", __FUNCTION__, baseName.c_str());
|
||||
Graphics::Surface *surf = new Graphics::Surface();
|
||||
surf->create(_screenW, _screenH, _targetFormat);
|
||||
|
||||
delete _compositeSurface;
|
||||
_compositeSurface = nullptr;
|
||||
|
||||
for (uint i = 0; i < num; i++) {
|
||||
Common::Point p = getMikeStart(i, num);
|
||||
Common::Point sz = getMikeSize(num);
|
||||
Common::File fileP;
|
||||
Common::Path nameP(Common::String::format("%s%dP.CEL", baseName.c_str(), i + 1));
|
||||
if (!fileP.open(nameP))
|
||||
error("unable to load image %s", nameP.toString().c_str());
|
||||
|
||||
_image->loadStream(fileP);
|
||||
Graphics::Surface *conv = _image->getSurface()->convertTo(_targetFormat);
|
||||
surf->copyRectToSurface(*conv, p.x, p.y,
|
||||
Common::Rect(0, 0, sz.x, sz.y));
|
||||
|
||||
conv->free();
|
||||
delete conv;
|
||||
|
||||
Common::File fileW;
|
||||
Common::Path nameW(Common::String::format("%s%dW.CEL", baseName.c_str(), i + 1));
|
||||
if (!fileW.open(nameW))
|
||||
error("unable to load image %s", nameW.toString().c_str());
|
||||
|
||||
_image->loadStream(fileW);
|
||||
conv = _image->getSurface()->convertTo(_targetFormat);
|
||||
surf->copyRectToSurface(*conv, p.x + sz.x, p.y,
|
||||
Common::Rect(0, 0, sz.x, sz.y));
|
||||
|
||||
conv->free();
|
||||
delete conv;
|
||||
|
||||
}
|
||||
|
||||
_compositeSurface = surf;
|
||||
|
||||
Common::File fileCtrl;
|
||||
if (fileCtrl.open(Common::Path(dirname + "/CONTROLHELP.CEL")))
|
||||
_ctrlHelpImage->loadStream(fileCtrl);
|
||||
}
|
||||
|
||||
void PlumbersGame3DO::postSceneBitmaps() {
|
||||
if (_scenes[_curSceneIdx]._style == Scene::STYLE_VIDEO) {
|
||||
_videoDecoder = new Video::ThreeDOMovieDecoder();
|
||||
_videoDecoder->setOutputPixelFormat(_targetFormat);
|
||||
_curChoice = 0;
|
||||
if (!_videoDecoder->loadFile(Common::Path(_scenes[_curSceneIdx]._sceneName))) {
|
||||
_actions.push(ChangeScene);
|
||||
return;
|
||||
}
|
||||
_videoDecoder->start();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_scenes[_curSceneIdx]._decisionChoices == 1) {
|
||||
_curChoice = 0;
|
||||
_actions.push(ChangeScene);
|
||||
return;
|
||||
}
|
||||
|
||||
_showScoreFl = true;
|
||||
_leftButtonDownFl = true;
|
||||
_setDurationFl = false;
|
||||
if (_scenes[_curSceneIdx]._style == Scene::STYLE_DECISION_MIKE) {
|
||||
loadMikeDecision(_scenes[_curSceneIdx]._sceneName, _scenes[_curSceneIdx]._decisionBitmap,
|
||||
_scenes[_curSceneIdx]._decisionChoices);
|
||||
_hiLite = 0;
|
||||
_kbdHiLite = 0;
|
||||
updateHiLite();
|
||||
} else if (_scenes[_curSceneIdx]._style == Scene::STYLE_DECISION_TUN) {
|
||||
loadImage(_scenes[_curSceneIdx]._sceneName + ".cel");
|
||||
_hiLite = 0;
|
||||
_kbdHiLite = 0;
|
||||
updateHiLite();
|
||||
Common::File fileCtrl;
|
||||
if (fileCtrl.open("tuntest/dec/controlhelp.cel"))
|
||||
_ctrlHelpImage->loadStream(fileCtrl);
|
||||
} else {
|
||||
loadImage(_scenes[_curSceneIdx]._sceneName + "/" + _scenes[_curSceneIdx]._decisionBitmap);
|
||||
_hiLite = -1;
|
||||
_kbdHiLite = -1;
|
||||
}
|
||||
|
||||
_mouseHiLite = getMouseHiLite();
|
||||
}
|
||||
|
||||
void PlumbersGame3DO::startGraphics() {
|
||||
_image = new Image::Cel3DODecoder();
|
||||
_ctrlHelpImage = new Image::Cel3DODecoder();
|
||||
_screenW = 320;
|
||||
_screenH = 240;
|
||||
_targetFormat = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
|
||||
|
||||
initGraphics(_screenW, _screenH, &_targetFormat);
|
||||
}
|
||||
|
||||
void PlumbersGame3DO::blitImage() {
|
||||
const Graphics::Surface *surface;
|
||||
bool ctrlHelp = false;
|
||||
bool needConv = false;
|
||||
|
||||
if (_leftShoulderPressed && _leftButtonDownFl && _ctrlHelpImage) {
|
||||
surface = _ctrlHelpImage->getSurface();
|
||||
ctrlHelp = true;
|
||||
needConv = true;
|
||||
} else if (_videoDecoder)
|
||||
surface = _videoDecoder->decodeNextFrame();
|
||||
else if (_compositeSurface)
|
||||
surface = _compositeSurface;
|
||||
else {
|
||||
surface = _image->getSurface();
|
||||
needConv = true;
|
||||
}
|
||||
|
||||
Graphics::Surface modSurf;
|
||||
bool modded = false;
|
||||
Graphics::Surface *conv = nullptr;
|
||||
|
||||
if (_hiLite >= 0 && _leftButtonDownFl && !ctrlHelp) {
|
||||
modSurf.create(surface->w, surface->h, _targetFormat);
|
||||
modSurf.copyRectToSurface(*surface, 0, 0, Common::Rect(0, 0, surface->w, surface->h));
|
||||
const Common::Rect rec = _scenes[_curSceneIdx]._choices[_hiLite]._region;
|
||||
|
||||
for (int y = rec.top; y <= rec.bottom; y++) {
|
||||
uint16 *p = (uint16 *) modSurf.getPixels() + modSurf.w * y + rec.left;
|
||||
for (int x = rec.left; x < rec.right; x++, p++) {
|
||||
uint r, g, b;
|
||||
r = (*p >> 10) & 0x1f;
|
||||
g = (*p >> 5) & 0x1f;
|
||||
b = (*p >> 0) & 0x1f;
|
||||
|
||||
// TODO: figure out the correct multipliers
|
||||
*p = _targetFormat.RGBToColor(3 * r / 2, 3 * g / 2, 3 * b / 2);
|
||||
}
|
||||
}
|
||||
modded = true;
|
||||
}
|
||||
|
||||
if (needConv) {
|
||||
conv = surface->convertTo(_targetFormat);
|
||||
surface = conv;
|
||||
}
|
||||
|
||||
blitImageSurface(modded ? &modSurf : surface);
|
||||
|
||||
if (needConv) {
|
||||
conv->free();
|
||||
delete conv;
|
||||
}
|
||||
}
|
||||
|
||||
void PlumbersGame3DO::skipVideo() {
|
||||
if (_scenes[_curSceneIdx]._sceneName == "janp1weaver"
|
||||
|| _scenes[_curSceneIdx]._sceneName == "janp2weaver") {
|
||||
// Skip janp2weaver and janp3weaver
|
||||
_curSceneIdx = getSceneNumb("titleweaver");
|
||||
_actions.push(ShowScene);
|
||||
} else {
|
||||
_actions.push(ChangeScene);
|
||||
}
|
||||
_videoDecoder->close();
|
||||
delete _videoDecoder;
|
||||
_videoDecoder = nullptr;
|
||||
}
|
||||
|
||||
void PlumbersGame3DO::joyUp() {
|
||||
int decNum = _scenes[_curSceneIdx]._decisionChoices;
|
||||
if (!_leftButtonDownFl)
|
||||
return;
|
||||
_kbdHiLite = _kbdHiLite < 0 ? 0 : (_kbdHiLite + decNum - 1) % decNum;
|
||||
_hiLite = _kbdHiLite;
|
||||
updateHiLite();
|
||||
}
|
||||
|
||||
void PlumbersGame3DO::joyDown() {
|
||||
if (!_leftButtonDownFl)
|
||||
return;
|
||||
int decNum = _scenes[_curSceneIdx]._decisionChoices;
|
||||
_kbdHiLite = _kbdHiLite < 0 ? 0 : (_kbdHiLite + 1) % decNum;
|
||||
_hiLite = _kbdHiLite;
|
||||
updateHiLite();
|
||||
}
|
||||
|
||||
void PlumbersGame3DO::joyA() {
|
||||
if (_kbdHiLite < 0 || !_leftButtonDownFl)
|
||||
return;
|
||||
debugC(5, kDebugGeneral, "Accepting enter press with choice = %d", _kbdHiLite);
|
||||
_curChoice = _kbdHiLite;
|
||||
_totScore += _scenes[_curSceneIdx]._choices[_kbdHiLite]._points;
|
||||
_actions.push(ChangeScene);
|
||||
_leftButtonDownFl = false;
|
||||
}
|
||||
|
||||
void PlumbersGame3DO::handleEvent(const Common::Event &event) {
|
||||
switch (event.type) {
|
||||
case Common::EVENT_JOYBUTTON_DOWN:
|
||||
if (_videoDecoder) {
|
||||
if (_cheatFSM < ARRAYSIZE(cheatJoy) && event.joystick.button == cheatJoy[_cheatFSM]) {
|
||||
_cheatFSM++;
|
||||
if (_cheatFSM == ARRAYSIZE(cheatJoy)) {
|
||||
debugC(1, kDebugGeneral, "Cheat enabled");
|
||||
_cheatEnabled = true;
|
||||
}
|
||||
} else if (event.joystick.button == cheatJoy[0])
|
||||
_cheatFSM = 1;
|
||||
else
|
||||
_cheatFSM = 0;
|
||||
}
|
||||
if (_videoDecoder && (event.joystick.button == Common::JOYSTICK_BUTTON_A ||
|
||||
event.joystick.button == Common::JOYSTICK_BUTTON_B ||
|
||||
event.joystick.button == Common::JOYSTICK_BUTTON_X)) {
|
||||
skipVideo();
|
||||
return;
|
||||
}
|
||||
if (event.joystick.button == Common::JOYSTICK_BUTTON_DPAD_UP ||
|
||||
event.joystick.button == Common::JOYSTICK_BUTTON_DPAD_LEFT) {
|
||||
joyUp();
|
||||
return;
|
||||
}
|
||||
if (event.joystick.button == Common::JOYSTICK_BUTTON_DPAD_DOWN ||
|
||||
event.joystick.button == Common::JOYSTICK_BUTTON_DPAD_RIGHT) {
|
||||
joyDown();
|
||||
return;
|
||||
}
|
||||
if (event.joystick.button == Common::JOYSTICK_BUTTON_A) {
|
||||
joyA();
|
||||
return;
|
||||
}
|
||||
if (event.joystick.button == Common::JOYSTICK_BUTTON_LEFT_SHOULDER) {
|
||||
_leftShoulderPressed = true;
|
||||
if (_leftButtonDownFl && _ctrlHelpImage)
|
||||
_actions.push(Redraw);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case Common::EVENT_JOYBUTTON_UP:
|
||||
if (event.joystick.button == Common::JOYSTICK_BUTTON_LEFT_SHOULDER) {
|
||||
_leftShoulderPressed = false;
|
||||
if (_leftButtonDownFl && _ctrlHelpImage)
|
||||
_actions.push(Redraw);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case Common::EVENT_KEYDOWN:
|
||||
if (_videoDecoder) {
|
||||
if (_cheatFSM < ARRAYSIZE(cheatKbd) && event.kbd.keycode == cheatKbd[_cheatFSM]) {
|
||||
_cheatFSM++;
|
||||
if (_cheatFSM == ARRAYSIZE(cheatKbd)) {
|
||||
debugC(1, kDebugGeneral, "Cheat enabled");
|
||||
_cheatEnabled = true;
|
||||
}
|
||||
} else if (event.kbd.keycode == cheatKbd[0])
|
||||
_cheatFSM = 1;
|
||||
else
|
||||
_cheatFSM = 0;
|
||||
}
|
||||
if (event.kbd.keycode == Common::KEYCODE_SPACE && _videoDecoder) {
|
||||
skipVideo();
|
||||
return;
|
||||
}
|
||||
if ((event.kbd.keycode == Common::KEYCODE_UP ||
|
||||
event.kbd.keycode == Common::KEYCODE_LEFT)) {
|
||||
joyUp();
|
||||
return;
|
||||
}
|
||||
if ((event.kbd.keycode == Common::KEYCODE_DOWN ||
|
||||
event.kbd.keycode == Common::KEYCODE_RIGHT)) {
|
||||
joyDown();
|
||||
return;
|
||||
}
|
||||
if (event.kbd.keycode == Common::KEYCODE_RETURN) {
|
||||
joyA();
|
||||
return;
|
||||
}
|
||||
if (event.kbd.keycode == Common::KEYCODE_q) {
|
||||
_leftShoulderPressed = true;
|
||||
if (_leftButtonDownFl && _ctrlHelpImage)
|
||||
_actions.push(Redraw);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case Common::EVENT_KEYUP:
|
||||
if (event.kbd.keycode == Common::KEYCODE_q) {
|
||||
_leftShoulderPressed = false;
|
||||
if (_leftButtonDownFl && _ctrlHelpImage)
|
||||
_actions.push(Redraw);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
PlumbersGame::handleEvent(event);
|
||||
}
|
||||
|
||||
int PlumbersGame3DO::getSceneNumb(const Common::String &sName) {
|
||||
debugC(1, kDebugGeneral, "%s : %s", __FUNCTION__, sName.c_str());
|
||||
if (sName == "miketest/sc04" && _cheatEnabled)
|
||||
return PlumbersGame::getSceneNumb("miketest/sc04a");
|
||||
|
||||
return PlumbersGame::getSceneNumb(sName);
|
||||
}
|
||||
|
||||
void PlumbersGame3DO::updateHiLite() {
|
||||
_actions.push(Redraw);
|
||||
if (_hiLite < 0)
|
||||
return;
|
||||
if (_scenes[_curSceneIdx]._style == Scene::STYLE_DECISION_MIKE) {
|
||||
playSound(Common::String::format("%s/%s%dS.Aiff",
|
||||
_scenes[_curSceneIdx]._sceneName.c_str(),
|
||||
_scenes[_curSceneIdx]._decisionBitmap.c_str(), _hiLite + 1));
|
||||
} else if (_scenes[_curSceneIdx]._style == Scene::STYLE_DECISION_TUN) {
|
||||
playSound(Common::String::format("%s%c.aiff", _scenes[_curSceneIdx]._sceneName.c_str(), _hiLite + 'a'));
|
||||
}
|
||||
}
|
||||
|
||||
void PlumbersGame3DO::preActions() {
|
||||
if (_leftButtonDownFl) {
|
||||
int nh = getMouseHiLite();
|
||||
if (nh != _mouseHiLite) {
|
||||
_mouseHiLite = nh;
|
||||
_hiLite = _mouseHiLite;
|
||||
updateHiLite();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
engines/plumbers/POTFILES
Normal file
1
engines/plumbers/POTFILES
Normal file
@@ -0,0 +1 @@
|
||||
engines/plumbers/metaengine.cpp
|
||||
3
engines/plumbers/configure.engine
Normal file
3
engines/plumbers/configure.engine
Normal file
@@ -0,0 +1,3 @@
|
||||
# This file is included from the main "configure" script
|
||||
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] [components]
|
||||
add_engine plumbers "Plumbers Don't Wear Ties" yes
|
||||
43
engines/plumbers/console.cpp
Normal file
43
engines/plumbers/console.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/* 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 "plumbers/console.h"
|
||||
|
||||
namespace Plumbers {
|
||||
|
||||
Console::Console() {
|
||||
_allowSkip = false;
|
||||
registerCmd("allowSkip", WRAP_METHOD(Console, Cmd_allowSkip));
|
||||
}
|
||||
|
||||
bool Console::Cmd_allowSkip(int argc, const char** argv) {
|
||||
if (argc != 1) {
|
||||
debugPrintf("Usage: %s\n", argv[0]);
|
||||
debugPrintf("Enables/Disables the possibility to skip screen delays\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
_allowSkip ^= true;
|
||||
debugPrintf("Skipping delay is now %s\n", _allowSkip ? "Enabled" : "Disabled");
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Plumbers
|
||||
40
engines/plumbers/console.h
Normal file
40
engines/plumbers/console.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLUMBERS_CONSOLE_H
|
||||
#define PLUMBERS_CONSOLE_H
|
||||
|
||||
#include "gui/debugger.h"
|
||||
|
||||
namespace Plumbers {
|
||||
|
||||
class Console : public GUI::Debugger {
|
||||
public:
|
||||
bool _allowSkip;
|
||||
|
||||
explicit Console();
|
||||
~Console(void) override {}
|
||||
|
||||
bool Cmd_allowSkip(int argc, const char** argv);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
3
engines/plumbers/credits.pl
Normal file
3
engines/plumbers/credits.pl
Normal file
@@ -0,0 +1,3 @@
|
||||
begin_section("Plumbers");
|
||||
add_person("Retro-Junk;", "bambarbee", "");
|
||||
end_section();
|
||||
91
engines/plumbers/detection.cpp
Normal file
91
engines/plumbers/detection.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/* 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 "base/plugins.h"
|
||||
|
||||
#include "engines/advancedDetector.h"
|
||||
#include "engines/game.h"
|
||||
|
||||
#include "plumbers/plumbers.h"
|
||||
|
||||
static const PlainGameDescriptor plumbersGames[] = {
|
||||
{"plumbers", "Plumbers Don't Wear Ties!"},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
static const DebugChannelDef debugFlagList[] = {
|
||||
{Plumbers::kDebugGeneral, "general", "General debug level"},
|
||||
DEBUG_CHANNEL_END
|
||||
};
|
||||
|
||||
namespace Plumbers {
|
||||
|
||||
static const ADGameDescription gameDescriptions[] = {
|
||||
// Plumbers PC version
|
||||
{
|
||||
"plumbers",
|
||||
nullptr,
|
||||
AD_ENTRY1s("GAME.BIN", "02c965b11e952ce1ee83019576f5aef5", 41622),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_NO_FLAGS,
|
||||
GUIO1(GUIO_NOMIDI)
|
||||
},
|
||||
|
||||
// Plumbers 3DO version
|
||||
{
|
||||
"plumbers",
|
||||
nullptr,
|
||||
AD_ENTRY1s("launchme", "d3ab77d1a8a2289422a0f51e7aa91821", 143300),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatform3DO,
|
||||
ADGF_NO_FLAGS,
|
||||
GUIO1(GUIO_NOMIDI)
|
||||
},
|
||||
|
||||
AD_TABLE_END_MARKER
|
||||
};
|
||||
|
||||
} // End of namespace Plumbers
|
||||
|
||||
class PlumbersMetaEngineDetection : public AdvancedMetaEngineDetection<ADGameDescription> {
|
||||
public:
|
||||
PlumbersMetaEngineDetection() : AdvancedMetaEngineDetection(Plumbers::gameDescriptions, plumbersGames) {
|
||||
}
|
||||
|
||||
const char *getName() const override {
|
||||
return "plumbers";
|
||||
}
|
||||
|
||||
const char *getEngineName() const override {
|
||||
return "Plumbers Don't Wear Ties";
|
||||
}
|
||||
|
||||
const char *getOriginalCopyright() const override {
|
||||
return "Plumbers Don't Wear Ties (C) 1993-94 Kirin Entertainment";
|
||||
}
|
||||
|
||||
const DebugChannelDef *getDebugChannels() const override {
|
||||
return debugFlagList;
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_PLUGIN_STATIC(PLUMBERS_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, PlumbersMetaEngineDetection);
|
||||
68
engines/plumbers/metaengine.cpp
Normal file
68
engines/plumbers/metaengine.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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 "base/plugins.h"
|
||||
|
||||
#include "common/translation.h"
|
||||
|
||||
#include "engines/advancedDetector.h"
|
||||
#include "gui/message.h"
|
||||
|
||||
#include "plumbers/plumbers.h"
|
||||
|
||||
namespace Plumbers {
|
||||
const char *PlumbersGame::getGameId() const { return _gameDescription->gameId; }
|
||||
Common::Platform PlumbersGame::getPlatform() const { return _gameDescription->platform; }
|
||||
} // End of namespace Plumbers
|
||||
|
||||
class PlumbersMetaEngine : public AdvancedMetaEngine<ADGameDescription> {
|
||||
const char *getName() const override {
|
||||
return "plumbers";
|
||||
}
|
||||
|
||||
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
|
||||
bool hasFeature(MetaEngineFeature f) const override;
|
||||
};
|
||||
|
||||
Common::Error PlumbersMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
|
||||
if (desc->platform == Common::kPlatform3DO) {
|
||||
#ifdef USE_RGB_COLOR
|
||||
*engine = new Plumbers::PlumbersGame3DO(syst, desc);
|
||||
#else
|
||||
// I18N: Plumbers is the title of the game. 3DO is the name of platform
|
||||
GUI::MessageDialog dialog(_("3DO Plumbers requires RGB support."));
|
||||
dialog.runModal();
|
||||
return Common::kUnsupportedColorMode;
|
||||
#endif
|
||||
} else
|
||||
*engine = new Plumbers::PlumbersGameWindows(syst, desc);
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
bool PlumbersMetaEngine::hasFeature(MetaEngineFeature f) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if PLUGIN_ENABLED_DYNAMIC(PLUMBERS)
|
||||
REGISTER_PLUGIN_DYNAMIC(PLUMBERS, PLUGIN_TYPE_ENGINE, PlumbersMetaEngine);
|
||||
#else
|
||||
REGISTER_PLUGIN_STATIC(PLUMBERS, PLUGIN_TYPE_ENGINE, PlumbersMetaEngine);
|
||||
#endif
|
||||
22
engines/plumbers/module.mk
Normal file
22
engines/plumbers/module.mk
Normal file
@@ -0,0 +1,22 @@
|
||||
MODULE := engines/plumbers
|
||||
|
||||
MODULE_OBJS = \
|
||||
plumbers.o \
|
||||
console.o \
|
||||
metaengine.o \
|
||||
windows.o
|
||||
|
||||
ifdef USE_RGB_COLOR
|
||||
MODULE_OBJS += 3do.o
|
||||
endif
|
||||
|
||||
# This module can be built as a plugin
|
||||
ifeq ($(ENABLE_PLUMBERS), DYNAMIC_PLUGIN)
|
||||
PLUGIN := 1
|
||||
endif
|
||||
|
||||
# Include common rules
|
||||
include $(srcdir)/rules.mk
|
||||
|
||||
# Detection objects
|
||||
DETECT_OBJS += $(MODULE)/detection.o
|
||||
402
engines/plumbers/plumbers.cpp
Normal file
402
engines/plumbers/plumbers.cpp
Normal file
@@ -0,0 +1,402 @@
|
||||
/* 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 "plumbers/plumbers.h"
|
||||
#include "plumbers/console.h"
|
||||
|
||||
#include "audio/decoders/aiff.h"
|
||||
#include "audio/decoders/wave.h"
|
||||
#include "audio/audiostream.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/debug-channels.h"
|
||||
#include "common/error.h"
|
||||
#include "common/events.h"
|
||||
#include "common/file.h"
|
||||
#include "common/system.h"
|
||||
#include "common/timer.h"
|
||||
|
||||
#include "engines/util.h"
|
||||
|
||||
#include "graphics/cursorman.h"
|
||||
#include "graphics/font.h"
|
||||
#include "graphics/fontman.h"
|
||||
#include "graphics/paletteman.h"
|
||||
#include "graphics/scaler/downscaler.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
namespace Plumbers {
|
||||
|
||||
PlumbersGame::PlumbersGame(OSystem *syst, const ADGameDescription *gameDesc) :
|
||||
Engine(syst), _gameDescription(gameDesc), _console(nullptr), _image(nullptr),
|
||||
_compositeSurface(nullptr), _videoDecoder(nullptr), _quit(false) {
|
||||
_timerInstalled = false;
|
||||
_showScoreFl = false;
|
||||
_setDurationFl = false;
|
||||
_leftButtonDownFl = false;
|
||||
_endGameFl = false;
|
||||
_curSceneIdx = -1;
|
||||
_prvSceneIdx = -1;
|
||||
_curBitmapIdx = -1;
|
||||
_curChoice = 0;
|
||||
_totScene = -1;
|
||||
_totScore = 0;
|
||||
}
|
||||
|
||||
PlumbersGame::~PlumbersGame() {
|
||||
delete _image;
|
||||
//_console is deleted by Engine
|
||||
}
|
||||
|
||||
static const byte MOUSECURSOR_SCI[] = {
|
||||
1,1,0,0,0,0,0,0,0,0,0,
|
||||
1,2,1,0,0,0,0,0,0,0,0,
|
||||
1,2,2,1,0,0,0,0,0,0,0,
|
||||
1,2,2,2,1,0,0,0,0,0,0,
|
||||
1,2,2,2,2,1,0,0,0,0,0,
|
||||
1,2,2,2,2,2,1,0,0,0,0,
|
||||
1,2,2,2,2,2,2,1,0,0,0,
|
||||
1,2,2,2,2,2,2,2,1,0,0,
|
||||
1,2,2,2,2,2,2,2,2,1,0,
|
||||
1,2,2,2,2,2,2,2,2,2,1,
|
||||
1,2,2,2,2,2,1,0,0,0,0,
|
||||
1,2,1,0,1,2,2,1,0,0,0,
|
||||
1,1,0,0,1,2,2,1,0,0,0,
|
||||
0,0,0,0,0,1,2,2,1,0,0,
|
||||
0,0,0,0,0,1,2,2,1,0,0,
|
||||
0,0,0,0,0,0,1,2,2,1,0
|
||||
};
|
||||
|
||||
static const byte MOUSECURSOR_AMIGA[] = {
|
||||
1,1,0,0,0,0,0,0,
|
||||
1,2,1,0,0,0,0,0,
|
||||
1,2,2,1,0,0,0,0,
|
||||
1,2,2,2,1,0,0,0,
|
||||
1,2,2,2,2,1,0,0,
|
||||
1,2,2,2,2,2,1,0,
|
||||
1,1,1,2,2,1,1,0,
|
||||
0,0,0,1,2,1,0,0,
|
||||
0,0,0,1,2,2,1,0,
|
||||
0,0,0,0,1,2,1,0,
|
||||
0,0,0,0,1,2,2,1,
|
||||
0,0,0,0,0,1,1,0,
|
||||
};
|
||||
|
||||
static const byte cursorPalette[] = {
|
||||
0, 0, 0, // Black / Transparent
|
||||
0x80, 0x80, 0x80, // Gray
|
||||
0xff, 0xff, 0xff // White
|
||||
};
|
||||
|
||||
void PlumbersGame::handleEvent(const Common::Event &event) {
|
||||
switch (event.type) {
|
||||
case Common::EVENT_QUIT:
|
||||
case Common::EVENT_RETURN_TO_LAUNCHER:
|
||||
_quit = true;
|
||||
break;
|
||||
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
if (_leftButtonDownFl) {
|
||||
_curChoice = getMouseHiLite();
|
||||
|
||||
if (_curChoice >= 0 && _curChoice < _scenes[_curSceneIdx]._decisionChoices) {
|
||||
debugC(5, kDebugGeneral, "Accepting mouse click with choice = %d", _curChoice);
|
||||
_totScore += _scenes[_curSceneIdx]._choices[_curChoice]._points;
|
||||
_actions.push(ChangeScene);
|
||||
_leftButtonDownFl = false;
|
||||
}
|
||||
} else if (_console->_allowSkip && _timerInstalled) {
|
||||
// Allows to skip speech by skipping wait delay
|
||||
onTimer(this);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Common::Error PlumbersGame::run() {
|
||||
startGraphics();
|
||||
|
||||
_console = new Console();
|
||||
setDebugger(_console);
|
||||
|
||||
if (_screenW > 320)
|
||||
CursorMan.replaceCursor(MOUSECURSOR_SCI, 11, 16, 0, 0, 0);
|
||||
else
|
||||
CursorMan.replaceCursor(MOUSECURSOR_AMIGA, 8, 12, 0, 0, 0);
|
||||
CursorMan.replaceCursorPalette(cursorPalette, 0, 3);
|
||||
CursorMan.showMouse(true);
|
||||
|
||||
readTables();
|
||||
|
||||
_showScoreFl = false;
|
||||
_leftButtonDownFl = false;
|
||||
_endGameFl = false;
|
||||
_totScore = 0;
|
||||
_curSceneIdx = _prvSceneIdx = 0;
|
||||
_curChoice = 0;
|
||||
_actions.clear();
|
||||
_actions.push(ShowScene);
|
||||
|
||||
_quit = false;
|
||||
|
||||
while (!_quit && !_endGameFl) {
|
||||
Common::Event event;
|
||||
while (g_system->getEventManager()->pollEvent(event)) {
|
||||
handleEvent(event);
|
||||
}
|
||||
|
||||
preActions();
|
||||
|
||||
while (!_actions.empty()) {
|
||||
switch (_actions.pop()) {
|
||||
case Redraw:
|
||||
drawScreen();
|
||||
break;
|
||||
case ShowScene:
|
||||
showScene();
|
||||
break;
|
||||
case UpdateScene:
|
||||
updateScene();
|
||||
break;
|
||||
case ChangeScene:
|
||||
changeScene();
|
||||
break;
|
||||
case PlaySound:
|
||||
playSound(_scenes[_curSceneIdx]._sceneName + "/" + _scenes[_curSceneIdx]._waveFilename);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_videoDecoder) {
|
||||
if (_videoDecoder->endOfVideo()) {
|
||||
_actions.push(ChangeScene);
|
||||
_videoDecoder->close();
|
||||
delete _videoDecoder;
|
||||
_videoDecoder = nullptr;
|
||||
} else if (_videoDecoder->needsUpdate()) {
|
||||
drawScreen();
|
||||
}
|
||||
}
|
||||
|
||||
g_system->updateScreen();
|
||||
g_system->delayMillis(_videoDecoder ? (1000 / 60) : 10);
|
||||
}
|
||||
|
||||
g_system->getTimerManager()->removeTimerProc(onTimer);
|
||||
stopSound();
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
void PlumbersGame::loadImage(const Common::String &name) {
|
||||
debugC(1, kDebugGeneral, "%s : %s", __FUNCTION__, name.c_str());
|
||||
Common::File file;
|
||||
if (!file.open(Common::Path(name)))
|
||||
error("unable to load image %s", name.c_str());
|
||||
|
||||
_image->loadStream(file);
|
||||
delete _compositeSurface;
|
||||
_compositeSurface = nullptr;
|
||||
}
|
||||
|
||||
void PlumbersGame::blitImageSurface(const Graphics::Surface *surface) {
|
||||
int w = CLIP<int>(surface->w, 0, _screenW);
|
||||
int h = CLIP<int>(surface->h, 0, _screenH);
|
||||
|
||||
int x = (_screenW - w) / 2;
|
||||
int y = (_screenH - h) / 2;
|
||||
|
||||
g_system->copyRectToScreen(surface->getPixels(), surface->pitch, x, y, w, h);
|
||||
}
|
||||
|
||||
void PlumbersGame::blitImage() {
|
||||
blitImageSurface(_compositeSurface ? _compositeSurface : _image->getSurface());
|
||||
}
|
||||
|
||||
void PlumbersGame::drawScreen() {
|
||||
debugC(_videoDecoder ? 10 : 1, kDebugGeneral, "%s : %s", __FUNCTION__, _image ? "YES" : "NO");
|
||||
if (_videoDecoder ? _videoDecoder->needsUpdate() : _image || _compositeSurface) {
|
||||
if (_setDurationFl) {
|
||||
g_system->getTimerManager()->removeTimerProc(onTimer);
|
||||
g_system->getTimerManager()->installTimerProc(onTimer, _bitmaps[_curBitmapIdx]._duration * 1000, this, "timer");
|
||||
_timerInstalled = true;
|
||||
_actions.push(UpdateScene);
|
||||
}
|
||||
|
||||
g_system->fillScreen(0);
|
||||
|
||||
blitImage();
|
||||
|
||||
if (_showScoreFl) {
|
||||
Graphics::PixelFormat screenFormat = g_system->getScreenFormat();
|
||||
Common::String score = Common::String::format("Your Score is: %ld", _totScore);
|
||||
const Graphics::Font &font(*FontMan.getFontByUsage(
|
||||
_screenW >= 640 ? Graphics::FontManager::kBigGUIFont : Graphics::FontManager::kGUIFont));
|
||||
int scoreTop = _screenH - _screenH / 12;
|
||||
int scoreMaxWidth = _screenW >= 640 ? 200 : 150;
|
||||
uint scoreColor = screenFormat.bytesPerPixel == 1 ? 0xff : screenFormat.RGBToColor(0xff, 0xff, 0xff);
|
||||
Common::Rect rect(10, scoreTop, scoreMaxWidth, scoreTop + font.getFontHeight());
|
||||
if (getPlatform() != Common::kPlatform3DO)
|
||||
g_system->fillScreen(rect, 0);
|
||||
Graphics::Surface *screen = g_system->lockScreen();
|
||||
font.drawString(screen, score, rect.left, rect.top, scoreMaxWidth - 10,
|
||||
scoreColor, Graphics::kTextAlignCenter);
|
||||
g_system->unlockScreen();
|
||||
_showScoreFl = false;
|
||||
}
|
||||
|
||||
if (_image->hasPalette())
|
||||
g_system->getPaletteManager()->setPalette(_image->getPalette().data(), 0, _image->getPalette().size());
|
||||
g_system->updateScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void PlumbersGame::playSound(const Common::String &name) {
|
||||
debugC(3, kDebugGeneral, "%s : %s", __FUNCTION__, name.c_str());
|
||||
Common::File *file = new Common::File();
|
||||
if (!file->open(Common::Path(name)))
|
||||
error("unable to load sound %s", name.c_str());
|
||||
|
||||
Audio::AudioStream *stream;
|
||||
if (name.hasSuffixIgnoreCase(".aiff"))
|
||||
stream = Audio::makeAIFFStream(file, DisposeAfterUse::YES);
|
||||
else
|
||||
stream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
|
||||
stopSound();
|
||||
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, stream, -1, Audio::Mixer::kMaxChannelVolume);
|
||||
}
|
||||
|
||||
void PlumbersGame::stopSound() {
|
||||
debugC(3, kDebugGeneral, "%s", __FUNCTION__);
|
||||
if (_mixer->isSoundHandleActive(_soundHandle))
|
||||
_mixer->stopHandle(_soundHandle);
|
||||
}
|
||||
|
||||
void PlumbersGame::showScene() {
|
||||
debugC(1, kDebugGeneral, "%s : %d", __FUNCTION__, _curSceneIdx);
|
||||
_curBitmapIdx = _scenes[_curSceneIdx]._startBitmap - 1;
|
||||
updateScene();
|
||||
if (_scenes[_curSceneIdx]._waveFilename != "")
|
||||
_actions.push(PlaySound);
|
||||
_actions.push(Redraw);
|
||||
}
|
||||
|
||||
int PlumbersGame::getMouseHiLite() {
|
||||
Common::Point mousePos = g_system->getEventManager()->getMousePos();
|
||||
for (int i = 0; i < _scenes[_curSceneIdx]._decisionChoices && i < kMaxChoice; i++) {
|
||||
if (_scenes[_curSceneIdx]._choices[i]._region.contains(mousePos))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void PlumbersGame::updateScene() {
|
||||
debugC(2, kDebugGeneral, "%s : %d", __FUNCTION__, _curBitmapIdx);
|
||||
_curBitmapIdx++;
|
||||
if (_curBitmapIdx >= _scenes[_curSceneIdx]._startBitmap + _scenes[_curSceneIdx]._bitmapNum) {
|
||||
postSceneBitmaps();
|
||||
} else {
|
||||
loadImage(_scenes[_curSceneIdx]._sceneName + "/" + _bitmaps[_curBitmapIdx]._filename);
|
||||
_setDurationFl = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PlumbersGame::changeScene() {
|
||||
debugC(1, kDebugGeneral, "%s : %d", __FUNCTION__, _curChoice);
|
||||
if (_scenes[_curSceneIdx]._choices[_curChoice]._sceneName == "SC-1") {
|
||||
_curSceneIdx = _prvSceneIdx;
|
||||
_curBitmapIdx = 9999;
|
||||
_actions.push(UpdateScene);
|
||||
_actions.push(Redraw);
|
||||
} else if (_scenes[_curSceneIdx]._choices[_curChoice]._sceneName == "restart") {
|
||||
_curSceneIdx = 0;
|
||||
_totScore = 0;
|
||||
_actions.push(UpdateScene);
|
||||
_actions.push(Redraw);
|
||||
} else if (_scenes[_curSceneIdx]._choices[_curChoice]._sceneName == "SC32767"
|
||||
|| _scenes[_curSceneIdx]._choices[_curChoice]._sceneName == "end") {
|
||||
_endGameFl = true;
|
||||
} else {
|
||||
if (_scenes[_curSceneIdx]._decisionChoices > 1)
|
||||
_prvSceneIdx = _curSceneIdx;
|
||||
if (_scenes[_curSceneIdx]._choices[_curChoice]._skipScene) {
|
||||
_curSceneIdx = getSceneNumb(_scenes[_curSceneIdx]._choices[_curChoice]._sceneName);
|
||||
_curBitmapIdx = 9999;
|
||||
_actions.push(UpdateScene);
|
||||
_actions.push(Redraw);
|
||||
g_system->getTimerManager()->removeTimerProc(onTimer);
|
||||
_timerInstalled = false;
|
||||
} else {
|
||||
_curSceneIdx = getSceneNumb(_scenes[_curSceneIdx]._choices[_curChoice]._sceneName);
|
||||
_actions.push(ShowScene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlumbersGame::processTimer() {
|
||||
debugC(7, kDebugGeneral, "%s", __FUNCTION__);
|
||||
_timerInstalled = false;
|
||||
if (!_endGameFl)
|
||||
_actions.push(Redraw);
|
||||
}
|
||||
|
||||
void PlumbersGame::onTimer(void *arg) {
|
||||
g_system->getTimerManager()->removeTimerProc(onTimer);
|
||||
((PlumbersGame*)arg)->processTimer();
|
||||
}
|
||||
|
||||
void PlumbersGame::initTables() {
|
||||
for (uint i = 0; i < ARRAYSIZE(_scenes); i++) {
|
||||
_scenes[i]._bitmapNum = 0;
|
||||
_scenes[i]._startBitmap = 0;
|
||||
_scenes[i]._decisionChoices = 0;
|
||||
_scenes[i]._sceneName = "";
|
||||
_scenes[i]._waveFilename = "";
|
||||
_scenes[i]._decisionBitmap = "";
|
||||
_scenes[i]._style = Scene::STYLE_PC;
|
||||
for (uint j = 0; j < ARRAYSIZE(_scenes[i]._choices); j++) {
|
||||
_scenes[i]._choices[j]._points = 0;
|
||||
_scenes[i]._choices[j]._skipScene = 0;
|
||||
_scenes[i]._choices[j]._region = Common::Rect(0, 0, 0, 0);
|
||||
_scenes[i]._choices[j]._sceneName = "";
|
||||
}
|
||||
}
|
||||
for (uint i = 0; i < ARRAYSIZE(_bitmaps); i++) {
|
||||
_bitmaps[i]._duration = 0;
|
||||
_bitmaps[i]._filename = "";
|
||||
}
|
||||
}
|
||||
|
||||
int PlumbersGame::getSceneNumb(const Common::String &sName) {
|
||||
debugC(1, kDebugGeneral, "%s : %s", __FUNCTION__, sName.c_str());
|
||||
for (int sCurScene = 0; sCurScene < _totScene; sCurScene++) {
|
||||
if (sName == _scenes[sCurScene]._sceneName)
|
||||
return sCurScene;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Plumbers
|
||||
206
engines/plumbers/plumbers.h
Normal file
206
engines/plumbers/plumbers.h
Normal file
@@ -0,0 +1,206 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLUMBERS_PLUMBERS_H
|
||||
#define PLUMBERS_PLUMBERS_H
|
||||
|
||||
#include "engines/engine.h"
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/platform.h"
|
||||
#include "common/queue.h"
|
||||
#include "common/rect.h"
|
||||
#include "common/str.h"
|
||||
|
||||
#include "audio/mixer.h"
|
||||
|
||||
#include "video/video_decoder.h"
|
||||
#include "image/image_decoder.h"
|
||||
|
||||
struct ADGameDescription;
|
||||
|
||||
namespace Graphics {
|
||||
struct Surface;
|
||||
}
|
||||
|
||||
namespace Plumbers {
|
||||
|
||||
class Console;
|
||||
|
||||
enum PlumbersDebugChannels {
|
||||
kDebugGeneral = 1,
|
||||
};
|
||||
|
||||
static const int kMaxChoice = 3;
|
||||
|
||||
struct Choice {
|
||||
long _points;
|
||||
int _skipScene;
|
||||
Common::Rect _region;
|
||||
Common::String _sceneName;
|
||||
};
|
||||
|
||||
struct Scene {
|
||||
int _bitmapNum;
|
||||
int _startBitmap;
|
||||
int _decisionChoices;
|
||||
Common::String _sceneName;
|
||||
Common::String _waveFilename;
|
||||
Common::String _decisionBitmap;
|
||||
enum {
|
||||
STYLE_PC = 0,
|
||||
STYLE_DECISION_MIKE = 1,
|
||||
STYLE_DECISION_TUN = 2,
|
||||
STYLE_VIDEO = 3
|
||||
} _style;
|
||||
Choice _choices[kMaxChoice];
|
||||
};
|
||||
|
||||
class PlumbersGame : public Engine {
|
||||
public:
|
||||
PlumbersGame(OSystem *syst, const ADGameDescription *gameDesc);
|
||||
~PlumbersGame() override;
|
||||
|
||||
Common::Error run() override;
|
||||
|
||||
// Detection related functions
|
||||
const ADGameDescription *_gameDescription;
|
||||
const char *getGameId() const;
|
||||
Common::Platform getPlatform() const;
|
||||
|
||||
protected:
|
||||
virtual void readTables() = 0;
|
||||
virtual void postSceneBitmaps() = 0;
|
||||
virtual bool handlePlatformJoyButton(int button) { return false; }
|
||||
virtual bool handlePlatformKeyDown(int button) { return false; }
|
||||
virtual void loadImage(const Common::String &name);
|
||||
virtual void startGraphics() = 0;
|
||||
void blitImageSurface(const Graphics::Surface *surface);
|
||||
virtual void blitImage();
|
||||
virtual void handleEvent(const Common::Event &event);
|
||||
virtual int getSceneNumb(const Common::String &sName);
|
||||
virtual void preActions() {}
|
||||
|
||||
static const int kMaxName = 13 + 1;
|
||||
static const int kMaxBitmaps = 2000;
|
||||
static const int kMaxScene = 100;
|
||||
void initTables();
|
||||
|
||||
struct {
|
||||
int _duration;
|
||||
Common::String _filename;
|
||||
} _bitmaps[kMaxBitmaps];
|
||||
|
||||
Scene _scenes[kMaxScene];
|
||||
int _totScene;
|
||||
long _totScore;
|
||||
|
||||
Graphics::PixelFormat _targetFormat;
|
||||
|
||||
Image::ImageDecoder *_image;
|
||||
Console *_console;
|
||||
Video::VideoDecoder *_videoDecoder;
|
||||
bool _showScoreFl;
|
||||
bool _setDurationFl;
|
||||
bool _leftButtonDownFl;
|
||||
bool _endGameFl;
|
||||
bool _timerInstalled;
|
||||
int _curSceneIdx, _prvSceneIdx;
|
||||
int _curBitmapIdx;
|
||||
int _curChoice;
|
||||
int _screenW, _screenH;
|
||||
bool _quit;
|
||||
|
||||
enum Action {
|
||||
Redraw,
|
||||
ShowScene,
|
||||
UpdateScene,
|
||||
ChangeScene,
|
||||
PlaySound
|
||||
};
|
||||
|
||||
Common::Queue<Action> _actions;
|
||||
Graphics::Surface *_compositeSurface;
|
||||
|
||||
void drawScreen();
|
||||
|
||||
Audio::SoundHandle _soundHandle;
|
||||
|
||||
void playSound(const Common::String &name);
|
||||
void stopSound();
|
||||
|
||||
void showScene();
|
||||
void updateScene();
|
||||
void changeScene();
|
||||
|
||||
void processTimer();
|
||||
static void onTimer(void *arg);
|
||||
|
||||
int getMouseHiLite();
|
||||
};
|
||||
|
||||
class PlumbersGame3DO : public PlumbersGame {
|
||||
public:
|
||||
PlumbersGame3DO(OSystem *syst, const ADGameDescription *gameDesc);
|
||||
|
||||
protected:
|
||||
void readTables() override;
|
||||
void postSceneBitmaps() override;
|
||||
void startGraphics() override;
|
||||
void handleEvent(const Common::Event &event) override;
|
||||
void blitImage() override;
|
||||
int getSceneNumb(const Common::String &sName) override;
|
||||
void preActions() override;
|
||||
|
||||
private:
|
||||
void skipVideo();
|
||||
void loadMikeDecision(const Common::String &dirname, const Common::String &baseFilename, uint num);
|
||||
void joyUp();
|
||||
void joyDown();
|
||||
void joyA();
|
||||
void updateHiLite();
|
||||
|
||||
bool _cheatEnabled;
|
||||
int _cheatFSM;
|
||||
bool _leftShoulderPressed;
|
||||
int _kbdHiLite;
|
||||
int _mouseHiLite;
|
||||
int _hiLite;
|
||||
Image::ImageDecoder *_ctrlHelpImage;
|
||||
};
|
||||
|
||||
class PlumbersGameWindows : public PlumbersGame {
|
||||
public:
|
||||
PlumbersGameWindows(OSystem *syst, const ADGameDescription *gameDesc);
|
||||
|
||||
protected:
|
||||
void readTables() override;
|
||||
void postSceneBitmaps() override;
|
||||
void loadImage(const Common::String &name) override;
|
||||
void startGraphics() override;
|
||||
|
||||
private:
|
||||
bool _halfSize;
|
||||
};
|
||||
|
||||
} // End of namespace Plumbers
|
||||
|
||||
#endif
|
||||
143
engines/plumbers/windows.cpp
Normal file
143
engines/plumbers/windows.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
/* 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 "plumbers/plumbers.h"
|
||||
#include "plumbers/console.h"
|
||||
|
||||
#include "audio/decoders/aiff.h"
|
||||
#include "audio/decoders/wave.h"
|
||||
#include "audio/audiostream.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/debug-channels.h"
|
||||
#include "common/error.h"
|
||||
#include "common/events.h"
|
||||
#include "common/file.h"
|
||||
#include "common/system.h"
|
||||
#include "common/timer.h"
|
||||
|
||||
#include "engines/util.h"
|
||||
|
||||
#include "graphics/cursorman.h"
|
||||
#include "graphics/font.h"
|
||||
#include "graphics/fontman.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "graphics/scaler/downscaler.h"
|
||||
|
||||
#include "image/bmp.h"
|
||||
|
||||
namespace Plumbers {
|
||||
PlumbersGameWindows::PlumbersGameWindows(OSystem *syst, const ADGameDescription *gameDesc) : PlumbersGame(syst, gameDesc), _halfSize(false) {
|
||||
}
|
||||
|
||||
void PlumbersGameWindows::loadImage(const Common::String &name) {
|
||||
PlumbersGame::loadImage(name);
|
||||
|
||||
if (_halfSize) {
|
||||
_compositeSurface = new Graphics::Surface();
|
||||
const Graphics::Surface *inSurf = _image->getSurface();
|
||||
_compositeSurface->create(_screenW, _screenH, inSurf->format);
|
||||
Graphics::downscaleSurfaceByHalf(_compositeSurface, inSurf, _image->getPalette().data());
|
||||
}
|
||||
}
|
||||
|
||||
void PlumbersGameWindows::startGraphics() {
|
||||
_image = new Image::BitmapDecoder();
|
||||
|
||||
Graphics::ModeWithFormatList modes = {
|
||||
// First try for a 640x480 mode
|
||||
Graphics::ModeWithFormat(640, 480, Graphics::PixelFormat::createFormatCLUT8()),
|
||||
// System doesn't support it, so fall back on 320x240 mode
|
||||
Graphics::ModeWithFormat(320, 240, Graphics::PixelFormat::createFormatCLUT8()),
|
||||
};
|
||||
|
||||
int modeIdx = initGraphicsAny(modes);
|
||||
|
||||
if (modeIdx == 0) {
|
||||
_screenW = 640;
|
||||
_screenH = 480;
|
||||
} else {
|
||||
_halfSize = true;
|
||||
_screenW = 320;
|
||||
_screenH = 240;
|
||||
}
|
||||
}
|
||||
|
||||
void PlumbersGameWindows::readTables() {
|
||||
Common::File file;
|
||||
if (!file.open("game.bin"))
|
||||
error("sReadTables(): Error reading BIN file");
|
||||
|
||||
initTables();
|
||||
|
||||
_totScore = file.readSint32LE();
|
||||
file.skip(10);
|
||||
_totScene = file.readSint16LE();
|
||||
file.skip(6);
|
||||
|
||||
char buf[kMaxName];
|
||||
for (int i = 0; i < kMaxScene; i++) {
|
||||
_scenes[i]._bitmapNum = file.readSint16LE();
|
||||
_scenes[i]._startBitmap = file.readSint16LE();
|
||||
_scenes[i]._decisionChoices = file.readSint16LE();
|
||||
file.read(buf, kMaxName);
|
||||
_scenes[i]._sceneName = Common::String(buf);
|
||||
file.read(buf, kMaxName);
|
||||
_scenes[i]._waveFilename = Common::String(buf);
|
||||
file.read(buf, kMaxName);
|
||||
_scenes[i]._decisionBitmap = Common::String(buf);
|
||||
_scenes[i]._style = Scene::STYLE_PC;
|
||||
|
||||
for (int j = 0; j < kMaxChoice; j++) {
|
||||
_scenes[i]._choices[j]._points = file.readSint32LE();
|
||||
_scenes[i]._choices[j]._sceneName = Common::String::format("SC%02d", file.readSint16LE());
|
||||
_scenes[i]._choices[j]._skipScene = file.readSint16LE();
|
||||
int left = file.readSint16LE();
|
||||
int top = file.readSint16LE();
|
||||
int right = file.readSint16LE();
|
||||
int bottom = file.readSint16LE();
|
||||
if (_halfSize)
|
||||
_scenes[i]._choices[j]._region = Common::Rect(left / 2, top / 2, right / 2, bottom / 2);
|
||||
else
|
||||
_scenes[i]._choices[j]._region = Common::Rect(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < kMaxBitmaps; i++) {
|
||||
_bitmaps[i]._duration = file.readSint16LE() * 100;
|
||||
file.read(buf, kMaxName);
|
||||
_bitmaps[i]._filename = Common::String(buf);
|
||||
}
|
||||
}
|
||||
|
||||
void PlumbersGameWindows::postSceneBitmaps() {
|
||||
if (_scenes[_curSceneIdx]._decisionChoices == 1) {
|
||||
_curChoice = 0;
|
||||
_actions.push(ChangeScene);
|
||||
return;
|
||||
}
|
||||
|
||||
_showScoreFl = true;
|
||||
_leftButtonDownFl = true;
|
||||
_setDurationFl = false;
|
||||
loadImage(_scenes[_curSceneIdx]._sceneName + "/" + _scenes[_curSceneIdx]._decisionBitmap);
|
||||
}
|
||||
} // End of namespace Plumbers
|
||||
Reference in New Issue
Block a user