scummvm/saga/actionmap.cpp

193 lines
4.8 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2004 The ScummVM project
*
* The ReInherit Engine is (C)2000-2003 by Daniel Balsom.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
/* Action map module */
#include "saga/saga.h"
#include "saga/cvar_mod.h"
#include "saga/gfx.h"
#include "saga/console.h"
#include "saga/actionmap.h"
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
ACTIONMAP_ENTRY *exmap_entry;
CLICKAREA *clickarea;
Point *point;
assert(exmap_res != NULL);
MemoryReadStream readS(exmap_res, exmap_res_len);
// Load exits
_nExits = readS.readSint16LE();
if (_nExits < 0) {
return;
}
_exitsTbl = (ACTIONMAP_ENTRY *)malloc(_nExits * sizeof *_exitsTbl);
if (_exitsTbl == NULL) {
warning("Memory allocation failure");
return;
}
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->clickareas = (CLICKAREA *)malloc(exmap_entry->nClickareas * sizeof *(exmap_entry->clickareas));
if (exmap_entry->clickareas == NULL) {
warning("Error: Memory allocation failed");
return;
}
// 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();
}
}
}
}
ActionMap::~ActionMap(void) {
// Frees the currently loaded exit map data
ACTIONMAP_ENTRY *exmap_entry;
CLICKAREA *clickarea;
int i;
if (_exitsTbl) {
for (i = 0; i < _nExits; i++) {
exmap_entry = &_exitsTbl[i];
for (int k = 0; k < exmap_entry->nClickareas; k++) {
clickarea = &exmap_entry->clickareas[k];
free(clickarea->points);
}
free(exmap_entry->clickareas);
}
free(_exitsTbl);
}
}
const int ActionMap::getExitScene(int exitNum) {
assert(exitNum < _nExits);
return _exitsTbl[exitNum].exitScene;
}
int ActionMap::hitTest(const Point& imouse) {
ACTIONMAP_ENTRY *exmap_entry;
CLICKAREA *clickarea;
Point *points;
int n_points;
int i, k;
// Loop through all scene objects
for (i = 0; i < _nExits; i++) {
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 (hitTestPoly(points, n_points, imouse)) {
return i;
}
}
}
}
return -1;
}
int ActionMap::draw(SURFACE *ds, int color) {
ACTIONMAP_ENTRY *exmap_entry;
CLICKAREA *clickarea;
int i, k;
for (i = 0; i < _nExits; i++) {
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
drawFrame(ds, &clickarea->points[0], &clickarea->points[1], color);
} else if (clickarea->n_points > 2) {
// Otherwise draw a polyline
drawPolyLine(ds, clickarea->points, clickarea->n_points, color);
}
}
}
return SUCCESS;
}
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);
}
}
} // End of namespace Saga