2003-09-28 15:50:47 +00:00
/* ScummVM - Scumm Interpreter
* Copyright ( C ) 2003 The ScummVM project
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*
* $ Header $
*
*/
2003-10-17 13:12:50 +00:00
# include "stdafx.h"
2003-09-28 15:50:47 +00:00
# include "queen/logic.h"
2003-10-31 13:47:28 +00:00
# include "queen/command.h"
2003-10-21 09:05:16 +00:00
# include "queen/cutaway.h"
2003-10-09 09:09:40 +00:00
# include "queen/defs.h"
2003-11-09 20:50:03 +00:00
# include "queen/debug.h"
2003-10-16 13:54:48 +00:00
# include "queen/display.h"
2003-10-11 10:09:23 +00:00
# include "queen/graphics.h"
2003-10-23 06:44:35 +00:00
# include "queen/input.h"
2003-11-26 13:53:17 +00:00
# include "queen/journal.h"
2003-12-01 20:48:41 +00:00
# include "queen/resource.h"
2003-11-15 21:33:04 +00:00
# include "queen/sound.h"
2003-10-27 15:00:25 +00:00
# include "queen/talk.h"
2003-10-11 10:09:23 +00:00
# include "queen/walk.h"
2003-10-17 13:12:50 +00:00
2003-09-28 15:50:47 +00:00
2003-10-03 19:47:41 +00:00
namespace Queen {
2003-10-30 10:56:38 +00:00
const VerbEnum Logic : : PANEL_VERBS [ ] = {
2003-10-25 09:11:35 +00:00
VERB_NONE ,
VERB_OPEN ,
VERB_CLOSE ,
VERB_MOVE ,
VERB_GIVE ,
VERB_LOOK_AT ,
VERB_PICK_UP ,
VERB_TALK_TO ,
VERB_USE ,
VERB_SCROLL_UP ,
VERB_SCROLL_DOWN ,
VERB_DIGIT_1 , // inventory item 1
VERB_DIGIT_2 , // inventory item 2
VERB_DIGIT_3 , // inventory item 3
VERB_DIGIT_4 , // inventory item 4
} ;
2003-10-23 18:46:04 +00:00
2003-10-30 10:56:38 +00:00
char * Verb : : _verbName [ 13 ] ;
2003-10-23 18:46:04 +00:00
Direction State : : findDirection ( uint16 state ) {
// queen.c l.4014-4021
static const Direction sd [ ] = {
DIR_BACK ,
DIR_RIGHT ,
DIR_LEFT ,
DIR_FRONT
} ;
return sd [ ( state > > 2 ) & 3 ] ;
}
StateTalk State : : findTalk ( uint16 state ) {
return ( state & ( 1 < < 9 ) ) ? STATE_TALK_TALK : STATE_TALK_MUTE ;
}
StateGrab State : : findGrab ( uint16 state ) {
// queen.c l.4022-4029
static const StateGrab gd [ ] = {
STATE_GRAB_NONE ,
STATE_GRAB_DOWN ,
STATE_GRAB_UP ,
STATE_GRAB_MID
} ;
return gd [ state & 3 ] ;
}
StateOn State : : findOn ( uint16 state ) {
return ( state & ( 1 < < 8 ) ) ? STATE_ON_ON : STATE_ON_OFF ;
}
Verb State : : findDefaultVerb ( uint16 state ) {
Verb v ;
switch ( ( state > > 4 ) & 0xF ) {
case 1 :
2003-10-30 10:56:38 +00:00
v = Verb ( VERB_OPEN ) ;
2003-10-23 18:46:04 +00:00
break ;
case 3 :
2003-10-30 10:56:38 +00:00
v = Verb ( VERB_CLOSE ) ;
2003-10-23 18:46:04 +00:00
break ;
case 7 :
2003-10-30 10:56:38 +00:00
v = Verb ( VERB_MOVE ) ;
2003-10-23 18:46:04 +00:00
break ;
case 8 :
2003-10-30 10:56:38 +00:00
v = Verb ( VERB_GIVE ) ;
2003-10-23 18:46:04 +00:00
break ;
2003-11-08 23:45:45 +00:00
case 12 :
2003-10-30 10:56:38 +00:00
v = Verb ( VERB_USE ) ;
2003-10-23 18:46:04 +00:00
break ;
2003-11-08 23:45:45 +00:00
case 14 :
2003-10-30 10:56:38 +00:00
v = Verb ( VERB_PICK_UP ) ;
2003-10-23 18:46:04 +00:00
break ;
2003-11-08 23:45:45 +00:00
case 9 :
2003-10-30 10:56:38 +00:00
v = Verb ( VERB_TALK_TO ) ;
2003-10-23 18:46:04 +00:00
break ;
2003-11-08 23:45:45 +00:00
case 6 :
2003-10-30 10:56:38 +00:00
v = Verb ( VERB_LOOK_AT ) ;
2003-10-23 18:46:04 +00:00
break ;
default :
2003-10-30 10:56:38 +00:00
v = Verb ( VERB_NONE ) ;
2003-10-23 18:46:04 +00:00
break ;
}
return v ;
}
2003-10-25 20:26:50 +00:00
StateUse State : : findUse ( uint16 state ) {
return ( state & ( 1 < < 10 ) ) ? STATE_USE : STATE_USE_ON ;
}
2003-10-23 18:46:04 +00:00
void State : : alterOn ( uint16 * objState , StateOn state ) {
switch ( state ) {
case STATE_ON_ON :
* objState | = ( 1 < < 8 ) ;
break ;
case STATE_ON_OFF :
* objState & = ~ ( 1 < < 8 ) ;
break ;
}
}
void State : : alterDefaultVerb ( uint16 * objState , Verb v ) {
uint16 val ;
2003-10-30 10:56:38 +00:00
switch ( v . value ( ) ) {
2003-10-23 18:46:04 +00:00
case VERB_OPEN :
2003-10-24 08:55:13 +00:00
val = 1 ;
2003-10-23 18:46:04 +00:00
break ;
case VERB_CLOSE :
val = 3 ;
break ;
case VERB_MOVE :
val = 7 ;
break ;
case VERB_GIVE :
val = 8 ;
break ;
2003-11-08 23:45:45 +00:00
case VERB_USE :
2003-10-23 18:46:04 +00:00
val = 12 ;
break ;
2003-11-08 23:45:45 +00:00
case VERB_PICK_UP :
2003-10-23 18:46:04 +00:00
val = 14 ;
break ;
2003-11-08 23:45:45 +00:00
case VERB_TALK_TO :
2003-10-23 18:46:04 +00:00
val = 9 ;
break ;
2003-11-08 23:45:45 +00:00
case VERB_LOOK_AT :
2003-10-23 18:46:04 +00:00
val = 6 ;
break ;
default :
val = 0 ;
break ;
}
2003-10-24 08:55:13 +00:00
* objState = ( * objState & ~ 0xF0 ) | ( val < < 4 ) ;
2003-10-23 18:46:04 +00:00
}
2003-10-27 15:00:25 +00:00
2003-10-29 13:06:10 +00:00
Common : : RandomSource Logic : : randomizer ;
2003-11-09 20:50:03 +00:00
Logic : : Logic ( Resource * theResource , Graphics * graphics , Display * theDisplay , Input * input , Sound * sound )
: _resource ( theResource ) , _graphics ( graphics ) , _display ( theDisplay ) ,
2003-10-25 09:11:35 +00:00
_input ( input ) , _sound ( sound ) {
_settings . talkSpeed = DEFAULT_TALK_SPEED ;
2003-09-29 22:27:08 +00:00
_jas = _resource - > loadFile ( " QUEEN.JAS " , 20 ) ;
2003-10-10 09:19:52 +00:00
_joe . x = _joe . y = 0 ;
2003-10-16 16:58:30 +00:00
_joe . scale = 100 ;
2003-10-11 10:09:23 +00:00
_walk = new Walk ( this , _graphics ) ;
2003-11-15 21:33:04 +00:00
_cmd = new Command ( this , _graphics , _input , _walk , _sound ) ;
2003-11-09 20:50:03 +00:00
_dbg = new Debug ( _input , this , _graphics ) ;
2003-10-13 14:21:17 +00:00
memset ( _gameState , 0 , sizeof ( _gameState ) ) ;
2003-11-09 14:16:46 +00:00
memset ( _talkSelected , 0 , sizeof ( _talkSelected ) ) ;
2003-09-28 15:50:47 +00:00
initialise ( ) ;
}
2003-10-05 16:07:07 +00:00
Logic : : ~ Logic ( ) {
2003-10-28 12:42:35 +00:00
delete [ ] _jas ;
2003-10-11 10:09:23 +00:00
delete _walk ;
2003-10-31 13:47:28 +00:00
delete _cmd ;
2003-11-09 20:50:03 +00:00
delete _dbg ;
2003-09-28 15:50:47 +00:00
}
2003-10-05 16:07:07 +00:00
void Logic : : initialise ( ) {
2003-10-09 09:09:40 +00:00
int16 i , j ;
2003-09-28 15:50:47 +00:00
uint8 * ptr = _jas ;
2003-11-08 23:45:45 +00:00
2003-10-14 12:55:31 +00:00
_numRooms = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
_numNames = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
_numObjects = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
_numDescriptions = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
2003-11-08 23:45:45 +00:00
2003-10-14 12:55:31 +00:00
// Object data
2003-10-02 14:44:51 +00:00
_objectData = new ObjectData [ _numObjects + 1 ] ;
2003-10-14 12:55:31 +00:00
memset ( & _objectData [ 0 ] , 0 , sizeof ( ObjectData ) ) ;
2003-10-06 13:20:29 +00:00
for ( i = 1 ; i < = _numObjects ; i + + ) {
2003-10-14 12:55:31 +00:00
_objectData [ i ] . readFrom ( ptr ) ;
2003-10-02 14:44:51 +00:00
}
2003-11-08 23:45:45 +00:00
2003-10-14 12:55:31 +00:00
// Room data
2003-09-28 19:57:01 +00:00
_roomData = new uint16 [ _numRooms + 2 ] ;
2003-10-14 12:55:31 +00:00
_roomData [ 0 ] = 0 ;
2003-10-06 13:20:29 +00:00
for ( i = 1 ; i < = ( _numRooms + 1 ) ; i + + ) {
2003-10-14 12:55:31 +00:00
_roomData [ i ] = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
2003-09-28 15:50:47 +00:00
}
_roomData [ _numRooms + 1 ] = _numObjects ;
2003-10-14 12:55:31 +00:00
// SFX Name
2003-10-02 14:55:28 +00:00
// the following table isn't available in demo version
if ( _resource - > isDemo ( ) ) {
_sfxName = NULL ;
}
else {
_sfxName = new uint16 [ _numRooms + 1 ] ;
2003-10-14 12:55:31 +00:00
_sfxName [ 0 ] = 0 ;
2003-10-06 13:20:29 +00:00
for ( i = 1 ; i < = _numRooms ; i + + ) {
2003-10-14 12:55:31 +00:00
_sfxName [ i ] = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
2003-10-02 14:55:28 +00:00
}
}
2003-09-28 15:50:47 +00:00
2003-10-14 12:55:31 +00:00
// Item information
_numItems = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
2003-09-28 15:50:47 +00:00
2003-10-08 08:55:07 +00:00
_itemData = new ItemData [ _numItems + 1 ] ;
2003-10-14 12:55:31 +00:00
memset ( & _itemData [ 0 ] , 0 , sizeof ( ItemData ) ) ;
2003-10-06 13:20:29 +00:00
for ( i = 1 ; i < = _numItems ; i + + ) {
2003-10-14 12:55:31 +00:00
_itemData [ i ] . readFrom ( ptr ) ;
2003-09-28 15:50:47 +00:00
}
2003-11-08 23:45:45 +00:00
2003-10-14 12:55:31 +00:00
// Graphic Image Data
_numGraphics = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
2003-09-28 15:50:47 +00:00
2003-10-02 14:44:51 +00:00
_graphicData = new GraphicData [ _numGraphics + 1 ] ;
2003-10-14 12:55:31 +00:00
memset ( & _graphicData [ 0 ] , 0 , sizeof ( GraphicData ) ) ;
2003-10-06 13:20:29 +00:00
for ( i = 1 ; i < = _numGraphics ; i + + ) {
2003-10-14 12:55:31 +00:00
_graphicData [ i ] . readFrom ( ptr ) ;
2003-10-02 14:44:51 +00:00
}
2003-11-08 23:45:45 +00:00
2003-10-06 08:24:38 +00:00
_objMax = new int16 [ _numRooms + 1 ] ;
_areaMax = new int16 [ _numRooms + 1 ] ;
2003-10-14 12:55:31 +00:00
_area = new Area [ _numRooms + 1 ] [ MAX_AREAS_NUMBER ] ;
2003-10-05 16:07:07 +00:00
2003-10-14 12:55:31 +00:00
_objMax [ 0 ] = 0 ;
_areaMax [ 0 ] = 0 ;
memset ( & _area [ 0 ] , 0 , sizeof ( Area ) * MAX_AREAS_NUMBER ) ;
2003-10-06 13:20:29 +00:00
for ( i = 1 ; i < = _numRooms ; i + + ) {
2003-10-14 12:55:31 +00:00
_objMax [ i ] = ( int16 ) READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
_areaMax [ i ] = ( int16 ) READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
memset ( & _area [ i ] [ 0 ] , 0 , sizeof ( Area ) ) ;
2003-10-09 09:09:40 +00:00
for ( j = 1 ; j < = _areaMax [ i ] ; j + + ) {
2003-10-14 12:55:31 +00:00
assert ( j < MAX_AREAS_NUMBER ) ;
_area [ i ] [ j ] . readFrom ( ptr ) ;
2003-10-09 09:09:40 +00:00
}
2003-10-07 08:22:53 +00:00
}
2003-10-06 13:20:29 +00:00
_objectBox = new Box [ _numObjects + 1 ] ;
2003-10-14 12:55:31 +00:00
memset ( & _objectBox [ 0 ] , 0 , sizeof ( Box ) ) ;
2003-10-06 13:20:29 +00:00
for ( i = 1 ; i < = _numObjects ; i + + ) {
2003-10-14 12:55:31 +00:00
_objectBox [ i ] . readFrom ( ptr ) ;
2003-10-06 13:20:29 +00:00
}
2003-10-07 08:22:53 +00:00
2003-10-14 12:55:31 +00:00
// Walk OFF Data
_numWalkOffs = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
2003-10-06 13:20:29 +00:00
_walkOffData = new WalkOffData [ _numWalkOffs + 1 ] ;
2003-10-14 12:55:31 +00:00
memset ( & _walkOffData [ 0 ] , 0 , sizeof ( WalkOffData ) ) ;
2003-10-06 13:20:29 +00:00
for ( i = 1 ; i < = _numWalkOffs ; i + + ) {
2003-10-14 12:55:31 +00:00
_walkOffData [ i ] . readFrom ( ptr ) ;
2003-10-06 13:20:29 +00:00
}
2003-10-14 12:55:31 +00:00
// Special Object Descriptions
_numObjDesc = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
2003-10-06 13:20:29 +00:00
_objectDescription = new ObjectDescription [ _numObjDesc + 1 ] ;
2003-10-14 12:55:31 +00:00
memset ( & _objectDescription [ 0 ] , 0 , sizeof ( ObjectDescription ) ) ;
2003-10-06 13:20:29 +00:00
for ( i = 1 ; i < = _numObjDesc ; i + + ) {
2003-10-14 12:55:31 +00:00
_objectDescription [ i ] . readFrom ( ptr ) ;
2003-10-06 13:20:29 +00:00
}
2003-10-31 13:47:28 +00:00
_cmd - > readCommandsFrom ( ptr ) ;
2003-10-12 18:44:44 +00:00
2003-10-14 12:55:31 +00:00
_entryObj = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
2003-10-12 18:44:44 +00:00
2003-10-14 12:55:31 +00:00
// Furniture DATA
_numFurniture = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
2003-10-12 18:44:44 +00:00
_furnitureData = new FurnitureData [ _numFurniture + 1 ] ;
2003-10-14 12:55:31 +00:00
memset ( & _furnitureData [ 0 ] , 0 , sizeof ( _furnitureData ) ) ;
2003-10-12 18:44:44 +00:00
for ( i = 1 ; i < = _numFurniture ; i + + ) {
2003-10-14 12:55:31 +00:00
_furnitureData [ i ] . readFrom ( ptr ) ;
2003-10-12 18:44:44 +00:00
}
2003-10-14 12:55:31 +00:00
// Actors
_numActors = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
_numAAnim = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
_numAName = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
_numAFile = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
2003-10-12 18:44:44 +00:00
_actorData = new ActorData [ _numActors + 1 ] ;
2003-10-14 12:55:31 +00:00
memset ( & _actorData [ 0 ] , 0 , sizeof ( ActorData ) ) ;
2003-10-12 18:44:44 +00:00
for ( i = 1 ; i < = _numActors ; i + + ) {
2003-10-14 12:55:31 +00:00
_actorData [ i ] . readFrom ( ptr ) ;
2003-10-12 18:44:44 +00:00
}
2003-10-14 12:55:31 +00:00
_numGraphicAnim = READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
2003-10-12 18:44:44 +00:00
_graphicAnim = new GraphicAnim [ _numGraphicAnim + 1 ] ;
2003-10-14 12:55:31 +00:00
memset ( & _graphicAnim [ 0 ] , 0 , sizeof ( GraphicAnim ) ) ;
2003-10-12 18:44:44 +00:00
for ( i = 1 ; i < = _numGraphicAnim ; i + + ) {
2003-10-14 12:55:31 +00:00
_graphicAnim [ i ] . readFrom ( ptr ) ;
2003-10-12 18:44:44 +00:00
}
2003-10-13 14:21:17 +00:00
2003-10-12 18:44:44 +00:00
_currentRoom = _objectData [ _entryObj ] . room ;
_entryObj = 0 ;
2003-10-14 12:55:31 +00:00
if ( memcmp ( ptr , _resource - > JASVersion ( ) , 5 ) ! = 0 ) {
warning ( " Unexpected queen.jas file format " ) ;
}
2003-10-12 18:44:44 +00:00
_objDescription = new char * [ _numDescriptions + 1 ] ;
_objDescription [ 0 ] = 0 ;
for ( i = 1 ; i < = _numDescriptions ; i + + )
_objDescription [ i ] = _resource - > getJAS2Line ( ) ;
//Patch for German text bug
if ( _resource - > getLanguage ( ) = = GERMAN ) {
char * txt = new char [ 48 ] ;
strcpy ( txt , " Es bringt nicht viel, das festzubinden. " ) ;
_objDescription [ 296 ] = txt ;
}
_objName = new char * [ _numNames + 1 ] ;
_objName [ 0 ] = 0 ;
for ( i = 1 ; i < = _numNames ; i + + )
_objName [ i ] = _resource - > getJAS2Line ( ) ;
_roomName = new char * [ _numRooms + 1 ] ;
_roomName [ 0 ] = 0 ;
for ( i = 1 ; i < = _numRooms ; i + + )
_roomName [ i ] = _resource - > getJAS2Line ( ) ;
2003-10-30 10:56:38 +00:00
Verb : : initName ( 0 , NULL ) ;
2003-10-12 18:44:44 +00:00
for ( i = 1 ; i < = 12 ; i + + )
2003-10-30 10:56:38 +00:00
Verb : : initName ( i , _resource - > getJAS2Line ( ) ) ;
2003-10-12 18:44:44 +00:00
_joeResponse [ 0 ] = 0 ;
for ( i = 1 ; i < = JOE_RESPONSE_MAX ; i + + )
_joeResponse [ i ] = _resource - > getJAS2Line ( ) ;
_aAnim = new char * [ _numAAnim + 1 ] ;
_aAnim [ 0 ] = 0 ;
for ( i = 1 ; i < = _numAAnim ; i + + )
_aAnim [ i ] = _resource - > getJAS2Line ( ) ;
_aName = new char * [ _numAName + 1 ] ;
_aName [ 0 ] = 0 ;
for ( i = 1 ; i < = _numAName ; i + + )
_aName [ i ] = _resource - > getJAS2Line ( ) ;
_aFile = new char * [ _numAFile + 1 ] ;
_aFile [ 0 ] = 0 ;
for ( i = 1 ; i < = _numAFile ; i + + )
_aFile [ i ] = _resource - > getJAS2Line ( ) ;
2003-10-25 09:11:35 +00:00
_settings . textToggle = true ;
2003-10-12 18:44:44 +00:00
if ( _resource - > isFloppy ( ) )
2003-11-15 21:33:04 +00:00
_sound - > speechToggle ( false ) ;
2003-10-12 18:44:44 +00:00
else
2003-11-15 21:33:04 +00:00
_sound - > speechToggle ( true ) ;
2003-10-09 09:09:40 +00:00
2003-10-31 13:47:28 +00:00
_cmd - > clear ( false ) ;
2003-11-08 11:32:32 +00:00
_scene = 0 ;
2003-10-31 13:47:28 +00:00
memset ( _gameState , 0 , sizeof ( _gameState ) ) ;
2003-10-16 13:54:48 +00:00
_graphics - > loadPanel ( ) ;
2003-10-12 17:38:01 +00:00
_graphics - > bobSetupControl ( ) ;
2003-10-14 19:06:44 +00:00
joeSetup ( ) ;
2003-10-13 14:21:17 +00:00
zoneSetupPanel ( ) ;
2003-10-12 17:38:01 +00:00
2003-10-11 10:09:23 +00:00
_oldRoom = 0 ;
2003-09-28 15:50:47 +00:00
}
2003-10-02 11:03:34 +00:00
2003-12-02 16:49:56 +00:00
ObjectData * Logic : : objectData ( int index ) const {
2003-12-05 13:56:07 +00:00
index = ABS ( index ) ; // cyx: is that really necessary ?
2003-11-06 21:06:01 +00:00
if ( index < = _numObjects )
return & _objectData [ index ] ;
else
error ( " [Logic::objectData] Invalid object data index: %i " , index ) ;
2003-10-02 14:44:51 +00:00
}
2003-10-02 06:38:58 +00:00
2003-12-02 16:49:56 +00:00
uint16 Logic : : roomData ( int room ) const {
2003-10-02 08:49:38 +00:00
return _roomData [ room ] ;
2003-10-02 06:38:58 +00:00
}
2003-12-02 16:49:56 +00:00
uint16 Logic : : objMax ( int room ) const {
2003-10-02 08:49:38 +00:00
return _objMax [ room ] ;
2003-10-02 06:38:58 +00:00
}
2003-12-02 16:49:56 +00:00
GraphicData * Logic : : graphicData ( int index ) const {
return & _graphicData [ index ] ;
}
Area * Logic : : area ( int room , int num ) const {
2003-10-09 13:14:16 +00:00
return & _area [ room ] [ num ] ;
}
2003-12-02 16:49:56 +00:00
Area * Logic : : currentRoomArea ( int num ) const {
2003-10-18 17:42:24 +00:00
if ( num = = 0 | | num > _areaMax [ _currentRoom ] ) {
error ( " Logic::currentRoomArea() - Bad area number = %d (max = %d), currentRoom = %d " , num , _areaMax [ _currentRoom ] , _currentRoom ) ;
}
2003-11-06 21:06:01 +00:00
2003-10-09 13:14:16 +00:00
return & _area [ _currentRoom ] [ num ] ;
}
2003-12-02 16:49:56 +00:00
uint16 Logic : : areaMax ( int room ) const {
2003-10-09 13:14:16 +00:00
return _areaMax [ room ] ;
}
2003-12-02 16:49:56 +00:00
uint16 Logic : : currentRoomAreaMax ( ) const {
2003-10-09 13:14:16 +00:00
return _areaMax [ _currentRoom ] ;
2003-10-02 11:03:34 +00:00
}
2003-12-02 16:49:56 +00:00
uint16 Logic : : walkOffCount ( ) const {
2003-10-02 08:49:38 +00:00
return _numWalkOffs ;
}
2003-12-02 16:49:56 +00:00
WalkOffData * Logic : : walkOffData ( int index ) const {
2003-10-06 13:20:29 +00:00
return & _walkOffData [ index ] ;
2003-10-02 08:49:38 +00:00
}
2003-10-05 16:07:07 +00:00
uint16 Logic : : findBob ( uint16 obj ) {
2003-10-02 14:44:51 +00:00
uint16 i ;
uint16 bobnum = 0 ;
uint16 bobtype = 0 ; // 1 for animated, 0 for static
2003-10-02 19:37:51 +00:00
if ( obj > _numObjects )
error ( " Object index (%i) > _numObjects (%i) " , obj , _numObjects ) ;
2003-10-02 19:20:00 +00:00
2003-10-02 14:44:51 +00:00
uint16 room = _objectData [ obj ] . room ;
2003-10-02 19:20:00 +00:00
if ( room > = _numRooms ) {
warning ( " room (%i) > _numRooms (%i) " , room , _numRooms ) ;
}
2003-11-08 23:45:45 +00:00
2003-10-02 14:44:51 +00:00
int16 img = _objectData [ obj ] . image ;
if ( img ! = 0 ) {
if ( img = = - 3 | | img = = - 4 ) {
// a person object
for ( i = _roomData [ room ] + 1 ; i < = obj ; + + i ) {
img = _objectData [ i ] . image ;
if ( img = = - 3 | | img = = - 4 ) {
+ + bobnum ;
}
}
}
else {
if ( img < = - 10 ) {
// object has been turned off, but the image order hasn't been updated
if ( _graphicData [ - ( img + 10 ) ] . lastFrame ! = 0 ) {
bobtype = 1 ;
}
}
else if ( img = = - 2 ) {
// -1 static, -2 animated
bobtype = 1 ;
}
else if ( img > 0 ) {
if ( _graphicData [ img ] . lastFrame ! = 0 ) {
bobtype = 1 ;
}
}
uint16 idxAnimated = 0 ;
uint16 idxStatic = 0 ;
for ( i = _roomData [ room ] + 1 ; i < = obj ; + + i ) {
img = _objectData [ i ] . image ;
if ( img < = - 10 ) {
if ( _graphicData [ - ( img + 10 ) ] . lastFrame ! = 0 ) {
+ + idxAnimated ;
}
else {
+ + idxStatic ;
}
}
else if ( img > 0 ) {
if ( img > 5000 ) {
img - = 5000 ;
}
2003-10-02 19:20:00 +00:00
if ( img > = _numGraphics )
warning ( " img (%i) >= _numGraphics (%i) " , img , _numGraphics ) ;
2003-10-02 14:44:51 +00:00
if ( _graphicData [ img ] . lastFrame ! = 0 ) {
+ + idxAnimated ;
}
else {
+ + idxStatic ;
}
}
2003-10-03 19:59:19 +00:00
else if ( img = = - 1 ) {
+ + idxStatic ;
}
else if ( img = = - 2 ) {
+ + idxAnimated ;
}
2003-10-02 14:44:51 +00:00
}
if ( bobtype = = 0 ) {
// static bob
2003-10-03 19:59:19 +00:00
if ( idxStatic > 0 ) {
2003-10-11 10:09:23 +00:00
bobnum = 19 + _numFurnitureStatic + idxStatic ;
2003-10-03 19:59:19 +00:00
}
2003-10-02 14:44:51 +00:00
}
else {
// animated bob
2003-10-03 19:59:19 +00:00
if ( idxAnimated > 0 ) {
2003-10-12 13:16:35 +00:00
bobnum = 4 + _numFurnitureAnimated + idxAnimated ;
2003-10-03 19:59:19 +00:00
}
2003-10-02 14:44:51 +00:00
}
}
}
return bobnum ;
}
2003-10-05 16:07:07 +00:00
uint16 Logic : : findFrame ( uint16 obj ) {
2003-10-02 14:44:51 +00:00
uint16 i ;
uint16 framenum = 0 ;
uint16 room = _objectData [ obj ] . room ;
int16 img = _objectData [ obj ] . image ;
if ( img = = - 3 | | img = = - 4 ) {
uint16 bobnum = 0 ;
for ( i = _roomData [ room ] + 1 ; i < = obj ; + + i ) {
img = _objectData [ i ] . image ;
if ( img = = - 3 | | img = = - 4 ) {
+ + bobnum ;
}
}
if ( bobnum < = 3 ) {
2003-10-12 13:16:35 +00:00
framenum = 29 + FRAMES_JOE_XTRA + bobnum ;
2003-10-02 14:44:51 +00:00
}
}
else {
uint16 idx = 0 ;
for ( i = _roomData [ room ] + 1 ; i < obj ; + + i ) {
img = _objectData [ i ] . image ;
if ( img < = - 10 ) {
GraphicData * pgd = & _graphicData [ - ( img + 10 ) ] ;
2003-11-26 23:06:34 +00:00
if ( pgd - > lastFrame ! = 0 ) {
2003-10-02 14:44:51 +00:00
// skip all the frames of the animation
idx + = ABS ( pgd - > lastFrame ) - pgd - > firstFrame + 1 ;
}
else {
2003-10-12 13:16:35 +00:00
// static bob, skip one frame
2003-10-02 14:44:51 +00:00
+ + idx ;
}
}
else if ( img = = - 1 ) {
+ + idx ;
}
else if ( img > 0 ) {
if ( img > 5000 ) {
img - = 5000 ;
}
GraphicData * pgd = & _graphicData [ img ] ;
uint16 lastFrame = ABS ( pgd - > lastFrame ) ;
if ( pgd - > firstFrame < 0 ) {
idx + = lastFrame ;
}
else if ( lastFrame ! = 0 ) {
idx + = ( lastFrame - pgd - > firstFrame ) + 1 ;
}
else {
+ + idx ;
}
}
}
img = _objectData [ obj ] . image ;
if ( img < = - 10 ) {
GraphicData * pgd = & _graphicData [ - ( img + 10 ) ] ;
if ( pgd - > lastFrame ! = 0 ) {
2003-10-03 19:59:19 +00:00
idx + = ABS ( pgd - > lastFrame ) - pgd - > firstFrame + 1 ;
2003-10-02 14:44:51 +00:00
}
else {
+ + idx ;
}
}
else if ( img = = - 1 | | img > 0 ) {
+ + idx ;
}
// calculate only if there are person frames
if ( idx > 0 ) {
2003-10-12 13:16:35 +00:00
framenum = 36 + FRAMES_JOE_XTRA + _numFurnitureStatic + _numFurnitureAnimatedLen + idx ;
2003-10-02 14:44:51 +00:00
}
}
return framenum ;
}
2003-10-03 19:47:41 +00:00
2003-10-10 09:19:52 +00:00
2003-11-03 19:52:14 +00:00
uint16 Logic : : objectForPerson ( uint16 bobNum ) const {
2003-10-10 09:19:52 +00:00
uint16 bobcur = 0 ;
// first object number in the room
uint16 cur = _roomData [ _currentRoom ] + 1 ;
// last object number in the room
uint16 last = _roomData [ _currentRoom + 1 ] ;
while ( cur < = last ) {
int16 image = _objectData [ cur ] . image ;
if ( image = = - 3 | | image = = - 4 ) {
// the object is a bob
+ + bobcur ;
}
if ( bobcur = = bobNum ) {
return cur ;
}
2003-10-10 20:03:34 +00:00
+ + cur ;
2003-10-10 09:19:52 +00:00
}
return 0 ;
}
2003-11-03 19:52:14 +00:00
WalkOffData * Logic : : walkOffPointForObject ( uint16 obj ) const {
2003-10-10 09:19:52 +00:00
uint16 i ;
for ( i = 1 ; i < = _numWalkOffs ; + + i ) {
if ( _walkOffData [ i ] . entryObj = = obj ) {
return & _walkOffData [ i ] ;
}
}
return NULL ;
}
2003-10-07 00:26:04 +00:00
void Logic : : joeFacing ( uint16 dir ) {
_joe . facing = dir ;
}
void Logic : : joeX ( uint16 x ) {
_joe . x = x ;
}
void Logic : : joeY ( uint16 y ) {
_joe . y = y ;
}
2003-11-15 15:44:50 +00:00
void Logic : : joeWalk ( JoeWalkMode walking ) {
2003-10-15 09:23:05 +00:00
_joe . walk = walking ;
2003-11-15 21:16:01 +00:00
// Do this so that Input doesn't need to know the walk value
_input - > dialogueRunning ( JWM_SPEAK = = walking ) ;
2003-10-09 09:09:40 +00:00
}
2003-10-09 13:14:16 +00:00
void Logic : : joeScale ( uint16 scale ) {
_joe . scale = scale ;
}
2003-11-27 13:49:00 +00:00
void Logic : : joeCutFacing ( uint16 dir ) {
_joe . cutFacing = dir ;
}
2003-10-14 19:06:44 +00:00
void Logic : : joePrevFacing ( uint16 dir ) {
_joe . prevFacing = dir ;
}
2003-10-05 16:07:07 +00:00
int16 Logic : : gameState ( int index ) {
2003-10-04 08:50:48 +00:00
if ( index > = 0 & & index < GAME_STATE_COUNT )
return _gameState [ index ] ;
else
error ( " [QueenLogic::gameState] invalid index: %i " , index ) ;
}
2003-10-05 16:07:07 +00:00
void Logic : : gameState ( int index , int16 newValue ) {
2003-11-08 16:36:54 +00:00
if ( index > = 0 & & index < GAME_STATE_COUNT ) {
2003-11-26 13:53:17 +00:00
// debug(0, "Logic::gameState() - GAMESTATE[%d] = %d", index, newValue);
2003-11-08 16:36:54 +00:00
_gameState [ index ] = newValue ;
}
2003-10-04 08:50:48 +00:00
else
error ( " [QueenLogic::gameState] invalid index: %i " , index ) ;
}
2003-10-09 09:09:40 +00:00
void Logic : : zoneSet ( uint16 screen , uint16 zone , uint16 x1 , uint16 y1 , uint16 x2 , uint16 y2 ) {
2003-10-18 17:42:24 +00:00
debug ( 9 , " Logic::zoneSet(%d, %d, (%d,%d), (%d,%d)) " , screen , zone , x1 , y1 , x2 , y2 ) ;
2003-10-09 09:09:40 +00:00
ZoneSlot * pzs = & _zones [ screen ] [ zone ] ;
pzs - > valid = true ;
pzs - > box . x1 = x1 ;
pzs - > box . y1 = y1 ;
pzs - > box . x2 = x2 ;
pzs - > box . y2 = y2 ;
}
void Logic : : zoneSet ( uint16 screen , uint16 zone , const Box & box ) {
debug ( 9 , " Logic::zoneSet(%d, %d, (%d,%d), (%d,%d)) " , screen , zone , box . x1 , box . y1 , box . x2 , box . y2 ) ;
ZoneSlot * pzs = & _zones [ screen ] [ zone ] ;
pzs - > valid = true ;
pzs - > box = box ;
}
2003-10-25 09:11:35 +00:00
uint16 Logic : : zoneIn ( uint16 screen , uint16 x , uint16 y ) const {
2003-10-09 09:09:40 +00:00
2003-10-31 13:47:28 +00:00
debug ( 9 , " Logic::zoneIn(%d, (%d,%d)) " , screen , x , y ) ;
2003-10-09 09:09:40 +00:00
int i ;
if ( screen = = ZONE_PANEL ) {
y - = ROOM_ZONE_HEIGHT ;
}
for ( i = 1 ; i < MAX_ZONES_NUMBER ; + + i ) {
2003-10-25 09:11:35 +00:00
const ZoneSlot * pzs = & _zones [ screen ] [ i ] ;
2003-10-09 09:09:40 +00:00
if ( pzs - > valid & & pzs - > box . contains ( x , y ) ) {
return i ;
}
}
return 0 ;
}
2003-10-25 09:11:35 +00:00
uint16 Logic : : zoneInArea ( uint16 screen , uint16 x , uint16 y ) const {
2003-10-09 09:09:40 +00:00
uint16 zone = zoneIn ( screen , x , y ) ;
if ( zone < = _objMax [ _currentRoom ] ) {
zone = 0 ;
}
else {
zone - = _objMax [ _currentRoom ] ;
}
return zone ;
}
void Logic : : zoneClearAll ( uint16 screen ) {
2003-10-31 13:47:28 +00:00
debug ( 9 , " Logic::zoneClearAll(%d) " , screen ) ;
2003-10-09 09:09:40 +00:00
int i ;
for ( i = 1 ; i < MAX_ZONES_NUMBER ; + + i ) {
_zones [ screen ] [ i ] . valid = false ;
}
}
void Logic : : zoneSetup ( ) {
2003-10-18 17:42:24 +00:00
debug ( 9 , " Logic::zoneSetup() " ) ;
2003-10-09 09:09:40 +00:00
zoneClearAll ( ZONE_ROOM ) ;
int i ;
int zoneNum ;
// setup objects zones
uint16 maxObjRoom = _objMax [ _currentRoom ] ;
uint16 objRoomNum = _roomData [ _currentRoom ] ;
zoneNum = 1 ;
for ( i = objRoomNum + 1 ; i < = objRoomNum + maxObjRoom ; + + i ) {
if ( _objectData [ i ] . name ! = 0 ) {
zoneSet ( ZONE_ROOM , zoneNum , _objectBox [ i ] ) ;
}
+ + zoneNum ;
}
// setup room zones (areas)
uint16 maxAreaRoom = _areaMax [ _currentRoom ] ;
for ( zoneNum = 1 ; zoneNum < = maxAreaRoom ; + + zoneNum ) {
zoneSet ( ZONE_ROOM , maxObjRoom + zoneNum , _area [ _currentRoom ] [ zoneNum ] . box ) ;
2003-10-11 10:09:23 +00:00
}
}
2003-10-12 17:38:01 +00:00
void Logic : : zoneSetupPanel ( ) {
// verbs
2003-10-25 09:11:35 +00:00
int i ;
2003-10-12 17:38:01 +00:00
for ( i = 0 ; i < = 7 ; + + i ) {
int x = i * 20 ;
zoneSet ( ZONE_PANEL , i + 1 , x , 10 , x + 19 , 49 ) ;
}
// inventory scrolls
2003-10-25 09:11:35 +00:00
zoneSet ( ZONE_PANEL , 9 , 160 , 10 , 179 , 29 ) ;
zoneSet ( ZONE_PANEL , 10 , 160 , 30 , 179 , 49 ) ;
2003-10-12 17:38:01 +00:00
// inventory items
2003-10-25 09:11:35 +00:00
zoneSet ( ZONE_PANEL , 11 , 180 , 10 , 213 , 49 ) ;
zoneSet ( ZONE_PANEL , 12 , 214 , 10 , 249 , 49 ) ;
zoneSet ( ZONE_PANEL , 13 , 250 , 10 , 284 , 49 ) ;
zoneSet ( ZONE_PANEL , 14 , 285 , 10 , 320 , 49 ) ;
2003-10-12 17:38:01 +00:00
}
2003-10-11 10:09:23 +00:00
void Logic : : roomErase ( ) {
_graphics - > frameEraseAll ( false ) ;
_graphics - > bankErase ( 15 ) ;
_graphics - > bankErase ( 11 ) ;
_graphics - > bankErase ( 10 ) ;
_graphics - > bankErase ( 12 ) ;
// TODO: TALKHEAD=0;
2003-10-16 13:54:48 +00:00
if ( _currentRoom > = 114 ) {
_display - > palFadeOut ( 0 , 255 , _currentRoom ) ;
}
else {
_display - > palFadeOut ( 0 , 223 , _currentRoom ) ;
}
2003-10-11 10:09:23 +00:00
// TODO: credits system
2003-10-13 14:21:17 +00:00
// invalidates all persons animations
uint16 i ;
for ( i = 0 ; i < = 3 ; + + i ) {
_personFrames [ i ] = 0 ;
}
for ( i = 1 ; i < = 16 ; + + i ) {
2003-10-15 16:31:51 +00:00
_newAnim [ i ] [ 0 ] . frame = 0 ;
2003-10-13 14:21:17 +00:00
}
2003-10-11 10:09:23 +00:00
uint16 cur = _roomData [ _oldRoom ] + 1 ;
uint16 last = _roomData [ _oldRoom + 1 ] ;
while ( cur < = last ) {
ObjectData * pod = & _objectData [ cur ] ;
if ( pod - > name = = 0 ) {
// object has been deleted, invalidate image
pod - > image = 0 ;
}
else if ( pod - > image > - 4000 & & pod - > image < = - 10 ) {
if ( _graphicData [ ABS ( pod - > image + 10 ) ] . lastFrame = = 0 ) {
// static Bob
pod - > image = - 1 ;
}
else {
// animated Bob
pod - > image = - 2 ;
}
}
+ + cur ;
}
}
2003-10-12 13:16:35 +00:00
void Logic : : roomSetupFurniture ( ) {
2003-11-08 16:36:54 +00:00
int16 gstate [ 9 ] ;
2003-10-11 10:09:23 +00:00
_numFurnitureStatic = 0 ;
_numFurnitureAnimated = 0 ;
_numFurnitureAnimatedLen = 0 ;
uint16 curImage = 36 + FRAMES_JOE_XTRA ;
// count the furniture and update gameState
uint16 furnitureTotal = 0 ;
uint16 i ;
2003-10-13 14:21:17 +00:00
for ( i = 1 ; i < = _numFurniture ; + + i ) {
if ( _furnitureData [ i ] . room = = _currentRoom ) {
+ + furnitureTotal ;
2003-11-08 16:36:54 +00:00
gstate [ furnitureTotal ] = _furnitureData [ i ] . gameStateValue ;
2003-10-13 14:21:17 +00:00
}
}
2003-10-12 13:16:35 +00:00
if ( furnitureTotal = = 0 ) {
return ;
}
2003-10-11 10:09:23 +00:00
// unpack the furniture from the bank 15
// there are 3 kinds :
2003-10-12 13:16:35 +00:00
// - static (bobs), gamestate range = ]0;5000]
2003-10-11 10:09:23 +00:00
// - animated (bobs), gamestate range = ]0;5000]
2003-10-12 13:16:35 +00:00
// - static (paste downs), gamestate range = [5000; [
2003-10-11 10:09:23 +00:00
2003-10-12 13:16:35 +00:00
// unpack the static bobs
2003-10-11 10:09:23 +00:00
for ( i = 1 ; i < = furnitureTotal ; + + i ) {
2003-11-08 16:36:54 +00:00
int16 obj = gstate [ i ] ;
2003-10-11 10:09:23 +00:00
if ( obj > 0 & & obj < = 5000 ) {
GraphicData * pgd = & _graphicData [ obj ] ;
if ( pgd - > lastFrame = = 0 ) {
+ + _numFurnitureStatic ;
+ + curImage ;
_graphics - > bankUnpack ( pgd - > firstFrame , curImage , 15 ) ;
2003-10-12 13:16:35 +00:00
+ + _numFrames ;
2003-10-11 10:09:23 +00:00
BobSlot * pbs = _graphics - > bob ( 19 + _numFurnitureStatic ) ;
pbs - > active = true ;
pbs - > x = pgd - > x ;
pbs - > y = pgd - > y ;
pbs - > frameNum = curImage ;
}
}
}
// unpack the animated bobs
uint16 curBob = 0 ;
for ( i = 1 ; i < = furnitureTotal ; + + i ) {
2003-11-08 16:36:54 +00:00
int16 obj = gstate [ i ] ;
2003-10-11 10:09:23 +00:00
if ( obj > 0 & & obj < = 5000 ) {
GraphicData * pgd = & _graphicData [ obj ] ;
bool rebound = false ;
int16 lastFrame = pgd - > lastFrame ;
if ( lastFrame < 0 ) {
rebound = true ;
lastFrame = - lastFrame ;
}
if ( lastFrame > 0 ) {
_numFurnitureAnimatedLen + = lastFrame - pgd - > firstFrame + 1 ;
+ + _numFurnitureAnimated ;
uint16 image = curImage + 1 ;
int k ;
2003-11-13 10:44:31 +00:00
for ( k = pgd - > firstFrame ; k < = lastFrame ; + + k ) {
2003-10-11 10:09:23 +00:00
+ + curImage ;
_graphics - > bankUnpack ( k , curImage , 15 ) ;
2003-10-12 13:16:35 +00:00
+ + _numFrames ;
2003-10-11 10:09:23 +00:00
}
BobSlot * pbs = _graphics - > bob ( 5 + curBob ) ;
2003-11-30 20:41:02 +00:00
pbs - > animNormal ( image , curImage , pgd - > speed / 4 , rebound , false ) ;
2003-10-11 10:09:23 +00:00
pbs - > x = pgd - > x ;
pbs - > y = pgd - > y ;
+ + curBob ;
}
}
}
2003-10-12 13:16:35 +00:00
// unpack the paste downs
2003-10-11 10:09:23 +00:00
+ + curImage ;
for ( i = 1 ; i < = furnitureTotal ; + + i ) {
2003-11-08 16:36:54 +00:00
int16 obj = gstate [ i ] ;
2003-10-11 10:09:23 +00:00
if ( obj > 5000 ) {
obj - = 5000 ;
GraphicData * pgd = & _graphicData [ obj ] ;
_graphics - > bankUnpack ( pgd - > firstFrame , curImage , 15 ) ;
_graphics - > bobPaste ( curImage , pgd - > x , pgd - > y ) ;
2003-10-12 13:16:35 +00:00
// no need to increment curImage here, as bobPaste() destroys the
// unpacked frame after blitting it
2003-10-11 10:09:23 +00:00
}
}
}
void Logic : : roomSetupObjects ( ) {
2003-10-12 13:16:35 +00:00
uint16 i ;
2003-10-12 16:37:56 +00:00
// furniture frames are reserved in ::roomSetupFurniture(), we append objects
// frames after the furniture ones.
2003-10-12 13:16:35 +00:00
uint16 curImage = 36 + FRAMES_JOE_XTRA + _numFurnitureStatic + _numFurnitureAnimatedLen ;
uint16 firstRoomObj = _roomData [ _currentRoom ] + 1 ;
uint16 lastRoomObj = _roomData [ _currentRoom + 1 ] ;
2003-10-12 16:37:56 +00:00
uint16 numObjectStatic = 0 ;
uint16 numObjectAnimated = 0 ;
uint16 curBob ;
2003-10-12 13:16:35 +00:00
2003-10-12 16:37:56 +00:00
// invalidates all Bobs for persons (except Joe's one)
2003-10-12 13:16:35 +00:00
for ( i = 1 ; i < = 3 ; + + i ) {
_graphics - > bob ( i ) - > active = false ;
}
2003-10-12 16:37:56 +00:00
// static/animated Bobs
for ( i = firstRoomObj ; i < = lastRoomObj ; + + i ) {
2003-10-15 08:46:18 +00:00
ObjectData * pod = & _objectData [ i ] ;
2003-10-12 16:37:56 +00:00
// setup blanks bobs for turned off objects (in case
// you turn them on again)
2003-10-15 08:46:18 +00:00
if ( pod - > image = = - 1 ) {
2003-10-12 16:37:56 +00:00
// static OFF Bob
curBob = 20 + _numFurnitureStatic + numObjectStatic ;
+ + numObjectStatic ;
// create a blank frame for the for the OFF object
+ + _numFrames ;
+ + curImage ;
}
2003-10-15 08:46:18 +00:00
else if ( pod - > image = = - 2 ) {
2003-10-12 16:37:56 +00:00
// animated OFF Bob
curBob = 5 + _numFurnitureAnimated + numObjectAnimated ;
+ + numObjectAnimated ;
}
2003-10-15 08:46:18 +00:00
else if ( pod - > image > 0 & & pod - > image < 5000 ) {
GraphicData * pgd = & _graphicData [ pod - > image ] ;
int16 lastFrame = pgd - > lastFrame ;
bool rebound = false ;
if ( lastFrame < 0 ) {
lastFrame = - lastFrame ;
rebound = true ;
}
if ( pgd - > firstFrame < 0 ) {
2003-10-15 16:31:51 +00:00
// FIXME: if(TEMPA[1]<0) bobs[CURRBOB].xflip=1;
curBob = 5 + _numFurnitureAnimated ;
2003-10-20 08:34:48 +00:00
animSetup ( pgd , curImage + 1 , curBob + numObjectAnimated , pod - > name > 0 ) ;
curImage + = pgd - > lastFrame ;
2003-10-15 16:31:51 +00:00
+ + numObjectAnimated ;
2003-10-15 08:46:18 +00:00
}
else if ( lastFrame ! = 0 ) {
// animated objects
uint16 j ;
uint16 firstFrame = curImage + 1 ;
for ( j = pgd - > firstFrame ; j < = lastFrame ; + + j ) {
+ + curImage ;
_graphics - > bankUnpack ( j , curImage , 15 ) ;
+ + _numFrames ;
}
curBob = 5 + _numFurnitureAnimated + numObjectAnimated ;
if ( pod - > name > 0 ) {
BobSlot * pbs = _graphics - > bob ( curBob ) ;
pbs - > active = true ;
pbs - > x = pgd - > x ;
pbs - > y = pgd - > y ;
pbs - > frameNum = firstFrame ;
if ( pgd - > speed > 0 ) {
2003-11-30 20:41:02 +00:00
pbs - > animNormal ( firstFrame , curImage , pgd - > speed / 4 , rebound , false ) ;
2003-10-15 08:46:18 +00:00
}
}
+ + numObjectAnimated ;
}
else {
// static objects
curBob = 20 + _numFurnitureStatic + numObjectStatic ;
+ + curImage ;
_graphics - > bobClear ( curBob ) ;
// FIXME: if((COMPANEL==2) && (FULLSCREEN==1)) bobs[CURRBOB].y2=199;
2003-10-12 16:37:56 +00:00
2003-10-15 08:46:18 +00:00
_graphics - > bankUnpack ( pgd - > firstFrame , curImage , 15 ) ;
+ + _numFrames ;
if ( pod - > name > 0 ) {
BobSlot * pbs = _graphics - > bob ( curBob ) ;
pbs - > active = true ;
pbs - > x = pgd - > x ;
pbs - > y = pgd - > y ;
pbs - > frameNum = curImage ;
}
+ + numObjectStatic ;
}
}
2003-10-12 16:37:56 +00:00
}
// persons Bobs
for ( i = firstRoomObj ; i < = lastRoomObj ; + + i ) {
ObjectData * pod = & _objectData [ i ] ;
if ( pod - > image = = - 3 | | pod - > image = = - 4 ) {
2003-11-30 20:41:02 +00:00
debug ( 0 , " Logic::roomSetupObjects() - Setting up person %X, name=%X " , i , pod - > name ) ;
2003-10-13 14:21:17 +00:00
uint16 noun = i - _roomData [ _currentRoom ] ;
if ( pod - > name > 0 ) {
curImage = personSetup ( noun , curImage ) ;
}
else {
curImage = personAllocate ( noun , curImage ) ;
}
2003-10-12 16:37:56 +00:00
}
}
2003-10-12 13:16:35 +00:00
// paste downs list
+ + curImage ;
_numFrames = curImage ;
for ( i = firstRoomObj ; i < = lastRoomObj ; + + i ) {
2003-11-14 16:16:55 +00:00
ObjectData * pod = & _objectData [ i ] ;
if ( pod - > name > 0 ) {
int16 obj = pod - > image ;
if ( obj > 5000 ) {
obj - = 5000 ;
GraphicData * pgd = & _graphicData [ obj ] ;
_graphics - > bankUnpack ( pgd - > firstFrame , curImage , 15 ) ;
_graphics - > bobPaste ( curImage , pgd - > x , pgd - > y ) ;
}
2003-10-12 13:16:35 +00:00
}
}
2003-10-11 10:09:23 +00:00
}
2003-10-15 08:46:18 +00:00
uint16 Logic : : roomRefreshObject ( uint16 obj ) {
2003-10-19 18:52:28 +00:00
2003-10-15 08:46:18 +00:00
uint16 curImage = _numFrames ;
2003-11-04 19:51:31 +00:00
if ( obj = = 0 | | obj > _numObjects ) {
warning ( " Invalid object number %d " , obj ) ;
return curImage ;
}
2003-10-15 08:46:18 +00:00
ObjectData * pod = & _objectData [ obj ] ;
if ( pod - > image = = 0 ) {
return curImage ;
}
2003-11-16 10:47:31 +00:00
debug ( 0 , " Logic::roomRefreshObject(%X, %s) " , obj , _objName [ ABS ( pod - > name ) ] ) ;
2003-10-15 08:46:18 +00:00
// check the object is in the current room
if ( pod - > room ! = _currentRoom ) {
2003-12-10 14:19:04 +00:00
debug ( 0 , " Trying to display an object (%i=%s) that is not in room (object room=%i, current room=%i) " , obj , _objName [ ABS ( pod - > name ) ] , pod - > room , _currentRoom ) ;
2003-10-15 08:46:18 +00:00
return curImage ;
}
// find bob for the object
uint16 curBob = findBob ( obj ) ;
BobSlot * pbs = _graphics - > bob ( curBob ) ;
if ( pod - > image = = - 3 | | pod - > image = = - 4 ) {
// a person object
2003-11-10 14:06:55 +00:00
if ( pod - > name < = 0 ) {
2003-10-15 08:46:18 +00:00
_graphics - > bobClear ( curBob ) ;
}
else {
// find person number
uint16 pNum = 1 ;
uint16 i = _roomData [ _currentRoom ] + 1 ;
while ( i < obj ) {
if ( _objectData [ i ] . image = = - 3 | | _objectData [ i ] . image = = - 4 ) {
+ + pNum ;
}
+ + i ;
}
curImage = _personFrames [ pNum ] - 1 ;
if ( _personFrames [ pNum ] = = 0 ) {
curImage = _numFrames ;
_personFrames [ pNum ] = curImage ;
}
curImage = personSetup ( obj - _roomData [ _currentRoom ] , curImage ) ;
}
return curImage ;
}
2003-11-26 23:03:21 +00:00
// find frame used for object
curImage = findFrame ( obj ) ;
2003-10-15 08:46:18 +00:00
if ( pod - > name < 0 | | pod - > image < 0 ) {
// object is hidden or disabled
_graphics - > bobClear ( curBob ) ;
return curImage ;
}
2003-10-15 10:01:54 +00:00
int image = pod - > image ;
2003-10-15 16:31:51 +00:00
if ( image > 5000 ) {
2003-10-15 10:01:54 +00:00
image - = 5000 ;
2003-10-15 16:31:51 +00:00
}
GraphicData * pgd = & _graphicData [ image ] ;
bool rebound = false ;
int16 lastFrame = pgd - > lastFrame ;
if ( lastFrame < 0 ) {
lastFrame = - lastFrame ;
rebound = true ;
}
if ( pgd - > firstFrame < 0 ) {
2003-10-20 08:34:48 +00:00
animSetup ( pgd , curImage , curBob , pod - > name ! = 0 ) ;
curImage + = pgd - > lastFrame - 1 ;
2003-10-15 16:31:51 +00:00
}
else if ( lastFrame ! = 0 ) {
// turn on an animated bob
_graphics - > bankUnpack ( pgd - > firstFrame , 2 , 15 ) ;
pbs - > animating = false ;
uint16 firstImage = curImage ;
- - curImage ;
uint16 j ;
for ( j = pgd - > firstFrame ; j < = lastFrame ; + + j ) {
+ + curImage ;
_graphics - > bankUnpack ( j , curImage , 15 ) ;
}
pbs - > active = true ;
pbs - > x = pgd - > x ;
pbs - > y = pgd - > y ;
pbs - > frameNum = firstImage ;
if ( pgd - > speed > 0 ) {
2003-11-30 20:41:02 +00:00
pbs - > animNormal ( firstImage , curImage , pgd - > speed / 4 , rebound , false ) ;
2003-10-15 08:46:18 +00:00
}
2003-10-15 16:31:51 +00:00
}
else {
// frame 2 is used as a buffer frame to prevent BOB flickering
_graphics - > bankUnpack ( pgd - > firstFrame , 2 , 15 ) ;
_graphics - > bankUnpack ( pgd - > firstFrame , curImage , 15 ) ;
pbs - > active = true ;
pbs - > x = pgd - > x ;
pbs - > y = pgd - > y ;
pbs - > frameNum = curImage ;
}
2003-10-15 10:01:54 +00:00
2003-10-15 08:46:18 +00:00
return curImage ;
}
2003-11-26 13:53:17 +00:00
void Logic : : roomSetup ( const char * room , int comPanel , bool inCutaway ) {
2003-10-11 10:09:23 +00:00
2003-10-17 13:12:50 +00:00
char filename [ 20 ] ;
2003-10-11 10:09:23 +00:00
// loads background image
2003-10-17 13:12:50 +00:00
sprintf ( filename , " %s.PCX " , room ) ;
_graphics - > loadBackdrop ( filename , _currentRoom ) ;
// custom colors
_display - > palCustomColors ( _currentRoom ) ;
2003-10-11 10:09:23 +00:00
// setup graphics to enter fullscreen/panel mode
2003-10-16 13:54:48 +00:00
_display - > screenMode ( comPanel , inCutaway ) ;
2003-10-11 10:09:23 +00:00
// reset sprites table (bounding box...)
_graphics - > bobClearAll ( ) ;
// load/setup objects associated to this room
2003-10-17 13:12:50 +00:00
sprintf ( filename , " %s.BBK " , room ) ;
_graphics - > bankLoad ( filename , 15 ) ;
2003-10-18 17:42:24 +00:00
zoneSetup ( ) ;
2003-10-12 13:16:35 +00:00
_numFrames = 37 + FRAMES_JOE_XTRA ;
roomSetupFurniture ( ) ;
2003-10-11 10:09:23 +00:00
roomSetupObjects ( ) ;
}
2003-11-30 20:41:02 +00:00
void Logic : : roomDisplay ( uint16 room , RoomDisplayMode mode , uint16 scale , int comPanel , bool inCutaway ) {
2003-10-12 13:16:35 +00:00
2003-12-03 20:53:59 +00:00
debug ( 0 , " Logic::roomDisplay(%d, %d, %d, %d, %d) " , room , mode , scale , comPanel , inCutaway ) ;
2003-10-11 10:09:23 +00:00
roomErase ( ) ;
2003-11-30 20:41:02 +00:00
// XXX _sound->loadSFX(SFXNAME[_currentRoom]);
roomSetup ( roomName ( room ) , comPanel , inCutaway ) ;
2003-10-11 10:09:23 +00:00
ObjectData * pod = NULL ;
2003-10-12 13:16:35 +00:00
if ( mode ! = RDM_FADE_NOJOE ) {
2003-10-14 19:06:44 +00:00
pod = joeSetupInRoom ( mode ! = RDM_FADE_JOE_XY , scale ) ;
2003-10-11 10:09:23 +00:00
}
2003-12-05 20:16:32 +00:00
if ( mode ! = RDM_NOFADE_JOE ) {
2003-10-23 06:44:35 +00:00
update ( ) ;
2003-11-15 15:44:50 +00:00
BobSlot * joe = _graphics - > bob ( 0 ) ;
2003-12-05 20:16:32 +00:00
if ( IS_CD_INTRO_ROOM ( _currentRoom ) ) {
2003-11-15 15:44:50 +00:00
_display - > palFadeIn ( 0 , 255 , _currentRoom , joe - > active , joe - > x , joe - > y ) ;
2003-10-16 13:54:48 +00:00
}
else {
2003-11-15 15:44:50 +00:00
_display - > palFadeIn ( 0 , 223 , _currentRoom , joe - > active , joe - > x , joe - > y ) ;
2003-10-16 13:54:48 +00:00
}
2003-12-05 20:16:32 +00:00
}
2003-10-11 10:09:23 +00:00
if ( pod ! = NULL ) {
2003-11-26 20:40:43 +00:00
_walk - > moveJoe ( 0 , pod - > x , pod - > y , inCutaway ) ;
2003-10-09 09:09:40 +00:00
}
}
uint16 Logic : : findScale ( uint16 x , uint16 y ) {
uint16 scale = 100 ;
uint16 areaNum = zoneInArea ( ZONE_ROOM , x , y ) ;
if ( areaNum ! = 0 ) {
scale = _area [ _currentRoom ] [ areaNum ] . calcScale ( y ) ;
}
return scale ;
}
2003-10-13 14:21:17 +00:00
void Logic : : personSetData ( int16 noun , const char * actorName , bool loadBank , Person * pp ) {
2003-11-08 23:45:45 +00:00
2003-10-13 14:21:17 +00:00
if ( noun < = 0 ) {
2003-11-07 10:57:21 +00:00
warning ( " Logic::personSetData() - Invalid object number: %i " , noun ) ;
2003-10-13 14:21:17 +00:00
}
uint16 i ;
uint16 obj = _roomData [ _currentRoom ] + noun ;
int16 img = _objectData [ obj ] . image ;
if ( img ! = - 3 & & img ! = - 4 ) {
warning ( " Logic::personSetData() - Object %d is not a person " , obj ) ;
return ;
}
// search Bob number for the person
uint16 bobNum = 0 ;
for ( i = _roomData [ _currentRoom ] + 1 ; i < = obj ; + + i ) {
img = _objectData [ i ] . image ;
if ( img = = - 3 | | img = = - 4 ) {
+ + bobNum ;
}
}
// search for a matching actor
2003-10-14 06:41:08 +00:00
uint16 actor = 0 ;
2003-10-13 14:21:17 +00:00
for ( i = 1 ; i < = _numActors ; + + i ) {
ActorData * pad = & _actorData [ i ] ;
if ( pad - > room = = _currentRoom ) {
if ( _gameState [ pad - > gameStateSlot ] = = pad - > gameStateValue ) {
2003-10-14 06:41:08 +00:00
if ( ( bobNum > 0 & & bobNum = = pad - > bobNum ) | | strcmp ( _aName [ pad - > name ] , actorName ) = = 0 ) {
2003-10-13 14:21:17 +00:00
actor = i ;
break ;
}
}
}
}
2003-12-06 13:15:17 +00:00
if ( actor ! = 0 ) {
2003-10-14 06:41:08 +00:00
2003-12-06 13:15:17 +00:00
pp - > actor = & _actorData [ actor ] ;
pp - > name = _aName [ pp - > actor - > name ] ;
if ( pp - > actor - > anim ! = 0 ) {
pp - > anim = _aAnim [ pp - > actor - > anim ] ;
2003-10-13 14:21:17 +00:00
}
else {
2003-12-06 13:15:17 +00:00
pp - > anim = NULL ;
}
debug ( 0 , " Logic::personSetData() - name=%s n=%d " , pp - > name , actor ) ;
if ( loadBank ) {
const char * actorFile = _aFile [ pp - > actor - > actorFile ] ;
if ( actorFile ) {
_graphics - > bankLoad ( actorFile , pp - > actor - > bankNum ) ;
}
// if actorFile is null, the person data is already loaded as
// it is contained in objects room bank (.bbk)
}
2003-11-08 23:45:45 +00:00
2003-10-13 14:21:17 +00:00
pp - > bobFrame = 29 + FRAMES_JOE_XTRA + pp - > actor - > bobNum ;
}
}
uint16 Logic : : personSetup ( uint16 noun , uint16 curImage ) {
Person p ;
personSetData ( noun , " " , true , & p ) ;
const ActorData * pad = p . actor ;
uint16 scale = 100 ;
uint16 a = zoneInArea ( ZONE_ROOM , pad - > x , pad - > y ) ;
if ( a > 0 ) {
// person is not standing in the area box, scale it accordingly
scale = currentRoomArea ( a ) - > calcScale ( pad - > y ) ;
}
2003-11-20 09:38:54 +00:00
if ( noun = = 0 ) {
warning ( " Trying to setup person 0 " ) ;
return curImage ;
}
2003-12-06 13:15:17 +00:00
_graphics - > bankUnpack ( pad - > bobFrameStanding , p . bobFrame , p . actor - > bankNum ) ;
2003-10-13 14:21:17 +00:00
bool xflip = false ;
uint16 person = _roomData [ _currentRoom ] + noun ;
if ( _objectData [ person ] . image = = - 3 ) {
// person is facing left
xflip = true ;
}
BobSlot * pbs = _graphics - > bob ( pad - > bobNum ) ;
pbs - > active = true ;
pbs - > scale = scale ;
pbs - > x = pad - > x ;
pbs - > y = pad - > y ;
pbs - > frameNum = p . bobFrame ;
pbs - > xflip = xflip ;
2003-11-08 23:45:45 +00:00
2003-12-03 10:32:12 +00:00
debug ( 0 , " Logic::personSetup(%d, %d) - bob = %d name = %s " , noun , curImage , pad - > bobNum , p . name ) ;
2003-11-13 10:44:31 +00:00
2003-10-13 14:21:17 +00:00
if ( p . anim ! = NULL ) {
_personFrames [ pad - > bobNum ] = curImage + 1 ;
curImage = animCreate ( curImage , & p ) ;
}
else {
animErase ( pad - > bobNum ) ;
}
return curImage ;
}
uint16 Logic : : personAllocate ( uint16 noun , uint16 curImage ) {
2003-11-08 23:45:45 +00:00
2003-10-13 14:21:17 +00:00
uint16 i ;
uint16 person = _roomData [ _currentRoom ] + noun ;
// search Bob number for the person
uint16 bobNum = 0 ;
for ( i = _roomData [ _currentRoom ] + 1 ; i < = person ; + + i ) {
int16 img = _objectData [ i ] . image ;
if ( img = = - 3 | | img = = - 4 ) {
+ + bobNum ;
}
}
2003-11-08 23:45:45 +00:00
2003-10-13 14:21:17 +00:00
// search for a matching actor
uint16 actor = 0 ;
for ( i = 1 ; i < = _numActors ; + + i ) {
ActorData * pad = & _actorData [ i ] ;
if ( pad - > room = = _currentRoom ) {
if ( _gameState [ pad - > gameStateSlot ] = = pad - > gameStateValue ) {
if ( bobNum > 0 & & bobNum = = pad - > bobNum ) {
actor = i ;
break ;
}
}
}
}
2003-11-08 23:45:45 +00:00
2003-10-13 14:21:17 +00:00
if ( actor > 0 ) {
2003-11-08 23:20:23 +00:00
const char * animStr = _aAnim [ _actorData [ actor ] . anim ] ;
if ( animStr ) {
2003-10-13 14:21:17 +00:00
bool allocatedFrames [ 256 ] ;
memset ( allocatedFrames , 0 , sizeof ( allocatedFrames ) ) ;
uint16 f1 , f2 ;
do {
sscanf ( animStr , " %3hu,%3hu " , & f1 , & f2 ) ;
animStr + = 8 ;
allocatedFrames [ f1 ] = true ;
} while ( f1 ! = 0 ) ;
for ( i = 1 ; i < = 255 ; + + i ) {
if ( allocatedFrames [ i ] ) {
+ + curImage ;
}
}
2003-10-20 08:34:48 +00:00
// FIXME: shouldn't this line be executed BEFORE curImage is incremented ?
2003-10-13 14:21:17 +00:00
_personFrames [ bobNum ] = curImage + 1 ;
}
}
return curImage ;
}
uint16 Logic : : animCreate ( uint16 curImage , const Person * person ) {
2003-10-15 16:31:51 +00:00
AnimFrame * animFrames = _newAnim [ person - > actor - > bobNum ] ;
2003-10-13 14:21:17 +00:00
uint16 allocatedFrames [ 256 ] ;
memset ( allocatedFrames , 0 , sizeof ( allocatedFrames ) ) ;
const char * p = person - > anim ;
int frame = 0 ;
uint16 f1 , f2 ;
do {
sscanf ( p , " %3hu,%3hu " , & f1 , & f2 ) ;
2003-10-15 16:31:51 +00:00
animFrames [ frame ] . frame = f1 ;
animFrames [ frame ] . speed = f2 ;
2003-11-08 23:45:45 +00:00
2003-10-13 14:21:17 +00:00
if ( f1 > 500 ) {
// SFX
allocatedFrames [ f1 - 500 ] = 1 ;
}
else {
allocatedFrames [ f1 ] = 1 ;
}
p + = 8 ;
2003-10-15 16:31:51 +00:00
+ + frame ;
2003-10-13 14:21:17 +00:00
} while ( f1 ! = 0 ) ;
// ajust frame numbers
uint16 n = 1 ;
uint16 i ;
for ( i = 1 ; i < = 255 ; + + i ) {
if ( allocatedFrames [ i ] ! = 0 ) {
allocatedFrames [ i ] = n ;
+ + n ;
}
}
2003-10-15 16:31:51 +00:00
for ( i = 0 ; animFrames [ i ] . frame ! = 0 ; + + i ) {
uint16 frameNum = animFrames [ i ] . frame ;
2003-10-13 14:21:17 +00:00
if ( frameNum > 500 ) {
2003-10-15 16:31:51 +00:00
animFrames [ i ] . frame = curImage + allocatedFrames [ frameNum - 500 ] + 500 ;
2003-10-13 14:21:17 +00:00
}
else {
2003-10-15 16:31:51 +00:00
animFrames [ i ] . frame = curImage + allocatedFrames [ frameNum ] ;
2003-10-13 14:21:17 +00:00
}
}
2003-11-08 23:45:45 +00:00
2003-10-13 14:21:17 +00:00
// unpack necessary frames
for ( i = 1 ; i < = 255 ; + + i ) {
if ( allocatedFrames [ i ] ! = 0 ) {
+ + curImage ;
2003-12-06 13:15:17 +00:00
_graphics - > bankUnpack ( i , curImage , person - > actor - > bankNum ) ;
2003-10-13 14:21:17 +00:00
}
}
2003-11-08 23:45:45 +00:00
2003-10-13 14:21:17 +00:00
// start animation
2003-11-30 20:41:02 +00:00
_graphics - > bob ( person - > actor - > bobNum ) - > animString ( animFrames ) ;
2003-11-08 23:45:45 +00:00
2003-10-13 14:21:17 +00:00
return curImage ;
}
void Logic : : animErase ( uint16 bobNum ) {
2003-10-20 08:34:48 +00:00
2003-10-15 16:31:51 +00:00
_newAnim [ bobNum ] [ 0 ] . frame = 0 ;
2003-10-13 14:21:17 +00:00
BobSlot * pbs = _graphics - > bob ( bobNum ) ;
pbs - > animating = false ;
pbs - > anim . string . buffer = NULL ;
}
2003-12-03 13:00:56 +00:00
void Logic : : animReset ( uint16 bobNum ) {
if ( _newAnim [ bobNum ] [ 0 ] . frame ! = 0 ) {
_graphics - > bob ( bobNum ) - > animString ( _newAnim [ bobNum ] ) ;
}
}
2003-10-20 08:34:48 +00:00
void Logic : : animSetup ( const GraphicData * gd , uint16 firstImage , uint16 bobNum , bool visible ) {
2003-10-15 16:31:51 +00:00
int16 tempFrames [ 20 ] ;
memset ( tempFrames , 0 , sizeof ( tempFrames ) ) ;
uint16 numTempFrames = 0 ;
uint16 i , j ;
for ( i = 1 ; i < = _numGraphicAnim ; + + i ) {
const GraphicAnim * pga = & _graphicAnim [ i ] ;
if ( pga - > keyFrame = = gd - > firstFrame ) {
int16 frame = pga - > frame ;
if ( frame > 500 ) { // SFX
frame - = 500 ;
}
bool foundMatchingFrame = false ;
for ( j = 0 ; j < numTempFrames ; + + j ) {
if ( tempFrames [ j ] = = frame ) {
foundMatchingFrame = true ;
break ;
}
}
if ( ! foundMatchingFrame ) {
assert ( numTempFrames < 20 ) ;
tempFrames [ numTempFrames ] = frame ;
+ + numTempFrames ;
}
}
}
// sort found frames ascending
bool swap = true ;
while ( swap ) {
swap = false ;
for ( i = 0 ; i < numTempFrames - 1 ; + + i ) {
if ( tempFrames [ i ] > tempFrames [ i + 1 ] ) {
SWAP ( tempFrames [ i ] , tempFrames [ i + 1 ] ) ;
swap = true ;
}
}
}
// queen.c l.962-980 / l.1269-1294
for ( i = 0 ; i < gd - > lastFrame ; + + i ) {
_graphics - > bankUnpack ( ABS ( tempFrames [ i ] ) , firstImage + i , 15 ) ;
}
2003-10-20 08:34:48 +00:00
BobSlot * pbs = _graphics - > bob ( bobNum ) ;
pbs - > animating = false ;
if ( visible ) {
pbs - > x = gd - > x ;
pbs - > y = gd - > y ;
if ( tempFrames [ 0 ] < 0 ) {
pbs - > xflip = true ;
}
AnimFrame * paf = _newAnim [ bobNum ] ;
2003-10-15 16:31:51 +00:00
for ( i = 1 ; i < = _numGraphicAnim ; + + i ) {
const GraphicAnim * pga = & _graphicAnim [ i ] ;
if ( pga - > keyFrame = = gd - > firstFrame ) {
2003-10-19 18:52:28 +00:00
uint16 frameNr = 0 ;
2003-10-15 16:31:51 +00:00
for ( j = 1 ; j < = gd - > lastFrame ; + + j ) {
2003-10-19 18:52:28 +00:00
if ( pga - > frame > 500 ) {
if ( pga - > frame - 500 = = tempFrames [ j - 1 ] ) {
frameNr = j + firstImage - 1 + 500 ;
}
2003-10-15 16:31:51 +00:00
}
2003-10-19 18:52:28 +00:00
else if ( pga - > frame = = tempFrames [ j - 1 ] ) {
2003-10-15 16:31:51 +00:00
frameNr = j + firstImage - 1 ;
}
}
paf - > frame = frameNr ;
paf - > speed = pga - > speed ;
+ + paf ;
}
}
paf - > frame = 0 ;
paf - > speed = 0 ;
2003-10-20 08:34:48 +00:00
pbs - > animString ( _newAnim [ bobNum ] ) ;
2003-10-15 16:31:51 +00:00
}
}
2003-10-23 18:46:04 +00:00
void Logic : : joeSetupFromBanks ( const char * animBank , const char * standBank ) {
2003-10-21 09:05:16 +00:00
int i ;
2003-10-23 18:46:04 +00:00
_graphics - > bankLoad ( animBank , 13 ) ;
2003-10-14 19:06:44 +00:00
for ( i = 11 ; i < = 28 + FRAMES_JOE_XTRA ; + + i ) {
_graphics - > bankUnpack ( i - 10 , i , 13 ) ;
}
_graphics - > bankErase ( 13 ) ;
2003-10-23 18:46:04 +00:00
_graphics - > bankLoad ( standBank , 7 ) ;
2003-10-14 19:06:44 +00:00
_graphics - > bankUnpack ( 1 , 33 + FRAMES_JOE_XTRA , 7 ) ;
_graphics - > bankUnpack ( 3 , 34 + FRAMES_JOE_XTRA , 7 ) ;
_graphics - > bankUnpack ( 5 , 35 + FRAMES_JOE_XTRA , 7 ) ;
2003-10-21 09:05:16 +00:00
}
2003-10-14 19:06:44 +00:00
2003-10-21 09:05:16 +00:00
void Logic : : joeSetup ( ) {
joeSetupFromBanks ( " joe_a.BBK " , " joe_b.BBK " ) ;
2003-11-27 13:49:00 +00:00
joeFacing ( DIR_FRONT ) ;
2003-10-14 19:06:44 +00:00
}
ObjectData * Logic : : joeSetupInRoom ( bool autoPosition , uint16 scale ) {
2003-11-16 19:55:04 +00:00
debug ( 0 , " Logic::joeSetupInRoom(%d, %d) joe.x=%d joe.y=%d " , autoPosition , scale , _joe . x , _joe . y ) ;
2003-10-14 19:06:44 +00:00
uint16 oldx ;
uint16 oldy ;
WalkOffData * pwo = NULL ;
2003-11-06 21:06:01 +00:00
ObjectData * pod = objectData ( _entryObj ) ;
2003-10-14 19:06:44 +00:00
if ( pod = = NULL ) {
error ( " Logic::joeSetupInRoom() - No object data for obj %d " , _entryObj ) ;
}
2003-11-16 19:55:04 +00:00
if ( ! autoPosition | | joeX ( ) ! = 0 | | joeY ( ) ! = 0 ) {
oldx = joeX ( ) ;
oldy = joeY ( ) ;
2003-10-14 19:06:44 +00:00
}
else {
// find the walk off point for the entry object and make
// Joe walking to that point
pwo = walkOffPointForObject ( _entryObj ) ;
if ( pwo ! = NULL ) {
oldx = pwo - > x ;
oldy = pwo - > y ;
}
else {
// no walk off point, use object position
oldx = pod - > x ;
oldy = pod - > y ;
}
}
2003-12-03 20:53:59 +00:00
debug ( 0 , " Logic::joeSetupInRoom() - oldx=%d, oldy=%d scale=%d " , oldx , oldy , scale ) ;
2003-10-14 19:06:44 +00:00
if ( scale > 0 & & scale < 100 ) {
2003-12-05 20:16:32 +00:00
joeScale ( scale ) ;
2003-10-14 19:06:44 +00:00
}
else {
uint16 a = zoneInArea ( ZONE_ROOM , oldx , oldy ) ;
if ( a > 0 ) {
2003-12-05 20:16:32 +00:00
joeScale ( currentRoomArea ( a ) - > calcScale ( oldy ) ) ;
2003-10-14 19:06:44 +00:00
}
else {
2003-12-05 20:16:32 +00:00
joeScale ( 100 ) ;
2003-10-14 19:06:44 +00:00
}
}
2003-11-27 13:49:00 +00:00
if ( joeCutFacing ( ) > 0 ) {
joeFacing ( joeCutFacing ( ) ) ;
joeCutFacing ( 0 ) ;
2003-11-10 14:06:55 +00:00
}
2003-11-27 13:49:00 +00:00
else {
// check to see which way Joe entered room
switch ( State : : findDirection ( pod - > state ) ) {
case DIR_BACK :
joeFacing ( DIR_FRONT ) ;
break ;
case DIR_FRONT :
joeFacing ( DIR_BACK ) ;
break ;
case DIR_LEFT :
joeFacing ( DIR_RIGHT ) ;
break ;
case DIR_RIGHT :
joeFacing ( DIR_LEFT ) ;
break ;
}
}
joePrevFacing ( joeFacing ( ) ) ;
2003-10-23 18:46:04 +00:00
2003-10-14 19:06:44 +00:00
BobSlot * pbs = _graphics - > bob ( 0 ) ;
2003-12-05 20:16:32 +00:00
pbs - > scale = joeScale ( ) ;
2003-10-14 19:06:44 +00:00
2003-11-27 13:49:00 +00:00
if ( _currentRoom = = 108 ) {
_graphics - > cameraBob ( - 1 ) ;
_graphics - > bankLoad ( " joe_e.act " , 7 ) ;
_graphics - > bankUnpack ( 2 , 29 + FRAMES_JOE_XTRA , 7 ) ;
_display - > horizontalScroll ( 320 ) ;
joeFacing ( DIR_RIGHT ) ;
joeCutFacing ( DIR_RIGHT ) ;
joePrevFacing ( DIR_RIGHT ) ;
}
2003-10-14 19:06:44 +00:00
joeFace ( ) ;
pbs - > active = true ;
pbs - > x = oldx ;
pbs - > y = oldy ;
pbs - > frameNum = 29 + FRAMES_JOE_XTRA ;
2003-11-16 19:55:04 +00:00
joeX ( 0 ) ;
joeY ( 0 ) ;
2003-10-14 19:06:44 +00:00
if ( pwo ! = NULL ) {
// entryObj has a walk off point, then walk from there to object x,y
return pod ;
}
return NULL ;
}
uint16 Logic : : joeFace ( ) {
debug ( 9 , " Logic::joeFace() - curFace = %d, prevFace = %d " , _joe . facing , _joe . prevFacing ) ;
BobSlot * pbs = _graphics - > bob ( 0 ) ;
uint16 frame ;
if ( _currentRoom = = 108 ) {
frame = 1 ;
}
else {
frame = 33 ;
2003-11-27 13:49:00 +00:00
if ( joeFacing ( ) = = DIR_FRONT ) {
if ( joePrevFacing ( ) = = DIR_BACK ) {
2003-10-14 19:06:44 +00:00
pbs - > frameNum = 33 + FRAMES_JOE_XTRA ;
2003-10-23 06:44:35 +00:00
update ( ) ;
2003-10-14 19:06:44 +00:00
}
frame = 34 ;
}
2003-11-27 13:49:00 +00:00
else if ( joeFacing ( ) = = DIR_BACK ) {
if ( joePrevFacing ( ) = = DIR_FRONT ) {
2003-10-14 19:06:44 +00:00
pbs - > frameNum = 33 + FRAMES_JOE_XTRA ;
2003-10-23 06:44:35 +00:00
update ( ) ;
2003-10-14 19:06:44 +00:00
}
frame = 35 ;
}
2003-11-27 13:49:00 +00:00
else if ( ( joeFacing ( ) = = DIR_LEFT & & joePrevFacing ( ) = = DIR_RIGHT )
| | ( joeFacing ( ) = = DIR_RIGHT & & joePrevFacing ( ) = = DIR_LEFT ) ) {
2003-10-14 19:06:44 +00:00
pbs - > frameNum = 34 + FRAMES_JOE_XTRA ;
2003-10-23 06:44:35 +00:00
update ( ) ;
2003-10-14 19:06:44 +00:00
}
pbs - > frameNum = frame + FRAMES_JOE_XTRA ;
2003-12-05 20:16:32 +00:00
pbs - > scale = joeScale ( ) ;
2003-11-27 13:49:00 +00:00
pbs - > xflip = ( joeFacing ( ) = = DIR_LEFT ) ;
2003-10-23 06:44:35 +00:00
update ( ) ;
2003-11-27 13:49:00 +00:00
joePrevFacing ( joeFacing ( ) ) ;
2003-10-14 19:06:44 +00:00
switch ( frame ) {
2003-11-27 13:49:00 +00:00
case 33 :
frame = 1 ;
break ;
case 34 :
frame = 3 ;
break ;
case 35 :
frame = 5 ;
break ;
2003-10-14 19:06:44 +00:00
}
}
pbs - > frameNum = 29 + FRAMES_JOE_XTRA ;
_graphics - > bankUnpack ( frame , pbs - > frameNum , 7 ) ;
return frame ;
}
2003-10-21 09:05:16 +00:00
void Logic : : joeGrab ( uint16 state , uint16 speed ) {
2003-10-23 18:46:04 +00:00
StateGrab sg = State : : findGrab ( state ) ;
2003-10-21 09:05:16 +00:00
if ( sg ! = STATE_GRAB_NONE ) {
joeGrabDirection ( sg , speed ) ;
}
}
void Logic : : joeGrabDirection ( StateGrab grab , uint16 speed ) {
// if speed == 0, then keep Joe in position
uint16 frame = 0 ;
BobSlot * bobJoe = _graphics - > bob ( 0 ) ;
switch ( grab ) {
case STATE_GRAB_NONE :
break ;
case STATE_GRAB_MID :
2003-12-05 20:16:32 +00:00
if ( joeFacing ( ) = = DIR_BACK ) {
2003-11-16 10:47:31 +00:00
frame = 6 ;
2003-10-21 09:05:16 +00:00
}
2003-12-05 20:16:32 +00:00
else if ( joeFacing ( ) = = DIR_FRONT ) {
2003-11-16 10:47:31 +00:00
frame = 4 ;
2003-10-21 09:05:16 +00:00
}
else {
frame = 2 ;
}
break ;
case STATE_GRAB_DOWN :
2003-12-05 20:16:32 +00:00
if ( joeFacing ( ) = = DIR_BACK ) {
2003-10-21 09:05:16 +00:00
frame = 9 ;
}
else {
frame = 8 ;
}
break ;
case STATE_GRAB_UP :
// turn back
_graphics - > bankUnpack ( 5 , 29 + FRAMES_JOE_XTRA , 7 ) ;
2003-12-05 20:16:32 +00:00
bobJoe - > xflip = ( joeFacing ( ) = = DIR_LEFT ) ;
bobJoe - > scale = joeScale ( ) ;
2003-10-23 06:44:35 +00:00
update ( ) ;
2003-10-21 09:05:16 +00:00
// grab up
2003-11-08 23:45:45 +00:00
_graphics - > bankUnpack ( 7 , 29 + FRAMES_JOE_XTRA , 7 ) ;
2003-12-05 20:16:32 +00:00
bobJoe - > xflip = ( joeFacing ( ) = = DIR_LEFT ) ;
bobJoe - > scale = joeScale ( ) ;
2003-11-08 23:45:45 +00:00
update ( ) ;
2003-10-21 09:05:16 +00:00
// turn back
if ( speed = = 0 ) {
frame = 7 ;
}
else {
frame = 5 ;
}
break ;
}
2003-11-08 23:45:45 +00:00
2003-10-21 09:05:16 +00:00
if ( frame ! = 0 ) {
_graphics - > bankUnpack ( frame , 29 + FRAMES_JOE_XTRA , 7 ) ;
2003-12-05 20:16:32 +00:00
bobJoe - > xflip = ( joeFacing ( ) = = DIR_LEFT ) ;
bobJoe - > scale = joeScale ( ) ;
2003-10-23 06:44:35 +00:00
update ( ) ;
2003-10-21 09:05:16 +00:00
// extra delay for grab down
if ( grab = = STATE_GRAB_DOWN ) {
2003-10-23 06:44:35 +00:00
update ( ) ;
update ( ) ;
2003-10-21 09:05:16 +00:00
}
if ( speed > 0 ) {
joeFace ( ) ;
}
}
}
void Logic : : joeUseDress ( bool showCut ) {
if ( showCut ) {
joeFacing ( DIR_FRONT ) ;
joeFace ( ) ;
if ( gameState ( VAR_DRESSING_MODE ) = = 0 ) {
playCutaway ( " cdres.CUT " ) ;
2003-11-06 15:47:37 +00:00
inventoryInsertItem ( ITEM_CLOTHES ) ;
2003-10-21 09:05:16 +00:00
}
else {
playCutaway ( " cudrs.CUT " ) ;
}
}
_display - > palSetJoe ( JP_DRESS ) ;
joeSetupFromBanks ( " JoeD_A.BBK " , " JoeD_B.BBK " ) ;
2003-11-06 15:47:37 +00:00
inventoryDeleteItem ( ITEM_DRESS ) ;
2003-10-21 09:05:16 +00:00
gameState ( VAR_DRESSING_MODE , 2 ) ;
}
void Logic : : joeUseClothes ( bool showCut ) {
if ( showCut ) {
joeFacing ( DIR_FRONT ) ;
joeFace ( ) ;
playCutaway ( " cdclo.CUT " ) ;
2003-11-06 15:47:37 +00:00
inventoryInsertItem ( ITEM_DRESS ) ;
2003-10-21 09:05:16 +00:00
}
_display - > palSetJoe ( JP_CLOTHES ) ;
joeSetupFromBanks ( " Joe_A.BBK " , " Joe_B.BBK " ) ;
2003-11-06 15:47:37 +00:00
inventoryDeleteItem ( ITEM_CLOTHES ) ;
2003-10-21 09:05:16 +00:00
gameState ( VAR_DRESSING_MODE , 0 ) ;
}
void Logic : : joeUseUnderwear ( ) {
_display - > palSetJoe ( JP_CLOTHES ) ;
joeSetupFromBanks ( " JoeU_A.BBK " , " JoeU_B.BBK " ) ;
gameState ( VAR_DRESSING_MODE , 1 ) ;
}
2003-11-26 21:46:29 +00:00
void Logic : : makePersonSpeak ( const char * sentence , Person * person , const char * voiceFilePrefix ) {
_cmd - > clear ( false ) ;
Talk : : speak ( sentence , person , voiceFilePrefix , _graphics , _input , this , _resource , _sound ) ;
}
2003-11-06 08:44:33 +00:00
void Logic : : dialogue ( const char * dlgFile , int personInRoom , char * cutaway ) {
char cutawayFile [ 20 ] ;
if ( cutaway = = NULL ) {
cutaway = cutawayFile ;
}
2003-11-14 14:35:52 +00:00
_display - > fullscreen ( true ) ;
2003-11-06 08:44:33 +00:00
Talk : : talk ( dlgFile , personInRoom , cutaway , _graphics , _input , this , _resource , _sound ) ;
2003-12-03 13:00:56 +00:00
if ( ! cutaway [ 0 ] ) {
_display - > fullscreen ( false ) ;
}
2003-11-06 08:44:33 +00:00
}
2003-11-02 16:47:31 +00:00
void Logic : : playCutaway ( const char * cutFile , char * next ) {
2003-10-21 09:05:16 +00:00
2003-11-02 16:47:31 +00:00
char nextFile [ 20 ] ;
if ( next = = NULL ) {
next = nextFile ;
}
2003-12-02 19:58:31 +00:00
_graphics - > textClear ( CmdText : : COMMAND_Y_POS , CmdText : : COMMAND_Y_POS ) ;
2003-10-23 06:44:35 +00:00
Cutaway : : run ( cutFile , next , _graphics , _input , this , _resource , _sound ) ;
2003-10-21 09:05:16 +00:00
}
2003-10-23 18:46:04 +00:00
2003-10-27 15:00:25 +00:00
void Logic : : joeSpeak ( uint16 descNum , bool objectType ) {
// joeSpeak(k, false) == SPEAK(JOE_RESPstr[k],"JOE",find_cd_desc(k))
// joeSpeak(k, true) == SPEAK(OBJECT_DESCRstr[k],"JOE",find_cd_desc(JOERESPMAX+k))
const char * text = objectType ? _objDescription [ descNum ] : _joeResponse [ descNum ] ;
if ( objectType ) {
descNum + = JOE_RESPONSE_MAX ;
}
char descFilePrefix [ 10 ] ;
sprintf ( descFilePrefix , " JOE%04i " , descNum ) ;
2003-11-26 21:46:29 +00:00
makePersonSpeak ( text , NULL , descFilePrefix ) ;
2003-10-27 15:00:25 +00:00
}
Verb Logic : : findVerbUnderCursor ( int16 cursorx , int16 cursory ) const {
2003-10-25 09:11:35 +00:00
2003-10-30 10:56:38 +00:00
return Verb ( PANEL_VERBS [ zoneIn ( ZONE_PANEL , cursorx , cursory ) ] ) ;
2003-10-25 09:11:35 +00:00
}
2003-10-27 15:00:25 +00:00
uint16 Logic : : findObjectUnderCursor ( int16 cursorx , int16 cursory ) const {
uint16 roomObj = 0 ;
if ( cursory < ROOM_ZONE_HEIGHT ) {
int16 x = cursorx + _display - > horizontalScroll ( ) ;
roomObj = zoneIn ( ZONE_ROOM , x , cursory ) ;
}
return roomObj ;
}
2003-10-26 13:54:26 +00:00
uint16 Logic : : findObjectRoomNumber ( uint16 zoneNum ) const {
2003-10-25 20:26:50 +00:00
// l.316-327 select.c
uint16 noun = zoneNum ;
uint16 objectMax = _objMax [ _currentRoom ] ;
2003-12-02 16:49:56 +00:00
debug ( 0 , " Logic::findObjectRoomNumber(%X, %X) " , zoneNum , objectMax ) ;
2003-10-25 20:26:50 +00:00
if ( zoneNum > objectMax ) {
// this is an area box, check for associated object
2003-12-04 13:21:26 +00:00
uint16 obj = currentRoomArea ( zoneNum - objectMax ) - > object ;
2003-12-02 16:49:56 +00:00
if ( obj ! = 0 & & objectData ( obj ) - > name ! = 0 ) {
2003-10-25 20:26:50 +00:00
// there is an object, get its number
noun = obj - _roomData [ _currentRoom ] ;
}
}
return noun ;
}
2003-10-26 13:54:26 +00:00
uint16 Logic : : findObjectGlobalNumber ( uint16 zoneNum ) const {
return _roomData [ _currentRoom ] + findObjectRoomNumber ( zoneNum ) ;
}
2003-10-31 13:47:28 +00:00
uint16 Logic : : findInventoryItem ( int invSlot ) const {
// queen.c l.3894-3898
if ( invSlot > = 0 & & invSlot < 4 ) {
return _inventoryItem [ invSlot ] ;
}
return 0 ;
}
void Logic : : inventorySetup ( ) {
2003-11-08 23:45:45 +00:00
2003-10-31 13:47:28 +00:00
_graphics - > bankLoad ( " objects.BBK " , 14 ) ;
2003-11-06 15:47:37 +00:00
_inventoryItem [ 0 ] = ITEM_BAT ;
2003-11-13 12:39:37 +00:00
_inventoryItem [ 1 ] = ITEM_JOURNAL ;
2003-11-07 02:33:20 +00:00
_inventoryItem [ 2 ] = ITEM_NONE ;
_inventoryItem [ 3 ] = ITEM_NONE ;
2003-10-31 13:47:28 +00:00
}
void Logic : : inventoryRefresh ( ) {
2003-11-08 23:45:45 +00:00
2003-10-31 13:47:28 +00:00
int16 i ;
uint16 x = 182 ;
for ( i = 0 ; i < 4 ; + + i ) {
uint16 itemNum = _inventoryItem [ i ] ;
if ( itemNum ! = 0 ) {
// 1st object in inventory uses frame 8,
// whereas 2nd, 3rd and 4th uses frame 9
uint16 dstFrame = ( itemNum ! = 0 ) ? 8 : 9 ;
// unpack frame for object and draw it
_graphics - > bankUnpack ( _itemData [ itemNum ] . frame , dstFrame , 14 ) ;
_graphics - > bobDrawInventoryItem ( dstFrame , x , 14 ) ;
}
else {
// no object, clear the panel
_graphics - > bobDrawInventoryItem ( 0 , x , 14 ) ;
}
x + = 35 ;
}
// XXX OLDVERB=VERB;
update ( ) ;
}
2003-11-02 14:49:51 +00:00
int16 Logic : : previousInventoryItem ( int16 start ) const {
int i ;
for ( i = start - 1 ; i > = 1 ; i - - )
if ( _itemData [ i ] . name > 0 )
return i ;
for ( i = _numItems ; i > start ; i - - )
if ( _itemData [ i ] . name > 0 )
return i ;
return 0 ; //nothing found
}
int16 Logic : : nextInventoryItem ( int16 start ) const {
int i ;
for ( i = start + 1 ; i < _numItems ; i + + )
if ( _itemData [ i ] . name > 0 )
return i ;
for ( i = 1 ; i < start ; i + + )
if ( _itemData [ i ] . name > 0 )
return i ;
return 0 ; //nothing found
}
void Logic : : removeDuplicateItems ( ) {
for ( int i = 0 ; i < 4 ; i + + )
for ( int j = i + 1 ; j < 4 ; j + + )
if ( _inventoryItem [ i ] = = _inventoryItem [ j ] )
2003-11-07 02:33:20 +00:00
_inventoryItem [ j ] = ITEM_NONE ;
2003-11-02 14:49:51 +00:00
}
uint16 Logic : : numItemsInventory ( ) const {
uint16 count = 0 ;
for ( int i = 1 ; i < _numItems ; i + + )
if ( _itemData [ i ] . name > 0 )
count + + ;
return count ;
}
2003-10-31 13:47:28 +00:00
void Logic : : inventoryInsertItem ( uint16 itemNum , bool refresh ) {
2003-11-02 14:49:51 +00:00
int16 item = _inventoryItem [ 0 ] = ( int16 ) itemNum ;
2003-12-05 13:56:07 +00:00
_itemData [ itemNum ] . name = ABS ( _itemData [ itemNum ] . name ) ; //set visible
2003-11-02 14:49:51 +00:00
for ( int i = 1 ; i < 4 ; i + + ) {
item = nextInventoryItem ( item ) ;
_inventoryItem [ i ] = item ;
removeDuplicateItems ( ) ;
}
2003-11-08 23:45:45 +00:00
2003-11-02 14:49:51 +00:00
if ( refresh )
inventoryRefresh ( ) ;
2003-10-31 13:47:28 +00:00
}
void Logic : : inventoryDeleteItem ( uint16 itemNum , bool refresh ) {
2003-11-02 14:49:51 +00:00
int16 item = ( int16 ) itemNum ;
2003-12-05 13:56:07 +00:00
_itemData [ itemNum ] . name = - ABS ( _itemData [ itemNum ] . name ) ; //set invisible
2003-11-02 14:49:51 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
item = nextInventoryItem ( item ) ;
_inventoryItem [ i ] = item ;
removeDuplicateItems ( ) ;
}
2003-11-08 23:45:45 +00:00
2003-11-02 14:49:51 +00:00
if ( refresh )
inventoryRefresh ( ) ;
2003-10-31 13:47:28 +00:00
}
void Logic : : inventoryScroll ( uint16 count , bool up ) {
2003-11-02 14:49:51 +00:00
if ( ! ( numItemsInventory ( ) > 4 ) )
return ;
if ( up ) {
for ( int i = 3 ; i > 0 ; i - - )
_inventoryItem [ i ] = _inventoryItem [ i - 1 ] ;
_inventoryItem [ 0 ] = previousInventoryItem ( _inventoryItem [ 0 ] ) ;
2003-11-02 21:37:20 +00:00
} else {
for ( int i = 0 ; i < 3 ; i + + )
_inventoryItem [ i ] = _inventoryItem [ i + 1 ] ;
_inventoryItem [ 3 ] = nextInventoryItem ( _inventoryItem [ 3 ] ) ;
2003-11-02 14:49:51 +00:00
}
inventoryRefresh ( ) ;
2003-10-31 13:47:28 +00:00
}
void Logic : : objectCopy ( int dummyObjectIndex , int realObjectIndex ) {
// P3_COPY_FROM function in cutaway.c
/* Copy data from Dummy (D) object to object (K)
If COPY_FROM Object images are greater than COPY_TO Object
images then swap the objects around . */
ObjectData * dummyObject = objectData ( dummyObjectIndex ) ;
ObjectData * realObject = objectData ( realObjectIndex ) ;
int fromState = ( dummyObject - > name < 0 ) ? - 1 : 0 ;
int frameCountReal = 1 ;
int frameCountDummy = 1 ;
int graphic = realObject - > image ;
if ( graphic > 0 ) {
if ( graphic > 5000 )
graphic - = 5000 ;
GraphicData * data = graphicData ( graphic ) ;
if ( data - > lastFrame > 0 )
frameCountReal = data - > lastFrame - data - > firstFrame + 1 ;
graphic = dummyObject - > image ;
if ( graphic > 0 ) {
if ( graphic > 5000 )
graphic - = 5000 ;
data = graphicData ( graphic ) ;
if ( data - > lastFrame > 0 )
frameCountDummy = data - > lastFrame - data - > firstFrame + 1 ;
}
}
ObjectData temp = * realObject ;
* realObject = * dummyObject ;
if ( frameCountDummy > frameCountReal )
* dummyObject = temp ;
2003-12-05 13:56:07 +00:00
realObject - > name = ABS ( realObject - > name ) ;
2003-10-31 13:47:28 +00:00
if ( fromState = = - 1 )
2003-12-05 13:56:07 +00:00
dummyObject - > name = - ABS ( dummyObject - > name ) ;
2003-10-31 13:47:28 +00:00
// Make sure that WALK_OFF_DATA is copied too!
for ( int i = 1 ; i < = _numWalkOffs ; i + + ) {
WalkOffData * walkOff = & _walkOffData [ i ] ;
if ( walkOff - > entryObj = = ( int16 ) dummyObjectIndex ) {
walkOff - > entryObj = ( int16 ) realObjectIndex ;
break ;
}
}
}
void Logic : : checkPlayer ( ) {
update ( ) ;
_cmd - > updatePlayer ( ) ;
}
2003-11-02 16:47:31 +00:00
void Logic : : customMoveJoe ( int facing , uint16 areaNum , uint16 walkDataNum ) {
// queen.c l.2838-2911
debug ( 9 , " customMoveJoe(%d, %d, %d) \n " , facing , areaNum , walkDataNum ) ;
// Stop animating Joe
_graphics - > bob ( 0 ) - > animating = false ;
2003-11-08 23:45:45 +00:00
// Make Joe face the right direction
2003-11-02 16:47:31 +00:00
joeFacing ( facing ) ;
joeFace ( ) ;
_newRoom = 0 ;
_entryObj = 0 ;
char nextCut [ 20 ] ;
memset ( nextCut , 0 , sizeof ( nextCut ) ) ;
switch ( _currentRoom ) {
2003-12-03 10:32:12 +00:00
case ROOM_JUNGLE_BRIDGE :
2003-11-02 16:47:31 +00:00
joeSpeak ( 16 ) ;
break ;
2003-12-03 10:32:12 +00:00
case ROOM_JUNGLE_GORILLA_1 :
2003-11-02 16:47:31 +00:00
playCutaway ( " c6c.CUT " , nextCut ) ;
break ;
2003-12-03 10:32:12 +00:00
case ROOM_JUNGLE_GORILLA_2 :
2003-11-02 16:47:31 +00:00
playCutaway ( " c14b.CUT " , nextCut ) ;
break ;
2003-12-03 10:32:12 +00:00
case ROOM_AMAZON_ENTRANCE :
2003-11-02 16:47:31 +00:00
if ( areaNum = = 3 ) {
playCutaway ( " c16a.CUT " , nextCut ) ;
}
break ;
2003-12-03 10:32:12 +00:00
case ROOM_AMAZON_HIDEOUT :
2003-11-02 16:47:31 +00:00
if ( walkDataNum = = 4 ) {
playCutaway ( " c17a.CUT " , nextCut ) ;
}
else if ( walkDataNum = = 2 ) {
playCutaway ( " c17b.CUT " , nextCut ) ;
}
break ;
2003-12-03 10:32:12 +00:00
case ROOM_FLODA_OUTSIDE :
2003-11-02 16:47:31 +00:00
playCutaway ( " c22a.CUT " , nextCut ) ;
break ;
2003-12-03 10:32:12 +00:00
case ROOM_FLODA_KITCHEN :
2003-11-02 16:47:31 +00:00
playCutaway ( " c26b.CUT " , nextCut ) ;
break ;
2003-12-03 10:32:12 +00:00
case ROOM_FLODA_KLUNK :
2003-11-02 16:47:31 +00:00
playCutaway ( " c30a.CUT " , nextCut ) ;
break ;
2003-12-03 10:32:12 +00:00
case ROOM_FLODA_HENRY :
2003-11-02 16:47:31 +00:00
playCutaway ( " c32c.CUT " , nextCut ) ;
break ;
2003-12-03 10:32:12 +00:00
case ROOM_TEMPLE_ZOMBIES :
2003-11-02 16:47:31 +00:00
if ( areaNum = = 6 ) {
if ( _gameState [ 21 ] = = 0 ) {
playCutaway ( " c50d.CUT " , nextCut ) ;
while ( nextCut [ 0 ] ! = ' \0 ' ) {
playCutaway ( nextCut , nextCut ) ;
}
2003-11-03 19:52:14 +00:00
_gameState [ 21 ] = 1 ;
2003-11-02 16:47:31 +00:00
} else {
playCutaway ( " c50h.CUT " , nextCut ) ;
}
}
break ;
2003-12-03 10:32:12 +00:00
case ROOM_TEMPLE_SNAKE :
2003-11-02 16:47:31 +00:00
playCutaway ( " c53b.CUT " , nextCut ) ;
break ;
2003-12-03 10:32:12 +00:00
case ROOM_TEMPLE_LIZARD_LASER :
2003-11-02 16:47:31 +00:00
joeSpeak ( 19 ) ;
break ;
2003-12-03 10:32:12 +00:00
case ROOM_HOTEL_DOWNSTAIRS :
2003-11-02 16:47:31 +00:00
joeSpeak ( 21 ) ;
break ;
2003-12-03 10:32:12 +00:00
case ROOM_HOTEL_LOBBY :
if ( _gameState [ VAR_ESCAPE_FROM_HOTEL_COUNT ] = = 0 ) {
2003-11-02 16:47:31 +00:00
playCutaway ( " c73a.CUT " ) ;
2003-12-03 10:32:12 +00:00
_gameState [ VAR_ESCAPE_FROM_HOTEL_COUNT ] = 1 ;
2003-11-02 16:47:31 +00:00
joeUseUnderwear ( ) ;
joeFace ( ) ;
}
2003-12-03 10:32:12 +00:00
else if ( _gameState [ VAR_ESCAPE_FROM_HOTEL_COUNT ] = = 1 ) {
2003-11-02 16:47:31 +00:00
playCutaway ( " c73b.CUT " ) ;
2003-12-03 10:32:12 +00:00
_gameState [ VAR_ESCAPE_FROM_HOTEL_COUNT ] = 2 ;
2003-11-02 16:47:31 +00:00
}
2003-12-03 10:32:12 +00:00
else if ( _gameState [ VAR_ESCAPE_FROM_HOTEL_COUNT ] = = 2 ) {
2003-11-02 16:47:31 +00:00
playCutaway ( " c73c.CUT " ) ;
}
break ;
2003-12-03 10:32:12 +00:00
case ROOM_TEMPLE_MAZE_5 :
2003-11-02 16:47:31 +00:00
if ( areaNum = = 7 ) {
joeSpeak ( 17 ) ;
}
break ;
2003-12-03 10:32:12 +00:00
case ROOM_TEMPLE_MAZE_6 :
2003-11-02 16:47:31 +00:00
if ( areaNum = = 5 & & _gameState [ 187 ] = = 0 ) {
playCutaway ( " c101b.CUT " , nextCut ) ;
}
break ;
2003-12-03 10:32:12 +00:00
case ROOM_FLODA_FRONTDESK :
2003-11-02 16:47:31 +00:00
if ( areaNum = = 3 ) {
2003-12-03 10:32:12 +00:00
if ( _gameState [ VAR_BYPASS_FLODA_RECEPTIONIST ] = = 1 ) {
2003-11-02 16:47:31 +00:00
playCutaway ( " c103e.CUT " , nextCut ) ;
}
2003-12-03 10:32:12 +00:00
else if ( _gameState [ VAR_BYPASS_FLODA_RECEPTIONIST ] = = 0 ) {
2003-11-02 16:47:31 +00:00
playCutaway ( " c103b.CUT " , nextCut ) ;
2003-12-03 10:32:12 +00:00
_gameState [ VAR_BYPASS_FLODA_RECEPTIONIST ] = 1 ;
2003-11-02 16:47:31 +00:00
}
}
break ;
}
while ( strlen ( nextCut ) > 4 & &
2003-12-03 10:32:12 +00:00
scumm_stricmp ( nextCut + strlen ( nextCut ) - 4 , " .cut " ) = = 0 ) {
2003-11-02 16:47:31 +00:00
playCutaway ( nextCut , nextCut ) ;
}
}
2003-11-04 13:51:36 +00:00
void Logic : : handlePinnacleRoom ( ) {
// camera does not follow Joe anymore
_graphics - > cameraBob ( - 1 ) ;
2003-11-30 20:41:02 +00:00
roomDisplay ( ROOM_JUNGLE_PINNACLE , RDM_NOFADE_JOE , 100 , 2 , true ) ;
2003-11-04 13:51:36 +00:00
BobSlot * joe = _graphics - > bob ( 6 ) ;
BobSlot * piton = _graphics - > bob ( 7 ) ;
// set scrolling value to mouse position to avoid glitch
_display - > horizontalScroll ( _input - > mousePosX ( ) ) ;
joe - > x = piton - > x = 3 * _input - > mousePosX ( ) / 4 + 200 ;
joe - > frameNum = _input - > mousePosX ( ) / 36 + 43 + FRAMES_JOE_XTRA ;
// adjust bounding box for fullscreen
joe - > box . y2 = piton - > box . y2 = GAME_SCREEN_HEIGHT - 1 ;
// bobs have been unpacked from animating objects, we don't need them
// to animate anymore ; so turn animating off
joe - > animating = piton - > animating = false ;
update ( ) ;
2003-11-15 15:44:50 +00:00
_display - > palFadeIn ( 0 , 223 , ROOM_JUNGLE_PINNACLE , joe - > active , joe - > x , joe - > y ) ;
2003-11-04 13:51:36 +00:00
_entryObj = 0 ;
uint16 prevObj = 0 ;
while ( _input - > mouseButton ( ) = = 0 | | _entryObj = = 0 ) {
update ( ) ;
int mx = _input - > mousePosX ( ) ;
int my = _input - > mousePosY ( ) ;
// update screen scrolling
_display - > horizontalScroll ( _input - > mousePosX ( ) ) ;
// update bobs position / frame
joe - > x = piton - > x = 3 * mx / 4 + 200 ;
joe - > frameNum = mx / 36 + 43 + FRAMES_JOE_XTRA ;
uint16 curObj = findObjectUnderCursor ( mx , my ) ;
if ( curObj ! = 0 & & curObj ! = prevObj ) {
_entryObj = 0 ;
curObj + = _roomData [ _currentRoom ] ; // global object number
ObjectData * objData = & _objectData [ curObj ] ;
if ( objData - > name > 0 ) {
_entryObj = objData - > entryObj ;
char textCmd [ CmdText : : MAX_COMMAND_LEN ] ;
sprintf ( textCmd , " %s %s " , Verb ( VERB_WALK_TO ) . name ( ) , _objName [ objData - > name ] ) ;
_graphics - > textCurrentColor ( INK_MAP7 ) ;
_graphics - > textSetCentered ( 5 , textCmd ) ;
}
prevObj = curObj ;
}
}
_input - > clearMouseButton ( ) ;
_newRoom = _objectData [ _entryObj ] . room ;
2003-11-16 10:47:31 +00:00
// Only a few commands can be triggered from this room :
// piton -> crash : 0x216 (obj=0x2a, song=3)
// piton -> floda : 0x217 (obj=0x29, song=16)
// piton -> bob : 0x219 (obj=0x2f, song=6)
// piton -> embark : 0x218 (obj=0x2c, song=7)
// piton -> jungle : 0x20B (obj=0x2b, song=3)
// piton -> amazon : 0x21A (obj=0x30, song=3)
2003-11-04 13:51:36 +00:00
//
2003-11-16 10:47:31 +00:00
// Because none of these update objects/areas/gamestate, the EXECUTE_ACTION()
// call, as the original does, is useless. All we have to do is the playsong
// call (all songs have the PLAY_BEFORE type). This way we could get rid of
// the hack described in execute.c l.334-339.
2003-11-04 13:51:36 +00:00
//
// XXX if (com->song > 0) { playsong(com->song); }
2003-11-16 10:47:31 +00:00
joe - > active = piton - > active = false ;
_graphics - > textClear ( 5 , 5 ) ;
2003-11-04 13:51:36 +00:00
// camera follows Joe again
_graphics - > cameraBob ( 0 ) ;
2003-11-12 10:50:05 +00:00
2003-11-16 10:47:31 +00:00
_display - > palFadeOut ( 0 , 223 , ROOM_JUNGLE_PINNACLE ) ;
2003-11-04 13:51:36 +00:00
}
2003-10-23 06:44:35 +00:00
void Logic : : update ( ) {
_graphics - > update ( _currentRoom ) ;
_input - > delay ( ) ;
_display - > palCustomScroll ( _currentRoom ) ;
BobSlot * joe = _graphics - > bob ( 0 ) ;
_display - > update ( joe - > active , joe - > x , joe - > y ) ;
2003-11-09 20:50:03 +00:00
_dbg - > update ( _input - > checkKeys ( ) ) ;
2003-11-09 21:31:18 +00:00
if ( _input - > quickSave ( ) )
if ( ! _input - > cutawayRunning ( ) ) {
_input - > quickSaveReset ( ) ;
gameSave ( 0 , " Quicksave " ) ;
}
if ( _input - > quickLoad ( ) )
if ( ! _input - > cutawayRunning ( ) ) {
_input - > quickLoadReset ( ) ;
gameLoad ( 0 ) ;
}
}
bool Logic : : gameSave ( uint16 slot , const char * desc ) {
if ( ! desc ) //no description entered
return false ;
debug ( 3 , " Saving game to slot %d " , slot ) ;
int i , j ;
char * buf = new char [ 32 ] ;
memcpy ( buf , desc , strlen ( desc ) < 32 ? strlen ( desc ) : 32 ) ;
for ( i = strlen ( desc ) ; i < 32 ; i + + )
buf [ i ] = ' \0 ' ;
byte * saveData = new byte [ SAVEGAME_SIZE ] ;
byte * ptr = saveData ;
memcpy ( ptr , buf , 32 ) ; ptr + = 32 ;
2003-11-09 21:55:19 +00:00
delete [ ] buf ;
2003-11-09 21:31:18 +00:00
WRITE_BE_UINT16 ( ptr , _settings . talkSpeed ) ; ptr + = 2 ;
WRITE_BE_UINT16 ( ptr , _settings . musicVolume ) ; ptr + = 2 ;
2003-11-15 21:33:04 +00:00
WRITE_BE_UINT16 ( ptr , _sound - > sfxOn ( ) ? 1 : 0 ) ; ptr + = 2 ;
WRITE_BE_UINT16 ( ptr , _sound - > speechOn ( ) ? 1 : 0 ) ; ptr + = 2 ;
WRITE_BE_UINT16 ( ptr , _sound - > musicOn ( ) ? 1 : 0 ) ; ptr + = 2 ;
2003-11-09 21:31:18 +00:00
WRITE_BE_UINT16 ( ptr , _settings . textToggle ? 1 : 0 ) ; ptr + = 2 ;
for ( i = 0 ; i < 4 ; i + + ) {
WRITE_BE_UINT16 ( ptr , _inventoryItem [ i ] ) ; ptr + = 2 ;
}
WRITE_BE_UINT16 ( ptr , _graphics - > bob ( 0 ) - > x ) ; ptr + = 2 ;
WRITE_BE_UINT16 ( ptr , _graphics - > bob ( 0 ) - > y ) ; ptr + = 2 ;
WRITE_BE_UINT16 ( ptr , _currentRoom ) ; ptr + = 2 ;
for ( i = 1 ; i < = _numObjects ; i + + )
_objectData [ i ] . writeTo ( ptr ) ;
for ( i = 1 ; i < = _numItems ; i + + )
_itemData [ i ] . writeTo ( ptr ) ;
for ( i = 0 ; i < GAME_STATE_COUNT ; i + + ) {
WRITE_BE_UINT16 ( ptr , gameState ( i ) ) ; ptr + = 2 ;
}
for ( i = 1 ; i < = _numRooms ; i + + )
for ( j = 1 ; j < = _areaMax [ i ] ; j + + )
_area [ i ] [ j ] . writeTo ( ptr ) ;
2003-11-09 21:55:19 +00:00
for ( i = 0 ; i < TALK_SELECTED_COUNT ; i + + )
2003-11-09 21:31:18 +00:00
_talkSelected [ i ] . writeTo ( ptr ) ;
for ( i = 1 ; i < = _numWalkOffs ; i + + )
_walkOffData [ i ] . writeTo ( ptr ) ;
WRITE_BE_UINT16 ( ptr , _joe . facing ) ; ptr + = 2 ;
WRITE_BE_UINT16 ( ptr , 0 ) ; ptr + = 2 ; //TODO: tmpbamflag
WRITE_BE_UINT16 ( ptr , 0 ) ; ptr + = 2 ; //TODO: lastoverride
//TODO: lastmerge, lastalter, altmrgpri
for ( i = 0 ; i < 3 ; i + + ) {
WRITE_BE_UINT16 ( ptr , 0 ) ; ptr + = 2 ;
}
if ( ( ptr - saveData ) ! = SAVEGAME_SIZE ) {
delete [ ] saveData ;
return false ;
}
bool result = _resource - > writeSave ( slot , saveData , SAVEGAME_SIZE ) ;
delete [ ] saveData ;
return result ;
}
bool Logic : : gameLoad ( uint16 slot ) {
int i , j ;
byte * saveData = new byte [ SAVEGAME_SIZE ] ;
byte * ptr = saveData ;
if ( ! _resource - > readSave ( slot , saveData ) ) {
warning ( " Couldn't load savegame from slot %d " , slot ) ;
delete [ ] saveData ;
return false ;
}
debug ( 3 , " Loading game from slot %d " , slot ) ;
ptr + = 32 ; //skip description
_settings . talkSpeed = ( int16 ) READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
_settings . musicVolume = ( int16 ) READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
2003-11-15 21:33:04 +00:00
_sound - > sfxToggle ( READ_BE_UINT16 ( ptr ) ! = 0 ) ; ptr + = 2 ;
_sound - > speechToggle ( READ_BE_UINT16 ( ptr ) ! = 0 ) ; ptr + = 2 ;
_sound - > musicToggle ( READ_BE_UINT16 ( ptr ) ! = 0 ) ; ptr + = 2 ;
2003-11-09 21:31:18 +00:00
_settings . textToggle = READ_BE_UINT16 ( ptr ) ! = 0 ; ptr + = 2 ;
for ( i = 0 ; i < 4 ; i + + ) {
_inventoryItem [ i ] = ( int16 ) READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
}
_joe . x = ( int16 ) READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
_joe . y = ( int16 ) READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
currentRoom ( READ_BE_UINT16 ( ptr ) ) ; ptr + = 2 ;
for ( i = 1 ; i < = _numObjects ; i + + )
_objectData [ i ] . readFrom ( ptr ) ;
for ( i = 1 ; i < = _numItems ; i + + )
_itemData [ i ] . readFrom ( ptr ) ;
for ( i = 0 ; i < GAME_STATE_COUNT ; i + + ) {
gameState ( i , ( int16 ) READ_BE_UINT16 ( ptr ) ) ; ptr + = 2 ;
}
for ( i = 1 ; i < = _numRooms ; i + + )
for ( j = 1 ; j < = _areaMax [ i ] ; j + + )
_area [ i ] [ j ] . readFrom ( ptr ) ;
2003-11-09 21:55:19 +00:00
for ( i = 0 ; i < TALK_SELECTED_COUNT ; i + + )
2003-11-09 21:31:18 +00:00
_talkSelected [ i ] . readFrom ( ptr ) ;
for ( i = 1 ; i < = _numWalkOffs ; i + + )
_walkOffData [ i ] . readFrom ( ptr ) ;
joeFacing ( READ_BE_UINT16 ( ptr ) ) ; ptr + = 2 ;
READ_BE_UINT16 ( ptr ) ; ptr + = 2 ; //TODO: tmpbamflag
READ_BE_UINT16 ( ptr ) ; ptr + = 2 ; //TODO: lastoverride
//_sound->playSound(_sound->lastOverride())
//TODO: lastmerge, lastalter, altmrgpri
for ( i = 0 ; i < 3 ; i + + ) {
READ_BE_UINT16 ( ptr ) ; ptr + = 2 ;
}
if ( ( ptr - saveData ) ! = SAVEGAME_SIZE ) {
delete [ ] saveData ;
return false ;
}
2003-11-27 13:49:00 +00:00
joeCutFacing ( joeFacing ( ) ) ;
2003-11-09 21:31:18 +00:00
joeFace ( ) ;
//OLDX = _joe.x;
//OLDY = _joe.y;
_oldRoom = 0 ;
newRoom ( _currentRoom ) ;
_entryObj = 0 ;
switch ( gameState ( VAR_DRESSING_MODE ) ) {
case 0 :
joeUseClothes ( false ) ;
break ;
case 1 :
joeUseUnderwear ( ) ;
break ;
case 2 :
joeUseDress ( false ) ;
break ;
}
inventoryRefresh ( ) ;
//bamflag = ..
delete [ ] saveData ;
return true ;
2003-10-23 06:44:35 +00:00
}
2003-10-21 09:05:16 +00:00
2003-11-14 14:35:52 +00:00
void Logic : : sceneStart ( ) {
2003-11-10 12:21:10 +00:00
debug ( 0 , " [Logic::sceneStart] _scene = %i " , _scene ) ;
2003-11-08 11:32:32 +00:00
_scene + + ;
2003-11-30 20:41:02 +00:00
_display - > showMouseCursor ( false ) ;
2003-11-08 11:32:32 +00:00
2003-11-14 14:35:52 +00:00
if ( 1 = = _scene ) { // && _input->cutawayRunning()) { // sceneStart is always called when cutaway is running
2003-11-08 11:32:32 +00:00
_display - > palFadePanel ( ) ;
}
2003-11-08 23:45:45 +00:00
2003-11-08 11:32:32 +00:00
update ( ) ;
}
2003-11-14 14:35:52 +00:00
void Logic : : sceneStop ( ) {
2003-11-10 12:21:10 +00:00
debug ( 0 , " [Logic::sceneStop] _scene = %i " , _scene ) ;
2003-11-08 11:32:32 +00:00
_scene - - ;
if ( _scene > 0 )
return ;
_display - > palSetAllDirty ( ) ;
2003-11-30 20:41:02 +00:00
_display - > showMouseCursor ( true ) ;
2003-11-08 11:32:32 +00:00
zoneSetupPanel ( ) ;
}
2003-10-23 18:46:04 +00:00
2003-11-15 15:44:50 +00:00
void Logic : : useJournal ( ) {
if ( _resource - > isDemo ( ) ) {
2003-11-26 21:46:29 +00:00
makePersonSpeak ( " This is a demo, so I can't load or save games*14 " , NULL , " " ) ;
2003-11-15 15:44:50 +00:00
}
else {
2003-11-26 20:40:43 +00:00
2003-11-26 13:53:17 +00:00
// XXX save some vars
2003-11-26 20:40:43 +00:00
//
// XXX tmpbamflag=bamflag;
// XXX bamflag=0;
// XXX in_journal=1;
_cmd - > clear ( false ) ;
2003-11-26 13:53:17 +00:00
Journal j ( this , _graphics , _display , _sound , & _settings ) ;
j . use ( ) ;
2003-11-26 20:40:43 +00:00
_walk - > stopJoe ( ) ;
2003-11-26 13:53:17 +00:00
// XXX restore vars
2003-11-26 20:40:43 +00:00
//
// XXX in_journal=0;
// XXX bamflag=tmpbamflag;
// XXX TALKQUIT=CUTQUIT=0; Make sure that we turn off cut stuff in case we use Journal during cutaways
2003-11-26 13:53:17 +00:00
2003-11-15 15:44:50 +00:00
}
}
2003-12-10 14:19:04 +00:00
void Logic : : executeSpecialMove ( uint16 sm ) {
// FIXME: for now, we initialise the various 'asm' procs here but,
// in order to support the 'interview' mini-game', we will have to do
// that in a proper setupAsmForGame() or setupAsmForInterview() function.
static const SpecialMoveProc proc [ 40 ] = {
/* 00 */
NULL ,
NULL ,
& Logic : : asmMakeJoeUseDress ,
& Logic : : asmMakeJoeUseNormalClothes ,
/* 04 */
& Logic : : asmMakeJoeUseUnderwear ,
& Logic : : asmSwitchToDressPalette ,
& Logic : : asmSwitchToNormalPalette ,
& Logic : : asmStartCarAnimation ,
/* 08 */
& Logic : : asmStopCarAnimation ,
& Logic : : asmStartFightAnimation ,
& Logic : : asmWaitForFrankPosition ,
& Logic : : asmMakeFrankGrowing ,
/* 12 */
& Logic : : asmMakeRobotGrowing ,
& Logic : : asmShrinkRobot ,
& Logic : : asmEndGame ,
& Logic : : asmPutCameraOnDino ,
/* 16 */
& Logic : : asmPutCameraOnJoe ,
NULL , // XXX alternative introduction
NULL , // XXX alternative introduction
& Logic : : asmSetAzuraInLove ,
/* 20 */
& Logic : : asmPanRightFromJoe ,
& Logic : : asmSetLightsOff ,
& Logic : : asmSetLightsOn ,
& Logic : : asmSetManequinAreaOn ,
/* 24 */
& Logic : : asmPanToJoe ,
& Logic : : asmTurnGuardOn ,
& Logic : : asmPanLeft320To144 ,
& Logic : : asmSmooch ,
/* 28 */
& Logic : : asmMakeLightningHitPlane ,
& Logic : : asmScaleBlimp ,
& Logic : : asmScaleEnding ,
& Logic : : asmWaitForCarPosition ,
/* 32 */
& Logic : : asmShakeScreen ,
& Logic : : asmAttemptPuzzle ,
& Logic : : asmScaleTitle ,
NULL , // XXX PC Demo ?
/* 36 */
& Logic : : asmPanRightToHugh ,
& Logic : : asmMakeWhiteFlash ,
& Logic : : asmPanRightToJoeAndRita ,
& Logic : : asmPanLeftToBomb
} ;
if ( sm > = ARRAYSIZE ( proc ) | | proc [ sm ] = = NULL ) {
warning ( " unhandled / invalid special move : %d " , sm ) ;
}
else {
debug ( 0 , " Special move: %d " , sm ) ;
( this - > * proc [ sm ] ) ( ) ;
}
}
void Logic : : asmMakeJoeUseDress ( ) {
joeUseDress ( false ) ;
}
void Logic : : asmMakeJoeUseNormalClothes ( ) {
joeUseClothes ( false ) ;
}
void Logic : : asmMakeJoeUseUnderwear ( ) {
joeUseUnderwear ( ) ;
}
void Logic : : asmSwitchToDressPalette ( ) {
_display - > palSetJoe ( JP_DRESS ) ;
}
void Logic : : asmSwitchToNormalPalette ( ) {
_display - > palSetJoe ( JP_CLOTHES ) ;
}
void Logic : : asmStartCarAnimation ( ) {
// Carbam background animation - room 74
_graphics - > initCarBamScene ( ) ;
}
void Logic : : asmStopCarAnimation ( ) {
// CR 2 - Turn off big oil splat and gun shots!
_graphics - > cleanupCarBamScene ( findBob ( 594 ) ) ; // Oil object
}
void Logic : : asmStartFightAnimation ( ) {
// Fight1 background animation - room 69
_graphics - > initFightBamScene ( ) ;
gameState ( 148 , 1 ) ;
}
void Logic : : asmWaitForFrankPosition ( ) {
// c69e.cut
_graphics - > bamData ( ) - > flag = 2 ;
while ( _graphics - > bamData ( ) - > flag ) {
update ( ) ;
}
}
void Logic : : asmMakeFrankGrowing ( ) {
// c69z.cut
_graphics - > bankUnpack ( 1 , 38 , 15 ) ;
BobSlot * bobFrank = _graphics - > bob ( 5 ) ;
bobFrank - > frameNum = 38 ;
bobFrank - > curPos ( 160 , 200 ) ;
bobFrank - > box . y2 = GAME_SCREEN_HEIGHT - 1 ;
int i ;
for ( i = 10 ; i < = 100 ; i + = 4 ) {
bobFrank - > scale = i ;
update ( ) ;
}
for ( i = 0 ; i < = 20 ; + + i ) {
update ( ) ;
}
objectData ( 521 ) - > name = ABS ( objectData ( 521 ) - > name ) ; // Dinoray
objectData ( 526 ) - > name = ABS ( objectData ( 526 ) - > name ) ; // Frank obj
objectData ( 522 ) - > name = - ABS ( objectData ( 522 ) - > name ) ; // TMPD object off
objectData ( 525 ) - > name = - ABS ( objectData ( 525 ) - > name ) ; // Floda guards off
objectData ( 523 ) - > name = - ABS ( objectData ( 523 ) - > name ) ; // Sparky object off
gameState ( 157 , 1 ) ; // No more Ironstein
}
void Logic : : asmMakeRobotGrowing ( ) {
// c69z.cut
_graphics - > bankUnpack ( 1 , 38 , 15 ) ;
BobSlot * bobRobot = _graphics - > bob ( 5 ) ;
bobRobot - > frameNum = 38 ;
bobRobot - > curPos ( 160 , 200 ) ;
bobRobot - > box . y2 = GAME_SCREEN_HEIGHT - 1 ;
int i ;
for ( i = 10 ; i < = 100 ; i + = 4 ) {
bobRobot - > scale = i ;
update ( ) ;
}
for ( i = 0 ; i < = 20 ; + + i ) {
update ( ) ;
}
objectData ( 524 ) - > name = - ABS ( objectData ( 524 ) - > name ) ; // Azura object off
objectData ( 526 ) - > name = - ABS ( objectData ( 526 ) - > name ) ; // Frank object off
}
void Logic : : asmShrinkRobot ( ) {
int i ;
for ( i = 100 ; i > = 35 ; i - = 5 ) {
_graphics - > bob ( 6 ) - > scale = i ;
update ( ) ;
}
}
void Logic : : asmEndGame ( ) {
int i ;
for ( i = 0 ; i < 40 ; + + i ) {
update ( ) ;
}
OSystem : : instance ( ) - > quit ( ) ;
debug ( 0 , " Game completed " ) ;
}
void Logic : : asmPutCameraOnDino ( ) {
_graphics - > cameraBob ( - 1 ) ;
while ( _display - > horizontalScroll ( ) < 320 ) {
_display - > horizontalScroll ( _display - > horizontalScroll ( ) + 16 ) ;
if ( _display - > horizontalScroll ( ) > 320 ) {
_display - > horizontalScroll ( 320 ) ;
}
update ( ) ;
}
_graphics - > cameraBob ( 1 ) ;
}
void Logic : : asmPutCameraOnJoe ( ) {
_graphics - > cameraBob ( 0 ) ;
}
void Logic : : asmSetAzuraInLove ( ) {
gameState ( VAR_AZURA_IN_LOVE , 1 ) ;
}
void Logic : : asmPanRightFromJoe ( ) {
_graphics - > cameraBob ( - 1 ) ;
while ( _display - > horizontalScroll ( ) < 320 ) {
_display - > horizontalScroll ( _display - > horizontalScroll ( ) + 16 ) ;
if ( _display - > horizontalScroll ( ) > 320 ) {
_display - > horizontalScroll ( 320 ) ;
}
update ( ) ;
}
}
void Logic : : asmSetLightsOff ( ) {
_display - > palCustomLightsOff ( currentRoom ( ) ) ;
}
void Logic : : asmSetLightsOn ( ) {
_display - > palCustomLightsOn ( currentRoom ( ) ) ;
}
void Logic : : asmSetManequinAreaOn ( ) {
area ( ROOM_FLODA_FRONTDESK , 7 ) - > mapNeighbours = ABS ( area ( ROOM_FLODA_FRONTDESK , 7 ) - > mapNeighbours ) ;
}
void Logic : : asmPanToJoe ( ) {
int i = _graphics - > bob ( 0 ) - > x - 160 ;
if ( i < 0 ) {
i = 0 ;
}
else if ( i > 320 ) {
i = 320 ;
}
_graphics - > cameraBob ( - 1 ) ;
if ( i < _display - > horizontalScroll ( ) ) {
while ( _display - > horizontalScroll ( ) > i ) {
_display - > horizontalScroll ( _display - > horizontalScroll ( ) - 16 ) ;
if ( _display - > horizontalScroll ( ) < i ) {
_display - > horizontalScroll ( i ) ;
}
update ( ) ;
}
}
else {
while ( _display - > horizontalScroll ( ) < i ) {
_display - > horizontalScroll ( _display - > horizontalScroll ( ) + 16 ) ;
if ( _display - > horizontalScroll ( ) > i ) {
_display - > horizontalScroll ( i ) ;
}
}
update ( ) ;
}
_graphics - > cameraBob ( 0 ) ;
}
void Logic : : asmTurnGuardOn ( ) {
gameState ( 85 , 1 ) ;
}
void Logic : : asmPanLeft320To144 ( ) {
_graphics - > cameraBob ( - 1 ) ;
while ( _display - > horizontalScroll ( ) > 144 ) {
_display - > horizontalScroll ( _display - > horizontalScroll ( ) - 8 ) ;
if ( _display - > horizontalScroll ( ) < 144 ) {
_display - > horizontalScroll ( 144 ) ;
}
update ( ) ;
}
}
void Logic : : asmSmooch ( ) {
_graphics - > cameraBob ( - 1 ) ;
BobSlot * bobAzura = _graphics - > bob ( 5 ) ;
BobSlot * bobJoe = _graphics - > bob ( 6 ) ;
while ( _display - > horizontalScroll ( ) < 320 ) {
_display - > horizontalScroll ( _display - > horizontalScroll ( ) + 8 ) ;
if ( bobJoe - > x - bobAzura - > x > 128 ) {
bobAzura - > x + = 10 ;
bobJoe - > x + = 6 ;
}
else {
bobAzura - > x + = 8 ;
bobJoe - > x + = 8 ;
}
update ( ) ;
}
}
void Logic : : asmMakeLightningHitPlane ( ) {
_graphics - > cameraBob ( - 1 ) ;
short iy = 0 , x , ydir = - 1 , j , k ;
BobSlot * planeBob = _graphics - > bob ( 5 ) ;
BobSlot * lightningBob = _graphics - > bob ( 20 ) ;
planeBob - > box . y2 = lightningBob - > box . y2 = 199 ;
planeBob - > y = 135 ;
planeBob - > scale = 20 ;
for ( x = 660 ; x > 163 ; x - = 6 ) {
planeBob - > x = x ;
planeBob - > y = 135 + iy ;
iy - = ydir ;
if ( iy < - 9 | | iy > 9 )
ydir = - ydir ;
planeBob - > scale + + ;
if ( planeBob - > scale > 100 )
planeBob - > scale = 100 ;
int scrollX = x - 163 ;
if ( scrollX > 320 )
scrollX = 320 ;
_display - > horizontalScroll ( scrollX ) ;
update ( ) ;
}
planeBob - > scale = 100 ;
_display - > horizontalScroll ( 0 ) ;
planeBob - > x - = - 8 ;
planeBob - > y + = 6 ;
lightningBob - > x = 160 ;
lightningBob - > y = 0 ;
// 23/2/95 - Play lightning SFX
// XXX sfxplay(NULLstr);
_graphics - > bankUnpack ( 18 , lightningBob - > frameNum , 15 ) ;
_graphics - > bankUnpack ( 4 , planeBob - > frameNum , 15 ) ;
// Plane plunges into the jungle!
BobSlot * fireBob = _graphics - > bob ( 6 ) ;
fireBob - > animating = true ;
fireBob - > x = planeBob - > x ;
fireBob - > y = planeBob - > y + 10 ;
_graphics - > bankUnpack ( 19 , fireBob - > frameNum , 15 ) ;
update ( ) ;
k = 20 ;
j = 1 ;
for ( x = 163 ; x > - 30 ; x - = 10 ) {
planeBob - > y + = 4 ;
fireBob - > y + = 4 ;
planeBob - > x = fireBob - > x = x ;
if ( k < 40 ) {
_graphics - > bankUnpack ( j , planeBob - > frameNum , 15 ) ;
_graphics - > bankUnpack ( k , fireBob - > frameNum , 15 ) ;
k + + ;
j + + ;
if ( j = = 4 )
j = 1 ;
}
update ( ) ;
}
_graphics - > cameraBob ( 0 ) ;
}
void Logic : : asmScaleBlimp ( ) {
int16 z = 256 ;
BobSlot * bob = _graphics - > bob ( 7 ) ;
int16 x = bob - > x ;
int16 y = bob - > y ;
while ( bob - > x > 150 ) {
bob - > x = x * 256 / z + 150 ;
bob - > x = y * 256 / z + 112 ;
bob - > scale = 100 * 256 / z ;
+ + z ;
if ( z % 6 = = 0 ) {
- - x ;
}
update ( ) ;
}
}
void Logic : : asmScaleEnding ( ) {
_graphics - > bob ( 7 ) - > active = false ; // Turn off blimp
BobSlot * b = _graphics - > bob ( 20 ) ;
b - > x = 160 ;
b - > y = 100 ;
int i ;
for ( i = 5 ; i < = 100 ; i + = 5 ) {
b - > scale = i ;
update ( ) ;
}
for ( i = 0 ; i < 50 ; + + i ) {
update ( ) ;
}
_display - > palFadeOut ( 0 , 255 , currentRoom ( ) ) ;
}
void Logic : : asmWaitForCarPosition ( ) {
// Wait for car to reach correct position before pouring oil
while ( _graphics - > bamData ( ) - > index ! = 60 ) {
update ( ) ;
}
}
void Logic : : asmShakeScreen ( ) {
OSystem : : instance ( ) - > set_shake_pos ( 3 ) ;
update ( ) ;
OSystem : : instance ( ) - > set_shake_pos ( 0 ) ;
update ( ) ;
}
void Logic : : asmAttemptPuzzle ( ) {
static short n = 0 ;
+ + n ;
if ( n & 4 ) {
joeSpeak ( 226 , true ) ;
}
}
void Logic : : asmScaleTitle ( ) {
BobSlot * bob = _graphics - > bob ( 5 ) ;
bob - > animating = false ;
bob - > x = 161 ;
bob - > y = 200 ;
bob - > scale = 100 ;
int i ;
for ( i = 5 ; i < = 100 ; i + = 5 ) {
bob - > scale = i ;
bob - > y - = 4 ;
update ( ) ;
}
}
void Logic : : asmPanRightToHugh ( ) {
BobSlot * bob_thugA1 = _graphics - > bob ( 20 ) ;
BobSlot * bob_thugA2 = _graphics - > bob ( 21 ) ;
BobSlot * bob_thugA3 = _graphics - > bob ( 22 ) ;
BobSlot * bob_hugh1 = _graphics - > bob ( 1 ) ;
BobSlot * bob_hugh2 = _graphics - > bob ( 23 ) ;
BobSlot * bob_hugh3 = _graphics - > bob ( 24 ) ;
BobSlot * bob_thugB1 = _graphics - > bob ( 25 ) ;
BobSlot * bob_thugB2 = _graphics - > bob ( 26 ) ;
_graphics - > cameraBob ( - 1 ) ;
_input - > fastMode ( true ) ;
update ( ) ;
int i = 4 , k = 160 ;
// Adjust thug1 gun so it matches rest of body
bob_thugA1 - > x + = ( k / 2 ) * 2 - 45 ;
bob_thugA2 - > x + = ( k / 2 ) * 2 ;
bob_thugA3 - > x + = ( k / 2 ) * 2 ;
bob_hugh1 - > x + = ( k / 2 ) * 3 + ( k / 2 ) ;
bob_hugh2 - > x + = ( k / 2 ) * 3 + ( k / 2 ) ;
bob_hugh3 - > x + = ( k / 2 ) * 3 + ( k / 2 ) ;
bob_thugB1 - > x + = ( k / 2 ) * 4 + k ;
bob_thugB2 - > x + = ( k / 2 ) * 4 + k ;
if ( i = = 3 ) {
bob_thugB1 - > x + = 10 ;
bob_thugB2 - > x + = 10 ;
}
i * = 2 ;
int horizontalScroll = 0 ;
while ( horizontalScroll < k ) {
horizontalScroll = horizontalScroll + i ;
if ( horizontalScroll > k )
horizontalScroll = k ;
//debug(0, "horizontalScroll = %i", horizontalScroll);
_display - > horizontalScroll ( horizontalScroll ) ;
bob_thugA1 - > x - = i * 2 ;
bob_thugA2 - > x - = i * 2 ;
bob_thugA3 - > x - = i * 2 ;
bob_hugh1 - > x - = i * 3 ;
bob_hugh2 - > x - = i * 3 ;
bob_hugh3 - > x - = i * 3 ;
bob_thugB1 - > x - = i * 4 ;
bob_thugB2 - > x - = i * 4 ;
update ( ) ;
if ( _input - > cutawayQuit ( ) )
return ;
}
_input - > fastMode ( false ) ;
}
void Logic : : asmMakeWhiteFlash ( ) {
_display - > palCustomFlash ( ) ;
}
void Logic : : asmPanRightToJoeAndRita ( ) { // cdint.cut
BobSlot * bob_box = _graphics - > bob ( 20 ) ;
BobSlot * bob_beam = _graphics - > bob ( 21 ) ;
BobSlot * bob_crate = _graphics - > bob ( 22 ) ;
BobSlot * bob_clock = _graphics - > bob ( 23 ) ;
BobSlot * bob_hands = _graphics - > bob ( 24 ) ;
_graphics - > cameraBob ( - 1 ) ;
_input - > fastMode ( true ) ;
update ( ) ;
bob_box - > x + = 280 * 2 ;
bob_beam - > x + = 30 ;
bob_crate - > x + = 180 * 3 ;
int horizontalScroll = _display - > horizontalScroll ( ) ;
int i = 1 ;
while ( horizontalScroll < 290 ) {
horizontalScroll = horizontalScroll + i ;
if ( horizontalScroll > 290 )
horizontalScroll = 290 ;
//debug(0, "horizontalScroll = %i", horizontalScroll);
_display - > horizontalScroll ( horizontalScroll ) ;
bob_box - > x - = i * 2 ;
bob_beam - > x - = i ;
bob_crate - > x - = i * 3 ;
bob_clock - > x - = i * 2 ;
bob_hands - > x - = i * 2 ;
update ( ) ;
if ( _input - > cutawayQuit ( ) )
return ;
}
_input - > fastMode ( false ) ;
}
void Logic : : asmPanLeftToBomb ( ) { // cdint.cut
BobSlot * bob21 = _graphics - > bob ( 21 ) ;
BobSlot * bob22 = _graphics - > bob ( 22 ) ;
_graphics - > cameraBob ( - 1 ) ;
_input - > fastMode ( true ) ;
int horizontalScroll = _display - > horizontalScroll ( ) ;
int i = 5 ;
while ( horizontalScroll > 0 | | bob21 - > x < 136 ) {
horizontalScroll - = i ;
if ( horizontalScroll < 0 )
horizontalScroll = 0 ;
//debug(0, "horizontalScroll = %i", horizontalScroll);
_display - > horizontalScroll ( horizontalScroll ) ;
if ( horizontalScroll < 272 & & bob21 - > x < 136 )
bob21 - > x + = ( i / 2 ) ;
bob22 - > x + = i ;
update ( ) ;
if ( _input - > cutawayQuit ( ) )
return ;
}
_input - > fastMode ( false ) ;
}
2003-10-03 19:47:41 +00:00
} // End of namespace Queen
2003-10-05 16:07:07 +00:00