aboutsummaryrefslogtreecommitdiff
path: root/engines/m4
diff options
context:
space:
mode:
authorPaul Gilbert2010-02-27 05:30:53 +0000
committerPaul Gilbert2010-02-27 05:30:53 +0000
commit75a0022dff6dc861df04a517be88242bd9324f9a (patch)
tree9944bd9967425fe75cfbd1a5de5c0b4687a197a8 /engines/m4
parentf40c466d5e4996fd8ec604e0bd469cefa5c122e0 (diff)
downloadscummvm-rg350-75a0022dff6dc861df04a517be88242bd9324f9a.tar.gz
scummvm-rg350-75a0022dff6dc861df04a517be88242bd9324f9a.tar.bz2
scummvm-rg350-75a0022dff6dc861df04a517be88242bd9324f9a.zip
Beginnings of code for scene info loading
svn-id: r48143
Diffstat (limited to 'engines/m4')
-rw-r--r--engines/m4/globals.cpp6
-rw-r--r--engines/m4/globals.h1
-rw-r--r--engines/m4/resource.cpp28
-rw-r--r--engines/m4/resource.h3
-rw-r--r--engines/m4/scene.cpp164
-rw-r--r--engines/m4/scene.h51
6 files changed, 225 insertions, 28 deletions
diff --git a/engines/m4/globals.cpp b/engines/m4/globals.cpp
index 856c1bb817..1ce2f24658 100644
--- a/engines/m4/globals.cpp
+++ b/engines/m4/globals.cpp
@@ -511,6 +511,10 @@ bool Player::saidAny(const char *word1, const char *word2, const char *word3,
/*--------------------------------------------------------------------------*/
MadsObject::MadsObject(Common::SeekableReadStream *stream) {
+ load(stream);
+}
+
+void MadsObject::load(Common::SeekableReadStream *stream) {
// Get the next data block
uint8 obj[0x30];
stream->read(obj, 0x30);
@@ -519,7 +523,7 @@ MadsObject::MadsObject(Common::SeekableReadStream *stream) {
descId = READ_LE_UINT16(&obj[0]);
roomNumber = READ_LE_UINT16(&obj[2]);
article = (MADSArticles)obj[4];
- vocabCount = obj[5];
+ vocabCount = obj[5] & 0x7f;
assert(vocabCount <= 3);
for (int i = 0; i < vocabCount; ++i) {
diff --git a/engines/m4/globals.h b/engines/m4/globals.h
index aee0e6fa9c..6349376643 100644
--- a/engines/m4/globals.h
+++ b/engines/m4/globals.h
@@ -174,6 +174,7 @@ class MadsObject {
public:
MadsObject() {};
MadsObject(Common::SeekableReadStream *stream);
+ void load(Common::SeekableReadStream *stream);
bool isInInventory() const { return roomNumber == PLAYER_INVENTORY; };
uint16 descId;
diff --git a/engines/m4/resource.cpp b/engines/m4/resource.cpp
index a1c5290afa..eee1214e7f 100644
--- a/engines/m4/resource.cpp
+++ b/engines/m4/resource.cpp
@@ -369,6 +369,34 @@ const char *MADSResourceManager::getResourceName(char asciiCh, int prefix, Exten
}
/**
+ * Another variation for forming resource names
+ */
+const char *MADSResourceManager::getResourceName(ResourcePrefixType prefixType, int idx, const char *extension) {
+ static char resourceName[100];
+
+ strcpy(resourceName, "*");
+
+ if (extension) {
+ switch (prefixType) {
+ case RESPREFIX_GL:
+ strcat(resourceName, "GL000");
+ break;
+ case RESPREFIX_SC:
+ case RESPREFIX_RM:
+ strcat(resourceName, (prefixType == RESPREFIX_SC) ? "SC" : "RM");
+ sprintf(resourceName + 3, "%.3d", idx);
+ break;
+ default:
+ break;
+ }
+
+ strcat(resourceName, extension);
+ }
+
+ return &resourceName[0];
+}
+
+/**
* Forms an AA resource name based on the given passed index
*/
const char *MADSResourceManager::getAAName(int index) {
diff --git a/engines/m4/resource.h b/engines/m4/resource.h
index 2c6bacced6..b41b1b0799 100644
--- a/engines/m4/resource.h
+++ b/engines/m4/resource.h
@@ -115,6 +115,8 @@ enum ResourceType {RESTYPE_ROOM, RESTYPE_SC, RESTYPE_TEXT, RESTYPE_QUO, RESTYPE_
enum ExtensionType {EXTTYPE_SS = 1, EXTTYPE_AA = 2, EXTTYPE_DAT = 3, EXTTYPE_HH = 4, EXTTYPE_ART = 5,
EXTTYPE_INT = 6, EXTTYPE_NONE = -1};
+enum ResourcePrefixType {RESPREFIX_GL = 1, RESPREFIX_SC = 2, RESPREFIX_RM = 3};
+
class MADSResourceManager : public ResourceManager {
private:
ResourceType getResourceType(const char *resourceName);
@@ -126,6 +128,7 @@ public:
bool resourceExists(const char *resourceName);
static const char *getResourceName(char asciiCh, int prefix, ExtensionType extType, const char *suffix, int index);
+ static const char *getResourceName(ResourcePrefixType prefixType, int idx, const char *extension);
static const char *getAAName(int index);
};
diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp
index e70b4d4bd8..3729d17437 100644
--- a/engines/m4/scene.cpp
+++ b/engines/m4/scene.cpp
@@ -59,6 +59,7 @@ Scene::~Scene() {
}
void Scene::loadScene(int sceneNumber) {
+ _previousScene = _currentScene;
_currentScene = sceneNumber;
// Load scene background and set palette
@@ -596,29 +597,21 @@ MadsScene::MadsScene(MadsEngine *vm): Scene(vm) {
strcpy(_statusText, "");
_interfaceSurface = new MadsInterfaceView(vm);
_currentAction = kVerbNone;
+ _spriteSlotsStart = 0;
}
-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);
-
- // Signal the script engine what scene is to be active
- _sceneLogic.selectScene(sceneNumber);
- _sceneLogic.setupScene();
-
- // Add the scene if necessary to the list of scenes that have been visited
- _vm->globals()->addVisitedScene(sceneNumber);
-
+/**
+ * Secondary scene loading code
+ */
+void MadsScene::loadScene2(int sceneNumber, const char *aaName) {
- // Do any scene specific setup
- _sceneLogic.enterScene();
+ _sceneInfo.load(sceneNumber);
+}
+/**
+ * Existing ScummVM code that needs to be eventually replaced with MADS code
+ */
+void MadsScene::loadSceneTemporary() {
/* Existing code that eventually needs to be replaced with the proper MADS code */
// Set system palette entries
_vm->_palette->blockRange(0, 7);
@@ -626,11 +619,11 @@ void MadsScene::loadScene(int sceneNumber) {
{0x00<<2, 0x10<<2, 0x16<<2, 0}};
_vm->_palette->setPalette(&sysColors[0], 4, 3);
- _backgroundSurface->loadBackground(sceneNumber, &_palData);
+ _backgroundSurface->loadBackground(_currentScene, &_palData);
_vm->_palette->addRange(_palData);
_backgroundSurface->translate(_palData);
- if (sceneNumber < 900) {
+ if (_currentScene < 900) {
/*_backgroundSurface->fillRect(Common::Rect(0, MADS_SURFACE_HEIGHT,
_backgroundSurface->width(), _backgroundSurface->height()),
_vm->_palette->BLACK);*/
@@ -644,19 +637,46 @@ void MadsScene::loadScene(int sceneNumber) {
}
// Don't load other screen resources for system screens
- if (sceneNumber >= 900)
+ if (_currentScene >= 900)
return;
- loadSceneHotSpotsMads(sceneNumber);
+ loadSceneHotSpotsMads(_currentScene);
// TODO: set walker scaling
// TODO: destroy woodscript buffer
// Load scene walk path file (*.COD/*.WW?)
- loadSceneCodes(sceneNumber);
+ loadSceneCodes(_currentScene);
// Load inverse color table file (*.IPL)
- loadSceneInverseColorTable(sceneNumber);
+ loadSceneInverseColorTable(_currentScene);
+}
+
+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);
+
+ // Signal the script engine what scene is to be active
+ _sceneLogic.selectScene(sceneNumber);
+ _sceneLogic.setupScene();
+
+ // Add the scene if necessary to the list of scenes that have been visited
+ _vm->globals()->addVisitedScene(sceneNumber);
+
+ // Secondary scene load routine
+ loadScene2(sceneNumber, "*I0.AA");
+
+ // Do any scene specific setup
+ _sceneLogic.enterScene();
+
+ // Existing ScummVM code that needs to be eventually replaced with MADS code
+ loadSceneTemporary();
// Purge resources
_vm->res()->purge();
@@ -774,9 +794,71 @@ void MadsScene::setStatusText(const char *text) {
strcpy(_statusText, text);
}
+/**
+ * Draws all the elements of the scene
+ */
+void MadsScene::drawElements() {
+
+ // Display animations
+ for (int idx = 0; idx < _spriteSlotsStart; ++idx) {
+
+ }
+
+
+ // Text display loop
+ for (int idx = 0; idx < TEXT_DISPLAY_SIZE; ++idx) {
+ if (_textDisplay[idx].active && (_textDisplay[idx].field_A >= 0)) {
+ _textDisplay[idx].font->setColours(0xFF, (_textDisplay[idx].colour2 == 0) ?
+ _textDisplay[idx].colour1 : _textDisplay[idx].colour2, _textDisplay[idx].colour1);
+ _textDisplay[idx].font->writeString(this, _textDisplay[idx].message,
+ _textDisplay[idx].bounds.left, _textDisplay[idx].bounds.top,
+ width() - _textDisplay[idx].bounds.left, _textDisplay[idx].spacing);
+ }
+ }
+
+ // Copy the user interface surface onto the surface
+ _interfaceSurface->copyTo(this, 0, this->height() - _interfaceSurface->height());
+
+/*
+ // At this point, in the original engine, the dirty/changed areas were copied to the screen. At the moment,
+ // the current M4 engine framework doesn't support dirty areas, but this is being kept in case that ever changes
+ for (int idx = 0; idx < DIRTY_AREA_SIZE; ++idx) {
+ if (_dirtyAreas[idx].active && _dirtyAreas[idx].active2 &&
+ (_dirtyAreas[idx].bounds.width() > 0) && (_dirtyAreas[idx].bounds.height() > 0)) {
+ // Copy changed area to screen
+
+ }
+ }
+*/
+
+ // Some kind of copying over of slot entries
+ for (int idx = 0, idx2 = 0; idx < _spriteSlotsStart; ++idx) {
+ if (_spriteSlots[idx].spriteId >= 0) {
+ if (idx != idx2) {
+ // Copy over the slot entry
+ _spriteSlots[idx2] = _spriteSlots[idx];
+ }
+ ++idx2;
+ }
+ }
+
+ // Clear up any now inactive text display entries
+ for (int idx = 0; idx < TEXT_DISPLAY_SIZE; ++idx) {
+ if (_textDisplay[idx].field_A < 0) {
+ _textDisplay[idx].active = false;
+ _textDisplay[idx].field_A = 0;
+ }
+ }
+}
+
+
void MadsScene::update() {
+ // Copy the bare scene in
_backgroundSurface->copyTo(this);
+ // Draw all the various elements
+ drawElements();
+
// Handle display of any status text
if (_statusText[0]) {
// Text colors are inverted in Dragonsphere
@@ -789,8 +871,6 @@ void MadsScene::update() {
_vm->_font->writeString(this, _statusText, (width() - _vm->_font->getWidth(_statusText)) / 2, 142, 0);
}
- _interfaceSurface->copyTo(this, 0, this->height() - _interfaceSurface->height());
-
//***DEBUG***
_sceneSprites[0]->getFrame(1)->copyTo(this, 120, 90, 0);
}
@@ -833,4 +913,34 @@ void MadsScene::loadPlayerSprites(const char *prefix) {
error("Couldn't find player sprites");
}
+/*--------------------------------------------------------------------------*/
+
+void MadsSceneInfo::load(int sceneId) {
+ const char *sceneInfoStr = MADSResourceManager::getResourceName(RESPREFIX_RM, sceneId, ".DAT");
+ Common::SeekableReadStream *rawStream = _vm->_resourceManager->get(sceneInfoStr);
+ MadsPack sceneInfo(rawStream);
+ Common::SeekableReadStream *stream = sceneInfo.getItemStream(0);
+
+ int resSceneId = stream->readUint16LE();
+ assert(resSceneId == sceneId);
+
+ artFileNum = stream->readUint16LE();
+ field_4 = stream->readUint16LE();
+ width = stream->readUint16LE();
+ height = stream->readUint16LE();
+ assert((width == 320) && (height == 156));
+
+ stream->skip(24);
+
+ objectCount = stream->readUint16LE();
+
+ stream->skip(40);
+
+ for (int i = 0; i < objectCount; ++i) {
+ objects[i].load(stream);
+ }
+
+ _vm->_resourceManager->toss(sceneInfoStr);
+}
+
} // End of namespace M4
diff --git a/engines/m4/scene.h b/engines/m4/scene.h
index a0a07bce6a..f94ecc0574 100644
--- a/engines/m4/scene.h
+++ b/engines/m4/scene.h
@@ -29,6 +29,7 @@
class View;
#include "m4/assets.h"
+#include "m4/font.h"
#include "m4/hotspot.h"
#include "m4/graphics.h"
#include "m4/viewmgr.h"
@@ -90,6 +91,7 @@ private:
HotSpotList _sceneHotspots;
protected:
int _currentScene;
+ int _previousScene;
GameInterfaceView *_interfaceSurface;
M4Surface *_backgroundSurface;
M4Surface *_codeSurface;
@@ -161,8 +163,48 @@ public:
M4InterfaceView *getInterface() { return (M4InterfaceView *)_interfaceSurface; };
};
+struct SpriteSlot {
+ int16 spriteId;
+ int16 scale;
+ uint16 spriteListIndex;
+};
+
+struct TextDisplay {
+ bool active;
+ int spacing;
+ Common::Rect bounds;
+ int16 field_A;
+ uint8 colour1, colour2;
+ Font *font;
+ char message[100];
+};
+
+struct DirtyArea {
+ bool active;
+ bool active2;
+ Common::Rect bounds;
+};
+
+class MadsSceneInfo {
+public:
+ int sceneId;
+ int artFileNum;
+ int field_4;
+ int width;
+ int height;
+
+ int objectCount;
+ MadsObject objects[32];
+
+ void load(int sceneId);
+};
+
typedef Common::Array<SpriteAsset *> SpriteAssetArray;
+#define SPRITE_SLOTS_SIZE 50
+#define TEXT_DISPLAY_SIZE 40
+#define DIRTY_AREA_SIZE 90
+
class MadsScene : public Scene {
private:
MadsEngine *_vm;
@@ -170,8 +212,17 @@ private:
int _currentAction;
char _statusText[100];
MadsSceneLogic _sceneLogic;
+ MadsSceneInfo _sceneInfo;
SpriteAsset *_playerSprites;
SpriteAssetArray _sceneSprites;
+ SpriteSlot _spriteSlots[50];
+ TextDisplay _textDisplay[TEXT_DISPLAY_SIZE];
+ DirtyArea _dirtyAreas[DIRTY_AREA_SIZE];
+ int _spriteSlotsStart;
+
+ void drawElements();
+ void loadScene2(int sceneNumber, const char *aaName);
+ void loadSceneTemporary();
public:
char _aaName[100];
public: