diff options
| -rw-r--r-- | engines/hugo/object.h | 34 | ||||
| -rw-r--r-- | engines/hugo/object_v1d.cpp | 39 | ||||
| -rw-r--r-- | engines/hugo/object_v1w.cpp | 2 | ||||
| -rw-r--r-- | engines/hugo/object_v2d.cpp | 31 | ||||
| -rw-r--r-- | engines/hugo/schedule.cpp | 254 | ||||
| -rw-r--r-- | engines/hugo/schedule.h | 11 | ||||
| -rw-r--r-- | engines/hugo/schedule_v1d.cpp | 229 | ||||
| -rw-r--r-- | engines/hugo/schedule_v2d.cpp | 324 | 
8 files changed, 399 insertions, 525 deletions
| diff --git a/engines/hugo/object.h b/engines/hugo/object.h index 922ae75d27..5e468ffcbb 100644 --- a/engines/hugo/object.h +++ b/engines/hugo/object.h @@ -48,6 +48,7 @@ public:  	object_t  *_objects;  	uint16    _numObj; +	virtual void homeIn(int objIndex1, int objIndex2, int8 objDx, int8 objDy) = 0;  	virtual void moveObjects() = 0;  	virtual void updateImages() = 0;  	virtual void swapImages(int objIndex1, int objIndex2) = 0; @@ -103,19 +104,10 @@ public:  	ObjectHandler_v1d(HugoEngine *vm);  	virtual ~ObjectHandler_v1d(); -	void moveObjects(); -	void updateImages(); -	void swapImages(int objIndex1, int objIndex2); -}; - -class ObjectHandler_v1w : public ObjectHandler { -public: -	ObjectHandler_v1w(HugoEngine *vm); -	~ObjectHandler_v1w(); - -	void moveObjects(); -	void updateImages(); -	void swapImages(int objIndex1, int objIndex2); +	virtual void homeIn(int objIndex1, int objIndex2, int8 objDx, int8 objDy); +	virtual void moveObjects(); +	virtual void updateImages(); +	virtual void swapImages(int objIndex1, int objIndex2);  };  class ObjectHandler_v2d : public ObjectHandler_v1d { @@ -123,8 +115,10 @@ public:  	ObjectHandler_v2d(HugoEngine *vm);  	virtual ~ObjectHandler_v2d(); -	void moveObjects(); -	void updateImages(); +	virtual void moveObjects(); +	virtual void updateImages(); + +	void homeIn(int objIndex1, int objIndex2, int8 objDx, int8 objDy);  };  class ObjectHandler_v3d : public ObjectHandler_v2d { @@ -132,7 +126,17 @@ public:  	ObjectHandler_v3d(HugoEngine *vm);  	~ObjectHandler_v3d(); +	virtual void moveObjects(); +	virtual void swapImages(int objIndex1, int objIndex2); +}; + +class ObjectHandler_v1w : public ObjectHandler_v3d { +public: +	ObjectHandler_v1w(HugoEngine *vm); +	~ObjectHandler_v1w(); +  	void moveObjects(); +	void updateImages();  	void swapImages(int objIndex1, int objIndex2);  }; diff --git a/engines/hugo/object_v1d.cpp b/engines/hugo/object_v1d.cpp index 76b114f354..6eb44fcaa0 100644 --- a/engines/hugo/object_v1d.cpp +++ b/engines/hugo/object_v1d.cpp @@ -228,7 +228,7 @@ void ObjectHandler_v1d::moveObjects() {  						obj->cycling = CYCLE_FORWARD;  				} else {  					obj->cycling = NOT_CYCLING; -					_vm->boundaryCollision(obj);     // Must have got hero! +					_vm->boundaryCollision(obj);    // Must have got hero!  				}  				dxOld = obj->vx;  				currImage = obj->currImagePtr;      // Get (new) ptr to current image @@ -275,7 +275,7 @@ void ObjectHandler_v1d::moveObjects() {  	// Move objects, allowing for boundaries  	for (int i = 0; i < _numObj; i++) { -		object_t *obj = &_objects[i];                         // Get pointer to object +		object_t *obj = &_objects[i];               // Get pointer to object  		if ((obj->screenIndex == *_vm->_screen_p) && (obj->vx || obj->vy)) {  			// Only process if it's moving @@ -289,7 +289,7 @@ void ObjectHandler_v1d::moveObjects() {  			int y2 = obj->y + currImage->y2;        // Bottom edge  			if ((obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING)) -				_vm->clearBoundary(x1, x2, y2);          // Clear our own boundary +				_vm->clearBoundary(x1, x2, y2);     // Clear our own boundary  			// Allowable motion wrt boundary  			int dx = _vm->deltaX(x1, x2, obj->vx, y2); @@ -307,7 +307,7 @@ void ObjectHandler_v1d::moveObjects() {  			}  			if ((obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING)) -				_vm->storeBoundary(x1, x2, y2);          // Re-store our own boundary +				_vm->storeBoundary(x1, x2, y2);     // Re-store our own boundary  			obj->x += dx;                           // Update object position  			obj->y += dy; @@ -337,12 +337,12 @@ void ObjectHandler_v1d::moveObjects() {  	// If maze mode is enabled, do special maze processing  	if (_maze.enabledFl) { -		seq_t *currImage = _vm->_hero->currImagePtr;    // Get ptr to current image +		seq_t *currImage = _vm->_hero->currImagePtr;// Get ptr to current image  		// hero coordinates -		int x1 = _vm->_hero->x + currImage->x1;         // Left edge of object -		int x2 = _vm->_hero->x + currImage->x2;         // Right edge -		int y1 = _vm->_hero->y + currImage->y1;         // Top edge -		int y2 = _vm->_hero->y + currImage->y2;         // Bottom edge +		int x1 = _vm->_hero->x + currImage->x1;     // Left edge of object +		int x2 = _vm->_hero->x + currImage->x2;     // Right edge +		int y1 = _vm->_hero->y + currImage->y1;     // Top edge +		int y2 = _vm->_hero->y + currImage->y2;     // Bottom edge  		_vm->_scheduler->processMaze(x1, x2, y1, y2);  	} @@ -367,4 +367,25 @@ void ObjectHandler_v1d::swapImages(int objIndex1, int objIndex2) {  	_vm->_heroImage = (_vm->_heroImage == HERO) ? objIndex2 : HERO;  } +void ObjectHandler_v1d::homeIn(int objIndex1, int objIndex2, int8 objDx, int8 objDy) { +	// object obj1 will home in on object obj2 +	object_t *obj1 = &_objects[objIndex1]; +	object_t *obj2 = &_objects[objIndex2]; +	obj1->pathType = AUTO; +	int dx = obj1->x + obj1->currImagePtr->x1 - obj2->x - obj2->currImagePtr->x1; +	int dy = obj1->y + obj1->currImagePtr->y1 - obj2->y - obj2->currImagePtr->y1; + +	if (dx == 0)                                    // Don't EVER divide by zero! +		dx = 1; +	if (dy == 0) +		dy = 1; + +	if (abs(dx) > abs(dy)) { +		obj1->vx = objDx * -SIGN(dx); +		obj1->vy = abs((objDy * dy) / dx) * -SIGN(dy); +	} else { +		obj1->vy = objDy * SIGN(dy); +		obj1->vx = abs((objDx * dx) / dy) * SIGN(dx); +	} +}  } // End of namespace Hugo diff --git a/engines/hugo/object_v1w.cpp b/engines/hugo/object_v1w.cpp index 015c85ea8d..e5716f8b8c 100644 --- a/engines/hugo/object_v1w.cpp +++ b/engines/hugo/object_v1w.cpp @@ -46,7 +46,7 @@  namespace Hugo { -ObjectHandler_v1w::ObjectHandler_v1w(HugoEngine *vm) : ObjectHandler(vm) { +ObjectHandler_v1w::ObjectHandler_v1w(HugoEngine *vm) : ObjectHandler_v3d(vm) {  }  ObjectHandler_v1w::~ObjectHandler_v1w() { diff --git a/engines/hugo/object_v2d.cpp b/engines/hugo/object_v2d.cpp index f97f8af002..f2b7fb3cda 100644 --- a/engines/hugo/object_v2d.cpp +++ b/engines/hugo/object_v2d.cpp @@ -288,7 +288,7 @@ void ObjectHandler_v2d::moveObjects() {  	// Move objects, allowing for boundaries  	for (int i = 0; i < _numObj; i++) { -		object_t *obj = &_objects[i];                         // Get pointer to object +		object_t *obj = &_objects[i];               // Get pointer to object  		if ((obj->screenIndex == *_vm->_screen_p) && (obj->vx || obj->vy)) {  			// Only process if it's moving @@ -302,7 +302,7 @@ void ObjectHandler_v2d::moveObjects() {  			int y2 = obj->y + currImage->y2;        // Bottom edge  			if ((obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING)) -				_vm->clearBoundary(x1, x2, y2);          // Clear our own boundary +				_vm->clearBoundary(x1, x2, y2);     // Clear our own boundary  			// Allowable motion wrt boundary  			int dx = _vm->deltaX(x1, x2, obj->vx, y2); @@ -320,7 +320,7 @@ void ObjectHandler_v2d::moveObjects() {  			}  			if ((obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING)) -				_vm->storeBoundary(x1, x2, y2);          // Re-store our own boundary +				_vm->storeBoundary(x1, x2, y2);     // Re-store our own boundary  			obj->x += dx;                           // Update object position  			obj->y += dy; @@ -342,8 +342,8 @@ void ObjectHandler_v2d::moveObjects() {  	// Clear all object baselines from the boundary file.  	for (int i = 0; i < _numObj; i++) { -		object_t *obj = &_objects[i];               // Get pointer to object -		seq_t *currImage = obj->currImagePtr;       // Get ptr to current image +		object_t *obj = &_objects[i];                   // Get pointer to object +		seq_t *currImage = obj->currImagePtr;           // Get ptr to current image  		if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING))  			_vm->clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);  	} @@ -361,4 +361,25 @@ void ObjectHandler_v2d::moveObjects() {  	}  } +void ObjectHandler_v2d::homeIn(int objIndex1, int objIndex2, int8 objDx, int8 objDy) { +	// object obj1 will home in on object obj2 +	object_t *obj1 = &_objects[objIndex1]; +	object_t *obj2 = &_objects[objIndex2]; +	obj1->pathType = AUTO; +	int dx = obj1->x + obj1->currImagePtr->x1 - obj2->x - obj2->currImagePtr->x1; +	int dy = obj1->y + obj1->currImagePtr->y1 - obj2->y - obj2->currImagePtr->y1; + +	if (dx == 0)                                        // Don't EVER divide by zero! +		dx = 1; +	if (dy == 0) +		dy = 1; + +	if (abs(dx) > abs(dy)) { +		obj1->vx = objDx * -SIGN(dx); +		obj1->vy = abs((objDy * dy) / dx) * -SIGN(dy); +	} else { +		obj1->vy = objDy * -SIGN(dy); +		obj1->vx = abs((objDx * dx) / dy) * -SIGN(dx); +	} +}  } // End of namespace Hugo diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp index 361352d95b..76250c68cb 100644 --- a/engines/hugo/schedule.cpp +++ b/engines/hugo/schedule.cpp @@ -39,6 +39,9 @@  #include "hugo/file.h"  #include "hugo/display.h"  #include "hugo/util.h" +#include "hugo/object.h" +#include "hugo/sound.h" +#include "hugo/parser.h"  namespace Hugo { @@ -1000,4 +1003,255 @@ void Scheduler::insertAction(act *action) {  	}  } +/** +* This function performs the action in the event structure pointed to by p +* It dequeues the event and returns it to the free list.  It returns a ptr +* to the next action in the list, except special case of NEW_SCREEN +*/ +event_t *Scheduler::doAction(event_t *curEvent) { +	debugC(1, kDebugSchedule, "doAction - Event action type : %d", curEvent->action->a0.actType); + +	status_t &gameStatus = _vm->getGameStatus(); +	act *action = curEvent->action; +	object_t *obj1; +	int       dx, dy; +	event_t  *wrkEvent;                             // Save ev_p->next_p for return + +	switch (action->a0.actType) { +	case ANULL:                                     // Big NOP from DEL_EVENTS +		break; +	case ASCHEDULE:                                 // act0: Schedule an action list +		insertActionList(action->a0.actIndex); +		break; +	case START_OBJ:                                 // act1: Start an object cycling +		_vm->_object->_objects[action->a1.objIndex].cycleNumb = action->a1.cycleNumb; +		_vm->_object->_objects[action->a1.objIndex].cycling = action->a1.cycle; +		break; +	case INIT_OBJXY:                                // act2: Initialise an object +		_vm->_object->_objects[action->a2.objIndex].x = action->a2.x;          // Coordinates +		_vm->_object->_objects[action->a2.objIndex].y = action->a2.y; +		break; +	case PROMPT:                                    // act3: Prompt user for key phrase +		promptAction(action); +		break; +	case BKGD_COLOR:                                // act4: Set new background color +		_vm->_screen->setBackgroundColor(action->a4.newBackgroundColor); +		break; +	case INIT_OBJVXY:                               // act5: Initialise an object velocity +		_vm->_object->setVelocity(action->a5.objIndex, action->a5.vx, action->a5.vy); +		break; +	case INIT_CARRY:                                // act6: Initialise an object +		_vm->_object->setCarry(action->a6.objIndex, action->a6.carriedFl);  // carried status +		break; +	case INIT_HF_COORD:                             // act7: Initialise an object to hero's "feet" coords +		_vm->_object->_objects[action->a7.objIndex].x = _vm->_hero->x - 1; +		_vm->_object->_objects[action->a7.objIndex].y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1; +		_vm->_object->_objects[action->a7.objIndex].screenIndex = *_vm->_screen_p;  // Don't forget screen! +		break; +	case NEW_SCREEN:                                // act8: Start new screen +		newScreen(action->a8.screenIndex); +		break; +	case INIT_OBJSTATE:                             // act9: Initialise an object state +		_vm->_object->_objects[action->a9.objIndex].state = action->a9.newState; +		break; +	case INIT_PATH:                                 // act10: Initialise an object path and velocity +		_vm->_object->setPath(action->a10.objIndex, (path_t) action->a10.newPathType, action->a10.vxPath, action->a10.vyPath); +		break; +	case COND_R:                                    // act11: action lists conditional on object state +		if (_vm->_object->_objects[action->a11.objIndex].state == action->a11.stateReq) +			insertActionList(action->a11.actPassIndex); +		else +			insertActionList(action->a11.actFailIndex); +		break; +	case TEXT:                                      // act12: Text box (CF WARN) +		Utils::Box(BOX_ANY, "%s", _vm->_file->fetchString(action->a12.stringIndex));   // Fetch string from file +		break; +	case SWAP_IMAGES:                               // act13: Swap 2 object images +		_vm->_object->swapImages(action->a13.objIndex1, action->a13.objIndex2); +		break; +	case COND_SCR:                                  // act14: Conditional on current screen +		if (_vm->_object->_objects[action->a14.objIndex].screenIndex == action->a14.screenReq) +			insertActionList(action->a14.actPassIndex); +		else +			insertActionList(action->a14.actFailIndex); +		break; +	case AUTOPILOT:                                 // act15: Home in on a (stationary) object +		_vm->_object->homeIn(action->a15.objIndex1, action->a15.objIndex2, action->a15.dx, action->a15.dy); +		break; +	case INIT_OBJ_SEQ:                              // act16: Set sequence number to use +		// Note: Don't set a sequence at time 0 of a new screen, it causes +		// problems clearing the boundary bits of the object!  t>0 is safe +		_vm->_object->_objects[action->a16.objIndex].currImagePtr = _vm->_object->_objects[action->a16.objIndex].seqList[action->a16.seqIndex].seqPtr; +		break; +	case SET_STATE_BITS:                            // act17: OR mask with curr obj state +		_vm->_object->_objects[action->a17.objIndex].state |= action->a17.stateMask; +		break; +	case CLEAR_STATE_BITS:                          // act18: AND ~mask with curr obj state +		_vm->_object->_objects[action->a18.objIndex].state &= ~action->a18.stateMask; +		break; +	case TEST_STATE_BITS:                           // act19: If all bits set, do apass else afail +		if ((_vm->_object->_objects[action->a19.objIndex].state & action->a19.stateMask) == action->a19.stateMask) +			insertActionList(action->a19.actPassIndex); +		else +			insertActionList(action->a19.actFailIndex); +		break; +	case DEL_EVENTS:                                // act20: Remove all events of this action type +		delEventType(action->a20.actTypeDel); +		break; +	case GAMEOVER:                                  // act21: Game over! +		// NOTE: Must wait at least 1 tick before issuing this action if +		// any objects are to be made invisible! +		gameStatus.gameOverFl = true; +		break; +	case INIT_HH_COORD:                             // act22: Initialise an object to hero's actual coords +		_vm->_object->_objects[action->a22.objIndex].x = _vm->_hero->x; +		_vm->_object->_objects[action->a22.objIndex].y = _vm->_hero->y; +		_vm->_object->_objects[action->a22.objIndex].screenIndex = *_vm->_screen_p;// Don't forget screen! +		break; +	case EXIT:                                      // act23: Exit game back to DOS +		_vm->endGame(); +		break; +	case BONUS:                                     // act24: Get bonus score for action +		processBonus(action->a24.pointIndex); +		break; +	case COND_BOX:                                  // act25: Conditional on bounding box +		obj1 = &_vm->_object->_objects[action->a25.objIndex]; +		dx = obj1->x + obj1->currImagePtr->x1; +		dy = obj1->y + obj1->currImagePtr->y2; +		if ((dx >= action->a25.x1) && (dx <= action->a25.x2) && +		        (dy >= action->a25.y1) && (dy <= action->a25.y2)) +			insertActionList(action->a25.actPassIndex); +		else +			insertActionList(action->a25.actFailIndex); +		break; +	case SOUND:                                     // act26: Play a sound (or tune) +		if (action->a26.soundIndex < _vm->_tunesNbr) +			_vm->_sound->playMusic(action->a26.soundIndex); +		else +			_vm->_sound->playSound(action->a26.soundIndex, BOTH_CHANNELS, MED_PRI); +		break; +	case ADD_SCORE:                                 // act27: Add object's value to score +		_vm->adjustScore(_vm->_object->_objects[action->a27.objIndex].objValue); +		break; +	case SUB_SCORE:                                 // act28: Subtract object's value from score +		_vm->adjustScore(-_vm->_object->_objects[action->a28.objIndex].objValue); +		break; +	case COND_CARRY:                                // act29: Conditional on object being carried +		if (_vm->_object->isCarried(action->a29.objIndex)) +			insertActionList(action->a29.actPassIndex); +		else +			insertActionList(action->a29.actFailIndex); +		break; +	case INIT_MAZE:                                 // act30: Enable and init maze structure +		_maze.enabledFl = true; +		_maze.size = action->a30.mazeSize; +		_maze.x1 = action->a30.x1; +		_maze.y1 = action->a30.y1; +		_maze.x2 = action->a30.x2; +		_maze.y2 = action->a30.y2; +		_maze.x3 = action->a30.x3; +		_maze.x4 = action->a30.x4; +		_maze.firstScreenIndex = action->a30.firstScreenIndex; +		break; +	case EXIT_MAZE:                                 // act31: Disable maze mode +		_maze.enabledFl = false; +		break; +	case INIT_PRIORITY: +		_vm->_object->_objects[action->a32.objIndex].priority = action->a32.priority; +		break; +	case INIT_SCREEN: +		_vm->_object->_objects[action->a33.objIndex].screenIndex = action->a33.screenIndex; +		break; +	case AGSCHEDULE:                                // act34: Schedule a (global) action list +		insertActionList(action->a34.actIndex); +		break; +	case REMAPPAL:                                  // act35: Remap a palette color +		_vm->_screen->remapPal(action->a35.oldColorIndex, action->a35.newColorIndex); +		break; +	case COND_NOUN:                                 // act36: Conditional on noun mentioned +		if (_vm->_parser->isWordPresent(_vm->_arrayNouns[action->a36.nounIndex])) +			insertActionList(action->a36.actPassIndex); +		else +			insertActionList(action->a36.actFailIndex); +		break; +	case SCREEN_STATE:                              // act37: Set new screen state +		_vm->_screenStates[action->a37.screenIndex] = action->a37.newState; +		break; +	case INIT_LIPS:                                 // act38: Position lips on object +		_vm->_object->_objects[action->a38.lipsObjIndex].x = _vm->_object->_objects[action->a38.objIndex].x + action->a38.dxLips; +		_vm->_object->_objects[action->a38.lipsObjIndex].y = _vm->_object->_objects[action->a38.objIndex].y + action->a38.dyLips; +		_vm->_object->_objects[action->a38.lipsObjIndex].screenIndex = *_vm->_screen_p; // Don't forget screen! +		_vm->_object->_objects[action->a38.lipsObjIndex].cycling = CYCLE_FORWARD; +		break; +	case INIT_STORY_MODE:                           // act39: Init story_mode flag +		// This is similar to the QUIET path mode, except that it is +		// independant of it and it additionally disables the ">" prompt +		gameStatus.storyModeFl = action->a39.storyModeFl; + +		// End the game after story if this is special vendor demo mode +		if (gameStatus.demoFl && action->a39.storyModeFl == false) +			_vm->endGame(); +		break; +	case WARN:                                      // act40: Text box (CF TEXT) +		Utils::Box(BOX_OK, "%s", _vm->_file->fetchString(action->a40.stringIndex)); +		break; +	case COND_BONUS:                                // act41: Perform action if got bonus +		if (_vm->_points[action->a41.BonusIndex].scoredFl) +			insertActionList(action->a41.actPassIndex); +		else +			insertActionList(action->a41.actFailIndex); +		break; +	case TEXT_TAKE:                                 // act42: Text box with "take" message +		Utils::Box(BOX_ANY, TAKE_TEXT, _vm->_arrayNouns[_vm->_object->_objects[action->a42.objIndex].nounIndex][TAKE_NAME]); +		break; +	case YESNO:                                     // act43: Prompt user for Yes or No +		if (Utils::Box(BOX_YESNO, "%s", _vm->_file->fetchString(action->a43.promptIndex)) != 0) +			insertActionList(action->a43.actYesIndex); +		else +			insertActionList(action->a43.actNoIndex); +		break; +	case STOP_ROUTE:                                // act44: Stop any route in progress +		gameStatus.routeIndex = -1; +		break; +	case COND_ROUTE:                                // act45: Conditional on route in progress +		if (gameStatus.routeIndex >= action->a45.routeIndex) +			insertActionList(action->a45.actPassIndex); +		else +			insertActionList(action->a45.actFailIndex); +		break; +	case INIT_JUMPEXIT:                             // act46: Init status.jumpexit flag +		// This is to allow left click on exit to get there immediately +		// For example the plane crash in Hugo2 where hero is invisible +		// Couldn't use INVISIBLE flag since conflicts with boat in Hugo1 +		gameStatus.jumpExitFl = action->a46.jumpExitFl; +		break; +	case INIT_VIEW:                                 // act47: Init object.viewx, viewy, dir +		_vm->_object->_objects[action->a47.objIndex].viewx = action->a47.viewx; +		_vm->_object->_objects[action->a47.objIndex].viewy = action->a47.viewy; +		_vm->_object->_objects[action->a47.objIndex].direction = action->a47.direction; +		break; +	case INIT_OBJ_FRAME:                            // act48: Set seq,frame number to use +		// Note: Don't set a sequence at time 0 of a new screen, it causes +		// problems clearing the boundary bits of the object!  t>0 is safe +		_vm->_object->_objects[action->a48.objIndex].currImagePtr = _vm->_object->_objects[action->a48.objIndex].seqList[action->a48.seqIndex].seqPtr; +		for (dx = 0; dx < action->a48.frameIndex; dx++) +			_vm->_object->_objects[action->a48.objIndex].currImagePtr = _vm->_object->_objects[action->a48.objIndex].currImagePtr->nextSeqPtr; +		break; +	case OLD_SONG: +		// Replaces ACT26 for DOS games. +		_vm->_sound->DOSSongPtr = _vm->_textData[action->a49.songIndex]; +		break; +	default: +		error("An error has occurred: %s", "doAction"); +		break; +	} + +	if (action->a0.actType == NEW_SCREEN) {         // New_screen() deletes entire list +		return 0;                                   // next_p = 0 since list now empty +	} else { +		wrkEvent = curEvent->nextEvent; +		delQueue(curEvent);                         // Return event to free list +		return wrkEvent;                            // Return next event ptr +	} +}  } // End of namespace Hugo diff --git a/engines/hugo/schedule.h b/engines/hugo/schedule.h index 436b6e7792..6337a8bb06 100644 --- a/engines/hugo/schedule.h +++ b/engines/hugo/schedule.h @@ -85,9 +85,11 @@ protected:  	act    **_actListArr;  	virtual const char *getCypher() = 0; -	virtual event_t *doAction(event_t *curEvent) = 0; +	virtual void delEventType(action_t actTypeDel) = 0;  	virtual void delQueue(event_t *curEvent) = 0; +	virtual void promptAction(act *action) = 0; +	event_t *doAction(event_t *curEvent);  	event_t *getQueue();  	uint32 getDosTicks(bool updateFl); @@ -106,8 +108,9 @@ public:  	virtual void runScheduler();  protected: +	virtual void delEventType(action_t actTypeDel);  	virtual void delQueue(event_t *curEvent); -	virtual event_t *doAction(event_t *curEvent); +	virtual void promptAction(act *action);  };  class Scheduler_v2d : public Scheduler_v1d { @@ -116,9 +119,11 @@ public:  	virtual ~Scheduler_v2d();  	virtual const char *getCypher(); +  protected: +	void delEventType(action_t actTypeDel);  	void delQueue(event_t *curEvent); -	event_t *doAction(event_t *curEvent); +	void promptAction(act *action);  };  class Scheduler_v3d : public Scheduler_v2d { diff --git a/engines/hugo/schedule_v1d.cpp b/engines/hugo/schedule_v1d.cpp index 966085260b..68933f375e 100644 --- a/engines/hugo/schedule_v1d.cpp +++ b/engines/hugo/schedule_v1d.cpp @@ -39,10 +39,7 @@  #include "hugo/schedule.h"  #include "hugo/file.h"  #include "hugo/display.h" -#include "hugo/parser.h"  #include "hugo/util.h" -#include "hugo/sound.h" -#include "hugo/object.h"  namespace Hugo { @@ -84,200 +81,6 @@ void Scheduler_v1d::delQueue(event_t *curEvent) {  }  /** -* This function performs the action in the event structure pointed to by p -* It dequeues the event and returns it to the free list.  It returns a ptr -* to the next action in the list, except special case of NEW_SCREEN -*/ -event_t *Scheduler_v1d::doAction(event_t *curEvent) { -	debugC(1, kDebugSchedule, "doAction - Event action type : %d", curEvent->action->a0.actType); - -	status_t &gameStatus = _vm->getGameStatus(); -	act *action = curEvent->action; -	char     *response;                             // User's response string -	object_t *obj1; -	object_t *obj2; -	int       dx, dy; -	event_t  *wrkEvent;                             // Save ev_p->next_p for return - -	switch (action->a0.actType) { -	case ANULL:                                     // Big NOP from DEL_EVENTS -		break; -	case ASCHEDULE:                                 // act0: Schedule an action list -		insertActionList(action->a0.actIndex); -		break; -	case START_OBJ:                                 // act1: Start an object cycling -		_vm->_object->_objects[action->a1.objIndex].cycleNumb = action->a1.cycleNumb; -		_vm->_object->_objects[action->a1.objIndex].cycling = action->a1.cycle; -		break; -	case INIT_OBJXY:                                // act2: Initialise an object -		_vm->_object->_objects[action->a2.objIndex].x = action->a2.x;          // Coordinates -		_vm->_object->_objects[action->a2.objIndex].y = action->a2.y; -		break; -	case PROMPT: {                                  // act3: Prompt user for key phrase -		response = Utils::Box(BOX_PROMPT, "%s", _vm->_file->fetchString(action->a3.promptIndex)); -		strcpy(response, _vm->_file->fetchString(action->a3.promptIndex)); -		if (action->a3.encodedFl) -			decodeString(response); - -		warning("STUB: doAction(act3), expecting answer %s", response); - -		// TODO: The answer of the player is not handled currently! Once it'll be read in the messageBox, uncomment this block -#if 0 -		if (strstr (response, action->a3.response)) -			insertActionList(action->a3.actPassIndex); -		else -			insertActionList(action->a3.actFailIndex); -#endif - -		// HACK: As the answer is not read, currently it's always considered correct -		insertActionList(action->a3.actPassIndex); -		break; -		} -	case BKGD_COLOR:                                // act4: Set new background color -		_vm->_screen->setBackgroundColor(action->a4.newBackgroundColor); -		break; -	case INIT_OBJVXY:                               // act5: Initialise an object velocity -		_vm->_object->setVelocity(action->a5.objIndex, action->a5.vx, action->a5.vy); -		break; -	case INIT_CARRY:                                // act6: Initialise an object -		_vm->_object->setCarry(action->a6.objIndex, action->a6.carriedFl);  // carried status -		break; -	case INIT_HF_COORD:                             // act7: Initialise an object to hero's "feet" coords -		_vm->_object->_objects[action->a7.objIndex].x = _vm->_hero->x - 1; -		_vm->_object->_objects[action->a7.objIndex].y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1; -		_vm->_object->_objects[action->a7.objIndex].screenIndex = *_vm->_screen_p;  // Don't forget screen! -		break; -	case NEW_SCREEN:                                // act8: Start new screen -		newScreen(action->a8.screenIndex); -		break; -	case INIT_OBJSTATE:                             // act9: Initialise an object state -		_vm->_object->_objects[action->a9.objIndex].state = action->a9.newState; -		break; -	case INIT_PATH:                                 // act10: Initialise an object path and velocity -		_vm->_object->setPath(action->a10.objIndex, (path_t) action->a10.newPathType, action->a10.vxPath, action->a10.vyPath); -		break; -	case COND_R:                                    // act11: action lists conditional on object state -		if (_vm->_object->_objects[action->a11.objIndex].state == action->a11.stateReq) -			insertActionList(action->a11.actPassIndex); -		else -			insertActionList(action->a11.actFailIndex); -		break; -	case TEXT:                                      // act12: Text box (CF WARN) -		Utils::Box(BOX_ANY, "%s", _vm->_file->fetchString(action->a12.stringIndex));   // Fetch string from file -		break; -	case SWAP_IMAGES:                               // act13: Swap 2 object images -		_vm->_object->swapImages(action->a13.objIndex1, action->a13.objIndex2); -		break; -	case COND_SCR:                                  // act14: Conditional on current screen -		if (_vm->_object->_objects[action->a14.objIndex].screenIndex == action->a14.screenReq) -			insertActionList(action->a14.actPassIndex); -		else -			insertActionList(action->a14.actFailIndex); -		break; -	case AUTOPILOT:                                 // act15: Home in on a (stationary) object -		// object p1 will home in on object p2 -		obj1 = &_vm->_object->_objects[action->a15.objIndex1]; -		obj2 = &_vm->_object->_objects[action->a15.objIndex2]; -		obj1->pathType = AUTO; -		dx = obj1->x + obj1->currImagePtr->x1 - obj2->x - obj2->currImagePtr->x1; -		dy = obj1->y + obj1->currImagePtr->y1 - obj2->y - obj2->currImagePtr->y1; - -		if (dx == 0)                                // Don't EVER divide by zero! -			dx = 1; -		if (dy == 0) -			dy = 1; - -		if (abs(dx) > abs(dy)) { -			obj1->vx = action->a15.dx * -SIGN(dx); -			obj1->vy = abs((action->a15.dy * dy) / dx) * -SIGN(dy); -		} else { -			obj1->vy = action->a15.dy * SIGN(dy); -			obj1->vx = abs((action->a15.dx * dx) / dy) * SIGN(dx); -		} -		break; -	case INIT_OBJ_SEQ:                              // act16: Set sequence number to use -		// Note: Don't set a sequence at time 0 of a new screen, it causes -		// problems clearing the boundary bits of the object!  t>0 is safe -		_vm->_object->_objects[action->a16.objIndex].currImagePtr = _vm->_object->_objects[action->a16.objIndex].seqList[action->a16.seqIndex].seqPtr; -		break; -	case SET_STATE_BITS:                            // act17: OR mask with curr obj state -		_vm->_object->_objects[action->a17.objIndex].state |= action->a17.stateMask; -		break; -	case CLEAR_STATE_BITS:                          // act18: AND ~mask with curr obj state -		_vm->_object->_objects[action->a18.objIndex].state &= ~action->a18.stateMask; -		break; -	case TEST_STATE_BITS:                           // act19: If all bits set, do apass else afail -		if ((_vm->_object->_objects[action->a19.objIndex].state & action->a19.stateMask) == action->a19.stateMask) -			insertActionList(action->a19.actPassIndex); -		else -			insertActionList(action->a19.actFailIndex); -		break; -	case DEL_EVENTS:                                // act20: Remove all events of this action type -		// Note: actions are not deleted here, simply turned into NOPs! -		wrkEvent = _headEvent;                      // The earliest event -		while (wrkEvent) {                          // While events found in list -			if (wrkEvent->action->a20.actType == action->a20.actTypeDel) -				wrkEvent->action->a20.actType = ANULL; -			wrkEvent = wrkEvent->nextEvent; -		} -		break; -	case GAMEOVER:                                  // act21: Game over! -		// NOTE: Must wait at least 1 tick before issuing this action if -		// any objects are to be made invisible! -		gameStatus.gameOverFl = true; -		break; -	case INIT_HH_COORD:                             // act22: Initialise an object to hero's actual coords -		_vm->_object->_objects[action->a22.objIndex].x = _vm->_hero->x; -		_vm->_object->_objects[action->a22.objIndex].y = _vm->_hero->y; -		_vm->_object->_objects[action->a22.objIndex].screenIndex = *_vm->_screen_p;// Don't forget screen! -		break; -	case EXIT:                                      // act23: Exit game back to DOS -		_vm->endGame(); -		break; -	case BONUS:                                     // act24: Get bonus score for action -		processBonus(action->a24.pointIndex); -		break; -	case COND_BOX:                                  // act25: Conditional on bounding box -		obj1 = &_vm->_object->_objects[action->a25.objIndex]; -		dx = obj1->x + obj1->currImagePtr->x1; -		dy = obj1->y + obj1->currImagePtr->y2; -		if ((dx >= action->a25.x1) && (dx <= action->a25.x2) && -		        (dy >= action->a25.y1) && (dy <= action->a25.y2)) -			insertActionList(action->a25.actPassIndex); -		else -			insertActionList(action->a25.actFailIndex); -		break; -	case ADD_SCORE:                                 // act27: Add object's value to score -		_vm->adjustScore(_vm->_object->_objects[action->a27.objIndex].objValue); -		break; -	case SUB_SCORE:                                 // act28: Subtract object's value from score -		_vm->adjustScore(-_vm->_object->_objects[action->a28.objIndex].objValue); -		break; -	case COND_CARRY:                                // act29: Conditional on object being carried -		if (_vm->_object->isCarried(action->a29.objIndex)) -			insertActionList(action->a29.actPassIndex); -		else -			insertActionList(action->a29.actFailIndex); -		break; -	case OLD_SONG: -		// Replaces ACT26 for DOS games. -		_vm->_sound->DOSSongPtr = _vm->_textData[action->a49.songIndex]; -		break; -	default: -		error("An error has occurred: %s", "doAction"); -		break; -	} - -	if (action->a0.actType == NEW_SCREEN) {         // New_screen() deletes entire list -		return 0;                                   // next_p = 0 since list now empty -	} else { -		wrkEvent = curEvent->nextEvent; -		delQueue(curEvent);                         // Return event to free list -		return wrkEvent;                            // Return next event ptr -	} -} - -/**  * This is the scheduler which runs every tick.  It examines the event queue  * for any events whose time has come.  It dequeues these events and performs  * the action associated with the event, returning it to the free queue @@ -292,4 +95,36 @@ void Scheduler_v1d::runScheduler() {  		curEvent = doAction(curEvent);              // Perform the action (returns next_p)  } +void Scheduler_v1d::delEventType(action_t actTypeDel) { +	// Note: actions are not deleted here, simply turned into NOPs! +	event_t *wrkEvent = _headEvent;                 // The earliest event +	while (wrkEvent) {                              // While events found in list +		if (wrkEvent->action->a20.actType == actTypeDel) +			wrkEvent->action->a20.actType = ANULL; +		wrkEvent = wrkEvent->nextEvent; +	} +} + +void Scheduler_v1d::promptAction(act *action) { +	Utils::Box(BOX_PROMPT, "%s", _vm->_file->fetchString(action->a3.promptIndex)); +	char response[256]; +	strcpy(response, _vm->_file->fetchString(action->a3.responsePtr[0])); +	if (action->a3.encodedFl) { +		warning("Encrypted flag set"); +		decodeString(response); +	} + +	warning("STUB: doAction(act3), expecting answer %s", response); + +	// TODO: The answer of the player is not handled currently! Once it'll be read in the messageBox, uncomment this block +#if 0 +	if (strstr (response, action->a3.response)) +		insertActionList(action->a3.actPassIndex); +	else +		insertActionList(action->a3.actFailIndex); +#endif + +	// HACK: As the answer is not read, currently it's always considered correct +	insertActionList(action->a3.actPassIndex); +}  } // End of namespace Hugo diff --git a/engines/hugo/schedule_v2d.cpp b/engines/hugo/schedule_v2d.cpp index 191b33ed4a..b5ce8dff62 100644 --- a/engines/hugo/schedule_v2d.cpp +++ b/engines/hugo/schedule_v2d.cpp @@ -40,10 +40,7 @@  #include "hugo/global.h"  #include "hugo/file.h"  #include "hugo/display.h" -#include "hugo/parser.h"  #include "hugo/util.h" -#include "hugo/sound.h" -#include "hugo/object.h"  namespace Hugo { @@ -90,306 +87,43 @@ void Scheduler_v2d::delQueue(event_t *curEvent) {  	_freeEvent = curEvent;  } -/** -* This function performs the action in the event structure pointed to by p -* It dequeues the event and returns it to the free list.  It returns a ptr -* to the next action in the list, except special case of NEW_SCREEN -*/ -event_t *Scheduler_v2d::doAction(event_t *curEvent) { -	debugC(1, kDebugSchedule, "doAction - Event action type : %d", curEvent->action->a0.actType); +void Scheduler_v2d::delEventType(action_t actTypeDel) { +	// Note: actions are not deleted here, simply turned into NOPs! +	event_t *wrkEvent = _headEvent;                 // The earliest event +	event_t *saveEvent; -	status_t &gameStatus = _vm->getGameStatus(); -	act *action = curEvent->action; -	char     *response;                             // User's response string -	object_t *obj1; -	object_t *obj2; -	int       dx, dy; -	event_t  *wrkEvent;                             // Save ev_p->next_p for return -	event_t  *saveEvent;                            // Used in DEL_EVENTS - -	switch (action->a0.actType) { -	case ANULL:                                     // Big NOP from DEL_EVENTS -		break; -	case ASCHEDULE:                                 // act0: Schedule an action list -		insertActionList(action->a0.actIndex); -		break; -	case START_OBJ:                                 // act1: Start an object cycling -		_vm->_object->_objects[action->a1.objIndex].cycleNumb = action->a1.cycleNumb; -		_vm->_object->_objects[action->a1.objIndex].cycling = action->a1.cycle; -		break; -	case INIT_OBJXY:                                // act2: Initialise an object -		_vm->_object->_objects[action->a2.objIndex].x = action->a2.x;          // Coordinates -		_vm->_object->_objects[action->a2.objIndex].y = action->a2.y; -		break; -	case PROMPT: {                                  // act3: Prompt user for key phrase -		response = Utils::Box(BOX_PROMPT, "%s", _vm->_file->fetchString(action->a3.promptIndex)); +	while (wrkEvent) {                              // While events found in list +		saveEvent = wrkEvent->nextEvent; +		if (wrkEvent->action->a20.actType == actTypeDel) +			delQueue(wrkEvent); +		wrkEvent = saveEvent; +	} +} -		warning("STUB: doAction(act3), expecting answer %s", _vm->_file->fetchString(action->a3.responsePtr[0])); +void Scheduler_v2d::promptAction(act *action) { +	Utils::Box(BOX_PROMPT, "%s", _vm->_file->fetchString(action->a3.promptIndex)); +	warning("STUB: doAction(act3), expecting answer %s", _vm->_file->fetchString(action->a3.responsePtr[0])); -		// TODO: The answer of the player is not handled currently! Once it'll be read in the messageBox, uncomment this block +	// TODO: The answer of the player is not handled currently! Once it'll be read in the messageBox, uncomment this block  #if 0 -		bool      found; -		char     *tmpStr;                           // General purpose string ptr +	char *response = Utils::Box(BOX_PROMPT, "%s", _vm->_file->fetchString(action->a3.promptIndex)); -		for (found = false, dx = 0; !found && (action->a3.responsePtr[dx] != -1); dx++) { -			tmpStr = _vm->_file->fetchString(action->a3.responsePtr[dx]); -			if (strstr(Utils::strlwr(response) , tmpStr)) -				found = true; -		} +	bool  found = false; +	char *tmpStr;                                   // General purpose string ptr -		if (found) -			insertActionList(action->a3.actPassIndex); -		else -			insertActionList(action->a3.actFailIndex); -#endif +	for (dx = 0; !found && (action->a3.responsePtr[dx] != -1); dx++) { +		tmpStr = _vm->_file->fetchString(action->a3.responsePtr[dx]); +		if (strstr(Utils::strlwr(response) , tmpStr)) +			found = true; +	} -		// HACK: As the answer is not read, currently it's always considered correct +	if (found)  		insertActionList(action->a3.actPassIndex); -		break; -		} -	case BKGD_COLOR:                                // act4: Set new background color -		_vm->_screen->setBackgroundColor(action->a4.newBackgroundColor); -		break; -	case INIT_OBJVXY:                               // act5: Initialise an object velocity -		_vm->_object->setVelocity(action->a5.objIndex, action->a5.vx, action->a5.vy); -		break; -	case INIT_CARRY:                                // act6: Initialise an object -		_vm->_object->setCarry(action->a6.objIndex, action->a6.carriedFl);  // carried status -		break; -	case INIT_HF_COORD:                             // act7: Initialise an object to hero's "feet" coords -		_vm->_object->_objects[action->a7.objIndex].x = _vm->_hero->x - 1; -		_vm->_object->_objects[action->a7.objIndex].y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1; -		_vm->_object->_objects[action->a7.objIndex].screenIndex = *_vm->_screen_p;  // Don't forget screen! -		break; -	case NEW_SCREEN:                                // act8: Start new screen -		newScreen(action->a8.screenIndex); -		break; -	case INIT_OBJSTATE:                             // act9: Initialise an object state -		_vm->_object->_objects[action->a9.objIndex].state = action->a9.newState; -		break; -	case INIT_PATH:                                 // act10: Initialise an object path and velocity -		_vm->_object->setPath(action->a10.objIndex, (path_t) action->a10.newPathType, action->a10.vxPath, action->a10.vyPath); -		break; -	case COND_R:                                    // act11: action lists conditional on object state -		if (_vm->_object->_objects[action->a11.objIndex].state == action->a11.stateReq) -			insertActionList(action->a11.actPassIndex); -		else -			insertActionList(action->a11.actFailIndex); -		break; -	case TEXT:                                      // act12: Text box (CF WARN) -		Utils::Box(BOX_ANY, "%s", _vm->_file->fetchString(action->a12.stringIndex));   // Fetch string from file -		break; -	case SWAP_IMAGES:                               // act13: Swap 2 object images -		_vm->_object->swapImages(action->a13.objIndex1, action->a13.objIndex2); -		break; -	case COND_SCR:                                  // act14: Conditional on current screen -		if (_vm->_object->_objects[action->a14.objIndex].screenIndex == action->a14.screenReq) -			insertActionList(action->a14.actPassIndex); -		else -			insertActionList(action->a14.actFailIndex); -		break; -	case AUTOPILOT:                                 // act15: Home in on a (stationary) object -		// object p1 will home in on object p2 -		obj1 = &_vm->_object->_objects[action->a15.objIndex1]; -		obj2 = &_vm->_object->_objects[action->a15.objIndex2]; -		obj1->pathType = AUTO; -		dx = obj1->x + obj1->currImagePtr->x1 - obj2->x - obj2->currImagePtr->x1; -		dy = obj1->y + obj1->currImagePtr->y1 - obj2->y - obj2->currImagePtr->y1; - -		if (dx == 0)                                // Don't EVER divide by zero! -			dx = 1; -		if (dy == 0) -			dy = 1; - -		if (abs(dx) > abs(dy)) { -			obj1->vx = action->a15.dx * -SIGN(dx); -			obj1->vy = abs((action->a15.dy * dy) / dx) * -SIGN(dy); -		} else { -			obj1->vy = action->a15.dy * -SIGN(dy); -			obj1->vx = abs((action->a15.dx * dx) / dy) * -SIGN(dx); -		} -		break; -	case INIT_OBJ_SEQ:                              // act16: Set sequence number to use -		// Note: Don't set a sequence at time 0 of a new screen, it causes -		// problems clearing the boundary bits of the object!  t>0 is safe -		_vm->_object->_objects[action->a16.objIndex].currImagePtr = _vm->_object->_objects[action->a16.objIndex].seqList[action->a16.seqIndex].seqPtr; -		break; -	case SET_STATE_BITS:                            // act17: OR mask with curr obj state -		_vm->_object->_objects[action->a17.objIndex].state |= action->a17.stateMask; -		break; -	case CLEAR_STATE_BITS:                          // act18: AND ~mask with curr obj state -		_vm->_object->_objects[action->a18.objIndex].state &= ~action->a18.stateMask; -		break; -	case TEST_STATE_BITS:                           // act19: If all bits set, do apass else afail -		if ((_vm->_object->_objects[action->a19.objIndex].state & action->a19.stateMask) == action->a19.stateMask) -			insertActionList(action->a19.actPassIndex); -		else -			insertActionList(action->a19.actFailIndex); -		break; -	case DEL_EVENTS:                                // act20: Remove all events of this action type -		// Note: actions are not deleted here, simply turned into NOPs! -		wrkEvent = _headEvent;                      // The earliest event -		while (wrkEvent) {                          // While events found in list -			saveEvent = wrkEvent->nextEvent; -			if (wrkEvent->action->a20.actType == action->a20.actTypeDel) -				delQueue(wrkEvent); -			wrkEvent = saveEvent; -		} -		break; -	case GAMEOVER:                                  // act21: Game over! -		// NOTE: Must wait at least 1 tick before issuing this action if -		// any objects are to be made invisible! -		gameStatus.gameOverFl = true; -		break; -	case INIT_HH_COORD:                             // act22: Initialise an object to hero's actual coords -		_vm->_object->_objects[action->a22.objIndex].x = _vm->_hero->x; -		_vm->_object->_objects[action->a22.objIndex].y = _vm->_hero->y; -		_vm->_object->_objects[action->a22.objIndex].screenIndex = *_vm->_screen_p;// Don't forget screen! -		break; -	case EXIT:                                      // act23: Exit game back to DOS -		_vm->endGame(); -		break; -	case BONUS:                                     // act24: Get bonus score for action -		processBonus(action->a24.pointIndex); -		break; -	case COND_BOX:                                  // act25: Conditional on bounding box -		obj1 = &_vm->_object->_objects[action->a25.objIndex]; -		dx = obj1->x + obj1->currImagePtr->x1; -		dy = obj1->y + obj1->currImagePtr->y2; -		if ((dx >= action->a25.x1) && (dx <= action->a25.x2) && -		        (dy >= action->a25.y1) && (dy <= action->a25.y2)) -			insertActionList(action->a25.actPassIndex); -		else -			insertActionList(action->a25.actFailIndex); -		break; -	case SOUND:                                     // act26: Play a sound (or tune) -		if (action->a26.soundIndex < _vm->_tunesNbr) -			_vm->_sound->playMusic(action->a26.soundIndex); -		else -			_vm->_sound->playSound(action->a26.soundIndex, BOTH_CHANNELS, MED_PRI); -		break; -	case ADD_SCORE:                                 // act27: Add object's value to score -		_vm->adjustScore(_vm->_object->_objects[action->a27.objIndex].objValue); -		break; -	case SUB_SCORE:                                 // act28: Subtract object's value from score -		_vm->adjustScore(-_vm->_object->_objects[action->a28.objIndex].objValue); -		break; -	case COND_CARRY:                                // act29: Conditional on object being carried -		if (_vm->_object->isCarried(action->a29.objIndex)) -			insertActionList(action->a29.actPassIndex); -		else -			insertActionList(action->a29.actFailIndex); -		break; -	case INIT_MAZE:                                 // act30: Enable and init maze structure -		_maze.enabledFl = true; -		_maze.size = action->a30.mazeSize; -		_maze.x1 = action->a30.x1; -		_maze.y1 = action->a30.y1; -		_maze.x2 = action->a30.x2; -		_maze.y2 = action->a30.y2; -		_maze.x3 = action->a30.x3; -		_maze.x4 = action->a30.x4; -		_maze.firstScreenIndex = action->a30.firstScreenIndex; -		break; -	case EXIT_MAZE:                                 // act31: Disable maze mode -		_maze.enabledFl = false; -		break; -	case INIT_PRIORITY: -		_vm->_object->_objects[action->a32.objIndex].priority = action->a32.priority; -		break; -	case INIT_SCREEN: -		_vm->_object->_objects[action->a33.objIndex].screenIndex = action->a33.screenIndex; -		break; -	case AGSCHEDULE:                                // act34: Schedule a (global) action list -		insertActionList(action->a34.actIndex); -		break; -	case REMAPPAL:                                  // act35: Remap a palette color -		_vm->_screen->remapPal(action->a35.oldColorIndex, action->a35.newColorIndex); -		break; -	case COND_NOUN:                                 // act36: Conditional on noun mentioned -		if (_vm->_parser->isWordPresent(_vm->_arrayNouns[action->a36.nounIndex])) -			insertActionList(action->a36.actPassIndex); -		else -			insertActionList(action->a36.actFailIndex); -		break; -	case SCREEN_STATE:                              // act37: Set new screen state -		_vm->_screenStates[action->a37.screenIndex] = action->a37.newState; -		break; -	case INIT_LIPS:                                 // act38: Position lips on object -		_vm->_object->_objects[action->a38.lipsObjIndex].x = _vm->_object->_objects[action->a38.objIndex].x + action->a38.dxLips; -		_vm->_object->_objects[action->a38.lipsObjIndex].y = _vm->_object->_objects[action->a38.objIndex].y + action->a38.dyLips; -		_vm->_object->_objects[action->a38.lipsObjIndex].screenIndex = *_vm->_screen_p; // Don't forget screen! -		_vm->_object->_objects[action->a38.lipsObjIndex].cycling = CYCLE_FORWARD; -		break; -	case INIT_STORY_MODE:                           // act39: Init story_mode flag -		// This is similar to the QUIET path mode, except that it is -		// independant of it and it additionally disables the ">" prompt -		gameStatus.storyModeFl = action->a39.storyModeFl; - -		// End the game after story if this is special vendor demo mode -		if (gameStatus.demoFl && action->a39.storyModeFl == false) -			_vm->endGame(); -		break; -	case WARN:                                      // act40: Text box (CF TEXT) -		Utils::Box(BOX_OK, "%s", _vm->_file->fetchString(action->a40.stringIndex)); -		break; -	case COND_BONUS:                                // act41: Perform action if got bonus -		if (_vm->_points[action->a41.BonusIndex].scoredFl) -			insertActionList(action->a41.actPassIndex); -		else -			insertActionList(action->a41.actFailIndex); -		break; -	case TEXT_TAKE:                                 // act42: Text box with "take" message -		Utils::Box(BOX_ANY, TAKE_TEXT, _vm->_arrayNouns[_vm->_object->_objects[action->a42.objIndex].nounIndex][TAKE_NAME]); -		break; -	case YESNO:                                     // act43: Prompt user for Yes or No -		if (Utils::Box(BOX_YESNO, "%s", _vm->_file->fetchString(action->a43.promptIndex)) != 0) -			insertActionList(action->a43.actYesIndex); -		else -			insertActionList(action->a43.actNoIndex); -		break; -	case STOP_ROUTE:                                // act44: Stop any route in progress -		gameStatus.routeIndex = -1; -		break; -	case COND_ROUTE:                                // act45: Conditional on route in progress -		if (gameStatus.routeIndex >= action->a45.routeIndex) -			insertActionList(action->a45.actPassIndex); -		else -			insertActionList(action->a45.actFailIndex); -		break; -	case INIT_JUMPEXIT:                             // act46: Init status.jumpexit flag -		// This is to allow left click on exit to get there immediately -		// For example the plane crash in Hugo2 where hero is invisible -		// Couldn't use INVISIBLE flag since conflicts with boat in Hugo1 -		gameStatus.jumpExitFl = action->a46.jumpExitFl; -		break; -	case INIT_VIEW:                                 // act47: Init object.viewx, viewy, dir -		_vm->_object->_objects[action->a47.objIndex].viewx = action->a47.viewx; -		_vm->_object->_objects[action->a47.objIndex].viewy = action->a47.viewy; -		_vm->_object->_objects[action->a47.objIndex].direction = action->a47.direction; -		break; -	case INIT_OBJ_FRAME:                            // act48: Set seq,frame number to use -		// Note: Don't set a sequence at time 0 of a new screen, it causes -		// problems clearing the boundary bits of the object!  t>0 is safe -		_vm->_object->_objects[action->a48.objIndex].currImagePtr = _vm->_object->_objects[action->a48.objIndex].seqList[action->a48.seqIndex].seqPtr; -		for (dx = 0; dx < action->a48.frameIndex; dx++) -			_vm->_object->_objects[action->a48.objIndex].currImagePtr = _vm->_object->_objects[action->a48.objIndex].currImagePtr->nextSeqPtr; -		break; -	case OLD_SONG: -		// Replaces ACT26 for DOS games. -		_vm->_sound->DOSSongPtr = _vm->_textData[action->a49.songIndex]; -		break; -	default: -		error("An error has occurred: %s", "doAction"); -		break; -	} +	else +		insertActionList(action->a3.actFailIndex); +#endif -	if (action->a0.actType == NEW_SCREEN) {         // New_screen() deletes entire list -		return 0;                                   // next_p = 0 since list now empty -	} else { -		wrkEvent = curEvent->nextEvent; -		delQueue(curEvent);                         // Return event to free list -		return wrkEvent;                            // Return next event ptr -	} +	// HACK: As the answer is not read, currently it's always considered correct +	insertActionList(action->a3.actPassIndex);  }  } // End of namespace Hugo | 
