aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/m4/mads_logic.cpp95
-rw-r--r--engines/m4/mads_logic.h7
-rw-r--r--engines/m4/mads_scene.cpp151
-rw-r--r--engines/m4/mads_scene.h87
-rw-r--r--engines/m4/mads_views.cpp4
-rw-r--r--engines/m4/mads_views.h4
-rw-r--r--engines/m4/scene.cpp2
-rw-r--r--engines/m4/scene.h3
8 files changed, 237 insertions, 116 deletions
diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp
index e69e8c38ca..472db1a2b0 100644
--- a/engines/m4/mads_logic.cpp
+++ b/engines/m4/mads_logic.cpp
@@ -77,6 +77,74 @@ uint16 MadsSceneLogic::loadSpriteSet(uint16 suffixNum, uint16 sepChar) {
return _madsVm->scene()->loadSceneSpriteSet(resName);
}
+uint16 MadsSceneLogic::startSpriteSequence(uint16 srcSpriteIdx, int v0, int numTicks, int fld24, int timeoutTicks, int extraTicks) {
+ M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(1);
+ uint8 pixel = *_madsVm->scene()->getWalkSurface()->getBasePtr(spriteFrame->x + (spriteFrame->width() / 2),
+ spriteFrame->y + (spriteFrame->height() / 2));
+
+ return _madsVm->scene()->_timerList.add(srcSpriteIdx, v0, 1, fld24, timeoutTicks, extraTicks, numTicks, 0, 0,
+ -1, 100, (int)pixel - 1, 1, 1, 0, 0);
+}
+
+uint16 MadsSceneLogic::startSpriteSequence2(uint16 srcSpriteIdx, int v0, int numTicks, int fld24, int timeoutTicks, int extraTicks) {
+ M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(1);
+ uint8 pixel = *_madsVm->scene()->getWalkSurface()->getBasePtr(spriteFrame->x + (spriteFrame->width() / 2),
+ spriteFrame->y + (spriteFrame->height() / 2));
+
+ return _madsVm->scene()->_timerList.add(srcSpriteIdx, v0, 1, fld24, timeoutTicks, extraTicks, numTicks, 0, 0,
+ -1, 100, (int)pixel - 1, 1, 2, 0, 0);
+}
+
+uint16 MadsSceneLogic::startSpriteSequence3(uint16 srcSpriteIdx, int v0, int numTicks, int fld24, int timeoutTicks, int extraTicks) {
+ M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(1);
+ uint8 pixel = *_madsVm->scene()->getWalkSurface()->getBasePtr(spriteFrame->x + (spriteFrame->width() / 2),
+ spriteFrame->y + (spriteFrame->height() / 2));
+
+ return _madsVm->scene()->_timerList.add(srcSpriteIdx, v0, 1, fld24, timeoutTicks, extraTicks, numTicks, 0, 0,
+ -1, 100, (int)pixel - 1, -1, 1, 0, 0);
+}
+
+void MadsSceneLogic::activateHotspot(int idx, bool active) {
+ // TODO:
+}
+
+void MadsSceneLogic::lowRoomsEntrySound() {
+ if (!_madsVm->globals()->_config.musicFlag) {
+ _madsVm->_sound->playSound(2);
+ } else {
+ // Play different sounds for each of the rooms
+ switch (_madsVm->globals()->sceneNumber) {
+ case 101:
+ _madsVm->_sound->playSound(11);
+ break;
+ case 102:
+ _madsVm->_sound->playSound(12);
+ break;
+ case 103:
+ _madsVm->_sound->playSound(3);
+ _madsVm->_sound->playSound(25);
+ break;
+ case 104:
+ _madsVm->_sound->playSound(10);
+ break;
+ case 105:
+ if ((_madsVm->globals()->previousScene < 104) || (_madsVm->globals()->previousScene > 108))
+ _madsVm->_sound->playSound(10);
+ break;
+ case 106:
+ _madsVm->_sound->playSound(13);
+ break;
+ case 107:
+ _madsVm->_sound->playSound(3);
+ break;
+ case 108:
+ _madsVm->_sound->playSound(15);
+ break;
+ default:
+ break;
+ }
+ }
+}
/*--------------------------------------------------------------------------*/
@@ -114,6 +182,33 @@ void MadsSceneLogic::enterScene() {
_spriteIndexes[11] = loadSpriteSet(1, 'a');
_spriteIndexes[12] = loadSpriteSet(8, 'x');
_spriteIndexes[13] = loadSpriteSet(0, 'x');
+
+ _spriteIndexes[15] = startSpriteSequence(_spriteIndexes[0], 0, 5, 0, 0, 25);
+ _spriteIndexes[16] = startSpriteSequence(_spriteIndexes[1], 0, 4, 0, 1, 0);
+ _spriteIndexes[17] = startSpriteSequence(_spriteIndexes[2], 0, 4, 0, 1, 0);
+
+ _madsVm->scene()->_timerList.unk2(0, 2, 7, 0x46);
+
+ _spriteIndexes[18] = startSpriteSequence2(_spriteIndexes[3], 0, 10, 0, 0, 60);
+ _spriteIndexes[19] = startSpriteSequence(_spriteIndexes[4], 0, 5, 0, 1, 0);
+ _spriteIndexes[20] = startSpriteSequence(_spriteIndexes[5], 0, 10, 0, 2, 0);
+ _spriteIndexes[21] = startSpriteSequence(_spriteIndexes[6], 0, 6, 0, 0, 0);
+
+ _spriteIndexes[23] = startSpriteSequence(_spriteIndexes[8], 0, 6, 0, 10, 4);
+ _spriteIndexes[24] = startSpriteSequence(_spriteIndexes[9], 0, 6, 0, 32, 47);
+
+ activateHotspot(0x137, false); // SHIELD MODULATOR
+ // shield_panel_opened = 0;
+
+ if (_madsVm->globals()->previousScene != -1)
+ _madsVm->globals()->_globals[10] = 0;
+ if (_madsVm->globals()->previousScene != -2) {
+ //playerPos = (100, 152);
+ }
+
+ // TODO: EXTRA STUFF
+
+ lowRoomsEntrySound();
}
void MadsSceneLogic::doAction() {
diff --git a/engines/m4/mads_logic.h b/engines/m4/mads_logic.h
index 2514f4e3f4..88f8c6e928 100644
--- a/engines/m4/mads_logic.h
+++ b/engines/m4/mads_logic.h
@@ -35,9 +35,14 @@ class MadsSceneLogic {
private:
// Library interface methods
uint16 loadSpriteSet(uint16 suffixNum, uint16 sepChar);
+ uint16 startSpriteSequence(uint16 srcSpriteIdx, int v0, int numTicks, int fld24, int timeoutTicks, int extraTicks);
+ uint16 startSpriteSequence2(uint16 srcSpriteIdx, int v0, int numTicks, int fld24, int timeoutTicks, int extraTicks);
+ uint16 startSpriteSequence3(uint16 srcSpriteIdx, int v0, int numTicks, int fld24, int timeoutTicks, int extraTicks);
+ void activateHotspot(int idx, bool active);
+ void lowRoomsEntrySound();
private:
int _sceneNumber;
- uint16 _spriteIndexes[50];
+ int16 _spriteIndexes[50];
// Support functions
const char *formAnimName(char sepChar, int16 suffixNum);
diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp
index 53f232472d..26acafa521 100644
--- a/engines/m4/mads_scene.cpp
+++ b/engines/m4/mads_scene.cpp
@@ -44,7 +44,6 @@ MadsScene::MadsScene(MadsEngine *vm): _sceneResources(), Scene(vm, &_sceneResour
_vm = vm;
_interfaceSurface = new MadsInterfaceView(vm);
- _spriteSlotsStart = 0;
for (int i = 0; i < 3; ++i)
actionNouns[i] = 0;
}
@@ -158,11 +157,6 @@ void MadsScene::leaveScene() {
delete _sceneResources.hotspots;
delete _sceneResources.props;
-
- // Delete the sprites
- for (uint i = 0; i <_sceneSprites.size(); ++i) delete _sceneSprites[i];
- _sceneSprites.clear();
-
delete _walkSurface;
Scene::leaveScene();
@@ -269,12 +263,8 @@ void MadsScene::setAction(int action, int objectId) {
* Draws all the elements of the scene
*/
void MadsScene::drawElements() {
-
// Display animations
- for (int idx = 0; idx < _spriteSlotsStart; ++idx) {
-
- }
-
+ _spriteSlots.draw(this);
// Text display
_textDisplay.draw(this);
@@ -283,17 +273,6 @@ void MadsScene::drawElements() {
_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) {
@@ -303,7 +282,7 @@ void MadsScene::drawElements() {
}
++idx2;
}
- }
+ }*/
}
@@ -330,7 +309,7 @@ void MadsScene::update() {
}
//***DEBUG***
- _sceneSprites[0]->getFrame(1)->copyTo(this, 120, 90, 0);
+ _spriteSlots.getSprite(0).getFrame(1)->copyTo(this, 120, 90, 0);
}
int MadsScene::loadSceneSpriteSet(const char *setName) {
@@ -341,13 +320,7 @@ int MadsScene::loadSceneSpriteSet(const char *setName) {
if (!strchr(resName, '.'))
strcat(resName, ".SS");
- Common::SeekableReadStream *data = _vm->res()->get(resName);
- SpriteAsset *spriteSet = new SpriteAsset(_vm, data, data->size(), resName);
- spriteSet->translate(_vm->_palette);
- _vm->res()->toss(resName);
-
- _sceneSprites.push_back(spriteSet);
- return _sceneSprites.size() - 1;
+ return _spriteSlots.addSprites(resName);
}
void MadsScene::loadPlayerSprites(const char *prefix) {
@@ -646,6 +619,79 @@ void MadsAction::set() {
/*--------------------------------------------------------------------------*/
+MadsTimerList::MadsTimerList() {
+ for (int i = 0; i < TIMER_LIST_SIZE; ++i) {
+ MadsTimerEntry rec;
+ rec.active = 0;
+ rec.walkObjectIndex = -1;
+ _entries.push_back(rec);
+ }
+}
+
+bool MadsTimerList::unk2(int index, int v1, int v2, int v3) {
+ if (_entries[index].len27 >= TIMER_ENTRY_SUBSET_MAX)
+ return true;
+
+ int subIndex = _entries[index].len27++;
+ _entries[index].fld27[subIndex] = v1;
+ _entries[index].fld2C[subIndex] = v2;
+ _entries[index].field36 = v3;
+
+ return false;
+}
+
+int MadsTimerList::add(int spriteListIndex, int v0, int frameIndex, char field_24, int timeoutTicks, int extraTicks, int numTicks,
+ int height, int width, char field_12, char scale, char depth, int field_C, int field_A, int numSprites,
+ int spriteNum) {
+
+ // Find a free slot
+ uint timerIndex = 0;
+ while ((timerIndex < _entries.size()) && (_entries[timerIndex].active))
+ ++timerIndex;
+ if (timerIndex == _entries.size())
+ error("TimerList full");
+
+ if (spriteNum <= 0)
+ spriteNum = 1;
+ if (numSprites == 0)
+ numSprites = _madsVm->scene()->_spriteSlots.getSprite(spriteListIndex).getCount();
+ if (spriteNum == numSprites)
+ field_C = 0;
+
+ // Set the list entry fields
+ _entries[timerIndex].active = true;
+ _entries[timerIndex].spriteListIndex = spriteListIndex;
+ _entries[timerIndex].field_2 = v0;
+ _entries[timerIndex].frameIndex = frameIndex;
+ _entries[timerIndex].spriteNum = spriteNum;
+ _entries[timerIndex].numSprites = numSprites;
+ _entries[timerIndex].field_A = field_A;
+ _entries[timerIndex].field_C = field_C;
+ _entries[timerIndex].depth = depth;
+ _entries[timerIndex].scale = scale;
+ _entries[timerIndex].field_12 = field_12;
+ _entries[timerIndex].width = width;
+ _entries[timerIndex].height = height;
+ _entries[timerIndex].numTicks = numTicks;
+ _entries[timerIndex].extraTicks = extraTicks;
+
+ _entries[timerIndex].timeout = g_system->getMillis() + timeoutTicks * GAME_FRAME_DELAY;
+
+ _entries[timerIndex].field_24 = field_24;
+ _entries[timerIndex].field_25 = 0;
+ _entries[timerIndex].field_13 = 0;
+ _entries[timerIndex].walkObjectIndex = -1;
+ _entries[timerIndex].len27 = 0;
+ _entries[timerIndex].field_3B = 0; //word_84206
+
+ for (int i = 0; i < 3; ++i)
+ _entries[timerIndex].actionNouns[i] = _madsVm->scene()->actionNouns[i];
+
+ return timerIndex;
+}
+
+/*--------------------------------------------------------------------------*/
+
void MadsSceneResources::load(int sId) {
const char *sceneInfoStr = MADSResourceManager::getResourceName(RESPREFIX_RM, sId, ".DAT");
Common::SeekableReadStream *rawStream = _vm->_resourceManager->get(sceneInfoStr);
@@ -687,45 +733,10 @@ void MadsSceneResources::load(int sId) {
/*--------------------------------------------------------------------------*/
-MadsScreenText::MadsScreenText() {
- for (int i = 0; i < OLD_TEXT_DISPLAY_SIZE; ++i)
- _textDisplay[i].active = false;
- for (int i = 0; i < TIMED_TEXT_SIZE; ++i)
- _timedText[i].flags = 0;
- _abortTimedText = false;
-}
-
-/**
- * Adds the specified string to the list of on-screen display text
- */
-int MadsScreenText::add(const Common::Point &destPos, uint fontColours, int widthAdjust, const char *msg, Font *font) {
- // Find a free slot
- int idx = 0;
- while ((idx < OLD_TEXT_DISPLAY_SIZE) && _textDisplay[idx].active)
- ++idx;
- if (idx == OLD_TEXT_DISPLAY_SIZE)
- error("Ran out of text display slots");
-
- // Set up the entry values
- _textDisplay[idx].active = true;
- _textDisplay[idx].active2 = 1;
- _textDisplay[idx].bounds.left = destPos.x;
- _textDisplay[idx].bounds.top = destPos.y;
- _textDisplay[idx].bounds.setWidth(font->getWidth(msg, widthAdjust));
- _textDisplay[idx].bounds.setHeight(font->getHeight());
- _textDisplay[idx].font = font;
- strncpy(_textDisplay[idx].message, msg, 100);
- _textDisplay[idx].message[99] = '\0';
- _textDisplay[idx].colour1 = fontColours & 0xff;
- _textDisplay[idx].colour2 = fontColours >> 8;
- _textDisplay[idx].spacing = widthAdjust;
-
- return idx;
-}
-
/**
* Adds a new entry to the timed on-screen text display list
*/
+/*
int MadsScreenText::addTimed(const Common::Point &destPos, uint fontColours, uint flags, int vUnknown, uint32 timeout, const char *message) {
// Find a free slot
int idx = 0;
@@ -749,7 +760,7 @@ int MadsScreenText::addTimed(const Common::Point &destPos, uint fontColours, uin
_timedText[idx].timeout = timeout;
_timedText[idx].frameTimer = g_system->getMillis();
_timedText[idx].field_1C = vUnknown;
- _timedText[idx].field_1D = 0; /* word_84206 */
+ _timedText[idx].field_1D = 0; // word_84206
// Copy the current action noun list
for (int i = 0; i < 3; ++i)
@@ -762,9 +773,6 @@ int MadsScreenText::addTimed(const Common::Point &destPos, uint fontColours, uin
return idx;
}
-/**
- * Draws any text display entries to the screen
- */
void MadsScreenText::draw(M4Surface *surface) {
}
@@ -811,5 +819,6 @@ void MadsScreenText::addTimedText(TimedText *entry) {
// TODO: code from 'loc_244ec' onwards
}
+*/
} // End of namespace M4
diff --git a/engines/m4/mads_scene.h b/engines/m4/mads_scene.h
index 317b5fb93c..06f039d4e2 100644
--- a/engines/m4/mads_scene.h
+++ b/engines/m4/mads_scene.h
@@ -65,29 +65,18 @@ public:
};
#define TIMED_TEXT_SIZE 10
-#define OLD_TEXT_DISPLAY_SIZE 40
#define TEXT_4A_SIZE 30
enum TalkTextFlags {TEXTFLAG_2 = 2, TEXTFLAG_4 = 4, TEXTFLAG_8 = 8, TEXTFLAG_40 = 0x40,
TEXTFLAG_ACTIVE = 0x80};
-struct TextDisplay {
- bool active;
- int spacing;
- int16 active2;
- Common::Rect bounds;
- int colour1, colour2;
- Font *font;
- char message[100];
-};
-
struct TimedText {
uint8 flags;
int colour1;
int colour2;
Common::Point position;
int textDisplayIndex;
- int unk4AIndex;
+ int timerIndex;
uint32 timeout;
uint32 frameTimer;
bool field_1C;
@@ -96,30 +85,58 @@ struct TimedText {
char message[100];
};
-struct Text4A {
- uint8 active;
- uint8 field25;
+#define TIMER_ENTRY_SUBSET_MAX 5
+
+struct MadsTimerEntry {
+ int8 active;
+ int8 spriteListIndex;
+
+ int field_2;
+
+ int frameIndex;
+ int spriteNum;
+ int numSprites;
+
+ int field_A;
+ int field_C;
+
+ int depth;
+ int scale;
+ int walkObjectIndex;
+
+ int field_12;
+ int field_13;
+
+ int width;
+ int height;
+
+ int field_24;
+ int field_25;
+ int len27;
+ int8 fld27[TIMER_ENTRY_SUBSET_MAX];
+ int16 fld2C[TIMER_ENTRY_SUBSET_MAX];
+ int8 field36;
+ int field_3B;
+
+ uint16 actionNouns[3];
+ int numTicks;
+ int extraTicks;
+ int32 timeout;
};
-class MadsScreenText {
-private:
- TextDisplay _textDisplay[OLD_TEXT_DISPLAY_SIZE];
- TimedText _timedText[TIMED_TEXT_SIZE];
- Text4A _text4A[TEXT_4A_SIZE];
- bool _abortTimedText;
+#define TIMER_LIST_SIZE 30
- void addTimedText(TimedText *entry);
+class MadsTimerList {
+private:
+ Common::Array<MadsTimerEntry> _entries;
public:
- MadsScreenText();
+ MadsTimerList();
- // TextDisplay list
- int add(const Common::Point &destPos, uint fontColours, int widthAdjust, const char *msg, Font *font);
- void setActive2(int16 idx) { _textDisplay[idx].active2 = -1; }
- // TimedText list
- int addTimed(const Common::Point &destPos, uint fontColours, uint flags, int vUnknown, uint32 timeout, const char *message);
-
- void draw(M4Surface *surface);
- void timedDisplay();
+ MadsTimerEntry &operator[](int index) { return _entries[index]; }
+ bool unk2(int index, int v1, int v2, int v3);
+ int add(int spriteListIndex, int v0, int v1, char field_24, int timeoutTicks, int extraTicks, int numTicks,
+ int height, int width, char field_12, char scale, char depth, int field_C, int field_A,
+ int numSprites, int spriteNum);
};
enum MadsActionMode {ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, ACTMODE_TALK = 6};
@@ -157,9 +174,6 @@ public:
const char *statusText() const { return _statusText; }
};
-typedef Common::Array<SpriteAsset *> SpriteAssetArray;
-
-#define SPRITE_SLOTS_SIZE 50
#define DIRTY_AREA_SIZE 90
class MadsScene : public Scene {
@@ -170,11 +184,7 @@ private:
MadsSceneLogic _sceneLogic;
SpriteAsset *_playerSprites;
- SpriteAssetArray _sceneSprites;
- SpriteSlot _spriteSlots[50];
- MadsScreenText _textDisplay;
DirtyArea _dirtyAreas[DIRTY_AREA_SIZE];
- int _spriteSlotsStart;
void drawElements();
void loadScene2(const char *aaName);
@@ -186,6 +196,7 @@ private:
public:
char _aaName[100];
uint16 actionNouns[3];
+ MadsTimerList _timerList;
public:
MadsScene(MadsEngine *vm);
virtual ~MadsScene();
diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp
index e8a5aa6f4f..fdfbf16f9e 100644
--- a/engines/m4/mads_views.cpp
+++ b/engines/m4/mads_views.cpp
@@ -47,7 +47,7 @@ int MadsSpriteSlots::getIndex() {
return startIndex++;
}
-void MadsSpriteSlots::addSprites(const char *resName) {
+int MadsSpriteSlots::addSprites(const char *resName) {
// Get the sprite set
Common::SeekableReadStream *data = _vm->res()->get(resName);
SpriteAsset *spriteSet = new SpriteAsset(_vm, data, data->size(), resName);
@@ -56,7 +56,7 @@ void MadsSpriteSlots::addSprites(const char *resName) {
_sprites.push_back(SpriteList::value_type(spriteSet));
_vm->res()->toss(resName);
- // Translate the sprite set to the current palette
+ return _sprites.size() - 1;
}
class DepthEntry {
diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h
index 7dd991ffd6..bb151d7078 100644
--- a/engines/m4/mads_views.h
+++ b/engines/m4/mads_views.h
@@ -76,7 +76,7 @@ public:
}
int getIndex();
- void addSprites(const char *resName);
+ int addSprites(const char *resName);
void clear() {
startIndex = 0;
_sprites.clear();
@@ -155,7 +155,7 @@ public:
class MadsView: public View {
-protected:
+public:
MadsSpriteSlots _spriteSlots;
MadsTextDisplay _textDisplay;
ScreenObjects _screenObjects;
diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp
index 15c68f276c..72e24767a9 100644
--- a/engines/m4/scene.cpp
+++ b/engines/m4/scene.cpp
@@ -39,7 +39,7 @@
namespace M4 {
-Scene::Scene(MadsM4Engine *vm, SceneResources *res): View(vm, Common::Rect(0, 0, vm->_screen->width(),
+Scene::Scene(MadsM4Engine *vm, SceneResources *res): MadsView(vm, Common::Rect(0, 0, vm->_screen->width(),
vm->_screen->height())), _sceneResources(res) {
_screenType = VIEWID_SCENE;
diff --git a/engines/m4/scene.h b/engines/m4/scene.h
index 5dafb138db..e0a72fe848 100644
--- a/engines/m4/scene.h
+++ b/engines/m4/scene.h
@@ -76,7 +76,7 @@ class M4Engine;
class MadsEngine;
class InterfaceView;
-class Scene : public View {
+class Scene : public MadsView {
private:
HotSpotList _sceneHotspots;
protected:
@@ -113,6 +113,7 @@ public:
void hideInterface();
GameInterfaceView *getInterface() { return _interfaceSurface; }
SceneResources &getSceneResources() { return *_sceneResources; }
+ M4Surface *getWalkSurface() const { return _walkSurface; }
void onRefresh(RectList *rects, M4Surface *destSurface);
bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);