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 .
*
*/
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"
2010-11-19 17:03:07 +00:00
# include "common/memstream.h"
2007-09-07 20:30:10 +00:00
# include "common/savefile.h"
2011-04-24 08:34:27 +00:00
# include "common/textconsole.h"
2007-09-06 20:51:40 +00:00
2011-08-15 15:51:21 +00:00
# include "audio/mididrv.h"
2007-09-06 10:48:00 +00:00
namespace Agi {
2011-08-15 04:21:19 +00:00
void WinnieEngine : : parseRoomHeader ( WTP_ROOM_HDR * roomHdr , byte * buffer , int len ) {
2007-09-23 12:25:44 +00:00
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 ( ) ;
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : parseObjHeader ( WTP_OBJ_HDR * objHdr , byte * buffer , int len ) {
2007-09-23 12:25:44 +00:00
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 ( ) ;
}
2011-08-15 04:21:19 +00:00
uint32 WinnieEngine : : readRoom ( int iRoom , uint8 * buffer , WTP_ROOM_HDR & roomHdr ) {
2011-07-03 17:47:37 +00:00
Common : : String fileName ;
2007-09-23 12:02:34 +00:00
2013-05-02 22:26:58 +00:00
if ( getPlatform ( ) = = Common : : kPlatformDOS )
2011-07-03 17:47:37 +00:00
fileName = Common : : String : : format ( IDS_WTP_ROOM_DOS , iRoom ) ;
2011-08-15 04:21:19 +00:00
else if ( getPlatform ( ) = = Common : : kPlatformAmiga )
2011-07-03 17:47:37 +00:00
fileName = Common : : String : : format ( IDS_WTP_ROOM_AMIGA , iRoom ) ;
2011-08-15 04:21:19 +00:00
else if ( getPlatform ( ) = = Common : : kPlatformC64 )
2011-07-03 17:47:37 +00:00
fileName = Common : : String : : format ( IDS_WTP_ROOM_C64 , iRoom ) ;
2011-08-15 04:21:19 +00:00
else if ( getPlatform ( ) = = Common : : kPlatformApple2GS )
2011-07-03 17:47:37 +00:00
fileName = Common : : String : : format ( IDS_WTP_ROOM_APPLE , iRoom ) ;
2011-07-03 17:39:45 +00:00
2007-09-06 20:51:40 +00:00
Common : : File file ;
2011-07-03 17:47:37 +00:00
if ( ! file . open ( fileName ) ) {
warning ( " Could not open file \' %s \' " , fileName . c_str ( ) ) ;
2007-09-20 21:55:37 +00:00
return 0 ;
2007-09-22 20:16:24 +00:00
}
2011-07-03 17:39:45 +00:00
2007-09-06 20:51:40 +00:00
uint32 filelen = file . size ( ) ;
2011-08-15 04:21:19 +00:00
if ( getPlatform ( ) = = Common : : kPlatformC64 ) { // Skip the loading address
2007-09-23 02:15:48 +00:00
filelen - = 2 ;
file . seek ( 2 , SEEK_CUR ) ;
}
2011-07-03 17:39:45 +00:00
memset ( buffer , 0 , 4096 ) ;
2007-09-06 20:51:40 +00:00
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
}
2011-08-15 04:21:19 +00:00
uint32 WinnieEngine : : readObj ( int iObj , uint8 * buffer ) {
2011-07-03 17:47:37 +00:00
Common : : String fileName ;
2011-07-03 17:39:45 +00:00
2013-05-02 22:26:58 +00:00
if ( getPlatform ( ) = = Common : : kPlatformDOS )
2011-07-03 17:47:37 +00:00
fileName = Common : : String : : format ( IDS_WTP_OBJ_DOS , iObj ) ;
2011-08-15 04:21:19 +00:00
else if ( getPlatform ( ) = = Common : : kPlatformAmiga )
2011-07-03 17:47:37 +00:00
fileName = Common : : String : : format ( IDS_WTP_OBJ_AMIGA , iObj ) ;
2011-08-15 04:21:19 +00:00
else if ( getPlatform ( ) = = Common : : kPlatformC64 )
2011-07-03 17:47:37 +00:00
fileName = Common : : String : : format ( IDS_WTP_OBJ_C64 , iObj ) ;
2011-08-15 04:21:19 +00:00
else if ( getPlatform ( ) = = Common : : kPlatformApple2GS )
2011-07-03 17:47:37 +00:00
fileName = Common : : String : : format ( IDS_WTP_OBJ_APPLE , iObj ) ;
2011-07-03 17:39:45 +00:00
2007-09-06 23:45:32 +00:00
Common : : File file ;
2011-07-03 17:47:37 +00:00
if ( ! file . open ( fileName ) ) {
warning ( " Could not open file \' %s \' " , fileName . c_str ( ) ) ;
2007-09-19 22:29:14 +00:00
return 0 ;
2007-09-22 20:16:24 +00:00
}
2011-07-03 17:39:45 +00:00
2007-09-06 23:45:32 +00:00
uint32 filelen = file . size ( ) ;
2011-08-15 04:21:19 +00:00
if ( getPlatform ( ) = = Common : : kPlatformC64 ) { // Skip the loading address
2007-09-23 13:47:50 +00:00
filelen - = 2 ;
file . seek ( 2 , SEEK_CUR ) ;
}
2011-07-03 17:39:45 +00:00
memset ( buffer , 0 , 2048 ) ;
2007-09-06 23:45:32 +00:00
file . read ( buffer , filelen ) ;
file . close ( ) ;
2007-09-19 22:29:14 +00:00
return filelen ;
2007-09-06 23:45:32 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : randomize ( ) {
2007-09-06 10:48:00 +00:00
int iObj = 0 ;
int iRoom = 0 ;
bool done ;
for ( int i = 0 ; i < IDI_WTP_MAX_OBJ_MISSING ; i + + ) {
done = false ;
2009-06-06 17:39:13 +00:00
2007-09-06 10:48:00 +00:00
while ( ! done ) {
2011-08-15 04:21:19 +00:00
iObj = rnd ( IDI_WTP_MAX_OBJ - 1 ) ;
2007-09-06 10:48:00 +00:00
done = true ;
2009-06-06 17:39:13 +00:00
2007-09-06 10:48:00 +00:00
for ( int j = 0 ; j < IDI_WTP_MAX_OBJ_MISSING ; j + + ) {
2011-08-15 04:21:19 +00:00
if ( _gameStateWinnie . iUsedObj [ j ] = = iObj ) {
2007-09-06 10:48:00 +00:00
done = false ;
break ;
}
}
}
2011-08-15 04:21:19 +00:00
_gameStateWinnie . iUsedObj [ i ] = iObj ;
2008-01-27 19:47:41 +00:00
2007-09-06 10:48:00 +00:00
done = false ;
while ( ! done ) {
2011-08-15 04:21:19 +00:00
iRoom = rnd ( IDI_WTP_MAX_ROOM_NORMAL ) ;
2007-09-06 10:48:00 +00:00
done = true ;
2009-06-06 17:39:13 +00:00
2007-09-06 10:48:00 +00:00
for ( int j = 0 ; j < IDI_WTP_MAX_ROOM_OBJ ; j + + ) {
2011-08-15 04:21:19 +00:00
if ( _gameStateWinnie . iObjRoom [ j ] = = iRoom ) {
2007-09-06 10:48:00 +00:00
done = false ;
break ;
}
}
}
2011-08-15 04:21:19 +00:00
_gameStateWinnie . iObjRoom [ iObj ] = iRoom ;
2007-09-06 10:48:00 +00:00
}
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : intro ( ) {
2007-09-22 20:16:24 +00:00
drawPic ( IDS_WTP_FILE_LOGO ) ;
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_INTRO_0 ) ;
_gfx - > doUpdate ( ) ;
_system - > delayMillis ( 0x640 ) ;
2009-06-06 17:39:13 +00:00
2011-08-15 04:21:19 +00:00
if ( getPlatform ( ) = = Common : : kPlatformAmiga )
_gfx - > clearScreen ( 0 ) ;
2009-06-06 17:39:13 +00:00
2007-09-22 20:16:24 +00:00
drawPic ( IDS_WTP_FILE_TITLE ) ;
2009-06-06 17:39:13 +00:00
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_INTRO_1 ) ;
_gfx - > doUpdate ( ) ;
_system - > delayMillis ( 0x640 ) ;
2009-06-06 17:39:13 +00:00
2007-09-20 22:05:37 +00:00
if ( ! playSound ( IDI_WTP_SND_POOH_0 ) )
return ;
2009-06-06 17:39:13 +00:00
2007-09-20 22:05:37 +00:00
if ( ! playSound ( IDI_WTP_SND_POOH_1 ) )
return ;
2009-06-06 17:39:13 +00:00
2007-09-20 22:05:37 +00:00
if ( ! playSound ( IDI_WTP_SND_POOH_2 ) )
return ;
2007-09-06 10:48:00 +00:00
}
2011-08-15 04:21:19 +00:00
int WinnieEngine : : getObjInRoom ( int iRoom ) {
2008-01-27 19:47:41 +00:00
for ( int iObj = 1 ; iObj < IDI_WTP_MAX_ROOM_OBJ ; iObj + + )
2011-08-15 04:21:19 +00:00
if ( _gameStateWinnie . iObjRoom [ iObj ] = = iRoom )
2007-09-06 20:51:40 +00:00
return iObj ;
return 0 ;
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : setTakeDrop ( int fCanSel [ ] ) {
2011-05-07 19:25:55 +00:00
fCanSel [ IDI_WTP_SEL_TAKE ] = getObjInRoom ( _room ) ;
2011-08-15 04:21:19 +00:00
fCanSel [ IDI_WTP_SEL_DROP ] = _gameStateWinnie . iObjHave ;
2007-09-06 20:51:40 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : setFlag ( int iFlag ) {
_gameStateWinnie . fGame [ iFlag ] = 1 ;
2007-09-07 20:30:10 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : clearFlag ( int iFlag ) {
_gameStateWinnie . fGame [ iFlag ] = 0 ;
2007-09-07 20:30:10 +00:00
}
2011-08-15 04:21:19 +00:00
int WinnieEngine : : parser ( int pc , int index , uint8 * buffer ) {
2007-09-06 20:51:40 +00:00
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
2011-08-15 04:21:19 +00:00
while ( ! shouldQuit ( ) ) {
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 + + ) ;
2011-08-15 04:21:19 +00:00
if ( _gameStateWinnie . fGame [ iBlock ] ! = fBlock )
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_OK ;
// extract text from block
opcode = * ( buffer + pc ) ;
2009-09-30 16:16:53 +00:00
switch ( opcode ) {
2007-09-06 20:51:40 +00:00
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
2011-05-07 19:25:55 +00:00
setTakeDrop ( fCanSel ) ;
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 ) ) ;
2011-08-15 04:21:19 +00:00
XOR80 ( szMenu ) ;
2007-09-06 20:51:40 +00:00
break ;
default :
// print description
2008-01-11 09:52:06 +00:00
printStrWinnie ( ( char * ) ( buffer + pc ) ) ;
2011-08-15 04:21:19 +00:00
if ( 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 ) ;
2011-08-15 04:21:19 +00:00
if ( + + _gameStateWinnie . nMoves = = IDI_WTP_MAX_MOVES_UNTIL_WIND )
2007-09-23 17:00:35 +00:00
_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
2009-09-30 16:16:53 +00:00
switch ( iSel ) {
2007-09-06 20:51:40 +00:00
case IDI_WTP_SEL_HOME :
2009-09-30 16:16:53 +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 ;
2009-06-06 17:39:13 +00:00
2007-09-06 20:51:40 +00:00
if ( hdr . roomNew [ iDir ] = = IDI_WTP_ROOM_NONE ) {
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_CANT_GO ) ;
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 ) ;
2011-05-07 19:25:55 +00:00
setTakeDrop ( fCanSel ) ;
2007-09-06 20:51:40 +00:00
break ;
case IDI_WTP_SEL_DROP :
2007-09-23 17:00:35 +00:00
dropObj ( _room ) ;
2011-05-07 19:25:55 +00:00
setTakeDrop ( fCanSel ) ;
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 + + ) ;
2009-09-30 16:16:53 +00:00
switch ( opcode ) {
2007-09-06 20:51:40 +00:00
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 ) ;
2011-08-15 04:21:19 +00:00
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 ) {
2011-08-15 04:21:19 +00:00
_room = 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 :
2011-08-15 04:21:19 +00:00
_room = rnd ( IDI_WTP_MAX_ROOM_TELEPORT ) + 1 ;
2007-09-06 20:51:40 +00:00
return IDI_WTP_PAR_GOTO ;
default :
opcode = 0 ;
break ;
}
2011-08-15 04:21:19 +00:00
} while ( opcode & & ! shouldQuit ( ) ) ;
2007-09-06 20:51:40 +00:00
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 ;
2011-08-15 04:21:19 +00:00
_gfx - > doUpdate ( ) ;
2007-09-06 20:51:40 +00:00
}
2009-05-24 15:17:42 +00:00
2009-01-04 19:52:59 +00:00
return IDI_WTP_PAR_OK ;
2007-09-06 20:51:40 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : keyHelp ( ) {
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_KEYHELP ) ;
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_HELP_0 ) ;
getSelection ( kSelAnyKey ) ;
printStr ( IDS_WTP_HELP_1 ) ;
getSelection ( kSelAnyKey ) ;
2007-09-06 23:45:32 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : inventory ( ) {
if ( _gameStateWinnie . iObjHave )
printObjStr ( _gameStateWinnie . iObjHave , IDI_WTP_OBJ_TAKE ) ;
2007-09-06 23:45:32 +00:00
else {
2011-08-15 04:21:19 +00:00
clearTextArea ( ) ;
drawStr ( IDI_WTP_ROW_MENU , IDI_WTP_COL_MENU , IDA_DEFAULT , IDS_WTP_INVENTORY_0 ) ;
2007-09-06 23:45:32 +00:00
}
2011-08-15 04:21:19 +00:00
Common : : String missing = Common : : String : : format ( IDS_WTP_INVENTORY_1 , _gameStateWinnie . nObjMiss ) ;
2011-07-03 17:47:37 +00:00
2011-08-15 04:21:19 +00:00
drawStr ( IDI_WTP_ROW_OPTION_4 , IDI_WTP_COL_MENU , IDA_DEFAULT , missing . c_str ( ) ) ;
_gfx - > doUpdate ( ) ;
getSelection ( kSelAnyKey ) ;
2007-09-06 23:45:32 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : printObjStr ( int iObj , int iStr ) {
2007-09-06 23:45:32 +00:00
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 ) ;
}
2011-08-15 04:21:19 +00:00
bool WinnieEngine : : isRightObj ( int iRoom , int iObj , int * iCode ) {
2007-09-07 20:09:00 +00:00
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 ;
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : takeObj ( int iRoom ) {
if ( _gameStateWinnie . iObjHave ) {
2007-09-07 20:09:00 +00:00
// player is already carrying an object, can't take
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_CANT_TAKE ) ;
getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
} else {
// take object
int iObj = getObjInRoom ( iRoom ) ;
2009-06-06 17:39:13 +00:00
2011-08-15 04:21:19 +00:00
_gameStateWinnie . iObjHave = iObj ;
_gameStateWinnie . iObjRoom [ iObj ] = 0 ;
2007-09-07 20:09:00 +00:00
2011-08-15 04:21:19 +00:00
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
2011-08-15 04:21:19 +00:00
printObjStr ( _gameStateWinnie . iObjHave , IDI_WTP_OBJ_TAKE ) ;
getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
// HACK WARNING
if ( iObj = = 18 ) {
2011-08-15 04:21:19 +00:00
_gameStateWinnie . fGame [ 0x0d ] = 1 ;
2007-09-07 20:09:00 +00:00
}
}
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : dropObj ( int iRoom ) {
2007-09-07 20:09:00 +00:00
int iCode ;
if ( getObjInRoom ( iRoom ) ) {
// there already is an object in the room, can't drop
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_CANT_DROP ) ;
getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
} else {
// HACK WARNING
2011-08-15 04:21:19 +00:00
if ( _gameStateWinnie . iObjHave = = 18 ) {
_gameStateWinnie . fGame [ 0x0d ] = 0 ;
2007-09-07 20:09:00 +00:00
}
2011-08-15 04:21:19 +00:00
if ( isRightObj ( iRoom , _gameStateWinnie . iObjHave , & iCode ) ) {
2007-09-07 20:09:00 +00:00
// object has been dropped in the right place
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_OK ) ;
getSelection ( kSelAnyKey ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_DROP_OK ) ;
2011-08-15 04:21:19 +00:00
printObjStr ( _gameStateWinnie . iObjHave , IDI_WTP_OBJ_DROP ) ;
getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
// increase amount of objects returned, decrease amount of objects missing
2011-08-15 04:21:19 +00:00
_gameStateWinnie . nObjMiss - - ;
_gameStateWinnie . 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 + + ) {
2011-08-15 04:21:19 +00:00
if ( _gameStateWinnie . iUsedObj [ i ] = = _gameStateWinnie . iObjHave ) {
_gameStateWinnie . iUsedObj [ i ] ^ = 0x80 ;
2007-09-07 20:09:00 +00:00
break ;
}
}
// set flag according to dropped object's id
2011-08-15 04:21:19 +00:00
_gameStateWinnie . fGame [ iCode ] = 1 ;
2008-01-27 19:47:41 +00:00
2007-09-07 20:09:00 +00:00
// player is carrying nothing
2011-08-15 04:21:19 +00:00
_gameStateWinnie . iObjHave = 0 ;
2008-01-27 19:47:41 +00:00
2011-08-15 04:21:19 +00:00
if ( ! _gameStateWinnie . 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 ) ;
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_GAME_OVER_0 ) ;
getSelection ( kSelAnyKey ) ;
printStr ( IDS_WTP_GAME_OVER_1 ) ;
getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
}
} else {
// drop object in the given room
2011-08-15 04:21:19 +00:00
_gameStateWinnie . iObjRoom [ _gameStateWinnie . iObjHave ] = iRoom ;
2007-09-07 20:09:00 +00:00
// object has been dropped in the wrong place
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_WRONG_PLACE ) ;
getSelection ( kSelAnyKey ) ;
2009-06-06 17:39:13 +00:00
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_DROP ) ;
2007-09-07 20:09:00 +00:00
drawRoomPic ( ) ;
2009-06-06 17:39:13 +00:00
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_WRONG_PLACE ) ;
getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
// print object description
2011-08-15 04:21:19 +00:00
printObjStr ( _gameStateWinnie . iObjHave , IDI_WTP_OBJ_DESC ) ;
getSelection ( kSelAnyKey ) ;
2007-09-07 20:09:00 +00:00
2011-08-15 04:21:19 +00:00
_gameStateWinnie . iObjHave = 0 ;
2007-09-07 20:09:00 +00:00
}
}
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : dropObjRnd ( ) {
if ( ! _gameStateWinnie . 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 ) {
2011-08-15 04:21:19 +00:00
iRoom = rnd ( IDI_WTP_MAX_ROOM_NORMAL ) ;
2007-09-07 20:47:31 +00:00
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 + + ) {
2011-08-15 04:21:19 +00:00
if ( _gameStateWinnie . iObjRoom [ j ] = = iRoom ) {
2007-09-07 20:47:31 +00:00
done = false ;
}
}
}
2011-08-15 04:21:19 +00:00
_gameStateWinnie . iObjRoom [ _gameStateWinnie . iObjHave ] = iRoom ;
_gameStateWinnie . iObjHave = 0 ;
2007-09-07 20:47:31 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : 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 ;
2011-08-15 04:21:19 +00:00
_gameStateWinnie . nMoves = 0 ;
if ( ! _gameStateWinnie . nObjMiss )
2007-09-07 20:47:31 +00:00
return ;
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_WIND_0 ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_WIND_0 ) ;
2011-08-15 04:21:19 +00:00
getSelection ( kSelAnyKey ) ;
2009-06-06 17:39:13 +00:00
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_WIND_1 ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_WIND_0 ) ;
2011-08-15 04:21:19 +00:00
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 + + ) {
2011-08-15 04:21:19 +00:00
if ( ! ( _gameStateWinnie . iUsedObj [ i ] & IDI_XOR_KEY ) ) {
2007-09-07 20:47:31 +00:00
done = false ;
while ( ! done ) {
2011-08-15 04:21:19 +00:00
iRoom = rnd ( IDI_WTP_MAX_ROOM_NORMAL ) ;
2007-09-07 20:47:31 +00:00
done = true ;
2009-06-06 17:39:13 +00:00
2007-09-07 20:47:31 +00:00
for ( int j = 0 ; j < IDI_WTP_MAX_ROOM_OBJ ; j + + ) {
2011-08-15 04:21:19 +00:00
if ( _gameStateWinnie . iObjRoom [ j ] = = iRoom ) {
2007-09-07 20:47:31 +00:00
done = false ;
}
}
}
2011-08-15 04:21:19 +00:00
_gameStateWinnie . iObjRoom [ _gameStateWinnie . iUsedObj [ i ] ] = iRoom ;
2007-09-07 20:47:31 +00:00
}
}
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : mist ( ) {
2007-09-23 15:09:48 +00:00
// mist length in turns is (2-5)
2011-08-15 04:21:19 +00:00
_mist = rnd ( 4 ) + 2 ;
2007-09-23 15:09:48 +00:00
2007-09-23 17:00:35 +00:00
_room = IDI_WTP_ROOM_MIST ;
2007-09-23 15:09:48 +00:00
drawRoomPic ( ) ;
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_MIST ) ;
2007-09-23 15:09:48 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : tigger ( ) {
2007-09-23 17:00:35 +00:00
_room = IDI_WTP_ROOM_TIGGER ;
2007-09-23 15:09:48 +00:00
drawRoomPic ( ) ;
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_TIGGER ) ;
2007-09-23 15:09:48 +00:00
dropObjRnd ( ) ;
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : showOwlHelp ( ) {
if ( _gameStateWinnie . iObjHave ) {
printStr ( IDS_WTP_OWL_0 ) ;
getSelection ( kSelAnyKey ) ;
printObjStr ( _gameStateWinnie . iObjHave , IDI_WTP_OBJ_HELP ) ;
getSelection ( kSelAnyKey ) ;
2007-09-07 20:47:31 +00:00
}
2007-09-23 17:00:35 +00:00
if ( getObjInRoom ( _room ) ) {
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_OWL_0 ) ;
getSelection ( kSelAnyKey ) ;
2007-09-23 17:00:35 +00:00
printObjStr ( getObjInRoom ( _room ) , IDI_WTP_OBJ_HELP ) ;
2011-08-15 04:21:19 +00:00
getSelection ( kSelAnyKey ) ;
2007-09-07 20:47:31 +00:00
}
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : drawMenu ( char * szMenu , int iSel , int fCanSel [ ] ) {
2007-09-06 20:51:40 +00:00
int iRow = 0 , iCol = 0 ;
2011-08-15 04:21:19 +00:00
clearTextArea ( ) ;
drawStr ( IDI_WTP_ROW_MENU , IDI_WTP_COL_MENU , IDA_DEFAULT , szMenu ) ;
2007-09-06 20:51:40 +00:00
if ( fCanSel [ IDI_WTP_SEL_NORTH ] )
2011-08-15 04:21:19 +00:00
drawStr ( IDI_WTP_ROW_OPTION_4 , IDI_WTP_COL_NSEW , IDA_DEFAULT , IDS_WTP_NSEW ) ;
2007-09-06 20:51:40 +00:00
if ( fCanSel [ IDI_WTP_SEL_TAKE ] )
2011-08-15 04:21:19 +00:00
drawStr ( IDI_WTP_ROW_OPTION_4 , IDI_WTP_COL_TAKE , IDA_DEFAULT , IDS_WTP_TAKE ) ;
2007-09-06 20:51:40 +00:00
if ( fCanSel [ IDI_WTP_SEL_DROP ] )
2011-08-15 04:21:19 +00:00
drawStr ( IDI_WTP_ROW_OPTION_4 , IDI_WTP_COL_DROP , IDA_DEFAULT , IDS_WTP_DROP ) ;
2008-01-27 19:47:41 +00:00
2009-09-30 16:16:53 +00:00
switch ( iSel ) {
2007-09-06 20:51:40 +00:00
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 ;
}
2011-08-15 04:21:19 +00:00
drawStr ( iRow , iCol - 1 , IDA_DEFAULT , " > " ) ;
_gfx - > doUpdate ( ) ;
2007-09-06 20:51:40 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : incMenuSel ( int * iSel , int fCanSel [ ] ) {
2007-09-06 20:51:40 +00:00
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
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : decMenuSel ( int * iSel , int fCanSel [ ] ) {
2007-09-06 20:51:40 +00:00
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
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : getMenuMouseSel ( int * iSel , int fCanSel [ ] , int x , int y ) {
2009-09-30 16:16:53 +00:00
switch ( y ) {
2007-09-07 20:30:10 +00:00
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 ;
}
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : makeSel ( int * iSel , int fCanSel [ ] ) {
2011-05-07 19:25:55 +00:00
if ( fCanSel [ * iSel ] )
return ;
keyHelp ( ) ;
clrMenuSel ( iSel , fCanSel ) ;
2007-09-06 20:51:40 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : 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 ) ;
2011-08-15 04:21:19 +00:00
while ( ! shouldQuit ( ) ) {
while ( _system - > getEventManager ( ) - > pollEvent ( event ) ) {
2009-09-30 16:16:53 +00:00
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 ) ) {
2011-08-15 04:21:19 +00:00
_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 ) ) {
2011-08-15 04:21:19 +00:00
_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 ) ) {
2011-08-15 04:21:19 +00:00
_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 ) ) {
2011-08-15 04:21:19 +00:00
_gfx - > setCursorPalette ( true ) ;
2007-09-07 16:22:31 +00:00
} else {
2011-08-15 04:21:19 +00:00
_gfx - > setCursorPalette ( false ) ;
2007-09-07 16:22:31 +00:00
}
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 ;
2011-05-07 19:25:55 +00:00
makeSel ( iSel , fCanSel ) ;
2011-08-15 04:21:19 +00:00
_gfx - > setCursorPalette ( false ) ;
2007-09-09 23:13:35 +00:00
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 ;
2011-05-07 19:25:55 +00:00
makeSel ( iSel , fCanSel ) ;
2011-08-15 04:21:19 +00:00
_gfx - > setCursorPalette ( false ) ;
2007-09-09 23:13:35 +00:00
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 ;
2011-05-07 19:25:55 +00:00
makeSel ( iSel , fCanSel ) ;
2011-08-15 04:21:19 +00:00
_gfx - > setCursorPalette ( false ) ;
2007-09-09 23:13:35 +00:00
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 ;
2011-05-07 19:25:55 +00:00
makeSel ( iSel , fCanSel ) ;
2011-08-15 04:21:19 +00:00
_gfx - > setCursorPalette ( false ) ;
2007-09-09 23:13:35 +00:00
return ;
} else {
2011-08-15 04:21:19 +00:00
_gfx - > setCursorPalette ( false ) ;
2007-09-09 23:13:35 +00:00
}
2009-09-30 16:16:53 +00:00
switch ( * iSel ) {
2007-09-06 20:51:40 +00:00
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 :
2011-08-15 04:21:19 +00:00
if ( event . kbd . keycode = = Common : : KEYCODE_d & & ( event . kbd . flags & Common : : KBD_CTRL ) & & _console ) {
_console - > attach ( ) ;
_console - > onFrame ( ) ;
2007-10-13 23:48:59 +00:00
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 ;
2011-05-07 19:25:55 +00:00
makeSel ( iSel , fCanSel ) ;
2007-09-06 20:51:40 +00:00
break ;
case Common : : KEYCODE_s :
2007-09-07 16:22:31 +00:00
if ( event . kbd . flags & Common : : KBD_CTRL ) {
2011-08-15 04:21:19 +00:00
flipflag ( fSoundOn ) ;
2007-09-06 20:51:40 +00:00
} else {
* iSel = IDI_WTP_SEL_SOUTH ;
2011-05-07 19:25:55 +00:00
makeSel ( iSel , fCanSel ) ;
2007-09-06 20:51:40 +00:00
}
break ;
case Common : : KEYCODE_e :
* iSel = IDI_WTP_SEL_EAST ;
2011-05-07 19:25:55 +00:00
makeSel ( iSel , fCanSel ) ;
2007-09-06 20:51:40 +00:00
break ;
case Common : : KEYCODE_w :
* iSel = IDI_WTP_SEL_WEST ;
2011-05-07 19:25:55 +00:00
makeSel ( iSel , fCanSel ) ;
2007-09-06 20:51:40 +00:00
break ;
case Common : : KEYCODE_t :
* iSel = IDI_WTP_SEL_TAKE ;
2011-05-07 19:25:55 +00:00
makeSel ( iSel , fCanSel ) ;
2007-09-06 20:51:40 +00:00
break ;
case Common : : KEYCODE_d :
* iSel = IDI_WTP_SEL_DROP ;
2011-05-07 19:25:55 +00:00
makeSel ( iSel , fCanSel ) ;
2007-09-06 20:51:40 +00:00
break ;
case Common : : KEYCODE_RETURN :
2009-09-30 16:16:53 +00:00
switch ( * iSel ) {
2007-09-06 20:51:40 +00:00
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 ;
}
2013-07-15 08:58:52 +00:00
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 ) ;
}
}
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : gameLoop ( ) {
2007-09-06 20:51:40 +00:00
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 ;
2011-12-10 20:12:35 +00:00
uint8 decodePhase = 0 ;
2007-09-06 20:51:40 +00:00
2011-12-10 20:12:35 +00:00
while ( ! shouldQuit ( ) ) {
if ( decodePhase = = 0 ) {
if ( ! _gameStateWinnie . nObjMiss & & ( _room = = IDI_WTP_ROOM_PICNIC ) )
_room = IDI_WTP_ROOM_PARTY ;
2007-09-23 17:00:35 +00:00
2011-12-10 20:12:35 +00:00
readRoom ( _room , roomdata , hdr ) ;
drawRoomPic ( ) ;
_gfx - > doUpdate ( ) ;
decodePhase = 1 ;
}
2009-06-06 17:39:13 +00:00
2011-12-10 20:12:35 +00:00
if ( decodePhase = = 1 ) {
if ( getObjInRoom ( _room ) ) {
printObjStr ( getObjInRoom ( _room ) , IDI_WTP_OBJ_DESC ) ;
getSelection ( kSelAnyKey ) ;
}
decodePhase = 2 ;
}
2009-06-06 17:39:13 +00:00
2011-12-10 20:12:35 +00:00
if ( decodePhase = = 2 ) {
for ( iBlock = 0 ; iBlock < IDI_WTP_MAX_BLOCK ; iBlock + + ) {
if ( parser ( hdr . ofsDesc [ iBlock ] - _roomOffset , iBlock , roomdata ) = = IDI_WTP_PAR_BACK ) {
decodePhase = 1 ;
break ;
}
}
if ( decodePhase = = 2 )
decodePhase = 3 ;
}
2009-05-24 15:17:42 +00:00
2011-12-10 20:12:35 +00:00
if ( decodePhase = = 3 ) {
for ( iBlock = 0 ; iBlock < IDI_WTP_MAX_BLOCK ; iBlock + + ) {
if ( parser ( hdr . ofsBlock [ iBlock ] - _roomOffset , iBlock , roomdata ) = = IDI_WTP_PAR_GOTO ) {
decodePhase = 0 ;
break ;
} else if ( parser ( hdr . ofsBlock [ iBlock ] - _roomOffset , iBlock , roomdata ) = = IDI_WTP_PAR_BACK ) {
decodePhase = 2 ;
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
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : drawPic ( const char * szName ) {
2011-07-03 17:47:37 +00:00
Common : : String fileName = szName ;
2007-09-06 10:48:00 +00:00
2011-08-15 04:21:19 +00:00
if ( getPlatform ( ) ! = Common : : kPlatformAmiga )
2011-07-03 17:47:37 +00:00
fileName + = " .pic " ;
Common : : File file ;
if ( ! file . open ( fileName ) ) {
warning ( " Could not open file \' %s \' " , fileName . c_str ( ) ) ;
2007-09-11 20:09:39 +00:00
return ;
2007-09-22 17:56:23 +00:00
}
2009-06-06 17:39:13 +00:00
2009-10-01 12:09:02 +00:00
uint8 * buffer = ( uint8 * ) malloc ( 4096 ) ;
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
2011-08-15 04:21:19 +00:00
_picture - > decodePicture ( buffer , size , 1 , IDI_WTP_PIC_WIDTH , IDI_WTP_PIC_HEIGHT ) ;
_picture - > showPic ( IDI_WTP_PIC_X0 , IDI_WTP_PIC_Y0 , IDI_WTP_PIC_WIDTH , IDI_WTP_PIC_HEIGHT ) ;
2007-09-06 10:48:00 +00:00
2007-09-20 21:55:37 +00:00
free ( buffer ) ;
2007-09-06 10:48:00 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : drawObjPic ( int iObj , int x0 , int y0 ) {
2007-09-07 20:09:00 +00:00
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
2011-08-15 04:21:19 +00:00
_picture - > setOffset ( x0 , y0 ) ;
_picture - > decodePicture ( buffer + objhdr . ofsPic - _objOffset , objSize , 0 , IDI_WTP_PIC_WIDTH , IDI_WTP_PIC_HEIGHT ) ;
_picture - > setOffset ( 0 , 0 ) ;
_picture - > showPic ( 10 , 0 , IDI_WTP_PIC_WIDTH , IDI_WTP_PIC_HEIGHT ) ;
2007-09-07 20:09:00 +00:00
2007-09-20 21:55:37 +00:00
free ( buffer ) ;
2007-09-07 20:09:00 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : drawRoomPic ( ) {
2007-09-06 20:51:40 +00:00
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
2011-08-15 04:21:19 +00:00
_gfx - > clearScreen ( 0 ) ;
2007-09-06 20:51:40 +00:00
// 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
2011-08-15 04:21:19 +00:00
_picture - > decodePicture ( buffer + roomhdr . ofsPic - _roomOffset , 4096 , 1 , IDI_WTP_PIC_WIDTH , IDI_WTP_PIC_HEIGHT ) ;
_picture - > showPic ( IDI_WTP_PIC_X0 , IDI_WTP_PIC_Y0 , IDI_WTP_PIC_WIDTH , IDI_WTP_PIC_HEIGHT ) ;
2007-09-06 20:51:40 +00:00
// 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
}
2011-08-15 04:21:19 +00:00
bool WinnieEngine : : playSound ( ENUM_WTP_SOUND iSound ) {
2011-08-14 17:14:37 +00:00
// TODO: Only DOS sound is supported, currently
2013-05-02 22:26:58 +00:00
if ( getPlatform ( ) ! = Common : : kPlatformDOS ) {
2011-08-14 17:14:37 +00:00
warning ( " STUB: playSound(%d) " , iSound ) ;
return false ;
}
Common : : String fileName = Common : : String : : format ( IDS_WTP_SND_DOS , iSound ) ;
Common : : File file ;
if ( ! file . open ( fileName ) )
return false ;
uint32 size = file . size ( ) ;
byte * data = new byte [ size ] ;
file . read ( data , size ) ;
file . close ( ) ;
2013-04-18 18:07:39 +00:00
_game . sounds [ 0 ] = AgiSound : : createFromRawResource ( data , size , 0 , _soundemu ) ;
2011-08-15 04:21:19 +00:00
_sound - > startSound ( 0 , 0 ) ;
2011-08-14 17:14:37 +00:00
bool cursorShowing = CursorMan . showMouse ( false ) ;
2011-08-15 04:21:19 +00:00
_system - > updateScreen ( ) ;
2011-08-14 17:14:37 +00:00
// Loop until the sound is done
bool skippedSound = false ;
2011-08-15 04:21:19 +00:00
while ( ! shouldQuit ( ) & & _game . sounds [ 0 ] - > isPlaying ( ) ) {
2011-08-14 17:14:37 +00:00
Common : : Event event ;
2011-08-15 04:21:19 +00:00
while ( _system - > getEventManager ( ) - > pollEvent ( event ) ) {
2011-08-14 17:14:37 +00:00
switch ( event . type ) {
case Common : : EVENT_KEYDOWN :
2011-08-15 04:21:19 +00:00
_sound - > stopSound ( ) ;
2011-08-14 17:14:37 +00:00
skippedSound = true ;
break ;
default :
break ;
}
}
2011-08-15 04:21:19 +00:00
_system - > delayMillis ( 10 ) ;
2011-08-14 17:14:37 +00:00
}
if ( cursorShowing ) {
CursorMan . showMouse ( true ) ;
2011-08-15 04:21:19 +00:00
_system - > updateScreen ( ) ;
2011-08-14 17:14:37 +00:00
}
2011-08-15 04:21:19 +00:00
delete _game . sounds [ 0 ] ;
_game . sounds [ 0 ] = 0 ;
2011-08-14 17:14:37 +00:00
2011-08-15 04:21:19 +00:00
return ! shouldQuit ( ) & & ! skippedSound ;
2007-09-20 22:05:37 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : clrMenuSel ( int * iSel , int fCanSel [ ] ) {
2007-09-06 20:51:40 +00:00
* 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 ;
}
2011-08-15 04:21:19 +00:00
_gfx - > setCursorPalette ( false ) ;
2007-09-06 10:48:00 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : printRoomStr ( int iRoom , int iStr ) {
2007-09-06 21:48:33 +00:00
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 ) ;
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : gameOver ( ) {
2007-09-07 20:30:10 +00:00
// sing the Pooh song forever
2011-08-15 04:21:19 +00:00
while ( ! shouldQuit ( ) ) {
printStr ( IDS_WTP_SONG_0 ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_POOH_0 ) ;
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_SONG_1 ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_POOH_1 ) ;
2011-08-15 04:21:19 +00:00
printStr ( IDS_WTP_SONG_2 ) ;
2007-09-20 22:05:37 +00:00
playSound ( IDI_WTP_SND_POOH_2 ) ;
2011-08-15 04:21:19 +00:00
getSelection ( kSelAnyKey ) ;
2007-09-07 20:30:10 +00:00
}
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : saveGame ( ) {
2007-12-08 18:25:00 +00:00
int i = 0 ;
2007-09-23 16:32:03 +00:00
2011-08-15 04:21:19 +00:00
Common : : OutSaveFile * outfile = getSaveFileMan ( ) - > openForSaving ( IDS_WTP_FILE_SAVEGAME ) ;
2011-07-03 17:47:37 +00:00
if ( ! outfile )
2007-09-23 16:32:03 +00:00
return ;
2011-04-12 14:53:15 +00:00
outfile - > writeUint32BE ( MKTAG ( ' W ' , ' I ' , ' N ' , ' N ' ) ) ; // header
2007-12-08 18:25:00 +00:00
outfile - > writeByte ( WTP_SAVEGAME_VERSION ) ;
2011-08-15 04:21:19 +00:00
outfile - > writeByte ( _gameStateWinnie . fSound ) ;
outfile - > writeByte ( _gameStateWinnie . nMoves ) ;
outfile - > writeByte ( _gameStateWinnie . nObjMiss ) ;
outfile - > writeByte ( _gameStateWinnie . nObjRet ) ;
outfile - > writeByte ( _gameStateWinnie . iObjHave ) ;
2007-12-08 18:25:00 +00:00
2009-01-29 05:26:12 +00:00
for ( i = 0 ; i < IDI_WTP_MAX_FLAG ; i + + )
2011-08-15 04:21:19 +00:00
outfile - > writeByte ( _gameStateWinnie . fGame [ i ] ) ;
2007-12-08 18:25:00 +00:00
2009-01-29 05:26:12 +00:00
for ( i = 0 ; i < IDI_WTP_MAX_OBJ_MISSING ; i + + )
2011-08-15 04:21:19 +00:00
outfile - > writeByte ( _gameStateWinnie . iUsedObj [ i ] ) ;
2007-12-08 18:25:00 +00:00
2009-01-29 05:26:12 +00:00
for ( i = 0 ; i < IDI_WTP_MAX_ROOM_OBJ ; i + + )
2011-08-15 04:21:19 +00:00
outfile - > writeByte ( _gameStateWinnie . iObjRoom [ i ] ) ;
2007-12-08 18:25:00 +00:00
outfile - > finalize ( ) ;
2009-05-19 11:42:14 +00:00
if ( outfile - > err ( ) )
2011-07-03 17:47:37 +00:00
warning ( " Can't write file '%s'. (Disk full?) " , IDS_WTP_FILE_SAVEGAME ) ;
2007-12-08 18:25:00 +00:00
delete outfile ;
2007-09-07 20:30:10 +00:00
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : loadGame ( ) {
2007-12-08 18:25:00 +00:00
int saveVersion = 0 ;
int i = 0 ;
2007-09-23 16:32:03 +00:00
2011-08-15 04:21:19 +00:00
Common : : InSaveFile * infile = getSaveFileMan ( ) - > openForLoading ( IDS_WTP_FILE_SAVEGAME ) ;
2011-07-03 17:47:37 +00:00
if ( ! infile )
2007-09-07 20:30:10 +00:00
return ;
2011-04-12 14:53:15 +00:00
if ( infile - > readUint32BE ( ) = = MKTAG ( ' W ' , ' I ' , ' N ' , ' N ' ) ) {
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
2011-08-15 04:21:19 +00:00
_gameStateWinnie . fSound = infile - > readByte ( ) ;
_gameStateWinnie . nMoves = infile - > readByte ( ) ;
_gameStateWinnie . nObjMiss = infile - > readByte ( ) ;
_gameStateWinnie . nObjRet = infile - > readByte ( ) ;
_gameStateWinnie . iObjHave = infile - > readByte ( ) ;
2007-12-10 18:51:48 +00:00
} 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
2011-08-15 04:21:19 +00:00
_gameStateWinnie . fSound = infile - > readByte ( ) ;
2007-12-10 18:51:48 +00:00
infile - > readByte ( ) ; // first 8 bits of nMoves
2011-08-15 04:21:19 +00:00
_gameStateWinnie . nMoves = infile - > readByte ( ) ;
2007-12-10 18:51:48 +00:00
infile - > readByte ( ) ; // first 8 bits of nObjMiss
2011-08-15 04:21:19 +00:00
_gameStateWinnie . nObjMiss = infile - > readByte ( ) ;
2007-12-10 18:51:48 +00:00
infile - > readByte ( ) ; // first 8 bits of nObjRet
2011-08-15 04:21:19 +00:00
_gameStateWinnie . nObjRet = infile - > readByte ( ) ;
2007-12-10 18:51:48 +00:00
infile - > readUint16LE ( ) ; // skip unused field
infile - > readUint16LE ( ) ; // skip unused field
infile - > readUint16LE ( ) ; // skip unused field
infile - > readByte ( ) ; // first 8 bits of iObjHave
2011-08-15 04:21:19 +00:00
_gameStateWinnie . iObjHave = infile - > readByte ( ) ;
2007-12-10 18:51:48 +00:00
infile - > readUint16LE ( ) ; // skip unused field
infile - > readUint16LE ( ) ; // skip unused field
infile - > readUint16LE ( ) ; // skip unused field
}
2007-12-08 18:25:00 +00:00
2009-01-29 05:26:12 +00:00
for ( i = 0 ; i < IDI_WTP_MAX_FLAG ; i + + )
2011-08-15 04:21:19 +00:00
_gameStateWinnie . fGame [ i ] = infile - > readByte ( ) ;
2007-12-08 18:25:00 +00:00
2009-01-29 05:26:12 +00:00
for ( i = 0 ; i < IDI_WTP_MAX_OBJ_MISSING ; i + + )
2011-08-15 04:21:19 +00:00
_gameStateWinnie . iUsedObj [ i ] = infile - > readByte ( ) ;
2007-12-08 18:25:00 +00:00
2009-01-29 05:26:12 +00:00
for ( i = 0 ; i < IDI_WTP_MAX_ROOM_OBJ ; i + + )
2011-08-15 04:21:19 +00:00
_gameStateWinnie . iObjRoom [ i ] = infile - > readByte ( ) ;
2007-12-08 18:25:00 +00:00
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
}
2011-08-15 04:21:19 +00:00
void WinnieEngine : : printStrWinnie ( char * szMsg ) {
if ( getPlatform ( ) ! = Common : : kPlatformAmiga )
printStrXOR ( szMsg ) ;
2008-01-11 09:52:06 +00:00
else
2011-08-15 04:21:19 +00:00
printStr ( szMsg ) ;
2008-01-11 09:52:06 +00:00
}
2007-10-13 23:48:59 +00:00
// Console-related functions
2011-08-15 04:21:19 +00:00
void WinnieEngine : : debugCurRoom ( ) {
_console - > DebugPrintf ( " Current Room = %d \n " , _room ) ;
2007-10-13 23:48:59 +00:00
}
2007-09-06 10:48:00 +00:00
2011-08-15 04:21:19 +00:00
WinnieEngine : : WinnieEngine ( OSystem * syst , const AGIGameDescription * gameDesc ) : PreAgiEngine ( syst , gameDesc ) {
2011-08-16 02:03:58 +00:00
_console = new WinnieConsole ( this ) ;
2007-09-06 10:48:00 +00:00
}
2011-08-15 04:21:19 +00:00
WinnieEngine : : ~ WinnieEngine ( ) {
delete _console ;
}
void WinnieEngine : : init ( ) {
2011-08-15 15:51:21 +00:00
// Initialize sound
switch ( MidiDriver : : getMusicType ( MidiDriver : : detectDevice ( MDT_PCSPK | MDT_PCJR ) ) ) {
case MT_PCSPK :
_soundemu = SOUND_EMU_PC ;
break ;
case MT_PCJR :
_soundemu = SOUND_EMU_PCJR ;
break ;
default :
_soundemu = SOUND_EMU_NONE ;
break ;
}
_sound = new SoundMgr ( this , _mixer ) ;
2011-08-15 15:33:20 +00:00
setflag ( fSoundOn , true ) ; // enable sound
2011-08-15 04:21:19 +00:00
memset ( & _gameStateWinnie , 0 , sizeof ( _gameStateWinnie ) ) ;
_gameStateWinnie . fSound = 1 ;
_gameStateWinnie . nObjMiss = IDI_WTP_MAX_OBJ_MISSING ;
_gameStateWinnie . nObjRet = 0 ;
_gameStateWinnie . fGame [ 0 ] = 1 ;
_gameStateWinnie . fGame [ 1 ] = 1 ;
2007-09-23 17:00:35 +00:00
_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
2011-08-15 04:21:19 +00:00
if ( getPlatform ( ) ! = Common : : kPlatformAmiga ) {
2008-01-11 09:52:06 +00:00
_isBigEndian = false ;
_roomOffset = IDI_WTP_OFS_ROOM ;
_objOffset = IDI_WTP_OFS_OBJ ;
} else {
_isBigEndian = true ;
_roomOffset = 0 ;
_objOffset = 0 ;
}
2011-08-15 04:21:19 +00:00
if ( getPlatform ( ) = = Common : : kPlatformC64 | | getPlatform ( ) = = Common : : kPlatformApple2GS )
_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
}
2011-08-15 04:21:19 +00:00
Common : : Error WinnieEngine : : go ( ) {
init ( ) ;
2007-09-06 10:48:00 +00:00
randomize ( ) ;
2011-08-15 04:21:19 +00:00
// The intro is not supported on these platforms yet
if ( getPlatform ( ) ! = Common : : kPlatformC64 & & getPlatform ( ) ! = Common : : kPlatformApple2GS )
2007-09-23 02:15:48 +00:00
intro ( ) ;
2011-08-15 04:21:19 +00:00
2007-09-22 23:36:00 +00:00
gameLoop ( ) ;
2007-09-06 10:48:00 +00:00
2011-08-15 04:21:19 +00:00
return Common : : kNoError ;
2007-09-06 10:48:00 +00:00
}
2011-08-15 04:21:19 +00:00
} // End of namespace AGI