aboutsummaryrefslogtreecommitdiff
path: root/engines/cine
diff options
context:
space:
mode:
Diffstat (limited to 'engines/cine')
-rw-r--r--engines/cine/anim.cpp2
-rw-r--r--engines/cine/anim.h2
-rw-r--r--engines/cine/cine.cpp19
-rw-r--r--engines/cine/gfx.cpp55
-rw-r--r--engines/cine/main_loop.cpp4
-rw-r--r--engines/cine/object.cpp9
-rw-r--r--engines/cine/object.h15
-rw-r--r--engines/cine/various.cpp15
-rw-r--r--engines/cine/various.h4
9 files changed, 83 insertions, 42 deletions
diff --git a/engines/cine/anim.cpp b/engines/cine/anim.cpp
index c19435c59a..c2c815596e 100644
--- a/engines/cine/anim.cpp
+++ b/engines/cine/anim.cpp
@@ -49,7 +49,7 @@ struct AnimHeader2Struct {
uint16 field_E;
};
-AnimData animDataTable[NUM_MAX_ANIMDATA];
+Common::Array<AnimData> animDataTable;
static const AnimDataEntry transparencyData[] = {
{"ALPHA", 0xF},
diff --git a/engines/cine/anim.h b/engines/cine/anim.h
index 317654064b..8b1541eb3f 100644
--- a/engines/cine/anim.h
+++ b/engines/cine/anim.h
@@ -150,7 +150,7 @@ public:
#define NUM_MAX_ANIMDATA 255
-extern AnimData animDataTable[NUM_MAX_ANIMDATA];
+extern Common::Array<AnimData> animDataTable;
void freeAnimDataTable(void);
void freeAnimDataRange(byte startIdx, byte numIdx);
diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp
index 127d390f66..c30cac63a5 100644
--- a/engines/cine/cine.cpp
+++ b/engines/cine/cine.cpp
@@ -124,6 +124,22 @@ int CineEngine::modifyGameSpeed(int speedChange) {
}
void CineEngine::initialize() {
+ // Resize object table to its correct size and reset all its elements
+ objectTable.resize(NUM_MAX_OBJECT);
+ resetObjectTable();
+
+ // Resize animation data table to its correct size and reset all its elements
+ animDataTable.resize(NUM_MAX_ANIMDATA);
+ freeAnimDataTable();
+
+ // Resize zone data table to its correct size and reset all its elements
+ zoneData.resize(NUM_MAX_ZONE);
+ Common::set_to(zoneData.begin(), zoneData.end(), 0);
+
+ // Resize zone query table to its correct size and reset all its elements
+ zoneQuery.resize(NUM_MAX_ZONE);
+ Common::set_to(zoneQuery.begin(), zoneQuery.end(), 0);
+
_timerDelayMultiplier = 12; // Set default speed
setupOpcodes();
@@ -160,8 +176,7 @@ void CineEngine::initialize() {
freeAnimDataTable();
overlayList.clear();
messageTable.clear();
-
- memset(objectTable, 0, sizeof(objectTable));
+ resetObjectTable();
var8 = 0;
diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp
index b882c9760e..c6c5faf464 100644
--- a/engines/cine/gfx.cpp
+++ b/engines/cine/gfx.cpp
@@ -276,9 +276,11 @@ void FWRenderer::drawMessage(const char *str, int x, int y, int width, byte colo
/*! \brief Draw rectangle on screen
* \param x Top left corner coordinate
* \param y Top left corner coordinate
- * \param width Rectangle width
- * \param height Rectangle height
+ * \param width Rectangle width (Negative values draw the box horizontally flipped)
+ * \param height Rectangle height (Negative values draw the box vertically flipped)
* \param color Fill color
+ * \note Rectangle's drawn width is always at least one.
+ * \note Rectangle's drawn height is always at least one.
*/
void FWRenderer::drawPlainBox(int x, int y, int width, int height, byte color) {
int i;
@@ -313,12 +315,18 @@ void FWRenderer::drawPlainBox(int x, int y, int width, int height, byte color) {
height = 0;
}
- // Draw the box if it's not empty
- if (width > 0 && height > 0) {
- byte *dest = _backBuffer + y * 320 + x;
- for (i = 0; i < height; i++) {
- memset(dest + i * 320, color, width);
- }
+ // Make width and height at least one
+ // which forces this function to always draw something.
+ // This fixes at least the showing of the oxygen gauge meter in
+ // Operation Stealth's first arcade sequence where this function
+ // is called with a height of zero.
+ width = MAX(1, width);
+ height = MAX(1, height);
+
+ // Draw the filled rectangle
+ byte *dest = _backBuffer + y * 320 + x;
+ for (i = 0; i < height; i++) {
+ memset(dest + i * 320, color, width);
}
}
@@ -428,7 +436,7 @@ void FWRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
switch (it->type) {
// color sprite
case 0:
- sprite = animDataTable + objectTable[it->objIdx].frame;
+ sprite = &animDataTable[objectTable[it->objIdx].frame];
len = sprite->_realWidth * sprite->_height;
mask = new byte[len];
memcpy(mask, sprite->mask(), len);
@@ -463,7 +471,7 @@ void FWRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
// bitmap
case 4:
assert(it->objIdx < NUM_MAX_OBJECT);
- obj = objectTable + it->objIdx;
+ obj = &objectTable[it->objIdx];
if (obj->frame < 0) {
return;
@@ -1066,7 +1074,7 @@ void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
if (objectTable[it->objIdx].frame < 0) {
break;
}
- sprite = animDataTable + objectTable[it->objIdx].frame;
+ sprite = &animDataTable[objectTable[it->objIdx].frame];
len = sprite->_realWidth * sprite->_height;
mask = new byte[len];
generateMask(sprite->data(), mask, len, objectTable[it->objIdx].part);
@@ -1099,8 +1107,8 @@ void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
case 20:
assert(it->objIdx < NUM_MAX_OBJECT);
var5 = it->x; // A global variable updated here!
- obj = objectTable + it->objIdx;
- sprite = animDataTable + obj->frame;
+ obj = &objectTable[it->objIdx];
+ sprite = &animDataTable[obj->frame];
if (obj->frame < 0 || it->x < 0 || it->x > 8 || !_bgTable[it->x].bg || sprite->_bpp != 1) {
break;
@@ -1109,13 +1117,24 @@ void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
maskBgOverlay(_bgTable[it->x].bg, sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, obj->x, obj->y);
break;
- // TODO: Figure out what this overlay type is and name it
- // TODO: Check it this implementation really works correctly (Some things might be wrong, needs testing)
+ // FIXME: Looking at Operation Stealth's disassembly I can't find any codepath that
+ // will draw a type 21 overlay. But looking at the first arcade sequence's scripts
+ // it looks like the oxygen gauge meter is implemented using a type 21 overlay.
+ // So for the time being I'm simply drawing type 21 overlays as type 22 overlays
+ // and hoping for the best.
+ // TODO: Check how the original game looks under DOSBox to see if the oxygen gauge works in it
+ case 21:
+ // A filled rectangle:
case 22: {
+ // TODO: Check it this implementation really works correctly (Some things might be wrong, needs testing).
assert(it->objIdx < NUM_MAX_OBJECT);
- obj = objectTable + it->objIdx;
- byte transCol = obj->part & 0x0F;
- drawPlainBox(obj->x, obj->y, obj->frame, obj->costume, transCol);
+ obj = &objectTable[it->objIdx];
+ byte color = obj->part & 0x0F;
+ int width = obj->frame;
+ int height = obj->costume;
+ drawPlainBox(obj->x, obj->y, width, height, color);
+ debug(5, "renderOverlay: type=%d, x=%d, y=%d, width=%d, height=%d, color=%d",
+ it->type, obj->x, obj->y, width, height, color);
break;
}
diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp
index 9361eb3822..3b0dc80bfb 100644
--- a/engines/cine/main_loop.cpp
+++ b/engines/cine/main_loop.cpp
@@ -333,9 +333,7 @@ void CineEngine::mainLoop(int bootScriptIdx) {
// Clear the zoneQuery table (Operation Stealth specific)
if (g_cine->getGameType() == Cine::GType_OS) {
- for (uint i = 0; i < NUM_MAX_ZONE; i++) {
- zoneQuery[i] = 0;
- }
+ Common::set_to(zoneQuery.begin(), zoneQuery.end(), 0);
}
if (g_cine->getGameType() == Cine::GType_OS) {
diff --git a/engines/cine/object.cpp b/engines/cine/object.cpp
index c02e01c8ce..9781975f7c 100644
--- a/engines/cine/object.cpp
+++ b/engines/cine/object.cpp
@@ -35,9 +35,16 @@
namespace Cine {
-objectStruct objectTable[NUM_MAX_OBJECT];
+Common::Array<objectStruct> objectTable;
Common::List<overlay> overlayList;
+/*! \brief Resets all elements in the object table. */
+void resetObjectTable() {
+ for (Common::Array<objectStruct>::iterator it = objectTable.begin(); it != objectTable.end(); it++) {
+ it->clear();
+ }
+}
+
void loadObject(char *pObjectName) {
uint16 numEntry;
uint16 entrySize;
diff --git a/engines/cine/object.h b/engines/cine/object.h
index 7ad65eb75f..3bf6cdcc42 100644
--- a/engines/cine/object.h
+++ b/engines/cine/object.h
@@ -38,6 +38,17 @@ struct objectStruct {
int16 costume;
char name[20];
uint16 part;
+
+ /*! \brief Sets all member variables to zero. */
+ void clear() {
+ this->x = 0;
+ this->y = 0;
+ this->mask = 0;
+ this->frame = 0;
+ this->costume = 0;
+ memset(this->name, 0, sizeof(this->name));
+ this->part = 0;
+ }
};
struct overlay {
@@ -52,10 +63,10 @@ struct overlay {
#define NUM_MAX_OBJECT 255
#define NUM_MAX_VAR 255
-extern objectStruct objectTable[NUM_MAX_OBJECT];
-
+extern Common::Array<objectStruct> objectTable;
extern Common::List<overlay> overlayList;
+void resetObjectTable();
void loadObject(char *pObjectName);
void setupObject(byte objIdx, uint16 param1, uint16 param2, uint16 param3, uint16 param4);
void modifyObjectParam(byte objIdx, byte paramIdx, int16 newValue);
diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp
index 0ead13e3ab..2fe2701e52 100644
--- a/engines/cine/various.cpp
+++ b/engines/cine/various.cpp
@@ -124,8 +124,8 @@ static const int16 canUseOnItemTable[] = { 1, 0, 0, 1, 1, 0, 0 };
CommandeType objectListCommand[20];
int16 objListTab[20];
-uint16 zoneData[NUM_MAX_ZONE];
-uint16 zoneQuery[NUM_MAX_ZONE]; //!< Only exists in Operation Stealth
+Common::Array<uint16> zoneData;
+Common::Array<uint16> zoneQuery; //!< Only exists in Operation Stealth
/*! \brief Move the player character using the keyboard
* \param x Negative values move left, positive right, zero not at all
@@ -616,16 +616,7 @@ void CineEngine::resetEngine() {
relTable.clear();
scriptTable.clear();
messageTable.clear();
-
- for (int i = 0; i < NUM_MAX_OBJECT; i++) {
- objectTable[i].x = 0;
- objectTable[i].y = 0;
- objectTable[i].part = 0;
- objectTable[i].name[0] = 0;
- objectTable[i].frame = 0;
- objectTable[i].mask = 0;
- objectTable[i].costume = 0;
- }
+ resetObjectTable();
globalVars.reset();
diff --git a/engines/cine/various.h b/engines/cine/various.h
index acab15e235..926a1821d9 100644
--- a/engines/cine/various.h
+++ b/engines/cine/various.h
@@ -127,8 +127,8 @@ struct SelectedObjStruct {
};
#define NUM_MAX_ZONE 16
-extern uint16 zoneData[NUM_MAX_ZONE];
-extern uint16 zoneQuery[NUM_MAX_ZONE];
+extern Common::Array<uint16> zoneData;
+extern Common::Array<uint16> zoneQuery;
void addMessage(byte param1, int16 param2, int16 param3, int16 param4, int16 param5);