diff options
Diffstat (limited to 'saga/actionmap.cpp')
-rw-r--r-- | saga/actionmap.cpp | 159 |
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); } } |