From 28e5422fd88e91bf8005ac290d5a36e8ba6a5b19 Mon Sep 17 00:00:00 2001 From: Andrew Kurushin Date: Fri, 17 Dec 2004 11:18:56 +0000 Subject: actors rearrangement bugfix svn-id: r16094 --- saga/actor.cpp | 433 ++++++++++++++++++++++++------------------------------- saga/actor.h | 85 +++++------ saga/music.cpp | 2 +- saga/sfuncs.cpp | 121 +++++----------- saga/sthread.cpp | 12 +- 5 files changed, 269 insertions(+), 384 deletions(-) diff --git a/saga/actor.cpp b/saga/actor.cpp index 860f011be6..ebe4663909 100644 --- a/saga/actor.cpp +++ b/saga/actor.cpp @@ -59,7 +59,7 @@ ACTIONTIMES ActionTDeltas[] = { { ACTION_SPEAK, 200 } }; -Actor::Actor(SagaEngine *vm) : _vm(vm), _initialized(false) { +Actor::Actor(SagaEngine *vm) : _vm(vm) { int i; // Get actor resource file context @@ -75,13 +75,42 @@ Actor::Actor(SagaEngine *vm) : _vm(vm), _initialized(false) { } _count = 0; - _initialized = true; } Actor::~Actor() { - if (!_initialized) { - return; - } + debug(0, "Actor::~Actor()"); +} + +bool Actor::isValidActor(int index) { + + if (!IS_VALID_ACTOR_INDEX(index)) + return false; + + return (_tbl[index] != zeroActorIterator); +} + +ActorList::iterator Actor::getActorIterator(int index) { + + if(!isValidActor(index)) + error("Actor::getActorIterator wrong actor 0x%x", index); + + return _tbl[index]; +} + +void Actor::reorderActorUp(int index) { + ActorList::iterator actorIterator; + + actorIterator = getActorIterator(index); + actorIterator = _list.reorderUp(actorIterator, actorCompare); + _tbl[index] = actorIterator; +} + +void Actor::reorderActorDown(int index) { + ActorList::iterator actorIterator; + + actorIterator = getActorIterator(index); + actorIterator = _list.reorderDown(actorIterator, actorCompare); + _tbl[index] = actorIterator; } int Actor::direct(int msec) { @@ -109,17 +138,19 @@ int Actor::direct(int msec) { case INTENT_PATH: // Actor intends to go somewhere. Well good for him { - WALKINTENT *a_walkint; - a_walkint = (WALKINTENT *)a_intent->a_data; - handleWalkIntent(actor, a_walkint, &a_intent->a_idone, msec); + uint16 actorId = actor->actorId; //backup + handleWalkIntent(actor, &a_intent->walkIntent, &a_intent->a_idone, msec); + + actorIterator = getActorIterator(ACTOR_ID_TO_INDEX(actorId)); + actor = actorIterator.operator->(); + actorIntentIterator = actor->a_intentlist.begin(); + a_intent = actorIntentIterator.operator->(); } break; case INTENT_SPEAK: // Actor wants to blab { - SPEAKINTENT *a_speakint; - a_speakint = (SPEAKINTENT *)a_intent->a_data; - handleSpeakIntent(actor, a_speakint, &a_intent->a_idone, msec); + handleSpeakIntent(actor, &a_intent->speakIntent, &a_intent->a_idone, msec); } break; @@ -129,7 +160,6 @@ int Actor::direct(int msec) { // If this actor intent was flagged as completed, remove it. if (a_intent->a_idone) { - a_intent->deleteData(); actor->a_intentlist.erase(actorIntentIterator); actor->action = actor->def_action; actor->action_flags = actor->def_action_flags; @@ -173,7 +203,6 @@ int Actor::drawList() { ActorIntentList::iterator actorIntentIterator; ACTORINTENT *a_intent; - SPEAKINTENT *a_speakint; ActorDialogList::iterator actorDialogIterator; ACTORDIALOGUE *a_dialogue; @@ -200,9 +229,8 @@ int Actor::drawList() { if (actorIntentIterator != actor->a_intentlist.end()) { a_intent = actorIntentIterator.operator->(); if (a_intent->a_itype == INTENT_SPEAK) { - a_speakint = (SPEAKINTENT *)a_intent->a_data; - actorDialogIterator = a_speakint->si_diaglist.begin(); - if (actorDialogIterator != a_speakint->si_diaglist.end()) { + actorDialogIterator = a_intent->speakIntent.si_diaglist.begin(); + if (actorDialogIterator != a_intent->speakIntent.si_diaglist.end()) { a_dialogue = actorDialogIterator.operator->(); diag_x = actor->s_pt.x; diag_y = actor->s_pt.y; @@ -227,15 +255,10 @@ int Actor::skipDialogue() { ActorIntentList::iterator actorIntentIterator; ACTORINTENT *a_intent; - SPEAKINTENT *a_speakint; ActorDialogList::iterator actorDialogIterator; ACTORDIALOGUE *a_dialogue; - if (!_initialized) { - return FAILURE; - } - for (actorIterator = _list.begin(); actorIterator != _list.end(); ++actorIterator) { actor = actorIterator.operator->(); // Check the actor's current intent for a speak intent @@ -245,14 +268,13 @@ int Actor::skipDialogue() { if (a_intent->a_itype == INTENT_SPEAK) { // Okay, found a speak intent. Remove one dialogue entry // from it, releasing any semaphore */ - a_speakint = (SPEAKINTENT *)a_intent->a_data; - actorDialogIterator = a_speakint->si_diaglist.begin(); - if (actorDialogIterator != a_speakint->si_diaglist.end()) { + actorDialogIterator = a_intent->speakIntent.si_diaglist.begin(); + if (actorDialogIterator != a_intent->speakIntent.si_diaglist.end()) { a_dialogue = actorDialogIterator.operator->(); if (a_dialogue->d_sem != NULL) { _vm->_script->SThreadReleaseSem(a_dialogue->d_sem); } - a_speakint->si_diaglist.erase(actorDialogIterator); + a_intent->speakIntent.si_diaglist.erase(actorDialogIterator); // And stop any currently playing voices _vm->_sound->stopVoice(); } @@ -263,67 +285,52 @@ int Actor::skipDialogue() { return SUCCESS; } -int Actor::create(int actor_id, int x, int y) { - ACTOR actor; - - if (actor_id == 1) { - actor_id = 0; - } else { - actor_id = actor_id & ~0x2000; - } - - actor.id = actor_id; - actor.a_pt.x = x; - actor.a_pt.y = y; - - if (addActor(&actor) != SUCCESS) { +void Actor::create(uint16 actorId, int x, int y) { + ACTOR sampleActor; + sampleActor.actorId = actorId; + sampleActor.a_pt.x = x; + sampleActor.a_pt.y = y; - return FAILURE; - } - - return SUCCESS; + addActor(&sampleActor); } -int Actor::addActor(ACTOR * actor) { +void Actor::addActor(ACTOR * actor) { ActorList::iterator actorIterator; int last_frame; - int i; - if (!_initialized) { - return FAILURE; - } + actor->index = ACTOR_ID_TO_INDEX(actor->actorId); - if ((actor->id < 0) || (actor->id >= ACTORCOUNT)) { - return FAILURE; - } + debug(0, "Actor::addActor actorId=0x%X index=0x%X", actor->actorId, actor->index); - if (_tbl[actor->id] != zeroActorIterator) { - return FAILURE; + if (!IS_VALID_ACTOR_INDEX(actor->index)) { + error("Wrong Actor actorId=0x%X index=0x%X", actor->actorId, actor->index); + } + + if (_tbl[actor->index] != zeroActorIterator) { + error("Actor::addActor actor already exist actorId=0x%X index=0x%X", actor->actorId, actor->index); } AtoS(&actor->s_pt, &actor->a_pt); - i = actor->id; - actor->sl_rn = ActorTable[i].spritelist_rn; - actor->si_rn = ActorTable[i].spriteindex_rn; + actor->sl_rn = ActorTable[actor->index].spritelist_rn; + actor->si_rn = ActorTable[actor->index].spriteindex_rn; loadActorSpriteIndex(actor, actor->si_rn, &last_frame); if (_vm->_sprite->loadList(actor->sl_rn, &actor->sl_p) != SUCCESS) { - return FAILURE; + error("Actor::addActor unable to load sprite list actorId=0x%X index=0x%X", actor->actorId, actor->index); } if (last_frame >= _vm->_sprite->getListLen(actor->sl_p)) { debug(0, "Appending to sprite list %d.", actor->sl_rn); - if (_vm->_sprite->appendList(actor->sl_rn + 1, - actor->sl_p) != SUCCESS) { - return FAILURE; + if (_vm->_sprite->appendList(actor->sl_rn + 1, actor->sl_p) != SUCCESS) { + error("Actor::addActor unable append sprite list actorId=0x%X index=0x%X", actor->actorId, actor->index); } } - actor->flags = ActorTable[i].flags; - actor->a_dcolor = ActorTable[i].color; + actor->flags = ActorTable[actor->index].flags; + actor->a_dcolor = ActorTable[actor->index].color; actor->orient = ACTOR_DEFAULT_ORIENT; actor->def_action = 0; actor->def_action_flags = 0; @@ -336,54 +343,45 @@ int Actor::addActor(ACTOR * actor) { actor = actorIterator.operator->(); - _tbl[i] = actorIterator; + _tbl[actor->index] = actorIterator; _count++; - - return SUCCESS; } -int Actor::getActorIndex(uint16 actor_id) { - uint16 actorIdx; +int Actor::getActorIndex(uint16 actorId) { + int actorIdx = ACTOR_ID_TO_INDEX(actorId); - if (actor_id == 1) { - actorIdx = 0; - } else { - actorIdx = actor_id & ~0x2000; - } - - if (actorIdx >= ACTORCOUNT) { - error("Wrong actorIdx=%i", actorIdx); + if (!IS_VALID_ACTOR_INDEX(actorIdx)) { + error("Wrong Actor actorId=0x%X actorIdx=0x%X", actorId, actorIdx); } if (_tbl[actorIdx] == zeroActorIterator) { + _vm->_console->DebugPrintf(S_WARN_PREFIX "Actor::getActorIndex Actor id 0x%X not found.\n", actorId); + warning("Actor::getActorIndex Actor not found actorId=0x%X actorIdx=0x%X", actorId, actorIdx); return -1; } return actorIdx; } -int Actor::actorExists(uint16 actor_id) { - uint16 actor_idx; - - if (actor_id == 1) { - actor_idx = 0; - } else { - actor_idx = actor_id & ~0x2000; +bool Actor::actorExists(uint16 actorId) { + int actorIdx = ACTOR_ID_TO_INDEX(actorId); + + if (!IS_VALID_ACTOR_INDEX(actorIdx)) { + error("Wrong Actor actorId=0x%X actorIdx=0x%X", actorId, actorIdx); } - if (_tbl[actor_idx] == zeroActorIterator) { - return 0; + if (_tbl[actorIdx] == zeroActorIterator) { + return false; } - return 1; + return true; } -int Actor::speak(int index, const char *d_string, uint16 d_voice_rn, SEMAPHORE *sem) { +void Actor::speak(uint16 actorId, const char *d_string, uint16 d_voice_rn, SEMAPHORE *sem) { ActorList::iterator actorIterator; ACTOR *actor; ActorIntentList::iterator actorIntentIterator; ACTORINTENT *a_intent_p = NULL; - SPEAKINTENT *a_speakint; ACTORINTENT a_intent; int use_existing_ai = 0; ACTORDIALOGUE a_dialogue; @@ -394,11 +392,7 @@ int Actor::speak(int index, const char *d_string, uint16 d_voice_rn, SEMAPHORE * a_dialogue.d_sem_held = 1; a_dialogue.d_sem = sem; - actorIterator = _tbl[index]; - if (actorIterator == zeroActorIterator) { - return FAILURE; - } - + actorIterator = getActorIterator(ACTOR_ID_TO_INDEX(actorId)); actor = actorIterator.operator->(); // If actor's last registered intent is to speak, we can queue the @@ -416,18 +410,15 @@ int Actor::speak(int index, const char *d_string, uint16 d_voice_rn, SEMAPHORE * if (use_existing_ai) { // Store the current dialogue off the existing actor intent - a_speakint = (SPEAKINTENT *)a_intent_p->a_data; - a_speakint->si_diaglist.push_back(a_dialogue); + a_intent_p->speakIntent.si_diaglist.push_back(a_dialogue); } else { // Create a new actor intent a_intent.a_itype = INTENT_SPEAK; a_intent.a_idone = 0; a_intent.a_iflags = 0; - a_intent.createData(); - a_speakint = (SPEAKINTENT *)a_intent.a_data; - a_speakint->si_last_action = actor->action; - a_speakint->si_diaglist.push_back(a_dialogue); + a_intent.speakIntent.si_last_action = actor->action; + a_intent.speakIntent.si_diaglist.push_back(a_dialogue); actor->a_intentlist.push_back(a_intent); } @@ -435,8 +426,6 @@ int Actor::speak(int index, const char *d_string, uint16 d_voice_rn, SEMAPHORE * if (sem != NULL) { _vm->_script->SThreadHoldSem(sem); } - - return SUCCESS; } int Actor::handleSpeakIntent(ACTOR *actor, SPEAKINTENT *a_speakint, int *complete_p, int msec) { @@ -518,33 +507,29 @@ int Actor::getSpeechTime(const char *d_string, uint16 d_voice_rn) { return voice_len; } -int Actor::setOrientation(int index, int orient) { +void Actor::setOrientation(uint16 actorId, int orient) { + ActorList::iterator actorIterator; ACTOR *actor; - - actor = lookupActor(index); - if (actor == NULL) { - return FAILURE; - } + + actorIterator = getActorIterator(ACTOR_ID_TO_INDEX(actorId)); + actor = actorIterator.operator->(); if ((orient < 0) || (orient > 7)) { - return FAILURE; + error("Actor::setOrientation wrong orientation 0x%X", orient); } actor->orient = orient; - - return SUCCESS; } -int Actor::setAction(int index, int action_n, uint16 action_flags) { +void Actor::setAction(uint16 actorId, int action_n, uint16 action_flags) { + ActorList::iterator actorIterator; ACTOR *actor; - actor = lookupActor(index); - if (actor == NULL) { - return FAILURE; - } + actorIterator = getActorIterator(ACTOR_ID_TO_INDEX(actorId)); + actor = actorIterator.operator->(); if ((action_n < 0) || (action_n >= actor->action_ct)) { - return FAILURE; + error("Actor::setAction wrong action_n 0x%X", action_n); } actor->action = action_n; @@ -552,48 +537,32 @@ int Actor::setAction(int index, int action_n, uint16 action_flags) { actor->action_frame = 0; actor->action_time = 0; - return SUCCESS; } -int Actor::setDefaultAction(int index, int action_n, uint16 action_flags) { +void Actor::setDefaultAction(uint16 actorId, int action_n, uint16 action_flags) { + ActorList::iterator actorIterator; ACTOR *actor; - actor = lookupActor(index); - if (actor == NULL) { - return FAILURE; - } + actorIterator = getActorIterator(ACTOR_ID_TO_INDEX(actorId)); + actor = actorIterator.operator->(); if ((action_n < 0) || (action_n >= actor->action_ct)) { - return FAILURE; + error("Actor::setDefaultAction wrong action_n 0x%X", action_n); } actor->def_action = action_n; actor->def_action_flags = action_flags; - - return SUCCESS; } - +/* ACTOR *Actor::lookupActor(int index) { ActorList::iterator actorIterator; ACTOR *actor; - if (!_initialized) { - return NULL; - } - - if ((index < 0) || (index >= ACTORCOUNT)) { - return NULL; - } - - if (_tbl[index] == zeroActorIterator) { - return NULL; - } - - actorIterator = _tbl[index]; + actorIterator = getActorIterator(index); actor = actorIterator.operator->(); return actor; -} +}*/ int Actor::loadActorSpriteIndex(ACTOR * actor, int si_rn, int *last_frame_p) { byte *res_p; @@ -647,68 +616,43 @@ int Actor::loadActorSpriteIndex(ACTOR * actor, int si_rn, int *last_frame_p) { return SUCCESS; } -int Actor::deleteActor(int index) { +void Actor::deleteActor(uint16 actorId) { ActorList::iterator actorIterator; ACTOR *actor; - if (!_initialized) { - return FAILURE; - } - - if ((index < 0) || (index >= ACTORCOUNT)) { - return FAILURE; - } - - actorIterator = _tbl[index]; - - if (actorIterator == zeroActorIterator) { - return FAILURE; - } - + debug(0, "Actor::deleteActor actorId=0x%X", actorId); + + actorIterator = getActorIterator(ACTOR_ID_TO_INDEX(actorId)); actor = actorIterator.operator->(); _vm->_sprite->freeSprite(actor->sl_p); _list.erase(actorIterator); - _tbl[index] = zeroActorIterator; - - return SUCCESS; + _tbl[ACTOR_ID_TO_INDEX(actorId)] = zeroActorIterator; } -int Actor::walkTo(int id, const Point *walk_pt, uint16 flags, SEMAPHORE *sem) { +void Actor::walkTo(uint16 actorId, const Point *walk_pt, uint16 flags, SEMAPHORE *sem) { ACTORINTENT actor_intent; - WALKINTENT *walk_intent; ActorList::iterator actorIterator; ACTOR *actor; - assert(_initialized); assert(walk_pt != NULL); - - if ((id < 0) || (id >= ACTORCOUNT)) { - return FAILURE; - } - - if (_tbl[id] == zeroActorIterator) { - return FAILURE; - } - - actorIterator = _tbl[id]; + + actorIterator = getActorIterator(ACTOR_ID_TO_INDEX(actorId)); actor = actorIterator.operator->(); - + actor_intent.a_itype = INTENT_PATH; actor_intent.a_iflags = 0; - actor_intent.createData(); - walk_intent = (WALKINTENT*)actor_intent.a_data; - walk_intent->wi_flags = flags; - walk_intent->sem_held = 1; - walk_intent->sem = sem; + actor_intent.walkIntent.wi_flags = flags; + actor_intent.walkIntent.sem_held = 1; + actor_intent.walkIntent.sem = sem; // handleWalkIntent() will create path on initialization - walk_intent->wi_init = 0; - walk_intent->dst_pt = *walk_pt; + actor_intent.walkIntent.wi_init = 0; + actor_intent.walkIntent.dst_pt = *walk_pt; actor->a_intentlist.push_back(actor_intent); @@ -716,7 +660,6 @@ int Actor::walkTo(int id, const Point *walk_pt, uint16 flags, SEMAPHORE *sem) { _vm->_script->SThreadHoldSem(sem); } - return SUCCESS; } int Actor::setPathNode(WALKINTENT *walk_int, Point *src_pt, Point *dst_pt, SEMAPHORE *sem) { @@ -762,7 +705,7 @@ int Actor::handleWalkIntent(ACTOR *actor, WALKINTENT *a_walkint, int *complete_p // Initialize walk intent if (!a_walkint->wi_init) { setPathNode(a_walkint, &actor->a_pt, &a_walkint->dst_pt, a_walkint->sem); - setDefaultAction(actor->id, ACTION_IDLE, ACTION_NONE); + setDefaultAction(actor->actorId, ACTION_IDLE, ACTION_NONE); a_walkint->wi_init = 1; } @@ -883,31 +826,22 @@ int Actor::handleWalkIntent(ACTOR *actor, WALKINTENT *a_walkint, int *complete_p actor->s_pt.x = actor->a_pt.x >> 2; actor->s_pt.y = actor->a_pt.y >> 2; - ActorList::iterator actorIterator; - if (_list.locate(actor, actorIterator)) { - if (path_slope < 0) { - _list.reorderUp(actorIterator, actorCompare); - } else { - _list.reorderDown(actorIterator, actorCompare); - } + if (path_slope < 0) { + reorderActorUp(actor->index); } else { - error("Actor::handleWalkIntent() actor not found list"); + reorderActorDown(actor->index); } - + // here "actor" pointer may be invalid return SUCCESS; } -int Actor::move(int index, const Point *move_pt) { +void Actor::move(uint16 actorId, const Point *move_pt) { ActorList::iterator actorIterator; ACTOR *actor; int move_up = 0; - actorIterator = _tbl[index]; - if (actorIterator == zeroActorIterator) { - return FAILURE; - } - + actorIterator = getActorIterator(ACTOR_ID_TO_INDEX(actorId)); actor = actorIterator.operator->(); if (move_pt->y < actor->a_pt.y) { @@ -919,24 +853,20 @@ int Actor::move(int index, const Point *move_pt) { AtoS(&actor->s_pt, &actor->a_pt); - if (move_up) { - _list.reorderUp(actorIterator, actorCompare); + if (move_up) { + reorderActorUp(actor->index); } else { - _list.reorderDown(actorIterator, actorCompare); + reorderActorDown(actor->index); } + // here "actor" pointer may be invalid - return SUCCESS; } -int Actor::moveRelative(int index, const Point *move_pt) { +void Actor::moveRelative(uint16 actorId, const Point *move_pt) { ActorList::iterator actorIterator; ACTOR *actor; - actorIterator = _tbl[index]; - if (actorIterator == zeroActorIterator) { - return FAILURE; - } - + actorIterator = getActorIterator(ACTOR_ID_TO_INDEX(actorId)); actor = actorIterator.operator->(); actor->a_pt.x += move_pt->x; @@ -945,12 +875,11 @@ int Actor::moveRelative(int index, const Point *move_pt) { AtoS(&actor->s_pt, &actor->a_pt); if (actor->a_pt.y < 0) { - _list.reorderUp(actorIterator, actorCompare); + reorderActorUp(actor->index); } else { - _list.reorderDown(actorIterator, actorCompare); + reorderActorDown(actor->index); } - - return SUCCESS; + // here "actor" pointer may be invalid } @@ -968,75 +897,95 @@ int Actor::StoA(Point *actor, const Point screen) { return SUCCESS; } -void Actor::CF_actor_add(int argc, const char **argv) { - ACTOR actor; - - actor.id = (uint16) atoi(argv[1]); +// Console wrappers - must be safe to run +// TODO - checkup ALL arguments, cause wrong arguments may fall function with "error" - actor.a_pt.x = atoi(argv[2]); - actor.a_pt.y = atoi(argv[3]); +void Actor::CF_actor_add(int argc, const char **argv) { + uint16 actorId = (uint16) atoi(argv[1]); + int x = atoi(argv[2]); + int y = atoi(argv[3]); + int actorIdx = ACTOR_ID_TO_INDEX(actorId); + + if (!IS_VALID_ACTOR_INDEX(actorIdx)) { + _vm->_console->DebugPrintf("Actor::CF_actor_add Invalid actorId 0x%X.\n",actorId); + return; + } + + if (actorExists(actorId)) { + _vm->_console->DebugPrintf("Actor::CF_actor_add Actor already exist actorId 0x%X.\n",actorId); + return; + } - addActor(&actor); + create(actorId, x, y); } void Actor::CF_actor_del(int argc, const char **argv) { - int id; - - id = atoi(argv[1]); - - deleteActor(id); + uint16 actorId = (uint16) atoi(argv[1]); + + if (!isValidActor(ACTOR_ID_TO_INDEX(actorId))) { + _vm->_console->DebugPrintf("Actor::CF_actor_del Invalid actorId 0x%X.\n",actorId); + return; + } + deleteActor(actorId); } void Actor::CF_actor_move(int argc, const char **argv) { - int id; + uint16 actorId = (uint16) atoi(argv[1]); Point move_pt; - id = atoi(argv[1]); - move_pt.x = atoi(argv[2]); move_pt.y = atoi(argv[3]); - move(id, &move_pt); + if (!isValidActor(ACTOR_ID_TO_INDEX(actorId))) { + _vm->_console->DebugPrintf("Actor::CF_actor_move Invalid actorId 0x%X.\n",actorId); + return; + } + + move(actorId, &move_pt); } void Actor::CF_actor_moverel(int argc, const char **argv) { - int id; + uint16 actorId = (uint16) atoi(argv[1]); Point move_pt; - id = atoi(argv[1]); - move_pt.x = atoi(argv[2]); move_pt.y = atoi(argv[3]); - moveRelative(id, &move_pt); + if (!isValidActor(ACTOR_ID_TO_INDEX(actorId))) { + _vm->_console->DebugPrintf("Actor::CF_actor_moverel Invalid actorId 0x%X.\n",actorId); + return; + } + + moveRelative(actorId, &move_pt); } void Actor::CF_actor_seto(int argc, const char **argv) { - int id; + uint16 actorId = (uint16) atoi(argv[1]); int orient; - id = atoi(argv[1]); orient = atoi(argv[2]); +//TODO orient check + if (!isValidActor(ACTOR_ID_TO_INDEX(actorId))) { + _vm->_console->DebugPrintf("Actor::CF_actor_seto Invalid actorId 0x%X.\n",actorId); + return; + } - setOrientation(id, orient); + setOrientation(actorId, orient); } void Actor::CF_actor_setact(int argc, const char **argv) { - int index = 0; + uint16 actorId = (uint16) atoi(argv[1]); int action_n = 0; - ACTOR *actor; - - index = atoi(argv[1]); action_n = atoi(argv[2]); - actor = lookupActor(index); - if (actor == NULL) { - _vm->_console->DebugPrintf("Invalid actor index.\n"); + if (!isValidActor(ACTOR_ID_TO_INDEX(actorId))) { + _vm->_console->DebugPrintf("Actor::CF_actor_setact Invalid actorId 0x%X.\n",actorId); return; } - if ((action_n < 0) || (action_n >= actor->action_ct)) { +//TODO action_n check +/* if ((action_n < 0) || (action_n >= actor->action_ct)) { _vm->_console->DebugPrintf("Invalid action number.\n"); return; } @@ -1046,8 +995,8 @@ void Actor::CF_actor_setact(int argc, const char **argv) { actor->act_tbl[action_n].dir[1].frame_count, actor->act_tbl[action_n].dir[2].frame_count, actor->act_tbl[action_n].dir[3].frame_count); - - setAction(index, action_n, ACTION_LOOP); +*/ + setAction(actorId, action_n, ACTION_LOOP); } } // End of namespace Saga diff --git a/saga/actor.h b/saga/actor.h index 1a38f6c4d3..45ed17b59a 100644 --- a/saga/actor.h +++ b/saga/actor.h @@ -45,6 +45,9 @@ namespace Saga { #define ACTOR_LMULT 4 +#define IS_VALID_ACTOR_INDEX(index) ((index >= 0) && (index < ACTORCOUNT)) +#define ACTOR_ID_TO_INDEX(id) ((((uint16)id) == 1 ) ? 0 : (int)(((uint16)id) & ~0x2000)) + enum ACTOR_INTENTS { INTENT_NONE = 0, INTENT_PATH = 1, @@ -158,46 +161,22 @@ struct ACTORINTENT { int a_itype; uint16 a_iflags; int a_idone; - void *a_data; + SPEAKINTENT speakIntent; + WALKINTENT walkIntent; - void createData() { - assert(a_data == NULL); - - if(INTENT_SPEAK == a_itype) { - a_data = new SPEAKINTENT; - } - else - if(INTENT_PATH == a_itype) { - a_data = new WALKINTENT; - } - } - void deleteData() { - - if(INTENT_SPEAK == a_itype) { - SPEAKINTENT *a_speakint; - - assert(a_data); - a_speakint = (SPEAKINTENT *)a_data; - delete a_speakint; - } - else - if(INTENT_PATH == a_itype) { - WALKINTENT *a_walkint; - - assert(a_data); - a_walkint = (WALKINTENT *)a_data; - delete a_walkint; - } - a_data = NULL; + ACTORINTENT() { + a_itype = 0; + a_iflags = 0; + a_idone = 0; } - - ACTORINTENT() { memset(this, 0, sizeof(*this)); } }; typedef Common::List ActorIntentList; struct ACTOR { - int id; // Actor id + int index; // Actor index + uint16 actorId; // Actor id + int name_i; // Actor's index in actor name string list uint16 flags; @@ -234,7 +213,8 @@ struct ACTOR { ACTORACTION *act_tbl; // Action lookup table int action_ct; // Number of actions in the action LUT ACTOR() { - id = 0; + index = 0; + actorId = 0; name_i = 0; flags = 0; sl_rn = 0; @@ -277,32 +257,28 @@ public: int direct(int msec); - int create(int actor_id, int x, int y); - int actorExists(uint16 actor_id); + void create(uint16 actorId, int x, int y); + bool actorExists(uint16 actorId); int drawList(); int AtoS(Point *logical, const Point *actor); int StoA(Point *actor, const Point screen); - int move(int index, const Point *move_pt); - int moveRelative(int index, const Point *move_pt); + void move(uint16 actorId, const Point *move_pt); + void moveRelative(uint16 actorId, const Point *move_pt); - int walkTo(int index, const Point *walk_pt, uint16 flags, SEMAPHORE *sem); - - int getActorIndex(uint16 actor_id); - - int speak(int index, const char *d_string, uint16 d_voice_rn, SEMAPHORE *sem); + void walkTo(uint16 actorId, const Point *walk_pt, uint16 flags, SEMAPHORE *sem); + + void speak(uint16 actorId, const char *d_string, uint16 d_voice_rn, SEMAPHORE *sem); int skipDialogue(); int getSpeechTime(const char *d_string, uint16 d_voice_rn); - int setOrientation(int index, int orient); - int setAction(int index, int action_n, uint16 action_flags); - int setDefaultAction(int index, int action_n, uint16 action_flags); + void setOrientation(uint16 actorId, int orient); + void setAction(uint16 actorId, int action_n, uint16 action_flags); + void setDefaultAction(uint16 actorId, int action_n, uint16 action_flags); - int addActor(ACTOR * actor); - int deleteActor(int index); - ACTOR *lookupActor(int index); + void deleteActor(uint16 actorId); private: int handleWalkIntent(ACTOR *actor, WALKINTENT *a_walk_int, int *complete_p, int msec); @@ -310,8 +286,17 @@ private: int setPathNode(WALKINTENT *walk_int, Point *src_pt, Point *dst_pt, SEMAPHORE *sem); int loadActorSpriteIndex(ACTOR *actor, int si_rn, int *last_frame_p); + ActorList::iterator getActorIterator(int index); + int getActorIndex(uint16 actorId); + + void reorderActorUp(int index); + void reorderActorDown(int index); + bool isValidActor(int index); + + //ACTOR *lookupActor(int index); + void addActor(ACTOR * actor); + SagaEngine *_vm; - bool _initialized; RSCFILE_CONTEXT *_actorContext; uint16 _count; int _aliasTbl[ACTORCOUNT]; diff --git a/saga/music.cpp b/saga/music.cpp index dd10297b2c..01c208edaf 100644 --- a/saga/music.cpp +++ b/saga/music.cpp @@ -139,7 +139,7 @@ void RAWInputStream::refill() { if (len & 1) len--; - if (GAME_GetFeatures() & GF_BIG_ENDIAN_DATA) { + if (IS_BIG_ENDIAN) { uint16 *ptr16 = (uint16 *)ptr; for (uint32 i = 0; i < (len / 2); i++) ptr16[i] = TO_BE_16(ptr16[i]); diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp index ade1c34114..e6680cfdbc 100644 --- a/saga/sfuncs.cpp +++ b/saga/sfuncs.cpp @@ -208,25 +208,19 @@ int Script::SF_actorWalkTo(SCRIPTFUNC_PARAMS) { SDataWord_T actor_parm; SDataWord_T x_parm; SDataWord_T y_parm; - int actor_id; - int actor_idx; + uint16 actorId; Point pt; actor_parm = thread->pop(); x_parm = thread->pop(); y_parm = thread->pop(); - actor_id = _vm->_sdata->readWordS(actor_parm); - actor_idx = _vm->_actor->getActorIndex(actor_id); - if (actor_idx < 0) { - _vm->_console->DebugPrintf(S_WARN_PREFIX "SF.08: Actor id 0x%X not found.\n", actor_id); - return FAILURE; - } + actorId = _vm->_sdata->readWordS(actor_parm); pt.x = _vm->_sdata->readWordS(x_parm); pt.y = _vm->_sdata->readWordS(y_parm); - _vm->_actor->walkTo(actor_idx, &pt, 0, &thread->sem); + _vm->_actor->walkTo(actorId, &pt, 0, &thread->sem); return SUCCESS; } @@ -251,22 +245,19 @@ int Script::SF_doAction(SCRIPTFUNC_PARAMS) { int Script::SF_setFacing(SCRIPTFUNC_PARAMS) { SDataWord_T actor_parm; SDataWord_T orient_parm; - int actor_id; - int actor_idx; + uint16 actorId; int orientation; actor_parm = thread->pop(); orient_parm = thread->pop(); - actor_id = _vm->_sdata->readWordS(actor_parm); + actorId = _vm->_sdata->readWordS(actor_parm); orientation = _vm->_sdata->readWordS(orient_parm); - actor_idx = _vm->_actor->getActorIndex(actor_id); - if (actor_idx < 0) { - _vm->_console->DebugPrintf(S_WARN_PREFIX "SF.08: Actor id 0x%X not found.\n", actor_id); - return FAILURE; - } - _vm->_actor->setOrientation(actor_idx, orientation); + if (!_vm->_actor->actorExists(actorId)) { + _vm->_actor->create(actorId, 0, 0); + } + _vm->_actor->setOrientation(actorId, orientation); return SUCCESS; } @@ -484,25 +475,19 @@ int Script::SF_actorWalkToAsync(SCRIPTFUNC_PARAMS) { SDataWord_T actor_parm; SDataWord_T x_parm; SDataWord_T y_parm; - int actor_id; - int actor_idx; + uint16 actorId; Point pt; actor_parm = thread->pop(); + x_parm = thread->pop(); y_parm = thread->pop(); - actor_id = _vm->_sdata->readWordS(actor_parm); - actor_idx = _vm->_actor->getActorIndex(actor_id); - if (actor_idx < 0) { - _vm->_console->DebugPrintf(S_WARN_PREFIX "SF.08: Actor id 0x%X not found.\n", - actor_id); - return FAILURE; - } + actorId = _vm->_sdata->readWordS(actor_parm); pt.x = _vm->_sdata->readWordS(x_parm); pt.y = _vm->_sdata->readWordS(y_parm); - _vm->_actor->walkTo(actor_idx, &pt, 0, NULL); + _vm->_actor->walkTo(actorId, &pt, 0, NULL); return SUCCESS; } @@ -535,28 +520,21 @@ int Script::SF_moveTo(SCRIPTFUNC_PARAMS) { SDataWord_T actor_parm; SDataWord_T x_parm; SDataWord_T y_parm; - int actor_id; - int actor_idx; - int result; + uint16 actorId; Point pt; actor_parm = thread->pop(); x_parm = thread->pop(); y_parm = thread->pop(); - actor_id = _vm->_sdata->readWordS(actor_parm); + actorId = _vm->_sdata->readWordS(actor_parm); pt.x = _vm->_sdata->readWordS(x_parm); pt.y = _vm->_sdata->readWordS(y_parm); - if (!_vm->_actor->actorExists(actor_id)) { - result = _vm->_actor->create(actor_id, pt.x, pt.y); - if (result != SUCCESS) { - _vm->_console->DebugPrintf(S_WARN_PREFIX "SF.30: Couldn't create actor 0x%X.\n", actor_id); - return FAILURE; - } + if (!_vm->_actor->actorExists(actorId)) { + _vm->_actor->create(actorId, pt.x, pt.y); } else { - actor_idx = _vm->_actor->getActorIndex(actor_id); - _vm->_actor->move(actor_idx, &pt); + _vm->_actor->move(actorId, &pt); } return SUCCESS; @@ -636,7 +614,7 @@ int Script::SF_actorWalk(SCRIPTFUNC_PARAMS) { SDataWord_T x_parm; SDataWord_T y_parm; SDataWord_T flags_parm; - int actor_idx; + uint16 actorId; Point pt; actor_parm = thread->pop(); @@ -644,19 +622,15 @@ int Script::SF_actorWalk(SCRIPTFUNC_PARAMS) { y_parm = thread->pop(); flags_parm = thread->pop(); - actor_idx = _vm->_actor->getActorIndex(_vm->_sdata->readWordS(actor_parm)); - if (actor_idx < 0) { - _vm->_console->DebugPrintf(S_WARN_PREFIX "SF.36: Actor id 0x%X not found.\n", (int)actor_parm); - return FAILURE; - } + actorId = _vm->_sdata->readWordS(actor_parm); pt.x = _vm->_sdata->readWordS(x_parm); pt.y = _vm->_sdata->readWordS(y_parm); #if 1 - _vm->_actor->walkTo(actor_idx, &pt, 0, NULL); + _vm->_actor->walkTo(actorId, &pt, 0, NULL); #else - _vm->_actor->walkTo(actor_idx, &pt, 0, &thread->sem); + _vm->_actor->walkTo(actorId, &pt, 0, &thread->sem); #endif return SUCCESS; @@ -674,8 +648,7 @@ int Script::SF_cycleActorFrames(SCRIPTFUNC_PARAMS) { SDataWord_T flags_parm; SDataWord_T delay_parm; SDataWord_T action_parm; - int actor_id; - int actor_idx; + uint16 actorId; int action; //uint16 flags; @@ -683,14 +656,10 @@ int Script::SF_cycleActorFrames(SCRIPTFUNC_PARAMS) { flags_parm = thread->pop(); action_parm = thread->pop(); delay_parm = thread->pop(); - actor_id = _vm->_sdata->readWordS(actor_parm); + actorId = _vm->_sdata->readWordS(actor_parm); action = _vm->_sdata->readWordS(action_parm); - actor_idx = _vm->_actor->getActorIndex(actor_id); - if (_vm->_actor->setAction(actor_idx, action, ACTION_NONE) != SUCCESS) { - _vm->_console->DebugPrintf(S_WARN_PREFIX "SF.37: Actor::setAction() failed.\n"); - return FAILURE; - } + _vm->_actor->setAction(actorId, action, ACTION_NONE); return SUCCESS; } @@ -707,22 +676,17 @@ int Script::SF_setFrame(SCRIPTFUNC_PARAMS) { SDataWord_T frame_parm; SDataWord_T action_parm; - int actor_id; - int actor_idx; + uint16 actorId; int action; actor_parm = thread->pop(); action_parm = thread->pop(); frame_parm = thread->pop(); - actor_id = _vm->_sdata->readWordS(actor_parm); + actorId = _vm->_sdata->readWordS(actor_parm); action = _vm->_sdata->readWordS(action_parm); - actor_idx = _vm->_actor->getActorIndex(actor_id); - if (_vm->_actor->setAction(actor_idx, action, ACTION_NONE) != SUCCESS) { - _vm->_console->DebugPrintf(S_WARN_PREFIX "SF.38: Actor::setAction() failed.\n"); - return FAILURE; - } + _vm->_actor->setAction(actorId, action, ACTION_NONE); return SUCCESS; } @@ -803,10 +767,8 @@ int Script::SF_placeActor(SCRIPTFUNC_PARAMS) { SDataWord_T orient_parm; SDataWord_T action_parm; SDataWord_T frame_parm; - int actor_id; - int actor_idx; + uint16 actorId; int action_state; - int result; Point pt; actor_parm = thread->pop(); @@ -816,25 +778,20 @@ int Script::SF_placeActor(SCRIPTFUNC_PARAMS) { action_parm = thread->pop(); frame_parm = thread->pop(); - actor_id = _vm->_sdata->readWordS(actor_parm); + actorId = _vm->_sdata->readWordS(actor_parm); pt.x = _vm->_sdata->readWordS(x_parm); pt.y = _vm->_sdata->readWordS(y_parm); - action_state = _vm->_sdata->readWordU(action_parm); - - if (!_vm->_actor->actorExists(actor_id)) { - result = _vm->_actor->create(actor_id, pt.x, pt.y); - if (result != SUCCESS) { - _vm->_console->DebugPrintf(S_WARN_PREFIX "SF.43: Couldn't create actor 0x%X.\n", actor_id); - return FAILURE; - } + action_state = _vm->_sdata->readWordS(action_parm); + + if (!_vm->_actor->actorExists(actorId)) { + _vm->_actor->create(actorId, pt.x, pt.y); } else { - actor_idx = _vm->_actor->getActorIndex(actor_id); - _vm->_actor->move(actor_idx, &pt); + _vm->_actor->move(actorId, &pt); } - - actor_idx = _vm->_actor->getActorIndex(actor_id); - _vm->_actor->setDefaultAction(actor_idx, action_state, ACTION_NONE); - _vm->_actor->setAction(actor_idx, action_state, ACTION_NONE); + if (action_state < 0) + action_state = ACTION_IDLE; + _vm->_actor->setDefaultAction(actorId, action_state, ACTION_NONE); + _vm->_actor->setAction(actorId, action_state, ACTION_NONE); return SUCCESS; } diff --git a/saga/sthread.cpp b/saga/sthread.cpp index f50524f80d..2df3ee9633 100644 --- a/saga/sthread.cpp +++ b/saga/sthread.cpp @@ -720,7 +720,7 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) { case 0x53: { int n_voices; - int a_index; + uint16 actorId; int voice_rn; n_voices = scriptS.readByte(); @@ -729,22 +729,16 @@ int Script::SThreadRun(SCRIPT_THREAD *thread, int instr_limit) { scriptS.readByte(); scriptS.readUint16LE(); - a_index = _vm->_actor->getActorIndex(param1); - if (a_index < 0) { - _vm->_console->DebugPrintf(S_WARN_PREFIX "%X: DLGP Actor id not found.\n", thread->i_offset); - debug(9, "%X: DLGP Actor id not found.\n", thread->i_offset); - } + actorId = param1; for (i = 0; i < n_voices; i++) { data = thread->pop(); - if (a_index < 0) - continue; if (!isVoiceLUTPresent()) { voice_rn = -1; } else { voice_rn = currentScript()->voice->voices[data]; } - _vm->_actor->speak(a_index, currentScript()->diag->str[data], voice_rn, &thread->sem); + _vm->_actor->speak(actorId, currentScript()->diag->str[data], voice_rn, &thread->sem); } } break; -- cgit v1.2.3