Worked on separating scene logic into separate classes for M4 and MADS

svn-id: r47728
This commit is contained in:
Paul Gilbert 2010-01-30 23:03:07 +00:00
parent 676bebe2be
commit 3d1a43bc54
10 changed files with 503 additions and 367 deletions

View file

@ -311,12 +311,12 @@ bool MadsConsole::cmdObject(int argc, const char **argv) {
DebugPrintf("Usage: object ['list' | '#objnum' | 'add #objnum']\n"); DebugPrintf("Usage: object ['list' | '#objnum' | 'add #objnum']\n");
} else if (!strcmp(argv[1], "list")) { } else if (!strcmp(argv[1], "list")) {
// List of objects // List of objects
for (uint objStart = 0; objStart < _vm->_globals->getObjectsSize(); objStart += 5) { for (uint objStart = 0; objStart < _vm->globals()->getObjectsSize(); objStart += 5) {
DebugPrintf("%2d - ", objStart); DebugPrintf("%2d - ", objStart);
for (uint objId = objStart; objId < MIN<uint>(_vm->_globals->getObjectsSize(), objStart + 5); ++objId) { for (uint objId = objStart; objId < MIN<uint>(_vm->globals()->getObjectsSize(), objStart + 5); ++objId) {
if (objId != objStart) DebugPrintf(", "); if (objId != objStart) DebugPrintf(", ");
uint16 descId = _vm->_globals->getObject(objId)->descId; uint16 descId = _vm->globals()->getObject(objId)->descId;
DebugPrintf("%s", _vm->_globals->getVocab(descId)); DebugPrintf("%s", _vm->globals()->getVocab(descId));
} }
DebugPrintf("\n"); DebugPrintf("\n");
@ -327,12 +327,12 @@ bool MadsConsole::cmdObject(int argc, const char **argv) {
// Add the specified object to the player's inventory // Add the specified object to the player's inventory
int objNum = strToInt(argv[2]); int objNum = strToInt(argv[2]);
if ((objNum < 0) || (objNum >= (int)_vm->_globals->getObjectsSize())) if ((objNum < 0) || (objNum >= (int)_vm->globals()->getObjectsSize()))
DebugPrintf("Invalid object specified\n"); DebugPrintf("Invalid object specified\n");
else if (_vm->isM4()) else if (_vm->isM4())
DebugPrintf("Not implemented for M4 games\n"); DebugPrintf("Not implemented for M4 games\n");
else { else {
_vm->_scene->getMadsInterface()->addObjectToInventory(objNum); _vm->_scene->getInterface()->addObjectToInventory(objNum);
return false; return false;
} }
@ -340,19 +340,19 @@ bool MadsConsole::cmdObject(int argc, const char **argv) {
// Print the details of a specific object // Print the details of a specific object
int objNum = strToInt(argv[1]); int objNum = strToInt(argv[1]);
if ((objNum < 0) || (objNum >= (int)_vm->_globals->getObjectsSize())) if ((objNum < 0) || (objNum >= (int)_vm->globals()->getObjectsSize()))
DebugPrintf("Invalid object specified\n"); DebugPrintf("Invalid object specified\n");
else { else {
const MadsObject *obj = _vm->_globals->getObject(objNum); const MadsObject *obj = _vm->globals()->getObject(objNum);
DebugPrintf("Object #%d (%s) room=%d article=%d/%s vocabs=%d", objNum, _vm->_globals->getVocab(obj->descId), DebugPrintf("Object #%d (%s) room=%d article=%d/%s vocabs=%d", objNum, _vm->globals()->getVocab(obj->descId),
obj->roomNumber, (int)obj->article, englishMADSArticleList[obj->article], obj->vocabCount); obj->roomNumber, (int)obj->article, englishMADSArticleList[obj->article], obj->vocabCount);
if (obj->vocabCount > 0) { if (obj->vocabCount > 0) {
DebugPrintf(" - "); DebugPrintf(" - ");
for (int i = 0; i < obj->vocabCount; ++i) { for (int i = 0; i < obj->vocabCount; ++i) {
if (i != 0) DebugPrintf(", "); if (i != 0) DebugPrintf(", ");
DebugPrintf("%s (%d)/%d", _vm->_globals->getVocab(obj->vocabList[i].vocabId), DebugPrintf("%s (%d)/%d", _vm->globals()->getVocab(obj->vocabList[i].vocabId),
obj->vocabList[i].vocabId, obj->vocabList[i].unk); obj->vocabList[i].vocabId, obj->vocabList[i].unk);
} }
} }
@ -371,13 +371,13 @@ bool MadsConsole::cmdMessage(int argc, const char **argv) {
else { else {
int messageIdx = strToInt(argv[1]); int messageIdx = strToInt(argv[1]);
if ((argc == 3) && !strcmp(argv[2], "id")) if ((argc == 3) && !strcmp(argv[2], "id"))
messageIdx = _vm->_globals->messageIndexOf(messageIdx); messageIdx = _vm->globals()->messageIndexOf(messageIdx);
if (messageIdx == -1) if (messageIdx == -1)
DebugPrintf("Unknown message"); DebugPrintf("Unknown message");
else else
{ {
const char *msg = _vm->_globals->loadMessage(messageIdx); const char *msg = _vm->globals()->loadMessage(messageIdx);
Dialog *dlg = new Dialog(_vm, msg, "TEST DIALOG"); Dialog *dlg = new Dialog(_vm, msg, "TEST DIALOG");
_vm->_viewManager->addView(dlg); _vm->_viewManager->addView(dlg);

View file

@ -191,7 +191,7 @@ void Dialog::addBarLine() {
*/ */
void Dialog::getVocab(int vocabId, char **line) { void Dialog::getVocab(int vocabId, char **line) {
assert(vocabId > 0); assert(vocabId > 0);
const char *vocabStr = _madsVm->_globals->getVocab(vocabId); const char *vocabStr = _madsVm->globals()->getVocab(vocabId);
strcpy(*line, vocabStr); strcpy(*line, vocabStr);
if (_commandCase) if (_commandCase)

View file

@ -265,9 +265,19 @@ void Kernel::unpauseEngines() {
// TODO: A proper implementation of game unpausing // TODO: A proper implementation of game unpausing
} }
//-------------------------------------------------------------------------- /*--------------------------------------------------------------------------*/
MadsGlobals::MadsGlobals(MadsM4Engine *vm): _vm(vm) { Globals::Globals(MadsM4Engine *vm): _vm(vm) {
}
bool Globals::isInterfaceVisible() {
return _vm->_interfaceView->isVisible();
}
/*--------------------------------------------------------------------------*/
MadsGlobals::MadsGlobals(MadsEngine *vm): Globals(vm) {
_vm = vm;
} }
MadsGlobals::~MadsGlobals() { MadsGlobals::~MadsGlobals() {
@ -284,10 +294,6 @@ MadsGlobals::~MadsGlobals() {
_madsMessages.clear(); _madsMessages.clear();
} }
bool MadsGlobals::isInterfaceVisible() {
return _vm->_interfaceView->isVisible();
}
void MadsGlobals::loadMadsVocab() { void MadsGlobals::loadMadsVocab() {
Common::SeekableReadStream *vocabS = _vm->res()->get("vocab.dat"); Common::SeekableReadStream *vocabS = _vm->res()->get("vocab.dat");
int curPos = 0; int curPos = 0;
@ -402,7 +408,13 @@ const char *MadsGlobals::loadMessage(uint index) {
return (char*)buffer; return (char*)buffer;
} }
//-------------------------------------------------------------------------- /*--------------------------------------------------------------------------*/
M4Globals::M4Globals(M4Engine *vm): Globals(vm) {
_vm = vm;
}
/*--------------------------------------------------------------------------*/
Player::Player(MadsM4Engine *vm) : _vm(vm) { Player::Player(MadsM4Engine *vm) : _vm(vm) {
commandsAllowed = true; commandsAllowed = true;

View file

@ -36,6 +36,8 @@
namespace M4 { namespace M4 {
class MadsM4Engine; class MadsM4Engine;
class M4Engine;
class MadsEngine;
class ScriptInterpreter; class ScriptInterpreter;
class ScriptFunction; class ScriptFunction;
@ -183,7 +185,28 @@ public:
typedef Common::Array<Common::SharedPtr<MadsObject> > MadsObjectArray; typedef Common::Array<Common::SharedPtr<MadsObject> > MadsObjectArray;
class MadsGlobals { class Globals {
private:
MadsM4Engine *_vm;
public:
Globals(MadsM4Engine *vm);
virtual ~Globals() {};
bool isInterfaceVisible();
};
class M4Globals: public Globals {
private:
M4Engine *_vm;
public:
M4Globals(M4Engine *vm);
virtual ~M4Globals() {};
bool invSuppressClickSound;
};
class MadsGlobals: public Globals {
private: private:
struct MessageItem { struct MessageItem {
uint32 id; uint32 id;
@ -192,18 +215,15 @@ private:
uint16 compSize; uint16 compSize;
}; };
MadsM4Engine *_vm; MadsEngine *_vm;
Common::Array<char* > _madsVocab; Common::Array<char* > _madsVocab;
Common::Array<char* > _madsQuotes; Common::Array<char* > _madsQuotes;
Common::Array<MessageItem* > _madsMessages; Common::Array<MessageItem* > _madsMessages;
MadsObjectArray _madsObjects; MadsObjectArray _madsObjects;
public: public:
MadsGlobals(MadsM4Engine *vm); MadsGlobals(MadsEngine *vm);
~MadsGlobals(); ~MadsGlobals();
bool isInterfaceVisible();
// M4 variables
bool invSuppressClickSound;
// MADS variables // MADS variables
bool easyMouse; bool easyMouse;
bool invObjectsStill; bool invObjectsStill;

View file

@ -1191,7 +1191,8 @@ bool GUIButton::onEvent(M4EventType eventType, int32 param, int x, int y, GUIObj
_buttonState = BUTTON_PRESSED; _buttonState = BUTTON_PRESSED;
} }
_madsVm->_globals->invSuppressClickSound = false; if (_vm->isM4())
_m4Vm->globals()->invSuppressClickSound = false;
} else { } else {
// Button isn't pressed // Button isn't pressed
if (_tracking) if (_tracking)

View file

@ -274,10 +274,10 @@ void HotSpotList::loadHotSpots(Common::SeekableReadStream* hotspotStream, int ho
currentHotSpot->setVerb(""); currentHotSpot->setVerb("");
if (currentHotSpot->getVocabID() > 0) if (currentHotSpot->getVocabID() > 0)
currentHotSpot->setVocab(_madsVm->_globals->getVocab(currentHotSpot->getVocabID())); currentHotSpot->setVocab(_madsVm->globals()->getVocab(currentHotSpot->getVocabID()));
if (currentHotSpot->getVerbID() > 0) if (currentHotSpot->getVerbID() > 0)
currentHotSpot->setVerb(_madsVm->_globals->getVocab(currentHotSpot->getVerbID())); currentHotSpot->setVerb(_madsVm->globals()->getVocab(currentHotSpot->getVerbID()));
} }
} }
} }

View file

@ -118,6 +118,7 @@ MadsM4Engine::MadsM4Engine(OSystem *syst, const M4GameDescription *gameDesc) :
Common::addDebugChannel(kDebugConversations, "conversations", "Conversations debugging"); Common::addDebugChannel(kDebugConversations, "conversations", "Conversations debugging");
_resourceManager = NULL; _resourceManager = NULL;
_globals = NULL;
} }
@ -174,7 +175,6 @@ Common::Error MadsM4Engine::run() {
_actor = NULL; _actor = NULL;
} }
_rails = new Rails(); // needs to be initialized before _scene _rails = new Rails(); // needs to be initialized before _scene
_scene = new Scene(this);
_dialogs = new Dialogs(); _dialogs = new Dialogs();
_viewManager = new ViewManager(this); _viewManager = new ViewManager(this);
_inventory = new Inventory(this); _inventory = new Inventory(this);
@ -298,10 +298,13 @@ void MadsM4Engine::dumpFile(const char* filename, bool uncompress) {
M4Engine::M4Engine(OSystem *syst, const M4GameDescription *gameDesc): MadsM4Engine(syst, gameDesc) { M4Engine::M4Engine(OSystem *syst, const M4GameDescription *gameDesc): MadsM4Engine(syst, gameDesc) {
// FIXME // FIXME
_m4Vm = this; _m4Vm = this;
_globals = new M4Globals(this);
} }
M4Engine::~M4Engine() { M4Engine::~M4Engine() {
delete _resourceManager; delete _resourceManager;
delete _globals;
} }
Common::Error M4Engine::run() { Common::Error M4Engine::run() {
@ -314,7 +317,7 @@ Common::Error M4Engine::run() {
// Set up needed common functionality // Set up needed common functionality
MadsM4Engine::run(); MadsM4Engine::run();
_scene = new M4Scene(this);
_script->open("m4.dat"); _script->open("m4.dat");
#ifdef SCRIPT_TEST #ifdef SCRIPT_TEST
@ -506,22 +509,24 @@ Common::Error MadsEngine::run() {
// Set up needed common functionality // Set up needed common functionality
MadsM4Engine::run(); MadsM4Engine::run();
_scene = new MadsScene(this);
_palette->setMadsSystemPalette(); _palette->setMadsSystemPalette();
_mouse->init("cursor.ss", NULL); _mouse->init("cursor.ss", NULL);
_mouse->setCursorNum(0); _mouse->setCursorNum(0);
// Load MADS data files // Load MADS data files
_globals->loadMadsVocab(); // vocab.dat MadsGlobals *globals = (MadsGlobals *)_globals;
_globals->loadMadsQuotes(); // quotes.dat globals->loadMadsVocab(); // vocab.dat
_globals->loadMadsMessagesInfo(); // messages.dat globals->loadMadsQuotes(); // quotes.dat
_globals->loadMadsObjects(); globals->loadMadsMessagesInfo(); // messages.dat
globals->loadMadsObjects();
// Setup globals // Setup globals
_madsVm->_globals->easyMouse = true; globals->easyMouse = true;
_madsVm->_globals->invObjectsStill = false; globals->invObjectsStill = false;
_madsVm->_globals->textWindowStill = false; globals->textWindowStill = false;
_madsVm->_globals->storyMode = 0; globals->storyMode = 0;
// Test code to dump all messages to the console // Test code to dump all messages to the console
//for (int i = 0; i < _globals->getMessagesSize(); i++) //for (int i = 0; i < _globals->getMessagesSize(); i++)

View file

@ -175,6 +175,8 @@ public:
// //
ResourceManager *_resourceManager; ResourceManager *_resourceManager;
Globals *_globals;
SaveLoad *_saveLoad; SaveLoad *_saveLoad;
ViewManager *_viewManager; ViewManager *_viewManager;
Palette *_palette; Palette *_palette;
@ -206,7 +208,8 @@ public:
virtual Common::Error run(); virtual Common::Error run();
MadsGlobals *_globals; MadsGlobals *globals() { return (MadsGlobals *)_globals; };
MadsScene *scene() { return (MadsScene *)_scene; };
}; };
class M4Engine: public MadsM4Engine { class M4Engine: public MadsM4Engine {
@ -215,6 +218,9 @@ public:
virtual ~M4Engine(); virtual ~M4Engine();
virtual Common::Error run(); virtual Common::Error run();
M4Globals *globals() { return (M4Globals *)_globals; };
M4Scene *scene() { return (M4Scene *)_scene; };
}; };
// FIXME: remove globals // FIXME: remove globals

View file

@ -52,14 +52,12 @@ Scene::Scene(MadsM4Engine *vm): View(vm, Common::Rect(0, 0, vm->_screen->width()
_sceneResources.props = new HotSpotList(); _sceneResources.props = new HotSpotList();
_backgroundSurface = new M4Surface(); _backgroundSurface = new M4Surface();
_codeSurface = new M4Surface(); _codeSurface = new M4Surface();
_madsInterfaceSurface = new MadsInterfaceView(vm);
_sceneSprites = NULL;
_palData = NULL; _palData = NULL;
_interfacePal = NULL; _interfacePal = NULL;
_interfaceSurface = NULL;
_inverseColorTable = NULL; _inverseColorTable = NULL;
strcpy(_statusText, ""); strcpy(_statusText, "");
_vm->_rails->setCodeSurface(_codeSurface); _vm->_rails->setCodeSurface(_codeSurface);
_currentAction = kVerbNone;
} }
Scene::~Scene() { Scene::~Scene() {
@ -73,7 +71,6 @@ Scene::~Scene() {
delete _backgroundSurface; delete _backgroundSurface;
delete _codeSurface; delete _codeSurface;
delete _sceneSprites;
// _vm->_palette->deleteAllRanges(); // _vm->_palette->deleteAllRanges();
@ -85,17 +82,6 @@ Scene::~Scene() {
void Scene::loadScene(int sceneNumber) { void Scene::loadScene(int sceneNumber) {
_currentScene = sceneNumber; _currentScene = sceneNumber;
// Close the menu if it's active
if (!_vm->isM4()) {
View *mainMenu = _vm->_viewManager->getView(VIEWID_MAINMENU);
if (mainMenu != NULL) {
_vm->_viewManager->deleteView(mainMenu);
}
}
// TODO: Check if we were loading a game
// Load scene background and set palette // Load scene background and set palette
if (_palData) { if (_palData) {
_vm->_palette->deleteRange(_palData); _vm->_palette->deleteRange(_palData);
@ -106,79 +92,10 @@ void Scene::loadScene(int sceneNumber) {
_vm->_palette->deleteRange(_interfacePal); _vm->_palette->deleteRange(_interfacePal);
delete _interfacePal; delete _interfacePal;
} }
}
if (_vm->isM4()) { void Scene::show() {
_backgroundSurface->loadBackground(sceneNumber); _vm->_viewManager->addView(this);
_palData = NULL;
} else {
// Set system palette entries
_vm->_palette->blockRange(0, 7);
RGB8 sysColors[3] = { {0x1f<<2, 0x2d<<2, 0x31<<2, 0}, {0x24<<2, 0x37<<2, 0x3a<<2, 0},
{0x00<<2, 0x10<<2, 0x16<<2, 0}};
_vm->_palette->setPalette(&sysColors[0], 4, 3);
_backgroundSurface->loadBackground(sceneNumber, &_palData);
_vm->_palette->addRange(_palData);
_backgroundSurface->translate(_palData);
if (sceneNumber < 900) {
/*_backgroundSurface->fillRect(Common::Rect(0, MADS_SURFACE_HEIGHT,
_backgroundSurface->width(), _backgroundSurface->height()),
_vm->_palette->BLACK);*/
// TODO: interface palette
_madsInterfaceSurface->madsloadInterface(0, &_interfacePal);
_vm->_palette->addRange(_interfacePal);
_madsInterfaceSurface->translate(_interfacePal);
_backgroundSurface->copyFrom(_madsInterfaceSurface, Common::Rect(0, 0, 320, 44), 0, 200 - 44);
_madsInterfaceSurface->initialise();
}
}
if (_vm->getGameType() == GType_Burger &&
sceneNumber != TITLE_SCENE_BURGER && sceneNumber != MAINMENU_SCENE_BURGER)
_vm->_interfaceView->setStatusText("");
// Load scene def file (*.CHK)
if (_vm->isM4()) {
loadSceneResources(sceneNumber);
loadSceneInverseColorTable(sceneNumber);
} else {
// Don't load other screen resources for system screens
if (sceneNumber >= 900)
return;
loadSceneHotSpotsMads(sceneNumber);
}
// TODO: set walker scaling
// TODO: destroy woodscript buffer
// Load scene walk path file (*.COD/*.WW?)
loadSceneCodes(sceneNumber);
// Load inverse color table file (*.IPL)
loadSceneInverseColorTable(sceneNumber);
if (_vm->isM4()) {
if (_vm->getGameType() != GType_Burger) {
// Load scene sprites file (*.SSB)
loadSceneSprites(sceneNumber);
// Load scene sprite codes file (*.SSC)
loadSceneSpriteCodes(sceneNumber);
}
if (sceneNumber != TITLE_SCENE_BURGER && sceneNumber != MAINMENU_SCENE_BURGER) {
_vm->_interfaceView->show();
showSprites();
}
}
// Purge resources
_vm->res()->purge();
} }
void Scene::loadSceneResources(int sceneNumber) { void Scene::loadSceneResources(int sceneNumber) {
@ -248,27 +165,6 @@ void Scene::loadSceneHotSpotsMads(int sceneNumber) {
delete hotspotStream; delete hotspotStream;
} }
void Scene::loadSceneCodes(int sceneNumber, int index) {
char filename[kM4MaxFilenameSize];
Common::SeekableReadStream *sceneS;
if (_vm->isM4()) {
sprintf(filename, "%i.cod", sceneNumber);
sceneS = _vm->res()->openFile(filename);
_codeSurface->loadCodesM4(sceneS);
_vm->res()->toss(filename);
} else if (_vm->getGameType() == GType_Phantom || _vm->getGameType() == GType_DragonSphere) {
sprintf(filename, "rm%i.ww%i", sceneNumber, index);
MadsPack walkData(filename, _vm);
sceneS = walkData.getItemStream(0);
_codeSurface->loadCodesMads(sceneS);
_vm->res()->toss(filename);
} else if (_vm->getGameType() == GType_RexNebular) {
// TODO
return;
}
}
void Scene::loadSceneInverseColorTable(int sceneNumber) { void Scene::loadSceneInverseColorTable(int sceneNumber) {
char filename[kM4MaxFilenameSize]; char filename[kM4MaxFilenameSize];
Common::SeekableReadStream *iplS; Common::SeekableReadStream *iplS;
@ -287,18 +183,6 @@ void Scene::loadSceneInverseColorTable(int sceneNumber) {
} }
void Scene::loadSceneSprites(int sceneNumber) {
char filename[kM4MaxFilenameSize];
sprintf(filename, "%i.ssb", sceneNumber);
Common::SeekableReadStream *sceneS = _vm->res()->get(filename);
_sceneSprites = new SpriteAsset(_vm, sceneS, sceneS->size(), filename);
_vm->res()->toss(filename);
printf("Scene has %d sprites, each one having %d colors\n", _sceneSprites->getCount(), _sceneSprites->getColorCount());
}
void Scene::loadSceneSpriteCodes(int sceneNumber) { void Scene::loadSceneSpriteCodes(int sceneNumber) {
char filename[kM4MaxFilenameSize]; char filename[kM4MaxFilenameSize];
sprintf(filename, "%i.ssc", sceneNumber); sprintf(filename, "%i.ssc", sceneNumber);
@ -349,60 +233,6 @@ void Scene::showSprites() {
// TODO // TODO
} }
void Scene::checkHotspotAtMousePos(int x, int y) {
if (_vm->getGameType() == GType_Riddle)
return;
// TODO: loads of things to do here, only the mouse cursor and the status
// text is changed for now
// Only scene hotspots are checked for now, not parallax/props, as the
// latter ones are not used by Orion Burger
HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
if (currentHotSpot != NULL && currentHotSpot->getActive()) {
if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
_vm->_mouse->getCursorNum() != CURSOR_TAKE &&
_vm->_mouse->getCursorNum() != CURSOR_USE &&
_vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
_vm->_mouse->setCursorNum(currentHotSpot->getCursor());
}
_vm->_interfaceView->setStatusText(currentHotSpot->getPrep());
} else {
if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
_vm->_mouse->getCursorNum() != CURSOR_TAKE &&
_vm->_mouse->getCursorNum() != CURSOR_USE &&
_vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
_vm->_mouse->setCursorNum(0);
} else {
}
}
}
void Scene::checkHotspotAtMousePosMads(int x, int y) {
HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
if (currentHotSpot != NULL) {
_vm->_mouse->setCursorNum(currentHotSpot->getCursor());
// This is the "easy" interface, which updates the status text when the mouse is moved
// TODO: toggle this code for easy/normal interface mode
char statusText[50];
int verbId = _currentAction;
if (verbId == kVerbNone)
verbId = currentHotSpot->getVerbID();
if (verbId == kVerbNone)
verbId = kVerbWalkTo;
sprintf(statusText, "%s %s\n", _madsVm->_globals->getVocab(verbId), currentHotSpot->getVocab());
statusText[0] = toupper(statusText[0]); // capitalize first letter
setMADSStatusText(statusText);
} else {
_vm->_mouse->setCursorNum(0);
setMADSStatusText("");
}
}
// Test function, shows all scene hotspots // Test function, shows all scene hotspots
void Scene::showHotSpots() { void Scene::showHotSpots() {
int i = 0; int i = 0;
@ -450,11 +280,6 @@ void Scene::playIntro() {
} }
void Scene::show() {
_vm->_viewManager->addView(this);
_vm->_viewManager->addView(_madsInterfaceSurface);
}
void Scene::update() { void Scene::update() {
// TODO: Needs a proper implementation // TODO: Needs a proper implementation
// NOTE: Don't copy the background when in M4 mode or WoodScript anims won't be shown // NOTE: Don't copy the background when in M4 mode or WoodScript anims won't be shown
@ -473,7 +298,7 @@ void Scene::update() {
_vm->_font->writeString(this, _statusText, (width() - _vm->_font->getWidth(_statusText)) / 2, 142, 0); _vm->_font->writeString(this, _statusText, (width() - _vm->_font->getWidth(_statusText)) / 2, 142, 0);
} }
_madsInterfaceSurface->copyTo(this, 0, this->height() - _madsInterfaceSurface->height()); _interfaceSurface->copyTo(this, 0, this->height() - _interfaceSurface->height());
} }
} }
@ -492,76 +317,13 @@ bool Scene::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &cap
switch (eventType) { switch (eventType) {
case MEVENT_LEFT_CLICK: case MEVENT_LEFT_CLICK:
{ leftClick(x, y);
if (_vm->getGameType() == GType_Burger) {
// Place a Wilbur sprite with the correct facing
HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
if (currentHotSpot != NULL && currentHotSpot->getActive()) {
update();
_vm->_actor->setWalkerDirection(currentHotSpot->getFacing());
/*
int posX = currentHotSpot->getFeetX();
int posY = currentHotSpot->getFeetY() -
scaleValue(_vm->_actor->getWalkerHeight(), _vm->_actor->getWalkerScaling(), 0);
//_vm->_actor->placeWalkerSpriteAt(0, posX, posY);
*/
// Player said.... (for scene scripts)
printf("Player said: %s %s\n", currentHotSpot->getVerb(), currentHotSpot->getVocab());
// FIXME: This should be moved somewhere else, and is incomplete
if (_vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
if (_vm->_mouse->getVerb() == NULL) {
strcpy(_vm->_player->verb, currentHotSpot->getVerb());
} else {
strcpy(_vm->_player->verb, _vm->_mouse->getVerb());
}
} else {
strcpy(_vm->_player->verb, _vm->_interfaceView->_inventory.getSelectedObjectName());
}
strcpy(_vm->_player->noun, currentHotSpot->getVocab());
strcpy(_vm->_player->object, "");
_vm->_player->commandReady = true;
printf("## Player said: %s %s\n", _vm->_player->verb, _vm->_player->noun);
}
}
if (!_vm->isM4()) {
HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
if (currentHotSpot != NULL) {
char statusText[50];
if (currentHotSpot->getVerbID() != 0) {
sprintf(statusText, "%s %s\n", currentHotSpot->getVerb(), currentHotSpot->getVocab());
} else {
sprintf(statusText, "%s %s\n", _madsVm->_globals->getVocab(kVerbWalkTo), currentHotSpot->getVocab());
}
statusText[0] = toupper(statusText[0]); // capitalize first letter
setMADSStatusText(statusText);
}
}
}
break; break;
case MEVENT_RIGHT_CLICK: case MEVENT_RIGHT_CLICK:
if (_vm->getGameType() == GType_Burger) { rightClick(x, y);
nextCommonCursor();
_vm->_interfaceView->_inventory.clearSelected();
} else {
// ***DEBUG*** - sample dialog display
int idx = 3; //_madsVm->_globals->messageIndexOf(0x277a);
const char *msg = _madsVm->_globals->loadMessage(idx);
Dialog *dlg = new Dialog(_vm, msg, "TEST DIALOG");
_vm->_viewManager->addView(dlg);
_vm->_viewManager->moveToFront(dlg);
}
break; break;
case MEVENT_MOVE: case MEVENT_MOVE:
if (_vm->isM4()) checkHotspotAtMousePos(x, y);
checkHotspotAtMousePos(x, y);
else
checkHotspotAtMousePosMads(x, y);
break; break;
default: default:
return false; return false;
@ -570,29 +332,6 @@ bool Scene::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &cap
return true; return true;
} }
void Scene::nextCommonCursor() {
int cursorIndex = _vm->_mouse->getCursorNum();
switch (cursorIndex) {
case CURSOR_ARROW:
cursorIndex = CURSOR_LOOK;
break;
case CURSOR_LOOK:
cursorIndex = CURSOR_TAKE;
break;
case CURSOR_TAKE:
cursorIndex = CURSOR_USE;
break;
case CURSOR_USE:
cursorIndex = CURSOR_ARROW;
break;
default:
cursorIndex = CURSOR_ARROW;
}
_vm->_mouse->setCursorNum(cursorIndex);
}
enum boxSprites { enum boxSprites {
topLeft = 0, topLeft = 0,
topRight = 1, topRight = 1,
@ -691,7 +430,313 @@ void Scene::showMADSV2TextBox(char *text, int x, int y, char *faceName) {
boxSprites->getFrame(bottomRight)->copyTo(_backgroundSurface, curX, curY + 1); boxSprites->getFrame(bottomRight)->copyTo(_backgroundSurface, curX, curY + 1);
} }
void Scene::setAction(int action, int objectId) { /*--------------------------------------------------------------------------*/
M4Scene::M4Scene(M4Engine *vm): Scene(vm) {
_vm = vm;
_sceneSprites = NULL;
}
M4Scene::~M4Scene() {
delete _sceneSprites;
}
void M4Scene::loadSceneSprites(int sceneNumber) {
char filename[kM4MaxFilenameSize];
sprintf(filename, "%i.ssb", sceneNumber);
Common::SeekableReadStream *sceneS = _vm->res()->get(filename);
_sceneSprites = new SpriteAsset(_vm, sceneS, sceneS->size(), filename);
_vm->res()->toss(filename);
printf("Scene has %d sprites, each one having %d colors\n", _sceneSprites->getCount(), _sceneSprites->getColorCount());
}
void M4Scene::loadScene(int sceneNumber) {
Scene::loadScene(sceneNumber);
_backgroundSurface->loadBackground(sceneNumber);
_palData = NULL;
if (_vm->getGameType() == GType_Burger &&
sceneNumber != TITLE_SCENE_BURGER && sceneNumber != MAINMENU_SCENE_BURGER)
_vm->_interfaceView->setStatusText("");
// Load scene def file (*.CHK)
loadSceneResources(sceneNumber);
loadSceneInverseColorTable(sceneNumber);
// TODO: set walker scaling
// TODO: destroy woodscript buffer
// Load scene walk path file (*.COD/*.WW?)
loadSceneCodes(sceneNumber);
// Load inverse color table file (*.IPL)
loadSceneInverseColorTable(sceneNumber);
if (_vm->getGameType() != GType_Burger) {
// Load scene sprites file (*.SSB)
loadSceneSprites(sceneNumber);
// Load scene sprite codes file (*.SSC)
loadSceneSpriteCodes(sceneNumber);
}
if (sceneNumber != TITLE_SCENE_BURGER && sceneNumber != MAINMENU_SCENE_BURGER) {
_vm->_interfaceView->show();
showSprites();
}
// Purge resources
_vm->res()->purge();
}
void M4Scene::loadSceneCodes(int sceneNumber, int index) {
char filename[kM4MaxFilenameSize];
Common::SeekableReadStream *sceneS;
sprintf(filename, "%i.cod", sceneNumber);
sceneS = _vm->res()->openFile(filename);
_codeSurface->loadCodesM4(sceneS);
_vm->res()->toss(filename);
}
void M4Scene::checkHotspotAtMousePos(int x, int y) {
if (_vm->getGameType() == GType_Riddle)
return;
// TODO: loads of things to do here, only the mouse cursor and the status
// text is changed for now
// Only scene hotspots are checked for now, not parallax/props, as the
// latter ones are not used by Orion Burger
HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
if (currentHotSpot != NULL && currentHotSpot->getActive()) {
if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
_vm->_mouse->getCursorNum() != CURSOR_TAKE &&
_vm->_mouse->getCursorNum() != CURSOR_USE &&
_vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
_vm->_mouse->setCursorNum(currentHotSpot->getCursor());
}
_vm->_interfaceView->setStatusText(currentHotSpot->getPrep());
} else {
if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
_vm->_mouse->getCursorNum() != CURSOR_TAKE &&
_vm->_mouse->getCursorNum() != CURSOR_USE &&
_vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
_vm->_mouse->setCursorNum(0);
} else {
}
}
}
void M4Scene::leftClick(int x, int y) {
if (_vm->getGameType() == GType_Burger) {
// Place a Wilbur sprite with the correct facing
HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
if (currentHotSpot != NULL && currentHotSpot->getActive()) {
update();
_vm->_actor->setWalkerDirection(currentHotSpot->getFacing());
/*
int posX = currentHotSpot->getFeetX();
int posY = currentHotSpot->getFeetY() -
scaleValue(_vm->_actor->getWalkerHeight(), _vm->_actor->getWalkerScaling(), 0);
//_vm->_actor->placeWalkerSpriteAt(0, posX, posY);
*/
// Player said.... (for scene scripts)
printf("Player said: %s %s\n", currentHotSpot->getVerb(), currentHotSpot->getVocab());
// FIXME: This should be moved somewhere else, and is incomplete
if (_vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
if (_vm->_mouse->getVerb() == NULL) {
strcpy(_vm->_player->verb, currentHotSpot->getVerb());
} else {
strcpy(_vm->_player->verb, _vm->_mouse->getVerb());
}
} else {
strcpy(_vm->_player->verb, _vm->_interfaceView->_inventory.getSelectedObjectName());
}
strcpy(_vm->_player->noun, currentHotSpot->getVocab());
strcpy(_vm->_player->object, "");
_vm->_player->commandReady = true;
printf("## Player said: %s %s\n", _vm->_player->verb, _vm->_player->noun);
}
}
}
void M4Scene::rightClick(int x, int y) {
if (_vm->getGameType() == GType_Burger) {
nextCommonCursor();
_vm->_interfaceView->_inventory.clearSelected();
}
}
void M4Scene::setAction(int action, int objectId) {
}
void M4Scene::nextCommonCursor() {
int cursorIndex = _vm->_mouse->getCursorNum();
switch (cursorIndex) {
case CURSOR_ARROW:
cursorIndex = CURSOR_LOOK;
break;
case CURSOR_LOOK:
cursorIndex = CURSOR_TAKE;
break;
case CURSOR_TAKE:
cursorIndex = CURSOR_USE;
break;
case CURSOR_USE:
cursorIndex = CURSOR_ARROW;
break;
default:
cursorIndex = CURSOR_ARROW;
}
_vm->_mouse->setCursorNum(cursorIndex);
}
/*--------------------------------------------------------------------------*/
MadsScene::MadsScene(MadsEngine *vm): Scene(vm) {
_vm = vm;
_interfaceSurface = new MadsInterfaceView(vm);
_currentAction = kVerbNone;
}
void MadsScene::loadScene(int sceneNumber) {
// Close the menu if it's active
View *mainMenu = _vm->_viewManager->getView(VIEWID_MAINMENU);
if (mainMenu != NULL) {
_vm->_viewManager->deleteView(mainMenu);
}
// Handle common scene setting
Scene::loadScene(sceneNumber);
// TODO: Check if we were loading a game
// Set system palette entries
_vm->_palette->blockRange(0, 7);
RGB8 sysColors[3] = { {0x1f<<2, 0x2d<<2, 0x31<<2, 0}, {0x24<<2, 0x37<<2, 0x3a<<2, 0},
{0x00<<2, 0x10<<2, 0x16<<2, 0}};
_vm->_palette->setPalette(&sysColors[0], 4, 3);
_backgroundSurface->loadBackground(sceneNumber, &_palData);
_vm->_palette->addRange(_palData);
_backgroundSurface->translate(_palData);
if (sceneNumber < 900) {
/*_backgroundSurface->fillRect(Common::Rect(0, MADS_SURFACE_HEIGHT,
_backgroundSurface->width(), _backgroundSurface->height()),
_vm->_palette->BLACK);*/
// TODO: interface palette
_interfaceSurface->madsloadInterface(0, &_interfacePal);
_vm->_palette->addRange(_interfacePal);
_interfaceSurface->translate(_interfacePal);
_backgroundSurface->copyFrom(_interfaceSurface, Common::Rect(0, 0, 320, 44), 0, 200 - 44);
_interfaceSurface->initialise();
}
// Don't load other screen resources for system screens
if (sceneNumber >= 900)
return;
loadSceneHotSpotsMads(sceneNumber);
// TODO: set walker scaling
// TODO: destroy woodscript buffer
// Load scene walk path file (*.COD/*.WW?)
loadSceneCodes(sceneNumber);
// Load inverse color table file (*.IPL)
loadSceneInverseColorTable(sceneNumber);
// Purge resources
_vm->res()->purge();
}
void MadsScene::show() {
Scene::show();
_vm->_viewManager->addView(_interfaceSurface);
}
void MadsScene::loadSceneCodes(int sceneNumber, int index) {
char filename[kM4MaxFilenameSize];
Common::SeekableReadStream *sceneS;
if (_vm->getGameType() == GType_Phantom || _vm->getGameType() == GType_DragonSphere) {
sprintf(filename, "rm%i.ww%i", sceneNumber, index);
MadsPack walkData(filename, _vm);
sceneS = walkData.getItemStream(0);
_codeSurface->loadCodesMads(sceneS);
_vm->res()->toss(filename);
} else if (_vm->getGameType() == GType_RexNebular) {
// TODO
}
}
void MadsScene::checkHotspotAtMousePos(int x, int y) {
HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
if (currentHotSpot != NULL) {
_vm->_mouse->setCursorNum(currentHotSpot->getCursor());
// This is the "easy" interface, which updates the status text when the mouse is moved
// TODO: toggle this code for easy/normal interface mode
char statusText[50];
int verbId = _currentAction;
if (verbId == kVerbNone)
verbId = currentHotSpot->getVerbID();
if (verbId == kVerbNone)
verbId = kVerbWalkTo;
sprintf(statusText, "%s %s\n", _madsVm->globals()->getVocab(verbId), currentHotSpot->getVocab());
statusText[0] = toupper(statusText[0]); // capitalize first letter
setMADSStatusText(statusText);
} else {
_vm->_mouse->setCursorNum(0);
setMADSStatusText("");
}
}
void MadsScene::leftClick(int x, int y) {
HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
if (currentHotSpot != NULL) {
char statusText[50];
if (currentHotSpot->getVerbID() != 0) {
sprintf(statusText, "%s %s\n", currentHotSpot->getVerb(), currentHotSpot->getVocab());
} else {
sprintf(statusText, "%s %s\n", _madsVm->globals()->getVocab(kVerbWalkTo), currentHotSpot->getVocab());
}
statusText[0] = toupper(statusText[0]); // capitalize first letter
setMADSStatusText(statusText);
}
}
void MadsScene::rightClick(int x, int y) {
// ***DEBUG*** - sample dialog display
int idx = 3; //_madsVm->_globals->messageIndexOf(0x277a);
const char *msg = _madsVm->globals()->loadMessage(idx);
Dialog *dlg = new Dialog(_vm, msg, "TEST DIALOG");
_vm->_viewManager->addView(dlg);
_vm->_viewManager->moveToFront(dlg);
}
void MadsScene::setAction(int action, int objectId) {
VALIDATE_MADS; VALIDATE_MADS;
char statusText[50]; char statusText[50];
@ -699,12 +744,12 @@ void Scene::setAction(int action, int objectId) {
// a second object can be selected, as in 'use gun to shoot person', with requires a target // a second object can be selected, as in 'use gun to shoot person', with requires a target
// Set up the new action // Set up the new action
strcpy(statusText, _madsVm->_globals->getVocab(action)); strcpy(statusText, _madsVm->globals()->getVocab(action));
statusText[0] = toupper(statusText[0]); // capitalize first letter statusText[0] = toupper(statusText[0]); // capitalize first letter
if (objectId != -1) { if (objectId != -1) {
MadsObject *obj = _madsVm->_globals->getObject(objectId); MadsObject *obj = _madsVm->globals()->getObject(objectId);
sprintf(statusText + strlen(statusText), " %s", _madsVm->_globals->getVocab(obj->descId)); sprintf(statusText + strlen(statusText), " %s", _madsVm->globals()->getVocab(obj->descId));
} else { } else {
_currentAction = action; _currentAction = action;
} }
@ -712,14 +757,13 @@ void Scene::setAction(int action, int objectId) {
setMADSStatusText(statusText); setMADSStatusText(statusText);
} }
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* MadsInterfaceView handles the user interface section at the bottom of * MadsInterfaceView handles the user interface section at the bottom of
* game screens in MADS games * game screens in MADS games
*-------------------------------------------------------------------------- *--------------------------------------------------------------------------
*/ */
MadsInterfaceView::MadsInterfaceView(MadsM4Engine *vm): View(vm, Common::Rect(0, MADS_SURFACE_HEIGHT, MadsInterfaceView::MadsInterfaceView(MadsM4Engine *vm): InterfaceView(vm, Common::Rect(0, MADS_SURFACE_HEIGHT,
vm->_screen->width(), vm->_screen->height())) { vm->_screen->width(), vm->_screen->height())) {
_screenType = VIEWID_INTERFACE; _screenType = VIEWID_INTERFACE;
_highlightedElement = -1; _highlightedElement = -1;
@ -772,8 +816,8 @@ void MadsInterfaceView::initialise() {
// Build up the inventory list // Build up the inventory list
_inventoryList.clear(); _inventoryList.clear();
for (uint i = 0; i < _madsVm->_globals->getObjectsSize(); ++i) { for (uint i = 0; i < _madsVm->globals()->getObjectsSize(); ++i) {
MadsObject *obj = _madsVm->_globals->getObject(i); MadsObject *obj = _madsVm->globals()->getObject(i);
if (obj->roomNumber == PLAYER_INVENTORY) if (obj->roomNumber == PLAYER_INVENTORY)
_inventoryList.push_back(i); _inventoryList.push_back(i);
} }
@ -823,7 +867,7 @@ void MadsInterfaceView::setSelectedObject(int objectNumber) {
void MadsInterfaceView::addObjectToInventory(int objectNumber) { void MadsInterfaceView::addObjectToInventory(int objectNumber) {
if (_inventoryList.indexOf(objectNumber) == -1) { if (_inventoryList.indexOf(objectNumber) == -1) {
_madsVm->_globals->getObject(objectNumber)->roomNumber = PLAYER_INVENTORY; _madsVm->globals()->getObject(objectNumber)->roomNumber = PLAYER_INVENTORY;
_inventoryList.push_back(objectNumber); _inventoryList.push_back(objectNumber);
} }
@ -847,7 +891,7 @@ void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
((actionIndex == 0) ? ITEM_SELECTED : ITEM_NORMAL)); ((actionIndex == 0) ? ITEM_SELECTED : ITEM_NORMAL));
// Get the verb action and capitalise it // Get the verb action and capitalise it
const char *verbStr = _madsVm->_globals->getVocab(kVerbLook + actionIndex); const char *verbStr = _madsVm->globals()->getVocab(kVerbLook + actionIndex);
strcpy(buffer, verbStr); strcpy(buffer, verbStr);
if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A'; if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
@ -875,7 +919,7 @@ void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
if ((_topIndex + i) >= _inventoryList.size()) if ((_topIndex + i) >= _inventoryList.size())
break; break;
const char *descStr = _madsVm->_globals->getVocab(_madsVm->_globals->getObject( const char *descStr = _madsVm->globals()->getVocab(_madsVm->globals()->getObject(
_inventoryList[_topIndex + i])->descId); _inventoryList[_topIndex + i])->descId);
strcpy(buffer, descStr); strcpy(buffer, descStr);
if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A'; if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
@ -898,21 +942,21 @@ void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
M4Sprite *spr = _objectSprites->getFrame(_objectFrameNumber / INV_ANIM_FRAME_SPEED); M4Sprite *spr = _objectSprites->getFrame(_objectFrameNumber / INV_ANIM_FRAME_SPEED);
spr->copyTo(destSurface, INVENTORY_X, INVENTORY_Y, 0); spr->copyTo(destSurface, INVENTORY_X, INVENTORY_Y, 0);
if (!_madsVm->_globals->invObjectsStill && !dialogVisible) { if (!_madsVm->globals()->invObjectsStill && !dialogVisible) {
// If objetcs are to animated, move to the next frame // If objetcs are to animated, move to the next frame
if (++_objectFrameNumber >= (_objectSprites->getCount() * INV_ANIM_FRAME_SPEED)) if (++_objectFrameNumber >= (_objectSprites->getCount() * INV_ANIM_FRAME_SPEED))
_objectFrameNumber = 0; _objectFrameNumber = 0;
} }
// List the vocab actions for the currently selected object // List the vocab actions for the currently selected object
MadsObject *obj = _madsVm->_globals->getObject(_selectedObject); MadsObject *obj = _madsVm->globals()->getObject(_selectedObject);
int yIndex = MIN(_highlightedElement - VOCAB_START, obj->vocabCount - 1); int yIndex = MIN(_highlightedElement - VOCAB_START, obj->vocabCount - 1);
for (int i = 0; i < obj->vocabCount; ++i) { for (int i = 0; i < obj->vocabCount; ++i) {
const Common::Rect r(_screenObjects[VOCAB_START + i]); const Common::Rect r(_screenObjects[VOCAB_START + i]);
// Get the vocab description and capitalise it // Get the vocab description and capitalise it
const char *descStr = _madsVm->_globals->getVocab(obj->vocabList[i].vocabId); const char *descStr = _madsVm->globals()->getVocab(obj->vocabList[i].vocabId);
strcpy(buffer, descStr); strcpy(buffer, descStr);
if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A'; if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
@ -958,7 +1002,7 @@ bool MadsInterfaceView::onEvent(M4EventType eventType, int32 param1, int x, int
_vm->_scene->setAction(kVerbLook + (_highlightedElement - ACTIONS_START)); _vm->_scene->setAction(kVerbLook + (_highlightedElement - ACTIONS_START));
} else if ((_highlightedElement >= VOCAB_START) && (_highlightedElement < (VOCAB_START + 5))) { } else if ((_highlightedElement >= VOCAB_START) && (_highlightedElement < (VOCAB_START + 5))) {
// A vocab action was selected // A vocab action was selected
MadsObject *obj = _madsVm->_globals->getObject(_selectedObject); MadsObject *obj = _madsVm->globals()->getObject(_selectedObject);
int vocabIndex = MIN(_highlightedElement - VOCAB_START, obj->vocabCount - 1); int vocabIndex = MIN(_highlightedElement - VOCAB_START, obj->vocabCount - 1);
if (vocabIndex >= 0) if (vocabIndex >= 0)
_vm->_scene->setAction(obj->vocabList[vocabIndex].vocabId, _selectedObject); _vm->_scene->setAction(obj->vocabList[vocabIndex].vocabId, _selectedObject);
@ -1050,5 +1094,4 @@ bool MadsInterfaceView::handleKeypress(int32 keycode) {
return false; return false;
} }
} // End of namespace M4 } // End of namespace M4

View file

@ -75,57 +75,96 @@ struct SceneResources {
int32 railNodeCount; // # of rails int32 railNodeCount; // # of rails
}; };
class MadsInterfaceView; class M4Engine;
class MadsEngine;
class InterfaceView;
class Scene: public View { class Scene: public View {
public:
Scene(MadsM4Engine *vm);
~Scene();
// TODO: perhaps move playIntro() someplace else?
void playIntro();
void show();
void loadScene(int sceneNumber);
void loadSceneResources(int sceneNumber);
void loadSceneHotSpotsMads(int sceneNumber);
void loadSceneCodes(int sceneNumber, int index = 0);
void loadSceneInverseColorTable(int sceneNumber);
void loadSceneSprites(int sceneNumber);
void loadSceneSpriteCodes(int sceneNumber);
void showSprites();
void checkHotspotAtMousePos(int x, int y);
void checkHotspotAtMousePosMads(int x, int y);
void showHotSpots();
void showCodes();
int getCurrentScene() { return _currentScene; }
SceneResources getSceneResources() { return _sceneResources; }
M4Surface *getBackgroundSurface() const { return _backgroundSurface; }
byte *getInverseColorTable() const { return _inverseColorTable; }
MadsInterfaceView *getMadsInterface() { return _madsInterfaceSurface; }
void setAction(int action, int objectId = -1);
void update();
void setMADSStatusText(const char *text) { strcpy(_statusText, text); }
void showMADSV2TextBox(char *text, int x, int y, char *faceName);
void onRefresh(RectList *rects, M4Surface *destSurface);
bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
private: private:
byte *_inverseColorTable;
HotSpotList _sceneHotspots;
char _statusText[100];
protected:
int _currentScene; int _currentScene;
InterfaceView *_interfaceSurface;
M4Surface *_backgroundSurface; M4Surface *_backgroundSurface;
M4Surface *_codeSurface; M4Surface *_codeSurface;
MadsInterfaceView *_madsInterfaceSurface;
byte *_inverseColorTable;
RGBList *_palData; RGBList *_palData;
RGBList *_interfacePal; RGBList *_interfacePal;
SceneResources _sceneResources; SceneResources _sceneResources;
HotSpotList _sceneHotspots; public:
Scene(MadsM4Engine *vm);
virtual ~Scene();
// Methods that differ between engines
virtual void loadScene(int sceneNumber);
virtual void loadSceneCodes(int sceneNumber, int index = 0) = 0;
virtual void show();
virtual void checkHotspotAtMousePos(int x, int y) = 0;
virtual void leftClick(int x, int y) = 0;
virtual void rightClick(int x, int y) = 0;
virtual void setAction(int action, int objectId = -1) = 0;
// TODO: perhaps move playIntro() someplace else?
void playIntro();
void loadSceneResources(int sceneNumber);
void loadSceneHotSpotsMads(int sceneNumber);
void loadSceneInverseColorTable(int sceneNumber);
void loadSceneSpriteCodes(int sceneNumber);
void showSprites();
void showHotSpots();
void showCodes();
int getCurrentScene() { return _currentScene; }
M4Surface *getBackgroundSurface() const { return _backgroundSurface; }
byte *getInverseColorTable() const { return _inverseColorTable; }
void update();
void setMADSStatusText(const char *text) { strcpy(_statusText, text); }
void showMADSV2TextBox(char *text, int x, int y, char *faceName);
InterfaceView *getInterface() { return _interfaceSurface; }
SceneResources getSceneResources() { return _sceneResources; }
void onRefresh(RectList *rects, M4Surface *destSurface);
bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
};
class M4Scene: public Scene {
private:
M4Engine *_vm;
SpriteAsset *_sceneSprites; SpriteAsset *_sceneSprites;
SpriteAsset *_walkerSprite; SpriteAsset *_walkerSprite;
int _currentAction;
char _statusText[100];
void loadSceneSprites(int sceneNumber);
void nextCommonCursor(); void nextCommonCursor();
public:
M4Scene(M4Engine *vm);
virtual ~M4Scene();
// Methods that differ between engines
virtual void loadScene(int sceneNumber);
virtual void loadSceneCodes(int sceneNumber, int index = 0);
virtual void checkHotspotAtMousePos(int x, int y);
virtual void leftClick(int x, int y);
virtual void rightClick(int x, int y);
virtual void setAction(int action, int objectId = -1);
};
class MadsScene: public Scene {
private:
MadsEngine *_vm;
int _currentAction;
public:
MadsScene(MadsEngine *vm);
virtual ~MadsScene() {};
// Methods that differ between engines
virtual void loadScene(int sceneNumber);
virtual void loadSceneCodes(int sceneNumber, int index = 0);
virtual void show();
virtual void checkHotspotAtMousePos(int x, int y);
virtual void leftClick(int x, int y);
virtual void rightClick(int x, int y);
virtual void setAction(int action, int objectId = -1);
}; };
enum InterfaceFontMode {ITEM_NORMAL, ITEM_HIGHLIGHTED, ITEM_SELECTED}; enum InterfaceFontMode {ITEM_NORMAL, ITEM_HIGHLIGHTED, ITEM_SELECTED};
@ -143,7 +182,17 @@ public:
} }
}; };
class MadsInterfaceView: public View { class InterfaceView: public View {
public:
InterfaceView(MadsM4Engine *vm, const Common::Rect &bounds): View(vm, bounds) {};
~InterfaceView() {};
virtual void initialise() {};
virtual void setSelectedObject(int objectNumber) {};
virtual void addObjectToInventory(int objectNumber) {};
};
class MadsInterfaceView: public InterfaceView {
private: private:
IntegerList _inventoryList; IntegerList _inventoryList;
RectList _screenObjects; RectList _screenObjects;
@ -165,9 +214,9 @@ public:
MadsInterfaceView(MadsM4Engine *vm); MadsInterfaceView(MadsM4Engine *vm);
~MadsInterfaceView(); ~MadsInterfaceView();
void initialise(); virtual void initialise();
void setSelectedObject(int objectNumber); virtual void setSelectedObject(int objectNumber);
void addObjectToInventory(int objectNumber); virtual void addObjectToInventory(int objectNumber);
void onRefresh(RectList *rects, M4Surface *destSurface); void onRefresh(RectList *rects, M4Surface *destSurface);
bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents); bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);