Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

33
engines/supernova/NOTES Normal file
View File

@@ -0,0 +1,33 @@
Engine
----------
MouseFields
[0;256[ - Viewport
[256;512[ - Command Row
[512;768[ - Inventory
[768;769] - Inventory Arrows
Dimensions
Viewport: (0,0) (320, 150)
Command Row: (0, 150) (320, 159)
Inventory: (0, 161) (270, 200)
Inventory Arrows: (271, 161) (279, 200)
Exit Maps: (283, 163) (317, 197)
Text
-------
AE - 216 ae - 204
OE - 231 oe - 224
UE - 232 ue - 201
SZ - 341
Ingame Bugs
------------
In Cabin_R3 (starting room) you can take the discman from your locker without
opening it first.
Improvements
-------------
Incidate in inventory (?) what parts of your space suit you are wearing

View File

@@ -0,0 +1,3 @@
engines/supernova/supernova.cpp
engines/supernova/metaengine.cpp

View 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 supernova "Mission Supernova" yes

View File

@@ -0,0 +1,36 @@
/* 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 "gui/debugger.h"
#include "supernova/supernova.h"
#include "supernova/game-manager.h"
#include "supernova/console.h"
namespace Supernova {
Console::Console(SupernovaEngine *vm, GameManager *gm)
{
_vm = vm;
_gm = gm;
}
}

View File

@@ -0,0 +1,44 @@
/* 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 SUPERNOVA_CONSOLE_H
#define SUPERNOVA_CONSOLE_H
#include "gui/debugger.h"
namespace Supernova {
class SupernovaEngine;
class GameManager;
class Console : public GUI::Debugger {
public:
Console(Supernova::SupernovaEngine *vm, Supernova::GameManager *gm);
~Console() override {}
private:
SupernovaEngine *_vm;
GameManager *_gm;
};
}
#endif

View File

@@ -0,0 +1,5 @@
begin_section("Supernova");
add_person("Joseph-Eugene Winzer", "Joefish", "");
add_person("Jarom&iacute;r Wysoglad", "Vyzygold", "");
add_person("Thierry Crozat", "criezy", "");
end_section();

View File

@@ -0,0 +1,106 @@
/* 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/file.h"
#include "engines/advancedDetector.h"
#include "supernova/supernova.h"
#include "supernova/detection.h"
static const PlainGameDescriptor supernovaGames[] = {
{"msn1", "Mission Supernova - Part 1: The fate of Horst Hummel"},
{"msn2", "Mission Supernova - Part 2: The Doppelg\303\244nger"},
{nullptr, nullptr}
};
namespace Supernova {
static const ADGameDescription gameDescriptions[] = {
// Mission Supernova 1
{
"msn1",
nullptr,
AD_ENTRY1s("msn_data.000", "f64f16782a86211efa919fbae41e7568", 24163),
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO3(GAMEOPTION_TTS, GAMEOPTION_IMPROVED, GUIO_NOMIDI)
},
{
"msn1",
nullptr,
AD_ENTRY1s("msn_data.000", "f64f16782a86211efa919fbae41e7568", 24163),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO3(GAMEOPTION_TTS, GAMEOPTION_IMPROVED, GUIO_NOMIDI)
},
{
"msn1",
nullptr,
AD_ENTRY1s("msn_data.000", "f64f16782a86211efa919fbae41e7568", 24163),
Common::IT_ITA,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO3(GAMEOPTION_TTS, GAMEOPTION_IMPROVED, GUIO_NOMIDI)
},
// Mission Supernova 2
{
"msn2",
nullptr,
AD_ENTRY1s("ms2_data.000", "e595610cba4a6d24a763e428d05cc83f", 24805),
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO3(GAMEOPTION_TTS, GAMEOPTION_IMPROVED, GUIO_NOMIDI)
},
{
"msn2",
nullptr,
AD_ENTRY1s("ms2_data.000", "e595610cba4a6d24a763e428d05cc83f", 24805),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO3(GAMEOPTION_TTS, GAMEOPTION_IMPROVED, GUIO_NOMIDI)
},
AD_TABLE_END_MARKER
};
}
class SupernovaMetaEngineDetection: public AdvancedMetaEngineDetection<ADGameDescription> {
public:
SupernovaMetaEngineDetection() : AdvancedMetaEngineDetection(Supernova::gameDescriptions, supernovaGames) {
}
const char *getName() const override {
return "supernova";
}
const char *getEngineName() const override {
return "Mission Supernova";
}
const char *getOriginalCopyright() const override {
return "Mission Supernova (C) 1994 Thomas and Steffen Dingel";
}
};
REGISTER_PLUGIN_STATIC(SUPERNOVA_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, SupernovaMetaEngineDetection);

View File

@@ -0,0 +1,28 @@
/* 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 SUPERNOVA_DETECTION_H
#define SUPERNOVA_DETECTION_H
#define GAMEOPTION_IMPROVED GUIO_GAMEOPTIONS1
#define GAMEOPTION_TTS GUIO_GAMEOPTIONS2
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,204 @@
/* 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 SUPERNOVA_GAME_MANAGER_H
#define SUPERNOVA_GAME_MANAGER_H
#include "common/events.h"
#include "common/rect.h"
#include "common/keyboard.h"
#include "common/error.h"
#include "supernova/room.h"
#include "supernova/sound.h"
namespace Supernova {
const int32 kMaxTimerValue = 0x7FFFFFFF;
enum EventFunction { kNoFn, kSupernovaFn, kGuardReturnedFn, kGuardWalkFn, kTaxiFn, kSearchStartFn, kSoberFn, kPyramidEndFn, kCaughtFn};
class Inventory {
public:
Inventory(Object *nullObject, int &inventoryScroll)
: _numObjects(0)
, _nullObject(nullObject)
, _inventoryScroll(inventoryScroll) {
for (int i = 0; i < kMaxCarry; ++i)
_inventory[i] = nullptr;
}
void add(Object &obj);
void remove(Object &obj);
void clear();
Object *get(int index) const;
Object *get(ObjectId id) const;
int getSize() const { return _numObjects; }
private:
Object *_inventory[kMaxCarry];
Object *_nullObject;
int &_inventoryScroll;
int _numObjects;
};
class GuiElement : public Common::Rect {
public:
GuiElement();
void setSize(int x1, int y1, int x2, int y2);
void setText(const char *text);
void setTextPosition(int x, int y);
void setColor(int bgColor, int textColor, int bgColorHighlighted, int textColorHightlighted);
void setHighlight(bool isHighlighted);
const char *getText() const {
return _text;
}
int getBackgroundColor() const {
return _bgColor;
}
int getTextColor() const {
return _textColor;
}
const Common::Point &getTextPos() const {
return _textPosition;
}
bool isHighlighted() const {
return _isHighlighted;
}
private:
Common::Point _textPosition;
char _text[128];
int _bgColor;
int _textColor;
int _bgColorNormal;
int _bgColorHighlighted;
int _textColorNormal;
int _textColorHighlighted;
bool _isHighlighted;
};
class GameManager {
public:
GameManager(SupernovaEngine *vm, Sound *sound);
virtual ~GameManager();
virtual void updateEvents();
void processInput(Common::CustomEventType action);
void processInput();
virtual void executeRoom();
virtual bool serialize(Common::WriteStream *out);
virtual bool deserialize(Common::ReadStream *in, int version);
static int guiCommands[];
static int guiStatusCommands[];
SupernovaEngine *_vm;
Sound *_sound;
Common::KeyState _key;
Common::CustomEventType _action;
Common::EventType _mouseClickType;
bool _mouseClicked;
bool _keyPressed;
int _mouseX;
int _mouseY;
int _mouseField;
Room *_currentRoom;
Room *_lastRoom;
bool _newRoom;
Room **_rooms;
Inventory _inventory;
bool _processInput;
bool _guiEnabled;
bool _animationEnabled;
byte _roomBrightness;
Action _inputVerb;
Object _nullObject;
Object *_currentInputObject;
Object *_inputObject[2];
int32 _oldTime;
uint _timePaused;
bool _timerPaused;
int32 _messageDuration;
int32 _animationTimer;
int _inventoryScroll;
int _exitList[25];
GuiElement _guiCommandButton[10];
GuiElement _guiInventory[8];
GuiElement _guiInventoryArrow[2];
// Dialog
int _currentSentence;
int _sentenceNumber[6];
int _texts[6];
byte _rows[6];
byte _rowsStart[6];
int32 _time;
bool _dead;
void takeObject(Object &obj);
void setObjectNull(Object *&obj);
bool isNullObject(Object *obj);
virtual void initState();
virtual void initRooms();
virtual void destroyRooms();
void initGui();
virtual bool canSaveGameStateCurrently();
virtual bool genericInteract(Action verb, Object &obj1, Object &obj2);
void getInput(bool onlyKeys = false);
void wait(int ticks, bool checkInput = false, bool waitForSpeech = false);
bool waitOnInput(int ticks, Common::KeyCode &keycode, bool waitForSpeech = false);
void screenShake();
virtual void roomBrightness();
void showMenu();
void animationOff();
void animationOn();
void edit(Common::String &input, int x, int y, uint length);
int invertSection(int section);
virtual void drawMapExits();
void drawStatus();
void drawCommandBox();
void drawInventory();
void drawGUI();
void changeRoom(RoomId id);
void resetInputState();
virtual void handleInput();
virtual void handleTime();
void pauseTimer(bool pause);
virtual void loadTime();
virtual void saveTime();
void setAnimationTimer(int ticks);
void dead(int messageId);
int dialog(int num, byte rowLength[6], int text[6], int number);
void sentence(int number, bool brightness);
void say(int textId);
void say(const char *text);
void reply(int textId, int aus1, int aus2);
void reply(const char *text, int aus1, int aus2);
void mousePosDialog(int x, int y);
virtual void takeMoney(int amount);
};
}
#endif // SUPERNOVA_GAME_MANAGER_H

View File

@@ -0,0 +1,290 @@
/* 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/algorithm.h"
#include "common/file.h"
#include "common/stream.h"
#include "common/system.h"
#include "common/config-manager.h"
#include "common/memstream.h"
#include "graphics/paletteman.h"
#include "graphics/surface.h"
#include "supernova/graphics.h"
#include "supernova/msn_def.h"
#include "supernova/screen.h"
#include "supernova/supernova.h"
namespace Supernova {
MSNImage::MSNImage(SupernovaEngine *vm)
: _palette(0), _vm(vm) {
_encodedImage = nullptr;
_filenumber = -1;
_pitch = 0;
_numSections = 0;
_numClickFields = 0;
for (int i = 0; i < kMaxSections; ++i) {
_section[i].x1 = 0;
_section[i].x2 = 0;
_section[i].y1 = 0;
_section[i].y2 = 0;
_section[i].next = 0;
_section[i].addressLow = 0xFFFF;
_section[i].addressHigh = 0xFF;
}
for (int i = 0; i < kMaxClickFields; ++i) {
_clickField[i].x1 = 0;
_clickField[i].x2 = 0;
_clickField[i].y1 = 0;
_clickField[i].y2 = 0;
_clickField[i].next = 0;
}
}
MSNImage::~MSNImage() {
destroy();
}
bool MSNImage::init(int filenumber) {
Common::File file;
_filenumber = filenumber;
if (_vm->_MSPart == 1) {
if (!file.open(Common::Path(Common::String::format("msn_data.%03d", filenumber)))) {
warning("Image data file msn_data.%03d could not be read!", filenumber);
return false;
}
loadStream(file);
}
else if (_vm->_MSPart == 2) {
if (!loadFromEngineDataFile()) {
if (!file.open(Common::Path(Common::String::format("ms2_data.%03d", filenumber)))) {
warning("Image data file ms2_data.%03d could not be read!", filenumber);
return false;
}
loadStream(file);
}
}
return true;
}
bool MSNImage::loadPbmFromEngineDataFile() {
Common::String name;
if (_vm->_MSPart == 2) {
if (_filenumber == 38)
name = "IMG3";
else
return false;
} else if (_vm->_MSPart == 1) {
if (_filenumber == 1)
name = "IMG1";
else if (_filenumber == 2)
name = "IMG2";
else
return false;
} else
return false;
Common::SeekableReadStream *stream = _vm->getBlockFromDatFile(name);
if (stream == nullptr)
return false;
stream->read(_encodedImage, stream->size());
return true;
}
bool MSNImage::loadFromEngineDataFile() {
Common::String name;
if (_vm->_MSPart == 1) {
return false;
} else if (_vm->_MSPart == 2) {
if (_filenumber == 15)
name = "M015";
else if (_filenumber == 27)
name = "M027";
else if (_filenumber == 28)
name = "M028";
else
return false;
}
Common::SeekableReadStream *stream = _vm->getBlockFromDatFile(name);
if (stream == nullptr)
return false;
return loadStream(*stream);
}
bool MSNImage::loadStream(Common::SeekableReadStream &stream) {
destroy();
uint size = 0;
size = (stream.readUint16LE() + 0xF) >> 4;
size |= (stream.readUint16LE() & 0xF) << 12;
size += 0x70; // zus_paragraph
size *= 16; // a paragraph is 16 bytes
_encodedImage = new byte[size];
byte palette[717];
g_system->getPaletteManager()->grabPalette(palette, 16, 239);
_palette.resize(239, false);
_palette.set(palette, 0, 239);
byte pal_diff;
byte flag = stream.readByte();
if (flag == 0) {
pal_diff = 0;
_palette.set(47, 0xE0, 0xE0, 0xE0);
} else {
pal_diff = 1;
for (int i = flag; i != 0; --i) {
byte r = stream.readByte() << 2;
byte g = stream.readByte() << 2;
byte b = stream.readByte() << 2;
_palette.set(239 - i, r, g, b);
}
}
_numSections = stream.readByte();
for (int i = 0; i < kMaxSections; ++i) {
_section[i].addressHigh = 0xff;
_section[i].addressLow = 0xffff;
_section[i].x2 = 0;
_section[i].next = 0;
}
for (int i = 0; i < _numSections; ++i) {
_section[i].x1 = stream.readUint16LE();
_section[i].x2 = stream.readUint16LE();
_section[i].y1 = stream.readByte();
_section[i].y2 = stream.readByte();
_section[i].next = stream.readByte();
_section[i].addressLow = stream.readUint16LE();
_section[i].addressHigh = stream.readByte();
}
_numClickFields = stream.readByte();
for (int i = 0; i < _numClickFields; ++i) {
_clickField[i].x1 = stream.readUint16LE();
_clickField[i].x2 = stream.readUint16LE();
_clickField[i].y1 = stream.readByte();
_clickField[i].y2 = stream.readByte();
_clickField[i].next = stream.readByte();
}
for (int i = _numClickFields; i < kMaxClickFields; ++i) {
_clickField[i].x1 = 0;
_clickField[i].x2 = 0;
_clickField[i].y1 = 0;
_clickField[i].y2 = 0;
_clickField[i].next = 0;
}
// Newspaper images may be in the engine data file. So first try to read
// it from there.
if (!loadPbmFromEngineDataFile()) {
// Load the image from the stream
byte zwCodes[256] = {0};
byte numRepeat = stream.readByte();
byte numZw = stream.readByte();
stream.read(zwCodes, numZw);
numZw += numRepeat;
byte input = 0;
uint i = 0;
while (stream.read(&input, 1)) {
if (input < numRepeat) {
++input;
byte value = stream.readByte();
for (--value; input > 0; --input) {
_encodedImage[i++] = value;
}
} else if (input < numZw) {
input = zwCodes[input - numRepeat];
--input;
_encodedImage[i++] = input;
_encodedImage[i++] = input;
} else {
input -= pal_diff;
_encodedImage[i++] = input;
}
}
}
loadSections();
return true;
}
bool MSNImage::loadSections() {
bool isNewspaper = (_vm->_MSPart == 1 && (_filenumber == 1 || _filenumber == 2)) ||
(_vm->_MSPart == 2 && _filenumber == 38);
int imageWidth = isNewspaper ? 640 : 320;
int imageHeight = isNewspaper ? 480 : 200;
_pitch = imageWidth;
for (int section = 0; section < _numSections; ++section) {
Graphics::Surface *surface = new Graphics::Surface;
_sectionSurfaces.push_back(surface);
if (isNewspaper) {
Color color1 = isNewspaper ? kColorWhite63 : kColorWhite44;
surface->create(imageWidth, imageHeight, g_system->getScreenFormat());
byte *surfacePixels = static_cast<byte *>(surface->getPixels());
for (int i = 0; i < imageWidth * imageHeight / 8; ++i) {
*surfacePixels++ = (_encodedImage[i] & 0x80) ? color1 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x40) ? color1 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x20) ? color1 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x10) ? color1 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x08) ? color1 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x04) ? color1 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x02) ? color1 : kColorBlack;
*surfacePixels++ = (_encodedImage[i] & 0x01) ? color1 : kColorBlack;
}
} else {
uint32 offset = (_section[section].addressHigh << 16) + _section[section].addressLow;
if (offset == kInvalidAddress || _section[section].x2 == 0) {
return false;
}
int width = _section[section].x2 - _section[section].x1 + 1;
int height = _section[section].y2 - _section[section].y1 + 1;
surface->create(width, height, g_system->getScreenFormat());
byte *surfacePixels = static_cast<byte *>(surface->getPixels());
Common::copy(_encodedImage + offset, _encodedImage + offset + width * height, surfacePixels);
}
}
return true;
}
void MSNImage::destroy() {
_palette.clear();
if (_encodedImage) {
delete[] _encodedImage;
_encodedImage = nullptr;
}
for (Common::Array<Graphics::Surface *>::iterator it = _sectionSurfaces.begin();
it != _sectionSurfaces.end(); ++it) {
(*it)->free();
}
}
}

View 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/>.
*
*/
#ifndef SUPERNOVA_GRAPHICS_H
#define SUPERNOVA_GRAPHICS_H
#include "common/scummsys.h"
#include "graphics/palette.h"
#include "image/image_decoder.h"
#include "supernova/supernova.h"
namespace Common {
class SeekableReadStream;
}
namespace Graphics {
struct Surface;
}
namespace Supernova {
class SupernovaEngine;
class MSNImage : public Image::ImageDecoder {
public:
MSNImage(SupernovaEngine *vm);
~MSNImage() override;
void destroy() override;
bool loadStream(Common::SeekableReadStream &stream) override;
const Graphics::Surface *getSurface() const override { return _sectionSurfaces[0]; }
const Graphics::Palette &getPalette() const override { return _palette; }
bool init(int filenumber);
static const int kMaxSections = 50;
static const int kMaxClickFields = 80;
static const uint32 kInvalidAddress = 0x00FFFFFF;
int _filenumber;
int _pitch;
int _numSections;
int _numClickFields;
Common::Array<Graphics::Surface *> _sectionSurfaces;
Graphics::Palette _palette;
byte *_encodedImage;
struct Section {
int16 x1;
int16 x2;
byte y1;
byte y2;
byte next;
uint16 addressLow;
byte addressHigh;
} _section[kMaxSections];
struct ClickField {
int16 x1;
int16 x2;
byte y1;
byte y2;
byte next;
} _clickField[kMaxClickFields];
private:
SupernovaEngine *_vm;
bool loadFromEngineDataFile();
bool loadPbmFromEngineDataFile();
bool loadSections();
};
}
#endif

655
engines/supernova/imageid.h Normal file
View File

@@ -0,0 +1,655 @@
/* 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 SUPERNOVA_IMAGEID_H
#define SUPERNOVA_IMAGEID_H
namespace Supernova {
enum ImageId {
// file 0
kImageAxacussanShipBackground,
kImageAxacussanShipCenterMouthOpen,
kImageAxacussanShipRightMouthOpen,
// file 1
kImageNewspaper1,
// file 2
kImageNewspaper2,
// file 3
kImageElevatorBackground,
kImageElevatorGreenButton,
kImageElevatorRedButton,
kImageElevatorDoorAnimation1,
kImageElevatorDoorAnimation2,
kImageElevatorDoorAnimation3,
kImageElevatorDoorAnimation4,
kImageElevatorDoorAnimation5,
kImageElevatorDummy1,
kImageElevatorDummy2,
kImageElevatorDummy3,
kImageElevatorDummy4,
// file 4
kImageShipSpaceBackground,
kImageShipSpaceRope,
kImageShipSpaceDummy1,
kImageShipSpaceDummy2,
// file 5
kImageBusStationBackground,
kImageBusStationArrived,
kImageBusStationPlantAnimation1,
kImageBusStationPlantAnimation2,
kImageBusStationPlantAnimation3,
kImageBusStationPlantAnimation4,
kImageBusStationPlantAnimation5,
kImageBusStationPlantAnimation6,
kImageBusStationPlantAnimation7,
kImageBusStationDoorOpened,
// file 6
kImageOfficesBackground,
kImageOfficesDoorOpenTopLeft,
kImageOfficesDoorOpenBottomLeft,
kImageOfficesDoorOpenTopRight,
kImageOfficesDoorOpenBottomRight,
kImageOfficesAlienCorridorAnimation1,
kImageOfficesAlienCorridorAnimation2,
kImageOfficesAlienCorridorAnimation3,
kImageOfficesAlienCorridorAnimation4,
kImageOfficesAlienCorridorAnimation5,
kImageOfficesAlienCorridorAnimation6,
kImageOfficesAlienTopOfficeAnimation1,
kImageOfficesAlienTopOfficeAnimation2,
kImageOfficesAlienTopOfficeAnimation3,
kImageOfficesAlienTopOfficeAnimation4,
kImageOfficesAlienTopOfficeAnimation5,
kImageOfficesAlienBottomOfficeAnimation1,
kImageOfficesAlienBottomOfficeAnimation2,
kImageOfficesAlienBottomOfficeAnimation3,
kImageOfficesAlienBottomOfficeAnimation4,
kImageOfficesAlienBottomOfficeAnimation5,
kImageOfficesAlienBottom,
// file 7
kImageOfficeLeftBackground,
kImageOfficeLeftDecoration,
kImageOfficeLeftMemo,
kImageOfficeLeftGraffiti,
kImageOfficeLeftTerminalSmashed,
kImageOfficeLeftDrawerMoney,
kImageOfficeLeftSafeOpen,
kImageOfficeLeftSafeClosed,
kImageOfficeLeftSafeMoney,
kImageOfficeLeftDoorOpen,
kImageOfficeLeftAlienShootAnimation1,
kImageOfficeLeftAlienShootAnimation2,
kImageOfficeLeftAlienShootAnimation3,
kImageOfficeLeftAlienShootAnimation4,
kImageOfficeLeftAlienShootAnimation5,
kImageOfficeLeftAlienShootAnimation6,
kImageOfficeLeftTerminalText,
kImageOfficeLeftDoorClosed,
kImageOfficeLeftDummy1,
kImageOfficeLeftDummy2,
kImageOfficeLeftDummy3,
kImageOfficeLeftDummy4,
kImageOfficeLeftDummy5,
// file 8
kImageOfficeRightBackground,
kImageOfficeRightDecorationPictures,
kImageOfficeRightDecorationPlants,
kImageOfficeRightDoorOpen,
kImageOfficeRightTerminalSmashed,
kImageOfficeRightAlienShootAnimation1,
kImageOfficeRightAlienShootAnimation2,
kImageOfficeRightAlienShootAnimation3,
kImageOfficeRightAlienTalking,
kImageOfficeRightDummy1,
kImageOfficeRightDummy2,
kImageOfficeRightDummy3,
kImageOfficeRightDummy4,
// file 9
kImageShipCockpitBackground,
kImageShipCockpitPilotAnimation1,
kImageShipCockpitPilotAnimation2,
kImageShipCockpitPilotAnimation3,
kImageShipCockpitPilotAnimation4,
kImageShipCockpitPilotAnimation5,
kImageShipCockpitPilotAnimation6,
kImageShipCockpitPilotAnimation7,
kImageShipCockpitPilotAnimation8,
kImageShipCockpitPilotAnimation9,
kImageShipCockpitPilotAnimation10,
kImageShipCockpitPilotAnimation11,
kImageShipCockpitPilotAnimation12,
kImageShipCockpitPilotAnimation13,
kImageShipCockpitPilotAnimation14,
kImageShipCockpitPilotAnimation15,
kImageShipCockpitPilotAnimation16,
kImageShipCockpitPilotAnimation17,
kImageShipCockpitPilotAnimation18,
kImageShipCockpitPilotAnimation19,
kImageShipCockpitPilotAnimation20,
kImageShipCockpitDisplayStatusAnimation1,
kImageShipCockpitDisplayStatusAnimation2,
kImageShipCockpitWindowRocks,
// file 10
kImageRestaurantEntranceBackground,
kImageRestaurantEntrancePorterAnimation1,
kImageRestaurantEntrancePorterAnimation2,
kImageRestaurantEntrancePorterAnimation3,
kImageRestaurantEntrancePorterAnimation4,
kImageRestaurantEntranceBathroomDoorAnimation1,
kImageRestaurantEntranceBathroomDoorAnimation2,
kImageRestaurantEntranceBathroomDoorAnimation3,
kImageRestaurantEntranceBathroomDoorAnimation4,
kImageRestaurantEntranceBathroomDoorAnimation5,
kImageRestaurantEntranceGreenCandy,
kImageRestaurantEntranceBlueCandy,
kImageRestaurantEntrancePinkCandy,
kImageRestaurantEntranceWhiteCandy,
kImageRestaurantEntranceBlackCandy,
kImageRestaurantEntraceDummy1,
kImageRestaurantEntraceDummy2,
// file 11
kImageDeathScreen,
// file 12
kImageRocksBackground,
kImageRocksRockAnimation1,
kImageRocksRockAnimation2,
kImageRocksRockAnimation3,
// file 13
kImageBluePlanetBackground,
kImageBluePlanetShipAnimation1,
kImageBluePlanetShipAnimation2,
kImageBluePlanetShipAnimation3,
kImageBluePlanetShipAnimation4,
kImageBluePlanetShipAnimation5,
kImageBluePlanetShipAnimation6,
kImageBluePlanetShipAnimation7,
kImageBluePlanetShipAnimation8,
kImageBluePlanetShipAnimation9,
kImageBluePlanetShipAnimation10,
kImageBluePlanetShipAnimation11,
kImageBluePlanetShipAnimation12,
kImageBluePlanetShipAnimation13,
// file 14
kImageRogerCrashBackground,
kImageRogerCrashAnimation1,
kImageRogerCrashAnimation2,
kImageRogerCrashAnimation3,
kImageRogerCrashAnimation4,
kImageRogerCrashAnimation5,
kImageRogerCrashAnimation6,
kImageRogerCrashAnimation7,
kImageRogerCrashAnimation8,
kImageRogerCrashAnimation9,
kImageRogerCrashAnimation10,
kImageRogerCrashAnimation11,
kImageRogerCrashAnimation12,
kImageRogerCrashAnimation13,
kImageRogerCrashAnimation14,
kImageRogerCrashAnimation15,
kImageRogerCrashAnimation16,
kImageRogerCrashAnimation17,
kImageRogerCrashAnimation18,
kImageRogerCrashAnimation19,
// file 15
kImageShipCorridorBackground,
kImageShipCorridorCockpitDoorOpen,
kImageShipCorridorSleepCabinDoorAnimation1,
kImageShipCorridorSleepCabinDoorAnimation2,
kImageShipCorridorSleepCabinDoorAnimation3,
kImageShipCorridorDummy1,
// file 16
kImageAxacussCorridorTileWalled,
kImageAxacussCorridorToLeft,
kImageAxacussCorridorToRight,
kImageAxacussCorridorToTop,
kImageAxacussCorridorToBottom,
kImageAxacussCorridorTile,
kImageAxacussCorridorDoorClosed,
kImageAxacussCorridorDoorOpen,
kImageAxacussCorridorDesk,
kImageAxacussCorridorLaptop,
kImageAxacussCorridorStuff10,
kImageAxacussCorridorStuff11,
kImageAxacussCorridorStuff12,
kImageAxacussCorridorStuff13,
kImageAxacussCorridorStuff14,
kImageAxacussCorridorStuff15,
kImageAxacussCorridorStuff16,
kImageAxacussCorridorStuff17,
kImageAxacussCorridorStuff18,
kImageAxacussCorridorStuff19,
kImageAxacussCorridorStuff20,
kImageAxacussCorridorStuff21,
kImageAxacussCorridorStuff22,
kImageAxacussCorridorStuff23,
kImageAxacussCorridorStuff24,
kImageAxacussCorridorStuff25,
kImageAxacussCorridorStuff26,
kImageAxacussCorridorStuff27,
kImageAxacussCorridorStuff28,
kImageAxacussCorridorAlarmStatus,
kImageAxacussCorridorAlienRight,
kImageAxacussCorridorAlienLeft,
kImageAxacussCorridorAlienBottom,
kImageAxacussCorridorAlienTop,
// file 17
kImageShipCorridorCabinBackground,
kImageShipCorridorCabinL1Open,
kImageShipCorridorCabinL2Open,
kImageShipCorridorCabinL3Open,
kImageShipCorridorCabinR1Open,
kImageShipCorridorCabinR2Open,
kImageShipCorridorCabinR3Open,
kImageShipCorridorCabinAirlockDoorAnimation1,
kImageShipCorridorCabinAirlockDoorAnimation2,
kImageShipCorridorCabinAirlockDoorAnimation3,
kImageShipCorridorCabinDummy1,
kImageShipCorridorCabinDummy2,
kImageShipCorridorCabinDummy3,
kImageShipCorridorCabinDummy4,
kImageShipCorridorCabinDummy5,
kImageShipCorridorCabinDummy6,
// file 18
kImageShipGeneratorBackground,
kImageShipGeneratorHatchOpen,
kImageShipGeneratorJunctionBoxOpen,
kImageShipGeneratorJunctionBoxOffline,
kImageShipGeneratorJunctionBoxDisplay,
kImageShipGeneratorKeycard,
kImageShipGeneratorSpoolFloating,
kImageShipGeneratorSpoolOnGround,
kImageShipGeneratorCableUnplugged,
kImageShipGeneratorCablePluggedIn,
kImageShipGeneratorHatchRocks,
kImageShipGeneratorRopeRocks,
kImageShipGeneratorRopeSpace,
kImageShipGeneratorRopeFloor,
kImageShipGeneratorDummy1,
kImageShipGeneratorDummy2,
kImageShipGeneratorDummy3,
kImageShipGeneratorDummy4,
kImageShipGeneratorDummy5,
kImageShipGeneratorDummy6,
kImageShipGeneratorDummy7,
kImageShipGeneratorDummy8,
// file 19
kImageRogerShipBackground,
kImageRogerShipButtonPressed1,
kImageRogerShipButtonPressed2,
kImageRogerShipButtonPressed3,
kImageRogerShipButtonPressed4,
kImageRogerShipCardInSlot,
kImageRogerShipCompartmentOpen,
kImageRogerShipUnknown7,
kImageRogerShipDisplayLeftOn,
kImageRogerShipGreenDisplayAnimation1,
kImageRogerShipGreenDisplayAnimation2,
kImageRogerShipGreenDisplayAnimation3,
kImageRogerShipGreenDisplayAnimation4,
kImageRogerShipGreenDisplayAnimation5,
kImageRogerShipGreenDisplayAnimation6,
kImageRogerShipGreenDisplayAnimation7,
kImageRogerShipBlueDisplayAnimation1,
kImageRogerShipBlueDisplayAnimation2,
kImageRogerShipBlueDisplayAnimation3,
kImageRogerShipBlueDisplayAnimation4,
kImageRogerShipBlueDisplayAnimation5,
kImageRogerShipBlueDisplayAnimation6,
kImageRogerShipBlueDisplayAnimation7,
kImageRogerShipUnknown23,
kImageRogerShipDisplaySinewaveAnimation1,
kImageRogerShipDisplaySinewaveAnimation2,
kImageRogerShipDisplaySinewaveAnimation3,
kImageRogerShipDisplaySinewaveAnimation4,
kImageRogerShipDisplaySinewaveAnimation5,
kImageRogerShipDisplaySinewaveAnimation6,
kImageRogerShipDisplaySinewaveAnimation7,
kImageRogerShipDisplaySinewaveAnimation8,
kImageRogerShipDisplaySinewaveAnimation9,
kImageRogerShipDisplaySinewaveAnimation10,
kImageRogerShipDisplaySinewaveAnimation11,
kImageRogerShipDisplaySinewaveAnimation12,
kImageRogerShipDisplaySinewaveAnimation13,
kImageRogerShipDisplaySinewaveAnimation14,
kImageRogerShipCompartmentContent,
kImageRogerShipDummy1,
kImageRogerShipDummy2,
// file 20
kImageHelpScreen,
// file 21
kImageShipCabinLeftBackground,
kImageShipCabinLeftPaintingSunset,
kImageShipCabinLeftPaintingLandscape,
kImageShipCabinLeftPaintingAbstract,
kImageShipCabinLeftTableStuff1,
kImageShipCabinLeftCeilingPencil,
kImageShipCabinLeft3Decoration,
kImageShipCabinLeftSocketPluggedIn,
kImageShipCabinLeftVinyl,
kImageShipCabinLeftTurntable,
kImageShipCabinLeftSocketUnplugged,
kImageShipCabinLeftTurntableCableCut,
kImageShipCabinLeftTurntableCable,
kImageShipCabinLeftTurntableAnimation1,
kImageShipCabinLeftTurntableAnimation2,
kImageShipCabinLeftTurntableAnimation3,
kImageShipCabinLeftTableStuff2,
kImageShipCabinLeftLockerOpen,
kImageShipCabinLeftLockerBooksOpen,
kImageShipCabinLeftLockerSpoolOpen,
kImageShipCabinLeftLockerPistolRemoved,
kImageShipCabinLeftLockerSpoolRemoved,
kImageShipCabinLeftBedSafeOpen,
kImageShipCabinLeftBedSafeEmpty,
kImageShipCabinLeftDoorClosed,
kImageShipCabinLeftTurntableCableSparks,
kImageShipCabinLeftTurntableCableCutEnd,
kImageShipCabinLeftDummy1,
kImageShipCabinLeftDummy2,
kImageShipCabinLeftDummy3,
kImageShipCabinLeftDummy4,
kImageShipCabinLeftDummy5,
kImageShipCabinLeftDummy6,
kImageShipCabinLeftDummy7,
kImageShipCabinLeftDummy8,
kImageShipCabinLeftDummy9,
kImageShipCabinLeftDummy10,
kImageShipCabinLeftDummy11,
kImageShipCabinLeftDummy12,
// file 22
kImageShipCabinRightBackground,
kImageShipCabinRightPosterSnowman,
kImageShipCabinRightTableStuff,
kImageShipCabinRightCeilingChess,
kImageShipCabinRightTennisRacket,
kImageShipCabinRightTennisBallsFloating,
kImageShipCabinRightTennisBallsOnGround,
kImageShipCabinRightTableChess,
kImageShipCabinRight2Bed,
kImageShipCabinRightLockerBooksOpen,
kImageShipCabinRightLockerRopeOpen,
kImageShipCabinRightLockerOpen,
kImageShipCabinRightLockerRopeRemoved,
kImageShipCabinRightBedSafeOpen,
kImageShipCabinRightBedSafeEmpty,
kImageShipCabinRightDoorClosed,
kImageShipCabinRightLockerDiscmanRemoved,
kImageShipCabinRightDummy1,
kImageShipCabinRightDummy2,
// file 23
kImageShipBathroomBackground,
// file 24
kImageShipHoldBackgroundFloating,
kImageShipHoldBackgroundOnGround,
kImageShipHoldLandingModuleDoorOpen,
kImageShipHoldGeneratorHatchOpen,
kImageShipHoldLandingModuleSpool,
kImageShipHoldCableToGeneratorUnplugged,
kImageShipHoldCableToGeneratorPluggedIn,
kImageShipHoldDummy1,
kImageShipHoldDummy2,
// file 25
kImageShipLandingModuleBackground,
kImageShipLandingModuleDoorClosed,
kImageShipLandingModuleDisplayLeftOn,
kImageShipLandingModuleCablePluggedIn,
kImageShipLandingModuleCableSpoolConnected,
kImageShipLandingModuleCableToHold,
kImageShipLandingModuleDisplayRightOn,
kImageShipLandingModuleDisplayTop1On,
kImageShipLandingModuleDisplayTop2On,
kImageShipLandingModuleDisplayTop3On,
kImageShipLandingModuleCableWithTerminalStrip,
kImageShipLandingModuleDummy1,
kImageShipLandingModuleDummy2,
kImageShipLandingModuleDummy3,
kImageShipLandingModuleDummy4,
kImageShipLandingModuleDummy5,
kImageShipLandingModuleDummy6,
kImageShipLandingModuleDummy7,
kImageShipLandingModuleDummy8,
// file 26
kImageArsanoStar,
// file 27
kImageSaveLoadScreen,
// file 28
kImageRestaurantBackground,
kImageRestaurantAnimation1,
kImageRestaurantAnimation2,
kImageRestaurantAnimation3,
kImageRestaurantAnimation4,
kImageRestaurantAnimation5,
kImageRestaurantAnimation6,
kImageRestaurantAnimation7,
kImageRestaurantAnimation8,
kImageRestaurantAnimation9,
kImageRestaurantAnimation10,
kImageRestaurantAnimation11,
kImageRestaurantAnimation12,
kImageRestaurantAnimation13,
kImageRestaurantAnimation14,
kImageRestaurantAnimation15,
kImageRestaurantAnimation16,
kImageRestaurantAnimation17,
kImageRestaurantAnimation18,
kImageRestaurantAnimation19,
kImageRestaurantAnimation20,
kImageRestaurantAnimation21,
kImageRestaurantAnimation22,
// file 29
kImageRestaurantRogerBackground,
kImageRestaurantRogerEyes1Closed,
kImageRestaurantRogerMouthOpen,
kImageRestaurantRogerPlayingChess,
kImageRestaurantRogerWalletRemoved,
kImageRestaurantRogerHandAnimation1,
kImageRestaurantRogerHandAnimation2,
kImageRestaurantRogerHandAnimation3,
kImageRestaurantRogerHandAnimation4,
kImageRestaurantRogerHandAnimation5,
kImageRestaurantRogerEyes2Closed,
kImageRestaurantRogerChessBoard,
kImageRestaurantRogerEyes2Open,
kImageRestaurantRogerDummy1,
// file 30
kImageRogerOutsideBackground,
kImageRogerOutsideMouthOpen,
// file 31
kImageIntroScreenBackground,
kImageIntroScreenShipAnimation1,
kImageIntroScreenShipAnimation2,
kImageIntroScreenShipAnimation3,
kImageIntroScreenShipAnimation4,
kImageIntroScreenShipAnimation5,
kImageIntroScreenShipAnimation6,
// file 32
kImageBusStationSignBackground,
kImageBusStationSignPrice,
kImageBusStationSignPleaseWait,
kImageBusStationSignPleasantFlight,
// file 33
kImageShipSleepCabinBackground,
kImageShipSleepCabinTerminalWarning,
kImageShipSleepCabinTerminal1,
kImageShipSleepCabinTerminal2,
kImageShipSleepCabinStatusLight,
kImageShipSleepCabinTerminal3,
// file 34
kImageShipAirlockBackground,
kImageShipAirlockDoorLeftAnimation1,
kImageShipAirlockDoorLeftAnimation2,
kImageShipAirlockDoorLeftAnimation3,
kImageShipAirlockDoorRightAnimation1,
kImageShipAirlockDoorRightAnimation2,
kImageShipAirlockDoorRightAnimation3,
kImageShipAirlockHelmetRemoved,
kImageShipAirlockSpacesuitRemoved,
kImageShipAirlockSupplyRemoved,
kImageShipAirlockDoorLeftButton,
kImageShipAirlockDoorRightButton,
kImageShipAirlockManometerAnimation1,
kImageShipAirlockManometerAnimation2,
kImageShipAirlockManometerAnimation3,
kImageShipAirlockManometerAnimation4,
kImageShipAirlockManometerAnimation5,
kImageShipAirlockManometerAnimation6,
// file 35
kImageAxacussSpaceBackground,
kImageAxacussSpaceShipAnimation1,
kImageAxacussSpaceShipAnimation2,
kImageAxacussSpaceShipAnimation3,
kImageAxacussSpaceShipAnimation4,
kImageAxacussSpaceShipAnimation5,
kImageAxacussSpaceShipAnimation6,
kImageAxacussSpaceShipAnimation7,
kImageAxacussSpaceBusAnimation1,
kImageAxacussSpaceBusAnimation2,
kImageAxacussSpaceBusAnimation3,
kImageAxacussSpaceBusAnimation4,
kImageAxacussSpaceBusAnimation5,
kImageAxacussSpaceBusAnimation6,
kImageAxacussSpaceBusAnimation7,
kImageAxacussSpaceBusAnimation8,
kImageAxacussSpaceBusAnimation9,
kImageAxacussSpaceBusAnimation10,
kImageAxacussSpaceBusAnimation11,
kImageAxacussSpaceBusAnimation12,
kImageAxacussSpaceBusAnimation13,
kImageAxacussSpaceBusAnimation14,
// file 36
kImageAxacussanCapsuleBackground,
kImageAxacussanCapsuleRobotAnimation1,
kImageAxacussanCapsuleRobotAnimation2,
kImageAxacussanCapsuleRobotAnimation3,
kImageAxacussanCapsuleRobotAnimation4,
kImageAxacussanCapsuleDummy1,
// file 37
kImageArsanoMeetupBackground,
kImageArsanoMeetupRestaurantLightAnimation1,
kImageArsanoMeetupRestaurantLightAnimation2,
kImageArsanoMeetupRestaurantLightAnimation3,
kImageArsanoMeetupRestaurantLightAnimation4,
kImageArsanoMeetupRestaurantLightAnimation5,
kImageArsanoMeetupRestaurantDoorAnimation1,
kImageArsanoMeetupRestaurantDoorAnimation2,
kImageArsanoMeetupRestaurantDoorSignAnimation1,
kImageArsanoMeetupRestaurantDoorSignAnimation2,
kImageArsanoMeetupRestaurantDoorSignAnimation3,
kImageArsanoMeetupRestaurantDoorSignAnimation4,
kImageArsanoMeetupRestaurantDoorSignAnimation5,
kImageArsanoMeetupRestaurantSignAnimation1,
kImageArsanoMeetupRestaurantSignAnimation2,
kImageArsanoMeetupRestaurantSignAnimation3,
kImageArsanoMeetupRestaurantSignAnimation4,
kImageArsanoMeetupRestaurantSignAnimation5,
kImageArsanoMeetupRestaurantSignAnimation6,
kImageArsanoMeetupRestaurantSignAnimation7,
kImageArsanoMeetupRestaurantSignAnimation8,
kImageArsanoMeetupRestaurantSignAnimation9,
kImageArsanoMeetupRestaurantSignAnimation10,
kImageArsanoMeetupRestaurantSignAnimation11,
kImageArsanoMeetupRestaurantSignAnimation12,
kImageArsanoMeetupRestaurantSignAnimation13,
kImageArsanoMeetupRestaurantSignAnimation14,
// file 38
kImageArsanoAfterNovaBackground,
kImageArsanoAfterNovaRogerShipAnimation1,
kImageArsanoAfterNovaRogerShipAnimation2,
kImageArsanoAfterNovaRogerShipAnimation3,
kImageArsanoAfterNovaRogerShipAnimation4,
kImageArsanoAfterNovaRogerShipAnimation5,
kImageArsanoAfterNovaRogerShipAnimation6,
kImageArsanoAfterNovaRogerShipAnimation7,
kImageArsanoAfterNovaRogerShipAnimation8,
kImageArsanoAfterNovaRogerShipAnimation9,
kImageArsanoAfterNovaRogerShipAnimation10,
kImageArsanoAfterNovaRogerShipAnimation11,
kImageArsanoAfterNovaRoger,
// file 39
kImageArsanoDesolate,
// file 40
kImageIntersectionBackground,
kImageIntersectionGuardRemoved,
kImageIntersectionGuardMouthOpen,
kImageIntersectionGuardShootAnimation1,
kImageIntersectionGuardShootAnimation2,
kImageIntersectionGuardMouthClosed,
kImageIntersectionDoorOpen,
kImageIntersectoinKeycard,
// file 41
kImageInformationDeskBackground,
kImageInformationDeskAlienMouthOpen,
kImageInformationDeskAlienHandMoved,
kImageInformationDeskAlienShoot,
// file 42
kImageArtGalleryBackground,
kImageArtGalleryAlienShootAnimation1,
kImageArtGalleryAlienShootAnimation2,
kImageArtGalleryAlienShootAnimation3,
kImageArtGalleryThrowingBlockAnimation1,
kImageArtGalleryThrowingBlockAnimation2,
kImageArtGalleryThrowingBlockAnimation3,
kImageArtGalleryThrowingBlockAnimation4,
kImageArtGalleryThrowingBlockAnimation5,
kImageArtGalleryThrowingBlockAnimation6,
kImageArtGalleryThrowingBlockAnimation7,
kImageArtGalleryDummy1,
// file 43
kImageCellBackground,
kImageCellCablePluggedIn,
kImageCellCableUnplugged,
kImageCellCableCutUnplugged,
kImageCellCableCutPluggedIn,
kImageCellCableCutTableUnplugged,
kImageCellCableCutTablePluggedIn,
kImageCellTableTablet,
kImageCellRobotComesAnimation1,
kImageCellRobotComesAnimation2,
kImageCellRobotComesAnimation3,
kImageCellRobotComesAnimation4,
kImageCellRobotComesAnimation5,
kImageCellRobotComesAnimation6,
kImageCellRobotComesAnimation7,
kImageCellRobotComesAnimation8,
kImageCellRobotComesAnimation9,
kImageCellRobotComesAnimation10,
kImageCellRobotComesAnimation11,
kImageCellRobotLeavesAnimation1,
kImageCellRobotLeavesAnimation2,
kImageCellRobotLeavesAnimation3,
kImageCellRobotLeavesAnimation4,
kImageCellRobotLeavesAnimation5,
kImageCellRobotLeavesAnimation6,
kImageCellRobotLeavesAnimation7,
kImageCellRobotLeavesAnimation8,
kImageCellRobotLeavesAnimation9,
kImageCellRobotSparks,
kImageCellRobotBroken,
kImageCellDoorClosed,
kImageCellDummy1,
// file 55
kImageOutroScreen
};
}
#endif

View File

@@ -0,0 +1,425 @@
/* 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/file.h"
#include "common/savefile.h"
#include "common/system.h"
#include "common/translation.h"
#include "graphics/thumbnail.h"
#include "engines/advancedDetector.h"
#include "supernova/supernova.h"
#include "supernova/detection.h"
#include "backends/keymapper/action.h"
#include "backends/keymapper/keymapper.h"
#include "backends/keymapper/standard-actions.h"
static const ADExtraGuiOptionsMap optionsList[] = {
{
GAMEOPTION_IMPROVED,
{
_s("Improved mode"),
_s("Removes some repetitive actions, adds possibility to change verbs by keyboard"),
"improved",
true,
0,
0
}
},
{
GAMEOPTION_TTS,
{
_s("Enable Text to Speech"),
_s("Use TTS to read the descriptions (if TTS is available)"),
"tts_enabled",
false,
0,
0
}
},
AD_EXTRA_GUI_OPTIONS_TERMINATOR
};
class SupernovaMetaEngine : public AdvancedMetaEngine<ADGameDescription> {
public:
const char *getName() const override {
return "supernova";
}
const ADExtraGuiOptionsMap *getAdvancedExtraGuiOptions() const override {
return optionsList;
}
bool hasFeature(MetaEngineFeature f) const override;
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
SaveStateList listSaves(const char *target) const override;
bool removeSaveState(const char *target, int slot) const override;
int getMaximumSaveSlot() const override {
return 99;
}
SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override;
Common::String getSavegameFile(int saveGameIdx, const char *target) const override {
const char *prefix = target;
if (!strncmp(target, "msn1", 4))
prefix = "msn_save";
if (!strncmp(target, "msn2", 4))
prefix = "ms2_save";
if (saveGameIdx == kSavegameFilePattern)
return Common::String::format("%s.###", prefix);
else
return Common::String::format("%s.%03d", prefix, saveGameIdx);
}
Common::KeymapArray initKeymaps(const char *target) const override;
};
bool SupernovaMetaEngine::hasFeature(MetaEngineFeature f) const {
switch (f) {
case kSupportsLoadingDuringStartup:
case kSupportsListSaves:
case kSupportsDeleteSave:
case kSavesSupportMetaInfo:
case kSavesSupportThumbnail:
case kSavesSupportCreationDate:
case kSavesSupportPlayTime:
return true;
default:
return false;
}
}
Common::Error SupernovaMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
*engine = new Supernova::SupernovaEngine(syst);
return Common::kNoError;
}
SaveStateList SupernovaMetaEngine::listSaves(const char *target) const {
Common::StringArray filenames;
const Common::String pattern = getSavegameFilePattern(target);
filenames = g_system->getSavefileManager()->listSavefiles(pattern);
SaveStateList saveFileList;
for (Common::StringArray::const_iterator file = filenames.begin();
file != filenames.end(); ++file) {
int saveSlot = atoi(file->c_str() + file->size() - 3);
if (saveSlot >= 0 && saveSlot <= getMaximumSaveSlot()) {
Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(*file);
if (savefile) {
uint saveHeader = savefile->readUint32LE();
if ((saveHeader == SAVEGAME_HEADER && !strncmp(target, "msn1", 4)) ||
(saveHeader == SAVEGAME_HEADER2 && !strncmp(target, "msn2", 4))) {
byte saveVersion = savefile->readByte();
if (saveVersion <= SAVEGAME_VERSION) {
int saveFileDescSize = savefile->readSint16LE();
char* saveFileDesc = new char[saveFileDescSize];
savefile->read(saveFileDesc, saveFileDescSize);
saveFileList.push_back(SaveStateDescriptor(this, saveSlot, saveFileDesc));
delete [] saveFileDesc;
}
}
delete savefile;
}
}
}
Common::sort(saveFileList.begin(), saveFileList.end(), SaveStateDescriptorSlotComparator());
return saveFileList;
}
bool SupernovaMetaEngine::removeSaveState(const char *target, int slot) const {
return g_system->getSavefileManager()->removeSavefile(getSavegameFile(slot, target));
}
SaveStateDescriptor SupernovaMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(getSavegameFile(slot, target));
if (savefile) {
uint saveHeader = savefile->readUint32LE();
if ((!strncmp(target, "msn1", 4) && saveHeader != SAVEGAME_HEADER) ||
(!strncmp(target, "msn2", 4) && saveHeader != SAVEGAME_HEADER2)) {
delete savefile;
return SaveStateDescriptor();
}
byte saveVersion = savefile->readByte();
if (saveVersion > SAVEGAME_VERSION){
delete savefile;
return SaveStateDescriptor();
}
int descriptionSize = savefile->readSint16LE();
char* description = new char[descriptionSize];
savefile->read(description, descriptionSize);
SaveStateDescriptor desc(this, slot, description);
delete [] description;
uint32 saveDate = savefile->readUint32LE();
int day = (saveDate >> 24) & 0xFF;
int month = (saveDate >> 16) & 0xFF;
int year = saveDate & 0xFFFF;
desc.setSaveDate(year, month, day);
uint16 saveTime = savefile->readUint16LE();
int hour = (saveTime >> 8) & 0xFF;
int minutes = saveTime & 0xFF;
desc.setSaveTime(hour, minutes);
uint32 playTime =savefile->readUint32LE();
desc.setPlayTime(playTime * 1000);
if (Graphics::checkThumbnailHeader(*savefile)) {
Graphics::Surface *thumbnail;
if (!Graphics::loadThumbnail(*savefile, thumbnail)) {
delete savefile;
return SaveStateDescriptor();
}
desc.setThumbnail(thumbnail);
}
delete savefile;
return desc;
}
return SaveStateDescriptor();
}
Common::KeymapArray SupernovaMetaEngine::initKeymaps(const char *target) const {
using namespace Common;
using namespace Supernova;
Common::String gameId = ConfMan.get("gameid", target);
Keymap *engineKeymap = new Keymap(Keymap::kKeymapTypeGame, "supernova-default", _("Default keymappings"));
Keymap *menuKeymap = new Keymap(Keymap::kKeymapTypeGame, "menu", _("Menu keymappings"));
Keymap *cutsceneKeymap = new Keymap(Keymap::kKeymapTypeGame, "cutscene", _("Cutscene keymappings"));
Keymap *improvedKeymap = new Keymap(Keymap::kKeymapTypeGame, "improved-mode", _("Improved mode keymappings"));
Keymap *textReaderKeymap = new Keymap(Keymap::kKeymapTypeGame, "text-reader", _("Text reader keymappings"));
Keymap *computerKeymap = new Keymap(Keymap::kKeymapTypeGame, "computer", _("Computer keymappings"));
Common::Action *act;
act = new Common::Action(kStandardActionLeftClick, _("Interact"));
act->setLeftClickEvent();
act->addDefaultInputMapping("MOUSE_LEFT");
act->addDefaultInputMapping("JOY_A");
engineKeymap->addAction(act);
act = new Common::Action(kStandardActionRightClick, _("Perform default action"));
act->setRightClickEvent();
act->addDefaultInputMapping("MOUSE_RIGHT");
act->addDefaultInputMapping("JOY_B");
engineKeymap->addAction(act);
act = new Common::Action("HELP", _("Help"));
act->setCustomEngineActionEvent(kActionHelp);
act->addDefaultInputMapping("F1");
act->addDefaultInputMapping("JOY_LEFT");
engineKeymap->addAction(act);
act = new Common::Action("INSTRUCTIONS", _("Instructions"));
act->setCustomEngineActionEvent(kActionInstr);
act->addDefaultInputMapping("F2");
act->addDefaultInputMapping("JOY_RIGHT");
engineKeymap->addAction(act);
act = new Common::Action("INFORMATION", _("Information"));
act->setCustomEngineActionEvent(kActionInfo);
act->addDefaultInputMapping("F3");
act->addDefaultInputMapping("JOY_UP");
engineKeymap->addAction(act);
act = new Common::Action("TEXTSPEED", _("Text speed"));
act->setCustomEngineActionEvent(kActionSpeed);
act->addDefaultInputMapping("F4");
act->addDefaultInputMapping("JOY_DOWN");
engineKeymap->addAction(act);
act = new Common::Action("PAUSE", _("Pause"));
act->setCustomEngineActionEvent(kActionPause);
act->addDefaultInputMapping("F5");
engineKeymap->addAction(act);
act = new Common::Action("QUIT", _("Quit"));
act->setCustomEngineActionEvent(kActionQuit);
act->addDefaultInputMapping("A+x");
act->addDefaultInputMapping("JOY_Y");
engineKeymap->addAction(act);
act = new Common::Action("UP", _("Up"));
act->setCustomEngineActionEvent(kActionUp);
act->addDefaultInputMapping("UP");
act->addDefaultInputMapping("JOY_UP");
textReaderKeymap->addAction(act);
act = new Common::Action("DOWN", _("Down"));
act->setCustomEngineActionEvent(kActionDown);
act->addDefaultInputMapping("DOWN");
act->addDefaultInputMapping("JOY_DOWN");
textReaderKeymap->addAction(act);
act = new Common::Action("PGUP", _("Previous page"));
act->setCustomEngineActionEvent(kActionPgUp);
act->addDefaultInputMapping("PAGEUP");
act->addDefaultInputMapping("JOY_RIGHT_SHOULDER");
textReaderKeymap->addAction(act);
act = new Common::Action("PGDOWN", _("Next page"));
act->setCustomEngineActionEvent(kActionPgDown);
act->addDefaultInputMapping("PAGEDOWN");
act->addDefaultInputMapping("JOY_LEFT_SHOULDER");
textReaderKeymap->addAction(act);
act = new Common::Action("EXIT", _("Exit"));
act->setCustomEngineActionEvent(kActionExit);
act->addDefaultInputMapping("ESCAPE");
act->addDefaultInputMapping("JOY_B");
textReaderKeymap->addAction(act);
act = new Common::Action("SELECT", _("Select"));
act->setLeftClickEvent();
act->addDefaultInputMapping("MOUSE_LEFT");
act->addDefaultInputMapping("JOY_A");
menuKeymap->addAction(act);
act = new Common::Action("SKIP", _("Skip cutscene"));
act->setCustomEngineActionEvent(kActionSkip);
act->addDefaultInputMapping("ESCAPE");
act->addDefaultInputMapping("JOY_B");
cutsceneKeymap->addAction(act);
act = new Common::Action("SKPL", _("Skip line"));
act->setCustomEngineActionEvent(kActionSkipLine);
act->addDefaultInputMapping("SPACE");
act->addDefaultInputMapping("JOY_A");
cutsceneKeymap->addAction(act);
act = new Common::Action("GO", _("Go"));
act->setCustomEngineActionEvent(kActionGo);
act->addDefaultInputMapping("1");
improvedKeymap->addAction(act);
act = new Common::Action("LOOK", _("Look"));
act->setCustomEngineActionEvent(kActionLook);
act->addDefaultInputMapping("2");
improvedKeymap->addAction(act);
act = new Common::Action("TAKE", _("Take"));
act->setCustomEngineActionEvent(kActionTake);
act->addDefaultInputMapping("3");
improvedKeymap->addAction(act);
act = new Common::Action("OPEN", _("Open"));
act->setCustomEngineActionEvent(kActionOpen);
act->addDefaultInputMapping("4");
improvedKeymap->addAction(act);
act = new Common::Action("CLOSE", _("Close"));
act->setCustomEngineActionEvent(kActionClose);
act->addDefaultInputMapping("5");
improvedKeymap->addAction(act);
act = new Common::Action("PUSH", _("Push"));
act->setCustomEngineActionEvent(kActionPush);
act->addDefaultInputMapping("6");
improvedKeymap->addAction(act);
act = new Common::Action("PULL", _("Pull"));
act->setCustomEngineActionEvent(kActionPull);
act->addDefaultInputMapping("7");
improvedKeymap->addAction(act);
act = new Common::Action("USE", _("Use"));
act->setCustomEngineActionEvent(kActionUse);
act->addDefaultInputMapping("8");
improvedKeymap->addAction(act);
act = new Common::Action("TALK", _("Talk"));
act->setCustomEngineActionEvent(kActionTalk);
act->addDefaultInputMapping("9");
improvedKeymap->addAction(act);
act = new Common::Action("GIVE", _("Give"));
act->setCustomEngineActionEvent(kActionGive);
act->addDefaultInputMapping("0");
improvedKeymap->addAction(act);
if (gameId == "msn1") {
act = new Common::Action("EXIT", _("Exit"));
act->setCustomEngineActionEvent(kActionExit);
act->addDefaultInputMapping("ESCAPE");
act->addDefaultInputMapping("JOY_B");
computerKeymap->addAction(act);
act = new Common::Action("OFFICE", _("Office manager"));
act->setCustomEngineActionEvent(kActionOfficeManager);
act->addDefaultInputMapping("1");
act->addDefaultInputMapping("JOY_LEFT");
computerKeymap->addAction(act);
act = new Common::Action("PHONE", _("Phone"));
act->setCustomEngineActionEvent(kActionPhone);
act->addDefaultInputMapping("2");
act->addDefaultInputMapping("JOY_UP");
computerKeymap->addAction(act);
act = new Common::Action("PROTEXT", _("ProText"));
act->setCustomEngineActionEvent(kActionProText);
act->addDefaultInputMapping("3");
act->addDefaultInputMapping("JOY_RIGHT");
computerKeymap->addAction(act);
act = new Common::Action("CALCULATA", _("Calculata"));
act->setCustomEngineActionEvent(kActionCalculata);
act->addDefaultInputMapping("4");
act->addDefaultInputMapping("JOY_DOWN");
computerKeymap->addAction(act);
}
Common::KeymapArray keymaps(6);
keymaps[0] = engineKeymap;
keymaps[1] = menuKeymap;
keymaps[2] = cutsceneKeymap;
keymaps[3] = improvedKeymap;
keymaps[4] = textReaderKeymap;
keymaps[5] = computerKeymap;
menuKeymap->setEnabled(false);
cutsceneKeymap->setEnabled(false);
textReaderKeymap->setEnabled(false);
computerKeymap->setEnabled(false);
return keymaps;
}
#if PLUGIN_ENABLED_DYNAMIC(SUPERNOVA)
REGISTER_PLUGIN_DYNAMIC(SUPERNOVA, PLUGIN_TYPE_ENGINE, SupernovaMetaEngine);
#else
REGISTER_PLUGIN_STATIC(SUPERNOVA, PLUGIN_TYPE_ENGINE, SupernovaMetaEngine);
#endif

View File

@@ -0,0 +1,30 @@
MODULE := engines/supernova
MODULE_OBJS := \
console.o \
graphics.o \
metaengine.o \
resman.o \
room.o \
supernova1/rooms.o \
supernova2/rooms.o \
screen.o \
sound.o \
game-manager.o \
supernova1/state.o \
supernova2/state.o \
supernova.o
MODULE_DIRS += \
engines/supernova
# This module can be built as a plugin
ifeq ($(ENABLE_SUPERNOVA), DYNAMIC_PLUGIN)
PLUGIN := 1
endif
# Include common rules
include $(srcdir)/rules.mk
# Detection objects
DETECT_OBJS += $(MODULE)/detection.o

277
engines/supernova/msn_def.h Normal file
View File

@@ -0,0 +1,277 @@
/* 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 SUPERNOVA_MSN_DEF_H
#define SUPERNOVA_MSN_DEF_H
// Avoid error on expansion of macro switch in the ObjectID enum below
#ifdef SWITCH
#undef SWITCH
#endif
#include "common/scummsys.h"
namespace Supernova {
const int kTextSpeed[] = {19, 14, 10, 7, 4};
const int kMsecPerTick = 55;
const int kMaxSection = 40;
const int kMaxDialog = 2;
const int kMaxObject = 30;
const int kMaxCarry = 30;
const int kSleepAutosaveSlot = 999;
const byte kShownFalse = 0;
const byte kShownTrue = 1;
const byte kSectionInvert = 128;
enum MessagePosition {
kMessageNormal,
kMessageLeft,
kMessageRight,
kMessageCenter,
kMessageTop
};
enum ObjectType {
NULLTYPE = 0,
TAKE = 1,
OPENABLE = 2,
OPENED = 4,
CLOSED = 8,
EXIT = 16,
PRESS = 32,
COMBINABLE = 64,
CARRIED = 128,
UNNECESSARY = 256,
WORN = 512,
TALK = 1024,
OCCUPIED = 2048,
CAUGHT = 4096
};
typedef uint16 ObjectTypes;
enum Action {
ACTION_WALK,
ACTION_LOOK,
ACTION_TAKE,
ACTION_OPEN,
ACTION_CLOSE,
ACTION_PRESS,
ACTION_PULL,
ACTION_USE,
ACTION_TALK,
ACTION_GIVE
};
enum RoomId {
// Supernova 1
INTRO1,CORRIDOR_ROOM,HALL,SLEEP,COCKPIT,AIRLOCK,
HOLD,LANDINGMODULE,GENERATOR,OUTSIDE,
CABIN_R1,CABIN_R2,CABIN_R3,CABIN_L1,CABIN_L2,CABIN_L3,BATHROOM,
ROCKS,CAVE,MEETUP,ENTRANCE,REST,ROGER,GLIDER,MEETUP2,MEETUP3,
CELL,CORRIDOR1,CORRIDOR2,CORRIDOR3,CORRIDOR4,CORRIDOR5,CORRIDOR6,CORRIDOR7,CORRIDOR8,CORRIDOR9,
BCORRIDOR,GUARD,GUARD3,OFFICE_L1,OFFICE_L2,OFFICE_R1,OFFICE_R2,OFFICE_L,
ELEVATOR,STATION,SIGN_ROOM,OUTRO,NUMROOMS1,
// Supernova 2
INTRO2 = 0,AIRPORT,TAXISTAND,STREET,GAMES,CABIN2,KIOSK,
CULTURE_PALACE,CHECKOUT,CITY1,CITY2,ELEVATOR2,APARTMENT,SHIP,
PYRAMID,PYR_ENTRANCE,UPSTAIRS1,DOWNSTAIRS1,
BOTTOM_RIGHT_DOOR,BOTTOM_LEFT_DOOR,UPSTAIRS2,DOWNSTAIRS2,
UPPER_DOOR,PUZZLE_FRONT,PUZZLE_BEHIND,
FORMULA1_F,FORMULA1_N,FORMULA2_F,FORMULA2_N,TOMATO_F,TOMATO_N,
MONSTER_F,MONSTER1_N,MONSTER2_N,UPSTAIRS3,DOWNSTAIRS3,
LCORRIDOR1,LCORRIDOR2,HOLE_ROOM,IN_HOLE,FLOORDOOR,FLOORDOOR_U,
BST_DOOR,HALL2,COFFIN_ROOM,MASK,
MUSEUM,MUS_ENTRANCE,MUS1,MUS2,MUS3,MUS4,MUS5,MUS6,MUS7,MUS8,
MUS9,MUS10,MUS11,MUS_ROUND,
MUS12,MUS13,MUS14,MUS15,MUS16,MUS17,MUS18,MUS19,MUS20,MUS21,MUS22,
NUMROOMS2,NULLROOM
};
enum ObjectId {
INVALIDOBJECT = -1,
NULLOBJECT = 0,
// Supernova 1
KEYCARD,KNIFE,WATCH,
SOCKET,
BUTTON,HATCH1,
BUTTON1,BUTTON2,MANOMETER,SUIT,HELMET,LIFESUPPORT,
SCRAP_LK,OUTERHATCH_TOP,GENERATOR_TOP,TERMINALSTRIP,LANDINGMOD_OUTERHATCH,
HOLD_WIRE,
LANDINGMOD_BUTTON,LANDINGMOD_SOCKET,LANDINGMOD_WIRE,LANDINGMOD_HATCH,LANDINGMOD_MONITOR,
KEYBOARD,
KEYCARD2,OUTERHATCH,GENERATOR_WIRE,TRAP,SHORT_WIRE,CLIP,
VOLTMETER,LADDER,GENERATOR_ROPE,
KITCHEN_HATCH,SLEEP_SLOT,
MONITOR,INSTRUMENTS,
COMPUTER,CABINS,CABIN,
SLOT_K1,SLOT_K2,SLOT_K3,SLOT_K4,
SHELF1,SHELF2,SHELF3,SHELF4,
ROPE,BOOK,DISCMAN,CHESS,
SLOT_KL1,SLOT_KL2,SLOT_KL3,SLOT_KL4,
SHELF_L1,SHELF_L2,SHELF_L3,SHELF_L4,
PISTOL,BOOK2,SPOOL,
RECORD,TURNTABLE,TURNTABLE_BUTTON,WIRE,WIRE2,PLUG,
PEN,
BATHROOM_DOOR,BATHROOM_EXIT,SHOWER,TOILET,
STONE,
SPACESHIPS,SPACESHIP,STAR,DOOR,MEETUP_SIGN,
PORTER,BATHROOM_BUTTON,BATHROOM_SIGN,KITCHEN_SIGN,CAR_SLOT,
ARSANO_BATHROOM,COINS,SCHNUCK,EGG,PILL,PILL_HULL,STAIRCASE,
MEETUP_EXIT,
ROGER_W,WALLET,KEYCARD_R,CUP,
GLIDER_BUTTON1,GLIDER_BUTTON2,GLIDER_BUTTON3,GLIDER_BUTTON4,GLIDER_SLOT,GLIDER_BUTTONS,
GLIDER_DISPLAY,GLIDER_INSTRUMENTS,GLIDER_KEYCARD,
UFO,
CELL_BUTTON,CELL_TABLE,CELL_WIRE,TRAY,CELL_DOOR,MAGNET,
NEWSPAPER,TABLE,
PILLAR1,PILLAR2,DOOR1,DOOR2,DOOR3,DOOR4,
GUARDIAN,LAMP,
MASTERKEYCARD,PAINTING,MONEY,LOCKER,LETTER,
JUNGLE,STATION_SLOT,STATION_SIGN,
// Supernova2
TAXI,TRANSMITTER,ROD,OCCUPIED_CABIN,
SLOT1,CHAIR,CORRIDOR,G_RIGHT,G_LEFT,PYRA_ENTRANCE,
PART0,PART1,PART2,PART3,PART4,PART5,PART6,PART7,
PART8,PART9,PART10,PART11,PART12,PART13,PART14,PART15,
TKNIFE,NOTE,MOUTH,
HOLE1,HOLE2,HOLE3,HOLE4,HOLE5,HOLE6,HOLE7,HOLE8,HOLE9,HOLE10,
HOLE11,HOLE12,HOLE13,HOLE14,HOLE15,HOLE16,HOLE17,HOLE18,HOLE19,HOLE20,
HOLE21,HOLE22,HOLE23,HOLE24,HOLE25,SIGN,
SLOT,HOLE,STONES,
BST1,BST2,BST3,BST4,BST5,BST6,BST7,BST8,
BST9,BST10,BST11,BST12,BST13,BST14,BST15,BST16,
COFFIN,SUN,MONSTER,EYE,EYE1,EYE2,L_BALL,R_BALL,
PRIZE,REAR_STREET,
BMASK,BOTTLE,PLAYER,TOOTHBRUSH,BOOKS,LEXICON,PLANT,SNAKE,
JOYSTICK,BOTTLE1,BOTTLE2,BOTTLE3,BOTTLE4,BOX,FACES,
SELLER,POSTER,AXACUSSER,KP_ENTRANCE,CHIP,CARD,
SCRIBBLE1,SCRIBBLE2,BELL,KEYPAD,DOOR_L,DOOR_R,ID_CARD,
UNDER_BED,KEY,HATCH,CABINET,
SMALL_DOOR,BACK_MONEY,WALL,SUCTION_CUP,IMITATION,SP_KEYCARD,ALARM_CRACKER,
ENCRYPTED_DOOR,ALARM_SYSTEM,MUS_STREET,BIG_DOOR,MUSIC_SYSTEM,
HANDLE,SWITCH,DOOR_SWITCH,CABLE,RCABLE,
MUSCARD,HEAD, DISPLAY
};
enum StringId {
kNoString = -1,
// 0
kStringCommandGo = 0, kStringCommandLook, kStringCommandTake, kStringCommandOpen, kStringCommandClose,
kStringCommandPress, kStringCommandPull, kStringCommandUse, kStringCommandTalk, kStringCommandGive,
kStringStatusCommandGo, kStringStatusCommandLook, kStringStatusCommandTake, kStringStatusCommandOpen, kStringStatusCommandClose,
kStringStatusCommandPress, kStringStatusCommandPull, kStringStatusCommandUse, kStringStatusCommandTalk, kStringStatusCommandGive,
kPhrasalVerbParticleGiveTo, kPhrasalVerbParticleUseWith, kStringDefaultDescription, kStringDialogSeparator, kStringConversationEnd,
// 25
kStringHelpOverview1, kStringHelpOverview2, kStringHelpOverview3, kStringHelpOverview4, kStringHelpOverview5,
kStringHelpOverview6, kStringHelpOverview7, kStringTextSpeed, kStringLeaveGame, kStringYes,
kStringNo
};
ObjectType operator|(ObjectType a, ObjectType b);
ObjectType operator&(ObjectType a, ObjectType b);
ObjectType operator^(ObjectType a, ObjectType b);
ObjectType &operator|=(ObjectType &a, ObjectType b);
ObjectType &operator&=(ObjectType &a, ObjectType b);
ObjectType &operator^=(ObjectType &a, ObjectType b);
struct Object {
Object()
: _name(kNoString)
, _description(kStringDefaultDescription)
, _id(INVALIDOBJECT)
, _roomId(NULLROOM)
, _type(NULLTYPE)
, _click(0)
, _click2(0)
, _section(0)
, _exitRoom(NULLROOM)
, _direction(0)
{}
Object(byte roomId, int name, int description, ObjectId id, ObjectType type,
byte click, byte click2, byte section = 0, RoomId exitRoom = NULLROOM, byte direction = 0)
: _name(name)
, _description(description)
, _id(id)
, _roomId(roomId)
, _type(type)
, _click(click)
, _click2(click2)
, _section(section)
, _exitRoom(exitRoom)
, _direction(direction)
{}
void resetProperty(ObjectType type = NULLTYPE) {
_type = type;
}
void setProperty(ObjectType type) {
_type |= type;
}
void disableProperty(ObjectType type) {
_type &= ~type;
}
bool hasProperty(ObjectType type) const {
return _type & type;
}
static bool combine(Object &obj1, Object &obj2, ObjectId id1, ObjectId id2) {
if (obj1.hasProperty(COMBINABLE))
return (((obj1._id == id1) && (obj2._id == id2)) ||
((obj1._id == id2) && (obj2._id == id1)));
else
return false;
}
byte _roomId;
int _name;
int _description;
ObjectId _id;
ObjectTypes _type;
byte _click;
byte _click2;
byte _section;
RoomId _exitRoom;
byte _direction;
};
#define ticksToMsec(x) (x * kMsecPerTick)
}
#endif // SUPERNOVA_MSN_DEF_H

View File

@@ -0,0 +1,563 @@
/* 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 "audio/audiostream.h"
#include "audio/decoders/raw.h"
#include "audio/mixer.h"
#include "audio/mods/protracker.h"
#include "common/memstream.h"
#include "common/system.h"
#include "graphics/cursorman.h"
#include "supernova/graphics.h"
#include "supernova/resman.h"
#include "supernova/screen.h"
#include "supernova/supernova.h"
namespace Supernova {
struct AudioInfo {
int _filenumber;
int _offsetStart;
int _offsetEnd;
};
static Common::MemoryReadStream *convertToMod(const char *filename, int version = 1);
static const AudioInfo audioInfo1[] = {
{44, 0, -1},
{45, 0, -1},
{46, 0, 2510},
{46, 2510, 4020},
{46, 4020, -1},
{47, 0, 24010},
{47, 24010, -1},
{48, 0, 2510},
{48, 2510, 10520},
{48, 10520, 13530},
{48, 13530, -1},
{50, 0, 12786},
{50, 12786, -1},
{51, 0, -1},
{53, 0, -1},
{54, 0, 8010},
{54, 8010, 24020},
{54, 24020, 30030},
{54, 30030, 31040},
{54, 31040, -1},
};
static const AudioInfo audioInfo2[] = {
{55, 18230, -1},
{47, 0, 16010},
{47, 16010, 17020},
{49, 8010, -1},
{49, 0, 8010},
{53, 30020, -1},
{55, 7010, 17020},
{55, 0, 7010},
{53, 5010, 30020},
{55, 18230, -1},
{55, 17020, 18230},
{53, 0, 5010},
{47, 17020, -1},
{51, 9020, -1},
{51, 0, 6010},
{50, 0, -1},
{51, 6010, 9020},
{54, 0, -1},
{48, 0, -1}
};
static const byte mouseNormal[64] = {
0xff,0x3f,0xff,0x1f,0xff,0x0f,0xff,0x07,
0xff,0x03,0xff,0x01,0xff,0x00,0x7f,0x00,
0x3f,0x00,0x1f,0x00,0x0f,0x00,0x0f,0x00,
0xff,0x00,0x7f,0x18,0x7f,0x38,0x7f,0xfc,
0x00,0x00,0x00,0x40,0x00,0x60,0x00,0x70,
0x00,0x78,0x00,0x7c,0x00,0x7e,0x00,0x7f,
0x80,0x7f,0xc0,0x7f,0xe0,0x7f,0x00,0x7e,
0x00,0x66,0x00,0x43,0x00,0x03,0x00,0x00
};
static const byte mouseWait[64] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,
0x01,0x80,0x01,0x80,0x11,0x88,0x31,0x8c,
0x31,0x8c,0x11,0x88,0x01,0x80,0x01,0x80,
0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xfe,0x7f,0xf4,0x2f,0xf4,0x2f,
0x14,0x28,0x24,0x24,0x44,0x22,0x84,0x21,
0x84,0x21,0xc4,0x23,0xe4,0x27,0x74,0x2e,
0x34,0x2c,0x14,0x28,0xfe,0x7f,0x00,0x00
};
ResourceManager::ResourceManager(SupernovaEngine *vm)
: _audioRate(11931)
, _vm(vm) {
if (_vm->_MSPart == 1)
_soundSamples = new Common::ScopedPtr<Audio::SeekableAudioStream>[kAudioNumSamples1];
else if (_vm->_MSPart == 2)
_soundSamples = new Common::ScopedPtr<Audio::SeekableAudioStream>[kAudioNumSamples2];
initGraphics();
}
ResourceManager::~ResourceManager() {
if (_vm->_MSPart == 1) {
for (int i = 0; i < 44; i++)
delete _images[i];
}
if (_vm->_MSPart == 2) {
for (int i = 0; i < 47; i++)
delete _images[i];
}
delete[] _soundSamples;
delete[] _images;
}
void ResourceManager::initGraphics() {
Screen::initPalette();
initCursorGraphics();
if (_vm->_MSPart == 1)
initImages1();
else if (_vm->_MSPart == 2)
initImages2();
}
void ResourceManager::initCursorGraphics() {
const uint16 *bufferNormal = reinterpret_cast<const uint16 *>(mouseNormal);
const uint16 *bufferWait = reinterpret_cast<const uint16 *>(mouseWait);
for (uint i = 0; i < sizeof(mouseNormal) / 4; ++i) {
for (uint bit = 0; bit < 16; ++bit) {
uint mask = 0x8000 >> bit;
uint bitIndex = i * 16 + bit;
_cursorNormal[bitIndex] = (READ_LE_UINT16(bufferNormal + i) & mask) ?
kColorCursorTransparent : kColorBlack;
if (READ_LE_UINT16(bufferNormal + i + 16) & mask)
_cursorNormal[bitIndex] = kColorLightRed;
_cursorWait[bitIndex] = (READ_LE_UINT16(bufferWait + i) & mask) ?
kColorCursorTransparent : kColorBlack;
if (READ_LE_UINT16(bufferWait + i + 16) & mask)
_cursorWait[bitIndex] = kColorLightRed;
}
}
}
void ResourceManager::initImages1() {
_images = new MSNImage *[kNumImageFiles1];
for (int i = 0; i < kNumImageFiles1; ++i) {
_images[i] = nullptr;
}
}
void ResourceManager::initImages2() {
_images = new MSNImage *[kNumImageFiles2];
for (int i = 0; i < kNumImageFiles2; ++i) {
_images[i] = nullptr;
}
}
// Sound
// Note:
// - samples start with a header of 6 bytes: 01 SS SS 00 AD 00
// where SS SS (LE uint16) is the size of the sound sample + 2
// - samples end with a footer of 4 bytes: 00 00
// Skip those in the buffer
void ResourceManager::loadSound1(AudioId id) {
Common::File file;
if (!file.open(Common::Path(Common::String::format("msn_data.%03d", audioInfo1[id]._filenumber)))) {
error("File %s could not be read!", file.getName());
}
int length = 0;
byte *buffer = nullptr;
if (audioInfo1[id]._offsetEnd == -1) {
file.seek(0, SEEK_END);
length = file.pos() - audioInfo1[id]._offsetStart - 10;
} else {
length = audioInfo1[id]._offsetEnd - audioInfo1[id]._offsetStart - 10;
}
buffer = new byte[length];
file.seek(audioInfo1[id]._offsetStart + 6);
file.read(buffer, length);
file.close();
byte streamFlag = Audio::FLAG_UNSIGNED | Audio::FLAG_LITTLE_ENDIAN;
_soundSamples[id].reset(Audio::makeRawStream(buffer, length, _audioRate,
streamFlag, DisposeAfterUse::YES));
}
void ResourceManager::loadSound2(AudioId id) {
Common::File file;
if (!file.open(Common::Path(Common::String::format("ms2_data.%03d", audioInfo2[id]._filenumber)))) {
error("File %s could not be read!", file.getName());
}
int length = 0;
byte *buffer = nullptr;
if (audioInfo2[id]._offsetEnd == -1) {
file.seek(0, SEEK_END);
length = file.pos() - audioInfo2[id]._offsetStart - 10;
} else {
length = audioInfo2[id]._offsetEnd - audioInfo2[id]._offsetStart - 10;
}
buffer = new byte[length];
file.seek(audioInfo2[id]._offsetStart + 6);
file.read(buffer, length);
file.close();
byte streamFlag = Audio::FLAG_UNSIGNED | Audio::FLAG_LITTLE_ENDIAN;
_soundSamples[id].reset(Audio::makeRawStream(buffer, length, _audioRate,
streamFlag, DisposeAfterUse::YES));
}
void ResourceManager::loadImage(int filenumber) {
if (_vm->_MSPart == 1) {
if (filenumber < 44) {
_images[filenumber] = new MSNImage(_vm);
if (!_images[filenumber]->init(filenumber))
error("Failed reading image file msn_data.%03d", filenumber);
} else {
_images[44] = new MSNImage(_vm);
if (!_images[44]->init(filenumber))
error("Failed reading image file msn_data.%03d", filenumber);
}
} else if (_vm->_MSPart == 2) {
_images[filenumber] = new MSNImage(_vm);
if (!_images[filenumber]->init(filenumber))
error("Failed reading image file ms2_data.%03d", filenumber);
}
}
Audio::SeekableAudioStream *ResourceManager::getSoundStream(AudioId index) {
if (!_soundSamples[index]) {
if (_vm->_MSPart == 1)
loadSound1(index);
else if (_vm->_MSPart == 2)
loadSound2(index);
}
Audio::SeekableAudioStream *stream;
stream = _soundSamples[index].get();
stream->rewind();
return stream;
}
Audio::AudioStream *ResourceManager::getSoundStream(MusicId index) {
switch (index) {
case kMusicIntro:
if (!_musicIntroBuffer) {
if (_vm->_MSPart == 1)
_musicIntroBuffer.reset(convertToMod("msn_data.052", 1));
else if (_vm->_MSPart == 2)
_musicIntroBuffer.reset(convertToMod("ms2_data.052", 2));
}
_musicIntro.reset(Audio::makeProtrackerStream(_musicIntroBuffer.get()));
return _musicIntro.get();
case kMusicMadMonkeys:
// fall through
case kMusicOutro:
if (!_musicOutroBuffer) {
if (_vm->_MSPart == 1)
_musicOutroBuffer.reset(convertToMod("msn_data.049", 1));
else if (_vm->_MSPart == 2)
_musicOutroBuffer.reset(convertToMod("ms2_data.056", 2));
}
_musicOutro.reset(Audio::makeProtrackerStream(_musicOutroBuffer.get()));
return _musicOutro.get();
default:
error("Invalid music constant in playAudio()");
}
}
Audio::AudioStream *ResourceManager::getSirenStream() {
if (!_sirenStream)
initSiren();
return _sirenStream.get();
}
MSNImage *ResourceManager::getImage(int filenumber) {
//check array boundaries
if (_vm->_MSPart == 1 && filenumber > 43 && filenumber != 55)
return nullptr;
if (_vm->_MSPart == 2 && filenumber > 46)
return nullptr;
if (filenumber == 55) {
if (!_images[44])
loadImage(filenumber);
return _images[44];
} else {
if (!_images[filenumber])
loadImage(filenumber);
return _images[filenumber];
}
}
// Generate a tone which minimal length is the length and ends at the end
// of sine period
// NOTE: Size of the SineTable has to be the same as audioRate and a multiple of 4
byte *ResourceManager::generateTone(byte *buffer, int frequency, int length, int audioRate, Math::SineTable &table) {
int i = 0;
// Make sure length is a multiple of audioRate / frequency to end on a full sine wave and not in the middle.
// Also the length we have is a minimum length, so only increase it.
int r = 1 + (length - 1) * frequency / audioRate;
length = (1 + 2 * r * audioRate / frequency) / 2;
for(; i < length; i++) {
buffer[i] = (byte)
((table.at((i * frequency) % audioRate) * 127) + 127);
}
return buffer + length;
}
// Tones with frequencies between 1500 Hz and 1800 Hz, frequencies go up and down
// with a step of 10 Hz.
void ResourceManager::initSiren() {
int audioRate = 44000;
int length = audioRate / 90; // minimal length of each tone
// * 60 for the minimal length, another 20 * length as a spare, for longer tones
byte *buffer = new byte[length * 80];
byte *pBuffer = buffer;
Math::SineTable table(audioRate);
for (int i = 0; i < 30; i++)
pBuffer = generateTone(pBuffer, 1800 - i * 10, length, audioRate, table);
for (int i = 0; i < 30; i++)
pBuffer = generateTone(pBuffer, 1500 + i * 10, length, audioRate, table);
byte streamFlag = Audio::FLAG_UNSIGNED;
_sirenStream.reset(Audio::makeLoopingAudioStream(
Audio::makeRawStream(buffer, pBuffer - buffer, audioRate,
streamFlag, DisposeAfterUse::YES), 0));
}
static Common::MemoryReadStream *convertToMod(const char *filename, int version) {
// MSN format
struct {
uint16 seg;
uint16 start;
uint16 end;
uint16 loopStart;
uint16 loopEnd;
char volume;
char dummy[5];
} instr2[22];
int nbInstr2; // 22 for version1, 15 for version 2
int16 songLength;
char arrangement[128];
int16 patternNumber;
int32 note2[28][64][4];
nbInstr2 = ((version == 1) ? 22 : 15);
Common::File msnFile;
msnFile.open(filename);
if (!msnFile.isOpen()) {
warning("Data file '%s' not found", msnFile.getName());
return nullptr;
}
for (int i = 0 ; i < nbInstr2 ; ++i) {
instr2[i].seg = msnFile.readUint16LE();
instr2[i].start = msnFile.readUint16LE();
instr2[i].end = msnFile.readUint16LE();
instr2[i].loopStart = msnFile.readUint16LE();
instr2[i].loopEnd = msnFile.readUint16LE();
instr2[i].volume = msnFile.readByte();
msnFile.read(instr2[i].dummy, 5);
}
songLength = msnFile.readSint16LE();
msnFile.read(arrangement, 128);
patternNumber = msnFile.readSint16LE();
for (int p = 0 ; p < patternNumber ; ++p) {
for (int n = 0 ; n < 64 ; ++n) {
for (int k = 0 ; k < 4 ; ++k) {
note2[p][n][k] = msnFile.readSint32LE();
}
}
}
/* MOD format */
struct {
char iname[22];
uint16 length;
char finetune;
char volume;
uint16 loopStart;
uint16 loopLength;
} instr[31];
int32 note[28][64][4];
// We can't recover some MOD effects since several of them are mapped to 0.
// Assume the MSN effect of value 0 is Arpeggio (MOD effect of value 0).
const char invConvEff[8] = {0, 1, 2, 3, 10, 12, 13 ,15};
// Reminder from convertToMsn
// 31 30 29 28 27 26 25 24 - 23 22 21 20 19 18 17 16 - 15 14 13 12 11 10 09 08 - 07 06 05 04 03 02 01 00
// h h h h g g g g f f f f e e e e d d d d c c c c b b b b a a a a
//
// MSN:
// hhhh (4 bits) Cleared to 0
// dddd c (5 bits) Sample index | after mapping through convInstr
// ccc (3 bits) Effect type | after mapping through convEff
// bbbb aaaa (8 bits) Effect value | unmodified
// gggg ffff eeee (12 bits) Sample period | unmodified
//
// MS2:
// hhhh (4 bits) Cleared to 0
// dddd (4 bits) Sample index | after mapping through convInstr
// cccc (4 bits) Effect type | unmodified
// bbbb aaaa (8 bits) Effect value | unmodified
// gggg ffff eeee (12 bits) Sample period | transformed (0xE000 / p) - 256
//
// MOD:
// hhhh dddd (8 bits) Sample index
// cccc (4 bits) Effect type for this channel/division
// bbbb aaaa (8 bits) Effect value
// gggg ffff eeee (12 bits) Sample period
// Can we recover the instruments mapping? I don't think so as part of the original instrument index is cleared.
// And it doesn't really matter as long as we are consistent.
// However we need to make sure 31 (or 15 in MS2) is mapped to 0 in MOD.
// We just add 1 to all other values, and this means a 1 <-> 1 mapping for the instruments
for (int p = 0; p < patternNumber; ++p) {
for (int n = 0; n < 64; ++n) {
for (int k = 0; k < 4; ++k) {
int32* l = &(note[p][n][k]);
*l = note2[p][n][k];
int32 i = 0;
if (nbInstr2 == 22) { // version 1
i = ((*l & 0xF800) >> 11);
int32 e = ((*l & 0x0700) >> 8);
int32 e1 = invConvEff[e];
*l &= 0x0FFF00FF;
*l |= (e1 << 8);
} else { // version 2
int32 h = (*l >> 16);
i = ((*l & 0xF000) >> 12);
*l &= 0x00000FFF;
if (h)
h = 0xE000 / (h + 256);
*l |= (h << 16);
if (i == 15)
i = 31;
}
// Add back index in note
if (i != 31) {
++i;
*l |= ((i & 0x0F) << 12);
*l |= ((i & 0xF0) << 24);
}
}
}
}
for (int i = 0; i < 31; ++i) {
// iname is not stored in the mod file. Just set it to 'instrument#'
// finetune is not stored either. Assume 0.
memset(instr[i].iname, 0, 22);
Common::sprintf_s(instr[i].iname, "instrument%d", i+1);
instr[i].length = 0;
instr[i].finetune = 0;
instr[i].volume = 0;
instr[i].loopStart = 0;
instr[i].loopLength = 0;
if (i < nbInstr2) {
instr[i].length = ((instr2[i].end - instr2[i].start) >> 1);
instr[i].loopStart = ((instr2[i].loopStart - instr2[i].start) >> 1);
instr[i].loopLength = (( instr2[i].loopEnd - instr2[i].loopStart) >> 1);
instr[i].volume = instr2[i].volume;
}
}
// The ciaaSpeed is kind of useless and not present in the MSN file.
// Traditionally 0x78 in SoundTracker. Was used in NoiseTracker as a restart point.
// ProTracker uses 0x7F. FastTracker uses it as a restart point, whereas ScreamTracker 3 uses 0x7F like ProTracker.
// You can use this to roughly detect which tracker made a MOD, and detection gets more accurate for more obscure MOD types.
char ciaaSpeed = 0x7F;
// The mark cannot be recovered either. Since we have 4 channels and 31 instrument it can be either ID='M.K.' or ID='4CHN'.
// Assume 'M.K.'
const char mark[4] = { 'M', '.', 'K', '.' };
Common::MemoryWriteStreamDynamic buffer(DisposeAfterUse::NO);
buffer.write(msnFile.getName(), 19);
buffer.writeByte(0);
for (int i = 0 ; i < 31 ; ++i) {
buffer.write(instr[i].iname, 22);
buffer.writeUint16BE(instr[i].length);
buffer.writeByte(instr[i].finetune);
buffer.writeByte(instr[i].volume);
buffer.writeUint16BE(instr[i].loopStart);
buffer.writeUint16BE(instr[i].loopLength);
}
buffer.writeByte((char)songLength);
buffer.writeByte(ciaaSpeed);
buffer.write(arrangement, 128);
buffer.write(mark, 4);
for (int p = 0 ; p < patternNumber ; ++p) {
for (int n = 0 ; n < 64 ; ++n) {
for (int k = 0 ; k < 4 ; ++k) {
// buffer.writeUint32BE(*((uint32*)(note[p][n]+k)));
buffer.writeSint32BE(note[p][n][k]);
}
}
}
uint nb;
char buf[4096];
while ((nb = msnFile.read(buf, 4096)) > 0)
buffer.write(buf, nb);
return new Common::MemoryReadStream(buffer.getData(), buffer.size(), DisposeAfterUse::YES);
}
int ResourceManager::getAudioRate() {
return _audioRate;
}
const byte *ResourceManager::getCursor(CursorId id) const {
switch (id) {
case kCursorNormal:
return _cursorNormal;
case kCursorWait:
return _cursorWait;
default:
return nullptr;
}
}
}

View File

@@ -0,0 +1,90 @@
/* 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 SUPERNOVA_RESOURCES_H
#define SUPERNOVA_RESOURCES_H
#include "audio/audiostream.h"
#include "common/ptr.h"
#include "math/sinetables.h"
#include "supernova/graphics.h"
#include "supernova/sound.h"
#include "supernova/supernova.h"
namespace Common {
class MemoryReadStream;
}
namespace Supernova {
class SupernovaEngine;
class ResourceManager {
public:
enum CursorId {
kCursorNormal,
kCursorWait
};
public:
static const int kNumImageFiles1 = 45;
static const int kNumImageFiles2 = 47;
public:
ResourceManager(SupernovaEngine *vm);
~ResourceManager();
Audio::SeekableAudioStream *getSoundStream(AudioId index);
Audio::AudioStream *getSoundStream(MusicId index);
Audio::AudioStream *getSirenStream();
MSNImage *getImage(int filenumber);
const byte *getCursor(CursorId id) const;
int getAudioRate();
private:
void initGraphics();
void initCursorGraphics();
void initImages1();
void initImages2();
void loadImage(int filenumber);
void loadSound1(AudioId id);
void loadSound2(AudioId id);
void initSiren();
byte *generateTone(byte *buffer, int frequency, int length, int audioRate, Math::SineTable &table);
private:
Common::ScopedPtr<Audio::SeekableAudioStream> *_soundSamples;
Common::ScopedPtr<Common::MemoryReadStream> _musicIntroBuffer;
Common::ScopedPtr<Common::MemoryReadStream> _musicOutroBuffer;
Common::ScopedPtr<Audio::AudioStream> _musicIntro;
Common::ScopedPtr<Audio::AudioStream> _musicOutro;
Common::ScopedPtr<Audio::AudioStream> _sirenStream;
SupernovaEngine *_vm;
int _audioRate;
MSNImage **_images;
byte _cursorNormal[256];
byte _cursorWait[256];
};
}
#endif

188
engines/supernova/room.cpp Normal file
View File

@@ -0,0 +1,188 @@
/* 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/system.h"
#include "graphics/cursorman.h"
#include "supernova/screen.h"
#include "supernova/supernova.h"
#include "supernova/game-manager.h"
namespace Supernova {
Room::Room() {
_seen = false;
_fileNumber = 0;
_id = NULLROOM;
_vm = nullptr;
for (int i = 0; i < kMaxSection; ++i)
_shown[i] = kShownFalse;
for (int i = 0; i < kMaxDialog; ++i)
_sentenceRemoved[i] = 0;
}
Room::~Room() {
}
bool Room::serialize(Common::WriteStream *out) {
if (out->err())
return false;
out->writeSint32LE(_id);
for (int i = 0; i < kMaxSection; ++i)
out->writeByte(_shown[i]);
for (int i = 0; i < kMaxDialog ; ++i)
out->writeByte(_sentenceRemoved[i]);
int numObjects = 0;
while ((numObjects < kMaxObject) && (_objectState[numObjects]._id != INVALIDOBJECT))
++numObjects;
out->writeSint32LE(numObjects);
for (int i = 0; i < numObjects; ++i) {
out->writeSint32LE(_objectState[i]._name);
out->writeSint32LE(_objectState[i]._description);
out->writeByte(_objectState[i]._roomId);
out->writeSint32LE(_objectState[i]._id);
out->writeSint32LE(_objectState[i]._type);
out->writeByte(_objectState[i]._click);
out->writeByte(_objectState[i]._click2);
out->writeByte(_objectState[i]._section);
out->writeSint32LE(_objectState[i]._exitRoom);
out->writeByte(_objectState[i]._direction);
}
out->writeByte(_seen);
return !out->err();
}
bool Room::deserialize(Common::ReadStream *in, int version) {
if (in->err())
return false;
in->readSint32LE();
for (int i = 0; i < kMaxSection; ++i)
_shown[i] = in->readByte();
// Prior to version 3, _sentenceRemoved was part of _shown (the last two values)
// But on the other hand dialog was not implemented anyway, so we don't even try to
// recover it.
for (int i = 0; i < kMaxDialog ; ++i)
_sentenceRemoved[i] = version < 3 ? 0 : in->readByte();
int numObjects = in->readSint32LE();
for (int i = 0; i < numObjects; ++i) {
_objectState[i]._name = in->readSint32LE();
_objectState[i]._description = in->readSint32LE();
_objectState[i]._roomId = in->readByte();
_objectState[i]._id = static_cast<ObjectId>(in->readSint32LE());
_objectState[i]._type = static_cast<ObjectType>(in->readSint32LE());
_objectState[i]._click = in->readByte();
_objectState[i]._click2 = in->readByte();
_objectState[i]._section = in->readByte();
_objectState[i]._exitRoom = static_cast<RoomId>(in->readSint32LE());
_objectState[i]._direction = in->readByte();
}
_seen = in->readByte();
return !in->err();
}
bool Room::hasSeen() {
return _seen;
}
void Room::setRoomSeen(bool seen) {
_seen = seen;
}
int Room::getFileNumber() const {
return _fileNumber;
}
RoomId Room::getId() const {
return _id;
}
void Room::setSectionVisible(uint section, bool visible) {
if (section < kMaxSection)
_shown[section] = visible ? kShownTrue : kShownFalse;
else
_shown[section - kSectionInvert] = visible ? kShownFalse : kShownTrue;
}
bool Room::isSectionVisible(uint index) const {
return _shown[index] == kShownTrue;
}
void Room::removeSentenceByMask(int mask, int number) {
if (number > 0) {
_sentenceRemoved[number - 1] |= mask;
}
}
void Room::removeSentence(int sentence, int number) {
if (number > 0)
_sentenceRemoved[number - 1] |= (1 << sentence);
}
void Room::addSentence(int sentence, int number) {
if (number > 0)
_sentenceRemoved[number - 1] &= ~(1 << sentence);
}
void Room::addAllSentences(int number) {
if (number > 0)
_sentenceRemoved[number - 1] = 0;
}
bool Room::sentenceRemoved(int sentence, int number) {
if (number <= 0)
return false;
return (_sentenceRemoved[number - 1] & (1 << sentence));
}
bool Room::allSentencesRemoved(int maxSentence, int number) {
if (number <= 0)
return false;
for (int i = 0, flag = 1 ; i < maxSentence ; ++i, flag <<= 1)
if (!(_sentenceRemoved[number - 1] & flag))
return false;
return true;
}
Object *Room::getObject(uint index) {
return &_objectState[index];
}
void Room::animation() {
}
void Room::onEntrance() {
}
bool Room::interact(Action verb, Object &obj1, Object &obj2) {
return false;
}
}

77
engines/supernova/room.h Normal file
View File

@@ -0,0 +1,77 @@
/* 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 SUPERNOVA_ROOM_H
#define SUPERNOVA_ROOM_H
#include "common/str.h"
#include "supernova/msn_def.h"
namespace Common {
class ReadStream;
class WriteStream;
}
namespace Supernova {
class GameManager1;
class SupernovaEngine;
class Room {
public:
Room();
bool hasSeen();
void setRoomSeen(bool seen);
int getFileNumber() const;
RoomId getId() const;
void setSectionVisible(uint section, bool visible);
bool isSectionVisible(uint index) const;
void removeSentence(int sentence, int number);
void removeSentenceByMask(int mask, int number);
void addSentence(int sentence, int number);
void addAllSentences(int number);
bool sentenceRemoved(int sentence, int number);
bool allSentencesRemoved(int maxSentence, int number);
Object *getObject(uint index);
virtual ~Room();
virtual void animation();
virtual void onEntrance();
virtual bool interact(Action verb, Object &obj1, Object &obj2);
virtual bool serialize(Common::WriteStream *out);
virtual bool deserialize(Common::ReadStream *in, int version);
protected:
int _fileNumber;
char _shown[kMaxSection];
byte _sentenceRemoved[kMaxDialog];
Object _objectState[kMaxObject];
RoomId _id;
SupernovaEngine *_vm;
private:
bool _seen;
};
}
#endif // SUPERNOVA_ROOM_H

View File

@@ -0,0 +1,694 @@
/* 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/str.h"
#include "common/system.h"
#include "engines/util.h"
#include "graphics/cursorman.h"
#include "graphics/paletteman.h"
#include "graphics/surface.h"
#include "common/config-manager.h"
#include "common/text-to-speech.h"
#include "supernova/imageid.h"
#include "supernova/resman.h"
#include "supernova/game-manager.h"
#include "supernova/screen.h"
#include "supernova/supernova.h"
#include "supernova/screenstatic.cpp"
namespace Supernova {
ScreenBuffer::ScreenBuffer()
: _x(0)
, _y(0)
, _width(0)
, _height(0)
, _pixels(nullptr) {
}
ScreenBufferStack::ScreenBufferStack()
: _last(_buffer) {
}
void ScreenBufferStack::push(int x, int y, int width, int height) {
if (_last == ARRAYEND(_buffer))
return;
Graphics::Surface *screenSurface = g_system->lockScreen();
if (x < 0) {
width += x;
x = 0;
}
if (x + width > screenSurface->w)
width = screenSurface->w - x;
if (y < 0) {
height += y;
y = 0;
}
if (y + height > screenSurface->h)
height = screenSurface->h - y;
_last->_pixels = new byte[width * height];
byte *pixels = _last->_pixels;
const byte *screen = static_cast<const byte *>(screenSurface->getBasePtr(x, y));
for (int i = 0; i < height; ++i) {
Common::copy(screen, screen + width, pixels);
screen += screenSurface->pitch;
pixels += width;
}
g_system->unlockScreen();
_last->_x = x;
_last->_y = y;
_last->_width = width;
_last->_height = height;
++_last;
}
void ScreenBufferStack::restore() {
if (_last == _buffer)
return;
--_last;
g_system->copyRectToScreen(_last->_pixels, _last->_width, _last->_x,
_last->_y, _last->_width, _last->_height);
delete[] _last->_pixels;
}
Marquee::Marquee(Screen *screen, MarqueeId id, const char *text)
: _text(text)
, _textBegin(text)
, _delay(0)
, _loop(false)
, _oldColor(nullptr)
, _screen(screen) {
if (_screen->_vm->_MSPart == 1) {
_color = kColorLightBlue;
if (id == kMarqueeIntro) {
_y = 191;
_loop = true;
} else if (id == kMarqueeOutro) {
_y = 1;
}
} else if (_screen->_vm->_MSPart == 2) {
byte purple[3] = {0x9b, 0x00, 0xfb};
_oldColor = new byte[3];
_screen->_vm->_system->getPaletteManager()->grabPalette(_oldColor, kColorPurple, 1);
_screen->_vm->_system->getPaletteManager()->setPalette(purple, kColorPurple, 1);
_color = kColorPurple;
if (id == kMarqueeIntro) {
_y = 191;
_loop = true;
} else if (id == kMarqueeOutro) {
_y = 191;
}
}
_textWidth = Screen::textWidth(_text);
_x = kScreenWidth / 2 - _textWidth / 2;
_screen->_textCursorX = _x;
_screen->_textCursorY = _y;
_screen->_textColor = _color;
}
Marquee::~Marquee() {
if (_screen->_vm->_MSPart == 2) {
_screen->_vm->_system->getPaletteManager()->setPalette(_oldColor, kColorPurple, 1);
delete[] _oldColor;
}
}
void Marquee::clearText() {
_screen->renderBox(_x, _y - 1, _textWidth + 1, 9, kColorBlack);
}
void Marquee::reset() {
_text = _textBegin;
clearText();
_textWidth = Screen::textWidth(_text);
_x = kScreenWidth / 2 - _textWidth / 2;
_screen->_textCursorX = _x;
}
bool Marquee::renderCharacter() {
if (_delay != 0) {
_delay--;
return true;
}
switch (*_text) {
case '\233':
if (_loop) {
_loop = false;
_text = _textBegin;
clearText();
_textWidth = Screen::textWidth(_text);
_x = kScreenWidth / 2 - _textWidth / 2;
_screen->_textCursorX = _x;
} else
return false;
break;
case '\1':
clearText();
_text++;
_textWidth = Screen::textWidth(_text);
_x = kScreenWidth / 2 - _textWidth / 2;
_screen->_textCursorX = _x;
if (_screen->_vm->_MSPart == 1) {
_color = kColorLightBlue;
_screen->_textColor = _color;
} else if (_screen->_vm->_MSPart == 2) {
_color = kColorPurple;
_screen->_textColor = _color;
}
break;
case '^':
_color = kColorLightYellow;
_screen->_textColor = _color;
_text++;
break;
case '#':
_delay = 50;
_text++;
break;
default:
_screen->renderText((uint16)*_text++);
_delay = 1;
break;
}
return true;
}
Screen::Screen(SupernovaEngine *vm, ResourceManager *resMan)
: _vm(vm)
, _resMan(resMan)
, _currentImage(nullptr)
, _viewportBrightness(255)
, _guiBrightness(255)
, _screenWidth(320)
, _screenHeight(200)
, _textColor(kColorBlack)
, _textCursorX(0)
, _textCursorY(0)
, _messageShown(false) {
changeCursor(ResourceManager::kCursorNormal);
}
int Screen::getScreenWidth() const {
return _screenWidth;
}
int Screen::getScreenHeight() const {
return _screenHeight;
}
int Screen::getGuiBrightness() const {
return _guiBrightness;
}
void Screen::setViewportBrightness(int brightness) {
_viewportBrightness = brightness;
}
int Screen::getViewportBrightness() const {
return _viewportBrightness;
}
void Screen::setGuiBrightness(int brightness) {
_guiBrightness = brightness;
}
MSNImage *Screen::getCurrentImage() {
return _currentImage;
}
const Screen::ImageInfo *Screen::getImageInfo(ImageId id) const {
return &imageInfo[(int)id];
}
bool Screen::isMessageShown() const {
return _messageShown;
}
Common::Point Screen::getTextCursorPos() {
return Common::Point(_textCursorX, _textCursorY);
}
void Screen::setTextCursorPos(int x, int y) {
_textCursorX = x;
_textCursorY = y;
}
byte Screen::getTextCursorColor() {
return _textColor;
}
void Screen::setTextCursorColor(byte color) {
_textColor = color;
}
void Screen::renderMessage(int stringId, MessagePosition position,
Common::String var1, Common::String var2) {
Common::String text = _vm->getGameString(stringId);
if (!var1.empty()) {
if (!var2.empty())
text = Common::String::format(text.c_str(), var1.c_str(), var2.c_str());
else
text = Common::String::format(text.c_str(), var1.c_str());
}
renderMessage(text, position);
}
void Screen::renderMessage(const Common::String &text, MessagePosition position) {
if (!text.empty())
renderMessage(text.c_str(), position);
}
void Screen::renderText(const uint16 character) {
char text[2];
text[0] = character & 0xFF;
text[1] = 0;
renderText(text, _textCursorX, _textCursorY, _textColor);
}
void Screen::renderText(const char *text) {
renderText(text, _textCursorX, _textCursorY, _textColor);
}
void Screen::renderText(int stringId) {
renderText(_vm->getGameString(stringId));
}
void Screen::renderText(const Common::String &text) {
if (!text.empty())
renderText(text.c_str());
}
void Screen::renderText(const GuiElement &guiElement) {
renderText(guiElement.getText(), guiElement.getTextPos().x,
guiElement.getTextPos().y, guiElement.getTextColor());
}
void Screen::renderText(const uint16 character, int x, int y, byte color) {
char text[2];
text[0] = character & 0xFF;
text[1] = 0;
renderText(text, x, y, color);
}
void Screen::renderText(const char *text, int x, int y, byte color) {
Graphics::Surface *screen = _vm->_system->lockScreen();
byte *cursor = static_cast<byte *>(screen->getBasePtr(x, y));
const byte *basePtr = cursor;
byte c;
while ((c = *text++) != '\0') {
if (c < 32) {
continue;
} else if (c == 225) {
c = 128;
}
for (uint i = 0; i < 5; ++i) {
if (font[c - 32][i] == 0xff) {
break;
}
byte *ascentLine = cursor;
for (byte j = font[c - 32][i]; j != 0; j >>= 1) {
if (j & 1) {
*cursor = color;
}
cursor += kScreenWidth;
}
cursor = ++ascentLine;
}
++cursor;
}
_vm->_system->unlockScreen();
uint numChars = cursor - basePtr;
uint absPosition = y * kScreenWidth + x + numChars;
_textCursorX = absPosition % kScreenWidth;
_textCursorY = absPosition / kScreenWidth;
_textColor = color;
}
void Screen::renderText(const Common::String &text, int x, int y, byte color) {
if (!text.empty())
renderText(text.c_str(), x, y, color);
}
void Screen::renderText(int stringId, int x, int y, byte color) {
renderText(_vm->getGameString(stringId), x, y, color);
}
void Screen::renderImageSection(const MSNImage *image, int section, bool invert) {
// Note: inverting means we are removing the section. So we should get the rect for that
// section but draw the background (section 0) instead.
if (section > image->_numSections - 1)
return;
Common::Rect sectionRect(image->_section[section].x1,
image->_section[section].y1,
image->_section[section].x2 + 1,
image->_section[section].y2 + 1);
bool bigImage = false;
if (_vm->_MSPart == 1)
bigImage = image->_filenumber == 1 || image->_filenumber == 2;
else if (_vm->_MSPart == 2)
bigImage = image->_filenumber == 38;
if (bigImage) {
sectionRect.setWidth(640);
sectionRect.setHeight(480);
if (_screenWidth != 640) {
_screenWidth = 640;
_screenHeight = 480;
initGraphics(_screenWidth, _screenHeight);
}
} else {
if (_screenWidth != 320) {
_screenWidth = 320;
_screenHeight = 200;
initGraphics(_screenWidth, _screenHeight);
}
}
uint offset = 0;
int pitch = sectionRect.width();
if (invert) {
pitch = image->_pitch;
offset = image->_section[section].y1 * pitch +
image->_section[section].x1;
section = 0;
}
void *pixels = image->_sectionSurfaces[section]->getPixels();
_vm->_system->copyRectToScreen(static_cast<const byte *>(pixels) + offset,
pitch, sectionRect.left, sectionRect.top,
sectionRect.width(), sectionRect.height());
}
void Screen::renderImage(ImageId id, bool removeImage) {
ImageInfo info = imageInfo[id];
const MSNImage *image = _resMan->getImage(info.filenumber);
if (_currentImage != image)
setCurrentImage(info.filenumber);
do {
renderImageSection(image, info.section, removeImage);
info.section = image->_section[info.section].next;
} while (info.section != 0);
}
void Screen::renderImage(int section) {
bool removeImage = false;
if (section > kSectionInvert) {
removeImage = true;
section -= kSectionInvert;
}
if (!_currentImage || section >= kMaxSection)
return;
do {
renderImageSection(_currentImage, section, removeImage);
section = _currentImage->_section[section].next;
} while (section != 0);
}
bool Screen::setCurrentImage(int filenumber) {
_currentImage = _resMan->getImage(filenumber);
_vm->_system->getPaletteManager()->setPalette(_currentImage->getPalette().data(), 16, 239);
paletteBrightness();
return true;
}
void Screen::saveScreen(int x, int y, int width, int height) {
_screenBuffer.push(x, y, width, height);
}
void Screen::saveScreen(const GuiElement &guiElement) {
saveScreen(guiElement.left, guiElement.top, guiElement.width(), guiElement.height());
}
void Screen::restoreScreen() {
_screenBuffer.restore();
}
void Screen::renderRoom(Room &room) {
if (room.getId() == INTRO1 || room.getId() == INTRO2)
return;
if (setCurrentImage(room.getFileNumber())) {
for (int i = 0; i < _currentImage->_numSections; ++i) {
int section = i;
if (room.isSectionVisible(section)) {
do {
renderImageSection(_currentImage, section, false);
section = _currentImage->_section[section].next;
} while (section != 0);
}
}
}
}
int Screen::textWidth(const uint16 key) {
char text[2];
text[0] = key & 0xFF;
text[1] = 0;
return textWidth(text);
}
int Screen::textWidth(const char *text) {
int charWidth = 0;
while (*text != '\0' && *text != '\1') {
byte c = *text++;
if (c < 32 || c == 155) {
// 155 is used for looping in Marquee text and is not used otherwise
// (it is beyond the end of the font).
continue;
} else if (c == 225) {
c = 35;
}
for (uint i = 0; i < 5; ++i) {
if (font[c - 32][i] == 0xff) {
break;
}
++charWidth;
}
++charWidth;
}
return charWidth;
}
int Screen::textWidth(const Common::String &text) {
return Screen::textWidth(text.c_str());
}
void Screen::renderMessage(const char *text, MessagePosition position, int positionX, int positionY) {
Common::String t(text);
char *row[20];
Common::String::iterator p = t.begin();
uint numRows = 0;
int rowWidthMax = 0;
int x = 0;
int y = 0;
byte textColor = 0;
while (*p != '\0') {
row[numRows] = p;
++numRows;
while ((*p != '\0') && (*p != '|')) {
++p;
}
if (*p == '|') {
*p = '\0';
++p;
}
}
for (uint i = 0; i < numRows; ++i) {
int rowWidth = textWidth(row[i]);
if (rowWidth > rowWidthMax)
rowWidthMax = rowWidth;
}
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled")) {
Common::String ttsText;
for (uint i = 0; i < numRows; ++i) {
if (!ttsText.empty())
ttsText += ' ';
ttsText += row[i];
}
ttsMan->say(ttsText, Common::TextToSpeechManager::QUEUE_NO_REPEAT, Common::kDos850);
}
switch (position) {
case kMessageNormal:
default:
x = 160 - rowWidthMax / 2;
textColor = kColorWhite99;
break;
case kMessageTop:
x = 160 - rowWidthMax / 2;
textColor = kColorLightYellow;
break;
case kMessageCenter:
x = 160 - rowWidthMax / 2;
textColor = kColorLightRed;
break;
case kMessageLeft:
x = 3;
textColor = kColorLightYellow;
break;
case kMessageRight:
x = 317 - rowWidthMax;
textColor = kColorLightGreen;
break;
}
if (position == kMessageNormal) {
y = 70 - ((numRows * 9) / 2);
} else if (position == kMessageTop) {
y = 5;
} else {
y = 142;
}
if (positionX != -1 && positionY != -1) {
x = positionX;
y = positionY;
}
int message_columns = x - 3;
int message_rows = y - 3;
int message_width = rowWidthMax + 6;
int message_height = numRows * 9 + 5;
saveScreen(message_columns, message_rows, message_width, message_height);
renderBox(message_columns, message_rows, message_width, message_height, kColorWhite35);
for (uint i = 0; i < numRows; ++i) {
renderText(row[i], x, y, textColor);
y += 9;
}
_messageShown = true;
}
void Screen::removeMessage() {
if (_messageShown) {
restoreScreen();
_messageShown = false;
}
}
void Screen::renderBox(int x, int y, int width, int height, byte color) {
_vm->_system->fillScreen(Common::Rect(x, y, x + width, y + height), color);
}
void Screen::renderBox(const GuiElement &guiElement) {
renderBox(guiElement.left, guiElement.top, guiElement.width(),
guiElement.height(), guiElement.getBackgroundColor());
}
void Screen::initPalette() {
g_system->getPaletteManager()->setPalette(initVGAPalette, 0, 256);
}
void Screen::paletteBrightness() {
byte palette[768];
_vm->_system->getPaletteManager()->grabPalette(palette, 0, 255);
for (uint i = 0; i < 48; ++i) {
palette[i] = (initVGAPalette[i] * _guiBrightness) >> 8;
}
for (uint i = 0; i < 717; ++i) {
const byte *imagePalette;
if (_currentImage && _currentImage->hasPalette()) {
imagePalette = _currentImage->getPalette().data();
} else {
imagePalette = palette + 48;
}
palette[i + 48] = (imagePalette[i] * _viewportBrightness) >> 8;
}
_vm->_system->getPaletteManager()->setPalette(palette, 0, 255);
}
void Screen::paletteFadeOut(int minBrightness) {
while (_guiBrightness > minBrightness + 10) {
_guiBrightness -= 10;
if (_viewportBrightness > _guiBrightness)
_viewportBrightness = _guiBrightness;
paletteBrightness();
_vm->_system->updateScreen();
_vm->_system->delayMillis(_vm->_delay);
}
_guiBrightness = minBrightness;
_viewportBrightness = minBrightness;
paletteBrightness();
_vm->_system->updateScreen();
}
void Screen::paletteFadeIn(int maxViewportBrightness) {
while (_guiBrightness < 245) {
if (_viewportBrightness < maxViewportBrightness)
_viewportBrightness += 10;
_guiBrightness += 10;
paletteBrightness();
_vm->_system->updateScreen();
_vm->_system->delayMillis(_vm->_delay);
}
_guiBrightness = 255;
_viewportBrightness = maxViewportBrightness;
paletteBrightness();
_vm->_system->updateScreen();
}
void Screen::setColor63(byte value) {
byte color[3] = {value, value, value};
_vm->_system->getPaletteManager()->setPalette(color, 63, 1);
}
void Screen::changeCursor(ResourceManager::CursorId id) {
CursorMan.replaceCursor(_resMan->getCursor(id),
16, 16, 0, 0, kColorCursorTransparent);
CursorMan.replaceCursorPalette(initVGAPalette, 0, 16);
CursorMan.showMouse(true);
}
}

205
engines/supernova/screen.h Normal file
View File

@@ -0,0 +1,205 @@
/* 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 SUPERNOVA_SCREEN_H
#define SUPERNOVA_SCREEN_H
#include "common/array.h"
#include "common/rect.h"
#include "common/scummsys.h"
#include "supernova/imageid.h"
#include "supernova/msn_def.h"
#include "supernova/resman.h"
namespace Supernova {
class SupernovaEngine;
class GameManager;
class ResourceManager;
class GuiElement;
class Room;
class MSNImage;
class Screen;
const int kScreenWidth = 320;
const int kScreenHeight = 200;
const int kFontWidth = 5;
const int kFontWidth2 = 4;
const int kFontHeight = 8;
enum Color {
kColorBlack = 0,
kColorWhite25 = 1,
kColorWhite35 = 2,
kColorWhite44 = 3,
kColorWhite99 = 4,
kColorDarkGreen = 5,
kColorGreen = 6,
kColorDarkRed = 7,
kColorRed = 8,
kColorDarkBlue = 9,
kColorBlue = 10,
kColorWhite63 = 11,
kColorLightBlue = 12,
kColorLightGreen = 13,
kColorLightYellow = 14,
kColorLightRed = 15,
kColorPurple = 16,
kColorCursorTransparent = kColorWhite25
};
class ScreenBuffer {
friend class ScreenBufferStack;
public:
ScreenBuffer();
private:
byte *_pixels;
int _x;
int _y;
int _width;
int _height;
};
class ScreenBufferStack {
public:
ScreenBufferStack();
void push(int x, int y, int width, int height);
void restore();
private:
ScreenBuffer _buffer[8];
ScreenBuffer *_last;
};
class Marquee {
public:
enum MarqueeId {
kMarqueeIntro,
kMarqueeOutro
};
Marquee(Screen *screen, MarqueeId id, const char *text);
~Marquee();
bool renderCharacter();
void reset();
private:
void clearText();
Screen *_screen;
const char *const _textBegin;
const char *_text;
bool _loop;
int _delay;
int _color;
byte *_oldColor;
int _x;
int _y;
int _textWidth;
};
class Screen {
friend class Marquee;
public:
struct ImageInfo {
int filenumber;
int section;
};
public:
static void initPalette();
static int textWidth(const uint16 key);
static int textWidth(const char *text);
static int textWidth(const Common::String &text);
public:
Screen(SupernovaEngine *vm, ResourceManager *resMan);
int getScreenWidth() const;
int getScreenHeight() const;
int getViewportBrightness() const;
void setViewportBrightness(int brightness);
int getGuiBrightness() const;
void setGuiBrightness(int brightness);
MSNImage *getCurrentImage();
const ImageInfo *getImageInfo(ImageId id) const;
bool isMessageShown() const;
void paletteFadeIn(int maxViewportBrightness);
void paletteFadeOut(int minBrightness);
void paletteBrightness();
void renderImage(ImageId id, bool removeImage = false);
void renderImage(int section);
bool setCurrentImage(int filenumber);
void saveScreen(int x, int y, int width, int height);
void saveScreen(const GuiElement &guiElement);
void restoreScreen();
void renderRoom(Room &room);
void renderMessage(const char *text, MessagePosition position = kMessageNormal, int positionX = -1, int positionY = -1);
void renderMessage(const Common::String &text, MessagePosition position = kMessageNormal);
void renderMessage(int stringId, MessagePosition position = kMessageNormal,
Common::String var1 = "", Common::String var2 = "");
void removeMessage();
void renderText(const uint16 character);
void renderText(const char *text);
void renderText(const Common::String &text);
void renderText(int stringId);
void renderText(const uint16 character, int x, int y, byte color);
void renderText(const char *text, int x, int y, byte color);
void renderText(const Common::String &text, int x, int y, byte color);
void renderText(int stringId, int x, int y, byte color);
void renderText(const GuiElement &guiElement);
void renderBox(int x, int y, int width, int height, byte color);
void renderBox(const GuiElement &guiElement);
void setColor63(byte value);
Common::Point getTextCursorPos();
void setTextCursorPos(int x, int y);
byte getTextCursorColor();
void setTextCursorColor(byte color);
void update();
void changeCursor(ResourceManager::CursorId);
private:
void renderImageSection(const MSNImage *image, int section, bool invert);
private:
SupernovaEngine *_vm;
ResourceManager *_resMan;
MSNImage *_currentImage;
ScreenBufferStack _screenBuffer;
int _screenWidth;
int _screenHeight;
int _textCursorX;
int _textCursorY;
int _textColor;
byte _viewportBrightness;
byte _guiBrightness;
bool _messageShown;
};
}
#endif

View File

@@ -0,0 +1,541 @@
/* 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/>.
*
*/
namespace Supernova {
static const Screen::ImageInfo imageInfo[] = {
{ 0, 0}, { 0, 1}, { 0, 2},
{ 1, 0},
{ 2, 0},
{ 3, 0}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4}, { 3, 5},
{ 3, 6}, { 3, 7}, { 3, 8}, { 3, 9}, { 3, 10}, { 3, 11},
{ 4, 0}, { 4, 1}, { 4, 2}, { 4, 3},
{ 5, 0}, { 5, 1}, { 5, 2}, { 5, 3}, { 5, 4}, { 5, 5},
{ 5, 6}, { 5, 7}, { 5, 8}, { 5, 9},
{ 6, 0}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, { 6, 5},
{ 6, 6}, { 6, 7}, { 6, 8}, { 6, 9}, { 6, 10}, { 6, 11},
{ 6, 12}, { 6, 13}, { 6, 14}, { 6, 15}, { 6, 16}, { 6, 17},
{ 6, 18}, { 6, 19}, { 6, 20}, { 6, 21},
{ 7, 0}, { 7, 1}, { 7, 2}, { 7, 3}, { 7, 4}, { 7, 5},
{ 7, 6}, { 7, 7}, { 7, 8}, { 7, 9}, { 7, 10}, { 7, 11},
{ 7, 12}, { 7, 13}, { 7, 14}, { 7, 15}, { 7, 16}, { 7, 17},
{ 7, 18}, { 7, 19}, { 7, 20}, { 7, 21}, { 7, 22},
{ 8, 0}, { 8, 1}, { 8, 2}, { 8, 3}, { 8, 4}, { 8, 5},
{ 8, 6}, { 8, 7}, { 8, 8}, { 8, 9}, { 8, 10}, { 8, 11},
{ 8, 12},
{ 9, 0}, { 9, 1}, { 9, 2}, { 9, 3}, { 9, 4}, { 9, 5},
{ 9, 6}, { 9, 7}, { 9, 8}, { 9, 9}, { 9, 10}, { 9, 11},
{ 9, 12}, { 9, 13}, { 9, 14}, { 9, 15}, { 9, 16}, { 9, 17},
{ 9, 18}, { 9, 19}, { 9, 20}, { 9, 21}, { 9, 22}, { 9, 23},
{10, 0}, {10, 1}, {10, 2}, {10, 3}, {10, 4}, {10, 5},
{10, 6}, {10, 7}, {10, 8}, {10, 9}, {10, 10}, {10, 11},
{10, 12}, {10, 13}, {10, 14}, {10, 15}, {10, 16},
{11, 0},
{12, 0}, {12, 1}, {12, 2}, {12, 3},
{13, 0}, {13, 1}, {13, 2}, {13, 3}, {13, 4}, {13, 5},
{13, 6}, {13, 7}, {13, 8}, {13, 9}, {13, 10}, {13, 11},
{13, 12}, {13, 13},
{14, 0}, {14, 1}, {14, 2}, {14, 3}, {14, 4}, {14, 5},
{14, 6}, {14, 7}, {14, 8}, {14, 9}, {14, 10}, {14, 11},
{14, 12}, {14, 13}, {14, 14}, {14, 15}, {14, 16}, {14, 17},
{14, 18}, {14, 19},
{15, 0}, {15, 1}, {15, 2}, {15, 3}, {15, 4}, {15, 5},
{16, 0}, {16, 1}, {16, 2}, {16, 3}, {16, 4}, {16, 5},
{16, 6}, {16, 7}, {16, 8}, {16, 9}, {16, 10}, {16, 11},
{16, 12}, {16, 13}, {16, 14}, {16, 15}, {16, 16}, {16, 17},
{16, 18}, {16, 19}, {16, 20}, {16, 21}, {16, 22}, {16, 23},
{16, 24}, {16, 25}, {16, 26}, {16, 27}, {16, 28}, {16, 29},
{16, 30}, {16, 31}, {16, 32}, {16, 33},
{17, 0}, {17, 1}, {17, 2}, {17, 3}, {17, 4}, {17, 5},
{17, 6}, {17, 7}, {17, 8}, {17, 9}, {17, 10}, {17, 11},
{17, 12}, {17, 13}, {17, 14}, {17, 15},
{18, 0}, {18, 1}, {18, 2}, {18, 3}, {18, 4}, {18, 5},
{18, 6}, {18, 7}, {18, 8}, {18, 9}, {18, 10}, {18, 11},
{18, 12}, {18, 13}, {18, 14}, {18, 15}, {18, 16}, {18, 17},
{18, 18}, {18, 19}, {18, 20}, {18, 21},
{19, 0}, {19, 1}, {19, 2}, {19, 3}, {19, 4}, {19, 5},
{19, 6}, {19, 7}, {19, 8}, {19, 9}, {19, 10}, {19, 11},
{19, 12}, {19, 13}, {19, 14}, {19, 15}, {19, 16}, {19, 17},
{19, 18}, {19, 19}, {19, 20}, {19, 21}, {19, 22}, {19, 23},
{19, 24}, {19, 25}, {19, 26}, {19, 27}, {19, 28}, {19, 29},
{19, 30}, {19, 31}, {19, 32}, {19, 33}, {19, 34}, {19, 35},
{19, 36}, {19, 37}, {19, 38}, {19, 39}, {19, 40},
{20, 0},
{21, 0}, {21, 1}, {21, 2}, {21, 3}, {21, 4}, {21, 5},
{21, 6}, {21, 7}, {21, 8}, {21, 9}, {21, 10}, {21, 11},
{21, 12}, {21, 13}, {21, 14}, {21, 15}, {21, 16}, {21, 17},
{21, 18}, {21, 19}, {21, 20}, {21, 21}, {21, 22}, {21, 23},
{21, 24}, {21, 25}, {21, 26}, {21, 27}, {21, 28}, {21, 29},
{21, 30}, {21, 31}, {21, 32}, {21, 33}, {21, 34}, {21, 35},
{21, 36}, {21, 37}, {21, 38},
{22, 0}, {22, 1}, {22, 2}, {22, 3}, {22, 4}, {22, 5},
{22, 6}, {22, 7}, {22, 8}, {22, 9}, {22, 10}, {22, 11},
{22, 12}, {22, 13}, {22, 14}, {22, 15}, {22, 16}, {22, 17},
{22, 18},
{23, 0},
{24, 0}, {24, 1}, {24, 2}, {24, 3}, {24, 4}, {24, 5},
{24, 6}, {24, 7}, {24, 8},
{25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
{25, 6}, {25, 7}, {25, 8}, {25, 9}, {25, 10}, {25, 11},
{25, 12}, {25, 13}, {25, 14}, {25, 15}, {25, 16}, {25, 17},
{25, 18},
{26, 0},
{27, 0},
{28, 0}, {28, 1}, {28, 2}, {28, 3}, {28, 4}, {28, 5},
{28, 6}, {28, 7}, {28, 8}, {28, 9}, {28, 10}, {28, 11},
{28, 12}, {28, 13}, {28, 14}, {28, 15}, {28, 16}, {28, 17},
{28, 18}, {28, 19}, {28, 20}, {28, 21}, {28, 22},
{29, 0}, {29, 1}, {29, 2}, {29, 3}, {29, 4}, {29, 5},
{29, 6}, {29, 7}, {29, 8}, {29, 9}, {29, 10}, {29, 11},
{29, 12}, {29, 13},
{30, 0}, {30, 1},
{31, 0}, {31, 1}, {31, 2}, {31, 3}, {31, 4}, {31, 5},
{31, 6},
{32, 0}, {32, 1}, {32, 2}, {32, 3},
{33, 0}, {33, 1}, {33, 2}, {33, 3}, {33, 4}, {33, 5},
{34, 0}, {34, 1}, {34, 2}, {34, 3}, {34, 4}, {34, 5},
{34, 6}, {34, 7}, {34, 8}, {34, 9}, {34, 10}, {34, 11},
{34, 12}, {34, 13}, {34, 14}, {34, 15}, {34, 16}, {34, 17},
{35, 0}, {35, 1}, {35, 2}, {35, 3}, {35, 4}, {35, 5},
{35, 6}, {35, 7}, {35, 8}, {35, 9}, {35, 10}, {35, 11},
{35, 12}, {35, 13}, {35, 14}, {35, 15}, {35, 16}, {35, 17},
{35, 18}, {35, 19}, {35, 20}, {35, 21},
{36, 0}, {36, 1}, {36, 2}, {36, 3}, {36, 4}, {36, 5},
{37, 0}, {37, 1}, {37, 2}, {37, 3}, {37, 4}, {37, 5},
{37, 6}, {37, 7}, {37, 8}, {37, 9}, {37, 10}, {37, 11},
{37, 12}, {37, 13}, {37, 14}, {37, 15}, {37, 16}, {37, 17},
{37, 18}, {37, 19}, {37, 20}, {37, 21}, {37, 22}, {37, 23},
{37, 24}, {37, 25}, {37, 26},
{38, 0}, {38, 1}, {38, 2}, {38, 3}, {38, 4}, {38, 5},
{38, 6}, {38, 7}, {38, 8}, {38, 9}, {38, 10}, {38, 11},
{38, 12},
{39, 0},
{40, 0}, {40, 1}, {40, 2}, {40, 3}, {40, 4}, {40, 5},
{40, 6}, {40, 7},
{41, 0}, {41, 1}, {41, 2}, {41, 3},
{42, 0}, {42, 1}, {42, 2}, {42, 3}, {42, 4}, {42, 5},
{42, 6}, {42, 7}, {42, 8}, {42, 9}, {42, 10}, {42, 11},
{43, 0}, {43, 1}, {43, 2}, {43, 3}, {43, 4}, {43, 5},
{43, 6}, {43, 7}, {43, 8}, {43, 9}, {43, 10}, {43, 11},
{43, 12}, {43, 13}, {43, 14}, {43, 15}, {43, 16}, {43, 17},
{43, 18}, {43, 19}, {43, 20}, {43, 21}, {43, 22}, {43, 23},
{43, 24}, {43, 25}, {43, 26}, {43, 27}, {43, 28}, {43, 29},
{43, 30}, {43, 31},
{55, 0}
};
// Default palette
static const byte initVGAPalette[768] = {
0x00, 0x00, 0x00,
0x40, 0x40, 0x40,
0x58, 0x58, 0x58,
0x70, 0x70, 0x70,
0xfc, 0xfc, 0xfc,
0x00, 0xd0, 0x00,
0x00, 0xfc, 0x00,
0xd8, 0x00, 0x00,
0xfc, 0x00, 0x00,
0x00, 0x00, 0x78,
0x00, 0x00, 0xb0,
0xa0, 0xa0, 0xa0,
0x50, 0xc8, 0xfc,
0x28, 0xfc, 0x28,
0xf0, 0xf0, 0x00,
0xfc, 0x28, 0x28,
0x00, 0x00, 0x00,
0x14, 0x14, 0x14,
0x20, 0x20, 0x20,
0x2c, 0x2c, 0x2c,
0x38, 0x38, 0x38,
0x44, 0x44, 0x44,
0x50, 0x50, 0x50,
0x60, 0x60, 0x60,
0x70, 0x70, 0x70,
0x80, 0x80, 0x80,
0x90, 0x90, 0x90,
0xa0, 0xa0, 0xa0,
0xb4, 0xb4, 0xb4,
0xc8, 0xc8, 0xc8,
0xe0, 0xe0, 0xe0,
0xfc, 0xfc, 0xfc,
0x00, 0x00, 0xfc,
0x40, 0x00, 0xfc,
0x7c, 0x00, 0xfc,
0xbc, 0x00, 0xfc,
0xfc, 0x00, 0xfc,
0xfc, 0x00, 0xbc,
0xfc, 0x00, 0x7c,
0xfc, 0x00, 0x40,
0xfc, 0x00, 0x00,
0xfc, 0x40, 0x00,
0xfc, 0x7c, 0x00,
0xfc, 0xbc, 0x00,
0xfc, 0xfc, 0x00,
0xbc, 0xfc, 0x00,
0x7c, 0xfc, 0x00,
0x40, 0xfc, 0x00,
0x00, 0xfc, 0x00,
0x00, 0xfc, 0x40,
0x00, 0xfc, 0x7c,
0x00, 0xfc, 0xbc,
0x00, 0xfc, 0xfc,
0x00, 0xbc, 0xfc,
0x00, 0x7c, 0xfc,
0x00, 0x40, 0xfc,
0x7c, 0x7c, 0xfc,
0x9c, 0x7c, 0xfc,
0xbc, 0x7c, 0xfc,
0xdc, 0x7c, 0xfc,
0xfc, 0x7c, 0xfc,
0xfc, 0x7c, 0xdc,
0xfc, 0x7c, 0xbc,
0xfc, 0x7c, 0x9c,
0xfc, 0x7c, 0x7c,
0xfc, 0x9c, 0x7c,
0xfc, 0xbc, 0x7c,
0xfc, 0xdc, 0x7c,
0xfc, 0xfc, 0x7c,
0xdc, 0xfc, 0x7c,
0xbc, 0xfc, 0x7c,
0x9c, 0xfc, 0x7c,
0x7c, 0xfc, 0x7c,
0x7c, 0xfc, 0x9c,
0x7c, 0xfc, 0xbc,
0x7c, 0xfc, 0xdc,
0x7c, 0xfc, 0xfc,
0x7c, 0xdc, 0xfc,
0x7c, 0xbc, 0xfc,
0x7c, 0x9c, 0xfc,
0xb4, 0xb4, 0xfc,
0xc4, 0xb4, 0xfc,
0xd8, 0xb4, 0xfc,
0xe8, 0xb4, 0xfc,
0xfc, 0xb4, 0xfc,
0xfc, 0xb4, 0xe8,
0xfc, 0xb4, 0xd8,
0xfc, 0xb4, 0xc4,
0xfc, 0xb4, 0xb4,
0xfc, 0xc4, 0xb4,
0xfc, 0xd8, 0xb4,
0xfc, 0xe8, 0xb4,
0xfc, 0xfc, 0xb4,
0xe8, 0xfc, 0xb4,
0xd8, 0xfc, 0xb4,
0xc4, 0xfc, 0xb4,
0xb4, 0xfc, 0xb4,
0xb4, 0xfc, 0xc4,
0xb4, 0xfc, 0xd8,
0xb4, 0xfc, 0xe8,
0xb4, 0xfc, 0xfc,
0xb4, 0xe8, 0xfc,
0xb4, 0xd8, 0xfc,
0xb4, 0xc4, 0xfc,
0x00, 0x00, 0x70,
0x1c, 0x00, 0x70,
0x38, 0x00, 0x70,
0x54, 0x00, 0x70,
0x70, 0x00, 0x70,
0x70, 0x00, 0x54,
0x70, 0x00, 0x38,
0x70, 0x00, 0x1c,
0x70, 0x00, 0x00,
0x70, 0x1c, 0x00,
0x70, 0x38, 0x00,
0x70, 0x54, 0x00,
0x70, 0x70, 0x00,
0x54, 0x70, 0x00,
0x38, 0x70, 0x00,
0x1c, 0x70, 0x00,
0x00, 0x70, 0x00,
0x00, 0x70, 0x1c,
0x00, 0x70, 0x38,
0x00, 0x70, 0x54,
0x00, 0x70, 0x70,
0x00, 0x54, 0x70,
0x00, 0x38, 0x70,
0x00, 0x1c, 0x70,
0x38, 0x38, 0x70,
0x44, 0x38, 0x70,
0x54, 0x38, 0x70,
0x60, 0x38, 0x70,
0x70, 0x38, 0x70,
0x70, 0x38, 0x60,
0x70, 0x38, 0x54,
0x70, 0x38, 0x44,
0x70, 0x38, 0x38,
0x70, 0x44, 0x38,
0x70, 0x54, 0x38,
0x70, 0x60, 0x38,
0x70, 0x70, 0x38,
0x60, 0x70, 0x38,
0x54, 0x70, 0x38,
0x44, 0x70, 0x38,
0x38, 0x70, 0x38,
0x38, 0x70, 0x44,
0x38, 0x70, 0x54,
0x38, 0x70, 0x60,
0x38, 0x70, 0x70,
0x38, 0x60, 0x70,
0x38, 0x54, 0x70,
0x38, 0x44, 0x70,
0x50, 0x50, 0x70,
0x58, 0x50, 0x70,
0x60, 0x50, 0x70,
0x68, 0x50, 0x70,
0x70, 0x50, 0x70,
0x70, 0x50, 0x68,
0x70, 0x50, 0x60,
0x70, 0x50, 0x58,
0x70, 0x50, 0x50,
0x70, 0x58, 0x50,
0x70, 0x60, 0x50,
0x70, 0x68, 0x50,
0x70, 0x70, 0x50,
0x68, 0x70, 0x50,
0x60, 0x70, 0x50,
0x58, 0x70, 0x50,
0x50, 0x70, 0x50,
0x50, 0x70, 0x58,
0x50, 0x70, 0x60,
0x50, 0x70, 0x68,
0x50, 0x70, 0x70,
0x50, 0x68, 0x70,
0x50, 0x60, 0x70,
0x50, 0x58, 0x70,
0x00, 0x00, 0x40,
0x10, 0x00, 0x40,
0x20, 0x00, 0x40,
0x30, 0x00, 0x40,
0x40, 0x00, 0x40,
0x40, 0x00, 0x30,
0x40, 0x00, 0x20,
0x40, 0x00, 0x10,
0x40, 0x00, 0x00,
0x40, 0x10, 0x00,
0x40, 0x20, 0x00,
0x40, 0x30, 0x00,
0x40, 0x40, 0x00,
0x30, 0x40, 0x00,
0x20, 0x40, 0x00,
0x10, 0x40, 0x00,
0x00, 0x40, 0x00,
0x00, 0x40, 0x10,
0x00, 0x40, 0x20,
0x00, 0x40, 0x30,
0x00, 0x40, 0x40,
0x00, 0x30, 0x40,
0x00, 0x20, 0x40,
0x00, 0x10, 0x40,
0x20, 0x20, 0x40,
0x28, 0x20, 0x40,
0x30, 0x20, 0x40,
0x38, 0x20, 0x40,
0x40, 0x20, 0x40,
0x40, 0x20, 0x38,
0x40, 0x20, 0x30,
0x40, 0x20, 0x28,
0x40, 0x20, 0x20,
0x40, 0x28, 0x20,
0x40, 0x30, 0x20,
0x40, 0x38, 0x20,
0x40, 0x40, 0x20,
0x38, 0x40, 0x20,
0x30, 0x40, 0x20,
0x28, 0x40, 0x20,
0x20, 0x40, 0x20,
0x20, 0x40, 0x28,
0x20, 0x40, 0x30,
0x20, 0x40, 0x38,
0x20, 0x40, 0x40,
0x20, 0x38, 0x40,
0x20, 0x30, 0x40,
0x20, 0x28, 0x40,
0x2c, 0x2c, 0x40,
0x30, 0x2c, 0x40,
0x34, 0x2c, 0x40,
0x3c, 0x2c, 0x40,
0x40, 0x2c, 0x40,
0x40, 0x2c, 0x3c,
0x40, 0x2c, 0x34,
0x40, 0x2c, 0x30,
0x40, 0x2c, 0x2c,
0x40, 0x30, 0x2c,
0x40, 0x34, 0x2c,
0x40, 0x3c, 0x2c,
0x40, 0x40, 0x2c,
0x3c, 0x40, 0x2c,
0x34, 0x40, 0x2c,
0x30, 0x40, 0x2c,
0x2c, 0x40, 0x2c,
0x2c, 0x40, 0x30,
0x2c, 0x40, 0x34,
0x2c, 0x40, 0x3c,
0x2c, 0x40, 0x40,
0x2c, 0x3c, 0x40,
0x2c, 0x34, 0x40,
0x2c, 0x30, 0x40,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00
};
static const byte font[][5] = {
{0x00,0x00,0x00,0xff,0x00},
{0x5f,0xff,0x00,0x00,0x00},
{0x03,0x00,0x03,0xff,0x00},
{0x14,0x7f,0x14,0x7f,0x14},
{0x24,0x2a,0x7f,0x2a,0x12},
{0x61,0x10,0x08,0x04,0x43},
{0x38,0x4e,0x59,0x26,0x50},
{0x03,0xff,0x00,0x00,0x00},
{0x3e,0x41,0xff,0x00,0x00},
{0x41,0x3e,0xff,0x00,0x00},
{0x10,0x54,0x38,0x54,0x10},
{0x10,0x10,0x7c,0x10,0x10},
{0x80,0x40,0xff,0x00,0x00},
{0x10,0x10,0x10,0x10,0x10},
{0x40,0xff,0x00,0x00,0x00},
{0x60,0x10,0x08,0x04,0x03},
{0x3e,0x41,0x41,0x41,0x3e}, /* digits */
{0x04,0x02,0x7f,0xff,0x00},
{0x42,0x61,0x51,0x49,0x46},
{0x22,0x41,0x49,0x49,0x36},
{0x18,0x14,0x12,0x7f,0x10},
{0x27,0x45,0x45,0x45,0x39},
{0x3e,0x49,0x49,0x49,0x32},
{0x01,0x61,0x19,0x07,0x01},
{0x36,0x49,0x49,0x49,0x36},
{0x26,0x49,0x49,0x49,0x3e},
{0x44,0xff,0x00,0x00,0x00},
{0x80,0x44,0xff,0x00,0x00},
{0x10,0x28,0x44,0xff,0x00},
{0x28,0x28,0x28,0x28,0x28},
{0x44,0x28,0x10,0xff,0x00},
{0x02,0x01,0x51,0x09,0x06},
{0x3e,0x41,0x5d,0x5d,0x1e},
{0x7c,0x12,0x11,0x12,0x7c}, /* uppercase letters*/
{0x7f,0x49,0x49,0x49,0x36},
{0x3e,0x41,0x41,0x41,0x22},
{0x7f,0x41,0x41,0x22,0x1c},
{0x7f,0x49,0x49,0x49,0xff},
{0x7f,0x09,0x09,0x09,0xff},
{0x3e,0x41,0x41,0x49,0x3a},
{0x7f,0x08,0x08,0x08,0x7f},
{0x41,0x7f,0x41,0xff,0x00},
{0x20,0x40,0x40,0x3f,0xff},
{0x7f,0x08,0x14,0x22,0x41},
{0x7f,0x40,0x40,0x40,0xff},
{0x7f,0x02,0x04,0x02,0x7f},
{0x7f,0x02,0x0c,0x10,0x7f},
{0x3e,0x41,0x41,0x41,0x3e},
{0x7f,0x09,0x09,0x09,0x06},
{0x3e,0x41,0x51,0x21,0x5e},
{0x7f,0x09,0x19,0x29,0x46},
{0x26,0x49,0x49,0x49,0x32},
{0x01,0x01,0x7f,0x01,0x01},
{0x3f,0x40,0x40,0x40,0x3f},
{0x07,0x18,0x60,0x18,0x07},
{0x1f,0x60,0x18,0x60,0x1f},
{0x63,0x14,0x08,0x14,0x63},
{0x03,0x04,0x78,0x04,0x03},
{0x61,0x51,0x49,0x45,0x43},
{0x7f,0x41,0x41,0xff,0x00},
{0x03,0x04,0x08,0x10,0x60},
{0x41,0x41,0x7f,0xff,0x00},
{0x02,0x01,0x02,0xff,0x00},
{0x80,0x80,0x80,0x80,0x80},
{0x01,0x02,0xff,0x00,0x00},
{0x38,0x44,0x44,0x44,0x7c}, /* lowercase letters */
{0x7f,0x44,0x44,0x44,0x38},
{0x38,0x44,0x44,0x44,0x44},
{0x38,0x44,0x44,0x44,0x7f},
{0x38,0x54,0x54,0x54,0x58},
{0x04,0x7e,0x05,0x01,0xff},
{0x98,0xa4,0xa4,0xa4,0x7c},
{0x7f,0x04,0x04,0x04,0x78},
{0x7d,0xff,0x00,0x00,0x00},
{0x80,0x80,0x7d,0xff,0x00},
{0x7f,0x10,0x28,0x44,0xff},
{0x7f,0xff,0x00,0x00,0x00},
{0x7c,0x04,0x7c,0x04,0x78},
{0x7c,0x04,0x04,0x04,0x78},
{0x38,0x44,0x44,0x44,0x38},
{0xfc,0x24,0x24,0x24,0x18},
{0x18,0x24,0x24,0x24,0xfc},
{0x7c,0x08,0x04,0x04,0xff},
{0x48,0x54,0x54,0x54,0x24},
{0x04,0x3e,0x44,0x40,0xff},
{0x7c,0x40,0x40,0x40,0x3c},
{0x0c,0x30,0x40,0x30,0x0c},
{0x3c,0x40,0x3c,0x40,0x3c},
{0x44,0x28,0x10,0x28,0x44},
{0x9c,0xa0,0xa0,0xa0,0x7c},
{0x44,0x64,0x54,0x4c,0x44},
{0x08,0x36,0x41,0xff,0x00},
{0x77,0xff,0x00,0x00,0x00},
{0x41,0x36,0x08,0xff,0x00},
{0x02,0x01,0x02,0x01,0xff},
{0xff,0x00,0x00,0x00,0x00},
{0xfe,0x49,0x49,0x4e,0x30}, /* sharp S */
{0x7c,0x41,0x40,0x41,0x3c}, /* umlauts */
{0x04,0x06,0x7f,0x06,0x04}, /* arrows */
{0x20,0x60,0xfe,0x60,0x20},
{0x38,0x45,0x44,0x45,0x7c}, /* umlauts */
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0x79,0x14,0x12,0x14,0x79},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0x38,0x45,0x44,0x45,0x38},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0xff,0x00,0x00,0x00,0x00},
{0x3d,0x42,0x42,0x42,0x3d},
{0x3d,0x40,0x40,0x40,0x3d},
};
}

View File

@@ -0,0 +1,80 @@
/* 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 "audio/audiostream.h"
#include "audio/mixer.h"
#include "audio/decoders/raw.h"
#include "audio/mods/protracker.h"
#include "common/system.h"
#include "supernova/resman.h"
#include "supernova/sound.h"
#include "supernova/supernova.h"
namespace Supernova {
Sound::Sound(Audio::Mixer *mixer, ResourceManager *resMan)
: _mixer(mixer)
, _resMan(resMan) {
}
void Sound::play(AudioId index) {
Audio::AudioStream *stream = _resMan->getSoundStream(index);
stop();
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, stream,
-1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
}
void Sound::play(MusicId index) {
Audio::AudioStream *stream = _resMan->getSoundStream(index);
stop();
_mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, stream,
-1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
}
void Sound::playSiren() {
Audio::AudioStream *stream = _resMan->getSirenStream();
stop();
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, stream,
-1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
}
bool Sound::isPlaying() {
return _mixer->isSoundHandleActive(_soundHandle);
}
void Sound::stop() {
if (_mixer->isSoundHandleActive(_soundHandle))
_mixer->stopHandle(_soundHandle);
}
int Sound::getVolume() {
return _mixer->getChannelVolume(_soundHandle);
}
void Sound::setVolume(int volume) {
_mixer->setChannelVolume(_soundHandle, volume);
}
}

106
engines/supernova/sound.h Normal file
View File

@@ -0,0 +1,106 @@
/* 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 SUPERNOVA_SOUND_H
#define SUPERNOVA_SOUND_H
#include "audio/mixer.h"
namespace Supernova {
class SupernovaEngine;
class ResourceManager;
enum AudioId {
// Supernova 1
kAudioFoundLocation, // 44|0
kAudioCrash, // 45|0
kAudioVoiceHalt, // 46|0
kAudioGunShot, // 46|2510
kAudioSmash, // 46|4020
kAudioVoiceSupernova, // 47|0
kAudioVoiceYeah, // 47|24010
kAudioRobotShock, // 48|0
kAudioRobotBreaks, // 48|2510
kAudioShock, // 48|10520
kAudioTurntable, // 48|13530
kAudioSiren, // 50|0
kAudioSnoring, // 50|12786
kAudioRocks, // 51|0
kAudioDeath, // 53|0
kAudioAlarm, // 54|0
kAudioSuccess, // 54|8010
kAudioSlideDoor, // 54|24020
kAudioDoorOpen, // 54|30030
kAudioDoorClose, // 54|31040
kAudioNumSamples1,
// Supernova 2
kAudioIntroDing = 0,
kAudioSuccess2,
kAudioTaxiOpen,
kAudioTaxiLeaving,
kAudioTaxiArriving,
kAudioKiosk,
kAudioStage1,
kAudioStage2,
kAudioAppearance1,
kAudioAppearance2,
kAudioAppearance3,
kAudioElevatorBell,
kAudioElevator1,
kAudioShip1,
kAudioShip2,
kAudioShip3,
kAudioShipDeath,
kAudioDeath2,
kAudioCaught,
kAudioNumSamples2
};
enum MusicId {
kMusicIntro,
kMusicOutro,
kMusicMadMonkeys
};
class Sound {
public:
public:
Sound(Audio::Mixer *mixer, ResourceManager *resMan);
void play(AudioId index);
void play(MusicId index);
void playSiren();
void setVolume(int volume);
int getVolume();
void stop();
bool isPlaying();
private:
Audio::Mixer *_mixer;
ResourceManager *_resMan;
Audio::SoundHandle _soundHandle;
};
}
#endif

View File

@@ -0,0 +1,861 @@
/* 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/config-manager.h"
#include "common/debug.h"
#include "common/debug-channels.h"
#include "common/endian.h"
#include "common/error.h"
#include "common/events.h"
#include "common/file.h"
#include "common/fs.h"
#include "common/memstream.h"
#include "common/savefile.h"
#include "common/str.h"
#include "common/system.h"
#include "common/translation.h"
#include "common/text-to-speech.h"
#include "engines/util.h"
#include "engines/advancedDetector.h"
#include "graphics/cursorman.h"
#include "graphics/surface.h"
#include "graphics/screen.h"
#include "graphics/thumbnail.h"
#include "gui/saveload.h"
#include "supernova/resman.h"
#include "supernova/screen.h"
#include "supernova/sound.h"
#include "supernova/supernova.h"
#include "supernova/supernova1/state.h"
#include "supernova/supernova2/state.h"
#include "supernova/game-manager.h"
#include "backends/keymapper/keymapper.h"
namespace Supernova {
ObjectType operator|(ObjectType a, ObjectType b) {
return static_cast<ObjectType>(+a | +b);
}
ObjectType operator&(ObjectType a, ObjectType b) {
return static_cast<ObjectType>(+a & +b);
}
ObjectType operator^(ObjectType a, ObjectType b) {
return static_cast<ObjectType>(+a ^ +b);
}
ObjectType &operator|=(ObjectType &a, ObjectType b) {
return a = a | b;
}
ObjectType &operator&=(ObjectType &a, ObjectType b) {
return a = a & b;
}
ObjectType &operator^=(ObjectType &a, ObjectType b) {
return a = a ^ b;
}
SupernovaEngine::SupernovaEngine(OSystem *syst)
: Engine(syst)
, _gm(nullptr)
, _sound(nullptr)
, _resMan(nullptr)
, _screen(nullptr)
, _allowLoadGame(true)
, _allowSaveGame(true)
, _sleepAutoSave(nullptr)
, _sleepAuoSaveVersion(-1)
, _delay(33)
, _textSpeed(kTextSpeed[2])
, _improved(false) {
if (ConfMan.hasKey("textspeed"))
_textSpeed = ConfMan.getInt("textspeed");
if (ConfMan.get("gameid") == "msn1")
_MSPart = 1;
else if (ConfMan.get("gameid") == "msn2")
_MSPart = 2;
else
_MSPart = 0;
_improved = ConfMan.getBool("improved");
}
SupernovaEngine::~SupernovaEngine() {
delete _sleepAutoSave;
delete _gm;
delete _sound;
delete _resMan;
delete _screen;
}
Common::Error SupernovaEngine::run() {
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
if (ttsMan != nullptr) {
ttsMan->setLanguage(ConfMan.get("language"));
ttsMan->enable(ConfMan.getBool("tts_enabled"));
}
init();
while (!shouldQuit()) {
uint32 start = _system->getMillis();
_gm->updateEvents();
_gm->executeRoom();
_system->updateScreen();
int end = _delay - (_system->getMillis() - start);
if (end > 0)
_system->delayMillis(end);
}
_mixer->stopAll();
return Common::kNoError;
}
void SupernovaEngine::init() {
Graphics::ModeList modes;
modes.push_back(Graphics::Mode(320, 200));
modes.push_back(Graphics::Mode(640, 480));
initGraphicsModes(modes);
initGraphics(320, 200);
Common::Error status = loadGameStrings();
if (status.getCode() != Common::kNoError)
error("Failed reading game strings");
_resMan = new ResourceManager(this);
_sound = new Sound(_mixer, _resMan);
_screen = new Screen(this, _resMan);
if (_MSPart == 1)
_gm = new GameManager1(this, _sound);
else if (_MSPart == 2)
_gm = new GameManager2(this, _sound);
setDebugger(new Console(this, _gm));
setTotalPlayTime(0);
int saveSlot = ConfMan.getInt("save_slot");
if (saveSlot >= 0) {
if (loadGameState(saveSlot).getCode() != Common::kNoError)
error("Failed to load save game from slot %i", saveSlot);
}
}
bool SupernovaEngine::hasFeature(EngineFeature f) const {
switch (f) {
case kSupportsReturnToLauncher:
return true;
case kSupportsLoadingDuringRuntime:
return true;
case kSupportsSavingDuringRuntime:
return true;
default:
return false;
}
}
void SupernovaEngine::pauseEngineIntern(bool pause) {
_mixer->pauseAll(pause);
_gm->pauseTimer(pause);
}
Common::Error SupernovaEngine::loadGameStrings() {
Common::String string_id("TEXT");
Common::SeekableReadStream *stream = getBlockFromDatFile(string_id);
if (stream == nullptr) {
Common::Language l = Common::parseLanguage(ConfMan.get("language"));
GUIErrorMessageFormat(_("Unable to locate the text for %s language in engine data file."), Common::getLanguageDescription(l));
return Common::kReadingFailed;
}
int size = stream->size();
while (size > 0) {
Common::String s;
char ch;
while ((ch = (char)stream->readByte()) != '\0')
s += ch;
_gameStrings.push_back(s);
size -= s.size() + 1;
}
return Common::kNoError;
}
const Common::String &SupernovaEngine::getGameString(int idx) const {
if (idx < 0 || idx >= (int)_gameStrings.size())
return _nullString;
return _gameStrings[idx];
}
void SupernovaEngine::setGameString(int idx, const Common::String &string) {
if (idx < 0)
return;
while ((int)_gameStrings.size() <= idx)
_gameStrings.push_back(Common::String());
_gameStrings[idx] = string;
}
void SupernovaEngine::playSound(AudioId sample) {
if (!shouldQuit())
_sound->play(sample);
}
void SupernovaEngine::playSound(MusicId index) {
if (!shouldQuit())
_sound->play(index);
}
void SupernovaEngine::renderImage(int section) {
_gm->_currentRoom->setSectionVisible(section, true);
_screen->renderImage(section);
}
void SupernovaEngine::renderImage(ImageId id, bool removeImage) {
_gm->_currentRoom->setSectionVisible(_screen->getImageInfo(id)->section, !removeImage);
_screen->renderImage(id, removeImage);
}
bool SupernovaEngine::setCurrentImage(int filenumber) {
return _screen->setCurrentImage(filenumber);
}
void SupernovaEngine::saveScreen(int x, int y, int width, int height) {
_screen->saveScreen(x, y, width, height);
}
void SupernovaEngine::saveScreen(const GuiElement &guiElement) {
_screen->saveScreen(guiElement);
}
void SupernovaEngine::restoreScreen() {
_screen->restoreScreen();
}
void SupernovaEngine::renderRoom(Room &room) {
_screen->renderRoom(room);
}
void SupernovaEngine::renderMessage(const char *text, MessagePosition position) {
_gm->_messageDuration = (Common::strnlen(text, 512) + 20) * _textSpeed / 10;
_screen->renderMessage(text, position);
}
void SupernovaEngine::renderMessage(const Common::String &text, MessagePosition position) {
_gm->_messageDuration = (text.size() + 20) * _textSpeed / 10;
_screen->renderMessage(text, position);
}
void SupernovaEngine::renderMessage(int stringId, MessagePosition position, Common::String var1, Common::String var2) {
_gm->_messageDuration = (getGameString(stringId).size() + 20) * _textSpeed / 10;
_screen->renderMessage(stringId, position, var1, var2);
}
void SupernovaEngine::renderMessage(int stringId, int x, int y) {
_gm->_messageDuration = (getGameString(stringId).size() + 20) * _textSpeed / 10;
_screen->renderMessage(getGameString(stringId).c_str(), kMessageNormal, x, y);
}
void SupernovaEngine::removeMessage() {
_screen->removeMessage();
}
void SupernovaEngine::renderText(const uint16 character) {
_screen->renderText(character);
}
void SupernovaEngine::renderText(const char *text) {
_screen->renderText(text);
}
void SupernovaEngine::renderText(const Common::String &text) {
_screen->renderText(text);
}
void SupernovaEngine::renderText(int stringId) {
_screen->renderText(stringId);
}
void SupernovaEngine::renderText(const GuiElement &guiElement) {
_screen->renderText(guiElement);
}
void SupernovaEngine::renderText(const uint16 character, int x, int y, byte color) {
_screen->renderText(character, x, y, color);
}
void SupernovaEngine::renderText(const char *text, int x, int y, byte color) {
_screen->renderText(text, x, y, color);
}
void SupernovaEngine::renderText(const Common::String &text, int x, int y, byte color) {
_screen->renderText(text, x, y, color);
}
void SupernovaEngine::renderText(int stringId, int x, int y, byte color) {
_screen->renderText(stringId, x, y, color);
}
void SupernovaEngine::renderBox(int x, int y, int width, int height, byte color) {
_screen->renderBox(x, y, width, height, color);
}
void SupernovaEngine::renderBox(const GuiElement &guiElement) {
_screen->renderBox(guiElement);
}
void SupernovaEngine::paletteBrightness() {
_screen->paletteBrightness();
}
void SupernovaEngine::paletteFadeOut(int minBrightness) {
if (!shouldQuit())
_screen->paletteFadeOut(minBrightness);
}
void SupernovaEngine::paletteFadeIn() {
if (!shouldQuit()) {
_gm->roomBrightness();
_screen->paletteFadeIn(_gm->_roomBrightness);
}
}
void SupernovaEngine::setColor63(byte value) {
_screen->setColor63(value);
}
void SupernovaEngine::setTextSpeed() {
// turn off keymapper so that we can select speed using Keys 1-5
Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper();
keymapper->disableAllGameKeymaps();
keymapper->getKeymap("menu")->setEnabled(true);
const Common::String &textSpeedString = getGameString(kStringTextSpeed);
int stringWidth = Screen::textWidth(textSpeedString);
int textX = (kScreenWidth - stringWidth) / 2;
int textY = 100;
stringWidth += 4;
int boxX = stringWidth > 110 ? (kScreenWidth - stringWidth) / 2 : 105;
int boxY = 97;
int boxWidth = stringWidth > 110 ? stringWidth : 110;
int boxHeight = 27;
_gm->animationOff();
_gm->saveTime();
saveScreen(boxX, boxY, boxWidth, boxHeight);
renderBox(boxX, boxY, boxWidth, boxHeight, kColorBlue);
renderText(textSpeedString, textX, textY, kColorWhite99); // Text speed
// Find the closest index in kTextSpeed for the current _textSpeed.
// Important note: values in kTextSpeed decrease with the index.
int speedIndex = 0;
while (speedIndex < 4 && _textSpeed < (kTextSpeed[speedIndex] + kTextSpeed[speedIndex+1]) / 2)
++speedIndex;
char nbString[2];
nbString[1] = 0;
for (int i = 0; i < 5; ++i) {
byte color = i == speedIndex ? kColorWhite63 : kColorWhite35;
renderBox(110 + 21 * i, 111, 16, 10, color);
nbString[0] = '1' + i;
renderText(nbString, 115 + 21 * i, 112, kColorWhite99);
}
do {
_gm->getInput();
int key = _gm->_keyPressed ? _gm->_key.keycode : Common::KEYCODE_INVALID;
if (!_gm->_keyPressed && _gm->_mouseClicked && _gm->_mouseY >= 111 && _gm->_mouseY < 121 && (_gm->_mouseX + 16) % 21 < 16)
key = Common::KEYCODE_0 - 5 + (_gm->_mouseX + 16) / 21;
if (key == Common::KEYCODE_ESCAPE)
break;
else if (key >= Common::KEYCODE_1 && key <= Common::KEYCODE_5) {
speedIndex = key - Common::KEYCODE_1;
_textSpeed = kTextSpeed[speedIndex];
ConfMan.setInt("textspeed", _textSpeed);
break;
}
} while (!shouldQuit());
_gm->resetInputState();
restoreScreen();
_gm->loadTime();
_gm->animationOn();
keymapper->getKeymap("menu")->setEnabled(false);
keymapper->getKeymap("supernova-default")->setEnabled(true);
keymapper->getKeymap("improved-mode")->setEnabled(true);
}
void SupernovaEngine::showHelpScreen1() {
if (_screen->isMessageShown())
_screen->removeMessage();
_gm->animationOff();
_gm->saveTime();
paletteFadeOut();
renderImage(kImageHelpScreen);
renderBox(100, 100, 192, 78, kColorWhite35);
renderText(kStringHelpOverview1, 105, 105, kColorWhite99);
renderText(kStringHelpOverview2, 105, 115, kColorWhite99);
renderText(kStringHelpOverview3, 105, 125, kColorWhite99);
renderText(kStringHelpOverview4, 105, 135, kColorWhite99);
renderText(kStringHelpOverview5, 105, 145, kColorWhite99);
renderText(kStringHelpOverview6, 105, 155, kColorWhite99);
renderText(kStringHelpOverview7, 105, 165, kColorWhite99);
paletteFadeIn();
_gm->getInput(true);
paletteFadeOut();
_gm->loadTime();
_gm->animationOn();
}
void SupernovaEngine::showHelpScreen2() {
if (_screen->isMessageShown())
_screen->removeMessage();
_gm->animationOff();
_gm->saveTime();
paletteFadeOut();
setCurrentImage(27);
renderImage(0);
paletteFadeIn();
_gm->getInput(true);
paletteFadeOut();
_gm->loadTime();
_gm->animationOn();
}
Common::SeekableReadStream *SupernovaEngine::getBlockFromDatFile(Common::String name) {
Common::String cur_lang = ConfMan.get("language");
// Validate the data file header
Common::File f;
char id[5], lang[5];
id[4] = lang[4] = '\0';
if (!f.open(SUPERNOVA_DAT)) {
GUIErrorMessageFormat(_("Unable to locate the '%s' engine data file."), SUPERNOVA_DAT);
return nullptr;
}
f.read(id, 3);
if (strncmp(id, "MSN", 3) != 0) {
GUIErrorMessageFormat(_("The '%s' engine data file is corrupt."), SUPERNOVA_DAT);
return nullptr;
}
int version = f.readByte();
if (version != SUPERNOVA_DAT_VERSION) {
GUIErrorMessageFormat(
_("Incorrect version of the '%s' engine data file found. Expected %d but got %d."),
SUPERNOVA_DAT, SUPERNOVA_DAT_VERSION, version);
return nullptr;
}
uint32 gameBlockSize = 0;
while (!f.eos()) {
int part = f.readByte();
gameBlockSize = f.readUint32LE();
if (f.eos()){
GUIErrorMessageFormat(_("Unable to find block for part %d"), _MSPart);
return nullptr;
}
if (part == _MSPart) {
break;
} else
f.skip(gameBlockSize);
}
uint32 readSize = 0;
while (readSize < gameBlockSize) {
f.read(id, 4);
f.read(lang, 4);
uint32 size = f.readUint32LE();
if (f.eos())
break;
if (name == id && cur_lang == lang) {
return f.readStream(size);
} else {
f.skip(size);
// size + 4 bytes for id + 4 bytes for lang + 4 bytes for size
readSize += size + 12;
}
}
return nullptr;
}
Common::Error SupernovaEngine::showTextReader(const char *extension) {
Common::SeekableReadStream *stream;
Common::String blockName;
blockName = Common::String::format("%s%d", extension, _MSPart);
blockName.toUppercase();
if ((stream = getBlockFromDatFile(blockName)) == nullptr) {
Common::File file;
Common::Path filename;
if (_MSPart == 1)
filename = Common::Path(Common::String::format("msn.%s", extension));
if (_MSPart == 2)
filename = Common::Path(Common::String::format("ms2.%s", extension));
if (!file.open(filename)) {
GUIErrorMessageFormat(_("Unable to find '%s' in game folder or the engine data file."), filename.toString().c_str());
return Common::kReadingFailed;
}
stream = file.readStream(file.size());
}
int linesInFile = 0;
while (!stream->eos()) {
stream->readLine();
++linesInFile;
}
--linesInFile;
stream->seek(0);
stream->clearErr();
if (_screen->isMessageShown())
_screen->removeMessage();
_gm->animationOff();
_gm->saveTime();
paletteFadeOut();
g_system->fillScreen(kColorWhite35);
for (int y = 6; y < (200 - kFontHeight); y += (kFontHeight + 2)) {
Common::String line = stream->readLine();
if (stream->eos())
break;
_screen->renderText(line, 6, y, kColorWhite99);
}
paletteFadeIn();
Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper();
keymapper->disableAllGameKeymaps();
keymapper->getKeymap("text-reader")->setEnabled(true);
const int linesPerPage = 19;
int lineNumber = 0;
bool exitReader = false;
do {
stream->seek(0);
stream->clearErr();
for (int i = 0; i < lineNumber; ++i)
stream->readLine();
g_system->fillScreen(kColorWhite35);
for (int y = 6; y < (_screen->getScreenHeight() - kFontHeight); y += (kFontHeight + 2)) {
Common::String line = stream->readLine();
if (stream->eos())
break;
_screen->renderText(line, 6, y, kColorWhite99);
}
_gm->getInput(true);
switch (_gm->_action) {
case kActionExit:
exitReader = true;
break;
case kActionUp:
lineNumber = lineNumber > 0 ? lineNumber - 1 : 0;
break;
case kActionDown:
lineNumber = lineNumber < linesInFile - (linesPerPage + 1) ? lineNumber + 1
: linesInFile - linesPerPage;
break;
case kActionPgUp:
lineNumber = lineNumber > linesPerPage ? lineNumber - linesPerPage : 0;
break;
case kActionPgDown:
lineNumber = lineNumber < linesInFile - (linesPerPage * 2) ? lineNumber + linesPerPage
: linesInFile - linesPerPage;
break;
default:
break;
}
} while (!exitReader && !shouldQuit());
paletteFadeOut();
_gm->loadTime();
_gm->animationOn();
keymapper->getKeymap("text-reader")->setEnabled(false);
keymapper->getKeymap("supernova-default")->setEnabled(true);
keymapper->getKeymap("improved-mode")->setEnabled(true);
return Common::kNoError;
}
bool SupernovaEngine::quitGameDialog() {
bool quit = false;
Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper();
keymapper->disableAllGameKeymaps();
keymapper->getKeymap("menu")->setEnabled(true);
GuiElement guiQuitBox;
guiQuitBox.setColor(kColorRed, kColorWhite99, kColorRed, kColorWhite99);
guiQuitBox.setSize(112, 97, 112 + 96, 97 + 27);
guiQuitBox.setText(getGameString(kStringLeaveGame).c_str());
guiQuitBox.setTextPosition(guiQuitBox.left + 3, guiQuitBox.top + 3);
GuiElement guiQuitYes;
guiQuitYes.setColor(kColorWhite35, kColorWhite99, kColorWhite35, kColorWhite99);
guiQuitYes.setSize(115, 111, 158, 121);
guiQuitYes.setText(getGameString(kStringYes).c_str());
guiQuitYes.setTextPosition(132, 112);
GuiElement guiQuitNo;
guiQuitNo.setColor(kColorWhite35, kColorWhite99, kColorWhite35, kColorWhite99);
guiQuitNo.setSize(162, 111, 205, 121);
guiQuitNo.setText(getGameString(kStringNo).c_str());
guiQuitNo.setTextPosition(173, 112);
_gm->animationOff();
saveScreen(guiQuitBox);
renderBox(guiQuitBox);
renderText(guiQuitBox);
renderBox(guiQuitYes);
renderText(guiQuitYes);
renderBox(guiQuitNo);
renderText(guiQuitNo);
do {
_gm->getInput();
if (_gm->_keyPressed) {
if (_gm->_key.keycode == Common::KEYCODE_j) {
quit = true;
break;
} else if (_gm->_key.keycode == Common::KEYCODE_n) {
quit = false;
break;
}
}
if (_gm->_mouseClicked) {
if (guiQuitYes.contains(_gm->_mouseX, _gm->_mouseY)) {
quit = true;
break;
} else if (guiQuitNo.contains(_gm->_mouseX, _gm->_mouseY)) {
quit = false;
break;
}
}
} while (true);
_gm->resetInputState();
restoreScreen();
_gm->animationOn();
keymapper->getKeymap("menu")->setEnabled(false);
keymapper->getKeymap("supernova-default")->setEnabled(true);
keymapper->getKeymap("improved-mode")->setEnabled(true);
return quit;
}
bool SupernovaEngine::canLoadGameStateCurrently(Common::U32String *msg) {
return _allowLoadGame;
}
Common::Error SupernovaEngine::loadGameState(int slot) {
return (loadGame(slot) ? Common::kNoError : Common::kReadingFailed);
}
bool SupernovaEngine::canSaveGameStateCurrently(Common::U32String *msg) {
// Do not allow saving when either _allowSaveGame, _animationEnabled or _guiEnabled is false
return _allowSaveGame && _gm->canSaveGameStateCurrently();
}
Common::Error SupernovaEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
return (saveGame(slot, desc) ? Common::kNoError : Common::kWritingFailed);
}
bool SupernovaEngine::serialize(Common::WriteStream *out) {
if (!_gm->serialize(out))
return false;
out->writeByte(_screen->getGuiBrightness());
out->writeByte(_screen->getViewportBrightness());
return true;
}
bool SupernovaEngine::deserialize(Common::ReadStream *in, int version) {
if (!_gm->deserialize(in, version))
return false;
if (version >= 5) {
_screen->setGuiBrightness(in->readByte());
_screen->setViewportBrightness(in->readByte());
} else {
_screen->setGuiBrightness(255);
_screen->setViewportBrightness(255);
}
return true;
}
Common::String SupernovaEngine::getSaveStateName(int slot) const {
if (_MSPart == 1)
return Common::String::format("msn_save.%03d", slot);
else if (_MSPart == 2)
return Common::String::format("ms2_save.%03d", slot);
return "";
}
bool SupernovaEngine::loadGame(int slot) {
if (slot < 0)
return false;
// Stop any sound currently playing.
_sound->stop();
// Make sure no message is displayed as this would otherwise delay the
// switch to the new location until a mouse click.
removeMessage();
if (slot == kSleepAutosaveSlot) {
if (_sleepAutoSave != nullptr && deserialize(_sleepAutoSave, _sleepAuoSaveVersion)) {
// We no longer need the sleep autosave
delete _sleepAutoSave;
_sleepAutoSave = nullptr;
return true;
}
// Old version used to save it literally in the kSleepAutosaveSlot, so
// continue to try to load it from there.
}
Common::String filename = getSaveStateName(slot);
Common::InSaveFile *savefile = _saveFileMan->openForLoading(filename);
if (!savefile)
return false;
uint saveHeader = savefile->readUint32LE();
if ((_MSPart == 1 && saveHeader != SAVEGAME_HEADER) ||
(_MSPart == 2 && saveHeader != SAVEGAME_HEADER2)) {
warning("No header found in '%s'", filename.c_str());
delete savefile;
return false; //Common::kUnknownError
}
byte saveVersion = savefile->readByte();
// Save version 1 was used during development and is no longer supported
if (saveVersion > SAVEGAME_VERSION || saveVersion < 10) {
warning("Save game version %i not supported", saveVersion);
delete savefile;
return false; //Common::kUnknownError;
}
int descriptionSize = savefile->readSint16LE();
savefile->skip(descriptionSize);
savefile->skip(6);
setTotalPlayTime(savefile->readUint32LE() * 1000);
Graphics::skipThumbnail(*savefile);
if (!deserialize(savefile, saveVersion)) {
delete savefile;
return false;
};
// With version 9 onward the sleep auto-save is save at the end of a normal save.
delete _sleepAutoSave;
_sleepAutoSave = nullptr;
if (saveVersion >= 9) {
_sleepAuoSaveVersion = saveVersion;
byte hasAutoSave = savefile->readByte();
if (hasAutoSave) {
_sleepAutoSave = new Common::MemoryReadWriteStream(DisposeAfterUse::YES);
uint nb;
char buf[4096];
while ((nb = savefile->read(buf, 4096)) > 0)
_sleepAutoSave->write(buf, nb);
}
}
delete savefile;
return true;
}
bool SupernovaEngine::saveGame(int slot, const Common::String &description) {
if (slot < 0)
return false;
if (slot == kSleepAutosaveSlot) {
delete _sleepAutoSave;
_sleepAutoSave = new Common::MemoryReadWriteStream(DisposeAfterUse::YES);
_sleepAuoSaveVersion = SAVEGAME_VERSION;
serialize(_sleepAutoSave);
return true;
}
Common::String filename = getSaveStateName(slot);
Common::OutSaveFile *savefile = _saveFileMan->openForSaving(filename);
if (!savefile)
return false;
if (_MSPart == 1)
savefile->writeUint32LE(SAVEGAME_HEADER);
else if (_MSPart == 2)
savefile->writeUint32LE(SAVEGAME_HEADER2);
savefile->writeByte(SAVEGAME_VERSION);
TimeDate currentDate;
_system->getTimeAndDate(currentDate);
uint32 saveDate = (currentDate.tm_mday & 0xFF) << 24 | ((currentDate.tm_mon + 1) & 0xFF) << 16 | ((currentDate.tm_year + 1900) & 0xFFFF);
uint16 saveTime = (currentDate.tm_hour & 0xFF) << 8 | ((currentDate.tm_min) & 0xFF);
savefile->writeSint16LE(description.size() + 1);
savefile->write(description.c_str(), description.size() + 1);
savefile->writeUint32LE(saveDate);
savefile->writeUint16LE(saveTime);
savefile->writeUint32LE(getTotalPlayTime() / 1000);
Graphics::saveThumbnail(*savefile);
serialize(savefile);
if (_sleepAutoSave == nullptr)
savefile->writeByte(0);
else {
savefile->writeByte(1);
savefile->write(_sleepAutoSave->getData(), _sleepAutoSave->size());
}
savefile->finalize();
delete savefile;
return true;
}
void SupernovaEngine::errorTempSave(bool saving) {
GUIErrorMessage(saving
? _("Failed to save temporary game state. Make sure your save game directory is set in ScummVM and that you can write to it.")
: _("Failed to load temporary game state."));
error("Unrecoverable error");
}
void SupernovaEngine::stopSound() {
_sound->stop();
}
}

View File

@@ -0,0 +1,174 @@
/* 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 SUPERNOVA_SUPERNOVA_H
#define SUPERNOVA_SUPERNOVA_H
#include "common/array.h"
#include "common/events.h"
#include "common/random.h"
#include "common/scummsys.h"
#include "engines/engine.h"
#include "common/file.h"
#include "supernova/console.h"
#include "supernova/graphics.h"
#include "supernova/msn_def.h"
#include "supernova/room.h"
#include "supernova/sound.h"
#include "supernova/imageid.h"
#include "supernova/game-manager.h"
namespace Common {
class MemoryReadWriteStream;
}
namespace Supernova {
#define SAVEGAME_HEADER MKTAG('M','S','N','1')
#define SAVEGAME_HEADER2 MKTAG('M','S','N','2')
#define SAVEGAME_VERSION 10
#define SUPERNOVA_DAT "supernova.dat"
#define SUPERNOVA_DAT_VERSION 4
class GuiElement;
class ResourceManager;
class Sound;
class console;
class GameManager;
class GameManager1;
class Screen;
class SupernovaEngine : public Engine {
public:
explicit SupernovaEngine(OSystem *syst);
~SupernovaEngine() override;
Common::Error run() override;
Common::Error loadGameState(int slot) override;
bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override;
Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override;
bool hasFeature(EngineFeature f) const override;
void pauseEngineIntern(bool pause) override;
GameManager *_gm;
Sound *_sound;
ResourceManager *_resMan;
Screen *_screen;
bool _allowLoadGame;
bool _allowSaveGame;
Common::StringArray _gameStrings;
Common::String _nullString;
int _sleepAuoSaveVersion;
Common::MemoryReadWriteStream* _sleepAutoSave;
uint _delay;
int _textSpeed;
char _MSPart;
bool _improved;
Common::Error loadGameStrings();
void init();
Common::String getSaveStateName(int slot) const override;
bool loadGame(int slot);
bool saveGame(int slot, const Common::String &description);
bool serialize(Common::WriteStream *out);
bool deserialize(Common::ReadStream *in, int version);
bool quitGameDialog();
void errorTempSave(bool saving);
void setTextSpeed();
const Common::String &getGameString(int idx) const;
void setGameString(int idx, const Common::String &string);
void showHelpScreen1();
void showHelpScreen2();
Common::SeekableReadStream *getBlockFromDatFile(Common::String name);
Common::Error showTextReader(const char *extension);
// forwarding calls
void playSound(AudioId sample);
void playSound(MusicId index);
void paletteFadeIn();
void paletteFadeOut(int minBrightness = 0);
void paletteBrightness();
void renderImage(int section);
void renderImage(ImageId id, bool removeImage = false);
bool setCurrentImage(int filenumber);
void saveScreen(int x, int y, int width, int height);
void saveScreen(const GuiElement &guiElement);
void restoreScreen();
void renderRoom(Room &room);
void renderMessage(const char *text, MessagePosition position = kMessageNormal);
void renderMessage(const Common::String &text, MessagePosition position = kMessageNormal);
void renderMessage(int stringId, MessagePosition position = kMessageNormal,
Common::String var1 = "", Common::String var2 = "");
void renderMessage(int stringId, int x, int y);
void removeMessage();
void renderText(const uint16 character);
void renderText(const char *text);
void renderText(const Common::String &text);
void renderText(int stringId);
void renderText(const uint16 character, int x, int y, byte color);
void renderText(const char *text, int x, int y, byte color);
void renderText(const Common::String &text, int x, int y, byte color);
void renderText(int stringId, int x, int y, byte color);
void renderText(const GuiElement &guiElement);
void renderBox(int x, int y, int width, int height, byte color);
void renderBox(const GuiElement &guiElement);
void setColor63(byte value);
void stopSound();
};
enum SUPERNOVAAction {
kActionNone,
kActionPause,
kActionQuit,
kActionSkip,
kActionSkipLine,
kActionHelp,
kActionInstr,
kActionInfo,
kActionSpeed,
kActionGo,
kActionLook,
kActionTake,
kActionOpen,
kActionClose,
kActionPush,
kActionPull,
kActionUse,
kActionTalk,
kActionGive,
kActionUp,
kActionDown,
kActionPgUp,
kActionPgDown,
kActionExit,
kActionOfficeManager,
kActionPhone,
kActionProText,
kActionCalculata,
};
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,549 @@
/* 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 SUPERNOVA_ROOMS_H
#define SUPERNOVA_ROOMS_H
#include "common/str.h"
#include "supernova/msn_def.h"
#include "supernova/room.h"
namespace Common {
class ReadStream;
class WriteStream;
}
namespace Supernova {
class GameManager1;
class SupernovaEngine;
class Room1: public Room {
public:
Room1();
protected:
GameManager1 *_gm;
int _dialogsX[6];
};
// Room 0
class Intro : public Room1 {
public:
Intro(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
private:
bool animate(int section1, int section2, int duration);
bool animate(int section1, int section2, int duration, MessagePosition position,
int text);
bool animate(int section1, int section2, int section3, int section4, int duration,
MessagePosition position, int text);
void titleScreen();
void titleFadeIn();
void cutscene();
void leaveCutscene();
bool _shouldExit;
Common::String _introText;
};
// Spaceship
class ShipCorridor : public Room1 {
public:
ShipCorridor(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class ShipHall: public Room1 {
public:
ShipHall(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class ShipSleepCabin: public Room1 {
public:
ShipSleepCabin(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
void animation() override;
void onEntrance() override;
private:
byte _color;
};
class ShipCockpit : public Room1 {
public:
ShipCockpit(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
void animation() override;
void onEntrance() override;
private:
byte _color;
};
class ShipCabinL1: public Room1 {
public:
ShipCabinL1(SupernovaEngine *vm, GameManager1 *gm);
private:
};
class ShipCabinL2 : public Room1 {
public:
ShipCabinL2(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class ShipCabinL3 : public Room1 {
public:
ShipCabinL3(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class ShipCabinR1 : public Room1 {
public:
ShipCabinR1(SupernovaEngine *vm, GameManager1 *gm);
private:
};
class ShipCabinR2 : public Room1 {
public:
ShipCabinR2(SupernovaEngine *vm, GameManager1 *gm);
private:
};
class ShipCabinR3 : public Room1 {
public:
ShipCabinR3(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
void onEntrance() override;
private:
};
class ShipCabinBathroom : public Room1 {
public:
ShipCabinBathroom(SupernovaEngine *vm, GameManager1 *gm);
private:
};
class ShipAirlock : public Room1 {
public:
ShipAirlock(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
void onEntrance() override;
private:
};
class ShipHold : public Room1 {
public:
ShipHold(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
void onEntrance() override;
private:
};
class ShipLandingModule : public Room1 {
public:
ShipLandingModule(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class ShipGenerator : public Room1 {
public:
ShipGenerator(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class ShipOuterSpace : public Room1 {
public:
ShipOuterSpace(SupernovaEngine *vm, GameManager1 *gm);
private:
};
// Arsano
class ArsanoRocks : public Room1 {
public:
ArsanoRocks(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class ArsanoCave : public Room1 {
public:
ArsanoCave(SupernovaEngine *vm, GameManager1 *gm);
private:
};
class ArsanoMeetup : public Room1 {
public:
ArsanoMeetup(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
byte _sign;
byte _beacon;
};
class ArsanoEntrance : public Room1 {
public:
ArsanoEntrance(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
void animation() override;
private:
int _dialog1[5];
int _dialog2[5];
int _dialog3[5];
byte _eyewitness;
};
class ArsanoRemaining : public Room1 {
public:
ArsanoRemaining(SupernovaEngine *vm, GameManager1 *gm);
void animation() override;
private:
bool _chewing;
int _i;
};
class ArsanoRoger : public Room1 {
public:
ArsanoRoger(SupernovaEngine *vm, GameManager1 *gm);
void animation() override;
void onEntrance() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
int _dialog1[4];
byte _eyewitness;
byte _hands;
};
class ArsanoGlider : public Room1 {
public:
ArsanoGlider(SupernovaEngine *vm, GameManager1 *gm);
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
byte _sinus;
};
class ArsanoMeetup2 : public Room1 {
public:
ArsanoMeetup2(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
void shipStart();
private:
// TODO: change to 6, fix initialization
int _dialog1[2];
int _dialog2[2];
int _dialog3[4];
int _dialog4[3];
};
class ArsanoMeetup3 : public Room1 {
public:
ArsanoMeetup3(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
int _dialog2[4];
int _dialog3[2];
};
// Axacuss
class AxacussCell : public Room1 {
public:
AxacussCell(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
void animation() override;
void onEntrance() override;
private:
};
class AxacussCorridor1 : public Room1 {
public:
AxacussCorridor1(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
private:
};
class AxacussCorridor2 : public Room1 {
public:
AxacussCorridor2(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
private:
};
class AxacussCorridor3 : public Room1 {
public:
AxacussCorridor3(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
private:
};
class AxacussCorridor4 : public Room1 {
public:
AxacussCorridor4(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class AxacussCorridor5 : public Room1 {
public:
AxacussCorridor5(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
void stopInteract(int sum);
bool handleMoneyDialog();
// TODO: Change to 6, or change struct, and fix initialization
int _dialog1[2];
int _dialog2[2];
int _dialog3[4];
byte _rows[6];
};
class AxacussCorridor6 : public Room1 {
public:
AxacussCorridor6(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class AxacussCorridor7 : public Room1 {
public:
AxacussCorridor7(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
private:
};
class AxacussCorridor8 : public Room1 {
public:
AxacussCorridor8(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class AxacussCorridor9 : public Room1 {
public:
AxacussCorridor9(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class AxacussBcorridor : public Room1 {
public:
AxacussBcorridor(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class AxacussIntersection : public Room1 {
public:
AxacussIntersection(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class AxacussExit : public Room1 {
public:
AxacussExit(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class AxacussOffice1 : public Room1 {
public:
AxacussOffice1(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class AxacussOffice2 : public Room1 {
public:
AxacussOffice2(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class AxacussOffice3 : public Room1 {
public:
AxacussOffice3(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class AxacussOffice4 : public Room1 {
public:
AxacussOffice4(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class AxacussOffice5 : public Room1 {
public:
AxacussOffice5(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class AxacussElevator : public Room1 {
public:
AxacussElevator(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class AxacussStation : public Room1 {
public:
AxacussStation(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class AxacussSign : public Room1 {
public:
AxacussSign(SupernovaEngine *vm, GameManager1 *gm);
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
};
class Outro : public Room1 {
public:
Outro(SupernovaEngine *vm, GameManager1 *gm);
void onEntrance() override;
void animation() override;
private:
void animate(int filenumber, int section1, int section2, int duration);
void animate(int filenumber, int section1, int section2, int duration, MessagePosition position,
const char *text);
void animate(int filenumber, int section1, int section2, int section3, int section4, int duration,
MessagePosition position, const char *text);
Common::String _outroText;
};
}
#endif // SUPERNOVA_ROOMS_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,123 @@
/* 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 SUPERNOVA_STATE_H
#define SUPERNOVA_STATE_H
#include "common/error.h"
#include "common/events.h"
#include "common/rect.h"
#include "common/keyboard.h"
#include "supernova/supernova1/rooms.h"
#include "supernova/room.h"
#include "supernova/sound.h"
#include "supernova/game-manager.h"
namespace Supernova {
class GameManager;
class GameState {
public:
int32 _timeSleep;
int32 _timeAlarm;
int32 _eventTime;
EventFunction _eventCallback;
int32 _arrivalDaysLeft;
int32 _shipEnergyDaysLeft;
int32 _landingModuleEnergyDaysLeft;
uint16 _greatFlag;
int16 _timeRobot;
int16 _money;
byte _coins;
byte _shoes;
byte _origin;
byte _destination;
byte _language;
bool _corridorSearch;
bool _alarmOn;
bool _terminalStripConnected;
bool _terminalStripWire;
bool _cableConnected;
bool _powerOff;
bool _dream;
bool _nameSeen[4];
bool _playerHidden;
};
class GameManager1: public GameManager {
public:
GameManager1(SupernovaEngine *vm, Sound *sound);
~GameManager1() override;
GameState _state;
void updateEvents() override;
void executeRoom() override;
bool serialize(Common::WriteStream *out) override;
bool deserialize(Common::ReadStream *in, int version) override;
void initState() override;
void initRooms() override;
void destroyRooms() override;
bool canSaveGameStateCurrently() override;
bool genericInteract(Action verb, Object &obj1, Object &obj2) override;
bool isHelmetOff();
void great(uint number);
bool airless();
void shock();
void turnOff();
void turnOn();
void roomBrightness() override;
void openLocker(const Room *room, Object *obj, Object *lock, int section);
void closeLocker(const Room *room, Object *obj, Object *lock, int section);
void drawMapExits() override;
void handleInput() override;
void handleTime() override;
void loadTime() override;
void saveTime() override;
void shot(int a, int b);
void takeMoney(int amount) override;
void search(int time);
void startSearch();
void guardNoticed();
void busted(int i);
void corridorOnEntrance();
void telomat(int number);
void novaScroll();
void supernovaEvent();
void guardReturnedEvent();
void walk(int a);
void guardWalkEvent();
void taxiEvent();
void searchStartEvent();
void guardShot();
void guard3Shot();
void alarm();
void alarmSound();
private:
int _prevImgId;
};
}
#endif // SUPERNOVA_STATE_H

View File

@@ -0,0 +1,188 @@
/* 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 SUPERNOVA_STRINGID_H
#define SUPERNOVA_STRINGID_H
#include "common/scummsys.h"
namespace Supernova {
enum StringId1 {
// 36
kStringTitleVersion = 36, kStringTitle1, kStringTitle2, kStringTitle3,
kStringIntro1, kStringIntro2, kStringIntro3, kStringIntro4, kStringIntro5,
kStringIntro6, kStringIntro7, kStringIntro8, kStringIntro9, kStringIntro10,
// 50
kStringIntro11, kStringIntro12, kStringIntro13, kStringBroken, kStringTakeMessage,
kStringKeycard, kStringKeycardDescription, kStringKnife, kStringKnifeDescription, kStringWatch,
kStringDiscman, kStringDiscmanDescription, kStringHatch, kStringButton, kStringHatchButtonDescription,
kStringLadder, kStringExit, kStringCockpitHatchDescription, kStringKitchenHatchDescription, kStringStasisHatchDescription,
kStringStasisHatchDescription2, kStringSlot, kStringSlotDescription, kStringCorridor, kStringComputer,
// 75
kStringComputerPassword, kStringInstruments, kStringInstrumentsDescription1, kStringMonitor, kStringMonitorDescription,
kStringImage, kStringGenericDescription1, kStringGenericDescription2, kStringGenericDescription3, kStringGenericDescription4,
kStringMagnete, kStringMagneteDescription, kStringPen, kStringPenDescription, kStringShelf,
kStringCompartment, kStringSocket, kStringToilet, kStringPistol, kStringPistolDescription,
kStringBooks, kStringBooksDescription, kStringSpool, kStringSpoolDescription, kStringBook,
// 100
kStringUnderwear, kStringUnderwearDescription, kStringClothes, kStringJunk, kStringJunkDescription,
kStringFolders, kStringFoldersDescription, kStringPoster, kStringPosterDescription1, kStringPosterDescription2,
kStringSpeaker, kStringRecord, kStringRecordDescription, kStringRecordStand, kStringRecordStandDescription,
kStringTurntable, kStringTurntableDescription, kStringWire, kStringPlug, kStringImageDescription1,
kStringDrawingInstruments, kStringDrawingInstrumentsDescription, kStringChessGame, kStringChessGameDescription1, kStringTennisRacket,
// 125
kStringTennisRacketDescription, kStringTennisBall, kStringChessGameDescription2, kStringBed, kStringBedDescription,
kStringCompartmentDescription, kStringAlbums, kStringAlbumsDescription, kStringRope, kStringRopeDescription,
kStringShelfDescription, kStringClothesDescription, kStringSocks, kStringBookHitchhiker, kStringBathroom,
kStringBathroomDescription, kStringShower, kStringHatchDescription1, kStringHatchDescription2, kStringHelmet,
kStringHelmetDescription, kStringSuit, kStringSuitDescription, kStringLifeSupport, kStringLifeSupportDescription,
// 150
kStringScrap, kStringScrapDescription1, kStringTerminalStrip, kStringScrapDescription2, kStringReactor,
kStringReactorDescription, kStringNozzle, kStringPumpkin, kStringPumpkinDescription, kStringLandingModule,
kStringLandingModuleDescription, kStringHatchDescription3, kStringGenerator, kStringGeneratorDescription, kStringScrapDescription3,
kSafetyButtonDescription, kStringKeyboard, kStringGeneratorWire, kStringEmptySpool, kStringKeycard2,
kStringKeycard2Description, kStringTrap, kStringVoltmeter, kStringClip, kStringWireDescription,
// 175
kStringStone, kStringCaveOpening, kStringCaveOpeningDescription, kStringExitDescription, kStringCave,
kStringSign, kStringSignDescription, kStringEntrance, kStringStar, kStringSpaceshift,
kStringPorter, kStringPorterDescription, kStringDoor, kStringChewingGum, kStringGummyBears,
kStringChocolateBall, kStringEgg, kStringLiquorice, kStringPill, kStringPillDescription,
kStringVendingMachine, kStringVendingMachineDescription, kStringToiletDescription, kStringStaircase, kStringCoins,
// 200
kStringCoinsDescription, kStringTabletPackage, kStringTabletPackageDescription, kStringChair, kStringShoes,
kStringShoesDescription, kStringFrogFace, kStringScrible, kStringScribleDescription, kStringWallet,
kStringMenu, kStringMenuDescription, kStringCup, kStringCupDescription, kStringBill,
kStringBillDescription, kStringKeycard3, kStringAnnouncement, kStringAnnouncementDescription, kStringRoger,
kStringUfo, kStringUfoDescription, kStringTray, kStringTrayDescription, kStringLamp,
// 225
kStringLampDescription, kStringEyes, kStringEyesDescription, kStringSocketDescription, kStringMetalBlock,
kStringMetalBlockDescription, kStringRobot, kStringRobotDescription, kStringTable, kStringTableDescription,
kStringCellDoor, kStringCellDoorDescription, kStringLaptop, kStringWristwatch, kStringPillar,
kStringDoorDescription1, kStringDoorDescription2, kStringDoorDescription3, kStringDoorDescription4, kStringDontEnter,
kStringAxacussan, kStringAxacussanDescription, kStringImageDescription2, kStringMastercard, kStringMastercardDescription,
// 250
kStringLamp2, kStringGenericDescription5, kStringMoney, kStringMoneyDescription1, kStringLocker,
kStringLockerDescription, kStringLetter, kStringCube, kStringGenericDescription6, kStringGenericDescription7,
kStringStrangeThing, kStringGenericDescription8, kStringImageDescription3, kStringPlant, kStringStatue,
kStringStatueDescription, kStringPlantDescription, kStringComputerDescription, kStringGraffiti, kStringGraffitiDescription,
kStringMoneyDescription2, kStringJungle, kStringJungleDescription, kStringOutro1, kStringOutro2,
// 275
kStringOutro3, kStringOutro4, kStringOutro5, kStringOutro6, kStringOutro7,
kStringOutro8, kStringOutro9, kStringOutro10, kStringOutro11, kStringOutro12,
kStringOutro13, kStringOutro14, kStringWireAndPlug, kStringWireAndClip, kStringWireAndPlug2,
kStringSignDescription2, kStringCoin, kStringDoorDescription5, kStringDoorDescription6, kStringKeycard2Description2,
kSringSpoolAndClip, kStringIntroCutscene1, kStringIntroCutscene2, kStringIntroCutscene3, kStringIntroCutscene4,
// 300
kStringIntroCutscene5, kStringIntroCutscene6, kStringIntroCutscene7, kStringIntroCutscene8, kStringIntroCutscene9,
kStringIntroCutscene10, kStringIntroCutscene11, kStringIntroCutscene12, kStringIntroCutscene13, kStringIntroCutscene14,
kStringIntroCutscene15, kStringIntroCutscene16, kStringIntroCutscene17, kStringIntroCutscene18, kStringIntroCutscene19,
kStringIntroCutscene20, kStringIntroCutscene21, kStringIntroCutscene22, kStringIntroCutscene23, kStringIntroCutscene24,
kStringIntroCutscene25, kStringIntroCutscene26, kStringIntroCutscene27, kStringIntroCutscene28, kStringIntroCutscene29,
// 325
kStringIntroCutscene30, kStringIntroCutscene31, kStringIntroCutscene32, kStringIntroCutscene33, kStringIntroCutscene34,
kStringIntroCutscene35, kStringIntroCutscene36, kStringIntroCutscene37, kStringIntroCutscene38, kStringIntroCutscene39,
kStringIntroCutscene40, kStringIntroCutscene41, kStringIntroCutscene42, kStringShipHall1, kStringShipSleepCabin1,
kStringShipSleepCabin2, kStringShipSleepCabin3, kStringShipSleepCabin4, kStringShipSleepCabin5, kStringShipSleepCabin6,
kStringShipSleepCabin7, kStringShipSleepCabin8, kStringShipSleepCabin9, kStringShipSleepCabin10, kStringShipSleepCabin11,
// 350
kStringShipSleepCabin12, kStringShipSleepCabin13, kStringShipSleepCabin14, kStringShipSleepCabin15, kStringShipSleepCabin16,
kStringShipCockpit1, kStringShipCockpit2, kStringShipCockpit3, kStringShipCockpit4, kStringShipCockpit5,
kStringShipCockpit6, kStringShipCockpit7, kStringShipCockpit8, kStringShipCockpit9, kStringShipCockpit10,
kStringShipCockpit11, kStringShipCockpit12, kStringShipCockpit13, kStringShipCabinL3_1, kStringShipCabinL3_2,
kStringShipCabinL3_3, kStringShipCabinL3_4, kStringShipCabinL3_5, kStringShipAirlock1, kStringShipAirlock2,
// 375
kStringShipAirlock3, kStringShipAirlock4, kStringShipHold1, kStringCable1, kStringCable2,
kStringCable3, kStringCable4, kStringShipHold2, kStringShipHold3, kStringShipHold4,
kStringShipHold5, kStringShipHold6, kStringShipHold7, kStringShipHold8, kStringShipHold9,
kStringShipHold10, kStringShipHold11, kStringShipHold12, kStringShipHold13, kStringShipHold14,
kStringShipHold15, kStringShipHold16, kStringArsanoMeetup1, kStringArsanoMeetup2, kStringArsanoMeetup3,
// 400
kStringArsanoEntrance1, kStringArsanoEntrance2, kStringArsanoEntrance3, kStringArsanoEntrance4, kStringArsanoEntrance5,
kStringArsanoEntrance6, kStringArsanoEntrance7, kStringArsanoEntrance8, kStringArsanoEntrance9, kStringArsanoEntrance10,
kStringArsanoEntrance11, kStringArsanoEntrance12, kStringArsanoEntrance13, kStringArsanoEntrance14, kStringArsanoEntrance15,
kStringArsanoEntrance16, kStringArsanoEntrance17, kStringArsanoEntrance18, kStringArsanoEntrance19, kStringArsanoEntrance20,
kStringArsanoEntrance21, kStringArsanoEntrance22, kStringArsanoEntrance23, kStringArsanoEntrance24, kStringArsanoEntrance25,
// 425
kStringArsanoEntrance26, kStringArsanoEntrance27, kStringArsanoDialog1, kStringArsanoDialog2, kStringArsanoDialog3,
kStringArsanoDialog4, kStringArsanoDialog5, kStringArsanoDialog6, kStringArsanoDialog7, kStringArsanoDialog8,
kStringArsanoDialog9, kStringDialogArsanoRoger1, kStringDialogArsanoRoger2, kStringDialogArsanoRoger3, kStringDialogArsanoMeetup3_1,
kStringDialogArsanoMeetup3_2, kStringDialogArsanoMeetup3_3, kStringDialogArsanoMeetup3_4, kStringDialogArsanoMeetup3_5, kStringArsanoRoger1,
kStringArsanoRoger2, kStringArsanoRoger3, kStringArsanoRoger4, kStringArsanoRoger5, kStringArsanoRoger6,
// 450
kStringArsanoRoger7, kStringArsanoRoger8, kStringArsanoRoger9, kStringArsanoRoger10, kStringArsanoRoger11,
kStringArsanoRoger12, kStringArsanoRoger13, kStringArsanoRoger14, kStringArsanoRoger15, kStringArsanoRoger16,
kStringArsanoRoger17, kStringArsanoRoger18, kStringArsanoRoger19, kStringArsanoRoger20, kStringArsanoRoger21,
kStringArsanoRoger22, kStringArsanoRoger23, kStringArsanoRoger24, kStringArsanoRoger25, kStringArsanoRoger26,
kStringArsanoRoger27, kStringArsanoRoger28, kStringArsanoRoger29, kStringArsanoRoger30, kStringArsanoRoger31,
// 475
kStringArsanoRoger32, kStringArsanoRoger33, kStringArsanoRoger34, kStringArsanoRoger35, kStringArsanoRoger36,
kStringArsanoRoger37, kStringArsanoRoger38, kStringArsanoRoger39, kStringArsanoRoger40, kStringArsanoGlider1,
kStringArsanoMeetup2_1, kStringArsanoMeetup2_2, kStringArsanoMeetup2_3, kStringArsanoMeetup2_4, kStringArsanoMeetup2_5,
kStringArsanoMeetup2_6, kStringArsanoMeetup2_7, kStringArsanoMeetup2_8, kStringArsanoMeetup2_9, kStringArsanoMeetup2_10,
kStringArsanoMeetup2_11, kStringArsanoMeetup2_12, kStringArsanoMeetup2_13, kStringArsanoMeetup3_1, kStringArsanoMeetup3_2,
// 500
kStringArsanoMeetup3_3, kStringArsanoMeetup3_4, kStringArsanoMeetup3_5, kStringArsanoMeetup3_6, kStringArsanoMeetup3_7,
kStringArsanoMeetup3_8, kStringArsanoMeetup3_9, kStringArsanoMeetup3_10, kStringArsanoMeetup3_11, kStringArsanoMeetup3_12,
kStringArsanoMeetup3_13, kStringArsanoMeetup3_14, kStringArsanoMeetup3_15, kStringArsanoMeetup3_16, kStringArsanoMeetup3_17,
kStringArsanoMeetup3_18, kStringArsanoMeetup3_19, kStringArsanoMeetup3_20, kStringArsanoMeetup3_21, kStringArsanoMeetup3_22,
kStringArsanoMeetup3_23, kStringArsanoMeetup3_24, kStringArsanoMeetup3_25, kStringArsanoMeetup3_26, kStringArsanoMeetup3_27,
// 525
kStringArsanoMeetup3_28, kStringAxacussCell_1, kStringAxacussCell_2, kStringAxacussCell_3, kStringAxacussCell_4,
kStringAxacussCell_5, kStringOk, kStringDialogArsanoMeetup2_1, kStringDialogArsanoMeetup2_2, kStringDialogArsanoMeetup2_3,
kStringDialogArsanoMeetup2_4, kStringDialogArsanoMeetup2_5, kStringDialogArsanoMeetup2_6, kStringDialogArsanoMeetup2_7, kStringDialogArsanoMeetup2_8,
kStringDialogArsanoMeetup2_9, kStringDialogArsanoMeetup2_10, kStringDialogArsanoMeetup2_11, kStringDialogAxacussCorridor5_1, kStringDialogAxacussCorridor5_2,
kStringDialogAxacussCorridor5_3, kStringDialogAxacussCorridor5_4, kStringDialogAxacussCorridor5_5, kStringDialogAxacussCorridor5_6, kStringDialogAxacussCorridor5_7,
// 550
kStringDialogX1, kStringDialogX2, kStringDialogX3, kStringAxacussCorridor5_1, kStringAxacussCorridor5_2,
kStringAxacussCorridor5_3, kStringAxacussCorridor5_4, kStringAxacussCorridor5_5, kStringAxacussCorridor5_6, kStringAxacussCorridor5_7,
kStringAxacussBcorridor_1, kStringAxacussOffice1_1, kStringAxacussOffice1_2, kStringAxacussOffice1_3, kStringAxacussOffice1_4,
kStringAxacussOffice1_5, kStringAxacussOffice1_6, kStringAxacussOffice1_7, kStringAxacussOffice1_8, kStringAxacussOffice1_9,
kStringAxacussOffice1_10, kStringAxacussOffice1_11, kStringAxacussOffice1_12, kStringAxacussOffice1_13, kStringAxacussOffice1_14,
// 575
kStringAxacussOffice1_15, kStringAxacussOffice1_16, kStringAxacussOffice3_1, kStringAxacussElevator_1, kStringAxacussElevator_2,
kStringAxacussElevator_3, kStringShock, kStringShot, kStringCloseLocker_1, kStringIsHelmetOff_1,
kStringGenericInteract_1, kStringGenericInteract_2, kStringGenericInteract_3, kStringGenericInteract_4, kStringGenericInteract_5,
kStringGenericInteract_6, kStringGenericInteract_7, kStringGenericInteract_8, kStringGenericInteract_9, kStringGenericInteract_10,
kStringGenericInteract_11, kStringGenericInteract_12, kStringGenericInteract_13, kStringGenericInteract_14, kStringGenericInteract_15,
// 600
kStringGenericInteract_16, kStringGenericInteract_17, kStringGenericInteract_18, kStringGenericInteract_19, kStringGenericInteract_20,
kStringGenericInteract_21, kStringGenericInteract_22, kStringGenericInteract_23, kStringGenericInteract_24, kStringGenericInteract_25,
kStringGenericInteract_26, kStringGenericInteract_27, kStringGenericInteract_28, kStringGenericInteract_29, kStringGenericInteract_30,
kStringGenericInteract_31, kStringGenericInteract_32, kStringGenericInteract_33, kStringGenericInteract_34, kStringGenericInteract_35,
kStringGenericInteract_36, kStringGenericInteract_37, kStringGenericInteract_38, kStringGenericInteract_39, kStringGenericInteract_40,
// 625
kStringGenericInteract_41, kStringGenericInteract_42, kStringGenericInteract_43, kStringSupernova1, kStringSupernova2,
kStringSupernova3, kStringSupernova4, kStringSupernova5, kStringSupernova6, kStringSupernova7,
kStringSupernova8, kStringGuardNoticed1, kStringGuardNoticed2, kStringTelomat1, kStringTelomat2,
kStringTelomat3, kStringTelomat4, kStringTelomat5, kStringTelomat6, kStringTelomat7,
kStringTelomat8, kStringTelomat9, kStringTelomat10, kStringTelomat11, kStringTelomat12,
// 650
kStringTelomat13, kStringTelomat14, kStringTelomat15, kStringTelomat16, kStringTelomat17,
kStringTelomat18, kStringTelomat19, kStringTelomat20, kStringTelomat21, kStringAlarm,
// Add two placeholder strings at the end for variable text
kStringPlaceholder1, kStringPlaceholder2,
// String for money in inventory
kStringInventoryMoney
};
}
#endif // SUPERNOVA_STRINGID_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,713 @@
/* 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 SUPERNOVA2_ROOMS_H
#define SUPERNOVA2_ROOMS_H
#include "common/str.h"
#include "supernova/msn_def.h"
#include "supernova/room.h"
namespace Common {
class ReadStream;
class WriteStream;
}
namespace Supernova {
class GameManager2;
class SupernovaEngine;
struct RoomEntry {
int _e;
int _s;
int _z;
int _r;
RoomId _exitRoom;
};
class Room2 : public Room {
protected:
GameManager2 *_gm;
};
class Intro2 : public Room2 {
public:
Intro2(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
private:
void titleScreen();
bool tvSay(int mod1, int mod2, int rest, MessagePosition pos, int id);
bool tvRest(int mod1, int mod2, int rest);
bool displayThoughtMessage(int id);
bool thoughts1();
bool tvDialogue();
bool thoughts2();
Common::String _introText;
};
class Airport : public Room2 {
public:
Airport(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
};
class TaxiStand : public Room2 {
public:
TaxiStand(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Street : public Room2 {
public:
Street(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Games : public Room2 {
public:
Games(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Cabin2 : public Room2 {
public:
Cabin2(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Kiosk : public Room2 {
public:
Kiosk(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class CulturePalace : public Room2 {
public:
CulturePalace(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
void notEnoughMoney();
};
class Checkout : public Room2 {
public:
Checkout(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
void appearance();
void shouting();
};
class City1 : public Room2 {
public:
City1(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class City2 : public Room2 {
public:
City2(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Elevator2 : public Room2 {
public:
Elevator2(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
void jobDescription();
};
class Apartment : public Room2 {
public:
Apartment(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Ship : public Room2 {
public:
Ship(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
Common::String _outroText;
Common::String _outroText2;
private:
void kill();
void outro();
};
class Pyramid : public Room2 {
public:
Pyramid(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class PyrEntrance : public Room2 {
public:
PyrEntrance(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
uint32 _waitTime;
};
class Upstairs1 : public Room2 {
public:
Upstairs1(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Downstairs1 : public Room2 {
public:
Downstairs1(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class BottomRightDoor : public Room2 {
public:
BottomRightDoor(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class BottomLeftDoor : public Room2 {
public:
BottomLeftDoor(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Upstairs2 : public Room2 {
public:
Upstairs2(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Downstairs2 : public Room2 {
public:
Downstairs2(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class UpperDoor : public Room2 {
public:
UpperDoor(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class PuzzleFront : public Room2 {
public:
PuzzleFront(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class PuzzleBehind : public Room2 {
public:
PuzzleBehind(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Formula1F : public Room2 {
public:
Formula1F(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Formula1N : public Room2 {
public:
Formula1N(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Formula2F : public Room2 {
public:
Formula2F(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Formula2N : public Room2 {
public:
Formula2N(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class TomatoF : public Room2 {
public:
TomatoF(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class TomatoN : public Room2 {
public:
TomatoN(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class MonsterF : public Room2 {
public:
MonsterF(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Monster1N : public Room2 {
public:
Monster1N(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Monster2N : public Room2 {
public:
Monster2N(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Upstairs3 : public Room2 {
public:
Upstairs3(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Downstairs3 : public Room2 {
public:
Downstairs3(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class LCorridor1 : public Room2 {
public:
LCorridor1(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class LCorridor2 : public Room2 {
public:
LCorridor2(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class HoleRoom : public Room2 {
public:
HoleRoom(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class InHole : public Room2 {
public:
InHole(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Floordoor : public Room2 {
public:
Floordoor(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class FloordoorU : public Room2 {
public:
FloordoorU(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class BstDoor : public Room2 {
public:
BstDoor(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
private:
bool _password[16];
};
class Hall2 : public Room2 {
public:
Hall2(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class CoffinRoom : public Room2 {
public:
CoffinRoom(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mask : public Room2 {
public:
Mask(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Museum : public Room2 {
public:
Museum(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class MusEntrance : public Room2 {
public:
MusEntrance(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus1 : public Room2 {
public:
Mus1(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus2 : public Room2 {
public:
Mus2(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus3 : public Room2 {
public:
Mus3(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus4 : public Room2 {
public:
Mus4(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus5 : public Room2 {
public:
Mus5(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus6 : public Room2 {
public:
Mus6(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus7 : public Room2 {
public:
Mus7(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus8 : public Room2 {
public:
Mus8(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus9 : public Room2 {
public:
Mus9(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus10 : public Room2 {
public:
Mus10(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus11 : public Room2 {
public:
Mus11(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class MusRound : public Room2 {
public:
MusRound(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus12 : public Room2 {
public:
Mus12(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus13 : public Room2 {
public:
Mus13(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus14 : public Room2 {
public:
Mus14(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus15 : public Room2 {
public:
Mus15(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus16 : public Room2 {
public:
Mus16(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus17 : public Room2 {
public:
Mus17(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus18 : public Room2 {
public:
Mus18(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus19 : public Room2 {
public:
Mus19(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus20 : public Room2 {
public:
Mus20(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus21 : public Room2 {
public:
Mus21(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
class Mus22 : public Room2 {
public:
Mus22(SupernovaEngine *vm, GameManager2 *gm);
void onEntrance() override;
void animation() override;
bool interact(Action verb, Object &obj1, Object &obj2) override;
};
}
#endif // SUPERNOVA2_ROOMS_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,134 @@
/* 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 SUPERNOVA2_STATE_H
#define SUPERNOVA2_STATE_H
#include "common/events.h"
#include "common/rect.h"
#include "common/keyboard.h"
#include "supernova/room.h"
#include "supernova/supernova2/rooms.h"
#include "supernova/sound.h"
#include "supernova/game-manager.h"
namespace Supernova {
struct ConstructionEntry {
int _e;
int _s;
int _z;
int _r;
int _a;
};
struct GameState2 {
int16 _money;
int32 _startTime;
bool _addressKnown;
Room *_previousRoom;
bool _poleMagnet;
char _admission;
bool _tipsy;
bool _dark;
char _elevatorE;
char _elevatorNumber;
bool _toMuseum;
EventFunction _eventCallback;
uint32 _eventTime;
int16 _pyraE;
char _pyraS;
char _pyraZ;
int16 _pyraDirection;
int16 _puzzleTab[15];
bool _alarmCracked;
bool _alarmOn;
bool _haste;
byte _pressureCounter;
bool _sirenOn;
byte _taxiPossibility;
};
class GameManager2: public GameManager{
public:
GameManager2(SupernovaEngine *vm, Sound *sound);
~GameManager2() override;
GameState2 _state;
void updateEvents() override;
void executeRoom() override;
bool serialize(Common::WriteStream *out) override;
bool deserialize(Common::ReadStream *in, int version) override;
byte _dials[6];
//state
unsigned char _puzzleField[16];
bool _mapOn;
bool _steps;
bool _cracking;
bool _alarmBefore;
RoomId _securityTab[10];
int _restTime;
void initState() override;
void initRooms() override;
void destroyRooms() override;
bool canSaveGameStateCurrently() override;
bool genericInteract(Action verb, Object &obj1, Object &obj2) override;
void roomBrightness() override {}
void drawMapExits() override;
void handleInput() override;
void handleTime() override;
void loadTime() override {}
void saveTime() override {}
void takeMoney(int amount) override;
void taxi();
void leaveTaxi();
void taxiUnknownDestination();
void taxiPayment(int price, int destination);
void playerTakeOut();
void sober();
void playCD();
bool talk(int mod1, int mod2, int rest, MessagePosition pos, int id);
bool talkRest(int mod1, int mod2, int rest);
void pyramidEnd();
void passageConstruction();
byte wall(int s, int z, int direction, int stepsForward, int stepsRight);
bool move(Action verb, Object &obj);
void compass();
void puzzleConstruction();
void drawClock();
void caught();
void caught2();
void alarm();
void crack(int time);
bool crackDoor(int time);
void museumDoorInteract(Action verb, Object &obj1, Object &obj2);
void securityEntrance();
void pressureAlarmCount();
void pressureAlarmEntrance();
};
}
#endif // SUPERNOVA2_STATE_H

View File

@@ -0,0 +1,176 @@
/* 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 SUPERNOVA2_STRINGID_H
#define SUPERNOVA2_STRINGID_H
#include "common/scummsys.h"
namespace Supernova {
enum StringId2 {
// 36
kString23 = 36, kString24, kString25, kString26,
kString27, kStringGenericInteract1, kStringGenericInteract2, kStringGenericInteract3, kStringGenericInteract4,
kStringGenericInteract5, kStringGenericInteract6, kStringGenericInteract7, kStringGenericInteract8, kStringGenericInteract9,
// 50
kStringGenericInteract10, kStringGenericInteract11, kStringGenericInteract12, kStringGenericInteract13, kStringIntro1,
kStringIntro2, kStringIntro3, kStringIntro4, kStringIntro5, kStringOutro1,
kStringOutro2, kStringOutro3, kStringOutro4, kStringOutro5, kStringShout1,
kStringShout2, kStringShout3, kStringShout4, kStringShout5, kStringShout6,
kStringShout7, kStringShout8, kStringShout9, kStringShout10, kStringShout11,
// 75
kStringShout12, kStringShout13, kStringShout14, kStringShout15, kStringMuseum8,
kStringMuseum9, kStringMuseum7, kStringMuseum6, kStringMuseum15, kStringMuseum16,
kStringMuseum10, kStringMuseum12, kStringMuseum13, kStringMuseum14, kStringMuseum1,
kStringMuseum2, kStringMuseum3, kStringMuseum4, kStringMuseum5, kStringMuseum23,
kStringMuseum24, kStringMuseum17, kStringMuseum18, kStringMuseum19, kStringMuseum20,
// 100
kStringMuseum21, kStringMuseum22, kStringDinosaur, kStringDinosaurDescription, kStringEntrance,
kStringDoor, kStringRoad, kStringCamera, kStringCameraDescription, kStringMainEntrance,
kStringCorridor, kStringDinosaurDescription2, kStringDinosaurHead, kStringDinosaurHeadDescription, kStringAlarmSystem,
kStringSuctionCup, kStringWall, kStringOpening, kStringLetter, kStringMassive,
kStringInscriptionDescription, kStringPyramid0, kStringPyramid1, kStringPyramid2, kStringPyramid3,
// 125
kStringPyramid4, kStringPiece, kStringPyramid5, kStringPyramid6, kStringPyramid7,
kStringPyramid8, kStringPyramid9, kStringPyramid10, kStringPyramid11, kStringPyramid12,
kStringPyramid13, kStringPyramid14, kStringPyramid15, kStringPyramid17, kStringPyramid18,
kStringPyramid19, kStringDirection1, kStringDirection2, kStringDirection3, kStringDirection4,
kStringRope, kStringSign, kStringSignDescription, kStringEntrance1Description, kStringPyramid,
// 150
kStringPyramidDescription, kStringSun, kStringSunDescription, kStringSign5Description, kStringRight,
kStringLeft, kStringButton, kStringInscription, kStringTomato, kStringFunnyDescription,
kStringKnife1, kStringKnife1Description, kStringMonster, kStringRopeDescription, kStringEyes,
kStringMouth, kStringMonster1Description, kStringNote, kStringNoteDescription, kStringOpeningDescription1,
kStringOpeningDescription2, kStringNoteDescription1, kStringSlot, kStringSlotDescription3, kStringOpeningDescription3,
// 175
kStringStones, kStringPlate, kStringCoffin, kStringExit, kStringCreepy,
kStringToothbrush, kStringToothbrushDescription1, kStringToothpaste, kStringBall, kStringBallDescription,
kStringEye, kStringEyeDescription, kStringLooksMetal, kStringTaxiArrives, kStringNothingHappens,
kStringEmpty, kStringWalletOpen, kStringAttachMagnet, kStringPoleMagnet, kStringCunning,
kStringMustBuyFirst, kStringInsertChip, kStringTransferCD, kStringCDNotInserted, kStringRemoveChip,
// 200
kStringChipNotInserted, kStringWhatFor, kStringMMCD, kStringChipEmpty, kStringListeningToCD,
kStringNoChip, kStringTipsy, kStringXa, kStringAirportEntrance, kStringAirport,
kStringDowntown, kStringCulturePalace, kStringEarth, kStringPrivateApartment, kStringLeaveTaxi,
kStringPay, kStringAddress, kStringCheater, kStringNotEnoughMoney, kStringTaxiAccelerating,
kString5MinutesLater, kStringAlreadyHavePole, kStringSawPole, kStringOnlyShop, kStringCabinOccupiedSay,
// 225
kStringTakeMoney, kStringAlreadyPaid, kStringNoMoney, kStringPay10Xa, kStringWillPassOut,
kStringRest, kStringCypher, kStringWillTakeIt, kStringTooExpensive, kStringWouldBuy,
kStringMeHorstHummel, kStringHaveMusicChip, kStringGreatMask, kStringThreeYears, kStringStrongDrink,
kStringMusicDevice, kStringArtusToothbrush, kStringSellInBulk, kStringRarityBooks, kStringEncyclopedia,
kStringLargestDictionary, kStringOver400Words, kStringNotSale, kStringGaveOne, kStringExcited,
// 250
kStringFromGame, kStringRobust, kStringCheapSwill, kStringStickers, kStringDishes,
kStringUgly, kStringSellsWell, kStringThatCosts, kStringTakeALook, kStringNonsense,
kStringImSorry, kStringGoodEvening, kStringHello, kStringScaredMe, kStringHowSo,
kStringDisguise, kStringWhatDisguise, kStringStopPretending, kStringYouDisguised, kStringIAmHorstHummel,
kStringGiveItUp, kStringGestures, kStringMovesDifferently, kStringHeIsRobot, kStringYouAreCrazy,
// 275
kStringYouIdiot, kStringShutUp, kStringKnife, kStringKnifeDescription, kStringMoney,
kStringDiscman, kStringDiscmanDescription, kStringSuctionCupDescription, kStringSpecialCard, kStringSpecialCardDescription,
kStringAlarmCracker, kStringAlarmCrackerDescription, kStringKeycard, kStringSpaceship, kStringSpaceshipDescription,
kStringVehicles, kStringVehiclesDescription, kStringVehicle, kStringVehicleDescription, kStringEntranceDescription,
kStringWallet, kStringWalletDescription, kStringDevice, kStringDeviceDescription, kStringIdCard,
// 300
kStringIdCardDescription, kStringStaircase, kStringStaircaseDescription, kStringBusinessStreet, kStringBusinessStreetDescription,
kStringRod, kStringPost, kStringRailing, kStringPoster, kStringPosterDescription,
kStringCabin, kStringCabinFree, kStringCabinOccupied, kStringFeet, kStringFeetDescription,
kStringHood, kStringHoodDescription, kString400Xa, kString10Xa, kStringSlotDescription1,
kStringSlotDescription2, kStringChair, kStringChairDescription, kStringScribble, kStringFace,
// 325
kStringFaceDescription, kStringBooks, kStringDictionary, kStringPlant, kStringMask,
kStringSnake, kStringCup, kStringJoystick, kStringToothbrushDescription, kStringMusic,
kStringMusicDescription, kStringBottle, kStringBottleDescription, kStringBox, kStringSeller,
kStringWhat, kStringNotInformed, kStringHorstHummel, kStringNiceWeather, kUnused1,
kStringHereIsXa, kString500Xa, kString1000Xa, kString5000Xa, kString10000Xa,
// 350
kStringThankYou, kStringWhatYouOffer, kStringHello2, kStringWhatYouWant, kStringWhoAreYou,
kStringHorstHummel2, kStringNeverHeard, kStringYouDontKnow, kStringImOnTV, kStringIDontKnow,
kStringFunny, kStringAha, kStringICan, kStringFromWhom, kStringCost,
kStringAsYouSay, kStringGetCard, kStringOnlyParticipation, kStringWhatForIt, kStringMakeOffer,
kStringGoodOffer, kStringGiveCard, kStringIdiot, kStringCheckout1, kStringCheckout2,
// 375
kStringCheckout3, kStringYes2, kStringNo2, kStringCheckout4, kStringCheckout5,
kStringCheckout6, kStringCheckout7, kStringCheckout8, kStringCheckout9, kStringCheckout10,
kStringCheckout11, kStringCheckout12, kStringCheckout13, kStringCheckout14, kStringCheckout15,
kStringCheckout16, kStringCheckout17, kStringCheckout18, kStringCheckout19, kStringCheckout20,
kStringCheckout21, kStringCheckout22, kStringCheckout23, kStringCheckout24, kStringCheckout25,
// 400
kStringCheckout26, kStringCheckout27, kStringCheckout28, kStringCheckout29, kStringCheckout30,
kStringCheckout31, kStringCheckout32, kStringCheckout33, kStringCheckout34, kStringCheckout35,
kStringCheckout36, kStringCheckout37, kStringCheckout38, kStringCheckout39, kStringCheckout40,
kStringCheckout41, kStringCheckout42, kStringCheckout43, kStringCheckout44, kStringCheckout45,
kStringCheckout46, kStringCheckout47, kStringCheckout48, kStringCheckout49, kStringAtMusicContest,
// 425
kStringNoImitation, kStringGoodJoke, kStringCommon, kStringIWillProof, kStringIWillPerform,
kStringAppearance32, kStringAppearance1, kStringAppearance2, kStringAppearance3, kStringAppearance4,
kStringAppearance5, kStringAppearance6, kStringAppearance7, kStringAppearance8, kStringAppearance9,
kStringAppearance10, kStringAppearance11, kStringAppearance12, kStringAppearance13, kStringAppearance14,
kStringAppearance15, kStringAppearance16, kStringAppearance17, kStringAppearance18, kStringAppearance19,
// 450
kStringAppearance20, kStringAppearance21, kStringAppearance22, kStringAppearance23, kStringAppearance24,
kStringAppearance25, kStringAppearance26, kStringAppearance27, kStringAppearance28, kStringAppearance29,
kStringAppearance30, kStringAppearance31, kStringElevator1, kStringElevator2, kStringElevator3,
kStringElevator4, kStringElevator5, kStringElevator6, kStringElevator7, kStringElevator8,
kStringElevator9, kUnused2, kStringElevator11, kStringElevator12, kStringElevator13,
// 475
kStringElevator14, kStringElevator15, kStringElevator16, kStringElevator17, kStringElevator18,
kStringElevator19, kStringElevator20, kStringElevator21, kStringElevator22, kStringElevator23,
kStringElevator24, kStringElevator25, kStringElevator26, kStringElevator27, kStringElevator28,
kStringElevator29, kStringElevator30, kStringElevator31, kStringElevator32, kStringElevator33,
kStringElevator34, kStringElevator35, kStringElevator36, kStringElevator37, kStringElevator38,
// 500
kStringElevator39, kStringElevator40, kStringElevator41, kStringElevator42, kStringElevator43,
kStringElevator44, kStringElevator45, kStringElevator46, kStringElevator47, kStringElevator48,
kStringElevator49, kStringElevator50, kStringElevator51, kStringElevator52, kStringElevator53,
kStringElevator54, kStringElevator55, kStringElevator56, kStringElevator57, kStringElevator58,
kStringElevator59, kStringElevator60, kStringElevator61, kStringElevator62, kStringElevator63,
// 525
kStringElevator64, kStringElevator65, kStringApartment1, kStringApartment2, kStringApartment3,
kStringApartment4, kStringApartment5, kStringApartment6, kStringApartment7, kStringApartment8,
kStringShip0, kStringShip1, kStringShip2, kStringShip3, kStringShip4,
kStringShip5, kStringShip6, kStringShip7, kStringShip8, kStringShip9,
kStringShip10, kStringShip11, kStringShip12, kStringShip13, kStringShip14,
// 550
kStringShip15, kStringShip16, kStringShip17, kStringShip18, kStringShip19,
kStringFascinating, kStringTaxis, kStringTaxisDescription, kStringAxacussan, kStringParticipationCard,
kStringAxacussian, kStringSign1Description, kStringSign2Description, kStringSign3Description, kStringSign4Description,
kStringBell, kStringDisplay, kStringKeypad, kStringKeypadDescription, kStringChip,
kStringChipDescription, kStringHatch, kStringHatchDescription, kStringMusicSystem, kStringMusicSystemDescription,
// 575
kStringSpeakers, kStringSpeakersDescription, kStringPencils, kStringPencilsDescription, kStringMetalBlocks,
kStringMetalBlocksDescription, kStringImage, kStringImageDescription, kStringCabinet, kStringCabinetDescription,
kStringElevator, kStringUnderBed, kStringUnderBedDescription, kStringKey, kStringKeyDescription,
kStringSwitch, kStringHandle, kStringHatch2, kStringSpaceSuit, kStringSpaceSuitDescription,
kStringCable, kStringCableDescription1, kStringCableDescription2, kStringIntro6, kStringIntro7,
// 600
kStringIntro8, kStringIntroTV1, kStringIntroTV2, kStringIntroTV3, kStringIntroTV4,
kStringIntroTV5, kStringIntroTV6, kStringIntroTV7, kStringIntroTV8, kStringIntroTV9,
kStringIntroTV10, kStringIntroTV11, kStringIntroTV12, kStringIntroTV13, kStringIntroTV14,
kStringIntroTV15, kStringIntroTV16, kStringIntro9, kStringIntro10, kStringIntro11,
kStringIntro12, kStringIntro13, kStringIntro14, kStringMonsterDescription, kStringPyramid16,
// 625
kStringMuseum11, kStringTellTicket1, kStringTellTicket2, kStringElevator10a, kStringElevator10b
};
}
#endif // SUPERNOVA2_STRINGID_H