2007-09-06 10:48:00 +00:00
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers , whose names
* are too numerous to list here . Please refer to the COPYRIGHT
* file distributed with this source distribution .
*
* 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 . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
* $ URL $
* $ Id $
*
*/
2007-09-18 16:20:44 +00:00
# include "agi/preagi.h"
2007-09-06 10:48:00 +00:00
# include "agi/preagi_winnie.h"
# include "agi/graphics.h"
2007-09-07 16:22:31 +00:00
# include "graphics/cursorman.h"
2008-10-06 12:48:52 +00:00
# include "common/events.h"
2007-09-07 20:30:10 +00:00
# include "common/savefile.h"
2007-12-08 18:25:00 +00:00
# include "common/stream.h"
2007-09-06 20:51:40 +00:00
2007-09-06 10:48:00 +00:00
namespace Agi {
2007-09-23 12:25:44 +00:00
void Winnie : : parseRoomHeader ( WTP_ROOM_HDR * roomHdr , byte * buffer , int len ) {
int i ;
2008-01-11 09:52:06 +00:00
Common : : MemoryReadStreamEndian readS ( buffer , len , _isBigEndian ) ;
2007-09-23 12:25:44 +00:00
roomHdr - > roomNumber = readS . readByte ( ) ;
roomHdr - > objId = readS . readByte ( ) ;
roomHdr - > ofsPic = readS . readUint16 ( ) ;
roomHdr - > fileLen = readS . readUint16 ( ) ;
roomHdr - > reserved0 = readS . readUint16 ( ) ;
for ( i = 0 ; i < IDI_WTP_MAX_DIR ; i + + )
2007-09-23 13:40:28 +00:00
roomHdr - > roomNew [ i ] = readS . readByte ( ) ;
2007-09-23 12:25:44 +00:00
2007-09-23 13:40:28 +00:00
roomHdr - > objX = readS . readByte ( ) ;
roomHdr - > objY = readS . readByte ( ) ;
2007-09-23 12:25:44 +00:00
roomHdr - > reserved1 = readS . readUint16 ( ) ;
for ( i = 0 ; i < IDI_WTP_MAX_BLOCK ; i + + )
roomHdr - > ofsDesc [ i ] = readS . readUint16 ( ) ;
for ( i = 0 ; i < IDI_WTP_MAX_BLOCK ; i + + )
roomHdr - > ofsBlock [ i ] = readS . readUint16 ( ) ;
for ( i = 0 ; i < IDI_WTP_MAX_STR ; i + + )
roomHdr - > ofsStr [ i ] = readS . readUint16 ( ) ;
roomHdr - > reserved2 = readS . readUint32 ( ) ;
for ( i = 0 ; i < IDI_WTP_MAX_BLOCK ; i + + )
for ( byte j = 0 ; j < IDI_WTP_MAX_BLOCK ; j + + )
roomHdr - > opt [ i ] . ofsOpt [ j ] = readS . readUint16 ( ) ;
}
void Winnie : : parseObjHeader ( WTP_OBJ_HDR * objHdr , byte * buffer , int len ) {
int i ;
2008-01-11 09:52:06 +00:00
Common : : MemoryReadStreamEndian readS ( buffer , len , _isBigEndian ) ;
2007-09-23 12:25:44 +00:00
objHdr - > fileLen = readS . readUint16 ( ) ;
objHdr - > objId = readS . readUint16 ( ) ;
for ( i = 0 ; i < IDI_WTP_MAX_OBJ_STR_END ; i + + )
objHdr - > ofsEndStr [ i ] = readS . readUint16 ( ) ;
for ( i = 0 ; i < IDI_WTP_MAX_OBJ_STR ; i + + )
objHdr - > ofsStr [ i ] = readS . readUint16 ( ) ;
objHdr - > ofsPic = readS . readUint16 ( ) ;
}
2007-09-23 00:12:07 +00:00
uint32 Winnie : : readRoom ( int iRoom , uint8 * buffer , WTP_ROOM_HDR & roomHdr ) {
2007-09-06 20:51:40 +00:00
char szFile [ 256 ] = { 0 } ;
2007-09-23 12:02:34 +00:00
2007-09-22 20:16:24 +00:00
if ( _vm - > getPlatform ( ) = = Common : : kPlatformPC )
sprintf ( szFile , IDS_WTP_ROOM_DOS , iRoom ) ;
else if ( _vm - > getPlatform ( ) = = Common : : kPlatformAmiga )
sprintf ( szFile , IDS_WTP_ROOM_AMIGA , iRoom ) ;
2007-09-23 02:15:48 +00:00
else if ( _vm - > getPlatform ( ) = = Common : : kPlatformC64 )
sprintf ( szFile , IDS_WTP_ROOM_C64 , iRoom ) ;
2007-09-24 19:37:57 +00:00
else if ( _vm - > getPlatform ( ) = = Common : : kPlatformApple2GS )
sprintf ( szFile , IDS_WTP_ROOM_APPLE , iRoom ) ;
2007-09-06 20:51:40 +00:00
Common : : File file ;
2007-09-22 20:16:24 +00:00
if ( ! file . open ( szFile ) ) {
warning ( " Could not open file \' %s \' " , szFile ) ;
2007-09-20 21:55:37 +00:00
return 0 ;
2007-09-22 20:16:24 +00:00
}
2007-09-06 20:51:40 +00:00
uint32 filelen = file . size ( ) ;
2007-09-23 02:15:48 +00:00
if ( _vm - > getPlatform ( ) = = Common : : kPlatformC64 ) { //Skip the loading address
filelen - = 2 ;
file . seek ( 2 , SEEK_CUR ) ;
}
2007-09-06 20:51:40 +00:00
memset ( buffer , 0 , sizeof ( buffer ) ) ;
file . read ( buffer , filelen ) ;
file . close ( ) ;
2007-09-23 00:12:07 +00:00
2007-09-23 12:25:44 +00:00
parseRoomHeader ( & roomHdr , buffer , filelen ) ;
2007-09-23 00:12:07 +00:00
2007-09-20 21:55:37 +00:00
return filelen ;
2007-09-06 20:51:40 +00:00
}
2007-09-20 21:55:37 +00:00
uint32 Winnie : : readObj ( int iObj , uint8 * buffer ) {
2007-09-06 23:45:32 +00:00
char szFile [ 256 ] = { 0 } ;
2007-09-22 20:16:24 +00:00
if ( _vm - > getPlatform ( ) = = Common : : kPlatformPC )
sprintf ( szFile , IDS_WTP_OBJ_DOS , iObj ) ;
else if ( _vm - > getPlatform ( ) = = Common : : kPlatformAmiga )
sprintf ( szFile , IDS_WTP_OBJ_AMIGA , iObj ) ;
2007-09-23 02:15:48 +00:00
else if ( _vm - > getPlatform ( ) = = Common : : kPlatformC64 )
sprintf ( szFile , IDS_WTP_OBJ_C64 , iObj ) ;
2007-09-24 19:37:57 +00:00
else if ( _vm - > getPlatform ( ) = = Common : : kPlatformApple2GS )
sprintf ( szFile , IDS_WTP_OBJ_APPLE , iObj ) ;
2007-09-06 23:45:32 +00:00
Common : : File file ;
2007-09-22 20:16:24 +00:00
if ( ! file . open ( szFile ) ) {
warning ( " Could not open file \' %s \' " , szFile ) ;
2007-09-19 22:29:14 +00:00
return 0 ;
2007-09-22 20:16:24 +00:00
}
2007-09-06 23:45:32 +00:00
uint32 filelen = file . size ( ) ;
2007-09-23 13:47:50 +00:00
if ( _vm - > getPlatform ( ) = = Common : : kPlatformC64 ) { //Skip the loading address
filelen - = 2 ;
file . seek ( 2 , SEEK_CUR ) ;
}
2007-09-06 23:45:32 +00:00
memset ( buffer , 0 , sizeof ( buffer ) ) ;
file . read ( buffer , filelen ) ;
file . close ( ) ;
2007-09-19 22:29:14 +00:00
return filelen ;
2007-09-06 23:45:32 +00:00
}
2007-09-06 10:48:00 +00:00
void Winnie : : randomize ( ) {
int iObj = 0 ;
int iRoom = 0 ;
bool done ;
for ( int i = 0 ; i < IDI_WTP_MAX_OBJ_MISSING ; i + + ) {
done = false ;
while ( ! done ) {
2007-09-24 01:27:22 +00:00
iObj = _vm - > rnd ( IDI_WTP_MAX_OBJ - 1 ) ;
2007-09-06 10:48:00 +00:00
done = true ;
for ( int j = 0 ; j < IDI_WTP_MAX_OBJ_MISSING ; j + + ) {
2007-09-23 17:00:35 +00:00
if ( _game . iUsedObj [ j ] = = iObj ) {
2007-09-06 10:48:00 +00:00
done = false ;
break ;
}
}
}
2007-09-23 17:00:35 +00:00
_game . iUsedObj [ i ] = iObj ;
2008-01-27 19:47:41 +00:00
2007-09-06 10:48:00 +00:00
done = false ;
while ( ! done ) {
2007-09-24 01:27:22 +00:00
iRoom = _vm - > rnd ( IDI_WTP_MAX_ROOM_NORMAL ) ;
2007-09-06 10:48:00 +00:00
done = true ;
for ( int j = 0 ; j < IDI_WTP_MAX_ROOM_OBJ ; j + + ) {
2007-09-23 17:00:35 +00:00
if ( _game . iObjRoom [ j ] = = iRoom ) {
2007-09-06 10:48:00 +00:00
done = false ;
break ;
}
}
}
2007-09-23 17:00:35 +00:00
_game . iObjRoom [ iObj ] = iRoom ;
2007-09-06 10:48:00 +00:00
}
}
void Winnie : : intro ( ) {
2007-09-22 20:16:24 +00:00
drawPic ( IDS_WTP_FILE_LOGO ) ;
2007-09-06 20:51:40 +00:00
_vm - > printStr ( IDS_WTP_INTRO_0 ) ;
2007-09-20 22:15:09 +00:00
_vm - > _gfx - > doUpdate ( ) ;
_vm - > _system - > updateScreen ( ) ;
2007-09-12 22:17:08 +00:00
_vm - > _system - > delayMillis ( 0x640 ) ;
2007-09-22 17:56:23 +00:00
if ( _vm - > getPlatform ( ) = = Common : : kPlatformAmiga )
_vm - > _gfx - > clearScreen ( 0 ) ;
2007-09-22 20:16:24 +00:00
drawPic ( IDS_WTP_FILE_TITLE ) ;
2007-09-06 20:51:40 +00:00
_vm - > printStr ( IDS_WTP_INTRO_1 ) ;
2007-09-20 22:15:09 +00:00
_vm - > _gfx - > doUpdate ( ) ;
_vm - > _system - > updateScreen ( ) ;
2007-09-12 22:17:08 +00:00
_vm - > _system - > delayMillis ( 0x640 ) ;
2007-09-20 22:05:37 +00:00
if ( ! playSound ( IDI_WTP_SND_POOH_0 ) )
return ;
if ( ! playSound ( IDI_WTP_SND_POOH_1 ) )
return ;
if ( ! playSound ( IDI_WTP_SND_POOH_2 ) )
return ;
2007-09-06 10:48:00 +00:00
}
2007-09-06 20:51:40 +00:00
int Winnie : : getObjInRoom ( int iRoom ) {
2008-01-27 19:47:41 +00:00
for ( int iObj = 1 ; iObj < IDI_WTP_MAX_ROOM_OBJ ; iObj + + )
if ( _game . iObjRoom [ iObj ] = = iRoom )
2007-09-06 20:51:40 +00:00
return iObj ;
return 0 ;
}
# define setTakeDrop() {\
2007-09-23 17:00:35 +00:00
if ( getObjInRoom ( _room ) ) \
2007-09-06 20:51:40 +00:00
fCanSel [ IDI_WTP_SEL_TAKE ] = true ; \
else \
fCanSel [ IDI_WTP_SEL_TAKE ] = false ; \
2007-09-23 17:00:35 +00:00
if ( _game . iObjHave ) \
2007-09-06 20:51:40 +00:00
fCanSel [ IDI_WTP_SEL_DROP ] = true ; \
else \
fCanSel [ IDI_WTP_SEL_DROP ] = false ; \
}
2007-09-07 20:30:10 +00:00
void Winnie : : setFlag ( int iFlag ) {
2007-09-23 17:00:35 +00:00
_game . fGame [ iFlag ] = 1 ;
2007-09-07 20:30:10 +00:00
}
void Winnie : : clearFlag ( int iFlag ) {
2007-09-23 17:00:35 +00:00
_game . fGame [ iFlag ] = 0 ;
2007-09-07 20:30:10 +00:00
}
2007-09-06 20:51:40 +00:00
int Winnie : : parser ( int pc , int index , uint8 * buffer ) {
WTP_ROOM_HDR hdr ;
int startpc = pc ;
int8 opcode ;
int iNewRoom = 0 ;
int iSel , iDir , iBlock ;
int fCanSel [ IDI_WTP_SEL_LAST + 1 ] ;
char szMenu [ 121 ] = { 0 } ;
bool done ;
int fBlock ;
// extract header from buffer
2007-09-23 12:25:44 +00:00
parseRoomHeader ( & hdr , buffer , sizeof ( WTP_ROOM_HDR ) ) ;
2007-09-06 20:51:40 +00:00
2008-08-05 21:38:59 +00:00
for ( ; ; ) {
2007-09-06 20:51:40 +00:00
pc = startpc ;
// check if block is to be run
iBlock = * ( buffer + pc + + ) ;
if ( iBlock = = 0 )
return IDI_WTP_PAR_OK ;
fBlock = * ( buffer + pc + + ) ;
2007-09-23 17:00:35 +00:00
if ( _game . fGame [ iBlock ] ! = fBlock )
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_OK ;
// extract text from block
opcode = * ( buffer + pc ) ;
switch ( opcode ) {
case 0 :
case IDO_WTP_OPTION_0 :
case IDO_WTP_OPTION_1 :
case IDO_WTP_OPTION_2 :
// clear fCanSel block
memset ( fCanSel , 0 , sizeof ( fCanSel ) ) ;
// check if NSEW directions should be displayed
if ( hdr . roomNew [ 0 ] )
2008-01-27 19:47:41 +00:00
fCanSel [ IDI_WTP_SEL_NORTH ] = fCanSel [ IDI_WTP_SEL_SOUTH ] =
2007-09-06 20:51:40 +00:00
fCanSel [ IDI_WTP_SEL_EAST ] = fCanSel [ IDI_WTP_SEL_WEST ] = true ;
// check if object in room or player carrying one
setTakeDrop ( ) ;
2008-01-27 19:47:41 +00:00
2007-09-06 20:51:40 +00:00
// check which rows have a menu option
for ( iSel = 0 ; iSel < IDI_WTP_MAX_OPTION ; iSel + + ) {
opcode = * ( buffer + pc + + ) ;
if ( opcode ) {
fCanSel [ opcode - IDO_WTP_OPTION_0 ] = true ;
fCanSel [ iSel + IDI_WTP_SEL_REAL_OPT_1 ] = opcode - 0x14 ;
}
}
// extract menu string
strcpy ( szMenu , ( char * ) ( buffer + pc ) ) ;
_vm - > XOR80 ( szMenu ) ;
break ;
default :
// print description
2008-01-11 09:52:06 +00:00
printStrWinnie ( ( char * ) ( buffer + pc ) ) ;
2007-09-19 09:54:42 +00:00
if ( _vm - > getSelection ( kSelBackspace ) = = 1 )
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_OK ;
2008-01-27 19:47:41 +00:00
else
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_BACK ;
}
// input handler
done = false ;
while ( ! done ) {
// run wind if it's time
2007-09-23 17:00:35 +00:00
if ( _doWind )
2007-09-07 20:47:31 +00:00
wind ( ) ;
2007-09-06 20:51:40 +00:00
// get menu selection
getMenuSel ( szMenu , & iSel , fCanSel ) ;
2007-09-23 17:00:35 +00:00
if ( + + _game . nMoves = = IDI_WTP_MAX_MOVES_UNTIL_WIND )
_doWind = true ;
2007-09-06 20:51:40 +00:00
2007-09-23 17:00:35 +00:00
if ( _winnieEvent & & ( _room < = IDI_WTP_MAX_ROOM_TELEPORT ) ) {
if ( ! _tiggerMist ) {
_tiggerMist = 1 ;
2007-09-23 15:09:48 +00:00
tigger ( ) ;
2007-09-06 20:51:40 +00:00
} else {
2007-09-23 17:00:35 +00:00
_tiggerMist = 0 ;
2007-09-23 15:09:48 +00:00
mist ( ) ;
2007-09-06 20:51:40 +00:00
}
2007-09-23 17:00:35 +00:00
_winnieEvent = false ;
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_GOTO ;
}
// process selection
switch ( iSel ) {
case IDI_WTP_SEL_HOME :
2007-09-23 17:00:35 +00:00
switch ( _room ) {
2007-09-06 20:51:40 +00:00
case IDI_WTP_ROOM_HOME :
case IDI_WTP_ROOM_MIST :
case IDI_WTP_ROOM_TIGGER :
break ;
default :
2007-09-23 17:00:35 +00:00
_room = IDI_WTP_ROOM_HOME ;
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_GOTO ;
}
break ;
case IDI_WTP_SEL_BACK :
return IDI_WTP_PAR_BACK ;
case IDI_WTP_SEL_OPT_1 :
case IDI_WTP_SEL_OPT_2 :
case IDI_WTP_SEL_OPT_3 :
done = true ;
break ;
case IDI_WTP_SEL_NORTH :
case IDI_WTP_SEL_SOUTH :
case IDI_WTP_SEL_EAST :
case IDI_WTP_SEL_WEST :
iDir = iSel - IDI_WTP_SEL_NORTH ;
if ( hdr . roomNew [ iDir ] = = IDI_WTP_ROOM_NONE ) {
2007-09-06 21:48:33 +00:00
_vm - > printStr ( IDS_WTP_CANT_GO ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-06 20:51:40 +00:00
} else {
2007-09-23 17:00:35 +00:00
_room = hdr . roomNew [ iDir ] ;
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_GOTO ;
}
break ;
case IDI_WTP_SEL_TAKE :
2007-09-23 17:00:35 +00:00
takeObj ( _room ) ;
2007-09-06 21:48:33 +00:00
setTakeDrop ( ) ;
2007-09-06 20:51:40 +00:00
break ;
case IDI_WTP_SEL_DROP :
2007-09-23 17:00:35 +00:00
dropObj ( _room ) ;
2007-09-06 21:48:33 +00:00
setTakeDrop ( ) ;
2007-09-06 20:51:40 +00:00
break ;
}
}
// jump to the script block of the selected option
2008-01-11 09:52:06 +00:00
pc = hdr . opt [ index ] . ofsOpt [ iSel ] - _roomOffset ;
2007-09-23 12:31:21 +00:00
2007-09-06 20:51:40 +00:00
opcode = * ( buffer + pc ) ;
if ( ! opcode ) pc + + ;
// process script
do {
opcode = * ( buffer + pc + + ) ;
switch ( opcode ) {
case IDO_WTP_GOTO_ROOM :
opcode = * ( buffer + pc + + ) ;
iNewRoom = opcode ;
break ;
case IDO_WTP_PRINT_MSG :
opcode = * ( buffer + pc + + ) ;
2007-09-23 17:00:35 +00:00
printRoomStr ( _room , opcode ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-06 20:51:40 +00:00
break ;
case IDO_WTP_PRINT_STR :
opcode = * ( buffer + pc + + ) ;
2007-09-23 17:00:35 +00:00
printRoomStr ( _room , opcode ) ;
2007-09-06 20:51:40 +00:00
break ;
case IDO_WTP_DROP_OBJ :
opcode = * ( buffer + pc + + ) ;
opcode = - 1 ;
2007-09-07 20:47:31 +00:00
dropObjRnd ( ) ;
2007-09-06 20:51:40 +00:00
break ;
case IDO_WTP_FLAG_CLEAR :
opcode = * ( buffer + pc + + ) ;
2007-09-07 20:30:10 +00:00
clearFlag ( opcode ) ;
2007-09-06 20:51:40 +00:00
break ;
case IDO_WTP_FLAG_SET :
opcode = * ( buffer + pc + + ) ;
2007-09-07 20:30:10 +00:00
setFlag ( opcode ) ;
2007-09-06 20:51:40 +00:00
break ;
case IDO_WTP_GAME_OVER :
2007-09-07 20:30:10 +00:00
gameOver ( ) ;
2007-09-06 20:51:40 +00:00
break ;
case IDO_WTP_WALK_MIST :
2007-09-23 15:09:48 +00:00
_mist - - ;
if ( ! _mist ) {
2007-09-23 17:00:35 +00:00
_room = _vm - > rnd ( IDI_WTP_MAX_ROOM_TELEPORT ) + 1 ;
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_GOTO ;
}
break ;
case IDO_WTP_PLAY_SOUND :
opcode = * ( buffer + pc + + ) ;
2007-09-20 22:05:37 +00:00
playSound ( ( ENUM_WTP_SOUND ) opcode ) ;
2007-09-06 20:51:40 +00:00
break ;
case IDO_WTP_SAVE_GAME :
2007-09-07 20:30:10 +00:00
saveGame ( ) ;
2007-09-23 17:00:35 +00:00
_room = IDI_WTP_ROOM_HOME ;
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_GOTO ;
case IDO_WTP_LOAD_GAME :
2007-09-07 20:30:10 +00:00
loadGame ( ) ;
2007-09-23 17:00:35 +00:00
_room = IDI_WTP_ROOM_HOME ;
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_GOTO ;
case IDO_WTP_OWL_HELP :
opcode = * ( buffer + pc + + ) ;
2007-09-07 20:47:31 +00:00
showOwlHelp ( ) ;
2007-09-06 20:51:40 +00:00
break ;
case IDO_WTP_GOTO_RND :
2007-09-23 17:00:35 +00:00
_room = _vm - > rnd ( IDI_WTP_MAX_ROOM_TELEPORT ) + 1 ;
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_GOTO ;
default :
opcode = 0 ;
break ;
}
} while ( opcode ) ;
if ( iNewRoom ) {
2007-09-23 17:00:35 +00:00
_room = iNewRoom ;
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_GOTO ;
}
if ( iBlock = = 1 )
return IDI_WTP_PAR_OK ;
2007-09-20 22:15:09 +00:00
_vm - > _gfx - > doUpdate ( ) ;
_vm - > _system - > updateScreen ( ) ;
2007-09-06 20:51:40 +00:00
}
}
2007-09-06 23:45:32 +00:00
void Winnie : : keyHelp ( ) {
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_KEYHELP ) ;
2007-09-06 23:45:32 +00:00
_vm - > printStr ( IDS_WTP_HELP_0 ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-06 23:45:32 +00:00
_vm - > printStr ( IDS_WTP_HELP_1 ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-06 23:45:32 +00:00
}
void Winnie : : inventory ( ) {
char szMissing [ 41 ] = { 0 } ;
2007-09-23 17:00:35 +00:00
if ( _game . iObjHave )
printObjStr ( _game . iObjHave , IDI_WTP_OBJ_TAKE ) ;
2007-09-06 23:45:32 +00:00
else {
_vm - > clearTextArea ( ) ;
_vm - > drawStr ( IDI_WTP_ROW_MENU , IDI_WTP_COL_MENU , IDA_DEFAULT , IDS_WTP_INVENTORY_0 ) ;
}
2007-09-23 17:00:35 +00:00
sprintf ( szMissing , IDS_WTP_INVENTORY_1 , _game . nObjMiss ) ;
2007-09-06 23:45:32 +00:00
_vm - > drawStr ( IDI_WTP_ROW_OPTION_4 , IDI_WTP_COL_MENU , IDA_DEFAULT , szMissing ) ;
2007-09-24 01:46:42 +00:00
_vm - > _gfx - > doUpdate ( ) ;
_vm - > _system - > updateScreen ( ) ; //TODO: Move to game's main loop
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-06 23:45:32 +00:00
}
void Winnie : : printObjStr ( int iObj , int iStr ) {
WTP_OBJ_HDR hdr ;
uint8 * buffer = ( uint8 * ) malloc ( 2048 ) ;
2007-09-20 21:55:37 +00:00
readObj ( iObj , buffer ) ;
2007-09-23 12:25:44 +00:00
parseObjHeader ( & hdr , buffer , sizeof ( hdr ) ) ;
2008-01-11 09:52:06 +00:00
printStrWinnie ( ( char * ) ( buffer + hdr . ofsStr [ iStr ] - _objOffset ) ) ;
2007-09-06 23:45:32 +00:00
free ( buffer ) ;
}
2007-09-07 20:09:00 +00:00
bool Winnie : : isRightObj ( int iRoom , int iObj , int * iCode ) {
WTP_ROOM_HDR roomhdr ;
WTP_OBJ_HDR objhdr ;
2007-09-19 22:29:14 +00:00
uint8 * roomdata = ( uint8 * ) malloc ( 4096 ) ;
uint8 * objdata = ( uint8 * ) malloc ( 2048 ) ;
2007-09-07 20:09:00 +00:00
2007-09-23 00:12:07 +00:00
readRoom ( iRoom , roomdata , roomhdr ) ;
2007-09-20 21:55:37 +00:00
readObj ( iObj , objdata ) ;
2007-09-23 12:25:44 +00:00
parseObjHeader ( & objhdr , objdata , sizeof ( WTP_OBJ_HDR ) ) ;
2007-09-07 20:09:00 +00:00
2007-09-19 22:29:14 +00:00
free ( roomdata ) ;
free ( objdata ) ;
2007-09-07 20:09:00 +00:00
* iCode = objhdr . objId ;
if ( objhdr . objId = = 11 ) objhdr . objId = 34 ;
if ( roomhdr . objId = = objhdr . objId )
return true ;
else
return false ;
}
void Winnie : : takeObj ( int iRoom ) {
2007-09-23 17:00:35 +00:00
if ( _game . iObjHave ) {
2007-09-07 20:09:00 +00:00
// player is already carrying an object, can't take
_vm - > printStr ( IDS_WTP_CANT_TAKE ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
} else {
// take object
int iObj = getObjInRoom ( iRoom ) ;
2007-09-23 17:00:35 +00:00
_game . iObjHave = iObj ;
_game . iObjRoom [ iObj ] = 0 ;
2007-09-07 20:09:00 +00:00
_vm - > printStr ( IDS_WTP_OK ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_TAKE ) ;
2007-09-07 20:09:00 +00:00
drawRoomPic ( ) ;
// print object "take" string
2007-09-23 17:00:35 +00:00
printObjStr ( _game . iObjHave , IDI_WTP_OBJ_TAKE ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
// HACK WARNING
if ( iObj = = 18 ) {
2007-09-23 17:00:35 +00:00
_game . fGame [ 0x0d ] = 1 ;
2007-09-07 20:09:00 +00:00
}
}
}
void Winnie : : dropObj ( int iRoom ) {
int iCode ;
if ( getObjInRoom ( iRoom ) ) {
// there already is an object in the room, can't drop
_vm - > printStr ( IDS_WTP_CANT_DROP ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
} else {
// HACK WARNING
2007-09-23 17:00:35 +00:00
if ( _game . iObjHave = = 18 ) {
_game . fGame [ 0x0d ] = 0 ;
2007-09-07 20:09:00 +00:00
}
2007-09-23 17:00:35 +00:00
if ( isRightObj ( iRoom , _game . iObjHave , & iCode ) ) {
2007-09-07 20:09:00 +00:00
// object has been dropped in the right place
_vm - > printStr ( IDS_WTP_OK ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_DROP_OK ) ;
2007-09-23 17:00:35 +00:00
printObjStr ( _game . iObjHave , IDI_WTP_OBJ_DROP ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
// increase amount of objects returned, decrease amount of objects missing
2007-09-23 17:00:35 +00:00
_game . nObjMiss - - ;
_game . nObjRet + + ;
2008-01-27 19:47:41 +00:00
2007-09-07 20:09:00 +00:00
// xor the dropped object with 0x80 to signify it has been dropped in the right place
for ( int i = 0 ; i < IDI_WTP_MAX_OBJ_MISSING ; i + + ) {
2007-09-23 17:00:35 +00:00
if ( _game . iUsedObj [ i ] = = _game . iObjHave ) {
_game . iUsedObj [ i ] ^ = 0x80 ;
2007-09-07 20:09:00 +00:00
break ;
}
}
// set flag according to dropped object's id
2007-09-23 17:00:35 +00:00
_game . fGame [ iCode ] = 1 ;
2008-01-27 19:47:41 +00:00
2007-09-07 20:09:00 +00:00
// player is carrying nothing
2007-09-23 17:00:35 +00:00
_game . iObjHave = 0 ;
2008-01-27 19:47:41 +00:00
2007-09-23 17:00:35 +00:00
if ( ! _game . nObjMiss ) {
2007-09-07 20:09:00 +00:00
// all objects returned, tell player to find party
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_FANFARE ) ;
2007-09-07 20:09:00 +00:00
_vm - > printStr ( IDS_WTP_GAME_OVER_0 ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
_vm - > printStr ( IDS_WTP_GAME_OVER_1 ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
}
} else {
// drop object in the given room
2007-09-23 17:00:35 +00:00
_game . iObjRoom [ _game . iObjHave ] = iRoom ;
2007-09-07 20:09:00 +00:00
// object has been dropped in the wrong place
_vm - > printStr ( IDS_WTP_WRONG_PLACE ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_DROP ) ;
2007-09-07 20:09:00 +00:00
drawRoomPic ( ) ;
_vm - > printStr ( IDS_WTP_WRONG_PLACE ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
// print object description
2007-09-23 17:00:35 +00:00
printObjStr ( _game . iObjHave , IDI_WTP_OBJ_DESC ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
2007-09-23 17:00:35 +00:00
_game . iObjHave = 0 ;
2007-09-07 20:09:00 +00:00
}
}
}
2007-09-07 20:47:31 +00:00
void Winnie : : dropObjRnd ( ) {
2007-09-23 17:00:35 +00:00
if ( ! _game . iObjHave )
2007-09-07 20:47:31 +00:00
return ;
2008-01-27 19:47:41 +00:00
2007-09-09 15:28:26 +00:00
int iRoom = 0 ;
2007-09-07 20:47:31 +00:00
bool done = false ;
while ( ! done ) {
iRoom = _vm - > rnd ( IDI_WTP_MAX_ROOM_NORMAL ) ;
done = true ;
2007-09-23 17:00:35 +00:00
if ( iRoom = = _room )
2007-09-07 20:47:31 +00:00
done = false ;
for ( int j = 0 ; j < IDI_WTP_MAX_ROOM_OBJ ; j + + ) {
2007-09-23 17:00:35 +00:00
if ( _game . iObjRoom [ j ] = = iRoom ) {
2007-09-07 20:47:31 +00:00
done = false ;
}
}
}
2007-09-23 17:00:35 +00:00
_game . iObjRoom [ _game . iObjHave ] = iRoom ;
_game . iObjHave = 0 ;
2007-09-07 20:47:31 +00:00
}
void Winnie : : wind ( ) {
2007-09-09 15:28:26 +00:00
int iRoom = 0 ;
2007-09-07 20:47:31 +00:00
bool done ;
2007-09-23 17:00:35 +00:00
_doWind = 0 ;
_game . nMoves = 0 ;
if ( ! _game . nObjMiss )
2007-09-07 20:47:31 +00:00
return ;
_vm - > printStr ( IDS_WTP_WIND_0 ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_WIND_0 ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:47:31 +00:00
_vm - > printStr ( IDS_WTP_WIND_1 ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_WIND_0 ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:47:31 +00:00
dropObjRnd ( ) ;
// randomize positions of objects at large
for ( int i = 0 ; i < IDI_WTP_MAX_OBJ_MISSING ; i + + ) {
2007-09-23 17:00:35 +00:00
if ( ! ( _game . iUsedObj [ i ] & IDI_XOR_KEY ) ) {
2007-09-07 20:47:31 +00:00
done = false ;
while ( ! done ) {
iRoom = _vm - > rnd ( IDI_WTP_MAX_ROOM_NORMAL ) ;
done = true ;
for ( int j = 0 ; j < IDI_WTP_MAX_ROOM_OBJ ; j + + ) {
2007-09-23 17:00:35 +00:00
if ( _game . iObjRoom [ j ] = = iRoom ) {
2007-09-07 20:47:31 +00:00
done = false ;
}
}
}
2007-09-23 17:00:35 +00:00
_game . iObjRoom [ _game . iUsedObj [ i ] ] = iRoom ;
2007-09-07 20:47:31 +00:00
}
}
}
2007-09-23 15:09:48 +00:00
void Winnie : : mist ( ) {
// mist length in turns is (2-5)
_mist = _vm - > rnd ( 4 ) + 2 ;
2007-09-23 17:00:35 +00:00
_room = IDI_WTP_ROOM_MIST ;
2007-09-23 15:09:48 +00:00
drawRoomPic ( ) ;
_vm - > printStr ( IDS_WTP_MIST ) ;
}
void Winnie : : tigger ( ) {
2007-09-23 17:00:35 +00:00
_room = IDI_WTP_ROOM_TIGGER ;
2007-09-23 15:09:48 +00:00
drawRoomPic ( ) ;
_vm - > printStr ( IDS_WTP_TIGGER ) ;
dropObjRnd ( ) ;
}
2007-09-07 20:47:31 +00:00
void Winnie : : showOwlHelp ( ) {
2007-09-23 17:00:35 +00:00
if ( _game . iObjHave ) {
2007-09-07 20:47:31 +00:00
_vm - > printStr ( IDS_WTP_OWL_0 ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-23 17:00:35 +00:00
printObjStr ( _game . iObjHave , IDI_WTP_OBJ_HELP ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:47:31 +00:00
}
2007-09-23 17:00:35 +00:00
if ( getObjInRoom ( _room ) ) {
2007-09-07 20:47:31 +00:00
_vm - > printStr ( IDS_WTP_OWL_0 ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-23 17:00:35 +00:00
printObjStr ( getObjInRoom ( _room ) , IDI_WTP_OBJ_HELP ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:47:31 +00:00
}
}
2007-09-06 20:51:40 +00:00
void Winnie : : drawMenu ( char * szMenu , int iSel , int fCanSel [ ] ) {
int iRow = 0 , iCol = 0 ;
_vm - > clearTextArea ( ) ;
_vm - > drawStr ( IDI_WTP_ROW_MENU , IDI_WTP_COL_MENU , IDA_DEFAULT , szMenu ) ;
if ( fCanSel [ IDI_WTP_SEL_NORTH ] )
_vm - > drawStr ( IDI_WTP_ROW_OPTION_4 , IDI_WTP_COL_NSEW , IDA_DEFAULT , IDS_WTP_NSEW ) ;
if ( fCanSel [ IDI_WTP_SEL_TAKE ] )
_vm - > drawStr ( IDI_WTP_ROW_OPTION_4 , IDI_WTP_COL_TAKE , IDA_DEFAULT , IDS_WTP_TAKE ) ;
if ( fCanSel [ IDI_WTP_SEL_DROP ] )
_vm - > drawStr ( IDI_WTP_ROW_OPTION_4 , IDI_WTP_COL_DROP , IDA_DEFAULT , IDS_WTP_DROP ) ;
2008-01-27 19:47:41 +00:00
2007-09-06 20:51:40 +00:00
switch ( iSel ) {
case IDI_WTP_SEL_OPT_1 :
case IDI_WTP_SEL_OPT_2 :
case IDI_WTP_SEL_OPT_3 :
2008-01-11 10:59:43 +00:00
iRow = IDI_WTP_ROW_OPTION_1 + iSel ;
2007-09-06 20:51:40 +00:00
iCol = IDI_WTP_COL_OPTION ;
break ;
case IDI_WTP_SEL_NORTH :
iRow = IDI_WTP_ROW_OPTION_4 ;
iCol = IDI_WTP_COL_NORTH ;
break ;
case IDI_WTP_SEL_SOUTH :
iRow = IDI_WTP_ROW_OPTION_4 ;
iCol = IDI_WTP_COL_SOUTH ;
break ;
case IDI_WTP_SEL_EAST :
iRow = IDI_WTP_ROW_OPTION_4 ;
iCol = IDI_WTP_COL_EAST ;
break ;
case IDI_WTP_SEL_WEST :
iRow = IDI_WTP_ROW_OPTION_4 ;
iCol = IDI_WTP_COL_WEST ;
break ;
case IDI_WTP_SEL_TAKE :
iRow = IDI_WTP_ROW_OPTION_4 ;
iCol = IDI_WTP_COL_TAKE ;
break ;
case IDI_WTP_SEL_DROP :
iRow = IDI_WTP_ROW_OPTION_4 ;
iCol = IDI_WTP_COL_DROP ;
break ;
}
2008-01-11 10:59:43 +00:00
_vm - > drawStr ( iRow , iCol - 1 , IDA_DEFAULT , " > " ) ;
2007-09-06 20:51:40 +00:00
_vm - > _gfx - > doUpdate ( ) ;
2007-09-20 22:15:09 +00:00
_vm - > _system - > updateScreen ( ) ; //TODO: Move to game's main loop
2007-09-06 20:51:40 +00:00
}
void Winnie : : incMenuSel ( int * iSel , int fCanSel [ ] ) {
do {
* iSel + = 1 ;
if ( * iSel > IDI_WTP_SEL_DROP ) * iSel = IDI_WTP_SEL_OPT_1 ;
2007-09-18 20:16:33 +00:00
} while ( ! fCanSel [ * iSel ] ) ;
2007-09-06 20:51:40 +00:00
}
void Winnie : : decMenuSel ( int * iSel , int fCanSel [ ] ) {
do {
* iSel - = 1 ;
if ( * iSel < IDI_WTP_SEL_OPT_1 ) * iSel = IDI_WTP_SEL_DROP ;
2007-09-18 20:16:33 +00:00
} while ( ! fCanSel [ * iSel ] ) ;
2007-09-06 20:51:40 +00:00
}
2007-09-07 20:30:10 +00:00
void Winnie : : getMenuMouseSel ( int * iSel , int fCanSel [ ] , int x , int y ) {
switch ( y ) {
case IDI_WTP_ROW_OPTION_1 :
case IDI_WTP_ROW_OPTION_2 :
case IDI_WTP_ROW_OPTION_3 :
2008-01-11 10:59:43 +00:00
if ( fCanSel [ y - IDI_WTP_ROW_OPTION_1 ] ) * iSel = y - IDI_WTP_ROW_OPTION_1 ;
2007-09-07 20:30:10 +00:00
break ;
case IDI_WTP_ROW_OPTION_4 :
if ( fCanSel [ IDI_WTP_SEL_NORTH ] & & ( x > IDI_WTP_COL_NORTH - 1 ) & & ( x < 6 ) ) * iSel = IDI_WTP_SEL_NORTH ;
if ( fCanSel [ IDI_WTP_SEL_SOUTH ] & & ( x > IDI_WTP_COL_SOUTH - 1 ) & & ( x < 13 ) ) * iSel = IDI_WTP_SEL_SOUTH ;
if ( fCanSel [ IDI_WTP_SEL_EAST ] & & ( x > IDI_WTP_COL_EAST - 1 ) & & ( x < 19 ) ) * iSel = IDI_WTP_SEL_EAST ;
if ( fCanSel [ IDI_WTP_SEL_WEST ] & & ( x > IDI_WTP_COL_WEST - 1 ) & & ( x < 25 ) ) * iSel = IDI_WTP_SEL_WEST ;
if ( fCanSel [ IDI_WTP_SEL_TAKE ] & & ( x > IDI_WTP_COL_TAKE - 1 ) & & ( x < 33 ) ) * iSel = IDI_WTP_SEL_TAKE ;
if ( fCanSel [ IDI_WTP_SEL_DROP ] & & ( x > IDI_WTP_COL_DROP - 1 ) & & ( x < 39 ) ) * iSel = IDI_WTP_SEL_DROP ;
break ;
}
}
2007-09-06 20:51:40 +00:00
# define makeSel() {\
if ( fCanSel [ * iSel ] ) { \
return ; \
} else { \
keyHelp ( ) ; \
clrMenuSel ( iSel , fCanSel ) ; \
} \
}
void Winnie : : getMenuSel ( char * szMenu , int * iSel , int fCanSel [ ] ) {
2007-09-07 16:22:31 +00:00
Common : : Event event ;
2007-09-06 20:51:40 +00:00
int x , y ;
clrMenuSel ( iSel , fCanSel ) ;
drawMenu ( szMenu , * iSel , fCanSel ) ;
2007-09-07 16:22:31 +00:00
// Show the mouse cursor for the menu
CursorMan . showMouse ( true ) ;
2008-09-30 12:27:38 +00:00
while ( ! _vm - > shouldQuit ( ) ) {
2007-09-07 16:22:31 +00:00
while ( _vm - > _system - > getEventManager ( ) - > pollEvent ( event ) ) {
switch ( event . type ) {
2008-07-16 04:22:56 +00:00
case Common : : EVENT_RTL :
2007-09-06 20:51:40 +00:00
case Common : : EVENT_QUIT :
2008-07-08 01:33:57 +00:00
return ;
2007-09-06 20:51:40 +00:00
case Common : : EVENT_MOUSEMOVE :
2007-09-09 15:33:00 +00:00
x = event . mouse . x / 8 ;
y = event . mouse . y / 8 ;
2007-09-07 20:30:10 +00:00
getMenuMouseSel ( iSel , fCanSel , x , y ) ;
2007-09-07 16:22:31 +00:00
// Change cursor
2008-01-11 09:52:06 +00:00
if ( fCanSel [ IDI_WTP_SEL_NORTH ] & & hotspotNorth . contains ( event . mouse . x , event . mouse . y ) ) {
2007-09-07 16:22:31 +00:00
_vm - > _gfx - > setCursorPalette ( true ) ;
2008-01-11 09:52:06 +00:00
} else if ( fCanSel [ IDI_WTP_SEL_SOUTH ] & & hotspotSouth . contains ( event . mouse . x , event . mouse . y ) ) {
2008-01-27 19:47:41 +00:00
_vm - > _gfx - > setCursorPalette ( true ) ;
2008-01-11 09:52:06 +00:00
} else if ( fCanSel [ IDI_WTP_SEL_WEST ] & & hotspotWest . contains ( event . mouse . x , event . mouse . y ) ) {
2007-09-07 16:22:31 +00:00
_vm - > _gfx - > setCursorPalette ( true ) ;
2008-01-11 09:52:06 +00:00
} else if ( fCanSel [ IDI_WTP_SEL_EAST ] & & hotspotEast . contains ( event . mouse . x , event . mouse . y ) ) {
2007-09-07 16:22:31 +00:00
_vm - > _gfx - > setCursorPalette ( true ) ;
} else {
_vm - > _gfx - > setCursorPalette ( false ) ;
}
2007-09-06 20:51:40 +00:00
break ;
case Common : : EVENT_LBUTTONUP :
2007-09-09 23:13:35 +00:00
// Click to move
2008-01-11 09:52:06 +00:00
if ( fCanSel [ IDI_WTP_SEL_NORTH ] & & hotspotNorth . contains ( event . mouse . x , event . mouse . y ) ) {
2007-09-09 23:13:35 +00:00
* iSel = IDI_WTP_SEL_NORTH ;
makeSel ( ) ;
_vm - > _gfx - > setCursorPalette ( false ) ;
return ;
2008-01-11 09:52:06 +00:00
} else if ( fCanSel [ IDI_WTP_SEL_SOUTH ] & & hotspotSouth . contains ( event . mouse . x , event . mouse . y ) ) {
2007-09-09 23:13:35 +00:00
* iSel = IDI_WTP_SEL_SOUTH ;
makeSel ( ) ;
_vm - > _gfx - > setCursorPalette ( false ) ;
return ;
2008-01-11 09:52:06 +00:00
} else if ( fCanSel [ IDI_WTP_SEL_WEST ] & & hotspotWest . contains ( event . mouse . x , event . mouse . y ) ) {
2007-09-09 23:13:35 +00:00
* iSel = IDI_WTP_SEL_WEST ;
makeSel ( ) ;
_vm - > _gfx - > setCursorPalette ( false ) ;
return ;
2008-01-11 09:52:06 +00:00
} else if ( fCanSel [ IDI_WTP_SEL_EAST ] & & hotspotEast . contains ( event . mouse . x , event . mouse . y ) ) {
2007-09-09 23:13:35 +00:00
* iSel = IDI_WTP_SEL_EAST ;
makeSel ( ) ;
_vm - > _gfx - > setCursorPalette ( false ) ;
return ;
} else {
_vm - > _gfx - > setCursorPalette ( false ) ;
}
2007-09-06 20:51:40 +00:00
switch ( * iSel ) {
case IDI_WTP_SEL_OPT_1 :
case IDI_WTP_SEL_OPT_2 :
case IDI_WTP_SEL_OPT_3 :
for ( int iSel2 = 0 ; iSel2 < IDI_WTP_MAX_OPTION ; iSel2 + + ) {
if ( * iSel = = ( fCanSel [ iSel2 + IDI_WTP_SEL_REAL_OPT_1 ] - 1 ) ) {
* iSel = iSel2 ;
2007-09-07 16:22:31 +00:00
// Menu selection made, hide the mouse cursor
CursorMan . showMouse ( false ) ;
2007-09-06 20:51:40 +00:00
return ;
}
}
break ;
default :
if ( fCanSel [ * iSel ] ) {
2007-09-07 16:22:31 +00:00
// Menu selection made, hide the mouse cursor
CursorMan . showMouse ( false ) ;
2007-09-06 20:51:40 +00:00
return ;
}
break ;
}
break ;
case Common : : EVENT_RBUTTONUP :
* iSel = IDI_WTP_SEL_BACK ;
2007-09-07 16:22:31 +00:00
// Menu selection made, hide the mouse cursor
CursorMan . showMouse ( false ) ;
2007-09-06 20:51:40 +00:00
return ;
case Common : : EVENT_WHEELUP :
decMenuSel ( iSel , fCanSel ) ;
break ;
case Common : : EVENT_WHEELDOWN :
incMenuSel ( iSel , fCanSel ) ;
break ;
case Common : : EVENT_KEYDOWN :
2007-10-13 23:48:59 +00:00
if ( event . kbd . keycode = = Common : : KEYCODE_d & & ( event . kbd . flags & Common : : KBD_CTRL ) & & _vm - > _console ) {
_vm - > _console - > attach ( ) ;
_vm - > _console - > onFrame ( ) ;
continue ;
}
2007-09-07 16:22:31 +00:00
switch ( event . kbd . keycode ) {
2007-09-06 20:51:40 +00:00
case Common : : KEYCODE_ESCAPE :
* iSel = IDI_WTP_SEL_HOME ;
2007-09-07 16:22:31 +00:00
// Menu selection made, hide the mouse cursor
CursorMan . showMouse ( false ) ;
2007-09-06 20:51:40 +00:00
return ;
case Common : : KEYCODE_BACKSPACE :
* iSel = IDI_WTP_SEL_BACK ;
2007-09-07 16:22:31 +00:00
// Menu selection made, hide the mouse cursor
CursorMan . showMouse ( false ) ;
2007-09-06 20:51:40 +00:00
return ;
case Common : : KEYCODE_c :
2007-09-06 23:45:32 +00:00
inventory ( ) ;
2007-09-06 20:51:40 +00:00
break ;
case Common : : KEYCODE_SPACE :
case Common : : KEYCODE_RIGHT :
case Common : : KEYCODE_DOWN :
incMenuSel ( iSel , fCanSel ) ;
break ;
case Common : : KEYCODE_LEFT :
case Common : : KEYCODE_UP :
decMenuSel ( iSel , fCanSel ) ;
break ;
case Common : : KEYCODE_1 :
case Common : : KEYCODE_2 :
case Common : : KEYCODE_3 :
2007-09-07 16:22:31 +00:00
* iSel = event . kbd . keycode - Common : : KEYCODE_1 ;
2007-09-06 20:51:40 +00:00
if ( fCanSel [ * iSel + IDI_WTP_SEL_REAL_OPT_1 ] ) {
2007-09-07 16:22:31 +00:00
// Menu selection made, hide the mouse cursor
CursorMan . showMouse ( false ) ;
2007-09-06 20:51:40 +00:00
return ;
} else {
2007-09-06 23:45:32 +00:00
keyHelp ( ) ;
2007-09-06 20:51:40 +00:00
clrMenuSel ( iSel , fCanSel ) ;
}
break ;
case Common : : KEYCODE_n :
* iSel = IDI_WTP_SEL_NORTH ;
makeSel ( ) ;
break ;
case Common : : KEYCODE_s :
2007-09-07 16:22:31 +00:00
if ( event . kbd . flags & Common : : KBD_CTRL ) {
2007-09-19 08:27:32 +00:00
_vm - > flipflag ( fSoundOn ) ;
2007-09-06 20:51:40 +00:00
} else {
* iSel = IDI_WTP_SEL_SOUTH ;
makeSel ( ) ;
}
break ;
case Common : : KEYCODE_e :
* iSel = IDI_WTP_SEL_EAST ;
makeSel ( ) ;
break ;
case Common : : KEYCODE_w :
* iSel = IDI_WTP_SEL_WEST ;
makeSel ( ) ;
break ;
case Common : : KEYCODE_t :
* iSel = IDI_WTP_SEL_TAKE ;
makeSel ( ) ;
break ;
case Common : : KEYCODE_d :
* iSel = IDI_WTP_SEL_DROP ;
makeSel ( ) ;
break ;
case Common : : KEYCODE_RETURN :
switch ( * iSel ) {
case IDI_WTP_SEL_OPT_1 :
case IDI_WTP_SEL_OPT_2 :
case IDI_WTP_SEL_OPT_3 :
for ( int iSel2 = 0 ; iSel2 < IDI_WTP_MAX_OPTION ; iSel2 + + ) {
if ( * iSel = = ( fCanSel [ iSel2 + IDI_WTP_SEL_REAL_OPT_1 ] - 1 ) ) {
* iSel = iSel2 ;
2007-09-07 16:22:31 +00:00
// Menu selection made, hide the mouse cursor
CursorMan . showMouse ( false ) ;
2007-09-06 20:51:40 +00:00
return ;
}
}
break ;
default :
if ( fCanSel [ * iSel ] ) {
2007-09-07 16:22:31 +00:00
// Menu selection made, hide the mouse cursor
CursorMan . showMouse ( false ) ;
2007-09-06 20:51:40 +00:00
return ;
}
break ;
}
2008-01-27 19:47:41 +00:00
default :
2008-01-11 10:20:31 +00:00
if ( ! event . kbd . flags ) { // if the control/alt/shift keys are not pressed
2007-10-13 23:48:59 +00:00
keyHelp ( ) ;
clrMenuSel ( iSel , fCanSel ) ;
}
2007-09-06 20:51:40 +00:00
break ;
}
break ;
default :
break ;
}
drawMenu ( szMenu , * iSel , fCanSel ) ;
}
}
}
void Winnie : : gameLoop ( ) {
WTP_ROOM_HDR hdr ;
2007-09-19 22:29:14 +00:00
uint8 * roomdata = ( uint8 * ) malloc ( 4096 ) ;
2007-09-06 20:51:40 +00:00
int iBlock ;
phase0 :
2007-09-23 17:00:35 +00:00
if ( ! _game . nObjMiss & & ( _room = = IDI_WTP_ROOM_PICNIC ) )
_room = IDI_WTP_ROOM_PARTY ;
readRoom ( _room , roomdata , hdr ) ;
2007-09-06 20:51:40 +00:00
drawRoomPic ( ) ;
2007-09-20 22:15:09 +00:00
_vm - > _gfx - > doUpdate ( ) ;
_vm - > _system - > updateScreen ( ) ;
2007-09-06 20:51:40 +00:00
phase1 :
2007-09-23 17:00:35 +00:00
if ( getObjInRoom ( _room ) ) {
printObjStr ( getObjInRoom ( _room ) , IDI_WTP_OBJ_DESC ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-06 20:51:40 +00:00
}
phase2 :
for ( iBlock = 0 ; iBlock < IDI_WTP_MAX_BLOCK ; iBlock + + ) {
2008-01-11 09:52:06 +00:00
if ( parser ( hdr . ofsDesc [ iBlock ] - _roomOffset , iBlock , roomdata ) = = IDI_WTP_PAR_BACK )
goto phase1 ;
2007-09-06 20:51:40 +00:00
}
2008-09-30 12:27:38 +00:00
while ( ! _vm - > shouldQuit ( ) ) {
2007-09-06 20:51:40 +00:00
for ( iBlock = 0 ; iBlock < IDI_WTP_MAX_BLOCK ; iBlock + + ) {
2008-01-11 09:52:06 +00:00
switch ( parser ( hdr . ofsBlock [ iBlock ] - _roomOffset , iBlock , roomdata ) ) {
case IDI_WTP_PAR_GOTO :
goto phase0 ;
break ;
case IDI_WTP_PAR_BACK :
goto phase2 ;
break ;
2007-09-06 20:51:40 +00:00
}
}
}
2007-09-20 21:55:37 +00:00
free ( roomdata ) ;
2007-09-06 20:51:40 +00:00
}
2007-09-06 10:48:00 +00:00
void Winnie : : drawPic ( const char * szName ) {
char szFile [ 256 ] = { 0 } ;
2008-01-11 10:59:43 +00:00
Common : : File file ;
2007-09-19 22:29:14 +00:00
uint8 * buffer = ( uint8 * ) malloc ( 4096 ) ;
2007-09-06 10:48:00 +00:00
// construct filename
2007-09-24 19:37:57 +00:00
if ( _vm - > getPlatform ( ) ! = Common : : kPlatformAmiga )
2007-09-22 20:16:24 +00:00
sprintf ( szFile , " %s.pic " , szName ) ;
else
strcpy ( szFile , szName ) ;
if ( ! file . open ( szFile ) ) {
warning ( " Could not open file \' %s \' " , szFile ) ;
2007-09-11 20:09:39 +00:00
return ;
2007-09-22 17:56:23 +00:00
}
2007-09-11 20:09:39 +00:00
uint32 size = file . size ( ) ;
file . read ( buffer , size ) ;
file . close ( ) ;
2007-09-06 10:48:00 +00:00
2007-09-11 20:09:39 +00:00
_vm - > _picture - > decodePicture ( buffer , size , 1 , IDI_WTP_PIC_WIDTH , IDI_WTP_PIC_HEIGHT ) ;
2007-09-06 10:48:00 +00:00
_vm - > _picture - > showPic ( IDI_WTP_PIC_X0 , IDI_WTP_PIC_Y0 , IDI_WTP_PIC_WIDTH , IDI_WTP_PIC_HEIGHT ) ;
2007-09-20 21:55:37 +00:00
free ( buffer ) ;
2007-09-06 10:48:00 +00:00
}
2007-09-07 20:09:00 +00:00
void Winnie : : drawObjPic ( int iObj , int x0 , int y0 ) {
if ( ! iObj )
return ;
2008-01-11 10:59:43 +00:00
WTP_OBJ_HDR objhdr ;
uint8 * buffer = ( uint8 * ) malloc ( 2048 ) ;
2007-09-20 21:55:37 +00:00
uint32 objSize = readObj ( iObj , buffer ) ;
2007-09-23 12:25:44 +00:00
parseObjHeader ( & objhdr , buffer , sizeof ( WTP_OBJ_HDR ) ) ;
2008-01-27 19:47:41 +00:00
2007-09-07 20:09:00 +00:00
_vm - > _picture - > setOffset ( x0 , y0 ) ;
2008-01-11 09:52:06 +00:00
_vm - > _picture - > decodePicture ( buffer + objhdr . ofsPic - _objOffset , objSize , 0 , IDI_WTP_PIC_WIDTH , IDI_WTP_PIC_HEIGHT ) ;
2007-09-07 20:09:00 +00:00
_vm - > _picture - > setOffset ( 0 , 0 ) ;
_vm - > _picture - > showPic ( 10 , 0 , IDI_WTP_PIC_WIDTH , IDI_WTP_PIC_HEIGHT ) ;
2007-09-20 21:55:37 +00:00
free ( buffer ) ;
2007-09-07 20:09:00 +00:00
}
2007-09-06 20:51:40 +00:00
void Winnie : : drawRoomPic ( ) {
WTP_ROOM_HDR roomhdr ;
2007-09-19 22:29:14 +00:00
uint8 * buffer = ( uint8 * ) malloc ( 4096 ) ;
2007-09-23 17:00:35 +00:00
int iObj = getObjInRoom ( _room ) ;
2007-09-06 20:51:40 +00:00
// clear gfx screen
_vm - > _gfx - > clearScreen ( 0 ) ;
// read room picture
2007-09-23 17:00:35 +00:00
readRoom ( _room , buffer , roomhdr ) ;
2007-09-06 20:51:40 +00:00
// draw room picture
2008-01-11 09:52:06 +00:00
_vm - > _picture - > decodePicture ( buffer + roomhdr . ofsPic - _roomOffset , 4096 , 1 , IDI_WTP_PIC_WIDTH , IDI_WTP_PIC_HEIGHT ) ;
2007-09-06 20:51:40 +00:00
_vm - > _picture - > showPic ( IDI_WTP_PIC_X0 , IDI_WTP_PIC_Y0 , IDI_WTP_PIC_WIDTH , IDI_WTP_PIC_HEIGHT ) ;
// draw object picture
2007-09-24 23:28:23 +00:00
drawObjPic ( iObj , IDI_WTP_PIC_X0 + roomhdr . objX , IDI_WTP_PIC_Y0 + roomhdr . objY ) ;
2007-09-06 20:51:40 +00:00
2007-09-20 21:55:37 +00:00
free ( buffer ) ;
2007-09-06 20:51:40 +00:00
}
2007-09-20 22:05:37 +00:00
bool Winnie : : playSound ( ENUM_WTP_SOUND iSound ) {
//TODO
warning ( " STUB: playSound(%d) " , iSound ) ;
return 1 ;
}
2007-09-06 20:51:40 +00:00
void Winnie : : clrMenuSel ( int * iSel , int fCanSel [ ] ) {
* iSel = IDI_WTP_SEL_OPT_1 ;
2007-09-18 20:16:33 +00:00
while ( ! fCanSel [ * iSel ] ) {
2007-09-06 20:51:40 +00:00
* iSel + = 1 ;
}
2008-01-11 09:52:06 +00:00
_vm - > _gfx - > setCursorPalette ( false ) ;
2007-09-06 10:48:00 +00:00
}
2007-09-06 21:48:33 +00:00
void Winnie : : printRoomStr ( int iRoom , int iStr ) {
WTP_ROOM_HDR hdr ;
uint8 * buffer = ( uint8 * ) malloc ( 4096 ) ;
2007-09-23 00:12:07 +00:00
readRoom ( iRoom , buffer , hdr ) ;
2008-01-11 09:52:06 +00:00
printStrWinnie ( ( char * ) ( buffer + hdr . ofsStr [ iStr - 1 ] - _roomOffset ) ) ;
2007-09-06 21:48:33 +00:00
free ( buffer ) ;
}
2007-09-07 20:30:10 +00:00
void Winnie : : gameOver ( ) {
// sing the Pooh song forever
for ( ; ; ) {
_vm - > printStr ( IDS_WTP_SONG_0 ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_POOH_0 ) ;
2007-09-07 20:30:10 +00:00
_vm - > printStr ( IDS_WTP_SONG_1 ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_POOH_1 ) ;
2007-09-07 20:30:10 +00:00
_vm - > printStr ( IDS_WTP_SONG_2 ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_POOH_2 ) ;
2007-09-19 09:54:42 +00:00
_vm - > getSelection ( kSelAnyKey ) ;
2007-09-07 20:30:10 +00:00
}
}
void Winnie : : saveGame ( ) {
2007-09-23 16:32:03 +00:00
Common : : OutSaveFile * outfile ;
char szFile [ 256 ] = { 0 } ;
2007-12-08 18:25:00 +00:00
int i = 0 ;
2007-09-23 16:32:03 +00:00
sprintf ( szFile , IDS_WTP_FILE_SAVEGAME ) ;
if ( ! ( outfile = _vm - > getSaveFileMan ( ) - > openForSaving ( szFile ) ) )
return ;
2007-12-08 18:25:00 +00:00
outfile - > writeUint32BE ( MKID_BE ( ' WINN ' ) ) ; // header
outfile - > writeByte ( WTP_SAVEGAME_VERSION ) ;
outfile - > writeByte ( _game . fSound ) ;
outfile - > writeByte ( _game . nMoves ) ;
outfile - > writeByte ( _game . nObjMiss ) ;
outfile - > writeByte ( _game . nObjRet ) ;
outfile - > writeByte ( _game . iObjHave ) ;
for ( i = 0 ; i < IDI_WTP_MAX_FLAG ; i + + )
outfile - > writeByte ( _game . fGame [ i ] ) ;
for ( i = 0 ; i < IDI_WTP_MAX_OBJ_MISSING ; i + + )
outfile - > writeByte ( _game . iUsedObj [ i ] ) ;
for ( i = 0 ; i < IDI_WTP_MAX_ROOM_OBJ ; i + + )
outfile - > writeByte ( _game . iObjRoom [ i ] ) ;
outfile - > finalize ( ) ;
if ( outfile - > ioFailed ( ) )
warning ( " Can't write file '%s'. (Disk full?) " , szFile ) ;
delete outfile ;
2007-09-07 20:30:10 +00:00
}
void Winnie : : loadGame ( ) {
Common : : InSaveFile * infile ;
char szFile [ 256 ] = { 0 } ;
2007-12-08 18:25:00 +00:00
int saveVersion = 0 ;
int i = 0 ;
2007-09-23 16:32:03 +00:00
2007-09-07 20:30:10 +00:00
sprintf ( szFile , IDS_WTP_FILE_SAVEGAME ) ;
if ( ! ( infile = _vm - > getSaveFileMan ( ) - > openForLoading ( szFile ) ) )
return ;
2007-12-10 18:57:17 +00:00
if ( infile - > readUint32BE ( ) = = MKID_BE ( ' WINN ' ) ) {
2007-12-10 18:51:48 +00:00
saveVersion = infile - > readByte ( ) ;
if ( saveVersion ! = WTP_SAVEGAME_VERSION )
warning ( " Old save game version (%d, current version is %d). Will try and read anyway, but don't be surprised if bad things happen " , saveVersion , WTP_SAVEGAME_VERSION ) ;
2007-12-08 18:25:00 +00:00
2007-12-10 18:51:48 +00:00
_game . fSound = infile - > readByte ( ) ;
_game . nMoves = infile - > readByte ( ) ;
_game . nObjMiss = infile - > readByte ( ) ;
_game . nObjRet = infile - > readByte ( ) ;
_game . iObjHave = infile - > readByte ( ) ;
} else {
// This is probably a save from the original interpreter, throw a warning and attempt
// to read it as LE
warning ( " No header found in save game, assuming it came from the original interpreter " ) ;
// Note that the original saves variables as 16-bit integers, but only 8 bits are used.
// Since we read the save file data as little-endian, we skip the first byte of each
// variable
2008-01-27 19:47:41 +00:00
2007-12-10 20:19:53 +00:00
infile - > seek ( 0 ) ; // Jump back to the beginning of the file
2007-12-10 18:57:17 +00:00
2007-12-10 20:19:53 +00:00
infile - > readUint16LE ( ) ; // skip unused field
2007-12-10 18:51:48 +00:00
infile - > readByte ( ) ; // first 8 bits of fSound
_game . fSound = infile - > readByte ( ) ;
infile - > readByte ( ) ; // first 8 bits of nMoves
_game . nMoves = infile - > readByte ( ) ;
infile - > readByte ( ) ; // first 8 bits of nObjMiss
_game . nObjMiss = infile - > readByte ( ) ;
infile - > readByte ( ) ; // first 8 bits of nObjRet
_game . nObjRet = infile - > readByte ( ) ;
infile - > readUint16LE ( ) ; // skip unused field
infile - > readUint16LE ( ) ; // skip unused field
infile - > readUint16LE ( ) ; // skip unused field
infile - > readByte ( ) ; // first 8 bits of iObjHave
_game . iObjHave = infile - > readByte ( ) ;
infile - > readUint16LE ( ) ; // skip unused field
infile - > readUint16LE ( ) ; // skip unused field
infile - > readUint16LE ( ) ; // skip unused field
}
2007-12-08 18:25:00 +00:00
for ( i = 0 ; i < IDI_WTP_MAX_FLAG ; i + + )
_game . fGame [ i ] = infile - > readByte ( ) ;
for ( i = 0 ; i < IDI_WTP_MAX_OBJ_MISSING ; i + + )
_game . iUsedObj [ i ] = infile - > readByte ( ) ;
for ( i = 0 ; i < IDI_WTP_MAX_ROOM_OBJ ; i + + )
_game . iObjRoom [ i ] = infile - > readByte ( ) ;
2008-01-27 19:47:41 +00:00
// Note that saved games from the original interpreter have 2 more 16-bit fields here
2007-12-10 18:57:17 +00:00
// which are ignored
2007-12-08 18:25:00 +00:00
delete infile ;
2007-09-07 20:30:10 +00:00
}
2008-01-11 09:52:06 +00:00
void Winnie : : printStrWinnie ( char * szMsg ) {
if ( _vm - > getPlatform ( ) ! = Common : : kPlatformAmiga )
_vm - > printStrXOR ( szMsg ) ;
else
_vm - > printStr ( szMsg ) ;
}
2007-10-13 23:48:59 +00:00
// Console-related functions
void Winnie : : debugCurRoom ( ) {
_vm - > _console - > DebugPrintf ( " Current Room = %d \n " , _room ) ;
}
2007-09-06 10:48:00 +00:00
2007-10-13 23:48:59 +00:00
Winnie : : Winnie ( PreAgiEngine * vm ) : _vm ( vm ) {
_vm - > _console = new Winnie_Console ( _vm , this ) ;
2007-09-06 10:48:00 +00:00
}
void Winnie : : init ( ) {
2007-09-23 17:00:35 +00:00
memset ( & _game , 0 , sizeof ( _game ) ) ;
_game . fSound = 1 ;
_game . nObjMiss = IDI_WTP_MAX_OBJ_MISSING ;
_game . nObjRet = 0 ;
_game . fGame [ 0 ] = 1 ;
_game . fGame [ 1 ] = 1 ;
_room = IDI_WTP_ROOM_HOME ;
2007-09-23 16:32:03 +00:00
_mist = - 1 ;
2007-09-23 17:00:35 +00:00
_doWind = false ;
_winnieEvent = false ;
2007-09-23 16:32:03 +00:00
2008-01-11 09:52:06 +00:00
if ( _vm - > getPlatform ( ) ! = Common : : kPlatformAmiga ) {
_isBigEndian = false ;
_roomOffset = IDI_WTP_OFS_ROOM ;
_objOffset = IDI_WTP_OFS_OBJ ;
} else {
_isBigEndian = true ;
_roomOffset = 0 ;
_objOffset = 0 ;
}
2007-09-24 19:37:57 +00:00
if ( _vm - > getPlatform ( ) = = Common : : kPlatformC64 | | _vm - > getPlatform ( ) = = Common : : kPlatformApple2GS )
2007-09-23 16:32:03 +00:00
_vm - > _picture - > setPictureVersion ( AGIPIC_C64 ) ;
2008-01-11 09:52:06 +00:00
hotspotNorth = Common : : Rect ( 20 , 0 , ( IDI_WTP_PIC_WIDTH + 10 ) * 2 , 10 ) ;
hotspotSouth = Common : : Rect ( 20 , IDI_WTP_PIC_HEIGHT - 10 , ( IDI_WTP_PIC_WIDTH + 10 ) * 2 , IDI_WTP_PIC_HEIGHT ) ;
hotspotEast = Common : : Rect ( IDI_WTP_PIC_WIDTH * 2 , 0 , ( IDI_WTP_PIC_WIDTH + 10 ) * 2 , IDI_WTP_PIC_HEIGHT ) ;
hotspotWest = Common : : Rect ( 20 , 0 , 30 , IDI_WTP_PIC_HEIGHT ) ;
2007-09-06 10:48:00 +00:00
}
void Winnie : : run ( ) {
randomize ( ) ;
2007-09-24 19:37:57 +00:00
if ( _vm - > getPlatform ( ) ! = Common : : kPlatformC64 & & _vm - > getPlatform ( ) ! = Common : : kPlatformApple2GS )
2007-09-23 02:15:48 +00:00
intro ( ) ;
2007-09-22 23:36:00 +00:00
gameLoop ( ) ;
2007-09-06 10:48:00 +00:00
}
}