Add support for loading T7G Mac resources using the MacResManager.

svn-id: r49005
This commit is contained in:
Matthew Hoops 2010-05-11 15:41:31 +00:00
parent 59476e44b9
commit 1c0ffdc42d
8 changed files with 113 additions and 57 deletions

View file

@ -26,6 +26,8 @@
#include "groovie/cursor.h"
#include "groovie/groovie.h"
#include "common/archive.h"
#include "common/macresman.h"
#include "graphics/cursorman.h"
namespace Groovie {
@ -136,26 +138,32 @@ static const uint16 cursorDataOffsets[NUM_IMGS] = {
const uint GrvCursorMan_t7g::_cursorImg[NUM_STYLES] = {3, 5, 4, 3, 1, 0, 2, 6, 7, 8, 8};
const uint GrvCursorMan_t7g::_cursorPal[NUM_STYLES] = {0, 0, 0, 0, 2, 0, 1, 3, 5, 4, 6};
GrvCursorMan_t7g::GrvCursorMan_t7g(OSystem *system) :
GrvCursorMan_t7g::GrvCursorMan_t7g(OSystem *system, Common::MacResManager *macResFork) :
GrvCursorMan(system) {
// Open the cursors file
Common::File robgjd;
if (!robgjd.open("rob.gjd")) {
error("Groovie::Cursor: Couldn't open rob.gjd");
return;
Common::SeekableReadStream *robgjd = 0;
if (macResFork) {
// Open the cursors file from the resource fork
robgjd = macResFork->getResource("rob.gjd");
} else {
// Open the cursors file
robgjd = SearchMan.createReadStreamForMember("rob.gjd");
}
if (!robgjd)
error("Groovie::Cursor: Couldn't open rob.gjd");
// Load the images
for (uint imgnum = 0; imgnum < NUM_IMGS; imgnum++) {
robgjd.seek(cursorDataOffsets[imgnum]);
_images.push_back(loadImage(robgjd));
robgjd->seek(cursorDataOffsets[imgnum]);
_images.push_back(loadImage(*robgjd));
}
// Load the palettes
robgjd.seek(-0x60 * NUM_PALS, SEEK_END);
robgjd->seek(-0x60 * NUM_PALS, SEEK_END);
for (uint palnum = 0; palnum < NUM_PALS; palnum++) {
_palettes.push_back(loadPalette(robgjd));
_palettes.push_back(loadPalette(*robgjd));
}
// Build the cursors
@ -164,7 +172,7 @@ GrvCursorMan_t7g::GrvCursorMan_t7g(OSystem *system) :
_cursors.push_back(s);
}
robgjd.close();
delete robgjd;
}
GrvCursorMan_t7g::~GrvCursorMan_t7g() {
@ -179,7 +187,7 @@ GrvCursorMan_t7g::~GrvCursorMan_t7g() {
}
}
byte *GrvCursorMan_t7g::loadImage(Common::File &file) {
byte *GrvCursorMan_t7g::loadImage(Common::SeekableReadStream &file) {
uint16 decompbytes = 0, offset, i, length;
uint8 flagbyte, lengthmask = 0x0F, offsetlen, var_8;
byte *cursorStorage = new byte[65536];
@ -217,7 +225,7 @@ byte *GrvCursorMan_t7g::loadImage(Common::File &file) {
return cursorStorage;
}
byte *GrvCursorMan_t7g::loadPalette(Common::File &file) {
byte *GrvCursorMan_t7g::loadPalette(Common::SeekableReadStream &file) {
byte *palette = new byte[4 * 32];
for (uint8 colournum = 0; colournum < 32; colournum++) {
palette[colournum * 4 + 0] = file.readByte();

View file

@ -30,6 +30,10 @@
#include "common/array.h"
#include "common/file.h"
namespace Common {
class MacResManager;
}
namespace Groovie {
class Cursor {
@ -70,7 +74,7 @@ protected:
class GrvCursorMan_t7g : public GrvCursorMan {
public:
GrvCursorMan_t7g(OSystem *system);
GrvCursorMan_t7g(OSystem *system, Common::MacResManager *macResFork = 0);
~GrvCursorMan_t7g();
private:
@ -83,8 +87,8 @@ private:
Common::Array<byte *> _palettes;
// Loading functions
byte *loadImage(Common::File &file);
byte *loadPalette(Common::File &file);
byte *loadImage(Common::SeekableReadStream &file);
byte *loadPalette(Common::SeekableReadStream &file);
};
class GrvCursorMan_v2 : public GrvCursorMan {

View file

@ -63,8 +63,8 @@ static const GroovieGameDescription gameDescriptions[] = {
{
{
"t7g", "",
AD_ENTRY1s("script.grv", "6e30b54b1f3bc2262cdcf7961db2ae67", 17191),
Common::EN_ANY, Common::kPlatformMacintosh, ADGF_NO_FLAGS, Common::GUIO_NONE
AD_ENTRY1s("T7GMac", "a139540fa2be2247005ccf888b7231e3", 1830783),
Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, Common::GUIO_NONE
},
kGroovieT7G, 0
},

View file

@ -26,6 +26,7 @@
#include "common/config-manager.h"
#include "common/debug-channels.h"
#include "common/events.h"
#include "common/macresman.h"
#include "engines/util.h"
@ -42,7 +43,7 @@ namespace Groovie {
GroovieEngine::GroovieEngine(OSystem *syst, const GroovieGameDescription *gd) :
Engine(syst), _gameDescription(gd), _debugger(NULL), _script(NULL),
_resMan(NULL), _grvCursorMan(NULL), _videoPlayer(NULL), _musicPlayer(NULL),
_graphicsMan(NULL), _waitingForInput(false) {
_graphicsMan(NULL), _macResFork(NULL), _waitingForInput(false) {
// Adding the default directories
const Common::FSNode gameDataDir(ConfMan.get("path"));
@ -73,6 +74,7 @@ GroovieEngine::~GroovieEngine() {
delete _musicPlayer;
delete _graphicsMan;
delete _script;
delete _macResFork;
}
Common::Error GroovieEngine::run() {
@ -104,8 +106,14 @@ Common::Error GroovieEngine::run() {
// Create the resource and cursor managers and the video player
switch (_gameDescription->version) {
case kGroovieT7G:
_resMan = new ResMan_t7g();
_grvCursorMan = new GrvCursorMan_t7g(_system);
if (_gameDescription->desc.platform == Common::kPlatformMacintosh) {
_macResFork = new Common::MacResManager();
if (!_macResFork->open(_gameDescription->desc.filesDescriptions[0].fileName))
error("Could not open %s as a resource fork", _gameDescription->desc.filesDescriptions[0].fileName);
}
_resMan = new ResMan_t7g(_macResFork);
_grvCursorMan = new GrvCursorMan_t7g(_system, _macResFork);
_videoPlayer = new VDXPlayer(this);
break;
case kGroovieV2:
@ -116,11 +124,10 @@ Common::Error GroovieEngine::run() {
}
// Create the music player
if (_gameDescription->desc.platform == Common::kPlatformMacintosh) {
if (_gameDescription->desc.platform == Common::kPlatformMacintosh)
_musicPlayer = new MusicPlayerMac(this);
} else {
else
_musicPlayer = new MusicPlayerXMI(this, _gameDescription->version == kGroovieT7G ? "fat" : "sample");
}
// Load volume levels
syncSoundSettings();
@ -129,9 +136,10 @@ Common::Error GroovieEngine::run() {
Common::String filename = _gameDescription->desc.filesDescriptions[0].fileName;
if (_gameDescription->version == kGroovieT7G) {
// Run The 7th Guest's demo if requested
if (ConfMan.hasKey("demo_mode") && ConfMan.getBool("demo_mode")) {
if (ConfMan.hasKey("demo_mode") && ConfMan.getBool("demo_mode"))
filename = Common::String("demo.grv");
}
else if (_gameDescription->desc.platform == Common::kPlatformMacintosh)
filename = "script.grv"; // Stored inside the executable's resource fork
} else if (_gameDescription->version == kGroovieV2) {
// Open the disk index
Common::File disk;

View file

@ -36,6 +36,10 @@
#include "groovie/resource.h"
#include "groovie/script.h"
namespace Common {
class MacResManager;
}
/**
* This is the namespace of the Groovie engine.
*
@ -103,6 +107,8 @@ public:
MusicPlayer *_musicPlayer;
GraphicsMan *_graphicsMan;
Common::MacResManager *_macResFork;
private:
const GroovieGameDescription *_gameDescription;
Debugger *_debugger;

View file

@ -23,6 +23,9 @@
*
*/
#include "common/archive.h"
#include "common/macresman.h"
#include "groovie/groovie.h"
#include "groovie/resource.h"
@ -73,7 +76,7 @@ Common::SeekableReadStream *ResMan::open(uint32 fileRef) {
static const char t7g_gjds[][0x15] = {"at", "b", "ch", "d", "dr", "fh", "ga", "hdisk", "htbd", "intro", "jhek", "k", "la", "li", "mb", "mc", "mu", "n", "p", "xmi", "gamwav"};
ResMan_t7g::ResMan_t7g() {
ResMan_t7g::ResMan_t7g(Common::MacResManager *macResFork) : _macResFork(macResFork) {
for (int i = 0; i < 0x15; i++) {
// Prepare the filename
Common::String filename = t7g_gjds[i];
@ -89,19 +92,25 @@ uint16 ResMan_t7g::getRef(Common::String name, Common::String scriptname) {
Common::String rlFileName(t7g_gjds[_lastGjd]);
rlFileName += ".rl";
// Open the RL file
Common::File rlFile;
if (!rlFile.open(rlFileName)) {
error("Groovie::Resource: Couldn't open %s", rlFileName.c_str());
return false;
Common::SeekableReadStream *rlFile = 0;
if (_macResFork) {
// Open the RL file from the resource fork
rlFile = _macResFork->getResource(rlFileName);
} else {
// Open the RL file
rlFile = SearchMan.createReadStreamForMember(rlFileName);
}
if (!rlFile)
error("Groovie::Resource: Couldn't open %s", rlFileName.c_str());
uint16 resNum;
bool found = false;
for (resNum = 0; !found && !rlFile.err() && !rlFile.eos(); resNum++) {
for (resNum = 0; !found && !rlFile->err() && !rlFile->eos(); resNum++) {
// Read the resource name
char readname[12];
rlFile.read(readname, 12);
rlFile->read(readname, 12);
// Test whether it's the resource we're searching
Common::String resname(readname, 12);
@ -111,11 +120,11 @@ uint16 ResMan_t7g::getRef(Common::String name, Common::String scriptname) {
}
// Skip the rest of resource information
rlFile.read(readname, 8);
rlFile->read(readname, 8);
}
// Close the RL file
rlFile.close();
delete rlFile;
// Verify we really found the resource
if (!found) {
@ -135,32 +144,37 @@ bool ResMan_t7g::getResInfo(uint32 fileRef, ResInfo &resInfo) {
Common::String rlFileName(t7g_gjds[resInfo.gjd]);
rlFileName += ".rl";
// Open the RL file
Common::File rlFile;
if (!rlFile.open(rlFileName)) {
error("Groovie::Resource: Couldn't open %s", rlFileName.c_str());
return false;
Common::SeekableReadStream *rlFile = 0;
if (_macResFork) {
// Open the RL file from the resource fork
rlFile = _macResFork->getResource(rlFileName);
} else {
// Open the RL file
rlFile = SearchMan.createReadStreamForMember(rlFileName);
}
if (!rlFile)
error("Groovie::Resource: Couldn't open %s", rlFileName.c_str());
// Seek to the position of the desired resource
rlFile.seek(resNum * 20);
if (rlFile.eos()) {
rlFile.close();
rlFile->seek(resNum * 20);
if (rlFile->eos()) {
delete rlFile;
error("Groovie::Resource: Invalid resource number: 0x%04X (%s)", resNum, rlFileName.c_str());
return false;
}
// Read the resource name (just for debugging purposes)
char resname[12];
rlFile.read(resname, 12);
rlFile->read(resname, 12);
debugC(2, kGroovieDebugResource | kGroovieDebugAll, "Groovie::Resource: Resource name: %12s", resname);
// Read the resource information
resInfo.offset = rlFile.readUint32LE();
resInfo.size = rlFile.readUint32LE();
resInfo.offset = rlFile->readUint32LE();
resInfo.size = rlFile->readUint32LE();
// Close the resource RL file
rlFile.close();
delete rlFile;
return true;
}

View file

@ -26,6 +26,10 @@
#ifndef GROOVIE_RESOURCE_H
#define GROOVIE_RESOURCE_H
namespace Common {
class MacResManager;
}
namespace Groovie {
struct ResInfo {
@ -50,11 +54,14 @@ protected:
class ResMan_t7g : public ResMan {
public:
ResMan_t7g();
ResMan_t7g(Common::MacResManager *macResFork = 0);
~ResMan_t7g() {}
uint16 getRef(Common::String name, Common::String scriptname);
bool getResInfo(uint32 fileRef, ResInfo &resInfo);
private:
Common::MacResManager *_macResFork;
};
class ResMan_v2 : public ResMan {

View file

@ -30,11 +30,13 @@
#include "groovie/cell.h"
#include "groovie/saveload.h"
#include "common/archive.h"
#include "common/config-manager.h"
#include "common/debug-channels.h"
#include "common/endian.h"
#include "common/events.h"
#include "common/EventRecorder.h"
#include "common/macresman.h"
#define NUM_OPCODES 90
@ -128,22 +130,29 @@ void Script::timerTick() {
}
bool Script::loadScript(Common::String filename) {
// Try to open the script file
Common::File scriptfile;
if (!scriptfile.open(filename)) {
return false;
Common::SeekableReadStream *scriptfile = 0;
if (_vm->_macResFork) {
// Try to open the script file from the resource fork
scriptfile = _vm->_macResFork->getResource(filename);
} else {
// Try to open the script file
scriptfile = SearchMan.createReadStreamForMember(filename);
}
if (!scriptfile)
return false;
// Save the script filename
_scriptFile = filename;
// Load the code
_codeSize = scriptfile.size();
_codeSize = scriptfile->size();
_code = new byte[_codeSize];
if (!_code)
return false;
scriptfile.read(_code, _codeSize);
scriptfile.close();
scriptfile->read(_code, _codeSize);
delete scriptfile;
// Patch the loaded code for known script bugs
if (filename.equals("dr.grv")) {