aboutsummaryrefslogtreecommitdiff
path: root/saga/actionmap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'saga/actionmap.cpp')
-rw-r--r--saga/actionmap.cpp159
1 files changed, 102 insertions, 57 deletions
diff --git a/saga/actionmap.cpp b/saga/actionmap.cpp
index b3e647f0e0..613aa5e0b1 100644
--- a/saga/actionmap.cpp
+++ b/saga/actionmap.cpp
@@ -35,112 +35,157 @@ namespace Saga {
ActionMap::ActionMap(SagaEngine *vm, const byte * exmap_res, size_t exmap_res_len) : _vm(vm) {
// Loads exit map data from specified exit map resource
R_ACTIONMAP_ENTRY *exmap_entry;
- Point *exmap_pt_tbl;
-
- int exit_ct;
- int i, pt;
+ R_CLICKAREA *clickarea;
+ Point *point;
assert(exmap_res != NULL);
MemoryReadStream readS(exmap_res, exmap_res_len);
// Load exits
- exit_ct = readS.readSint16LE();
- if (exit_ct < 0) {
+ _nExits = readS.readSint16LE();
+ if (_nExits < 0) {
return;
}
- exmap_entry = (R_ACTIONMAP_ENTRY *)malloc(exit_ct * sizeof *exmap_entry);
- if (exmap_entry == NULL) {
+ _exitsTbl = (R_ACTIONMAP_ENTRY *)malloc(_nExits * sizeof *_exitsTbl);
+ if (_exitsTbl == NULL) {
warning("Memory allocation failure");
return;
}
- for (i = 0; i < exit_ct; i++) {
- exmap_entry[i].unknown00 = readS.readSint16LE();
- exmap_entry[i].unknown02 = readS.readSint16LE();
- exmap_entry[i].exitScene = readS.readSint16LE();
- exmap_entry[i].unknown06 = readS.readSint16LE();
+ for (int i = 0; i < _nExits; i++) {
+ exmap_entry = &_exitsTbl[i];
+ exmap_entry->flags = readS.readByte();
+ exmap_entry->nClickareas = readS.readByte();
+ exmap_entry->defaultVerb = readS.readByte();
+ readS.readByte();
+ exmap_entry->exitScene = readS.readUint16LE();
+ exmap_entry->entranceNum = readS.readUint16LE();
- exmap_entry[i].pt_count = readS.readSint16LE();
- if (exmap_entry[i].pt_count < 0) {
- free(exmap_entry);
- return;
- }
+ exmap_entry->clickareas = (R_CLICKAREA *)malloc(exmap_entry->nClickareas * sizeof *(exmap_entry->clickareas));
- exmap_pt_tbl = (Point *)malloc(exmap_entry[i].pt_count * sizeof *exmap_pt_tbl);
- if (exmap_pt_tbl == NULL) {
- warning("Memory allocation failure");
+ if (exmap_entry->clickareas == NULL) {
+ warning("Error: Memory allocation failed");
return;
}
- for (pt = 0; pt < exmap_entry[i].pt_count; pt++) {
- exmap_pt_tbl[pt].x = readS.readSint16LE();
- exmap_pt_tbl[pt].y = readS.readSint16LE();
+ // Load all clickareas for this object
+ for (int k = 0; k < exmap_entry->nClickareas; k++) {
+ clickarea = &exmap_entry->clickareas[k];
+ clickarea->n_points = readS.readUint16LE();
+ assert(clickarea->n_points != 0);
+
+ clickarea->points = (Point *)malloc(clickarea->n_points * sizeof *(clickarea->points));
+ if (clickarea->points == NULL) {
+ warning("Error: Memory allocation failed");
+ return;
+ }
+
+ // Load all points for this clickarea
+ for (int m = 0; m < clickarea->n_points; m++) {
+ point = &clickarea->points[m];
+ point->x = readS.readSint16LE();
+ point->y = readS.readSint16LE();
+ }
}
-
- exmap_entry[i].pt_tbl = exmap_pt_tbl;
}
-
- _nExits = exit_ct;
- _exitsTbl = exmap_entry;
}
ActionMap::~ActionMap(void) {
// Frees the currently loaded exit map data
R_ACTIONMAP_ENTRY *exmap_entry;
+ R_CLICKAREA *clickarea;
int i;
if (_exitsTbl) {
for (i = 0; i < _nExits; i++) {
exmap_entry = &_exitsTbl[i];
- if (exmap_entry != NULL)
- free(exmap_entry->pt_tbl);
+ for (int k = 0; k < exmap_entry->nClickareas; k++) {
+ clickarea = &exmap_entry->clickareas[k];
+ free(clickarea->points);
+ }
+ free(exmap_entry->clickareas);
}
free(_exitsTbl);
}
}
-int ActionMap::draw(R_SURFACE *ds, int color) {
- int i;
+const int ActionMap::getExitScene(int exitNum) {
+ assert(exitNum < _nExits);
+ return _exitsTbl[exitNum].exitScene;
+}
+
+
+int ActionMap::hitTest(Point imouse) {
+ R_ACTIONMAP_ENTRY *exmap_entry;
+ R_CLICKAREA *clickarea;
+ Point *points;
+ int n_points;
+
+ int i, k;
+
+ // Loop through all scene objects
for (i = 0; i < _nExits; i++) {
- if (_exitsTbl[i].pt_count == 2) {
- _vm->_gfx->drawFrame(ds,
- &_exitsTbl[i].pt_tbl[0],
- &_exitsTbl[i].pt_tbl[1], color);
- } else if (_exitsTbl[i].pt_count > 2) {
- _vm->_gfx->drawPolyLine(ds, _exitsTbl[i].pt_tbl,
- _exitsTbl[i].pt_count, color);
+ exmap_entry = &_exitsTbl[i];
+
+ // Hit-test all clickareas for this object
+ for (k = 0; k < exmap_entry->nClickareas; k++) {
+ clickarea = &exmap_entry->clickareas[k];
+ n_points = clickarea->n_points;
+ points = clickarea->points;
+
+ if (n_points == 2) {
+ // Hit-test a box region
+ if ((imouse.x > points[0].x) && (imouse.x <= points[1].x) &&
+ (imouse.y > points[0].y) &&
+ (imouse.y <= points[1].y)) {
+ return i;
+ }
+ } else if (n_points > 2) {
+ // Hit-test a polygon
+ if (_vm->_gfx->hitTestPoly(points, n_points, imouse)) {
+ return i;
+ }
+ }
}
}
- return R_SUCCESS;
+ return -1;
}
-void ActionMap::info(void) {
- Point *pt;
-
- int i;
- int pt_i;
+int ActionMap::draw(R_SURFACE *ds, int color) {
+ R_ACTIONMAP_ENTRY *exmap_entry;
+ R_CLICKAREA *clickarea;
- _vm->_console->print("%d exits loaded.\n", _nExits);
+ int i, k;
for (i = 0; i < _nExits; i++) {
- _vm->_console->print ("Action %d: Exit to: %d; Pts: %d; Unk0: %d Unk2: %d Scr_N: %d",
- i, _exitsTbl[i].exitScene,
- _exitsTbl[i].pt_count,
- _exitsTbl[i].unknown00,
- _exitsTbl[i].unknown02,
- _exitsTbl[i].unknown06);
+ exmap_entry = &_exitsTbl[i];
+
+ for (k = 0; k < exmap_entry->nClickareas; k++) {
+ clickarea = &exmap_entry->clickareas[k];
+ if (clickarea->n_points == 2) {
+ // 2 points represent a box
+ _vm->_gfx->drawFrame(ds, &clickarea->points[0], &clickarea->points[1], color);
+ } else if (clickarea->n_points > 2) {
+ // Otherwise draw a polyline
+ _vm->_gfx->drawPolyLine(ds, clickarea->points, clickarea->n_points, color);
+ }
+ }
+ }
- for (pt_i = 0; pt_i < _exitsTbl[i].pt_count; pt_i++) {
- pt = &_exitsTbl[i].pt_tbl[pt_i];
+ return R_SUCCESS;
+}
- _vm->_console->print(" pt: %d (%d, %d)", pt_i, pt->x, pt->y);
- }
+void ActionMap::info(void) {
+ _vm->_console->print("%d exits loaded.\n", _nExits);
+
+ for (int i = 0; i < _nExits; i++) {
+ _vm->_console->print ("Action %d: Exit to: %d", i, _exitsTbl[i].exitScene);
}
}