diff options
| -rw-r--r-- | saga/actor.cpp | 433 | ||||
| -rw-r--r-- | saga/actor.h | 85 | ||||
| -rw-r--r-- | saga/music.cpp | 2 | ||||
| -rw-r--r-- | saga/sfuncs.cpp | 121 | ||||
| -rw-r--r-- | 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<ACTORINTENT> 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; | 
