aboutsummaryrefslogtreecommitdiff
path: root/engines/m4
diff options
context:
space:
mode:
authorPaul Gilbert2010-04-27 11:23:27 +0000
committerPaul Gilbert2010-04-27 11:23:27 +0000
commit46c520f7972cac192b018896a039264a47984526 (patch)
tree514b98d44c6297ebf1b717cdc43aebd3c0f92f2b /engines/m4
parent03b229dcbaa184341dffbf7ed3f6cf5921647055 (diff)
downloadscummvm-rg350-46c520f7972cac192b018896a039264a47984526.tar.gz
scummvm-rg350-46c520f7972cac192b018896a039264a47984526.tar.bz2
scummvm-rg350-46c520f7972cac192b018896a039264a47984526.zip
Added further timer method implementation. Also renamed some of the classes to match those of the original engine, based on the contents of various in-game error messages
svn-id: r48816
Diffstat (limited to 'engines/m4')
-rw-r--r--engines/m4/m4.cpp4
-rw-r--r--engines/m4/m4.h1
-rw-r--r--engines/m4/mads_logic.cpp8
-rw-r--r--engines/m4/mads_scene.cpp4
-rw-r--r--engines/m4/mads_scene.h2
-rw-r--r--engines/m4/mads_views.cpp152
-rw-r--r--engines/m4/mads_views.h30
7 files changed, 152 insertions, 49 deletions
diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp
index 01c51a5e19..0e6dd48e17 100644
--- a/engines/m4/m4.cpp
+++ b/engines/m4/m4.cpp
@@ -493,6 +493,7 @@ MadsEngine::MadsEngine(OSystem *syst, const M4GameDescription *gameDesc): MadsM4
_madsVm = this;
_globals = new MadsGlobals(this);
+ _currentTimer = 0;
}
MadsEngine::~MadsEngine() {
@@ -582,7 +583,8 @@ Common::Error MadsEngine::run() {
if (g_system->getMillis() >= nextFrame) {
_viewManager->refreshAll();
- nextFrame = g_system->getMillis();// + GAME_FRAME_DELAY;
+ nextFrame = g_system->getMillis() + GAME_FRAME_DELAY;
+ ++_currentTimer;
}
g_system->delayMillis(10);
diff --git a/engines/m4/m4.h b/engines/m4/m4.h
index 618e942ba5..f732bdd559 100644
--- a/engines/m4/m4.h
+++ b/engines/m4/m4.h
@@ -210,6 +210,7 @@ private:
void showDialog();
public:
MadsConversation _converse;
+ uint32 _currentTimer;
public:
MadsEngine(OSystem *syst, const M4GameDescription *gameDesc);
virtual ~MadsEngine();
diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp
index 472db1a2b0..a0f7272533 100644
--- a/engines/m4/mads_logic.cpp
+++ b/engines/m4/mads_logic.cpp
@@ -82,7 +82,7 @@ uint16 MadsSceneLogic::startSpriteSequence(uint16 srcSpriteIdx, int v0, int numT
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,
+ return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, v0, 1, fld24, timeoutTicks, extraTicks, numTicks, 0, 0,
-1, 100, (int)pixel - 1, 1, 1, 0, 0);
}
@@ -91,7 +91,7 @@ uint16 MadsSceneLogic::startSpriteSequence2(uint16 srcSpriteIdx, int v0, int num
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,
+ return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, v0, 1, fld24, timeoutTicks, extraTicks, numTicks, 0, 0,
-1, 100, (int)pixel - 1, 1, 2, 0, 0);
}
@@ -100,7 +100,7 @@ uint16 MadsSceneLogic::startSpriteSequence3(uint16 srcSpriteIdx, int v0, int num
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,
+ return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, v0, 1, fld24, timeoutTicks, extraTicks, numTicks, 0, 0,
-1, 100, (int)pixel - 1, -1, 1, 0, 0);
}
@@ -187,7 +187,7 @@ void MadsSceneLogic::enterScene() {
_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);
+ _madsVm->scene()->_sequenceList.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);
diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp
index ad6370e08f..4b6e03b7bc 100644
--- a/engines/m4/mads_scene.cpp
+++ b/engines/m4/mads_scene.cpp
@@ -312,6 +312,10 @@ void MadsScene::update() {
_spriteSlots.getSprite(0).getFrame(1)->copyTo(this, 120, 90, 0);
}
+void MadsScene::updateState() {
+ _sequenceList.tick();
+}
+
int MadsScene::loadSceneSpriteSet(const char *setName) {
char resName[100];
strcpy(resName, setName);
diff --git a/engines/m4/mads_scene.h b/engines/m4/mads_scene.h
index 864f7428a4..43a90b621f 100644
--- a/engines/m4/mads_scene.h
+++ b/engines/m4/mads_scene.h
@@ -159,6 +159,8 @@ public:
virtual void setAction(int action, int objectId = -1);
virtual void update();
+ virtual void updateState();
+
int loadSceneSpriteSet(const char *setName);
void loadPlayerSprites(const char *prefix);
void showMADSV2TextBox(char *text, int x, int y, char *faceName);
diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp
index 8e4004f75e..9fcd89b895 100644
--- a/engines/m4/mads_views.cpp
+++ b/engines/m4/mads_views.cpp
@@ -247,8 +247,8 @@ void ScreenObjects::setActive(int category, int idx, bool active) {
/*--------------------------------------------------------------------------*/
-DynamicHotspots::DynamicHotspots(MadsView &owner): _owner(owner) {
- for (int i = 0; HITBOX_AREA_SIZE; ++i) {
+MadsDynamicHotspots::MadsDynamicHotspots(MadsView &owner): _owner(owner) {
+ for (int i = 0; i < DYNAMIC_HOTSPOTS_SIZE; ++i) {
DynamicHotspot rec;
rec.active = false;
}
@@ -256,13 +256,13 @@ DynamicHotspots::DynamicHotspots(MadsView &owner): _owner(owner) {
_count = 0;
}
-int DynamicHotspots::add(int descId, int field14, int timerIndex, const Common::Rect &bounds) {
+int MadsDynamicHotspots::add(int descId, int field14, int timerIndex, const Common::Rect &bounds) {
// Find a free slot
uint idx = 0;
while ((idx < _entries.size()) && !_entries[idx].active)
++idx;
if (idx == _entries.size())
- error("DynamicHotspots overflow");
+ error("MadsDynamicHotspots overflow");
_entries[idx].active = true;
_entries[idx].descId = descId;
@@ -276,12 +276,12 @@ int DynamicHotspots::add(int descId, int field14, int timerIndex, const Common::
++_count;
_flag = true;
- _owner._timerList[timerIndex].dynamicHotspotIndex = idx;
+ _owner._sequenceList[timerIndex].dynamicHotspotIndex = idx;
return idx;
}
-int DynamicHotspots::setPosition(int index, int xp, int yp, int facing) {
+int MadsDynamicHotspots::setPosition(int index, int xp, int yp, int facing) {
if (index >= 0) {
_entries[index].pos.x = xp;
_entries[index].pos.y = yp;
@@ -291,17 +291,17 @@ int DynamicHotspots::setPosition(int index, int xp, int yp, int facing) {
return index;
}
-int DynamicHotspots::set17(int index, int v) {
+int MadsDynamicHotspots::set17(int index, int v) {
if (index >= 0)
_entries[index].field_17 = v;
return index;
}
-void DynamicHotspots::remove(int index) {
+void MadsDynamicHotspots::remove(int index) {
if (_entries[index].active) {
if (_entries[index].timerIndex >= 0)
- _owner._timerList[_entries[index].timerIndex].dynamicHotspotIndex = -1;
+ _owner._sequenceList[_entries[index].timerIndex].dynamicHotspotIndex = -1;
_entries[index].active = false;
--_count;
@@ -309,7 +309,7 @@ void DynamicHotspots::remove(int index) {
}
}
-void DynamicHotspots::reset() {
+void MadsDynamicHotspots::reset() {
for (uint i = 0; i < _entries.size(); ++i)
_entries[i].active = false;
@@ -319,29 +319,29 @@ void DynamicHotspots::reset() {
/*--------------------------------------------------------------------------*/
-MadsTimerList::MadsTimerList(MadsView &owner): _owner(owner) {
+MadsSequenceList::MadsSequenceList(MadsView &owner): _owner(owner) {
for (int i = 0; i < TIMER_LIST_SIZE; ++i) {
- MadsTimerEntry rec;
+ MadsSequenceEntry rec;
rec.active = 0;
rec.dynamicHotspotIndex = -1;
_entries.push_back(rec);
}
}
-bool MadsTimerList::unk2(int index, int v1, int v2, int v3) {
+bool MadsSequenceList::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;
+ _entries[index].fld36[subIndex] = 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 MadsSequenceList::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 frameStart, int field_A, int numSprites,
int spriteNum) {
// Find a free slot
@@ -356,7 +356,7 @@ int MadsTimerList::add(int spriteListIndex, int v0, int frameIndex, char field_2
if (numSprites == 0)
numSprites = _madsVm->scene()->_spriteSlots.getSprite(spriteListIndex).getCount();
if (spriteNum == numSprites)
- field_C = 0;
+ frameStart = 0;
// Set the list entry fields
_entries[timerIndex].active = true;
@@ -366,7 +366,7 @@ int MadsTimerList::add(int spriteListIndex, int v0, int frameIndex, char field_2
_entries[timerIndex].spriteNum = spriteNum;
_entries[timerIndex].numSprites = numSprites;
_entries[timerIndex].field_A = field_A;
- _entries[timerIndex].field_C = field_C;
+ _entries[timerIndex].frameStart = frameStart;
_entries[timerIndex].depth = depth;
_entries[timerIndex].scale = scale;
_entries[timerIndex].field_12 = field_12;
@@ -375,7 +375,7 @@ int MadsTimerList::add(int spriteListIndex, int v0, int frameIndex, char field_2
_entries[timerIndex].numTicks = numTicks;
_entries[timerIndex].extraTicks = extraTicks;
- _entries[timerIndex].timeout = g_system->getMillis() + timeoutTicks * GAME_FRAME_DELAY;
+ _entries[timerIndex].timeout = _madsVm->_currentTimer + timeoutTicks;
_entries[timerIndex].field_24 = field_24;
_entries[timerIndex].field_25 = 0;
@@ -390,7 +390,7 @@ int MadsTimerList::add(int spriteListIndex, int v0, int frameIndex, char field_2
return timerIndex;
}
-void MadsTimerList::remove(int timerIndex) {
+void MadsSequenceList::remove(int timerIndex) {
if (_entries[timerIndex].active) {
if (_entries[timerIndex].dynamicHotspotIndex >= 0)
_owner._dynamicHotspots.remove(_entries[timerIndex].dynamicHotspotIndex);
@@ -400,8 +400,8 @@ void MadsTimerList::remove(int timerIndex) {
_owner._spriteSlots.deleteTimer(timerIndex);
}
-void MadsTimerList::setSpriteSlot(int timerIndex, MadsSpriteSlot &spriteSlot) {
- MadsTimerEntry &timerEntry = _entries[timerIndex];
+void MadsSequenceList::setSpriteSlot(int timerIndex, MadsSpriteSlot &spriteSlot) {
+ MadsSequenceEntry &timerEntry = _entries[timerIndex];
SpriteAsset &sprite = _owner._spriteSlots.getSprite(timerEntry.spriteListIndex);
// TODO: Figure out logic for spriteId value based on SPRITE_SLOT.field_0
@@ -421,8 +421,11 @@ void MadsTimerList::setSpriteSlot(int timerIndex, MadsSpriteSlot &spriteSlot) {
}
}
-bool MadsTimerList::loadSprites(int timerIndex) {
- MadsTimerEntry &timerEntry = _entries[timerIndex];
+bool MadsSequenceList::loadSprites(int timerIndex) {
+ MadsSequenceEntry &timerEntry = _entries[timerIndex];
+ int slotIndex;
+ bool result = false;
+ int idx = -1;
_owner._spriteSlots.deleteTimer(timerIndex);
if (timerEntry.field_25 != 0) {
@@ -430,21 +433,102 @@ bool MadsTimerList::loadSprites(int timerIndex) {
return false;
}
- // TODO: Rest of method
+ if (timerEntry.spriteListIndex == -1) {
+ timerEntry.field_25 = -1;
+ } else if ((slotIndex = _owner._spriteSlots.getIndex()) >= 0) {
+ MadsSpriteSlot &spriteSlot = _owner._spriteSlots[slotIndex];
+ setSpriteSlot(timerIndex, spriteSlot);
- return true;
+ int x2 = 0, y2 = 0;
+
+ if ((timerEntry.field_13 != 0) || (timerEntry.dynamicHotspotIndex >= 0)) {
+ SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(timerEntry.spriteListIndex);
+ M4Sprite *frame = spriteSet.getFrame(timerEntry.frameIndex);
+ int width = frame->width() * timerEntry.scale / 200;
+ int height = frame->height() * timerEntry.scale / 100;
+
+ warning("frame size %d x %d", width, height);
+
+ // TODO: Missing stuff here, and I'm not certain about the dynamic hotspot stuff below
+
+ if (timerEntry.dynamicHotspotIndex >= 0) {
+ DynamicHotspot &dynHotspot = _owner._dynamicHotspots[timerEntry.dynamicHotspotIndex];
+
+ dynHotspot.bounds.left = MAX(x2 - width, 0);
+ dynHotspot.bounds.right = MAX(x2 - width, 319) - dynHotspot.bounds.left + 1;
+ dynHotspot.bounds.top = MAX(y2 - height, 0);
+ dynHotspot.bounds.bottom = MIN(y2, 155) - dynHotspot.bounds.top;
+
+ _owner._dynamicHotspots._flag = true;
+ }
+ }
+
+ // Frame adjustments
+ if (timerEntry.numSprites != timerEntry.spriteNum)
+ timerEntry.frameIndex += timerEntry.frameStart;
+
+ if (timerEntry.frameIndex >= timerEntry.spriteNum) {
+ if (timerEntry.frameIndex > timerEntry.numSprites) {
+ result = true;
+ if (timerEntry.field_A != 2) {
+ timerEntry.frameIndex = timerEntry.spriteNum;
+ } else {
+ timerEntry.frameIndex = timerEntry.numSprites - 1;
+ timerEntry.frameStart = -1;
+ }
+ }
+ } else {
+ result = true;
+
+ if (timerEntry.field_A == 2) {
+ timerEntry.frameIndex = timerEntry.spriteNum + 1;
+ timerEntry.frameStart = 1;
+ } else {
+ timerEntry.frameIndex = timerEntry.numSprites;
+ }
+ }
+
+ if (result && (timerEntry.field_24 != 0)) {
+ if (--timerEntry.field_24 != 0)
+ timerEntry.field_25 = -1;
+ }
+ } else {
+ // Out of sprite slots
+ timerEntry.field_25 = -1;
+ }
+
+ if (timerEntry.len27 > 0) {
+ for (int i = 0; i <= timerEntry.len27; ++i) {
+ if ((!timerEntry.fld27[i] && (timerEntry.field_25 != 0)) ||
+ ((timerEntry.fld27[i] == 1) && result)) {
+ idx = i;
+ } else if (timerEntry.fld27[i] > 1) {
+ int v = timerEntry.fld2C[i];
+ if ((v == timerEntry.frameIndex) || (v == 0))
+ idx = i;
+ }
+ }
+ }
+
+ if (idx >= 0) {
+ _owner._abortTimers = timerEntry.fld36[idx];
+
+ // TODO: Figure out word_84208, timerEntry.field_3B[]
+ }
+
+ return result;
}
/**
* Handles counting down entries in the timer list for action
*/
-void MadsTimerList::tick() {
+void MadsSequenceList::tick() {
for (uint idx = 0; idx < _entries.size(); ++idx) {
if ((_owner._abortTimers2 == 0) && (_owner._abortTimers != 0))
break;
- MadsTimerEntry &timerEntry = _entries[idx];
- uint32 currentTimer = g_system->getMillis();
+ MadsSequenceEntry &timerEntry = _entries[idx];
+ uint32 currentTimer = _madsVm->_currentTimer;
if (!timerEntry.active || (currentTimer < timerEntry.timeout))
continue;
@@ -459,9 +543,17 @@ void MadsTimerList::tick() {
}
}
+void MadsSequenceList::delay(uint32 v1, uint32 v2) {
+ for (uint idx = 0; idx < _entries.size(); ++idx) {
+ if (_entries[idx].active) {
+ _entries[idx].timeout += v1 - v2;
+ }
+ }
+}
+
//--------------------------------------------------------------------------
-MadsView::MadsView(View *view): _view(view), _dynamicHotspots(*this), _timerList(*this) {
+MadsView::MadsView(View *view): _view(view), _dynamicHotspots(*this), _sequenceList(*this) {
_abortTimers = 0;
_abortTimers2 = 0;
}
diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h
index cf449c2880..a1d07c97f0 100644
--- a/engines/m4/mads_views.h
+++ b/engines/m4/mads_views.h
@@ -169,16 +169,17 @@ public:
DynamicHotspot() { active = false; }
};
-#define HITBOX_AREA_SIZE 8
+#define DYNAMIC_HOTSPOTS_SIZE 8
-class DynamicHotspots {
+class MadsDynamicHotspots {
private:
MadsView &_owner;
Common::Array<DynamicHotspot> _entries;
- bool _flag;
int _count;
public:
- DynamicHotspots(MadsView &owner);
+ bool _flag;
+public:
+ MadsDynamicHotspots(MadsView &owner);
DynamicHotspot &operator[](uint idx) { return _entries[idx]; }
int add(int descId, int field14, int timerIndex, const Common::Rect &bounds);
@@ -190,7 +191,7 @@ public:
#define TIMER_ENTRY_SUBSET_MAX 5
-struct MadsTimerEntry {
+struct MadsSequenceEntry {
int8 active;
int8 spriteListIndex;
@@ -201,7 +202,7 @@ struct MadsTimerEntry {
int numSprites;
int field_A;
- int field_C;
+ int frameStart;
int depth;
int scale;
@@ -218,7 +219,7 @@ struct MadsTimerEntry {
int len27;
int8 fld27[TIMER_ENTRY_SUBSET_MAX];
int16 fld2C[TIMER_ENTRY_SUBSET_MAX];
- int8 field36;
+ int8 fld36[TIMER_ENTRY_SUBSET_MAX];
int field_3B;
uint16 actionNouns[3];
@@ -229,22 +230,23 @@ struct MadsTimerEntry {
#define TIMER_LIST_SIZE 30
-class MadsTimerList {
+class MadsSequenceList {
private:
MadsView &_owner;
- Common::Array<MadsTimerEntry> _entries;
+ Common::Array<MadsSequenceEntry> _entries;
public:
- MadsTimerList(MadsView &owner);
+ MadsSequenceList(MadsView &owner);
- MadsTimerEntry &operator[](int index) { return _entries[index]; }
+ MadsSequenceEntry &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 height, int width, char field_12, char scale, char depth, int frameStart, int field_A,
int numSprites, int spriteNum);
void remove(int timerIndex);
void setSpriteSlot(int timerIndex, MadsSpriteSlot &spriteSlot);
bool loadSprites(int timerIndex);
void tick();
+ void delay(uint32 v1, uint32 v2);
};
class MadsView {
@@ -254,8 +256,8 @@ public:
MadsSpriteSlots _spriteSlots;
MadsTextDisplay _textDisplay;
ScreenObjects _screenObjects;
- DynamicHotspots _dynamicHotspots;
- MadsTimerList _timerList;
+ MadsDynamicHotspots _dynamicHotspots;
+ MadsSequenceList _sequenceList;
int _abortTimers;
int8 _abortTimers2;