aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBendegúz Nagy2016-07-11 17:06:24 +0200
committerBendegúz Nagy2016-08-26 23:02:22 +0200
commit536e9c1bb9e603e420843647a092b50f7668a996 (patch)
treeb6fb84741c0f064978bae45fc6c8dd4a266b6006
parentd77ffceff9cc8266c9fea4ab33c90b5c78341ec7 (diff)
downloadscummvm-rg350-536e9c1bb9e603e420843647a092b50f7668a996.tar.gz
scummvm-rg350-536e9c1bb9e603e420843647a092b50f7668a996.tar.bz2
scummvm-rg350-536e9c1bb9e603e420843647a092b50f7668a996.zip
DM: Add f248_timelineProcessEvent6_squareWall
-rw-r--r--engines/dm/champion.cpp2
-rw-r--r--engines/dm/dm.cpp4
-rw-r--r--engines/dm/dm.h2
-rw-r--r--engines/dm/dungeonman.h13
-rw-r--r--engines/dm/timeline.cpp175
-rw-r--r--engines/dm/timeline.h6
6 files changed, 190 insertions, 12 deletions
diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp
index 4a1508fb84..a9684111b0 100644
--- a/engines/dm/champion.cpp
+++ b/engines/dm/champion.cpp
@@ -820,7 +820,7 @@ uint16 ChampionMan::f307_getStatisticAdjustedAttack(Champion* champ, uint16 stat
void ChampionMan::f314_wakeUp() {
_vm->_g321_stopWaitingForPlayerInput = true;
_g300_partyIsSleeping = false;
- _vm->waitMs(10);
+ _vm->f22_delay(10);
_vm->_displayMan->f98_drawFloorAndCeiling();
_vm->_eventMan->_g441_primaryMouseInput = g447_PrimaryMouseInput_Interface;
_vm->_eventMan->_g442_secondaryMouseInput = g448_SecondaryMouseInput_Movement;
diff --git a/engines/dm/dm.cpp b/engines/dm/dm.cpp
index 8a49b23e87..932de5a60c 100644
--- a/engines/dm/dm.cpp
+++ b/engines/dm/dm.cpp
@@ -199,8 +199,8 @@ DMEngine::~DMEngine() {
DebugMan.clearAllDebugChannels();
}
-void DMEngine::waitMs(uint16 ms) {
- _system->delayMillis(ms * 20);
+void DMEngine::f22_delay(uint16 verticalBlank) {
+ _system->delayMillis(verticalBlank * 20); // Google says most Amiga games had a refreshrate of 50 hz
}
uint16 DMEngine::f30_getScaledProduct(uint16 val, uint16 scale, uint16 vale2) {
diff --git a/engines/dm/dm.h b/engines/dm/dm.h
index 5b8061c809..1e1fc6a53c 100644
--- a/engines/dm/dm.h
+++ b/engines/dm/dm.h
@@ -184,7 +184,7 @@ public:
explicit DMEngine(OSystem *syst);
~DMEngine();
- void waitMs(uint16 ms);
+ void f22_delay(uint16 ms); // @ F0022_MAIN_Delay
uint16 f30_getScaledProduct(uint16 val, uint16 scale, uint16 vale2); // @ F0030_MAIN_GetScaledProduct
uint16 getRandomNumber(uint32 max) { return _rnd->getRandomNumber(max - 1); }
int16 M1_ordinalToIndex(int16 val); // @ M01_ORDINAL_TO_INDEX
diff --git a/engines/dm/dungeonman.h b/engines/dm/dungeonman.h
index 2763906d5d..e0a1d8ff50 100644
--- a/engines/dm/dungeonman.h
+++ b/engines/dm/dungeonman.h
@@ -260,6 +260,7 @@ public:
Thing getNextThing() { return _nextThing; }
uint16 getWordOffset() { return _textDataRef >> 3; }
bool isVisible() { return _textDataRef & 1; }
+ void setVisible(bool visible) { _textDataRef = (_textDataRef & ~1) | (visible ? 1 : 0); }
}; // @ TEXTSTRING
enum SensorActionType {
@@ -306,8 +307,8 @@ enum SensorType {
class Sensor {
Thing _nextThing;
uint16 _datAndType;
- uint16 _attributes;
- uint16 _action;
+ uint16 _attributes; // A
+ uint16 _action; // B
public:
explicit Sensor(uint16 *rawDat) : _nextThing(rawDat[0]), _datAndType(rawDat[1]), _attributes(rawDat[2]), _action(rawDat[3]) {}
@@ -315,8 +316,8 @@ public:
void setNextThing(Thing thing) { _nextThing = thing; }
SensorType getType() { return (SensorType)(_datAndType & 0x7F); } // @ M39_TYPE
uint16 getData() { return _datAndType >> 7; } // @ M40_DATA
- uint16 getDataMask1() { return (_datAndType >> 7) & 0xF; } // @ M42_MASK1
- uint16 getDataMask2() { return (_datAndType >> 11) & 0xF; } // @ M43_MASK2
+ static uint16 getDataMask1(uint16 data) { return (data >> 7) & 0xF; } // @ M42_MASK1
+ static uint16 getDataMask2(uint16 data) { return (data >> 11) & 0xF; } // @ M43_MASK2
void setData(int16 dat) { _datAndType = (_datAndType & 0x7F) | (dat << 7); } // @ M41_SET_DATA
void setTypeDisabled() { _datAndType &= 0xFF80; } // @ M44_SET_TYPE_DISABLED
@@ -333,6 +334,8 @@ public:
uint16 getTargetMapY() { return (_action >> 11); }
uint16 getTargetMapX() { return (_action >> 6) & 0x1F; }
direction getTargetCell() { return (direction)((_action >> 4) & 3); }
+ uint16 M47_kineticEnergy() { return (_action & 0xFF); }// @ M47_KINETIC_ENERGY
+ uint16 M48_stepEnergy() { return (_action >> 8) & 0xFF; }// @ M48_STEP_ENERGY
uint16 M49_localEffect() { return (_action >> 4); }
@@ -652,7 +655,7 @@ class DungeonMan {
int16 f170_getRandomOrnOrdinal(bool allowed, int16 count, int16 mapX, int16 mapY, int16 modulo); // @ F0170_DUNGEON_GetRandomOrnamentOrdinal
void f171_setSquareAspectOrnOrdinals(uint16 *aspectArray, bool leftAllowed, bool frontAllowed, bool rightAllowed, int16 dir,
- int16 mapX, int16 mapY, bool isFakeWall); // @ F0171_DUNGEON_SetSquareAspectRandomWallOrnamentOrdinals
+ int16 mapX, int16 mapY, bool isFakeWall); // @ F0171_DUNGEON_SetSquareAspectRandomWallOrnamentOrdinals
public:
diff --git a/engines/dm/timeline.cpp b/engines/dm/timeline.cpp
index 5b2d137d83..524b5a5050 100644
--- a/engines/dm/timeline.cpp
+++ b/engines/dm/timeline.cpp
@@ -256,7 +256,7 @@ void Timeline::f261_processTimeline() {
f250_timelineProcessEvent8_squareTeleporter(L0681_ps_Event);
break;
case k6_TMEventTypeWall:
- //F0248_TIMELINE_ProcessEvent6_Square_Wall(L0681_ps_Event);
+ f248_timelineProcessEvent6_squareWall(L0681_ps_Event);
break;
case k5_TMEventTypeCorridor:
//F0245_TIMELINE_ProcessEvent5_Square_Corridor(L0681_ps_Event);
@@ -568,4 +568,177 @@ void Timeline::f250_timelineProcessEvent8_squareTeleporter(TimelineEvent* event)
clearFlag(*L0652_puc_Square, k0x0008_TeleporterOpen);
}
}
+
+void Timeline::f248_timelineProcessEvent6_squareWall(TimelineEvent* event) {
+ Thing L0634_T_Thing;
+ int16 L0635_i_ThingType;
+ int16 L0636_i_Multiple;
+#define AL0636_B_TriggerSetEffect L0636_i_Multiple
+#define AL0636_i_BitMask L0636_i_Multiple
+ uint16 L0637_ui_SensorData;
+ Sensor* L0638_ps_Sensor;
+ TextString* L0639_ps_TextString;
+ uint16 L0640_ui_SensorType;
+ int16 L0641_i_MapX;
+ int16 L0642_i_MapY;
+ uint16 L0643_ui_Cell;
+
+
+ L0634_T_Thing = _vm->_dungeonMan->f161_getSquareFirstThing(L0641_i_MapX = event->_B._location._mapX, L0642_i_MapY = event->_B._location._mapY);
+ L0643_ui_Cell = event->_C.A._cell;
+ while (L0634_T_Thing != Thing::_endOfList) {
+ if (((L0635_i_ThingType = L0634_T_Thing.getType()) == k2_TextstringType) && (L0634_T_Thing.getCell() == event->_C.A._cell)) {
+ L0639_ps_TextString = (TextString*)_vm->_dungeonMan->f156_getThingData(L0634_T_Thing);
+ if (event->_C.A._effect == k2_SensorEffToggle) {
+ L0639_ps_TextString->setVisible(!L0639_ps_TextString->isVisible());
+ } else {
+ L0639_ps_TextString->setVisible(event->_C.A._effect == k0_SensorEffSet);
+ }
+ } else {
+ if (L0635_i_ThingType == k3_SensorThingType) {
+ L0638_ps_Sensor = (Sensor*)_vm->_dungeonMan->f156_getThingData(L0634_T_Thing);
+ L0640_ui_SensorType = L0638_ps_Sensor->getType();
+ L0637_ui_SensorData = L0638_ps_Sensor->getData();
+ if (L0640_ui_SensorType == k6_SensorWallCountdown) {
+ if (L0637_ui_SensorData > 0) {
+ if (event->_C.A._effect == k0_SensorEffSet) {
+ if (L0637_ui_SensorData < 511) {
+ L0637_ui_SensorData++;
+ }
+ } else {
+ L0637_ui_SensorData--;
+ }
+ L0638_ps_Sensor->setData(L0637_ui_SensorData);
+ if (L0638_ps_Sensor->getEffectA() == k3_SensorEffHold) {
+ AL0636_B_TriggerSetEffect = ((L0637_ui_SensorData == 0) != L0638_ps_Sensor->getRevertEffectA());
+ _vm->_movsens->f272_sensorTriggerEffect(L0638_ps_Sensor, AL0636_B_TriggerSetEffect ? k0_SensorEffSet : k1_SensorEffClear, L0641_i_MapX, L0642_i_MapY, L0643_ui_Cell);
+ } else {
+ if (L0637_ui_SensorData == 0) {
+ _vm->_movsens->f272_sensorTriggerEffect(L0638_ps_Sensor, L0638_ps_Sensor->getEffectA(), L0641_i_MapX, L0642_i_MapY, L0643_ui_Cell);
+ }
+ }
+ }
+ } else {
+ if (L0640_ui_SensorType == k5_SensorWallAndOrGate) {
+ AL0636_i_BitMask = 1 << (event->_C.A._cell);
+ if (event->_C.A._effect == k2_SensorEffToggle) {
+ if (getFlag(L0637_ui_SensorData, AL0636_i_BitMask)) {
+ clearFlag(L0637_ui_SensorData, AL0636_i_BitMask);
+ } else {
+ setFlag(L0637_ui_SensorData, AL0636_i_BitMask);
+ }
+ } else {
+ if (event->_C.A._effect) {
+ clearFlag(L0637_ui_SensorData, AL0636_i_BitMask);
+ } else {
+ setFlag(L0637_ui_SensorData, AL0636_i_BitMask);
+ }
+ }
+ L0638_ps_Sensor->setData(L0637_ui_SensorData);
+ AL0636_B_TriggerSetEffect = (Sensor::getDataMask1(L0637_ui_SensorData) == Sensor::getDataMask2(L0637_ui_SensorData)) != L0638_ps_Sensor->getRevertEffectA();
+ if (L0638_ps_Sensor->getEffectA() == k3_SensorEffHold) {
+ _vm->_movsens->f272_sensorTriggerEffect(L0638_ps_Sensor, AL0636_B_TriggerSetEffect ? k0_SensorEffSet : k1_SensorEffClear, L0641_i_MapX, L0642_i_MapY, L0643_ui_Cell);
+ } else {
+ if (AL0636_B_TriggerSetEffect) {
+ _vm->_movsens->f272_sensorTriggerEffect(L0638_ps_Sensor, L0638_ps_Sensor->getEffectA(), L0641_i_MapX, L0642_i_MapY, L0643_ui_Cell);
+ }
+ }
+ } else {
+ if ((((L0640_ui_SensorType >= k7_SensorWallSingleProjLauncherNewObj) && (L0640_ui_SensorType <= k10_SensorWallDoubleProjLauncherExplosion)) || (L0640_ui_SensorType == k14_SensorWallSingleProjLauncherSquareObj) || (L0640_ui_SensorType == k15_SensorWallDoubleProjLauncherSquareObj)) && (L0634_T_Thing.getCell() == event->_C.A._cell)) {
+ f247_triggerProjectileLauncher(L0638_ps_Sensor, event);
+ if (L0638_ps_Sensor->getOnlyOnce()) {
+ L0638_ps_Sensor->setTypeDisabled();
+ }
+ } else {
+ if (L0640_ui_SensorType == k18_SensorWallEndGame) {
+ _vm->f22_delay(60 * L0638_ps_Sensor->getValue());
+ _vm->_g524_restartGameAllowed = false;
+ _vm->_g302_gameWon = true;
+ warning(false, "MISSING CODE: F0444_STARTEND_Endgame");
+ }
+ }
+ }
+ }
+ }
+ }
+ L0634_T_Thing = _vm->_dungeonMan->f159_getNextThing(L0634_T_Thing);
+ }
+ _vm->_movsens->f271_processRotationEffect();
+}
+
+void Timeline::f247_triggerProjectileLauncher(Sensor* sensor, TimelineEvent* event) {
+ Thing L0622_T_FirstProjectileAssociatedThing;
+ Thing L0623_T_SecondProjectileAssociatedThing;
+ uint16 L0624_ui_Cell;
+ int16 L0625_i_SensorType;
+ int16 L0626_i_MapX;
+ int16 L0627_i_MapY;
+ uint16 L0628_ui_ProjectileCell;
+ int16 L0629_i_SensorData;
+ int16 L0630_i_KineticEnergy;
+ int16 L0631_i_StepEnergy;
+ bool L0632_B_LaunchSingleProjectile;
+ uint16 L0633_ui_ThingCell;
+
+
+ L0626_i_MapX = event->_B._location._mapX;
+ L0627_i_MapY = event->_B._location._mapY;
+ L0624_ui_Cell = event->_C.A._cell;
+ L0628_ui_ProjectileCell = returnOppositeDir((direction)L0624_ui_Cell);
+ L0625_i_SensorType = sensor->getType();
+ L0629_i_SensorData = sensor->getData();
+ L0630_i_KineticEnergy = sensor->M47_kineticEnergy();
+ L0631_i_StepEnergy = sensor->M48_stepEnergy();
+ L0632_B_LaunchSingleProjectile = (L0625_i_SensorType == k7_SensorWallSingleProjLauncherNewObj) ||
+ (L0625_i_SensorType == k8_SensorWallSingleProjLauncherExplosion) ||
+ (L0625_i_SensorType == k14_SensorWallSingleProjLauncherSquareObj);
+ if ((L0625_i_SensorType == k8_SensorWallSingleProjLauncherExplosion) || (L0625_i_SensorType == k10_SensorWallDoubleProjLauncherExplosion)) {
+ L0622_T_FirstProjectileAssociatedThing = L0623_T_SecondProjectileAssociatedThing = Thing(L0629_i_SensorData + Thing::_firstExplosion.toUint16());
+ } else {
+ if ((L0625_i_SensorType == k14_SensorWallSingleProjLauncherSquareObj) || (L0625_i_SensorType == k15_SensorWallDoubleProjLauncherSquareObj)) {
+ L0622_T_FirstProjectileAssociatedThing = _vm->_dungeonMan->f161_getSquareFirstThing(L0626_i_MapX, L0627_i_MapY);
+ while (L0622_T_FirstProjectileAssociatedThing != Thing::_none) { /* BUG0_19 The game crashes when an object launcher sensor is triggered. Thing::_none should be Thing::_endOfList. If there are no more objects on the square then this loop may return an undefined value, this can crash the game. In the original DM and CSB dungeons, the number of times that these sensors are triggered is always controlled to be equal to the number of available objects (with a countdown sensor or a number of once only sensors) */
+ L0633_ui_ThingCell = L0622_T_FirstProjectileAssociatedThing.getCell();
+ if ((L0622_T_FirstProjectileAssociatedThing.getType() > k3_SensorThingType) && ((L0633_ui_ThingCell == L0624_ui_Cell) || (L0633_ui_ThingCell == returnNextVal(L0624_ui_Cell))))
+ break;
+ L0622_T_FirstProjectileAssociatedThing = _vm->_dungeonMan->f159_getNextThing(L0622_T_FirstProjectileAssociatedThing);
+ }
+ if (L0622_T_FirstProjectileAssociatedThing == Thing::_none) { /* BUG0_19 The game crashes when an object launcher sensor is triggered. Thing::_none should be Thing::_endOfList */
+ return;
+ }
+ _vm->_dungeonMan->f164_unlinkThingFromList(L0622_T_FirstProjectileAssociatedThing, Thing(0), L0626_i_MapX, L0627_i_MapY); /* The object is removed without triggering any sensor effects */
+ if (!L0632_B_LaunchSingleProjectile) {
+ L0623_T_SecondProjectileAssociatedThing = _vm->_dungeonMan->f161_getSquareFirstThing(L0626_i_MapX, L0627_i_MapY);
+ while (L0623_T_SecondProjectileAssociatedThing != Thing::_none) { /* BUG0_19 The game crashes when an object launcher sensor is triggered. Thing::_none should be Thing::_endOfList. If there are no more objects on the square then this loop may return an undefined value, this can crash the game */
+ L0633_ui_ThingCell = L0623_T_SecondProjectileAssociatedThing.getCell();
+ if ((L0623_T_SecondProjectileAssociatedThing.getType() > k3_SensorThingType) && ((L0633_ui_ThingCell == L0624_ui_Cell) || (L0633_ui_ThingCell == returnNextVal(L0624_ui_Cell))))
+ break;
+ L0623_T_SecondProjectileAssociatedThing = _vm->_dungeonMan->f159_getNextThing(L0623_T_SecondProjectileAssociatedThing);
+ }
+ if (L0623_T_SecondProjectileAssociatedThing == Thing::_none) { /* BUG0_19 The game crashes when an object launcher sensor is triggered. Thing::_none should be Thing::_endOfList */
+ L0632_B_LaunchSingleProjectile = true;
+ } else {
+ _vm->_dungeonMan->f164_unlinkThingFromList(L0623_T_SecondProjectileAssociatedThing, Thing(0), L0626_i_MapX, L0627_i_MapY); /* The object is removed without triggering any sensor effects */
+ }
+ }
+ } else {
+ if ((L0622_T_FirstProjectileAssociatedThing = _vm->_dungeonMan->f167_getObjForProjectileLaucherOrObjGen(L0629_i_SensorData)) == Thing::_none) {
+ return;
+ }
+ if (!L0632_B_LaunchSingleProjectile && ((L0623_T_SecondProjectileAssociatedThing = _vm->_dungeonMan->f167_getObjForProjectileLaucherOrObjGen(L0629_i_SensorData)) == Thing::_none)) {
+ L0632_B_LaunchSingleProjectile = true;
+ }
+ }
+ }
+ if (L0632_B_LaunchSingleProjectile) {
+ L0628_ui_ProjectileCell = M21_normalizeModulo4(L0628_ui_ProjectileCell + _vm->getRandomNumber(2));
+ }
+ L0626_i_MapX += _vm->_dirIntoStepCountEast[L0624_ui_Cell], L0627_i_MapY += _vm->_dirIntoStepCountNorth[L0624_ui_Cell]; /* BUG0_20 The game crashes if the launcher sensor is on a map boundary and shoots in a direction outside the map */
+ _vm->_projexpl->_g365_createLanucherProjectile = true;
+ _vm->_projexpl->f212_projectileCreate(L0622_T_FirstProjectileAssociatedThing, L0626_i_MapX, L0627_i_MapY, L0628_ui_ProjectileCell, (direction)L0624_ui_Cell, L0630_i_KineticEnergy, 100, L0631_i_StepEnergy);
+ if (!L0632_B_LaunchSingleProjectile) {
+ _vm->_projexpl->f212_projectileCreate(L0623_T_SecondProjectileAssociatedThing, L0626_i_MapX, L0627_i_MapY, returnNextVal(L0628_ui_ProjectileCell), (direction)L0624_ui_Cell, L0630_i_KineticEnergy, 100, L0631_i_StepEnergy);
+ }
+ _vm->_projexpl->_g365_createLanucherProjectile = false;
+}
}
diff --git a/engines/dm/timeline.h b/engines/dm/timeline.h
index a0d2877704..a11b26c297 100644
--- a/engines/dm/timeline.h
+++ b/engines/dm/timeline.h
@@ -31,8 +31,9 @@
#include "dm.h"
namespace DM {
+ class Sensor;
-/* Event types */
+ /* Event types */
enum TimelineEventType {
/* Used when a creature in a group was damaged or killed by a Poison Cloud or by a closing door or if Lord Chaos is surrounded by = 3, Fluxcages */
kM3_TMEventTypeCreateReactionEvent29DangerOnSquare = -3, // @ CM3_EVENT_CREATE_REACTION_EVENT_29_DANGER_ON_SQUARE
@@ -169,7 +170,8 @@ public:
void f251_timelineProcessEvent9_squarePit(TimelineEvent *event); // @ F0251_TIMELINE_ProcessEvent9_Square_Pit
void f249_moveTeleporterOrPitSquareThings(uint16 mapX, uint16 mapY); // @ F0249_TIMELINE_MoveTeleporterOrPitSquareThings
void f250_timelineProcessEvent8_squareTeleporter(TimelineEvent *event); // @ F0250_TIMELINE_ProcessEvent8_Square_Teleporter
-
+ void f248_timelineProcessEvent6_squareWall(TimelineEvent *event); // @ F0248_TIMELINE_ProcessEvent6_Square_Wall
+ void f247_triggerProjectileLauncher(Sensor *sensor, TimelineEvent *event); // @ F0247_TIMELINE_TriggerProjectileLauncher
};