From 2289ea371b46a0696ae54923f32c1027b73afe34 Mon Sep 17 00:00:00 2001 From: Andrew Kurushin Date: Fri, 24 Dec 2004 20:44:39 +0000 Subject: - remove old stuff - work on "walking" in progress svn-id: r16298 --- saga/actionmap.cpp | 157 ++++++---------------- saga/actionmap.h | 50 +++---- saga/actor.cpp | 373 ++++++----------------------------------------------- saga/actor.h | 140 +------------------- saga/console.cpp | 24 ++-- saga/console.h | 8 +- saga/interface.cpp | 13 +- saga/objectmap.cpp | 100 +++++++++++++- saga/objectmap.h | 44 +++++-- saga/saga.h | 26 +++- saga/scene.cpp | 20 +-- saga/scene.h | 10 +- saga/script.h | 21 +-- saga/sfuncs.cpp | 46 +++---- saga/sthread.cpp | 26 +--- 15 files changed, 332 insertions(+), 726 deletions(-) (limited to 'saga') diff --git a/saga/actionmap.cpp b/saga/actionmap.cpp index 426bc1cda3..e629b799c3 100644 --- a/saga/actionmap.cpp +++ b/saga/actionmap.cpp @@ -32,125 +32,60 @@ 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); - - MemoryReadStreamEndian readS(exmap_res, exmap_res_len, IS_BIG_ENDIAN); +void ActionMap::load(const byte *resourcePointer, size_t resourceLength) { + int i; - // Load exits - _nExits = readS.readSint16(); - if (_nExits < 0) { - return; + if (resourceLength < 4) { + error("ActionMap::load wrong resourceLength"); } - _exitsTbl = (ACTIONMAP_ENTRY *)malloc(_nExits * sizeof *_exitsTbl); - if (_exitsTbl == NULL) { - warning("Memory allocation failure"); - return; - } + MemoryReadStreamEndian readS(resourcePointer, resourceLength, IS_BIG_ENDIAN); - 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.readUint16(); - exmap_entry->entranceNum = readS.readUint16(); + _stepZoneListCount = readS.readSint16(); + if (_stepZoneListCount < 0) { + error("ActionMap::load _stepZoneListCount < 0"); + } - exmap_entry->clickareas = (CLICKAREA *)malloc(exmap_entry->nClickareas * sizeof *(exmap_entry->clickareas)); + if (_stepZoneList) + error("ActionMap::load _stepZoneList != NULL"); - if (exmap_entry->clickareas == NULL) { - warning("Error: Memory allocation failed"); - return; - } + _stepZoneList = (HitZone **) malloc(_stepZoneListCount * sizeof (HitZone *)); + if (_stepZoneList == NULL) { + error("ActionMap::load Memory allocation failure"); + } - // Load all clickareas for this object - for (int k = 0; k < exmap_entry->nClickareas; k++) { - clickarea = &exmap_entry->clickareas[k]; - clickarea->n_points = readS.readUint16(); - 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.readSint16(); - point->y = readS.readSint16(); - } - } + for (i = 0; i < _stepZoneListCount; i++) { + _stepZoneList[i] = new HitZone(&readS); } } -ActionMap::~ActionMap(void) { - // Frees the currently loaded exit map data - ACTIONMAP_ENTRY *exmap_entry; - CLICKAREA *clickarea; +void ActionMap::freeMem() { 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); + if (_stepZoneList) { + for (i = 0; i < _stepZoneListCount; i++) { + delete _stepZoneList[i]; } - free(_exitsTbl); + free(_stepZoneList); } } -const int ActionMap::getExitScene(int exitNum) { - assert(exitNum < _nExits); +int ActionMap::getExitSceneNumber(int index) const { + if (index >= _stepZoneListCount) + error("ActionMap::getExitSceneNumber wrong index"); - return _exitsTbl[exitNum].exitScene; + return _stepZoneList[index]->getSceneNumber(); } - -int ActionMap::hitTest(const Point& imouse) { - ACTIONMAP_ENTRY *exmap_entry; - CLICKAREA *clickarea; - Point *points; - int n_points; - - int i, k; +int ActionMap::hitTest(const Point &testPoint) { + int i; // 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; - } - } + for (i = 0; i < _stepZoneListCount; i++) { + if (_stepZoneList[i]->hitTest(testPoint)) { + return i; } } @@ -158,34 +93,20 @@ int ActionMap::hitTest(const Point& imouse) { } 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); - } - } + int i; + + for (i = 0; i < _stepZoneListCount; i++) { + _stepZoneList[i]->draw(ds, color); } return SUCCESS; } -void ActionMap::info(void) { - _vm->_console->DebugPrintf("%d exits loaded.\n\n", _nExits); +void ActionMap::cmdInfo() { + _vm->_console->DebugPrintf("%d step zone(s) loaded.\n\n", _stepZoneListCount); - for (int i = 0; i < _nExits; i++) { - _vm->_console->DebugPrintf("Action %d: Exit to: %d\n", i, _exitsTbl[i].exitScene); + for (int i = 0; i < _stepZoneListCount; i++) { + _vm->_console->DebugPrintf("StepZone %d: Exit to Scene number: %d\n", i, _stepZoneList[i]->getSceneNumber()); } } diff --git a/saga/actionmap.h b/saga/actionmap.h index fa2f8dc887..12e6f7a9a3 100644 --- a/saga/actionmap.h +++ b/saga/actionmap.h @@ -26,49 +26,35 @@ #ifndef SAGA_ACTIONMAP_H_ #define SAGA_ACTIONMAP_H_ -namespace Saga { - -enum ACTION_FLAGS { - ACTION_ENABLED = (1<<0), // Zone is enabled - ACTION_EXIT = (1<<1), // Causes char to exit - - // The following flag causes the zone to act differently. - // When the actor hits the zone, it will immediately begin walking - // in the specified direction, and the actual specified effect of - // the zone will be delayed until the actor leaves the zone. - ACTION_AUTOWALK = (1<<2), - - // zone activates only when character stops walking - ACTION_TERMINUS = (1<<3) -}; +#include "saga/objectmap.h" -struct ACTIONMAP_ENTRY { - int flags; - int nClickareas; - int defaultVerb; - int exitScene; - int entranceNum; +namespace Saga { - CLICKAREA *clickareas; -}; class ActionMap { public: - int reg(void); - ActionMap(SagaEngine *vm, const byte *exmap_res, size_t exmap_res_len); - ~ActionMap(void); - - const int getExitScene(int exitNum); - int hitTest(const Point& imousePt); + ActionMap(SagaEngine *vm): _vm(vm) { + _stepZoneList = NULL; + _stepZoneListCount = 0; + } + ~ActionMap(void) { + freeMem(); + } + + void load(const byte *resourcePointer, size_t resourceLength); + void freeMem(); + + int getExitSceneNumber(int index) const; + int hitTest(const Point &testPoint); int draw(SURFACE *ds, int color); - void info(void); + void cmdInfo(); private: SagaEngine *_vm; - int _nExits; - ACTIONMAP_ENTRY *_exitsTbl; + int _stepZoneListCount; + HitZone **_stepZoneList; }; } // End of namespace Saga diff --git a/saga/actor.cpp b/saga/actor.cpp index 6ada6e5b0d..e8542628dc 100644 --- a/saga/actor.cpp +++ b/saga/actor.cpp @@ -53,11 +53,6 @@ static int actorCompare(const ActorDataPointer& actor1, const ActorDataPointer& } } -ACTIONTIMES ActionTDeltas[] = { - { ACTION_IDLE, 80 }, - { ACTION_WALK, 80 }, - { ACTION_SPEAK, 200 } -}; // Lookup table to convert 8 cardinal directions to 4 int ActorDirectectionsLUT[8] = { @@ -495,74 +490,6 @@ void Actor::handleActions(int msec, bool setup) { } int Actor::direct(int msec) { -/* int i; - ActorData *actor; - - ActorIntentList::iterator actorIntentIterator; - ACTORINTENT *a_intent; - - int o_idx; - int action_tdelta; - - // Walk down the actor list and direct each actor - for (i = 0; i < ACTORCOUNT; i++) { - actor = &_actors[i]; - if (actor->disabled) continue; - - // Process the actor intent list - actorIntentIterator = actor->a_intentlist.begin(); - if (actorIntentIterator != actor->a_intentlist.end()) { - a_intent = actorIntentIterator.operator->(); - switch (a_intent->a_itype) { - case INTENT_NONE: - // Actor doesn't really feel like doing anything at all - break; - case INTENT_PATH: - // Actor intends to go somewhere. Well good for him - { - handleWalkIntent(actor, &a_intent->walkIntent, &a_intent->a_idone, msec); - } - break; - default: - break; - } - - // If this actor intent was flagged as completed, remove it. - if (a_intent->a_idone) { - actor->a_intentlist.erase(actorIntentIterator); - actor->action = actor->def_action; - actor->action_flags = actor->def_action_flags; - actor->action_frame = 0; - actor->action_time = 0; - } - } else { - // Actor has no intent, idle? - } - - // Process actor actions - actor->action_time += msec; - - if (actor->action >= ACTION_COUNT) { - action_tdelta = ACTOR_ACTIONTIME; - } else { - action_tdelta = ActionTDeltas[actor->action].time; - } - - if (actor->action_time >= action_tdelta) { - actor->action_time -= action_tdelta; - actor->action_frame++; - - o_idx = ActorOrientationLUT[actor->orient]; - if (actor->frames[actor->action].dir[o_idx].frameCount <= actor->action_frame) { - if (actor->action_flags & ACTION_LOOP) { - actor->action_frame = 0; - } else { - actor->action_frame--; - } - } - } - } -*/ // FIXME: HACK. This should be turned into cycle event. _lastTickMsec += msec; @@ -591,26 +518,31 @@ void Actor::createDrawOrderList() { _drawOrderList.pushBack(actor, actorCompare); - middle = ITE_STATUS_Y - actor->location.y / ACTOR_LMULT, + // tiled stuff + { + } + { + middle = ITE_STATUS_Y - actor->location.y / ACTOR_LMULT, - _vm->_scene->getSlopes(beginSlope, endSlope); + _vm->_scene->getSlopes(beginSlope, endSlope); - actor->screenDepth = (14 * middle) / endSlope + 1; + actor->screenDepth = (14 * middle) / endSlope + 1; - if (middle <= beginSlope) { - actor->screenScale = 256; - } else { - if (middle >= endSlope) { - actor->screenScale = 1; + if (middle <= beginSlope) { + actor->screenScale = 256; } else { - middle -= beginSlope; - endSlope -= beginSlope; - actor->screenScale = 256 - (middle * 256) / endSlope; + if (middle >= endSlope) { + actor->screenScale = 1; + } else { + middle -= beginSlope; + endSlope -= beginSlope; + actor->screenScale = 256 - (middle * 256) / endSlope; + } } - } - actor->screenPosition.x = (actor->location.x / ACTOR_LMULT); - actor->screenPosition.y = (actor->location.y / ACTOR_LMULT) - actor->location.z; + actor->screenPosition.x = (actor->location.x / ACTOR_LMULT); + actor->screenPosition.y = (actor->location.y / ACTOR_LMULT) - actor->location.z; + } } } @@ -645,7 +577,10 @@ int Actor::drawActors() { warning("Actor::drawActors frameNumber invalid for actorId 0x%X", actor->actorId); continue; } - + + // tiled stuff + { + } _vm->_sprite->drawOccluded(back_buf, spriteList, frameNumber, actor->screenPosition, actor->screenScale, actor->screenDepth); } @@ -694,262 +629,36 @@ int Actor::drawActors() { return SUCCESS; } -/* -void Actor::setOrientation(uint16 actorId, int orient) { - ActorData *actor; - - actor = getActor(actorId); - if ((orient < 0) || (orient > 7)) { - error("Actor::setOrientation wrong orientation 0x%X", orient); - } - - actor->orient = orient; +void Actor::StoA(Point &actorPoint, const Point &screenPoint) { + actorPoint.x = (screenPoint.x * ACTOR_LMULT); + actorPoint.y = (screenPoint.y * ACTOR_LMULT); } -void Actor::setAction(uint16 actorId, int action_n, uint16 action_flags) { +bool Actor::actorWalkTo(uint16 actorId, const ActorLocation &actorLocation) { + BOOL result = TRUE; ActorData *actor; actor = getActor(actorId); - if ((action_n < 0) || (action_n >= actor->framesCount)) { - error("Actor::setAction wrong action_n 0x%X", action_n); +/* if (a == protag) + { + sceneDoors[ 2 ] = 0xff; // closed + sceneDoors[ 3 ] = 0; // open } + else + { + sceneDoors[ 2 ] = 0; // open + sceneDoors[ 3 ] = 0xff; // closed + }*/ - actor->action = action_n; - actor->action_flags = action_flags; - actor->action_frame = 0; - actor->action_time = 0; - -} - -void Actor::setDefaultAction(uint16 actorId, int action_n, uint16 action_flags) { - ActorData *actor; - - actor = getActor(actorId); - - if ((action_n < 0) || (action_n >= actor->framesCount)) { - error("Actor::setDefaultAction wrong action_n 0x%X", action_n); + // tiled stuff + { } - - actor->def_action = action_n; - actor->def_action_flags = action_flags; -} - -void Actor::walkTo(uint16 actorId, const Point *walk_pt, uint16 flags, SEMAPHORE *sem) { - ACTORINTENT actor_intent; - ActorData *actor; - - assert(walk_pt != NULL); - - actor = getActor(actorId); - - actor_intent.a_itype = INTENT_PATH; - actor_intent.a_iflags = 0; - - - actor_intent.walkIntent.wi_flags = flags; - actor_intent.walkIntent.sem_held = 1; - actor_intent.walkIntent.sem = sem; - - // handleWalkIntent() will create path on initialization - actor_intent.walkIntent.wi_init = 0; - actor_intent.walkIntent.dst_pt = *walk_pt; - - actor->a_intentlist.push_back(actor_intent); - int is = actor->a_intentlist.size(); - debug(9, "actor->a_intentlist.size() %i", is); - - if (sem != NULL) { - _vm->_script->SThreadHoldSem(sem); + { } -} -*/ -int Actor::setPathNode(WALKINTENT *walk_int, const Point &src_pt, Point *dst_pt, SEMAPHORE *sem) { - WALKNODE new_node; + return false; - walk_int->wi_active = 1; - walk_int->org = src_pt; - - assert((walk_int != NULL) && (dst_pt != NULL)); - - new_node.node_pt = *dst_pt; - new_node.calc_flag = 0; - - walk_int->nodelist.push_back(new_node); - - return SUCCESS; -} -/* -int Actor::handleWalkIntent(ActorData *actor, WALKINTENT *a_walkint, int *complete_p, int delta_time) { - WalkNodeList::iterator walkNodeIterator; - WalkNodeList::iterator nextWalkNodeIterator; - - WALKNODE *node_p; - int dx; - int dy; - - double path_a; - double path_b; - double path_slope; - - double path_x; - double path_y; - int path_time; - - double new_a_x; - double new_a_y; - - int actor_x; - int actor_y; - - char buf[100]; - - // Initialize walk intent - if (!a_walkint->wi_init) { - setPathNode(a_walkint, Point(actor->actorX,actor->actorY), &a_walkint->dst_pt, a_walkint->sem); - setDefaultAction(actor->actorId, ACTION_IDLE, ACTION_NONE); - a_walkint->wi_init = 1; - } - - assert(a_walkint->wi_active); - - walkNodeIterator = a_walkint->nodelist.begin(); - nextWalkNodeIterator = walkNodeIterator; - - node_p = walkNodeIterator.operator->(); - - if (node_p->calc_flag == 0) { - - debug(2, "Calculating new path vector to point (%d, %d)", node_p->node_pt.x, node_p->node_pt.y); - - dx = a_walkint->org.x - node_p->node_pt.x; - dy = a_walkint->org.y - node_p->node_pt.y; - - if (dx == 0) { - - debug(0, "Vertical paths not implemented."); - - a_walkint->nodelist.erase(walkNodeIterator); - a_walkint->wi_active = 0; - - // Release path semaphore - if ((a_walkint->sem != NULL) && a_walkint->sem_held) { - _vm->_script->SThreadReleaseSem(a_walkint->sem); - } - - *complete_p = 1; - return FAILURE; - } - - a_walkint->slope = (float)dy / dx; - - if (dx > 0) { - a_walkint->x_dir = -1; - if (!(a_walkint->wi_flags & WALK_NOREORIENT)) { - if (a_walkint->slope > 1.0) { - actor->orient = ORIENT_N; - } else if (a_walkint->slope < -1.0) { - actor->orient = ORIENT_S; - } else { - actor->orient = ORIENT_W; - } - } - } else { - a_walkint->x_dir = 1; - if (!(a_walkint->wi_flags & WALK_NOREORIENT)) { - if (a_walkint->slope > 1.0) { - actor->orient = ORIENT_S; - } else if (a_walkint->slope < -1.0) { - actor->orient = ORIENT_N; - } else { - actor->orient = ORIENT_E; - } - } - } - - sprintf(buf, "%f", a_walkint->slope); - - debug(2, "Path slope: %s.", buf); - - actor->action = ACTION_WALK; - actor->action_flags = ACTION_LOOP; - a_walkint->time = 0; - node_p->calc_flag = 1; - } - - a_walkint->time += delta_time; - path_time = a_walkint->time; - - path_a = ACTOR_BASE_SPEED * path_time; - path_b = ACTOR_BASE_SPEED * path_time * ACTOR_BASE_ZMOD; - path_slope = a_walkint->slope * a_walkint->x_dir; - - path_x = (path_a * path_b) / sqrt((path_a * path_a) * (path_slope * path_slope) + (path_b * path_b)); - - path_y = path_slope * path_x; - path_x = path_x * a_walkint->x_dir; - - new_a_x = path_x + a_walkint->org.x; - new_a_y = path_y + a_walkint->org.y; - - if (((a_walkint->x_dir == 1) && new_a_x >= node_p->node_pt.x) || - ((a_walkint->x_dir != 1) && (new_a_x <= node_p->node_pt.x))) { - Point endpoint; - int exitNum; - - debug(2, "Path complete."); - a_walkint->nodelist.erase(walkNodeIterator); - a_walkint->wi_active = 0; - - // Release path semaphore - if (a_walkint->sem != NULL) { - _vm->_script->SThreadReleaseSem(a_walkint->sem); - } - - actor->action_frame = 0; - actor->action = ACTION_IDLE; - - endpoint.x = (int)new_a_x / ACTOR_LMULT; - endpoint.y = (int)new_a_y / ACTOR_LMULT; - if ((exitNum = _vm->_scene->_actionMap->hitTest(endpoint)) != -1) { - if (actor->flags & kProtagonist) - _vm->_scene->changeScene(_vm->_scene->_actionMap->getExitScene(exitNum)); - } - *complete_p = 1; - return FAILURE; - } - - actor_x = (int)new_a_x; - actor_y = (int)new_a_y; - - actor->actorX = (int)new_a_x; - actor->actorY = (int)new_a_y; - - return SUCCESS; -} - -void Actor::move(uint16 actorId, const Point &movePoint) { - ActorData *actor; - - actor = getActor(actorId); - - actor->actorX = movePoint.x; - actor->actorY = movePoint.y; -} - -void Actor::moveRelative(uint16 actorId, const Point &movePoint) { - ActorData *actor; - - actor = getActor(actorId); - - actor->actorX += movePoint.x; - actor->actorY += movePoint.y; -} -*/ -void Actor::StoA(Point &actorPoint, const Point &screenPoint) { - actorPoint.x = (screenPoint.x * ACTOR_LMULT); - actorPoint.y = (screenPoint.y * ACTOR_LMULT); } void Actor::actorSpeech(uint16 actorId, const char **strings, int stringsCount, uint16 sampleResourceId, int speechFlags) { diff --git a/saga/actor.h b/saga/actor.h index 80722baf14..bc445324dc 100644 --- a/saga/actor.h +++ b/saga/actor.h @@ -83,17 +83,6 @@ enum SpeechFlags { kSpeakSlow = 4 }; -enum ActorDirections { - kDirUp = 0, - kDirUpRight = 1, - kDirRight = 2, - kDirDownRight = 3, - kDirDown = 4, - kDirDownLeft = 5, - kDirLeft = 6, - kDirUpLeft = 7 -}; - enum ActorFrameTypes { kFrameStand = 0, kFrameWalk = 1, @@ -121,38 +110,6 @@ enum ActorFlagsEx { kActorRandom = (1 << 10) }; -enum ACTOR_INTENTS { - INTENT_NONE = 0, - INTENT_PATH = 1 -}; - -enum ACTOR_WALKFLAGS { - WALK_NONE = 0x00, - WALK_NOREORIENT = 0x01 -}; - -enum ACTOR_ORIENTATIONS { - ORIENT_N = 0, - ORIENT_NE = 1, - ORIENT_E = 2, - ORIENT_SE = 3, - ORIENT_S = 4, - ORIENT_SW = 5, - ORIENT_W = 6, - ORIENT_NW = 7 -}; - -enum ACTOR_ACTIONS { - ACTION_IDLE = 0, - ACTION_WALK = 1, - ACTION_SPEAK = 2, - ACTION_COUNT -}; - -enum ACTOR_ACTIONFLAGS { - ACTION_NONE = 0x00, - ACTION_LOOP = 0x01 -}; struct ActorFrameRange { int frameIndex; @@ -163,63 +120,6 @@ struct ActorFrameSequence { ActorFrameRange directions[ACTOR_DIRECTIONS_COUNT]; }; -struct WALKNODE { - int calc_flag; - Point node_pt; - WALKNODE() { - calc_flag = 0; - } -}; - -typedef Common::List WalkNodeList; - -struct WALKINTENT { - int wi_active; - uint16 wi_flags; - int wi_init; - - int time; - float slope; - int x_dir; - Point org; - Point cur; - - Point dst_pt; - WalkNodeList nodelist; - - int sem_held; - SEMAPHORE *sem; - - WALKINTENT() { - wi_active = 0; - wi_flags = 0; - wi_init = 0; - - time = 0; - slope = 0; - x_dir = 0; - - sem_held = 0; - sem = NULL; - } -}; - -struct ACTORINTENT { - int a_itype; - uint16 a_iflags; - int a_idone; - - WALKINTENT walkIntent; - - ACTORINTENT() { - a_itype = 0; - a_iflags = 0; - a_idone = 0; - } -}; - -typedef Common::List ActorIntentList; - struct ActorLocation { int x; // Actor's logical coordinates int y; // @@ -261,20 +161,6 @@ struct ActorData { int framesCount; // Actor's frames count int frameListResourceId; // Actor's frame list resource id - - -///old stuff - int idle_time; - int orient; - int speaking; - ActorIntentList a_intentlist; - int def_action; - uint16 def_action_flags; - int action; - uint16 action_flags; - int action_frame; - int action_time; -/// end old stuff void cycleWrap(int cycleLimit) { if (actionCycle >= cycleLimit) @@ -315,27 +201,12 @@ struct ActorData { cycleTimeCount = 0; cycleFlags = 0; - idle_time = 0; - orient = 0; - speaking = 0; - def_action = 0; - def_action_flags = 0; - action = 0; - action_flags = 0; - action_frame = 0; - action_time = 0; } }; typedef ActorData* ActorDataPointer; typedef SortedList ActorOrderList; - -struct ACTIONTIMES { - int action; - int time; -}; - struct SpeechData { int speechColor; int outlineColor; @@ -373,13 +244,9 @@ public: void StoA(Point &actorPoint, const Point &screenPoint); - void move(uint16 actorId, const Point &movePoint){} - void moveRelative(uint16 actorId, const Point &movePoint){} - - void walkTo(uint16 actorId, const Point *walk_pt, uint16 flags, SEMAPHORE *sem) {} - + + bool actorWalkTo(uint16 actorId, const ActorLocation &actorLocation); ActorData *getActor(uint16 actorId); -// action ActorFrameRange *getActorFrameRange(uint16 actorId, int frameType); // speech @@ -397,9 +264,6 @@ public: } private: - int handleWalkIntent(ActorData *actor, WALKINTENT *a_walk_int, int *complete_p, int msec); - int setPathNode(WALKINTENT *walk_int, const Point &src_pt, Point *dst_pt, SEMAPHORE *sem); - bool loadActorResources(ActorData * actor); void createDrawOrderList(); diff --git a/saga/console.cpp b/saga/console.cpp index 903a91cd0b..b10230ae5b 100644 --- a/saga/console.cpp +++ b/saga/console.cpp @@ -68,10 +68,10 @@ Console::Console(SagaEngine *vm) : Common::Debugger() { #endif // Scene commands - DCmd_Register("scene_change", &Console::Cmd_SceneChange); - DCmd_Register("scene_info", &Console::Cmd_SceneInfo); - DCmd_Register("action_info", &Console::Cmd_ActionInfo); - DCmd_Register("object_info", &Console::Cmd_ObjectInfo); + DCmd_Register("scene_change", &Console::cmdSceneChange); + DCmd_Register("scene_info", &Console::cmdSceneInfo); + DCmd_Register("action_map_info", &Console::cmdActionMapInfo); + DCmd_Register("object_map_info", &Console::cmdObjectMapInfo); // CVAR_Register_I(&_sceneNumber, "scene", NULL, CVAR_READONLY, 0, 0); // Script commands @@ -187,26 +187,26 @@ bool Console::Cmd_AnimInfo(int argc, const char **argv) { return true; } -bool Console::Cmd_SceneChange(int argc, const char **argv) { +bool Console::cmdSceneChange(int argc, const char **argv) { if (argc != 2) DebugPrintf("Usage: %s \n", argv[0]); else - _vm->_scene->sceneChangeCmd(argc, argv); + _vm->_scene->cmdSceneChange(argc, argv); return true; } -bool Console::Cmd_SceneInfo(int argc, const char **argv) { - _vm->_scene->sceneInfoCmd(); +bool Console::cmdSceneInfo(int argc, const char **argv) { + _vm->_scene->cmdSceneInfo(); return true; } -bool Console::Cmd_ActionInfo(int argc, const char **argv) { - _vm->_scene->CF_actioninfo(); +bool Console::cmdActionMapInfo(int argc, const char **argv) { + _vm->_scene->cmdActionMapInfo(); return true; } -bool Console::Cmd_ObjectInfo(int argc, const char **argv) { - _vm->_scene->CF_objectinfo(); +bool Console::cmdObjectMapInfo(int argc, const char **argv) { + _vm->_scene->cmdObjectMapInfo(); return true; } diff --git a/saga/console.h b/saga/console.h index c4b1ea34ed..8c82abee16 100644 --- a/saga/console.h +++ b/saga/console.h @@ -52,10 +52,10 @@ private: bool Cmd_AnimInfo(int argc, const char **argv); - bool Cmd_SceneChange(int argc, const char **argv); - bool Cmd_SceneInfo(int argc, const char **argv); - bool Cmd_ActionInfo(int argc, const char **argv); - bool Cmd_ObjectInfo(int argc, const char **argv); + bool cmdSceneChange(int argc, const char **argv); + bool cmdSceneInfo(int argc, const char **argv); + bool cmdActionMapInfo(int argc, const char **argv); + bool cmdObjectMapInfo(int argc, const char **argv); bool Cmd_ScriptInfo(int argc, const char **argv); bool Cmd_ScriptExec(int argc, const char **argv); diff --git a/saga/interface.cpp b/saga/interface.cpp index a2f42d2318..b951d4203b 100644 --- a/saga/interface.cpp +++ b/saga/interface.cpp @@ -555,6 +555,8 @@ int Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePt) { } int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) { + return FALSE; +/* int objectNum; uint16 object_flags = 0; @@ -566,6 +568,8 @@ int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) { if (objectNum == -1) { // Player clicked on empty spot - walk here regardless of verb _vm->_actor->StoA(iactor_pt, imousePt); + error("!"); + _vm->_actor->walkTo(1, &iactor_pt, 0, NULL); return SUCCESS; } @@ -585,13 +589,17 @@ int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) { } else { // Not a normal scene object - walk to it as if it weren't there _vm->_actor->StoA(iactor_pt, imousePt); - _vm->_actor->walkTo(1, &iactor_pt, 0, NULL); +// _vm->_actor->walkTo(1, &iactor_pt, 0, NULL); + error("!"); + } - return SUCCESS; + return SUCCESS;*/ } int Interface::handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt) { + return FALSE; + /* const char *object_name; int objectNum; uint16 object_flags = 0; @@ -623,6 +631,7 @@ int Interface::handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt) { setStatusText(new_status); return SUCCESS; + */ } int Interface::hitTest(const Point& imousePt, int *ibutton) { diff --git a/saga/objectmap.cpp b/saga/objectmap.cpp index fcae5c4d75..a9976711da 100644 --- a/saga/objectmap.cpp +++ b/saga/objectmap.cpp @@ -36,6 +36,103 @@ namespace Saga { +HitZone::HitZone(MemoryReadStreamEndian *readStream) { + int i, j; + HitZone::ClickArea *clickArea; + Point *point; + + _flags = readStream->readByte(); + _clickAreasCount = readStream->readByte(); + _defaultVerb = readStream->readByte(); + readStream->readByte(); // pad + _nameNumber = readStream->readUint16(); + _scriptNumber = readStream->readUint16(); + + _clickAreas = (HitZone::ClickArea *)malloc(_clickAreasCount * sizeof *_clickAreas); + + if (_clickAreas == NULL) { + error("HitZone::HitZone Memory allocation failed"); + } + + for (i = 0; i < _clickAreasCount; i++) { + clickArea = &_clickAreas[i]; + clickArea->pointsCount = readStream->readUint16(); + + assert(clickArea->pointsCount); + + clickArea->points = (Point *)malloc(clickArea->pointsCount * sizeof *(clickArea->points)); + if (clickArea->points == NULL) { + error("HitZone::HitZone Memory allocation failed"); + } + + for (j = 0; j < clickArea->pointsCount; j++) { + point = &clickArea->points[j]; + point->x = readStream->readSint16(); + point->y = readStream->readSint16(); + } + } +} + +HitZone::~HitZone() { + for (int i = 0; i < _clickAreasCount; i++) { + free(_clickAreas[i].points); + } + free(_clickAreas); +} + +bool HitZone::hitTest(const Point &testPoint) { + int i, pointsCount; + HitZone::ClickArea *clickArea; + Point *points; + + if (_flags & kHitZoneEnabled) { + for (i = 0; i < _clickAreasCount; i++) { + clickArea = &_clickAreas[i]; + pointsCount = clickArea->pointsCount; + points = clickArea->points; + + if (pointsCount == 2) { + // Hit-test a box region + if ((testPoint.x >= points[0].x) && + (testPoint.x <= points[1].x) && + (testPoint.y >= points[0].y) && + (testPoint.y <= points[1].y)) { + return true; + } + } else { + if (pointsCount > 2) { + // Hit-test a polygon + if (hitTestPoly(points, pointsCount, testPoint)) { + return true; + } + } + } + } + } + return false; +} + +void HitZone::draw(SURFACE *ds, int color) { + int i, pointsCount; + HitZone::ClickArea *clickArea; + Point *points; + for (i = 0; i < _clickAreasCount; i++) { + clickArea = &_clickAreas[i]; + pointsCount = clickArea->pointsCount; + points = clickArea->points; + if (pointsCount == 2) { + // 2 points represent a box + drawFrame(ds, &points[0], &points[1], color); + } else { + if (pointsCount > 2) { + // Otherwise draw a polyline + drawPolyLine(ds, points, pointsCount, color); + } + } + } +} + + // Initializes the object map module, creates module allocation context ObjectMap::ObjectMap(SagaEngine *vm) : _vm(vm) { _objectsLoaded = false; @@ -225,6 +322,7 @@ const uint16 ObjectMap::getFlags(int object) { return 0; } + // If 'object' is a valid object number in the currently loaded object // name list resource, the funciton sets '*ep_num' to the entrypoint number // corresponding to 'object' and returns SUCCESS. Otherwise, it returns @@ -342,7 +440,7 @@ int ObjectMap::hitTest(const Point& imousePt) { return -1; } -void ObjectMap::info(void) { +void ObjectMap::cmdInfo(void) { int i; _vm->_console->DebugPrintf("%d objects loaded.\n", _nObjects); diff --git a/saga/objectmap.h b/saga/objectmap.h index 4e1d326507..b025602016 100644 --- a/saga/objectmap.h +++ b/saga/objectmap.h @@ -26,22 +26,43 @@ #ifndef SAGA_OBJECTMAP_H_ #define SAGA_OBJECTMAP_H_ +#include "saga/stream.h" + namespace Saga { -enum OBJECT_FLAGS { - OBJECT_ENABLED = (1<<0), // Object is enabled - OBJECT_EXIT = (1<<1), // Causes char to exit - // Causes the character not to walk to the object (but they will - // look at it). - OBJECT_NOWALK = (1<<2), +class HitZone { +private: + struct ClickArea { + int pointsCount; + Point *points; + }; +public: + + HitZone(MemoryReadStreamEndian *readStream); + ~HitZone(); + + int getSceneNumber() const { + return _nameNumber; + } + + int getEntranceNumber() const { + return _scriptNumber; + } + + void draw(SURFACE *ds, int color); + bool hitTest(const Point &testPoint); +private: + int _flags; // HitZoneFlags + int _clickAreasCount; + int _defaultVerb; + int _nameNumber; + int _scriptNumber; - // When the object is clicked on it projects the - // click point downwards from the middle of the object until it - // reaches the lowest point in the zone. - OBJECT_PROJECT = (1<<3) + ClickArea *_clickAreas; }; + struct OBJECTMAP_ENTRY { byte flags; byte defaultVerb; @@ -55,7 +76,6 @@ struct OBJECTMAP_ENTRY { class ObjectMap{ public: - int reg(void); ObjectMap(SagaEngine *vm); ~ObjectMap(void); int load(const byte *om_res, size_t om_res_len); @@ -67,7 +87,7 @@ public: const int getEPNum(int object); int draw(SURFACE *draw_surface, const Point& imousePt, int color, int color2); int hitTest(const Point& imousePt); - void info(void); + void cmdInfo(void); private: diff --git a/saga/saga.h b/saga/saga.h index 5ca7191149..62442e4879 100644 --- a/saga/saga.h +++ b/saga/saga.h @@ -64,7 +64,6 @@ class PalAnim; #define MAXPATH 512 struct RSCFILE_CONTEXT; -struct SEMAPHORE; struct SPRITELIST; enum ERRORCODE { @@ -82,6 +81,31 @@ enum scriptTimings { kScriptTimeTicksPerSecond = (728L/10L) }; +enum Directions { + kDirUp = 0, + kDirUpRight = 1, + kDirRight = 2, + kDirDownRight = 3, + kDirDown = 4, + kDirDownLeft = 5, + kDirLeft = 6, + kDirUpLeft = 7 +}; + +enum HitZoneFlags { + kHitZoneEnabled = (1 << 0), // Zone is enabled + kHitZoneExit = (1 << 1), // Causes char to exit + + // The following flag causes the zone to act differently. + // When the actor hits the zone, it will immediately begin walking + // in the specified direction, and the actual specified effect of + // the zone will be delayed until the actor leaves the zone. + kHitZoneAutoWalk = (1 << 2), + + // zone activates only when character stops walking + kHitZoneTerminus = (1 << 3) +}; + struct CLICKAREA { int n_points; Point *points; diff --git a/saga/scene.cpp b/saga/scene.cpp index 8793bc57cf..b159fd1304 100644 --- a/saga/scene.cpp +++ b/saga/scene.cpp @@ -119,7 +119,7 @@ Scene::Scene(SagaEngine *vm) : _vm(vm), _initialized(false) { _animEntries = 0; _sceneProc = NULL; _objectMap = NULL; - _actionMap = NULL; + _actionMap = new ActionMap(_vm); memset(&_bg, 0, sizeof(_bg)); memset(&_bgMask, 0, sizeof(_bgMask)); @@ -129,6 +129,7 @@ Scene::Scene(SagaEngine *vm) : _vm(vm), _initialized(false) { Scene::~Scene() { if (_initialized) { endScene(); + delete _actionMap; free(_sceneLUT); } } @@ -684,7 +685,7 @@ int Scene::processSceneResources() { break; case SAGA_ACTION_MAP: debug(0, "Loading exit map resource..."); - _actionMap = new ActionMap(_vm, res_data, res_data_len); + _actionMap->load(res_data, res_data_len); break; case SAGA_ISO_TILESET: if (_sceneMode == SCENE_MODE_NORMAL) { @@ -850,10 +851,9 @@ int Scene::endScene() { _vm->_palanim->freePalAnim(); delete _objectMap; - delete _actionMap; _objectMap = NULL; - _actionMap = NULL; + _actionMap->freeMem(); _animList.clear(); @@ -867,7 +867,7 @@ int Scene::endScene() { return SUCCESS; } -void Scene::sceneChangeCmd(int argc, const char **argv) { +void Scene::cmdSceneChange(int argc, const char **argv) { int scene_num = 0; scene_num = atoi(argv[1]); @@ -886,7 +886,7 @@ void Scene::sceneChangeCmd(int argc, const char **argv) { } } -void Scene::sceneInfoCmd() { +void Scene::cmdSceneInfo() { const char *fmt = "%-20s %d\n"; _vm->_console->DebugPrintf(fmt, "Scene number:", _sceneNumber); @@ -906,12 +906,12 @@ int Scene::SC_defaultScene(int param, SCENE_INFO *scene_info, void *refCon) { return ((Scene *)refCon)->defaultScene(param, scene_info); } -void Scene::CF_actioninfo() { - _actionMap->info(); +void Scene::cmdActionMapInfo() { + _actionMap->cmdInfo(); } -void Scene::CF_objectinfo() { - _objectMap->info(); +void Scene::cmdObjectMapInfo() { + _objectMap->cmdInfo(); } int Scene::defaultScene(int param, SCENE_INFO *scene_info) { diff --git a/saga/scene.h b/saga/scene.h index 5f2bf3678b..b05693ca01 100644 --- a/saga/scene.h +++ b/saga/scene.h @@ -214,8 +214,12 @@ class Scene { Scene(SagaEngine *vm); ~Scene(); - void CF_actioninfo(); - void CF_objectinfo(); +// Console functions + void cmdSceneInfo(); + void cmdActionMapInfo(); + void cmdObjectMapInfo(); + + void cmdSceneChange(int argc, const char **argv); int startScene(); int nextScene(); @@ -236,8 +240,6 @@ class Scene { bool initialized() { return _initialized; } - void sceneInfoCmd(); - void sceneChangeCmd(int argc, const char **argv); int getSceneLUT(int num); int currentSceneNumber() { return _sceneNumber; } diff --git a/saga/script.h b/saga/script.h index 50dc69f739..7f230361f5 100644 --- a/saga/script.h +++ b/saga/script.h @@ -64,10 +64,6 @@ enum SCRIPT_VERBS { #define STHREAD_TIMESLICE 8 -struct SEMAPHORE { - int hold_count; -}; - enum { kVarObject = 0, kVarWithObject, @@ -109,6 +105,7 @@ enum CycleFlags { kCycleRandom = (1 << 2), kCycleReverse = (1 << 3) }; + struct SCRIPT_THREAD { int flags; // ThreadFlags int waitType; // ThreadWaitTypes @@ -119,8 +116,6 @@ struct SCRIPT_THREAD { unsigned long ep_offset; // Entrypoint offset unsigned long i_offset; // Instruction offset - SEMAPHORE sem; // FIXME: no equivalent. should be replaced with flags - // The scripts are allowed to access the stack like any other memory // area. It's therefore probably quite important that our stacks work // the same as in the original interpreter. @@ -157,6 +152,16 @@ struct SCRIPT_THREAD { flags |= kTFlagWaiting; } + void waitWalk(void *aThreadObj) { + wait(kWaitTypeWalk); + threadObj = aThreadObj; + } + + void waitDelay(int aSleepTime) { + wait(kWaitTypeDelay); + sleepTime = aSleepTime; + } + SCRIPT_THREAD() { memset(this, 0, sizeof(*this)); } }; @@ -257,8 +262,6 @@ public: SCRIPT_THREAD *SThreadCreate(); int SThreadExecute(SCRIPT_THREAD *thread, int ep_num); int executeThreads(uint msec); - int SThreadHoldSem(SEMAPHORE *sem); - int SThreadReleaseSem(SEMAPHORE *sem); int SThreadDebugStep(); void SThreadCompleteThread(void); int SThreadDestroy(SCRIPT_THREAD *thread); @@ -293,7 +296,7 @@ private: int SF_objectIsCarried(SCRIPTFUNC_PARAMS); int SF_setStatusText(SCRIPTFUNC_PARAMS); int SF_commandMode(SCRIPTFUNC_PARAMS); - int SF_actorWalkTo(SCRIPTFUNC_PARAMS); + int sfScriptWalkTo(SCRIPTFUNC_PARAMS); int SF_doAction(SCRIPTFUNC_PARAMS); int sfSetActorFacing(SCRIPTFUNC_PARAMS); int SF_startBgdAnim(SCRIPTFUNC_PARAMS); diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp index f62d589967..9bfc78ce8d 100644 --- a/saga/sfuncs.cpp +++ b/saga/sfuncs.cpp @@ -51,7 +51,7 @@ void Script::setupScriptFuncList(void) { OPCODE(SF_objectIsCarried), OPCODE(SF_setStatusText), OPCODE(SF_commandMode), - OPCODE(SF_actorWalkTo), + OPCODE(sfScriptWalkTo), OPCODE(SF_doAction), OPCODE(sfSetActorFacing), OPCODE(SF_startBgdAnim), @@ -143,8 +143,7 @@ int Script::sfWait(SCRIPTFUNC_PARAMS) { time = getUWord(thread->pop()); if (!_skipSpeeches) { - thread->wait(kWaitTypeDelay); // put thread to sleep - thread->sleepTime = ticksToMSec(time); + thread->waitDelay(ticksToMSec(time)); // put thread to sleep } return SUCCESS; } @@ -198,26 +197,25 @@ int Script::SF_commandMode(SCRIPTFUNC_PARAMS) { // Script function #6 (0x06) blocking // Commands the specified actor to walk to the given position // Param1: actor id -// Param2: actor destination x -// Param3: actor destination y -int Script::SF_actorWalkTo(SCRIPTFUNC_PARAMS) { - ScriptDataWord actor_parm; - ScriptDataWord x_parm; - ScriptDataWord y_parm; +// Param2: actor x +// Param3: actor y +int Script::sfScriptWalkTo(SCRIPTFUNC_PARAMS) { uint16 actorId; - Point pt; - - actor_parm = thread->pop(); - x_parm = thread->pop(); - y_parm = thread->pop(); - - actorId = getSWord(actor_parm); - - pt.x = getSWord(x_parm); - pt.y = getSWord(y_parm); + ActorLocation actorLocation; + ActorData *actor; - _vm->_actor->walkTo(actorId, &pt, 0, &thread->sem); + actorId = getSWord(thread->pop()); + actorLocation.x = getSWord(thread->pop()); + actorLocation.y = getSWord(thread->pop()); + + actor = _vm->_actor->getActor(actorId); + actorLocation.z = actor->location.z; + + actor->flags &= ~kFollower; + if (_vm->_actor->actorWalkTo(actorId, actorLocation)) { + thread->waitWalk(actor); + } return SUCCESS; } @@ -493,7 +491,7 @@ int Script::SF_actorWalkToAsync(SCRIPTFUNC_PARAMS) { pt.x = getSWord(x_parm); pt.y = getSWord(y_parm); - _vm->_actor->walkTo(actorId, &pt, 0, NULL); +// error("!"); return SUCCESS; } @@ -683,11 +681,7 @@ int Script::SF_actorWalk(SCRIPTFUNC_PARAMS) { pt.x = getSWord(x_parm); pt.y = getSWord(y_parm); -#if 1 - _vm->_actor->walkTo(actorId, &pt, 0, NULL); -#else - _vm->_actor->walkTo(actorId, &pt, 0, &thread->sem); -#endif +// error("!"); return SUCCESS; } diff --git a/saga/sthread.cpp b/saga/sthread.cpp index dfaffed4ab..aa868cbd9a 100644 --- a/saga/sthread.cpp +++ b/saga/sthread.cpp @@ -206,28 +206,7 @@ size_t Script::SThreadGetReadLen(SCRIPT_THREAD *thread) { } -int Script::SThreadHoldSem(SEMAPHORE *sem) { - if (sem == NULL) { - return FAILURE; - } - - sem->hold_count++; - - return SUCCESS; -} - -int Script::SThreadReleaseSem(SEMAPHORE *sem) { - if (sem == NULL) { - return FAILURE; - } - sem->hold_count--; - if (sem->hold_count < 0) { - sem->hold_count = 0; - } - - return SUCCESS; -} int Script::SThreadDebugStep() { if (_dbg_singlestep) { @@ -278,13 +257,10 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) { if (thread->flags & kTFlagWaiting) break; - if (thread->sem.hold_count) //TODO: remove it - break; - saved_offset = thread->i_offset; operandChar = scriptS.readByte(); - debug(2, "Executing thread offset: %lu (%x) stack: %d", thread->i_offset, operandChar, thread->stackSize()); +// debug(2, "Executing thread offset: %lu (%x) stack: %d", thread->i_offset, operandChar, thread->stackSize()); switch (operandChar) { case 0x01: // nextblock // Some sort of "jump to the start of the next memory -- cgit v1.2.3