mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-23 12:44:02 +00:00
MTROPOLIS: Add detection for Obsidian demos, support for Mac, preliminary support for PC
This commit is contained in:
parent
715492b3ca
commit
af56ac89ef
@ -29,11 +29,11 @@
|
|||||||
namespace MTropolis {
|
namespace MTropolis {
|
||||||
|
|
||||||
static const MTropolisGameDescription gameDescriptions[] = {
|
static const MTropolisGameDescription gameDescriptions[] = {
|
||||||
{
|
|
||||||
// Obsidian Macintosh
|
{ // Obsidian Macintosh
|
||||||
{
|
{
|
||||||
"obsidian",
|
"obsidian",
|
||||||
"V1.0, 1/13/97, installed, CD",
|
"V1.0, 1/13/97, CD",
|
||||||
{
|
{
|
||||||
{ "Obsidian Installer", 0, "1c272c23dc50b771970cabe8410c9349", 9250304 },
|
{ "Obsidian Installer", 0, "1c272c23dc50b771970cabe8410c9349", 9250304 },
|
||||||
{ "Obsidian Data 2", 0, "1e590e3154c1af09efb951a07abc48b8", 563287808 },
|
{ "Obsidian Data 2", 0, "1e590e3154c1af09efb951a07abc48b8", 563287808 },
|
||||||
@ -52,8 +52,8 @@ static const MTropolisGameDescription gameDescriptions[] = {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
// Obsidian Windows, installed
|
{ // Obsidian Windows, installed
|
||||||
{
|
{
|
||||||
"obsidian",
|
"obsidian",
|
||||||
"V1.0, 1/13/97, installed, CD",
|
"V1.0, 1/13/97, installed, CD",
|
||||||
@ -108,9 +108,127 @@ static const MTropolisGameDescription gameDescriptions[] = {
|
|||||||
0,
|
0,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ // Obsidian Macintosh demo
|
||||||
|
{
|
||||||
|
"obsidian",
|
||||||
|
"Demo",
|
||||||
|
{
|
||||||
|
{ "Obsidian Demo", 0, "abd1b5e7ac133f4c4b8c45ac67a4c44d", 920832 },
|
||||||
|
{ "Basic.rPP", 0, "cb567ec1423a35903d8d5f458409e681", 210432 },
|
||||||
|
{ "Experimental.rPP", 0, "26aa5fe1a6a152ade74e23a706673c50", 102016 },
|
||||||
|
{ "Extras.rPP", 0, "c0e4c0401f2107ba3a3b7d282a76d99b", 377600 },
|
||||||
|
{ "mCursors.cPP", 0, "a52e2aaf3b1a5c7d93a2949693bca694", 13312 },
|
||||||
|
{ "mNet.rPP", 0, "ed5d998e7db6daae1f24bb124cc269aa", 134784 },
|
||||||
|
{ "Obsidian.cPP", 0, "6da7babae9725a716f27f9f4ea382e92", 7552 },
|
||||||
|
{ "RSGKit.rPP", 0, "c359e3c932b09280d1ccf21f8fb52bd7", 668160 },
|
||||||
|
{ "Obs Demo Large w Sega", 0, "34efe95fc32dcf0a2a90bf6854c08e95", 98953679 },
|
||||||
|
AD_LISTEND
|
||||||
|
},
|
||||||
|
Common::EN_ANY,
|
||||||
|
Common::kPlatformMacintosh,
|
||||||
|
ADGF_DEMO,
|
||||||
|
GUIO0()
|
||||||
|
},
|
||||||
|
GID_OBSIDIAN,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // Obsidian PC demo from PC Gamer Disc 2.12 (1997-01)
|
||||||
|
{
|
||||||
|
"obsidian",
|
||||||
|
"Demo",
|
||||||
|
{
|
||||||
|
{ "OBSIDIAN.EXE", 0, "b6fb0e0df88c1524bcd0c5de9f5e882c", 750080 },
|
||||||
|
{ "OBSIDIAN.R95", 0, "5361ef93e36d722665594b724e0018fd", 183296 },
|
||||||
|
{ "TEXTWORK.R95", 0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
|
||||||
|
{ "EXPRMNTL.R95", 0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
|
||||||
|
{ "MCURSORS.C95", 0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
|
||||||
|
{ "OBSIDI~1.MPL", 0, "643a989213b42cbac319d04676447624", 29096880 },
|
||||||
|
AD_LISTEND
|
||||||
|
},
|
||||||
|
Common::EN_ANY,
|
||||||
|
Common::kPlatformWindows,
|
||||||
|
ADGF_DEMO | ADGF_UNSTABLE,
|
||||||
|
GUIO0()
|
||||||
|
},
|
||||||
|
GID_OBSIDIAN,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // Obsidian PC demo
|
||||||
|
{
|
||||||
|
"obsidian",
|
||||||
|
"Demo",
|
||||||
|
{
|
||||||
|
{ "OBSIDIAN DEMO.EXE", 0, "1bac38af354fd79ae3285e6c737705b7", 751104 },
|
||||||
|
{ "OBSIDIAN1.R95", 0, "5361ef93e36d722665594b724e0018fd", 183296 },
|
||||||
|
{ "OBSIDIAN2.R95", 0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
|
||||||
|
{ "OBSIDIAN3.R95", 0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
|
||||||
|
{ "OBSIDIAN4.C95", 0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
|
||||||
|
{ "OBSIDIAN DEMO DATA.MPL", 0, "77d04f62825c9f424baba46922ffb60f", 29552976 },
|
||||||
|
AD_LISTEND
|
||||||
|
},
|
||||||
|
Common::EN_ANY,
|
||||||
|
Common::kPlatformWindows,
|
||||||
|
ADGF_DEMO | ADGF_UNSTABLE,
|
||||||
|
GUIO0()
|
||||||
|
},
|
||||||
|
GID_OBSIDIAN,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // Obsidian PC demo
|
||||||
|
{
|
||||||
|
"obsidian",
|
||||||
|
"Demo",
|
||||||
|
{
|
||||||
|
{ "OBSIDIAN.EXE", 0, "b6fb0e0df88c1524bcd0c5de9f5e882c", 750080 },
|
||||||
|
{ "OBSIDIAN.R95", 0, "5361ef93e36d722665594b724e0018fd", 183296 },
|
||||||
|
{ "TEXTWORK.R95", 0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
|
||||||
|
{ "EXPRMNTL.R95", 0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
|
||||||
|
{ "MCURSORS.C95", 0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
|
||||||
|
{ "OBSIDIAN DEMO DATA.MPL", 0, "4d557cd0a5f2311685d213053ebbd567", 116947911 },
|
||||||
|
AD_LISTEND
|
||||||
|
},
|
||||||
|
Common::EN_ANY,
|
||||||
|
Common::kPlatformWindows,
|
||||||
|
ADGF_DEMO | ADGF_UNSTABLE,
|
||||||
|
GUIO0()
|
||||||
|
},
|
||||||
|
GID_OBSIDIAN,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // Obsidian PC demo
|
||||||
|
{
|
||||||
|
"obsidian",
|
||||||
|
"Demo",
|
||||||
|
{
|
||||||
|
{ "OBSIDIAN DEMO.EXE", 0, "1bac38af354fd79ae3285e6c737705b7", 751104 },
|
||||||
|
{ "OBSIDIAN1.R95", 0, "5361ef93e36d722665594b724e0018fd", 183296 },
|
||||||
|
{ "OBSIDIAN2.R95", 0, "96346d39c4bb04f525edbf06ffe047e0", 148992 },
|
||||||
|
{ "OBSIDIAN3.R95", 0, "aa0431c2be37e33883747c61d3e980ff", 108544 },
|
||||||
|
{ "OBSIDIAN4.C95", 0, "47cf6abb95f3c43cdcbdf7ea1de3478d", 145920 },
|
||||||
|
{ "OBSIDIAN DEMO DATA.MPL", 0, "4d557cd0a5f2311685d213053ebbd567", 116947911 },
|
||||||
|
AD_LISTEND
|
||||||
|
},
|
||||||
|
Common::EN_ANY,
|
||||||
|
Common::kPlatformWindows,
|
||||||
|
ADGF_DEMO | ADGF_UNSTABLE,
|
||||||
|
GUIO0()
|
||||||
|
},
|
||||||
|
GID_OBSIDIAN,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
|
||||||
{ AD_TABLE_END_MARKER, 0, 0, 0 }
|
{ AD_TABLE_END_MARKER, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace MTropolisEngine
|
} // End of namespace MTropolis
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -172,6 +172,7 @@ struct MacObsidianResources : public ProjectResources {
|
|||||||
~MacObsidianResources();
|
~MacObsidianResources();
|
||||||
|
|
||||||
void setup(bool haveWordGames);
|
void setup(bool haveWordGames);
|
||||||
|
void setup_mac_demo();
|
||||||
Common::SeekableReadStream *getSegmentStream(int index) const;
|
Common::SeekableReadStream *getSegmentStream(int index) const;
|
||||||
const Common::SharedPtr<CursorGraphicCollection> &getCursorGraphics() const;
|
const Common::SharedPtr<CursorGraphicCollection> &getCursorGraphics() const;
|
||||||
const Common::SharedPtr<Obsidian::WordGameData> &getWordGameData() const;
|
const Common::SharedPtr<Obsidian::WordGameData> &getWordGameData() const;
|
||||||
@ -290,6 +291,65 @@ void MacObsidianResources::setup(bool haveWordGames) {
|
|||||||
debug(1, "Finished unpacking installer resources");
|
debug(1, "Finished unpacking installer resources");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacObsidianResources::setup_mac_demo() {
|
||||||
|
debug(1, "Opening resources...");
|
||||||
|
|
||||||
|
const char *cursorSources[4] = {"Obsidian Demo", "Basic.rPP", "mCursors.cPP", "Obsidian.cPP"};
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
const char *fileName = cursorSources[i];
|
||||||
|
|
||||||
|
Common::MacResManager resMan;
|
||||||
|
if (!resMan.open(Common::Path(fileName)))
|
||||||
|
error("Failed to open resources in file '%s'", fileName);
|
||||||
|
|
||||||
|
if (!loadCursorsFromMacResources(*_cursorGraphics, resMan))
|
||||||
|
error("Failed to read cursor resources from file '%s'", fileName);
|
||||||
|
}
|
||||||
|
debug(1, "Loading word games...");
|
||||||
|
|
||||||
|
{
|
||||||
|
Common::MacResManager resMan;
|
||||||
|
if (!resMan.open(Common::Path("RSGKit.rPP")))
|
||||||
|
error("Couldn't find word game file in installer archive");
|
||||||
|
|
||||||
|
_wordGameData.reset(new Obsidian::WordGameData());
|
||||||
|
|
||||||
|
Common::SeekableReadStream *stream = resMan.getDataFork();
|
||||||
|
if (!stream)
|
||||||
|
error("Failed to open word game file");
|
||||||
|
|
||||||
|
Obsidian::WordGameLoadBucket buckets[] = {
|
||||||
|
{0, 0}, // 0 letters
|
||||||
|
{0xD7C8, 0xD7CC}, // 1 letter
|
||||||
|
{0xD7CC, 0xD84D}, // 2 letter
|
||||||
|
{0xD84D, 0xE25D}, // 3 letter
|
||||||
|
{0x1008C, 0x12AA8}, // 4 letter
|
||||||
|
{0x14C58, 0x19614}, // 5 letter
|
||||||
|
{0x1C73C, 0x230C1}, // 6 letter
|
||||||
|
{0x26D10, 0x2EB98}, // 7 letter
|
||||||
|
{0x32ADC, 0x3AA0E}, // 8 letter
|
||||||
|
{0x3E298, 0x45B88}, // 9 letter
|
||||||
|
{0x48BE8, 0x4E0D0}, // 10 letter
|
||||||
|
{0x4FFB0, 0x53460}, // 11 letter
|
||||||
|
{0x545F0, 0x56434}, // 12 letter
|
||||||
|
{0x56D84, 0x57CF0}, // 13 letter
|
||||||
|
{0x58158, 0x58833}, // 14 letter
|
||||||
|
{0x58A08, 0x58CD8}, // 15 letter
|
||||||
|
{0x58D8C, 0x58EAD}, // 16 letter
|
||||||
|
{0x58EF4, 0x58F72}, // 17 letter
|
||||||
|
{0x58F90, 0x58FDC}, // 18 letter
|
||||||
|
{0, 0}, // 19 letter
|
||||||
|
{0x58FEC, 0x59001}, // 20 letter
|
||||||
|
{0x59008, 0x59034}, // 21 letter
|
||||||
|
{0x5903C, 0x59053}, // 22 letter
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!_wordGameData->load(stream, buckets, 23, 1, false))
|
||||||
|
error("Failed to load word game data");
|
||||||
|
}
|
||||||
|
debug(1, "Finished loading demo resources");
|
||||||
|
}
|
||||||
|
|
||||||
Common::SeekableReadStream *MacObsidianResources::getSegmentStream(int index) const {
|
Common::SeekableReadStream *MacObsidianResources::getSegmentStream(int index) const {
|
||||||
return _segmentStreams[index];
|
return _segmentStreams[index];
|
||||||
}
|
}
|
||||||
@ -311,8 +371,9 @@ MacObsidianResources::~MacObsidianResources() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MTropolisEngine::MTropolisEngine(OSystem *syst, const MTropolisGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
|
MTropolisEngine::MTropolisEngine(OSystem *syst, const MTropolisGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
|
||||||
|
const Common::FSNode gameDataDir(ConfMan.get("path"));
|
||||||
|
SearchMan.addSubDirectoryMatching(gameDataDir, "Resource");
|
||||||
if (gameDesc->gameID == GID_OBSIDIAN && _gameDescription->desc.platform == Common::kPlatformWindows) {
|
if (gameDesc->gameID == GID_OBSIDIAN && _gameDescription->desc.platform == Common::kPlatformWindows) {
|
||||||
const Common::FSNode gameDataDir(ConfMan.get("path"));
|
|
||||||
SearchMan.addSubDirectoryMatching(gameDataDir, "Obsidian");
|
SearchMan.addSubDirectoryMatching(gameDataDir, "Obsidian");
|
||||||
SearchMan.addSubDirectoryMatching(gameDataDir, "Obsidian/RESOURCE");
|
SearchMan.addSubDirectoryMatching(gameDataDir, "Obsidian/RESOURCE");
|
||||||
SearchMan.addSubDirectoryMatching(gameDataDir, "RESOURCE");
|
SearchMan.addSubDirectoryMatching(gameDataDir, "RESOURCE");
|
||||||
@ -384,23 +445,52 @@ Common::Error MTropolisEngine::run() {
|
|||||||
_runtime->addVolume(5, "OBSIDIAN5", true);
|
_runtime->addVolume(5, "OBSIDIAN5", true);
|
||||||
|
|
||||||
Common::SharedPtr<ProjectDescription> desc(new ProjectDescription(kProjectPlatformWindows));
|
Common::SharedPtr<ProjectDescription> desc(new ProjectDescription(kProjectPlatformWindows));
|
||||||
desc->addSegment(0, "Obsidian Data 1.MPL");
|
|
||||||
desc->addSegment(1, "Obsidian Data 2.MPX");
|
if (_gameDescription->desc.flags & ADGF_DEMO) {
|
||||||
desc->addSegment(2, "Obsidian Data 3.MPX");
|
if (Common::File::exists("OBSIDI~1.MPL")) {
|
||||||
desc->addSegment(3, "Obsidian Data 4.MPX");
|
desc->addSegment(0, "OBSIDI~1.MPL");
|
||||||
desc->addSegment(4, "Obsidian Data 5.MPX");
|
} else {
|
||||||
desc->addSegment(5, "Obsidian Data 6.MPX");
|
desc->addSegment(0, "OBSIDIAN DEMO DATA.MPL");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
desc->addSegment(0, "Obsidian Data 1.MPL");
|
||||||
|
desc->addSegment(1, "Obsidian Data 2.MPX");
|
||||||
|
desc->addSegment(2, "Obsidian Data 3.MPX");
|
||||||
|
desc->addSegment(3, "Obsidian Data 4.MPX");
|
||||||
|
desc->addSegment(4, "Obsidian Data 5.MPX");
|
||||||
|
desc->addSegment(5, "Obsidian Data 6.MPX");
|
||||||
|
|
||||||
|
Common::SharedPtr<Obsidian::WordGameData> wgData = loadWinObsidianWordGameData();
|
||||||
|
desc->addPlugIn(PlugIns::createObsidian(wgData));
|
||||||
|
}
|
||||||
|
|
||||||
Common::SharedPtr<CursorGraphicCollection> cursors(new CursorGraphicCollection());
|
Common::SharedPtr<CursorGraphicCollection> cursors(new CursorGraphicCollection());
|
||||||
{
|
{
|
||||||
|
const char *cursorSources[3];
|
||||||
// Has to be in this order, some resources from MCURSORS will clobber resources from the player executable
|
// Has to be in this order, some resources from MCURSORS will clobber resources from the player executable
|
||||||
const char *cursorFiles[3] = {"Obsidian.exe", "MCURSORS.C95", "Obsidian.c95"};
|
if (Common::File::exists("OBSIDIAN4.C95")) {
|
||||||
|
cursorSources[1] = "OBSIDIAN4.C95";
|
||||||
|
} else {
|
||||||
|
cursorSources[1] = "MCURSORS.C95";
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
if (Common::File::exists("OBSIDIAN DEMO.EXE")) {
|
||||||
|
cursorSources[0] = "OBSIDIAN DEMO.EXE";
|
||||||
|
} else {
|
||||||
|
cursorSources[0] = "OBSIDIAN.EXE";
|
||||||
|
}
|
||||||
|
if (!(_gameDescription->desc.flags & ADGF_DEMO)) {
|
||||||
|
cursorSources[2] = "Obsidian.c95";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < (_gameDescription->desc.flags & ADGF_DEMO ? 2 : 3); i++) {
|
||||||
|
const char *fileName = cursorSources[i];
|
||||||
Common::File f;
|
Common::File f;
|
||||||
if (!f.open(cursorFiles[i]) || !loadCursorsFromPE(*cursors, &f)) {
|
if (!f.open(Common::Path(fileName)))
|
||||||
error("Failed to load resources");
|
error("Failed to open resources in file '%s'", fileName);
|
||||||
}
|
|
||||||
|
if (!loadCursorsFromPE(*cursors, &f))
|
||||||
|
error("Failed to read cursor resources from file '%s'", fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,8 +506,6 @@ Common::Error MTropolisEngine::run() {
|
|||||||
static_cast<Standard::StandardPlugIn *>(standardPlugIn.get())->getHacks().allowGarbledListModData = true;
|
static_cast<Standard::StandardPlugIn *>(standardPlugIn.get())->getHacks().allowGarbledListModData = true;
|
||||||
desc->addPlugIn(standardPlugIn);
|
desc->addPlugIn(standardPlugIn);
|
||||||
|
|
||||||
desc->addPlugIn(PlugIns::createObsidian(wgData));
|
|
||||||
|
|
||||||
_runtime->queueProject(desc);
|
_runtime->queueProject(desc);
|
||||||
|
|
||||||
} else if (_gameDescription->gameID == GID_OBSIDIAN && _gameDescription->desc.platform == Common::kPlatformMacintosh) {
|
} else if (_gameDescription->gameID == GID_OBSIDIAN && _gameDescription->desc.platform == Common::kPlatformMacintosh) {
|
||||||
@ -431,9 +519,6 @@ Common::Error MTropolisEngine::run() {
|
|||||||
MacObsidianResources *resources = new MacObsidianResources();
|
MacObsidianResources *resources = new MacObsidianResources();
|
||||||
Common::SharedPtr<ProjectResources> resPtr(resources);
|
Common::SharedPtr<ProjectResources> resPtr(resources);
|
||||||
|
|
||||||
// Non-English releases don't have Bureau word game puzzles
|
|
||||||
resources->setup(_gameDescription->desc.language == Common::Language::EN_ANY);
|
|
||||||
|
|
||||||
_runtime->addVolume(0, "Installed", true);
|
_runtime->addVolume(0, "Installed", true);
|
||||||
_runtime->addVolume(1, "OBSIDIAN1", true);
|
_runtime->addVolume(1, "OBSIDIAN1", true);
|
||||||
_runtime->addVolume(2, "OBSIDIAN2", true);
|
_runtime->addVolume(2, "OBSIDIAN2", true);
|
||||||
@ -443,8 +528,18 @@ Common::Error MTropolisEngine::run() {
|
|||||||
|
|
||||||
Common::SharedPtr<ProjectDescription> desc(new ProjectDescription(kProjectPlatformMacintosh));
|
Common::SharedPtr<ProjectDescription> desc(new ProjectDescription(kProjectPlatformMacintosh));
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
if (_gameDescription->desc.flags & ADGF_DEMO) {
|
||||||
desc->addSegment(i, resources->getSegmentStream(i));
|
resources->setup_mac_demo();
|
||||||
|
|
||||||
|
desc->addSegment(0, "Obs Demo Large w Sega");
|
||||||
|
} else {
|
||||||
|
// Non-English releases don't have Bureau word game puzzles
|
||||||
|
resources->setup(_gameDescription->desc.language == Common::Language::EN_ANY);
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
desc->addSegment(i, resources->getSegmentStream(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Common::SharedPtr<MTropolis::PlugIn> standardPlugIn = PlugIns::createStandard();
|
Common::SharedPtr<MTropolis::PlugIn> standardPlugIn = PlugIns::createStandard();
|
||||||
static_cast<Standard::StandardPlugIn *>(standardPlugIn.get())->getHacks().allowGarbledListModData = true;
|
static_cast<Standard::StandardPlugIn *>(standardPlugIn.get())->getHacks().allowGarbledListModData = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user